| @@ -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; | |||||
| } | |||||
| } | |||||
| @@ -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; | |||||
| @@ -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 /> | ||||
| @@ -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> | ||||
| ); | ); | ||||
| @@ -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: { | ||||
| @@ -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> | ||||
| @@ -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; | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| @@ -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') | |||||
| ); | |||||
| } | |||||
| @@ -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' | ||||
| @@ -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); | ||||
| } | } | ||||