Commit 0c38f37f authored by chenshouchao's avatar chenshouchao

Merge branch 'release' into 'feat-20220705-customTemplate'

# Conflicts:
#   src/views/Project/ProjectWorkbench/workbenchList/index.tsx
parents e290d95b 95bf189b
<?xml version="1.0" encoding="UTF-8"?>
<svg width="13px" height="12px" viewBox="0 0 13 12" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>刷新</title>
<g id="上线UI" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="任务列表" transform="translate(-1394.000000, -308.000000)">
<g id="刷新" transform="translate(1384.000000, 298.000000)">
<g id="编组" transform="translate(8.000000, 8.000000)">
<rect id="矩形" x="0" y="0" width="16" height="16"></rect>
<path d="M14.1034483,5.0750097 L12.3103448,6.87501758 C11.862069,4.9250128 10.0689767,3.42499873 7.97701897,3.42499873 C5.51150172,3.42499873 3.49426034,5.45000759 3.49426034,7.92501842 C3.49426034,10.3999842 5.51150172,12.4249931 7.97701897,12.4249931 C10.3678534,12.4249931 12.3850948,10.5500599 12.4597328,8.15001941 L13.8045603,6.8000135 C13.8793103,7.17501139 13.9540603,7.55002053 13.9540603,8.0000225 C13.9540603,11.2999882 11.2644052,14 7.97701897,14 C4.68965517,14 2,11.2999882 2,8.0000225 C2,4.70001181 4.68965517,2 7.97701897,2 C9.91954397,2 11.712681,2.97499677 12.7586207,4.40000675 L12.9080086,4.17500577 L15,4.17500577 L14.1034483,5.0750097 Z" id="路径" fill="#8A9099"></path>
</g>
</g>
</g>
</g>
</svg>
\ No newline at end of file
......@@ -5,6 +5,7 @@
.tabHeader {
display: flex;
align-items: center;
justify-content: space-between;
}
.tabHeaderSelect {
......@@ -84,4 +85,18 @@
width: 10%;
display: flex;
justify-content: center;
}
.tabUpdate {
cursor: pointer;
width: 32px;
height: 32px;
display: flex;
align-items: center;
justify-content: center;
}
.tabUpdate:hover {
background: #F0F2F5;
border-radius: 4px;
}
\ No newline at end of file
......@@ -22,21 +22,25 @@ import SimpleDialog from "./components/simpleDialog";
import { useStores } from "@/store";
import { observer } from "mobx-react-lite";
import useMyRequest from "@/hooks/useMyRequest";
import ActionsComponent from "../../../../components/Material.Ui/Table/ActionsComponent";
import runTime from "../../../../assets/project/runTime.svg";
import jobCost 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";
import jobCadence from "../../../../assets/project/jobCadence.svg";
import jobStop from "../../../../assets/project/jobStop.svg";
import jobDel from "../../../../assets/project/jobDel.svg";
import noData from "../../../../assets/project/noTemplate.svg";
import ActionsComponent from "../../../../components/Material.Ui/Table/ActionsComponent"
import runTime from '../../../../assets/project/runTime.svg'
import jobCost 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'
import jobCadence from '../../../../assets/project/jobCadence.svg'
import jobStop from '../../../../assets/project/jobStop.svg'
import jobDel from '../../../../assets/project/jobDel.svg'
import noData from '../../../../assets/project/noTemplate.svg'
import onload from '../../../../assets/project/onload.svg'
import {
getWorkflowJobList,
deleteWorkflowJob,
cancelWorkflowJob,
} from "@/api/workbench_api";
import { toJS } from "mobx";
import { observer } from "mobx-react-lite";
import usePass from "@/hooks/usePass";
import styles from "./index.module.css";
import { toJS } from "mobx";
......@@ -64,28 +68,73 @@ const currencies = [
},
];
let timer: string | number | NodeJS.Timeout | null | undefined = null
const ProjectMembers = observer(() => {
const { currentProjectStore } = useStores();
const projectId = toJS(currentProjectStore.currentProjectInfo.id);
const [jobName, setJobName] = useState("");
const [jobList, setJobList] = useState([]);
const [currency, setCurrency] = useState("ALL");
const [page, setPage] = useState(0);
const [size, setSize] = useState(10);
const [rowsPerPage, setRowsPerPage] = useState(10);
const [count, setCount] = useState(0);
/** 简单弹窗 */
const [jobData, setJobData] = useState("");
const [openDialog, setOpenDialog] = useState(false);
const [dialogType, setDialogType] = useState("del");
// 获取作业列表
const { run: getWorkflowJobInfo } = useMyRequest(getWorkflowJobList, {
onSuccess: (result: any) => {
setJobList(result.data.content);
setCount(result.data.totalElements);
},
});
const navigate = useNavigate();
const { currentProjectStore } = useStores();
const projectId = toJS(currentProjectStore.currentProjectInfo.id);
const isPass = usePass();
const [jobName, setJobName] = useState('')
const [jobList, setJobList] = useState([])
const [currency, setCurrency] = useState('ALL');
const [page, setPage] = useState(0)
const [size, setSize] = useState(10)
const [rowsPerPage, setRowsPerPage] = useState(10)
const [count, setCount] = useState(0)
/** 简单弹窗 */
const [jobData, setJobData] = useState('');
const [openDialog, setOpenDialog] = useState(false);
const [dialogType, setDialogType] = useState('del');
// 获取作业列表
const { run: getWorkflowJobInfo } = useMyRequest(getWorkflowJobList, {
onSuccess: (result: any) => {
setJobList(result.data.content);
setCount(result.data.totalElements)
timer && clearTimeout(timer)
timer = null;
timer = setTimeout(() => {
getWorkflowJobInfo({
projectId: currentProjectStore.currentProjectInfo.id as string,
page: page,
size: size,
name: jobName,
state: currency === 'ALL' ? "" : currency
});
}, 60000);
},
});
const navigate = useNavigate()
// 删除作业
const { run: delWorkflowJob } = useMyRequest(deleteWorkflowJob, {
onSuccess: (result: any) => {
setOpenDialog(false)
getWorkflowJobInfo({
projectId: currentProjectStore.currentProjectInfo.id as string,
page: page,
size: size,
name: jobName,
state: currency === 'ALL' ? "" : currency
});
},
});
// 删除作业
const { run: cancelWorkflowJobInfo } = useMyRequest(cancelWorkflowJob, {
onSuccess: (result: any) => {
setOpenDialog(false)
getWorkflowJobInfo({
projectId: currentProjectStore.currentProjectInfo.id as string,
page: page,
size: size,
name: jobName,
state: currency === 'ALL' ? "" : currency
});
},
});
const searchChange = (data: any) => {
setJobName(data.length > 30 ? data.slice(0, 30) : data);
}
// 删除作业
const { run: delWorkflowJob } = useMyRequest(deleteWorkflowJob, {
......@@ -119,9 +168,15 @@ const ProjectMembers = observer(() => {
setJobName(data.length > 30 ? data.slice(0, 30) : data);
};
const handleChange = (event: any) => {
setCurrency(event.target.value);
};
useEffect(() => {
getWorkflowJobInfo({
projectId: currentProjectStore.currentProjectInfo.id as string,
page: page,
size: size,
name: jobName,
state: currency === 'ALL' ? "" : currency
});
}, [projectId, getWorkflowJobInfo]);
/** 关闭弹窗 */
const closeDialog = () => {
......@@ -194,20 +249,15 @@ const ProjectMembers = observer(() => {
}, 300);
}, [jobName, currency, projectId, getWorkflowJobInfo, page, size]);
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 rowClick = useCallback(
(id: string) => {
navigate(`/product/cadd/projectJobDetail`, {
state: { taskId: id },
});
},
[navigate],
);
const renderStatusText = (data: string) => {
switch (data) {
......@@ -224,30 +274,60 @@ const ProjectMembers = observer(() => {
}
};
const renderProgress = (data: any) => {
switch (data) {
case "RUNNING":
return "#1370FF";
case "ABORTED":
return "#C2C6CC";
case "FAILED":
return "#FF4E4E";
case "SUCCEEDED":
return "#0DD09B";
default:
return "#C2C6CC";
}
};
<Box className={styles.tabHeader}>
/** 点击每一行 */
const rowClick = useCallback(
(id: string) => {
navigate(`/product/cadd/projectJobDetail`, {
state: { taskId: id },
});
},
[navigate]
);
<Box sx={{ display: 'flex' }}>
<OutlinedInput
onChange={(e: any) => {
searchChange(e.target.value)
}}
value={jobName}
placeholder="输入关键词搜索"
size="small"
sx={{ width: 340, height: 32 }}
endAdornment={<SearchIcon style={{ color: "#8A9099" }} />}
/>
<Box className={styles.tabHeaderSelect}>
<TextField
select
label="运行状态"
value={currency}
onChange={handleChange}
size="small"
sx={{
width: 180, height: 32,
['& .MuiOutlinedInput-root']: {
height: '32px',
color: "#1E2633",
fontSize: '14px'
},
['& .MuiInputLabel-root']: {
color: "#8A9099",
fontSize: '14px'
},
}}
>
{currencies.map((option) => (
<MenuItem key={option.value} value={option.value}>
{option.label}
</MenuItem>
))}
</TextField>
</Box>
</Box>
<Box className={styles.tabUpdate} onClick={() => {
getWorkflowJobInfo({
projectId: currentProjectStore.currentProjectInfo.id as string,
page: page,
size: size,
name: jobName,
state: currency === 'ALL' ? "" : currency
})
}} >
<img alt="" src={onload} />
</Box>
return (
<Box className={styles.headerBox}>
......@@ -263,109 +343,92 @@ const ProjectMembers = observer(() => {
endAdornment={<SearchIcon style={{ color: "#8A9099" }} />}
/>
<Box className={styles.tabHeaderSelect}>
<TextField
select
label="运行状态"
value={currency}
onChange={handleChange}
size="small"
sx={{
width: 180,
height: 32,
"& .MuiOutlinedInput-root": {
height: "32px",
color: "#1E2633",
fontSize: "14px",
},
"& .MuiInputLabel-root": {
color: "#8A9099",
fontSize: "14px",
},
}}
>
{currencies.map((option) => (
<MenuItem key={option.value} value={option.value}>
{option.label}
</MenuItem>
))}
</TextField>
</Box>
</Box>
<Box className={styles.body}>
{
jobList.length === 0 &&
<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>
}
{
jobList.length > 0 && jobList.map((item: any, key) => {
return (
<Box className={styles.tabBox} onClick={() => rowClick(item.id)}>
<Box className={styles.tabBoxInfo}>
<div className={styles.tabBoxTitle}>{item.name}</div>
<Box className={styles.tabBoxDescInfo}>
<div className={styles.tabBoxDesc} style={{ marginRight: "24px" }} >创建时间:{item.createTime}</div>
<div className={styles.tabBoxDesc}>创建人:{item.creator}</div>
</Box>
</Box>
<Box className={styles.tabBoxMiddle}>
<img alt="" src={runTime} />
<div className={styles.tabBoxTime}>{item.costTime}</div>
</Box>
<Box className={styles.tabBoxMiddle}>
<img alt="" src={jobCost} />
<div className={styles.tabBoxTime}>{item.jobCost}</div>
</Box>
<Box className={styles.tabBoxJobStatus}>
<img alt="" src={renderStatusIcon(item.state)} />
<div className={styles.tabBoxStatusText}>{renderStatusText(item.state)}</div>
<Box sx={{ width: '100%' }}>
<LinearProgress variant="determinate" value={(item.completeNum / item.totalNum) * 100}
sx={{
borderRadius: '3px', height: "6px",
backgroundColor: "#F0F2F5",
marginRight: '16px',
[`& .${linearProgressClasses.bar}`]: {
backgroundColor: renderProgress(item.state),
borderRadius: '3px',
},
}}
/>
</Box>
<div style={{ color: renderProgress(item.state) }} className={styles.tabBoxStatusText}>{item.completeNum + "/" + item.totalNum}</div>
</Box>
<Box className={styles.body}>
{jobList.length === 0 && (
<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>
)}
{jobList.length > 0 &&
jobList.map((item: any, key) => {
return (
<Box className={styles.tabBox} onClick={() => rowClick(item.id)}>
<Box className={styles.tabBoxInfo}>
<div className={styles.tabBoxTitle}>{item.name}</div>
<Box className={styles.tabBoxDescInfo}>
<div
className={styles.tabBoxDesc}
style={{ marginRight: "24px" }}
>
创建时间:{item.createTime}
</div>
<div className={styles.tabBoxDesc}>
创建人:{item.creator}
</div>
</Box>
</Box>
<Box className={styles.tabBoxMiddle}>
<img alt="" src={runTime} />
<div className={styles.tabBoxTime}>{item.costTime}</div>
</Box>
<Box className={styles.tabBoxMiddle}>
<img alt="" src={jobCost} />
<div className={styles.tabBoxTime}>{item.jobCost}</div>
</Box>
<Box className={styles.tabBoxJobStatus}>
<img alt="" src={renderStatusIcon(item.state)} />
<div className={styles.tabBoxStatusText}>
{renderStatusText(item.state)}
</div>
<Box sx={{ width: "100%" }}>
<LinearProgress
variant="determinate"
value={(item.completeNum / item.totalNum) * 100}
sx={{
borderRadius: "3px",
height: "6px",
backgroundColor: "#F0F2F5",
marginRight: "16px",
[`& .${linearProgressClasses.bar}`]: {
backgroundColor: renderProgress(item.state),
borderRadius: "3px",
},
}}
/>
</Box>
<div
style={{ color: renderProgress(item.state) }}
className={styles.tabBoxStatusText}
>
{item.completeNum + "/" + item.totalNum}
</div>
</Box>
{
item.state === "RUNNING" && isPass("PROJECT_WORKBENCH_JOBS_STOP", 'USER') && <Box className={styles.tabBoxJobOperate}>
<img alt=""
src={jobStop}
style={{ cursor: "pointer" }}
onClick={(event) => {
event.stopPropagation();
event.nativeEvent.stopImmediatePropagation();
setJobData(item.id)
setOpenDialog(true)
setDialogType('stop')
}}
/>
</Box>
}
{
item.state !== "RUNNING" && isPass("PROJECT_WORKBENCH_JOBS_DELETE", 'MANAGER') && <Box className={styles.tabBoxJobOperate}>
<img alt=""
src={jobDel}
style={{ cursor: "pointer" }}
onClick={(event) => {
event.stopPropagation();
event.nativeEvent.stopImmediatePropagation();
setJobData(item.id)
setOpenDialog(true)
setDialogType('del')
}}
/>
</Box>
}
</Box>
)
})
}
</Box>
<Box className={styles.tabBoxJobOperate}>
<img
......@@ -398,19 +461,8 @@ const ProjectMembers = observer(() => {
onRowsPerPageChange={handleChangeRowsPerPage} //
/>
<SimpleDialog
text={
dialogType === "del"
? "任务被删除后将无法恢复,确认继续吗?"
: "正在运行的任务终止后将无法重新运行,确认继续吗?"
}
title={dialogType === "del" ? "删除任务" : "终止任务"}
openDialog={openDialog}
closeDialog={closeDialog}
onConfirm={onConfirm}
/>
</Box>
);
</Box >
);
});
export default memo(ProjectMembers);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment