feat(editor): Show strikethrough line for all single main input and single main output nodes in new canvas (no-changelog) (#10925)

This commit is contained in:
Alex Grozav
2024-09-25 11:28:07 +03:00
committed by GitHub
parent bdc0622f59
commit a6cfb3b0c5
4 changed files with 52 additions and 43 deletions

View File

@@ -4,7 +4,7 @@ import { NodeConnectionType } from 'n8n-workflow';
import { createCanvasNodeProvide } from '@/__tests__/data'; import { createCanvasNodeProvide } from '@/__tests__/data';
import { createTestingPinia } from '@pinia/testing'; import { createTestingPinia } from '@pinia/testing';
import { setActivePinia } from 'pinia'; import { setActivePinia } from 'pinia';
import { CanvasNodeRenderType } from '@/types'; import { CanvasConnectionMode, CanvasNodeRenderType } from '@/types';
const renderComponent = createComponentRenderer(CanvasNodeDefault); const renderComponent = createComponentRenderer(CanvasNodeDefault);
@@ -158,6 +158,36 @@ describe('CanvasNodeDefault', () => {
}); });
expect(getByText('Test Node').closest('.node')).not.toHaveClass('disabled'); expect(getByText('Test Node').closest('.node')).not.toHaveClass('disabled');
}); });
it('should render strike-through when node is disabled and has node input and output handles', () => {
const { container } = renderComponent({
global: {
provide: {
...createCanvasNodeProvide({
data: {
disabled: true,
inputs: [{ type: NodeConnectionType.Main, index: 0 }],
outputs: [{ type: NodeConnectionType.Main, index: 0 }],
connections: {
[CanvasConnectionMode.Input]: {
[NodeConnectionType.Main]: [
[{ node: 'node', type: NodeConnectionType.Main, index: 0 }],
],
},
[CanvasConnectionMode.Output]: {
[NodeConnectionType.Main]: [
[{ node: 'node', type: NodeConnectionType.Main, index: 0 }],
],
},
},
},
}),
},
},
});
expect(container.querySelector('.disabledStrikeThrough')).toBeVisible();
});
}); });
describe('running', () => { describe('running', () => {

View File

@@ -30,7 +30,14 @@ const {
hasIssues, hasIssues,
render, render,
} = useCanvasNode(); } = useCanvasNode();
const { mainOutputs, mainInputs, nonMainInputs, requiredNonMainInputs } = useNodeConnections({ const {
mainOutputs,
mainOutputConnections,
mainInputs,
mainInputConnections,
nonMainInputs,
requiredNonMainInputs,
} = useNodeConnections({
inputs, inputs,
outputs, outputs,
connections, connections,
@@ -86,6 +93,15 @@ const dataTestId = computed(() => {
return `canvas-${type}-node`; return `canvas-${type}-node`;
}); });
const isStrikethroughVisible = computed(() => {
const isSingleMainInputNode =
mainInputs.value.length === 1 && mainInputConnections.value.length <= 1;
const isSingleMainOutputNode =
mainOutputs.value.length === 1 && mainOutputConnections.value.length <= 1;
return isDisabled.value && isSingleMainInputNode && isSingleMainOutputNode;
});
function openContextMenu(event: MouseEvent) { function openContextMenu(event: MouseEvent) {
emit('open:contextmenu', event); emit('open:contextmenu', event);
} }
@@ -103,7 +119,7 @@ function openContextMenu(event: MouseEvent) {
</div> </div>
</N8nTooltip> </N8nTooltip>
<CanvasNodeStatusIcons :class="$style.statusIcons" /> <CanvasNodeStatusIcons :class="$style.statusIcons" />
<CanvasNodeDisabledStrikeThrough v-if="isDisabled" /> <CanvasNodeDisabledStrikeThrough v-if="isStrikethroughVisible" />
<div :class="$style.description"> <div :class="$style.description">
<div v-if="label" :class="$style.label"> <div v-if="label" :class="$style.label">
{{ label }} {{ label }}

View File

@@ -1,36 +1,12 @@
import CanvasNodeDisabledStrikeThrough from '@/components/canvas/elements/nodes/render-types/parts/CanvasNodeDisabledStrikeThrough.vue'; import CanvasNodeDisabledStrikeThrough from '@/components/canvas/elements/nodes/render-types/parts/CanvasNodeDisabledStrikeThrough.vue';
import { createComponentRenderer } from '@/__tests__/render'; import { createComponentRenderer } from '@/__tests__/render';
import { NodeConnectionType } from 'n8n-workflow';
import { createCanvasNodeProvide } from '@/__tests__/data';
import { CanvasConnectionMode } from '@/types';
const renderComponent = createComponentRenderer(CanvasNodeDisabledStrikeThrough); const renderComponent = createComponentRenderer(CanvasNodeDisabledStrikeThrough);
describe('CanvasNodeDisabledStrikeThrough', () => { describe('CanvasNodeDisabledStrikeThrough', () => {
it('should render node correctly', () => { it('should render node correctly', () => {
const { container } = renderComponent({ const { container } = renderComponent();
global: {
provide: {
...createCanvasNodeProvide({
data: {
connections: {
[CanvasConnectionMode.Input]: {
[NodeConnectionType.Main]: [
[{ node: 'node', type: NodeConnectionType.Main, index: 0 }],
],
},
[CanvasConnectionMode.Output]: {
[NodeConnectionType.Main]: [
[{ node: 'node', type: NodeConnectionType.Main, index: 0 }],
],
},
},
},
}),
},
},
});
expect(container.firstChild).toBeVisible(); expect(container.firstChild).toHaveClass('disabledStrikeThrough');
}); });
}); });

View File

@@ -1,21 +1,8 @@
<script setup lang="ts"> <script setup lang="ts">
import { computed, useCssModule } from 'vue'; import { computed, useCssModule } from 'vue';
import { useNodeConnections } from '@/composables/useNodeConnections';
import { useCanvasNode } from '@/composables/useCanvasNode';
const $style = useCssModule(); const $style = useCssModule();
const { inputs, outputs, connections } = useCanvasNode();
const { mainInputConnections, mainOutputConnections } = useNodeConnections({
inputs,
outputs,
connections,
});
const isVisible = computed(
() => mainInputConnections.value.length === 1 && mainOutputConnections.value.length === 1,
);
const isSuccessStatus = computed( const isSuccessStatus = computed(
() => false, () => false,
// @TODO Implement this // @TODO Implement this
@@ -31,7 +18,7 @@ const classes = computed(() => {
</script> </script>
<template> <template>
<div v-if="isVisible" :class="classes"></div> <div :class="classes"></div>
</template> </template>
<style lang="scss" module> <style lang="scss" module>