75 lines
2.3 KiB
JavaScript
75 lines
2.3 KiB
JavaScript
export const NODE_TYPES = [
|
|
{ type: 'start', label: 'Start' },
|
|
{ type: 'condition', label: 'Condition' },
|
|
{ type: 'approval', label: 'Approval' },
|
|
{ type: 'notify', label: 'Notify' },
|
|
{ type: 'action', label: 'Action' },
|
|
{ type: 'end', label: 'End' },
|
|
];
|
|
|
|
export function labelFor(node) {
|
|
const type = node.type || node.data?.nodeType;
|
|
const config = node.config || node.data?.config || {};
|
|
if (type === 'approval') return `Approval (${config.mode || 'single'})`;
|
|
if (type === 'end') return `End (${config.outcome || 'completed'})`;
|
|
if (type === 'notify') return 'Notify';
|
|
if (type === 'action') return config.name || 'Action';
|
|
if (type === 'condition') return 'Condition';
|
|
return 'Start';
|
|
}
|
|
|
|
export function edgeLabel(when) {
|
|
if (!when || !when.field) return '';
|
|
return `${when.field} ${when.op || 'eq'} ${when.value ?? ''}`;
|
|
}
|
|
|
|
export function toFlow(definition) {
|
|
const layout = definition.layout || {};
|
|
return {
|
|
nodes: (definition.nodes || []).map((node, index) => ({
|
|
id: node.id,
|
|
position: layout[node.id] || { x: 80 + (index % 3) * 220, y: 80 + Math.floor(index / 3) * 140 },
|
|
data: {
|
|
label: labelFor(node),
|
|
nodeType: node.type,
|
|
config: node.config || {},
|
|
},
|
|
})),
|
|
edges: (definition.edges || []).map((edge) => ({
|
|
id: edge.id,
|
|
source: edge.source,
|
|
target: edge.target,
|
|
label: edgeLabel(edge.when),
|
|
data: { when: edge.when || null },
|
|
})),
|
|
};
|
|
}
|
|
|
|
export function fromFlow(nodes, edges) {
|
|
return {
|
|
nodes: nodes.map((node) => ({
|
|
id: node.id,
|
|
type: node.data.nodeType,
|
|
config: node.data.config || {},
|
|
})),
|
|
edges: edges.map((edge) => {
|
|
const when = edge.data && edge.data.when && edge.data.when.field ? edge.data.when : null;
|
|
return {
|
|
id: edge.id,
|
|
source: edge.source,
|
|
target: edge.target,
|
|
...(when ? { when } : {}),
|
|
};
|
|
}),
|
|
layout: Object.fromEntries(nodes.map((node) => [node.id, node.position])),
|
|
};
|
|
}
|
|
|
|
export function defaultConfig(type) {
|
|
if (type === 'approval') return { mode: 'sequential', approvers: ['l1manager'], escalate_vacant: true };
|
|
if (type === 'notify') return { recipients: ['l1manager'], subject: '', body: '' };
|
|
if (type === 'action') return { name: 'set_status', status: 'approved' };
|
|
if (type === 'end') return { outcome: 'completed' };
|
|
return {};
|
|
}
|