From df68b2ef229207c78d8bdcb57a01e82e75b9001b Mon Sep 17 00:00:00 2001 From: Long Hoang <1732217+loong@users.noreply.github.com> Date: Tue, 17 Dec 2024 09:17:47 +0800 Subject: [PATCH] feat: show potential way to document event (#31119) * feat: show potential way to document event * chore: add cron event docs * chore: rename cron job history event * chore: remove as typecasting and add event definitions to type union * fix: resolve type error from potentially missing properties field in events * fix: remove typecast * Update imports. * Update package-lock.json (leftover changes from previous PR). --------- Co-authored-by: Ivan Vasilov --- .../Integrations/CronJobs/CronJobCard.tsx | 12 +- .../data/telemetry/send-event-mutation.ts | 36 ++++- apps/studio/lib/constants/telemetry.ts | 124 +++++++++++++++++- 3 files changed, 161 insertions(+), 11 deletions(-) diff --git a/apps/studio/components/interfaces/Integrations/CronJobs/CronJobCard.tsx b/apps/studio/components/interfaces/Integrations/CronJobs/CronJobCard.tsx index b5f316f2b65..02539377fcd 100644 --- a/apps/studio/components/interfaces/Integrations/CronJobs/CronJobCard.tsx +++ b/apps/studio/components/interfaces/Integrations/CronJobs/CronJobCard.tsx @@ -78,7 +78,9 @@ export const CronJobCard = ({ job, onEditCronJob, onDeleteCronJob }: CronJobCard type="default" icon={} onClick={() => { - sendEvent({ action: TelemetryActions.CRON_JOBS_VIEW_PREVIOUS_RUNS_CLICKED }) + sendEvent({ + action: TelemetryActions.CRON_JOB_HISTORY_CLICKED, + }) }} > History @@ -90,7 +92,9 @@ export const CronJobCard = ({ job, onEditCronJob, onDeleteCronJob }: CronJobCard { - sendEvent({ action: TelemetryActions.CRON_JOB_UPDATE_CLICKED }) + sendEvent({ + action: TelemetryActions.CRON_JOB_UPDATE_CLICKED, + }) onEditCronJob(job) }} > @@ -99,7 +103,9 @@ export const CronJobCard = ({ job, onEditCronJob, onDeleteCronJob }: CronJobCard { - sendEvent({ action: TelemetryActions.CRON_JOB_DELETE_CLICKED }) + sendEvent({ + action: TelemetryActions.CRON_JOB_DELETE_CLICKED, + }) onDeleteCronJob(job) }} > diff --git a/apps/studio/data/telemetry/send-event-mutation.ts b/apps/studio/data/telemetry/send-event-mutation.ts index 4b91d4a0e02..3c39e446c07 100644 --- a/apps/studio/data/telemetry/send-event-mutation.ts +++ b/apps/studio/data/telemetry/send-event-mutation.ts @@ -4,14 +4,35 @@ import { components } from 'api-types' import { isBrowser, LOCAL_STORAGE_KEYS } from 'common' import { handleError, post } from 'data/fetchers' import { IS_PLATFORM } from 'lib/constants' -import { TelemetryActions } from 'lib/constants/telemetry' +import { + ConnectionStringCopiedEvent, + CronJobCreateClickedEvent, + CronJobCreatedEvent, + CronJobDeleteClickedEvent, + CronJobDeletedEvent, + CronJobHistoryClickedEvent, + CronJobUpdateClickedEvent, + CronJobUpdatedEvent, + TelemetryActions, +} from 'lib/constants/telemetry' import { useRouter } from 'next/router' import type { ResponseError } from 'types' -export type SendEventVariables = { - action: TelemetryActions - properties?: Record // Is arbitrary, but always aim to be self-explanatory with custom properties -} +export type SendEventVariables = + | ConnectionStringCopiedEvent + | CronJobCreatedEvent + | CronJobUpdatedEvent + | CronJobDeletedEvent + | CronJobCreateClickedEvent + | CronJobUpdateClickedEvent + | CronJobDeleteClickedEvent + | CronJobHistoryClickedEvent + + // TODO remove this once all events are documented + | { + action: TelemetryActions + properties?: Record // Is arbitrary, but always aim to be self-explanatory with custom properties + } type SendEventPayload = components['schemas']['TelemetryEventBodyV2'] @@ -47,7 +68,8 @@ export const useSendEventMutation = ({ return useMutation( (vars) => { - const { action, properties } = vars + const { action } = vars + const properties = 'properties' in vars ? vars.properties : {} const body: SendEventPayload = { action, @@ -62,7 +84,7 @@ export const useSendEventMutation = ({ viewport_height: isBrowser ? window.innerHeight : 0, viewport_width: isBrowser ? window.innerWidth : 0, }, - custom_properties: (properties || {}) as any, + custom_properties: properties as any, } return sendEvent({ body }) diff --git a/apps/studio/lib/constants/telemetry.ts b/apps/studio/lib/constants/telemetry.ts index 81ad6fc5257..8ad60351517 100644 --- a/apps/studio/lib/constants/telemetry.ts +++ b/apps/studio/lib/constants/telemetry.ts @@ -13,13 +13,14 @@ export enum TelemetryActions { ASSISTANT_EDIT_SQL_CLICKED = 'assistant_edit_sql_clicked', CONNECTION_STRING_COPIED = 'connection_string_copied', + CRON_JOB_CREATED = 'cron_job_created', CRON_JOB_UPDATED = 'cron_job_updated', CRON_JOB_DELETED = 'cron_job_deleted', CRON_JOB_DELETE_CLICKED = 'cron_job_delete_clicked', CRON_JOB_UPDATE_CLICKED = 'cron_job_update_clicked', CRON_JOB_CREATE_CLICKED = 'cron_job_create_clicked', - CRON_JOBS_VIEW_PREVIOUS_RUNS_CLICKED = 'cron_job_view_previous_runs_clicked', + CRON_JOB_HISTORY_CLICKED = 'cron_job_history_clicked', FEATURE_PREVIEW_ENABLED = 'feature_preview_enabled', FEATURE_PREVIEW_DISABLED = 'feature_preview_disabled', @@ -38,6 +39,127 @@ export enum TelemetryActions { SQL_EDITOR_RESULT_COPY_JSON_CLICKED = 'sql_editor_result_copy_markdown_clicked', } +/** + * User copied the database connection string. + * + * @group Events + * @source studio + */ +export interface ConnectionStringCopiedEvent { + action: TelemetryActions.CONNECTION_STRING_COPIED + properties: { + /** + * Method selected by user, e.g. URI, PSQL, SQLAlchemy, etc. + */ + connectionType: string + /** + * Language of the code block if selected, e.g. bash, go + */ + lang: string + /** + * Connection Method, e.g. direct, transaction_pooler, session_pooler + */ + connectionMethod: 'direct' | 'transaction_pooler' | 'session_pooler' + } +} + +/** + * Cron job created. + * + * @group Events + * @source studio + * @page /dashboard/project/{ref}/integrations/cron/jobs?dialog-shown=true + */ +export interface CronJobCreatedEvent { + action: TelemetryActions.CRON_JOB_CREATED + properties: { + /** + * What the cron job executes, e.g. sql_function or sql_snippet + */ + type: 'sql_function' | 'sql_snippet' + /** + * Schedule of the cron job in the format of * * * * * + */ + schedule: string + } +} + +/** + * Cron job updated. + * + * @group Events + * @source studio + * @page /dashboard/project/{ref}/integrations/cron/jobs?dialog-shown=true + */ +export interface CronJobUpdatedEvent { + action: TelemetryActions.CRON_JOB_UPDATED + properties: { + /** + * What the cron job executes, e.g. sql_function or sql_snippet + */ + type: 'sql_function' | 'sql_snippet' + /** + * Schedule of the cron job in the format of * * * * * + */ + schedule: string + } +} + +/** + * Cron job deleted. + * + * @group Events + * @source studio + * @page /dashboard/project/{ref}/integrations/cron/jobs + */ +export interface CronJobDeletedEvent { + action: TelemetryActions.CRON_JOB_DELETED +} + +/** + * Create job button clicked that opens the dialog. + * + * @group Events + * @source studio + * @page /dashboard/project/{ref}/integrations/cron/jobs + */ +export interface CronJobCreateClickedEvent { + action: TelemetryActions.CRON_JOB_CREATE_CLICKED +} + +/** + * Edit cron job button (hidden in the dropdown) clicked that opens the dialog. + * + * @group Events + * @source studio + * @page /dashboard/project/{ref}/integrations/cron/jobs + */ +export interface CronJobUpdateClickedEvent { + action: TelemetryActions.CRON_JOB_UPDATE_CLICKED +} + +/** + * Delete cron job button (hidden in the dropdown) clicked that opens the deletion confirmation modal. + * + * @group Events + * @source studio + * @page /dashboard/project/{ref}/integrations/cron/jobs + */ +export interface CronJobDeleteClickedEvent { + action: TelemetryActions.CRON_JOB_DELETE_CLICKED +} + +/** + * History button clicked to see previous runs of the cron job + * + * @group Events + * @source studio + * @page /dashboard/project/{ref}/integrations/cron/jobs + */ +export interface CronJobHistoryClickedEvent { + action: TelemetryActions.CRON_JOB_HISTORY_CLICKED +} + // [Joshen] Just adding these to start consolidating our telemetry configs // may change depending on how we choose to standardize across all apps // Events define the name of the event and it'll be used as the primary identification