feat(editor): Improve style of Canvas action buttons (#16724)

This commit is contained in:
Daria
2025-06-26 15:36:19 +03:00
committed by GitHub
parent 3af7efaffb
commit 4d211a0794
3 changed files with 42 additions and 94 deletions

View File

@@ -12,7 +12,7 @@ describe('Canvas Actions', () => {
}); });
it('adds sticky to canvas with default text and position', () => { it('adds sticky to canvas with default text and position', () => {
workflowPage.getters.addStickyButton().should('not.be.visible'); workflowPage.getters.addStickyButton().should('be.visible');
addDefaultSticky(); addDefaultSticky();
workflowPage.actions.deselectAll(); workflowPage.actions.deselectAll();

View File

@@ -437,7 +437,6 @@ export class WorkflowPage extends BasePage {
.click({ force: true }); .click({ force: true });
}, },
addSticky: () => { addSticky: () => {
this.getters.nodeCreatorPlusButton().realHover();
this.getters.addStickyButton().click(); this.getters.addStickyButton().click();
}, },
deleteSticky: () => { deleteSticky: () => {

View File

@@ -1,6 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
/* eslint-disable vue/no-multiple-template-root */ /* eslint-disable vue/no-multiple-template-root */
import { computed, defineAsyncComponent, onBeforeUnmount, onMounted, ref } from 'vue'; import { computed, defineAsyncComponent } from 'vue';
import { getMidCanvasPosition } from '@/utils/nodeViewUtils'; import { getMidCanvasPosition } from '@/utils/nodeViewUtils';
import { import {
DEFAULT_STICKY_HEIGHT, DEFAULT_STICKY_HEIGHT,
@@ -18,7 +18,6 @@ import type {
ToggleNodeCreatorOptions, ToggleNodeCreatorOptions,
} from '@/Interface'; } from '@/Interface';
import { useActions } from './NodeCreator/composables/useActions'; import { useActions } from './NodeCreator/composables/useActions';
import { useThrottleFn } from '@vueuse/core';
import KeyboardShortcutTooltip from '@/components/KeyboardShortcutTooltip.vue'; import KeyboardShortcutTooltip from '@/components/KeyboardShortcutTooltip.vue';
import { useI18n } from '@n8n/i18n'; import { useI18n } from '@n8n/i18n';
@@ -48,26 +47,10 @@ const i18n = useI18n();
const { getAddedNodesAndConnections } = useActions(); const { getAddedNodesAndConnections } = useActions();
const wrapperRef = ref<HTMLElement | undefined>();
const wrapperBoundingRect = ref<DOMRect | undefined>();
const isStickyNotesButtonVisible = ref(true);
const isOpenFocusPanelButtonVisible = computed(() => { const isOpenFocusPanelButtonVisible = computed(() => {
return posthogStore.getVariant(FOCUS_PANEL_EXPERIMENT.name) === FOCUS_PANEL_EXPERIMENT.variant; return posthogStore.getVariant(FOCUS_PANEL_EXPERIMENT.name) === FOCUS_PANEL_EXPERIMENT.variant;
}); });
const onMouseMove = useThrottleFn((event: MouseEvent) => {
if (wrapperBoundingRect.value) {
const offset = 100;
isStickyNotesButtonVisible.value =
event.clientX >= wrapperBoundingRect.value.left - offset &&
event.clientX <= wrapperBoundingRect.value.right + offset &&
event.clientY >= wrapperBoundingRect.value.top - offset &&
event.clientY <= wrapperBoundingRect.value.bottom + offset;
} else {
isStickyNotesButtonVisible.value = true;
}
}, 250);
function openNodeCreator() { function openNodeCreator() {
emit('toggleNodeCreator', { emit('toggleNodeCreator', {
source: NODE_CREATOR_OPEN_SOURCES.ADD_NODE_BUTTON, source: NODE_CREATOR_OPEN_SOURCES.ADD_NODE_BUTTON,
@@ -99,27 +82,10 @@ function nodeTypeSelected(value: NodeTypeSelectedPayload[]) {
emit('addNodes', getAddedNodesAndConnections(value)); emit('addNodes', getAddedNodesAndConnections(value));
closeNodeCreator(true); closeNodeCreator(true);
} }
function setWrapperRect() {
wrapperBoundingRect.value = wrapperRef.value?.getBoundingClientRect();
}
onMounted(() => {
setWrapperRect();
document.addEventListener('mousemove', onMouseMove);
window.addEventListener('resize', setWrapperRect);
});
onBeforeUnmount(() => {
document.removeEventListener('mousemove', onMouseMove);
window.removeEventListener('resize', setWrapperRect);
});
</script> </script>
<template> <template>
<div v-if="!createNodeActive" :class="$style.nodeButtonsWrapper"> <div v-if="!createNodeActive" :class="$style.nodeButtonsWrapper">
<div ref="wrapperRef" :class="$style.nodeCreatorButton">
<KeyboardShortcutTooltip <KeyboardShortcutTooltip
:label="i18n.baseText('nodeView.openNodesPanel')" :label="i18n.baseText('nodeView.openNodesPanel')"
:shortcut="{ keys: ['Tab'] }" :shortcut="{ keys: ['Tab'] }"
@@ -133,19 +99,19 @@ onBeforeUnmount(() => {
@click="openNodeCreator" @click="openNodeCreator"
/> />
</KeyboardShortcutTooltip> </KeyboardShortcutTooltip>
<div
:class="[$style.addStickyButton, isStickyNotesButtonVisible ? $style.visibleButton : '']"
data-test-id="add-sticky-button"
@click="addStickyNote"
>
<KeyboardShortcutTooltip <KeyboardShortcutTooltip
:label="i18n.baseText('nodeView.addStickyHint')" :label="i18n.baseText('nodeView.addStickyHint')"
:shortcut="{ keys: ['s'], shiftKey: true }" :shortcut="{ keys: ['s'], shiftKey: true }"
placement="left" placement="left"
> >
<n8n-icon-button type="tertiary" :icon="['far', 'note-sticky']" /> <n8n-icon-button
size="large"
type="tertiary"
:icon="['far', 'note-sticky']"
data-test-id="add-sticky-button"
@click="addStickyNote"
/>
</KeyboardShortcutTooltip> </KeyboardShortcutTooltip>
</div>
<KeyboardShortcutTooltip <KeyboardShortcutTooltip
v-if="isOpenFocusPanelButtonVisible" v-if="isOpenFocusPanelButtonVisible"
:label="i18n.baseText('nodeView.openFocusPanel')" :label="i18n.baseText('nodeView.openFocusPanel')"
@@ -160,7 +126,6 @@ onBeforeUnmount(() => {
/> />
</KeyboardShortcutTooltip> </KeyboardShortcutTooltip>
</div> </div>
</div>
<Suspense> <Suspense>
<LazyNodeCreator <LazyNodeCreator
:active="createNodeActive" :active="createNodeActive"
@@ -176,25 +141,9 @@ onBeforeUnmount(() => {
top: 0; top: 0;
right: 0; right: 0;
display: flex; display: flex;
} flex-direction: column;
gap: var(--spacing-2xs);
.addStickyButton { padding: var(--spacing-s);
margin-top: var(--spacing-2xs);
opacity: 0;
transition: 0.1s;
transition-timing-function: linear;
}
.visibleButton {
opacity: 1;
pointer-events: all;
}
.nodeCreatorButton {
position: absolute;
text-align: center;
top: var(--spacing-s);
right: var(--spacing-s);
pointer-events: all !important; pointer-events: all !important;
} }
</style> </style>