mirror of
https://github.com/suitenumerique/docs.git
synced 2026-05-14 02:46:24 +02:00
Compare commits
3 Commits
refacto/re
...
track-post
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c6a45ce58a | ||
|
|
3cfcdcf036 | ||
|
|
69006f0ef0 |
@@ -16,6 +16,7 @@ import { useTranslation } from 'react-i18next';
|
|||||||
import { isAPIError } from '@/api';
|
import { isAPIError } from '@/api';
|
||||||
import { Box, Icon } from '@/components';
|
import { Box, Icon } from '@/components';
|
||||||
import { useDocOptions, useDocStore } from '@/docs/doc-management/';
|
import { useDocOptions, useDocStore } from '@/docs/doc-management/';
|
||||||
|
import { useAnalytics } from '@/libs';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
AITransformActions,
|
AITransformActions,
|
||||||
@@ -217,22 +218,44 @@ const AIMenuItemTransform = ({
|
|||||||
children,
|
children,
|
||||||
icon,
|
icon,
|
||||||
}: PropsWithChildren<AIMenuItemTransform>) => {
|
}: PropsWithChildren<AIMenuItemTransform>) => {
|
||||||
|
const { trackEvent } = useAnalytics();
|
||||||
const { mutateAsync: requestAI, isPending } = useDocAITransform();
|
const { mutateAsync: requestAI, isPending } = useDocAITransform();
|
||||||
const editor = useBlockNoteEditor();
|
const editor = useBlockNoteEditor();
|
||||||
|
|
||||||
const requestAIAction = async (selectedBlocks: Block[]) => {
|
const requestAIAction = async (selectedBlocks: Block[]) => {
|
||||||
const text = await editor.blocksToMarkdownLossy(selectedBlocks);
|
const text = await editor.blocksToMarkdownLossy(selectedBlocks);
|
||||||
|
|
||||||
|
const requestStartTime = performance.now();
|
||||||
const responseAI = await requestAI({
|
const responseAI = await requestAI({
|
||||||
text,
|
text,
|
||||||
action,
|
action,
|
||||||
docId,
|
docId,
|
||||||
});
|
});
|
||||||
|
const requestDuration = performance.now() - requestStartTime;
|
||||||
|
|
||||||
|
const eventProperties = {
|
||||||
|
eventName: 'requestAIAction',
|
||||||
|
action: action,
|
||||||
|
docId: docId,
|
||||||
|
requestLength: text.length,
|
||||||
|
numberBlocks: selectedBlocks.length,
|
||||||
|
requestDuration: requestDuration,
|
||||||
|
};
|
||||||
|
|
||||||
if (!responseAI?.answer) {
|
if (!responseAI?.answer) {
|
||||||
|
trackEvent({
|
||||||
|
...eventProperties,
|
||||||
|
status: 'error',
|
||||||
|
});
|
||||||
throw new Error('No response from AI');
|
throw new Error('No response from AI');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trackEvent({
|
||||||
|
...eventProperties,
|
||||||
|
status: 'success',
|
||||||
|
responseLength: String(responseAI.answer),
|
||||||
|
});
|
||||||
|
|
||||||
const markdown = await editor.tryParseMarkdownToBlocks(responseAI.answer);
|
const markdown = await editor.tryParseMarkdownToBlocks(responseAI.answer);
|
||||||
editor.replaceBlocks(selectedBlocks, markdown);
|
editor.replaceBlocks(selectedBlocks, markdown);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -8,12 +8,14 @@ import { useCreateDoc } from '@/docs/doc-management';
|
|||||||
import { DocSearchModal } from '@/docs/doc-search';
|
import { DocSearchModal } from '@/docs/doc-search';
|
||||||
import { useAuth } from '@/features/auth';
|
import { useAuth } from '@/features/auth';
|
||||||
import { useCmdK } from '@/hook/useCmdK';
|
import { useCmdK } from '@/hook/useCmdK';
|
||||||
|
import { useAnalytics } from '@/libs';
|
||||||
|
|
||||||
import { useLeftPanelStore } from '../stores';
|
import { useLeftPanelStore } from '../stores';
|
||||||
|
|
||||||
export const LeftPanelHeader = ({ children }: PropsWithChildren) => {
|
export const LeftPanelHeader = ({ children }: PropsWithChildren) => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { authenticated } = useAuth();
|
const { authenticated } = useAuth();
|
||||||
|
const { trackEvent } = useAnalytics();
|
||||||
const [isSearchModalOpen, setIsSearchModalOpen] = useState(false);
|
const [isSearchModalOpen, setIsSearchModalOpen] = useState(false);
|
||||||
|
|
||||||
const openSearchModal = useCallback(() => {
|
const openSearchModal = useCallback(() => {
|
||||||
@@ -23,8 +25,10 @@ export const LeftPanelHeader = ({ children }: PropsWithChildren) => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trackEvent({ eventName: 'openSearchModal', position: 'LeftPanelHeader' });
|
||||||
|
|
||||||
setIsSearchModalOpen(true);
|
setIsSearchModalOpen(true);
|
||||||
}, []);
|
}, [trackEvent]);
|
||||||
|
|
||||||
const closeSearchModal = useCallback(() => {
|
const closeSearchModal = useCallback(() => {
|
||||||
setIsSearchModalOpen(false);
|
setIsSearchModalOpen(false);
|
||||||
@@ -46,6 +50,7 @@ export const LeftPanelHeader = ({ children }: PropsWithChildren) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const createNewDoc = () => {
|
const createNewDoc = () => {
|
||||||
|
trackEvent({ eventName: 'createNewDoc', position: 'LeftPanelHeader' });
|
||||||
createDoc();
|
createDoc();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,15 @@ type AnalyticEventUser = {
|
|||||||
email: string;
|
email: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type AnalyticEvent = AnalyticEventClick | AnalyticEventUser;
|
export type AnalyticEventGeneric = {
|
||||||
|
eventName: string;
|
||||||
|
[key: string]: string | number;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type AnalyticEvent =
|
||||||
|
| AnalyticEventClick
|
||||||
|
| AnalyticEventUser
|
||||||
|
| AnalyticEventGeneric;
|
||||||
|
|
||||||
export abstract class AbstractAnalytic {
|
export abstract class AbstractAnalytic {
|
||||||
public constructor() {
|
public constructor() {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import posthog from 'posthog-js';
|
|||||||
import { PostHogProvider as PHProvider } from 'posthog-js/react';
|
import { PostHogProvider as PHProvider } from 'posthog-js/react';
|
||||||
import { JSX, PropsWithChildren, ReactNode, useEffect } from 'react';
|
import { JSX, PropsWithChildren, ReactNode, useEffect } from 'react';
|
||||||
|
|
||||||
import { AbstractAnalytic, AnalyticEvent } from '@/libs/';
|
import { AbstractAnalytic, AnalyticEvent, AnalyticEventGeneric } from '@/libs/';
|
||||||
|
|
||||||
export class PostHogAnalytic extends AbstractAnalytic {
|
export class PostHogAnalytic extends AbstractAnalytic {
|
||||||
private conf?: PostHogConf = undefined;
|
private conf?: PostHogConf = undefined;
|
||||||
@@ -19,8 +19,14 @@ export class PostHogAnalytic extends AbstractAnalytic {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public trackEvent(evt: AnalyticEvent): void {
|
public trackEvent(evt: AnalyticEvent): void {
|
||||||
if (evt.eventName === 'user') {
|
switch (evt.eventName) {
|
||||||
posthog.identify(evt.id, { email: evt.email });
|
case 'user':
|
||||||
|
posthog.identify(evt.id as string, { email: evt.email });
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
const { eventName, ...properties } = evt as AnalyticEventGeneric;
|
||||||
|
posthog.capture(eventName, properties);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user