diff --git a/packages/frontend/editor-ui/src/features/ai/instanceAi/workflowSetup/components/WorkflowSetupSectionBody.vue b/packages/frontend/editor-ui/src/features/ai/instanceAi/workflowSetup/components/WorkflowSetupSectionBody.vue index 974c2b33a4a..89b37626673 100644 --- a/packages/frontend/editor-ui/src/features/ai/instanceAi/workflowSetup/components/WorkflowSetupSectionBody.vue +++ b/packages/frontend/editor-ui/src/features/ai/instanceAi/workflowSetup/components/WorkflowSetupSectionBody.vue @@ -21,6 +21,7 @@ import type { INodeUi, INodeUpdatePropertiesInformation, IUpdateInformation } fr import type { WorkflowSetupSection } from '../workflowSetup.types'; import { useWorkflowSetupContext } from '../composables/useWorkflowSetupContext'; import { AI_GATEWAY_MANAGED_TAG } from '../../constants'; +import { findPlaceholderDetails } from '@n8n/utils/placeholder'; const props = defineProps<{ section: WorkflowSetupSection; @@ -75,6 +76,25 @@ const parameterDefinitions = computed(() => { return nodeType.value.properties.filter((property) => names.has(property.name)); }); +const assignmentCollectionEditableValueIndices = computed>(() => { + const result: Record = {}; + for (const parameter of parameterDefinitions.value) { + if (parameter.type !== 'assignmentCollection') continue; + + const indices = new Set(); + const placeholderDetails = findPlaceholderDetails( + props.section.node.parameters[parameter.name], + ); + for (const detail of placeholderDetails) { + if (detail.path[0] !== 'assignments' || detail.path[2] !== 'value') continue; + const match = /^\[(\d+)\]$/.exec(detail.path[1] ?? ''); + if (match?.[1]) indices.add(Number.parseInt(match[1], 10)); + } + result[parameter.name] = [...indices]; + } + return result; +}); + const revealedIssues = ref(new Set()); watch( @@ -212,6 +232,7 @@ function onParameterValueChanged(update: IUpdateInformation) { :remove-first-parameter-margin="true" :remove-last-parameter-margin="true" :options-overrides="{ hideExpressionSelector: true, hideFocusPanelButton: true }" + :assignment-collection-editable-value-indices="assignmentCollectionEditableValueIndices" @value-changed="onParameterValueChanged" @parameter-blur="revealParameterIssues" /> diff --git a/packages/frontend/editor-ui/src/features/ndv/parameters/components/AssignmentCollection/Assignment.vue b/packages/frontend/editor-ui/src/features/ndv/parameters/components/AssignmentCollection/Assignment.vue index d55ce8f302a..7772a08373e 100644 --- a/packages/frontend/editor-ui/src/features/ndv/parameters/components/AssignmentCollection/Assignment.vue +++ b/packages/frontend/editor-ui/src/features/ndv/parameters/components/AssignmentCollection/Assignment.vue @@ -18,6 +18,7 @@ import { propertyNameFromExpression } from '@/app/utils/mappingUtils'; import { N8nIconButton, N8nTooltip } from '@n8n/design-system'; import { typeFromExpression } from '../../utils/assignmentCollection.utils'; import { injectWorkflowDocumentStore } from '@/app/stores/workflowDocument.store'; +import type { ParameterOptionsOverrides } from '@/features/ndv/shared/ndv.utils'; interface Props { path: string; @@ -27,6 +28,8 @@ interface Props { disableType?: boolean; isReadOnly?: boolean; index?: number; + valueOnly?: boolean; + optionsOverrides?: ParameterOptionsOverrides; } const props = defineProps(); @@ -91,7 +94,7 @@ const valueParameter = computed(() => { : 'value'; return { name: 'value', - displayName: 'Value', + displayName: props.valueOnly && assignment.value.name ? assignment.value.name : 'Value', default: '', placeholder, ...assignmentTypeToNodeProperty(assignment.value.type ?? 'string'), @@ -165,14 +168,14 @@ const onValueDrop = async (droppedExpression: string) => { > { />
- +
+ + +
+