fix(editor): Fix sticky color picker getting covered by nodes on new canvas (#12263)

This commit is contained in:
Alex Grozav 2024-12-17 15:48:35 +02:00 committed by GitHub
parent 9d50dade3d
commit 27bd3c85b3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 71 additions and 13 deletions

View file

@ -310,7 +310,6 @@ onBeforeUnmount(() => {
<CanvasNodeToolbar
v-if="nodeTypeDescription"
data-test-id="canvas-node-toolbar"
:read-only="readOnly"
:class="$style.canvasNodeToolbar"
@delete="onDelete"

View file

@ -1,4 +1,4 @@
import { fireEvent } from '@testing-library/vue';
import { fireEvent, waitFor } from '@testing-library/vue';
import CanvasNodeToolbar from '@/components/canvas/elements/nodes/CanvasNodeToolbar.vue';
import { createComponentRenderer } from '@/__tests__/render';
import { createCanvasNodeProvide, createCanvasProvide } from '@/__tests__/data';
@ -137,4 +137,45 @@ describe('CanvasNodeToolbar', () => {
expect(emitted('update')[0]).toEqual([{ color: 1 }]);
});
it('should have "forceVisible" class when hovered', async () => {
const { getByTestId } = renderComponent({
global: {
provide: {
...createCanvasNodeProvide(),
...createCanvasProvide(),
},
},
});
const toolbar = getByTestId('canvas-node-toolbar');
await fireEvent.mouseEnter(toolbar);
expect(toolbar).toHaveClass('forceVisible');
});
it('should have "forceVisible" class when sticky color picker is visible', async () => {
const { getByTestId } = renderComponent({
global: {
provide: {
...createCanvasNodeProvide({
data: {
render: {
type: CanvasNodeRenderType.StickyNote,
options: { color: 3 },
},
},
}),
...createCanvasProvide(),
},
},
});
const toolbar = getByTestId('canvas-node-toolbar');
await fireEvent.click(getByTestId('change-sticky-color'));
await waitFor(() => expect(toolbar).toHaveClass('forceVisible'));
});
});

View file

@ -1,5 +1,5 @@
<script setup lang="ts">
import { computed, useCssModule } from 'vue';
import { computed, ref, useCssModule } from 'vue';
import { useI18n } from '@/composables/useI18n';
import { useCanvasNode } from '@/composables/useCanvasNode';
import { CanvasNodeRenderType } from '@/types';
@ -27,9 +27,13 @@ const nodeDisabledTitle = computed(() => {
return isDisabled.value ? i18n.baseText('node.disable') : i18n.baseText('node.enable');
});
const isStickyColorSelectorOpen = ref(false);
const isHovered = ref(false);
const classes = computed(() => ({
[$style.canvasNodeToolbar]: true,
[$style.readOnly]: props.readOnly,
[$style.forceVisible]: isHovered.value || isStickyColorSelectorOpen.value,
}));
const isExecuteNodeVisible = computed(() => {
@ -72,10 +76,23 @@ function onChangeStickyColor(color: number) {
function onOpenContextMenu(event: MouseEvent) {
emit('open:contextmenu', event);
}
function onMouseEnter() {
isHovered.value = true;
}
function onMouseLeave() {
isHovered.value = false;
}
</script>
<template>
<div :class="classes">
<div
data-test-id="canvas-node-toolbar"
:class="classes"
@mouseenter="onMouseEnter"
@mouseleave="onMouseLeave"
>
<div :class="$style.canvasNodeToolbarItems">
<N8nIconButton
v-if="isExecuteNodeVisible"
@ -110,6 +127,7 @@ function onOpenContextMenu(event: MouseEvent) {
/>
<CanvasNodeStickyColorSelector
v-if="isStickyNoteChangeColorVisible"
v-model:visible="isStickyColorSelectorOpen"
@update="onChangeStickyColor"
/>
<N8nIconButton
@ -143,4 +161,8 @@ function onOpenContextMenu(event: MouseEvent) {
--button-font-color: var(--color-text-light);
}
}
.forceVisible {
opacity: 1 !important;
}
</style>

View file

@ -14,13 +14,10 @@ const { render, eventBus } = useCanvasNode();
const renderOptions = computed(() => render.value.options as CanvasNodeStickyNoteRender['options']);
const autoHideTimeout = ref<NodeJS.Timeout | null>(null);
const isPopoverVisible = ref(false);
const colors = computed(() => Array.from({ length: 7 }).map((_, index) => index + 1));
function togglePopover() {
isPopoverVisible.value = !isPopoverVisible.value;
}
const isPopoverVisible = defineModel<boolean>('visible');
function hidePopover() {
isPopoverVisible.value = false;
@ -59,22 +56,21 @@ onBeforeUnmount(() => {
<template>
<N8nPopover
v-model:visible="isPopoverVisible"
effect="dark"
trigger="click"
placement="top"
:popper-class="$style.popover"
:popper-style="{ width: '208px' }"
:visible="isPopoverVisible"
:teleported="false"
@mouseenter="onMouseEnter"
@mouseleave="onMouseLeave"
:teleported="true"
@before-enter="onMouseEnter"
@after-leave="onMouseLeave"
>
<template #reference>
<div
:class="$style.option"
data-test-id="change-sticky-color"
:title="i18n.baseText('node.changeColor')"
@click.stop="togglePopover"
>
<FontAwesomeIcon icon="palette" />
</div>