refactor(editor): Address issues with new icons (#17643)

This commit is contained in:
Tuukka Kantola
2025-07-29 14:04:07 +02:00
committed by GitHub
parent f730df398b
commit 3f10d7c9dd
16 changed files with 58 additions and 32 deletions

View File

@@ -41,33 +41,33 @@ describe('Execution', () => {
// Check canvas nodes after 1st step (workflow passed the manual trigger node // Check canvas nodes after 1st step (workflow passed the manual trigger node
workflowPage.getters workflowPage.getters
.canvasNodeByName('Manual') .canvasNodeByName('Manual')
.within(() => cy.get('svg[data-icon=check]')) .within(() => cy.get('svg[data-icon=node-success]'))
.should('exist'); .should('exist');
workflowPage.getters workflowPage.getters
.canvasNodeByName('Wait') .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 workflowPage.getters
.canvasNodeByName('Wait') .canvasNodeByName('Wait')
.within(() => cy.get('svg[data-icon=refresh-cw]')) .within(() => cy.get('svg[data-icon=refresh-cw]'))
.should('exist'); .should('exist');
workflowPage.getters workflowPage.getters
.canvasNodeByName('Set') .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); cy.wait(2000);
// Check canvas nodes after 2nd step (waiting node finished its execution and the http request node is about to start) // Check canvas nodes after 2nd step (waiting node finished its execution and the http request node is about to start)
workflowPage.getters workflowPage.getters
.canvasNodeByName('Manual') .canvasNodeByName('Manual')
.within(() => cy.get('svg[data-icon=check]')) .within(() => cy.get('svg[data-icon=node-success]'))
.should('exist'); .should('exist');
workflowPage.getters workflowPage.getters
.canvasNodeByName('Wait') .canvasNodeByName('Wait')
.within(() => cy.get('svg[data-icon=check]')) .within(() => cy.get('svg[data-icon=node-success]'))
.should('exist'); .should('exist');
workflowPage.getters workflowPage.getters
.canvasNodeByName('Set') .canvasNodeByName('Set')
.within(() => cy.get('svg[data-icon=check]')) .within(() => cy.get('svg[data-icon=node-success]'))
.should('exist'); .should('exist');
successToast().should('be.visible'); successToast().should('be.visible');
@@ -101,18 +101,18 @@ describe('Execution', () => {
// Check canvas nodes after 1st step (workflow passed the manual trigger node // Check canvas nodes after 1st step (workflow passed the manual trigger node
workflowPage.getters workflowPage.getters
.canvasNodeByName('Manual') .canvasNodeByName('Manual')
.within(() => cy.get('svg[data-icon=check]')) .within(() => cy.get('svg[data-icon=node-success]'))
.should('exist'); .should('exist');
workflowPage.getters workflowPage.getters
.canvasNodeByName('Wait') .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 workflowPage.getters
.canvasNodeByName('Wait') .canvasNodeByName('Wait')
.within(() => cy.get('svg[data-icon=refresh-cw]')) .within(() => cy.get('svg[data-icon=refresh-cw]'))
.should('exist'); .should('exist');
workflowPage.getters workflowPage.getters
.canvasNodeByName('Set') .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'); successToast().should('be.visible');
clearNotifications(); clearNotifications();
@@ -123,7 +123,7 @@ describe('Execution', () => {
// Check canvas nodes after workflow stopped // Check canvas nodes after workflow stopped
workflowPage.getters workflowPage.getters
.canvasNodeByName('Manual') .canvasNodeByName('Manual')
.within(() => cy.get('svg[data-icon=check]')) .within(() => cy.get('svg[data-icon=node-success]'))
.should('exist'); .should('exist');
workflowPage.getters workflowPage.getters
@@ -132,7 +132,7 @@ describe('Execution', () => {
workflowPage.getters workflowPage.getters
.canvasNodeByName('Set') .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'); successToast().should('be.visible');
@@ -181,29 +181,29 @@ describe('Execution', () => {
// Check canvas nodes after 1st step (workflow passed the manual trigger node // Check canvas nodes after 1st step (workflow passed the manual trigger node
workflowPage.getters workflowPage.getters
.canvasNodeByName('Webhook') .canvasNodeByName('Webhook')
.within(() => cy.get('svg[data-icon=check]')) .within(() => cy.get('svg[data-icon=node-success]'))
.should('exist'); .should('exist');
workflowPage.getters workflowPage.getters
.canvasNodeByName('Wait') .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 workflowPage.getters
.canvasNodeByName('Wait') .canvasNodeByName('Wait')
.within(() => cy.get('svg[data-icon=refresh-cw]')) .within(() => cy.get('svg[data-icon=refresh-cw]'))
.should('exist'); .should('exist');
workflowPage.getters workflowPage.getters
.canvasNodeByName('Set') .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); cy.wait(2000);
// Check canvas nodes after 2nd step (waiting node finished its execution and the http request node is about to start) // Check canvas nodes after 2nd step (waiting node finished its execution and the http request node is about to start)
workflowPage.getters workflowPage.getters
.canvasNodeByName('Webhook') .canvasNodeByName('Webhook')
.within(() => cy.get('svg[data-icon=check]')) .within(() => cy.get('svg[data-icon=node-success]'))
.should('exist'); .should('exist');
workflowPage.getters workflowPage.getters
.canvasNodeByName('Set') .canvasNodeByName('Set')
.within(() => cy.get('svg[data-icon=check]')) .within(() => cy.get('svg[data-icon=node-success]'))
.should('exist'); .should('exist');
successToast().should('be.visible'); successToast().should('be.visible');
@@ -578,11 +578,11 @@ describe('Execution', () => {
// Check that the previous nodes executed successfully // Check that the previous nodes executed successfully
workflowPage.getters workflowPage.getters
.canvasNodeByName('DebugHelper') .canvasNodeByName('DebugHelper')
.within(() => cy.get('svg[data-icon=check]')) .within(() => cy.get('svg[data-icon=node-success]'))
.should('exist'); .should('exist');
workflowPage.getters workflowPage.getters
.canvasNodeByName('Filter') .canvasNodeByName('Filter')
.within(() => cy.get('svg[data-icon=check]')) .within(() => cy.get('svg[data-icon=node-success]'))
.should('exist'); .should('exist');
errorToast().should('contain', 'Problem in node Telegram'); errorToast().should('contain', 'Problem in node Telegram');
@@ -596,7 +596,7 @@ describe('Execution', () => {
workflowPage.getters workflowPage.getters
.canvasNodeByName('Edit Fields') .canvasNodeByName('Edit Fields')
.within(() => cy.get('svg[data-icon=check]')) .within(() => cy.get('svg[data-icon=node-success]'))
.should('exist'); .should('exist');
workflowPage.getters.canvasNodeByName('Edit Fields').dblclick(); workflowPage.getters.canvasNodeByName('Edit Fields').dblclick();

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24"><path fill="currentColor" d="M10.12 3.3c.911-1.395 3.012-1.349 3.844.14l8.222 14.712c.838 1.5-.246 3.348-1.964 3.348H3.778c-1.718 0-2.802-1.848-1.964-3.348L10.036 3.44zM5.057 18.5h13.886L12 6.073z"/></svg>

After

Width:  |  Height:  |  Size: 300 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24"><path fill="currentColor" d="M4.5 9.5a2.5 2.5 0 1 1 0 5 2.5 2.5 0 0 1 0-5m7.5 0a2.5 2.5 0 1 1 0 5 2.5 2.5 0 0 1 0-5m7.5 0a2.5 2.5 0 1 1 0 5 2.5 2.5 0 0 1 0-5"/></svg>

After

Width:  |  Height:  |  Size: 261 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24"><path fill="currentColor" fill-rule="evenodd" d="M12 1c6.075 0 11 4.925 11 11s-4.925 11-11 11S1 18.075 1 12 5.925 1 12 1m5.56 5.44a1.5 1.5 0 0 0-2.12 0L12 9.878l-3.44-3.44A1.5 1.5 0 1 0 6.44 8.56L9.878 12l-3.44 3.44a1.5 1.5 0 1 0 2.122 2.12L12 14.122l3.44 3.44.114.103a1.5 1.5 0 0 0 2.11-2.11l-.104-.114L14.122 12l3.44-3.44a1.5 1.5 0 0 0 0-2.12" clip-rule="evenodd"/></svg>

After

Width:  |  Height:  |  Size: 468 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24"><path fill="currentColor" d="M16.297 2.515A3 3 0 0 1 16 8.5v2.26l.01.138a1 1 0 0 0 .545.756l.006.003 1.774.898.184.1A3 3 0 0 1 20 15.238V16a2 2 0 0 1-2 2h-4.5v4a1.5 1.5 0 0 1-3 0v-4H6a2 2 0 0 1-1.99-1.803L4 16v-.76l.008-.209a3 3 0 0 1 1.657-2.476l1.773-.898.007-.003a1 1 0 0 0 .545-.756L8 10.76V8.5a3 3 0 0 1 0-6h8z"/></svg>

After

Width:  |  Height:  |  Size: 419 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"><path fill="currentColor" d="M5.52 2.122c.322-.175.713-.16 1.021.037l14 9a1 1 0 0 1 0 1.682l-14 9A1.001 1.001 0 0 1 5 21V3a1 1 0 0 1 .52-.878"/></svg>

After

Width:  |  Height:  |  Size: 246 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24"><path fill="currentColor" d="M16.645 5.907a1.5 1.5 0 0 1 2.122.028 9.77 9.77 0 0 1 2.585 4.953 9.9 9.9 0 0 1-.53 5.579 9.66 9.66 0 0 1-3.476 4.357 9.36 9.36 0 0 1-5.28 1.657 9.36 9.36 0 0 1-5.292-1.623 9.66 9.66 0 0 1-3.504-4.335 9.9 9.9 0 0 1-.564-5.576 9.77 9.77 0 0 1 2.556-4.97l.11-.105a1.501 1.501 0 0 1 2.05 2.187l-.166.178a6.8 6.8 0 0 0-1.602 3.266 6.9 6.9 0 0 0 .393 3.884 6.66 6.66 0 0 0 2.413 2.989 6.36 6.36 0 0 0 3.595 1.105 6.36 6.36 0 0 0 3.59-1.128 6.66 6.66 0 0 0 2.394-3.005 6.9 6.9 0 0 0 .37-3.887 6.77 6.77 0 0 0-1.79-3.433 1.5 1.5 0 0 1 .026-2.12"/><path fill="currentColor" d="M12.035 1.481a1.5 1.5 0 0 1 1.5 1.5v9a1.5 1.5 0 0 1-3 0v-9a1.5 1.5 0 0 1 1.5-1.5"/></svg>

After

Width:  |  Height:  |  Size: 782 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24"><path fill="currentColor" d="M19.94 5.502a1.5 1.5 0 1 1 2.12 2.12L9.687 19.999a1.5 1.5 0 0 1-2.122 0L1.94 14.373a1.5 1.5 0 0 1 2.007-2.225l.115.104 4.564 4.564z"/></svg>

After

Width:  |  Height:  |  Size: 264 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24"><path fill="currentColor" d="M21 6a1 1 0 1 1 0 2h-1v12.125c0 .817-.424 1.534-.941 2.019-.522.488-1.256.856-2.059.856H7c-.803 0-1.537-.368-2.059-.856C4.424 21.659 4 20.943 4 20.125V8H3a1 1 0 0 1 0-2zm-7-5a3 3 0 0 1 3 3H7a3 3 0 0 1 3-3z"/></svg>

After

Width:  |  Height:  |  Size: 338 B

View File

@@ -3,6 +3,14 @@ import BoltFilled from './custom/bolt-filled.svg';
import Continue from './custom/continue.svg'; import Continue from './custom/continue.svg';
import EmptyOutput from './custom/empty-output.svg'; import EmptyOutput from './custom/empty-output.svg';
import GripLinesVertical from './custom/grip-lines-vertical.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 PopOut from './custom/pop-out.svg';
import Retry from './custom/retry.svg'; import Retry from './custom/retry.svg';
import RunOnce from './custom/run-once.svg'; import RunOnce from './custom/run-once.svg';
@@ -420,6 +428,14 @@ export const updatedIconSet = {
text: Text, text: Text,
toolbox: Toolbox, toolbox: Toolbox,
spinner: Spinner, 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 // lucide
'align-right': IconLucideAlignRight, 'align-right': IconLucideAlignRight,

View File

@@ -22,6 +22,8 @@ export default mergeConfig(
overrides: { overrides: {
// disable a default plugin // disable a default plugin
cleanupIds: false, cleanupIds: false,
// preserve viewBox for scalability
removeViewBox: false,
}, },
}, },
}, },

View File

@@ -110,7 +110,6 @@ const mainMenuItems = computed<IMenuItem[]>(() => [
id: 'variables', id: 'variables',
icon: 'variable', icon: 'variable',
label: i18n.baseText('mainSidebar.variables'), label: i18n.baseText('mainSidebar.variables'),
customIconSize: 'medium',
position: 'bottom', position: 'bottom',
route: { to: { name: VIEWS.VARIABLES } }, route: { to: { name: VIEWS.VARIABLES } },
}, },
@@ -118,7 +117,6 @@ const mainMenuItems = computed<IMenuItem[]>(() => [
id: 'insights', id: 'insights',
icon: 'chart-column-decreasing', icon: 'chart-column-decreasing',
label: 'Insights', label: 'Insights',
customIconSize: 'medium',
position: 'bottom', position: 'bottom',
route: { to: { name: VIEWS.INSIGHTS } }, route: { to: { name: VIEWS.INSIGHTS } },
available: available:

View File

@@ -116,7 +116,7 @@ watch(
@blur="onBlur" @blur="onBlur"
> >
<template #prefix> <template #prefix>
<n8n-icon :class="$style.ioSearchIcon" icon="search" /> <n8n-icon :class="$style.ioSearchIcon" icon="search" size="large" />
</template> </template>
</n8n-input> </n8n-input>
</template> </template>

View File

@@ -130,7 +130,7 @@ function onFocusNode() {
type="tertiary" type="tertiary"
text text
size="small" size="small"
icon="play" icon="node-play"
:disabled="isExecuting || isDisabled" :disabled="isExecuting || isDisabled"
:title="i18n.baseText('node.testStep')" :title="i18n.baseText('node.testStep')"
@click="executeNode" @click="executeNode"
@@ -142,7 +142,7 @@ function onFocusNode() {
type="tertiary" type="tertiary"
text text
size="small" size="small"
icon="power" icon="node-power"
:title="nodeDisabledTitle" :title="nodeDisabledTitle"
@click="onToggleNode" @click="onToggleNode"
/> />
@@ -152,7 +152,7 @@ function onFocusNode() {
type="tertiary" type="tertiary"
size="small" size="small"
text text
icon="trash-2" icon="node-trash"
:title="i18n.baseText('node.delete')" :title="i18n.baseText('node.delete')"
@click="onDeleteNode" @click="onDeleteNode"
/> />
@@ -174,7 +174,7 @@ function onFocusNode() {
type="tertiary" type="tertiary"
size="small" size="small"
text text
icon="ellipsis" icon="node-ellipsis"
@click="onOpenContextMenu" @click="onOpenContextMenu"
/> />
</div> </div>

View File

@@ -8,8 +8,8 @@ import { CanvasNodeDirtiness, CanvasNodeRenderType } from '@/types';
import { N8nTooltip } from '@n8n/design-system'; import { N8nTooltip } from '@n8n/design-system';
import { useCanvas } from '@/composables/useCanvas'; import { useCanvas } from '@/composables/useCanvas';
const { size = 'medium', spinnerScrim = false } = defineProps<{ const { size = 'large', spinnerScrim = false } = defineProps<{
size?: 'small' | 'medium'; size?: 'small' | 'medium' | 'large';
spinnerScrim?: boolean; spinnerScrim?: boolean;
}>(); }>();
@@ -60,7 +60,7 @@ const commonClasses = computed(() => [$style.status, spinnerScrim ? $style.spinn
<template #content> <template #content>
<TitledList :title="`${i18n.baseText('node.issues')}:`" :items="issues" /> <TitledList :title="`${i18n.baseText('node.issues')}:`" :items="issues" />
</template> </template>
<N8nIcon icon="triangle-alert" :size="size" /> <N8nIcon icon="node-error" :size="size" />
</N8nTooltip> </N8nTooltip>
</div> </div>
<div v-else-if="executionWaiting || executionStatus === 'waiting'"> <div v-else-if="executionWaiting || executionStatus === 'waiting'">
@@ -91,7 +91,7 @@ const commonClasses = computed(() => [$style.status, spinnerScrim ? $style.spinn
data-test-id="canvas-node-status-pinned" data-test-id="canvas-node-status-pinned"
:class="[...commonClasses, $style.pinnedData]" :class="[...commonClasses, $style.pinnedData]"
> >
<N8nIcon icon="pin" :size="size" /> <N8nIcon icon="node-pin" :size="size" />
</div> </div>
<div v-else-if="dirtiness !== undefined"> <div v-else-if="dirtiness !== undefined">
<N8nTooltip :show-after="500" placement="bottom"> <N8nTooltip :show-after="500" placement="bottom">
@@ -105,7 +105,7 @@ const commonClasses = computed(() => [$style.status, spinnerScrim ? $style.spinn
}} }}
</template> </template>
<div data-test-id="canvas-node-status-warning" :class="[...commonClasses, $style.warning]"> <div data-test-id="canvas-node-status-warning" :class="[...commonClasses, $style.warning]">
<N8nIcon icon="triangle" :size="size" /> <N8nIcon icon="node-dirty" :size="size" />
<span v-if="runDataIterations > 1" :class="$style.count"> {{ runDataIterations }}</span> <span v-if="runDataIterations > 1" :class="$style.count"> {{ runDataIterations }}</span>
</div> </div>
</N8nTooltip> </N8nTooltip>
@@ -115,7 +115,7 @@ const commonClasses = computed(() => [$style.status, spinnerScrim ? $style.spinn
data-test-id="canvas-node-status-success" data-test-id="canvas-node-status-success"
:class="[...commonClasses, $style.runData]" :class="[...commonClasses, $style.runData]"
> >
<N8nIcon icon="check" :size="size" /> <N8nIcon icon="node-success" :size="size" />
<span v-if="runDataIterations > 1" :class="$style.count"> {{ runDataIterations }}</span> <span v-if="runDataIterations > 1" :class="$style.count"> {{ runDataIterations }}</span>
</div> </div>
</template> </template>

View File

@@ -110,6 +110,8 @@ const plugins: UserConfig['plugins'] = [
overrides: { overrides: {
// disable a default plugin // disable a default plugin
cleanupIds: false, cleanupIds: false,
// preserve viewBox for scalability
removeViewBox: false,
}, },
}, },
}, },