diff --git a/packages/frontend/editor-ui/src/components/FocusPanel.vue b/packages/frontend/editor-ui/src/components/FocusPanel.vue
index cdbe50f1ce..fff230df15 100644
--- a/packages/frontend/editor-ui/src/components/FocusPanel.vue
+++ b/packages/frontend/editor-ui/src/components/FocusPanel.vue
@@ -28,6 +28,7 @@ import { useDebounce } from '@/composables/useDebounce';
import { htmlEditorEventBus } from '@/event-bus';
import { hasFocusOnInput, isFocusableEl } from '@/utils/typesUtils';
import type { ResizeData, TargetNodeParameterContext } from '@/Interface';
+import { useTelemetry } from '@/composables/useTelemetry';
import { useThrottleFn } from '@vueuse/core';
import { useStyles } from '@/composables/useStyles';
import { useExecutionData } from '@/composables/useExecutionData';
@@ -53,6 +54,7 @@ const nodeHelpers = useNodeHelpers();
const focusPanelStore = useFocusPanelStore();
const workflowsStore = useWorkflowsStore();
const nodeTypesStore = useNodeTypesStore();
+const telemetry = useTelemetry();
const nodeSettingsParameters = useNodeSettingsParameters();
const environmentsStore = useEnvironmentsStore();
const deviceSupport = useDeviceSupport();
@@ -262,6 +264,22 @@ function optionSelected(command: string) {
}
}
+function closeFocusPanel() {
+ telemetry.track('User closed focus panel', {
+ source: 'closeIcon',
+ parameters: focusPanelStore.focusedNodeParametersInTelemetryFormat,
+ });
+
+ focusPanelStore.closeFocusPanel();
+}
+
+function onExecute() {
+ telemetry.track(
+ 'User executed node from focus panel',
+ focusPanelStore.focusedNodeParametersInTelemetryFormat[0],
+ );
+}
+
const valueChangedDebounced = debounce(valueChanged, { debounceTime: 0 });
// Wait for editor to mount before focusing
@@ -343,13 +361,14 @@ const onResizeThrottle = useThrottleFn(onResize, 10);
:square="true"
:hide-label="true"
telemetry-source="focus"
- >
+ @execute="onExecute"
+ />
diff --git a/packages/frontend/editor-ui/src/components/Node/NodeCreation.vue b/packages/frontend/editor-ui/src/components/Node/NodeCreation.vue
index 6bd0ef7b16..2e5da6354f 100644
--- a/packages/frontend/editor-ui/src/components/Node/NodeCreation.vue
+++ b/packages/frontend/editor-ui/src/components/Node/NodeCreation.vue
@@ -21,6 +21,7 @@ import { useActions } from './NodeCreator/composables/useActions';
import KeyboardShortcutTooltip from '@/components/KeyboardShortcutTooltip.vue';
import AssistantIcon from '@n8n/design-system/components/AskAssistantIcon/AssistantIcon.vue';
import { useI18n } from '@n8n/i18n';
+import { useTelemetry } from '@/composables/useTelemetry';
import { useAssistantStore } from '@/stores/assistant.store';
type Props = {
@@ -46,6 +47,7 @@ const uiStore = useUIStore();
const focusPanelStore = useFocusPanelStore();
const posthogStore = usePostHog();
const i18n = useI18n();
+const telemetry = useTelemetry();
const assistantStore = useAssistantStore();
const { getAddedNodesAndConnections } = useActions();
@@ -86,6 +88,15 @@ function nodeTypeSelected(value: NodeTypeSelectedPayload[]) {
closeNodeCreator(true);
}
+function toggleFocusPanel() {
+ focusPanelStore.toggleFocusPanel();
+
+ telemetry.track(`User ${focusPanelStore.focusPanelActive ? 'opened' : 'closed'} focus panel`, {
+ source: 'canvasButton',
+ parameters: focusPanelStore.focusedNodeParametersInTelemetryFormat,
+ });
+}
+
function onAskAssistantButtonClick() {
if (!assistantStore.chatWindowOpen)
assistantStore.trackUserOpenedAssistant({
@@ -132,12 +143,7 @@ function onAskAssistantButtonClick() {
:shortcut="{ keys: ['f'], shiftKey: true }"
placement="left"
>
-
+
{{ i18n.baseText('aiAssistant.tooltip') }}
diff --git a/packages/frontend/editor-ui/src/components/ParameterInput.vue b/packages/frontend/editor-ui/src/components/ParameterInput.vue
index ad269933d3..8987eb8712 100644
--- a/packages/frontend/editor-ui/src/components/ParameterInput.vue
+++ b/packages/frontend/editor-ui/src/components/ParameterInput.vue
@@ -78,6 +78,7 @@ import { isCredentialOnlyNodeType } from '@/utils/credentialOnlyNodes';
import { hasFocusOnInput, isBlurrableEl, isFocusableEl, isSelectableEl } from '@/utils/typesUtils';
import { completeExpressionSyntax, shouldConvertToExpression } from '@/utils/expressions';
import CssEditor from './CssEditor/CssEditor.vue';
+import { useFocusPanelStore } from '@/stores/focusPanel.store';
type Picker = { $emit: (arg0: string, arg1: Date) => void };
@@ -141,6 +142,7 @@ const workflowsStore = useWorkflowsStore();
const settingsStore = useSettingsStore();
const nodeTypesStore = useNodeTypesStore();
const uiStore = useUIStore();
+const focusPanelStore = useFocusPanelStore();
// ESLint: false positive
// eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents
@@ -1000,6 +1002,10 @@ async function optionSelected(command: string) {
case 'focus':
nodeSettingsParameters.handleFocus(node.value, props.path, props.parameter);
+ telemetry.track('User opened focus panel', {
+ source: 'parameterButton',
+ parameters: focusPanelStore.focusedNodeParametersInTelemetryFormat,
+ });
return;
}
diff --git a/packages/frontend/editor-ui/src/stores/focusPanel.store.ts b/packages/frontend/editor-ui/src/stores/focusPanel.store.ts
index 3ea132970c..d73caa2fe4 100644
--- a/packages/frontend/editor-ui/src/stores/focusPanel.store.ts
+++ b/packages/frontend/editor-ui/src/stores/focusPanel.store.ts
@@ -152,6 +152,16 @@ export const useFocusPanelStore = defineStore(STORES.FOCUS_PANEL, () => {
return 'value' in p && 'node' in p;
}
+ const focusedNodeParametersInTelemetryFormat = computed<
+ Array<{ parameterPath: string; nodeType: string; nodeId: string }>
+ >(() =>
+ focusedNodeParameters.value.map((x) => ({
+ parameterPath: x.parameterPath,
+ nodeType: isRichParameter(x) ? x.node.type : 'unresolved',
+ nodeId: x.nodeId,
+ })),
+ );
+
// Ensure lastFocusTimestamp is set on initial load if panel is already active (e.g. after reload)
watchOnce(
() => currentFocusPanelData.value,
@@ -165,6 +175,7 @@ export const useFocusPanelStore = defineStore(STORES.FOCUS_PANEL, () => {
return {
focusPanelActive,
focusedNodeParameters,
+ focusedNodeParametersInTelemetryFormat,
lastFocusTimestamp,
focusPanelWidth,
openWithFocusedNodeParameter,
diff --git a/packages/frontend/editor-ui/src/views/NodeView.vue b/packages/frontend/editor-ui/src/views/NodeView.vue
index 7ddd7b8f9f..47e6425250 100644
--- a/packages/frontend/editor-ui/src/views/NodeView.vue
+++ b/packages/frontend/editor-ui/src/views/NodeView.vue
@@ -1233,6 +1233,11 @@ function onToggleFocusPanel() {
}
focusPanelStore.toggleFocusPanel();
+ telemetry.track(`User ${focusPanelStore.focusPanelActive ? 'opened' : 'closed'} focus panel`, {
+ source: 'canvasKeyboardShortcut',
+ parameters: focusPanelStore.focusedNodeParametersInTelemetryFormat,
+ parameterCount: focusPanelStore.focusedNodeParametersInTelemetryFormat.length,
+ });
}
function closeNodeCreator() {