mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-17 18:12:04 +00:00
fix(editor): Use previous node for FocusPanel execution hint (no-changelog) (#17575)
This commit is contained in:
@@ -116,7 +116,19 @@ const isExecutable = computed(() => {
|
|||||||
|
|
||||||
const node = computed(() => resolvedParameter.value?.node);
|
const node = computed(() => resolvedParameter.value?.node);
|
||||||
|
|
||||||
const { hasNodeRun } = useExecutionData({ node });
|
const { workflowRunData } = useExecutionData({ node });
|
||||||
|
|
||||||
|
const hasNodeRun = computed(() => {
|
||||||
|
if (!node.value) return true;
|
||||||
|
const parentNode = workflowsStore
|
||||||
|
.getCurrentWorkflow()
|
||||||
|
.getParentNodes(node.value.name, 'main', 1)[0];
|
||||||
|
return Boolean(
|
||||||
|
parentNode &&
|
||||||
|
workflowRunData.value &&
|
||||||
|
Object.prototype.hasOwnProperty.bind(workflowRunData.value)(parentNode),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
function getTypeOption<T>(optionName: string): T | undefined {
|
function getTypeOption<T>(optionName: string): T | undefined {
|
||||||
return resolvedParameter.value
|
return resolvedParameter.value
|
||||||
|
|||||||
@@ -328,6 +328,7 @@ function removeOverride(clearField = false) {
|
|||||||
:is-read-only="isReadOnly"
|
:is-read-only="isReadOnly"
|
||||||
:show-options="displayOptions"
|
:show-options="displayOptions"
|
||||||
:show-expression-selector="showExpressionSelector"
|
:show-expression-selector="showExpressionSelector"
|
||||||
|
:is-content-overridden="isContentOverride"
|
||||||
@update:model-value="optionSelected"
|
@update:model-value="optionSelected"
|
||||||
@menu-expanded="onMenuExpanded"
|
@menu-expanded="onMenuExpanded"
|
||||||
/>
|
/>
|
||||||
@@ -390,6 +391,7 @@ function removeOverride(clearField = false) {
|
|||||||
:is-read-only="isReadOnly"
|
:is-read-only="isReadOnly"
|
||||||
:show-options="displayOptions"
|
:show-options="displayOptions"
|
||||||
:show-expression-selector="showExpressionSelector"
|
:show-expression-selector="showExpressionSelector"
|
||||||
|
:is-content-overridden="isContentOverride"
|
||||||
@update:model-value="optionSelected"
|
@update:model-value="optionSelected"
|
||||||
@menu-expanded="onMenuExpanded"
|
@menu-expanded="onMenuExpanded"
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ interface Props {
|
|||||||
iconOrientation?: 'horizontal' | 'vertical';
|
iconOrientation?: 'horizontal' | 'vertical';
|
||||||
loading?: boolean;
|
loading?: boolean;
|
||||||
loadingMessage?: string;
|
loadingMessage?: string;
|
||||||
|
isContentOverridden?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = withDefaults(defineProps<Props>(), {
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
@@ -31,6 +32,7 @@ const props = withDefaults(defineProps<Props>(), {
|
|||||||
iconOrientation: 'vertical',
|
iconOrientation: 'vertical',
|
||||||
loading: false,
|
loading: false,
|
||||||
loadingMessage: () => useI18n().baseText('genericHelpers.loading'),
|
loadingMessage: () => useI18n().baseText('genericHelpers.loading'),
|
||||||
|
isContentOverridden: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
@@ -60,6 +62,7 @@ const canBeOpenedInFocusPanel = computed(
|
|||||||
isFocusPanelFeatureEnabled.value &&
|
isFocusPanelFeatureEnabled.value &&
|
||||||
!props.parameter.isNodeSetting &&
|
!props.parameter.isNodeSetting &&
|
||||||
!props.isReadOnly &&
|
!props.isReadOnly &&
|
||||||
|
!props.isContentOverridden &&
|
||||||
activeNode.value && // checking that it's inside ndv
|
activeNode.value && // checking that it's inside ndv
|
||||||
(props.parameter.type === 'string' || props.parameter.type === 'json'),
|
(props.parameter.type === 'string' || props.parameter.type === 'json'),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -88,6 +88,7 @@ vi.mock('@/composables/useTelemetry', () => ({
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
vi.mock('@n8n/i18n', () => ({
|
vi.mock('@n8n/i18n', () => ({
|
||||||
|
i18n: { baseText: vi.fn().mockImplementation((key) => key) },
|
||||||
useI18n: vi.fn().mockReturnValue({ baseText: vi.fn().mockImplementation((key) => key) }),
|
useI18n: vi.fn().mockReturnValue({ baseText: vi.fn().mockImplementation((key) => key) }),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import { useWorkflowsStore } from './workflows.store';
|
|||||||
import { LOCAL_STORAGE_FOCUS_PANEL, PLACEHOLDER_EMPTY_WORKFLOW_ID } from '@/constants';
|
import { LOCAL_STORAGE_FOCUS_PANEL, PLACEHOLDER_EMPTY_WORKFLOW_ID } from '@/constants';
|
||||||
import { useStorage } from '@/composables/useStorage';
|
import { useStorage } from '@/composables/useStorage';
|
||||||
import { watchOnce } from '@vueuse/core';
|
import { watchOnce } from '@vueuse/core';
|
||||||
|
import { isFromAIOverrideValue } from '@/utils/fromAIOverrideUtils';
|
||||||
|
|
||||||
// matches NodeCreator to ensure they fully overlap by default when both are open
|
// matches NodeCreator to ensure they fully overlap by default when both are open
|
||||||
const DEFAULT_PANEL_WIDTH = 385;
|
const DEFAULT_PANEL_WIDTH = 385;
|
||||||
@@ -63,17 +64,25 @@ export const useFocusPanelStore = defineStore(STORES.FOCUS_PANEL, () => {
|
|||||||
const focusPanelWidth = computed(() => currentFocusPanelData.value.width ?? DEFAULT_PANEL_WIDTH);
|
const focusPanelWidth = computed(() => currentFocusPanelData.value.width ?? DEFAULT_PANEL_WIDTH);
|
||||||
const _focusedNodeParameters = computed(() => currentFocusPanelData.value.parameters);
|
const _focusedNodeParameters = computed(() => currentFocusPanelData.value.parameters);
|
||||||
|
|
||||||
// An unenriched parameter indicates a missing nodeId
|
// An unenriched parameter indicates a missing nodeId or an otherwise unfocusable parameter
|
||||||
const focusedNodeParameters = computed<Array<RichFocusedNodeParameter | FocusedNodeParameter>>(
|
const focusedNodeParameters = computed<Array<RichFocusedNodeParameter | FocusedNodeParameter>>(
|
||||||
() =>
|
() =>
|
||||||
_focusedNodeParameters.value.map((x) => {
|
_focusedNodeParameters.value.map((x) => {
|
||||||
const node = workflowsStore.getNodeById(x.nodeId);
|
const node = workflowsStore.getNodeById(x.nodeId);
|
||||||
if (!node) return x;
|
if (!node) return x;
|
||||||
|
|
||||||
|
const value = get(node?.parameters ?? {}, x.parameterPath.replace(/parameters\./, ''));
|
||||||
|
|
||||||
|
// For overridden parameters we pretend they are gone
|
||||||
|
// To avoid situations where we show the raw value of a newly overridden, previously focused parameter
|
||||||
|
if (typeof value === 'string' && isFromAIOverrideValue(value)) {
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...x,
|
...x,
|
||||||
node,
|
node,
|
||||||
value: get(node?.parameters ?? {}, x.parameterPath.replace(/parameters\./, '')),
|
value,
|
||||||
} satisfies RichFocusedNodeParameter;
|
} satisfies RichFocusedNodeParameter;
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -2172,7 +2172,7 @@ onBeforeUnmount(() => {
|
|||||||
</Suspense>
|
</Suspense>
|
||||||
</WorkflowCanvas>
|
</WorkflowCanvas>
|
||||||
<FocusPanel
|
<FocusPanel
|
||||||
v-if="isFocusPanelFeatureEnabled"
|
v-if="isFocusPanelFeatureEnabled && !isLoading"
|
||||||
:is-canvas-read-only="isCanvasReadOnly"
|
:is-canvas-read-only="isCanvasReadOnly"
|
||||||
@save-keyboard-shortcut="onSaveWorkflow"
|
@save-keyboard-shortcut="onSaveWorkflow"
|
||||||
/>
|
/>
|
||||||
|
|||||||
Reference in New Issue
Block a user