You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

props.jsx 14 kB

2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427
  1. import { getNodeResult, getQueryByExperimentLog } from '@/services/experiment/index.js';
  2. import { elapsedTime } from '@/utils/date';
  3. import { downLoadZip } from '@/utils/downloadfile';
  4. import { DatabaseOutlined, ProfileOutlined } from '@ant-design/icons';
  5. import { Drawer, Form, Input, Tabs, message } from 'antd';
  6. import moment from 'moment';
  7. import { forwardRef, useImperativeHandle, useState } from 'react';
  8. import LogList from './LogList';
  9. import Styles from './editPipeline.less';
  10. const { TextArea } = Input;
  11. const Props = forwardRef(({ onParentChange }, ref) => {
  12. const [form] = Form.useForm();
  13. const [stagingItem, setStagingItem] = useState({});
  14. const [resultObj, setResultObj] = useState([]);
  15. const [logList, setLogList] = useState([]);
  16. const statusObj = {
  17. Running: '运行中',
  18. Succeeded: '成功',
  19. Pending: '等待中',
  20. Failed: '失败',
  21. Error: '错误',
  22. Terminated: '终止',
  23. Skipped: '未执行',
  24. Omitted: '未执行',
  25. };
  26. const statusColorObj = {
  27. Running: '#165bff',
  28. Succeeded: '#63a728',
  29. Pending: '#f981eb',
  30. Failed: '#c73131',
  31. Error: '#c73131',
  32. Terminated: '#8a8a8a',
  33. Skipped: '#8a8a8a',
  34. Omitted: '#8a8a8ae',
  35. };
  36. const exportResult = (e, val) => {
  37. const hide = message.loading('正在下载');
  38. hide();
  39. downLoadZip(`/api/mmp/minioStorage/download`, { path: val });
  40. };
  41. const timers = (time) => {
  42. let timer = new Date(time);
  43. let hours = timer.getHours(); //转换成时
  44. let minutes = timer.getMinutes(); //转换成分
  45. let secend = timer.getSeconds(); //转换成秒
  46. let str = `${minutes}分${secend}秒`;
  47. return str;
  48. };
  49. const items = [
  50. {
  51. key: '1',
  52. label: '日志详情',
  53. children: <LogList list={logList} status={stagingItem.experimentStatus}></LogList>,
  54. icon: <ProfileOutlined />,
  55. },
  56. {
  57. key: '2',
  58. label: '配置参数',
  59. icon: <DatabaseOutlined />,
  60. children: (
  61. <Form
  62. name="form"
  63. form={form}
  64. layout="vertical"
  65. labelCol={{
  66. span: 16,
  67. }}
  68. wrapperCol={{
  69. span: 16,
  70. }}
  71. style={{
  72. maxWidth: 600,
  73. }}
  74. initialValues={{
  75. remember: true,
  76. }}
  77. onFinish={onFinish}
  78. onFinishFailed={onFinishFailed}
  79. autoComplete="off"
  80. >
  81. <div className={Styles.editPipelinePropsContent}>
  82. <img
  83. style={{ width: '13px', marginRight: '10px' }}
  84. src={'/assets/images/static-message.png'}
  85. alt=""
  86. />
  87. 基本信息
  88. </div>
  89. <Form.Item
  90. label="任务名称"
  91. name="label"
  92. rules={[
  93. {
  94. required: true,
  95. message: '请输入任务名称',
  96. },
  97. ]}
  98. >
  99. <Input disabled />
  100. </Form.Item>
  101. <Form.Item
  102. label="任务ID"
  103. name="id"
  104. rules={[
  105. {
  106. required: true,
  107. message: '请输入任务id',
  108. },
  109. ]}
  110. >
  111. <Input disabled />
  112. </Form.Item>
  113. <div className={Styles.editPipelinePropsContent}>
  114. <img
  115. style={{ width: '13px', marginRight: '10px' }}
  116. src={'/assets/images/duty-message.png'}
  117. alt=""
  118. />
  119. 任务信息
  120. </div>
  121. <Form.Item
  122. label="镜像"
  123. name="image"
  124. rules={[
  125. {
  126. required: true,
  127. message: '请输入镜像',
  128. },
  129. ]}
  130. >
  131. <Input disabled />
  132. </Form.Item>
  133. <Form.Item label="工作目录" name="working_directory">
  134. <Input disabled />
  135. </Form.Item>
  136. <Form.Item label="启动命令" name="command">
  137. <Input disabled />
  138. </Form.Item>
  139. <Form.Item
  140. label="资源规格"
  141. name="resources_standard"
  142. rules={[
  143. {
  144. required: true,
  145. message: '请输入资源规格',
  146. },
  147. ]}
  148. >
  149. <Input disabled />
  150. </Form.Item>
  151. <Form.Item label="挂载路径" name="mount_path">
  152. <Input disabled />
  153. </Form.Item>
  154. <Form.Item label="环境变量" name="env_variables">
  155. <TextArea disabled />
  156. </Form.Item>
  157. {stagingItem.control_strategy &&
  158. Object.keys(stagingItem.control_strategy) &&
  159. Object.keys(stagingItem.control_strategy).length > 0
  160. ? Object.keys(stagingItem.control_strategy).map((item) => (
  161. <Form.Item label={stagingItem.control_strategy[item].label} disabled name={item}>
  162. <Input disabled />
  163. </Form.Item>
  164. ))
  165. : ''}
  166. <div className={Styles.editPipelinePropsContent}>
  167. <img
  168. style={{ width: '13px', marginRight: '10px' }}
  169. src={'/assets/images/duty-message.png'}
  170. alt=""
  171. />
  172. 输入参数
  173. </div>
  174. {stagingItem.in_parameters &&
  175. Object.keys(stagingItem.in_parameters) &&
  176. Object.keys(stagingItem.in_parameters).length > 0
  177. ? Object.keys(stagingItem.in_parameters).map((item) => (
  178. <Form.Item
  179. label={stagingItem.in_parameters[item].label + '(' + item + ')'}
  180. name={item}
  181. disabled
  182. rules={[{ required: stagingItem.in_parameters[item].require ? true : false }]}
  183. >
  184. <Input disabled />
  185. </Form.Item>
  186. ))
  187. : ''}
  188. <div className={Styles.editPipelinePropsContent}>
  189. <img
  190. style={{ width: '13px', marginRight: '10px' }}
  191. src={'/assets/images/duty-message.png'}
  192. alt=""
  193. />
  194. 输出参数
  195. </div>
  196. {stagingItem.out_parameters &&
  197. Object.keys(stagingItem.out_parameters) &&
  198. Object.keys(stagingItem.out_parameters).length > 0
  199. ? Object.keys(stagingItem.out_parameters).map((item) => (
  200. <Form.Item
  201. label={stagingItem.out_parameters[item].label + '(' + item + ')'}
  202. disabled
  203. rules={[{ required: stagingItem.out_parameters[item].require ? true : false }]}
  204. name={item}
  205. >
  206. <Input disabled />
  207. </Form.Item>
  208. ))
  209. : ''}
  210. </Form>
  211. ),
  212. },
  213. {
  214. key: '3',
  215. label: '输出结果',
  216. children: (
  217. <div
  218. style={{
  219. minHeight: '740px',
  220. background: '#f4f4f4',
  221. color: '#000',
  222. fontSize: '14px',
  223. padding: '0 10px 20px 20px',
  224. }}
  225. >
  226. {resultObj && resultObj.length > 0
  227. ? resultObj.map((item) => (
  228. <div>
  229. <div className={Styles.resultTop}>
  230. <span>{item.name}</span>
  231. <div style={{ display: 'flex' }}>
  232. <a
  233. onClick={(e) => {
  234. exportResult(e, item.path);
  235. }}
  236. style={{ marginRight: '10px' }}
  237. >
  238. 下载
  239. </a>
  240. <a style={{ marginRight: '10px' }}>导出到模型库</a>
  241. <a style={{ marginRight: '10px' }}>导出到数据集</a>
  242. </div>
  243. </div>
  244. <div style={{ margin: '15px 0' }} className={Styles.resultContent}>
  245. <span>文件名称</span>
  246. <span>文件大小</span>
  247. </div>
  248. {item.value && item.value.length > 0
  249. ? item.value.map((ele) => (
  250. <div className={Styles.resultContent}>
  251. <span>{ele.name}</span>
  252. <span>{ele.size}</span>
  253. </div>
  254. ))
  255. : null}
  256. </div>
  257. ))
  258. : null}
  259. </div>
  260. ),
  261. icon: <ProfileOutlined />,
  262. },
  263. ];
  264. const [open, setOpen] = useState(false);
  265. const afterOpenChange = () => {
  266. if (!open) {
  267. console.log(111, open);
  268. console.log(stagingItem, form.getFieldsValue());
  269. for (let i in form.getFieldsValue()) {
  270. for (let j in stagingItem.in_parameters) {
  271. if (i == j) {
  272. console.log(j, i);
  273. stagingItem.in_parameters[j].value = form.getFieldsValue()[i];
  274. }
  275. }
  276. for (let p in stagingItem.out_parameters) {
  277. if (i == p) {
  278. stagingItem.out_parameters[p].value = form.getFieldsValue()[i];
  279. }
  280. }
  281. for (let k in stagingItem.control_strategy) {
  282. if (i == k) {
  283. stagingItem.control_strategy[k].value = form.getFieldsValue()[i];
  284. }
  285. }
  286. }
  287. // setStagingItem({...stagingItem,})
  288. console.log(stagingItem.control_strategy);
  289. onParentChange({
  290. ...stagingItem,
  291. control_strategy: JSON.stringify(stagingItem.control_strategy),
  292. in_parameters: JSON.stringify(stagingItem.in_parameters),
  293. out_parameters: JSON.stringify(stagingItem.out_parameters),
  294. ...form.getFieldsValue(),
  295. });
  296. // onParentChange({...stagingItem,...form.getFieldsValue()})
  297. }
  298. };
  299. const onClose = () => {
  300. setOpen(false);
  301. };
  302. const onFinish = (values) => {
  303. console.log('Success:', values);
  304. };
  305. const onFinishFailed = (errorInfo) => {
  306. console.log('Failed:', errorInfo);
  307. };
  308. useImperativeHandle(ref, () => ({
  309. showDrawer(e, id, message) {
  310. setLogList([]);
  311. if (e.item && e.item.getModel().component_id) {
  312. const model = e.item.getModel() || {};
  313. const start_time = moment(model.experimentStartTime).valueOf() * 1.0e6;
  314. const params = {
  315. task_id: model.id,
  316. component_id: model.component_id,
  317. name: message.argo_ins_name,
  318. namespace: message.argo_ins_ns,
  319. start_time: start_time,
  320. };
  321. getQueryByExperimentLog(params).then((ret) => {
  322. const { log_type, pods, log_detail } = ret.data;
  323. if (log_type === 'normal') {
  324. const list = [
  325. {
  326. ...log_detail,
  327. log_type,
  328. },
  329. ];
  330. setLogList(list);
  331. } else if (log_type === 'resource') {
  332. const list = pods.map((v) => ({
  333. log_type,
  334. pod_name: v,
  335. log_content: '',
  336. start_time,
  337. }));
  338. setLogList(list);
  339. }
  340. getNodeResult({ id, node_id: e.item.getModel().id }).then((res) => {
  341. setResultObj(res.data);
  342. form.resetFields();
  343. form.setFieldsValue({
  344. ...e.item.getModel(),
  345. in_parameters: JSON.parse(e.item.getModel().in_parameters),
  346. out_parameters: JSON.parse(e.item.getModel().out_parameters),
  347. control_strategy: JSON.parse(e.item.getModel().control_strategy),
  348. });
  349. setStagingItem({
  350. ...e.item.getModel(),
  351. in_parameters: JSON.parse(e.item.getModel().in_parameters),
  352. out_parameters: JSON.parse(e.item.getModel().out_parameters),
  353. control_strategy: JSON.parse(e.item.getModel().control_strategy),
  354. });
  355. setOpen(true);
  356. });
  357. });
  358. } else {
  359. form.resetFields();
  360. form.setFieldsValue({
  361. ...e.item.getModel(),
  362. in_parameters: JSON.parse(e.item.getModel().in_parameters),
  363. out_parameters: JSON.parse(e.item.getModel().out_parameters),
  364. control_strategy: JSON.parse(e.item.getModel().control_strategy),
  365. });
  366. setStagingItem({
  367. ...e.item.getModel(),
  368. in_parameters: JSON.parse(e.item.getModel().in_parameters),
  369. out_parameters: JSON.parse(e.item.getModel().out_parameters),
  370. control_strategy: JSON.parse(e.item.getModel().control_strategy),
  371. });
  372. setOpen(true);
  373. }
  374. // console.log(e.item.getModel().in_parameters);
  375. },
  376. }));
  377. return (
  378. <>
  379. <Drawer
  380. title="任务执行详情"
  381. placement="right"
  382. closeIcon={false}
  383. onClose={onClose}
  384. afterOpenChange={afterOpenChange}
  385. open={open}
  386. width={600}
  387. destroyOnClose={true}
  388. >
  389. <div className={Styles.detailBox}>任务名称:{stagingItem.label}</div>
  390. <div className={Styles.detailBox}>
  391. 执行状态:
  392. <div
  393. style={{
  394. width: '8px',
  395. height: '8px',
  396. borderRadius: '50%',
  397. marginRight: '6px',
  398. backgroundColor: statusColorObj[stagingItem.experimentStatus],
  399. }}
  400. ></div>
  401. <span style={{ color: statusColorObj[stagingItem.experimentStatus] }}>
  402. {statusObj[stagingItem.experimentStatus]}
  403. </span>
  404. </div>
  405. <div className={Styles.detailBox}>
  406. 启动时间:{moment(stagingItem.experimentStartTime).format('YYYY-MM-DD HH:mm:ss')}
  407. </div>
  408. <div className={Styles.detailBox}>
  409. 耗时:
  410. {stagingItem.experimentEndTime
  411. ? elapsedTime(
  412. new Date(stagingItem.experimentStartTime),
  413. new Date(stagingItem.experimentEndTime),
  414. )
  415. : elapsedTime(new Date(stagingItem.experimentStartTime), new Date())}
  416. </div>
  417. <Tabs defaultActiveKey="1" items={items} />
  418. </Drawer>
  419. </>
  420. );
  421. });
  422. export default Props;