From 1392cb7cd6bdb025f2d03015f1c21b4eeabcfba9 Mon Sep 17 00:00:00 2001 From: YaHoo94 <673964817@qq.com> Date: Sat, 27 Jan 2024 09:08:30 +0800 Subject: [PATCH 1/5] merge --- ...itted.png => component-icon-1-Skipped.png} | Bin .../images/component-icon-2-Skipped.png | Bin 0 -> 3596 bytes .../experimentText/editPipeline.less | 14 +++ .../pages/Experiment/experimentText/index.jsx | 53 ++++++++- .../pages/Experiment/experimentText/props.jsx | 58 +++++++--- react-ui/src/pages/Experiment/index.jsx | 103 ++++++++++++++++-- react-ui/src/services/experiment/index.js | 18 +++ 7 files changed, 220 insertions(+), 26 deletions(-) rename react-ui/public/assets/images/{component-icon-1--Omitted.png => component-icon-1-Skipped.png} (100%) create mode 100644 react-ui/public/assets/images/component-icon-2-Skipped.png diff --git a/react-ui/public/assets/images/component-icon-1--Omitted.png b/react-ui/public/assets/images/component-icon-1-Skipped.png similarity index 100% rename from react-ui/public/assets/images/component-icon-1--Omitted.png rename to react-ui/public/assets/images/component-icon-1-Skipped.png diff --git a/react-ui/public/assets/images/component-icon-2-Skipped.png b/react-ui/public/assets/images/component-icon-2-Skipped.png new file mode 100644 index 0000000000000000000000000000000000000000..6ee447f3e7cf9117f9ec7d2d557926163ca9fe80 GIT binary patch literal 3596 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 { const propsRef=useRef() const navgite=useNavigate(); const locationParams =useParams () //新版本获取路由参数接口 let graph=null const [experimentStatusObj,setExperimentStatusObj]=useState({}) + const [experimentAllMessage,setExperimentAllMessage]=useState({}) + const statusObj={ + "Running":'运行中', + "Succeeded":'成功', + "Pending":'等待中', + "Failed":'失败', + "Error":'错误', + "Terminated":'终止', + "Skipped":'未执行', + "Omitted":'未执行', + } + const statusColorObj={ + "Running":'#165bff', + "Succeeded":'#63a728', + "Pending":'#f981eb', + "Failed":'#c73131', + "Error":'#c73131', + "Terminated":'#8a8a8a', + "Skipped":'#8a8a8a', + "Omitted":'#8a8a8ae', + } + const timers=(time)=>{ + let timer=new Date(time) + let hours = timer.getHours(); //转换成时 + let minutes = timer.getMinutes(); //转换成分 + let secend = timer.getSeconds(); //转换成秒 + + let str = `${minutes}分${secend}秒`; + return str; + } const pipelineContainer = useEmotionCss(() => { return { display: 'flex', @@ -88,11 +119,13 @@ const ExperimentText = React.FC = () => { console.log(JSON.parse(ret.data.dag)); getExperimentIns(locationParams.id).then(res=>{ if(res.code==200){ + console.log(ret.data,'data'); const experimentStatusObjs=JSON.parse(res.data.nodes_status) - const newNodeList= JSON.parse(ret.data.dag).nodes.map(item=>{console.log(experimentStatusObjs); return {...item,component_id:experimentStatusObjs&&experimentStatusObjs[item.id]&&experimentStatusObjs[item.id].id,img:experimentStatusObjs&&experimentStatusObjs[item.id]&&experimentStatusObjs[item.id].phase?item.img.slice(0,item.img.length-4)+'-'+experimentStatusObjs[item.id].phase+'.png':item.img}}) - const newData={...JSON.parse(ret.data.dag),nodes:newNodeList} - console.log(newData); - getGraphData(newData) + const newNodeList= JSON.parse(ret.data.dag).nodes.map(item=>{console.log(experimentStatusObjs); return {...item,experimentEndTime:experimentStatusObjs&&experimentStatusObjs[item.id]&&experimentStatusObjs[item.id].finishedAt,experimentStartTime:experimentStatusObjs&&experimentStatusObjs[item.id]&&experimentStatusObjs[item.id].startedAt,experimentStatus:experimentStatusObjs&&experimentStatusObjs[item.id]&&experimentStatusObjs[item.id].phase,component_id:experimentStatusObjs&&experimentStatusObjs[item.id]&&experimentStatusObjs[item.id].id,img:experimentStatusObjs&&experimentStatusObjs[item.id]&&experimentStatusObjs[item.id].phase?item.img.slice(0,item.img.length-4)+'-'+experimentStatusObjs[item.id].phase+'.png':item.img}}) + const newData={...JSON.parse(ret.data.dag),nodes:newNodeList} + console.log(newData); + setExperimentAllMessage(res.data) + getGraphData(newData) // setExperimentStatusObj(JSON.parse(ret.data.nodes_status)) } @@ -327,6 +360,16 @@ const ExperimentText = React.FC = () => { return (
+
启动时间:{momnet(experimentAllMessage.create_time).format('YYYY-MM-DD HH:mm:ss')}
+
执行时长:{experimentAllMessage.finish_time?timers(new Date(experimentAllMessage.finish_time).getTime()-new Date(experimentAllMessage.create_time).getTime()):timers(new Date().getTime()-new Date(experimentAllMessage.create_time).getTime())}
+
状态: +
+ {statusObj[experimentAllMessage.status]}
diff --git a/react-ui/src/pages/Experiment/experimentText/props.jsx b/react-ui/src/pages/Experiment/experimentText/props.jsx index 3bf1029b..2b2fec99 100644 --- a/react-ui/src/pages/Experiment/experimentText/props.jsx +++ b/react-ui/src/pages/Experiment/experimentText/props.jsx @@ -3,19 +3,48 @@ import { Button, Drawer,Form, Input ,Tabs } from 'antd'; import Styles from './editPipeline.less' import{getQueryByExperimentLog}from '@/services/experiment/index.js' import { ProfileOutlined, DatabaseOutlined} from '@ant-design/icons'; +import momnet from 'moment' const { TextArea } = Input; const Props = forwardRef(({onParentChange}, ref) =>{ const [form] = Form.useForm(); const [stagingItem,setStagingItem]=useState({}) const [messageItem,setMessageItem]=useState('') - + const statusObj={ + "Running":'运行中', + "Succeeded":'成功', + "Pending":'等待中', + "Failed":'失败', + "Error":'错误', + "Terminated":'终止', + "Skipped":'未执行', + "Omitted":'未执行', + } + const statusColorObj={ + "Running":'#165bff', + "Succeeded":'#63a728', + "Pending":'#f981eb', + "Failed":'#c73131', + "Error":'#c73131', + "Terminated":'#8a8a8a', + "Skipped":'#8a8a8a', + "Omitted":'#8a8a8ae', + } + const timers=(time)=>{ + let timer=new Date(time) + let hours = timer.getHours(); //转换成时 + let minutes = timer.getMinutes(); //转换成分 + let secend = timer.getSeconds(); //转换成秒 + + let str = `${minutes}分${secend}秒`; + return str; + } const items = [ { key: '1', label: '日志详情', children:
, icon: @@ -226,11 +255,6 @@ const Props = forwardRef(({onParentChange}, ref) =>{ form.resetFields(); form.setFieldsValue({...e.item.getModel(),in_parameters:JSON.parse(e.item.getModel().in_parameters),out_parameters:JSON.parse(e.item.getModel().out_parameters),control_strategy:JSON.parse(e.item.getModel().control_strategy)}) setStagingItem({...e.item.getModel(),in_parameters:JSON.parse(e.item.getModel().in_parameters),out_parameters:JSON.parse(e.item.getModel().out_parameters),control_strategy:JSON.parse(e.item.getModel().control_strategy)}) - // form.setFieldsValue({...e.item.getModel(),in_parameters:JSON.parse(e.item.getModel().in_parameters),out_parameters:JSON.parse(e.item.getModel().out_parameters)}) - // setStagingItem({...e.item.getModel(),in_parameters:JSON.parse(e.item.getModel().in_parameters),out_parameters:JSON.parse(e.item.getModel().out_parameters)}) - // setTimeout(() => { - // console.log(stagingItem); - // }, (500)); setOpen(true); }) } @@ -238,11 +262,6 @@ const Props = forwardRef(({onParentChange}, ref) =>{ form.resetFields(); form.setFieldsValue({...e.item.getModel(),in_parameters:JSON.parse(e.item.getModel().in_parameters),out_parameters:JSON.parse(e.item.getModel().out_parameters),control_strategy:JSON.parse(e.item.getModel().control_strategy)}) setStagingItem({...e.item.getModel(),in_parameters:JSON.parse(e.item.getModel().in_parameters),out_parameters:JSON.parse(e.item.getModel().out_parameters),control_strategy:JSON.parse(e.item.getModel().control_strategy)}) - // form.setFieldsValue({...e.item.getModel(),in_parameters:JSON.parse(e.item.getModel().in_parameters),out_parameters:JSON.parse(e.item.getModel().out_parameters)}) - // setStagingItem({...e.item.getModel(),in_parameters:JSON.parse(e.item.getModel().in_parameters),out_parameters:JSON.parse(e.item.getModel().out_parameters)}) - // setTimeout(() => { - // console.log(stagingItem); - // }, (500)); setOpen(true); } // console.log(e.item.getModel().in_parameters); @@ -252,7 +271,18 @@ const Props = forwardRef(({onParentChange}, ref) =>{ })); return ( <> - + +
任务名称:{stagingItem.label}
+
执行状态: +
+ {statusObj[stagingItem.experimentStatus]}
+
启动时间:{momnet(stagingItem.experimentStartTime).format('YYYY-MM-DD HH:mm:ss')}
+
耗时:{stagingItem.experimentEndTime?timers(new Date(stagingItem.experimentEndTime).getTime()-new Date(stagingItem.experimentStartTime).getTime()):timers(new Date().getTime()-new Date(stagingItem.experimentStartTime).getTime())}
diff --git a/react-ui/src/pages/Experiment/index.jsx b/react-ui/src/pages/Experiment/index.jsx index 91aa7704..2751ee34 100644 --- a/react-ui/src/pages/Experiment/index.jsx +++ b/react-ui/src/pages/Experiment/index.jsx @@ -1,8 +1,8 @@ import React ,{ useState,useEffect,useRef }from 'react'; import { Space, Table, Tag,Button,Modal, Form, Input ,message, Select,} from 'antd'; -import { PlusOutlined, EditOutlined ,PlayCircleOutlined} from '@ant-design/icons'; -import {getWorkflow,addWorkflow,removeWorkflow,cloneWorkflow} from '@/services/pipeline/index.js' -import {getExperiment,runExperiments,getExperimentById,postExperiment,putExperiment,getQueryByExperimentId} from '@/services/experiment/index.js' +import { PlusOutlined, EditOutlined ,PlayCircleOutlined,DeleteOutlined,FieldTimeOutlined} from '@ant-design/icons'; +import {getWorkflow,} from '@/services/pipeline/index.js' +import {getExperiment,runExperiments,getExperimentById,postExperiment,putExperiment,getQueryByExperimentId,deleteExperimentById,deleteQueryByExperimentInsId,putQueryByExperimentInsId} from '@/services/experiment/index.js' import Styles from './index.less' import { useNavigate} from 'react-router-dom'; import momnet from 'moment' @@ -14,9 +14,12 @@ const Experiment = React.FC = () => { const statusObj={ "Running":'运行中', "Succeeded":'成功', + "Pending":'等待中', "Failed":'失败', "Error":'错误', - "Teminated":'终止' + "Terminated":'终止', + "Skipped":'未执行', + "Omitted":'未执行', } const [experimentList, setExperimentList] = useState([]); @@ -258,7 +261,41 @@ const Experiment = React.FC = () => { > 编辑 - + ), }, @@ -278,14 +315,66 @@ const Experiment = React.FC = () => {
状态
运行时长
开始时间
+
操作
:''} {experimentInList&&experimentInList.length>0?experimentInList.map((item,index)=>(
routerToText(e,item,record)}>{index+1}
{statusObj[item.status]}
-
{item.finish_time?timers(new Date(item.finish_time).getTime()-new Date(item.start_time).getTime()):timers(new Date().getTime()-new Date(item.start_time).getTime())}
-
{momnet(item.start_time).format('YYYY-MM-DD HH:mm:ss')}
+
{item.finish_time?timers(new Date(item.finish_time).getTime()-new Date(item.create_time).getTime()):timers(new Date().getTime()-new Date(item.create_time).getTime())}
+
{momnet(item.create_time).format('YYYY-MM-DD HH:mm:ss')}
+
+ + +
)):''} diff --git a/react-ui/src/services/experiment/index.js b/react-ui/src/services/experiment/index.js index af4a3264..5409d042 100644 --- a/react-ui/src/services/experiment/index.js +++ b/react-ui/src/services/experiment/index.js @@ -21,12 +21,30 @@ export function getExperimentById(id) { method: 'GET', }); } +// 根据id删除实验 +export function deleteExperimentById(id) { + return request(`/api/mmp/experiment/${id}`, { + method: 'DELETE', + }); +} // 根据id查询实验实例 export function getQueryByExperimentId(id) { return request(`/api/mmp/experimentIns/queryByExperimentId/${id}`, { method: 'GET', }); } +// 根据id删除实验实例 +export function deleteQueryByExperimentInsId(id) { + return request(`/api/mmp/experimentIns/${id}`, { + method: 'DELETE', + }); +} +// 根据id终止实验实例 +export function putQueryByExperimentInsId(id) { + return request(`/api/mmp/experimentIns/${id}`, { + method: 'PUT', + }); +} // 根据id查询查询日志 export function getQueryByExperimentLog(params) { return request(`/api/mmp/experimentIns/log/`, { From 590c7de3140b5ad08ce3ece9032c7859d10ca098 Mon Sep 17 00:00:00 2001 From: fans <1141904845@qq.com> Date: Sat, 27 Jan 2024 10:30:11 +0800 Subject: [PATCH 2/5] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=AE=9E=E4=BE=8B?= =?UTF-8?q?=E5=88=97=E8=A1=A8=E7=9A=84=E5=AE=9E=E4=BE=8B=E7=8A=B6=E6=80=81?= =?UTF-8?q?=E5=88=97=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/ruoyi/platform/domain/Experiment.java | 8 +++++ .../impl/ExperimentInsServiceImpl.java | 18 ++++++++++- .../ExperimentDaoMapper.xml | 31 +++++++++++++------ 3 files changed, 47 insertions(+), 10 deletions(-) diff --git a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/domain/Experiment.java b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/domain/Experiment.java index a92188f4..222e8fa5 100644 --- a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/domain/Experiment.java +++ b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/domain/Experiment.java @@ -33,6 +33,8 @@ public class Experiment implements Serializable { */ @ApiModelProperty(name = "global_param") private String globalParam; + + private String statusList; /** * 简介 */ @@ -100,7 +102,13 @@ public class Experiment implements Serializable { this.globalParam = globalParam; } + public String getStatusList() { + return statusList; + } + public void setStatusList(String statusList) { + this.statusList = statusList; + } public String getCreateBy() { return createBy; diff --git a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/ExperimentInsServiceImpl.java b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/ExperimentInsServiceImpl.java index 3aeb7e40..f27b7797 100644 --- a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/ExperimentInsServiceImpl.java +++ b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/ExperimentInsServiceImpl.java @@ -1,6 +1,7 @@ package com.ruoyi.platform.service.impl; import com.ruoyi.common.security.utils.SecurityUtils; +import com.ruoyi.platform.domain.Experiment; import com.ruoyi.platform.domain.ExperimentIns; import com.ruoyi.platform.mapper.ExperimentDao; import com.ruoyi.platform.mapper.ExperimentInsDao; @@ -80,13 +81,17 @@ public class ExperimentInsServiceImpl implements ExperimentInsService { @Override public List getByExperimentId(Integer experimentId) throws IOException { List experimentInsList = experimentInsDao.getByExperimentId(experimentId); - + //搞个标记,当状态改变才去改表 + boolean flag = false; List result = new ArrayList(); if (experimentInsList!=null&&experimentInsList.size()>0) { for (ExperimentIns experimentIns : experimentInsList) { //当原本状态为null或非终止态时才调用argo接口 if (experimentIns != null && (StringUtils.isEmpty(experimentIns.getStatus())) || !isTerminatedState(experimentIns)) { experimentIns = this.queryStatusFromArgo(experimentIns); + if (!flag){ + flag = true; + } //只有当新状态是终止态时才更新数据库 if (isTerminatedState(experimentIns)) { //同时更新各个节点 @@ -97,6 +102,17 @@ public class ExperimentInsServiceImpl implements ExperimentInsService { } } + if (flag) { + List statusList = new ArrayList(); + // 更新实验状态列表 + for (int i=0;i + @@ -18,7 +19,7 @@ @@ -26,7 +27,7 @@ select - id,name, workflow_id, global_param, description, create_by, create_time, update_by, update_time, state + id,name, workflow_id, global_param, status_list, description, create_by, create_time, update_by, update_time, state from experiment state = 1 @@ -79,6 +83,9 @@ and global_param = #{experiment.globalParam} + + status_list = #{experiment.statusList}, + and description = #{experiment.description} @@ -117,6 +124,9 @@ and global_param = #{experiment.globalParam} + + status_list = #{experiment.statusList}, + and description = #{experiment.description} @@ -137,24 +147,24 @@ - insert into experiment(name,workflow_id, global_param, description, create_by, create_time, update_by, update_time, state) - values (#{name},#{workflowId}, #{globalParam}, #{description}, #{createBy}, #{createTime}, #{updateBy}, #{updateTime}, #{state}) + insert into experiment(name,workflow_id, global_param, status_list, description, create_by, create_time, update_by, update_time, state) + values (#{name},#{workflowId}, #{globalParam},#{entity.statusList}, #{description}, #{createBy}, #{createTime}, #{updateBy}, #{updateTime}, #{state}) - insert into experiment(name,workflow_id, global_param, description, create_by, create_time, update_by, update_time, state) + insert into experiment(name,workflow_id, global_param, status_list, description, create_by, create_time, update_by, update_time, state) values - (#{entity.name},#{entity.workflowId}, #{entity.globalParam}, #{entity.description}, #{entity.createBy}, #{entity.createTime}, + (#{entity.name},#{entity.workflowId}, #{entity.globalParam},#{entity.statusList}, #{entity.description}, #{entity.createBy}, #{entity.createTime}, #{entity.updateBy}, #{entity.updateTime}, #{entity.state}) - insert into experiment(name,workflow_id, global_param, description, create_by, create_time, update_by, update_time, state) + insert into experiment(name,workflow_id, global_param, status_list, description, create_by, create_time, update_by, update_time, state) values - (#{entity.name},#{entity.workflowId}, #{entity.globalParam}, #{entity.description}, #{entity.createBy}, #{entity.createTime}, + (#{entity.name},#{entity.workflowId}, #{entity.globalParam}, #{entity.statusList}, #{entity.description}, #{entity.createBy}, #{entity.createTime}, #{entity.updateBy}, #{entity.updateTime}, #{entity.state}) on duplicate key update @@ -182,6 +192,9 @@ global_param = #{globalParam}, + + status_list = #{statusList}, + description = #{description}, From c0cb78786a5a90b268a53539609e8c6c1dce8303 Mon Sep 17 00:00:00 2001 From: fans <1141904845@qq.com> Date: Sat, 27 Jan 2024 14:51:16 +0800 Subject: [PATCH 3/5] =?UTF-8?q?=E4=BF=AE=E6=94=B9error=E4=B8=BAfailed?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ruoyi/platform/service/impl/ExperimentInsServiceImpl.java | 4 +++- .../mapper/managementPlatform/ExperimentDaoMapper.xml | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/ExperimentInsServiceImpl.java b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/ExperimentInsServiceImpl.java index f27b7797..be1752ed 100644 --- a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/ExperimentInsServiceImpl.java +++ b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/ExperimentInsServiceImpl.java @@ -283,7 +283,9 @@ public class ExperimentInsServiceImpl implements ExperimentInsService { if (!StringUtils.equals(experimentIns.getStatus(),"Terminated")) { experimentIns.setStatus(StringUtils.isNotEmpty((String) status.get("phase"))?(String) status.get("phase"):"Pending"); } - + if (StringUtils.equals(experimentIns.getStatus(),"Error")) { + experimentIns.setStatus("Failed"); + } return experimentIns; diff --git a/ruoyi-modules/management-platform/src/main/resources/mapper/managementPlatform/ExperimentDaoMapper.xml b/ruoyi-modules/management-platform/src/main/resources/mapper/managementPlatform/ExperimentDaoMapper.xml index 33806863..d0ae5dbc 100644 --- a/ruoyi-modules/management-platform/src/main/resources/mapper/managementPlatform/ExperimentDaoMapper.xml +++ b/ruoyi-modules/management-platform/src/main/resources/mapper/managementPlatform/ExperimentDaoMapper.xml @@ -148,7 +148,7 @@ insert into experiment(name,workflow_id, global_param, status_list, description, create_by, create_time, update_by, update_time, state) - values (#{name},#{workflowId}, #{globalParam},#{entity.statusList}, #{description}, #{createBy}, #{createTime}, #{updateBy}, #{updateTime}, #{state}) + values (#{name},#{workflowId}, #{globalParam},#{statusList}, #{description}, #{createBy}, #{createTime}, #{updateBy}, #{updateTime}, #{state}) From 4b171cf70855f2d1344d0dafed3d9b313f84c23e Mon Sep 17 00:00:00 2001 From: fans <1141904845@qq.com> Date: Sat, 27 Jan 2024 15:53:32 +0800 Subject: [PATCH 4/5] =?UTF-8?q?=E4=BF=AE=E6=94=B9statusList=E5=88=97?= =?UTF-8?q?=E8=A1=A8=E6=A0=BC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ruoyi/platform/service/impl/ExperimentInsServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/ExperimentInsServiceImpl.java b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/ExperimentInsServiceImpl.java index be1752ed..600b4353 100644 --- a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/ExperimentInsServiceImpl.java +++ b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/ExperimentInsServiceImpl.java @@ -109,7 +109,7 @@ public class ExperimentInsServiceImpl implements ExperimentInsService { statusList.add(result.get(i).getStatus()); } Experiment experiment = experimentDao.queryById(experimentId); - experiment.setStatusList(statusList.toString()); + experiment.setStatusList(statusList.toString().substring(1, statusList.toString().length()-1)); experimentDao.update(experiment); } From 4c524449a549e6a45de5f3d70cd2dbd6e9b6284c Mon Sep 17 00:00:00 2001 From: YaHoo94 <673964817@qq.com> Date: Sat, 27 Jan 2024 16:25:24 +0800 Subject: [PATCH 5/5] merge --- react-ui/public/assets/images/fail-icon.png | Bin 0 -> 1008 bytes .../public/assets/images/omitted-icon.png | Bin 0 -> 1360 bytes .../public/assets/images/pending-icon.png | Bin 0 -> 1072 bytes .../public/assets/images/running-icon.png | Bin 0 -> 1108 bytes .../public/assets/images/success-icon.png | Bin 0 -> 1105 bytes react-ui/src/pages/Experiment/index.jsx | 35 ++++++++++++-- react-ui/src/pages/Experiment/index.less | 12 +++++ .../src/pages/Pipeline/editPipeline/index.jsx | 45 +++++++++++++++++- .../src/pages/Pipeline/editPipeline/props.jsx | 6 ++- 9 files changed, 90 insertions(+), 8 deletions(-) create mode 100644 react-ui/public/assets/images/fail-icon.png create mode 100644 react-ui/public/assets/images/omitted-icon.png create mode 100644 react-ui/public/assets/images/pending-icon.png create mode 100644 react-ui/public/assets/images/running-icon.png create mode 100644 react-ui/public/assets/images/success-icon.png diff --git a/react-ui/public/assets/images/fail-icon.png b/react-ui/public/assets/images/fail-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..da6c16cdfe6079bff23ff0d2fa5d16e8f004073e GIT binary patch literal 1008 zcmV znx25LDV=Vjo&b7+CaZSQR{cLkQf$SNY}0y%iLs@ppWe63S%>Rhhz!FI6=P%0*e>of z#yLG>OsSdvVN5<}?B

vV&*_dFcxPLo9H~ITz{CW`t6YxGT3AyUL|pq~=9I2mk`k zuxt8t7ofiJ)k5}<-VHI1w6s?ntJDIE6#G(M#9)FTfH;ES>&oP%QmTa7%b42dLhSy8 z=`fGxAKLktD_=4;3TdYi1Q6E{a}TAP&f5{tan&!NRF#@;n;WCO&5 zSZ*mb?CN;F2_Un?#@?@3w5f8Kip=V+8i;3(uiJp=s)djrd=lam&VFfNHq7Kev}1C9 zYXmI;k^L(O3kR42Fek=LH_(bRe--4`MhDE1Kh+!&%}fFF*1(JaGoyPAQqzV~7kGId z3$>@b(@Bx@2Lm$0S|bMnmCa4E`Y$GFaNcvkoY8ZueO@JmM_(OCc^caB7a_!NWLSjY zBxE{lN;@RvOhR&WuHpQn1y-XMNq z3^{O{$RQf4cf}upChr?oKC4@gm4+!g#!shM+JtZs<(|+>*TAVm*>>n?ocOgi%>+R zSuA5x`lh)FZH(bpA566B&D-khiV$F2X-@e|-}lglZ8=<#)gYz_JsPd(+~0SR)I84> zT+2~yjH+5G0dt%Z+ULFL@~1Qx4f)ubu->!UiikmQq6xye=(AX#IW-WX{lU4k?LT0O zSYOd+!O)zIoMCYRp=0-zfCjbbb&_8L%t4$Y z%AI37_{I_tMVsSl62vY_w*Iv`Skt$W)mb)h>59zQ6adqdZ&(qnL8@z-4>p;3HZ;F8 eboYzC2eZErQDtRt9~D>t0000K0%xl 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 { "Skipped":'未执行', "Omitted":'未执行', } + const statusColorObj={ + "Running":'#165bff', + "Succeeded":'#63a728', + "Pending":'#f981eb', + "Failed":'#c73131', + "Error":'#c73131', + "Terminated":'#8a8a8a', + "Skipped":'#8a8a8a', + "Omitted":'#8a8a8ae', + } + const statusImgObj={ + 'Running':'/assets/images/running-icon.png', + 'Succeeded':'/assets/images/success-icon.png', + 'Pending':'/assets/images/pending-icon.png', + 'Failed':'/assets/images/fail-icon.png', + 'Terminated':'/assets/images/omitted-icon.png', + 'Skipped':'/assets/images/omitted-icon.png', + 'Omitted':'/assets/images/omitted-icon.png', + } const [experimentList, setExperimentList] = useState([]); const [workflowList, setWorkflowList] = useState([]); @@ -59,10 +78,11 @@ const Experiment = React.FC = () => { setExpandedRowKeys(val) if(ret.code==200&&ret.data&&ret.data.length>0){ setExperimentInList(ret.data) - + getList() } else{ setExperimentInList([]) + getList() } }) } @@ -160,7 +180,6 @@ const Experiment = React.FC = () => { if(ret.code==200){ message.success('运行成功') getQueryByExperiment(id) - getList() } else{ message.error('运行失败') @@ -230,8 +249,14 @@ const Experiment = React.FC = () => { }, { title: '最近五次运行状态', - dataIndex: 'state', - key: 'state', + dataIndex: 'status_list', + key: 'status_list', + render: (text) => { + + let newText=text&&text.replace(/\s+/g,'').split(',') + console.log(newText); + return <>{ newText&&newText.length>0?newText.map((item,index)=>{console.log(item,statusImgObj[item]); return }):null} + } }, { @@ -321,7 +346,7 @@ const Experiment = React.FC = () => { {experimentInList&&experimentInList.length>0?experimentInList.map((item,index)=>(

routerToText(e,item,record)}>{index+1} -
{statusObj[item.status]}
+
{statusObj[item.status]}
{item.finish_time?timers(new Date(item.finish_time).getTime()-new Date(item.create_time).getTime()):timers(new Date().getTime()-new Date(item.create_time).getTime())}
{momnet(item.create_time).format('YYYY-MM-DD HH:mm:ss')}
diff --git a/react-ui/src/pages/Experiment/index.less b/react-ui/src/pages/Experiment/index.less index 701c4cbd..b015521e 100644 --- a/react-ui/src/pages/Experiment/index.less +++ b/react-ui/src/pages/Experiment/index.less @@ -32,4 +32,16 @@ font-size:15px; padding: 0 65px 0 40px; +} +.statusBox{ + display: flex; + align-items: center; + + .statusIcon{ + visibility: hidden; + transition: all 0.2s; + } +} +.statusBox:hover .statusIcon{ + visibility: visible; } \ No newline at end of file diff --git a/react-ui/src/pages/Pipeline/editPipeline/index.jsx b/react-ui/src/pages/Pipeline/editPipeline/index.jsx index 087f26af..c3f37b14 100644 --- a/react-ui/src/pages/Pipeline/editPipeline/index.jsx +++ b/react-ui/src/pages/Pipeline/editPipeline/index.jsx @@ -13,6 +13,7 @@ import { useNavigate} from 'react-router-dom'; const editPipeline = React.FC = () => { const propsRef=useRef() const navgite=useNavigate(); + const [contextMenu,setContextMenu]=useState({}) const locationParams =useParams () //新版本获取路由参数接口 let graph=null const pipelineContainer = useEmotionCss(() => { @@ -30,6 +31,7 @@ const editPipeline = React.FC = () => { }; }); const graphRef=useRef() + const onDragEnd=(val)=>{ console.log(val,'eee'); const _x = val.x @@ -117,9 +119,49 @@ const editPipeline = React.FC = () => { // graph.render() }) } + const handlerContextMenu=(e)=> { + e.stopPropagation(); + // this.menuType = e.item._cfg.type; + } + const initMenu=()=> { + // const selectedNodes = this.selectedNodes; + setContextMenu(new G6.Menu({ + getContent(evt) { + console.log(11111, evt); + + let ul = `
    +
  • 撤销
  • +
  • 恢复
  • +
  • 删除
  • + `; + }, + + + handleMenuClick:(target, item) => { + switch (target.getAttribute('code')) { + // case 'undo': + // this.$emit('handleMenuCall', { code: 'undo' }); + // break; + // case 'redo': + // this.$emit('handleMenuCall', { code: 'redo' }); + // break; + case 'delete': + graph.removeItem(item); + + break; + default: + break; + } + }, + offsetX: 16 + 20, + offsetY: 0, + itemTypes: ['node', 'canvas', 'edge'], + })); + }; useEffect(()=>{ getFirstWorkflow(locationParams.id) initGraph() + initMenu() },[]) const initGraph=()=>{ G6.registerNode( @@ -224,7 +266,7 @@ const editPipeline = React.FC = () => { animate: false, groupByTypes: false, fitView:true, - plugins: [], + plugins: [contextMenu], enabledStack: true, modes: { default: [ @@ -345,6 +387,7 @@ const editPipeline = React.FC = () => { }); }); }); + graph.on('contextmenu', handlerContextMenu); window.onresize = () => { if (!graph || graph.get('destroyed')) return; if (!graphRef.current || !graphRef.current.scrollWidth || !graphRef.current.scrollHeight) return; diff --git a/react-ui/src/pages/Pipeline/editPipeline/props.jsx b/react-ui/src/pages/Pipeline/editPipeline/props.jsx index 3f032ad1..cd243f48 100644 --- a/react-ui/src/pages/Pipeline/editPipeline/props.jsx +++ b/react-ui/src/pages/Pipeline/editPipeline/props.jsx @@ -49,8 +49,8 @@ const Props = forwardRef(({onParentChange}, ref) =>{ }; useImperativeHandle(ref, () => ({ showDrawer (e) { - console.log(e.item.getModel()); - // console.log(e.item.getModel().in_parameters); + if(e.item&&e.item.getModel()){ + // console.log(e.item.getModel().in_parameters); form.resetFields(); form.setFieldsValue({...e.item.getModel(),in_parameters:JSON.parse(e.item.getModel().in_parameters),out_parameters:JSON.parse(e.item.getModel().out_parameters),control_strategy:JSON.parse(e.item.getModel().control_strategy)}) setStagingItem({...e.item.getModel(),in_parameters:JSON.parse(e.item.getModel().in_parameters),out_parameters:JSON.parse(e.item.getModel().out_parameters),control_strategy:JSON.parse(e.item.getModel().control_strategy)}) @@ -60,6 +60,8 @@ const Props = forwardRef(({onParentChange}, ref) =>{ // console.log(stagingItem); // }, (500)); setOpen(true); + } + }, }));