Skip to content

Commit

Permalink
fix(editor): Add missing trigger waiting tooltip on new canvas (#11918)
Browse files Browse the repository at this point in the history
  • Loading branch information
alexgrozav authored Nov 27, 2024
1 parent f91fecf commit a8df221
Show file tree
Hide file tree
Showing 18 changed files with 352 additions and 54 deletions.
7 changes: 7 additions & 0 deletions packages/editor-ui/src/__tests__/data/canvas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { CanvasConnectionMode, CanvasNodeRenderType } from '@/types';
import { NodeConnectionType } from 'n8n-workflow';
import type { EventBus } from 'n8n-design-system';
import { createEventBus } from 'n8n-design-system';
import type { ViewportTransform } from '@vue-flow/core';

export function createCanvasNodeData({
id = 'node',
Expand Down Expand Up @@ -91,16 +92,22 @@ export function createCanvasNodeProps({
}

export function createCanvasProvide({
initialized = true,
isExecuting = false,
connectingHandle = undefined,
viewport = { x: 0, y: 0, zoom: 1 },
}: {
initialized?: boolean;
isExecuting?: boolean;
connectingHandle?: ConnectStartEvent;
viewport?: ViewportTransform;
} = {}) {
return {
[String(CanvasKey)]: {
initialized: ref(initialized),
isExecuting: ref(isExecuting),
connectingHandle: ref(connectingHandle),
viewport: ref(viewport),
} satisfies CanvasInjectionData,
};
}
Expand Down
4 changes: 4 additions & 0 deletions packages/editor-ui/src/__tests__/render.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,10 @@ export function createComponentRenderer(
global: {
...defaultOptions.global,
...options.global,
provide: {
...defaultOptions.global?.provide,
...options.global?.provide,
},
},
},
);
Expand Down
25 changes: 11 additions & 14 deletions packages/editor-ui/src/components/canvas/Canvas.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,7 @@ import type {
CanvasEventBusEvents,
ConnectStartEvent,
} from '@/types';
import type {
Connection,
XYPosition,
ViewportTransform,
NodeDragEvent,
GraphNode,
} from '@vue-flow/core';
import type { Connection, XYPosition, NodeDragEvent, GraphNode } from '@vue-flow/core';
import { useVueFlow, VueFlow, PanelPosition, MarkerType } from '@vue-flow/core';
import { Background } from '@vue-flow/background';
import { MiniMap } from '@vue-flow/minimap';
Expand Down Expand Up @@ -114,6 +108,7 @@ const {
project,
nodes: graphNodes,
onPaneReady,
onNodesInitialized,
findNode,
viewport,
onEdgeMouseLeave,
Expand Down Expand Up @@ -431,7 +426,6 @@ function emitWithLastSelectedNode(emitFn: (id: string) => void) {
*/
const defaultZoom = 1;
const zoom = ref(defaultZoom);
const isPaneMoving = ref(false);
function getProjectedPosition(event?: Pick<MouseEvent, 'clientX' | 'clientY'>) {
Expand Down Expand Up @@ -469,10 +463,6 @@ async function onResetZoom() {
await onZoomTo(defaultZoom);
}
function onViewportChange(viewport: ViewportTransform) {
zoom.value = viewport.zoom;
}
function setReadonly(value: boolean) {
setInteractive(!value);
elementsSelectable.value = true;
Expand Down Expand Up @@ -589,6 +579,8 @@ function onMinimapMouseLeave() {
* Lifecycle
*/
const initialized = ref(false);
onMounted(() => {
props.eventBus.on('fitView', onFitView);
props.eventBus.on('nodes:select', onSelectNodes);
Expand All @@ -604,6 +596,10 @@ onPaneReady(async () => {
isPaneReady.value = true;
});
onNodesInitialized(() => {
initialized.value = true;
});
watch(() => props.readOnly, setReadonly, {
immediate: true,
});
Expand All @@ -617,6 +613,8 @@ const isExecuting = toRef(props, 'executing');
provide(CanvasKey, {
connectingHandle,
isExecuting,
initialized,
viewport,
});
</script>

Expand Down Expand Up @@ -644,7 +642,6 @@ provide(CanvasKey, {
@connect-end="onConnectEnd"
@pane-click="onClickPane"
@contextmenu="onOpenContextMenu"
@viewport-change="onViewportChange"
@move-start="onPaneMoveStart"
@move-end="onPaneMoveEnd"
@node-drag-stop="onNodeDragStop"
Expand Down Expand Up @@ -717,7 +714,7 @@ provide(CanvasKey, {
:position="controlsPosition"
:show-interactive="false"
:show-bug-reporting-button="showBugReportingButton"
:zoom="zoom"
:zoom="viewport.zoom"
@zoom-to-fit="onFitView"
@zoom-in="onZoomIn"
@zoom-out="onZoomOut"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { createTestingPinia } from '@pinia/testing';
import { setActivePinia } from 'pinia';
import type { ConnectionLineProps } from '@vue-flow/core';
import { Position } from '@vue-flow/core';
import { createCanvasProvide } from '@/__tests__/data';

const DEFAULT_PROPS = {
sourceX: 0,
Expand All @@ -15,6 +16,11 @@ const DEFAULT_PROPS = {
} satisfies Partial<ConnectionLineProps>;
const renderComponent = createComponentRenderer(CanvasConnectionLine, {
props: DEFAULT_PROPS,
global: {
provide: {
...createCanvasProvide(),
},
},
});

beforeEach(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { createComponentRenderer } from '@/__tests__/render';
import { createPinia, setActivePinia } from 'pinia';
import { NodeConnectionType } from 'n8n-workflow';
import { fireEvent } from '@testing-library/vue';
import { createCanvasNodeProps } from '@/__tests__/data';
import { createCanvasNodeProps, createCanvasProvide } from '@/__tests__/data';

vi.mock('@/stores/nodeTypes.store', () => ({
useNodeTypesStore: vi.fn(() => ({
Expand All @@ -19,7 +19,14 @@ beforeEach(() => {
const pinia = createPinia();
setActivePinia(pinia);

renderComponent = createComponentRenderer(CanvasNode, { pinia });
renderComponent = createComponentRenderer(CanvasNode, {
pinia,
global: {
provide: {
...createCanvasProvide(),
},
},
});
});

describe('CanvasNode', () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import CanvasNodeRenderer from '@/components/canvas/elements/nodes/CanvasNodeRenderer.vue';
import { createComponentRenderer } from '@/__tests__/render';
import { createCanvasNodeProvide } from '@/__tests__/data';
import { createCanvasNodeProvide, createCanvasProvide } from '@/__tests__/data';
import { createTestingPinia } from '@pinia/testing';
import { setActivePinia } from 'pinia';
import { CanvasNodeRenderType } from '@/types';
Expand All @@ -17,6 +17,7 @@ describe('CanvasNodeRenderer', () => {
const { getByTestId } = renderComponent({
global: {
provide: {
...createCanvasProvide(),
...createCanvasNodeProvide(),
},
},
Expand All @@ -29,6 +30,7 @@ describe('CanvasNodeRenderer', () => {
const { getByTestId } = renderComponent({
global: {
provide: {
...createCanvasProvide(),
...createCanvasNodeProvide({
data: {
render: {
Expand All @@ -48,6 +50,7 @@ describe('CanvasNodeRenderer', () => {
const { getByTestId } = renderComponent({
global: {
provide: {
...createCanvasProvide(),
...createCanvasNodeProvide({
data: {
render: {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
import CanvasNodeDefault from '@/components/canvas/elements/nodes/render-types/CanvasNodeDefault.vue';
import { createComponentRenderer } from '@/__tests__/render';
import { NodeConnectionType } from 'n8n-workflow';
import { createCanvasNodeProvide } from '@/__tests__/data';
import { createCanvasNodeProvide, createCanvasProvide } from '@/__tests__/data';
import { createTestingPinia } from '@pinia/testing';
import { setActivePinia } from 'pinia';
import { CanvasConnectionMode, CanvasNodeRenderType } from '@/types';

const renderComponent = createComponentRenderer(CanvasNodeDefault);
const renderComponent = createComponentRenderer(CanvasNodeDefault, {
global: {
provide: {
...createCanvasProvide(),
},
},
});

beforeEach(() => {
const pinia = createTestingPinia();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
<script lang="ts" setup>
import { computed, useCssModule } from 'vue';
import { computed, ref, useCssModule, watch } from 'vue';
import { useNodeConnections } from '@/composables/useNodeConnections';
import { useI18n } from '@/composables/useI18n';
import CanvasNodeDisabledStrikeThrough from './parts/CanvasNodeDisabledStrikeThrough.vue';
import CanvasNodeStatusIcons from '@/components/canvas/elements/nodes/render-types/parts/CanvasNodeStatusIcons.vue';
import { useCanvasNode } from '@/composables/useCanvasNode';
import { NODE_INSERT_SPACER_BETWEEN_INPUT_GROUPS } from '@/constants';
import { N8nTooltip } from 'n8n-design-system';
import type { CanvasNodeDefaultRender } from '@/types';
import { useCanvas } from '@/composables/useCanvas';
const $style = useCssModule();
const i18n = useI18n();
Expand All @@ -16,6 +14,7 @@ const emit = defineEmits<{
'open:contextmenu': [event: MouseEvent];
}>();
const { initialized, viewport } = useCanvas();
const {
label,
subtitle,
Expand Down Expand Up @@ -105,22 +104,31 @@ const isStrikethroughVisible = computed(() => {
return isDisabled.value && isSingleMainInputNode && isSingleMainOutputNode;
});
const showTooltip = ref(false);
watch(initialized, () => {
if (initialized.value) {
showTooltip.value = true;
}
});
watch(viewport, () => {
showTooltip.value = false;
setTimeout(() => {
showTooltip.value = true;
}, 0);
});
function openContextMenu(event: MouseEvent) {
emit('open:contextmenu', event);
}
</script>

<template>
<div :class="classes" :style="styles" :data-test-id="dataTestId" @contextmenu="openContextMenu">
<CanvasNodeTooltip v-if="renderOptions.tooltip" :visible="showTooltip" />
<slot />
<N8nTooltip v-if="renderOptions.trigger" placement="bottom">
<template #content>
<span v-n8n-html="i18n.baseText('node.thisIsATriggerNode')" />
</template>
<div :class="$style.triggerIcon">
<FontAwesomeIcon icon="bolt" size="lg" />
</div>
</N8nTooltip>
<CanvasNodeTriggerIcon v-if="renderOptions.trigger" />
<CanvasNodeStatusIcons v-if="!isDisabled" :class="$style.statusIcons" />
<CanvasNodeDisabledStrikeThrough v-if="isStrikethroughVisible" />
<div :class="$style.description">
Expand Down Expand Up @@ -152,6 +160,7 @@ function openContextMenu(event: MouseEvent) {
--trigger-node--border-radius: 36px;
--canvas-node--status-icons-offset: var(--spacing-2xs);
position: relative;
height: var(--canvas-node--height);
width: var(--canvas-node--width);
display: flex;
Expand Down Expand Up @@ -298,12 +307,4 @@ function openContextMenu(event: MouseEvent) {
bottom: var(--canvas-node--status-icons-offset);
right: var(--canvas-node--status-icons-offset);
}
.triggerIcon {
position: absolute;
right: 100%;
margin: auto;
color: var(--color-primary);
padding: var(--spacing-2xs);
}
</style>
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ exports[`CanvasNodeDefault > configurable > should render configurable node corr
data-test-id="canvas-configurable-node"
style="--configurable-node--input-count: 0; --canvas-node--main-input-count: 0; --canvas-node--main-output-count: 0;"
>
<!--v-if-->
<!--v-if-->
Expand Down Expand Up @@ -35,6 +36,7 @@ exports[`CanvasNodeDefault > configuration > should render configurable configur
data-test-id="canvas-configurable-node"
style="--configurable-node--input-count: 0; --canvas-node--main-input-count: 0; --canvas-node--main-output-count: 0;"
>
<!--v-if-->
<!--v-if-->
Expand Down Expand Up @@ -64,6 +66,7 @@ exports[`CanvasNodeDefault > configuration > should render configuration node co
data-test-id="canvas-configuration-node"
style="--canvas-node--main-input-count: 0; --canvas-node--main-output-count: 0;"
>
<!--v-if-->
<!--v-if-->
Expand Down Expand Up @@ -93,6 +96,7 @@ exports[`CanvasNodeDefault > should render node correctly 1`] = `
data-test-id="canvas-default-node"
style="--canvas-node--main-input-count: 0; --canvas-node--main-output-count: 0;"
>
<!--v-if-->
<!--v-if-->
Expand Down Expand Up @@ -122,6 +126,7 @@ exports[`CanvasNodeDefault > trigger > should render trigger node correctly 1`]
data-test-id="canvas-trigger-node"
style="--canvas-node--main-input-count: 0; --canvas-node--main-output-count: 0;"
>
<!--v-if-->
Expand Down
Loading

0 comments on commit a8df221

Please sign in to comment.