Browse Source

feat: 修改流水线节点参数

pull/48/head
cp3hnu 1 year ago
parent
commit
445052caad
10 changed files with 213 additions and 60 deletions
  1. +43
    -0
      react-ui/src/components/ParameterInput/index.less
  2. +86
    -0
      react-ui/src/components/ParameterInput/index.tsx
  3. +3
    -3
      react-ui/src/pages/Experiment/components/ExperimentParameter/index.tsx
  4. +3
    -5
      react-ui/src/pages/Pipeline/components/PropsLabel/index.tsx
  5. +4
    -7
      react-ui/src/pages/Pipeline/editPipeline/index.jsx
  6. +38
    -34
      react-ui/src/pages/Pipeline/editPipeline/props.jsx
  7. +9
    -10
      react-ui/src/pages/Pipeline/editPipeline/props.less
  8. +18
    -1
      react-ui/src/pages/Pipeline/editPipeline/utils.tsx
  9. +7
    -0
      react-ui/src/types.ts
  10. +2
    -0
      react-ui/src/utils/index.ts

+ 43
- 0
react-ui/src/components/ParameterInput/index.less View File

@@ -0,0 +1,43 @@
.parameter-input {
flex: 1 1 auto;
min-width: 0;
height: 32px;
padding: 3px 11px;
border: 1px solid #d9d9d9;
border-radius: 6px;

&:hover {
border-color: @primary-color;
}

&__content {
display: flex;
align-items: center;
width: fit-content;
max-width: 100%;
height: 24px;
padding: 0 8px;
color: .addAlpha(@text-color, 0.8) [];
background-color: rgba(0, 0, 0, 0.06);
border-radius: 4px;

&__value {
.singleLine();
margin-right: 8px;
font-size: @font-size-input;
}

&__close-icon {
font-size: 10px;

&:hover {
color: #000;
}
}
}

&__placeholder {
color: rgba(0, 0, 0, 0.25);
font-size: @font-size-input;
}
}

+ 86
- 0
react-ui/src/components/ParameterInput/index.tsx View File

@@ -0,0 +1,86 @@
import { CloseOutlined } from '@ant-design/icons';
import { Input } from 'antd';
import styles from './index.less';

type ParameterInputData = {
value?: any;
showValue?: any;
fromSelect?: boolean;
} & Record<string, any>;

interface ParameterInputProps {
value?: ParameterInputData;
onChange?: (value: ParameterInputData) => void;
onClick?: () => void;
canInput?: boolean;
textArea?: boolean;
placeholder?: string;
allowClear?: boolean;
}

function ParameterInput({
value,
onChange,
onClick,
canInput = true,
textArea = false,
placeholder,
allowClear,
...rest
}: ParameterInputProps) {
// console.log('ParameterInput', value);

const valueObj =
typeof value === 'string' ? { value: value, fromSelect: false, showValue: value } : value;
if (valueObj && !valueObj.showValue) {
valueObj.showValue = valueObj.value;
}
const isSelect = valueObj?.fromSelect;
const InputComponent = textArea ? Input.TextArea : Input;

return (
<>
{isSelect || !canInput ? (
<div className={styles['parameter-input']} onClick={onClick}>
{valueObj?.showValue ? (
<div className={styles['parameter-input__content']}>
<span className={styles['parameter-input__content__value']}>
{valueObj?.showValue}
</span>
<CloseOutlined
className={styles['parameter-input__content__close-icon']}
onClick={() =>
onChange?.({
...valueObj,
fromSelect: false,
value: undefined,
showValue: undefined,
})
}
/>
</div>
) : (
<div className={styles['parameter-input__placeholder']}>{placeholder}</div>
)}
</div>
) : (
<InputComponent
{...rest}
placeholder={placeholder}
allowClear={allowClear}
value={valueObj?.showValue}
onChange={(e) =>
onChange?.({
...valueObj,
fromSelect: false,
value: e.target.value,
showValue: e.target.value,
})
}
/>
)}
</>
);
}

export default ParameterInput;

+ 3
- 3
react-ui/src/pages/Experiment/components/ExperimentParameter/index.tsx View File

@@ -146,7 +146,7 @@ function ExperimentParameter({ form, nodeData }: ExperimentParameterProps) {
name={['control_strategy', item.key]} name={['control_strategy', item.key]}
label={item.value.label} label={item.value.label}
getValueProps={(e) => { getValueProps={(e) => {
return { value: e.value };
return { value: e.showValue || e.value };
}} }}
> >
<Input disabled /> <Input disabled />
@@ -162,7 +162,7 @@ function ExperimentParameter({ form, nodeData }: ExperimentParameterProps) {
label={item.value.label + '(' + item.key + ')'} label={item.value.label + '(' + item.key + ')'}
rules={[{ required: item.value.require ? true : false }]} rules={[{ required: item.value.require ? true : false }]}
getValueProps={(e) => { getValueProps={(e) => {
return { value: e.value };
return { value: e.showValue || e.value };
}} }}
> >
<Input disabled /> <Input disabled />
@@ -178,7 +178,7 @@ function ExperimentParameter({ form, nodeData }: ExperimentParameterProps) {
label={item.value.label + '(' + item.key + ')'} label={item.value.label + '(' + item.key + ')'}
rules={[{ required: item.value.require ? true : false }]} rules={[{ required: item.value.require ? true : false }]}
getValueProps={(e) => { getValueProps={(e) => {
return { value: e.value };
return { value: e.showValue || e.value };
}} }}
> >
<Input disabled /> <Input disabled />


+ 3
- 5
react-ui/src/pages/Pipeline/components/PropsLabel/index.tsx View File

@@ -1,4 +1,4 @@
import { Button, Dropdown, type MenuProps } from 'antd';
import { Dropdown, type MenuProps } from 'antd';
import { useEffect } from 'react'; import { useEffect } from 'react';
import styles from './index.less'; import styles from './index.less';


@@ -22,7 +22,7 @@ function PropsLabel({ title, menuItems, onClick }: PropsLabelProps) {


return ( return (
<div className={styles['props-label']}> <div className={styles['props-label']}>
<span>{title}</span>
<div>{title}</div>
<Dropdown <Dropdown
menu={{ menu={{
items: menuItems, items: menuItems,
@@ -33,9 +33,7 @@ function PropsLabel({ title, menuItems, onClick }: PropsLabelProps) {
placement="topRight" placement="topRight"
arrow arrow
> >
<Button size="small" type="link">
参数
</Button>
<a onClick={(e) => e.preventDefault()}>参数</a>
</Dropdown> </Dropdown>
</div> </div>
); );


+ 4
- 7
react-ui/src/pages/Pipeline/editPipeline/index.jsx View File

@@ -28,7 +28,7 @@ const EditPipeline = () => {
let sourceAnchorIdx, targetAnchorIdx; let sourceAnchorIdx, targetAnchorIdx;


const onDragEnd = (val) => { const onDragEnd = (val) => {
console.log(val, 'eee');
console.log(val);
const _x = val.x; const _x = val.x;
const _y = val.y; const _y = val.y;
const point = graph.getPointByClient(_x, _y); const point = graph.getPointByClient(_x, _y);
@@ -41,10 +41,8 @@ const EditPipeline = () => {
id: val.component_name + '-' + s8(), id: val.component_name + '-' + s8(),
isCluster: false, isCluster: false,
}; };
console.log(graph, model);

console.log('model', model);
graph.addItem('node', model, true); graph.addItem('node', model, true);
console.log(graph);
}; };
const formChange = (val) => { const formChange = (val) => {
if (graph) { if (graph) {
@@ -73,7 +71,6 @@ const EditPipeline = () => {
} }


const [propsRes, propsError] = await to(propsRef.current.getFieldsValue()); const [propsRes, propsError] = await to(propsRef.current.getFieldsValue());
console.log(await to(propsRef.current.getFieldsValue()));
if (propsError) { if (propsError) {
message.error('基本信息必填项需配置'); message.error('基本信息必填项需配置');
return; return;
@@ -110,7 +107,6 @@ const EditPipeline = () => {
} }
}; };
const getGraphData = (data) => { const getGraphData = (data) => {
console.log('graph', graph);
if (graph) { if (graph) {
console.log(data); console.log(data);
graph.data(data); graph.data(data);
@@ -193,6 +189,7 @@ const EditPipeline = () => {
} }
} }


// eslint-disable-next-line
for (const key in edgeMap) { for (const key in edgeMap) {
const arcEdges = edgeMap[key]; const arcEdges = edgeMap[key];
const { length } = arcEdges; const { length } = arcEdges;
@@ -435,7 +432,7 @@ const EditPipeline = () => {
height: graphRef.current.clientHeight || '100%', height: graphRef.current.clientHeight || '100%',
animate: false, animate: false,
groupByTypes: false, groupByTypes: false,
fitView: true,
fitView: false,
plugins: [contextMenu], plugins: [contextMenu],
enabledStack: true, enabledStack: true,
modes: { modes: {


+ 38
- 34
react-ui/src/pages/Pipeline/editPipeline/props.jsx View File

@@ -1,4 +1,5 @@
import KFIcon from '@/components/KFIcon'; import KFIcon from '@/components/KFIcon';
import ParameterInput from '@/components/ParameterInput';
import SubAreaTitle from '@/components/SubAreaTitle'; import SubAreaTitle from '@/components/SubAreaTitle';
import { getComputingResourceReq } from '@/services/pipeline'; import { getComputingResourceReq } from '@/services/pipeline';
import { openAntdModal } from '@/utils/modal'; import { openAntdModal } from '@/utils/modal';
@@ -9,7 +10,7 @@ import { forwardRef, useEffect, useImperativeHandle, useState } from 'react';
import PropsLabel from '../components/PropsLabel'; import PropsLabel from '../components/PropsLabel';
import ResourceSelectorModal, { ResourceSelectorType } from '../components/ResourceSelectorModal'; import ResourceSelectorModal, { ResourceSelectorType } from '../components/ResourceSelectorModal';
import styles from './props.less'; import styles from './props.less';
import { createMenuItems } from './utils';
import { canInput, createMenuItems } from './utils';
const { TextArea } = Input; const { TextArea } = Input;


const Props = forwardRef(({ onParentChange }, ref) => { const Props = forwardRef(({ onParentChange }, ref) => {
@@ -40,7 +41,7 @@ const Props = forwardRef(({ onParentChange }, ref) => {


const afterOpenChange = () => { const afterOpenChange = () => {
if (!open) { if (!open) {
// console.log('zzzzz', form.getFieldsValue());
console.log('zzzzz', form.getFieldsValue());
const control_strategy = form.getFieldValue('control_strategy'); const control_strategy = form.getFieldValue('control_strategy');
const in_parameters = form.getFieldValue('in_parameters'); const in_parameters = form.getFieldValue('in_parameters');
const out_parameters = form.getFieldValue('out_parameters'); const out_parameters = form.getFieldValue('out_parameters');
@@ -77,6 +78,7 @@ const Props = forwardRef(({ onParentChange }, ref) => {
out_parameters: JSON.parse(model.out_parameters), out_parameters: JSON.parse(model.out_parameters),
control_strategy: JSON.parse(model.control_strategy), control_strategy: JSON.parse(model.control_strategy),
}; };
console.log('model', nodeData);
setStagingItem({ setStagingItem({
...nodeData, ...nodeData,
}); });
@@ -95,7 +97,7 @@ const Props = forwardRef(({ onParentChange }, ref) => {
} }
}, },
propClose: () => { propClose: () => {
close();
onClose();
}, },
})); }));


@@ -128,7 +130,8 @@ const Props = forwardRef(({ onParentChange }, ref) => {
} else { } else {
const jsonObj = pick(res, ['id', 'version', 'path']); const jsonObj = pick(res, ['id', 'version', 'path']);
const value = JSON.stringify(jsonObj); const value = JSON.stringify(jsonObj);
form.setFieldValue(name, { ...item, value });
const showValue = `${res.name}:${res.version}`;
form.setFieldValue(name, { ...item, value, showValue, fromSelect: true });
} }


if (type === ResourceSelectorType.Dataset) { if (type === ResourceSelectorType.Dataset) {
@@ -352,21 +355,23 @@ const Props = forwardRef(({ onParentChange }, ref) => {
handleParameterClick(['control_strategy', item.key], { handleParameterClick(['control_strategy', item.key], {
...item.value, ...item.value,
value, value,
fromSelect: true,
showValue: value,
}); });
}} }}
/> />
} }
getValueProps={(e) => {
return { value: e.value };
}}
getValueFromEvent={(e) => {
return {
...item.value,
value: e.target.value,
};
}}
// getValueProps={(e) => {
// return { value: e.value };
// }}
// getValueFromEvent={(e) => {
// return {
// ...item.value,
// value: e.target.value,
// };
// }}
> >
<Input placeholder={item.value.label} allowClear />
<ParameterInput placeholder={item.value.placeholder} allowClear></ParameterInput>
</Form.Item> </Form.Item>
))} ))}
<div className={styles['pipeline-drawer__title']}> <div className={styles['pipeline-drawer__title']}>
@@ -383,6 +388,8 @@ const Props = forwardRef(({ onParentChange }, ref) => {
handleParameterClick(['in_parameters', item.key], { handleParameterClick(['in_parameters', item.key], {
...item.value, ...item.value,
value, value,
fromSelect: true,
showValue: value,
}); });
}} }}
/> />
@@ -394,17 +401,12 @@ const Props = forwardRef(({ onParentChange }, ref) => {
name={['in_parameters', item.key]} name={['in_parameters', item.key]}
noStyle noStyle
rules={[{ required: item.value.require ? true : false }]} rules={[{ required: item.value.require ? true : false }]}
getValueProps={(e) => {
return { value: e.value };
}}
getValueFromEvent={(e) => {
return {
...item.value,
value: e.target.value,
};
}}
> >
<Input placeholder={item.value.label} allowClear />
<ParameterInput
placeholder={item.value.placeholder}
canInput={canInput(item.value)}
allowClear
></ParameterInput>
</Form.Item> </Form.Item>
{item.value.type === 'ref' && ( {item.value.type === 'ref' && (
<Form.Item noStyle> <Form.Item noStyle>
@@ -437,22 +439,24 @@ const Props = forwardRef(({ onParentChange }, ref) => {
handleParameterClick(['out_parameters', item.key], { handleParameterClick(['out_parameters', item.key], {
...item.value, ...item.value,
value, value,
fromSelect: true,
showValue: value,
}); });
}} }}
/> />
} }
rules={[{ required: item.value.require ? true : false }]} rules={[{ required: item.value.require ? true : false }]}
getValueProps={(e) => {
return { value: e.value };
}}
getValueFromEvent={(e) => {
return {
...item.value,
value: e.target.value,
};
}}
// getValueProps={(e) => {
// return { value: e.value };
// }}
// getValueFromEvent={(e) => {
// return {
// ...item.value,
// value: e.target.value,
// };
// }}
> >
<Input placeholder={item.value.label} allowClear />
<ParameterInput placeholder={item.value.placeholder} allowClear></ParameterInput>
</Form.Item> </Form.Item>
))} ))}
</Form> </Form>


+ 9
- 10
react-ui/src/pages/Pipeline/editPipeline/props.less View File

@@ -24,16 +24,15 @@
&__ref-row { &__ref-row {
display: flex; display: flex;
align-items: center; align-items: center;
}


&__select-button {
display: flex;
flex: none;
align-items: center;
justify-content: flex-start;
// width: 100px;
margin-left: 10px;
padding-right: 0;
padding-left: 0;
&__select-button {
display: flex;
flex: none;
align-items: center;
justify-content: flex-start;
margin-left: 10px;
padding-right: 0;
padding-left: 0;
}
} }
} }

+ 18
- 1
react-ui/src/pages/Pipeline/editPipeline/utils.tsx View File

@@ -1,4 +1,4 @@
import { PipelineGlobalParam } from '@/types';
import { PipelineGlobalParam, PipelineNodeModelParameter } from '@/types';
import { parseJsonText } from '@/utils'; import { parseJsonText } from '@/utils';
import { Graph, INode } from '@antv/g6'; import { Graph, INode } from '@antv/g6';
import { type MenuProps } from 'antd'; import { type MenuProps } from 'antd';
@@ -67,3 +67,20 @@ export function createMenuItems(
...nodes, ...nodes,
]; ];
} }

export function getInParameterComponent(
parameter: PipelineNodeModelParameter,
): React.ReactNode | null {
if (parameter.value) {
}

return null;
}

export function canInput(parameter: PipelineNodeModelParameter) {
const { type, item_type } = parameter;
return !(
type === 'ref' &&
(item_type === 'dataset' || item_type === 'model' || item_type === 'image')
);
}

+ 7
- 0
react-ui/src/types.ts View File

@@ -49,10 +49,17 @@ export type PipelineNodeModelParameter = {
value: any; value: any;
require: number; require: number;
type: string; type: string;
item_type: string;
placeholder?: string; placeholder?: string;
describe?: string; describe?: string;
fromSelect?: boolean;
showValue?: any;
editable: number;
}; };


// type ChangePropertyType<T, K extends keyof T, NewType> = Omit<T, K> & { [P in K]: NewType }

// 序列化后的流水线节点
export type PipelineNodeModelSerialize = Omit< export type PipelineNodeModelSerialize = Omit<
PipelineNodeModel, PipelineNodeModel,
'control_strategy' | 'in_parameters' | 'out_parameters' 'control_strategy' | 'in_parameters' | 'out_parameters'


+ 2
- 0
react-ui/src/utils/index.ts View File

@@ -3,6 +3,8 @@
* @Date: 2024-03-25 13:52:54 * @Date: 2024-03-25 13:52:54
* @Description: 工具类 * @Description: 工具类
*/ */

// 生成 8 位随机数
export function s8() { export function s8() {
return (((1 + Math.random()) * 0x100000000) | 0).toString(16).substring(1); return (((1 + Math.random()) * 0x100000000) | 0).toString(16).substring(1);
} }


Loading…
Cancel
Save