mirror of
https://github.com/n8n-io/n8n.git
synced 2025-01-12 13:27:31 -08:00
refactor(editor): Track advanced filter custom data usage (#6084)
This commit is contained in:
parent
ca4e0df90b
commit
f9b11c73b9
|
@ -1,5 +1,5 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed, reactive, onBeforeMount } from 'vue';
|
import { computed, reactive, onBeforeMount, ref } from 'vue';
|
||||||
import debounce from 'lodash/debounce';
|
import debounce from 'lodash/debounce';
|
||||||
import type { PopoverPlacement } from 'element-ui/types/popover';
|
import type { PopoverPlacement } from 'element-ui/types/popover';
|
||||||
import type {
|
import type {
|
||||||
|
@ -14,6 +14,7 @@ import { EnterpriseEditionFeature } from '@/constants';
|
||||||
import { useSettingsStore } from '@/stores/settings';
|
import { useSettingsStore } from '@/stores/settings';
|
||||||
import { useUsageStore } from '@/stores/usage';
|
import { useUsageStore } from '@/stores/usage';
|
||||||
import { useUIStore } from '@/stores/ui';
|
import { useUIStore } from '@/stores/ui';
|
||||||
|
import { useTelemetry } from '@/composables';
|
||||||
|
|
||||||
export type ExecutionFilterProps = {
|
export type ExecutionFilterProps = {
|
||||||
workflows?: IWorkflowShortResponse[];
|
workflows?: IWorkflowShortResponse[];
|
||||||
|
@ -25,6 +26,9 @@ const DATE_TIME_MASK = 'yyyy-MM-dd HH:mm';
|
||||||
const settingsStore = useSettingsStore();
|
const settingsStore = useSettingsStore();
|
||||||
const usageStore = useUsageStore();
|
const usageStore = useUsageStore();
|
||||||
const uiStore = useUIStore();
|
const uiStore = useUIStore();
|
||||||
|
|
||||||
|
const telemetry = useTelemetry();
|
||||||
|
|
||||||
const props = withDefaults(defineProps<ExecutionFilterProps>(), {
|
const props = withDefaults(defineProps<ExecutionFilterProps>(), {
|
||||||
popoverPlacement: 'bottom',
|
popoverPlacement: 'bottom',
|
||||||
});
|
});
|
||||||
|
@ -33,6 +37,7 @@ const emit = defineEmits<{
|
||||||
}>();
|
}>();
|
||||||
const debouncedEmit = debounce(emit, 500);
|
const debouncedEmit = debounce(emit, 500);
|
||||||
|
|
||||||
|
const isCustomDataFilterTracked = ref(false);
|
||||||
const isAdvancedExecutionFilterEnabled = computed(() =>
|
const isAdvancedExecutionFilterEnabled = computed(() =>
|
||||||
settingsStore.isEnterpriseFeatureEnabled(EnterpriseEditionFeature.AdvancedExecutionFilters),
|
settingsStore.isEnterpriseFeatureEnabled(EnterpriseEditionFeature.AdvancedExecutionFilters),
|
||||||
);
|
);
|
||||||
|
@ -109,6 +114,12 @@ const onFilterMetaChange = (index: number, prop: keyof ExecutionFilterMetadata,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
filter.metadata[index][prop] = value;
|
filter.metadata[index][prop] = value;
|
||||||
|
|
||||||
|
if (!isCustomDataFilterTracked.value) {
|
||||||
|
telemetry.track('User filtered executions with custom data');
|
||||||
|
isCustomDataFilterTracked.value = true;
|
||||||
|
}
|
||||||
|
|
||||||
debouncedEmit('filterChanged', filter);
|
debouncedEmit('filterChanged', filter);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -129,6 +140,7 @@ const goToUpgrade = () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
onBeforeMount(() => {
|
onBeforeMount(() => {
|
||||||
|
isCustomDataFilterTracked.value = false;
|
||||||
emit('filterChanged', filter);
|
emit('filterChanged', filter);
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -10,6 +10,18 @@ import ExecutionFilter from '@/components/ExecutionFilter.vue';
|
||||||
import { STORES } from '@/constants';
|
import { STORES } from '@/constants';
|
||||||
import { i18nInstance } from '@/plugins/i18n';
|
import { i18nInstance } from '@/plugins/i18n';
|
||||||
import type { IWorkflowShortResponse, ExecutionFilterType } from '@/Interface';
|
import type { IWorkflowShortResponse, ExecutionFilterType } from '@/Interface';
|
||||||
|
import { useTelemetry } from '@/composables';
|
||||||
|
|
||||||
|
vi.mock('@/composables', () => {
|
||||||
|
const track = vi.fn();
|
||||||
|
return {
|
||||||
|
useTelemetry: () => ({
|
||||||
|
track,
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
let telemetry: ReturnType<typeof useTelemetry>;
|
||||||
|
|
||||||
Vue.use(PiniaVuePlugin);
|
Vue.use(PiniaVuePlugin);
|
||||||
|
|
||||||
|
@ -58,6 +70,10 @@ const renderOptions: RenderOptions<ExecutionFilter> = {
|
||||||
};
|
};
|
||||||
|
|
||||||
describe('ExecutionFilter', () => {
|
describe('ExecutionFilter', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
telemetry = useTelemetry();
|
||||||
|
});
|
||||||
|
|
||||||
test.each([
|
test.each([
|
||||||
['development', 'default', false, workflowsData],
|
['development', 'default', false, workflowsData],
|
||||||
['development', 'default', true, workflowsData],
|
['development', 'default', true, workflowsData],
|
||||||
|
@ -120,4 +136,14 @@ describe('ExecutionFilter', () => {
|
||||||
expect(queryByTestId('executions-filter-reset-button')).not.toBeInTheDocument();
|
expect(queryByTestId('executions-filter-reset-button')).not.toBeInTheDocument();
|
||||||
expect(queryByTestId('execution-filter-badge')).not.toBeInTheDocument();
|
expect(queryByTestId('execution-filter-badge')).not.toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('telemetry sent only once after component is mounted', async () => {
|
||||||
|
const { getByTestId } = render(ExecutionFilter, renderOptions);
|
||||||
|
const customDataKeyInput = getByTestId('execution-filter-saved-data-key-input');
|
||||||
|
|
||||||
|
await userEvent.type(customDataKeyInput, 'test');
|
||||||
|
await userEvent.type(customDataKeyInput, 'key');
|
||||||
|
|
||||||
|
expect(telemetry.track).toHaveBeenCalledTimes(1);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue