refactor(editor): Move editor-ui and design-system to frontend dir (no-changelog) (#13564)

This commit is contained in:
Alex Grozav
2025-02-28 14:28:30 +02:00
committed by GitHub
parent 684353436d
commit f5743176e5
1635 changed files with 805 additions and 1079 deletions

View File

@@ -0,0 +1,177 @@
<script setup lang="ts">
/* eslint-disable vue/no-multiple-template-root */
import { defineAsyncComponent, onBeforeUnmount, onMounted, ref } from 'vue';
import { getMidCanvasPosition } from '@/utils/nodeViewUtils';
import {
DEFAULT_STICKY_HEIGHT,
DEFAULT_STICKY_WIDTH,
NODE_CREATOR_OPEN_SOURCES,
STICKY_NODE_TYPE,
} from '@/constants';
import { useUIStore } from '@/stores/ui.store';
import type { AddedNodesAndConnections, ToggleNodeCreatorOptions } from '@/Interface';
import { useActions } from './NodeCreator/composables/useActions';
import { useThrottleFn } from '@vueuse/core';
import KeyboardShortcutTooltip from '@/components/KeyboardShortcutTooltip.vue';
import { useI18n } from '@/composables/useI18n';
type Props = {
nodeViewScale: number;
createNodeActive?: boolean;
};
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const LazyNodeCreator = defineAsyncComponent(
async () => await import('@/components/Node/NodeCreator/NodeCreator.vue'),
);
const props = withDefaults(defineProps<Props>(), {
createNodeActive: false, // Determines if the node creator is open
});
const emit = defineEmits<{
addNodes: [value: AddedNodesAndConnections];
toggleNodeCreator: [value: ToggleNodeCreatorOptions];
}>();
const uiStore = useUIStore();
const i18n = useI18n();
const { getAddedNodesAndConnections } = useActions();
const wrapperRef = ref<HTMLElement | undefined>();
const wrapperBoundingRect = ref<DOMRect | undefined>();
const isStickyNotesButtonVisible = ref(true);
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() {
emit('toggleNodeCreator', {
source: NODE_CREATOR_OPEN_SOURCES.ADD_NODE_BUTTON,
createNodeActive: true,
});
}
function addStickyNote() {
if (document.activeElement) {
(document.activeElement as HTMLElement).blur();
}
const offset: [number, number] = [...uiStore.nodeViewOffsetPosition];
const position = getMidCanvasPosition(props.nodeViewScale, offset);
position[0] -= DEFAULT_STICKY_WIDTH / 2;
position[1] -= DEFAULT_STICKY_HEIGHT / 2;
emit('addNodes', getAddedNodesAndConnections([{ type: STICKY_NODE_TYPE, position }]));
}
function closeNodeCreator(hasAddedNodes = false) {
if (props.createNodeActive) {
emit('toggleNodeCreator', { createNodeActive: false, hasAddedNodes });
}
}
function nodeTypeSelected(nodeTypes: string[]) {
emit('addNodes', getAddedNodesAndConnections(nodeTypes.map((type) => ({ type }))));
closeNodeCreator(true);
}
onMounted(() => {
wrapperBoundingRect.value = wrapperRef.value?.getBoundingClientRect();
document.addEventListener('mousemove', onMouseMove);
});
onBeforeUnmount(() => {
document.removeEventListener('mousemove', onMouseMove);
});
</script>
<template>
<div v-if="!createNodeActive" :class="$style.nodeButtonsWrapper">
<div :class="$style.nodeCreatorButton" ref="wrapperRef" data-test-id="node-creator-plus-button">
<KeyboardShortcutTooltip
:label="i18n.baseText('nodeView.openNodesPanel')"
:shortcut="{ keys: ['Tab'] }"
placement="left"
>
<n8n-icon-button
size="large"
icon="plus"
type="tertiary"
:class="$style.nodeCreatorPlus"
@click="openNodeCreator"
/>
</KeyboardShortcutTooltip>
<div
:class="[$style.addStickyButton, isStickyNotesButtonVisible ? $style.visibleButton : '']"
data-test-id="add-sticky-button"
@click="addStickyNote"
>
<KeyboardShortcutTooltip
:label="i18n.baseText('nodeView.addStickyHint')"
:shortcut="{ keys: ['s'], shiftKey: true }"
placement="left"
>
<n8n-icon-button type="tertiary" :icon="['far', 'note-sticky']" />
</KeyboardShortcutTooltip>
</div>
</div>
</div>
<Suspense>
<LazyNodeCreator
:active="createNodeActive"
@node-type-selected="nodeTypeSelected"
@close-node-creator="closeNodeCreator"
/>
</Suspense>
</template>
<style lang="scss" module>
.nodeButtonsWrapper {
position: absolute;
top: 0;
right: 0;
display: flex;
}
.addStickyButton {
margin-top: var(--spacing-2xs);
opacity: 0;
transition: 0.1s;
transition-timing-function: linear;
}
.visibleButton {
opacity: 1;
pointer-events: all;
}
.noEvents {
pointer-events: none;
}
.nodeCreatorButton {
position: absolute;
text-align: center;
top: var(--spacing-s);
right: var(--spacing-s);
pointer-events: all !important;
}
.nodeCreatorPlus {
width: 36px;
height: 36px;
}
</style>