From 2294bcc8ebe0338e15d02fb19631ad94432f0c7a Mon Sep 17 00:00:00 2001 From: bill Date: Fri, 24 May 2024 19:08:21 +0800 Subject: [PATCH] feat: build react flow nodes and edges from mock data #918 --- web/src/interfaces/database/flow.ts | 19 ++++++++++ web/src/pages/flow/canvas/index.tsx | 16 ++++++--- web/src/pages/flow/canvas/node/index.less | 4 +-- web/src/pages/flow/canvas/node/index.tsx | 25 +++---------- web/src/pages/flow/hooks.ts | 8 +++-- web/src/pages/flow/interface.ts | 4 +++ web/src/pages/flow/mock.tsx | 40 +++++++++++++++++++++ web/src/pages/flow/utils.ts | 44 +++++++++++++++++++++++ 8 files changed, 129 insertions(+), 31 deletions(-) create mode 100644 web/src/interfaces/database/flow.ts create mode 100644 web/src/pages/flow/interface.ts create mode 100644 web/src/pages/flow/utils.ts diff --git a/web/src/interfaces/database/flow.ts b/web/src/interfaces/database/flow.ts new file mode 100644 index 0000000000..00f17cf78e --- /dev/null +++ b/web/src/interfaces/database/flow.ts @@ -0,0 +1,19 @@ +export type DSLComponents = Record; + +export interface DSL { + components: DSLComponents; + history: any[]; + path: string[]; + answer: any[]; +} + +export interface Operator { + obj: OperatorNode; + downstream: string[]; + upstream: string[]; +} + +export interface OperatorNode { + component_name: string; + params: Record; +} diff --git a/web/src/pages/flow/canvas/index.tsx b/web/src/pages/flow/canvas/index.tsx index a8e66a6111..d87296a18d 100644 --- a/web/src/pages/flow/canvas/index.tsx +++ b/web/src/pages/flow/canvas/index.tsx @@ -8,6 +8,7 @@ import ReactFlow, { OnConnect, OnEdgesChange, OnNodesChange, + Position, addEdge, applyEdgeChanges, applyNodeChanges, @@ -24,21 +25,27 @@ const nodeTypes = { textUpdater: TextUpdaterNode }; const initialNodes = [ { + sourcePosition: Position.Left, + targetPosition: Position.Right, id: 'node-1', type: 'textUpdater', - position: { x: 200, y: 50 }, - data: { value: 123 }, + position: { x: 400, y: 100 }, + data: { label: 123 }, }, { + sourcePosition: Position.Right, + targetPosition: Position.Left, id: '1', data: { label: 'Hello' }, - position: { x: 0, y: 0 }, + position: { x: 0, y: 50 }, type: 'input', }, { + sourcePosition: Position.Right, + targetPosition: Position.Left, id: '2', data: { label: 'World' }, - position: { x: 100, y: 100 }, + position: { x: 200, y: 50 }, }, ]; @@ -48,7 +55,6 @@ const initialEdges = [ interface IProps { sideWidth: number; - showDrawer(): void; } function FlowCanvas({ sideWidth }: IProps) { diff --git a/web/src/pages/flow/canvas/node/index.less b/web/src/pages/flow/canvas/node/index.less index afd79e51a4..43a78ca33b 100644 --- a/web/src/pages/flow/canvas/node/index.less +++ b/web/src/pages/flow/canvas/node/index.less @@ -1,6 +1,6 @@ .textUpdaterNode { - height: 50px; - border: 1px solid #eee; + // height: 50px; + border: 1px solid black; padding: 5px; border-radius: 5px; background: white; diff --git a/web/src/pages/flow/canvas/node/index.tsx b/web/src/pages/flow/canvas/node/index.tsx index f22006bcc9..13801cace5 100644 --- a/web/src/pages/flow/canvas/node/index.tsx +++ b/web/src/pages/flow/canvas/node/index.tsx @@ -1,41 +1,24 @@ -import { useCallback } from 'react'; import { Handle, NodeProps, Position } from 'reactflow'; import styles from './index.less'; -const handleStyle = { left: 10 }; - export function TextUpdaterNode({ data, isConnectable = true, -}: NodeProps<{ value: number }>) { - const onChange = useCallback((evt) => { - console.log(evt.target.value); - }, []); - +}: NodeProps<{ label: string }>) { return (
-
- - -
- {/* */} +
{data.label}
); } diff --git a/web/src/pages/flow/hooks.ts b/web/src/pages/flow/hooks.ts index 23754145f1..57d09c5da6 100644 --- a/web/src/pages/flow/hooks.ts +++ b/web/src/pages/flow/hooks.ts @@ -1,6 +1,6 @@ import { useSetModalState } from '@/hooks/commonHooks'; import React, { Dispatch, SetStateAction, useCallback, useState } from 'react'; -import { Node, ReactFlowInstance } from 'reactflow'; +import { Node, Position, ReactFlowInstance } from 'reactflow'; import { v4 as uuidv4 } from 'uuid'; export const useHandleDrag = () => { @@ -44,12 +44,14 @@ export const useHandleDrop = (setNodes: Dispatch>) => { }); const newNode = { id: uuidv4(), - type, + type: 'textUpdater', position: position || { x: 0, y: 0, }, - data: { label: `${type} node` }, + data: { label: `${type}` }, + sourcePosition: Position.Right, + targetPosition: Position.Left, }; setNodes((nds) => nds.concat(newNode)); diff --git a/web/src/pages/flow/interface.ts b/web/src/pages/flow/interface.ts new file mode 100644 index 0000000000..2d17dd48e4 --- /dev/null +++ b/web/src/pages/flow/interface.ts @@ -0,0 +1,4 @@ +export interface DSLComponentList { + id: string; + name: string; +} diff --git a/web/src/pages/flow/mock.tsx b/web/src/pages/flow/mock.tsx index b27aca08bf..68b4946dc1 100644 --- a/web/src/pages/flow/mock.tsx +++ b/web/src/pages/flow/mock.tsx @@ -9,3 +9,43 @@ export const componentList = [ { name: 'Retrieval', icon: , description: '' }, { name: 'Generate', icon: , description: '' }, ]; + +export const dsl = { + components: { + begin: { + obj: { + component_name: 'Begin', + params: {}, + }, + downstream: ['Answer:China'], + upstream: [], + }, + 'Answer:China': { + obj: { + component_name: 'Answer', + params: {}, + }, + downstream: ['Retrieval:China'], + upstream: ['begin', 'Generate:China'], + }, + 'Retrieval:China': { + obj: { + component_name: 'Retrieval', + params: {}, + }, + downstream: ['Generate:China'], + upstream: ['Answer:China'], + }, + 'Generate:China': { + obj: { + component_name: 'Generate', + params: {}, + }, + downstream: ['Answer:China'], + upstream: ['Retrieval:China'], + }, + }, + history: [], + path: ['begin'], + answer: [], +}; diff --git a/web/src/pages/flow/utils.ts b/web/src/pages/flow/utils.ts new file mode 100644 index 0000000000..b82140678d --- /dev/null +++ b/web/src/pages/flow/utils.ts @@ -0,0 +1,44 @@ +import { DSLComponents } from '@/interfaces/database/flow'; +import { Edge, Node, Position } from 'reactflow'; +import { v4 as uuidv4 } from 'uuid'; + +export const buildNodesFromDSLComponents = (data: DSLComponents) => { + const nodes: Node[] = []; + const edges: Edge[] = []; + + Object.entries(data).forEach(([key, value]) => { + const downstream = [...value.downstream]; + const upstream = [...value.upstream]; + nodes.push({ + id: key, + type: 'textUpdater', + position: { x: 0, y: 0 }, + data: { + label: value.obj.component_name, + params: value.obj.params, + downstream: downstream, + upstream: upstream, + }, + sourcePosition: Position.Left, + targetPosition: Position.Right, + }); + + // intermediate node + // The first and last nodes do not need to be considered + if (upstream.length > 0 && downstream.length > 0) { + for (let i = 0; i < upstream.length; i++) { + const up = upstream[i]; + for (let j = 0; j < downstream.length; j++) { + const down = downstream[j]; + edges.push({ + id: uuidv4(), + label: '', + type: 'step', + source: up, + target: down, + }); + } + } + } + }); +};