From 1d2d24727362d6bec7d3c159b637eaf9f35448be Mon Sep 17 00:00:00 2001 From: Ida Date: Sun, 3 May 2026 15:07:25 +0200 Subject: [PATCH] =?UTF-8?q?fix:=20alle=20Node=20definitionen=20korrigiert?= =?UTF-8?q?=20und=20im=20backend=20gesetzt=20-=20keine=20mapping=20layer?= =?UTF-8?q?=20sonder=20saubere=20quelldaten,=20fehlende=20dataRef=20parame?= =?UTF-8?q?ter=20hinzugef=C3=BCgt,=20damit=20jede=20node=20kontext=20nutze?= =?UTF-8?q?n=20kann?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/workflowApi.ts | 14 ++++++++++-- .../context/Automation2DataFlowContext.tsx | 22 ++++++++++++++----- .../editor/Automation2FlowEditor.tsx | 3 +++ .../FlowEditor/nodes/form/FormNodeConfig.tsx | 9 ++++++-- .../nodes/frontendTypeRenderers/index.tsx | 14 +++++++----- .../FlowEditor/nodes/shared/DataPicker.tsx | 22 +++++++++++++------ .../FlowEditor/nodes/shared/dataRef.ts | 6 ++++- .../nodes/start/FormStartNodeConfig.tsx | 9 ++++++-- 8 files changed, 74 insertions(+), 25 deletions(-) diff --git a/src/api/workflowApi.ts b/src/api/workflowApi.ts index 26e2367..dc64b40 100644 --- a/src/api/workflowApi.ts +++ b/src/api/workflowApi.ts @@ -85,11 +85,19 @@ export interface SystemVariable { description: string; } +/** Single form field type with its canonical port primitive. Delivered by GET /node-types. */ +export interface FormFieldType { + id: string; + label: string; + portType: string; +} + export interface NodeTypesResponse { nodeTypes: NodeType[]; categories: NodeTypeCategory[]; portTypeCatalog?: Record; systemVariables?: Record; + formFieldTypes?: FormFieldType[]; } export interface Automation2GraphNode { @@ -279,12 +287,14 @@ export async function fetchNodeTypes( const categories = data?.categories ?? []; const portTypeCatalog = data?.portTypeCatalog ?? undefined; const systemVariables = data?.systemVariables ?? undefined; + const formFieldTypes = data?.formFieldTypes ?? undefined; console.log( `${LOG} fetchNodeTypes response: ${nodeTypes.length} nodeTypes, ${categories.length} categories, ` + `${portTypeCatalog ? Object.keys(portTypeCatalog).length : 0} portTypes, ` + - `${systemVariables ? Object.keys(systemVariables).length : 0} sysVars` + `${systemVariables ? Object.keys(systemVariables).length : 0} sysVars, ` + + `${formFieldTypes ? formFieldTypes.length : 0} formFieldTypes` ); - return { nodeTypes, categories, portTypeCatalog, systemVariables }; + return { nodeTypes, categories, portTypeCatalog, systemVariables, formFieldTypes }; } export interface UpstreamPathEntry { diff --git a/src/components/FlowEditor/context/Automation2DataFlowContext.tsx b/src/components/FlowEditor/context/Automation2DataFlowContext.tsx index 8be4ea9..f36f87c 100644 --- a/src/components/FlowEditor/context/Automation2DataFlowContext.tsx +++ b/src/components/FlowEditor/context/Automation2DataFlowContext.tsx @@ -6,7 +6,7 @@ import React, { createContext, useContext, useMemo } from 'react'; import type { CanvasNode, CanvasConnection } from '../editor/FlowCanvas'; import { getAvailableSources } from '../nodes/shared/dataFlowGraph'; -import type { ApiRequestFunction, NodeType, PortField, PortSchema, SystemVariable } from '../../../api/workflowApi'; +import type { ApiRequestFunction, FormFieldType, NodeType, PortField, PortSchema, SystemVariable } from '../../../api/workflowApi'; export interface Automation2DataFlowContextValue { currentNodeId: string; @@ -17,6 +17,8 @@ export interface Automation2DataFlowContextValue { language: string; portTypeCatalog: Record; systemVariables: Record; + /** Canonical form field types from the API — maps UI type id to portType primitive. */ + formFieldTypes: FormFieldType[]; getNodeLabel: (node: { id: string; title?: string; label?: string; type?: string }) => string; getAvailableSourceIds: () => string[]; /** Present when rendered inside the flow editor (ConnectionPicker / tools). */ @@ -41,6 +43,7 @@ interface Automation2DataFlowProviderProps { language: string; portTypeCatalog?: Record; systemVariables?: Record; + formFieldTypes?: FormFieldType[]; instanceId?: string; request?: ApiRequestFunction; children: React.ReactNode; @@ -55,12 +58,18 @@ export const Automation2DataFlowProvider: React.FC { const value = useMemo((): Automation2DataFlowContextValue | null => { if (!node) return null; + const formTypeToPort: Record = Object.fromEntries( + formFieldTypes.map((f) => [f.id, f.portType]) + ); + const resolvePortType = (rawType: string): string => formTypeToPort[rawType] ?? rawType; + const parseGraphDefinedSchema = (parameterKey: string): PortSchema | null => { const raw = node.parameters?.[parameterKey]; if (!Array.isArray(raw)) return null; @@ -72,8 +81,8 @@ export const Automation2DataFlowProvider: React.FC).de ?? '') : ''; - const ftype = typeof rec.type === 'string' ? rec.type : 'str'; - if (ftype === 'group' && Array.isArray(rec.fields)) { + const rawType = typeof rec.type === 'string' ? rec.type : 'str'; + if (rawType === 'group' && Array.isArray(rec.fields)) { for (const sub of rec.fields as Record[]) { if (!sub || typeof sub.name !== 'string') continue; const sl = sub.label; @@ -85,7 +94,7 @@ export const Automation2DataFlowProvider: React.FC n.title ?? n.label ?? n.type ?? n.id, getAvailableSourceIds: () => getAvailableSources(node.id, nodes, connections), @@ -117,7 +127,7 @@ export const Automation2DataFlowProvider: React.FC diff --git a/src/components/FlowEditor/editor/Automation2FlowEditor.tsx b/src/components/FlowEditor/editor/Automation2FlowEditor.tsx index f2ddf7a..772e9df 100644 --- a/src/components/FlowEditor/editor/Automation2FlowEditor.tsx +++ b/src/components/FlowEditor/editor/Automation2FlowEditor.tsx @@ -99,6 +99,7 @@ export const Automation2FlowEditor: React.FC = ({ in const [categories, setCategories] = useState([]); const [portTypeCatalog, setPortTypeCatalog] = useState>({}); const [systemVariables, setSystemVariables] = useState>({}); + const [formFieldTypes, setFormFieldTypes] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [filter, setFilter] = useState(''); @@ -459,6 +460,7 @@ export const Automation2FlowEditor: React.FC = ({ in setRegistryCatalog(data.portTypeCatalog as never); } if (data.systemVariables) setSystemVariables(data.systemVariables); + if (data.formFieldTypes) setFormFieldTypes(data.formFieldTypes); } catch (err: unknown) { setError(err instanceof Error ? err.message : String(err)); setNodeTypes([]); @@ -904,6 +906,7 @@ export const Automation2FlowEditor: React.FC = ({ in language={language} portTypeCatalog={portTypeCatalog as Record} systemVariables={systemVariables as Record} + formFieldTypes={formFieldTypes} instanceId={instanceId} request={request} > diff --git a/src/components/FlowEditor/nodes/form/FormNodeConfig.tsx b/src/components/FlowEditor/nodes/form/FormNodeConfig.tsx index fbb8dc3..d0a07f6 100644 --- a/src/components/FlowEditor/nodes/form/FormNodeConfig.tsx +++ b/src/components/FlowEditor/nodes/form/FormNodeConfig.tsx @@ -7,11 +7,16 @@ import { FaGripVertical, FaTimes } from 'react-icons/fa'; import type { FormField, NodeConfigRendererProps } from '../shared/types'; import { FORM_FIELD_TYPES, FORM_FIELD_TYPE_LABELS } from '../../../../utils/attributeTypeMapper'; import styles from '../../editor/Automation2FlowEditor.module.css'; +import { useAutomation2DataFlow } from '../../context/Automation2DataFlowContext'; import { useLanguage } from '../../../../providers/language/LanguageContext'; export const FormNodeConfig: React.FC = ({ params, updateParam }) => { const { t } = useLanguage(); + const ctx = useAutomation2DataFlow(); + const fieldTypeOptions = ctx?.formFieldTypes?.length + ? ctx.formFieldTypes + : FORM_FIELD_TYPES.map((ft) => ({ id: ft, label: FORM_FIELD_TYPE_LABELS[ft] ?? ft, portType: 'str' })); const fields = (params.fields as FormField[]) ?? []; const moveField = (fromIndex: number, toIndex: number) => { @@ -88,8 +93,8 @@ export const FormNodeConfig: React.FC = ({ params, upda }} style={{ width: 'auto', minWidth: 90 }} > - {FORM_FIELD_TYPES.map(ft => ( - + {fieldTypeOptions.map((ft) => ( + ))}