Commit f300b769 authored by 吴永生#A02208's avatar 吴永生#A02208

Merge branch 'feat-20220620-taskSubmission' of…

Merge branch 'feat-20220620-taskSubmission' of http://120.77.149.83/sunyihao/bkunyun into feat-20220620-taskSubmission
parents 80ed28f7 57da0e88
<?xml version="1.0" encoding="UTF-8"?>
<svg width="16px" height="16px" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>编组 26备份 2</title>
<defs>
<filter color-interpolation-filters="auto" id="filter-1">
<feColorMatrix in="SourceGraphic" type="matrix" values="0 0 0 0 0.540000 0 0 0 0 0.564000 0 0 0 0 0.600000 0 0 0 1.000000 0"></feColorMatrix>
</filter>
<filter color-interpolation-filters="auto" id="filter-2">
<feColorMatrix in="SourceGraphic" type="matrix" values="0 0 0 0 0.540000 0 0 0 0 0.564000 0 0 0 0 0.600000 0 0 0 1.000000 0"></feColorMatrix>
</filter>
</defs>
<g id="上线UI" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g filter="url(#filter-1)" id="编组-26备份-2">
<g>
<g id="编组-24备份">
<rect id="矩形" x="0" y="0" width="16" height="16"></rect>
<g filter="url(#filter-2)" id="提示图标">
<g>
<circle id="椭圆形" stroke="#979797" stroke-width="1.5" cx="8" cy="8" r="7.25"></circle>
</g>
</g>
</g>
<g id="编组" transform="translate(5.000000, 3.500000)" fill="#8A9099" fill-rule="nonzero">
<path d="M2.30709006,9 L3.69095124,9 L3.69095124,7.65034906 L2.30709006,7.65034906 L2.30709006,9 Z M4.42953435,4.770966 C3.73711269,5.22116893 3.41447366,5.76045459 3.41447364,6.3457184 L3.41447364,6.75042212 L2.30659899,6.75042212 L2.30659899,6.25567783 C2.26043754,5.44579147 2.67589055,4.7259457 3.41398257,4.18570217 C4.24390642,3.60139623 4.65935941,3.0161324 4.56703652,2.47588887 C4.47471362,1.66648145 4.01359027,1.21627851 3.13701391,1.17125823 C2.12195322,1.12623793 1.47618407,1.71150176 1.24586792,2.92609181 L0,2.61094976 C0.369291561,0.811574815 1.52234551,-0.0433318336 3.36782113,0.0016884633 C4.98248953,0.0917290571 5.81290444,0.856595112 5.99705913,2.34130693 C6.04371164,3.24123387 5.53593576,4.05112022 4.42904326,4.770966 L4.42953435,4.770966 Z" id="形状"></path>
</g>
</g>
</g>
</g>
</svg>
\ No newline at end of file
import * as React from "react";
import FormGroup from "@mui/material/FormGroup";
import FormControlLabel from "@mui/material/FormControlLabel";
import Checkbox from "@mui/material/Checkbox";
import _ from "lodash";
type IMyCheckBoxProps = {
value: Array<any>;
options: Array<ICheckBoxOption>;
onChange: any; // 直接返回选中项的数组
};
type ICheckBoxOption = {
value: any;
label?: string;
disabled?: boolean;
};
export const optionsTransform = (
arr: Array<any>,
labelKey: string = "label",
valueKey: string = "value",
disabledKey: string = "disabled"
): Array<ICheckBoxOption> => {
return arr.map((item: any) => {
return {
value: item[valueKey],
label: item[labelKey],
disabled: item[disabledKey] || false,
};
});
};
export default function MyCheckBox(props: IMyCheckBoxProps) {
const { value, options, onChange } = props;
const getCheckedStatus = (
checkBoxItemValue: any,
valueArr: Array<any>
): boolean => {
const result = valueArr.indexOf(checkBoxItemValue);
return result === -1 ? false : true;
};
const handleMyCheckBoxOnChange = (e: any) => {
const resultArr = _.cloneDeep(value);
const clickValue = e.target.name;
const clickValueIndex = value.indexOf(clickValue);
if (clickValueIndex === -1) {
resultArr.push(clickValue);
onChange && onChange(resultArr);
} else {
resultArr.splice(clickValueIndex, 1);
onChange && onChange(resultArr);
}
};
return (
<FormGroup row>
{options.map((option) => {
return (
<FormControlLabel
key={option.value}
control={
<Checkbox
checked={getCheckedStatus(option.value, value)}
value={option.value}
/>
}
label={option.label}
name={option.value}
onChange={handleMyCheckBoxOnChange}
/>
);
})}
</FormGroup>
);
}
import * as React from "react";
import Radio from "@mui/material/Radio";
import RadioGroup from "@mui/material/RadioGroup";
import FormControlLabel from "@mui/material/FormControlLabel";
type IMyRadioProps = {
value: any;
options: Array<ICheckBoxOption>;
onChange: any;
};
type ICheckBoxOption = {
value: any;
label?: string;
disabled?: boolean;
};
// 如果后端给的options不是 value-label的字段可以用下面的方法转换
export const optionsTransform = (
arr: Array<any>,
labelKey: string = "label",
valueKey: string = "value",
disabledKey: string = "disabled"
): Array<ICheckBoxOption> => {
return arr.map((item: any) => {
return {
value: item[valueKey],
label: item[labelKey],
disabled: item[disabledKey] || false,
};
});
};
export default function MyRadio(props: IMyRadioProps) {
const { value, options, onChange } = props;
return (
<RadioGroup
row
aria-labelledby="demo-row-radio-buttons-group-label"
name="row-radio-buttons-group"
value={value}
onChange={onChange}
>
{options.map((option) => {
return (
<FormControlLabel
key={option.value}
value={option.value}
control={<Radio />}
label={option.label}
/>
);
})}
</RadioGroup>
);
}
......@@ -18,6 +18,22 @@ export interface IOption {
value: string;
disabled?: boolean;
}
export const optionsTransform = (
arr: Array<any>,
labelKey: string = "label",
valueKey: string = "value",
disabledKey: string = "disabled"
): Array<IOption> => {
return arr.map((item: any) => {
return {
label: item[labelKey],
value: item[valueKey],
disabled: item[disabledKey],
};
});
};
interface IProps
extends Omit<SelectProps, "value" | "options" | "onChange" | "title"> {
value?: IOption;
......
......@@ -55,3 +55,27 @@
color: red;
margin-left: 3px;
}
.taskConfigBox {
padding: 24px 44px 40px 44px;
}
.parameter {
margin-bottom: 20px;
position: relative;
}
.parameterTitle {
color: rgba(30, 38, 51, 1);
font-size: 14px;
font-weight: 600;
line-height: 22px;
margin-bottom: 12px;
}
.parameterDataType {
color: rgba(138, 144, 153, 1);
margin-left: 16px;
}
.parameterDesc {
position: absolute;
bottom: 12px;
right: -22px;
}
import { ITemplateConfig } from "../interface";
import { ITemplateConfig, IRenderTasks, IRenderTask } from "../interface";
import styles from "./index.module.css";
import MyInput from "@/components/mui/MyInput";
import Tooltip from "@mui/material/Tooltip";
import classnames from "classnames";
import { useState } from "react";
import { useState, useMemo } from "react";
import FileSelect from "@/components/FileSelect";
import moment from "moment";
import MySelect, { optionsTransform } from "../components/MySelect";
import MyCheckBox from "@/components/mui/MyCheckBox";
import MyRadio from "@/components/mui/MyRadio";
import _ from "lodash";
import fileSelectIcon from "@/assets/project/fileSelect.svg";
import questionMark from "@/assets/project/questionMark.svg";
type ConfigFormProps = {
templateConfigInfo: ITemplateConfig;
setParameter: any;
};
const ConfigForm = (props: ConfigFormProps) => {
const { templateConfigInfo } = props;
const { templateConfigInfo, setParameter } = props;
const [name, setName] = useState<string>(
`${templateConfigInfo.title}_${moment(new Date()).format(
"YYYY_MM_DD_HH_mm"
......@@ -38,6 +45,82 @@ const ConfigForm = (props: ConfigFormProps) => {
setName(e.target.value);
};
const renderTasks: IRenderTasks = useMemo(() => {
const result: IRenderTasks = [];
templateConfigInfo.tasks.forEach((task, taskIndex) => {
if (task.type === "batch") {
result.push({ ...task, flows: [] });
} else {
result[result.length - 1].flows.push({ ...task });
}
});
return result;
}, [templateConfigInfo]);
console.log(renderTasks);
// const options = [
// {
// key: "1aaaaa",
// value: "a",
// },
// {
// key: "bbbbbb",
// value: "b",
// },
// {
// key: "cccccc",
// value: "c",
// },
// {
// key: "dddddd",
// value: "d",
// },
// {
// key: "bbbbbb",
// value: "e",
// },
// {
// key: "cccccc",
// value: "f",
// },
// {
// key: "dddddd",
// value: "g",
// },
// ];
// path : [a, b]
// const [selectValue, setSelectValue] = useState("b");
// const [selectValue, setSelectValue] = useState<Array<any>>([]);
// const handleSelectChange = (e: any) => {
// console.log(e);
// setSelectValue(e.target.value);
// };
// const handleCheckBoxChange = (e: any) => {
// setSelectValue(e);
// };
// const handleRadioChange = (e: any) => {
// console.log(e);
// setSelectValue(e.target.value);
// };
// const renderFormItem = (domtype) => {
// }
const handleParameterChange = (
e: any,
taskId: string,
parameterName: string
) => {
console.log(e, taskId, parameterName);
setParameter(e.target.value, taskId, parameterName);
};
return (
<div className={styles.formBox}>
<div className={styles.templateDescBox}>
......@@ -99,11 +182,84 @@ const ConfigForm = (props: ConfigFormProps) => {
</div>
</div>
</div>
<FileSelect
{renderTasks.map((task, taskIndex) => {
return (
<div className={styles.taskBox} key={task.id + taskIndex}>
<div
className={classnames({
[styles.backgroundTitle]: true,
[styles.backgroundTitlePass]: true,
})}
>
{/* <img src="" alt="" /> */}
<span>下面的子项校验是否通过</span>
<span className={styles.backgroundTitleText}>{task.title}</span>
</div>
<div className={styles.taskConfigBox}>
{task.parameters.map((parameter, parameterIndex) => {
return (
<div
className={styles.parameter}
key={parameter.id || "" + parameterIndex}
>
<div className={styles.parameterTitle}>
{parameter.name}
<span className={styles.parameterDataType}>
{parameter.dataType}
</span>
</div>
{parameter.domType.toLowerCase() === "input" && (
<MyInput
value={parameter.value}
onChange={(e: any) =>
handleParameterChange(
e,
task.id,
parameter.name || ""
)
}
placeholder="请输入"
></MyInput>
)}
{/* {parameter.domType.toLowerCase()} */}
{parameter.description && (
<Tooltip title={parameter.description} placement="top">
<img
className={styles.parameterDesc}
src={questionMark}
alt=""
/>
</Tooltip>
)}
{/* question mark */}
</div>
);
})}
</div>
</div>
);
})}
{/* <MySelect
value={selectValue}
onChange={handleSelectChange}
multiple={true}
options={optionsTransform(options, "key")}
></MySelect> */}
{/* <MyCheckBox
value={selectValue}
onChange={handleCheckBoxChange}
options={optionsTransform(options, "key")}
></MyCheckBox> */}
{/* <MyRadio
value={selectValue}
onChange={handleRadioChange}
options={optionsTransform(options, "key")}
></MyRadio> */}
{/* <FileSelect
onClose={handleFileSelectOnClose}
open={fileSelectOpen}
onConfirm={onFileSelectConfirm}
/>
/> */}
</div>
);
};
......
import * as React from "react";
import Box from "@mui/material/Box";
import InputLabel from "@mui/material/InputLabel";
import MenuItem from "@mui/material/MenuItem";
import FormControl from "@mui/material/FormControl";
import Select, { SelectProps } from "@mui/material/Select";
export interface IOption {
label: string;
value: string;
disabled?: boolean;
}
export const optionsTransform = (
arr: Array<any>,
labelKey: string = "label",
valueKey: string = "value",
disabledKey: string = "disabled"
): Array<IOption> => {
return arr.map((item: any) => {
return {
label: item[labelKey],
value: item[valueKey],
disabled: item[disabledKey],
};
});
};
interface IProps
extends Omit<SelectProps, "value" | "options" | "onChange" | "title"> {
value?: any;
options: IOption[];
onChange?: any;
/** 类型变种 */
variant?: "standard" | "outlined" | "filled";
/** title */
title?: string;
/** 是否显示title */
isTitle?: boolean;
size?: "small" | "medium";
multiple?: boolean; // 多选
}
export default function MySelect(props: IProps) {
const {
value,
options,
onChange,
title,
isTitle = false,
variant,
size = "small",
multiple = false,
} = props;
return (
<Box sx={{ minWidth: 120 }}>
<FormControl fullWidth variant={variant}>
{isTitle ? (
<InputLabel id="demo-simple-select-label">
{title || "请选择"}
</InputLabel>
) : null}
<Select
labelId="demo-simple-select-label"
id="demo-simple-select"
label={title || ""}
size={size}
{...props}
value={value}
onChange={onChange}
multiple={multiple}
>
{options.length
? options?.map((item: IOption) => {
return (
<MenuItem
key={item.value}
value={item.value}
disabled={item?.disabled}
>
{item.label}
</MenuItem>
);
})
: null}
</Select>
</FormControl>
</Box>
);
}
......@@ -53,7 +53,6 @@
width: 608px;
box-sizing: border-box;
padding: 36px;
height: 2000px;
}
.swFlowBox {
flex: 1;
......
......@@ -7,12 +7,31 @@ import ButtonComponent from "@/components/mui/Button";
import ArrowBackIosNewIcon from "@mui/icons-material/ArrowBackIosNew";
import IconButton from "@mui/material/IconButton";
import { ITemplateConfig } from "./interface";
import _ from "lodash";
const ProjectSubmitWork = () => {
const [templateConfigInfo, setTemplateConfigInfo] = useState<ITemplateConfig>(
templateConfigJson as ITemplateConfig
);
const setParameter = (value: any, taskId: string, parameterName: string) => {
const result: ITemplateConfig = _.cloneDeep(templateConfigInfo);
result.tasks.forEach((tack) => {
if (tack.id === taskId) {
tack.parameters.forEach((parameter) => {
if (parameter.name === parameterName) {
parameter.value = value;
} else {
return;
}
});
} else {
return;
}
});
setTemplateConfigInfo(result);
};
return (
<div className={styles.swBox}>
<div className={styles.swHeader}>
......@@ -55,7 +74,10 @@ const ProjectSubmitWork = () => {
</div>
<div className={styles.swContent}>
<div className={styles.swFormBox}>
<ConfigForm templateConfigInfo={templateConfigInfo} />
<ConfigForm
templateConfigInfo={templateConfigInfo}
setParameter={setParameter}
/>
</div>
<div className={styles.swFlowBox}>
<WorkFlow />
......
......@@ -8,7 +8,7 @@ export interface ITemplateConfig {
tags: Array<string>;
source: string;
productId: string;
tasks?: Array<ITaskFlow | ITaskBatch>;
tasks: Array<ITaskFlow | ITaskBatch>;
}
export interface ITaskFlow {
......@@ -44,7 +44,7 @@ export interface IParameter {
name: string;
required: boolean;
domType: IDomType;
dataType: string;
dataType?: string;
value: string;
description: string;
validators: Array<IValidator>;
......@@ -52,13 +52,13 @@ export interface IParameter {
}
export type IDomType =
| "pathSelect"
| "datasetSelect"
| "fileSelect"
| "pathselect"
| "datasetselect"
| "fileselect"
| "input"
| "File"
| "file"
| "select"
| "multipleSelect"
| "multipleselect"
| "radio"
| "checkbox";
......@@ -81,3 +81,19 @@ export interface IEdge {
targetHandle: string;
lable: string;
}
// 提交任务时的动态表单的数据结构
export type IRenderTasks = Array<IRenderTask>;
export type IRenderTask = {
id: string;
title: string;
description: string;
position: {
x: number;
y: number;
};
type: "batch";
parameters: Array<IParameter>;
edges: Array<IEdge>;
flows: Array<ITaskFlow>;
};
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment