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
sunyihao
bkunyun
Commits
a4f71f04
Commit
a4f71f04
authored
Jun 14, 2022
by
rocosen
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'feat-permissions' into 'release'
Feat permissions See merge request
!32
parents
b4e8dbe8
aadd57cf
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
836 additions
and
27 deletions
+836
-27
api_manager.ts
src/api/api_manager.ts
+11
-0
workbench_api.ts
src/api/workbench_api.ts
+84
-0
noTemplate.svg
src/assets/project/noTemplate.svg
+58
-0
Button.tsx
src/components/mui/Button.tsx
+2
-0
usePass.ts
src/hooks/usePass.ts
+61
-20
index.tsx
src/index.tsx
+21
-7
index.ts
src/router/index.ts
+2
-0
currentProject.ts
src/store/modules/currentProject.ts
+1
-0
index.tsx
src/views/Project/ProjectWorkbench/index.tsx
+65
-0
index.tsx
src/views/Project/ProjectWorkbench/workbenchList/index.tsx
+33
-0
addTemplate.tsx
...ectWorkbench/workbenchTemplate/components/addTemplate.tsx
+77
-0
simpleDialog.tsx
...ctWorkbench/workbenchTemplate/components/simpleDialog.tsx
+27
-0
templateBox.tsx
...ectWorkbench/workbenchTemplate/components/templateBox.tsx
+50
-0
index.module.css
...oject/ProjectWorkbench/workbenchTemplate/index.module.css
+95
-0
index.tsx
...iews/Project/ProjectWorkbench/workbenchTemplate/index.tsx
+249
-0
No files found.
src/api/api_manager.ts
View file @
a4f71f04
...
@@ -10,6 +10,17 @@ const RESTAPI = {
...
@@ -10,6 +10,17 @@ const RESTAPI = {
API_PROJECT_GET
:
`
${
BACKEND_API_URI_PREFIX
}
/cpp/project/get`
,
//获取项目信息
API_PROJECT_GET
:
`
${
BACKEND_API_URI_PREFIX
}
/cpp/project/get`
,
//获取项目信息
API_CPCE_HPCZONE
:
`
${
BACKEND_API_URI_PREFIX
}
/cpp/cpce/hpczone`
,
//获取计算区列表
API_CPCE_HPCZONE
:
`
${
BACKEND_API_URI_PREFIX
}
/cpp/cpce/hpczone`
,
//获取计算区列表
API_USER_PERMISSION_LIST
:
`
${
BACKEND_API_URI_PREFIX
}
/uaa/routes/privilege/list`
,
//获取用户包含的权限列表
API_USER_PERMISSION_LIST
:
`
${
BACKEND_API_URI_PREFIX
}
/uaa/routes/privilege/list`
,
//获取用户包含的权限列表
API_WORKBENCH_TEMPLATE_LIST
:
`
${
BACKEND_API_URI_PREFIX
}
/cpp/workbench/project/workflowspec`
,
//查询项目下工作流模板列表
API_WORKBENCH_DELETE_TEMPLATE
:
`
${
BACKEND_API_URI_PREFIX
}
/cpp/workbench/project/workflowspec`
,
//项目管理员-删除工作流模板
API_WORKBENCH_ADD_TEMPLATE_LIST
:
`
${
BACKEND_API_URI_PREFIX
}
/cpp/workbench/product/workflowspec`
,
//项目管理员-添加工作流模板-模板列表
API_WORKBENCH_ADD_TEMPLATE
:
`
${
BACKEND_API_URI_PREFIX
}
/cpp/workbench/project/workflowspec`
,
//项目管理员-添加工作流模板-提交
}
}
export
default
RESTAPI
;
export
default
RESTAPI
;
src/api/workbench_api.ts
0 → 100644
View file @
a4f71f04
import
request
from
"@/utils/axios/service"
;
import
Api
from
"./api_manager"
;
function
current
()
{
return
request
({
url
:
Api
.
API_USER_FETCH
,
method
:
"get"
,
});
}
function
menu
()
{
return
request
({
url
:
"/accounts/menu-mock"
,
method
:
"get"
,
});
}
type
workflowspecTemplateParams
=
{
projectId
:
string
;
title
?:
string
;
};
// 查询项目下工作流模板列表
const
getWorkbenchTemplate
=
(
params
:
workflowspecTemplateParams
)
=>
{
return
request
({
url
:
Api
.
API_WORKBENCH_TEMPLATE_LIST
,
method
:
"get"
,
params
,
});
};
type
workflowspecDeleteTemplateParams
=
{
projectId
:
string
;
workflowSpecId
:
string
;
};
// 项目管理员-删除工作流模板
const
deleteWorkbenchTemplate
=
(
params
:
workflowspecDeleteTemplateParams
)
=>
{
return
request
({
url
:
Api
.
API_WORKBENCH_DELETE_TEMPLATE
,
method
:
"delete"
,
params
,
});
};
type
workflowspecGetAddTemplateParams
=
{
projectId
?:
string
;
productId
:
string
;
title
?:
string
;
};
// 项目管理员-添加工作流模板-模板列表
const
getAddWorkbenchTemplate
=
(
params
:
workflowspecGetAddTemplateParams
)
=>
{
return
request
({
url
:
Api
.
API_WORKBENCH_ADD_TEMPLATE_LIST
,
method
:
"get"
,
params
,
});
};
type
workflowspecAddTemplateParams
=
{
projectId
:
string
;
workflowSpecIds
:
string
[];
};
// 项目管理员-添加工作流模板-提交
const
addWorkbenchTemplate
=
(
params
:
workflowspecAddTemplateParams
)
=>
{
return
request
({
url
:
Api
.
API_WORKBENCH_ADD_TEMPLATE
,
method
:
"post"
,
data
:
params
,
});
};
export
{
current
,
menu
,
getWorkbenchTemplate
,
deleteWorkbenchTemplate
,
getAddWorkbenchTemplate
,
addWorkbenchTemplate
};
src/assets/project/noTemplate.svg
0 → 100644
View file @
a4f71f04
<?xml version="1.0" encoding="UTF-8"?>
<svg
width=
"83px"
height=
"70px"
viewBox=
"0 0 83 70"
version=
"1.1"
xmlns=
"http://www.w3.org/2000/svg"
xmlns:xlink=
"http://www.w3.org/1999/xlink"
>
<title>
切片
</title>
<defs>
<polygon
id=
"path-1"
points=
"0 0 65.7607024 0 65.7607024 46.987 0 46.987"
></polygon>
<linearGradient
x1=
"50%"
y1=
"20.7300519%"
x2=
"50%"
y2=
"102.568465%"
id=
"linearGradient-3"
>
<stop
stop-color=
"#E3F0FF"
offset=
"0%"
></stop>
<stop
stop-color=
"#8CBAFF"
offset=
"100%"
></stop>
</linearGradient>
<linearGradient
x1=
"50%"
y1=
"0%"
x2=
"50%"
y2=
"100%"
id=
"linearGradient-4"
>
<stop
stop-color=
"#CEE2F9"
offset=
"0%"
></stop>
<stop
stop-color=
"#9FC0F0"
offset=
"100%"
></stop>
</linearGradient>
<linearGradient
x1=
"50%"
y1=
"0%"
x2=
"50%"
y2=
"100%"
id=
"linearGradient-5"
>
<stop
stop-color=
"#DBEAFC"
offset=
"0%"
></stop>
<stop
stop-color=
"#8AAFE6"
offset=
"100%"
></stop>
</linearGradient>
<linearGradient
x1=
"50%"
y1=
"0%"
x2=
"50%"
y2=
"100%"
id=
"linearGradient-6"
>
<stop
stop-color=
"#DBEAFC"
offset=
"0%"
></stop>
<stop
stop-color=
"#8AAFE6"
offset=
"100%"
></stop>
</linearGradient>
<linearGradient
x1=
"50%"
y1=
"0%"
x2=
"50%"
y2=
"100%"
id=
"linearGradient-7"
>
<stop
stop-color=
"#F2F7FF"
offset=
"0%"
></stop>
<stop
stop-color=
"#E1EDFF"
offset=
"100%"
></stop>
</linearGradient>
<path
d=
"M17.9695,0 C18.1602024,0 18.3370714,0.101 18.435881,0.267 L18.435881,0.267 L22.5265952,7.169 C22.6254048,7.335 22.8022738,7.436 22.9929762,7.436 L22.9929762,7.436 L42.7677262,7.436 C42.9584286,7.436 43.1352976,7.335 43.233119,7.169 L43.233119,7.169 L47.3258095,0.267 C47.423631,0.101 47.6005,0 47.7912024,0 L47.7912024,0 L65.21725,0 C65.517631,0 65.7607024,0.246 65.7607024,0.55 L65.7607024,0.55 L65.7607024,18.864 C65.7607024,19.534 65.2231786,20.078 64.5611548,20.078 L64.5611548,20.078 L1.19855952,20.078 C0.536535714,20.078 0,19.534 0,18.864 L0,18.864 L0,0.55 C0,0.246 0.243071429,0 0.542464286,0 L0.542464286,0 Z M41.7340798,12.3811 L24.0274131,12.3811 C23.5254607,12.3811 23.1193536,12.7931 23.1193536,13.3001 C23.1193536,13.8081 23.5254607,14.2191 24.0274131,14.2191 L24.0274131,14.2191 L41.7340798,14.2191 C42.235044,14.2191 42.6421393,13.8081 42.6421393,13.3001 C42.6421393,12.7931 42.235044,12.3811 41.7340798,12.3811 L41.7340798,12.3811 Z"
id=
"path-8"
></path>
</defs>
<g
id=
"上线UI"
stroke=
"none"
stroke-width=
"1"
fill=
"none"
fill-rule=
"evenodd"
>
<g
id=
"工作台(子用户)"
transform=
"translate(-789.000000, -511.000000)"
>
<g
id=
"编组-6"
transform=
"translate(788.000000, 511.000000)"
>
<g
id=
"img_no-data"
transform=
"translate(1.000000, 0.000000)"
>
<g
transform=
"translate(8.645833, 6.999500)"
>
<g
id=
"编组"
transform=
"translate(0.000000, 8.970200)"
>
<mask
id=
"mask-2"
fill=
"white"
>
<use
xlink:href=
"#path-1"
></use>
</mask>
<g
id=
"Clip-2"
></g>
<path
d=
"M49.3205762,0 L32.8806476,0 L16.440719,0 L0.257695238,26.488 C0.0897190476,26.764 -0.000197619048,27.081 -0.000197619048,27.405 L-0.000197619048,45.323 C-0.000197619048,45.689 1.28235,46.987 1.64498095,46.987 L32.8806476,46.987 L64.1173024,46.987 C64.4789452,46.987 65.7614929,45.689 65.7614929,45.323 L65.7614929,27.405 C65.7614929,27.081 65.6725643,26.764 65.5036,26.488 L49.3205762,0 Z"
id=
"Fill-1"
fill=
"url(#linearGradient-3)"
mask=
"url(#mask-2)"
></path>
</g>
<polygon
id=
"Fill-3"
fill=
"url(#linearGradient-4)"
points=
"32.880944 8.5034 16.4400274 8.5034 16.4400274 18.3434 32.880944 18.3434 49.3208726 18.3434 49.3208726 8.5034"
></polygon>
<path
d=
"M1.25705476,53.0815 L16.4401262,18.3435 L16.4401262,8.5035 L0.250185714,35.4635 C0.0861619048,35.7355 0.000197619048,36.0495 0.000197619048,36.3675 L0.000197619048,52.8125 C0.000197619048,53.5315 0.969519048,53.7385 1.25705476,53.0815"
id=
"Fill-5"
fill=
"url(#linearGradient-5)"
></path>
<path
d=
"M64.5048333,53.0815 L49.3207738,18.3435 L49.3207738,8.5035 L65.5117024,35.4635 C65.6747381,35.7355 65.7607024,36.0495 65.7607024,36.3675 L65.7607024,52.8125 C65.7607024,53.5315 64.791381,53.7385 64.5048333,53.0815"
id=
"Fill-7"
fill=
"url(#linearGradient-6)"
></path>
<g
id=
"编组"
transform=
"translate(0.000198, 35.880000)"
>
<mask
id=
"mask-9"
fill=
"white"
>
<use
xlink:href=
"#path-8"
></use>
</mask>
<use
id=
"形状结合"
fill=
"url(#linearGradient-7)"
xlink:href=
"#path-8"
></use>
</g>
<line
x1=
"13.3284167"
y1=
"4.812"
x2=
"10.3582024"
y2=
"0"
id=
"Stroke-13"
stroke=
"#C2DAFE"
stroke-width=
"2"
stroke-linecap=
"round"
stroke-linejoin=
"round"
></line>
<line
x1=
"16.1112881"
y1=
"4.5181"
x2=
"17.7248476"
y2=
"0.0531"
id=
"Stroke-15"
stroke=
"#C2DAFE"
stroke-width=
"2"
stroke-linecap=
"round"
stroke-linejoin=
"round"
></line>
<line
x1=
"11.8462738"
y1=
"7.2143"
x2=
"7.17357143"
y2=
"6.7233"
id=
"Stroke-17"
stroke=
"#C2DAFE"
stroke-width=
"2"
stroke-linecap=
"round"
stroke-linejoin=
"round"
></line>
</g>
</g>
</g>
</g>
</g>
</svg>
\ No newline at end of file
src/components/mui/Button.tsx
View file @
a4f71f04
...
@@ -13,6 +13,7 @@ type ButtonTagProps = {
...
@@ -13,6 +13,7 @@ type ButtonTagProps = {
fontSize
?:
string
;
fontSize
?:
string
;
dropValue
?:
boolean
;
dropValue
?:
boolean
;
drop
?:
boolean
;
drop
?:
boolean
;
color
?:
"inherit"
|
"primary"
|
"secondary"
|
"success"
|
"error"
|
"info"
|
"warning"
|
undefined
,
}
}
...
@@ -35,6 +36,7 @@ const ButtonComponent = (props: ButtonTagProps) => {
...
@@ -35,6 +36,7 @@ const ButtonComponent = (props: ButtonTagProps) => {
<>
<>
<
Button
<
Button
variant=
{
props
.
variant
||
'contained'
}
variant=
{
props
.
variant
||
'contained'
}
color=
{
props
.
color
||
"primary"
}
disableRipple=
{
true
}
disableRipple=
{
true
}
disableFocusRipple=
{
true
}
disableFocusRipple=
{
true
}
classes=
{
{
classes=
{
{
...
...
src/hooks/usePass.ts
View file @
a4f71f04
...
@@ -2,33 +2,74 @@ import { operation, route } from "@/router";
...
@@ -2,33 +2,74 @@ import { operation, route } from "@/router";
import
{
useStores
}
from
"@/store"
;
import
{
useStores
}
from
"@/store"
;
import
{
useCallback
}
from
"react"
;
import
{
useCallback
}
from
"react"
;
const
roleList
:
any
[]
=
[
{
VIEWER
:
1
},
{
USER
:
2
},
{
MANAGER
:
3
},
{
OWNER
:
4
}
]
const
usePass
=
()
=>
{
const
usePass
=
()
=>
{
const
{
permissionStore
}
=
useStores
();
const
{
permissionStore
}
=
useStores
();
const
{
currentProjectStore
}
=
useStores
();
const
isPass
=
useCallback
(
const
isPass
=
useCallback
(
(
key
:
string
,
routes
?:
Array
<
route
|
operation
>
):
boolean
=>
{
(
key
:
string
,
role
?:
"VIEWER"
|
"USER"
|
"MANAGER"
|
"OWNER"
,
routes
?:
Array
<
route
|
operation
>
):
boolean
=>
{
if
(
routes
)
{
let
code
=
currentProjectStore
&&
currentProjectStore
.
currentProjectInfo
.
projectRole
for
(
let
item
of
routes
)
{
if
(
role
)
{
if
(
item
.
id
===
key
)
{
if
(
code
&&
roleList
.
filter
(
e
=>
e
[
role
])[
0
][
role
]
<=
roleList
.
filter
(
e
=>
e
[
code
as
string
])[
0
][
code
])
{
return
true
;
if
(
routes
)
{
}
else
if
(
for
(
let
item
of
routes
)
{
item
.
type
===
"page"
&&
if
(
item
.
id
===
key
)
{
item
.
children
?.
length
&&
return
true
;
isPass
(
key
,
item
.
children
)
}
else
if
(
)
{
item
.
type
===
"page"
&&
return
true
;
item
.
children
?.
length
&&
isPass
(
key
,
role
,
item
.
children
)
)
{
return
true
;
}
}
}
else
{
for
(
let
item
of
permissionStore
.
allRoutes
)
{
if
(
item
.
type
!==
"navigate"
&&
item
.
id
===
key
)
{
return
true
;
}
else
if
(
item
.
type
===
"page"
&&
item
.
children
?.
length
&&
isPass
(
key
,
role
,
item
.
children
)
)
{
return
true
;
}
}
}
}
}
else
{
return
false
}
}
}
else
{
}
else
{
for
(
let
item
of
permissionStore
.
allRoutes
)
{
if
(
routes
)
{
if
(
item
.
type
!==
"navigate"
&&
item
.
id
===
key
)
{
for
(
let
item
of
routes
)
{
return
true
;
if
(
item
.
id
===
key
)
{
}
else
if
(
return
true
;
item
.
type
===
"page"
&&
}
else
if
(
item
.
children
?.
length
&&
item
.
type
===
"page"
&&
isPass
(
key
,
item
.
children
)
item
.
children
?.
length
&&
)
{
isPass
(
key
,
role
,
item
.
children
)
return
true
;
)
{
return
true
;
}
}
}
else
{
for
(
let
item
of
permissionStore
.
allRoutes
)
{
if
(
item
.
type
!==
"navigate"
&&
item
.
id
===
key
)
{
return
true
;
}
else
if
(
item
.
type
===
"page"
&&
item
.
children
?.
length
&&
isPass
(
key
,
role
,
item
.
children
)
)
{
return
true
;
}
}
}
}
}
}
}
...
...
src/index.tsx
View file @
a4f71f04
...
@@ -8,19 +8,33 @@ import { stores } from "@/store/index";
...
@@ -8,19 +8,33 @@ import { stores } from "@/store/index";
import
{
MySnackbarProvider
}
from
"@/components/MySnackbar"
;
import
{
MySnackbarProvider
}
from
"@/components/MySnackbar"
;
import
"@/mocks/index"
;
import
"@/mocks/index"
;
import
'./assets/style/public.css'
import
'./assets/style/public.css'
import
{
createTheme
,
ThemeProvider
,
styled
}
from
'@mui/material/styles'
;
const
root
=
ReactDOM
.
createRoot
(
const
root
=
ReactDOM
.
createRoot
(
document
.
getElementById
(
"root"
)
as
HTMLElement
document
.
getElementById
(
"root"
)
as
HTMLElement
);
);
const
theme
=
createTheme
({
typography
:
{
fontFamily
:
[
'Roboto'
,
'Helvetica'
,
'Tahoma'
,
'Arial'
,
'"PingFang SC"'
,
'"Hiragino Sans GB"'
,
'"Heiti SC"'
,
'"WenQuanYi Micro Hei"'
,
'sans-serif'
,
'"Apple Color Emoji"'
,
'"Segoe UI Emoji"'
,
'"Segoe UI Symbol"'
].
join
(
','
),
},
palette
:
{
primary
:
{
main
:
'#136EFA'
},
secondary
:
{
main
:
'#4EB9FB'
}
}
});
root
.
render
(
root
.
render
(
<
React
.
StrictMode
>
<
React
.
StrictMode
>
<
Provider
{
...
stores
}
>
<
ThemeProvider
theme=
{
theme
}
>
<
MySnackbarProvider
<
Provider
{
...
stores
}
>
alertSx=
{
{
boxShadow
:
"0px 2px 4px 0px rgb(0 0 0 / 8%)"
}
}
<
MySnackbarProvider
>
alertSx=
{
{
boxShadow
:
"0px 2px 4px 0px rgb(0 0 0 / 8%)"
}
}
<
MyRouter
></
MyRouter
>
>
</
MySnackbarProvider
>
<
MyRouter
></
MyRouter
>
</
Provider
>
</
MySnackbarProvider
>
</
Provider
>
</
ThemeProvider
>
</
React
.
StrictMode
>
</
React
.
StrictMode
>
);
);
...
...
src/router/index.ts
View file @
a4f71f04
...
@@ -14,6 +14,7 @@ import * as React from "react";
...
@@ -14,6 +14,7 @@ import * as React from "react";
import
NotFound
from
"@/views/404"
;
import
NotFound
from
"@/views/404"
;
import
Demo
from
"@/views/demo"
;
import
Demo
from
"@/views/demo"
;
import
ProjectSetting
from
"@/views/Project/ProjectSetting"
;
import
ProjectSetting
from
"@/views/Project/ProjectSetting"
;
import
ProjectWorkbench
from
"@/views/Project/ProjectWorkbench"
;
export
type
route
=
{
export
type
route
=
{
id
?:
string
;
id
?:
string
;
...
@@ -47,6 +48,7 @@ export const elements: {
...
@@ -47,6 +48,7 @@ export const elements: {
}
=
{
}
=
{
Demo
:
Demo
,
Demo
:
Demo
,
ProjectSetting
:
ProjectSetting
,
ProjectSetting
:
ProjectSetting
,
ProjectWorkbench
:
ProjectWorkbench
};
};
export
const
routes
:
Array
<
route
|
navigate
>
=
[
export
const
routes
:
Array
<
route
|
navigate
>
=
[
...
...
src/store/modules/currentProject.ts
View file @
a4f71f04
...
@@ -3,6 +3,7 @@ type projectInfo = {
...
@@ -3,6 +3,7 @@ type projectInfo = {
id
?:
string
;
id
?:
string
;
name
?:
string
;
name
?:
string
;
desc
?:
string
;
desc
?:
string
;
projectRole
?:
string
;
};
};
type
productInfo
=
{
type
productInfo
=
{
...
...
src/views/Project/ProjectWorkbench/index.tsx
0 → 100644
View file @
a4f71f04
/*
* @Author: rocosen
* @Date: 2022-06-12 10:05:13
* @LastEditors: rocosen
* @LastEditTime: 2022-06-07 20:23:02
* @FilePath: /bkunyun/src/views/Project/ProjectSetting/index.tsx
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
import
{
memo
,
useState
,
useMemo
,
useEffect
}
from
"react"
;
import
{
Box
}
from
"@mui/system"
;
import
{
useStores
}
from
"@/store/index"
;
import
NoProject
from
"@/components/NoProject"
;
import
{
observer
}
from
"mobx-react-lite"
;
import
projectImg
from
"@/assets/project/projectIconSmall.svg"
;
import
WorkbenchTemplate
from
"./workbenchTemplate"
;
import
WorkbenchList
from
"./workbenchList"
;
import
Tabs
from
"@/components/mui/Tabs"
;
import
usePass
from
"@/hooks/usePass"
;
const
ProjectWorkbench
=
observer
(()
=>
{
const
{
currentProjectStore
}
=
useStores
();
const
isPass
=
usePass
();
const
[
value
,
setValue
]
=
useState
(
"workbenchTemplate"
);
useEffect
(()
=>
{
console
.
log
(
isPass
(
"PROJECT_WORKBENCH_FLOES_USE"
,
'USER'
),
"11111111111"
);
},
[])
const
tabList
=
useMemo
(()
=>
{
return
[
{
label
:
"工作流模版"
,
value
:
"workbenchTemplate"
,
component
:
<
WorkbenchTemplate
/>,
},
{
label
:
"任务列表"
,
value
:
"workbenchList"
,
component
:
<
WorkbenchList
/>,
},
];
},
[]);
const
changeTabs
=
(
val
:
string
)
=>
{
setValue
(
val
);
};
return
(
<
div
style=
{
{
padding
:
24
}
}
>
<
div
style=
{
{
display
:
"flex"
,
alignItems
:
"center"
}
}
>
<
img
src=
{
projectImg
}
alt=
"项目logo"
/>
<
span
style=
{
{
marginLeft
:
12
}
}
>
工作台
</
span
>
</
div
>
<
Box
sx=
{
{
width
:
"100%"
,
typography
:
"body1"
}
}
>
<
Tabs
value=
{
value
}
onChange=
{
changeTabs
}
tabList=
{
tabList
}
/>
</
Box
>
</
div
>
);
});
export
default
memo
(
ProjectWorkbench
);
src/views/Project/ProjectWorkbench/workbenchList/index.tsx
0 → 100644
View file @
a4f71f04
/*
* @Author: 吴永生#A02208 yongsheng.wu@wholion.com
* @Date: 2022-05-31 10:18:13
* @LastEditors: 吴永生#A02208 yongsheng.wu@wholion.com
* @LastEditTime: 2022-06-07 21:39:30
* @FilePath: /bkunyun/src/views/Project/ProjectSetting/index.tsx
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
import
{
memo
,
useCallback
,
useEffect
,
useMemo
,
useState
}
from
"react"
;
import
_
from
"lodash"
;
import
{
IResponse
,
useHttp
}
from
"@/api/http"
;
import
{
useStores
}
from
"@/store"
;
const
ProjectMembers
=
()
=>
{
const
http
=
useHttp
();
const
{
currentProjectStore
}
=
useStores
();
useEffect
(()
=>
{
},
[]);
return
(
<>
99999
</>
);
};
export
default
memo
(
ProjectMembers
);
src/views/Project/ProjectWorkbench/workbenchTemplate/components/addTemplate.tsx
0 → 100644
View file @
a4f71f04
import
{
memo
,
useCallback
,
useEffect
,
useMemo
,
useState
}
from
"react"
;
import
styles
from
"../index.module.css"
;
import
{
Box
,
Typography
}
from
"@mui/material"
;
import
Button
from
"@mui/material/Button"
;
import
Dialog
from
"@/components/mui/Dialog"
;
import
OutlinedInput
from
"@mui/material/OutlinedInput"
;
import
SearchIcon
from
"@mui/icons-material/Search"
;
import
Checkbox
from
'@mui/material/Checkbox'
;
import
CloseOutlinedIcon
from
'@mui/icons-material/CloseOutlined'
;
import
_
from
"lodash"
;
const
AddTemplate
=
(
props
:
any
)
=>
{
const
{
openAddTemplate
,
closeAddTemplateBlock
,
addTemplateList
,
templateSelectCallback
,
selectTemplateData
,
addTemplateCallback
,
searchTemplateNameCallback
}
=
props
;
return
(
<
Box
className=
{
styles
.
addTemplateMask
}
sx=
{
{
display
:
openAddTemplate
?
'flex'
:
'none'
}
}
>
<
Box
sx=
{
{
height
:
'50px'
,
display
:
'flex'
,
alignItems
:
'center'
}
}
>
<
CloseOutlinedIcon
sx=
{
{
color
:
"#ffffff"
,
marginRight
:
"10px"
,
cursor
:
"pointer"
}
}
onClick=
{
()
=>
{
closeAddTemplateBlock
()
}
}
/>
</
Box
>
<
Box
className=
{
styles
.
addTemplateBlock
}
>
<
Box
sx=
{
{
padding
:
"24px 32px"
}
}
>
<
Typography
sx=
{
{
fontSize
:
'18px'
,
fontWeight
:
'600'
,
color
:
"#1E2633"
}
}
>
添加工作流模版
</
Typography
>
<
Box
sx=
{
{
display
:
'flex'
,
justifyContent
:
'space-between'
,
alignItems
:
'center'
,
marginBottom
:
"20px"
}
}
>
<
OutlinedInput
onChange=
{
(
e
:
any
)
=>
{
_
.
debounce
(()
=>
{
searchTemplateNameCallback
(
e
.
target
.
value
)
},
200
)();
}
}
placeholder=
"输入关键词搜索"
size=
"small"
sx=
{
{
width
:
340
,
height
:
32
,
marginTop
:
"20px"
}
}
endAdornment=
{
<
SearchIcon
style=
{
{
color
:
"#8A9099"
}
}
/>
}
/>
<
Button
style=
{
{
backgroundColor
:
"#1370FF"
,
marginLeft
:
"12px"
}
}
variant=
"contained"
onClick=
{
addTemplateCallback
}
size=
"small"
>
添加模版
{
selectTemplateData
.
length
===
0
?
""
:
`(${selectTemplateData.length})`
}
</
Button
>
</
Box
>
<
Box
sx=
{
{
display
:
"flex"
,
flexWrap
:
'wrap'
,
overflowX
:
'hidden'
,
overflowY
:
'overlay'
,
marginLeft
:
'-8px'
}
}
>
{
addTemplateList
.
map
((
item
:
any
,
key
:
any
)
=>
{
return
(
<
Box
className=
{
styles
.
addTemplateBox
}
onClick=
{
()
=>
{
templateSelectCallback
(
item
.
id
)
}
}
sx=
{
{
border
:
selectTemplateData
.
includes
(
item
.
id
)
?
'1px solid #1370FF'
:
"1px solid #EBEDF0;"
}
}
>
<
Box
sx=
{
{
display
:
'flex'
,
justifyContent
:
'space-between'
,
alignItems
:
'center'
,
}
}
>
<
Typography
sx=
{
{
fontSize
:
'14px'
,
fontWeight
:
'600'
,
color
:
'#1E2633'
,
marginBottom
:
"4px"
,
overflow
:
'hidden'
,
textOverflow
:
'ellipsis'
}
}
>
{
item
.
title
}
</
Typography
>
<
Checkbox
size=
"small"
sx=
{
{
padding
:
"0px"
}
}
checked=
{
selectTemplateData
.
includes
(
item
.
id
)
}
/>
</
Box
>
<
Box
sx=
{
{
display
:
'flex'
,
marginBottom
:
"8px"
}
}
>
<
Typography
sx=
{
{
fontSize
:
'12px'
,
fontWeight
:
'400'
,
color
:
'#1370FF'
,
marginRight
:
"24px"
}
}
>
版本:
{
item
.
version
}
</
Typography
>
<
Typography
sx=
{
{
fontSize
:
'12px'
,
fontWeight
:
'400'
,
color
:
'#1370FF'
}
}
>
更新时间:
{
item
.
updateTime
}
</
Typography
>
</
Box
>
<
Typography
className=
{
styles
.
templateDescText
}
>
{
item
.
description
}
</
Typography
>
</
Box
>
)
})
}
</
Box
>
</
Box
>
</
Box
>
</
Box
>
);
};
export
default
memo
(
AddTemplate
);
src/views/Project/ProjectWorkbench/workbenchTemplate/components/simpleDialog.tsx
0 → 100644
View file @
a4f71f04
import
{
memo
,
useCallback
,
useEffect
,
useMemo
,
useState
}
from
"react"
;
import
styles
from
"../index.module.css"
;
import
{
Box
,
Typography
}
from
"@mui/material"
;
import
Button
from
"@mui/material/Button"
;
import
Dialog
from
"@/components/mui/Dialog"
;
const
SimpleDialog
=
(
props
:
any
)
=>
{
const
{
openDialog
,
closeDialog
,
onConfirm
,
text
,
title
}
=
props
;
return
(
<
>
<
Dialog
open=
{
openDialog
}
onClose=
{
closeDialog
}
onConfirm=
{
onConfirm
}
title=
{
title
}
>
<
Box
>
<
Typography
sx=
{
{
fontSize
:
'14px'
,
fontWeight
:
'400'
}
}
>
{
text
}
</
Typography
>
</
Box
>
</
Dialog
>
</>
);
};
export
default
memo
(
SimpleDialog
);
src/views/Project/ProjectWorkbench/workbenchTemplate/components/templateBox.tsx
0 → 100644
View file @
a4f71f04
import
{
memo
,
useCallback
,
useEffect
,
useMemo
,
useState
}
from
"react"
;
import
styles
from
"../index.module.css"
;
import
{
Box
,
Typography
}
from
"@mui/material"
;
import
Button
from
"@mui/material/Button"
;
import
usePass
from
"@/hooks/usePass"
;
const
TemplateBox
=
(
props
:
any
)
=>
{
const
info
=
props
.
data
const
isPass
=
usePass
();
return
(
<
Box
className=
{
styles
.
templateBlock
}
>
<
Box
>
<
Typography
sx=
{
{
fontSize
:
'14px'
,
fontWeight
:
'600'
,
color
:
'#1E2633'
,
marginBottom
:
"4px"
,
overflow
:
'hidden'
,
textOverflow
:
'ellipsis'
}
}
>
{
info
.
title
}
</
Typography
>
<
Box
sx=
{
{
display
:
'flex'
,
marginBottom
:
"8px"
}
}
>
<
Typography
sx=
{
{
fontSize
:
'12px'
,
fontWeight
:
'400'
,
color
:
'#1370FF'
,
marginRight
:
"24px"
}
}
>
版本:
{
info
.
version
}
</
Typography
>
<
Typography
sx=
{
{
fontSize
:
'12px'
,
fontWeight
:
'400'
,
color
:
'#1370FF'
}
}
>
更新时间:
{
info
.
updateTime
}
</
Typography
>
</
Box
>
<
Typography
className=
{
styles
.
templateDescText
}
>
{
info
.
description
}
</
Typography
>
</
Box
>
<
Box
sx=
{
{
display
:
'flex'
,
justifyContent
:
'end'
}
}
>
{
isPass
(
"PROJECT_WORKBENCH_FLOES_USE"
,
'MANAGER'
)
&&
<
Button
style=
{
{
backgroundColor
:
"#F0F2F5"
,
color
:
"#565C66"
}
}
variant=
"contained"
onClick=
{
()
=>
{
props
.
startDialog
(
info
.
id
)
}
}
size=
"small"
>
删除模版
</
Button
>
}
{
isPass
(
"PROJECT_WORKBENCH_FLOES_USE"
,
'USER'
)
&&
<
Button
style=
{
{
backgroundColor
:
"#1370FF"
,
marginLeft
:
"12px"
}
}
variant=
"contained"
// onClick=
{
addTemplateBlock
}
size=
"small"
>
使用模版
</
Button
>
}
</
Box
>
</
Box
>
);
};
export
default
memo
(
TemplateBox
);
src/views/Project/ProjectWorkbench/workbenchTemplate/index.module.css
0 → 100644
View file @
a4f71f04
.headerBox
{
/* display: flex;
justify-content: space-between;
align-items: center; */
margin-bottom
:
20px
;
}
.removeItemBox
{
color
:
#ff4e4e
;
margin-left
:
32px
;
cursor
:
pointer
;
}
.tabBox
{
width
:
100%
;
display
:
flex
;
align-items
:
center
;
justify-content
:
space-between
;
margin-bottom
:
24px
;
}
.templateBlock
{
width
:
21.4876%
;
height
:
160px
;
background
:
#FFFFFF
;
border-radius
:
4px
;
border
:
1px
solid
#EBEDF0
;
padding
:
16px
20px
;
display
:
flex
;
flex-direction
:
column
;
justify-content
:
space-between
;
margin
:
8px
;
}
.addTemplateMask
{
background
:
rgb
(
56
,
56
,
56
,
0.7
);
position
:
absolute
;
z-index
:
800
;
top
:
0%
;
left
:
0%
;
width
:
100%
;
height
:
100%
;
display
:
flex
;
align-items
:
end
;
flex-direction
:
column
;
}
.addTemplateBlock
{
background
:
#FFFFFF
;
z-index
:
900
;
border-radius
:
16px
0px
0px
0px
;
height
:
100%
;
width
:
100%
;
}
.addTemplateBox
{
width
:
16.8751%
;
height
:
114px
;
background
:
#FFFFFF
;
border-radius
:
4px
;
border
:
1px
solid
#F0F2F5
;
padding
:
16px
20px
;
margin
:
8px
;
cursor
:
pointer
;
}
.addTemplateBox
:hover
{
box-shadow
:
6px
8px
22px
0px
rgba
(
0
,
24
,
57
,
0.08
);
}
.templateDescText
{
overflow
:
hidden
;
text-overflow
:
ellipsis
;
-webkit-box-orient
:
vertical
;
-webkit-line-clamp
:
3
;
display
:
-webkit-box
;
height
:
54px
;
font-size
:
12px
!important
;
font-weight
:
400
!important
;
color
:
#8A9099
!important
;
}
.addNewTemplate
{
width
:
380px
;
height
:
194px
;
background
:
#FFFFFF
;
border-radius
:
4px
;
border
:
1px
solid
#EBEDF0
;
display
:
flex
;
justify-content
:
center
;
align-items
:
center
;
flex-direction
:
column
;
cursor
:
pointer
;
}
\ No newline at end of file
src/views/Project/ProjectWorkbench/workbenchTemplate/index.tsx
0 → 100644
View file @
a4f71f04
/*
* @Author: 吴永生#A02208 yongsheng.wu@wholion.com
* @Date: 2022-05-31 10:18:13
* @LastEditors: 吴永生#A02208 yongsheng.wu@wholion.com
* @LastEditTime: 2022-06-07 21:39:30
* @FilePath: /bkunyun/src/views/Project/ProjectSetting/index.tsx
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
import
{
memo
,
useCallback
,
useEffect
,
useMemo
,
useState
}
from
"react"
;
import
{
Box
,
Typography
}
from
"@mui/material"
;
import
styles
from
"./index.module.css"
;
import
OutlinedInput
from
"@mui/material/OutlinedInput"
;
import
SearchIcon
from
"@mui/icons-material/Search"
;
// import Button from "@/components/mui/Button";
import
Button
from
"@mui/material/Button"
;
import
Add
from
"@mui/icons-material/Add"
;
import
useMyRequest
from
"@/hooks/useMyRequest"
;
import
TemplateBox
from
"./components/templateBox"
import
SimpleDialog
from
"./components/simpleDialog"
import
AddTemplate
from
"./components/addTemplate"
import
noData
from
'../../../../assets/project/noTemplate.svg'
import
{
getWorkbenchTemplate
,
deleteWorkbenchTemplate
,
getAddWorkbenchTemplate
,
addWorkbenchTemplate
}
from
"@/api/workbench_api"
;
import
_
from
"lodash"
;
import
{
IResponse
,
useHttp
}
from
"@/api/http"
;
import
{
useStores
}
from
"@/store"
;
import
usePass
from
"@/hooks/usePass"
;
const
ProjectMembers
=
()
=>
{
const
{
currentProjectStore
}
=
useStores
();
const
isPass
=
usePass
();
/** 搜索模板名称 */
const
[
templateName
,
setTemplateName
]
=
useState
(
""
);
/** 模板列表 */
const
[
templateList
,
setTemplateList
]
=
useState
([]);
/** 选中的模板id */
const
[
templateId
,
setTemplateId
]
=
useState
(
''
);
/** 简单弹窗(删除模板) */
const
[
openDialog
,
setOpenDialog
]
=
useState
(
false
);
/** 增加模板 */
const
[
openAddTemplate
,
setOpenAddTemplate
]
=
useState
(
false
);
/** 可增加模板列表 */
const
[
addTemplateList
,
setAddTemplateList
]
=
useState
([]);
/** 已选择增加的模板列表 */
const
[
selectTemplateData
,
setSelectTemplateData
]
=
useState
<
string
[]
>
([]);
// 获取模板列表
const
{
run
:
getTemplateInfo
}
=
useMyRequest
(
getWorkbenchTemplate
,
{
onSuccess
:
(
result
:
any
)
=>
{
setTemplateList
(
result
.
data
);
},
});
// 删除模板
const
{
run
:
delTemplate
}
=
useMyRequest
(
deleteWorkbenchTemplate
,
{
onSuccess
:
(
result
:
any
)
=>
{
setOpenDialog
(
false
);
getTemplateInfo
({
projectId
:
currentProjectStore
.
currentProjectInfo
.
id
as
string
,
title
:
templateName
});
},
});
// 添加工作流模板-获取模板列表
const
{
run
:
getAddTemplateList
}
=
useMyRequest
(
getAddWorkbenchTemplate
,
{
onSuccess
:
(
result
:
any
)
=>
{
setAddTemplateList
(
result
.
data
)
setOpenAddTemplate
(
true
);
},
});
// 项目管理员-添加工作流模板-提交
const
{
run
:
addTemplate
}
=
useMyRequest
(
addWorkbenchTemplate
,
{
onSuccess
:
(
result
:
any
)
=>
{
setOpenAddTemplate
(
false
)
getTemplateInfo
({
projectId
:
currentProjectStore
.
currentProjectInfo
.
id
as
string
,
});
setSelectTemplateData
([])
},
});
useEffect
(()
=>
{
getTemplateInfo
({
projectId
:
currentProjectStore
.
currentProjectInfo
.
id
as
string
,
});
},
[
currentProjectStore
.
currentProjectInfo
.
id
,
getTemplateInfo
]);
/** 点击添加工作流模版 */
const
onAddMember
=
()
=>
{
// setAddMemberDialog(true);
};
/** 删除模板 */
const
deleteTemplate
=
()
=>
{
delTemplate
({
projectId
:
currentProjectStore
.
currentProjectInfo
.
id
as
string
,
workflowSpecId
:
templateId
,
})
};
/** 打开弹窗 */
const
startDialog
=
(
id
:
string
)
=>
{
setTemplateId
(
id
)
setOpenDialog
(
true
);
};
/** 关闭弹窗 */
const
closeDialog
=
()
=>
{
setOpenDialog
(
false
);
};
/** 增加模板 */
const
addTemplateBlock
=
()
=>
{
getAddTemplateList
({
projectId
:
currentProjectStore
.
currentProjectInfo
.
id
as
string
,
productId
:
'cadd'
,
})
};
/** 关闭增加模板 */
const
closeAddTemplateBlock
=
()
=>
{
setOpenAddTemplate
(
false
);
setSelectTemplateData
([])
};
/** 增加模板操作 */
const
addTemplateCallback
=
()
=>
{
addTemplate
({
projectId
:
currentProjectStore
.
currentProjectInfo
.
id
as
string
,
workflowSpecIds
:
selectTemplateData
})
}
/** 搜索模板 */
const
searchTemplateNameCallback
=
(
data
:
any
)
=>
{
getAddTemplateList
({
projectId
:
currentProjectStore
.
currentProjectInfo
.
id
as
string
,
productId
:
'cadd'
,
title
:
data
})
}
const
templateSelectCallback
=
(
data
:
string
)
=>
{
let
list
:
string
[]
=
[...
selectTemplateData
]
if
(
selectTemplateData
.
filter
(
e
=>
e
===
data
).
length
>
0
)
{
list
=
list
.
filter
(
e
=>
e
!==
data
)
setSelectTemplateData
(
list
)
}
else
{
list
.
push
(
data
)
setSelectTemplateData
(
list
)
}
}
useEffect
(()
=>
{
getTemplateInfo
({
projectId
:
currentProjectStore
.
currentProjectInfo
.
id
as
string
,
title
:
templateName
});
},
[
templateName
]);
return
(
<
Box
className=
{
styles
.
headerBox
}
>
<
Box
className=
{
styles
.
tabBox
}
>
<
OutlinedInput
onChange=
{
(
e
:
any
)
=>
{
_
.
debounce
(()
=>
{
setTemplateName
(
e
.
target
.
value
);
},
200
)();
}
}
placeholder=
"输入关键词搜索"
size=
"small"
sx=
{
{
width
:
340
,
height
:
32
}
}
endAdornment=
{
<
SearchIcon
style=
{
{
color
:
"#8A9099"
}
}
/>
}
/>
{
templateList
.
length
>
0
&&
isPass
(
"PROJECT_WORKBENCH_FLOES_ADD"
,
'MANAGER'
)
&&
<
Button
style=
{
{
backgroundColor
:
"#1370FF "
}
}
variant=
"contained"
onClick=
{
addTemplateBlock
}
startIcon=
{
<
Add
/>
}
size=
"small"
>
添加工作流模版
</
Button
>
}
</
Box
>
{
templateList
.
length
===
0
&&
!
isPass
(
"PROJECT_WORKBENCH_FLOES_ADD"
,
'MANAGER'
)
&&
<
Box
sx=
{
{
display
:
'flex'
,
alignItems
:
'center'
,
flexDirection
:
'column'
,
minHeight
:
'calc(100vh - 376px)'
,
justifyContent
:
'center'
}
}
>
<
img
alt=
""
src=
{
noData
}
/>
<
Typography
sx=
{
{
fontSize
:
'12px'
,
fontWeight
:
'400'
,
color
:
'#8A9099'
}
}
>
暂未开启模版
</
Typography
>
</
Box
>
}
{
templateList
.
length
>
0
&&
<
Box
sx=
{
{
display
:
"flex"
,
flexWrap
:
'wrap'
,
marginLeft
:
"-8px"
}
}
>
{
templateList
&&
templateList
.
length
>
0
&&
templateList
.
map
((
item
,
key
)
=>
{
return
<
TemplateBox
data=
{
item
}
startDialog=
{
startDialog
}
/>
})
}
</
Box
>
}
{
templateList
.
length
===
0
&&
isPass
(
"PROJECT_WORKBENCH_FLOES_ADD"
,
'MANAGER'
)
&&
<
Box
className=
{
styles
.
addNewTemplate
}
onClick=
{
addTemplateBlock
}
>
<
Add
sx=
{
{
color
:
"#565C66"
,
fontSize
:
"20px"
,
width
:
"30px"
,
height
:
'30px'
}
}
/>
<
Typography
sx=
{
{
fontSize
:
'14px'
,
fontWeight
:
'400'
,
color
:
'#8A9099'
,
marginTop
:
"15px"
}
}
>
添加工作流模版
</
Typography
>
</
Box
>
}
<
AddTemplate
openAddTemplate=
{
openAddTemplate
}
closeAddTemplateBlock=
{
closeAddTemplateBlock
}
addTemplateList=
{
addTemplateList
}
templateSelectCallback=
{
templateSelectCallback
}
selectTemplateData=
{
selectTemplateData
}
addTemplateCallback=
{
addTemplateCallback
}
searchTemplateNameCallback=
{
searchTemplateNameCallback
}
/>
<
SimpleDialog
text=
{
'确认移除该模板吗?'
}
title=
{
'删除模板'
}
openDialog=
{
openDialog
}
closeDialog=
{
closeDialog
}
onConfirm=
{
deleteTemplate
}
/>
</
Box
>
);
};
export
default
memo
(
ProjectMembers
);
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