From 4c87260effdbb3d567273b14359c36295aa12880 Mon Sep 17 00:00:00 2001 From: psychedelicious <4822129+psychedelicious@users.noreply.github.com> Date: Fri, 7 Feb 2025 14:05:18 +1100 Subject: [PATCH] feat(ui): migrated linear view exposed fields to builder form on load --- .../web/src/features/nodes/types/workflow.ts | 11 +++++---- .../nodes/util/workflow/validateWorkflow.ts | 24 ++++++++++++++++++- 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/invokeai/frontend/web/src/features/nodes/types/workflow.ts b/invokeai/frontend/web/src/features/nodes/types/workflow.ts index 1d79dc3ca26..8143de87465 100644 --- a/invokeai/frontend/web/src/features/nodes/types/workflow.ts +++ b/invokeai/frontend/web/src/features/nodes/types/workflow.ts @@ -74,10 +74,13 @@ export const zWorkflowV3 = z.object({ category: zWorkflowCategory.default('user'), version: z.literal('3.0.0'), }), - form: z.object({ - elements: z.record(z.lazy(() => zFormElement)), - layout: z.array(z.lazy(() => zElementId)), - }), + form: z + .object({ + elements: z.record(z.lazy(() => zFormElement)), + layout: z.array(z.lazy(() => zElementId)), + }) + // Catch must be a function else changes to the workflows parsed with this schema will mutate the catch value D: + .catch(() => ({ elements: {}, layout: [] })), }); export type WorkflowV3 = z.infer; // #endregion diff --git a/invokeai/frontend/web/src/features/nodes/util/workflow/validateWorkflow.ts b/invokeai/frontend/web/src/features/nodes/util/workflow/validateWorkflow.ts index 801f7d1fbf4..becb17c9570 100644 --- a/invokeai/frontend/web/src/features/nodes/util/workflow/validateWorkflow.ts +++ b/invokeai/frontend/web/src/features/nodes/util/workflow/validateWorkflow.ts @@ -6,7 +6,7 @@ import { isModelIdentifierFieldInputInstance, } from 'features/nodes/types/field'; import type { WorkflowV3 } from 'features/nodes/types/workflow'; -import { isWorkflowInvocationNode } from 'features/nodes/types/workflow'; +import { buildNodeFieldElement, isWorkflowInvocationNode } from 'features/nodes/types/workflow'; import { getNeedsUpdate } from 'features/nodes/util/node/nodeUpdate'; import { t } from 'i18next'; import { keyBy } from 'lodash-es'; @@ -226,5 +226,27 @@ export const validateWorkflow = async ( }); } }); + + if (_workflow.exposedFields.length > 0 && Object.values(_workflow.form.elements).length === 0) { + // Migrated exposed fields to form elements + for (const { nodeId, fieldName } of _workflow.exposedFields) { + const node = keyedNodes[nodeId]; + if (!node) { + continue; + } + const nodeTemplate = templates[node.data.type]; + if (!nodeTemplate) { + continue; + } + const fieldTemplate = nodeTemplate.inputs[fieldName]; + if (!fieldTemplate) { + continue; + } + const element = buildNodeFieldElement(nodeId, fieldName, fieldTemplate.type); + _workflow.form.elements[element.id] = element; + _workflow.form.layout.push(element.id); + } + } + return { workflow: _workflow, warnings }; };