|
- import KFIcon from '@/components/KFIcon';
- import ParameterInput from '@/components/ParameterInput';
- import SubAreaTitle from '@/components/SubAreaTitle';
- import { getComputingResourceReq } from '@/services/pipeline';
- import { openAntdModal } from '@/utils/modal';
- import { to } from '@/utils/promise';
- import { Button, Drawer, Form, Input, Select } from 'antd';
- import { pick } from 'lodash';
- import { forwardRef, useEffect, useImperativeHandle, useState } from 'react';
- import PropsLabel from '../components/PropsLabel';
- import ResourceSelectorModal, { ResourceSelectorType } from '../components/ResourceSelectorModal';
- import styles from './props.less';
- import { canInput, createMenuItems } from './utils';
- const { TextArea } = Input;
-
- const Props = forwardRef(({ onParentChange }, ref) => {
- const [form] = Form.useForm();
- const [stagingItem, setStagingItem] = useState({});
- const [open, setOpen] = useState(false);
- const [selectedModel, setSelectedModel] = useState(undefined); // 选择的模型,为了再次打开时恢复原来的选择
- const [selectedDataset, setSelectedDataset] = useState(undefined); // 选择的数据集,为了再次打开时恢复原来的选择
- const [resourceStandardList, setResourceStandardList] = useState([]); // 资源规模列表
- const [menuItems, setMenuItems] = useState([]);
-
- useEffect(() => {
- getComputingResource();
- }, []);
-
- // 获取资源规格列表数据
- const getComputingResource = async () => {
- const params = {
- page: 0,
- size: 1000,
- resource_type: '',
- };
- const [res] = await to(getComputingResourceReq(params));
- if (res && res.data && res.data.content) {
- setResourceStandardList(res.data.content);
- }
- };
-
- const afterOpenChange = () => {
- if (!open) {
- console.log('zzzzz', form.getFieldsValue());
- const control_strategy = form.getFieldValue('control_strategy');
- const in_parameters = form.getFieldValue('in_parameters');
- const out_parameters = form.getFieldValue('out_parameters');
- onParentChange({
- ...stagingItem,
- ...form.getFieldsValue(),
- control_strategy: JSON.stringify(control_strategy),
- in_parameters: JSON.stringify(in_parameters),
- out_parameters: JSON.stringify(out_parameters),
- });
- }
- };
- const onClose = () => {
- setOpen(false);
- };
- useImperativeHandle(ref, () => ({
- getFieldsValue: async () => {
- const [propsRes, propsError] = await to(form.validateFields());
- if (propsRes && !propsError) {
- const values = form.getFieldsValue();
- return values;
- } else {
- return Promise.reject(propsError);
- }
- },
- showDrawer(e, params, parentNodes) {
- if (e.item && e.item.getModel()) {
- form.resetFields();
- const model = e.item.getModel();
- try {
- const nodeData = {
- ...model,
- in_parameters: JSON.parse(model.in_parameters),
- out_parameters: JSON.parse(model.out_parameters),
- control_strategy: JSON.parse(model.control_strategy),
- };
- console.log('model', nodeData);
- setStagingItem({
- ...nodeData,
- });
- form.setFieldsValue({
- ...nodeData,
- });
- } catch (error) {
- console.log(error);
- }
- setSelectedModel(undefined);
- setSelectedDataset(undefined);
- setOpen(true);
-
- // 参数下拉菜单
- setMenuItems(createMenuItems(params, parentNodes));
- }
- },
- propClose: () => {
- onClose();
- },
- }));
-
- // 选择数据集、模型、镜像
- const selectResource = (name, item) => {
- let type;
- let resource;
- switch (item.item_type) {
- case 'dataset':
- type = ResourceSelectorType.Dataset;
- resource = selectedDataset;
- break;
- case 'model':
- type = ResourceSelectorType.Model;
- resource = selectedModel;
- break;
- default:
- type = ResourceSelectorType.Mirror;
- break;
- }
- const { close } = openAntdModal(ResourceSelectorModal, {
- type,
- defaultExpandedKeys: resource ? [resource.id] : [],
- defaultCheckedKeys: resource ? [`${resource.id}-${resource.version}`] : [],
- defaultActiveTab: resource?.activeTab,
- onOk: (res) => {
- if (res) {
- if (type === ResourceSelectorType.Mirror) {
- form.setFieldValue(name, res);
- } else {
- const jsonObj = pick(res, ['id', 'version', 'path']);
- const value = JSON.stringify(jsonObj);
- const showValue = `${res.name}:${res.version}`;
- form.setFieldValue(name, { ...item, value, showValue, fromSelect: true });
-
- if (type === ResourceSelectorType.Dataset) {
- setSelectedDataset(res);
- } else if (type === ResourceSelectorType.Model) {
- setSelectedModel(res);
- }
- }
- } else {
- if (type === ResourceSelectorType.Dataset) {
- setSelectedDataset(undefined);
- } else if (type === ResourceSelectorType.Model) {
- setSelectedModel(undefined);
- }
- form.setFieldValue(name, '');
- }
- close();
- },
- });
- };
-
- // 获取选择数据集、模型后面按钮 icon
- const getSelectBtnIcon = (item) => {
- const type = item.item_type;
- if (type === 'dataset') {
- return <KFIcon type="icon-xuanzeshujuji" />;
- } else if (type === 'model') {
- return <KFIcon type="icon-xuanzemoxing" />;
- } else {
- return <KFIcon type="icon-xuanzejingxiang" />;
- }
- };
-
- // 筛选资源规格
- const filterResourceStandard = (input, { computing_resource = '' }) => {
- return computing_resource.toLocaleLowerCase().includes(input.toLocaleLowerCase());
- };
-
- // 参数回填
- const handleParameterClick = (name, value) => {
- form.setFieldValue(name, value);
- };
-
- // 控制策略
- const controlStrategyList = Object.entries(stagingItem.control_strategy ?? {}).map(
- ([key, value]) => ({ key, value }),
- );
-
- // 输入参数
- const inParametersList = Object.entries(stagingItem.in_parameters ?? {}).map(([key, value]) => ({
- key,
- value,
- }));
-
- // 输出参数
- const outParametersList = Object.entries(stagingItem.out_parameters ?? {}).map(
- ([key, value]) => ({ key, value }),
- );
-
- return (
- <Drawer
- title="编辑任务"
- placement="right"
- rootStyle={{ marginTop: '45px' }}
- getContainer={false}
- closeIcon={false}
- onClose={onClose}
- afterOpenChange={afterOpenChange}
- open={open}
- width={520}
- className={styles['pipeline-drawer']}
- >
- <Form
- name="form"
- form={form}
- layout="vertical"
- labelCol={{
- span: 24,
- }}
- wrapperCol={{
- span: 24,
- }}
- style={{
- maxWidth: 600,
- }}
- autoComplete="off"
- >
- <div className={styles['pipeline-drawer__title']}>
- <SubAreaTitle image="/assets/images/static-message.png" title="基本信息"></SubAreaTitle>
- </div>
- <Form.Item
- label="任务名称"
- name="label"
- rules={[
- {
- required: true,
- message: '请输入任务名称',
- },
- ]}
- >
- <Input placeholder="请输入任务名称" allowClear />
- </Form.Item>
- <Form.Item
- label="任务ID"
- name="id"
- rules={[
- {
- required: true,
- message: '请输入任务id',
- },
- ]}
- >
- <Input disabled />
- </Form.Item>
- <div className={styles['pipeline-drawer__title']}>
- <SubAreaTitle image="/assets/images/duty-message.png" title="任务信息"></SubAreaTitle>
- </div>
- <Form.Item label="镜像" required>
- <div className={styles['pipeline-drawer__ref-row']}>
- <Form.Item name="image" noStyle rules={[{ required: true, message: '请输入镜像' }]}>
- <Input placeholder="请输入或选择镜像" allowClear />
- </Form.Item>
- <Form.Item noStyle>
- <Button
- type="link"
- size="small"
- icon={getSelectBtnIcon({ item_type: 'image' })}
- onClick={() => selectResource('image', { item_type: 'image' })}
- className={styles['pipeline-drawer__ref-row__select-button']}
- >
- 选择镜像
- </Button>
- </Form.Item>
- </div>
- </Form.Item>
- <Form.Item
- name="working_directory"
- label={
- <PropsLabel
- menuItems={menuItems}
- title="工作目录"
- onClick={(value) => {
- handleParameterClick('working_directory', value);
- }}
- />
- }
- >
- <Input placeholder="请输入工作目录" allowClear />
- </Form.Item>
- <Form.Item
- name="command"
- label={
- <PropsLabel
- menuItems={menuItems}
- title="启动命令"
- onClick={(value) => {
- handleParameterClick('command', value);
- }}
- />
- }
- >
- <TextArea placeholder="请输入启动命令" allowClear />
- </Form.Item>
- <Form.Item
- label="资源规格"
- name="resources_standard"
- rules={[
- {
- required: true,
- message: '请选择资源规格',
- },
- ]}
- >
- <Select
- showSearch
- placeholder="请选择资源规格"
- filterOption={filterResourceStandard}
- options={resourceStandardList}
- fieldNames={{
- label: 'description',
- value: 'standard',
- }}
- />
- </Form.Item>
- <Form.Item
- name="mount_path"
- label={
- <PropsLabel
- menuItems={menuItems}
- title="挂载路径"
- onClick={(value) => {
- handleParameterClick('mount_path', value);
- }}
- />
- }
- >
- <Input placeholder="请输入挂载路径" allowClear />
- </Form.Item>
- <Form.Item
- name="env_variables"
- label={
- <PropsLabel
- menuItems={menuItems}
- title="环境变量"
- onClick={(value) => {
- handleParameterClick('env_variables', value);
- }}
- />
- }
- >
- <TextArea placeholder="请输入环境变量" allowClear />
- </Form.Item>
- {controlStrategyList.map((item) => (
- <Form.Item
- key={item.key}
- name={['control_strategy', item.key]}
- label={
- <PropsLabel
- menuItems={menuItems}
- title={item.value.label}
- onClick={(value) => {
- handleParameterClick(['control_strategy', item.key], {
- ...item.value,
- value,
- fromSelect: true,
- showValue: value,
- });
- }}
- />
- }
- // getValueProps={(e) => {
- // return { value: e.value };
- // }}
- // getValueFromEvent={(e) => {
- // return {
- // ...item.value,
- // value: e.target.value,
- // };
- // }}
- >
- <ParameterInput placeholder={item.value.placeholder} allowClear></ParameterInput>
- </Form.Item>
- ))}
- <div className={styles['pipeline-drawer__title']}>
- <SubAreaTitle image="/assets/images/duty-message.png" title="输入参数"></SubAreaTitle>
- </div>
- {inParametersList.map((item) => (
- <Form.Item
- key={item.key}
- label={
- <PropsLabel
- menuItems={menuItems}
- title={item.value.label + '(' + item.key + ')'}
- onClick={(value) => {
- handleParameterClick(['in_parameters', item.key], {
- ...item.value,
- value,
- fromSelect: true,
- showValue: value,
- });
- }}
- />
- }
- required={item.value.require ? true : false}
- >
- <div className={styles['pipeline-drawer__ref-row']}>
- <Form.Item
- name={['in_parameters', item.key]}
- noStyle
- rules={[{ required: item.value.require ? true : false }]}
- >
- <ParameterInput
- placeholder={item.value.placeholder}
- canInput={canInput(item.value)}
- allowClear
- ></ParameterInput>
- </Form.Item>
- {item.value.type === 'ref' && (
- <Form.Item noStyle>
- <Button
- size="small"
- type="link"
- icon={getSelectBtnIcon(item.value)}
- onClick={() => selectResource(['in_parameters', item.key], item.value)}
- className={styles['pipeline-drawer__ref-row__select-button']}
- >
- {item.value.label}
- </Button>
- </Form.Item>
- )}
- </div>
- </Form.Item>
- ))}
- <div className={styles['pipeline-drawer__title']}>
- <SubAreaTitle image="/assets/images/duty-message.png" title="输出参数"></SubAreaTitle>
- </div>
- {outParametersList.map((item) => (
- <Form.Item
- key={item.key}
- name={['out_parameters', item.key]}
- label={
- <PropsLabel
- menuItems={menuItems}
- title={item.value.label + '(' + item.key + ')'}
- onClick={(value) => {
- handleParameterClick(['out_parameters', item.key], {
- ...item.value,
- value,
- fromSelect: true,
- showValue: value,
- });
- }}
- />
- }
- rules={[{ required: item.value.require ? true : false }]}
- // getValueProps={(e) => {
- // return { value: e.value };
- // }}
- // getValueFromEvent={(e) => {
- // return {
- // ...item.value,
- // value: e.target.value,
- // };
- // }}
- >
- <ParameterInput placeholder={item.value.placeholder} allowClear></ParameterInput>
- </Form.Item>
- ))}
- </Form>
- </Drawer>
- );
- });
-
- export default Props;
|