diff --git a/packages/frontend/core/src/components/blocksuite/block-suite-editor/starter-bar.tsx b/packages/frontend/core/src/components/blocksuite/block-suite-editor/starter-bar.tsx index ff380e247f..a04da56380 100644 --- a/packages/frontend/core/src/components/blocksuite/block-suite-editor/starter-bar.tsx +++ b/packages/frontend/core/src/components/blocksuite/block-suite-editor/starter-bar.tsx @@ -4,6 +4,7 @@ import { FeatureFlagService } from '@affine/core/modules/feature-flag'; import { TemplateDocService } from '@affine/core/modules/template-doc'; import { TemplateListMenu } from '@affine/core/modules/template-doc/view/template-list-menu'; import { useI18n } from '@affine/i18n'; +import track from '@affine/track'; import type { Store } from '@blocksuite/affine/store'; import { AiIcon, @@ -68,6 +69,7 @@ const StarterBarNotEmpty = ({ doc }: { doc: Store }) => { const handleSelectTemplate = useAsyncCallback( async (templateId: string) => { await docsService.duplicateFromTemplate(templateId, doc.id); + track.doc.editor.starterBar.quickStart({ with: 'template' }); }, [doc.id, docsService] ); @@ -78,6 +80,11 @@ const StarterBarNotEmpty = ({ doc }: { doc: Store }) => { editorService.editor.setMode('edgeless'); }, [doc.id, docsService.list, editorService.editor]); + const onTemplateMenuOpenChange = useCallback((open: boolean) => { + if (open) track.doc.editor.starterBar.openTemplateListMenu(); + setTemplateMenuOpen(open); + }, []); + const showAI = false; const showTemplate = !isTemplate && enableTemplateDoc; @@ -101,7 +108,7 @@ const StarterBarNotEmpty = ({ doc }: { doc: Store }) => { onSelect={handleSelectTemplate} rootOptions={{ open: templateMenuOpen, - onOpenChange: setTemplateMenuOpen, + onOpenChange: onTemplateMenuOpenChange, }} > { +export const TemplateValue = ({ + onChange: propOnChange, +}: PropertyValueProps) => { const docService = useService(DocService); const isTemplate = useLiveData( @@ -16,8 +19,9 @@ export const TemplateValue = () => { (e: ChangeEvent) => { const value = e.target.checked; docService.doc.record.setProperty('isTemplate', value); + propOnChange?.(value, true); }, - [docService.doc.record] + [docService.doc.record, propOnChange] ); const toggle = useCallback(() => { diff --git a/packages/frontend/core/src/components/root-app-sidebar/template-doc-entrance.tsx b/packages/frontend/core/src/components/root-app-sidebar/template-doc-entrance.tsx index 5f70fdf270..34a89fad1e 100644 --- a/packages/frontend/core/src/components/root-app-sidebar/template-doc-entrance.tsx +++ b/packages/frontend/core/src/components/root-app-sidebar/template-doc-entrance.tsx @@ -6,6 +6,7 @@ import { TemplateListMenuContentScrollable } from '@affine/core/modules/template import { WorkbenchService } from '@affine/core/modules/workbench'; import { inferOpenMode } from '@affine/core/utils'; import { useI18n } from '@affine/i18n'; +import track from '@affine/track'; import { TemplateIcon, TemplateOutlineIcon } from '@blocksuite/icons/rc'; import { useLiveData, useService } from '@toeverything/infra'; import { useCallback, useState } from 'react'; @@ -20,6 +21,11 @@ export const TemplateDocEntrance = () => { setMenuOpen(prev => !prev); }, []); + const onMenuOpenChange = useCallback((open: boolean) => { + if (open) track.$.sidebar.template.openTemplateListMenu(); + setMenuOpen(open); + }, []); + if (!enabled) { return null; } @@ -31,7 +37,7 @@ export const TemplateDocEntrance = () => { onClick={toggleMenu} > { createDoc(e, 'page'); track.$.navigationPanel.$.createDoc(); + track.$.sidebar.newDoc.quickStart({ with: 'page' }); }, [createDoc] ); @@ -109,6 +110,7 @@ function AddPageWithAsk({ className, style }: AddPageButtonProps) { (e?: MouseEvent) => { createDoc(e, 'edgeless'); track.$.navigationPanel.$.createDoc(); + track.$.sidebar.newDoc.quickStart({ with: 'edgeless' }); }, [createDoc] ); @@ -117,6 +119,7 @@ function AddPageWithAsk({ className, style }: AddPageButtonProps) { async (templateId: string) => { const docId = await docsService.duplicateFromTemplate(templateId); workbench.openDoc(docId); + track.$.sidebar.newDoc.quickStart({ with: 'template' }); }, [docsService, workbench] ); diff --git a/packages/frontend/track/src/events.ts b/packages/frontend/track/src/events.ts index a340b0b7c1..3263781620 100644 --- a/packages/frontend/track/src/events.ts +++ b/packages/frontend/track/src/events.ts @@ -38,6 +38,7 @@ type WorkspaceEvents = | 'openWorkspaceList'; type DocEvents = | 'createDoc' + | 'quickStart' | 'renameDoc' | 'linkDoc' | 'deleteDoc' @@ -126,6 +127,10 @@ type AttachmentEvents = | 'openPDFRendererFail'; // END SECTION +// SECTION: template +type TemplateEvents = 'openTemplateListMenu'; +// END SECTION + type UserEvents = | GeneralEvents | AppEvents @@ -141,7 +146,8 @@ type UserEvents = | AccountEvents | PaymentEvents | DNDEvents - | AttachmentEvents; + | AttachmentEvents + | TemplateEvents; interface PageDivision { [page: string]: { [segment: string]: { @@ -304,6 +310,10 @@ const PageEvents = { 'openPDFRendererFail', ], }, + sidebar: { + newDoc: ['quickStart'], + template: ['openTemplateListMenu', 'quickStart'], + }, }, doc: { editor: { @@ -315,6 +325,7 @@ const PageEvents = { toolbar: ['copyBlockToLink'], aiActions: ['requestSignIn'], pageBlockHeader: ['openDocInfo'], + starterBar: ['quickStart', 'openTemplateListMenu'], }, inlineDocInfo: { $: ['toggle'], @@ -450,6 +461,7 @@ export type EventArgs = { toggleFavorite: OrganizeItemArgs & { on: boolean }; toggle: { type: 'collapse' | 'expand' }; createDoc: { mode?: 'edgeless' | 'page' }; + quickStart: { with: 'page' | 'edgeless' | 'template' | 'ai' }; switchPageMode: { mode: 'edgeless' | 'page' }; createShareLink: { mode: 'edgeless' | 'page' }; copyShareLink: {