Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
B
bkunyun
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Administrator
bkunyun
Commits
93b21ec8
Commit
93b21ec8
authored
Aug 05, 2022
by
chenshouchao
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: 新增批算子联调前提交
parent
86b7b820
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
501 additions
and
32 deletions
+501
-32
api_manager.ts
src/api/api_manager.ts
+2
-0
project_api.ts
src/api/project_api.ts
+41
-1
index.module.css
...CommonComponents/RadioGroupOfButtonStyle/index.module.css
+3
-13
index.module.css
...s/CustomOperator/components/OperatorList/index.module.css
+17
-3
index.tsx
src/views/CustomOperator/components/OperatorList/index.tsx
+0
-0
index.tsx
src/views/CustomOperator/components/SaveOperator/index.tsx
+213
-0
index.tsx
src/views/CustomOperator/index.tsx
+155
-9
index.module.css
...onents/Flow/components/BatchOperatorFlow/index.module.css
+3
-0
index.tsx
...ct/components/Flow/components/BatchOperatorFlow/index.tsx
+0
-0
index.tsx
...ews/Project/components/Flow/components/FlowNode/index.tsx
+67
-6
No files found.
src/api/api_manager.ts
View file @
93b21ec8
...
@@ -41,6 +41,8 @@ const RESTAPI = {
...
@@ -41,6 +41,8 @@ const RESTAPI = {
API_SAVE_USERSPEC
:
`
${
BACKEND_API_URI_PREFIX
}
/cpp/workflow/saveuserspec`
,
// 保存用户自定义工作流模板
API_SAVE_USERSPEC
:
`
${
BACKEND_API_URI_PREFIX
}
/cpp/workflow/saveuserspec`
,
// 保存用户自定义工作流模板
API_OVERVIEW_GET
:
`
${
BACKEND_API_URI_PREFIX
}
/cpp/basicInformation`
,
// 获取概览基本信息
API_OVERVIEW_GET
:
`
${
BACKEND_API_URI_PREFIX
}
/cpp/basicInformation`
,
// 获取概览基本信息
API_TASK_OVERVIEW_LIST
:
`
${
BACKEND_API_URI_PREFIX
}
/cpp/workflowJobInformation`
,
// 查询任务概览
API_TASK_OVERVIEW_LIST
:
`
${
BACKEND_API_URI_PREFIX
}
/cpp/workflowJobInformation`
,
// 查询任务概览
API_OPERATOR_LISTSTREAMACTORS
:
`
${
BACKEND_API_URI_PREFIX
}
/cpp/workflow/liststreamactors`
,
// 获取流算子列表,可用于模糊查询,返回所有版本流算子
API_SAVE_BATCHACTOR
:
`
${
BACKEND_API_URI_PREFIX
}
/cpp/workflow/savebatchactor`
,
// 保存批算子
};
};
export
default
RESTAPI
;
export
default
RESTAPI
;
src/api/project_api.ts
View file @
93b21ec8
...
@@ -270,6 +270,44 @@ const getTaskOverview=(params:getTaskOverviewParams)=>{
...
@@ -270,6 +270,44 @@ const getTaskOverview=(params:getTaskOverviewParams)=>{
})
})
}
}
// 获取流算子列表,可用于模糊查询,返回所有版本流算子
type
getOperatorListParams
=
{
productId
:
string
;
keyword
?:
string
;
page
?:
number
;
size
?:
number
;
};
const
getOperatorList
=
(
params
:
getOperatorListParams
)
=>
{
return
request
({
url
:
Api
.
API_OPERATOR_LISTSTREAMACTORS
,
method
:
"get"
,
params
,
})
}
type
saveBatchQuery
=
{
productId
:
string
;
batchName
:
string
;
batchVersion
:
string
;
description
?:
string
;
isEdit
?:
string
;
}
type
saveBatchBody
=
Array
<
any
>
type
saveBatchParams
=
{
query
:
saveBatchQuery
;
body
:
saveBatchBody
;
}
// 提交工作流
const
saveBatchActor
=
(
params
:
saveBatchParams
)
=>
{
return
request
({
url
:
Api
.
API_SAVE_BATCHACTOR
,
method
:
"post"
,
params
:
params
.
query
,
data
:
params
.
body
,
});
};
export
{
export
{
current
,
current
,
...
@@ -292,5 +330,7 @@ export {
...
@@ -292,5 +330,7 @@ export {
submitWorkFlow
,
submitWorkFlow
,
getworkFlowTaskInfo
,
getworkFlowTaskInfo
,
getOverviewInfo
,
getOverviewInfo
,
getTaskOverview
getTaskOverview
,
getOperatorList
,
saveBatchActor
};
};
src/components/CommonComponents/RadioGroupOfButtonStyle/index.module.css
View file @
93b21ec8
...
@@ -4,7 +4,7 @@
...
@@ -4,7 +4,7 @@
align-items
:
center
;
align-items
:
center
;
border
:
1px
solid
#e6e8eb
;
border
:
1px
solid
#e6e8eb
;
border-radius
:
4px
;
border-radius
:
4px
;
background-color
:
#
F0F2F
5
;
background-color
:
#
f0f2f
5
;
cursor
:
pointer
;
cursor
:
pointer
;
height
:
32px
;
height
:
32px
;
box-sizing
:
border-box
;
box-sizing
:
border-box
;
...
@@ -12,7 +12,7 @@
...
@@ -12,7 +12,7 @@
}
}
.radio
{
.radio
{
position
:
relative
;
position
:
relative
;
min-width
:
6
4
px
;
min-width
:
6
3
px
;
height
:
28px
;
height
:
28px
;
box-sizing
:
border-box
;
box-sizing
:
border-box
;
font-size
:
14px
;
font-size
:
14px
;
...
@@ -28,18 +28,8 @@
...
@@ -28,18 +28,8 @@
white-space
:
nowrap
;
white-space
:
nowrap
;
}
}
.radio
:not
(
:last-child
)
::before
{
position
:
absolute
;
width
:
1px
;
height
:
16px
;
top
:
6px
;
right
:
0
;
content
:
''
;
background-color
:
#D1D6DE
;
}
.radioActive
{
.radioActive
{
color
:
#1370ff
;
color
:
#1370ff
;
background-color
:
#fff
;
background-color
:
#fff
;
box-shadow
:
2px
4px
12px
0px
rgba
(
0
,
27
,
63
,
0.06
);
box-shadow
:
2px
4px
12px
0px
rgba
(
0
,
27
,
63
,
0.06
);
}
}
src/views/CustomOperator/components/OperatorList/index.module.css
View file @
93b21ec8
...
@@ -38,22 +38,36 @@
...
@@ -38,22 +38,36 @@
}
}
.li
{
.li
{
background-color
:
RGBA
(
240
,
242
,
245
,
1
);
background-color
:
RGBA
(
240
,
242
,
245
,
1
);
padding
:
7px
7px
7px
28
px
;
padding
:
7px
9
px
;
color
:
rgba
(
30
,
38
,
51
,
1
);
color
:
rgba
(
30
,
38
,
51
,
1
);
font-size
:
14px
;
font-size
:
14px
;
line-height
:
22px
;
line-height
:
22px
;
margin-bottom
:
12px
;
margin-bottom
:
12px
;
position
:
relative
;
position
:
relative
;
display
:
flex
;
justify-content
:
space-between
;
align-items
:
center
;
}
.nameVersion
{
flex
:
1
;
/* text-align: left; */
margin-left
:
13px
;
word-wrap
:
break-word
;
/* text-overflow: clip; */
max-width
:
140px
;
}
}
.name
{
.name
{
margin-right
:
8px
;
margin-right
:
8px
;
}
}
.version
{
white-space
:
nowrap
;
}
.icon
{
.icon
{
width
:
6px
;
width
:
6px
;
height
:
10px
;
height
:
10px
;
position
:
absolute
;
/*
position: absolute;
top: 13px;
top: 13px;
left
:
9px
;
left: 9px;
*/
display
:
flex
;
display
:
flex
;
flex-direction
:
column
;
flex-direction
:
column
;
justify-content
:
space-between
;
justify-content
:
space-between
;
...
...
src/views/CustomOperator/components/OperatorList/index.tsx
View file @
93b21ec8
This diff is collapsed.
Click to expand it.
src/views/CustomOperator/components/SaveOperator/index.tsx
0 → 100644
View file @
93b21ec8
import
{
saveUserSpec
}
from
"@/api/workbench_api"
;
import
MyDialog
from
"@/components/mui/MyDialog"
;
import
MyInput
from
"@/components/mui/MyInput"
;
import
{
checkIsNumberLetterChinese
}
from
"@/utils/util"
;
import
{
useState
}
from
"react"
;
import
useMyRequest
from
"@/hooks/useMyRequest"
;
import
{
useStores
}
from
"@/store"
;
import
styles
from
"./index.module.css"
;
import
{
useMessage
}
from
"@/components/MySnackbar"
;
import
{
toJS
}
from
"mobx"
;
import
{
ITask
}
from
"@/views/Project/ProjectSubmitWork/interface"
;
interface
IProps
{
saveFormDialog
:
boolean
;
setSaveFormDialog
:
(
val
:
boolean
)
=>
void
;
onBack
?:
()
=>
void
;
title
:
string
;
setTitle
:
(
val
:
string
)
=>
void
;
version
:
string
;
setVersion
:
(
val
:
string
)
=>
void
;
description
:
string
;
setDescription
:
(
val
:
string
)
=>
void
;
creator
?:
string
;
templateConfigInfo
:
ITask
[];
id
?:
string
;
}
const
SaveOperator
=
(
props
:
IProps
)
=>
{
const
{
saveFormDialog
,
setSaveFormDialog
,
onBack
,
title
,
setTitle
,
version
,
setVersion
,
description
,
setDescription
,
templateConfigInfo
,
creator
,
id
,
}
=
props
;
const
{
currentProjectStore
}
=
useStores
();
const
Message
=
useMessage
();
const
productId
=
toJS
(
currentProjectStore
.
currentProductInfo
.
id
);
const
[
titleHelper
,
setTitleHelper
]
=
useState
({
// 算子名称错误提示
error
:
false
,
helperText
:
""
,
});
const
[
versionHelper
,
setVersionHelper
]
=
useState
({
// 算子版本错误提示
error
:
false
,
helperText
:
""
,
});
// 算子保存方法
const
{
run
:
saveUserSpecRun
}
=
useMyRequest
(
saveUserSpec
,
{
onSuccess
:
(
res
)
=>
{
Message
.
success
(
"保存成功!"
);
onBack
&&
onBack
();
},
});
// 关闭表单弹窗
const
handleCloseDialog
=
()
=>
{
setSaveFormDialog
(
false
);
};
// 算子名称
const
handleTitleChange
=
(
e
:
any
)
=>
{
const
title
=
e
.
target
.
value
;
setTitle
(
title
);
checkTitle
(
title
);
};
// 算子版本
const
handleVersionChange
=
(
e
:
any
)
=>
{
let
version
=
e
.
target
.
value
;
setVersion
(
version
);
checkVersion
(
version
);
};
// 算子描述
const
handleDescriptionChange
=
(
e
:
any
)
=>
{
let
description
=
e
.
target
.
value
;
if
(
description
.
length
<
301
)
{
setDescription
(
description
);
}
};
// 校验算子名称
const
checkTitle
=
(
title
:
string
)
=>
{
if
(
!
title
)
{
setTitleHelper
({
error
:
true
,
helperText
:
"必须输入算子名称"
,
});
return
false
;
}
else
if
(
title
.
length
>
15
)
{
setTitleHelper
({
error
:
true
,
helperText
:
"格式不正确,必须在15字符以内,仅限大小写字母、数字、中文"
,
});
return
false
;
}
else
if
(
!
checkIsNumberLetterChinese
(
title
))
{
setTitleHelper
({
error
:
true
,
helperText
:
"格式不正确,必须在15字符以内,仅限大小写字母、数字、中文"
,
});
return
false
;
}
else
{
setTitleHelper
({
error
:
false
,
helperText
:
""
,
});
return
true
;
}
};
// 校验版本号格式
const
checkVersion
=
(
version
:
string
)
=>
{
if
(
/^
[
1-9
]\d?(\.(
0|
[
1-9
]\d?)){2}
$/
.
test
(
version
))
{
setVersionHelper
({
error
:
false
,
helperText
:
""
,
});
}
else
{
setVersionHelper
({
error
:
true
,
helperText
:
"格式不正确,必须为X.Y.Z格式,且XYZ必须为0~99的正整数"
,
});
return
false
;
}
};
// 表单弹窗确定,新建算子
const
handleOncofirm
=
()
=>
{
if
(
checkTitle
(
title
)
&&
checkVersion
(
version
))
{
if
(
id
)
{
saveUserSpecRun
({
title
,
version
,
description
,
tasks
:
templateConfigInfo
,
productId
,
id
,
creator
,
});
}
else
{
saveUserSpecRun
({
title
,
version
,
description
,
tasks
:
templateConfigInfo
,
productId
,
});
}
}
};
return
(
<
MyDialog
open=
{
saveFormDialog
}
title=
"保存算子"
onClose=
{
handleCloseDialog
}
onConfirm=
{
handleOncofirm
}
>
<
div
className=
{
styles
.
saveBox
}
>
<
MyInput
value=
{
title
}
label=
"算子名称"
onChange=
{
handleTitleChange
}
required
error=
{
titleHelper
.
error
}
helperText=
{
titleHelper
.
helperText
}
style=
{
{
margin
:
"20px 0"
}
}
disabled=
{
id
?
true
:
false
}
></
MyInput
>
<
MyInput
value=
{
version
}
label=
"版本号"
onChange=
{
handleVersionChange
}
error=
{
versionHelper
.
error
}
helperText=
{
versionHelper
.
helperText
}
style=
{
{
marginBottom
:
"20px"
}
}
></
MyInput
>
<
div
style=
{
{
position
:
"relative"
}
}
>
<
MyInput
value=
{
description
}
id=
"desc"
label=
"模板描述"
placeholder=
"模板描述"
onChange=
{
handleDescriptionChange
}
multiline
rows=
{
4
}
/>
<
span
style=
{
{
position
:
"absolute"
,
bottom
:
"7px"
,
right
:
"12px"
,
color
:
description
.
length
>=
300
?
"#d32f2f"
:
"#C2C6CC"
,
}
}
>
{
description
.
length
}
/300
</
span
>
</
div
>
</
div
>
</
MyDialog
>
);
};
export
default
SaveOperator
;
src/views/CustomOperator/index.tsx
View file @
93b21ec8
...
@@ -3,7 +3,15 @@ import { observer } from "mobx-react-lite";
...
@@ -3,7 +3,15 @@ import { observer } from "mobx-react-lite";
import
FullScreenDrawer
from
"@/components/CommonComponents/FullScreenDrawer"
;
import
FullScreenDrawer
from
"@/components/CommonComponents/FullScreenDrawer"
;
import
MyButton
from
"@/components/mui/MyButton"
;
import
MyButton
from
"@/components/mui/MyButton"
;
import
OperatorList
from
"./components/OperatorList"
;
import
OperatorList
from
"./components/OperatorList"
;
import
Flow
from
"../Project/components/Flow"
;
// import Flow from "../Project/components/Flow";
import
useMyRequest
from
"@/hooks/useMyRequest"
;
import
{
saveBatchActor
}
from
"@/api/project_api"
;
import
{
useMessage
}
from
"@/components/MySnackbar"
;
import
{
useStores
}
from
"@/store"
;
import
BatchOperatorFlow
from
"../Project/components/Flow/components/BatchOperatorFlow"
;
import
{
toJS
}
from
"mobx"
;
import
{
ITask
}
from
"../Project/ProjectSubmitWork/interface"
;
import
_
from
"lodash"
;
import
styles
from
"./index.module.css"
;
import
styles
from
"./index.module.css"
;
type
IProps
=
{
type
IProps
=
{
...
@@ -12,24 +20,162 @@ type IProps = {
...
@@ -12,24 +20,162 @@ type IProps = {
const
CustomOperator
=
observer
((
props
:
IProps
)
=>
{
const
CustomOperator
=
observer
((
props
:
IProps
)
=>
{
const
{
setShowCustomOperator
}
=
props
;
const
{
setShowCustomOperator
}
=
props
;
const
Message
=
useMessage
();
const
[
operatorList
,
setOperatorList
]
=
useState
<
ITask
[]
>
([]);
const
{
currentProjectStore
}
=
useStores
();
const
productId
=
toJS
(
currentProjectStore
.
currentProductInfo
.
id
);
// const [showCustomOperator, setShowCustomOperator] = useState(false);
// const [showCustomOperator, setShowCustomOperator] = useState(false);
/** 设置选中唯一标识符 */
const
handleNodeClick
=
useCallback
((
val
:
string
)
=>
{
// setSelectTaskId(val);
// console.log(val);
},
[]);
// 保存批算子
const
{
run
:
saveBatchActorRun
}
=
useMyRequest
(
saveBatchActor
,
{
onSuccess
:
(
res
)
=>
{
console
.
log
(
"res"
,
res
);
},
});
const
handleSave
=
useCallback
(()
=>
{
saveBatchActorRun
({
query
:
{
productId
:
productId
as
string
,
batchName
:
"123456"
,
batchVersion
:
"1.0.0"
,
description
:
""
,
},
body
:
[],
});
},
[
saveBatchActorRun
,
productId
]);
// 判断 每个流算子必须至少有一条连接线。
const
checkHasOneLine
=
(
sourceArr
:
string
[],
targetArr
:
string
[])
=>
{
const
all
=
_
.
uniq
([...
sourceArr
,
...
targetArr
]);
if
(
all
.
length
===
operatorList
.
length
)
{
return
true
;
}
else
{
return
false
;
}
// _.uniq([2, 1, 2]);
};
// 判断 每个起始算子(可以有多个起始点)的输入必须为文件的路径输入或数据集的路径输入。
const
checkIn
=
(
targetArr
:
string
[])
=>
{
const
uniqTargetArr
=
_
.
uniq
(
targetArr
);
if
(
uniqTargetArr
.
length
===
operatorList
.
length
)
{
// 流节点连成一个圈了
return
false
;
}
let
check
=
true
;
operatorList
.
forEach
((
flowNode
)
=>
{
if
(
uniqTargetArr
.
indexOf
(
flowNode
.
id
)
===
-
1
)
{
// 该节点的输入没有连线 也就是说这个节点是起点
const
inArr
=
flowNode
.
parameters
.
filter
(
(
parameter
)
=>
parameter
.
parameterGroup
===
"in"
);
if
(
inArr
.
length
>
0
)
{
if
(
!
inArr
.
some
((
inItem
)
=>
{
return
inItem
.
domType
===
"dataset"
||
inItem
.
domType
===
"path"
;
})
)
{
check
=
false
;
}
}
else
{
// 起点没有输入
check
=
false
;
}
}
});
return
check
;
};
// 判断 起码有一个结尾算子(可以有多个结尾点)的输出必须为文件保存或数据集保存。
const
checkOut
=
(
sourceArr
:
string
[])
=>
{
const
uniqSourceArr
=
_
.
uniq
(
sourceArr
);
if
(
uniqSourceArr
.
length
===
operatorList
.
length
)
{
// 流节点连成一个圈了
return
false
;
}
let
check
=
true
;
operatorList
.
forEach
((
flowNode
)
=>
{
if
(
uniqSourceArr
.
indexOf
(
flowNode
.
id
)
===
-
1
)
{
// 该节点的输入没有连线 也就是说这个节点是起点
const
inArr
=
flowNode
.
parameters
.
filter
(
(
parameter
)
=>
parameter
.
parameterGroup
===
"in"
);
if
(
inArr
.
length
>
0
)
{
if
(
!
inArr
.
some
((
inItem
)
=>
{
return
inItem
.
domType
===
"dataset"
||
inItem
.
domType
===
"file"
;
})
)
{
check
=
false
;
}
}
else
{
// 起点没有输入
check
=
false
;
}
}
});
return
check
;
};
const
handleCheck
=
()
=>
{
if
(
operatorList
.
length
===
0
)
{
Message
.
error
(
"内容不能为空!"
);
return
;
}
let
sourceArr
:
string
[]
=
[];
let
targetArr
:
string
[]
=
[];
operatorList
.
forEach
((
flowNode
)
=>
{
flowNode
.
edges
.
forEach
((
edge
)
=>
{
edge
.
source
&&
sourceArr
.
push
(
edge
.
source
);
edge
.
target
&&
targetArr
.
push
(
edge
.
target
);
});
});
if
(
!
checkHasOneLine
([...
sourceArr
],
[...
targetArr
]))
{
Message
.
error
(
"内容校验未通过,请检查!"
);
return
;
}
if
(
!
checkIn
([...
targetArr
]))
{
Message
.
error
(
"内容校验未通过,请检查!"
);
return
;
}
if
(
!
checkOut
([...
sourceArr
]))
{
Message
.
error
(
"内容校验未通过,请检查!"
);
return
;
}
};
return
(
return
(
<
FullScreenDrawer
handleClose=
{
setShowCustomOperator
}
zIndex=
{
1100
}
>
<
FullScreenDrawer
handleClose=
{
setShowCustomOperator
}
zIndex=
{
1100
}
>
<
div
className=
{
styles
.
customOperator
}
>
<
div
className=
{
styles
.
customOperator
}
>
<
div
className=
{
styles
.
coTop
}
>
<
div
className=
{
styles
.
coTop
}
>
<
div
className=
{
styles
.
coTitle
}
>
添加算子
</
div
>
<
div
className=
{
styles
.
coTitle
}
>
添加算子
</
div
>
<
MyButton
text=
"添加"
></
MyButton
>
<
MyButton
text=
"添加"
onClick=
{
()
=>
{
handleCheck
();
}
}
></
MyButton
>
</
div
>
</
div
>
<
div
className=
{
styles
.
coContent
}
>
<
div
className=
{
styles
.
coContent
}
id=
"customOperatorFlow"
>
<
OperatorList
/>
<
OperatorList
<
Flow
operatorList=
{
operatorList
}
showControls=
{
false
}
setOperatorList=
{
setOperatorList
}
// tasks={templateConfigInfo}
/>
// setTasks={setTemplateConfigInfo}
<
BatchOperatorFlow
tasks=
{
operatorList
}
setTasks=
{
setOperatorList
}
type=
"edit"
type=
"edit"
// onFlowNodeClick={handleNodeClick}
onFlowNodeClick=
{
handleNodeClick
}
flowNodeDraggable=
{
true
}
// ListenState={!saveFormDialog}
// ListenState={!saveFormDialog}
showControls=
{
false
}
/>
/>
</
div
>
</
div
>
</
div
>
</
div
>
...
...
src/views/Project/components/Flow/components/BatchOperatorFlow/index.module.css
0 → 100644
View file @
93b21ec8
.reactFlowBox
>
div
:last-child
{
display
:
none
;
}
src/views/Project/components/Flow/components/BatchOperatorFlow/index.tsx
0 → 100644
View file @
93b21ec8
This diff is collapsed.
Click to expand it.
src/views/Project/components/Flow/components/FlowNode/index.tsx
View file @
93b21ec8
...
@@ -8,11 +8,15 @@
...
@@ -8,11 +8,15 @@
*/
*/
import
classNames
from
"classnames"
;
import
classNames
from
"classnames"
;
import
{
Handle
,
Position
}
from
"react-flow-renderer"
;
import
{
Handle
,
Position
}
from
"react-flow-renderer"
;
import
{
useMemo
}
from
"react"
;
// import { IParameter } from "@/views/Project/ProjectSubmitWork/interface";
import
{
uuid
}
from
"@/utils/util"
;
import
{
IExecutionStatus
}
from
"@/views/Project/ProjectSubmitWork/interface"
;
import
{
IExecutionStatus
}
from
"@/views/Project/ProjectSubmitWork/interface"
;
import
jobFail
from
"@/assets/project/jobFail.svg"
;
import
jobFail
from
"@/assets/project/jobFail.svg"
;
import
jobRun
from
"@/assets/project/jobRun.svg"
;
import
jobRun
from
"@/assets/project/jobRun.svg"
;
import
jobSue
from
"@/assets/project/jobSue.svg"
;
import
jobSue
from
"@/assets/project/jobSue.svg"
;
import
MyTooltip
from
"@/components/mui/MyTooltip"
;
import
styles
from
"./index.module.css"
;
import
styles
from
"./index.module.css"
;
/** 自定义flow节点 */
/** 自定义flow节点 */
...
@@ -35,23 +39,65 @@ const FlowNode = (props: any) => {
...
@@ -35,23 +39,65 @@ const FlowNode = (props: any) => {
const
{
const
{
dotStatus
,
dotStatus
,
selectedStatus
,
selectedStatus
,
info
:
{
title
,
isCheck
,
executionStatus
},
flowNodeStyle
=
{
display
:
"flex"
,
alignItems
:
"center"
},
// 样式
inStyle
=
{
background
:
"#C2C6CC "
,
left
:
12
},
// 样式
outStyle
=
{
background
:
"#C2C6CC "
,
left
:
12
},
// 样式
info
:
{
title
,
isCheck
,
executionStatus
,
parameters
},
}
=
data
;
}
=
data
;
/** 获取输入参数数组 */
const
inParamsArr
=
useMemo
(()
=>
{
return
(
(
parameters
?.
length
&&
parameters
?.
filter
((
item
:
any
)
=>
{
return
item
.
parameterGroup
===
"in"
;
}))
||
[]
);
},
[
parameters
]);
/** 获取输出参数数组 */
const
outParamsArr
=
useMemo
(()
=>
{
return
(
(
parameters
?.
length
&&
parameters
?.
filter
((
item
:
any
)
=>
{
return
item
.
parameterGroup
===
"out"
;
}))
||
[]
);
},
[
parameters
]);
return
(
return
(
<
div
<
div
style=
{
flowNodeStyle
}
className=
{
classNames
({
className=
{
classNames
({
[
styles
.
flowNode
]:
true
,
[
styles
.
flowNode
]:
true
,
[
styles
.
selectedFlowBox
]:
selectedStatus
,
[
styles
.
selectedFlowBox
]:
selectedStatus
,
})
}
})
}
>
>
{
dotStatus
?.
isInput
?
(
{
dotStatus
?.
isInput
?
(
<
Handle
style=
{
inStyle
}
type=
"target"
position=
{
Position
.
Top
}
/>
)
:
null
}
{
inParamsArr
?.
length
?
inParamsArr
.
map
((
item
:
any
,
index
:
number
)
=>
{
return
(
<
MyTooltip
title=
{
item
.
name
}
key=
{
uuid
()
}
>
<
Handle
<
Handle
style=
{
{
background
:
"#C2C6CC "
,
left
:
12
}
}
id=
{
item
.
name
}
style=
{
{
background
:
"#fff "
,
border
:
"1px solid #D1D6DE"
,
left
:
index
*
20
+
20
,
...
inStyle
,
}
}
type=
"target"
type=
"target"
position=
{
Position
.
Top
}
position=
{
Position
.
Top
}
/>
/>
)
:
null
}
</
MyTooltip
>
<
div
style=
{
{
display
:
"flex"
,
alignItems
:
"center"
}
}
>
);
})
:
null
}
<
div
>
{
title
||
""
}
{
title
||
""
}
{
isCheck
&&
<
span
className=
{
styles
.
successDot
}
></
span
>
}
{
isCheck
&&
<
span
className=
{
styles
.
successDot
}
></
span
>
}
{
getImgUrl
(
executionStatus
)
&&
(
{
getImgUrl
(
executionStatus
)
&&
(
...
@@ -63,12 +109,27 @@ const FlowNode = (props: any) => {
...
@@ -63,12 +109,27 @@ const FlowNode = (props: any) => {
)
}
)
}
</
div
>
</
div
>
{
dotStatus
?.
isOutput
?
(
{
dotStatus
?.
isOutput
?
(
<
Handle
style=
{
outStyle
}
type=
"source"
position=
{
Position
.
Bottom
}
/>
)
:
null
}
{
outParamsArr
?.
length
?
outParamsArr
.
map
((
item
:
any
,
index
:
number
)
=>
{
return
(
<
MyTooltip
title=
{
item
.
name
}
key=
{
uuid
()
}
>
<
Handle
<
Handle
style=
{
{
background
:
"#C2C6CC "
,
left
:
12
}
}
id=
{
item
.
name
}
style=
{
{
background
:
"#fff "
,
border
:
"1px solid #D1D6DE"
,
left
:
index
*
20
+
20
,
...
outStyle
,
}
}
type=
"source"
type=
"source"
position=
{
Position
.
Bottom
}
position=
{
Position
.
Bottom
}
/>
/>
)
:
null
}
</
MyTooltip
>
);
})
:
null
}
</
div
>
</
div
>
);
);
};
};
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment