dataflow-rs 2.1.5

A lightweight rules engine for building IFTTT-style automation and data processing pipelines in Rust. Define rules with JSONLogic conditions, execute actions, and chain workflows.
Documentation
import { useMemo, useCallback } from 'react';
import { ReactFlow, Background, Controls, type NodeTypes, type NodeMouseHandler } from '@xyflow/react';
import type { Workflow, JsonLogicValue } from '../../../../types';
import type { TreeSelectionType } from '../../WorkflowVisualizer';
import { useTheme } from '../../context';
import { FlowStartEndNode, FlowConditionNode, FlowSkipNode, FlowWorkflowGroupNode } from './nodes';
import { buildGroupFlowGraph } from './buildGroupFlowGraph';

const nodeTypes: NodeTypes = {
  startEnd: FlowStartEndNode,
  condition: FlowConditionNode,
  skip: FlowSkipNode,
  workflowGroup: FlowWorkflowGroupNode,
};

interface GroupFlowDiagramProps {
  workflows: Workflow[];
  name: string;
  onSelect: (selection: TreeSelectionType) => void;
}

export function GroupFlowDiagram({ workflows, name: _name, onSelect }: GroupFlowDiagramProps) {
  const { resolvedTheme } = useTheme();
  const { nodes, edges } = useMemo(() => buildGroupFlowGraph(workflows), [workflows]);

  const onNodeClick: NodeMouseHandler = useCallback((_event, node) => {
    if (node.type === 'workflowGroup') {
      const workflowId = node.data.workflowId as string;
      const workflow = workflows.find((w: Workflow) => w.id === workflowId);
      if (workflow) {
        onSelect({ type: 'workflow', workflow });
      }
    } else if (node.type === 'condition') {
      const workflowId = node.data.workflowId as string;
      if (workflowId) {
        const workflow = workflows.find((w: Workflow) => w.id === workflowId);
        if (workflow?.condition) {
          onSelect({
            type: 'workflow-condition',
            workflow,
            condition: workflow.condition as JsonLogicValue,
          });
        }
      }
    }
  }, [workflows, onSelect]);

  return (
    <div className="df-details-content">
      <div className="df-details-logic-editor" data-theme={resolvedTheme}>
        <div className="df-flow-diagram" data-theme={resolvedTheme}>
          <ReactFlow
            nodes={nodes}
            edges={edges}
            nodeTypes={nodeTypes}
            onNodeClick={onNodeClick}
            colorMode={resolvedTheme}
            fitView
            fitViewOptions={{ padding: 0.2, maxZoom: 0.75 }}
            nodesDraggable={false}
            nodesConnectable={false}
            elementsSelectable={false}
            panOnDrag
            zoomOnScroll
            minZoom={0.3}
            maxZoom={2}
            proOptions={{ hideAttribution: true }}
          >
            <Background gap={20} size={1} />
            <Controls showInteractive={false} />
          </ReactFlow>
        </div>
      </div>
    </div>
  );
}