diff --git a/packages/editor-ui/src/components/canvas/elements/nodes/CanvasNode.test.ts b/packages/editor-ui/src/components/canvas/elements/nodes/CanvasNode.test.ts
index 816310ac7d..4ac0c1d247 100644
--- a/packages/editor-ui/src/components/canvas/elements/nodes/CanvasNode.test.ts
+++ b/packages/editor-ui/src/components/canvas/elements/nodes/CanvasNode.test.ts
@@ -3,7 +3,8 @@ import { createComponentRenderer } from '@/__tests__/render';
import { createPinia, setActivePinia } from 'pinia';
import { NodeConnectionType } from 'n8n-workflow';
import { fireEvent } from '@testing-library/vue';
-import { createCanvasNodeProps, createCanvasProvide } from '@/__tests__/data';
+import { createCanvasNodeData, createCanvasNodeProps, createCanvasProvide } from '@/__tests__/data';
+import { CanvasNodeRenderType } from '@/types';
vi.mock('@/stores/nodeTypes.store', () => ({
useNodeTypesStore: vi.fn(() => ({
@@ -150,4 +151,30 @@ describe('CanvasNode', () => {
expect(getByTestId('overflow-node-button')).toBeInTheDocument();
});
});
+
+ describe('execute workflow button', () => {
+ const triggerNodeData = createCanvasNodeData({
+ name: 'foo',
+ render: {
+ type: CanvasNodeRenderType.Default,
+ options: { trigger: true },
+ },
+ });
+
+ it('should render execute workflow button if the node is a trigger node and is not read only', () => {
+ const { queryByTestId } = renderComponent({
+ props: createCanvasNodeProps({ readOnly: false, data: triggerNodeData }),
+ });
+
+ expect(queryByTestId('execute-workflow-button-foo')).toBeInTheDocument();
+ });
+
+ it('should not render execute workflow button if the node is a trigger node and is read only', () => {
+ const { queryByTestId } = renderComponent({
+ props: createCanvasNodeProps({ readOnly: true, data: triggerNodeData }),
+ });
+
+ expect(queryByTestId('execute-workflow-button-foo')).not.toBeInTheDocument();
+ });
+ });
});
diff --git a/packages/editor-ui/src/components/canvas/elements/nodes/CanvasNode.vue b/packages/editor-ui/src/components/canvas/elements/nodes/CanvasNode.vue
index 5b74b5cd7c..3c88db08f0 100644
--- a/packages/editor-ui/src/components/canvas/elements/nodes/CanvasNode.vue
+++ b/packages/editor-ui/src/components/canvas/elements/nodes/CanvasNode.vue
@@ -417,6 +417,7 @@ onBeforeUnmount(() => {
:type="data.type"
:hovered="nearbyHovered"
:disabled="isDisabled"
+ :read-only="readOnly"
:class="$style.trigger"
/>
diff --git a/packages/editor-ui/src/components/canvas/elements/nodes/render-types/parts/CanvasNodeTrigger.vue b/packages/editor-ui/src/components/canvas/elements/nodes/render-types/parts/CanvasNodeTrigger.vue
index 69794dadaa..3a3d0a7057 100644
--- a/packages/editor-ui/src/components/canvas/elements/nodes/render-types/parts/CanvasNodeTrigger.vue
+++ b/packages/editor-ui/src/components/canvas/elements/nodes/render-types/parts/CanvasNodeTrigger.vue
@@ -14,12 +14,14 @@ const {
type,
hovered,
disabled,
+ readOnly,
class: cls,
} = defineProps<{
name: string;
type: string;
hovered?: boolean;
disabled?: boolean;
+ readOnly?: boolean;
class?: string;
}>();
@@ -29,7 +31,7 @@ const style = useCssModule();
const containerClass = computed(() => ({
[cls ?? '']: true,
[style.container]: true,
- [style.interactive]: !disabled,
+ [style.interactive]: !disabled && !readOnly,
[style.hovered]: !!hovered,
[style.variant1]: variant.value === 1,
[style.variant2]: variant.value === 2,
@@ -55,42 +57,44 @@ const testId = computed(() => `execute-workflow-button-${name}`);
- {{ isChatOpen ? i18n.baseText('chat.hide') : i18n.baseText('chat.open') }}
- {{ i18n.baseText('nodeView.runButtonText.executeWorkflow') }}
-
-
+
+ {{ isChatOpen ? i18n.baseText('chat.hide') : i18n.baseText('chat.open') }}
+ {{ i18n.baseText('nodeView.runButtonText.executeWorkflow') }}
+
+
+
@@ -112,7 +116,7 @@ const testId = computed(() => `execute-workflow-button-${name}`);
align-items: center;
}
- &.hovered button {
+ &.interactive.hovered button {
pointer-events: all;
}
}