Commit bdfc974c authored by 吴永生#A02208's avatar 吴永生#A02208

feat: 添加节点

parent de23a8e5
...@@ -7,6 +7,10 @@ import ReactFlow, { ...@@ -7,6 +7,10 @@ import ReactFlow, {
Position, Position,
ReactFlowProps, ReactFlowProps,
Node, Node,
applyNodeChanges,
applyEdgeChanges,
EdgeChange,
NodeChange,
} from "react-flow-renderer"; } from "react-flow-renderer";
import { useCallback, useEffect, useMemo, useState } from "react"; import { useCallback, useEffect, useMemo, useState } from "react";
import classNames from "classnames"; import classNames from "classnames";
...@@ -22,6 +26,7 @@ import { ...@@ -22,6 +26,7 @@ import {
import { IBatchNode, ILine } from "./interface"; import { IBatchNode, ILine } from "./interface";
import styles from "./index.module.css"; import styles from "./index.module.css";
import { Tooltip } from "@mui/material";
/* /*
* @Author: 吴永生#A02208 yongsheng.wu@wholion.com * @Author: 吴永生#A02208 yongsheng.wu@wholion.com
* @Date: 2022-06-22 10:15:22 * @Date: 2022-06-22 10:15:22
...@@ -42,6 +47,8 @@ interface IProps extends ReactFlowProps { ...@@ -42,6 +47,8 @@ interface IProps extends ReactFlowProps {
type?: "edit" | "default"; type?: "edit" | "default";
/** 设置组件数据 组件为编辑状态使用 */ /** 设置组件数据 组件为编辑状态使用 */
setTasks?: (val: ITask[]) => void; setTasks?: (val: ITask[]) => void;
/** 点击流程node 节点 返回唯一标识符 */
onFlowNodeClick?: (val: string) => void;
} }
/** 获取imgUrl */ /** 获取imgUrl */
...@@ -61,40 +68,80 @@ const getImgUrl = (type: IExecutionStatus) => { ...@@ -61,40 +68,80 @@ const getImgUrl = (type: IExecutionStatus) => {
/** 自定义batch节点 */ /** 自定义batch节点 */
const BatchNode = (props: IBatchNode) => { const BatchNode = (props: IBatchNode) => {
const { data } = props; const { data } = props;
const { dotStatus, style, isFlowNode, label, selectedStatus } = data; const {
dotStatus,
style,
isFlowNode,
selectedStatus,
info: { title, isCheck, executionStatus, parameters },
} = data;
/** 获取输入参数数组 */
const inParamsArr = useMemo(() => {
return parameters.filter((item) => {
return item.parameterGroup === "in";
});
}, [parameters]);
/** 获取输出参数数组 */
const outParamsArr = useMemo(() => {
return parameters.filter((item) => {
return item.parameterGroup === "out";
});
}, [parameters]);
return ( return (
<div <div
className={classNames({ className={classNames({
[styles.batchNode]: true, [styles.batchNode]: true,
[styles.selectedBatchBox]: selectedStatus, [styles.selectedBatchBox]: selectedStatus,
[styles.runBatchNode]: data.executionStatus === "Running", [styles.runBatchNode]: executionStatus === "Running",
[styles.doneBatchNode]: data.executionStatus === "Done", [styles.doneBatchNode]: executionStatus === "Done",
[styles.errorBatchNode]: data.executionStatus === "Failed", [styles.errorBatchNode]: executionStatus === "Failed",
})} })}
style={style} style={style}
> >
{dotStatus?.isInput ? ( {inParamsArr?.length &&
<Handle inParamsArr.map((item, index) => {
style={{ background: "#fff ", border: "1px solid #D1D6DE", left: 20 }} return (
type="target" <Tooltip title={item.name}>
position={Position.Top} <Handle
/> // title={item.name}
) : null} style={{
background: "#fff ",
border: "1px solid #D1D6DE",
left: index * 20 + 20,
}}
type="target"
position={Position.Top}
/>
</Tooltip>
);
})}
<div <div
className={classNames({ className={classNames({
[styles.batchRotate]: isFlowNode, [styles.batchRotate]: isFlowNode,
})} })}
> >
{label || ""} {title || ""}
{data.isCheck && <span className={styles.successDot}></span>} {isCheck && <span className={styles.successDot}></span>}
</div> </div>
{dotStatus?.isOutput ? ( {outParamsArr?.length &&
<Handle outParamsArr.map((item, index) => {
style={{ background: "#fff ", border: "1px solid #D1D6DE", left: 20 }} return (
type="source" <Tooltip title={item.name}>
position={Position.Bottom} <Handle
/> style={{
) : null} background: "#fff ",
border: "1px solid #D1D6DE",
left: index * 20 + 20,
}}
type="source"
position={Position.Bottom}
/>
</Tooltip>
);
})}
</div> </div>
); );
}; };
...@@ -102,13 +149,17 @@ const BatchNode = (props: IBatchNode) => { ...@@ -102,13 +149,17 @@ const BatchNode = (props: IBatchNode) => {
/** 自定义flow节点 */ /** 自定义flow节点 */
const FlowNode = (props: any) => { const FlowNode = (props: any) => {
const { data } = props; const { data } = props;
const {
dotStatus,
info: { title, isCheck, executionStatus },
} = data;
return ( return (
<div <div
className={classNames({ className={classNames({
[styles.flowNode]: true, [styles.flowNode]: true,
})} })}
> >
{data?.dotStatus?.isInput ? ( {dotStatus?.isInput ? (
<Handle <Handle
style={{ background: "#C2C6CC ", left: 12 }} style={{ background: "#C2C6CC ", left: 12 }}
type="target" type="target"
...@@ -116,17 +167,17 @@ const FlowNode = (props: any) => { ...@@ -116,17 +167,17 @@ const FlowNode = (props: any) => {
/> />
) : null} ) : null}
<div style={{ display: "flex", alignItems: "center" }}> <div style={{ display: "flex", alignItems: "center" }}>
{data?.label || ""} {title || ""}
{data.isCheck && <span className={styles.successDot}></span>} {isCheck && <span className={styles.successDot}></span>}
{getImgUrl(data.executionStatus) && ( {getImgUrl(executionStatus) && (
<img <img
style={{ marginLeft: "6px" }} style={{ marginLeft: "6px" }}
src={getImgUrl(data.executionStatus)} src={getImgUrl(executionStatus)}
alt="" alt=""
/> />
)} )}
</div> </div>
{data?.dotStatus?.isOutput ? ( {dotStatus?.isOutput ? (
<Handle <Handle
style={{ background: "#C2C6CC ", left: 12 }} style={{ background: "#C2C6CC ", left: 12 }}
type="source" type="source"
...@@ -146,6 +197,7 @@ const Flow = (props: IProps) => { ...@@ -146,6 +197,7 @@ const Flow = (props: IProps) => {
selectedNodeId, selectedNodeId,
type: flowType = "default", type: flowType = "default",
setTasks, setTasks,
onFlowNodeClick,
} = props; } = props;
/** 自定义的节点类型 */ /** 自定义的节点类型 */
const nodeTypes = useMemo(() => { const nodeTypes = useMemo(() => {
...@@ -257,8 +309,8 @@ const Flow = (props: IProps) => { ...@@ -257,8 +309,8 @@ const Flow = (props: IProps) => {
type: item.type === "BATCH" ? "batchNode" : "flowNode", type: item.type === "BATCH" ? "batchNode" : "flowNode",
/** 每一项的数据 */ /** 每一项的数据 */
data: { data: {
label: item.title || "", // label: item.title || "",
info: item,
...(item.type === "BATCH" ...(item.type === "BATCH"
? { ? {
/** 是否有流节点 */ /** 是否有流节点 */
...@@ -269,12 +321,13 @@ const Flow = (props: IProps) => { ...@@ -269,12 +321,13 @@ const Flow = (props: IProps) => {
: inSideNodeId === item.id, : inSideNodeId === item.id,
} }
: {}), : {}),
/** 是否选中 */ // /** 是否选中 */
isCheck: item.isCheck, // isCheck: item.isCheck,
/** 运行状态 */ /** 运行状态 */
executionStatus: item.executionStatus, // executionStatus: item.executionStatus,
/** 输入输出圆点状态 */ /** 输入输出圆点状态 */
dotStatus: nodesInputAndOutputStatus(item.id), dotStatus: nodesInputAndOutputStatus(item.id),
/** 样式 */ /** 样式 */
style: { style: {
...getBatchStyle(item), ...getBatchStyle(item),
...@@ -359,6 +412,7 @@ const Flow = (props: IProps) => { ...@@ -359,6 +412,7 @@ const Flow = (props: IProps) => {
} }
} }
}); });
onFlowNodeClick && onFlowNodeClick(node.id);
}; };
const handlePaneClick = () => { const handlePaneClick = () => {
...@@ -367,9 +421,9 @@ const Flow = (props: IProps) => { ...@@ -367,9 +421,9 @@ const Flow = (props: IProps) => {
}; };
/** node节点 */ /** node节点 */
const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes); const [nodes, setNodes] = useNodesState(initialNodes);
/** 连线数组 */ /** 连线数组 */
const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges); const [edges, setEdges] = useEdgesState(initialEdges);
useEffect(() => { useEffect(() => {
setEdges(initialEdges); setEdges(initialEdges);
...@@ -379,6 +433,22 @@ const Flow = (props: IProps) => { ...@@ -379,6 +433,22 @@ const Flow = (props: IProps) => {
setNodes(initialNodes); setNodes(initialNodes);
}, [initialNodes, setNodes]); }, [initialNodes, setNodes]);
const onNodesChange = useCallback(
(changes: NodeChange[]) => {
console.log(changes, "1111");
setNodes((ns) => applyNodeChanges(changes, ns));
},
[setNodes]
);
const onEdgesChange = useCallback(
(changes: EdgeChange[]) => {
console.log(changes, "222222");
setEdges((es) => applyEdgeChanges(changes, es));
},
[setEdges]
);
return ( return (
<ReactFlow <ReactFlow
nodes={nodes} nodes={nodes}
......
...@@ -2,12 +2,13 @@ ...@@ -2,12 +2,13 @@
* @Author: 吴永生#A02208 yongsheng.wu@wholion.com * @Author: 吴永生#A02208 yongsheng.wu@wholion.com
* @Date: 2022-06-23 11:00:29 * @Date: 2022-06-23 11:00:29
* @LastEditors: 吴永生#A02208 yongsheng.wu@wholion.com * @LastEditors: 吴永生#A02208 yongsheng.wu@wholion.com
* @LastEditTime: 2022-07-07 11:23:14 * @LastEditTime: 2022-07-11 15:24:53
* @FilePath: /bkunyun/src/views/Project/components/Flow/interface.ts * @FilePath: /bkunyun/src/views/Project/components/Flow/interface.ts
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/ */
import { CSSProperties } from "react"; import { CSSProperties } from "react";
import { ITask } from "../../ProjectSubmitWork/interface";
/** 线的参数 */ /** 线的参数 */
export interface ILine { export interface ILine {
...@@ -40,7 +41,11 @@ export interface IBatchNodeData { ...@@ -40,7 +41,11 @@ export interface IBatchNodeData {
isCheck?: boolean; isCheck?: boolean;
/** 运行状态 */ /** 运行状态 */
executionStatus: string executionStatus: string
/** 每一项信息 */
info: ITask
} }
export interface IBatchNode { export interface IBatchNode {
data: IBatchNodeData data: IBatchNodeData
} }
\ No newline at end of file
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* @Author: 吴永生#A02208 yongsheng.wu@wholion.com * @Author: 吴永生#A02208 yongsheng.wu@wholion.com
* @Date: 2022-06-21 20:03:56 * @Date: 2022-06-21 20:03:56
* @LastEditors: 吴永生#A02208 yongsheng.wu@wholion.com * @LastEditors: 吴永生#A02208 yongsheng.wu@wholion.com
* @LastEditTime: 2022-07-11 11:31:14 * @LastEditTime: 2022-07-11 14:40:34
* @FilePath: /bkunyun/src/views/Project/ProjectSubmitWork/index.tsx * @FilePath: /bkunyun/src/views/Project/ProjectSubmitWork/index.tsx
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/ */
...@@ -69,6 +69,7 @@ const WorkFlowEdit = (props: IProps) => { ...@@ -69,6 +69,7 @@ const WorkFlowEdit = (props: IProps) => {
const handleNodeClick = useCallback((val: string) => { const handleNodeClick = useCallback((val: string) => {
setSelectTaskId(val); setSelectTaskId(val);
}, []); }, []);
return ( return (
<div className={styles.swBox}> <div className={styles.swBox}>
<div className={styles.swHeader}> <div className={styles.swHeader}>
...@@ -148,6 +149,7 @@ const WorkFlowEdit = (props: IProps) => { ...@@ -148,6 +149,7 @@ const WorkFlowEdit = (props: IProps) => {
tasks={templateConfigInfo} tasks={templateConfigInfo}
setTasks={setTemplateConfigInfo} setTasks={setTemplateConfigInfo}
type="edit" type="edit"
onFlowNodeClick={handleNodeClick}
/> />
</div> </div>
</div> </div>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment