|
|
@@ -22,11 +22,11 @@ import ReactFlow, {
|
|
|
useReactFlow,
|
|
|
} from "reactflow";
|
|
|
import GenericNode from "../../../../CustomNodes/GenericNode";
|
|
|
-import FrameSelectToolbar from "../FrameSelectToolbarComponent";
|
|
|
-import GroupNode from "../../../../CustomNodes/GroupNode";
|
|
|
-import ClearableEdge from "../../../../CustomEdges/ClearableEdge";
|
|
|
+// import FrameSelectToolbar from "../FrameSelectToolbarComponent";
|
|
|
+// import GroupNode from "../../../../CustomNodes/GroupNode";
|
|
|
+// import ClearableEdge from "../../../../CustomEdges/ClearableEdge";
|
|
|
import Chat from "../../../../components/chatComponent";
|
|
|
-import { Button } from "../../../../components/ui/button";
|
|
|
+// import { Button } from "../../../../components/ui/button";
|
|
|
import { TabsContext } from "../../../../contexts/tabsContext";
|
|
|
import { typesContext } from "../../../../contexts/typesContext";
|
|
|
import { undoRedoContext } from "../../../../contexts/undoRedoContext";
|
|
|
@@ -39,19 +39,26 @@ import ConnectionLineComponent from "../ConnectionLineComponent";
|
|
|
import SelectionMenu from "../SelectionMenuComponent";
|
|
|
import ExtraSidebar from "../extraSidebarComponent";
|
|
|
import { alertContext } from "../../../../contexts/alertContext";
|
|
|
+import Header from "../Header";
|
|
|
+import { Badge } from "@/components/bs-ui/badge";
|
|
|
+import { LayersIcon } from "@radix-ui/react-icons";
|
|
|
+import { Button } from "@/components/bs-ui/button";
|
|
|
+import { updateVersion } from "@/controllers/API/flow";
|
|
|
+import { captureAndAlertRequestErrorHoc } from "@/controllers/request";
|
|
|
|
|
|
const nodeTypes = {
|
|
|
genericNode: GenericNode,
|
|
|
- frameSelectToolbar: FrameSelectToolbar,
|
|
|
- groupNode: GroupNode
|
|
|
+ // frameSelectToolbar: FrameSelectToolbar,
|
|
|
+ // groupNode: GroupNode
|
|
|
};
|
|
|
|
|
|
const edgeTypes = {
|
|
|
- clearableEdge: ClearableEdge
|
|
|
+ // clearableEdge: ClearableEdge
|
|
|
};
|
|
|
|
|
|
export default function Page({flow, preFlow}: { flow: FlowType, preFlow: string }) {
|
|
|
let {
|
|
|
+ version,
|
|
|
setFlow,
|
|
|
setTabsState,
|
|
|
saveFlow,
|
|
|
@@ -72,34 +79,37 @@ export default function Page({flow, preFlow}: { flow: FlowType, preFlow: string
|
|
|
const { takeSnapshot } = useContext(undoRedoContext);
|
|
|
// 快捷键
|
|
|
const { keyBoardPanneRef, lastSelection, setLastSelection } = useKeyBoard(reactFlowWrapper)
|
|
|
- const [isSelecting, setIsSelecting] = useState<Boolean>(false);
|
|
|
- const [selectionNode, setSelectionNode] = useState([]);
|
|
|
+ // const [isSelecting, setIsSelecting] = useState<Boolean>(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;
|
|
|
-
|
|
|
- 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]);
|
|
|
+ // 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(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 <>
|
|
|
+ <Header flow={flow}></Header>
|
|
|
<div className="flex h-full overflow-hidden">
|
|
|
{Object.keys(data).length ? <ExtraSidebar flow={flow} /> : <></>}
|
|
|
{/* 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
|
|
|
/>
|
|
|
</ReactFlow>
|
|
|
<Chat flow={flow} reactFlowInstance={reactFlowInstance} />
|
|
|
- <p className="absolute top-0 left-[25%] w-[50%] text-[16px] mt-[14px]" style={{textAlign:"center",fontWeight:"600",color:"#fff"}}>{flow.name}</p>
|
|
|
+ {/* <p className="absolute top-0 left-[25%] w-[50%] text-[16px] mt-[14px]" style={{textAlign:"center",fontWeight:"600",color:"#fff"}}>{flow.name}</p> */}
|
|
|
+ <div className="absolute top-0 left-[25%] w-[50%] mt-[14px] flex justify-center items-center">
|
|
|
+ <p className="text-[#FFFFFF] text-[16px]" style={{fontWeight:"600"}}>{flow.name}</p>
|
|
|
+ <div className="w-[95px] h-[20px] bg-[#1A1A1A] text-[#999999] text-[11px] ml-[20px] flex items-center justify-center" style={{borderRadius:"10px"}}>{t('skills.currentVersion')}{version?.name}</div>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
) : (
|
|
|
<></>
|