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
ba4c0f70
Commit
ba4c0f70
authored
Oct 25, 2022
by
chenshouchao
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'feat-20221012-environment' into 'staging'
cn-Feat 20221012 environment See merge request
!150
parents
73c3aef2
82e2d8ba
Show whitespace changes
Inline
Side-by-side
Showing
48 changed files
with
2078 additions
and
285 deletions
+2078
-285
api_manager.ts
src/api/api_manager.ts
+6
-1
resourceCenter.ts
src/api/resourceCenter.ts
+58
-4
USERRESOURCES.svg
src/assets/project/USERRESOURCES.svg
+23
-0
USERRESOURCES_BLUE.svg
src/assets/project/USERRESOURCES_BLUE.svg
+23
-0
batchOperator.svg
src/assets/resourceCenter/batchOperator.svg
+61
-0
flowOperator.svg
src/assets/resourceCenter/flowOperator.svg
+81
-0
templateIcon.svg
src/assets/resourceCenter/templateIcon.svg
+22
-0
index.module.css
...ponents/BusinessComponents/ProductSelect/index.module.css
+0
-0
index.tsx
src/components/BusinessComponents/ProductSelect/index.tsx
+61
-0
index.module.css
src/components/CommonComponents/CardTable/index.module.css
+8
-0
index.tsx
src/components/CommonComponents/CardTable/index.tsx
+84
-0
index.tsx
src/components/CommonComponents/Code/index.tsx
+18
-4
useMyRouter.ts
src/components/MyRouter/useMyRouter.ts
+2
-2
index.module.css
src/components/mui/FormItemBox/index.module.css
+2
-2
MyMenu.tsx
src/components/mui/MyMenu.tsx
+7
-2
MySelect.tsx
src/components/mui/MySelect.tsx
+5
-2
index.ts
src/router/index.ts
+15
-2
permission.ts
src/store/modules/permission.ts
+5
-1
index.tsx
src/views/CustomOperator/components/OperatorList/index.tsx
+4
-8
index.tsx
src/views/CustomOperator/index.tsx
+16
-115
useCheckOperator.tsx
src/views/CustomOperator/useCheckOperator.tsx
+139
-0
index.tsx
src/views/MenuLayout/index.tsx
+1
-1
index.module.css
.../UserResourcesEnvironment/AddEnvironment/index.module.css
+1
-0
index.tsx
...sources/UserResourcesEnvironment/AddEnvironment/index.tsx
+39
-19
index.module.css
...esources/UserResourcesEnvironment/SeeEnv/index.module.css
+3
-4
index.tsx
...r/UserResources/UserResourcesEnvironment/SeeEnv/index.tsx
+33
-6
index.tsx
...ceCenter/UserResources/UserResourcesEnvironment/index.tsx
+9
-6
index.module.css
...ces/UserResourcesTemplate/TemplateDetail/index.module.css
+140
-0
index.tsx
...rResources/UserResourcesTemplate/TemplateDetail/index.tsx
+214
-0
index.module.css
...nter/UserResources/UserResourcesTemplate/index.module.css
+77
-0
index.tsx
...ourceCenter/UserResources/UserResourcesTemplate/index.tsx
+213
-0
index.module.css
.../WorkflowOperator/components/AddOperator/index.module.css
+6
-0
index.tsx
...sources/WorkflowOperator/components/AddOperator/index.tsx
+261
-26
utils.ts
...esources/WorkflowOperator/components/AddOperator/utils.ts
+149
-0
index.module.css
...WorkflowOperator/components/OperatorCard/index.module.css
+26
-6
index.tsx
...ources/WorkflowOperator/components/OperatorCard/index.tsx
+56
-11
index.tsx
...s/ResourceCenter/UserResources/WorkflowOperator/index.tsx
+61
-21
interface.ts
...esourceCenter/UserResources/WorkflowOperator/interface.ts
+19
-1
index.tsx
src/views/ResourceCenter/UserResources/index.tsx
+4
-4
index.module.css
...esourceCenter/components/SwitchBatchFolw/index.module.css
+13
-8
index.tsx
...views/ResourceCenter/components/SwitchBatchFolw/index.tsx
+14
-3
index.tsx
src/views/WorkFlowEdit/components/OperatorList/index.tsx
+6
-8
interface.ts
src/views/WorkFlowEdit/components/OperatorList/interface.ts
+2
-0
index.tsx
...iews/WorkFlowEdit/components/SaveCustomTemplate/index.tsx
+14
-16
index.tsx
src/views/WorkFlowEdit/index.tsx
+8
-1
index.module.css
src/views/demo/CardTableDemo/index.module.css
+0
-0
index.tsx
src/views/demo/CardTableDemo/index.tsx
+62
-0
index.tsx
src/views/demo/index.tsx
+7
-1
No files found.
src/api/api_manager.ts
View file @
ba4c0f70
...
...
@@ -2,7 +2,7 @@
* @Author: 吴永生#A02208 yongsheng.wu@wholion.com
* @Date: 2022-06-13 09:56:57
* @LastEditors: 吴永生 15770852798@163.com
* @LastEditTime: 2022-10-
19 21:14:11
* @LastEditTime: 2022-10-
24 13:41:26
* @FilePath: /bkunyun/src/api/api_manager.ts
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
...
...
@@ -55,6 +55,11 @@ const RESTAPI = {
API_ACTORENV_LIST
:
`
${
BACKEND_API_URI_PREFIX
}
/cpp/actorenv/list`
,
// 查询用户的应用环境(算子环境)
API_ACTORENV_DELETE
:
`
${
BACKEND_API_URI_PREFIX
}
/cpp/actorenv/delete`
,
// 删除用户算子环境
API_ACTORENV_DETAIL
:
`
${
BACKEND_API_URI_PREFIX
}
/cpp/actorenv/detail`
,
// 查询应用环境的详情信息
API_ACTOR_ENV_OPTIONS
:
`
${
BACKEND_API_URI_PREFIX
}
/cpp/actorenv/usableenv`
,
// 查询用户应用环境下拉
API_SAVE_OPERATOR
:
`
${
BACKEND_API_URI_PREFIX
}
/cpp/workflow/custom/actor`
,
// 保存自定义批流算子
API_WORKFLOWSPEC_LIST
:
`
${
BACKEND_API_URI_PREFIX
}
/cpp/workbench/product/workflowspec/list`
,
// 模板列表 所有的
API_WORKFLOWSPEC_DELETE
:
`
${
BACKEND_API_URI_PREFIX
}
/cpp/workbench/workflowspec/delete`
,
// 删除模板
API_WORKFLOWSPEC_DETAIL
:
`
${
BACKEND_API_URI_PREFIX
}
/cpp/workbench/workflowspec`
,
// 删除模板
};
export
default
RESTAPI
;
src/api/resourceCenter.ts
View file @
ba4c0f70
...
...
@@ -2,7 +2,7 @@
* @Author: 吴永生 15770852798@163.com
* @Date: 2022-10-19 17:09:23
* @LastEditors: 吴永生 15770852798@163.com
* @LastEditTime: 2022-10-
19 21:14:35
* @LastEditTime: 2022-10-
24 13:41:53
* @FilePath: /bkunyun/src/api/resourceCenter.ts
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
...
...
@@ -55,7 +55,7 @@ const addActorenvBuildenv = (params: addActorenvBuildenvParams) => {
// 获取公共环境
const
getActorenvList
=
(
params
:
{
type
:
'BATCH'
|
'FLOW'
|
''
,
type
?
:
'BATCH'
|
'FLOW'
|
''
,
page
:
number
,
size
:
number
,
title
?:
string
,
...
...
@@ -76,11 +76,11 @@ const deleteActorenv = (params: {id: string}) => {
};
// 获取算子列表
const
getOperatorList
=
(
data
:
IOperatorListParams
)
=>
{
const
getOperatorList
=
(
params
:
IOperatorListParams
)
=>
{
return
request
({
url
:
Api
.
API_OPERATOR_LIST
,
method
:
"get"
,
data
params
});
}
...
...
@@ -93,6 +93,55 @@ const getActorenvDetail = (params: {id: string}) => {
});
};
// 查询应用环境的详情信息
const
getActorEnvOptions
=
(
params
:
{
type
:
string
})
=>
{
return
request
({
url
:
`
${
Api
.
API_ACTOR_ENV_OPTIONS
}
`
,
method
:
"get"
,
params
});
};
// 获取工作流模板
const
getWorkflowspecList
=
(
params
:
{
productId
?:
string
,
title
?:
string
})
=>
{
return
request
({
// url:`${Api.API_WORKFLOWSPEC_LIST}/${params.productId}`,
url
:
`
${
Api
.
API_WORKFLOWSPEC_LIST
}
`
,
method
:
"get"
,
params
});
};
// API_WORKFLOWSPEC_LIST
// 新增应用环境
const
saveOperator
=
(
params
:
any
)
=>
{
return
request
({
url
:
Api
.
API_SAVE_OPERATOR
,
method
:
"post"
,
data
:
params
,
});
};
// 删除工作流模板
const
deleteWorkflowspec
=
(
params
:
{
id
:
string
})
=>
{
return
request
({
url
:
`
${
Api
.
API_WORKFLOWSPEC_DELETE
}
`
,
method
:
"delete"
,
params
});
};
// 获取工作流模板详情
const
getWorkflowspecDetail
=
(
id
:
string
)
=>
{
return
request
({
url
:
Api
.
API_WORKFLOWSPEC_DETAIL
+
'/'
+
id
,
method
:
"get"
,
});
};
export
{
getPublicEnv
,
getPublicProject
,
...
...
@@ -101,4 +150,9 @@ export {
deleteActorenv
,
getOperatorList
,
getActorenvDetail
,
getActorEnvOptions
,
getWorkflowspecList
,
saveOperator
,
deleteWorkflowspec
,
getWorkflowspecDetail
};
src/assets/project/USERRESOURCES.svg
0 → 100644
View file @
ba4c0f70
<?xml version="1.0" encoding="UTF-8"?>
<svg
width=
"16px"
height=
"16px"
viewBox=
"0 0 16 16"
version=
"1.1"
xmlns=
"http://www.w3.org/2000/svg"
xmlns:xlink=
"http://www.w3.org/1999/xlink"
>
<title>
编组 69备份 2
</title>
<defs>
<path
d=
"M14.2058659,3.5763545 L8.20586587,0.376450501 C7.76469814,0.141168108 7.23530186,0.141168108 6.79413413,0.376450501 L0.794134134,3.5763545 C0.305329737,3.83704236 1.54202278e-16,4.34591807 0,4.89989271 L0,11.0999285 C-8.68266642e-16,11.6538919 0.305317533,12.1627593 0.794106656,12.423452 L6.79410666,15.623516 C7.23528896,15.858818 7.76471104,15.858818 8.20589334,15.623516 L14.2058933,12.423452 C14.6946825,12.1627593 15,11.6538919 15,11.0999285 L15,4.89989271 C15,4.34591807 14.6946703,3.83704236 14.2058659,3.5763545 Z"
id=
"path-1"
></path>
</defs>
<g
id=
"新"
stroke=
"none"
stroke-width=
"1"
fill=
"none"
fill-rule=
"evenodd"
>
<g
id=
"编组-69备份-2"
>
<rect
id=
"矩形"
x=
"0"
y=
"0"
width=
"16"
height=
"16"
></rect>
<g
id=
"编组-66"
transform=
"translate(0.500000, 0.000000)"
>
<g
id=
"矩形"
>
<mask
id=
"mask-2"
fill=
"white"
>
<use
xlink:href=
"#path-1"
></use>
</mask>
<path
stroke=
"#8A9099"
stroke-width=
"1.5"
d=
"M7.14706707,1.0382196 C7.36765093,0.920578407 7.63234907,0.920578407 7.85293293,1.0382196 L7.85293293,1.0382196 L13.8529329,4.2381236 L14.25,11.0999285 L7.85294667,14.9617542 C7.63235552,15.0794052 7.36764448,15.0794052 7.14705333,14.9617542 L7.14705333,14.9617542 L1.14705333,11.7616902 L0.75,4.89989271 Z"
></path>
<path
d=
"M7.5,11.25 C9.78208033,11.25 11.543715,11.9030473 12.75,13.2731396 L12.75,13.2731396 L12.75,18.6744339 L2.25,18.6744339 L2.25,13.2731396 C3.45628505,11.9030473 5.21791967,11.25 7.5,11.25 Z"
stroke=
"#8A9099"
stroke-width=
"1.5"
mask=
"url(#mask-2)"
></path>
</g>
<circle
id=
"椭圆形"
stroke=
"#8A9099"
stroke-width=
"1.5"
cx=
"7.5"
cy=
"6.8"
r=
"2.25"
></circle>
</g>
</g>
</g>
</svg>
\ No newline at end of file
src/assets/project/USERRESOURCES_BLUE.svg
0 → 100644
View file @
ba4c0f70
<?xml version="1.0" encoding="UTF-8"?>
<svg
width=
"16px"
height=
"16px"
viewBox=
"0 0 16 16"
version=
"1.1"
xmlns=
"http://www.w3.org/2000/svg"
xmlns:xlink=
"http://www.w3.org/1999/xlink"
>
<title>
编组 69备份
</title>
<defs>
<path
d=
"M14.2058659,3.5763545 L8.20586587,0.376450501 C7.76469814,0.141168108 7.23530186,0.141168108 6.79413413,0.376450501 L0.794134134,3.5763545 C0.305329737,3.83704236 1.54202278e-16,4.34591807 0,4.89989271 L0,11.0999285 C-8.68266642e-16,11.6538919 0.305317533,12.1627593 0.794106656,12.423452 L6.79410666,15.623516 C7.23528896,15.858818 7.76471104,15.858818 8.20589334,15.623516 L14.2058933,12.423452 C14.6946825,12.1627593 15,11.6538919 15,11.0999285 L15,4.89989271 C15,4.34591807 14.6946703,3.83704236 14.2058659,3.5763545 Z"
id=
"path-1"
></path>
</defs>
<g
id=
"新"
stroke=
"none"
stroke-width=
"1"
fill=
"none"
fill-rule=
"evenodd"
>
<g
id=
"编组-69备份"
>
<rect
id=
"矩形"
x=
"0"
y=
"0"
width=
"16"
height=
"16"
></rect>
<g
id=
"编组-66"
transform=
"translate(0.500000, 0.000000)"
>
<g
id=
"矩形"
>
<mask
id=
"mask-2"
fill=
"white"
>
<use
xlink:href=
"#path-1"
></use>
</mask>
<path
stroke=
"#1370FF"
stroke-width=
"1.5"
d=
"M7.14706707,1.0382196 C7.36765093,0.920578407 7.63234907,0.920578407 7.85293293,1.0382196 L7.85293293,1.0382196 L13.8529329,4.2381236 L14.25,11.0999285 L7.85294667,14.9617542 C7.63235552,15.0794052 7.36764448,15.0794052 7.14705333,14.9617542 L7.14705333,14.9617542 L1.14705333,11.7616902 L0.75,4.89989271 Z"
></path>
<path
d=
"M7.5,11.25 C9.78208033,11.25 11.543715,11.9030473 12.75,13.2731396 L12.75,13.2731396 L12.75,18.6744339 L2.25,18.6744339 L2.25,13.2731396 C3.45628505,11.9030473 5.21791967,11.25 7.5,11.25 Z"
stroke=
"#1370FF"
stroke-width=
"1.5"
mask=
"url(#mask-2)"
></path>
</g>
<circle
id=
"椭圆形"
stroke=
"#1370FF"
stroke-width=
"1.5"
cx=
"7.5"
cy=
"6.8"
r=
"2.25"
></circle>
</g>
</g>
</g>
</svg>
\ No newline at end of file
src/assets/resourceCenter/batchOperator.svg
0 → 100644
View file @
ba4c0f70
<?xml version="1.0" encoding="UTF-8"?>
<svg
width=
"240px"
height=
"249px"
viewBox=
"0 0 240 249"
version=
"1.1"
xmlns=
"http://www.w3.org/2000/svg"
xmlns:xlink=
"http://www.w3.org/1999/xlink"
>
<title>
矩形备份 26
</title>
<defs>
<rect
id=
"path-1"
x=
"0"
y=
"0"
width=
"240"
height=
"249"
rx=
"8"
></rect>
<filter
x=
"-14.5%"
y=
"-17.6%"
width=
"129.1%"
height=
"135.2%"
filterUnits=
"objectBoundingBox"
id=
"filter-3"
>
<feOffset
dx=
"0"
dy=
"2"
in=
"SourceAlpha"
result=
"shadowOffsetOuter1"
></feOffset>
<feGaussianBlur
stdDeviation=
"3"
in=
"shadowOffsetOuter1"
result=
"shadowBlurOuter1"
></feGaussianBlur>
<feColorMatrix
values=
"0 0 0 0 0.803607664 0 0 0 0 0.598314046 0 0 0 0 0.12907149 0 0 0 1 0"
type=
"matrix"
in=
"shadowBlurOuter1"
result=
"shadowMatrixOuter1"
></feColorMatrix>
<feMerge>
<feMergeNode
in=
"shadowMatrixOuter1"
></feMergeNode>
<feMergeNode
in=
"SourceGraphic"
></feMergeNode>
</feMerge>
</filter>
<rect
id=
"path-4"
x=
"0"
y=
"0"
width=
"110"
height=
"91"
rx=
"5.5"
></rect>
</defs>
<g
id=
"新"
stroke=
"none"
stroke-width=
"1"
fill=
"none"
fill-rule=
"evenodd"
>
<g
id=
"矩形备份-26"
>
<mask
id=
"mask-2"
fill=
"white"
>
<use
xlink:href=
"#path-1"
></use>
</mask>
<use
id=
"蒙版"
fill=
"#FFFFFF"
xlink:href=
"#path-1"
></use>
<rect
id=
"矩形备份-6"
fill=
"#FFB919"
mask=
"url(#mask-2)"
x=
"0"
y=
"0"
width=
"240"
height=
"165"
></rect>
<g
id=
"编组-8备份-3"
mask=
"url(#mask-2)"
>
<g
transform=
"translate(65.000000, 37.000000)"
id=
"编组-19"
>
<g
id=
"矩形"
filter=
"url(#filter-3)"
>
<mask
id=
"mask-5"
fill=
"white"
>
<use
xlink:href=
"#path-4"
></use>
</mask>
<use
id=
"蒙版"
fill=
"#FFFFFF"
xlink:href=
"#path-4"
></use>
<rect
fill=
"#136EFA"
mask=
"url(#mask-5)"
x=
"0"
y=
"0"
width=
"2.5"
height=
"91.4251263"
></rect>
<rect
fill=
"#C2C6CC"
mask=
"url(#mask-5)"
x=
"15"
y=
"8.76679293"
width=
"25"
height=
"5.00959596"
></rect>
</g>
<g
id=
"编组-7"
transform=
"translate(15.250000, 26.070581)"
>
<path
d=
"M11.25,5.51515152 L7.125,5.51515152 C5.60621694,5.51515152 4.375,6.74636845 4.375,8.26515152 L4.375,46.8863636 C4.375,48.4051467 5.60621694,49.6363636 7.125,49.6363636 L11.25,49.6363636 L11.25,49.6363636"
id=
"路径-4"
stroke=
"#979797"
stroke-width=
"1.375"
></path>
<rect
id=
"矩形备份-10"
fill=
"#F0F2F5"
x=
"0"
y=
"0"
width=
"45"
height=
"11.030303"
rx=
"2.75"
></rect>
<rect
id=
"矩形备份-11"
fill=
"#F0F2F5"
x=
"0"
y=
"22.0606061"
width=
"24.75"
height=
"11.030303"
rx=
"2.75"
></rect>
<rect
id=
"矩形备份-15"
fill=
"#F0F2F5"
x=
"39.875"
y=
"33.332197"
width=
"24.75"
height=
"11.030303"
rx=
"2.75"
></rect>
<rect
id=
"矩形备份-12"
fill=
"#F0F2F5"
x=
"0"
y=
"44.1212121"
width=
"24.75"
height=
"11.030303"
rx=
"2.75"
></rect>
<rect
id=
"矩形备份-4"
fill=
"#C2C6CC"
x=
"2.25"
y=
"3.20453283"
width=
"32.5"
height=
"3.75719697"
></rect>
<rect
id=
"矩形备份-5"
fill=
"#C2C6CC"
x=
"2.25"
y=
"25.7477146"
width=
"13.75"
height=
"3.75719697"
></rect>
<rect
id=
"矩形备份-8"
fill=
"#C2C6CC"
x=
"2.25"
y=
"48.2908965"
width=
"13.75"
height=
"3.75719697"
></rect>
<rect
id=
"矩形备份-9"
fill=
"#C2C6CC"
x=
"42.25"
y=
"37.0193056"
width=
"13.75"
height=
"3.75719697"
></rect>
<ellipse
id=
"椭圆形备份-3"
fill=
"#0DD09B"
cx=
"39"
cy=
"5.00959596"
rx=
"1.25"
ry=
"1.25239899"
></ellipse>
<ellipse
id=
"椭圆形备份-4"
fill=
"#0DD09B"
cx=
"20.25"
cy=
"27.5527778"
rx=
"1.25"
ry=
"1.25239899"
></ellipse>
<ellipse
id=
"椭圆形备份-5"
fill=
"#0DD09B"
cx=
"20.25"
cy=
"50.0959596"
rx=
"1.25"
ry=
"1.25239899"
></ellipse>
<ellipse
id=
"椭圆形备份-6"
fill=
"#0DD09B"
cx=
"60.25"
cy=
"38.8243687"
rx=
"1.25"
ry=
"1.25239899"
></ellipse>
<line
x1=
"4.125"
y1=
"38.7726641"
x2=
"39.875"
y2=
"38.8473485"
id=
"路径-6"
stroke=
"#979797"
stroke-width=
"1.375"
></line>
</g>
</g>
</g>
<text
id=
"构建批式算子"
mask=
"url(#mask-2)"
font-family=
"PingFangSC-Medium, PingFang SC"
font-size=
"16"
font-weight=
"400"
line-spacing=
"24"
fill=
"#1E2633"
>
<tspan
x=
"72"
y=
"198.000567"
>
构建批式算子
</tspan>
</text>
<text
id=
"仅支持shell脚本"
mask=
"url(#mask-2)"
font-family=
"PingFangSC-Regular, PingFang SC"
font-size=
"12"
font-weight=
"normal"
line-spacing=
"20"
fill=
"#8A9099"
>
<tspan
x=
"77.484"
y=
"222"
>
仅支持shell脚本
</tspan>
</text>
</g>
</g>
</svg>
\ No newline at end of file
src/assets/resourceCenter/flowOperator.svg
0 → 100644
View file @
ba4c0f70
<?xml version="1.0" encoding="UTF-8"?>
<svg
width=
"240px"
height=
"249px"
viewBox=
"0 0 240 249"
version=
"1.1"
xmlns=
"http://www.w3.org/2000/svg"
xmlns:xlink=
"http://www.w3.org/1999/xlink"
>
<title>
编组 40备份 8
</title>
<defs>
<rect
id=
"path-1"
x=
"0"
y=
"0"
width=
"240"
height=
"249"
rx=
"8"
></rect>
<rect
id=
"path-3"
x=
"0"
y=
"0"
width=
"96.2033898"
height=
"23.9201798"
rx=
"4.80638562"
></rect>
<filter
x=
"-8.8%"
y=
"-27.2%"
width=
"117.7%"
height=
"171.1%"
filterUnits=
"objectBoundingBox"
id=
"filter-5"
>
<feOffset
dx=
"0"
dy=
"2"
in=
"SourceAlpha"
result=
"shadowOffsetOuter1"
></feOffset>
<feGaussianBlur
stdDeviation=
"2.5"
in=
"shadowOffsetOuter1"
result=
"shadowBlurOuter1"
></feGaussianBlur>
<feColorMatrix
values=
"0 0 0 0 0.114151225 0 0 0 0 0.59037626 0 0 0 0 0.477660275 0 0 0 1 0"
type=
"matrix"
in=
"shadowBlurOuter1"
></feColorMatrix>
</filter>
<rect
id=
"path-6"
x=
"0"
y=
"0"
width=
"96.2033898"
height=
"23.9201798"
rx=
"4.80638562"
></rect>
<filter
x=
"-8.8%"
y=
"-27.2%"
width=
"117.7%"
height=
"171.1%"
filterUnits=
"objectBoundingBox"
id=
"filter-8"
>
<feOffset
dx=
"0"
dy=
"2"
in=
"SourceAlpha"
result=
"shadowOffsetOuter1"
></feOffset>
<feGaussianBlur
stdDeviation=
"2.5"
in=
"shadowOffsetOuter1"
result=
"shadowBlurOuter1"
></feGaussianBlur>
<feColorMatrix
values=
"0 0 0 0 0.114151225 0 0 0 0 0.59037626 0 0 0 0 0.477660275 0 0 0 1 0"
type=
"matrix"
in=
"shadowBlurOuter1"
></feColorMatrix>
</filter>
<rect
id=
"path-9"
x=
"0"
y=
"0"
width=
"96.2033898"
height=
"23.9201798"
rx=
"4.80638562"
></rect>
<filter
x=
"-8.8%"
y=
"-27.2%"
width=
"117.7%"
height=
"171.1%"
filterUnits=
"objectBoundingBox"
id=
"filter-11"
>
<feOffset
dx=
"0"
dy=
"2"
in=
"SourceAlpha"
result=
"shadowOffsetOuter1"
></feOffset>
<feGaussianBlur
stdDeviation=
"2.5"
in=
"shadowOffsetOuter1"
result=
"shadowBlurOuter1"
></feGaussianBlur>
<feColorMatrix
values=
"0 0 0 0 0.114151225 0 0 0 0 0.59037626 0 0 0 0 0.477660275 0 0 0 1 0"
type=
"matrix"
in=
"shadowBlurOuter1"
></feColorMatrix>
</filter>
</defs>
<g
id=
"新"
stroke=
"none"
stroke-width=
"1"
fill=
"none"
fill-rule=
"evenodd"
>
<g
id=
"编组-40备份-8"
>
<mask
id=
"mask-2"
fill=
"white"
>
<use
xlink:href=
"#path-1"
></use>
</mask>
<use
id=
"蒙版"
fill=
"#FFFFFF"
xlink:href=
"#path-1"
></use>
<rect
id=
"矩形"
fill=
"#02AB83"
mask=
"url(#mask-2)"
x=
"0"
y=
"0"
width=
"240"
height=
"165"
></rect>
<g
id=
"编组-2"
mask=
"url(#mask-2)"
>
<g
transform=
"translate(56.000000, 40.000000)"
>
<g
id=
"矩形"
>
<mask
id=
"mask-4"
fill=
"white"
>
<use
xlink:href=
"#path-3"
></use>
</mask>
<g
id=
"蒙版"
>
<use
fill=
"black"
fill-opacity=
"1"
filter=
"url(#filter-5)"
xlink:href=
"#path-3"
></use>
<use
fill=
"#FFFFFF"
fill-rule=
"evenodd"
xlink:href=
"#path-3"
></use>
</g>
<rect
fill=
"#136EFA"
mask=
"url(#mask-4)"
x=
"0"
y=
"0"
width=
"2.18644068"
height=
"24.0319281"
></rect>
<rect
fill=
"#C2C6CC"
mask=
"url(#mask-4)"
x=
"13.1186441"
y=
"7.64652257"
width=
"50.2881356"
height=
"8.73888294"
></rect>
<ellipse
id=
"椭圆形备份-3"
fill=
"#0DD09B"
mask=
"url(#mask-4)"
cx=
"77.6186441"
cy=
"12.015964"
rx=
"3.27966102"
ry=
"3.2770811"
></ellipse>
</g>
<g
id=
"矩形"
transform=
"translate(32.796610, 30.586090)"
>
<mask
id=
"mask-7"
fill=
"white"
>
<use
xlink:href=
"#path-6"
></use>
</mask>
<g
id=
"蒙版"
>
<use
fill=
"black"
fill-opacity=
"1"
filter=
"url(#filter-8)"
xlink:href=
"#path-6"
></use>
<use
fill=
"#FFFFFF"
fill-rule=
"evenodd"
xlink:href=
"#path-6"
></use>
</g>
<rect
fill=
"#136EFA"
mask=
"url(#mask-7)"
x=
"0"
y=
"0"
width=
"2.18644068"
height=
"24.0319281"
></rect>
<rect
fill=
"#C2C6CC"
mask=
"url(#mask-7)"
x=
"13.1186441"
y=
"7.64652257"
width=
"50.2881356"
height=
"8.73888294"
></rect>
<ellipse
id=
"椭圆形备份-3"
fill=
"#0DD09B"
mask=
"url(#mask-7)"
cx=
"77.6186441"
cy=
"12.015964"
rx=
"3.27966102"
ry=
"3.2770811"
></ellipse>
</g>
<g
id=
"矩形"
transform=
"translate(4.372881, 60.079820)"
>
<mask
id=
"mask-10"
fill=
"white"
>
<use
xlink:href=
"#path-9"
></use>
</mask>
<g
id=
"蒙版"
>
<use
fill=
"black"
fill-opacity=
"1"
filter=
"url(#filter-11)"
xlink:href=
"#path-9"
></use>
<use
fill=
"#FFFFFF"
fill-rule=
"evenodd"
xlink:href=
"#path-9"
></use>
</g>
<rect
fill=
"#136EFA"
mask=
"url(#mask-10)"
x=
"0"
y=
"0"
width=
"2.18644068"
height=
"24.0319281"
></rect>
<rect
fill=
"#C2C6CC"
mask=
"url(#mask-10)"
x=
"13.1186441"
y=
"7.64652257"
width=
"50.2881356"
height=
"8.73888294"
></rect>
<ellipse
id=
"椭圆形备份-3"
fill=
"#0DD09B"
mask=
"url(#mask-10)"
cx=
"77.6186441"
cy=
"12.015964"
rx=
"3.27966102"
ry=
"3.2770811"
></ellipse>
</g>
</g>
</g>
<text
id=
"构建流式算子"
mask=
"url(#mask-2)"
font-family=
"PingFangSC-Medium, PingFang SC"
font-size=
"16"
font-weight=
"400"
line-spacing=
"24"
fill=
"#1E2633"
>
<tspan
x=
"72"
y=
"198"
>
构建流式算子
</tspan>
</text>
<text
id=
"仅支持Python脚本"
mask=
"url(#mask-2)"
font-family=
"PingFangSC-Regular, PingFang SC"
font-size=
"12"
font-weight=
"normal"
line-spacing=
"20"
fill=
"#8A9099"
>
<tspan
x=
"70.836"
y=
"222"
>
仅支持Python脚本
</tspan>
</text>
</g>
</g>
</svg>
\ No newline at end of file
src/assets/resourceCenter/templateIcon.svg
0 → 100644
View file @
ba4c0f70
<?xml version="1.0" encoding="UTF-8"?>
<svg
width=
"24px"
height=
"24px"
viewBox=
"0 0 24 24"
version=
"1.1"
xmlns=
"http://www.w3.org/2000/svg"
xmlns:xlink=
"http://www.w3.org/1999/xlink"
>
<title>
编组 84
</title>
<g
id=
"上线UI"
stroke=
"none"
stroke-width=
"1"
fill=
"none"
fill-rule=
"evenodd"
>
<g
id=
"个人资源-工作流模版"
transform=
"translate(-661.000000, -574.000000)"
>
<g
id=
"编组-4"
transform=
"translate(641.000000, 526.000000)"
>
<g
id=
"编组-84"
transform=
"translate(20.000000, 48.000000)"
>
<rect
id=
"矩形"
x=
"0"
y=
"0"
width=
"24"
height=
"24"
></rect>
<g
id=
"编组-83"
transform=
"translate(3.500000, 2.000000)"
>
<polyline
id=
"路径"
stroke=
"#1370FF"
stroke-width=
"1.5"
stroke-linecap=
"round"
stroke-linejoin=
"round"
points=
"17 8.19811748 17 4.99985 8.5 0 0 4.99985 0 14.9999 2.37372196 16.396235"
></polyline>
<circle
id=
"椭圆形"
fill=
"#1370FF"
cx=
"3"
cy=
"17"
r=
"2"
></circle>
<circle
id=
"椭圆形备份-13"
fill=
"#1370FF"
cx=
"17"
cy=
"12"
r=
"2"
></circle>
<polyline
id=
"路径-72"
stroke=
"#1370FF"
stroke-width=
"1.5"
points=
"0.283430346 5.19688053 8.5 9.92482816 8.5 19.6575672"
></polyline>
<line
x1=
"8.5"
y1=
"9.92482816"
x2=
"17"
y2=
"4.99985"
id=
"路径-73"
stroke=
"#1370FF"
stroke-width=
"1.5"
></line>
<polyline
id=
"路径"
stroke=
"#1370FF"
stroke-width=
"1.5"
stroke-linecap=
"round"
stroke-linejoin=
"round"
points=
"6.25871064 18.7359651 8.5 20 17 14.9999 17 12.5168189"
></polyline>
</g>
</g>
</g>
</g>
</g>
</svg>
\ No newline at end of file
src/components/BusinessComponents/ProductSelect/index.module.css
0 → 100644
View file @
ba4c0f70
src/components/BusinessComponents/ProductSelect/index.tsx
0 → 100644
View file @
ba4c0f70
import
MySelect
from
"@/components/mui/MySelect"
;
import
MyDialog
from
"@/components/mui/MyDialog"
;
import
{
toJS
}
from
"mobx"
;
import
{
useStores
}
from
"@/store"
;
import
{
useEffect
}
from
"react"
;
interface
IProductSelectProps
{
open
:
boolean
;
setOpen
:
any
;
productId
:
string
;
setProductId
:
any
;
okText
?:
string
;
onConfirm
?:
any
;
}
const
ProductSelect
=
(
props
:
IProductSelectProps
)
=>
{
const
{
open
,
productId
,
setProductId
,
okText
=
"下一步"
,
setOpen
,
onConfirm
,
}
=
props
;
const
{
productListStore
}
=
useStores
();
useEffect
(()
=>
{
if
(
!
productId
)
{
setProductId
(
toJS
(
productListStore
.
productList
)[
0
].
value
);
}
},
[
productId
,
productListStore
.
productList
,
setProductId
]);
const
handleChange
=
(
e
:
any
)
=>
{
console
.
log
(
e
);
setProductId
(
e
);
};
const
handleConfirm
=
()
=>
{
setOpen
(
false
);
onConfirm
&&
onConfirm
();
};
return
(
<
MyDialog
open=
{
open
}
title=
"选择产品"
okText=
{
okText
}
onClose=
{
()
=>
setOpen
(
false
)
}
onConfirm=
{
()
=>
handleConfirm
()
}
>
<
MySelect
value=
{
productId
}
onChange=
{
(
e
)
=>
handleChange
(
e
)
}
options=
{
[...
productListStore
?.
productList
]
||
[]
}
fullWidth
></
MySelect
>
</
MyDialog
>
);
};
export
default
ProductSelect
;
src/components/CommonComponents/CardTable/index.module.css
0 → 100644
View file @
ba4c0f70
.tableBox
{
display
:
flex
;
justify-content
:
flex-start
;
flex-wrap
:
wrap
;
}
.itemBox
{
/* flex: 1; */
}
src/components/CommonComponents/CardTable/index.tsx
0 → 100644
View file @
ba4c0f70
import
{
useCallback
,
useEffect
,
useMemo
,
useRef
,
useState
}
from
"react"
;
import
style
from
"./index.module.css"
;
interface
ICardTableProps
{
data
:
Array
<
any
>
;
// 列表数据
renderItem
:
any
;
// 单个卡片的渲染函数
itemMinWidth
?:
number
;
// 单个卡片的最小宽度,有这个参数时numberOfColumns参数失效,效果为根据屏幕大小和单个卡片的最小宽度来适配每行渲染个数
tableKey
?:
string
;
// 表格数据的key
numberOfColumns
?:
number
;
// 列数 每行渲染几个
horizontalSpacing
?:
number
;
// 水平方向的间隔
verticalSpacing
?:
number
;
// 垂直方向的间隔
}
const
CardTable
=
(
props
:
ICardTableProps
)
=>
{
const
{
data
,
renderItem
,
tableKey
=
"id"
,
numberOfColumns
:
propsNumberOfColumns
=
3
,
horizontalSpacing
=
20
,
verticalSpacing
=
20
,
itemMinWidth
,
}
=
props
;
const
[
numberOfColumns
,
setNumberOfColumns
]
=
useState
(
3
);
const
getNumberOfColumns
=
useCallback
(()
=>
{
if
(
itemMinWidth
)
{
const
boxWidth
=
tableBoxRef
?.
current
?.
offsetWidth
;
if
(
boxWidth
)
{
setNumberOfColumns
(
Math
.
floor
(
boxWidth
/
itemMinWidth
));
}
else
{
setNumberOfColumns
(
propsNumberOfColumns
);
}
}
else
{
setNumberOfColumns
(
propsNumberOfColumns
);
}
},
[
itemMinWidth
,
propsNumberOfColumns
]);
useEffect
(()
=>
{
getNumberOfColumns
();
},
[
getNumberOfColumns
]);
const
tableBoxRef
:
any
=
useRef
(
null
);
const
boxWidth
=
useMemo
(()
=>
{
return
`
${
100
/
numberOfColumns
}
%`
;
},
[
numberOfColumns
]);
window
.
onresize
=
()
=>
{
getNumberOfColumns
();
};
return
(
<
div
className=
{
style
.
tableBox
}
style=
{
{
marginLeft
:
`-${horizontalSpacing / 2}px`
,
marginRight
:
`-${horizontalSpacing / 2}px`
,
}
}
ref=
{
tableBoxRef
}
>
{
data
.
map
((
item
,
index
)
=>
{
return
(
<
div
className=
{
style
.
itemBox
}
key=
{
item
[
tableKey
]
?
item
[
tableKey
]
:
index
}
style=
{
{
width
:
boxWidth
,
paddingLeft
:
`${horizontalSpacing / 2}px`
,
paddingRight
:
`${horizontalSpacing / 2}px`
,
paddingBottom
:
`${verticalSpacing}px`
,
boxSizing
:
"border-box"
,
}
}
>
{
renderItem
(
item
,
index
)
}
</
div
>
);
})
}
</
div
>
);
};
export
default
CardTable
;
src/components/CommonComponents/Code/index.tsx
View file @
ba4c0f70
import
CodeMirror
from
"@uiw/react-codemirror"
;
/*
* @Author: 吴永生 15770852798@163.com
* @Date: 2022-10-20 19:45:32
* @LastEditors: 吴永生 15770852798@163.com
* @LastEditTime: 2022-10-21 10:19:46
* @FilePath: /bkunyun/src/components/CommonComponents/Code/index.tsx
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
import
CodeMirror
,
{
ReactCodeMirrorProps
}
from
"@uiw/react-codemirror"
;
// import { javascript } from "@codemirror/lang-javascript";
type
ICodeType
=
{
interface
ICodeType
extends
ReactCodeMirrorProps
{
value
:
string
;
onChange
:
any
;
height
?:
string
;
width
?:
string
;
maxWidth
?:
string
;
theme
?:
"light"
|
"dark"
;
}
;
}
const
Code
=
(
props
:
ICodeType
)
=>
{
const
{
value
,
onChange
,
height
,
theme
=
"dark"
}
=
props
;
const
{
value
,
onChange
,
height
,
theme
=
"dark"
,
width
,
maxWidth
}
=
props
;
return
(
<
CodeMirror
{
...
props
}
height=
{
height
||
"100%"
}
width=
{
width
||
"100%"
}
maxWidth=
{
maxWidth
||
"100%"
}
value=
{
value
}
onChange=
{
(
e
)
=>
onChange
(
e
)
}
theme=
{
theme
}
...
...
src/components/MyRouter/useMyRouter.ts
View file @
ba4c0f70
...
...
@@ -44,10 +44,11 @@ const useMyRouter = () => {
});
}
for
(
let
item
of
menuInfo
.
res
.
data
)
{
let
routeHead
=
`/
${
item
.
type
}
`
||
'/'
let
childrenRoutes
:
any
=
[]
for
(
let
route
of
item
.
routes
)
{
route
.
element
=
elements
[
route
.
element
]
||
NotFound
;
route
.
path
=
`
/product/
${
item
.
id
}${
route
.
path
}
`
;
route
.
path
=
`
${
routeHead
}
/
${
item
.
id
}${
route
.
path
}
`
if
(
Array
.
isArray
(
route
.
children
))
{
route
.
children
.
forEach
((
childrenItem
:
any
,
index
:
number
)
=>
{
if
(
childrenItem
.
path
)
{
...
...
@@ -62,7 +63,6 @@ const useMyRouter = () => {
route
.
children
=
route
.
children
.
filter
((
childrenItem
:
any
)
=>
!
childrenItem
.
path
)
}
}
// permissionStore.setAddRoutes(item.routes);
permissionStore
.
setAddRoutes
([...
childrenRoutes
,
...
item
.
routes
]);
}
menuStore
.
initMenu
(
menuInfo
.
res
.
data
);
...
...
src/components/mui/FormItemBox/index.module.css
View file @
ba4c0f70
...
...
@@ -31,7 +31,7 @@
.dynamicFormitem_helpText
{
position
:
absolute
;
bottom
:
-36px
;
font-size
:
1
3
px
;
font-size
:
1
2
px
;
line-height
:
1.15
;
color
:
#9894a5
;
}
...
...
@@ -41,6 +41,6 @@
.dynamicFormitem_errorTips
{
position
:
absolute
;
bottom
:
-20px
;
font-size
:
1
3
px
;
font-size
:
1
2
px
;
color
:
#ff4e4e
;
}
src/components/mui/MyMenu.tsx
View file @
ba4c0f70
...
...
@@ -77,14 +77,19 @@ const MyMenu = (props: IMyMenuProps) => {
const
open
=
Boolean
(
anchorEl
);
const
handleClick
=
(
event
:
React
.
MouseEvent
<
HTMLDivElement
>
)
=>
{
setAnchorEl
(
event
.
currentTarget
);
event
.
stopPropagation
();
};
const
handleClose
=
(
value
:
string
)
=>
{
setAnchorEl
(
null
);
};
const
handleMenuClick
=
(
value
:
string
)
=>
{
const
handleMenuClick
=
(
value
:
string
,
event
:
React
.
MouseEvent
<
HTMLLIElement
,
MouseEvent
>
)
=>
{
setValue
&&
setValue
(
value
);
setAnchorEl
(
null
);
event
.
stopPropagation
();
};
return
(
...
...
@@ -124,7 +129,7 @@ const MyMenu = (props: IMyMenuProps) => {
{
options
.
map
((
option
,
index
)
=>
{
return
(
<
MenuItem
onClick=
{
(
)
=>
handleMenuClick
(
option
.
valu
e
)
}
onClick=
{
(
e
)
=>
handleMenuClick
(
option
.
value
,
e
)
}
selected=
{
value
===
option
.
value
}
key=
{
index
}
>
...
...
src/components/mui/MySelect.tsx
View file @
ba4c0f70
...
...
@@ -2,7 +2,7 @@
* @Author: 吴永生#A02208 yongsheng.wu@wholion.com
* @Date: 2021-12-04 15:46:25
* @LastEditors: 吴永生 15770852798@163.com
* @LastEditTime: 2022-10-
19 18:41:0
4
* @LastEditTime: 2022-10-
24 17:39:2
4
* @FilePath: /lionet-slb-pc/src/components/SearchView/components/Collapse.tsx
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
...
...
@@ -49,6 +49,8 @@ interface IProps
isTitle
?:
boolean
;
/** 是否显示提示文案 */
error
?:
boolean
;
/** 默认值 */
defaultValue
?:
string
;
/** 提示文案 */
helpertext
?:
string
;
}
...
...
@@ -64,6 +66,7 @@ export default function MySelect(props: IProps) {
fullWidth
,
error
=
false
,
helpertext
,
defaultValue
,
...
other
}
=
props
;
...
...
@@ -193,7 +196,7 @@ export default function MySelect(props: IProps) {
},
});
const
[
insideValue
,
setInsideValue
]
=
useState
<
string
>
(
""
);
const
[
insideValue
,
setInsideValue
]
=
useState
<
string
>
(
defaultValue
||
""
);
const
handleChange
=
(
e
:
SelectChangeEvent
<
unknown
>
)
=>
{
setInsideValue
(
e
.
target
.
value
as
string
);
...
...
src/router/index.ts
View file @
ba4c0f70
...
...
@@ -2,7 +2,7 @@
* @Author: 吴永生#A02208 yongsheng.wu@wholion.com
* @Date: 2022-05-31 10:18:13
* @LastEditors: 吴永生 15770852798@163.com
* @LastEditTime: 2022-10-
18 10:54:54
* @LastEditTime: 2022-10-
24 20:23:02
* @FilePath: /bkunyun/src/router/index.ts
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
import { AnyMap } from "immer/dist/internal";
...
...
@@ -14,6 +14,7 @@ import * as React from "react";
import
NotFound
from
"@/views/404"
;
import
Demo
from
"@/views/demo"
;
import
SeeEnv
from
"@/views/ResourceCenter/UserResources/UserResourcesEnvironment/SeeEnv"
;
import
OperatorDetails
from
"@/views/ResourceCenter/UserResources/WorkflowOperator/components/OperatorDetails"
;
import
ProjectSetting
from
"@/views/Project/ProjectSetting"
;
import
ProjectData
from
"@/views/Project/ProjectData"
;
import
ProjectWorkbench
from
"@/views/Project/ProjectWorkbench"
;
...
...
@@ -53,9 +54,9 @@ export const elements: {
})
=>
JSX
.
Element
|
any
;
}
=
{
Demo
:
Demo
,
SeeTemplate
:
Demo
,
UserResources
:
UserResources
,
SeeEnv
:
SeeEnv
,
OperatorDetails
:
OperatorDetails
,
ProjectSetting
:
ProjectSetting
,
ProjectData
:
ProjectData
,
ProjectWorkbench
:
ProjectWorkbench
,
...
...
@@ -70,6 +71,11 @@ export const routes: Array<route | navigate> = [
from
:
"/"
,
to
:
"/home"
,
},
{
type
:
"navigate"
,
from
:
"/utility"
,
to
:
"/home"
,
},
{
type
:
"navigate"
,
from
:
"/product"
,
...
...
@@ -87,6 +93,13 @@ export const routes: Array<route | navigate> = [
path
:
"/home"
,
element
:
Home
,
},
{
type
:
"page"
,
name
:
"Utility"
,
path
:
"/utility"
,
element
:
MenuLayout
,
children
:
[],
},
{
type
:
"page"
,
name
:
"Product"
,
...
...
src/store/modules/permission.ts
View file @
ba4c0f70
...
...
@@ -38,7 +38,11 @@ class Permission {
if
(
route
.
type
===
"page"
&&
route
.
children
)
{
if
(
route
.
name
===
"Product"
)
{
for
(
let
item
of
this
.
addRoutes
)
{
route
.
children
.
push
(...
item
);
route
.
children
.
push
(...
item
.
filter
((
a
)
=>
a
.
path
.
indexOf
(
'product/'
)
!==
-
1
));
}
}
else
if
(
route
.
name
===
"Utility"
)
{
for
(
let
item
of
this
.
addRoutes
)
{
route
.
children
.
push
(...
item
.
filter
((
a
)
=>
a
.
path
.
indexOf
(
'utility/'
)
!==
-
1
));
}
}
else
{
this
.
AddInsertRoutes
(
route
.
children
);
...
...
src/views/CustomOperator/components/OperatorList/index.tsx
View file @
ba4c0f70
...
...
@@ -7,22 +7,18 @@ import { useState, useCallback, useEffect, useMemo } from "react";
import
{
getOperatorList
}
from
"@/api/project_api"
;
import
CircularProgress
from
"@mui/material/CircularProgress"
;
import
useMyRequest
from
"@/hooks/useMyRequest"
;
import
{
useStores
}
from
"@/store"
;
import
{
toJS
}
from
"mobx"
;
import
{
ITask
}
from
"@/views/Project/ProjectSubmitWork/interface"
;
import
{
observer
}
from
"mobx-react-lite"
;
type
IProps
=
{
operatorList
:
ITask
[];
setOperatorList
:
any
;
setInputActive
:
any
;
productId
:
string
;
};
const
OperatorList
=
observer
((
props
:
IProps
)
=>
{
const
{
operatorList
,
setOperatorList
,
setInputActive
}
=
props
;
// 流程图中流算子列表
const
{
currentProjectStore
}
=
useStores
();
const
OperatorList
=
(
props
:
IProps
)
=>
{
const
{
operatorList
,
setOperatorList
,
setInputActive
,
productId
}
=
props
;
// 流程图中流算子列表
const
[
list
,
setList
]
=
useState
<
ITask
[]
>
([]);
// 算子列表
const
productId
=
toJS
(
currentProjectStore
.
currentProductInfo
.
id
);
// 产品ID
const
[
keyword
,
setKeyword
]
=
useState
(
""
);
// 搜索算子列表时的关键词
const
[
dragItem
,
setDragItem
]
=
useState
<
any
>
({});
// 拖拽的算子
const
[
page
,
setPage
]
=
useState
(
0
);
// 算子列表页码
...
...
@@ -250,6 +246,6 @@ const OperatorList = observer((props: IProps) => {
</
div
>
</
div
>
);
}
)
;
};
export
default
OperatorList
;
src/views/CustomOperator/index.tsx
View file @
ba4c0f70
/*
* @Author: 吴永生 15770852798@163.com
* @Date: 2022-10-24 17:32:00
* @LastEditors: 吴永生 15770852798@163.com
* @LastEditTime: 2022-10-24 19:42:23
* @FilePath: /bkunyun/src/views/CustomOperator/index.tsx
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
import
React
,
{
useCallback
,
useEffect
,
useState
}
from
"react"
;
import
{
observer
}
from
"mobx-react-lite"
;
import
FullScreenDrawer
from
"@/components/CommonComponents/FullScreenDrawer"
;
import
MyButton
from
"@/components/mui/MyButton"
;
import
OperatorList
from
"./components/OperatorList"
;
// import Flow from "../Project/components/Flow";
import
{
useMessage
}
from
"@/components/MySnackbar"
;
import
BatchOperatorFlow
from
"../Project/components/Flow/components/BatchOperatorFlow"
;
import
SaveOperator
from
"./components/SaveOperator"
;
import
{
ITask
}
from
"../Project/ProjectSubmitWork/interface"
;
import
_
from
"lodash"
;
import
styles
from
"./index.module.css"
;
import
useCheckOperator
from
"./useCheckOperator"
;
type
IProps
=
{
setShowCustomOperator
:
any
;
initOperatorList
:
ITask
[];
productId
:
string
;
};
const
CustomOperator
=
observer
((
props
:
IProps
)
=>
{
const
{
setShowCustomOperator
,
initOperatorList
}
=
props
;
const
Message
=
useMessage
();
const
{
setShowCustomOperator
,
initOperatorList
,
productId
}
=
props
;
const
[
operatorList
,
setOperatorList
]
=
useState
<
ITask
[]
>
(
initOperatorList
);
const
[
saveFormDialog
,
setSaveFormDialog
]
=
useState
(
false
);
const
[
inputActive
,
setInputActive
]
=
useState
(
false
);
// const [showCustomOperator, setShowCustomOperator] = useState(false);
const
{
handleCheck
}
=
useCheckOperator
(
operatorList
,
()
=>
setSaveFormDialog
(
true
)
);
/** 设置选中唯一标识符 */
const
handleNodeClick
=
useCallback
((
val
:
string
)
=>
{
// setSelectTaskId(val);
},
[]);
// 判断 每个流算子必须至少有一条连接线。
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
||
""
).
toLowerCase
()
===
"dataset"
||
(
inItem
.
domType
||
""
).
toLowerCase
()
===
"path"
||
(
inItem
.
domType
||
""
).
toLowerCase
()
===
"file"
);
})
)
{
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
outArr
=
flowNode
.
parameters
.
filter
(
(
parameter
)
=>
parameter
.
parameterGroup
===
"out"
);
if
(
outArr
.
length
>
0
)
{
if
(
!
outArr
.
some
((
outItem
)
=>
{
return
(
(
outItem
.
domType
||
""
).
toLowerCase
()
===
"dataset"
||
(
outItem
.
domType
||
""
).
toLowerCase
()
===
"file"
||
(
outItem
.
domType
||
""
).
toLowerCase
()
===
"path"
||
(
outItem
.
domType
||
""
).
toLowerCase
()
===
"input"
);
})
)
{
check
=
false
;
}
}
else
{
// 起点没有输入
check
=
false
;
}
}
});
return
check
;
};
useEffect
(()
=>
{
sessionStorage
.
setItem
(
"operatorList"
,
JSON
.
stringify
(
operatorList
));
},
[
operatorList
]);
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
;
}
setSaveFormDialog
(
true
);
};
return
(
<
FullScreenDrawer
handleClose=
{
setShowCustomOperator
}
zIndex=
{
1100
}
>
<
div
className=
{
styles
.
customOperator
}
>
...
...
@@ -168,6 +68,7 @@ const CustomOperator = observer((props: IProps) => {
operatorList=
{
operatorList
}
setOperatorList=
{
setOperatorList
}
setInputActive=
{
setInputActive
}
productId=
{
productId
}
/>
<
BatchOperatorFlow
tasks=
{
operatorList
}
...
...
src/views/CustomOperator/useCheckOperator.tsx
0 → 100644
View file @
ba4c0f70
import
{
useMessage
}
from
"@/components/MySnackbar"
;
import
_
from
"lodash"
;
import
{
useState
}
from
"react"
;
import
{
ITask
}
from
"../Project/ProjectSubmitWork/interface"
;
/*
* @Author: 吴永生 15770852798@163.com
* @Date: 2022-10-24 18:08:47
* @LastEditors: 吴永生 15770852798@163.com
* @LastEditTime: 2022-10-24 18:31:12
* @FilePath: /bkunyun/src/views/CustomOperator/useCheckOperator.tsx
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
const
useCheckOperator
=
(
operatorList
:
ITask
[],
successCallBack
?:
any
,
nullText
?:
string
)
=>
{
const
Message
=
useMessage
();
const
[
checkStatus
,
setCheckStatus
]
=
useState
<
boolean
>
(
false
);
// 判断 每个起始算子(可以有多个起始点)的输入必须为文件的路径输入或数据集的路径输入。
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
||
""
).
toLowerCase
()
===
"dataset"
||
(
inItem
.
domType
||
""
).
toLowerCase
()
===
"path"
||
(
inItem
.
domType
||
""
).
toLowerCase
()
===
"file"
);
})
)
{
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
outArr
=
flowNode
.
parameters
.
filter
(
(
parameter
)
=>
parameter
.
parameterGroup
===
"out"
);
if
(
outArr
.
length
>
0
)
{
if
(
!
outArr
.
some
((
outItem
)
=>
{
return
(
(
outItem
.
domType
||
""
).
toLowerCase
()
===
"dataset"
||
(
outItem
.
domType
||
""
).
toLowerCase
()
===
"file"
||
(
outItem
.
domType
||
""
).
toLowerCase
()
===
"path"
||
(
outItem
.
domType
||
""
).
toLowerCase
()
===
"input"
);
})
)
{
check
=
false
;
}
}
else
{
// 起点没有输入
check
=
false
;
}
}
});
return
check
;
};
// 判断 每个流算子必须至少有一条连接线。
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
handleCheck
=
()
=>
{
if
(
operatorList
.
length
===
0
)
{
Message
.
error
(
nullText
||
"内容不能为空!"
);
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
;
}
setCheckStatus
(
true
);
successCallBack
();
};
return
{
handleCheck
,
checkStatus
};
};
export
default
useCheckOperator
;
src/views/MenuLayout/index.tsx
View file @
ba4c0f70
...
...
@@ -100,7 +100,7 @@ const MenuLayout = observer(() => {
src=
{
routerIcon
(
item
.
id
||
""
,
`/v3${item.path}`
===
pathname
pathname
.
indexOf
(
`/v3${item.path}`
)
!==
-
1
)
||
undefined
}
alt=
""
...
...
src/views/ResourceCenter/UserResources/UserResourcesEnvironment/AddEnvironment/index.module.css
View file @
ba4c0f70
...
...
@@ -36,6 +36,7 @@
}
.form
{
width
:
368px
;
min-width
:
368px
;
box-sizing
:
border-box
;
padding
:
16px
24px
;
border
:
1px
solid
#ebedf0
;
...
...
src/views/ResourceCenter/UserResources/UserResourcesEnvironment/AddEnvironment/index.tsx
View file @
ba4c0f70
...
...
@@ -33,23 +33,23 @@ const AddEnvironment = (props: IAddEnvironmentProps) => {
const
{
setAddopen
}
=
props
;
const
Message
=
useMessage
();
let
tokenInfo
=
getTokenInfo
();
const
[
hpczoneList
,
setHpczoneList
]
=
useState
<
Array
<
any
>>
([]);
const
[
publicProjectId
,
setPublicProjectId
]
=
useState
(
""
);
const
[
publicZoneId
,
setPublicZoneId
]
=
useState
(
""
);
const
[
computeType
,
setComputeType
]
=
useState
(
""
);
const
[
fileToken
,
setFileToken
]
=
useState
(
""
);
const
[
taskType
,
setTaskType
]
=
useState
<
"BATCH"
|
"FLOW"
>
(
"BATCH"
);
const
[
name
,
setName
]
=
useState
(
""
);
const
[
desc
,
setDesc
]
=
useState
(
""
);
const
[
baseEnvId
,
setBaseEnvId
]
=
useState
(
""
);
const
[
filePaths
,
setFilePaths
]
=
useState
<
Array
<
string
>>
([]);
const
[
isUploading
,
setIsUploading
]
=
useState
(
false
);
const
[
fileName
,
setFileName
]
=
useState
(
""
);
// const [bashScript, setBashScript] = useState('');
const
[
envList
,
setEnvList
]
=
useState
<
Array
<
any
>>
([]);
const
[
progress
,
setProgress
]
=
useState
(
"0%"
);
const
[
code
,
setCode
]
=
useState
(
""
);
const
[
upload
,
setUpload
]
=
useState
<
any
>
(()
=>
{});
const
[
hpczoneList
,
setHpczoneList
]
=
useState
<
Array
<
any
>>
([]);
// 计算区列表 通过计算区列表和计算区id拿fileServerEndPoint
const
[
publicProjectId
,
setPublicProjectId
]
=
useState
(
""
);
// 公共项目id 环境压缩包临时存放在公共项目下
const
[
publicZoneId
,
setPublicZoneId
]
=
useState
(
""
);
// 公共项目计算区id
const
[
computeType
,
setComputeType
]
=
useState
(
""
);
// 基础环境是cpu 还是 gpu
const
[
fileToken
,
setFileToken
]
=
useState
(
""
);
// 访问公共项目的fileToken
const
[
taskType
,
setTaskType
]
=
useState
<
"BATCH"
|
"FLOW"
>
(
"BATCH"
);
// 环境类型 批式环境还是流式环境
const
[
name
,
setName
]
=
useState
(
""
);
// 环境名称
const
[
desc
,
setDesc
]
=
useState
(
""
);
// 环境描述
const
[
baseEnvId
,
setBaseEnvId
]
=
useState
(
""
);
// 基础环境id
const
[
filePaths
,
setFilePaths
]
=
useState
<
Array
<
string
>>
([]);
// 环境压缩包上传后的路径集合(目前只有一个)
const
[
isUploading
,
setIsUploading
]
=
useState
(
false
);
// 保存接口loading
const
[
fileName
,
setFileName
]
=
useState
(
""
);
// 环境压缩包文件名
const
[
envList
,
setEnvList
]
=
useState
<
Array
<
any
>>
([]);
// 基础环境列表 和taskType环境类型有关
const
[
progress
,
setProgress
]
=
useState
(
"0%"
);
// 上传压缩包进度
const
[
code
,
setCode
]
=
useState
(
""
);
// 脚本内容
const
[
code
Width
,
setCodeWidth
]
=
useState
(
0
);
const
[
upload
,
setUpload
]
=
useState
<
any
>
(()
=>
{});
// 上传压缩包实例 用于暂停(取消上传)upload.abort(true);
const
[
nameHelper
,
setNameHelper
]
=
useState
({
error
:
false
,
text
:
"30字符以内,仅限字母、数字、中文"
,
...
...
@@ -298,6 +298,16 @@ const AddEnvironment = (props: IAddEnvironmentProps) => {
setFilePaths
([]);
};
const
getCodeWidth
=
()
=>
{
const
addEnvironmentCodeElement
=
document
.
getElementById
(
"addEnvironmentCode"
);
setCodeWidth
(
addEnvironmentCodeElement
?.
offsetWidth
||
0
);
};
useEffect
(()
=>
{
getCodeWidth
();
},
[]);
return
(
<
div
className=
{
style
.
addEnvironment
}
>
<
div
className=
{
style
.
left
}
>
...
...
@@ -370,7 +380,16 @@ const AddEnvironment = (props: IAddEnvironmentProps) => {
<
div
className=
{
style
.
label
}
>
上传环境压缩包
<
span
className=
{
style
.
zipText
}
>
(.zip)
</
span
>
<
span
className=
{
style
.
required
}
>
*
</
span
>
<
span
className=
{
style
.
download
}
>
下载模板
</
span
>
<
span
className=
{
style
.
download
}
onClick=
{
()
=>
window
.
open
(
"https://projectsif.oss-cn-beijing.aliyuncs.com/build_env_template.zip"
)
}
>
下载模板
</
span
>
</
div
>
<
div
className=
{
style
.
formItem
}
>
{
filePaths
.
length
===
0
&&
!
isUploading
&&
(
...
...
@@ -445,11 +464,12 @@ const AddEnvironment = (props: IAddEnvironmentProps) => {
<
div
className=
{
style
.
codeTitle
}
>
{
taskType
===
"BATCH"
?
"Shell脚本"
:
"Python脚本"
}
</
div
>
<
div
className=
{
style
.
code
}
>
<
div
className=
{
style
.
code
}
id=
"addEnvironmentCode"
>
<
Code
value=
{
code
}
onChange=
{
(
e
:
string
)
=>
setCode
(
e
)
}
height=
"535px"
width=
{
`${codeWidth}px`
}
/>
</
div
>
</
div
>
...
...
src/views/ResourceCenter/UserResources/UserResourcesEnvironment/SeeEnv/index.module.css
View file @
ba4c0f70
.seeEnv
{
position
:
relative
;
}
.titleBox
{
padding
:
14px
24px
;
display
:
flex
;
...
...
@@ -8,10 +11,6 @@
.goBackIcon
{
width
:
22px
;
height
:
22px
;
/* background-color: #fff; */
/* border-radius: 4px; */
/* margin-right: 12px; */
/* box-shadow: 0px 2px 5px 0px rgba(3, 47, 105, 0.09); */
cursor
:
pointer
;
}
.title
{
...
...
src/views/ResourceCenter/UserResources/UserResourcesEnvironment/SeeEnv/index.tsx
View file @
ba4c0f70
import
style
from
"./index.module.css"
;
import
React
,
{
useState
,
useEffect
,
useMemo
}
from
"react"
;
import
React
,
{
useState
,
useEffect
}
from
"react"
;
import
LogView
from
"@/views/ResourceCenter/components/LogView"
;
import
{
useNavigate
}
from
"react-router-dom"
;
import
BasicInfo
,
{
...
...
@@ -9,6 +9,7 @@ import { getActorenvDetail } from "@/api/resourceCenter";
import
useMyRequest
from
"@/hooks/useMyRequest"
;
import
goback
from
"@/assets/project/goback.svg"
;
import
{
useLocation
}
from
"react-router-dom"
;
import
MyCircularProgress
from
"@/components/mui/MyCircularProgress"
;
import
jobFail
from
"@/assets/project/jobFail.svg"
;
import
jobRun
from
"@/assets/project/jobRun.svg"
;
import
jobSue
from
"@/assets/project/jobSue.svg"
;
...
...
@@ -18,8 +19,34 @@ const SeeEnv = () => {
const
location
=
useLocation
();
const
[
id
,
setId
]
=
useState
(
""
);
const
[
info
,
setInfo
]
=
useState
<
any
>
({});
const
[
infoListTop
,
setInfoListTop
]
=
useState
<
Array
<
IInfoItem
>>
([]);
const
[
infoListBot
,
setInfoListBot
]
=
useState
<
Array
<
IInfoItem
>>
([]);
const
[
infoListTop
,
setInfoListTop
]
=
useState
<
Array
<
IInfoItem
>>
([
{
label
:
"构建状态"
,
value
:
""
,
},
{
label
:
"创建时间"
,
value
:
""
,
},
{
label
:
"构建时长"
,
value
:
""
,
},
{
label
:
"构建成本"
,
value
:
""
,
},
{
label
:
"基础环境"
,
value
:
""
,
},
]);
const
[
infoListBot
,
setInfoListBot
]
=
useState
<
Array
<
IInfoItem
>>
([
{
label
:
"描述"
,
value
:
""
,
},
]);
const
[
logs
,
setLogs
]
=
useState
<
Array
<
any
>>
([]);
const
getStatus
=
(
item
:
any
)
=>
{
...
...
@@ -58,7 +85,6 @@ const SeeEnv = () => {
const
{
run
,
loading
}
=
useMyRequest
(
getActorenvDetail
,
{
onSuccess
:
(
res
)
=>
{
console
.
log
(
res
);
setInfo
(
res
.
data
);
let
data
=
res
.
data
;
setInfoListTop
([
...
...
@@ -112,12 +138,13 @@ const SeeEnv = () => {
return
(
<
div
className=
{
style
.
seeEnv
}
>
<
MyCircularProgress
loading=
{
loading
}
/>
<
div
className=
{
style
.
titleBox
}
>
<
img
className=
{
style
.
goBackIcon
}
src=
{
goback
}
alt=
""
onClick=
{
()
=>
navigate
(
"/
product
/resourceCenter/userResources"
)
}
onClick=
{
()
=>
navigate
(
"/
utility
/resourceCenter/userResources"
)
}
/>
<
div
className=
{
style
.
title
}
>
{
info
.
title
}
</
div
>
<
div
className=
{
style
.
type
}
>
...
...
@@ -134,7 +161,7 @@ const SeeEnv = () => {
<
div
className=
{
style
.
logsBox
}
>
<
div
className=
{
style
.
logsTitle
}
>
日志
</
div
>
<
div
className=
{
style
.
LogViewBox
}
>
<
LogView
logs=
{
logs
}
></
LogView
>
{
!
loading
&&
<
LogView
logs=
{
logs
}
></
LogView
>
}
</
div
>
</
div
>
</
div
>
...
...
src/views/ResourceCenter/UserResources/UserResourcesEnvironment/index.tsx
View file @
ba4c0f70
...
...
@@ -20,7 +20,7 @@ const UserResourcesEnvironment = () => {
const
navigate
=
useNavigate
();
const
[
addOpen
,
setAddopen
]
=
useState
(
false
);
const
[
title
,
setTitle
]
=
useState
(
""
);
const
[
type
,
setType
]
=
useState
<
"BATCH"
|
"FLOW"
|
"
"
>
(
"
"
);
const
[
type
,
setType
]
=
useState
<
"BATCH"
|
"FLOW"
|
"
ALL"
>
(
"ALL
"
);
const
[
list
,
setList
]
=
useState
([]);
const
[
page
,
setPage
]
=
useState
(
0
);
const
[
count
,
setCount
]
=
useState
(
0
);
...
...
@@ -54,7 +54,7 @@ const UserResourcesEnvironment = () => {
width
:
140
,
},
];
const
{
run
:
getList
}
=
useMyRequest
(
getActorenvList
,
{
const
{
run
:
getList
,
loading
}
=
useMyRequest
(
getActorenvList
,
{
onSuccess
:
(
res
)
=>
{
setList
(
res
.
data
.
content
);
setCount
(
res
.
data
.
totalPages
-
1
);
...
...
@@ -72,7 +72,7 @@ const UserResourcesEnvironment = () => {
page
,
size
,
title
,
type
,
type
:
type
===
"ALL"
?
""
:
type
,
});
}
},
[
getList
,
page
,
size
,
title
,
type
,
addOpen
,
deleteOpen
]);
...
...
@@ -131,9 +131,7 @@ const UserResourcesEnvironment = () => {
};
const
hanleToSeeEnv
=
(
item
:
any
)
=>
{
console
.
log
(
"hanleToSeeEnv"
);
console
.
log
(
item
.
id
);
navigate
(
"/product/resourceCenter/userResources/seeEnv"
,
{
navigate
(
"/utility/resourceCenter/userResources/seeEnv"
,
{
state
:
{
id
:
item
.
id
},
});
};
...
...
@@ -207,6 +205,10 @@ const UserResourcesEnvironment = () => {
title=
"环境类型"
isTitle=
{
true
}
options=
{
[
{
label
:
"全部"
,
value
:
"ALL"
,
},
{
label
:
"批式"
,
value
:
"BATCH"
,
...
...
@@ -253,6 +255,7 @@ const UserResourcesEnvironment = () => {
nodataText=
"暂无应用环境"
paginationType=
"complex"
totalElements=
{
totalElements
}
loading=
{
loading
}
></
MyTable
>
</
div
>
{
addOpen
&&
<
AddEnvironment
setAddopen=
{
setAddopen
}
></
AddEnvironment
>
}
...
...
src/views/ResourceCenter/UserResources/UserResourcesTemplate/TemplateDetail/index.module.css
0 → 100644
View file @
ba4c0f70
.swBox
{
position
:
fixed
;
z-index
:
1000
;
top
:
0
;
left
:
0
;
width
:
100vw
;
height
:
100vh
;
background-color
:
RGBA
(
247
,
248
,
250
,
1
);
overflow-y
:
overlay
;
}
.swHeader
{
z-index
:
1001
;
position
:
sticky
;
top
:
0
;
height
:
56px
;
background-color
:
#fff
;
box-shadow
:
0px
3px
10px
0px
rgba
(
0
,
24
,
57
,
0.06
);
display
:
flex
;
justify-content
:
space-between
;
align-items
:
center
;
padding
:
0
24px
;
}
.swHeaderLeft
{
display
:
flex
;
justify-content
:
flex-start
;
align-items
:
center
;
}
.goBackIcon
{
cursor
:
pointer
;
}
.goBackIconBox
{
width
:
32px
;
height
:
32px
;
border-radius
:
4px
;
display
:
flex
;
align-items
:
center
;
justify-content
:
center
;
}
.goBackIconBox
:hover
{
background-color
:
rgb
(
240
,
242
,
245
);
}
.swTemplateTitle
{
margin
:
0
19px
0
3px
;
line-height
:
20px
;
font-size
:
14px
;
color
:
rgba
(
30
,
38
,
51
,
1
);
font-weight
:
700
;
}
.swContent
{
display
:
flex
;
height
:
calc
(
100vh
-
56px
);
}
.swFormBox
{
background-color
:
#fff
;
border-right
:
1px
solid
#ebedf0
;
width
:
360px
;
overflow-y
:
overlay
;
box-sizing
:
border-box
;
padding
:
24px
;
}
.swFlowBox
{
flex
:
1
;
height
:
calc
(
100vh
-
56px
);
}
.title
{
color
:
rgba
(
30
,
38
,
51
,
1
);
font-size
:
16px
;
line-height
:
24px
;
font-weight
:
600
;
margin-bottom
:
16px
;
}
.taskInfoLi
{
margin-bottom
:
20px
;
display
:
flex
;
justify-content
:
space-between
;
align-items
:
flex-start
;
}
.taskInfoParams
{
color
:
rgba
(
138
,
144
,
153
,
1
);
font-size
:
14px
;
line-height
:
22px
;
width
:
80px
;
margin-right
:
44px
;
word-wrap
:
break-word
;
}
.taskInfoValue
{
color
:
rgba
(
30
,
38
,
51
,
1
);
font-size
:
14px
;
line-height
:
22px
;
display
:
flex
;
position
:
relative
;
align-items
:
center
;
text-align
:
left
;
word-break
:
break-all
;
flex
:
1
;
justify-content
:
flex-end
;
word-wrap
:
break-word
;
}
.taskInfoValueShowAll
{
white-space
:
normal
;
}
.taskInfoValueIcon
{
margin-right
:
9px
;
}
.tabs
{
display
:
flex
;
justify-content
:
flex-start
;
border-bottom
:
1px
solid
rgba
(
240
,
242
,
245
,
1
);
}
.tabLi
{
cursor
:
pointer
;
font-size
:
14px
;
line-height
:
22px
;
padding-bottom
:
8px
;
color
:
rgba
(
138
,
144
,
153
,
1
);
margin-right
:
32px
;
position
:
relative
;
}
.tabLiAcitve
{
color
:
rgba
(
19
,
112
,
255
,
1
);
border-bottom
:
2px
solid
rgba
(
19
,
112
,
255
,
1
);
}
.overview
{
padding-top
:
19px
;
}
.params
{
padding-top
:
19px
;
}
.options
{
position
:
absolute
;
top
:
33px
;
max-height
:
230px
;
overflow-y
:
overlay
;
padding
:
8px
0px
;
background
:
#ffffff
;
box-shadow
:
0px
3px
10px
0px
rgba
(
0
,
24
,
57
,
0.14
);
border-radius
:
4px
;
z-index
:
1002
;
}
src/views/ResourceCenter/UserResources/UserResourcesTemplate/TemplateDetail/index.tsx
0 → 100644
View file @
ba4c0f70
import
{
useEffect
,
useState
,
useMemo
}
from
"react"
;
import
{
observer
}
from
"mobx-react-lite"
;
import
classNames
from
"classnames"
;
import
useMyRequest
from
"@/hooks/useMyRequest"
;
import
{
getWorkflowspecDetail
}
from
"@/api/resourceCenter"
;
import
{
IResponse
}
from
"@/api/http"
;
import
goback
from
"@/assets/project/goback.svg"
;
import
{
ITaskInfo
}
from
"@/views/Project/ProjectSubmitWork/interface"
;
import
Flow
from
"@/views/Project/components/Flow"
;
import
moment
from
"moment"
;
import
MyTooltip
from
"@/components/mui/MyTooltip"
;
import
{
toJS
}
from
"mobx"
;
import
{
useStores
}
from
"@/store"
;
import
styles
from
"./index.module.css"
;
interface
ITemplateDetailProps
{
id
:
string
;
setShowDetail
:
any
;
}
const
TemplateDetail
=
observer
((
props
:
ITemplateDetailProps
)
=>
{
const
{
id
,
setShowDetail
}
=
props
;
const
[
templateInfo
,
setTemplateInfo
]
=
useState
<
any
>
({});
const
[
overviewActive
,
setOverviewActive
]
=
useState
(
true
);
/** 选中的node Id */
const
[
activeFlowIndex
,
setActiveFlowIndex
]
=
useState
<
string
>
(
""
);
const
{
productListStore
}
=
useStores
();
const
getProductName
=
(
productId
:
string
)
=>
{
let
res
=
"-"
;
toJS
(
productListStore
.
productList
).
forEach
((
item
)
=>
{
if
(
item
.
value
===
productId
)
{
res
=
item
.
label
;
}
});
return
res
;
};
const
taskInfo
=
useMemo
(()
=>
{
if
(
activeFlowIndex
)
{
return
templateInfo
.
tasks
.
filter
(
(
task
:
any
)
=>
task
.
id
===
activeFlowIndex
)[
0
];
}
else
{
return
{};
}
},
[
templateInfo
,
activeFlowIndex
]);
const
randerParameters
=
useMemo
(()
=>
{
return
taskInfo
.
parameters
;
},
[
taskInfo
]);
/** 获取模版数据 */
const
{
run
}
=
useMyRequest
(
getWorkflowspecDetail
,
{
onSuccess
:
(
res
:
IResponse
<
ITaskInfo
>
)
=>
{
console
.
log
(
res
);
setTemplateInfo
(
res
.
data
);
},
});
useEffect
(()
=>
{
run
(
id
);
},
[
id
,
run
]);
/** 返回事件 */
const
onBack
=
()
=>
{
setShowDetail
(
false
);
};
const
setExternalSelectedNodeId
=
(
id
:
string
)
=>
{
setActiveFlowIndex
(
id
);
};
const
handleParams
=
()
=>
{
setOverviewActive
(
false
);
};
return
(
<
div
className=
{
styles
.
swBox
}
>
<
div
className=
{
styles
.
swHeader
}
>
<
div
className=
{
styles
.
swHeaderLeft
}
>
<
div
className=
{
styles
.
goBackIconBox
}
>
<
img
onClick=
{
onBack
}
className=
{
styles
.
goBackIcon
}
src=
{
goback
}
alt=
""
/>
</
div
>
<
div
className=
{
styles
.
swTemplateTitle
}
>
{
templateInfo
.
title
}
</
div
>
</
div
>
</
div
>
<
div
className=
{
styles
.
swContent
}
>
<
div
className=
{
styles
.
swFormBox
}
>
{
!
activeFlowIndex
&&
(
<
div
>
<
div
className=
{
styles
.
title
}
>
基础信息
</
div
>
<
div
className=
{
styles
.
taskInfoLi
}
>
<
div
className=
{
styles
.
taskInfoParams
}
>
模板名称
</
div
>
<
div
className=
{
styles
.
taskInfoValue
}
>
{
templateInfo
.
title
}
</
div
>
</
div
>
<
div
className=
{
styles
.
taskInfoLi
}
>
<
div
className=
{
styles
.
taskInfoParams
}
>
描述
</
div
>
<
div
className=
{
styles
.
taskInfoValue
}
>
{
templateInfo
.
description
}
</
div
>
</
div
>
<
div
className=
{
styles
.
taskInfoLi
}
>
<
div
className=
{
styles
.
taskInfoParams
}
>
创建时间
</
div
>
<
div
className=
{
styles
.
taskInfoValue
}
>
{
moment
(
new
Date
(
templateInfo
.
createdAt
)).
format
(
"yyyy-MM-DD hh:mm"
)
}
</
div
>
</
div
>
<
div
className=
{
styles
.
taskInfoLi
}
>
<
div
className=
{
styles
.
taskInfoParams
}
>
创建人
</
div
>
<
div
className=
{
styles
.
taskInfoValue
}
>
{
templateInfo
.
creator
}
</
div
>
</
div
>
<
div
className=
{
styles
.
taskInfoLi
}
>
<
div
className=
{
styles
.
taskInfoParams
}
>
版本
</
div
>
<
div
className=
{
styles
.
taskInfoValue
}
>
{
templateInfo
.
version
}
</
div
>
</
div
>
<
div
className=
{
styles
.
taskInfoLi
}
>
<
div
className=
{
styles
.
taskInfoParams
}
>
所属产品
</
div
>
<
div
className=
{
styles
.
taskInfoValue
}
>
{
getProductName
(
templateInfo
.
productId
)
}
</
div
>
</
div
>
</
div
>
)
}
{
activeFlowIndex
&&
(
<
div
className=
{
styles
.
suanziInfo
}
>
<
MyTooltip
>
<
div
className=
{
styles
.
title
}
>
{
taskInfo
?.
title
}
</
div
>
</
MyTooltip
>
<
div
className=
{
styles
.
tabs
}
>
<
div
className=
{
classNames
({
[
styles
.
tabLi
]:
true
,
[
styles
.
tabLiAcitve
]:
overviewActive
,
})
}
onClick=
{
()
=>
setOverviewActive
(
true
)
}
>
概览
</
div
>
<
div
className=
{
classNames
({
[
styles
.
tabLi
]:
true
,
[
styles
.
tabLiAcitve
]:
!
overviewActive
,
})
}
onClick=
{
()
=>
handleParams
()
}
>
参数
</
div
>
</
div
>
{
overviewActive
&&
(
<
div
className=
{
styles
.
overview
}
>
<
div
className=
{
styles
.
taskInfoLi
}
>
<
div
className=
{
styles
.
taskInfoParams
}
>
描述
</
div
>
<
div
className=
{
classNames
({
[
styles
.
taskInfoValue
]:
true
,
[
styles
.
taskInfoValueShowAll
]:
true
,
})
}
>
{
taskInfo
?.
description
}
</
div
>
</
div
>
<
div
className=
{
styles
.
taskInfoLi
}
>
<
div
className=
{
styles
.
taskInfoParams
}
>
算子版本
</
div
>
<
div
className=
{
styles
.
taskInfoValue
}
>
{
taskInfo
?.
version
||
"-"
}
</
div
>
</
div
>
</
div
>
)
}
{
!
overviewActive
&&
(
<
div
className=
{
styles
.
params
}
>
{
randerParameters
?.
map
((
parameter
:
any
)
=>
{
return
(
<
div
className=
{
styles
.
taskInfoLi
}
key=
{
parameter
.
name
}
>
<
div
className=
{
styles
.
taskInfoParams
}
>
{
parameter
.
name
}
</
div
>
<
div
className=
{
styles
.
taskInfoValue
}
>
{
parameter
.
defaultValue
||
"-"
}
</
div
>
</
div
>
);
})
}
</
div
>
)
}
</
div
>
)
}
</
div
>
<
div
className=
{
styles
.
swFlowBox
}
>
<
Flow
externalSelectedNodeId=
{
activeFlowIndex
}
tasks=
{
templateInfo
?.
tasks
}
setExternalSelectedNodeId=
{
setExternalSelectedNodeId
}
/>
</
div
>
</
div
>
</
div
>
);
});
export
default
TemplateDetail
;
src/views/ResourceCenter/UserResources/UserResourcesTemplate/index.module.css
0 → 100644
View file @
ba4c0f70
.template
{
padding
:
19px
24px
0
;
}
.top
{
display
:
flex
;
align-items
:
center
;
justify-content
:
space-between
;
margin-bottom
:
20px
;
}
.tableBox
{
height
:
calc
(
100vh
-
177px
);
}
.templateBox
{
border
:
2px
solid
#fff
;
box-shadow
:
0px
3px
12px
0px
rgba
(
3
,
47
,
105
,
0.09
);
border-radius
:
6px
;
background
:
linear-gradient
(
180deg
,
#f5f7fa
0%
,
#ffffff
100%
);
height
:
208px
;
box-sizing
:
border-box
;
padding
:
16px
20px
;
}
.templateTop
{
display
:
flex
;
align-items
:
center
;
justify-content
:
flex-start
;
margin-bottom
:
12px
;
}
.templateTopItem
{
font-size
:
12px
;
line-height
:
20px
;
color
:
rgba
(
138
,
144
,
153
,
1
);
}
.templateTopLine
{
width
:
1px
;
height
:
16px
;
background-color
:
rgba
(
221
,
225
,
230
,
1
);
margin
:
0
11px
;
}
.templateTitleBox
{
display
:
flex
;
align-items
:
center
;
justify-content
:
flex-start
;
margin-bottom
:
12px
;
}
.templateTitleBox
{
height
:
24px
;
}
.templateTitle
{
font-size
:
14px
;
line-height
:
22px
;
color
:
rgba
(
30
,
38
,
51
,
1
);
margin-left
:
8px
;
font-weight
:
550
;
}
.templateDesc
{
height
:
60px
;
font-size
:
12px
;
line-height
:
20px
;
color
:
rgba
(
86
,
92
,
102
,
1
);
margin-bottom
:
16px
;
overflow
:
hidden
;
text-overflow
:
ellipsis
;
-webkit-box-orient
:
vertical
;
-webkit-line-clamp
:
3
;
display
:
-webkit-box
;
}
.templateButtons
{
display
:
flex
;
align-items
:
center
;
justify-content
:
space-between
;
}
.button
{
cursor
:
pointer
;
line-height
:
22px
;
font-size
:
14px
;
color
:
rgba
(
19
,
112
,
255
,
1
);
}
src/views/ResourceCenter/UserResources/UserResourcesTemplate/index.tsx
0 → 100644
View file @
ba4c0f70
import
{
useEffect
,
useState
}
from
"react"
;
import
{
observer
}
from
"mobx-react"
;
import
SearchInput
from
"@/components/BusinessComponents/SearchInput"
;
import
MyButton
from
"@/components/mui/MyButton"
;
import
MySelect
from
"@/components/mui/MySelect"
;
import
Add
from
"@mui/icons-material/Add"
;
import
CardTable
from
"@/components/CommonComponents/CardTable"
;
import
useMyRequest
from
"@/hooks/useMyRequest"
;
import
{
getWorkflowspecList
,
deleteWorkflowspec
}
from
"@/api/resourceCenter"
;
import
MyDialog
from
"@/components/mui/MyDialog"
;
import
templateIcon
from
"@/assets/resourceCenter/templateIcon.svg"
;
import
{
useStores
}
from
"@/store"
;
import
{
toJS
}
from
"mobx"
;
import
ProductSelect
from
"@/components/BusinessComponents/ProductSelect"
;
import
WorkFlowEdit
from
"@/views/WorkFlowEdit"
;
import
{
useMessage
}
from
"@/components/MySnackbar"
;
import
TemplateDetail
from
"./TemplateDetail"
;
import
style
from
"./index.module.css"
;
const
UserResourcesTemplate
=
observer
(()
=>
{
const
[
title
,
setTitle
]
=
useState
(
""
);
const
Message
=
useMessage
();
const
[
showAddTemplate
,
setShowAddTemplate
]
=
useState
(
false
);
// 新增、编辑模板弹窗
const
[
showProductSelect
,
setShowProductSelect
]
=
useState
(
false
);
const
[
showDeleteDialog
,
setShowDeleteDialog
]
=
useState
(
false
);
const
[
showDetail
,
setShowDetail
]
=
useState
(
false
);
// 详情
const
[
templateId
,
setTemplateId
]
=
useState
(
""
);
const
[
product
,
setProduct
]
=
useState
(
""
);
// 搜索列表用
const
[
productId
,
setProductId
]
=
useState
(
""
);
// 新增模板用
const
[
list
,
setList
]
=
useState
([]);
const
{
productListStore
}
=
useStores
();
const
getProductName
=
(
productId
:
string
)
=>
{
let
res
=
"-"
;
toJS
(
productListStore
.
productList
).
forEach
((
item
)
=>
{
if
(
item
.
value
===
productId
)
{
res
=
item
.
label
;
}
});
return
res
;
};
const
renderItem
=
(
item
:
any
)
=>
{
return
(
<
div
className=
{
style
.
templateBox
}
>
<
div
className=
{
style
.
templateTop
}
>
<
div
className=
{
style
.
templateTopItem
}
>
{
getProductName
(
item
.
productId
)
}
</
div
>
<
div
className=
{
style
.
templateTopLine
}
></
div
>
<
div
className=
{
style
.
templateTopItem
}
>
{
item
.
version
}
</
div
>
<
div
className=
{
style
.
templateTopLine
}
></
div
>
<
div
className=
{
style
.
templateTopItem
}
>
{
item
.
updatedTime
}
</
div
>
</
div
>
<
div
className=
{
style
.
templateTitleBox
}
>
<
img
src=
{
templateIcon
}
alt=
""
/>
<
div
className=
{
style
.
templateTitle
}
>
{
item
.
title
}
</
div
>
</
div
>
<
div
className=
{
style
.
templateDesc
}
>
{
item
.
description
}
</
div
>
<
div
className=
{
style
.
templateButtons
}
>
<
div
className=
{
style
.
templateBL
}
>
<
span
className=
{
style
.
button
}
onClick=
{
()
=>
{
setTemplateId
(
item
.
id
);
setProductId
(
item
.
productId
);
setShowAddTemplate
(
true
);
}
}
>
升级
</
span
>
</
div
>
<
div
className=
{
style
.
templateBR
}
>
<
MyButton
text=
"删除"
variant=
"outlined"
style=
{
{
border
:
"1px solid rgba(221, 225, 230, 1)"
,
color
:
"rgba(138, 144, 153, 1)"
,
marginRight
:
"12px"
,
}
}
onClick=
{
()
=>
{
setShowDeleteDialog
(
true
);
setTemplateId
(
item
.
id
);
}
}
></
MyButton
>
<
MyButton
text=
"查看"
variant=
"outlined"
onClick=
{
()
=>
{
setTemplateId
(
item
.
id
);
setShowDetail
(
true
);
}
}
></
MyButton
>
</
div
>
</
div
>
</
div
>
);
};
// 获取模板列表
const
{
run
}
=
useMyRequest
(
getWorkflowspecList
,
{
onSuccess
:
(
result
:
any
)
=>
{
setList
(
result
.
data
);
},
});
useEffect
(()
=>
{
if
(
!
showAddTemplate
)
{
run
({
productId
:
product
===
"all"
?
""
:
product
,
title
,
});
}
},
[
run
,
title
,
product
,
showAddTemplate
]);
const
{
run
:
deleteWorkflowspecFn
}
=
useMyRequest
(
deleteWorkflowspec
,
{
onSuccess
:
()
=>
{
Message
.
success
(
"删除成功"
);
setShowDeleteDialog
(
false
);
run
({
productId
:
product
===
"all"
?
""
:
product
,
title
,
});
},
});
const
deleteConfirm
=
()
=>
{
deleteWorkflowspecFn
({
id
:
templateId
});
};
return
(
<
div
className=
{
style
.
template
}
>
<
div
className=
{
style
.
top
}
>
<
div
className=
{
style
.
topLeft
}
>
<
SearchInput
sx=
{
{
width
:
340
,
marginRight
:
"16px"
}
}
onKeyUp=
{
(
e
:
any
)
=>
{
if
(
e
.
keyCode
===
13
)
{
setTitle
(
e
.
target
.
value
);
}
}
}
></
SearchInput
>
<
MySelect
title=
"产品类型"
isTitle=
{
true
}
options=
{
[
{
label
:
"全部"
,
value
:
"all"
},
...
productListStore
?.
productList
,
]
||
[]
}
value=
{
product
}
onChange=
{
(
e
:
any
)
=>
setProduct
(
e
)
}
sx=
{
{
width
:
"150px"
,
height
:
"32px"
}
}
></
MySelect
>
</
div
>
<
div
className=
{
style
.
topRight
}
>
<
MyButton
text=
"新建自定义模板"
onClick=
{
()
=>
setShowProductSelect
(
true
)
}
startIcon=
{
<
Add
/>
}
></
MyButton
>
</
div
>
</
div
>
<
div
className=
{
style
.
tableBox
}
>
<
CardTable
data=
{
list
}
renderItem=
{
renderItem
}
minWidth=
{
377
}
></
CardTable
>
</
div
>
{
showAddTemplate
&&
(
<
WorkFlowEdit
id=
{
templateId
}
propsProductId=
{
productId
}
onBack=
{
()
=>
{
setShowAddTemplate
(
false
);
}
}
></
WorkFlowEdit
>
)
}
{
showProductSelect
&&
(
<
ProductSelect
open=
{
showProductSelect
}
setOpen=
{
setShowProductSelect
}
productId=
{
productId
}
setProductId=
{
setProductId
}
onConfirm=
{
()
=>
{
setTemplateId
(
""
);
setShowAddTemplate
(
true
);
}
}
></
ProductSelect
>
)
}
{
showDeleteDialog
&&
(
<
MyDialog
onClose=
{
()
=>
setShowDeleteDialog
(
false
)
}
onConfirm=
{
()
=>
deleteConfirm
()
}
open=
{
showDeleteDialog
}
isText=
{
true
}
title=
"提示"
>
确定要删除这个模板吗?
</
MyDialog
>
)
}
{
showDetail
&&
(
<
TemplateDetail
id=
{
templateId
}
setShowDetail=
{
setShowDetail
}
></
TemplateDetail
>
)
}
</
div
>
);
});
export
default
UserResourcesTemplate
;
src/views/ResourceCenter/UserResources/WorkflowOperator/components/AddOperator/index.module.css
View file @
ba4c0f70
.addOperatorBox
{
z-index
:
2
;
position
:
fixed
;
top
:
0
;
left
:
0
;
...
...
@@ -38,6 +39,7 @@
}
.form
{
width
:
368px
;
min-width
:
368px
;
box-sizing
:
border-box
;
padding
:
16px
24px
;
border
:
1px
solid
#ebedf0
;
...
...
@@ -47,6 +49,7 @@
}
.newForm
{
width
:
368px
;
min-width
:
368px
;
box-sizing
:
border-box
;
padding
:
16px
32px
0px
0
;
border-right
:
1px
solid
#ebedf0
;
...
...
@@ -61,6 +64,9 @@
}
.codeTitle
{
background-color
:
rgba
(
230
,
233
,
237
,
1
);
display
:
flex
;
justify-content
:
space-between
;
align-items
:
center
;
padding
:
11px
20px
;
color
:
rgba
(
30
,
38
,
51
,
1
);
font-size
:
14px
;
...
...
src/views/ResourceCenter/UserResources/WorkflowOperator/components/AddOperator/index.tsx
View file @
ba4c0f70
...
...
@@ -2,20 +2,21 @@
* @Author: 吴永生 15770852798@163.com
* @Date: 2022-10-18 16:12:55
* @LastEditors: 吴永生 15770852798@163.com
* @LastEditTime: 2022-10-
19 21:27:03
* @LastEditTime: 2022-10-
24 20:39:26
* @FilePath: /bkunyun/src/views/ResourceCenter/UserResources/WorkflowOperator/components/AddOperator/index.tsx
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
import
{
useEffect
,
useState
,
useCallback
,
useMemo
}
from
"react"
;
import
classNames
from
"classnames"
;
import
{
observer
}
from
"mobx-react"
;
import
{
Base64
}
from
"js-base64"
;
import
_
from
"lodash"
;
import
{
toJS
}
from
"mobx"
;
import
MyInput
from
"@/components/mui/MyInput"
;
import
MySelect
from
"@/components/mui/MySelect"
;
import
MyButton
from
"@/components/mui/MyButton"
;
import
style
from
"./index.module.css"
;
import
SwitchBatchFolw
from
"@/views/ResourceCenter/components/SwitchBatchFolw"
;
import
Code
from
"@/components/CommonComponents/Code"
;
import
RadioGroupOfButtonStyle
from
"@/components/CommonComponents/RadioGroupOfButtonStyle"
;
import
{
ITask
}
from
"@/views/Project/ProjectSubmitWork/interface"
;
...
...
@@ -23,15 +24,28 @@ import BatchOperatorFlow from "@/views/Project/components/Flow/components/BatchO
import
OperatorList
from
"@/views/CustomOperator/components/OperatorList"
;
import
FormItemBox
from
"@/components/mui/FormItemBox"
;
import
{
useStores
}
from
"@/store"
;
import
useMyRequest
from
"@/hooks/useMyRequest"
;
import
{
getActorEnvOptions
,
saveOperator
}
from
"@/api/resourceCenter"
;
import
{
IOperatorAddFormData
}
from
"../../interface"
;
import
{
checkFormData
,
checkParamsConfig
,
initCode
,
text
}
from
"./utils"
;
import
batchOperator
from
"@/assets/resourceCenter/batchOperator.svg"
;
import
flowOperator
from
"@/assets/resourceCenter/flowOperator.svg"
;
import
{
useMessage
}
from
"@/components/MySnackbar"
;
import
style
from
"./index.module.css"
;
import
MyPopover
from
"@/components/mui/MyPopover"
;
import
useCheckOperator
from
"@/views/CustomOperator/useCheckOperator"
;
interface
IAddOperator
{
setAddOpen
:
(
val
:
boolean
)
=>
void
;
pageType
:
string
;
setPageType
:
(
val
:
string
)
=>
void
;
detailsId
:
string
;
}
type
IBuildType
=
"ENVIRONMENT"
|
"OPERATOR"
;
const
AddOperator
=
observer
((
props
:
IAddOperator
)
=>
{
const
{
setAddOpen
}
=
props
;
const
{
pageType
,
setPageType
,
detailsId
}
=
props
;
const
Message
=
useMessage
();
/** 创建类型 BATCH - 批算子; FLOW - 流算子*/
const
[
taskType
,
setTaskType
]
=
useState
<
"BATCH"
|
"FLOW"
>
(
"BATCH"
);
...
...
@@ -44,9 +58,29 @@ const AddOperator = observer((props: IAddOperator) => {
const
[
inputActive
,
setInputActive
]
=
useState
(
false
);
/** 产品store */
const
{
productListStore
}
=
useStores
();
/** 产品第一项 默认所属产品值 */
const
defaultProduct
=
toJS
(
productListStore
?.
productList
)?.
length
?
toJS
(
productListStore
?.
productList
[
0
])?.
value
:
undefined
;
/** 应用环境下拉 */
const
[
actorEnvOptions
,
setActorEnvOptions
]
=
useState
([]);
/** 参数配置 */
const
[
code
,
setCode
]
=
useState
(
JSON
.
stringify
(
initCode
,
null
,
"
\
t"
));
/** 运行脚本 */
const
[
command
,
setCommand
]
=
useState
<
string
>
(
""
);
const
[
code
,
setCode
]
=
useState
(
""
);
// const [formData, setFormData] = useState<any>();
/** 表单数据 */
const
[
formData
,
setFormData
]
=
useState
<
IOperatorAddFormData
>
({});
/** 表单数据修改 */
const
[
formErrors
,
setFormErrors
]
=
useState
<
IOperatorAddFormData
>
({});
/** 是否打开帮助手册 */
const
[
tipsOpen
,
setTipsOpen
]
=
useState
<
boolean
>
(
false
);
const
{
handleCheck
,
checkStatus
}
=
useCheckOperator
(
operatorList
,
()
=>
{},
"流程编排不能为空"
);
const
buildTypeList
=
useMemo
(()
=>
{
return
[
...
...
@@ -55,29 +89,161 @@ const AddOperator = observer((props: IAddOperator) => {
];
},
[]);
/** 表单数据 */
const
changeFormData
=
useCallback
(
(
val
:
IOperatorAddFormData
)
=>
{
setFormData
({
...
formData
,
...
val
});
},
[
formData
]
);
const
paramsConfigBlur
=
useCallback
(()
=>
{
console
.
log
(
2
);
if
(
code
===
""
)
return
;
let
result
;
try
{
result
=
JSON
.
stringify
(
JSON
.
parse
(
code
),
null
,
"
\
t"
);
if
(
typeof
result
===
"string"
)
{
setCode
(
result
);
const
checkErrorArr
=
checkParamsConfig
(
result
);
if
(
checkErrorArr
.
length
)
{
// Message.error("参数配置不正确!");
// setFormErrors({
// ...formErrors,
// ...{ parameters: "参数配置不正确!" },
// });
const
codeDom
=
document
.
getElementById
(
"paramsConfig"
);
const
all
=
codeDom
?.
getElementsByClassName
(
"cm-line"
);
const
allArr
=
Array
.
prototype
.
slice
.
call
(
all
);
for
(
let
x
=
0
;
x
<
allArr
?.
length
;
x
++
)
{
const
a
=
`
${
allArr
[
x
]?.
innerHTML
}
`
.replace(/"/g, "")
.replace(/,/g, "")
.replace(/\t/g, "");
if (checkErrorArr.includes(a)) {
setTimeout(() => {
allArr[x].style =
"text-decoration: wavy underline; text-decoration-color: #ff4e4e;";
}, 200);
}
}
} else {
const newFormErrors = _.cloneDeep(formErrors);
delete newFormErrors.parameters;
setFormErrors(newFormErrors);
}
}
} catch (error) {
Message.error("JSON格式不正确!");
console.log("JSON格式不正确!");
}
}, [Message, code, formErrors]);
/** 获取应用环境下拉 */
const { run: fetchActorEnvOptions } = useMyRequest(getActorEnvOptions, {
onSuccess: (res: any) => {
if (res.message === "success") {
const newActorEnvOptions =
res?.data?.map((item: any) => {
return { label: item.title, value: item.id };
}) || [];
setActorEnvOptions(newActorEnvOptions);
}
},
});
useEffect(() => {
fetchActorEnvOptions({ type: taskType });
}, [fetchActorEnvOptions, taskType]);
/** 切换类型 */
const handleRadio = (val: IBuildType) => {
setBatchBuildType(val);
};
const
handleSubmit
=
()
=>
{
console
.
log
(
33
);
const handleSubmit = useCallback(() => {
const resultErrors = checkFormData(formData, batchBuildType);
// paramsConfigBlur();
formErrors?.parameters
? setFormErrors({ ...resultErrors, parameters: formErrors.parameters })
: setFormErrors({ ...resultErrors });
if (taskType === "BATCH" && batchBuildType === "OPERATOR") {
handleCheck();
}
if (Object.getOwnPropertyNames(resultErrors)?.length || !checkStatus)
return;
let newParameters = [];
try {
newParameters = JSON.parse(code);
} catch (err) {
console.log(err);
}
console.log(operatorList, "operatorList");
const params = {
...formData,
...(batchBuildType === "ENVIRONMENT" && taskType === "BATCH"
? { command: Base64.encode(command) }
: {}),
parameters:
batchBuildType === "OPERATOR" && taskType === "BATCH"
? operatorList
: newParameters,
type: taskType,
};
/** 基于流算子没有应用环境字段 */
if (batchBuildType === "OPERATOR") {
delete params.envId;
}
saveOperator(params).then((res: any) => {
if (res?.message === "success") {
Message.success("构建成功");
} else {
Message.success(res?.message || "构建失败");
}
});
}, [
Message,
batchBuildType,
checkStatus,
code,
command,
formData,
formErrors.parameters,
handleCheck,
operatorList,
taskType,
]);
return (
<div className={style.addOperatorBox}>
<div className={style.left}>
<SwitchBatchFolw
bottomImg={flowOperator}
topImg={batchOperator}
active={taskType}
setActive=
{
setTaskType
}
goBack=
{
()
=>
setAddOpen
(
false
)
}
></
SwitchBatchFolw
>
setActive={(e: "BATCH" | "FLOW") => {
setBatchBuildType("ENVIRONMENT");
setTaskType(e);
}}
goBack={() => setPageType("")}
/>
</div>
<div className={style.right}>
<div className={style.title}>
{taskType === "BATCH" ? "批式算子信息" : "流式算子信息"}
</div>
<
div
style=
{
{
paddingBottom
:
"20px"
}
}
>
{taskType === "BATCH" ? (
<div
style={{
paddingBottom: batchBuildType === "ENVIRONMENT" ? "20px" : "2px",
}}
>
<RadioGroupOfButtonStyle
RadiosBoxStyle={{ width: 236 }}
value={batchBuildType}
...
...
@@ -85,23 +251,35 @@ const AddOperator = observer((props: IAddOperator) => {
handleRadio={handleRadio}
/>
</div>
) : null}
<div className={style.content}>
<div
className={classNames({
[style.form]: batchBuildType === "ENVIRONMENT",
[
style
.
newForm
]:
batchBuildType
!=
"ENVIRONMENT"
,
[style.newForm]: batchBuildType !=
=
"ENVIRONMENT",
})}
>
<FormItemBox
label="算子名称"
labelClassName={style.labelClassName}
className=
{
style
.
operatorFormItem
}
className={classNames({
[style.operatorFormItem]: formErrors?.title,
})}
itemFlex="column"
errorMessage={formErrors?.title || ""}
require
>
<MyInput
helperText=
"30字符以内,仅限字母、数字、中文"
helperText={
formErrors?.title ? "" : "15字符以内,仅限字母、数字、中文"
}
placeholder="请输入算子名称"
value={formData?.title}
onChange={(e) => {
if (e.target.value?.length > 15) return;
changeFormData({ title: e.target.value });
}}
/>
</FormItemBox>
<FormItemBox
...
...
@@ -109,20 +287,35 @@ const AddOperator = observer((props: IAddOperator) => {
labelClassName={style.labelClassName}
className={style.operatorFormItem}
itemFlex="column"
errorMessage={formErrors?.version || ""}
require
>
<
MyInput
/>
<MyInput
value={formData?.version}
onChange={(e) => {
changeFormData({ version: e.target.value });
}}
/>
</FormItemBox>
<FormItemBox
label="所属产品"
labelClassName={style.labelClassName}
className=
{
style
.
operatorFormItem
}
errorMessage={formErrors?.productId || ""}
className={classNames({
[style.operatorFormItem]: batchBuildType === "ENVIRONMENT",
})}
itemFlex="column"
require
>
<MySelect
fullWidth
options={productListStore?.productList || []}
defaultValue={defaultProduct}
value={formData?.productId}
onChange={(e) => {
changeFormData({ productId: e });
}}
/>
</FormItemBox>
{batchBuildType === "ENVIRONMENT" ? (
...
...
@@ -130,12 +323,17 @@ const AddOperator = observer((props: IAddOperator) => {
label="应用环境"
labelClassName={style.labelClassName}
className={style.operatorFormItem}
errorMessage={formErrors?.envId || ""}
itemFlex="column"
require
>
<MySelect
fullWidth
options=
{
[{
label
:
"cadd"
,
value
:
"CADD"
}]
}
options={actorEnvOptions || []}
value={formData?.envId}
onChange={(e) => {
changeFormData({ envId: e });
}}
/>
</FormItemBox>
) : null}
...
...
@@ -143,22 +341,50 @@ const AddOperator = observer((props: IAddOperator) => {
<FormItemBox
label="描述"
labelClassName={style.labelClassName}
className=
{
style
.
operatorFormItem
}
itemFlex="column"
errorMessage={formErrors?.description || ""}
>
<
MyInput
multiline
rows=
{
4
}
placeholder=
"请输入算子描述"
/>
<MyInput
multiline
rows={4}
placeholder="请输入算子描述"
value={formData?.description}
onChange={(e) => {
changeFormData({ description: e.target.value });
}}
/>
</FormItemBox>
) : null}
</div>
{batchBuildType === "ENVIRONMENT" ? (
<div className={style.codeBox}>
<
div
className=
{
style
.
codeTitle
}
>
参数配置
</
div
>
<div className={style.codeTitle}>
<span>参数配置</span>
<MyPopover
open={tipsOpen}
changeOpen={(val) => setTipsOpen(val)}
content={<pre>{text}</pre>}
transformOrigin={{
vertical: "top",
horizontal: "right",
}}
>
<span style={{ color: "#1370FF" }}>帮助手册</span>
</MyPopover>
</div>
<div className={style.code}>
<Code
id="paramsConfig"
value={code}
onChange=
{
(
e
:
string
)
=>
setCode
(
e
)
}
// placeholder="dd"
onChange={(e: string, viewUpdate: any) => {
setCode(e);
}}
onBlur={paramsConfigBlur}
height="535px"
width="600"
style={{ flex: 1 }}
/>
</div>
</div>
...
...
@@ -169,17 +395,23 @@ const AddOperator = observer((props: IAddOperator) => {
labelClassName={style.labelClassName}
className={style.operatorFormItem}
itemFlex="column"
errorMessage={formErrors?.description || ""}
>
<MyInput
style={{ width: "420px" }}
multiline
rows={10}
placeholder="请输入算子描述"
value={formData?.description}
onChange={(e) => {
changeFormData({ description: e.target.value });
}}
/>
</FormItemBox>
</div>
)}
</div>
{taskType === "FLOW" ? null : (
<div className={style.parameterConfigBox}>
<div className={style.codeTitle}>
{batchBuildType === "ENVIRONMENT" ? "运行脚本" : "流程编排"}
...
...
@@ -187,8 +419,8 @@ const AddOperator = observer((props: IAddOperator) => {
{batchBuildType === "ENVIRONMENT" ? (
<div className={style.code}>
<Code
value=
{
code
}
onChange=
{
(
e
:
string
)
=>
setCode
(
e
)
}
value={command
}
onChange={(e: string) => setCommand
(e)}
height="350px"
/>
</div>
...
...
@@ -201,6 +433,7 @@ const AddOperator = observer((props: IAddOperator) => {
operatorList={operatorList}
setOperatorList={setOperatorList}
setInputActive={setInputActive}
productId={formData.productId || defaultProduct || ""}
/>
<BatchOperatorFlow
tasks={operatorList}
...
...
@@ -215,8 +448,10 @@ const AddOperator = observer((props: IAddOperator) => {
</div>
)}
</div>
)}
<div className={style.buttonBox}>
<
MyButton
text=
"开始构建"
></
MyButton
>
<MyButton text="开始构建"
onClick={handleSubmit} /
>
</div>
</div>
</div>
...
...
src/views/ResourceCenter/UserResources/WorkflowOperator/components/AddOperator/utils.ts
0 → 100644
View file @
ba4c0f70
/*
* @Author: 吴永生 15770852798@163.com
* @Date: 2022-10-20 17:36:14
* @LastEditors: 吴永生 15770852798@163.com
* @LastEditTime: 2022-10-24 15:52:56
* @FilePath: /bkunyun/src/views/ResourceCenter/UserResources/WorkflowOperator/components/AddOperator/utils.ts
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
import
{
IOperatorAddFormData
}
from
"../../interface"
;
type
IBuildType
=
"ENVIRONMENT"
|
"OPERATOR"
;
export
const
checkFormData
=
(
formData
:
IOperatorAddFormData
,
taskType
:
IBuildType
)
=>
{
const
reg
=
new
RegExp
(
"^[A-Za-z0-9
\
u4e00-
\
u9fa5]{1,15}$"
);
const
result
:
IOperatorAddFormData
=
{}
if
(
!
formData
?.
title
){
result
.
title
=
'请输入算子名称'
}
if
(
!
reg
.
test
(
formData
?.
title
||
''
)){
result
.
title
=
'格式不正确,仅限大小写字母、数字、中文'
}
if
(
!
/^
[
1-9
]\d?(\.(
0|
[
1-9
]\d?)){2}
$/
.
test
(
formData
?.
version
||
''
)){
result
.
version
=
'格式不正确,必须为X.Y.Z格式,且XYZ必须为0~99的正整数'
}
if
(
!
formData
?.
version
){
result
.
version
=
'请输入算子版本'
}
if
(
!
formData
?.
productId
){
result
.
productId
=
'请选择所属产品'
}
if
(
taskType
===
'ENVIRONMENT'
&&
!
formData
?.
envId
){
result
.
envId
=
'请选择应用环境'
}
return
result
}
/** 参数配置校验 */
export
const
checkParamsConfig
=
(
val
:
string
)
=>
{
let
result
:
any
=
[]
try
{
const
value
=
JSON
.
parse
(
val
)
value
?.
length
&&
value
.
forEach
((
item
:
any
)
=>
{
const
nameReg
=
new
RegExp
(
"^[A-Za-z][A-Za-z0-9_]{1,14}$"
);
const
titleReg
=
new
RegExp
(
"^[A-Za-z0-9
\
u4e00-
\
u9fa5]{1,15}$"
);
if
(
!
nameReg
.
test
(
item
?.
name
)
){
result
.
push
(
`name:
${
item
?.
name
}
`)
}
if( !titleReg.test(item?.title) ){
result.push(`
title
:
$
{
item
?.
title
}
`)
}
if( item?.description > 300 ){
result.push(`
description
:
$
{
item
?.
description
}
`)
}
if( !['STRING','FILE','DATASET','INT','FLOAT','DOUBLE','BOOLEAN','ARRAY_STRING','ARRAY_FILE','ARRAY_DATASET','ARRAY_INT','ARRAY_FLOAT','ARRAY_DOUBLE','ARRAY_BOOLEAN'].includes(item?.classType )){
result.push(`
classType
:
$
{
item
?.
classType
}
`)
}
if(!['true','false'].includes(String(item?.required)) ) {
result.push(`
required
:
$
{
item
?.
required
}
`)
}
if( !['PATH','DATASET','FILE','INPUT','SELECT','MULTIPLESELECT','RADIO','CHECKBOX'].includes(item?.domType )){
result.push(`
domType
:
$
{
item
?.
domType
}
`)
}
})
} catch(error){
console.log(error)
}
return result
}
export const initCode = [{
"name" : "timeout",
"classType" : "INT",
"required" : false,
"defaultValue" : 10000,
"description" : "",
"hidden" : true,
"title" : "",
"order" : 0,
"domType" : "INPUT",
"choices" : [
{
"label" : "是",
"value" : "true"
},
{
"label": "否",
"value": "false"
}
],
"validators" : [
{
"regex" : "^.*\\.(pdb|PDB|pdbqt|PDBQT)$",
"message" : "请输入PDB或PDBQT文件"
}
]
}]
export const text = `
{
// 参数名, 必填,在15字符以内,仅限大小写字母、数字、"_",且只能以大小写字母开头
"name"
:
"timeout"
,
/** 参数类型。可选值有 STRING:字符串、FILE:文件、DATASET:数据集、INT:整型、FLOAT:单精度浮点型、
* DOUBLE:多精度浮点型、BOOLEAN:布尔值、ARRAY_STRING:字符串数组、ARRAY_FILE:文件数组、ARRAY_DATASET:数据集数组、
* ARRAY_INT:整型数组、ARRAY_FLOAT:单精度浮点型数组、ARRAY_DOUBLE:多精度浮点型数组、ARRAY_BOOLEAN:布尔值数组
*/
"classType"
:
"INT"
,
// 是否必填。在使用该算子时是否必须输入改参数的值
"required"
:
false
,
// 默认值
"defaultValue"
:
10000
,
// 参数描述。在300字符以内
"description"
:
""
,
// 是否隐藏,隐藏就在页面不显示该参数 必填
"hidden"
:
true
,
// 页面展示的参数的名称
"title"
:
""
,
// 参数展示的顺序优先级
"order"
:
0
,
/**
* 前端填值的方式 PATH:路径选择器、DATASET:数据集选择器、FILE:文件选择器、INPUT:输入框、
* SELECT:下拉框、MULTIPLESELECT:多选下拉框、RADIO:单选按钮、CHECKBOX:多选按钮
*/
"domType"
:
"INPUT"
,
// 选项。当domType为SELECT、MULTIPLESELECT、RADIO、CHECKBOX时生效。以对象数组的形式保存
"choices"
:
[
{
// 在前端展示的值
"label"
:
"是"
,
//选中时传递服务使用的值
"value"
:
"true"
},
],
//用于校验输入值。以对象数组的形式保存
"validators"
:
[
{
//正则表达式
"regex"
:
"^.*
\\
.(pdb|PDB|pdbqt|PDBQT)$"
,
//不符合正则时的报错信息
"message"
:
"请输入PDB或PDBQT文件"
}
]
}
`
\ No newline at end of file
src/views/ResourceCenter/UserResources/WorkflowOperator/components/OperatorCard/index.module.css
View file @
ba4c0f70
...
...
@@ -3,6 +3,7 @@
height
:
108px
;
padding
:
20px
;
margin
:
0
20px
20px
0
;
cursor
:
pointer
;
background
:
linear-gradient
(
180deg
,
#f5f7fa
0%
,
#ffffff
100%
);
box-shadow
:
0px
3px
12px
0px
rgba
(
3
,
47
,
105
,
0.09
);
border-radius
:
6px
;
...
...
@@ -15,10 +16,20 @@
.itemHeaderBox
{
display
:
flex
;
justify-content
:
space-between
;
align-items
:
center
;
margin-bottom
:
20px
;
}
.startTitleBox
{
width
:
36px
;
height
:
36px
;
border-radius
:
4px
;
background
:
#a657f4
;
color
:
#fff
;
font-size
:
18px
;
font-weight
:
600
;
text-align
:
center
;
line-height
:
36px
;
}
.itemContentBox
{
display
:
flex
;
flex-wrap
:
wrap
;
...
...
@@ -30,17 +41,26 @@
color
:
#1e2633
;
}
.titleBox
{
display
:
block
;
font-size
:
16px
;
color
:
#1e2633
;
}
.operatorTypeBox
{
display
:
block
;
color
:
#8a9099
;
font-size
:
12px
;
}
.operationBox
{
display
:
inline-block
;
width
:
24px
;
height
:
24px
;
text-align
:
center
;
line-height
:
24px
;
cursor
:
pointer
;
}
.operationBox
:hover
{
background-color
:
#ebedf0
;
border-radius
:
2px
;
}
.infoBox
{
width
:
50%
;
font-weight
:
400
;
...
...
src/views/ResourceCenter/UserResources/WorkflowOperator/components/OperatorCard/index.tsx
View file @
ba4c0f70
...
...
@@ -2,45 +2,90 @@
* @Author: 吴永生 15770852798@163.com
* @Date: 2022-10-17 14:35:11
* @LastEditors: 吴永生 15770852798@163.com
* @LastEditTime: 2022-10-
19 21:08:31
* @LastEditTime: 2022-10-
24 20:38:16
* @FilePath: /bkunyun/src/views/ResourceCenter/UserResources/WorkflowOperator/index.tsx
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
import
styles
from
"./index.module.css"
;
import
{
IOperatorInfo
}
from
"../../interface"
;
import
{
IOperatorInfo
,
operatorType
}
from
"../../interface"
;
import
{
observer
}
from
"mobx-react"
;
import
{
useStores
}
from
"@/store"
;
import
{
useMemo
}
from
"react"
;
import
MyMenu
from
"@/components/mui/MyMenu"
;
import
{
useNavigate
}
from
"react-router-dom"
;
interface
IProps
{
operatorInfo
:
IOperatorInfo
;
setPageType
:
(
val
:
string
)
=>
void
;
setDetailsId
:
(
val
:
string
)
=>
void
;
}
const
OperatorCard
=
(
props
:
IProps
)
=>
{
const
OperatorCard
=
observer
((
props
:
IProps
)
=>
{
const
navigate
=
useNavigate
();
const
{
operatorInfo
:
{
title
=
""
,
type
,
version
},
operatorInfo
:
{
title
=
""
,
type
,
version
,
productId
,
createdTime
,
id
},
setPageType
,
setDetailsId
,
}
=
props
;
/** 产品store */
const
{
productListStore
}
=
useStores
();
const
productText
=
useMemo
(()
=>
{
const
result
=
productListStore
.
productList
?.
filter
((
item
)
=>
{
return
item
.
value
===
productId
;
});
return
result
?.
length
?
result
[
0
].
label
:
""
;
},
[
productListStore
.
productList
,
productId
]);
const
onClickOperation
=
(
val
:
string
)
=>
{
if
(
val
===
"upgrade"
)
{
setPageType
(
"edit"
);
setDetailsId
(
id
||
""
);
}
};
const
handleToSeeOperator
=
(
item
:
any
)
=>
{
navigate
(
"/utility/resourceCenter/userResources/seeFloe"
,
{
state
:
{
id
:
item
.
id
},
});
};
return
(
<
div
className=
{
styles
.
itemBox
}
>
<
div
className=
{
styles
.
itemBox
}
onClick=
{
handleToSeeOperator
}
>
<
div
className=
{
styles
.
itemHeaderBox
}
>
<
img
alt=
""
style=
{
{
width
:
36
,
height
:
36
}
}
/
>
<
div
>
<
div
className=
{
styles
.
startTitleBox
}
>
{
title
?.
slice
(
0
,
1
)
}
</
div
>
<
div
style=
{
{
flex
:
1
,
marginLeft
:
12
}
}
>
<
b
className=
{
styles
.
titleBox
}
>
{
title
}
</
b
>
<
span
className=
{
styles
.
operatorTypeBox
}
>
批算子
</
span
>
<
span
className=
{
styles
.
operatorTypeBox
}
>
{
operatorType
[
type
]
||
""
}
</
span
>
</
div
>
<
MyMenu
value=
""
options=
{
[{
label
:
"升级"
,
value
:
"upgrade"
}]
}
hasTriangle=
{
false
}
setValue=
{
onClickOperation
}
sx=
{
{
zIndex
:
1601
,
}
}
>
<
span
className=
{
styles
.
operationBox
}
>
大大
</
span
>
</
MyMenu
>
</
div
>
<
div
className=
{
styles
.
itemContentBox
}
>
<
p
className=
{
styles
.
infoBox
}
>
所属产品:
<
span
>
{
type
}
</
span
>
所属产品:
<
span
>
{
productText
}
</
span
>
</
p
>
<
p
className=
{
styles
.
infoBox
}
>
算子版本:
<
span
>
{
`V${version}`
}
</
span
>
</
p
>
<
p
className=
{
styles
.
infoBox
}
>
创建时间:
<
span
>
2022-10-11
</
span
>
创建时间:
<
span
>
{
createdTime
}
</
span
>
</
p
>
</
div
>
</
div
>
);
};
}
)
;
export
default
OperatorCard
;
src/views/ResourceCenter/UserResources/WorkflowOperator/index.tsx
View file @
ba4c0f70
...
...
@@ -2,13 +2,15 @@
* @Author: 吴永生 15770852798@163.com
* @Date: 2022-10-17 14:35:11
* @LastEditors: 吴永生 15770852798@163.com
* @LastEditTime: 2022-10-
19 21:11:50
* @LastEditTime: 2022-10-
24 20:40:16
* @FilePath: /bkunyun/src/views/ResourceCenter/UserResources/WorkflowOperator/index.tsx
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
// 应用环境
import
{
useEffect
,
useState
}
from
"react"
;
import
{
use
Callback
,
use
Effect
,
useState
}
from
"react"
;
import
{
observer
}
from
"mobx-react"
;
import
_
from
"lodash"
;
import
Add
from
"@mui/icons-material/Add"
;
import
SearchInput
from
"@/components/BusinessComponents/SearchInput"
;
import
MySelect
from
"@/components/mui/MySelect"
;
...
...
@@ -17,34 +19,55 @@ import OperatorCard from "./components/OperatorCard";
import
AddOperator
from
"./components/AddOperator"
;
import
{
useStores
}
from
"@/store"
;
import
{
getOperatorList
,
IOperatorListParams
}
from
"@/api/resourceCenter"
;
import
styles
from
"./index.module.css"
;
import
useMyRequest
from
"@/hooks/useMyRequest"
;
import
{
IOperatorInfo
}
from
"./interface"
;
import
styles
from
"./index.module.css"
;
const
WorkflowOperator
=
observer
(()
=>
{
const
[
addOpen
,
setAddOpen
]
=
useState
<
boolean
>
(
false
);
const
[
pageType
,
setPageType
]
=
useState
<
string
>
(
""
);
/** 产品store */
const
{
productListStore
}
=
useStores
();
/** 算子列表参数 */
const
[
searchParams
,
setSearchParams
]
=
useState
<
IOperatorListParams
>
({
keyword
:
""
,
productId
:
""
,
type
:
""
,
productId
:
"
all
"
,
type
:
"
all
"
,
});
const
[
detailsId
,
setDetailsId
]
=
useState
<
string
>
(
""
);
const
[
list
,
setList
]
=
useState
<
IOperatorInfo
[]
>
();
const
{
run
:
getList
}
=
useMyRequest
(
getOperatorList
,
{
// refreshDeps: [],
onSuccess
:
(
res
)
=>
{
console
.
log
(
res
);
setList
(
res
?.
data
);
},
});
const
newGetList
=
useCallback
(()
=>
{
const
params
=
_
.
cloneDeep
(
searchParams
);
if
(
params
.
productId
===
"all"
)
{
params
.
productId
=
""
;
}
if
(
params
.
type
===
"all"
)
{
params
.
type
=
""
;
}
getList
(
params
);
},
[
getList
,
searchParams
]);
// 按回车搜索
const
handleKeyWordChangeKeyUp
=
(
e
:
any
)
=>
{
if
(
e
.
keyCode
===
13
)
{
newGetList
();
}
};
useEffect
(()
=>
{
g
etList
();
},
[]);
newG
etList
();
},
[
searchParams
.
productId
,
searchParams
.
type
]);
return
(
<>
...
...
@@ -55,6 +78,7 @@ const WorkflowOperator = observer(() => {
sx=
{
{
width
:
340
,
marginRight
:
"16px"
}
}
placeholder=
"输入关键词搜索"
value=
{
searchParams
.
keyword
}
onKeyUp=
{
handleKeyWordChangeKeyUp
}
onChange=
{
(
e
)
=>
{
setSearchParams
({
...
searchParams
,
keyword
:
e
.
target
.
value
});
}
}
...
...
@@ -62,8 +86,13 @@ const WorkflowOperator = observer(() => {
<
MySelect
title=
"所属产品"
isTitle=
{
true
}
options=
{
productListStore
?.
productList
||
[]
}
value=
{
searchParams
.
keyword
}
options=
{
[
{
label
:
"全部"
,
value
:
"all"
},
...
productListStore
?.
productList
,
]
||
[]
}
value=
{
searchParams
.
productId
}
onChange=
{
(
e
)
=>
{
setSearchParams
({
...
searchParams
,
productId
:
e
});
}
}
...
...
@@ -73,11 +102,12 @@ const WorkflowOperator = observer(() => {
<
MySelect
title=
"环境类型"
isTitle=
{
true
}
value=
{
searchParams
.
keyword
}
value=
{
searchParams
.
type
}
onChange=
{
(
e
)
=>
{
setSearchParams
({
...
searchParams
,
type
:
e
});
}
}
options=
{
[
{
label
:
"全部"
,
value
:
"all"
},
{
label
:
"批式"
,
value
:
"BATCH"
,
...
...
@@ -92,22 +122,32 @@ const WorkflowOperator = observer(() => {
</
div
>
<
MyButton
text=
"构建算子"
img=
{
<
span
style=
{
{
fontSize
:
"14px"
,
marginRight
:
"8px"
}
}
className=
"iconfont icon-dianzan"
></
span
>
}
onClick=
{
()
=>
setAddOpen
(
true
)
}
startIcon=
{
<
Add
/>
}
onClick=
{
()
=>
{
setPageType
(
"add"
);
setDetailsId
(
""
);
}
}
></
MyButton
>
</
div
>
<
div
className=
{
styles
.
contentBox
}
>
{
list
?.
map
((
item
)
=>
{
return
<
OperatorCard
operatorInfo=
{
item
}
/>;
return
(
<
OperatorCard
setDetailsId=
{
setDetailsId
}
operatorInfo=
{
item
}
setPageType=
{
setPageType
}
/>
);
})
}
</
div
>
</
div
>
{
addOpen
&&
<
AddOperator
setAddOpen=
{
setAddOpen
}
/>
}
{
pageType
&&
(
<
AddOperator
detailsId=
{
detailsId
}
setPageType=
{
setPageType
}
pageType=
{
pageType
}
/>
)
}
</>
);
});
...
...
src/views/ResourceCenter/UserResources/WorkflowOperator/interface.ts
View file @
ba4c0f70
...
...
@@ -2,15 +2,32 @@
* @Author: 吴永生 15770852798@163.com
* @Date: 2022-10-19 20:50:18
* @LastEditors: 吴永生 15770852798@163.com
* @LastEditTime: 2022-10-
19 21:09:14
* @LastEditTime: 2022-10-
24 20:38:09
* @FilePath: /bkunyun/src/views/ResourceCenter/UserResources/WorkflowOperator/interface.ts
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
export
type
IOperatorType
=
'BATCH'
|
'FLOW'
export
interface
IOperatorInfo
{
id
:
string
;
title
:
string
;
type
:
IOperatorType
;
version
:
string
;
productId
:
string
;
createdTime
:
string
;
}
export
enum
operatorType
{
'FLOW'
=
'流算子'
,
'BATCH'
=
'批算子'
,
}
export
interface
IOperatorAddFormData
{
title
?:
string
;
type
?:
IOperatorType
;
version
?:
string
;
productId
?:
string
;
description
?:
string
;
envId
?:
string
;
parameters
?:
any
}
\ No newline at end of file
src/views/ResourceCenter/UserResources/index.tsx
View file @
ba4c0f70
import
style
from
"./index.module.css"
;
import
usePass
from
"@/hooks/usePass"
;
import
UserResourcesTemplate
from
"./UserResourcesTemplate"
;
import
UserResourcesEnvironment
from
"./UserResourcesEnvironment"
;
import
{
useMemo
,
useState
}
from
"react"
;
import
classNames
from
"classnames"
;
import
{
useMemo
}
from
"react"
;
import
Tabs
from
"@/components/mui/MyTabs"
;
import
WorkflowOperator
from
"./WorkflowOperator"
;
import
OperatorDetails
from
"./WorkflowOperator/components/OperatorDetails"
;
...
...
@@ -13,7 +13,7 @@ const UserResources = () => {
{
label
:
"工作流模版"
,
value
:
"USERRESOURCES_TEMPLATE"
,
component
:
<
div
/>,
component
:
<
UserResourcesTemplate
/>,
hide
:
!
isPass
(
"USERRESOURCES_TEMPLATE"
),
},
{
...
...
@@ -36,7 +36,7 @@ const UserResources = () => {
<
Tabs
title=
"个人资源"
tabList=
{
tabList
}
defaultValue=
{
"USERRESOURCES_
ENVIRONMENT
"
}
defaultValue=
{
"USERRESOURCES_
TEMPLATE
"
}
tabPanelSx=
{
{
padding
:
"0"
}
}
/>
{
/* <OperatorDetails /> */
}
...
...
src/views/ResourceCenter/components/SwitchBatchFolw/index.module.css
View file @
ba4c0f70
.switchBatchFolw
{
height
:
100vh
;
width
:
5
0vh
;
width
:
4
0vh
;
background-color
:
rgba
(
247
,
248
,
250
,
1
);
display
:
flex
;
flex-direction
:
column
;
align-items
:
flex-end
;
}
.goBackBox
{
box-sizing
:
border-box
;
height
:
110px
;
padding
:
64px
0
14px
25%
;
height
:
120px
;
padding
:
64px
0
24px
;
margin-right
:
44px
;
line-height
:
32px
;
font-size
:
18px
;
color
:
#8a9099
;
display
:
flex
;
justify-content
:
flex-start
;
align-items
:
center
;
width
:
calc
(
82%
-
54px
);
}
.goBackIcon
{
width
:
32px
;
...
...
@@ -31,33 +34,35 @@
color
:
#8a9099
;
}
.switchBox
{
width
:
100%
;
flex
:
1
;
display
:
flex
;
flex-direction
:
column
;
justify-content
:
space-around
;
justify-content
:
flex-start
;
align-items
:
flex-end
;
position
:
relative
;
}
.switchItem
{
width
:
100%
;
width
:
calc
(
82%
-
44px
)
;
position
:
relative
;
padding-right
:
44px
;
display
:
flex
;
flex-direction
:
column
;
align-items
:
flex-end
;
margin-bottom
:
40px
;
padding-right
:
calc
(
2%
+
34px
);
}
.activeSwitchItem
{
padding-right
:
34px
;
width
:
calc
(
86%
-
44px
);
}
.itemImg
{
width
:
58
%
;
width
:
100
%
;
cursor
:
pointer
;
}
.itemImg
:hover
{
box-shadow
:
0px
8px
20px
-6px
rgba
(
3
,
47
,
105
,
0.14
);
}
.activeImg
{
width
:
64%
;
box-shadow
:
0px
12px
30px
-8px
rgba
(
3
,
47
,
105
,
0.18
);
}
.activeImg
:hover
{
...
...
src/views/ResourceCenter/components/SwitchBatchFolw/index.tsx
View file @
ba4c0f70
/*
* @Author: 吴永生 15770852798@163.com
* @Date: 2022-10-18 09:32:40
* @LastEditors: 吴永生 15770852798@163.com
* @LastEditTime: 2022-10-24 14:57:06
* @FilePath: /bkunyun/src/views/ResourceCenter/components/SwitchBatchFolw/index.tsx
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
import
batchImg
from
"@/assets/resourceCenter/batchImg.svg"
;
import
flowImg
from
"@/assets/resourceCenter/flowImg.svg"
;
import
classNames
from
"classnames"
;
import
goback
from
"@/assets/project/goback.svg"
;
import
style
from
"./index.module.css"
;
type
ISwitchBatchFolwProps
=
{
topImg
?:
string
;
bottomImg
?:
string
;
active
:
"BATCH"
|
"FLOW"
;
setActive
:
any
;
goBack
:
any
;
};
const
SwitchBatchFolw
=
(
props
:
ISwitchBatchFolwProps
)
=>
{
const
{
active
,
setActive
,
goBack
}
=
props
;
const
{
active
,
setActive
,
goBack
,
topImg
,
bottomImg
}
=
props
;
return
(
<
div
className=
{
style
.
switchBatchFolw
}
>
<
div
className=
{
style
.
goBackBox
}
>
...
...
@@ -36,7 +47,7 @@ const SwitchBatchFolw = (props: ISwitchBatchFolwProps) => {
[
style
.
itemImg
]:
true
,
[
style
.
activeImg
]:
active
===
"BATCH"
,
})
}
src=
{
batchImg
}
src=
{
topImg
||
batchImg
}
alt=
""
/>
{
active
===
"BATCH"
&&
<
div
className=
{
style
.
arrow
}
></
div
>
}
...
...
@@ -53,7 +64,7 @@ const SwitchBatchFolw = (props: ISwitchBatchFolwProps) => {
[
style
.
itemImg
]:
true
,
[
style
.
activeImg
]:
active
===
"FLOW"
,
})
}
src=
{
flowImg
}
src=
{
bottomImg
||
flowImg
}
alt=
""
/>
{
active
===
"FLOW"
&&
<
div
className=
{
style
.
arrow
}
></
div
>
}
...
...
src/views/WorkFlowEdit/components/OperatorList/index.tsx
View file @
ba4c0f70
import
{
OutlinedInput
}
from
"@mui/material"
;
import
SearchIcon
from
"@mui/icons-material/Search"
;
import
classNames
from
"classnames"
;
import
{
useCallback
,
useEffect
,
useState
}
from
"react"
;
import
{
observer
}
from
"mobx-react-lite"
;
import
{
toJS
}
from
"mobx"
;
import
cloneDeep
from
"lodash/cloneDeep"
;
import
{
IOperatorItemProps
,
IOperatorListProps
}
from
"./interface"
;
...
...
@@ -11,7 +8,6 @@ import { ITask } from "@/views/Project/ProjectSubmitWork/interface";
import
useMyRequest
from
"@/hooks/useMyRequest"
;
import
{
IResponse
}
from
"@/api/http"
;
import
{
fetchOperatorList
}
from
"@/api/workbench_api"
;
import
{
useStores
}
from
"@/store"
;
import
noTemplate
from
"@/assets/project/noTemplate.svg"
;
import
SearchInput
from
"@/components/BusinessComponents/SearchInput"
;
...
...
@@ -158,10 +154,12 @@ const OperatorItem = (props: IOperatorItemProps) => {
};
const
OperatorList
=
observer
((
props
:
IOperatorListProps
)
=>
{
const
{
currentProjectStore
}
=
useStores
();
const
productId
=
toJS
(
currentProjectStore
.
currentProductInfo
.
id
);
const
{
templateConfigInfo
,
setTemplateConfigInfo
,
showCustomOperator
}
=
props
;
const
{
templateConfigInfo
,
productId
,
setTemplateConfigInfo
,
showCustomOperator
,
}
=
props
;
const
[
operatorListData
,
setOperatorListData
]
=
useState
<
ITask
[]
>
([]);
const
[
keyword
,
setKeyword
]
=
useState
<
string
>
(
""
);
...
...
src/views/WorkFlowEdit/components/OperatorList/interface.ts
View file @
ba4c0f70
...
...
@@ -20,4 +20,5 @@ export interface IOperatorListProps {
templateConfigInfo
:
ITask
[]
setTemplateConfigInfo
:
(
val
:
ITask
[])
=>
void
showCustomOperator
:
boolean
productId
:
string
}
\ No newline at end of file
src/views/WorkFlowEdit/components/SaveCustomTemplate/index.tsx
View file @
ba4c0f70
...
...
@@ -12,11 +12,9 @@ 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
;
...
...
@@ -32,6 +30,7 @@ interface IProps {
creator
?:
string
;
templateConfigInfo
:
ITask
[];
id
?:
string
;
productId
:
string
;
}
const
SaveCustomTemplate
=
(
props
:
IProps
)
=>
{
const
{
...
...
@@ -48,10 +47,9 @@ const SaveCustomTemplate = (props: IProps) => {
templateConfigInfo
,
creator
,
id
,
productId
,
}
=
props
;
const
{
currentProjectStore
}
=
useStores
();
const
Message
=
useMessage
();
const
productId
=
toJS
(
currentProjectStore
.
currentProductInfo
.
id
);
const
[
titleHelper
,
setTitleHelper
]
=
useState
({
// 自定义模板名称错误提示
error
:
false
,
...
...
@@ -192,17 +190,17 @@ const SaveCustomTemplate = (props: IProps) => {
// 表单弹窗确定,新建/编辑自定义模板保存
const
handleOncofirm
=
()
=>
{
if
(
checkTitle
(
title
)
&&
checkVersion
(
version
))
{
if
(
id
)
{
saveUserSpecRun
({
title
,
version
,
description
,
tasks
:
templateConfigInfo
,
productId
,
id
,
creator
,
});
}
else
{
//
if (id) {
//
saveUserSpecRun({
//
title,
//
version,
//
description,
//
tasks: templateConfigInfo,
//
productId,
//
id,
//
creator,
//
});
//
} else {
saveUserSpecRun
({
title
,
version
,
...
...
@@ -210,7 +208,7 @@ const SaveCustomTemplate = (props: IProps) => {
tasks
:
templateConfigInfo
,
productId
,
});
}
//
}
}
};
...
...
src/views/WorkFlowEdit/index.tsx
View file @
ba4c0f70
...
...
@@ -45,14 +45,18 @@ const radioOptions = [
interface
IProps
{
onBack
?:
()
=>
void
;
id
?:
string
;
propsProductId
?:
string
;
}
const
WorkFlowEdit
=
observer
((
props
:
IProps
)
=>
{
const
{
onBack
,
id
}
=
props
;
const
{
onBack
,
id
,
propsProductId
}
=
props
;
const
Message
=
useMessage
();
const
[
templateConfigInfo
,
setTemplateConfigInfo
]
=
useState
<
ITask
[]
>
([]);
// 算子大数组
const
[
showCustomOperator
,
setShowCustomOperator
]
=
useState
(
false
);
// 是否显示自定义算子
const
{
currentProjectStore
}
=
useStores
();
const
productId
=
propsProductId
?
propsProductId
:
toJS
(
currentProjectStore
.
currentProductInfo
.
id
);
const
zoneId
=
toJS
(
currentProjectStore
.
currentProjectInfo
.
zoneId
);
const
[
saveFormDialog
,
setSaveFormDialog
]
=
useState
(
false
);
// 保存弹窗显示与否控制
const
[
title
,
setTitle
]
=
useState
(
""
);
// 自定义模板名称
...
...
@@ -274,6 +278,7 @@ const WorkFlowEdit = observer((props: IProps) => {
showCustomOperator=
{
showCustomOperator
}
templateConfigInfo=
{
templateConfigInfo
}
setTemplateConfigInfo=
{
setTemplateConfigInfo
}
productId=
{
productId
as
string
}
/>
)
}
{
leftContentType
!==
"list"
&&
(
...
...
@@ -333,6 +338,7 @@ const WorkFlowEdit = observer((props: IProps) => {
templateConfigInfo=
{
templateConfigInfo
}
id=
{
id
}
oldversion=
{
oldversion
}
productId=
{
productId
as
string
}
/>
)
}
{
showCustomOperator
&&
(
...
...
@@ -341,6 +347,7 @@ const WorkFlowEdit = observer((props: IProps) => {
initOperatorList=
{
JSON
.
parse
(
sessionStorage
.
getItem
(
"operatorList"
)
||
"[]"
)
}
productId=
{
productId
as
string
}
/>
)
}
</
div
>
...
...
src/views/demo/CardTableDemo/index.module.css
0 → 100644
View file @
ba4c0f70
src/views/demo/CardTableDemo/index.tsx
0 → 100644
View file @
ba4c0f70
import
CardTable
from
"@/components/CommonComponents/CardTable"
;
const
CardTableDemo
=
()
=>
{
const
list
=
[
{
id
:
1
,
},
{
id
:
2
,
},
{
id
:
3
,
},
{
id
:
4
,
},
{
id
:
5
,
},
{
id
:
6
,
},
{
id
:
7
,
},
{
id
:
8
,
},
{
id
:
9
,
},
{
id
:
10
,
},
{
id
:
11
,
},
{
id
:
12
,
},
{
id
:
13
,
},
];
const
renderItem
=
(
item
:
any
)
=>
{
return
(
<
div
style=
{
{
border
:
"1px solid red"
,
height
:
"200px"
}
}
>
{
item
.
id
}
</
div
>
);
};
return
(
<
div
>
CardTableDemo
<
CardTable
data=
{
list
}
renderItem=
{
renderItem
}
numberOfColumns=
{
4
}
></
CardTable
>
</
div
>
);
};
export
default
CardTableDemo
;
src/views/demo/index.tsx
View file @
ba4c0f70
import
MyTableDemo
from
"./MyTableDemo"
;
import
QueueSelectDemo
from
"./QueueSelectDemo"
;
import
IconfontDemo
from
"./IconfontDemo"
;
import
CardTableDemo
from
"./CardTableDemo"
;
import
RadioGroupOfButtonStyle
from
"@/components/CommonComponents/RadioGroupOfButtonStyle"
;
import
{
useState
}
from
"react"
;
import
styles
from
"./index.module.css"
;
const
Demo
=
()
=>
{
const
radioOptionsArr
=
[
{
value
:
"cardTable"
,
label
:
"cardTable"
,
},
{
value
:
"iconfont"
,
label
:
"iconfont"
,
...
...
@@ -27,7 +32,7 @@ const Demo = () => {
const
handleRadio
=
(
e
:
string
)
=>
{
setSelectDemo
(
e
);
};
const
[
selectDemo
,
setSelectDemo
]
=
useState
(
"
iconfont
"
);
const
[
selectDemo
,
setSelectDemo
]
=
useState
(
"
cardTable
"
);
return
(
<
div
className=
{
styles
.
demoBox
}
>
...
...
@@ -37,6 +42,7 @@ const Demo = () => {
handleRadio=
{
handleRadio
}
/>
<
div
className=
{
styles
.
demoContentBox
}
>
{
selectDemo
===
"cardTable"
&&
<
CardTableDemo
></
CardTableDemo
>
}
{
selectDemo
===
"iconfont"
&&
<
IconfontDemo
></
IconfontDemo
>
}
{
selectDemo
===
"队列选择器"
&&
<
QueueSelectDemo
></
QueueSelectDemo
>
}
{
selectDemo
===
"表格"
&&
<
MyTableDemo
></
MyTableDemo
>
}
...
...
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