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
5ceeea43
Commit
5ceeea43
authored
Jul 25, 2022
by
jiangzijing
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat:项目概览接口初调
parent
398a522b
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
313 additions
and
40 deletions
+313
-40
api_manager.ts
src/api/api_manager.ts
+2
-0
project_api.ts
src/api/project_api.ts
+27
-0
index.module.css
src/views/Project/ProjectOverview/TaskCard/index.module.css
+22
-3
index.tsx
src/views/Project/ProjectOverview/TaskCard/index.tsx
+137
-13
index.module.css
src/views/Project/ProjectOverview/index.module.css
+20
-0
index.tsx
src/views/Project/ProjectOverview/index.tsx
+92
-19
index.tsx
src/views/Project/ProjectSetting/BaseInfo/index.tsx
+13
-5
No files found.
src/api/api_manager.ts
View file @
5ceeea43
...
...
@@ -39,6 +39,8 @@ const RESTAPI = {
API_OPERATOR_LIST
:
`
${
BACKEND_API_URI_PREFIX
}
/cpp/workflow/actorspecs`
,
// 获取算子列表
API_VERSION_OPERATOR
:
`
${
BACKEND_API_URI_PREFIX
}
/cpp/workflow/actorversion`
,
// 获取指定版本算子
API_SAVE_USERSPEC
:
`
${
BACKEND_API_URI_PREFIX
}
/cpp/workflow/saveuserspec`
,
// 保存用户自定义工作流模板
API_OVERVIEW_GET
:
`
${
BACKEND_API_URI_PREFIX
}
/cpp/basicInformation`
,
// 获取概览基本信息
API_TASK_OVERVIEW_LIST
:
`
${
BACKEND_API_URI_PREFIX
}
/cpp/workflowJobInformation`
,
// 查询任务概览
};
export
default
RESTAPI
;
src/api/project_api.ts
View file @
5ceeea43
...
...
@@ -246,6 +246,31 @@ const getworkFlowTaskInfo = (params: { jobId: string; taskId: string }) => {
});
};
//获取概览基本信息
const
getOverviewInfo
=
(
params
:
{
id
:
string
})
=>
{
return
request
({
url
:
`
${
Api
.
API_OVERVIEW_GET
}
/
${
params
.
id
}
`
,
method
:
"get"
,
})
}
//获取任务概览
type
getTaskOverviewParams
=
{
projectId
:
string
;
jobName
?:
string
;
day
?:
number
;
page
?:
number
;
size
?:
number
;
};
const
getTaskOverview
=
(
params
:
getTaskOverviewParams
)
=>
{
return
request
({
url
:
Api
.
API_TASK_OVERVIEW_LIST
,
method
:
"get"
,
params
,
})
}
export
{
current
,
menu
,
...
...
@@ -266,4 +291,6 @@ export {
fetchWorkFlowJob
,
submitWorkFlow
,
getworkFlowTaskInfo
,
getOverviewInfo
,
getTaskOverview
};
src/views/Project/ProjectOverview/TaskCard/index.module.css
View file @
5ceeea43
...
...
@@ -46,16 +46,14 @@
justify-content
:
center
;
width
:
78px
;
height
:
22px
;
background
:
#EBF3FF
;
border-radius
:
2px
;
font-size
:
12px
;
color
:
#1370FF
;
}
.statusImg
{
width
:
10px
;
height
:
10px
;
margin-right
:
3
px
;
margin-right
:
5
px
;
}
.taskCreator
{
...
...
@@ -91,6 +89,7 @@
flex
:
1
;
display
:
flex
;
position
:
relative
;
overflow
:
auto
;
}
.noResult
{
...
...
@@ -100,4 +99,23 @@
transform
:
translate
(
-50%
,
-50%
);
font-size
:
14px
;
color
:
#8A9099
;
}
.resultBox
{
padding
:
16px
24px
16px
42px
;
width
:
100%
;
}
.result
{
font-size
:
12px
;
color
:
#1E2633
;
cursor
:
pointer
;
}
.result
:hover
{
color
:
#1370FF
;
}
.outputLeftImg
{
vertical-align
:
middle
;
margin-right
:
8px
;
}
\ No newline at end of file
src/views/Project/ProjectOverview/TaskCard/index.tsx
View file @
5ceeea43
import
{
useMemo
,
useCallback
,
useEffect
,
useState
}
from
"react"
;
import
LinearProgress
,
{
linearProgressClasses
}
from
'@mui/material/LinearProgress'
;
import
MyProgress
from
"@/components/mui/MyProgress"
;
import
style
from
"./index.module.css"
;
import
runTime
from
'../../../../assets/project/runTime.svg'
import
jobCost
from
'../../../../assets/project/jobCost.svg'
import
jobCost
Img
from
'../../../../assets/project/jobCost.svg'
import
jobSue
from
'../../../../assets/project/jobSue.svg'
import
jobFail
from
'../../../../assets/project/jobFail.svg'
import
jobRun
from
'../../../../assets/project/jobRun.svg'
...
...
@@ -14,23 +16,131 @@ import onload from '../../../../assets/project/onload.svg'
import
fileIcon
from
"@/assets/project/fileIcon.svg"
;
import
dataSetIcon
from
"@/assets/project/dataSetIcon.svg"
;
const
TaskCard
=
()
=>
{
type
TaskCardProps
=
{
name
:
string
;
creator
:
string
;
state
:
string
;
completeNum
:
number
;
totalNum
:
number
;
costTime
:
string
;
jobCost
:
number
;
outputs
:
Array
<
any
>
;
};
const
TaskCard
=
(
props
:
TaskCardProps
)
=>
{
const
{
name
,
creator
,
state
,
completeNum
,
totalNum
,
costTime
,
jobCost
,
outputs
}
=
props
;
const
randerOutputs
=
useMemo
(()
=>
{
if
(
outputs
)
{
let
result
=
Object
.
keys
(
outputs
);
let
arr
=
result
.
map
((
item
:
any
)
=>
{
let
type
=
"file"
;
if
(
outputs
[
item
].
indexOf
(
"dataset"
)
!==
-
1
)
{
type
=
"dataset"
;
}
return
{
name
:
item
,
type
,
path
:
outputs
[
item
],
};
});
return
arr
;
}
else
{
return
[];
}
},
[
outputs
])
console
.
log
(
randerOutputs
)
// 渲染状态图标
const
renderStatusIcon
=
(
data
:
string
)
=>
{
switch
(
data
)
{
case
"RUNNING"
:
return
jobRun
case
"ABORTED"
:
return
jobCadence
case
"FAILED"
:
return
jobFail
case
"SUCCEEDED"
:
return
jobSue
default
:
return
jobCadence
}
}
// 渲染状态
const
renderStatusText
=
(
data
:
string
)
=>
{
switch
(
data
)
{
case
"RUNNING"
:
return
'正在运行'
case
"ABORTED"
:
return
'运行终止'
case
"FAILED"
:
return
'运行失败'
case
"SUCCEEDED"
:
return
'运行成功'
default
:
return
'未知'
}
}
// 渲染字体颜色
const
renderTextColor
=
(
data
:
string
)
=>
{
switch
(
data
)
{
case
"RUNNING"
:
return
"#1370FF"
;
case
"ABORTED"
:
return
"#C2C6CC"
;
case
"FAILED"
:
return
"#FF4E4E"
;
case
"SUCCEEDED"
:
return
"#0DD09B"
;
default
:
return
"#C2C6CC"
;
}
};
// 渲染状态框背景颜色
const
renderBackgroundColor
=
(
data
:
string
)
=>
{
switch
(
data
)
{
case
"RUNNING"
:
return
"#EBF3FF"
;
case
"ABORTED"
:
return
"#F5F6F7"
;
case
"FAILED"
:
return
"#FFECE8"
;
case
"SUCCEEDED"
:
return
"#E8FFF1"
;
default
:
return
"#C2C6CC"
;
}
};
//渲染进度条颜色
const
renderProgressColor
=
useCallback
((
data
:
any
)
=>
{
switch
(
data
)
{
case
"RUNNING"
:
return
"info"
;
case
"ABORTED"
:
return
"disable"
;
case
"FAILED"
:
return
"error"
;
case
"SUCCEEDED"
:
return
"success"
;
default
:
return
"disable"
;
}
},
[]);
return
<
div
className=
{
style
.
cardBox
}
>
<
div
className=
{
style
.
cardLeft
}
>
<
div
className=
{
style
.
topLine
}
>
<
div
className=
{
style
.
taskName
}
>
Docking兼分子动力学模拟
</
div
>
<
div
className=
{
style
.
taskStatus
}
>
<
img
src=
{
jobRun
}
alt=
""
className=
{
style
.
statusImg
}
/>
<
span
>
正在运行
</
span
>
<
div
className=
{
style
.
taskName
}
>
{
name
}
</
div
>
<
div
className=
{
style
.
taskStatus
}
style=
{
{
color
:
renderTextColor
(
state
),
background
:
renderBackgroundColor
(
state
)
}
}
>
<
img
src=
{
renderStatusIcon
(
state
)
}
alt=
""
className=
{
style
.
statusImg
}
/>
<
span
>
{
renderStatusText
(
state
)
}
</
span
>
</
div
>
</
div
>
<
div
className=
{
style
.
taskCreator
}
>
jiangzijing
</
div
>
<
div
className=
{
style
.
taskCreator
}
>
{
creator
}
</
div
>
<
div
className=
{
style
.
taskProgress
}
>
<
div
className=
{
style
.
progressInfo
}
>
<
div
>
Progress
</
div
>
<
div
>
8/10
</
div
>
<
div
style=
{
{
color
:
renderTextColor
(
state
)
}
}
>
{
completeNum
+
"/"
+
totalNum
}
</
div
>
</
div
>
<
LinearProgress
variant=
"determinate"
value=
{
80
}
{
/* <MyProgress color={renderProgressColor(state)} value={(completeNum / totalNum) * 100}/> */
}
<
LinearProgress
variant=
"determinate"
value=
{
(
completeNum
/
totalNum
)
*
100
}
sx=
{
{
borderRadius
:
'3px'
,
height
:
"6px"
,
...
...
@@ -40,16 +150,30 @@ const TaskCard = () => {
</
div
>
<
div
className=
{
style
.
bottomLine
}
>
<
img
alt=
""
src=
{
runTime
}
/>
<
div
className=
{
style
.
bottomInfo
}
>
0小时26分钟
</
div
>
<
img
alt=
""
src=
{
jobCost
}
/>
<
div
className=
{
style
.
bottomInfo
}
>
200.00
元
</
div
>
<
div
className=
{
style
.
bottomInfo
}
>
{
costTime
}
</
div
>
<
img
alt=
""
src=
{
jobCost
Img
}
/>
<
div
className=
{
style
.
bottomInfo
}
>
{
jobCost
?.
toFixed
(
2
)
}
元
</
div
>
</
div
>
</
div
>
<
div
className=
{
style
.
dividingLine
}
>
<
div
className=
{
style
.
arrow
}
></
div
>
</
div
>
<
div
className=
{
style
.
cardRight
}
>
{
false
?<
div
></
div
>:<
div
className=
{
style
.
noResult
}
>
暂无结果文件
</
div
>
}
{
randerOutputs
.
length
===
0
?
<
div
className=
{
style
.
noResult
}
>
暂无结果文件
</
div
>
:
<
div
className=
{
style
.
resultBox
}
>
{
randerOutputs
.
map
((
item
,
index
)
=>
{
return
<
div
key=
{
index
}
className=
{
style
.
result
}
>
<
img
className=
{
style
.
outputLeftImg
}
src=
{
item
.
type
===
"file"
?
fileIcon
:
dataSetIcon
}
alt=
""
/>
{
item
.
name
}
</
div
>
})
}
</
div
>
}
</
div
>
</
div
>
}
...
...
src/views/Project/ProjectOverview/index.module.css
View file @
5ceeea43
...
...
@@ -77,9 +77,28 @@
}
.taskDisplay
{
position
:
relative
;
margin
:
20px
24px
;
overflow
:
hidden
;
background
:
#F7F8FA
;
border-radius
:
8px
;
min-height
:
calc
(
100vh
-
275px
);
}
.noDataBox
{
position
:
absolute
;
top
:
50%
;
left
:
50%
;
transform
:
translate
(
-50%
,
-50%
);
display
:
flex
;
flex-direction
:
column
;
justify-content
:
center
;
align-items
:
center
;
}
.noDataText
{
margin-top
:
8px
;
font-size
:
14px
;
line-height
:
22px
;
color
:
#8a9099
;
}
\ No newline at end of file
src/views/Project/ProjectOverview/index.tsx
View file @
5ceeea43
import
React
,
{
useState
,
useCallback
,
useEffect
,
useMemo
}
from
"react"
;
import
{
observer
}
from
"mobx-react-lite"
;
import
useMyRequest
from
"@/hooks/useMyRequest"
;
import
{
getOverviewInfo
,
getTaskOverview
,
}
from
"@/api/project_api"
;
import
{
useStores
}
from
"@/store/index"
;
import
{
InputBase
,
IconButton
}
from
"@mui/material"
;
import
SearchIcon
from
"@mui/icons-material/Search"
;
import
NoProject
from
"@/components/BusinessComponents/NoProject"
;
import
{
observer
}
from
"mobx-react-lite"
;
import
projectImg
from
"@/assets/project/projectIconSmall.svg"
;
import
RadioGroupOfButtonStyle
from
"@/components/CommonComponents/RadioGroupOfButtonStyle"
;
import
TaskCard
from
'./TaskCard'
import
noFile
from
"@/assets/project/noFile.svg"
;
import
style
from
"./index.module.css"
;
const
ProjectOverview
=
observer
(()
=>
{
const
{
currentProjectStore
}
=
useStores
();
// 概览基本信息
const
[
overviewInfo
,
setOverviewInfo
]
=
useState
<
any
>
({});
// 任务概览列表
const
[
taskList
,
setTaskList
]
=
useState
([])
const
[
jobName
,
setJobName
]
=
useState
(
''
)
const
[
page
,
setPage
]
=
useState
(
0
)
const
[
size
,
setSize
]
=
useState
(
10
)
// 选择近7天or近15天or近30天
const
[
activeTab
,
setActiveTab
]
=
useState
(
"seven"
);
const
[
day
,
setDay
]
=
useState
(
"7"
);
// 获取概览基本信息
const
{
run
:
getOverview
}
=
useMyRequest
(
getOverviewInfo
,
{
onSuccess
:
(
result
:
any
)
=>
{
setOverviewInfo
(
result
.
data
);
},
});
// 获取任务概览
const
{
run
:
getTaskOverviewList
}
=
useMyRequest
(
getTaskOverview
,
{
onSuccess
:
(
result
:
any
)
=>
{
setTaskList
(
result
.
data
.
content
);
},
});
useEffect
(()
=>
{
getOverview
({
id
:
currentProjectStore
.
currentProjectInfo
.
id
as
string
,
});
},
[
currentProjectStore
.
currentProjectInfo
.
id
,
getOverview
]);
useEffect
(()
=>
{
getTaskOverviewList
({
projectId
:
currentProjectStore
.
currentProjectInfo
.
id
as
string
,
jobName
:
jobName
,
day
:
Number
(
day
),
page
:
page
,
size
:
size
,
});
},
[
currentProjectStore
.
currentProjectInfo
.
id
,
getTaskOverviewList
,
day
,
jobName
]);
// 搜索值改变
const
handleJobNameChange
=
(
e
:
any
)
=>
{
if
(
e
.
target
.
value
.
length
>
30
)
{
return
;
}
setJobName
(
e
.
target
.
value
);
};
// 按回车搜索
const
handleJobNameChangeKeyUp
=
(
e
:
any
)
=>
{
if
(
e
.
keyCode
===
13
)
{
}
};
if
(
currentProjectStore
.
currentProjectInfo
.
name
)
{
return
(
<>
...
...
@@ -34,17 +91,17 @@ const ProjectOverview = observer(() => {
<
div
className=
{
style
.
basicInformationRight
}
>
<
div
>
<
div
className=
{
style
.
otherInformationBox
}
>
项目总消费
</
div
>
<
div
><
span
className=
{
style
.
numberDisplay
}
>
1,324
</
span
>
元
</
div
>
<
div
><
span
className=
{
style
.
numberDisplay
}
>
{
overviewInfo
.
projectCost
?.
toFixed
(
2
)
}
</
span
>
元
</
div
>
</
div
>
<
div
className=
{
style
.
verticalLine
}
></
div
>
<
div
>
<
div
className=
{
style
.
otherInformationBox
}
>
项目预算
</
div
>
<
div
><
span
className=
{
style
.
numberDisplay
}
>
1,324
</
span
>
元
</
div
>
<
div
className=
{
style
.
otherInformationBox
}
>
项目
剩余
预算
</
div
>
<
div
><
span
className=
{
style
.
numberDisplay
}
>
{
overviewInfo
.
projectRemainingBudget
?.
toFixed
(
2
)
}
</
span
>
元
</
div
>
</
div
>
<
div
className=
{
style
.
verticalLine
}
></
div
>
<
div
>
<
div
className=
{
style
.
otherInformationBox
}
>
项目存储大小
</
div
>
<
div
><
span
className=
{
style
.
numberDisplay
}
>
123
</
span
>
G
</
div
>
<
div
><
span
className=
{
style
.
numberDisplay
}
>
{
overviewInfo
.
projectStorage
?.
toFixed
(
2
)
}
</
span
>
G
</
div
>
</
div
>
</
div
>
</
div
>
...
...
@@ -52,43 +109,59 @@ const ProjectOverview = observer(() => {
<
div
className=
{
style
.
searchLineLeft
}
>
<
div
className=
{
style
.
taskOverview
}
>
任务概览
</
div
>
<
RadioGroupOfButtonStyle
value=
{
activeTab
}
value=
{
day
}
radioOptions=
{
[
{
value
:
"
seven
"
,
label
:
"近7天"
},
{
value
:
"
fifteen
"
,
label
:
"近15天"
},
{
value
:
"
thirty
"
,
label
:
"近30天"
},
{
value
:
"
7
"
,
label
:
"近7天"
},
{
value
:
"
15
"
,
label
:
"近15天"
},
{
value
:
"
30
"
,
label
:
"近30天"
},
]
}
handleRadio=
{
set
ActiveTab
}
handleRadio=
{
set
Day
}
></
RadioGroupOfButtonStyle
>
</
div
>
<
div
className=
{
style
.
projectDataSearch
}
>
<
InputBase
className=
{
style
.
searchInput
}
placeholder=
"输入关键词搜索"
inputProps=
{
{
"aria-label"
:
"输入关键词搜索"
}
}
// value={keyWord
}
// onChange={handleKeyWord
Change}
value=
{
jobName
}
onChange=
{
handleJobName
Change
}
style=
{
{
width
:
"280px"
,
fontSize
:
"14px"
}
}
// onKeyUp={handleKeyWord
ChangeKeyUp}
onKeyUp=
{
handleJobName
ChangeKeyUp
}
/>
<
IconButton
type=
"submit"
className=
{
style
.
searchButton
}
aria
-
label=
"search"
size=
"small"
style=
{
{
padding
:
"4px"
}
}
// onClick={handleRefresh}
>
<
SearchIcon
className=
{
style
.
searchIcon
}
style=
{
{
color
:
"#999"
}
}
/>
</
IconButton
>
</
div
>
</
div
>
<
div
className=
{
style
.
taskDisplay
}
>
<
TaskCard
/>
<
TaskCard
/>
{
/* 任务列表为空展示 */
}
{
taskList
.
length
===
0
&&
(
<
div
className=
{
style
.
noDataBox
}
>
<
img
className=
{
style
.
noDataImg
}
src=
{
noFile
}
alt=
""
/>
<
span
className=
{
style
.
noDataText
}
>
暂无任务
</
span
>
</
div
>
)
}
{
/* 任务列表卡片渲染 */
}
{
taskList
.
length
>
0
&&
taskList
.
map
((
item
:
any
)
=>
{
return
<
TaskCard
name=
{
item
.
name
}
creator=
{
item
.
creator
}
state=
{
item
.
state
}
completeNum=
{
item
.
completeNum
}
totalNum=
{
item
.
totalNum
}
costTime=
{
item
.
costTime
}
jobCost=
{
item
.
jobCost
}
outputs=
{
item
.
outputs
}
key=
{
item
.
id
}
/>
})
}
</
div
>
</>
);
...
...
src/views/Project/ProjectSetting/BaseInfo/index.tsx
View file @
5ceeea43
...
...
@@ -117,7 +117,7 @@ const BaseInfo = observer(() => {
},
{
label
:
"项目预算:"
,
value
:
"100.00"
,
//todo改
value
:
projectInfo
.
projectBudget
,
},
{
label
:
"扣费账号:"
,
...
...
@@ -179,6 +179,13 @@ const BaseInfo = observer(() => {
});
};
const
budgetChange
=
(
e
:
any
)
=>
{
// console.log(e.target.value)
}
const
budgetBlur
=
(
e
:
any
)
=>
{
// console.log(e.target.value)
}
const
{
run
:
updateProjectRun
,
loading
:
updateLoading
}
=
useMyRequest
(
updateProject
,
{
...
...
@@ -327,10 +334,11 @@ const BaseInfo = observer(() => {
<
TextField
required
// error={nameCheck.error}
id=
"
name
"
id=
"
projectBudget
"
variant=
"outlined"
value=
"100.00"
//todo改
onChange=
{
nameChange
}
value=
{
projectInfo
.
projectBudget
}
onChange=
{
budgetChange
}
onBlur=
{
budgetBlur
}
// helperText={nameCheck.help}
size=
"small"
sx=
{
{
...
...
@@ -338,7 +346,7 @@ const BaseInfo = observer(() => {
}
}
InputProps=
{
{
startAdornment
:
<
InputAdornment
position=
"start"
>
¥
</
InputAdornment
>,
}
}
}
}
/>
</
div
>
<
div
className=
{
style
.
projectInfoListLi
}
>
...
...
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