fix(editor): Don't flag uiStore as dirty on node selected (#13641)
Some checks failed
Test Master / install-and-build (push) Waiting to run
Test Master / Unit tests (18.x) (push) Blocked by required conditions
Test Master / Unit tests (20.x) (push) Blocked by required conditions
Test Master / Unit tests (22.4) (push) Blocked by required conditions
Test Master / Lint (push) Blocked by required conditions
Test Master / Notify Slack on failure (push) Blocked by required conditions
Benchmark Docker Image CI / build (push) Has been cancelled

This commit is contained in:
Charlie Kolb 2025-03-04 17:49:03 +01:00 committed by GitHub
parent 5eddf00fa1
commit 4f6d76cd25
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 62 additions and 6 deletions

View file

@ -681,6 +681,55 @@ describe('useWorkflowsStore', () => {
});
});
describe('updateNodeAtIndex', () => {
it.each([
{
description: 'should update node at given index with provided data',
nodeIndex: 0,
nodeData: { name: 'Updated Node' },
initialNodes: [{ name: 'Original Node' }],
expectedNodes: [{ name: 'Updated Node' }],
expectedResult: true,
},
{
description: 'should not update node if index is invalid',
nodeIndex: -1,
nodeData: { name: 'Updated Node' },
initialNodes: [{ name: 'Original Node' }],
expectedNodes: [{ name: 'Original Node' }],
expectedResult: false,
},
{
description: 'should return false if node data is unchanged',
nodeIndex: 0,
nodeData: { name: 'Original Node' },
initialNodes: [{ name: 'Original Node' }],
expectedNodes: [{ name: 'Original Node' }],
expectedResult: false,
},
{
description: 'should update multiple properties of a node',
nodeIndex: 0,
nodeData: { name: 'Updated Node', type: 'newType' },
initialNodes: [{ name: 'Original Node', type: 'oldType' }],
expectedNodes: [{ name: 'Updated Node', type: 'newType' }],
expectedResult: true,
},
])('$description', ({ nodeIndex, nodeData, initialNodes, expectedNodes, expectedResult }) => {
workflowsStore.workflow.nodes = initialNodes as unknown as IWorkflowDb['nodes'];
const result = workflowsStore.updateNodeAtIndex(nodeIndex, nodeData);
expect(result).toBe(expectedResult);
expect(workflowsStore.workflow.nodes).toEqual(expectedNodes);
});
it('should throw error if out of bounds', () => {
workflowsStore.workflow.nodes = [];
expect(() => workflowsStore.updateNodeAtIndex(0, { name: 'Updated Node' })).toThrowError();
});
});
test.each([
// check userVersion behavior
[-1, 1, 1], // userVersion -1, use default (1)

View file

@ -62,7 +62,7 @@ import {
SEND_AND_WAIT_OPERATION,
Workflow,
} from 'n8n-workflow';
import { findLast } from 'lodash-es';
import { findLast, pick, isEqual } from 'lodash-es';
import { useRootStore } from '@/stores/root.store';
import * as workflowsApi from '@/api/workflows';
@ -1138,10 +1138,17 @@ export const useWorkflowsStore = defineStore(STORES.WORKFLOWS, () => {
return true;
}
function updateNodeAtIndex(nodeIndex: number, nodeData: Partial<INodeUi>): void {
/**
* @returns `true` if the object was changed
*/
function updateNodeAtIndex(nodeIndex: number, nodeData: Partial<INodeUi>): boolean {
if (nodeIndex !== -1) {
Object.assign(workflow.value.nodes[nodeIndex], nodeData);
const node = workflow.value.nodes[nodeIndex];
const changed = !isEqual(pick(node, Object.keys(nodeData)), nodeData);
Object.assign(node, nodeData);
return changed;
}
return false;
}
function setNodeIssue(nodeIssueData: INodeIssueData): boolean {
@ -1270,12 +1277,12 @@ export const useWorkflowsStore = defineStore(STORES.WORKFLOWS, () => {
);
}
uiStore.stateIsDirty = true;
updateNodeAtIndex(nodeIndex, {
const changed = updateNodeAtIndex(nodeIndex, {
[updateInformation.key]: updateInformation.value,
});
uiStore.stateIsDirty = uiStore.stateIsDirty || changed;
const excludeKeys = ['position', 'notes', 'notesInFlow'];
if (!excludeKeys.includes(updateInformation.key)) {