fix(editor): Add sticky note readonly state in new canvas (#10678)

This commit is contained in:
Alex Grozav 2024-09-05 14:18:13 +03:00 committed by GitHub
parent aa98c18cd7
commit c5bc8e6eb9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 75 additions and 41 deletions

View file

@ -91,21 +91,24 @@ export function createCanvasNodeProvide({
id = 'node', id = 'node',
label = 'Test Node', label = 'Test Node',
selected = false, selected = false,
readOnly = false,
data = {}, data = {},
eventBus = createEventBus<CanvasNodeEventBusEvents>(), eventBus = createEventBus<CanvasNodeEventBusEvents>(),
}: { }: {
id?: string; id?: string;
label?: string; label?: string;
selected?: boolean; selected?: boolean;
readOnly?: boolean;
data?: Partial<CanvasNodeData>; data?: Partial<CanvasNodeData>;
eventBus?: EventBus<CanvasNodeEventBusEvents>; eventBus?: EventBus<CanvasNodeEventBusEvents>;
} = {}) { } = {}) {
const props = createCanvasNodeProps({ id, label, selected, data }); const props = createCanvasNodeProps({ id, label, selected, readOnly, data });
return { return {
[`${CanvasNodeKey}`]: { [`${CanvasNodeKey}`]: {
id: ref(props.id), id: ref(props.id),
label: ref(props.label), label: ref(props.label),
selected: ref(props.selected), selected: ref(props.selected),
readOnly: ref(props.readOnly),
data: ref(props.data), data: ref(props.data),
eventBus: ref(eventBus), eventBus: ref(eventBus),
} satisfies CanvasNodeInjectionData, } satisfies CanvasNodeInjectionData,

View file

@ -219,12 +219,14 @@ const id = toRef(props, 'id');
const data = toRef(props, 'data'); const data = toRef(props, 'data');
const label = toRef(props, 'label'); const label = toRef(props, 'label');
const selected = toRef(props, 'selected'); const selected = toRef(props, 'selected');
const readOnly = toRef(props, 'readOnly');
provide(CanvasNodeKey, { provide(CanvasNodeKey, {
id, id,
data, data,
label, label,
selected, selected,
readOnly,
eventBus: canvasNodeEventBus, eventBus: canvasNodeEventBus,
}); });

View file

@ -93,4 +93,26 @@ describe('CanvasNodeToolbar', () => {
expect(emitted('open:contextmenu')[0]).toEqual([expect.any(MouseEvent)]); expect(emitted('open:contextmenu')[0]).toEqual([expect.any(MouseEvent)]);
}); });
it('should emit "update" when sticky note color is changed', async () => {
const { getAllByTestId, getByTestId, emitted } = renderComponent({
global: {
provide: {
...createCanvasNodeProvide({
data: {
render: {
type: CanvasNodeRenderType.StickyNote,
options: { color: 3 },
},
},
}),
},
},
});
await fireEvent.click(getByTestId('change-sticky-color'));
await fireEvent.click(getAllByTestId('color')[0]);
expect(emitted('update')[0]).toEqual([{ color: 1 }]);
});
}); });

View file

@ -47,7 +47,9 @@ const isDisableNodeVisible = computed(() => {
const isDeleteNodeVisible = computed(() => !props.readOnly); const isDeleteNodeVisible = computed(() => !props.readOnly);
const isStickyNoteNodeType = computed(() => render.value.type === CanvasNodeRenderType.StickyNote); const isStickyNoteChangeColorVisible = computed(
() => !props.readOnly && render.value.type === CanvasNodeRenderType.StickyNote,
);
function executeNode() { function executeNode() {
emit('run'); emit('run');
@ -106,7 +108,10 @@ function onOpenContextMenu(event: MouseEvent) {
:title="i18n.baseText('node.delete')" :title="i18n.baseText('node.delete')"
@click="onDeleteNode" @click="onDeleteNode"
/> />
<CanvasNodeStickyColorSelector v-if="isStickyNoteNodeType" @update="onChangeStickyColor" /> <CanvasNodeStickyColorSelector
v-if="isStickyNoteChangeColorVisible"
@update="onChangeStickyColor"
/>
<N8nIconButton <N8nIconButton
data-test-id="overflow-node-button" data-test-id="overflow-node-button"
type="tertiary" type="tertiary"

View file

@ -13,7 +13,7 @@ beforeEach(() => {
describe('CanvasNodeStickyNote', () => { describe('CanvasNodeStickyNote', () => {
it('should render node correctly', () => { it('should render node correctly', () => {
const { getByTestId } = renderComponent({ const { html } = renderComponent({
global: { global: {
provide: { provide: {
...createCanvasNodeProvide({ ...createCanvasNodeProvide({
@ -23,6 +23,23 @@ describe('CanvasNodeStickyNote', () => {
}, },
}); });
expect(getByTestId('canvas-sticky-note-node')).toMatchSnapshot(); expect(html()).toMatchSnapshot();
});
it('should disable resizing when node is readonly', () => {
const { container } = renderComponent({
global: {
provide: {
...createCanvasNodeProvide({
id: 'sticky',
readOnly: true,
}),
},
},
});
const resizeControls = container.querySelectorAll('.vue-flow__resize-control');
expect(resizeControls).toHaveLength(0);
}); });
}); });

View file

@ -20,7 +20,7 @@ const emit = defineEmits<{
const $style = useCssModule(); const $style = useCssModule();
const { id, isSelected, render, eventBus } = useCanvasNode(); const { id, isSelected, isReadOnly, render, eventBus } = useCanvasNode();
const renderOptions = computed(() => render.value.options as CanvasNodeStickyNoteRender['options']); const renderOptions = computed(() => render.value.options as CanvasNodeStickyNoteRender['options']);
@ -95,6 +95,7 @@ onBeforeUnmount(() => {
:min-width="150" :min-width="150"
:height="renderOptions.height" :height="renderOptions.height"
:width="renderOptions.width" :width="renderOptions.width"
:is-visible="!isReadOnly"
@resize="onResize" @resize="onResize"
/> />
<N8nSticky <N8nSticky

View file

@ -1,45 +1,27 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`CanvasNodeStickyNote > should render node correctly 1`] = ` exports[`CanvasNodeStickyNote > should render node correctly 1`] = `
<div "<div class="vue-flow__resize-control nodrag top line"></div>
class="n8n-sticky sticky clickable color-1 sticky" <div class="vue-flow__resize-control nodrag right line"></div>
data-test-id="canvas-sticky-note-node" <div class="vue-flow__resize-control nodrag bottom line"></div>
style="height: 180px; width: 240px;" <div class="vue-flow__resize-control nodrag left line"></div>
> <div class="vue-flow__resize-control nodrag top left handle"></div>
<div <div class="vue-flow__resize-control nodrag top right handle"></div>
class="wrapper" <div class="vue-flow__resize-control nodrag bottom left handle"></div>
> <div class="vue-flow__resize-control nodrag bottom right handle"></div>
<div <div class="n8n-sticky sticky clickable color-1 sticky" style="height: 180px; width: 240px;" data-test-id="canvas-sticky-note-node">
class="n8n-markdown" <div class="wrapper">
> <div class="n8n-markdown">
<div <div class="sticky"></div>
class="sticky"
/>
</div> </div>
</div> </div>
<div <div class="sticky-textarea" style="display: none;">
class="sticky-textarea" <div class="el-textarea el-input--large n8n-input">
style="display: none;"
>
<div
class="el-textarea el-input--large n8n-input"
>
<!-- input --> <!-- input -->
<!-- textarea --><textarea class="el-textarea__inner" name="sticky-input" rows="5" title="" tabindex="0" autocomplete="off" placeholder=""></textarea>
<!-- textarea -->
<textarea
autocomplete="off"
class="el-textarea__inner"
name="sticky-input"
placeholder=""
rows="5"
tabindex="0"
title=""
/>
<!--v-if--> <!--v-if-->
</div> </div>
</div> </div>
<!--v-if--> <!--v-if-->
</div> </div>"
`; `;

View file

@ -45,7 +45,7 @@ export function useCanvasNode() {
const connections = computed(() => data.value.connections); const connections = computed(() => data.value.connections);
const isDisabled = computed(() => data.value.disabled); const isDisabled = computed(() => data.value.disabled);
const isReadOnly = computed(() => node?.readOnly.value);
const isSelected = computed(() => node?.selected.value); const isSelected = computed(() => node?.selected.value);
const pinnedDataCount = computed(() => data.value.pinnedData.count); const pinnedDataCount = computed(() => data.value.pinnedData.count);
@ -75,6 +75,7 @@ export function useCanvasNode() {
outputs, outputs,
connections, connections,
isDisabled, isDisabled,
isReadOnly,
isSelected, isSelected,
pinnedDataCount, pinnedDataCount,
hasPinnedData, hasPinnedData,

View file

@ -155,6 +155,7 @@ export interface CanvasNodeInjectionData {
data: Ref<CanvasNodeData>; data: Ref<CanvasNodeData>;
label: Ref<NodeProps['label']>; label: Ref<NodeProps['label']>;
selected: Ref<NodeProps['selected']>; selected: Ref<NodeProps['selected']>;
readOnly: Ref<boolean>;
eventBus: Ref<EventBus<CanvasNodeEventBusEvents>>; eventBus: Ref<EventBus<CanvasNodeEventBusEvents>>;
} }