mirror of
https://github.com/n8n-io/n8n.git
synced 2025-02-21 02:56:40 -08:00
fix(editor): Don't show 'Test workflow' button if the canvas is read-only (#13199)
This commit is contained in:
parent
77be25d337
commit
56426e989f
|
@ -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();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -417,6 +417,7 @@ onBeforeUnmount(() => {
|
|||
:type="data.type"
|
||||
:hovered="nearbyHovered"
|
||||
:disabled="isDisabled"
|
||||
:read-only="readOnly"
|
||||
:class="$style.trigger"
|
||||
/>
|
||||
</div>
|
||||
|
|
|
@ -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}`);
|
|||
<FontAwesomeIcon icon="bolt" size="lg" />
|
||||
</div>
|
||||
|
||||
<N8nButton
|
||||
v-if="variant === 1 && type === CHAT_TRIGGER_NODE_TYPE"
|
||||
type="secondary"
|
||||
size="large"
|
||||
:disabled="isExecuting"
|
||||
:data-test-id="testId"
|
||||
@click.capture="toggleChatOpen('node')"
|
||||
>{{ isChatOpen ? i18n.baseText('chat.hide') : i18n.baseText('chat.open') }}</N8nButton
|
||||
>
|
||||
<N8nButton
|
||||
v-else-if="variant === 1"
|
||||
type="secondary"
|
||||
size="large"
|
||||
:disabled="isExecuting"
|
||||
:data-test-id="testId"
|
||||
@click.capture="runEntireWorkflow('node', name)"
|
||||
>{{ i18n.baseText('nodeView.runButtonText.executeWorkflow') }}</N8nButton
|
||||
>
|
||||
<N8nButton
|
||||
v-else-if="variant === 2 && type === CHAT_TRIGGER_NODE_TYPE"
|
||||
:type="isChatOpen ? 'secondary' : 'primary'"
|
||||
size="large"
|
||||
:disabled="isExecuting"
|
||||
:data-test-id="testId"
|
||||
:label="isChatOpen ? i18n.baseText('chat.hide') : i18n.baseText('chat.open')"
|
||||
@click.capture="toggleChatOpen('node')"
|
||||
/>
|
||||
<N8nButton
|
||||
v-else
|
||||
type="primary"
|
||||
size="large"
|
||||
:disabled="isExecuting"
|
||||
:data-test-id="testId"
|
||||
:label="i18n.baseText('nodeView.runButtonText.executeWorkflow')"
|
||||
@click.capture="runEntireWorkflow('node', name)"
|
||||
/>
|
||||
<template v-if="!readOnly">
|
||||
<N8nButton
|
||||
v-if="variant === 1 && type === CHAT_TRIGGER_NODE_TYPE"
|
||||
type="secondary"
|
||||
size="large"
|
||||
:disabled="isExecuting"
|
||||
:data-test-id="testId"
|
||||
@click.capture="toggleChatOpen('node')"
|
||||
>{{ isChatOpen ? i18n.baseText('chat.hide') : i18n.baseText('chat.open') }}</N8nButton
|
||||
>
|
||||
<N8nButton
|
||||
v-else-if="variant === 1"
|
||||
type="secondary"
|
||||
size="large"
|
||||
:disabled="isExecuting"
|
||||
:data-test-id="testId"
|
||||
@click.capture="runEntireWorkflow('node', name)"
|
||||
>{{ i18n.baseText('nodeView.runButtonText.executeWorkflow') }}</N8nButton
|
||||
>
|
||||
<N8nButton
|
||||
v-else-if="variant === 2 && type === CHAT_TRIGGER_NODE_TYPE"
|
||||
:type="isChatOpen ? 'secondary' : 'primary'"
|
||||
size="large"
|
||||
:disabled="isExecuting"
|
||||
:data-test-id="testId"
|
||||
:label="isChatOpen ? i18n.baseText('chat.hide') : i18n.baseText('chat.open')"
|
||||
@click.capture="toggleChatOpen('node')"
|
||||
/>
|
||||
<N8nButton
|
||||
v-else
|
||||
type="primary"
|
||||
size="large"
|
||||
:disabled="isExecuting"
|
||||
:data-test-id="testId"
|
||||
:label="i18n.baseText('nodeView.runButtonText.executeWorkflow')"
|
||||
@click.capture="runEntireWorkflow('node', name)"
|
||||
/>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -112,7 +116,7 @@ const testId = computed(() => `execute-workflow-button-${name}`);
|
|||
align-items: center;
|
||||
}
|
||||
|
||||
&.hovered button {
|
||||
&.interactive.hovered button {
|
||||
pointer-events: all;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue