mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-18 02:21:13 +00:00
feat(editor): Add experimental NDV pane in canvas (no-changelog) (#16419)
This commit is contained in:
@@ -53,7 +53,7 @@ import CanvasBackground from './elements/background/CanvasBackground.vue';
|
||||
import CanvasArrowHeadMarker from './elements/edges/CanvasArrowHeadMarker.vue';
|
||||
import Edge from './elements/edges/CanvasEdge.vue';
|
||||
import Node from './elements/nodes/CanvasNode.vue';
|
||||
import { useViewportAutoAdjust } from '@/components/canvas/composables/useViewportAutoAdjust';
|
||||
import { useViewportAutoAdjust } from './composables/useViewportAutoAdjust';
|
||||
import { isOutsideSelected } from '@/utils/htmlUtils';
|
||||
|
||||
const $style = useCssModule();
|
||||
|
||||
@@ -9,6 +9,8 @@ import { createEventBus } from '@n8n/utils/event-bus';
|
||||
import type { CanvasEventBusEvents } from '@/types';
|
||||
import { useVueFlow } from '@vue-flow/core';
|
||||
import { throttledRef } from '@vueuse/core';
|
||||
import { useSettingsStore } from '@/stores/settings.store';
|
||||
import ExperimentalNodeDetailsDrawer from './components/ExperimentalNodeDetailsDrawer.vue';
|
||||
|
||||
defineOptions({
|
||||
inheritAttrs: false,
|
||||
@@ -34,8 +36,9 @@ const props = withDefaults(
|
||||
);
|
||||
|
||||
const $style = useCssModule();
|
||||
const settingsStore = useSettingsStore();
|
||||
|
||||
const { onNodesInitialized } = useVueFlow({ id: props.id });
|
||||
const { onNodesInitialized, getSelectedNodes } = useVueFlow({ id: props.id });
|
||||
|
||||
const workflow = toRef(props, 'workflow');
|
||||
const workflowObject = toRef(props, 'workflowObject');
|
||||
@@ -79,12 +82,16 @@ const mappedConnectionsThrottled = throttledRef(mappedConnections, 200);
|
||||
/>
|
||||
</div>
|
||||
<slot />
|
||||
<ExperimentalNodeDetailsDrawer
|
||||
v-if="settingsStore.experimental__dockedNodeSettingsEnabled && !props.readOnly"
|
||||
:selected-nodes="getSelectedNodes"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" module>
|
||||
.wrapper {
|
||||
display: block;
|
||||
display: flex;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
@@ -96,5 +103,7 @@ const mappedConnectionsThrottled = throttledRef(mappedConnections, 200);
|
||||
height: 100%;
|
||||
position: relative;
|
||||
display: block;
|
||||
align-items: stretch;
|
||||
justify-content: stretch;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,15 +1,20 @@
|
||||
<script setup lang="ts">
|
||||
import NodeSettings from '@/components/NodeSettings.vue';
|
||||
import { useCanvasOperations } from '@/composables/useCanvasOperations';
|
||||
import { type IUpdateInformation } from '@/Interface';
|
||||
import { useNDVStore } from '@/stores/ndv.store';
|
||||
import { useNodeTypesStore } from '@/stores/nodeTypes.store';
|
||||
import { useWorkflowsStore } from '@/stores/workflows.store';
|
||||
import { createEventBus } from '@n8n/utils/event-bus';
|
||||
import { computed } from 'vue';
|
||||
|
||||
const { nodeId } = defineProps<{ nodeId: string }>();
|
||||
const { nodeId, canOpenNdv } = defineProps<{ nodeId: string; canOpenNdv?: boolean }>();
|
||||
|
||||
const settingsEventBus = createEventBus();
|
||||
const nodeTypesStore = useNodeTypesStore();
|
||||
const workflowsStore = useWorkflowsStore();
|
||||
const { setActiveNodeName } = useNDVStore();
|
||||
const { renameNode } = useCanvasOperations();
|
||||
|
||||
const activeNode = computed(() => workflowsStore.getNodeById(nodeId));
|
||||
const activeNodeType = computed(() => {
|
||||
@@ -18,10 +23,23 @@ const activeNodeType = computed(() => {
|
||||
}
|
||||
return null;
|
||||
});
|
||||
|
||||
function handleOpenNdv() {
|
||||
if (activeNode.value) {
|
||||
setActiveNodeName(activeNode.value.name);
|
||||
}
|
||||
}
|
||||
|
||||
function handleValueChanged(parameterData: IUpdateInformation) {
|
||||
if (parameterData.name === 'name' && parameterData.oldValue) {
|
||||
void renameNode(parameterData.oldValue as string, parameterData.value as string);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<NodeSettings
|
||||
:can-expand="canOpenNdv"
|
||||
:event-bus="settingsEventBus"
|
||||
:dragging="false"
|
||||
:active-node="activeNode"
|
||||
@@ -32,5 +50,8 @@ const activeNodeType = computed(() => {
|
||||
:block-u-i="false"
|
||||
:executable="false"
|
||||
:input-size="0"
|
||||
hide-connections
|
||||
@expand="handleOpenNdv"
|
||||
@value-changed="handleValueChanged"
|
||||
/>
|
||||
</template>
|
||||
@@ -0,0 +1,63 @@
|
||||
<script setup lang="ts">
|
||||
import { type CanvasNode } from '@/types';
|
||||
import ExperimentalCanvasNodeSettings from './ExperimentalCanvasNodeSettings.vue';
|
||||
import { N8nText } from '@n8n/design-system';
|
||||
import { computed, watch, ref } from 'vue';
|
||||
|
||||
const { selectedNodes } = defineProps<{ selectedNodes: CanvasNode[] }>();
|
||||
|
||||
const content = computed(() =>
|
||||
selectedNodes.length > 1
|
||||
? `${selectedNodes.length} nodes selected`
|
||||
: selectedNodes.length > 0
|
||||
? selectedNodes[0]
|
||||
: undefined,
|
||||
);
|
||||
const lastContent = ref<string | CanvasNode | undefined>();
|
||||
|
||||
// Sync lastContent to be "last defined content" (for drawer animation)
|
||||
watch(
|
||||
content,
|
||||
(newContent) => {
|
||||
if (newContent !== undefined) {
|
||||
lastContent.value = newContent;
|
||||
}
|
||||
},
|
||||
{ immediate: true },
|
||||
);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div :class="[$style.component, content === undefined ? $style.closed : '']">
|
||||
<N8nText v-if="typeof lastContent === 'string'" color="text-base">
|
||||
{{ lastContent }}
|
||||
</N8nText>
|
||||
<ExperimentalCanvasNodeSettings
|
||||
v-else-if="lastContent !== undefined"
|
||||
:node-id="lastContent.id"
|
||||
can-open-ndv
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" module>
|
||||
.component {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
z-index: 10;
|
||||
flex-grow: 0;
|
||||
flex-shrink: 0;
|
||||
border-left: var(--border-base);
|
||||
background-color: var(--color-background-xlight);
|
||||
width: #{$node-creator-width};
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: transform 0.2s ease;
|
||||
|
||||
&.closed {
|
||||
transform: translateX(100%);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -7,7 +7,7 @@ import { NODE_INSERT_SPACER_BETWEEN_INPUT_GROUPS } from '@/constants';
|
||||
import type { CanvasNodeDefaultRender } from '@/types';
|
||||
import { useCanvas } from '@/composables/useCanvas';
|
||||
import { useNodeSettingsInCanvas } from '@/components/canvas/composables/useNodeSettingsInCanvas';
|
||||
import CanvasNodeNodeSettings from './parts/CanvasNodeNodeSettings.vue';
|
||||
import ExperimentalCanvasNodeSettings from '../../../components/ExperimentalCanvasNodeSettings.vue';
|
||||
|
||||
const $style = useCssModule();
|
||||
const i18n = useI18n();
|
||||
@@ -153,7 +153,7 @@ function onActivate(event: MouseEvent) {
|
||||
@contextmenu="openContextMenu"
|
||||
@dblclick.stop="onActivate"
|
||||
>
|
||||
<CanvasNodeNodeSettings v-if="nodeSettingsZoom !== undefined" :node-id="id" />
|
||||
<ExperimentalCanvasNodeSettings v-if="nodeSettingsZoom !== undefined" :node-id="id" />
|
||||
<template v-else>
|
||||
<CanvasNodeTooltip v-if="renderOptions.tooltip" :visible="showTooltip" />
|
||||
<NodeIcon :icon-source="iconSource" :size="iconSize" :shrink="false" :disabled="isDisabled" />
|
||||
|
||||
Reference in New Issue
Block a user