127 lines
4.6 KiB
TypeScript
127 lines
4.6 KiB
TypeScript
/**
|
|
* Automation2 Flow Editor - Data flow context for Data Picker and DynamicValueField.
|
|
* Extended with portTypeCatalog and systemVariables for the Typed Port System.
|
|
*/
|
|
|
|
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';
|
|
|
|
export interface Automation2DataFlowContextValue {
|
|
currentNodeId: string;
|
|
nodes: CanvasNode[];
|
|
connections: CanvasConnection[];
|
|
nodeOutputsPreview: Record<string, unknown>;
|
|
nodeTypes: NodeType[];
|
|
language: string;
|
|
portTypeCatalog: Record<string, PortSchema>;
|
|
systemVariables: Record<string, SystemVariable>;
|
|
getNodeLabel: (node: { id: string; title?: string; label?: string; type?: string }) => string;
|
|
getAvailableSourceIds: () => string[];
|
|
/** Present when rendered inside the flow editor (ConnectionPicker / tools). */
|
|
instanceId?: string;
|
|
request?: ApiRequestFunction;
|
|
/** Build FormPayload-like schema from ``parameters[parameterKey]`` (fieldBuilder JSON). */
|
|
parseGraphDefinedSchema: (parameterKey: string) => PortSchema | null;
|
|
}
|
|
|
|
const Automation2DataFlowContext = createContext<Automation2DataFlowContextValue | null>(null);
|
|
|
|
export function useAutomation2DataFlow(): Automation2DataFlowContextValue | null {
|
|
return useContext(Automation2DataFlowContext);
|
|
}
|
|
|
|
interface Automation2DataFlowProviderProps {
|
|
node: CanvasNode | null;
|
|
nodes: CanvasNode[];
|
|
connections: CanvasConnection[];
|
|
nodeOutputsPreview: Record<string, unknown>;
|
|
nodeTypes: NodeType[];
|
|
language: string;
|
|
portTypeCatalog?: Record<string, PortSchema>;
|
|
systemVariables?: Record<string, SystemVariable>;
|
|
instanceId?: string;
|
|
request?: ApiRequestFunction;
|
|
children: React.ReactNode;
|
|
}
|
|
|
|
export const Automation2DataFlowProvider: React.FC<Automation2DataFlowProviderProps> = ({
|
|
node,
|
|
nodes,
|
|
connections,
|
|
nodeOutputsPreview,
|
|
nodeTypes,
|
|
language,
|
|
portTypeCatalog = {},
|
|
systemVariables = {},
|
|
instanceId,
|
|
request,
|
|
children,
|
|
}) => {
|
|
const value = useMemo((): Automation2DataFlowContextValue | null => {
|
|
if (!node) return null;
|
|
const parseGraphDefinedSchema = (parameterKey: string): PortSchema | null => {
|
|
const raw = node.parameters?.[parameterKey];
|
|
if (!Array.isArray(raw)) return null;
|
|
const fields: PortField[] = [];
|
|
for (const item of raw) {
|
|
if (typeof item !== 'object' || item === null) continue;
|
|
const rec = item as Record<string, unknown>;
|
|
if (typeof rec.name !== 'string') continue;
|
|
const lab = rec.label;
|
|
const desc =
|
|
typeof lab === 'string' ? lab : typeof lab === 'object' && lab !== null ? String((lab as Record<string, string>).de ?? '') : '';
|
|
const ftype = typeof rec.type === 'string' ? rec.type : 'str';
|
|
if (ftype === 'group' && Array.isArray(rec.fields)) {
|
|
for (const sub of rec.fields as Record<string, unknown>[]) {
|
|
if (!sub || typeof sub.name !== 'string') continue;
|
|
const sl = sub.label;
|
|
const sdesc =
|
|
typeof sl === 'string'
|
|
? sl
|
|
: typeof sl === 'object' && sl !== null
|
|
? String((sl as Record<string, string>).de ?? '')
|
|
: '';
|
|
fields.push({
|
|
name: `${rec.name}.${sub.name}`,
|
|
type: typeof sub.type === 'string' ? sub.type : 'str',
|
|
description: (sdesc && sdesc.trim()) || `${rec.name}.${sub.name}`,
|
|
required: Boolean(sub.required),
|
|
});
|
|
}
|
|
continue;
|
|
}
|
|
fields.push({
|
|
name: rec.name,
|
|
type: ftype,
|
|
description: (desc && desc.trim()) || rec.name,
|
|
required: Boolean(rec.required),
|
|
});
|
|
}
|
|
return fields.length ? { name: 'FormPayload_dynamic', fields } : null;
|
|
};
|
|
return {
|
|
currentNodeId: node.id,
|
|
nodes,
|
|
connections,
|
|
nodeOutputsPreview,
|
|
nodeTypes,
|
|
language,
|
|
portTypeCatalog,
|
|
systemVariables,
|
|
getNodeLabel: (n: { id: string; title?: string; label?: string; type?: string }) =>
|
|
n.title ?? n.label ?? n.type ?? n.id,
|
|
getAvailableSourceIds: () => getAvailableSources(node.id, nodes, connections),
|
|
instanceId,
|
|
request,
|
|
parseGraphDefinedSchema,
|
|
};
|
|
}, [node, nodes, connections, nodeOutputsPreview, nodeTypes, language, portTypeCatalog, systemVariables, instanceId, request]);
|
|
|
|
return (
|
|
<Automation2DataFlowContext.Provider value={value}>
|
|
{children}
|
|
</Automation2DataFlowContext.Provider>
|
|
);
|
|
};
|