feat(core): track template doc events (#9775)

close AF-2076
This commit is contained in:
CatsJuice
2025-01-19 13:13:30 +00:00
parent 7713920b71
commit 93106dae3b
5 changed files with 37 additions and 5 deletions

View File

@@ -4,6 +4,7 @@ import { FeatureFlagService } from '@affine/core/modules/feature-flag';
import { TemplateDocService } from '@affine/core/modules/template-doc'; import { TemplateDocService } from '@affine/core/modules/template-doc';
import { TemplateListMenu } from '@affine/core/modules/template-doc/view/template-list-menu'; import { TemplateListMenu } from '@affine/core/modules/template-doc/view/template-list-menu';
import { useI18n } from '@affine/i18n'; import { useI18n } from '@affine/i18n';
import track from '@affine/track';
import type { Store } from '@blocksuite/affine/store'; import type { Store } from '@blocksuite/affine/store';
import { import {
AiIcon, AiIcon,
@@ -68,6 +69,7 @@ const StarterBarNotEmpty = ({ doc }: { doc: Store }) => {
const handleSelectTemplate = useAsyncCallback( const handleSelectTemplate = useAsyncCallback(
async (templateId: string) => { async (templateId: string) => {
await docsService.duplicateFromTemplate(templateId, doc.id); await docsService.duplicateFromTemplate(templateId, doc.id);
track.doc.editor.starterBar.quickStart({ with: 'template' });
}, },
[doc.id, docsService] [doc.id, docsService]
); );
@@ -78,6 +80,11 @@ const StarterBarNotEmpty = ({ doc }: { doc: Store }) => {
editorService.editor.setMode('edgeless'); editorService.editor.setMode('edgeless');
}, [doc.id, docsService.list, editorService.editor]); }, [doc.id, docsService.list, editorService.editor]);
const onTemplateMenuOpenChange = useCallback((open: boolean) => {
if (open) track.doc.editor.starterBar.openTemplateListMenu();
setTemplateMenuOpen(open);
}, []);
const showAI = false; const showAI = false;
const showTemplate = !isTemplate && enableTemplateDoc; const showTemplate = !isTemplate && enableTemplateDoc;
@@ -101,7 +108,7 @@ const StarterBarNotEmpty = ({ doc }: { doc: Store }) => {
onSelect={handleSelectTemplate} onSelect={handleSelectTemplate}
rootOptions={{ rootOptions={{
open: templateMenuOpen, open: templateMenuOpen,
onOpenChange: setTemplateMenuOpen, onOpenChange: onTemplateMenuOpenChange,
}} }}
> >
<Badge <Badge

View File

@@ -4,8 +4,11 @@ import { useLiveData, useService } from '@toeverything/infra';
import { type ChangeEvent, useCallback } from 'react'; import { type ChangeEvent, useCallback } from 'react';
import * as styles from './template.css'; import * as styles from './template.css';
import type { PropertyValueProps } from './types';
export const TemplateValue = () => { export const TemplateValue = ({
onChange: propOnChange,
}: PropertyValueProps) => {
const docService = useService(DocService); const docService = useService(DocService);
const isTemplate = useLiveData( const isTemplate = useLiveData(
@@ -16,8 +19,9 @@ export const TemplateValue = () => {
(e: ChangeEvent<HTMLInputElement>) => { (e: ChangeEvent<HTMLInputElement>) => {
const value = e.target.checked; const value = e.target.checked;
docService.doc.record.setProperty('isTemplate', value); docService.doc.record.setProperty('isTemplate', value);
propOnChange?.(value, true);
}, },
[docService.doc.record] [docService.doc.record, propOnChange]
); );
const toggle = useCallback(() => { const toggle = useCallback(() => {

View File

@@ -6,6 +6,7 @@ import { TemplateListMenuContentScrollable } from '@affine/core/modules/template
import { WorkbenchService } from '@affine/core/modules/workbench'; import { WorkbenchService } from '@affine/core/modules/workbench';
import { inferOpenMode } from '@affine/core/utils'; import { inferOpenMode } from '@affine/core/utils';
import { useI18n } from '@affine/i18n'; import { useI18n } from '@affine/i18n';
import track from '@affine/track';
import { TemplateIcon, TemplateOutlineIcon } from '@blocksuite/icons/rc'; import { TemplateIcon, TemplateOutlineIcon } from '@blocksuite/icons/rc';
import { useLiveData, useService } from '@toeverything/infra'; import { useLiveData, useService } from '@toeverything/infra';
import { useCallback, useState } from 'react'; import { useCallback, useState } from 'react';
@@ -20,6 +21,11 @@ export const TemplateDocEntrance = () => {
setMenuOpen(prev => !prev); setMenuOpen(prev => !prev);
}, []); }, []);
const onMenuOpenChange = useCallback((open: boolean) => {
if (open) track.$.sidebar.template.openTemplateListMenu();
setMenuOpen(open);
}, []);
if (!enabled) { if (!enabled) {
return null; return null;
} }
@@ -31,7 +37,7 @@ export const TemplateDocEntrance = () => {
onClick={toggleMenu} onClick={toggleMenu}
> >
<Menu <Menu
rootOptions={{ open: menuOpen, onOpenChange: setMenuOpen }} rootOptions={{ open: menuOpen, onOpenChange: onMenuOpenChange }}
contentOptions={{ contentOptions={{
side: 'right', side: 'right',
align: 'end', align: 'end',

View File

@@ -102,6 +102,7 @@ function AddPageWithAsk({ className, style }: AddPageButtonProps) {
(e?: MouseEvent) => { (e?: MouseEvent) => {
createDoc(e, 'page'); createDoc(e, 'page');
track.$.navigationPanel.$.createDoc(); track.$.navigationPanel.$.createDoc();
track.$.sidebar.newDoc.quickStart({ with: 'page' });
}, },
[createDoc] [createDoc]
); );
@@ -109,6 +110,7 @@ function AddPageWithAsk({ className, style }: AddPageButtonProps) {
(e?: MouseEvent) => { (e?: MouseEvent) => {
createDoc(e, 'edgeless'); createDoc(e, 'edgeless');
track.$.navigationPanel.$.createDoc(); track.$.navigationPanel.$.createDoc();
track.$.sidebar.newDoc.quickStart({ with: 'edgeless' });
}, },
[createDoc] [createDoc]
); );
@@ -117,6 +119,7 @@ function AddPageWithAsk({ className, style }: AddPageButtonProps) {
async (templateId: string) => { async (templateId: string) => {
const docId = await docsService.duplicateFromTemplate(templateId); const docId = await docsService.duplicateFromTemplate(templateId);
workbench.openDoc(docId); workbench.openDoc(docId);
track.$.sidebar.newDoc.quickStart({ with: 'template' });
}, },
[docsService, workbench] [docsService, workbench]
); );

View File

@@ -38,6 +38,7 @@ type WorkspaceEvents =
| 'openWorkspaceList'; | 'openWorkspaceList';
type DocEvents = type DocEvents =
| 'createDoc' | 'createDoc'
| 'quickStart'
| 'renameDoc' | 'renameDoc'
| 'linkDoc' | 'linkDoc'
| 'deleteDoc' | 'deleteDoc'
@@ -126,6 +127,10 @@ type AttachmentEvents =
| 'openPDFRendererFail'; | 'openPDFRendererFail';
// END SECTION // END SECTION
// SECTION: template
type TemplateEvents = 'openTemplateListMenu';
// END SECTION
type UserEvents = type UserEvents =
| GeneralEvents | GeneralEvents
| AppEvents | AppEvents
@@ -141,7 +146,8 @@ type UserEvents =
| AccountEvents | AccountEvents
| PaymentEvents | PaymentEvents
| DNDEvents | DNDEvents
| AttachmentEvents; | AttachmentEvents
| TemplateEvents;
interface PageDivision { interface PageDivision {
[page: string]: { [page: string]: {
[segment: string]: { [segment: string]: {
@@ -304,6 +310,10 @@ const PageEvents = {
'openPDFRendererFail', 'openPDFRendererFail',
], ],
}, },
sidebar: {
newDoc: ['quickStart'],
template: ['openTemplateListMenu', 'quickStart'],
},
}, },
doc: { doc: {
editor: { editor: {
@@ -315,6 +325,7 @@ const PageEvents = {
toolbar: ['copyBlockToLink'], toolbar: ['copyBlockToLink'],
aiActions: ['requestSignIn'], aiActions: ['requestSignIn'],
pageBlockHeader: ['openDocInfo'], pageBlockHeader: ['openDocInfo'],
starterBar: ['quickStart', 'openTemplateListMenu'],
}, },
inlineDocInfo: { inlineDocInfo: {
$: ['toggle'], $: ['toggle'],
@@ -450,6 +461,7 @@ export type EventArgs = {
toggleFavorite: OrganizeItemArgs & { on: boolean }; toggleFavorite: OrganizeItemArgs & { on: boolean };
toggle: { type: 'collapse' | 'expand' }; toggle: { type: 'collapse' | 'expand' };
createDoc: { mode?: 'edgeless' | 'page' }; createDoc: { mode?: 'edgeless' | 'page' };
quickStart: { with: 'page' | 'edgeless' | 'template' | 'ai' };
switchPageMode: { mode: 'edgeless' | 'page' }; switchPageMode: { mode: 'edgeless' | 'page' };
createShareLink: { mode: 'edgeless' | 'page' }; createShareLink: { mode: 'edgeless' | 'page' };
copyShareLink: { copyShareLink: {