diff --git a/packages/frontend/core/src/components/affine/import-modal/index.tsx b/packages/frontend/core/src/components/affine/import-modal/index.tsx index 61f19719f2..b6766c38f7 100644 --- a/packages/frontend/core/src/components/affine/import-modal/index.tsx +++ b/packages/frontend/core/src/components/affine/import-modal/index.tsx @@ -2,6 +2,7 @@ import { Button, IconButton, Modal } from '@affine/component'; import { UrlService } from '@affine/core/modules/url'; import { WorkbenchService } from '@affine/core/modules/workbench'; import { useI18n } from '@affine/i18n'; +import track from '@affine/track'; import { MarkdownTransformer, NotionHtmlTransformer, @@ -294,19 +295,35 @@ export const ImportModal = ({ ...modalProps }) => { } setStatus('importing'); + track.$.importModal.$.import({ + type, + status: 'importing', + }); const pageIds = await importConfig.importFunction(docCollection, file); setPageIds(pageIds); setStatus('success'); + track.$.importModal.$.import({ + type, + status: 'success', + result: { + docCount: pageIds.length, + }, + }); } catch (error) { setImportError( error instanceof Error ? error.message : 'Unknown error occurred' ); setStatus('error'); + track.$.importModal.$.import({ + type, + status: 'failed', + error: importError || undefined, + }); } }, - [docCollection, t] + [docCollection, t, importError] ); const handleComplete = useCallback(() => { diff --git a/packages/frontend/core/src/components/affine/setting-modal/workspace-setting/new-workspace-setting-detail/export.tsx b/packages/frontend/core/src/components/affine/setting-modal/workspace-setting/new-workspace-setting-detail/export.tsx index 3062d0c5c3..e39ef4b1fe 100644 --- a/packages/frontend/core/src/components/affine/setting-modal/workspace-setting/new-workspace-setting-detail/export.tsx +++ b/packages/frontend/core/src/components/affine/setting-modal/workspace-setting/new-workspace-setting-detail/export.tsx @@ -5,6 +5,7 @@ import { useAsyncCallback } from '@affine/core/components/hooks/affine-async-hoo import { useSystemOnline } from '@affine/core/components/hooks/use-system-online'; import { DesktopApiService } from '@affine/core/modules/desktop-api/service'; import { useI18n } from '@affine/i18n'; +import track from '@affine/track'; import { useService, type Workspace, @@ -33,6 +34,9 @@ export const DesktopExportPanel = ({ } setSaving(true); try { + track.$.settingsPanel.workspace.export({ + type: 'workspace', + }); if (isOnline) { await workspace.engine.waitForDocSynced(); await workspace.engine.blob.sync(); diff --git a/packages/frontend/core/src/components/blocksuite/block-suite-header/menu/index.tsx b/packages/frontend/core/src/components/blocksuite/block-suite-header/menu/index.tsx index abe716f5e6..6530ebe82f 100644 --- a/packages/frontend/core/src/components/blocksuite/block-suite-header/menu/index.tsx +++ b/packages/frontend/core/src/components/blocksuite/block-suite-header/menu/index.tsx @@ -200,7 +200,7 @@ export const PageHeaderMenuButton = ({ }, [duplicate, pageId]); const handleOpenImportModal = useCallback(() => { - track.$.header.docOptions.import(); + track.$.header.importModal.open(); setOpenImportModalAtom(true); }, [setOpenImportModalAtom]); diff --git a/packages/frontend/core/src/components/page-list/operation-menu-items/snapshot.tsx b/packages/frontend/core/src/components/page-list/operation-menu-items/snapshot.tsx index aee3e5ea44..957d1f84e2 100644 --- a/packages/frontend/core/src/components/page-list/operation-menu-items/snapshot.tsx +++ b/packages/frontend/core/src/components/page-list/operation-menu-items/snapshot.tsx @@ -107,6 +107,11 @@ export const Snapshot = ({ className }: SnapshotProps) => { const file = await openFileOrFiles({ acceptType: 'Zip' }); if (!file) return null; + track.$.header.snapshot.import({ + type: 'snapshot', + status: 'importing', + }); + const importedDocs = ( await ZipTransformer.importDocs(docCollection, file) ).filter(doc => doc !== undefined); @@ -122,6 +127,13 @@ export const Snapshot = ({ className }: SnapshotProps) => { title: 'Imported Snapshot Successfully', message: `Imported ${importedDocs.length} doc(s)`, }); + track.$.header.snapshot.import({ + type: 'snapshot', + status: 'success', + result: { + docCount: importedDocs.length, + }, + }); return importedDocs; } catch (error) { console.error('Error importing snapshot:', error); @@ -129,6 +141,11 @@ export const Snapshot = ({ className }: SnapshotProps) => { title: 'Import Snapshot Failed', message: 'Failed to import snapshot. Please try again.', }); + track.$.header.snapshot.import({ + type: 'snapshot', + status: 'failed', + error: error instanceof Error ? error.message : undefined, + }); return null; } }, [docCollection]); @@ -165,6 +182,9 @@ export const Snapshot = ({ className }: SnapshotProps) => { case 'import': return handleImportSnapshot(); case 'export': + track.$.header.snapshot.export({ + type: 'snapshot', + }); return exportHandler('snapshot'); case 'disable': return disableSnapshotActionOption(); diff --git a/packages/frontend/core/src/components/root-app-sidebar/index.tsx b/packages/frontend/core/src/components/root-app-sidebar/index.tsx index 0538ba2722..d24fbf8be4 100644 --- a/packages/frontend/core/src/components/root-app-sidebar/index.tsx +++ b/packages/frontend/core/src/components/root-app-sidebar/index.tsx @@ -118,6 +118,7 @@ export const RootAppSidebar = (): ReactElement => { }, [setOpenSettingModalAtom]); const onOpenImportModal = useCallback(() => { + track.$.navigationPanel.importModal.open(); setOpenImportModalAtom(true); }, [setOpenImportModalAtom]); diff --git a/packages/frontend/i18n/src/i18n-completenesses.json b/packages/frontend/i18n/src/i18n-completenesses.json index f469c0a978..0d5cf75714 100644 --- a/packages/frontend/i18n/src/i18n-completenesses.json +++ b/packages/frontend/i18n/src/i18n-completenesses.json @@ -10,8 +10,8 @@ "fr": 73, "hi": 2, "it": 1, - "ja": 97, - "ko": 86, + "ja": 98, + "ko": 87, "pl": 0, "pt-BR": 94, "ru": 80, diff --git a/packages/frontend/track/src/events.ts b/packages/frontend/track/src/events.ts index ecdffc7bd9..8dd7201fe0 100644 --- a/packages/frontend/track/src/events.ts +++ b/packages/frontend/track/src/events.ts @@ -121,7 +121,6 @@ type UserEvents = | AuthEvents | AccountEvents | PaymentEvents; - interface PageDivision { [page: string]: { [segment: string]: { @@ -152,7 +151,7 @@ const PageEvents = { }, settingsPanel: { menu: ['openSettings'], - workspace: ['viewPlans'], + workspace: ['viewPlans', 'export'], profileAndBadge: ['viewPlans'], accountUsage: ['viewPlans'], accountSettings: ['uploadAvatar', 'removeAvatar', 'updateUserName'], @@ -214,7 +213,8 @@ const PageEvents = { 'openChangelog', 'dismissChangelog', ], - others: ['navigate', 'import'], + others: ['navigate'], + importModal: ['open'], workspaceList: [ 'open', 'signIn', @@ -231,6 +231,9 @@ const PageEvents = { docHistory: { $: ['open', 'close', 'switchPageMode', 'viewPlans'], }, + importModal: { + $: ['open', 'import'], + }, paywall: { storage: ['viewPlans'], aiAction: ['viewPlans'], @@ -259,6 +262,8 @@ const PageEvents = { ], history: ['open'], pageInfo: ['open'], + importModal: ['open'], + snapshot: ['import', 'export'], }, }, doc: { @@ -354,6 +359,16 @@ type AuthArgs = { provider?: string; }; +type ImportStatus = 'importing' | 'failed' | 'success'; +type ImportArgs = { + type: string; + status?: ImportStatus; + error?: string; + result?: { + docCount: number; + }; +}; + export type EventArgs = { createWorkspace: { flavour: string }; signIn: AuthArgs; @@ -393,6 +408,7 @@ export type EventArgs = { copyShareLink: { type: 'default' | 'doc' | 'whiteboard' | 'block' | 'element'; }; + import: ImportArgs; export: { type: string }; copyBlockToLink: { type: string;