(false);
+ // const [selectionNode, setSelectionNode] = useState([]);
// 选区左上角坐标(x1,y1) 右下角坐标(x2,y2)
- let selectPosition = {x1: 0, y1: 0, x2: 0, y2: 0};
+ // let selectPosition = {x1: 0, y1: 0, x2: 0, y2: 0};
const onSelectionChange = useCallback((flowItem) => {
- if (flowItem.nodes.length > 1) {
- flowItem.nodes.forEach(node => {
- selectPosition.x1 = selectPosition.x1 ? Math.min(node.position.x, selectPosition.x1) : node.position.x;
- selectPosition.y1 = selectPosition.y1 ? Math.min(node.position.y, selectPosition.y1) : node.position.y;
+ // if (flowItem.nodes.length > 1) {
+ // flowItem.nodes.forEach(node => {
+ // selectPosition.x1 = selectPosition.x1 ? Math.min(node.position.x, selectPosition.x1) : node.position.x;
+ // selectPosition.y1 = selectPosition.y1 ? Math.min(node.position.y, selectPosition.y1) : node.position.y;
- selectPosition.x2 = Math.max(node.position.x + node.width, selectPosition.x2);
- selectPosition.y2 = Math.max(node.position.y + node.height, selectPosition.y2);
- });
- setIsSelecting(() => true);
- setSelectionNode(flowItem.nodes);
- } else {
- setIsSelecting(() => false);
- setSelectionNode([]);
- }
- setLastSelection(flow);
- }, [isSelecting, setSelectionNode]);
+ // selectPosition.x2 = Math.max(node.position.x + node.width, selectPosition.x2);
+ // selectPosition.y2 = Math.max(node.position.y + node.height, selectPosition.y2);
+ // });
+ // setIsSelecting(() => true);
+ // setSelectionNode(flowItem.nodes);
+ // } else {
+ // setIsSelecting(() => false);
+ // setSelectionNode([]);
+ // }
+ setLastSelection(flowItem);
+ }, []);
+ // }, [isSelecting, setSelectionNode]);
const [selectionMenuVisible, setSelectionMenuVisible] = useState(false);
const [selectionEnded, setSelectionEnded] = useState(true);
// Workaround to show the menu only after the selection has ended.
useEffect(() => {
- if (selectionEnded && lastSelection && lastSelection.nodes && lastSelection.nodes.length > 1) {
+ console.log(lastSelection)
+ // if (selectionEnded && lastSelection && lastSelection.nodes && lastSelection.nodes.length > 1) {
+ if (selectionEnded && lastSelection && lastSelection.nodes.length > 1) {
setSelectionMenuVisible(true);
} else {
setSelectionMenuVisible(false);
@@ -171,39 +181,39 @@ export default function Page({flow, preFlow}: { flow: FlowType, preFlow: string
);
// 分组节点内边距
- const groupPadding = 50;
+ // const groupPadding = 50;
// 分组节点标题高度
- const groupTitleHeight = 0;
+ // const groupTitleHeight = 0;
// 创建分组
- const createGroup = useCallback(() => {
- let selectionIds = selectionNode.map(node => node.id);
- let newId = getNodeId("groupNode");
- let newNode = {
- data: {},
- l2_name: 'groupNode',
- id: newId,
- type: "groupNode",
- style: {
- width: selectPosition.x2 - selectPosition.x1 + groupPadding * 2,
- height: selectPosition.y2 - selectPosition.y1 + groupTitleHeight + groupPadding * 2,
- zIndex: -1
- },
- position: {
- x: selectPosition.x1 - groupPadding,
- y: selectPosition.y1 - groupPadding - groupTitleHeight
- }
- };
- setNodes((nds) => {
- nds.forEach(nd => {
- if (selectionIds.indexOf(nd.id) >= 0) {
- nd.parentNode = newId;
- nd.position.x -= (selectPosition.x1 - groupPadding);
- nd.position.y -= (selectPosition.y1 - groupPadding - groupTitleHeight);
- }
- });
- return nds.concat(newNode);
- });
- }, [selectionNode, setNodes]);
+ // const createGroup = useCallback(() => {
+ // let selectionIds = selectionNode.map(node => node.id);
+ // let newId = getNodeId("groupNode");
+ // let newNode = {
+ // data: {},
+ // l2_name: 'groupNode',
+ // id: newId,
+ // type: "groupNode",
+ // style: {
+ // width: selectPosition.x2 - selectPosition.x1 + groupPadding * 2,
+ // height: selectPosition.y2 - selectPosition.y1 + groupTitleHeight + groupPadding * 2,
+ // zIndex: -1
+ // },
+ // position: {
+ // x: selectPosition.x1 - groupPadding,
+ // y: selectPosition.y1 - groupPadding - groupTitleHeight
+ // }
+ // };
+ // setNodes((nds) => {
+ // nds.forEach(nd => {
+ // if (selectionIds.indexOf(nd.id) >= 0) {
+ // nd.parentNode = newId;
+ // nd.position.x -= (selectPosition.x1 - groupPadding);
+ // nd.position.y -= (selectPosition.y1 - groupPadding - groupTitleHeight);
+ // }
+ // });
+ // return nds.concat(newNode);
+ // });
+ // }, [selectionNode, setNodes]);
// const deleteGroup = useCallback((groupId) => {
// setNodes((nds) => {
@@ -218,28 +228,28 @@ export default function Page({flow, preFlow}: { flow: FlowType, preFlow: string
// }, [setNodes]);
// 进入多选模式后添加一个可点击的按钮节点
- useEffect(() => {
- if (isSelecting) {// 多选模式
- let newNode = {
- selectable: false,
- data: {
- createGroup: createGroup
- },
- id: "multipartNode",
- type: 'frameSelectToolbar',
- position: {
- x: selectPosition.x1,
- y: selectPosition.y1 - 50
- }
- };
- setNodes((nds) => nds.concat(newNode));
- } else {
- // 延时进程队列,防止还未触发点击事件,按钮就消失
- setTimeout(() => {
- setNodes((nds) => nds.filter((nd) => nd.id !== 'multipartNode'));
- }, 100);
- }
- }, [isSelecting, setNodes]);
+ // useEffect(() => {
+ // if (isSelecting) {// 多选模式
+ // let newNode = {
+ // selectable: false,
+ // data: {
+ // createGroup: createGroup
+ // },
+ // id: "multipartNode",
+ // type: 'frameSelectToolbar',
+ // position: {
+ // x: selectPosition.x1,
+ // y: selectPosition.y1 - 50
+ // }
+ // };
+ // setNodes((nds) => nds.concat(newNode));
+ // } else {
+ // // 延时进程队列,防止还未触发点击事件,按钮就消失
+ // setTimeout(() => {
+ // setNodes((nds) => nds.filter((nd) => nd.id !== 'multipartNode'));
+ // }, 100);
+ // }
+ // }, [isSelecting, setNodes]);
// const deleteGroup = useCallback((groupId) => {
// setNodes((nds) => {
@@ -261,7 +271,7 @@ export default function Page({flow, preFlow}: { flow: FlowType, preFlow: string
{
...params,
style: {stroke: "#555"},
- type: 'clearableEdge',
+ // type: 'clearableEdge',
className:
(params.targetHandle.split("|")[0] === "Text"
? "stroke-foreground "
@@ -339,8 +349,6 @@ export default function Page({flow, preFlow}: { flow: FlowType, preFlow: string
y: event.clientY - reactflowBounds.top,
});
- console.log(position);
-
// Generate a unique node ID
let {type} = data;
let newId = getNodeId(type);
@@ -414,7 +422,11 @@ export default function Page({flow, preFlow}: { flow: FlowType, preFlow: string
// 离开并保存
const handleSaveAndClose = async () => {
- await saveFlow(flow, true)
+ // await saveFlow(flow, true)
+ // blocker.proceed?.()
+ setFlow('leave and save', { ...flow })
+
+ await captureAndAlertRequestErrorHoc(updateVersion(version.id, { name: version.name, description: '', data: flow.data }))
blocker.proceed?.()
}
@@ -441,6 +453,7 @@ export default function Page({flow, preFlow}: { flow: FlowType, preFlow: string
}, [flow.data]); // 修改 id后, 需要监听 data这一层
return <>
+
{Object.keys(data).length ?
: <>>}
{/* Main area */}
@@ -464,7 +477,7 @@ export default function Page({flow, preFlow}: { flow: FlowType, preFlow: string
disableKeyboardA11y={true}
onInit={setReactFlowInstance}
nodeTypes={nodeTypes}
- edgeTypes={edgeTypes}
+ // edgeTypes={edgeTypes}
onEdgeUpdate={onEdgeUpdate}
onEdgeUpdateStart={onEdgeUpdateStart}
onEdgeUpdateEnd={onEdgeUpdateEnd}
@@ -540,7 +553,7 @@ export default function Page({flow, preFlow}: { flow: FlowType, preFlow: string
]);
} else {
setErrorData({
- title: "Invalid selection",
+ title: "无效的选择",
list: valiDateRes,
});
}
@@ -548,7 +561,11 @@ export default function Page({flow, preFlow}: { flow: FlowType, preFlow: string
/>
-
{flow.name}
+ {/*
{flow.name}
*/}
+
+
{flow.name}
+
{t('skills.currentVersion')}{version?.name}
+
) : (
<>>
diff --git a/src/pages/FlowPage/components/SelectionMenuComponent/index.tsx b/src/pages/FlowPage/components/SelectionMenuComponent/index.tsx
index 13e2897..f7f75f9 100644
--- a/src/pages/FlowPage/components/SelectionMenuComponent/index.tsx
+++ b/src/pages/FlowPage/components/SelectionMenuComponent/index.tsx
@@ -34,7 +34,7 @@ export default function SelectionMenu({ onClick, nodes, isVisible }) {
lastNodes && lastNodes.length > 0 ? lastNodes.map((n) => n.id) : []
}
>
-
+ {/*
*/}
+
+
);
diff --git a/src/pages/FlowPage/components/extraSidebarComponent/index.tsx b/src/pages/FlowPage/components/extraSidebarComponent/index.tsx
index ad2369f..9a20cba 100644
--- a/src/pages/FlowPage/components/extraSidebarComponent/index.tsx
+++ b/src/pages/FlowPage/components/extraSidebarComponent/index.tsx
@@ -42,7 +42,7 @@ export default function ExtraSidebar({ flow }: { flow: FlowType }) {
const { notificationCenter, setNotificationCenter, setSuccessData, setErrorData } = useContext(alertContext);
const [dataFilter, setFilterData] = useState(data);
const [search, setSearch] = useState("");
- const isPending = tabsState[flow.id]?.isPending;
+ // const isPending = tabsState[flow.id]?.isPending;
const [launch, setLaunch] = useState(true);
const [npc_zujianGengduo, setNpc_zujianGengduo] = useState(true);
const [npc_zujianScrollTop, setNpc_zujianScrollTop] = useState(0);
@@ -102,13 +102,16 @@ export default function ExtraSidebar({ flow }: { flow: FlowType }) {
{/* 简化 */}
-
+ {/*
+ {isPending ?

+ saveFlow(flow).then(_ =>
+ _ && setSuccessData({ title: t('success') }))
+ } className="w-[27px] ml-[1px] cursor-pointer" alt="" /> :

}
-
+
*/}
{/* 顶部按钮组 */}
{/*
@@ -173,14 +167,14 @@ export default function ExtraSidebar({ flow }: { flow: FlowType }) {
*/}
-
+ {/*

{ openPopUp(
); }} alt="" />

{ openPopUp(
); }} alt="" />

{ takeSnapshot(); uploadFlow() }} alt="" />
{isPending ?

saveFlow(flow).then(_ =>
_ && setSuccessData({ title: t('success') }))
- } className="w-[27px] ml-[1px] cursor-pointer" alt="" /> :

}
+ } className="w-[27px] ml-[1px] cursor-pointer" alt="" /> :

} */}
{/*
*/}
-
+ {/*
*/}
{/* */}
{/*
{/* 高级配置l2配置 */}
{
- saveFlow(flow, true);
+ saveFlow(flow);
setSuccessData({ title: t('success') });
}}>
diff --git a/src/pages/FlowPage/components/nodeToolbarComponent/index.tsx b/src/pages/FlowPage/components/nodeToolbarComponent/index.tsx
index 990efca..381c7b3 100644
--- a/src/pages/FlowPage/components/nodeToolbarComponent/index.tsx
+++ b/src/pages/FlowPage/components/nodeToolbarComponent/index.tsx
@@ -1,6 +1,6 @@
import { Combine, Copy, Download, MoreHorizontal, SaveAll, Settings2, Trash2 } from "lucide-react";
import cloneDeep from "lodash-es/cloneDeep";
-import { useContext, useState } from "react";
+import { useContext, useMemo, useState } from "react";
import { useReactFlow } from "reactflow";
import ShadTooltip from "../../../../components/ShadTooltipComponent";
import { TabsContext } from "../../../../contexts/tabsContext";
@@ -13,6 +13,9 @@ import { userContext } from "../../../../contexts/userContext";
import { bsconfirm } from "../../../../alerts/confirm";
import { alertContext } from "../../../../contexts/alertContext";
import React from "react";
+import { typesContext } from "@/contexts/typesContext";
+import { useNavigate, useParams } from "react-router-dom";
+import { CounterClockwiseClockIcon } from "@radix-ui/react-icons";
const NodeToolbarComponent = ({ data, deleteNode, openPopUp, position }) => {
const [nodeLength, setNodeLength] = useState(
@@ -31,7 +34,7 @@ const NodeToolbarComponent = ({ data, deleteNode, openPopUp, position }) => {
).length
);
- const { paste } = useContext(TabsContext);
+ const { version, paste } = useContext(TabsContext);
const reactFlowInstance = useReactFlow();
const isGroup = !!data.node?.flow;
@@ -44,6 +47,14 @@ const NodeToolbarComponent = ({ data, deleteNode, openPopUp, position }) => {
});
}
+ const { types } = useContext(typesContext);
+ const hasVersion = useMemo(() => {
+ // 部分组件开放“历史/history”入口:agent、chains、retrievers 、vector store 4类组件。
+ return ["chains", "agents", "vectorstores", "retrievers"].includes(types[data.type])
+ }, [data, types])
+
+ const navigate = useNavigate()
+ const { id: flowId } = useParams()
const { addSavedComponent, checkComponentsName } = useContext(userContext)
const handleSelectChange = (event) => {
switch (event) {
@@ -80,6 +91,13 @@ const NodeToolbarComponent = ({ data, deleteNode, openPopUp, position }) => {
break;
case "disabled":
break;
+ case "version":
+ navigate(`/diff/${flowId}/${version.id}/${data.id}`)
+ break;
+ case "export":
+ const cleanFlow = removeApiKeys({ data: { nodes: [{ data }] } } as any)
+ downloadNode(cleanFlow.data.nodes[0].data);
+ break;
case "ungroup":
takeSnapshot();
expandGroupNode(
@@ -130,6 +148,17 @@ const NodeToolbarComponent = ({ data, deleteNode, openPopUp, position }) => {
{/**/}
+ {/* 版本 */}
+ {
+ hasVersion && !isGroup &&
+
+
+ }
{nodeLength > 0 && (
@@ -169,6 +198,17 @@ const NodeToolbarComponent = ({ data, deleteNode, openPopUp, position }) => {
+ {isGroup && (
+
+
+
+ )}
+
+
{/* more */}
{/*