|
- import KFIcon from '@/components/KFIcon';
- import { ExperimentStatus } from '@/enums';
- import { useCheck } from '@/hooks';
- import { experimentStatusInfo } from '@/pages/Experiment/status';
- import themes from '@/styles/theme.less';
- import { type ExperimentInstance } from '@/types';
- import { elapsedTime, formatDate } from '@/utils/date';
- import { to } from '@/utils/promise';
- import { modalConfirm } from '@/utils/ui';
- import { DoubleRightOutlined } from '@ant-design/icons';
- import { App, Button, Checkbox, ConfigProvider, Typography } from 'antd';
- import classNames from 'classnames';
- import { useEffect, useMemo } from 'react';
- import { ExperimentListType, experimentListConfig } from '../ExperimentList/config';
- import styles from './index.less';
-
- type ExperimentInstanceProps = {
- type: ExperimentListType;
- experimentInsList?: ExperimentInstance[];
- experimentInsTotal: number;
- onClickInstance?: (instance: ExperimentInstance) => void;
- onRemove?: () => void;
- onTerminate?: (instance: ExperimentInstance) => void;
- onLoadMore?: () => void;
- };
-
- function ExperimentInstanceComponent({
- type,
- experimentInsList,
- experimentInsTotal,
- onClickInstance,
- onRemove,
- onTerminate,
- onLoadMore,
- }: ExperimentInstanceProps) {
- const { message } = App.useApp();
- const allIntanceIds = useMemo(() => {
- return experimentInsList?.map((item) => item.id) || [];
- }, [experimentInsList]);
- const [
- selectedIns,
- setSelectedIns,
- checked,
- indeterminate,
- checkAll,
- isSingleChecked,
- checkSingle,
- ] = useCheck(allIntanceIds);
- const config = experimentListConfig[type];
-
- useEffect(() => {
- // 关闭时清空
- if (allIntanceIds.length === 0) {
- setSelectedIns([]);
- }
- }, [allIntanceIds, setSelectedIns]);
-
- // 删除实验实例确认
- const handleRemove = (instance: ExperimentInstance) => {
- modalConfirm({
- title: '确定删除该条实例吗?',
- onOk: () => {
- deleteExperimentInstance(instance.id);
- },
- });
- };
-
- // 删除实验实例
- const deleteExperimentInstance = async (id: number) => {
- const request = config.deleteInsReq;
- const [res] = await to(request(id));
- if (res) {
- message.success('删除成功');
- onRemove?.();
- }
- };
-
- // 批量删除实验实例确认
- const handleDeleteAll = () => {
- modalConfirm({
- title: '确定批量删除选中的实例吗?',
- onOk: () => {
- batchDeleteExperimentInstances();
- },
- });
- };
-
- // 批量删除实验实例
- const batchDeleteExperimentInstances = async () => {
- const request = config.batchDeleteInsReq;
- const [res] = await to(request(selectedIns));
- if (res) {
- message.success('删除成功');
- setSelectedIns([]);
- onRemove?.();
- }
- };
-
- // 终止实验实例
- const terminateExperimentInstance = async (instance: ExperimentInstance) => {
- const request = config.stopInsReq;
- const [res] = await to(request(instance.id));
- if (res) {
- message.success('终止成功');
- onTerminate?.(instance);
- }
- };
-
- if (!experimentInsList || experimentInsList.length === 0) {
- return <div style={{ textAlign: 'center' }}>暂无数据</div>;
- }
-
- return (
- <div>
- <div className={styles.tableExpandBox} style={{ paddingBottom: '16px' }}>
- <div className={styles.check}>
- <Checkbox checked={checked} indeterminate={indeterminate} onChange={checkAll}></Checkbox>
- </div>
- <div className={styles.index}>序号</div>
- <div className={styles.description}>运行时长</div>
- <div className={styles.startTime}>开始时间</div>
- <div className={styles.status}>状态</div>
- <div className={styles.operation}>
- <span>操作</span>
- {selectedIns.length > 0 && (
- <Button
- style={{ position: 'absolute', right: '0' }}
- color="primary"
- variant="filled"
- size="small"
- onClick={handleDeleteAll}
- icon={<KFIcon type="icon-shanchu" />}
- >
- 删除
- </Button>
- )}
- </div>
- </div>
-
- {experimentInsList.map((item, index) => (
- <div
- key={item.id}
- className={classNames(styles.tableExpandBox, styles.tableExpandBoxContent)}
- >
- <div className={styles.check}>
- <Checkbox
- checked={isSingleChecked(item.id)}
- onChange={() => checkSingle(item.id)}
- ></Checkbox>
- </div>
- <a
- className={styles.index}
- style={{ padding: '0 16px' }}
- onClick={() => onClickInstance?.(item)}
- >
- {index + 1}
- </a>
- <div className={styles.description}>
- {elapsedTime(item.create_time, item.finish_time)}
- </div>
- <div className={styles.startTime}>
- <Typography.Text ellipsis={{ tooltip: formatDate(item.create_time) }}>
- {formatDate(item.create_time)}
- </Typography.Text>
- </div>
- <div className={styles.statusBox}>
- <img
- style={{ width: '17px', marginRight: '7px' }}
- src={experimentStatusInfo[item.status as ExperimentStatus]?.icon}
- draggable={false}
- alt=""
- />
- <span
- style={{ color: experimentStatusInfo[item.status as ExperimentStatus]?.color }}
- className={styles.statusIcon}
- >
- {experimentStatusInfo[item.status as ExperimentStatus]?.label}
- </span>
- </div>
- <div className={styles.operation}>
- <Button
- type="link"
- size="small"
- key="stop"
- disabled={
- item.status === ExperimentStatus.Succeeded ||
- item.status === ExperimentStatus.Failed ||
- item.status === ExperimentStatus.Terminated
- }
- icon={<KFIcon type="icon-zhongzhi" />}
- onClick={() => terminateExperimentInstance(item)}
- >
- 终止
- </Button>
- <ConfigProvider
- theme={{
- token: {
- colorLink: themes['warningColor'],
- },
- }}
- >
- <Button
- type="link"
- size="small"
- key="batchRemove"
- disabled={
- item.status === ExperimentStatus.Running ||
- item.status === ExperimentStatus.Pending
- }
- icon={<KFIcon type="icon-shanchu" />}
- onClick={() => handleRemove(item)}
- >
- 删除
- </Button>
- </ConfigProvider>
- </div>
- </div>
- ))}
- {experimentInsTotal > experimentInsList.length ? (
- <div className={styles.loadMoreBox}>
- <Button type="link" onClick={onLoadMore}>
- 更多
- <DoubleRightOutlined rotate={90} />
- </Button>
- </div>
- ) : null}
- </div>
- );
- }
-
- export default ExperimentInstanceComponent;
|