From 3f10d7c9dd01b7c357a85e717b9db074f2743d88 Mon Sep 17 00:00:00 2001 From: Tuukka Kantola Date: Tue, 29 Jul 2025 14:04:07 +0200 Subject: [PATCH] refactor(editor): Address issues with new icons (#17643) --- cypress/e2e/19-execution.cy.ts | 38 +++++++++---------- .../components/N8nIcon/custom/node-dirty.svg | 1 + .../N8nIcon/custom/node-ellipsis.svg | 1 + .../components/N8nIcon/custom/node-error.svg | 1 + .../components/N8nIcon/custom/node-pin.svg | 1 + .../components/N8nIcon/custom/node-play.svg | 1 + .../components/N8nIcon/custom/node-power.svg | 1 + .../N8nIcon/custom/node-success.svg | 1 + .../components/N8nIcon/custom/node-trash.svg | 1 + .../src/components/N8nIcon/icons.ts | 16 ++++++++ .../@n8n/design-system/vite.config.mts | 2 + .../editor-ui/src/components/MainSidebar.vue | 2 - .../src/components/RunDataSearch.vue | 2 +- .../elements/nodes/CanvasNodeToolbar.vue | 8 ++-- .../parts/CanvasNodeStatusIcons.vue | 12 +++--- packages/frontend/editor-ui/vite.config.mts | 2 + 16 files changed, 58 insertions(+), 32 deletions(-) create mode 100644 packages/frontend/@n8n/design-system/src/components/N8nIcon/custom/node-dirty.svg create mode 100644 packages/frontend/@n8n/design-system/src/components/N8nIcon/custom/node-ellipsis.svg create mode 100644 packages/frontend/@n8n/design-system/src/components/N8nIcon/custom/node-error.svg create mode 100644 packages/frontend/@n8n/design-system/src/components/N8nIcon/custom/node-pin.svg create mode 100644 packages/frontend/@n8n/design-system/src/components/N8nIcon/custom/node-play.svg create mode 100644 packages/frontend/@n8n/design-system/src/components/N8nIcon/custom/node-power.svg create mode 100644 packages/frontend/@n8n/design-system/src/components/N8nIcon/custom/node-success.svg create mode 100644 packages/frontend/@n8n/design-system/src/components/N8nIcon/custom/node-trash.svg diff --git a/cypress/e2e/19-execution.cy.ts b/cypress/e2e/19-execution.cy.ts index acb476734b..d88cf55c90 100644 --- a/cypress/e2e/19-execution.cy.ts +++ b/cypress/e2e/19-execution.cy.ts @@ -41,33 +41,33 @@ describe('Execution', () => { // Check canvas nodes after 1st step (workflow passed the manual trigger node workflowPage.getters .canvasNodeByName('Manual') - .within(() => cy.get('svg[data-icon=check]')) + .within(() => cy.get('svg[data-icon=node-success]')) .should('exist'); workflowPage.getters .canvasNodeByName('Wait') - .within(() => cy.get('svg[data-icon=check]').should('not.exist')); + .within(() => cy.get('svg[data-icon=node-success]').should('not.exist')); workflowPage.getters .canvasNodeByName('Wait') .within(() => cy.get('svg[data-icon=refresh-cw]')) .should('exist'); workflowPage.getters .canvasNodeByName('Set') - .within(() => cy.get('svg[data-icon=check]').should('not.exist')); + .within(() => cy.get('svg[data-icon=node-success]').should('not.exist')); cy.wait(2000); // Check canvas nodes after 2nd step (waiting node finished its execution and the http request node is about to start) workflowPage.getters .canvasNodeByName('Manual') - .within(() => cy.get('svg[data-icon=check]')) + .within(() => cy.get('svg[data-icon=node-success]')) .should('exist'); workflowPage.getters .canvasNodeByName('Wait') - .within(() => cy.get('svg[data-icon=check]')) + .within(() => cy.get('svg[data-icon=node-success]')) .should('exist'); workflowPage.getters .canvasNodeByName('Set') - .within(() => cy.get('svg[data-icon=check]')) + .within(() => cy.get('svg[data-icon=node-success]')) .should('exist'); successToast().should('be.visible'); @@ -101,18 +101,18 @@ describe('Execution', () => { // Check canvas nodes after 1st step (workflow passed the manual trigger node workflowPage.getters .canvasNodeByName('Manual') - .within(() => cy.get('svg[data-icon=check]')) + .within(() => cy.get('svg[data-icon=node-success]')) .should('exist'); workflowPage.getters .canvasNodeByName('Wait') - .within(() => cy.get('svg[data-icon=check]').should('not.exist')); + .within(() => cy.get('svg[data-icon=node-success]').should('not.exist')); workflowPage.getters .canvasNodeByName('Wait') .within(() => cy.get('svg[data-icon=refresh-cw]')) .should('exist'); workflowPage.getters .canvasNodeByName('Set') - .within(() => cy.get('svg[data-icon=check]').should('not.exist')); + .within(() => cy.get('svg[data-icon=node-success]').should('not.exist')); successToast().should('be.visible'); clearNotifications(); @@ -123,7 +123,7 @@ describe('Execution', () => { // Check canvas nodes after workflow stopped workflowPage.getters .canvasNodeByName('Manual') - .within(() => cy.get('svg[data-icon=check]')) + .within(() => cy.get('svg[data-icon=node-success]')) .should('exist'); workflowPage.getters @@ -132,7 +132,7 @@ describe('Execution', () => { workflowPage.getters .canvasNodeByName('Set') - .within(() => cy.get('svg[data-icon=check]').should('not.exist')); + .within(() => cy.get('svg[data-icon=node-success]').should('not.exist')); successToast().should('be.visible'); @@ -181,29 +181,29 @@ describe('Execution', () => { // Check canvas nodes after 1st step (workflow passed the manual trigger node workflowPage.getters .canvasNodeByName('Webhook') - .within(() => cy.get('svg[data-icon=check]')) + .within(() => cy.get('svg[data-icon=node-success]')) .should('exist'); workflowPage.getters .canvasNodeByName('Wait') - .within(() => cy.get('svg[data-icon=check]').should('not.exist')); + .within(() => cy.get('svg[data-icon=node-success]').should('not.exist')); workflowPage.getters .canvasNodeByName('Wait') .within(() => cy.get('svg[data-icon=refresh-cw]')) .should('exist'); workflowPage.getters .canvasNodeByName('Set') - .within(() => cy.get('svg[data-icon=check]').should('not.exist')); + .within(() => cy.get('svg[data-icon=node-success]').should('not.exist')); cy.wait(2000); // Check canvas nodes after 2nd step (waiting node finished its execution and the http request node is about to start) workflowPage.getters .canvasNodeByName('Webhook') - .within(() => cy.get('svg[data-icon=check]')) + .within(() => cy.get('svg[data-icon=node-success]')) .should('exist'); workflowPage.getters .canvasNodeByName('Set') - .within(() => cy.get('svg[data-icon=check]')) + .within(() => cy.get('svg[data-icon=node-success]')) .should('exist'); successToast().should('be.visible'); @@ -578,11 +578,11 @@ describe('Execution', () => { // Check that the previous nodes executed successfully workflowPage.getters .canvasNodeByName('DebugHelper') - .within(() => cy.get('svg[data-icon=check]')) + .within(() => cy.get('svg[data-icon=node-success]')) .should('exist'); workflowPage.getters .canvasNodeByName('Filter') - .within(() => cy.get('svg[data-icon=check]')) + .within(() => cy.get('svg[data-icon=node-success]')) .should('exist'); errorToast().should('contain', 'Problem in node ‘Telegram‘'); @@ -596,7 +596,7 @@ describe('Execution', () => { workflowPage.getters .canvasNodeByName('Edit Fields') - .within(() => cy.get('svg[data-icon=check]')) + .within(() => cy.get('svg[data-icon=node-success]')) .should('exist'); workflowPage.getters.canvasNodeByName('Edit Fields').dblclick(); diff --git a/packages/frontend/@n8n/design-system/src/components/N8nIcon/custom/node-dirty.svg b/packages/frontend/@n8n/design-system/src/components/N8nIcon/custom/node-dirty.svg new file mode 100644 index 0000000000..d412cee39f --- /dev/null +++ b/packages/frontend/@n8n/design-system/src/components/N8nIcon/custom/node-dirty.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/frontend/@n8n/design-system/src/components/N8nIcon/custom/node-ellipsis.svg b/packages/frontend/@n8n/design-system/src/components/N8nIcon/custom/node-ellipsis.svg new file mode 100644 index 0000000000..49a0fbb3a5 --- /dev/null +++ b/packages/frontend/@n8n/design-system/src/components/N8nIcon/custom/node-ellipsis.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/frontend/@n8n/design-system/src/components/N8nIcon/custom/node-error.svg b/packages/frontend/@n8n/design-system/src/components/N8nIcon/custom/node-error.svg new file mode 100644 index 0000000000..73ca51cd77 --- /dev/null +++ b/packages/frontend/@n8n/design-system/src/components/N8nIcon/custom/node-error.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/frontend/@n8n/design-system/src/components/N8nIcon/custom/node-pin.svg b/packages/frontend/@n8n/design-system/src/components/N8nIcon/custom/node-pin.svg new file mode 100644 index 0000000000..d01032ea6c --- /dev/null +++ b/packages/frontend/@n8n/design-system/src/components/N8nIcon/custom/node-pin.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/frontend/@n8n/design-system/src/components/N8nIcon/custom/node-play.svg b/packages/frontend/@n8n/design-system/src/components/N8nIcon/custom/node-play.svg new file mode 100644 index 0000000000..016530f36a --- /dev/null +++ b/packages/frontend/@n8n/design-system/src/components/N8nIcon/custom/node-play.svg @@ -0,0 +1 @@ + diff --git a/packages/frontend/@n8n/design-system/src/components/N8nIcon/custom/node-power.svg b/packages/frontend/@n8n/design-system/src/components/N8nIcon/custom/node-power.svg new file mode 100644 index 0000000000..6a3f39fb93 --- /dev/null +++ b/packages/frontend/@n8n/design-system/src/components/N8nIcon/custom/node-power.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/frontend/@n8n/design-system/src/components/N8nIcon/custom/node-success.svg b/packages/frontend/@n8n/design-system/src/components/N8nIcon/custom/node-success.svg new file mode 100644 index 0000000000..bebc44aec7 --- /dev/null +++ b/packages/frontend/@n8n/design-system/src/components/N8nIcon/custom/node-success.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/frontend/@n8n/design-system/src/components/N8nIcon/custom/node-trash.svg b/packages/frontend/@n8n/design-system/src/components/N8nIcon/custom/node-trash.svg new file mode 100644 index 0000000000..0ce3378df0 --- /dev/null +++ b/packages/frontend/@n8n/design-system/src/components/N8nIcon/custom/node-trash.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/frontend/@n8n/design-system/src/components/N8nIcon/icons.ts b/packages/frontend/@n8n/design-system/src/components/N8nIcon/icons.ts index 0263873c5d..9017221879 100644 --- a/packages/frontend/@n8n/design-system/src/components/N8nIcon/icons.ts +++ b/packages/frontend/@n8n/design-system/src/components/N8nIcon/icons.ts @@ -3,6 +3,14 @@ import BoltFilled from './custom/bolt-filled.svg'; import Continue from './custom/continue.svg'; import EmptyOutput from './custom/empty-output.svg'; import GripLinesVertical from './custom/grip-lines-vertical.svg'; +import NodeDirty from './custom/node-dirty.svg'; +import NodeEllipsis from './custom/node-ellipsis.svg'; +import NodeError from './custom/node-error.svg'; +import NodePin from './custom/node-pin.svg'; +import NodePlay from './custom/node-play.svg'; +import NodePower from './custom/node-power.svg'; +import NodeSuccess from './custom/node-success.svg'; +import NodeTrash from './custom/node-trash.svg'; import PopOut from './custom/pop-out.svg'; import Retry from './custom/retry.svg'; import RunOnce from './custom/run-once.svg'; @@ -420,6 +428,14 @@ export const updatedIconSet = { text: Text, toolbox: Toolbox, spinner: Spinner, + 'node-dirty': NodeDirty, + 'node-ellipsis': NodeEllipsis, + 'node-error': NodeError, + 'node-pin': NodePin, + 'node-play': NodePlay, + 'node-power': NodePower, + 'node-success': NodeSuccess, + 'node-trash': NodeTrash, // lucide 'align-right': IconLucideAlignRight, diff --git a/packages/frontend/@n8n/design-system/vite.config.mts b/packages/frontend/@n8n/design-system/vite.config.mts index fee0abbcb4..9f8095cbf2 100644 --- a/packages/frontend/@n8n/design-system/vite.config.mts +++ b/packages/frontend/@n8n/design-system/vite.config.mts @@ -22,6 +22,8 @@ export default mergeConfig( overrides: { // disable a default plugin cleanupIds: false, + // preserve viewBox for scalability + removeViewBox: false, }, }, }, diff --git a/packages/frontend/editor-ui/src/components/MainSidebar.vue b/packages/frontend/editor-ui/src/components/MainSidebar.vue index 065e8f21ce..962e0de45f 100644 --- a/packages/frontend/editor-ui/src/components/MainSidebar.vue +++ b/packages/frontend/editor-ui/src/components/MainSidebar.vue @@ -110,7 +110,6 @@ const mainMenuItems = computed(() => [ id: 'variables', icon: 'variable', label: i18n.baseText('mainSidebar.variables'), - customIconSize: 'medium', position: 'bottom', route: { to: { name: VIEWS.VARIABLES } }, }, @@ -118,7 +117,6 @@ const mainMenuItems = computed(() => [ id: 'insights', icon: 'chart-column-decreasing', label: 'Insights', - customIconSize: 'medium', position: 'bottom', route: { to: { name: VIEWS.INSIGHTS } }, available: diff --git a/packages/frontend/editor-ui/src/components/RunDataSearch.vue b/packages/frontend/editor-ui/src/components/RunDataSearch.vue index 51003afcb5..445d44f636 100644 --- a/packages/frontend/editor-ui/src/components/RunDataSearch.vue +++ b/packages/frontend/editor-ui/src/components/RunDataSearch.vue @@ -116,7 +116,7 @@ watch( @blur="onBlur" > diff --git a/packages/frontend/editor-ui/src/components/canvas/elements/nodes/CanvasNodeToolbar.vue b/packages/frontend/editor-ui/src/components/canvas/elements/nodes/CanvasNodeToolbar.vue index 7367bbf2d6..4bac64ba53 100644 --- a/packages/frontend/editor-ui/src/components/canvas/elements/nodes/CanvasNodeToolbar.vue +++ b/packages/frontend/editor-ui/src/components/canvas/elements/nodes/CanvasNodeToolbar.vue @@ -130,7 +130,7 @@ function onFocusNode() { type="tertiary" text size="small" - icon="play" + icon="node-play" :disabled="isExecuting || isDisabled" :title="i18n.baseText('node.testStep')" @click="executeNode" @@ -142,7 +142,7 @@ function onFocusNode() { type="tertiary" text size="small" - icon="power" + icon="node-power" :title="nodeDisabledTitle" @click="onToggleNode" /> @@ -152,7 +152,7 @@ function onFocusNode() { type="tertiary" size="small" text - icon="trash-2" + icon="node-trash" :title="i18n.baseText('node.delete')" @click="onDeleteNode" /> @@ -174,7 +174,7 @@ function onFocusNode() { type="tertiary" size="small" text - icon="ellipsis" + icon="node-ellipsis" @click="onOpenContextMenu" /> diff --git a/packages/frontend/editor-ui/src/components/canvas/elements/nodes/render-types/parts/CanvasNodeStatusIcons.vue b/packages/frontend/editor-ui/src/components/canvas/elements/nodes/render-types/parts/CanvasNodeStatusIcons.vue index 83f2fe1adc..ad406e629f 100644 --- a/packages/frontend/editor-ui/src/components/canvas/elements/nodes/render-types/parts/CanvasNodeStatusIcons.vue +++ b/packages/frontend/editor-ui/src/components/canvas/elements/nodes/render-types/parts/CanvasNodeStatusIcons.vue @@ -8,8 +8,8 @@ import { CanvasNodeDirtiness, CanvasNodeRenderType } from '@/types'; import { N8nTooltip } from '@n8n/design-system'; import { useCanvas } from '@/composables/useCanvas'; -const { size = 'medium', spinnerScrim = false } = defineProps<{ - size?: 'small' | 'medium'; +const { size = 'large', spinnerScrim = false } = defineProps<{ + size?: 'small' | 'medium' | 'large'; spinnerScrim?: boolean; }>(); @@ -60,7 +60,7 @@ const commonClasses = computed(() => [$style.status, spinnerScrim ? $style.spinn - +
@@ -91,7 +91,7 @@ const commonClasses = computed(() => [$style.status, spinnerScrim ? $style.spinn data-test-id="canvas-node-status-pinned" :class="[...commonClasses, $style.pinnedData]" > - +
@@ -105,7 +105,7 @@ const commonClasses = computed(() => [$style.status, spinnerScrim ? $style.spinn }}
- + {{ runDataIterations }}
@@ -115,7 +115,7 @@ const commonClasses = computed(() => [$style.status, spinnerScrim ? $style.spinn data-test-id="canvas-node-status-success" :class="[...commonClasses, $style.runData]" > - + {{ runDataIterations }}
diff --git a/packages/frontend/editor-ui/vite.config.mts b/packages/frontend/editor-ui/vite.config.mts index 51c61ae68d..c1b57fa3a8 100644 --- a/packages/frontend/editor-ui/vite.config.mts +++ b/packages/frontend/editor-ui/vite.config.mts @@ -110,6 +110,8 @@ const plugins: UserConfig['plugins'] = [ overrides: { // disable a default plugin cleanupIds: false, + // preserve viewBox for scalability + removeViewBox: false, }, }, },