Commit 19848612 authored by chenshouchao's avatar chenshouchao

feat: 完成任务详情联调

parent 19af5d31
......@@ -35,6 +35,7 @@ const RESTAPI = {
API_WORKBENCH_DEL_WORKFLOWJOB: `${BACKEND_API_URI_PREFIX}/cpp/workflow/job/`, //删除工作流任务
API_WORKBENCH_CANCEL_WORKFLOWJOB: `${BACKEND_API_URI_PREFIX}/cpp/workflow/cancel`, //取消工作流
API_SUBMIT_WORKFLOW: `${BACKEND_API_URI_PREFIX}/cpp/workflow/submit`, //提交工作流
API_WORKBENCH_WORKFLOW_TASKINFO: `${BACKEND_API_URI_PREFIX}/cpp/workbench/workflowjob/task-info`, //查询任务某个算子详情
};
export default RESTAPI;
......@@ -235,6 +235,14 @@ const submitWorkFlow = (params: submitWorkFlowParams) => {
});
};
// 查询任务某个算子详情
const getworkFlowTaskInfo = (params: { jobId: string; taskId: string }) => {
return request({
url: `${Api.API_WORKBENCH_WORKFLOW_TASKINFO}?jobId=${params.jobId}&taskId=${params.taskId}`,
method: "get",
});
};
export {
current,
menu,
......@@ -254,4 +262,5 @@ export {
fetchTemplateConfigInfo,
fetchWorkFlowJob,
submitWorkFlow,
getworkFlowTaskInfo,
};
......@@ -31,8 +31,6 @@
font-size: 14px;
color: rgba(30, 38, 51, 1);
font-weight: 600;
padding-right: 20px;
border-right: 1px solid rgba(235, 237, 240, 1);
}
.swContent {
......@@ -42,12 +40,109 @@
.swFormBox {
background-color: #fff;
border-right: 1xp solid rgba(235, 237, 240, 1);
width: 608px;
width: 360px;
overflow-y: scroll;
box-sizing: border-box;
padding: 36px;
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;
}
.taskResults {
padding: 24px;
background-color: rgba(247, 248, 250, 1);
margin-bottom: 24px;
}
.notResults {
background-color: rgba(247, 248, 250, 1);
padding: 54px 0;
text-align: center;
color: rgba(138, 144, 153, 1);
font-size: 14px;
line-height: 22px;
margin-bottom: 24px;
}
.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;
}
.taskInfoValue {
color: rgba(30, 38, 51, 1);
font-size: 14px;
line-height: 22px;
max-width: 210px;
text-overflow: ellipsis;
white-space: nowrap;
display: flex;
overflow: hidden;
position: relative;
align-items: center;
}
.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: scroll;
padding: 8px 0px;
background: #ffffff;
box-shadow: 0px 3px 10px 0px rgba(0, 24, 57, 0.14);
border-radius: 4px;
}
.option {
padding: 7px 16px;
font-size: 14px;
color: rgba(30, 38, 51, 1);
line-height: 22px;
cursor: pointer;
}
.option:hover {
color: rgba(19, 112, 255, 1);
}
.optionActive {
color: rgba(19, 112, 255, 1);
}
......@@ -6,28 +6,54 @@
* @FilePath: /bkunyun/src/views/Project/ProjectSubmitWork/index.tsx
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
import { useEffect, useState } from "react";
import { useEffect, useState, useMemo } from "react";
import ButtonComponent from "@/components/mui/Button";
import ArrowBackIosNewIcon from "@mui/icons-material/ArrowBackIosNew";
import IconButton from "@mui/material/IconButton";
import useMyRequest from "@/hooks/useMyRequest";
import { fetchWorkFlowJob } from "@/api/project_api";
import { fetchWorkFlowJob, getworkFlowTaskInfo } from "@/api/project_api";
import { useLocation, useNavigate } from "react-router-dom";
import { IResponse } from "@/api/http";
import jobSue from "@/assets/project/jobSue.svg";
import jobStop from "@/assets/project/jobStop.svg";
import jobRun from "@/assets/project/jobRun.svg";
import jobFail from "@/assets/project/jobFail.svg";
import classNames from "classnames";
import styles from "./index.module.css";
import { ITemplateConfig } from "../ProjectSubmitWork/interface";
import { ITaskInfo } from "../ProjectSubmitWork/interface";
import Flow from "../components/Flow";
import { style } from "@mui/system";
const stateMap = {
RUNNING: "正在运行",
ABORTED: "运行终止",
FAILED: "运行失败",
SUCCEEDED: "运行成功",
};
const statusMap = {
Done: "运行完成",
Running: "正在运行",
Failed: "运行失败",
Pending: "等待运行",
};
type IStatus = "Done" | "Running" | "Failed" | "Pending";
const ProjectSubmitWork = () => {
const [workFlowJobInfo, setWorkFlowJobInfo] = useState<ITemplateConfig>();
const [workFlowJobInfo, setWorkFlowJobInfo] = useState<ITaskInfo>();
const [patchInfo, setPatchInfo] = useState<any>();
const [activePatchId, setActivePatchId] = useState<string>("");
const [overviewActive, setOverviewActive] = useState(true);
const [activeFlowIndex, setActiveFlowIndex] = useState<number>(0);
const [showOptions, setShowOptions] = useState<boolean>(false);
const location: any = useLocation();
const navigate = useNavigate();
/** 获取模版数据 */
const { run } = useMyRequest(fetchWorkFlowJob, {
onSuccess: (res: IResponse<ITemplateConfig>) => {
console.log(res.data, "1111");
onSuccess: (res: IResponse<ITaskInfo>) => {
setWorkFlowJobInfo(res.data);
},
});
......@@ -35,10 +61,46 @@ const ProjectSubmitWork = () => {
useEffect(() => {
const locationInfo: any = location?.state;
run({
id: locationInfo.taskId,
// id: locationInfo.taskId,
id: "89a00e93-8bba-45ee-85b0-63c5cd42c570",
});
}, [location?.state, run]);
const { run: getworkFlowTaskInfoRun } = useMyRequest(getworkFlowTaskInfo, {
onSuccess: (res) => {
console.log(res);
setPatchInfo(res.data);
},
});
const handleBatch = (id: string) => {
setActivePatchId(id);
if (id) {
setActiveFlowIndex(0);
getworkFlowTaskInfoRun({
jobId: workFlowJobInfo?.id as string,
taskId: id,
});
}
};
const randerParameters = useMemo(() => {
if (patchInfo?.children) {
if (patchInfo.children.length > 0) {
return patchInfo.children[activeFlowIndex].parameters;
} else {
return patchInfo?.parameters;
}
} else {
return patchInfo?.parameters;
}
}, [activeFlowIndex, patchInfo]);
const handleParams = () => {
setOverviewActive(false);
setShowOptions(!showOptions);
};
return (
<div className={styles.swBox}>
<div className={styles.swHeader}>
......@@ -59,7 +121,7 @@ const ProjectSubmitWork = () => {
/>
</IconButton>
<div className={styles.swTemplateTitle}>{workFlowJobInfo?.title}</div>
<div className={styles.swTemplateTitle}>{workFlowJobInfo?.name}</div>
</div>
<div className={styles.swHeaderRight}>
<ButtonComponent
......@@ -71,10 +133,226 @@ const ProjectSubmitWork = () => {
</div>
<div className={styles.swContent}>
<div className={styles.swFormBox}>
<div>详情</div>
{!activePatchId && (
<div className={styles.taskInfo}>
<div className={styles.title}>任务结果</div>
<div className={styles.taskResults}>任务结果</div>
<div className={styles.notResults}>暂无结果文件</div>
<div className={styles.title}>任务信息</div>
<div className={styles.taskInfoLi}>
<div className={styles.taskInfoParams}>任务名称</div>
<div
className={styles.taskInfoValue}
title={workFlowJobInfo?.name}
>
{workFlowJobInfo?.name || "-"}
</div>
</div>
<div className={styles.taskInfoLi}>
<div className={styles.taskInfoParams}>任务ID</div>
<div
className={styles.taskInfoValue}
title={workFlowJobInfo?.id}
>
{workFlowJobInfo?.id || "-"}
</div>
</div>
<div className={styles.taskInfoLi}>
<div className={styles.taskInfoParams}>输出路径</div>
<div className={styles.taskInfoValue}>
{workFlowJobInfo?.outputPath || "-"}
</div>
</div>
<div className={styles.taskInfoLi}>
<div className={styles.taskInfoParams}>运行状态</div>
<div className={styles.taskInfoValue}>
{workFlowJobInfo?.state === "SUCCEEDED" && (
<img
className={styles.taskInfoValueIcon}
src={jobSue}
alt=""
/>
)}
{workFlowJobInfo?.state === "RUNNING" && (
<img
className={styles.taskInfoValueIcon}
src={jobRun}
alt=""
/>
)}
{workFlowJobInfo?.state === "ABORTED" && (
<img
className={styles.taskInfoValueIcon}
src={jobStop}
alt=""
/>
)}
{workFlowJobInfo?.state === "FAILED" && (
<img
className={styles.taskInfoValueIcon}
src={jobFail}
alt=""
/>
)}
{workFlowJobInfo?.state
? stateMap[workFlowJobInfo?.state]
: "-"}
</div>
</div>
<div className={styles.taskInfoLi}>
<div className={styles.taskInfoParams}>源模板</div>
<div className={styles.taskInfoValue}>
{workFlowJobInfo?.specTitle || "-"}
</div>
</div>
<div className={styles.taskInfoLi}>
<div className={styles.taskInfoParams}>源模板版本</div>
<div className={styles.taskInfoValue}>
{workFlowJobInfo?.specVersion || "-"}
</div>
</div>
<div className={styles.taskInfoLi}>
<div className={styles.taskInfoParams}>花费(元)</div>
<div className={styles.taskInfoValue}>
{workFlowJobInfo?.jobCost || "-"}
</div>
</div>
<div className={styles.taskInfoLi}>
<div className={styles.taskInfoParams}>创建人</div>
<div className={styles.taskInfoValue}>
{workFlowJobInfo?.creator || "-"}
</div>
</div>
<div className={styles.taskInfoLi}>
<div className={styles.taskInfoParams}>创建时间</div>
<div className={styles.taskInfoValue}>
{workFlowJobInfo?.createTime || "-"}
</div>
</div>
<div className={styles.taskInfoLi}>
<div className={styles.taskInfoParams}>运行时间</div>
<div className={styles.taskInfoValue}>
{workFlowJobInfo?.costTime || "-"}
</div>
</div>
<div className={styles.taskInfoLi}>
<div className={styles.taskInfoParams}>日志文件</div>
<div className={styles.taskInfoValue}>
{workFlowJobInfo?.logPath}
</div>
</div>
</div>
)}
{activePatchId && (
<div className={styles.suanziInfo}>
<div className={styles.title}>{patchInfo?.title}</div>
<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={() => setOverviewActive(false)}
onClick={() => handleParams()}
>
{patchInfo?.children.length > 0
? patchInfo?.children[activeFlowIndex].title
: patchInfo?.title}
{showOptions && patchInfo?.children.length > 0 && (
<div className={styles.options}>
{patchInfo?.children.map((item: any, index: number) => {
return (
<div
key={index}
className={styles.option}
onClick={() => setActiveFlowIndex(index)}
>
{item.title}
</div>
);
})}
</div>
)}
</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,
})}
>
{patchInfo?.description}
</div>
</div>
<div className={styles.taskInfoLi}>
<div className={styles.taskInfoParams}>算子版本</div>
<div className={styles.taskInfoValue}>
{patchInfo?.creator || "-"}
</div>
</div>
<div className={styles.taskInfoLi}>
<div className={styles.taskInfoParams}>算子状态</div>
<div className={styles.taskInfoValue}>
{patchInfo?.status === "Done" && (
<img
className={styles.taskInfoValueIcon}
src={jobSue}
alt=""
/>
)}
{patchInfo?.status === "Running" && (
<img
className={styles.taskInfoValueIcon}
src={jobRun}
alt=""
/>
)}
{patchInfo?.status === "Failed" && (
<img
className={styles.taskInfoValueIcon}
src={jobFail}
alt=""
/>
)}
{statusMap[patchInfo?.status as IStatus]}
</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.value || "-"}
</div>
</div>
);
})}
</div>
)}
</div>
)}
</div>
<div className={styles.swFlowBox}>
<Flow tasks={workFlowJobInfo?.tasks} />
<Flow tasks={workFlowJobInfo?.tasks} onBatchClick={handleBatch} />
</div>
</div>
</div>
......
......@@ -191,7 +191,7 @@ const ConfigForm = (props: ConfigFormProps) => {
>
{parameter.name}
<span className={styles.parameterDataType}>
{parameter.classType}
{parameter.classTypeName}
</span>
</div>
<div className={styles.parameterContent}>
......
......@@ -133,7 +133,7 @@ const ProjectSubmitWork = () => {
}
}
promotedParameters[parameter.name] = {
[parameter.classType]: value,
[parameter.classTypeName]: value,
};
});
});
......
......@@ -14,6 +14,7 @@ export interface IParameter {
required: boolean;
domType: IDomType;
classType: string;
classTypeName: string;
value: any;
description: string;
language: string;
......@@ -104,3 +105,18 @@ export type IRenderTask = {
flows: ITask[];
isCheck: boolean; // 里面的子项表单校验是否全部通过
};
export interface ITaskInfo extends ITemplateConfig {
name: string;
outputPath: string;
state: IState;
specTitle: string;
specVersion: string;
jobCost: string;
creator: string;
createTime: string;
costTime: string;
logPath: string;
}
type IState = "SUCCEEDED" | "RUNNING" | "ABORTED" | "FAILED";
......@@ -261,7 +261,7 @@ const Flow = (props: IProps) => {
onBatchClick && onBatchClick(item.parentNode);
} else {
setSelectedNodeId(node.id);
onBatchClick && onBatchClick(item.parentNode || "");
onBatchClick && onBatchClick(node.id || "");
}
}
});
......
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