mirror of
https://github.com/n8n-io/n8n.git
synced 2024-12-24 04:04:06 -08:00
fix(editor): Properly set colors for connections and labels on nodes with pinned data (#8209)
Co-authored-by: Alex Grozav <alex@grozav.com>
This commit is contained in:
parent
884396ea0d
commit
3b8ccb9fb9
|
@ -288,4 +288,126 @@ describe('Execution', () => {
|
|||
workflowPage.getters.successToast().contains('Execution deleted');
|
||||
});
|
||||
});
|
||||
|
||||
describe('connections should be colored differently for pinned data', () => {
|
||||
beforeEach(() => {
|
||||
cy.createFixtureWorkflow('Schedule_pinned.json', `Schedule pinned ${uuid()}`);
|
||||
workflowPage.actions.deselectAll();
|
||||
workflowPage.getters.zoomToFitButton().click();
|
||||
|
||||
workflowPage.getters
|
||||
.getConnectionBetweenNodes('Schedule Trigger', 'Edit Fields')
|
||||
.should('have.class', 'success')
|
||||
.should('have.class', 'pinned')
|
||||
.should('not.have.class', 'has-run');
|
||||
|
||||
workflowPage.getters
|
||||
.getConnectionBetweenNodes('Schedule Trigger', 'Edit Fields1')
|
||||
.should('have.class', 'success')
|
||||
.should('have.class', 'pinned')
|
||||
.should('not.have.class', 'has-run');
|
||||
|
||||
workflowPage.getters
|
||||
.getConnectionBetweenNodes('Edit Fields5', 'Edit Fields6')
|
||||
.should('not.have.class', 'success')
|
||||
.should('not.have.class', 'pinned');
|
||||
|
||||
workflowPage.getters
|
||||
.getConnectionBetweenNodes('Edit Fields7', 'Edit Fields9')
|
||||
.should('have.class', 'success')
|
||||
.should('have.class', 'pinned')
|
||||
.should('not.have.class', 'has-run');
|
||||
|
||||
workflowPage.getters
|
||||
.getConnectionBetweenNodes('Edit Fields1', 'Edit Fields2')
|
||||
.should('not.have.class', 'success')
|
||||
.should('not.have.class', 'pinned');
|
||||
|
||||
workflowPage.getters
|
||||
.getConnectionBetweenNodes('Edit Fields2', 'Edit Fields3')
|
||||
.should('have.class', 'success')
|
||||
.should('have.class', 'pinned')
|
||||
.should('not.have.class', 'has-run');
|
||||
});
|
||||
|
||||
it('when executing the workflow', () => {
|
||||
workflowPage.actions.executeWorkflow();
|
||||
|
||||
workflowPage.getters
|
||||
.getConnectionBetweenNodes('Schedule Trigger', 'Edit Fields')
|
||||
.should('have.class', 'success')
|
||||
.should('have.class', 'pinned')
|
||||
.should('have.class', 'has-run');
|
||||
|
||||
workflowPage.getters
|
||||
.getConnectionBetweenNodes('Schedule Trigger', 'Edit Fields1')
|
||||
.should('have.class', 'success')
|
||||
.should('have.class', 'pinned')
|
||||
.should('have.class', 'has-run');
|
||||
|
||||
workflowPage.getters
|
||||
.getConnectionBetweenNodes('Edit Fields5', 'Edit Fields6')
|
||||
.should('have.class', 'success')
|
||||
.should('not.have.class', 'pinned')
|
||||
.should('not.have.class', 'has-run');
|
||||
|
||||
workflowPage.getters
|
||||
.getConnectionBetweenNodes('Edit Fields7', 'Edit Fields9')
|
||||
.should('have.class', 'success')
|
||||
.should('have.class', 'pinned')
|
||||
.should('have.class', 'has-run');
|
||||
|
||||
workflowPage.getters
|
||||
.getConnectionBetweenNodes('Edit Fields1', 'Edit Fields2')
|
||||
.should('have.class', 'success')
|
||||
.should('not.have.class', 'pinned')
|
||||
.should('not.have.class', 'has-run');
|
||||
|
||||
workflowPage.getters
|
||||
.getConnectionBetweenNodes('Edit Fields2', 'Edit Fields3')
|
||||
.should('have.class', 'success')
|
||||
.should('have.class', 'pinned')
|
||||
.should('have.class', 'has-run');
|
||||
});
|
||||
|
||||
it('when executing a node', () => {
|
||||
workflowPage.actions.executeNode('Edit Fields3');
|
||||
|
||||
workflowPage.getters
|
||||
.getConnectionBetweenNodes('Schedule Trigger', 'Edit Fields')
|
||||
.should('have.class', 'success')
|
||||
.should('have.class', 'pinned')
|
||||
.should('have.class', 'has-run');
|
||||
|
||||
workflowPage.getters
|
||||
.getConnectionBetweenNodes('Schedule Trigger', 'Edit Fields1')
|
||||
.should('have.class', 'success')
|
||||
.should('have.class', 'pinned')
|
||||
.should('have.class', 'has-run');
|
||||
|
||||
workflowPage.getters
|
||||
.getConnectionBetweenNodes('Edit Fields5', 'Edit Fields6')
|
||||
.should('not.have.class', 'success')
|
||||
.should('not.have.class', 'pinned')
|
||||
.should('not.have.class', 'has-run');
|
||||
|
||||
workflowPage.getters
|
||||
.getConnectionBetweenNodes('Edit Fields7', 'Edit Fields9')
|
||||
.should('have.class', 'success')
|
||||
.should('have.class', 'pinned')
|
||||
.should('not.have.class', 'has-run');
|
||||
|
||||
workflowPage.getters
|
||||
.getConnectionBetweenNodes('Edit Fields1', 'Edit Fields2')
|
||||
.should('have.class', 'success')
|
||||
.should('not.have.class', 'pinned')
|
||||
.should('not.have.class', 'has-run');
|
||||
|
||||
workflowPage.getters
|
||||
.getConnectionBetweenNodes('Edit Fields2', 'Edit Fields3')
|
||||
.should('have.class', 'success')
|
||||
.should('have.class', 'pinned')
|
||||
.should('have.class', 'has-run');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
313
cypress/fixtures/Schedule_pinned.json
Normal file
313
cypress/fixtures/Schedule_pinned.json
Normal file
|
@ -0,0 +1,313 @@
|
|||
{
|
||||
"name": "Schedule + pinned",
|
||||
"nodes": [
|
||||
{
|
||||
"parameters": {
|
||||
"rule": {
|
||||
"interval": [
|
||||
{}
|
||||
]
|
||||
}
|
||||
},
|
||||
"id": "66358c29-b263-43dd-be25-3b068b0a88eb",
|
||||
"name": "Schedule Trigger",
|
||||
"type": "n8n-nodes-base.scheduleTrigger",
|
||||
"typeVersion": 1.1,
|
||||
"position": [
|
||||
660,
|
||||
340
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"options": {}
|
||||
},
|
||||
"id": "6d903354-4e59-4032-81fe-426a5d6ec33c",
|
||||
"name": "Edit Fields",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"typeVersion": 3.2,
|
||||
"position": [
|
||||
860,
|
||||
240
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"options": {}
|
||||
},
|
||||
"id": "d8a1e9cf-81d3-400f-97d4-ad6167e7b236",
|
||||
"name": "Edit Fields1",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"typeVersion": 3.2,
|
||||
"position": [
|
||||
860,
|
||||
440
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"options": {}
|
||||
},
|
||||
"id": "bdc41148-067e-4649-8f21-5707b128d877",
|
||||
"name": "Edit Fields2",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"typeVersion": 3.2,
|
||||
"position": [
|
||||
1080,
|
||||
440
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"options": {}
|
||||
},
|
||||
"id": "d5a4337f-a6b3-4b51-9b02-e668593d9ae8",
|
||||
"name": "Edit Fields3",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"typeVersion": 3.2,
|
||||
"position": [
|
||||
1300,
|
||||
440
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"options": {}
|
||||
},
|
||||
"id": "fbc23f60-e7f6-4423-9329-33b0e4809a9a",
|
||||
"name": "Edit Fields4",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"typeVersion": 3.2,
|
||||
"position": [
|
||||
1500,
|
||||
440
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"options": {}
|
||||
},
|
||||
"id": "eaee47b0-94ec-4137-bfeb-a6c1a2c63f81",
|
||||
"name": "Edit Fields5",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"typeVersion": 3.2,
|
||||
"position": [
|
||||
1080,
|
||||
240
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"options": {}
|
||||
},
|
||||
"id": "eabb6308-21e9-4e59-8f74-9220a03c3186",
|
||||
"name": "Edit Fields6",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"typeVersion": 3.2,
|
||||
"position": [
|
||||
1300,
|
||||
240
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"options": {}
|
||||
},
|
||||
"id": "8812a45b-5545-4080-aad8-8e9f7b17ecd7",
|
||||
"name": "Edit Fields7",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"typeVersion": 3.2,
|
||||
"position": [
|
||||
1500,
|
||||
240
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"options": {}
|
||||
},
|
||||
"id": "d5ea3c5b-0b3e-4514-93e1-9c88563bab5c",
|
||||
"name": "Edit Fields9",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"typeVersion": 3.2,
|
||||
"position": [
|
||||
1700,
|
||||
240
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"options": {}
|
||||
},
|
||||
"id": "7af34474-5cd0-40b1-abea-850858e3b495",
|
||||
"name": "Edit Fields10",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"typeVersion": 3.2,
|
||||
"position": [
|
||||
1700,
|
||||
440
|
||||
]
|
||||
}
|
||||
],
|
||||
"pinData": {
|
||||
"Schedule Trigger": [
|
||||
{
|
||||
"json": {
|
||||
"name": "First item",
|
||||
"code": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"json": {
|
||||
"name": "Second item",
|
||||
"code": 2
|
||||
}
|
||||
}
|
||||
],
|
||||
"Edit Fields7": [
|
||||
{
|
||||
"json": {
|
||||
"name": "First item",
|
||||
"code": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"json": {
|
||||
"name": "Second item",
|
||||
"code": 2
|
||||
}
|
||||
}
|
||||
],
|
||||
"Edit Fields2": [
|
||||
{
|
||||
"json": {
|
||||
"name": "First item",
|
||||
"code": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"json": {
|
||||
"name": "Second item",
|
||||
"code": 2
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"connections": {
|
||||
"Schedule Trigger": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Edit Fields",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
},
|
||||
{
|
||||
"node": "Edit Fields1",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Edit Fields1": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Edit Fields2",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Edit Fields2": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Edit Fields3",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Edit Fields3": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Edit Fields4",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Edit Fields5": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Edit Fields6",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Edit Fields6": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Edit Fields7",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Edit Fields": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Edit Fields5",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Edit Fields7": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Edit Fields9",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Edit Fields4": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Edit Fields10",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
"active": false,
|
||||
"settings": {
|
||||
"executionOrder": "v1"
|
||||
},
|
||||
"versionId": "9b6c68c0-f94f-45bc-a604-bf97d17a47ac",
|
||||
"meta": {
|
||||
"templateCredsSetupCompleted": true,
|
||||
"instanceId": "8a47b83b4479b11330fdf21ccc96d4a8117035a968612e452b4c87bfd09c16c7"
|
||||
},
|
||||
"id": "nWzcnYUb3AVaZpHG",
|
||||
"tags": []
|
||||
}
|
|
@ -1179,17 +1179,6 @@ export default defineComponent({
|
|||
.drop-add-node-label {
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.jtk-connector.success:not(.jtk-hover) {
|
||||
path:not(.jtk-connector-outline) {
|
||||
stroke: var(--color-success-light);
|
||||
}
|
||||
path[jtk-overlay-id='reverse-arrow'],
|
||||
path[jtk-overlay-id='endpoint-arrow'],
|
||||
path[jtk-overlay-id='midpoint-arrow'] {
|
||||
fill: var(--color-success-light);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss">
|
||||
|
@ -1262,7 +1251,6 @@ export default defineComponent({
|
|||
white-space: nowrap;
|
||||
font-size: var(--font-size-s);
|
||||
font-weight: var(--font-weight-regular);
|
||||
color: var(--color-success);
|
||||
margin-top: -15px;
|
||||
|
||||
&.floating {
|
||||
|
|
|
@ -755,9 +755,15 @@ export const getRunItemsLabel = (output: { total: number; iterations: number }):
|
|||
|
||||
export const addConnectionOutputSuccess = (
|
||||
connection: Connection,
|
||||
output: { total: number; iterations: number },
|
||||
output: { total: number; iterations: number; classNames?: string[] },
|
||||
) => {
|
||||
connection.addClass('success');
|
||||
const classNames: string[] = ['success'];
|
||||
|
||||
if (output.classNames) {
|
||||
classNames.push(...output.classNames);
|
||||
}
|
||||
|
||||
connection.addClass(classNames.join(' '));
|
||||
if (getOverlay(connection, OVERLAY_RUN_ITEMS_ID)) {
|
||||
connection.removeOverlay(OVERLAY_RUN_ITEMS_ID);
|
||||
}
|
||||
|
@ -771,7 +777,7 @@ export const addConnectionOutputSuccess = (
|
|||
const container = document.createElement('div');
|
||||
const span = document.createElement('span');
|
||||
|
||||
container.classList.add('connection-run-items-label');
|
||||
container.classList.add(...['connection-run-items-label', ...classNames]);
|
||||
span.classList.add('floating');
|
||||
span.innerHTML = getRunItemsLabel(output);
|
||||
container.appendChild(span);
|
||||
|
@ -791,6 +797,27 @@ export const addConnectionOutputSuccess = (
|
|||
});
|
||||
};
|
||||
|
||||
export const addClassesToOverlays = ({
|
||||
connection,
|
||||
overlayIds,
|
||||
classNames,
|
||||
includeConnector,
|
||||
}: {
|
||||
connection: Connection;
|
||||
overlayIds: string[];
|
||||
classNames: string[];
|
||||
includeConnector?: boolean;
|
||||
}) => {
|
||||
overlayIds.forEach((overlayId) => {
|
||||
const overlay = getOverlay(connection, overlayId);
|
||||
|
||||
overlay?.canvas?.classList.add(...classNames);
|
||||
if (includeConnector) {
|
||||
connection.connector.canvas?.classList.add(...classNames);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const getContentDimensions = (): { editorWidth: number; editorHeight: number } => {
|
||||
let contentWidth = window.innerWidth;
|
||||
let contentHeight = window.innerHeight;
|
||||
|
|
|
@ -2157,6 +2157,9 @@ export default defineComponent({
|
|||
}, []);
|
||||
|
||||
this.workflowsStore.addWorkflowTagIds(tagIds);
|
||||
setTimeout(() => {
|
||||
this.addPinDataConnections(this.workflowsStore.pinnedWorkflowData || ({} as IPinData));
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
this.showError(error, this.$locale.baseText('nodeView.showError.importWorkflowData.title'));
|
||||
|
@ -3803,7 +3806,22 @@ export default defineComponent({
|
|||
}) {
|
||||
const pinData = this.workflowsStore.pinnedWorkflowData;
|
||||
|
||||
if (pinData?.[name]) return;
|
||||
if (pinData?.[name]) {
|
||||
const { outgoing } = this.getIncomingOutgoingConnections(name);
|
||||
|
||||
outgoing.forEach((connection: Connection) => {
|
||||
if (connection.__meta?.sourceNodeName === name) {
|
||||
const hasRun = this.workflowsStore.getWorkflowResultDataByNodeName(name) !== null;
|
||||
NodeViewUtils.addClassesToOverlays({
|
||||
connection,
|
||||
overlayIds: [NodeViewUtils.OVERLAY_RUN_ITEMS_ID],
|
||||
classNames: hasRun ? ['has-run'] : [],
|
||||
includeConnector: true,
|
||||
});
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const sourceNodeName = name;
|
||||
const sourceNode = this.workflowsStore.getNodeByName(sourceNodeName);
|
||||
|
@ -4690,6 +4708,7 @@ export default defineComponent({
|
|||
NodeViewUtils.addConnectionOutputSuccess(connection, {
|
||||
total: pinData[nodeName].length,
|
||||
iterations: 0,
|
||||
classNames: ['pinned'],
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -5209,3 +5228,36 @@ export default defineComponent({
|
|||
top: var(--spacing-l);
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@mixin applyColorToConnection($partialSelector, $cssColorVarName, $labelCssColorVarName) {
|
||||
.jtk-connector#{$partialSelector}:not(.jtk-hover) {
|
||||
path:not(.jtk-connector-outline) {
|
||||
stroke: var(#{$cssColorVarName});
|
||||
}
|
||||
path[jtk-overlay-id='reverse-arrow'],
|
||||
path[jtk-overlay-id='endpoint-arrow'],
|
||||
path[jtk-overlay-id='midpoint-arrow'] {
|
||||
fill: var(#{$cssColorVarName});
|
||||
}
|
||||
}
|
||||
|
||||
.connection-run-items-label#{$partialSelector} {
|
||||
color: var(#{$labelCssColorVarName});
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.node-view) {
|
||||
@include applyColorToConnection('.success', '--color-success-light', '--color-success');
|
||||
@include applyColorToConnection(
|
||||
'.success.pinned',
|
||||
'--color-foreground-xdark',
|
||||
'--color-foreground-xdark'
|
||||
);
|
||||
@include applyColorToConnection(
|
||||
'.success.pinned.has-run',
|
||||
'--color-secondary',
|
||||
'--color-secondary'
|
||||
);
|
||||
}
|
||||
</style>
|
||||
|
|
Loading…
Reference in a new issue