From d666b65a7f5041d4a67d2cab0a29bbec8269dacc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Milorad=20FIlipovi=C4=87?= Date: Thu, 4 Sep 2025 09:17:53 +0200 Subject: [PATCH] feat(editor): Add telemetry events for data tables (no-changelog) (#19091) --- .../src/components/ParameterInput.vue | 1 + .../layouts/ResourcesListLayout.vue | 2 +- .../components/AddDataStoreModal.vue | 10 +++++-- .../dataStore/components/DataStoreActions.vue | 6 +++++ .../components/DataStoreBreadcrumbs.vue | 5 ++++ .../components/dataGrid/DataStoreTable.vue | 26 +++++++++++++++++++ 6 files changed, 47 insertions(+), 3 deletions(-) diff --git a/packages/frontend/editor-ui/src/components/ParameterInput.vue b/packages/frontend/editor-ui/src/components/ParameterInput.vue index 35188443ee..8a4a69ac56 100644 --- a/packages/frontend/editor-ui/src/components/ParameterInput.vue +++ b/packages/frontend/editor-ui/src/components/ParameterInput.vue @@ -931,6 +931,7 @@ function valueChanged(untypedValue: unknown) { is_custom: value === CUSTOM_API_CALL_KEY, push_ref: ndvStore.pushRef, parameter: props.parameter.name, + value: value as string, }); } // Track workflow input data mode change diff --git a/packages/frontend/editor-ui/src/components/layouts/ResourcesListLayout.vue b/packages/frontend/editor-ui/src/components/layouts/ResourcesListLayout.vue index 693d26212a..2815762d67 100644 --- a/packages/frontend/editor-ui/src/components/layouts/ResourcesListLayout.vue +++ b/packages/frontend/editor-ui/src/components/layouts/ResourcesListLayout.vue @@ -345,11 +345,11 @@ const setSorting = async (sort: string, persistUpdate = true) => { sortBy.value = sort; if (persistUpdate) { await savePaginationPreferences(); + sendSortingTelemetry(); } emit('update:pagination-and-sort', { sort, }); - sendSortingTelemetry(); }; const setCurrentPage = async (page: number, persistUpdate = true) => { diff --git a/packages/frontend/editor-ui/src/features/dataStore/components/AddDataStoreModal.vue b/packages/frontend/editor-ui/src/features/dataStore/components/AddDataStoreModal.vue index 28b9e8ded2..60c5192035 100644 --- a/packages/frontend/editor-ui/src/features/dataStore/components/AddDataStoreModal.vue +++ b/packages/frontend/editor-ui/src/features/dataStore/components/AddDataStoreModal.vue @@ -6,6 +6,7 @@ import { useUIStore } from '@/stores/ui.store'; import { useToast } from '@/composables/useToast'; import { useRoute, useRouter } from 'vue-router'; import { DATA_STORE_DETAILS, PROJECT_DATA_STORES } from '@/features/dataStore/constants'; +import { useTelemetry } from '@/composables/useTelemetry'; type Props = { modalName: string; @@ -20,6 +21,7 @@ const route = useRoute(); const router = useRouter(); const i18n = useI18n(); const toast = useToast(); +const telemetry = useTelemetry(); const dataStoreName = ref(''); const inputRef = ref(null); @@ -37,14 +39,18 @@ const onSubmit = async () => { dataStoreName.value, route.params.projectId as string, ); + telemetry.track('User created data table', { + data_table_id: newDataStore.id, + data_table_project_id: newDataStore.project?.id, + }); + dataStoreName.value = ''; + uiStore.closeModal(props.modalName); void router.push({ name: DATA_STORE_DETAILS, params: { id: newDataStore.id, }, }); - dataStoreName.value = ''; - uiStore.closeModal(props.modalName); } catch (error) { toast.showError(error, i18n.baseText('dataStore.add.error')); } diff --git a/packages/frontend/editor-ui/src/features/dataStore/components/DataStoreActions.vue b/packages/frontend/editor-ui/src/features/dataStore/components/DataStoreActions.vue index 876a372ebc..11a9ee975c 100644 --- a/packages/frontend/editor-ui/src/features/dataStore/components/DataStoreActions.vue +++ b/packages/frontend/editor-ui/src/features/dataStore/components/DataStoreActions.vue @@ -8,6 +8,7 @@ import { useMessage } from '@/composables/useMessage'; import { MODAL_CONFIRM } from '@/constants'; import { useDataStoreStore } from '@/features/dataStore/dataStore.store'; import { useToast } from '@/composables/useToast'; +import { useTelemetry } from '@/composables/useTelemetry'; type Props = { dataStore: DataStore; @@ -34,6 +35,7 @@ const dataStoreStore = useDataStoreStore(); const i18n = useI18n(); const message = useMessage(); const toast = useToast(); +const telemetry = useTelemetry(); const actions = computed>>(() => { const availableActions = [ @@ -93,6 +95,10 @@ const deleteDataStore = async () => { throw new Error(i18n.baseText('generic.unknownError')); } emit('onDeleted'); + telemetry.track('User deleted data table', { + data_table_id: props.dataStore.id, + data_table_project_id: props.dataStore.projectId, + }); } catch (error) { toast.showError(error, i18n.baseText('dataStore.delete.error')); } diff --git a/packages/frontend/editor-ui/src/features/dataStore/components/DataStoreBreadcrumbs.vue b/packages/frontend/editor-ui/src/features/dataStore/components/DataStoreBreadcrumbs.vue index 61deec230b..e2f6fd4f5e 100644 --- a/packages/frontend/editor-ui/src/features/dataStore/components/DataStoreBreadcrumbs.vue +++ b/packages/frontend/editor-ui/src/features/dataStore/components/DataStoreBreadcrumbs.vue @@ -8,6 +8,7 @@ import DataStoreActions from '@/features/dataStore/components/DataStoreActions.v import { PROJECT_DATA_STORES } from '@/features/dataStore/constants'; import { useDataStoreStore } from '@/features/dataStore/dataStore.store'; import { useToast } from '@/composables/useToast'; +import { telemetry } from '@/plugins/telemetry'; const BREADCRUMBS_SEPARATOR = '/'; @@ -77,6 +78,10 @@ const onNameSubmit = async (name: string) => { throw new Error(i18n.baseText('generic.unknownError')); } editableName.value = name; + telemetry.track('User renamed data table', { + data_table_id: props.dataStore.id, + data_table_project_id: props.dataStore.projectId, + }); } catch (error) { // Revert to original name if rename fails editableName.value = props.dataStore.name; diff --git a/packages/frontend/editor-ui/src/features/dataStore/components/dataGrid/DataStoreTable.vue b/packages/frontend/editor-ui/src/features/dataStore/components/dataGrid/DataStoreTable.vue index e06c1a5662..bbdbc4efa6 100644 --- a/packages/frontend/editor-ui/src/features/dataStore/components/dataGrid/DataStoreTable.vue +++ b/packages/frontend/editor-ui/src/features/dataStore/components/dataGrid/DataStoreTable.vue @@ -71,6 +71,7 @@ import ElDatePickerCellEditor from '@/features/dataStore/components/dataGrid/ElD import { onClickOutside } from '@vueuse/core'; import { useClipboard } from '@/composables/useClipboard'; import { reorderItem } from '@/features/dataStore/utils'; +import { useTelemetry } from '@/composables/useTelemetry'; // Register only the modules we actually use ModuleRegistry.registerModules([ @@ -105,6 +106,7 @@ const i18n = useI18n(); const toast = useToast(); const message = useMessage(); const { mapToAGCellType } = useDataStoreTypes(); +const telemetry = useTelemetry(); const dataStoreStore = useDataStoreStore(); @@ -226,6 +228,11 @@ const onDeleteColumn = async (columnId: string) => { props.dataStore.projectId, columnId, ); + telemetry.track('User deleted data table column', { + column_id: columnId, + column_type: columnToDelete.cellDataType, + data_table_id: props.dataStore.id, + }); } catch (error) { toast.showError(error, i18n.baseText('dataStore.deleteColumn.error')); colDefs.value.splice(columnToDeleteIndex, 0, columnToDelete); @@ -253,6 +260,11 @@ const onAddColumn = async (column: DataStoreColumnCreatePayload) => { return { ...row, [newColumn.name]: null }; }); refreshGridData(); + telemetry.track('User added data table column', { + column_id: newColumn.id, + column_type: newColumn.type, + data_table_id: props.dataStore.id, + }); return true; } catch (error) { toast.showError(error, i18n.baseText('dataStore.addColumn.error')); @@ -421,6 +433,9 @@ const onAddRowClick = async () => { refreshGridData(); await nextTick(); focusFirstEditableCell(newRow.id as number); + telemetry.track('User added row to data table', { + data_table_id: props.dataStore.id, + }); } catch (error) { toast.showError(error, i18n.baseText('dataStore.addRow.error')); } finally { @@ -529,6 +544,12 @@ const onCellValueChanged = async (params: CellValueChangedEvent) = await dataStoreStore.updateRow(props.dataStore.id, props.dataStore.projectId, id, { [fieldName]: value, }); + + telemetry.track('User edited data table content', { + data_table_id: props.dataStore.id, + column_id: colDef.colId, + column_type: colDef.cellDataType, + }); } catch (error) { // Revert cell to original value if the update fails const validOldValue = isDataStoreValue(oldValue) ? oldValue : null; @@ -764,6 +785,11 @@ const handleDeleteSelected = async () => { message: '', type: 'success', }); + + telemetry.track('User deleted rows in data table', { + data_table_id: props.dataStore.id, + deleted_row_count: idsToDelete.length, + }); } catch (error) { toast.showError(error, i18n.baseText('dataStore.deleteRows.error')); } finally {