mirror of
https://github.com/n8n-io/n8n.git
synced 2025-03-05 20:50:17 -08:00
feat: update diff loading
This commit is contained in:
parent
ed2a6a62b7
commit
0a15e85d63
|
@ -9,6 +9,7 @@ import type {
|
||||||
import WorkflowPreview from '@/components/WorkflowPreview.vue';
|
import WorkflowPreview from '@/components/WorkflowPreview.vue';
|
||||||
import WorkflowHistoryListItem from '@/components/WorkflowHistory/WorkflowHistoryListItem.vue';
|
import WorkflowHistoryListItem from '@/components/WorkflowHistory/WorkflowHistoryListItem.vue';
|
||||||
import { useI18n } from '@/composables/useI18n';
|
import { useI18n } from '@/composables/useI18n';
|
||||||
|
import { compareWorkflows } from '@/utils/workflowDiff';
|
||||||
|
|
||||||
const i18n = useI18n();
|
const i18n = useI18n();
|
||||||
|
|
||||||
|
@ -57,6 +58,14 @@ const workflowDiffPreview = computed<IWorkflowDb | undefined>(() => {
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const workflowComparison = computed(() => {
|
||||||
|
if (!workflowVersionPreview.value || !workflowDiffPreview.value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
return compareWorkflows(workflowVersionPreview.value, workflowDiffPreview.value);
|
||||||
|
});
|
||||||
|
|
||||||
const actions = computed(() =>
|
const actions = computed(() =>
|
||||||
props.isFirstItemShown
|
props.isFirstItemShown
|
||||||
? props.actions.filter((action) => action.value !== 'restore')
|
? props.actions.filter((action) => action.value !== 'restore')
|
||||||
|
@ -82,6 +91,7 @@ const onAction = ({
|
||||||
<WorkflowPreview
|
<WorkflowPreview
|
||||||
v-if="props.workflowVersion"
|
v-if="props.workflowVersion"
|
||||||
:workflow="workflowVersionPreview"
|
:workflow="workflowVersionPreview"
|
||||||
|
:diff="workflowComparison"
|
||||||
:loading="props.isListLoading"
|
:loading="props.isListLoading"
|
||||||
loader-type="spinner"
|
loader-type="spinner"
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -4,13 +4,14 @@ import { useI18n } from '@/composables/useI18n';
|
||||||
import { useToast } from '@/composables/useToast';
|
import { useToast } from '@/composables/useToast';
|
||||||
import type { IWorkflowDb, IWorkflowTemplate } from '@/Interface';
|
import type { IWorkflowDb, IWorkflowTemplate } from '@/Interface';
|
||||||
import { useExecutionsStore } from '@/stores/executions.store';
|
import { useExecutionsStore } from '@/stores/executions.store';
|
||||||
|
import type { WorkflowDiff } from '@/types/workflowDiff.types';
|
||||||
|
|
||||||
const props = withDefaults(
|
const props = withDefaults(
|
||||||
defineProps<{
|
defineProps<{
|
||||||
id?: string;
|
|
||||||
loading?: boolean;
|
loading?: boolean;
|
||||||
mode?: 'workflow' | 'execution';
|
mode?: 'workflow' | 'execution';
|
||||||
workflow?: IWorkflowDb | IWorkflowTemplate['workflow'];
|
workflow?: IWorkflowDb | IWorkflowTemplate['workflow'];
|
||||||
|
diff?: WorkflowDiff;
|
||||||
executionId?: string;
|
executionId?: string;
|
||||||
executionMode?: string;
|
executionMode?: string;
|
||||||
loaderType?: 'image' | 'spinner';
|
loaderType?: 'image' | 'spinner';
|
||||||
|
@ -21,6 +22,7 @@ const props = withDefaults(
|
||||||
loading: false,
|
loading: false,
|
||||||
mode: 'workflow',
|
mode: 'workflow',
|
||||||
workflow: undefined,
|
workflow: undefined,
|
||||||
|
diff: undefined,
|
||||||
executionId: undefined,
|
executionId: undefined,
|
||||||
executionMode: undefined,
|
executionMode: undefined,
|
||||||
loaderType: 'image',
|
loaderType: 'image',
|
||||||
|
@ -75,6 +77,16 @@ const loadWorkflow = () => {
|
||||||
}),
|
}),
|
||||||
'*',
|
'*',
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (props.diff) {
|
||||||
|
iframeRef.value?.contentWindow?.postMessage?.(
|
||||||
|
JSON.stringify({
|
||||||
|
command: 'setDiff',
|
||||||
|
diff: props.diff,
|
||||||
|
}),
|
||||||
|
'*',
|
||||||
|
);
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
toast.showError(
|
toast.showError(
|
||||||
error,
|
error,
|
||||||
|
|
|
@ -85,6 +85,7 @@ import { TelemetryHelpers } from 'n8n-workflow';
|
||||||
import { useWorkflowHelpers } from '@/composables/useWorkflowHelpers';
|
import { useWorkflowHelpers } from '@/composables/useWorkflowHelpers';
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
import { useSettingsStore } from './settings.store';
|
import { useSettingsStore } from './settings.store';
|
||||||
|
import type { WorkflowDiff } from '@/types';
|
||||||
|
|
||||||
const defaults: Omit<IWorkflowDb, 'id'> & { settings: NonNullable<IWorkflowDb['settings']> } = {
|
const defaults: Omit<IWorkflowDb, 'id'> & { settings: NonNullable<IWorkflowDb['settings']> } = {
|
||||||
name: '',
|
name: '',
|
||||||
|
@ -140,6 +141,8 @@ export const useWorkflowsStore = defineStore(STORES.WORKFLOWS, () => {
|
||||||
const isInDebugMode = ref(false);
|
const isInDebugMode = ref(false);
|
||||||
const chatMessages = ref<string[]>([]);
|
const chatMessages = ref<string[]>([]);
|
||||||
|
|
||||||
|
const workflowDiff = ref<WorkflowDiff | undefined>();
|
||||||
|
|
||||||
const workflowName = computed(() => workflow.value.name);
|
const workflowName = computed(() => workflow.value.name);
|
||||||
|
|
||||||
const workflowId = computed(() => workflow.value.id);
|
const workflowId = computed(() => workflow.value.id);
|
||||||
|
@ -1652,6 +1655,7 @@ export const useWorkflowsStore = defineStore(STORES.WORKFLOWS, () => {
|
||||||
getWorkflowExecution,
|
getWorkflowExecution,
|
||||||
getTotalFinishedExecutionsCount,
|
getTotalFinishedExecutionsCount,
|
||||||
getPastChatMessages,
|
getPastChatMessages,
|
||||||
|
workflowDiff,
|
||||||
outgoingConnectionsByNodeName,
|
outgoingConnectionsByNodeName,
|
||||||
incomingConnectionsByNodeName,
|
incomingConnectionsByNodeName,
|
||||||
nodeHasOutputConnection,
|
nodeHasOutputConnection,
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
export * from './workflowDiff.types';
|
||||||
export * from './canvas';
|
export * from './canvas';
|
||||||
export * from './externalHooks';
|
export * from './externalHooks';
|
||||||
export * from './pushConnection';
|
export * from './pushConnection';
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
export const enum NodeDiffStatus {
|
export const enum NodeDiffStatus {
|
||||||
EQ,
|
Eq = 'equal',
|
||||||
MODIFIED,
|
Modified = 'modified',
|
||||||
ADDED,
|
Added = 'added',
|
||||||
DELETED,
|
Deleted = 'deleted',
|
||||||
}
|
}
|
||||||
|
|
||||||
export type WorkflowDiff = Record<string, NodeDiffStatus>;
|
export type WorkflowDiff = Record<string, NodeDiffStatus>;
|
||||||
|
|
|
@ -201,12 +201,12 @@ describe('workflowDiff', () => {
|
||||||
const diff = compareWorkflows(baseWf, targetWf);
|
const diff = compareWorkflows(baseWf, targetWf);
|
||||||
|
|
||||||
expect(diff).toEqual({
|
expect(diff).toEqual({
|
||||||
'180ad8e0-c891-4b37-bab3-0a5b306ca48d': NodeDiffStatus.EQ,
|
'180ad8e0-c891-4b37-bab3-0a5b306ca48d': NodeDiffStatus.Eq,
|
||||||
'1cd4ee3f-5692-469c-a658-82483f1ef921': NodeDiffStatus.MODIFIED,
|
'1cd4ee3f-5692-469c-a658-82483f1ef921': NodeDiffStatus.Modified,
|
||||||
'9eedaa9f-7735-4fef-af11-deba888005ac': NodeDiffStatus.MODIFIED,
|
'9eedaa9f-7735-4fef-af11-deba888005ac': NodeDiffStatus.Modified,
|
||||||
'22593885-07ce-49ea-8a6c-ad17d983cada': NodeDiffStatus.ADDED,
|
'22593885-07ce-49ea-8a6c-ad17d983cada': NodeDiffStatus.Added,
|
||||||
'bcf43c50-007f-4d04-a236-a3a1ef628fe2': NodeDiffStatus.ADDED,
|
'bcf43c50-007f-4d04-a236-a3a1ef628fe2': NodeDiffStatus.Added,
|
||||||
'f8279104-a3e6-4663-b9bc-77fdbc615742': NodeDiffStatus.DELETED,
|
'f8279104-a3e6-4663-b9bc-77fdbc615742': NodeDiffStatus.Deleted,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -214,12 +214,12 @@ describe('workflowDiff', () => {
|
||||||
const diff = compareWorkflows(targetWf, baseWf);
|
const diff = compareWorkflows(targetWf, baseWf);
|
||||||
|
|
||||||
expect(diff).toEqual({
|
expect(diff).toEqual({
|
||||||
'180ad8e0-c891-4b37-bab3-0a5b306ca48d': NodeDiffStatus.EQ,
|
'180ad8e0-c891-4b37-bab3-0a5b306ca48d': NodeDiffStatus.Eq,
|
||||||
'1cd4ee3f-5692-469c-a658-82483f1ef921': NodeDiffStatus.MODIFIED,
|
'1cd4ee3f-5692-469c-a658-82483f1ef921': NodeDiffStatus.Modified,
|
||||||
'9eedaa9f-7735-4fef-af11-deba888005ac': NodeDiffStatus.MODIFIED,
|
'9eedaa9f-7735-4fef-af11-deba888005ac': NodeDiffStatus.Modified,
|
||||||
'22593885-07ce-49ea-8a6c-ad17d983cada': NodeDiffStatus.DELETED,
|
'22593885-07ce-49ea-8a6c-ad17d983cada': NodeDiffStatus.Deleted,
|
||||||
'bcf43c50-007f-4d04-a236-a3a1ef628fe2': NodeDiffStatus.DELETED,
|
'bcf43c50-007f-4d04-a236-a3a1ef628fe2': NodeDiffStatus.Deleted,
|
||||||
'f8279104-a3e6-4663-b9bc-77fdbc615742': NodeDiffStatus.ADDED,
|
'f8279104-a3e6-4663-b9bc-77fdbc615742': NodeDiffStatus.Added,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -38,17 +38,17 @@ export function compareWorkflows(
|
||||||
|
|
||||||
Object.keys(baseNodes).forEach((id) => {
|
Object.keys(baseNodes).forEach((id) => {
|
||||||
if (!targetNodes[id]) {
|
if (!targetNodes[id]) {
|
||||||
diff[id] = NodeDiffStatus.DELETED;
|
diff[id] = NodeDiffStatus.Deleted;
|
||||||
} else if (!nodesEqual(baseNodes[id], targetNodes[id])) {
|
} else if (!nodesEqual(baseNodes[id], targetNodes[id])) {
|
||||||
diff[id] = NodeDiffStatus.MODIFIED;
|
diff[id] = NodeDiffStatus.Modified;
|
||||||
} else {
|
} else {
|
||||||
diff[id] = NodeDiffStatus.EQ;
|
diff[id] = NodeDiffStatus.Eq;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Object.keys(targetNodes).forEach((id) => {
|
Object.keys(targetNodes).forEach((id) => {
|
||||||
if (!baseNodes[id]) {
|
if (!baseNodes[id]) {
|
||||||
diff[id] = NodeDiffStatus.ADDED;
|
diff[id] = NodeDiffStatus.Added;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -1349,6 +1349,8 @@ async function onPostMessageReceived(messageEvent: MessageEvent) {
|
||||||
executionsStore.activeExecution = (await executionsStore.fetchExecution(
|
executionsStore.activeExecution = (await executionsStore.fetchExecution(
|
||||||
json.executionId,
|
json.executionId,
|
||||||
)) as ExecutionSummary;
|
)) as ExecutionSummary;
|
||||||
|
} else if (json?.command === 'setDiff') {
|
||||||
|
workflowsStore.workflowDiff = json.diff;
|
||||||
}
|
}
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue