feat: modify the name of an operator #918 (#1333)

### What problem does this PR solve?

feat: modify the name of an operator #918

### Type of change


- [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
balibabu 2024-07-01 17:12:04 +08:00 committed by GitHub
parent 92e9320657
commit 8b1c145e56
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 117 additions and 40 deletions

View File

@ -1,5 +1,5 @@
const AnswerForm = () => { const AnswerForm = () => {
return <div>AnswerForm</div>; return <div></div>;
}; };
export default AnswerForm; export default AnswerForm;

View File

@ -32,7 +32,7 @@ export function BeginNode({ id, data, selected }: NodeProps<NodeData>) {
</Space> </Space>
</Flex> </Flex>
<section className={styles.bottomBox}> <section className={styles.bottomBox}>
<div className={styles.nodeName}>{id}</div> <div className={styles.nodeName}>{data.name}</div>
</section> </section>
</section> </section>
); );

View File

@ -59,7 +59,7 @@ export function CategorizeNode({ id, data, selected }: NodeProps<NodeData>) {
</Space> </Space>
</Flex> </Flex>
<section className={styles.bottomBox}> <section className={styles.bottomBox}>
<div className={styles.nodeName}>{id}</div> <div className={styles.nodeName}>{data.name}</div>
</section> </section>
</section> </section>
); );

View File

@ -62,7 +62,7 @@ export function RagNode({
</Flex> </Flex>
<section className={styles.bottomBox}> <section className={styles.bottomBox}>
<div className={styles.nodeName}>{id}</div> <div className={styles.nodeName}>{data.name}</div>
</section> </section>
</section> </section>
); );

View File

@ -42,7 +42,7 @@ const DynamicCategorize = ({ nodeId }: IProps) => {
} }
> >
<Form.Item <Form.Item
label={t('name')} label={t('name')} // TODO: repeatability check
name={[field.name, 'name']} name={[field.name, 'name']}
rules={[{ required: true, message: t('nameMessage') }]} rules={[{ required: true, message: t('nameMessage') }]}
> >

View File

@ -25,7 +25,7 @@ export const useBuildCategorizeToOptions = () => {
excludedNodes.every((y) => y !== x.data.label) && excludedNodes.every((y) => y !== x.data.label) &&
!toList.some((y) => y === x.id), // filter out selected values in other to fields from the current drop-down box options !toList.some((y) => y === x.id), // filter out selected values in other to fields from the current drop-down box options
) )
.map((x) => ({ label: x.id, value: x.id })); .map((x) => ({ label: x.data.name, value: x.id }));
}, },
[nodes], [nodes],
); );

View File

@ -1,5 +1,5 @@
import { IModalProps } from '@/interfaces/common'; import { IModalProps } from '@/interfaces/common';
import { Drawer, Form } from 'antd'; import { Drawer, Form, Input } from 'antd';
import { useEffect } from 'react'; import { useEffect } from 'react';
import { Node } from 'reactflow'; import { Node } from 'reactflow';
import AnswerForm from '../answer-form'; import AnswerForm from '../answer-form';
@ -7,7 +7,7 @@ import BeginForm from '../begin-form';
import CategorizeForm from '../categorize-form'; import CategorizeForm from '../categorize-form';
import { Operator } from '../constant'; import { Operator } from '../constant';
import GenerateForm from '../generate-form'; import GenerateForm from '../generate-form';
import { useHandleFormValuesChange } from '../hooks'; import { useHandleFormValuesChange, useHandleNodeNameChange } from '../hooks';
import MessageForm from '../message-form'; import MessageForm from '../message-form';
import RelevantForm from '../relevant-form'; import RelevantForm from '../relevant-form';
import RetrievalForm from '../retrieval-form'; import RetrievalForm from '../retrieval-form';
@ -36,6 +36,8 @@ const FlowDrawer = ({
const operatorName: Operator = node?.data.label; const operatorName: Operator = node?.data.label;
const OperatorForm = FormMap[operatorName]; const OperatorForm = FormMap[operatorName];
const [form] = Form.useForm(); const [form] = Form.useForm();
const { name, handleNameBlur, handleNameChange } =
useHandleNodeNameChange(node);
const { handleValuesChange } = useHandleFormValuesChange(node?.id); const { handleValuesChange } = useHandleFormValuesChange(node?.id);
@ -47,7 +49,13 @@ const FlowDrawer = ({
return ( return (
<Drawer <Drawer
title={node?.data.label} title={
<Input
value={name}
onBlur={handleNameBlur}
onChange={handleNameChange}
></Input>
}
placement="right" placement="right"
onClose={hideModal} onClose={hideModal}
open={visible} open={visible}

View File

@ -1,7 +1,7 @@
{ {
"edges": [ "edges": [
{ {
"id": "f42b5218-8052-4eb5-9cec-2dd302ad478a", "id": "1542fe3d-d13d-4e14-a253-c06cdf72e357",
"label": "", "label": "",
"source": "begin", "source": "begin",
"target": "answer:0", "target": "answer:0",
@ -10,7 +10,7 @@
} }
}, },
{ {
"id": "84c024e1-a96f-438c-905f-63ef725b0442", "id": "e0c46945-b60a-4da9-9a35-5dd654469e47",
"label": "", "label": "",
"source": "message:reject", "source": "message:reject",
"target": "answer:0", "target": "answer:0",
@ -19,7 +19,7 @@
} }
}, },
{ {
"id": "04b4bf3c-1f49-4cd8-9b93-779c9d8aa86c", "id": "5806636c-2bba-4c14-922e-3ef905c37f52",
"label": "", "label": "",
"source": "answer:0", "source": "answer:0",
"target": "categorize:0", "target": "categorize:0",
@ -28,7 +28,7 @@
} }
}, },
{ {
"id": "0c1ac8d3-9a45-44b1-92e1-f7e3f1b3be9b", "id": "ebce1598-cd0c-4863-a8b1-2f8a1de28040",
"label": "", "label": "",
"source": "categorize:0", "source": "categorize:0",
"target": "message:introduction", "target": "message:introduction",
@ -38,7 +38,7 @@
"sourceHandle": "interested" "sourceHandle": "interested"
}, },
{ {
"id": "309d9f73-f125-44aa-be84-e716dffb4af1", "id": "1e560fed-76f9-494b-a028-cd871acdee07",
"label": "", "label": "",
"source": "categorize:0", "source": "categorize:0",
"target": "generate:casual", "target": "generate:casual",
@ -48,7 +48,7 @@
"sourceHandle": "casual" "sourceHandle": "casual"
}, },
{ {
"id": "d8f39ec9-b993-42c7-aa88-e86192c8ee14", "id": "5aa430cc-19c4-4f82-9fed-5649651fff11",
"label": "", "label": "",
"source": "categorize:0", "source": "categorize:0",
"target": "message:reject", "target": "message:reject",
@ -58,7 +58,7 @@
"sourceHandle": "answer" "sourceHandle": "answer"
}, },
{ {
"id": "34047c0a-6c50-4cf7-a2e6-d1a8cd9b269b", "id": "c40b1dab-5f42-425f-9207-27e261d6b70f",
"label": "", "label": "",
"source": "categorize:0", "source": "categorize:0",
"target": "retrieval:0", "target": "retrieval:0",
@ -68,7 +68,7 @@
"sourceHandle": "about_job" "sourceHandle": "about_job"
}, },
{ {
"id": "0613a366-8476-44a5-8b6c-874007de7d5c", "id": "7216138f-cdc0-4992-851e-30916033d520",
"label": "", "label": "",
"source": "message:introduction", "source": "message:introduction",
"target": "answer:1", "target": "answer:1",
@ -77,7 +77,7 @@
} }
}, },
{ {
"id": "b14d80a7-3e63-4ba4-bfb2-80ad3a1b5980", "id": "3bb8ada2-b1ac-49cc-81bf-78ffb2c07d94",
"label": "", "label": "",
"source": "generate:aboutJob", "source": "generate:aboutJob",
"target": "answer:1", "target": "answer:1",
@ -86,7 +86,7 @@
} }
}, },
{ {
"id": "6126fd77-f407-4ce5-966b-62cb18011343", "id": "d60c4c33-ddd2-40ff-af62-aabb11e6a91c",
"label": "", "label": "",
"source": "generate:casual", "source": "generate:casual",
"target": "answer:1", "target": "answer:1",
@ -95,7 +95,7 @@
} }
}, },
{ {
"id": "24c6cc93-7f0d-4fae-a54d-a2a79336f58e", "id": "f425b2ec-fe5b-44d9-b5f3-c2953e12b600",
"label": "", "label": "",
"source": "generate:get_wechat", "source": "generate:get_wechat",
"target": "answer:1", "target": "answer:1",
@ -104,7 +104,7 @@
} }
}, },
{ {
"id": "f09d9bf3-d64c-4a23-a415-c53179e7366f", "id": "ebf55d7f-36bf-43ba-9166-34d8a4a68474",
"label": "", "label": "",
"source": "generate:nowechat", "source": "generate:nowechat",
"target": "answer:1", "target": "answer:1",
@ -113,7 +113,7 @@
} }
}, },
{ {
"id": "cd55cf28-ddac-476e-a73e-d6c0d54f62d2", "id": "8897e8ed-12b7-4ca4-a63b-7a5a702a1517",
"label": "", "label": "",
"source": "answer:1", "source": "answer:1",
"target": "categorize:1", "target": "categorize:1",
@ -122,7 +122,7 @@
} }
}, },
{ {
"id": "69ad4e49-c538-4406-900c-352644fde6b9", "id": "a0d646e9-6ef9-490d-9308-830c51b8a663",
"label": "", "label": "",
"source": "categorize:1", "source": "categorize:1",
"target": "retrieval:0", "target": "retrieval:0",
@ -132,7 +132,7 @@
"sourceHandle": "about_job" "sourceHandle": "about_job"
}, },
{ {
"id": "999c5601-e69d-4a35-a15e-474546babe64", "id": "6a0714f7-806f-49f4-bc36-210025e48f49",
"label": "", "label": "",
"source": "categorize:1", "source": "categorize:1",
"target": "generate:casual", "target": "generate:casual",
@ -142,7 +142,7 @@
"sourceHandle": "casual" "sourceHandle": "casual"
}, },
{ {
"id": "9debb81c-9b74-4e51-a6ae-a2f0188b781b", "id": "9267def3-9b81-4f50-87da-0eef85b4fe90",
"label": "", "label": "",
"source": "categorize:1", "source": "categorize:1",
"target": "generate:get_wechat", "target": "generate:get_wechat",
@ -152,7 +152,7 @@
"sourceHandle": "wechat" "sourceHandle": "wechat"
}, },
{ {
"id": "95e183eb-d114-4ad4-946b-3fb2d3df340c", "id": "d8bfe795-36e7-4172-9dfe-649ad37be4d8",
"label": "", "label": "",
"source": "categorize:1", "source": "categorize:1",
"target": "generate:nowechat", "target": "generate:nowechat",
@ -162,7 +162,7 @@
"sourceHandle": "giveup" "sourceHandle": "giveup"
}, },
{ {
"id": "c59c1a4b-18ed-4a74-bbef-fa961a51d6a4", "id": "94c5e5c5-3b35-412d-a6cb-4ed5f883fef2",
"label": "", "label": "",
"source": "retrieval:0", "source": "retrieval:0",
"target": "generate:aboutJob", "target": "generate:aboutJob",
@ -171,7 +171,7 @@
} }
}, },
{ {
"id": "aa902165-fe39-4cc4-8220-1abcf37b9f12", "id": "17da25cc-09c5-4a5e-ad27-2c6593f8fff5",
"label": "", "label": "",
"source": "relevant:0", "source": "relevant:0",
"target": "generate:aboutJob", "target": "generate:aboutJob",
@ -190,6 +190,7 @@
}, },
"data": { "data": {
"label": "Begin", "label": "Begin",
"name": "OliveGuestsPlay",
"form": { "form": {
"prologue": "您好我是AGI方向的猎头了解到您是这方面的大佬然后冒昧的就联系到您。这边有个机会想和您分享RAGFlow正在招聘您这个岗位的资深的工程师不知道您那边是不是感兴趣" "prologue": "您好我是AGI方向的猎头了解到您是这方面的大佬然后冒昧的就联系到您。这边有个机会想和您分享RAGFlow正在招聘您这个岗位的资深的工程师不知道您那边是不是感兴趣"
} }
@ -206,6 +207,7 @@
}, },
"data": { "data": {
"label": "Answer", "label": "Answer",
"name": "SolidRatsBurn",
"form": {} "form": {}
}, },
"sourcePosition": "left", "sourcePosition": "left",
@ -220,6 +222,7 @@
}, },
"data": { "data": {
"label": "Categorize", "label": "Categorize",
"name": "ShyHousesAccept",
"form": { "form": {
"llm_id": "deepseek-chat", "llm_id": "deepseek-chat",
"category_description": { "category_description": {
@ -258,6 +261,7 @@
}, },
"data": { "data": {
"label": "Message", "label": "Message",
"name": "ThreeRegionsGrow",
"form": { "form": {
"messages": [ "messages": [
"我简单介绍以下:\nRAGFlow 是一款基于深度文档理解构建的开源 RAGRetrieval-Augmented Generation引擎。RAGFlow 可以为各种规模的企业及个人提供一套精简的 RAG 工作流程结合大语言模型LLM针对用户各类不同的复杂格式数据提供可靠的问答以及有理有据的引用。https://github.com/infiniflow/ragflow\n您那边还有什么要了解的" "我简单介绍以下:\nRAGFlow 是一款基于深度文档理解构建的开源 RAGRetrieval-Augmented Generation引擎。RAGFlow 可以为各种规模的企业及个人提供一套精简的 RAG 工作流程结合大语言模型LLM针对用户各类不同的复杂格式数据提供可靠的问答以及有理有据的引用。https://github.com/infiniflow/ragflow\n您那边还有什么要了解的"
@ -276,6 +280,7 @@
}, },
"data": { "data": {
"label": "Answer", "label": "Answer",
"name": "FancyChickenCut",
"form": {} "form": {}
}, },
"sourcePosition": "left", "sourcePosition": "left",
@ -290,6 +295,7 @@
}, },
"data": { "data": {
"label": "Categorize", "label": "Categorize",
"name": "DeepAreasGrow",
"form": { "form": {
"llm_id": "deepseek-chat", "llm_id": "deepseek-chat",
"category_description": { "category_description": {
@ -329,6 +335,7 @@
}, },
"data": { "data": {
"label": "Generate", "label": "Generate",
"name": "TinyOlivesMelt",
"form": { "form": {
"llm_id": "deepseek-chat", "llm_id": "deepseek-chat",
"prompt": "你是AGI方向的猎头现在候选人的聊了和职位无关的话题请耐心的回应候选人并将话题往该AGI的职位上带最好能要到候选人微信号以便后面保持联系。", "prompt": "你是AGI方向的猎头现在候选人的聊了和职位无关的话题请耐心的回应候选人并将话题往该AGI的职位上带最好能要到候选人微信号以便后面保持联系。",
@ -349,6 +356,7 @@
}, },
"data": { "data": {
"label": "Retrieval", "label": "Retrieval",
"name": "SlimyDonkeysHug",
"form": { "form": {
"similarity_threshold": 0.2, "similarity_threshold": 0.2,
"keywords_similarity_weight": 0.3, "keywords_similarity_weight": 0.3,
@ -370,6 +378,7 @@
}, },
"data": { "data": {
"label": "Generate", "label": "Generate",
"name": "PetiteHoundsMove",
"form": { "form": {
"llm_id": "deepseek-chat", "llm_id": "deepseek-chat",
"prompt": "你是AGI方向的猎头候选人问了有关职位或公司的问题你根据以下职位信息回答。如果职位信息中不包含候选人的问题就回答不清楚、不知道、有待确认等。回答完后引导候选人加微信号\n - 方便加一下微信吗我把JD发您看看\n - 微信号多少我把详细职位JD发您\n 职位信息如下:\n {input}\n 职位信息如上。", "prompt": "你是AGI方向的猎头候选人问了有关职位或公司的问题你根据以下职位信息回答。如果职位信息中不包含候选人的问题就回答不清楚、不知道、有待确认等。回答完后引导候选人加微信号\n - 方便加一下微信吗我把JD发您看看\n - 微信号多少我把详细职位JD发您\n 职位信息如下:\n {input}\n 职位信息如上。",
@ -388,6 +397,7 @@
}, },
"data": { "data": {
"label": "Generate", "label": "Generate",
"name": "EagerSteaksWin",
"form": { "form": {
"llm_id": "deepseek-chat", "llm_id": "deepseek-chat",
"prompt": "你是AGI方向的猎头候选人表示不反感加微信如果对方已经报了微信号表示感谢和信任并表示马上会加上如果没有则问对方微信号多少。你的微信号是weixin_kevinE-mail是kkk@ragflow.com。说话不要重复。不要总是您好。", "prompt": "你是AGI方向的猎头候选人表示不反感加微信如果对方已经报了微信号表示感谢和信任并表示马上会加上如果没有则问对方微信号多少。你的微信号是weixin_kevinE-mail是kkk@ragflow.com。说话不要重复。不要总是您好。",
@ -408,6 +418,7 @@
}, },
"data": { "data": {
"label": "Generate", "label": "Generate",
"name": "IcyAntsBet",
"form": { "form": {
"llm_id": "deepseek-chat", "llm_id": "deepseek-chat",
"prompt": "你是AGI方向的猎头当你提出加微信时对方表示拒绝。你需要耐心礼貌的回应候选人表示对于保护隐私信息给予理解也可以询问他对该职位的看法和顾虑。并在恰当的时机再次询问微信联系方式。也可以鼓励候选人主动与你取得联系。你的微信号是weixin_kevinE-mail是kkk@ragflow.com。说话不要重复。不要总是您好。", "prompt": "你是AGI方向的猎头当你提出加微信时对方表示拒绝。你需要耐心礼貌的回应候选人表示对于保护隐私信息给予理解也可以询问他对该职位的看法和顾虑。并在恰当的时机再次询问微信联系方式。也可以鼓励候选人主动与你取得联系。你的微信号是weixin_kevinE-mail是kkk@ragflow.com。说话不要重复。不要总是您好。",
@ -428,6 +439,7 @@
}, },
"data": { "data": {
"label": "Message", "label": "Message",
"name": "SmallCarsRoll",
"form": { "form": {
"messages": [ "messages": [
"好的,祝您生活愉快,工作顺利。", "好的,祝您生活愉快,工作顺利。",

View File

@ -8,6 +8,7 @@ import { useFetchLlmList } from '@/hooks/llmHooks';
import { IGraph } from '@/interfaces/database/flow'; import { IGraph } from '@/interfaces/database/flow';
import { useIsFetching } from '@tanstack/react-query'; import { useIsFetching } from '@tanstack/react-query';
import React, { import React, {
ChangeEvent,
KeyboardEventHandler, KeyboardEventHandler,
useCallback, useCallback,
useEffect, useEffect,
@ -22,8 +23,9 @@ import {
} from '@/constants/knowledge'; } from '@/constants/knowledge';
import { Variable } from '@/interfaces/database/chat'; import { Variable } from '@/interfaces/database/chat';
import { useDebounceEffect } from 'ahooks'; import { useDebounceEffect } from 'ahooks';
import { FormInstance } from 'antd'; import { FormInstance, message } from 'antd';
import { humanId } from 'human-id'; import { humanId } from 'human-id';
import trim from 'lodash/trim';
import { useParams } from 'umi'; import { useParams } from 'umi';
import { NodeMap, Operator, RestrictedUpstreamMap } from './constant'; import { NodeMap, Operator, RestrictedUpstreamMap } from './constant';
import useGraphStore, { RFState } from './store'; import useGraphStore, { RFState } from './store';
@ -108,7 +110,11 @@ export const useHandleDrop = () => {
}; };
export const useShowDrawer = () => { export const useShowDrawer = () => {
const [clickedNode, setClickedNode] = useState<Node>(); const {
clickedNodeId: clickNodeId,
setClickedNodeId,
getNode,
} = useGraphStore((state) => state);
const { const {
visible: drawerVisible, visible: drawerVisible,
hideModal: hideDrawer, hideModal: hideDrawer,
@ -117,19 +123,17 @@ export const useShowDrawer = () => {
const handleShow = useCallback( const handleShow = useCallback(
(node: Node) => { (node: Node) => {
setClickedNode(node); setClickedNodeId(node.id);
if (node.data.label !== Operator.Answer) {
showDrawer(); showDrawer();
}
}, },
[showDrawer], [showDrawer, setClickedNodeId],
); );
return { return {
drawerVisible, drawerVisible,
hideDrawer, hideDrawer,
showDrawer: handleShow, showDrawer: handleShow,
clickedNode, clickedNode: getNode(clickNodeId),
}; };
}; };
@ -270,3 +274,35 @@ export const useValidateConnection = () => {
return isValidConnection; return isValidConnection;
}; };
export const useHandleNodeNameChange = (node?: Node) => {
const [name, setName] = useState<string>('');
const { updateNodeName, nodes } = useGraphStore((state) => state);
const previousName = node?.data.name;
const id = node?.id;
const handleNameBlur = useCallback(() => {
const existsSameName = nodes.some((x) => x.data.name === name);
if (trim(name) === '' || existsSameName) {
if (existsSameName && previousName !== name) {
message.error('The name cannot be repeated');
}
setName(previousName);
return;
}
if (id) {
updateNodeName(id, name);
}
}, [name, id, updateNodeName, previousName, nodes]);
const handleNameChange = useCallback((e: ChangeEvent<any>) => {
setName(e.target.value);
}, []);
useEffect(() => {
setName(previousName);
}, [previousName]);
return { name, handleNameBlur, handleNameChange };
};

View File

@ -54,7 +54,8 @@ export interface ICategorizeForm extends IGenerateForm {
} }
export type NodeData = { export type NodeData = {
label: string; label: string; // operator type
name: string; // operator name
color: string; color: string;
form: IBeginForm | IRetrievalForm | IGenerateForm | ICategorizeForm; form: IBeginForm | IRetrievalForm | IGenerateForm | ICategorizeForm;
}; };

View File

@ -45,6 +45,7 @@ export const dsl = {
}, },
data: { data: {
label: 'Begin', label: 'Begin',
name: 'begin',
}, },
sourcePosition: 'left', sourcePosition: 'left',
targetPosition: 'right', targetPosition: 'right',

View File

@ -26,6 +26,7 @@ export type RFState = {
edges: Edge[]; edges: Edge[];
selectedNodeIds: string[]; selectedNodeIds: string[];
selectedEdgeIds: string[]; selectedEdgeIds: string[];
clickedNodeId: string; // currently selected node
onNodesChange: OnNodesChange; onNodesChange: OnNodesChange;
onEdgesChange: OnEdgesChange; onEdgesChange: OnEdgesChange;
onConnect: OnConnect; onConnect: OnConnect;
@ -46,6 +47,8 @@ export type RFState = {
findNodeByName: (operatorName: Operator) => Node | undefined; findNodeByName: (operatorName: Operator) => Node | undefined;
updateMutableNodeFormItem: (id: string, field: string, value: any) => void; updateMutableNodeFormItem: (id: string, field: string, value: any) => void;
getOperatorTypeFromId: (id?: string | null) => string | undefined; getOperatorTypeFromId: (id?: string | null) => string | undefined;
updateNodeName: (id: string, name: string) => void;
setClickedNodeId: (id?: string) => void;
}; };
// this is our useStore hook that we can use in our components to get parts of the store and call actions // this is our useStore hook that we can use in our components to get parts of the store and call actions
@ -56,6 +59,7 @@ const useGraphStore = create<RFState>()(
edges: [] as Edge[], edges: [] as Edge[],
selectedNodeIds: [] as string[], selectedNodeIds: [] as string[],
selectedEdgeIds: [] as string[], selectedEdgeIds: [] as string[],
clickedNodeId: '',
onNodesChange: (changes: NodeChange[]) => { onNodesChange: (changes: NodeChange[]) => {
set({ set({
nodes: applyNodeChanges(changes, get().nodes), nodes: applyNodeChanges(changes, get().nodes),
@ -119,9 +123,6 @@ const useGraphStore = create<RFState>()(
} }
} }
}, },
// addOnlyOneEdgeBetweenTwoNodes: (connection: Connection) => {
// },
duplicateNode: (id: string) => { duplicateNode: (id: string) => {
const { getNode, addNode } = get(); const { getNode, addNode } = get();
const node = getNode(id); const node = getNode(id);
@ -196,6 +197,22 @@ const useGraphStore = create<RFState>()(
lodashSet(nodes, [idx, 'data', 'form', field], value); lodashSet(nodes, [idx, 'data', 'form', field], value);
} }
}, },
updateNodeName: (id, name) => {
if (id) {
set({
nodes: get().nodes.map((node) => {
if (node.id === id) {
node.data.name = name;
}
return node;
}),
});
}
},
setClickedNodeId: (id?: string) => {
set({ clickedNodeId: id });
},
}), }),
{ name: 'graph' }, { name: 'graph' },
), ),

View File

@ -1,6 +1,7 @@
import { DSLComponents } from '@/interfaces/database/flow'; import { DSLComponents } from '@/interfaces/database/flow';
import { removeUselessFieldsFromValues } from '@/utils/form'; import { removeUselessFieldsFromValues } from '@/utils/form';
import dagre from 'dagre'; import dagre from 'dagre';
import { humanId } from 'human-id';
import { curry, isEmpty } from 'lodash'; import { curry, isEmpty } from 'lodash';
import pipe from 'lodash/fp/pipe'; import pipe from 'lodash/fp/pipe';
import { Edge, MarkerType, Node, Position } from 'reactflow'; import { Edge, MarkerType, Node, Position } from 'reactflow';
@ -61,6 +62,7 @@ export const buildNodesAndEdgesFromDSLComponents = (data: DSLComponents) => {
position: { x: 0, y: 0 }, position: { x: 0, y: 0 },
data: { data: {
label: componentName, label: componentName,
name: humanId(),
form: params, form: params,
}, },
sourcePosition: Position.Left, sourcePosition: Position.Left,