/** * NodeConfigPanel - Generic parameter renderer for all node types. * Renders each parameter using FRONTEND_TYPE_RENDERERS based on frontendType. */ import React, { useState, useEffect, useCallback, useRef } from 'react'; import type { CanvasNode } from './FlowCanvas'; import type { NodeType, NodeTypeParameter } from '../../../api/workflowApi'; import type { ApiRequestFunction } from '../../../api/workflowApi'; import { getLabel } from '../nodes/shared/utils'; import { FRONTEND_TYPE_RENDERERS } from '../nodes/frontendTypeRenderers'; import styles from './Automation2FlowEditor.module.css'; import { useLanguage } from '../../../providers/language/LanguageContext'; interface NodeConfigPanelProps { node: CanvasNode | null; nodeType: NodeType | undefined; language: string; onParametersChange: (nodeId: string, parameters: Record) => void; onMergeNodeParameters?: (nodeId: string, patch: Record) => void; onNodeUpdate?: (nodeId: string, updates: Partial>) => void; instanceId?: string; request?: ApiRequestFunction; } export const NodeConfigPanel: React.FC = ({ node, nodeType, language, onParametersChange, onMergeNodeParameters: _onMergeNodeParameters, onNodeUpdate, instanceId, request, }) => { const { t } = useLanguage(); const [params, setParams] = useState>({}); const nodeIdRef = useRef(undefined); nodeIdRef.current = node?.id; const notifyParentTimeoutRef = useRef | null>(null); useEffect(() => { setParams(node?.parameters ?? {}); }, [node?.id, node?.parameters]); useEffect(() => { return () => { if (notifyParentTimeoutRef.current != null) { clearTimeout(notifyParentTimeoutRef.current); notifyParentTimeoutRef.current = null; } }; }, [node?.id]); const updateParam = useCallback( (key: string, value: unknown) => { setParams((prev) => { const next = { ...prev, [key]: value }; const id = nodeIdRef.current; if (id) { if (notifyParentTimeoutRef.current != null) { clearTimeout(notifyParentTimeoutRef.current); } notifyParentTimeoutRef.current = setTimeout(() => { notifyParentTimeoutRef.current = null; onParametersChange(id, next); }, 0); } return next; }); }, [onParametersChange] ); if (!node || !nodeType) return null; const isTrigger = node.type.startsWith('trigger.'); const showNameField = onNodeUpdate && !isTrigger; const parameters = nodeType.parameters || []; return (
{showNameField && (
onNodeUpdate(node.id, { title: e.target.value })} placeholder={t('z.B. Kundenformular prüfen, Land')} />

{t('Wird im Data Picker angezeigt, um diesen Node zu identifizieren.')}

)}

{getLabel(nodeType?.label, language) || node.type}

{nodeType?.description && (

{getLabel(nodeType.description, language)}

)} {parameters.map((param: NodeTypeParameter) => { const frontendType = param.frontendType || 'text'; const Renderer = FRONTEND_TYPE_RENDERERS[frontendType] ?? FRONTEND_TYPE_RENDERERS.text; return ( updateParam(param.name, val)} allParams={params} instanceId={instanceId} request={request} nodeType={node.type} /> ); })}
); };