Skip to content

Commit

Permalink
feat(core): sidebar template doc entrance (#9676)
Browse files Browse the repository at this point in the history
  • Loading branch information
CatsJuice committed Jan 15, 2025
1 parent 1c90747 commit 419611f
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ import {
workspaceWrapper,
} from './index.css';
import { AppSidebarJournalButton } from './journal-button';
import { TemplateDocEntrance } from './template-doc-entrance';
import { TrashButton } from './trash-button';
import { UpdaterButton } from './updater-button';
import { UserInfo } from './user-info';
Expand Down Expand Up @@ -192,6 +193,7 @@ export const RootAppSidebar = memo((): ReactElement => {
>
<span data-testid="import-modal-trigger">{t['Import']()}</span>
</MenuItem>
<TemplateDocEntrance />
<ExternalMenuLinkItem
href="https://affine.pro/blog?tag=Release+Note"
icon={<JournalIcon />}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import { Menu, MenuItem, MenuSeparator } from '@affine/component';
import { MenuItem as SidebarMenuItem } from '@affine/core/modules/app-sidebar/views';
import { DocsService } from '@affine/core/modules/doc';
import { FeatureFlagService } from '@affine/core/modules/feature-flag';
import { TemplateListMenuContentScrollable } from '@affine/core/modules/template-doc';
import { WorkbenchService } from '@affine/core/modules/workbench';
import { inferOpenMode } from '@affine/core/utils';
import { useI18n } from '@affine/i18n';
import { TemplateIcon, TemplateOutlineIcon } from '@blocksuite/icons/rc';
import { useLiveData, useService } from '@toeverything/infra';
import { useCallback, useState } from 'react';

import { useAsyncCallback } from '../hooks/affine-async-hooks';

export const TemplateDocEntrance = () => {
const t = useI18n();
const [menuOpen, setMenuOpen] = useState(false);
const docsService = useService(DocsService);
const featureFlagService = useService(FeatureFlagService);
const workbench = useService(WorkbenchService).workbench;
const enabled = useLiveData(featureFlagService.flags.enable_template_doc.$);

const toggleMenu = useCallback(() => {
setMenuOpen(prev => !prev);
}, []);

const createDocFromTemplate = useAsyncCallback(
async (templateId: string) => {
const docId = await docsService.duplicateFromTemplate(templateId);
workbench.openDoc(docId);
},
[docsService, workbench]
);

if (!enabled) {
return null;
}

return (
<SidebarMenuItem icon={<TemplateOutlineIcon />} onClick={toggleMenu}>
<Menu
rootOptions={{ open: menuOpen, onOpenChange: setMenuOpen }}
contentOptions={{
side: 'right',
align: 'end',
alignOffset: -4,
sideOffset: 16,
}}
items={
<TemplateListMenuContentScrollable
onSelect={createDocFromTemplate}
suffixItems={
<>
<MenuSeparator />
<CreateNewTemplateMenuItem />
</>
}
/>
}
>
<span>{t['Template']()}</span>
</Menu>
</SidebarMenuItem>
);
};

const CreateNewTemplateMenuItem = () => {
const t = useI18n();
const docsService = useService(DocsService);
const workbench = useService(WorkbenchService).workbench;

const createNewTemplate = useCallback(
(e: React.MouseEvent<HTMLDivElement>) => {
const record = docsService.createDoc({ isTemplate: true });
workbench.openDoc(record.id, { at: inferOpenMode(e) });
},
[docsService, workbench]
);

return (
<MenuItem
prefixIcon={<TemplateIcon />}
onClick={createNewTemplate}
onAuxClick={createNewTemplate}
>
{t['com.affine.template-list.create-new']()}
</MenuItem>
);
};
4 changes: 4 additions & 0 deletions packages/frontend/core/src/modules/doc/services/docs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ export class DocsService extends Service {
options: {
primaryMode?: DocMode;
docProps?: DocProps;
isTemplate?: boolean;
} = {}
) {
const doc = this.store.createBlockSuiteDoc();
Expand All @@ -114,6 +115,9 @@ export class DocsService extends Service {
if (options.primaryMode) {
docRecord.setPrimaryMode(options.primaryMode);
}
if (options.isTemplate) {
docRecord.setProperty('isTemplate', true);
}
this.eventBus.emit(DocCreated, docRecord);
return docRecord;
}
Expand Down
1 change: 1 addition & 0 deletions packages/frontend/i18n/src/resources/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -1631,6 +1631,7 @@
"com.affine.page-starter-bar.edgeless": "Edgeless",
"Template": "Template",
"com.affine.template-list.empty": "No template",
"com.affine.template-list.create-new": "Create new template",
"com.affine.settings.workspace.template.title": "My Templates",
"com.affine.settings.workspace.template.journal": "Template for journal",
"com.affine.settings.workspace.template.journal-desc": "Select a template for your journal",
Expand Down

0 comments on commit 419611f

Please sign in to comment.