# Conflicts: # ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/utils/K8sClientUtil.javamaster-fzznrj423
| @@ -0,0 +1 @@ | |||||
| <svg xmlns="http://www.w3.org/2000/svg" width="26" height="26" viewBox="0 0 26 26" fill="currentColor"><path class="a" d="M872.8,755.637h0v-.012Z" transform="translate(-848.576 -735.009)"/><path class="a" d="M122.155,109.158a13,13,0,1,0-13,13,13.015,13.015,0,0,0,13-13m-13,11.135a11.134,11.134,0,1,1,11.134-11.135,11.149,11.149,0,0,1-11.134,11.135" transform="translate(-96.155 -96.158)"/><path class="a" d="M344.559,345.281l-4.141-4.154,4.137-4.091a.957.957,0,1,0-1.346-1.36l-4.141,4.1-4.08-4.092a.957.957,0,0,0-1.355,1.351l4.075,4.087-4.107,4.062a.956.956,0,0,0,1.345,1.36l4.113-4.068,4.145,4.16a.957.957,0,0,0,1.355-1.352" transform="translate(-326.072 -328.091)"/></svg> | |||||
| @@ -0,0 +1 @@ | |||||
| <svg xmlns="http://www.w3.org/2000/svg" width="14.893" height="13.83" viewBox="0 0 14.893 13.83" fill="currentColor"><path class="a" d="M60.718,92.155a.532.532,0,0,1,.532.532v1.064h2.66a.532.532,0,0,1,0,1.064H61.25v1.064a.532.532,0,0,1-1.064,0V92.687a.532.532,0,0,1,.532-.532Zm-2.128,1.6a.532.532,0,0,1,0,1.064H50.08a.532.532,0,1,1,0-1.064h8.51Zm-5.319-6.383a.532.532,0,0,1,.532.532v3.191a.532.532,0,1,1-1.064,0V90.027H50.08a.532.532,0,1,1,0-1.064h2.66V87.9a.532.532,0,0,1,.532-.532Zm10.638,1.6a.532.532,0,0,1,0,1.064H55.4a.532.532,0,1,1,0-1.064Zm-3.191-6.383a.532.532,0,0,1,.532.532v1.064h2.66a.532.532,0,0,1,0,1.064H61.25V86.3a.532.532,0,0,1-1.064,0V83.113a.532.532,0,0,1,.532-.532Zm-2.128,1.6a.532.532,0,0,1,0,1.064H50.08a.532.532,0,1,1,0-1.064h8.51Z" transform="translate(-49.548 -82.581)"/></svg> | |||||
| @@ -0,0 +1 @@ | |||||
| <svg xmlns="http://www.w3.org/2000/svg" width="13.247" height="13.247" viewBox="0 0 13.247 13.247" fill="currentColor"><g transform="translate(-370.617 -114.129)"><path class="a" d="M93.531,82H83.716A1.718,1.718,0,0,0,82,83.716v9.815a1.718,1.718,0,0,0,1.716,1.716h9.815a1.718,1.718,0,0,0,1.716-1.716V83.716A1.718,1.718,0,0,0,93.531,82Zm.792,11.531a.793.793,0,0,1-.792.792H83.716a.793.793,0,0,1-.792-.792V83.716a.793.793,0,0,1,.792-.792h9.815a.793.793,0,0,1,.792.792ZM84,86.549a.462.462,0,0,1,.462-.462h4.148a.462.462,0,1,1,0,.924H84.465A.462.462,0,0,1,84,86.549Zm9.215,0a.462.462,0,0,1-.462.462h-1.7V87.8a.462.462,0,1,1-.924,0V85.3a.462.462,0,0,1,.924,0v.787h1.7a.462.462,0,0,1,.462.462Zm0,4.31a.462.462,0,0,1-.462.462H87.54a.462.462,0,1,1,0-.924h5.215A.462.462,0,0,1,93.217,90.859ZM85.926,89.61v2.5a.462.462,0,0,1-.924,0v-.787h-.537a.462.462,0,1,1,0-.924H85V89.61a.462.462,0,0,1,.924,0Z" transform="translate(288.617 32.129)"/></g></svg> | |||||
| @@ -0,0 +1,37 @@ | |||||
| .kf-modal { | |||||
| .ant-modal-content { | |||||
| padding: 20px 67px; | |||||
| background: linear-gradient(180deg, #cfdfff 0%, #d4e2ff 9.77%, #ffffff 40%, #ffffff 100%); | |||||
| border-radius: 21px; | |||||
| } | |||||
| .ant-modal-header { | |||||
| margin: 20px 0; | |||||
| background-color: transparent; | |||||
| } | |||||
| .ant-modal-footer { | |||||
| display: flex; | |||||
| justify-content: center; | |||||
| margin: 40px 0 20px 0; | |||||
| .ant-btn { | |||||
| height: 40px; | |||||
| padding: 0 30px; | |||||
| font-size: 16px; | |||||
| border-radius: 10px; | |||||
| } | |||||
| .ant-btn-default { | |||||
| color: #1d1d20; | |||||
| background: rgba(22, 100, 255, 0.06); | |||||
| border-color: transparent; | |||||
| } | |||||
| .ant-btn + .ant-btn { | |||||
| margin-left: 20px; | |||||
| } | |||||
| } | |||||
| .ant-modal-close { | |||||
| top: 27px; | |||||
| right: 27px; | |||||
| width: 26px; | |||||
| height: 26px; | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,25 @@ | |||||
| // 自定义 Modal | |||||
| import { ReactComponent as CloseIcon } from '@/assets/svg/modal-close.svg'; | |||||
| import ModalTitle from '@/components/ModalTitle'; | |||||
| import { Modal, type ModalProps } from 'antd'; | |||||
| import classNames from 'classnames'; | |||||
| import './index.less'; | |||||
| type KFModalProps = ModalProps & { | |||||
| image: string; | |||||
| }; | |||||
| function KFModal({ title, image, children, className, ...rest }: KFModalProps) { | |||||
| return ( | |||||
| <Modal | |||||
| className={classNames(['kf-modal', className])} | |||||
| {...rest} | |||||
| title={<ModalTitle title={title} image={image}></ModalTitle>} | |||||
| closeIcon={<CloseIcon></CloseIcon>} | |||||
| > | |||||
| {children} | |||||
| </Modal> | |||||
| ); | |||||
| } | |||||
| export default KFModal; | |||||
| @@ -0,0 +1,12 @@ | |||||
| @import '@/styles/theme.less'; | |||||
| .modal_title { | |||||
| display: flex; | |||||
| align-items: center; | |||||
| color: @kf-primary-color; | |||||
| font-size: 20px; | |||||
| &_image { | |||||
| width: 22px; | |||||
| margin-right: 10px; | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,18 @@ | |||||
| import React from 'react'; | |||||
| import styles from './index.less'; | |||||
| type ModalTitleProps = { | |||||
| title: React.ReactNode; | |||||
| image?: string; | |||||
| }; | |||||
| function ModalTitle({ title, image }: ModalTitleProps) { | |||||
| return ( | |||||
| <div className={styles.modal_title}> | |||||
| <img className={styles.modal_title_image} src={image} alt="" /> | |||||
| {title} | |||||
| </div> | |||||
| ); | |||||
| } | |||||
| export default ModalTitle; | |||||
| @@ -24,7 +24,7 @@ export function useStateRef<T>(initialValue: T) { | |||||
| * @param initialValue - The initial visibility state of the modal. | * @param initialValue - The initial visibility state of the modal. | ||||
| * @return An array containing the visibility state and functions to open and close the modal. | * @return An array containing the visibility state and functions to open and close the modal. | ||||
| */ | */ | ||||
| export function useModal(initialValue: boolean) { | |||||
| export function useAntdModal(initialValue: boolean) { | |||||
| const [visible, setVisible] = useState(initialValue); | const [visible, setVisible] = useState(initialValue); | ||||
| const open = useCallback(() => { | const open = useCallback(() => { | ||||
| @@ -0,0 +1 @@ | |||||
| @@ -1,9 +1,22 @@ | |||||
| import { getLabelStudioUrl } from '@/services/developmentEnvironment'; | |||||
| import { to } from '@/utils/promise'; | |||||
| import { useEffect, useState } from 'react'; | |||||
| import styles from './index.less'; | import styles from './index.less'; | ||||
| function DatasetAnnotation() { | function DatasetAnnotation() { | ||||
| const [iframeUrl, setIframeUrl] = useState(''); | |||||
| useEffect(() => { | |||||
| requestIframeUrl(); | |||||
| }, []); | |||||
| const requestIframeUrl = async () => { | |||||
| const [res] = await to(getLabelStudioUrl()); | |||||
| if (res && res.data) { | |||||
| setIframeUrl(res.data); | |||||
| } | |||||
| }; | |||||
| return ( | return ( | ||||
| <div className={styles.container}> | <div className={styles.container}> | ||||
| <iframe src="http://172.20.32.181:32102" className={styles.frame}></iframe> | |||||
| {iframeUrl && <iframe src={iframeUrl} className={styles.frame}></iframe>} | |||||
| </div> | </div> | ||||
| ); | ); | ||||
| } | } | ||||
| @@ -1,17 +1,7 @@ | |||||
| .modal { | .modal { | ||||
| :global { | :global { | ||||
| .ant-modal-content { | |||||
| width: 825px; | |||||
| padding: 20px 67px; | |||||
| background: linear-gradient(180deg, #cfdfff 0%, #d4e2ff 9.77%, #ffffff 40%, #ffffff 100%); | |||||
| border-radius: 21px; | |||||
| } | |||||
| .ant-modal-header { | |||||
| margin: 20px 0; | |||||
| background-color: transparent; | |||||
| } | |||||
| .ant-input { | .ant-input { | ||||
| height: 40px; | |||||
| height: 30px; | |||||
| border-color: #e6e6e6; | border-color: #e6e6e6; | ||||
| } | } | ||||
| .ant-select-single { | .ant-select-single { | ||||
| @@ -20,38 +10,11 @@ | |||||
| .ant-form-item .ant-form-item-label > label { | .ant-form-item .ant-form-item-label > label { | ||||
| color: rgba(29, 29, 32, 0.8); | color: rgba(29, 29, 32, 0.8); | ||||
| } | } | ||||
| .ant-modal-footer { | |||||
| display: flex; | |||||
| justify-content: center; | |||||
| margin: 40px 0 30px 0; | |||||
| } | |||||
| .ant-btn { | |||||
| width: 110px; | |||||
| height: 40px; | |||||
| font-size: 18px; | |||||
| background: rgba(22, 100, 255, 0.06); | |||||
| border-color: transparent; | |||||
| border-radius: 10px; | |||||
| } | |||||
| .ant-btn-primary { | |||||
| background: #1664ff; | |||||
| } | |||||
| } | |||||
| .title { | |||||
| display: flex; | |||||
| align-items: center; | |||||
| font-weight: 500; | |||||
| .image { | |||||
| width: 20px; | |||||
| margin-right: 10px; | |||||
| } | |||||
| } | } | ||||
| .global_param_item { | .global_param_item { | ||||
| max-height: 230px; | max-height: 230px; | ||||
| padding: 20px 12px; | |||||
| padding: 24px 12px 0; | |||||
| overflow-y: auto; | overflow-y: auto; | ||||
| border: 1px solid #e6e6e6; | border: 1px solid #e6e6e6; | ||||
| border-radius: 6px; | border-radius: 6px; | ||||
| @@ -1,5 +1,8 @@ | |||||
| import createExperimentIcon from '@/assets/img/create-experiment.png'; | |||||
| import editExperimentIcon from '@/assets/img/edit-experiment.png'; | |||||
| import KFModal from '@/components/KFModal'; | |||||
| import { type PipelineGlobalParam } from '@/types'; | import { type PipelineGlobalParam } from '@/types'; | ||||
| import { Form, Input, Modal, Radio, Select, type FormRule } from 'antd'; | |||||
| import { Form, Input, Radio, Select, type FormRule } from 'antd'; | |||||
| import { useState } from 'react'; | import { useState } from 'react'; | ||||
| import styles from './addExperimentModal.less'; | import styles from './addExperimentModal.less'; | ||||
| @@ -76,21 +79,22 @@ function AddExperimentModal({ | |||||
| workflowList = [], | workflowList = [], | ||||
| initialValues = {}, | initialValues = {}, | ||||
| }: AddExperimentModalProps) { | }: AddExperimentModalProps) { | ||||
| const dialogTitle = isAdd ? '新建实验' : '编辑实验'; | |||||
| const modalTitle = isAdd ? '新建实验' : '配置实验'; | |||||
| const modalIcon = isAdd ? createExperimentIcon : editExperimentIcon; | |||||
| const workflowDisabled = isAdd ? false : true; | const workflowDisabled = isAdd ? false : true; | ||||
| const [globalParam, setGlobalParam] = useState<PipelineGlobalParam[]>( | const [globalParam, setGlobalParam] = useState<PipelineGlobalParam[]>( | ||||
| initialValues.global_param || [], | initialValues.global_param || [], | ||||
| ); | ); | ||||
| const [form] = Form.useForm(); | const [form] = Form.useForm(); | ||||
| const layout = { | |||||
| const tailLayout = { | |||||
| labelCol: { span: 24 }, | labelCol: { span: 24 }, | ||||
| wrapperCol: { span: 24 }, | wrapperCol: { span: 24 }, | ||||
| }; | }; | ||||
| const tailLayout = { | |||||
| labelCol: { span: 8 }, | |||||
| wrapperCol: { span: 16 }, | |||||
| const layout = { | |||||
| labelCol: { span: 4 }, | |||||
| wrapperCol: { span: 20 }, | |||||
| }; | }; | ||||
| // 除了流水线选择发生变化 | // 除了流水线选择发生变化 | ||||
| @@ -105,14 +109,10 @@ function AddExperimentModal({ | |||||
| } | } | ||||
| }; | }; | ||||
| return ( | return ( | ||||
| <Modal | |||||
| <KFModal | |||||
| className={styles.modal} | className={styles.modal} | ||||
| title={ | |||||
| <div className={styles.title}> | |||||
| <img className={styles.image} src={`/assets/images/pipeline-edit-icon.png`} alt="" /> | |||||
| {dialogTitle} | |||||
| </div> | |||||
| } | |||||
| title={modalTitle} | |||||
| image={modalIcon} | |||||
| open={open} | open={open} | ||||
| okButtonProps={{ | okButtonProps={{ | ||||
| htmlType: 'submit', | htmlType: 'submit', | ||||
| @@ -120,6 +120,7 @@ function AddExperimentModal({ | |||||
| }} | }} | ||||
| onCancel={onCancel} | onCancel={onCancel} | ||||
| destroyOnClose={true} | destroyOnClose={true} | ||||
| width={825} | |||||
| > | > | ||||
| <Form | <Form | ||||
| name="form" | name="form" | ||||
| @@ -129,6 +130,8 @@ function AddExperimentModal({ | |||||
| autoComplete="off" | autoComplete="off" | ||||
| form={form} | form={form} | ||||
| {...layout} | {...layout} | ||||
| labelAlign="left" | |||||
| labelWrap | |||||
| > | > | ||||
| <Form.Item | <Form.Item | ||||
| label="实验名称" | label="实验名称" | ||||
| @@ -166,18 +169,21 @@ function AddExperimentModal({ | |||||
| </Select> | </Select> | ||||
| </Form.Item> | </Form.Item> | ||||
| {globalParam.length > 0 && ( | {globalParam.length > 0 && ( | ||||
| <Form.Item label="运行参数" tooltip="展示关联的流水线的参数,脱敏的参数以xxxx展示"> | |||||
| <Form.Item | |||||
| label="运行参数" | |||||
| tooltip="展示关联的流水线的参数,脱敏的参数以xxxx展示" | |||||
| {...tailLayout} | |||||
| > | |||||
| <div className={styles.global_param_item}> | <div className={styles.global_param_item}> | ||||
| <Form.List name="global_param"> | <Form.List name="global_param"> | ||||
| {(fields) => | {(fields) => | ||||
| fields.map(({ key, name, ...restField }) => ( | fields.map(({ key, name, ...restField }) => ( | ||||
| <Form.Item | <Form.Item | ||||
| {...tailLayout} | |||||
| {...restField} | {...restField} | ||||
| {...layout} | |||||
| key={key} | key={key} | ||||
| label={getParamType(globalParam[name])} | label={getParamType(globalParam[name])} | ||||
| name={[name, 'param_value']} | name={[name, 'param_value']} | ||||
| labelAlign="left" | |||||
| rules={getParamRules(globalParam[name]['param_type'])} | rules={getParamRules(globalParam[name]['param_type'])} | ||||
| > | > | ||||
| {getParamComponent( | {getParamComponent( | ||||
| @@ -192,7 +198,7 @@ function AddExperimentModal({ | |||||
| </Form.Item> | </Form.Item> | ||||
| )} | )} | ||||
| </Form> | </Form> | ||||
| </Modal> | |||||
| </KFModal> | |||||
| ); | ); | ||||
| } | } | ||||
| @@ -1,14 +1,18 @@ | |||||
| import { ReactComponent as ViewParam } from '@/assets/svg/view-param.svg'; | |||||
| import { useAntdModal } from '@/hooks'; | |||||
| import { getExperimentIns } from '@/services/experiment/index.js'; | import { getExperimentIns } from '@/services/experiment/index.js'; | ||||
| import { getWorkflowById } from '@/services/pipeline/index.js'; | import { getWorkflowById } from '@/services/pipeline/index.js'; | ||||
| import { elapsedTime } from '@/utils/date'; | import { elapsedTime } from '@/utils/date'; | ||||
| import { useEmotionCss } from '@ant-design/use-emotion-css'; | import { useEmotionCss } from '@ant-design/use-emotion-css'; | ||||
| import G6 from '@antv/g6'; | import G6 from '@antv/g6'; | ||||
| import { Button } from 'antd'; | |||||
| import momnet from 'moment'; | import momnet from 'moment'; | ||||
| import { useEffect, useRef, useState } from 'react'; | import { useEffect, useRef, useState } from 'react'; | ||||
| import { useNavigate, useParams } from 'react-router-dom'; | import { useNavigate, useParams } from 'react-router-dom'; | ||||
| import { s8 } from '../../../utils'; | import { s8 } from '../../../utils'; | ||||
| import { experimentStatusInfo } from '../status'; | import { experimentStatusInfo } from '../status'; | ||||
| import Styles from './editPipeline.less'; | |||||
| import styles from './index.less'; | |||||
| import ParamsModal from './paramsModal'; | |||||
| import Props from './props'; | import Props from './props'; | ||||
| function ExperimentText() { | function ExperimentText() { | ||||
| @@ -18,6 +22,7 @@ function ExperimentText() { | |||||
| const navgite = useNavigate(); | const navgite = useNavigate(); | ||||
| const locationParams = useParams(); //新版本获取路由参数接口 | const locationParams = useParams(); //新版本获取路由参数接口 | ||||
| let graph = null; | let graph = null; | ||||
| const [paramsModalOpen, openParamsModal, closeParamsModal] = useAntdModal(false); | |||||
| const timers = (time) => { | const timers = (time) => { | ||||
| let timer = new Date(time); | let timer = new Date(time); | ||||
| @@ -91,53 +96,50 @@ function ExperimentText() { | |||||
| }; | }; | ||||
| const getFirstWorkflow = (val) => { | const getFirstWorkflow = (val) => { | ||||
| getWorkflowById(val).then((ret) => { | getWorkflowById(val).then((ret) => { | ||||
| console.log(ret, 'retttttttttt'); | |||||
| if (ret.code == 200) { | |||||
| if (graph && ret.data && ret.data.dag) { | |||||
| console.log(JSON.parse(ret.data.dag)); | |||||
| getExperimentIns(locationParams.id).then((res) => { | |||||
| if (res.code == 200) { | |||||
| console.log(ret.data, 'data'); | |||||
| setMessage(res.data); | |||||
| const experimentStatusObjs = JSON.parse(res.data.nodes_status); | |||||
| 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 }; | |||||
| if (graph && ret.data && ret.data.dag) { | |||||
| console.log(JSON.parse(ret.data.dag)); | |||||
| getExperimentIns(locationParams.id).then((res) => { | |||||
| if (res.code == 200) { | |||||
| console.log(ret.data, 'data'); | |||||
| setMessage(res.data); | |||||
| const experimentStatusObjs = JSON.parse(res.data.nodes_status); | |||||
| 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 }; | |||||
| getGraphData(newData); | |||||
| // setExperimentStatusObj(JSON.parse(ret.data.nodes_status)) | |||||
| } | |||||
| }); | |||||
| } | |||||
| getGraphData(newData); | |||||
| // setExperimentStatusObj(JSON.parse(ret.data.nodes_status)) | |||||
| } | |||||
| }); | |||||
| } | } | ||||
| // graph&&graph.data(JSON.parse(ret.dag)) | // graph&&graph.data(JSON.parse(ret.dag)) | ||||
| // graph.render() | // graph.render() | ||||
| @@ -369,18 +371,18 @@ function ExperimentText() { | |||||
| }; | }; | ||||
| return ( | return ( | ||||
| <div className={pipelineContainer}> | <div className={pipelineContainer}> | ||||
| <div className={Styles.centerContainer}> | |||||
| <div className={Styles.buttonList}> | |||||
| <div className={Styles.allMessageItem}> | |||||
| <div className={styles.centerContainer}> | |||||
| <div className={styles.buttonList}> | |||||
| <div className={styles.allMessageItem}> | |||||
| 启动时间:{momnet(message.create_time).format('YYYY-MM-DD HH:mm:ss')} | 启动时间:{momnet(message.create_time).format('YYYY-MM-DD HH:mm:ss')} | ||||
| </div> | </div> | ||||
| <div className={Styles.allMessageItem}> | |||||
| <div className={styles.allMessageItem}> | |||||
| 执行时长: | 执行时长: | ||||
| {message.finish_time | {message.finish_time | ||||
| ? elapsedTime(new Date(message.create_time), new Date(message.finish_time)) | ? elapsedTime(new Date(message.create_time), new Date(message.finish_time)) | ||||
| : elapsedTime(new Date(message.create_time), new Date())} | : elapsedTime(new Date(message.create_time), new Date())} | ||||
| </div> | </div> | ||||
| <div className={Styles.allMessageItem}> | |||||
| <div className={styles.allMessageItem}> | |||||
| 状态: | 状态: | ||||
| <div | <div | ||||
| style={{ | style={{ | ||||
| @@ -395,10 +397,22 @@ function ExperimentText() { | |||||
| {experimentStatusInfo[message.status]?.label} | {experimentStatusInfo[message.status]?.label} | ||||
| </span> | </span> | ||||
| </div> | </div> | ||||
| <Button | |||||
| icon={<ViewParam style={{ verticalAlign: '-1px' }}></ViewParam>} | |||||
| className={styles.param_button} | |||||
| onClick={openParamsModal} | |||||
| > | |||||
| 执行参数 | |||||
| </Button> | |||||
| </div> | </div> | ||||
| <div className={graphStyle} ref={graphRef} id={Styles.graphStyle}></div> | |||||
| <div className={graphStyle} ref={graphRef} id={styles.graphStyle}></div> | |||||
| </div> | </div> | ||||
| <Props ref={propsRef} onParentChange={formChange}></Props> | <Props ref={propsRef} onParentChange={formChange}></Props> | ||||
| <ParamsModal | |||||
| open={paramsModalOpen} | |||||
| onCancel={closeParamsModal} | |||||
| globalParam={message.global_param} | |||||
| ></ParamsModal> | |||||
| </div> | </div> | ||||
| ); | ); | ||||
| } | } | ||||
| @@ -24,7 +24,7 @@ | |||||
| display: flex; | display: flex; | ||||
| align-items: center; | align-items: center; | ||||
| width: 100%; | width: 100%; | ||||
| height: 45px; | |||||
| height: 56px; | |||||
| padding: 0 30px; | padding: 0 30px; | ||||
| background: #ffffff; | background: #ffffff; | ||||
| box-shadow: 0px 3px 6px rgba(146, 146, 146, 0.09); | box-shadow: 0px 3px 6px rgba(146, 146, 146, 0.09); | ||||
| @@ -43,6 +43,10 @@ | |||||
| color: rgba(29, 29, 32, 0.8); | color: rgba(29, 29, 32, 0.8); | ||||
| font-size: 15px; | font-size: 15px; | ||||
| } | } | ||||
| .param_button { | |||||
| margin-right: 0; | |||||
| margin-left: auto; | |||||
| } | |||||
| .resultTop { | .resultTop { | ||||
| display: flex; | display: flex; | ||||
| align-items: center; | align-items: center; | ||||
| @@ -0,0 +1,30 @@ | |||||
| .params_container { | |||||
| max-height: 230px; | |||||
| padding: 15px; | |||||
| border: 1px solid #e6e6e6; | |||||
| border-radius: 8px; | |||||
| &_line { | |||||
| display: flex; | |||||
| align-items: center; | |||||
| margin-bottom: 15px; | |||||
| &_label { | |||||
| width: 120px; | |||||
| color: #1d1d20; | |||||
| font-size: 15px; | |||||
| } | |||||
| &_value { | |||||
| flex: 1; | |||||
| width: 100px; | |||||
| margin-left: 15px; | |||||
| padding: 10px 20px; | |||||
| color: #1d1d20; | |||||
| font-size: 15px; | |||||
| line-height: 20px; | |||||
| background: #f6f6f6; | |||||
| border: 1px solid #e0e0e1; | |||||
| border-radius: 4px; | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,34 @@ | |||||
| import parameterImg from '@/assets/img/modal-parameter.png'; | |||||
| import KFModal from '@/components/KFModal'; | |||||
| import { type PipelineGlobalParam } from '@/types'; | |||||
| import styles from './paramsModal.less'; | |||||
| type ParamsModalProps = { | |||||
| open: boolean; | |||||
| onCancel: () => void; | |||||
| globalParam?: PipelineGlobalParam[]; | |||||
| }; | |||||
| function ParamsModal({ open, onCancel, globalParam = [] }: ParamsModalProps) { | |||||
| return ( | |||||
| <KFModal | |||||
| title="执行参数" | |||||
| image={parameterImg} | |||||
| open={open} | |||||
| onOk={onCancel} | |||||
| onCancel={onCancel} | |||||
| cancelButtonProps={{ style: { display: 'none' } }} | |||||
| > | |||||
| <div className={styles.params_container}> | |||||
| {globalParam.map((item) => ( | |||||
| <div key={item.param_name} className={styles.params_container_line}> | |||||
| <span className={styles.params_container_line_label}>{item.param_name}</span> | |||||
| <span className={styles.params_container_line_value}>{item.param_value}</span> | |||||
| </div> | |||||
| ))} | |||||
| </div> | |||||
| </KFModal> | |||||
| ); | |||||
| } | |||||
| export default ParamsModal; | |||||
| @@ -6,7 +6,7 @@ import { Drawer, Form, Input, Tabs, message } from 'antd'; | |||||
| import moment from 'moment'; | import moment from 'moment'; | ||||
| import { forwardRef, useImperativeHandle, useState } from 'react'; | import { forwardRef, useImperativeHandle, useState } from 'react'; | ||||
| import LogList from './LogList'; | import LogList from './LogList'; | ||||
| import Styles from './editPipeline.less'; | |||||
| import Styles from './index.less'; | |||||
| const { TextArea } = Input; | const { TextArea } = Input; | ||||
| const Props = forwardRef(({ onParentChange }, ref) => { | const Props = forwardRef(({ onParentChange }, ref) => { | ||||
| const [form] = Form.useForm(); | const [form] = Form.useForm(); | ||||
| @@ -1,4 +1,5 @@ | |||||
| import { useModal } from '@/hooks'; | |||||
| import { ReactComponent as ParameterIcon } from '@/assets/svg/parameter.svg'; | |||||
| import { useAntdModal } from '@/hooks'; | |||||
| import { getWorkflowById, saveWorkflow } from '@/services/pipeline/index.js'; | import { getWorkflowById, saveWorkflow } from '@/services/pipeline/index.js'; | ||||
| import { to } from '@/utils/promise'; | import { to } from '@/utils/promise'; | ||||
| import { SaveOutlined } from '@ant-design/icons'; | import { SaveOutlined } from '@ant-design/icons'; | ||||
| @@ -7,7 +8,6 @@ import G6 from '@antv/g6'; | |||||
| import { Button, message } from 'antd'; | import { Button, message } from 'antd'; | ||||
| import { useEffect, useRef, useState } from 'react'; | import { useEffect, useRef, useState } from 'react'; | ||||
| import { useNavigate, useParams } from 'react-router-dom'; | import { useNavigate, useParams } from 'react-router-dom'; | ||||
| import { Icon } from 'umi'; | |||||
| import { s8 } from '../../../utils'; | import { s8 } from '../../../utils'; | ||||
| import Styles from './editPipeline.less'; | import Styles from './editPipeline.less'; | ||||
| import GlobalParamsDrawer from './globalParamsDrawer'; | import GlobalParamsDrawer from './globalParamsDrawer'; | ||||
| @@ -60,7 +60,7 @@ const EditPipeline = () => { | |||||
| }); | }); | ||||
| const graphRef = useRef(); | const graphRef = useRef(); | ||||
| const paramsDrawerRef = useRef(); | const paramsDrawerRef = useRef(); | ||||
| const [paramsDrawerVisible, openParamsDrawer, closeParamsDrawer] = useModal(false); | |||||
| const [paramsDrawerOpen, openParamsDrawer, closeParamsDrawer] = useAntdModal(false); | |||||
| const [globalParam, setGlobalParam] = useState([]); | const [globalParam, setGlobalParam] = useState([]); | ||||
| const onDragEnd = (val) => { | const onDragEnd = (val) => { | ||||
| @@ -704,7 +704,7 @@ const EditPipeline = () => { | |||||
| <div className={Styles.buttonList}> | <div className={Styles.buttonList}> | ||||
| <Button | <Button | ||||
| type="default" | type="default" | ||||
| icon={<Icon icon="local:parameter" style={{ verticalAlign: '-2px' }} />} | |||||
| icon={<ParameterIcon style={{ verticalAlign: '-2px' }} />} | |||||
| style={{ marginRight: '20px' }} | style={{ marginRight: '20px' }} | ||||
| onClick={openParamsDrawer} | onClick={openParamsDrawer} | ||||
| > | > | ||||
| @@ -735,7 +735,7 @@ const EditPipeline = () => { | |||||
| <Props ref={propsRef} onParentChange={formChange}></Props> | <Props ref={propsRef} onParentChange={formChange}></Props> | ||||
| <GlobalParamsDrawer | <GlobalParamsDrawer | ||||
| ref={paramsDrawerRef} | ref={paramsDrawerRef} | ||||
| open={paramsDrawerVisible} | |||||
| open={paramsDrawerOpen} | |||||
| globalParam={globalParam} | globalParam={globalParam} | ||||
| onClose={closeParamsDrawer} | onClose={closeParamsDrawer} | ||||
| ></GlobalParamsDrawer> | ></GlobalParamsDrawer> | ||||
| @@ -1,8 +1,16 @@ | |||||
| import { request } from '@umijs/max'; | import { request } from '@umijs/max'; | ||||
| // 查询流水线列表 | |||||
| // 查询开发环境url | |||||
| export function getJupyterUrl(params) { | export function getJupyterUrl(params) { | ||||
| return request(`/api/mmp/jupyter/getURL`, { | return request(`/api/mmp/jupyter/getURL`, { | ||||
| method: 'GET', | method: 'GET', | ||||
| params, | params, | ||||
| }); | }); | ||||
| } | } | ||||
| // 查询 labelStudio url | |||||
| export function getLabelStudioUrl(params) { | |||||
| return request(`/api/mmp/labelStudio/getURL`, { | |||||
| method: 'GET', | |||||
| params, | |||||
| }); | |||||
| } | |||||
| @@ -1,8 +1,8 @@ | |||||
| // 全局颜色变量 | // 全局颜色变量 | ||||
| @primary-color: #1664ff; // 主色调 | |||||
| // FIXME: 不能设置 @primary-color 不起作用,感觉是哪里被重置了 | |||||
| @kf-primary-color: #1664ff; // 主色调 | |||||
| // 导出变量 | // 导出变量 | ||||
| :export { | :export { | ||||
| primaryColor: #1664ff; // FIXME: 设置为 @primary-color 不起作用,感觉是哪里被重置了 | |||||
| primaryColor: @kf-primary-color; | |||||
| } | } | ||||
| @@ -264,7 +264,7 @@ public class K8sClientUtil { | |||||
| .withName(podName) | .withName(podName) | ||||
| .withLabels(selector) | .withLabels(selector) | ||||
| .endMetadata() | .endMetadata() | ||||
| .withNewSpec()//默认不被操作4小时后删除 | |||||
| .withNewSpec() //默认不被操作4小时后删除 | |||||
| .addNewContainer() | .addNewContainer() | ||||
| .withName(podName) | .withName(podName) | ||||
| .withImage(image) | .withImage(image) | ||||
| @@ -334,7 +334,7 @@ public class K8sClientUtil { | |||||
| .withName(podName) | .withName(podName) | ||||
| .withLabels(selector) | .withLabels(selector) | ||||
| .endMetadata() | .endMetadata() | ||||
| .withNewSpec().withSchedulerName("0 */1 * * *")//默认不被操作4小时后删除 | |||||
| .withNewSpec() | |||||
| .addNewContainer() | .addNewContainer() | ||||
| .withName(podName) | .withName(podName) | ||||
| .withImage(image) | .withImage(image) | ||||
| @@ -344,7 +344,7 @@ public class K8sClientUtil { | |||||
| .addNewVolume() | .addNewVolume() | ||||
| .withName("workspace").withPersistentVolumeClaim(new V1PersistentVolumeClaimVolumeSource().claimName(pvcName)) | .withName("workspace").withPersistentVolumeClaim(new V1PersistentVolumeClaimVolumeSource().claimName(pvcName)) | ||||
| .endVolume() | .endVolume() | ||||
| // .withTerminationGracePeriodSeconds(14400L) | |||||
| .withTerminationGracePeriodSeconds(14400L) | |||||
| .endSpec() | .endSpec() | ||||
| .build(); | .build(); | ||||