121 lines
3.2 KiB
TypeScript
121 lines
3.2 KiB
TypeScript
import type { Edge, Node } from '@xyflow/react'
|
|
import type {
|
|
AutomationWorkflow,
|
|
WorkflowEdgeDef,
|
|
WorkflowNodeData,
|
|
WorkflowNodeDef,
|
|
WorkflowNodeType,
|
|
} from './types'
|
|
import { nextNodeId } from './defaults'
|
|
import type { ActionsNodeData, ConditionNodeData, LabelCheckNodeData, LLMCheckNodeData, SetVarNodeData, SwitchNodeData } from './types'
|
|
|
|
export function workflowNodesToFlow(nodes: WorkflowNodeDef[]): Node[] {
|
|
return nodes.map((n) => ({
|
|
id: n.id,
|
|
type: n.type,
|
|
position: n.position,
|
|
data: n.data as Record<string, unknown>,
|
|
}))
|
|
}
|
|
|
|
export function workflowEdgesToFlow(edges: WorkflowEdgeDef[]): Edge[] {
|
|
return edges.map((e) => ({
|
|
id: e.id,
|
|
source: e.source,
|
|
target: e.target,
|
|
sourceHandle: e.sourceHandle ?? null,
|
|
animated: true,
|
|
}))
|
|
}
|
|
|
|
export function flowToWorkflow(
|
|
kind: AutomationWorkflow['kind'],
|
|
triggers: AutomationWorkflow['triggers'],
|
|
variables: AutomationWorkflow['variables'],
|
|
nodes: Node[],
|
|
edges: Edge[]
|
|
): AutomationWorkflow {
|
|
return {
|
|
version: 1,
|
|
kind,
|
|
triggers,
|
|
variables,
|
|
nodes: nodes.map((n) => ({
|
|
id: n.id,
|
|
type: n.type as WorkflowNodeType,
|
|
position: n.position,
|
|
data: (n.data ?? {}) as WorkflowNodeData,
|
|
})),
|
|
edges: edges.map((e) => ({
|
|
id: e.id,
|
|
source: e.source,
|
|
target: e.target,
|
|
sourceHandle: e.sourceHandle ?? undefined,
|
|
})),
|
|
}
|
|
}
|
|
|
|
export function defaultDataForNodeType(type: WorkflowNodeType): WorkflowNodeData {
|
|
switch (type) {
|
|
case 'condition':
|
|
return { field: 'subject', operator: 'contains', value: '' } satisfies ConditionNodeData
|
|
case 'label_check':
|
|
return { label: '', operator: 'has' } satisfies LabelCheckNodeData
|
|
case 'switch':
|
|
return {
|
|
field: 'subject',
|
|
cases: [
|
|
{ value: 'facture', label: 'Factures' },
|
|
{ value: 'newsletter', label: 'Newsletters' },
|
|
],
|
|
} satisfies SwitchNodeData
|
|
case 'llm_check':
|
|
return {
|
|
prompt: 'Ce message est-il du spam ou une arnaque ?',
|
|
provider: '',
|
|
model: '',
|
|
} satisfies LLMCheckNodeData
|
|
case 'actions':
|
|
return { actions: [{ type: 'label', value: '' }] } satisfies ActionsNodeData
|
|
case 'set_var':
|
|
return { name: 'result', value: '{{subject}}' } satisfies SetVarNodeData
|
|
case 'call_function':
|
|
case 'call_rule':
|
|
return { rule_id: '' }
|
|
default:
|
|
return {}
|
|
}
|
|
}
|
|
|
|
export function createFlowNode(
|
|
type: WorkflowNodeType,
|
|
position: { x: number; y: number }
|
|
): Node {
|
|
return {
|
|
id: nextNodeId(type),
|
|
type,
|
|
position,
|
|
data: defaultDataForNodeType(type) as Record<string, unknown>,
|
|
}
|
|
}
|
|
|
|
export function parseWorkflowFromRule(
|
|
workflow: unknown,
|
|
ruleKind: 'rule' | 'function'
|
|
): AutomationWorkflow | null {
|
|
if (!workflow || typeof workflow !== 'object') return null
|
|
const w = workflow as AutomationWorkflow
|
|
if (!Array.isArray(w.nodes) || w.nodes.length === 0) return null
|
|
return {
|
|
version: 1,
|
|
kind: w.kind ?? ruleKind,
|
|
triggers: w.triggers ?? {
|
|
operator: 'or',
|
|
groups: [{ operator: 'and', items: [{ type: 'message_received' }] }],
|
|
},
|
|
variables: w.variables ?? [],
|
|
nodes: w.nodes,
|
|
edges: w.edges ?? [],
|
|
}
|
|
}
|