chore(editor): telemetry for slash menu (#11438)

Close [BS-2959](https://linear.app/affine-design/issue/BS-2959/slash-menu埋点)
This commit is contained in:
L-Sun
2025-04-03 13:31:09 +00:00
parent f2865c7bb0
commit 90a3bd53cd
3 changed files with 34 additions and 1 deletions
@@ -0,0 +1,5 @@
import type { TelemetryEvent } from './types.js';
export type SlashMenuEventType = 'OpenSlashMenu' | 'SelectSlashMenuItem';
export type SlashMenuEvents = Record<SlashMenuEventType, TelemetryEvent>;
@@ -3,6 +3,7 @@ import { createIdentifier } from '@blocksuite/global/di';
import type { OutDatabaseAllEvents } from './database.js'; import type { OutDatabaseAllEvents } from './database.js';
import type { LinkToolbarEvents } from './link.js'; import type { LinkToolbarEvents } from './link.js';
import type { NoteEvents } from './note.js'; import type { NoteEvents } from './note.js';
import type { SlashMenuEvents } from './slash-menu.js';
import type { import type {
AttachmentUploadedEvent, AttachmentUploadedEvent,
BlockCreationEvent, BlockCreationEvent,
@@ -18,6 +19,7 @@ import type {
export type TelemetryEventMap = OutDatabaseAllEvents & export type TelemetryEventMap = OutDatabaseAllEvents &
LinkToolbarEvents & LinkToolbarEvents &
SlashMenuEvents &
NoteEvents & { NoteEvents & {
DocCreated: DocCreatedEvent; DocCreated: DocCreatedEvent;
Link: TelemetryEvent; Link: TelemetryEvent;
@@ -4,6 +4,10 @@ import {
getInlineEditorByModel, getInlineEditorByModel,
getTextContentFromInlineRange, getTextContentFromInlineRange,
} from '@blocksuite/affine-rich-text'; } from '@blocksuite/affine-rich-text';
import {
DocModeProvider,
TelemetryProvider,
} from '@blocksuite/affine-shared/services';
import type { AffineInlineEditor } from '@blocksuite/affine-shared/types'; import type { AffineInlineEditor } from '@blocksuite/affine-shared/types';
import { import {
createKeydownObserver, createKeydownObserver,
@@ -42,7 +46,6 @@ import {
parseGroup, parseGroup,
slashItemClassName, slashItemClassName,
} from './utils.js'; } from './utils.js';
type InnerSlashMenuContext = SlashMenuContext & { type InnerSlashMenuContext = SlashMenuContext & {
onClickItem: (item: SlashMenuActionItem) => void; onClickItem: (item: SlashMenuActionItem) => void;
searching: boolean; searching: boolean;
@@ -51,6 +54,14 @@ type InnerSlashMenuContext = SlashMenuContext & {
export class SlashMenu extends WithDisposable(LitElement) { export class SlashMenu extends WithDisposable(LitElement) {
static override styles = styles; static override styles = styles;
private get _telemetry() {
return this.context.std.getOptional(TelemetryProvider);
}
private get _editorMode() {
return this.context.std.get(DocModeProvider).getEditorMode();
}
private readonly _handleClickItem = (item: SlashMenuActionItem) => { private readonly _handleClickItem = (item: SlashMenuActionItem) => {
// Need to remove the search string // Need to remove the search string
// We must to do clean the slash string before we do the action // We must to do clean the slash string before we do the action
@@ -64,6 +75,15 @@ export class SlashMenu extends WithDisposable(LitElement) {
.waitForUpdate() .waitForUpdate()
.then(() => { .then(() => {
item.action(this.context); item.action(this.context);
this._telemetry?.track('SelectSlashMenuItem', {
page: this._editorMode ?? undefined,
segment:
this.context.model.flavour === 'affine:edgeless-text'
? 'edgeless-text'
: 'doc',
module: 'slash menu',
control: item.name,
});
this.abortController.abort(); this.abortController.abort();
}) })
.catch(console.error); .catch(console.error);
@@ -263,6 +283,12 @@ export class SlashMenu extends WithDisposable(LitElement) {
}, },
onAbort: () => this.abortController.abort(), onAbort: () => this.abortController.abort(),
}); });
this._telemetry?.track('OpenSlashMenu', {
page: this._editorMode ?? undefined,
type: this.context.model.flavour.split(':').pop(),
module: 'slash menu',
});
} }
protected override willUpdate() { protected override willUpdate() {