refactor(editor): Migrate RunDataJson.vue to composition API (#10861)

Co-authored-by: Raúl Gómez Morales <raul00gm@gmail.com>
This commit is contained in:
Ricardo Espinoza 2024-09-18 11:06:25 -04:00 committed by GitHub
parent a7d24d9dac
commit 05ae2aa9c5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -1,149 +1,112 @@
<script lang="ts"> <script setup lang="ts">
import { defineAsyncComponent, defineComponent, ref } from 'vue'; import { computed, defineAsyncComponent, ref } from 'vue';
import type { PropType } from 'vue';
import VueJsonPretty from 'vue-json-pretty'; import VueJsonPretty from 'vue-json-pretty';
import type { IDataObject, INodeExecutionData } from 'n8n-workflow'; import type { INodeExecutionData } from 'n8n-workflow';
import Draggable from '@/components/Draggable.vue'; import Draggable from '@/components/Draggable.vue';
import { executionDataToJson } from '@/utils/nodeTypesUtils'; import { executionDataToJson } from '@/utils/nodeTypesUtils';
import { isString } from '@/utils/typeGuards'; import { isString } from '@/utils/typeGuards';
import { shorten } from '@/utils/typesUtils'; import { shorten } from '@/utils/typesUtils';
import type { INodeUi } from '@/Interface'; import type { INodeUi } from '@/Interface';
import { mapStores } from 'pinia';
import { useNDVStore } from '@/stores/ndv.store'; import { useNDVStore } from '@/stores/ndv.store';
import MappingPill from './MappingPill.vue'; import MappingPill from './MappingPill.vue';
import { getMappedExpression } from '@/utils/mappingUtils'; import { getMappedExpression } from '@/utils/mappingUtils';
import { useWorkflowsStore } from '@/stores/workflows.store';
import { nonExistingJsonPath } from '@/constants'; import { nonExistingJsonPath } from '@/constants';
import { useExternalHooks } from '@/composables/useExternalHooks'; import { useExternalHooks } from '@/composables/useExternalHooks';
import TextWithHighlights from './TextWithHighlights.vue'; import TextWithHighlights from './TextWithHighlights.vue';
import { useTelemetry } from '@/composables/useTelemetry';
const LazyRunDataJsonActions = defineAsyncComponent( const LazyRunDataJsonActions = defineAsyncComponent(
async () => await import('@/components/RunDataJsonActions.vue'), async () => await import('@/components/RunDataJsonActions.vue'),
); );
export default defineComponent({ const props = withDefaults(
name: 'RunDataJson', defineProps<{
components: { editMode: { enabled?: boolean; value?: string };
VueJsonPretty, pushRef?: string;
Draggable, paneType?: string;
LazyRunDataJsonActions, node: INodeUi;
MappingPill, inputData: INodeExecutionData[];
TextWithHighlights, mappingEnabled?: boolean;
distanceFromActive: number;
runIndex?: number;
totalRuns?: number;
search?: string;
}>(),
{
editMode: () => ({}),
}, },
props: { );
editMode: {
type: Object as PropType<{ enabled?: boolean; value?: string }>,
default: () => ({}),
},
pushRef: {
type: String,
},
paneType: {
type: String,
},
node: {
type: Object as PropType<INodeUi>,
required: true,
},
inputData: {
type: Array as PropType<INodeExecutionData[]>,
required: true,
},
mappingEnabled: {
type: Boolean,
},
distanceFromActive: {
type: Number,
required: true,
},
runIndex: {
type: Number,
},
totalRuns: {
type: Number,
},
search: {
type: String,
},
},
setup() {
const externalHooks = useExternalHooks();
const selectedJsonPath = ref(nonExistingJsonPath); const ndvStore = useNDVStore();
const draggingPath = ref<null | string>(null);
const displayMode = ref('json');
return { const externalHooks = useExternalHooks();
externalHooks, const telemetry = useTelemetry();
selectedJsonPath,
draggingPath,
displayMode,
};
},
computed: {
...mapStores(useNDVStore, useWorkflowsStore),
jsonData(): IDataObject[] {
return executionDataToJson(this.inputData);
},
highlight(): boolean {
return this.ndvStore.highlightDraggables;
},
},
methods: {
getShortKey(el: HTMLElement): string {
if (!el) {
return '';
}
return shorten(el.dataset.name || '', 16, 2); const selectedJsonPath = ref(nonExistingJsonPath);
}, const draggingPath = ref<null | string>(null);
getJsonParameterPath(path: string): string { const displayMode = ref('json');
const subPath = path.replace(/^(\["?\d"?])/, ''); // remove item position
return getMappedExpression({ const jsonData = computed(() => executionDataToJson(props.inputData));
nodeName: this.node.name,
distanceFromActive: this.distanceFromActive,
path: subPath,
});
},
onDragStart(el: HTMLElement) {
if (el?.dataset.path) {
this.draggingPath = el.dataset.path;
}
this.ndvStore.resetMappingTelemetry(); const highlight = computed(() => ndvStore.highlightDraggables);
},
onDragEnd(el: HTMLElement) {
this.draggingPath = null;
const mappingTelemetry = this.ndvStore.mappingTelemetry;
const telemetryPayload = {
src_node_type: this.node.type,
src_field_name: el.dataset.name || '',
src_nodes_back: this.distanceFromActive,
src_run_index: this.runIndex,
src_runs_total: this.totalRuns,
src_field_nest_level: el.dataset.depth || 0,
src_view: 'json',
src_element: el,
success: false,
...mappingTelemetry,
};
setTimeout(() => { const getShortKey = (el: HTMLElement) => {
void this.externalHooks.run('runDataJson.onDragEnd', telemetryPayload); if (!el) {
this.$telemetry.track('User dragged data for mapping', telemetryPayload, { return '';
withPostHog: true, }
});
}, 1000); // ensure dest data gets set if drop return shorten(el.dataset.name ?? '', 16, 2);
}, };
getContent(value: unknown): string {
return isString(value) ? `"${value}"` : JSON.stringify(value); const getJsonParameterPath = (path: string) => {
}, const subPath = path.replace(/^(\["?\d"?])/, ''); // remove item position
getListItemName(path: string): string {
return path.replace(/^(\["?\d"?]\.?)/g, ''); return getMappedExpression({
}, nodeName: props.node.name,
}, distanceFromActive: props.distanceFromActive,
}); path: subPath,
});
};
const onDragStart = (el: HTMLElement) => {
if (el?.dataset.path) {
draggingPath.value = el.dataset.path;
}
ndvStore.resetMappingTelemetry();
};
const onDragEnd = (el: HTMLElement) => {
draggingPath.value = null;
const mappingTelemetry = ndvStore.mappingTelemetry;
const telemetryPayload = {
src_node_type: props.node.type,
src_field_name: el.dataset.name ?? '',
src_nodes_back: props.distanceFromActive,
src_run_index: props.runIndex,
src_runs_total: props.totalRuns,
src_field_nest_level: el.dataset.depth ?? 0,
src_view: 'json',
src_element: el,
success: false,
...mappingTelemetry,
};
setTimeout(() => {
void externalHooks.run('runDataJson.onDragEnd', telemetryPayload);
telemetry.track('User dragged data for mapping', telemetryPayload, {
withPostHog: true,
});
}, 1000); // ensure dest data gets set if drop
};
const getContent = (value: unknown) => {
return isString(value) ? `"${value}"` : JSON.stringify(value);
};
const getListItemName = (path: string) => {
return path.replace(/^(\["?\d"?]\.?)/g, '');
};
</script> </script>
<template> <template>