diff --git a/packages/frontend/editor-ui/src/components/ExpressionParameterInput.vue b/packages/frontend/editor-ui/src/components/ExpressionParameterInput.vue index 7eddb7bbba..a9768c3ed9 100644 --- a/packages/frontend/editor-ui/src/components/ExpressionParameterInput.vue +++ b/packages/frontend/editor-ui/src/components/ExpressionParameterInput.vue @@ -16,7 +16,8 @@ import { startCompletion } from '@codemirror/autocomplete'; import type { EditorState, SelectionRange } from '@codemirror/state'; import type { IDataObject } from 'n8n-workflow'; import { createEventBus, type EventBus } from '@n8n/utils/event-bus'; -import { CanvasKey, ExpressionLocalResolveContextSymbol } from '@/constants'; +import { CanvasKey } from '@/constants'; +import { useIsInExperimentalNdv } from '@/components/canvas/experimental/composables/useIsInExperimentalNdv'; const isFocused = ref(false); const segments = ref([]); @@ -56,8 +57,7 @@ const ndvStore = useNDVStore(); const workflowsStore = useWorkflowsStore(); const canvas = inject(CanvasKey, undefined); -const expressionLocalResolveCtx = inject(ExpressionLocalResolveContextSymbol, undefined); -const isInExperimentalNdv = computed(() => expressionLocalResolveCtx?.value !== undefined); +const isInExperimentalNdv = useIsInExperimentalNdv(); const isDragging = computed(() => ndvStore.isDraggableDragging); const isOutputPopoverVisible = computed( @@ -236,7 +236,7 @@ defineExpose({ focus, select }); :segments="segments" :is-read-only="isReadOnly" :virtual-ref="container" - :append-to="isInExperimentalNdv ? '#canvas' : undefined" + :append-to="isInExperimentalNdv ? 'body' : undefined" /> diff --git a/packages/frontend/editor-ui/src/components/FocusPanel.vue b/packages/frontend/editor-ui/src/components/FocusPanel.vue index b2832d8b0d..b16e04d82b 100644 --- a/packages/frontend/editor-ui/src/components/FocusPanel.vue +++ b/packages/frontend/editor-ui/src/components/FocusPanel.vue @@ -26,12 +26,16 @@ import { import { useEnvironmentsStore } from '@/stores/environments.ee.store'; import { htmlEditorEventBus } from '@/event-bus'; import { hasFocusOnInput, isFocusableEl } from '@/utils/typesUtils'; -import type { ResizeData, TargetNodeParameterContext } from '@/Interface'; +import type { INodeUi, ResizeData, TargetNodeParameterContext } from '@/Interface'; import { useTelemetry } from '@/composables/useTelemetry'; import { useThrottleFn } from '@vueuse/core'; -import { useStyles } from '@/composables/useStyles'; import { useExecutionData } from '@/composables/useExecutionData'; import { useWorkflowsStore } from '@/stores/workflows.store'; +import ExperimentalNodeDetailsDrawer from '@/components/canvas/experimental/components/ExperimentalNodeDetailsDrawer.vue'; +import { useExperimentalNdvStore } from '@/components/canvas/experimental/experimentalNdv.store'; +import { useNDVStore } from '@/stores/ndv.store'; +import { useVueFlow } from '@vue-flow/core'; +import ExperimentalFocusPanelHeader from '@/components/canvas/experimental/components/ExperimentalFocusPanelHeader.vue'; defineOptions({ name: 'FocusPanel' }); @@ -56,8 +60,10 @@ const nodeTypesStore = useNodeTypesStore(); const telemetry = useTelemetry(); const nodeSettingsParameters = useNodeSettingsParameters(); const environmentsStore = useEnvironmentsStore(); +const experimentalNdvStore = useExperimentalNdvStore(); +const ndvStore = useNDVStore(); const deviceSupport = useDeviceSupport(); -const styles = useStyles(); +const vueFlow = useVueFlow(workflowsStore.workflowId); const focusedNodeParameter = computed(() => focusPanelStore.focusedNodeParameters[0]); const resolvedParameter = computed(() => @@ -99,23 +105,28 @@ const isDisplayed = computed(() => { ); }); +const node = computed(() => { + if (!experimentalNdvStore.isNdvInFocusPanelEnabled || resolvedParameter.value) { + return resolvedParameter.value?.node; + } + + const selected = vueFlow.getSelectedNodes.value[0]?.id; + + return selected ? workflowsStore.allNodes.find((n) => n.id === selected) : undefined; +}); +const multipleNodesSelected = computed(() => vueFlow.getSelectedNodes.value.length > 1); + const isExecutable = computed(() => { - if (!resolvedParameter.value) return false; + if (!node.value) return false; if (!isDisplayed.value) return false; const foreignCredentials = nodeHelpers.getForeignCredentialsIfSharingEnabled( - resolvedParameter.value.node.credentials, - ); - return nodeHelpers.isNodeExecutable( - resolvedParameter.value.node, - !props.isCanvasReadOnly, - foreignCredentials, + node.value.credentials, ); + return nodeHelpers.isNodeExecutable(node.value, !props.isCanvasReadOnly, foreignCredentials); }); -const node = computed(() => resolvedParameter.value?.node); - const { workflowRunData } = useExecutionData({ node }); const hasNodeRun = computed(() => { @@ -275,6 +286,11 @@ function optionSelected(command: string) { } function closeFocusPanel() { + if (experimentalNdvStore.isNdvInFocusPanelEnabled && resolvedParameter.value) { + focusPanelStore.unsetParameters(); + return; + } + telemetry.track('User closed focus panel', { source: 'closeIcon', parameters: focusPanelStore.focusedNodeParametersInTelemetryFormat, @@ -354,6 +370,12 @@ function onResize(event: ResizeData) { } const onResizeThrottle = useThrottleFn(onResize, 10); + +function onOpenNdv() { + if (node.value) { + ndvStore.setActiveNodeName(node.value.name); + } +} -
+
@@ -792,7 +792,7 @@ function handleSelectAction(params: INodeParameters) {
!props.parameter.noDataExpression && props.showExpressionSelector && !props.isReadOnly, ); +const isInEmbeddedNdv = useIsInExperimentalNdv(); const canBeOpenedInFocusPanel = computed( () => !props.parameter.isNodeSetting && !props.isReadOnly && !props.isContentOverridden && - activeNode.value && // checking that it's inside ndv + (activeNode.value || isInEmbeddedNdv.value) && // checking that it's inside ndv (props.parameter.type === 'string' || props.parameter.type === 'json'), ); diff --git a/packages/frontend/editor-ui/src/components/canvas/Canvas.vue b/packages/frontend/editor-ui/src/components/canvas/Canvas.vue index 441f03ab7a..772845c0f5 100644 --- a/packages/frontend/editor-ui/src/components/canvas/Canvas.vue +++ b/packages/frontend/editor-ui/src/components/canvas/Canvas.vue @@ -922,7 +922,7 @@ provide(CanvasKey, { snap-to-grid :snap-grid="[GRID_SIZE, GRID_SIZE]" :min-zoom="0" - :max-zoom="experimentalNdvStore.isEnabled ? experimentalNdvStore.maxCanvasZoom : 4" + :max-zoom="experimentalNdvStore.isZoomedViewEnabled ? experimentalNdvStore.maxCanvasZoom : 4" :selection-key-code="selectionKeyCode" :zoom-activation-key-code="panningKeyCode" :pan-activation-key-code="panningKeyCode" diff --git a/packages/frontend/editor-ui/src/components/canvas/WorkflowCanvas.vue b/packages/frontend/editor-ui/src/components/canvas/WorkflowCanvas.vue index 699ae67945..3383b84160 100644 --- a/packages/frontend/editor-ui/src/components/canvas/WorkflowCanvas.vue +++ b/packages/frontend/editor-ui/src/components/canvas/WorkflowCanvas.vue @@ -9,8 +9,6 @@ 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 './experimental/components/ExperimentalNodeDetailsDrawer.vue'; defineOptions({ inheritAttrs: false, @@ -36,9 +34,8 @@ const props = withDefaults( ); const $style = useCssModule(); -const settingsStore = useSettingsStore(); -const { onNodesInitialized, getSelectedNodes } = useVueFlow(props.id); +const { onNodesInitialized } = useVueFlow(props.id); const workflow = toRef(props, 'workflow'); const workflowObject = toRef(props, 'workflowObject'); @@ -83,10 +80,6 @@ const mappedConnectionsThrottled = throttledRef(mappedConnections, 200); />
- diff --git a/packages/frontend/editor-ui/src/components/canvas/elements/buttons/CanvasControlButtons.vue b/packages/frontend/editor-ui/src/components/canvas/elements/buttons/CanvasControlButtons.vue index ada1fb3a5d..487a3de56a 100644 --- a/packages/frontend/editor-ui/src/components/canvas/elements/buttons/CanvasControlButtons.vue +++ b/packages/frontend/editor-ui/src/components/canvas/elements/buttons/CanvasControlButtons.vue @@ -33,7 +33,7 @@ const experimentalNdvStore = useExperimentalNdvStore(); const isExperimentalNdvActive = computed(() => experimentalNdvStore.isActive(props.zoom)); -const isToggleZoomVisible = computed(() => experimentalNdvStore.isEnabled); +const isToggleZoomVisible = computed(() => experimentalNdvStore.isZoomedViewEnabled); const isResetZoomVisible = computed(() => !isToggleZoomVisible.value && props.zoom !== 1); diff --git a/packages/frontend/editor-ui/src/components/canvas/elements/nodes/CanvasNodeToolbar.vue b/packages/frontend/editor-ui/src/components/canvas/elements/nodes/CanvasNodeToolbar.vue index b9344e5d55..4f65620b93 100644 --- a/packages/frontend/editor-ui/src/components/canvas/elements/nodes/CanvasNodeToolbar.vue +++ b/packages/frontend/editor-ui/src/components/canvas/elements/nodes/CanvasNodeToolbar.vue @@ -66,7 +66,7 @@ const isDisableNodeVisible = computed(() => { const isDeleteNodeVisible = computed(() => !props.readOnly); -const isFocusNodeVisible = computed(() => experimentalNdvStore.isEnabled); +const isFocusNodeVisible = computed(() => experimentalNdvStore.isZoomedViewEnabled); const isStickyNoteChangeColorVisible = computed( () => !props.readOnly && render.value.type === CanvasNodeRenderType.StickyNote, diff --git a/packages/frontend/editor-ui/src/components/canvas/experimental/components/ExperimentalCanvasNodeSettings.vue b/packages/frontend/editor-ui/src/components/canvas/experimental/components/ExperimentalCanvasNodeSettings.vue index 48fed40f5a..680864b4b1 100644 --- a/packages/frontend/editor-ui/src/components/canvas/experimental/components/ExperimentalCanvasNodeSettings.vue +++ b/packages/frontend/editor-ui/src/components/canvas/experimental/components/ExperimentalCanvasNodeSettings.vue @@ -8,10 +8,11 @@ import { useUIStore } from '@/stores/ui.store'; import { useWorkflowsStore } from '@/stores/workflows.store'; import { computed } from 'vue'; -const { nodeId, isReadOnly, subTitle } = defineProps<{ +const { nodeId, isReadOnly, subTitle, isEmbeddedInCanvas } = defineProps<{ nodeId: string; isReadOnly?: boolean; subTitle?: string; + isEmbeddedInCanvas?: boolean; }>(); defineSlots<{ actions?: {} }>(); @@ -75,10 +76,14 @@ function handleCaptureWheelEvent(event: WheelEvent) { :read-only="isReadOnly" :block-u-i="blockUi" :executable="!isReadOnly" - is-embedded-in-canvas + :is-embedded-in-canvas="isEmbeddedInCanvas" :sub-title="subTitle" extra-tabs-class-name="nodrag" extra-parameter-wrapper-class-name="nodrag" + is-ndv-v2 + hide-execute + :hide-docs="false" + hide-sub-connections @value-changed="handleValueChanged" @capture-wheel-body="handleCaptureWheelEvent" @dblclick-header="handleDoubleClickHeader" diff --git a/packages/frontend/editor-ui/src/components/canvas/experimental/components/ExperimentalEmbeddedNdvMapper.vue b/packages/frontend/editor-ui/src/components/canvas/experimental/components/ExperimentalEmbeddedNdvMapper.vue index 075f3c1e8d..918eb280dd 100644 --- a/packages/frontend/editor-ui/src/components/canvas/experimental/components/ExperimentalEmbeddedNdvMapper.vue +++ b/packages/frontend/editor-ui/src/components/canvas/experimental/components/ExperimentalEmbeddedNdvMapper.vue @@ -41,7 +41,7 @@ defineExpose({ :popper-class="$style.component" :width="360" :offset="8" - append-to="#canvas" + append-to="body" :popper-options="{ modifiers: [{ name: 'flip', enabled: false }], }" diff --git a/packages/frontend/editor-ui/src/components/canvas/experimental/components/ExperimentalEmbeddedNodeDetails.vue b/packages/frontend/editor-ui/src/components/canvas/experimental/components/ExperimentalEmbeddedNodeDetails.vue index be2ec08f5f..2f763f68c4 100644 --- a/packages/frontend/editor-ui/src/components/canvas/experimental/components/ExperimentalEmbeddedNodeDetails.vue +++ b/packages/frontend/editor-ui/src/components/canvas/experimental/components/ExperimentalEmbeddedNodeDetails.vue @@ -1,10 +1,8 @@ + + + + diff --git a/packages/frontend/editor-ui/src/components/canvas/experimental/components/ExperimentalNodeDetailsDrawer.vue b/packages/frontend/editor-ui/src/components/canvas/experimental/components/ExperimentalNodeDetailsDrawer.vue index 7a3d0602a4..32e4053726 100644 --- a/packages/frontend/editor-ui/src/components/canvas/experimental/components/ExperimentalNodeDetailsDrawer.vue +++ b/packages/frontend/editor-ui/src/components/canvas/experimental/components/ExperimentalNodeDetailsDrawer.vue @@ -1,50 +1,25 @@