Commit 537687c6 authored by jiangzijing's avatar jiangzijing

Merge branch 'feat-20220718' into 'staging'

Feat 20220718

See merge request !33
parents c50be623 45c5f606
...@@ -82,12 +82,12 @@ const theme = createTheme({ ...@@ -82,12 +82,12 @@ const theme = createTheme({
}, },
}, },
outlinedSecondary: { outlinedSecondary: {
border: "1px solid #FF4E4E", border: "1px solid rgba(221, 225, 230, 1)",
boxShadow: "none !important", boxShadow: "none !important",
color: "#FF4E4E", color: "rgba(30, 38, 51, 1)",
"&:hover": { "&:hover": {
backgroundColor: "#FFEDED ", backgroundColor: "rgba(240, 242, 245, 1) ",
border: "1px solid #FF4E4E", border: "1px solid rgba(221, 225, 230, 1)",
}, },
}, },
textSecondary: { textSecondary: {
......
...@@ -89,6 +89,7 @@ const MyDialog: React.FunctionComponent<IDialogProps> = (props) => { ...@@ -89,6 +89,7 @@ const MyDialog: React.FunctionComponent<IDialogProps> = (props) => {
onClick={onClose} onClick={onClose}
variant="outlined" variant="outlined"
size="small" size="small"
color="secondary"
/> />
) : null} ) : null}
{showConfirm ? ( {showConfirm ? (
......
...@@ -37,27 +37,36 @@ const MyInput = (props: MyInputProps) => { ...@@ -37,27 +37,36 @@ const MyInput = (props: MyInputProps) => {
fontSize: "14px", fontSize: "14px",
"&.MuiInputBase-sizeSmall": { "&.MuiInputBase-sizeSmall": {
height: "32px", height: "32px",
"& .MuiOutlinedInput-notchedOutline": {
height: "34px",
}, },
}, },
multiline: {
height: "auto",
textarea: {
padding: 0,
}, },
}, },
input: {},
},
}, },
MuiInputLabel: { MuiInputLabel: {
styleOverrides: { styleOverrides: {
root: { root: {
top: label ? "-5px" : "-10px", top: "-9px",
},
shrink: {
top: 0,
},
sizeSmall: {
top: "-5px",
}, },
}, },
}, },
MuiOutlinedInput: { MuiOutlinedInput: {
styleOverrides: { styleOverrides: {
root: { root: {
height: "36px", "&.Mui-focused .MuiOutlinedInput-notchedOutline": {
lineHeight: "36px", borderWidth: "1px",
paddingRight: "12px", },
":hover": { ":hover": {
"& .MuiOutlinedInput-notchedOutline": error "& .MuiOutlinedInput-notchedOutline": error
? {} ? {}
...@@ -70,9 +79,6 @@ const MyInput = (props: MyInputProps) => { ...@@ -70,9 +79,6 @@ const MyInput = (props: MyInputProps) => {
padding: "6.5px 12px", padding: "6.5px 12px",
verticalAlign: "middle", verticalAlign: "middle",
}, },
notchedOutline: {
height: "36px",
},
}, },
}, },
}, },
......
/*
* @Author: 吴永生#A02208 yongsheng.wu@wholion.com
* @Date: 2022-07-05 14:00:37
* @LastEditors: 吴永生#A02208 yongsheng.wu@wholion.com
* @LastEditTime: 2022-07-21 17:33:59
* @FilePath: /bkunyun/src/components/mui/MyInput.tsx
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
import TextField, { TextFieldProps } from "@mui/material/TextField";
import { ThemeProvider, createTheme } from "@mui/material/styles";
interface MyInputProps extends Omit<TextFieldProps, "value"> {
value?: string;
variant?: "standard" | "filled" | "outlined";
size?: "small" | "medium";
placeholder?: string;
fullWidth?: boolean; // 宽度是否和容器一致
error?: boolean;
}
const MyInput = (props: MyInputProps) => {
const {
size = "medium",
placeholder = "请输入",
fullWidth = true,
error = false,
label,
...other
} = props;
const theme = createTheme({
components: {
MuiInputBase: {
styleOverrides: {
root: {
height: "36px",
fontSize: "14px",
"&.MuiInputBase-sizeSmall": {
height: "32px",
},
},
},
},
MuiInputLabel: {
styleOverrides: {
root: {
top: "-9px",
},
shrink: {
top: 0,
},
sizeSmall: {
top: "-5px",
},
},
},
MuiOutlinedInput: {
styleOverrides: {
root: {
"&.Mui-focused .MuiOutlinedInput-notchedOutline": {
borderWidth: "1px",
},
":hover": {
"& .MuiOutlinedInput-notchedOutline": error
? {}
: {
borderColor: "#1370ff",
},
},
},
input: {
padding: "6.5px 12px",
verticalAlign: "middle",
},
},
},
},
});
return (
<ThemeProvider theme={theme}>
<TextField
error={error}
size={size}
placeholder={placeholder}
fullWidth={fullWidth}
label={label}
{...other}
/>
</ThemeProvider>
);
};
export default MyInput;
...@@ -97,14 +97,12 @@ const ConsoleLayout = observer(() => { ...@@ -97,14 +97,12 @@ const ConsoleLayout = observer(() => {
dropValue={productOpen} dropValue={productOpen}
drop={true} drop={true}
/> />
{/* <ArrowDropDownIcon classes={{ {/* <ArrowDropDownIcon classes={{
root: cx({ root: cx({
[style.ArrowDropDownIconRoot]: true, [style.ArrowDropDownIconRoot]: true,
[style.ArrowDropDownIconRootOpen]: Boolean(productOpen) [style.ArrowDropDownIconRootOpen]: Boolean(productOpen)
}) })
}} /> */} }} /> */}
<Menu <Menu
id="product-menu" id="product-menu"
anchorEl={productAnchorEl} anchorEl={productAnchorEl}
......
import React, { useState, useEffect } from "react"; import { useState, useEffect } from "react";
import { TextField } from "@mui/material";
import MyDialog from "@/components/mui/MyDialog"; import MyDialog from "@/components/mui/MyDialog";
import { checkIsNumberLetterChinese } from "@/utils/util"; import { checkIsNumberLetterChinese } from "@/utils/util";
import { useMessage } from "@/components/MySnackbar"; import { useMessage } from "@/components/MySnackbar";
......
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
.taskName { .taskName {
font-size: 14px; font-size: 14px;
font-weight: 500; font-weight: 500;
cursor: pointer;
} }
.taskStatus { .taskStatus {
......
...@@ -13,6 +13,7 @@ import fileIcon from "@/assets/project/fileIcon.svg"; ...@@ -13,6 +13,7 @@ import fileIcon from "@/assets/project/fileIcon.svg";
import dataSetIcon from "@/assets/project/dataSetIcon.svg"; import dataSetIcon from "@/assets/project/dataSetIcon.svg";
type TaskCardProps = { type TaskCardProps = {
id: string;
name: string; name: string;
creator: string; creator: string;
state: string; state: string;
...@@ -24,7 +25,7 @@ type TaskCardProps = { ...@@ -24,7 +25,7 @@ type TaskCardProps = {
}; };
const TaskCard = (props: TaskCardProps) => { const TaskCard = (props: TaskCardProps) => {
const { name, creator, state, completeNum, totalNum, costTime, jobCost, outputs } = props; const { id, name, creator, state, completeNum, totalNum, costTime, jobCost, outputs } = props;
const navigate = useNavigate(); const navigate = useNavigate();
const randerOutputs = useMemo(() => { const randerOutputs = useMemo(() => {
if (outputs) { if (outputs) {
...@@ -62,6 +63,12 @@ const TaskCard = (props: TaskCardProps) => { ...@@ -62,6 +63,12 @@ const TaskCard = (props: TaskCardProps) => {
}); });
} }
} }
// 跳转详情页
const gotoDetail = (id: string) => {
navigate(`/product/cadd/projectJobDetail`, {
state: { taskId: id },
});
}
// 渲染状态图标 // 渲染状态图标
const renderStatusIcon = (data: string) => { const renderStatusIcon = (data: string) => {
switch (data) { switch (data) {
...@@ -140,7 +147,7 @@ const TaskCard = (props: TaskCardProps) => { ...@@ -140,7 +147,7 @@ const TaskCard = (props: TaskCardProps) => {
return <div className={style.cardBox}> return <div className={style.cardBox}>
<div className={style.cardLeft}> <div className={style.cardLeft}>
<div className={style.topLine}> <div className={style.topLine}>
<div className={style.taskName}>{name}</div> <div className={style.taskName} onClick={() => gotoDetail(id)}>{name}</div>
<div className={style.taskStatus} style={{ color: renderTextColor(state), background: renderBackgroundColor(state) }}> <div className={style.taskStatus} style={{ color: renderTextColor(state), background: renderBackgroundColor(state) }}>
<img src={renderStatusIcon(state)} alt="" className={style.statusImg} /> <img src={renderStatusIcon(state)} alt="" className={style.statusImg} />
<span>{renderStatusText(state)}</span> <span>{renderStatusText(state)}</span>
...@@ -152,7 +159,7 @@ const TaskCard = (props: TaskCardProps) => { ...@@ -152,7 +159,7 @@ const TaskCard = (props: TaskCardProps) => {
<div>Progress</div> <div>Progress</div>
<div style={{ color: renderTextColor(state) }}>{completeNum + "/" + totalNum}</div> <div style={{ color: renderTextColor(state) }}>{completeNum + "/" + totalNum}</div>
</div> </div>
<MyProgress color={renderProgressColor(state)} value={(completeNum / totalNum) * 100}/> <MyProgress color={renderProgressColor(state)} value={(completeNum / totalNum) * 100} />
</div> </div>
<div className={style.bottomLine}> <div className={style.bottomLine}>
<img alt="" src={runTime} /> <img alt="" src={runTime} />
......
...@@ -38,6 +38,10 @@ ...@@ -38,6 +38,10 @@
color: #565C66; color: #565C66;
} }
.otherInformationBoxRight{
color: #565C66;
}
.numberDisplay { .numberDisplay {
font-size: 20px; font-size: 20px;
font-weight: 600; font-weight: 600;
...@@ -48,7 +52,7 @@ ...@@ -48,7 +52,7 @@
.verticalLine { .verticalLine {
height: 32px; height: 32px;
border: 1px solid #EBEDF0; border: 1px solid #EBEDF0;
margin-left: 10px; margin-left: 20px;
margin-right: 20px; margin-right: 20px;
} }
......
...@@ -44,12 +44,15 @@ const ProjectOverview = observer(() => { ...@@ -44,12 +44,15 @@ const ProjectOverview = observer(() => {
}, },
}); });
useEffect(() => { useEffect(() => {
if (currentProjectStore.currentProjectInfo.id) {
getOverview({ getOverview({
id: currentProjectStore.currentProjectInfo.id as string, id: currentProjectStore.currentProjectInfo.id as string,
}); });
}
}, [currentProjectStore.currentProjectInfo.id, getOverview]); }, [currentProjectStore.currentProjectInfo.id, getOverview]);
useEffect(() => { useEffect(() => {
if (currentProjectStore.currentProjectInfo.id) {
getTaskOverviewList({ getTaskOverviewList({
projectId: currentProjectStore.currentProjectInfo.id as string, projectId: currentProjectStore.currentProjectInfo.id as string,
jobName: jobName, jobName: jobName,
...@@ -57,6 +60,7 @@ const ProjectOverview = observer(() => { ...@@ -57,6 +60,7 @@ const ProjectOverview = observer(() => {
page: page, page: page,
size: size, size: size,
}); });
}
}, [currentProjectStore.currentProjectInfo.id, getTaskOverviewList, day, jobName]); }, [currentProjectStore.currentProjectInfo.id, getTaskOverviewList, day, jobName]);
const handleKeyWordChangeKeyUp = (e: any) => { const handleKeyWordChangeKeyUp = (e: any) => {
...@@ -64,6 +68,21 @@ const ProjectOverview = observer(() => { ...@@ -64,6 +68,21 @@ const ProjectOverview = observer(() => {
setJobName(e.target.value); setJobName(e.target.value);
} }
} }
const storageUnitFromB = (b: number) => {
if (b <= 0) {
return { data: '0.00', unit: 'KB' };
} else if (b < 1024 * 1024) {
return { data: (b / 1024).toFixed(2), unit: 'KB' };
} else if (b < 1024 * 1024 * 1024) {
return { data: (b / (1024 * 1024)).toFixed(2), unit: 'MB' };
} else if (b < 1024 * 1024 * 1024 * 1024) {
return { data: (b / (1024 * 1024 * 1024)).toFixed(2), unit: 'G' };
} else {
return { data: (b / (1024 * 1024 * 1024 * 1024)).toFixed(2), unit: 'T' };
}
};
if (currentProjectStore.currentProjectInfo.name) { if (currentProjectStore.currentProjectInfo.name) {
if (loading) { if (loading) {
return ( return (
...@@ -90,18 +109,21 @@ const ProjectOverview = observer(() => { ...@@ -90,18 +109,21 @@ const ProjectOverview = observer(() => {
</div> </div>
<div className={style.basicInformationRight}> <div className={style.basicInformationRight}>
<div> <div>
<div className={style.otherInformationBox}>项目总消费</div> <div className={style.otherInformationBoxRight}>项目总消费</div>
<div><span className={style.numberDisplay}>{overviewInfo.projectCost?.toFixed(2)}</span></div> <div><span className={style.numberDisplay}>{overviewInfo.projectCost?.toFixed(2)}</span></div>
</div> </div>
<div className={style.verticalLine}></div> <div className={style.verticalLine}></div>
<div> <div>
<div className={style.otherInformationBox}>项目剩余预算</div> <div className={style.otherInformationBoxRight}>项目剩余预算</div>
<div><span className={style.numberDisplay}>{overviewInfo.projectRemainingBudget?.toFixed(2)}</span></div> <div><span className={style.numberDisplay}>{overviewInfo.projectRemainingBudget?.toFixed(2)}</span></div>
</div> </div>
<div className={style.verticalLine}></div> <div className={style.verticalLine}></div>
<div> <div>
<div className={style.otherInformationBox}>项目存储大小</div> <div className={style.otherInformationBoxRight} style={{ marginRight: '20px' }}>项目存储大小</div>
<div><span className={style.numberDisplay}>{overviewInfo.projectStorage?.toFixed(2)}</span> G</div> <div>
<span className={style.numberDisplay}>{overviewInfo.projectStorage !== undefined ? storageUnitFromB(overviewInfo.projectStorage).data : ''}</span>
{overviewInfo.projectStorage !== undefined ? storageUnitFromB(overviewInfo.projectStorage).unit : ''}
</div>
</div> </div>
</div> </div>
</div> </div>
...@@ -134,6 +156,7 @@ const ProjectOverview = observer(() => { ...@@ -134,6 +156,7 @@ const ProjectOverview = observer(() => {
{/* 任务列表卡片渲染 */} {/* 任务列表卡片渲染 */}
{taskList.length > 0 && taskList.map((item: any) => { {taskList.length > 0 && taskList.map((item: any) => {
return <TaskCard return <TaskCard
id={item.id}
name={item.name} name={item.name}
creator={item.creator} creator={item.creator}
state={item.state} state={item.state}
......
...@@ -23,7 +23,7 @@ import InformationDisplay from "@/components/CommonComponents/InformationDisplay ...@@ -23,7 +23,7 @@ import InformationDisplay from "@/components/CommonComponents/InformationDisplay
import classnames from "classnames"; import classnames from "classnames";
import { TextField } from "@mui/material"; import { TextField } from "@mui/material";
import LoadingButton from "@mui/lab/LoadingButton"; import LoadingButton from "@mui/lab/LoadingButton";
import InputAdornment from '@mui/material/InputAdornment'; import InputAdornment from "@mui/material/InputAdornment";
import { useMessage } from "@/components/MySnackbar"; import { useMessage } from "@/components/MySnackbar";
import Loading from "@/views/Loading"; import Loading from "@/views/Loading";
import MyDialog from "@/components/mui/MyDialog"; import MyDialog from "@/components/mui/MyDialog";
...@@ -59,6 +59,13 @@ const BaseInfo = observer(() => { ...@@ -59,6 +59,13 @@ const BaseInfo = observer(() => {
).name; ).name;
// 弹窗显示控制 // 弹窗显示控制
const [dialogOpen, setDialogOpen] = useState(false); const [dialogOpen, setDialogOpen] = useState(false);
// 打开弹窗时重置表单
useEffect(() => {
if (dialogOpen) {
setDeleteProjectName("");
}
}, [dialogOpen]);
// 是否拥有编辑权限 // 是否拥有编辑权限
const hasEditAuth = useMemo(() => { const hasEditAuth = useMemo(() => {
if (!currentUserName) { if (!currentUserName) {
...@@ -75,7 +82,10 @@ const BaseInfo = observer(() => { ...@@ -75,7 +82,10 @@ const BaseInfo = observer(() => {
}, [currentUserName, projectInfo]); }, [currentUserName, projectInfo]);
const { run, loading } = useMyRequest(getProject, { const { run, loading } = useMyRequest(getProject, {
onSuccess: (result: any) => { onSuccess: (result: any) => {
setProjectInfo({ ...result.data, projectBudget: result.data.projectBudget.toFixed(2) }); setProjectInfo({
...result.data,
projectBudget: result.data.projectBudget.toFixed(2),
});
}, },
}); });
useEffect(() => { useEffect(() => {
...@@ -184,42 +194,49 @@ const BaseInfo = observer(() => { ...@@ -184,42 +194,49 @@ const BaseInfo = observer(() => {
}); });
}; };
const budgetChange = (e: any) => { const checkBudget = (budget: string, showMessage = false) => {
let inputValue = e.target.value.replace('.', '') let help = "";
if (inputValue.indexOf('.') !== -1) { if (budget) {
if (isNaN(Number(budget)) || Number(budget) > 10000000 || Number(budget) < 0) {
help = "格式错误,请输入0~10000000之间的数值,结果最高保留两位小数。";
setBudgetCheck({ setBudgetCheck({
error: true, error: true,
help: "格式错误,请输入正确的金额,可精确至分(两位小数)", help,
});
showMessage && message.error(help);
return false;
} else {
setBudgetCheck({
error: false,
help: "",
}); });
return return true;
} }
if (isNaN(Number(inputValue))) { } else {
help = "格式错误,请输入0~10000000之间的数值,结果最高保留两位小数。";
setBudgetCheck({ setBudgetCheck({
error: true, error: true,
help: "格式错误,请输入正确的金额,可精确至分(两位小数)", help,
}); });
return showMessage && message.error(help);
} else { return false;
}
}
const budgetChange = (e: any) => {
setProjectInfo({ setProjectInfo({
...projectInfo, ...projectInfo,
projectBudget: e.target.value projectBudget: e.target.value,
})
setBudgetCheck({
error: false,
help: "",
}); });
checkBudget(e.target.value);
} }
}
const budgetBlur = (e: any) => { const budgetBlur = (e: any) => {
setProjectInfo({ setProjectInfo({
...projectInfo, ...projectInfo,
projectBudget: Number(e.target.value).toFixed(2) projectBudget: Number(e.target.value) ? Number(e.target.value).toFixed(2) : e.target.value,
})
setBudgetCheck({
error: false,
help: "",
}); });
} };
const { run: updateProjectRun, loading: updateLoading } = useMyRequest( const { run: updateProjectRun, loading: updateLoading } = useMyRequest(
updateProject, updateProject,
...@@ -235,7 +252,7 @@ const BaseInfo = observer(() => { ...@@ -235,7 +252,7 @@ const BaseInfo = observer(() => {
// 修改项目 // 修改项目
const handleClickUpdate = () => { const handleClickUpdate = () => {
if (checkName(projectInfo.name, true)) { if (checkName(projectInfo.name, true) && checkBudget(projectInfo.projectBudget, true)) {
updateProjectRun({ ...projectInfo, product: "cadd" }); updateProjectRun({ ...projectInfo, product: "cadd" });
} else { } else {
return; return;
...@@ -312,9 +329,9 @@ const BaseInfo = observer(() => { ...@@ -312,9 +329,9 @@ const BaseInfo = observer(() => {
size="small" size="small"
sx={{ sx={{
width: "560px", width: "560px",
'& .MuiOutlinedInput-root': { "& .MuiOutlinedInput-root": {
height: '36px' height: "36px",
} },
}} }}
/> />
{/* <input {/* <input
...@@ -390,12 +407,14 @@ const BaseInfo = observer(() => { ...@@ -390,12 +407,14 @@ const BaseInfo = observer(() => {
size="small" size="small"
sx={{ sx={{
width: "560px", width: "560px",
'& .MuiOutlinedInput-root': { "& .MuiOutlinedInput-root": {
height: '36px' height: "36px",
} },
}} }}
InputProps={{ InputProps={{
startAdornment: <InputAdornment position="start">¥</InputAdornment>, startAdornment: (
<InputAdornment position="start">¥</InputAdornment>
),
}} }}
/> />
</div> </div>
...@@ -426,10 +445,10 @@ const BaseInfo = observer(() => { ...@@ -426,10 +445,10 @@ const BaseInfo = observer(() => {
删除项目将删除其存储的数据和所有相关资源,并且已删除的项目无法恢复!请谨慎操作! 删除项目将删除其存储的数据和所有相关资源,并且已删除的项目无法恢复!请谨慎操作!
</div> </div>
<MyButton <MyButton
text='删除项目' text="删除项目"
variant="contained" variant="contained"
onClick={() => setDialogOpen(true)} onClick={() => setDialogOpen(true)}
color='error' color="error"
// style={{ // style={{
// backgroundColor: "#fff", // backgroundColor: "#fff",
// color: "#FF4E4E", // color: "#FF4E4E",
......
...@@ -310,7 +310,15 @@ const ConfigForm = (props: ConfigFormProps) => { ...@@ -310,7 +310,15 @@ const ConfigForm = (props: ConfigFormProps) => {
onBlur={() => setSelectedBatchNodeId("")} onBlur={() => setSelectedBatchNodeId("")}
value={parameter.value} value={parameter.value}
onChange={(e: any) => onChange={(e: any) =>
handleParameterChange(e, taskId, parameter.name || "") handleParameterChange(
{
target: {
value: e,
},
},
taskId,
parameter.name || ""
)
} }
error={parameter.error || false} error={parameter.error || false}
helpertext={parameter.helperText} helpertext={parameter.helperText}
...@@ -324,7 +332,15 @@ const ConfigForm = (props: ConfigFormProps) => { ...@@ -324,7 +332,15 @@ const ConfigForm = (props: ConfigFormProps) => {
onBlur={() => setSelectedBatchNodeId("")} onBlur={() => setSelectedBatchNodeId("")}
value={parameter.value} value={parameter.value}
onChange={(e: any) => onChange={(e: any) =>
handleParameterChange(e, taskId, parameter.name || "") handleParameterChange(
{
target: {
value: e,
},
},
taskId,
parameter.name || ""
)
} }
multiple={true} multiple={true}
error={parameter.error || false} error={parameter.error || false}
......
import * as React from "react";
import InputLabel from "@mui/material/InputLabel";
import MenuItem from "@mui/material/MenuItem";
import FormControl from "@mui/material/FormControl";
import FormHelperText from "@mui/material/FormHelperText";
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; // 多选
error?: boolean;
helpertext?: string;
fullWidth?: boolean;
}
export default function MySelect(props: IProps) {
const {
value,
options,
onChange,
title,
isTitle = false,
variant,
size = "small",
multiple = false,
error = false,
helpertext,
fullWidth = true,
} = props;
return (
<FormControl fullWidth={fullWidth} variant={variant} error={error}>
{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>
{helpertext && error && <FormHelperText>{helpertext}</FormHelperText>}
</FormControl>
);
}
.formBox { .formBox {
height: 300px; padding: 8px 0;
width: 388px; width: 388px;
display: flex;
flex-direction: column;
padding: 10px 0;
justify-content: space-around;
} }
import style from "./index.module.css"; import style from "./index.module.css";
import { TextField, MenuItem } from "@mui/material"; import { MenuItem } from "@mui/material";
import MyInput from "@/components/mui/MyInput";
import MyDialog from "@/components/mui/MyDialog"; import MyDialog from "@/components/mui/MyDialog";
import React, { useState, useEffect } from "react"; import React, { useState, useEffect } from "react";
import useMyRequest from "@/hooks/useMyRequest"; import useMyRequest from "@/hooks/useMyRequest";
...@@ -165,7 +166,7 @@ const AddProject = (props: IAddProjectProps) => { ...@@ -165,7 +166,7 @@ const AddProject = (props: IAddProjectProps) => {
title="新建项目" title="新建项目"
> >
<div className={style.formBox} onClick={handleFromBox}> <div className={style.formBox} onClick={handleFromBox}>
<TextField <MyInput
required required
error={nameCheck.error} error={nameCheck.error}
id="name" id="name"
...@@ -174,9 +175,9 @@ const AddProject = (props: IAddProjectProps) => { ...@@ -174,9 +175,9 @@ const AddProject = (props: IAddProjectProps) => {
value={name} value={name}
onChange={handleNameChange} onChange={handleNameChange}
helperText={nameCheck.help} helperText={nameCheck.help}
size="small" sx={{ marginBottom: "20px" }}
/> />
<TextField <MyInput
id="zoneId" id="zoneId"
select select
required required
...@@ -185,7 +186,7 @@ const AddProject = (props: IAddProjectProps) => { ...@@ -185,7 +186,7 @@ const AddProject = (props: IAddProjectProps) => {
onChange={handleZoneIdChange} onChange={handleZoneIdChange}
variant="outlined" variant="outlined"
onClick={handleFromBox} onClick={handleFromBox}
size="small" sx={{ marginBottom: "20px" }}
> >
{zoneIdOptions && {zoneIdOptions &&
zoneIdOptions.map((option) => ( zoneIdOptions.map((option) => (
...@@ -193,8 +194,9 @@ const AddProject = (props: IAddProjectProps) => { ...@@ -193,8 +194,9 @@ const AddProject = (props: IAddProjectProps) => {
{option.name} {option.name}
</MenuItem> </MenuItem>
))} ))}
</TextField> </MyInput>
<TextField <div style={{ position: "relative" }}>
<MyInput
value={desc} value={desc}
error={descCheck.error} error={descCheck.error}
id="desc" id="desc"
...@@ -204,8 +206,18 @@ const AddProject = (props: IAddProjectProps) => { ...@@ -204,8 +206,18 @@ const AddProject = (props: IAddProjectProps) => {
placeholder="请输入项目描述" placeholder="请输入项目描述"
onChange={handleDescChange} onChange={handleDescChange}
helperText={descCheck.help} helperText={descCheck.help}
size="small"
/> />
<span
style={{
position: "absolute",
bottom: "7px",
right: "12px",
color: "rgba(194, 198, 204, 1)",
}}
>
{desc.length}/100
</span>
</div>
</div> </div>
</MyDialog> </MyDialog>
); );
......
...@@ -41,12 +41,16 @@ ...@@ -41,12 +41,16 @@
.projectlist { .projectlist {
flex: 1; flex: 1;
overflow-y: scroll; overflow-y: scroll;
border-top: 1px solid #f0f2f5;
} }
.projectli { .projectli {
cursor: pointer; cursor: pointer;
} }
.projectli:hover { .projectli:hover {
background-color: #f2f7ff; background-color: rgba(240, 242, 245, 1);
}
.projectliActive {
background-color: rgba(237, 244, 255, 1);
} }
.projectliBorderBox { .projectliBorderBox {
box-sizing: border-box; box-sizing: border-box;
...@@ -57,7 +61,7 @@ ...@@ -57,7 +61,7 @@
flex-direction: row; flex-direction: row;
justify-content: flex-start; justify-content: flex-start;
align-items: flex-start; align-items: flex-start;
border-top: 1px solid #f0f2f5; border-bottom: 1px solid #f0f2f5;
} }
.projectliLogo { .projectliLogo {
width: 24px; width: 24px;
......
...@@ -3,6 +3,7 @@ import style from "./index.module.css"; ...@@ -3,6 +3,7 @@ import style from "./index.module.css";
import { InputBase, IconButton } from "@mui/material"; import { InputBase, IconButton } from "@mui/material";
import SearchIcon from "@mui/icons-material/Search"; import SearchIcon from "@mui/icons-material/Search";
import AddIcon from "@mui/icons-material/Add"; import AddIcon from "@mui/icons-material/Add";
import classNames from "classnames";
import { useStores } from "@/store/index"; import { useStores } from "@/store/index";
import moment from "moment"; import moment from "moment";
import React, { useMemo, useState } from "react"; import React, { useMemo, useState } from "react";
...@@ -12,16 +13,19 @@ import { observer } from "mobx-react-lite"; ...@@ -12,16 +13,19 @@ import { observer } from "mobx-react-lite";
const ProjectListPopper = observer((props: any) => { const ProjectListPopper = observer((props: any) => {
const { handleChangeCurrentProject, handleClickOpen } = props; const { handleChangeCurrentProject, handleClickOpen } = props;
const { currentProjectStore } = useStores(); const { currentProjectStore } = useStores();
const projectList = toJS(currentProjectStore.projectList);
const currentProjectName = toJS(currentProjectStore.currentProjectInfo.name);
// 通过名称本地搜索
const [name, setName] = useState(""); const [name, setName] = useState("");
const nameChange = (e: any) => { const nameChange = (e: any) => {
setName(e.target.value); setName(e.target.value);
}; };
const list = useMemo(() => { const list = useMemo(() => {
return toJS(currentProjectStore.projectList).filter((item: any) => { return projectList.filter((item: any) => {
return item.name?.indexOf(name) !== -1; return item.name?.indexOf(name) !== -1;
}); });
}, [currentProjectStore.projectList, name]); }, [projectList, name]);
const handleProjectBox = (e: React.SyntheticEvent) => { const handleProjectBox = (e: React.SyntheticEvent) => {
e.nativeEvent.stopImmediatePropagation(); e.nativeEvent.stopImmediatePropagation();
...@@ -35,7 +39,10 @@ const ProjectListPopper = observer((props: any) => { ...@@ -35,7 +39,10 @@ const ProjectListPopper = observer((props: any) => {
className={style.searchButton} className={style.searchButton}
aria-label="search" aria-label="search"
> >
<SearchIcon className={style.searchIcon} /> <SearchIcon
className={style.searchIcon}
style={{ color: "rgba(153, 153, 153, 1)" }}
/>
</IconButton> </IconButton>
<InputBase <InputBase
className={style.searchInput} className={style.searchInput}
...@@ -57,7 +64,10 @@ const ProjectListPopper = observer((props: any) => { ...@@ -57,7 +64,10 @@ const ProjectListPopper = observer((props: any) => {
{list.map((item: any) => { {list.map((item: any) => {
return ( return (
<div <div
className={style.projectli} className={classNames({
[style.projectli]: true,
[style.projectliActive]: item.name === currentProjectName,
})}
key={item.id} key={item.id}
onClick={() => handleChangeCurrentProject(item)} onClick={() => handleChangeCurrentProject(item)}
> >
......
...@@ -9,9 +9,6 @@ import { ...@@ -9,9 +9,6 @@ import {
import noTemplate from "@/assets/project/noTemplate.svg"; import noTemplate from "@/assets/project/noTemplate.svg";
import MyInput from "@/components/mui/MyInput"; import MyInput from "@/components/mui/MyInput";
import MyCheckBox from "@/components/mui/MyCheckBox"; import MyCheckBox from "@/components/mui/MyCheckBox";
// import MySelect, {
// optionsTransform,
// } from "../../../Project/ProjectSubmitWork/components/MySelect";
import MySelect from "@/components/mui/MySelect"; import MySelect from "@/components/mui/MySelect";
import FileSelect, { import FileSelect, {
FileSelectType, FileSelectType,
...@@ -491,7 +488,14 @@ const ParameterSetting = (props: IParameterSettingProps) => { ...@@ -491,7 +488,14 @@ const ParameterSetting = (props: IParameterSettingProps) => {
<MySelect <MySelect
value={parameter.defaultValue} value={parameter.defaultValue}
onChange={(e: any) => onChange={(e: any) =>
handleParameterChange(e, parameter.name || "") handleParameterChange(
{
target: {
value: e,
},
},
parameter.name || ""
)
} }
error={parameter.error || false} error={parameter.error || false}
helpertext={parameter.helperText} helpertext={parameter.helperText}
...@@ -503,7 +507,14 @@ const ParameterSetting = (props: IParameterSettingProps) => { ...@@ -503,7 +507,14 @@ const ParameterSetting = (props: IParameterSettingProps) => {
<MySelect <MySelect
value={parameter.defaultValue} value={parameter.defaultValue}
onChange={(e: any) => onChange={(e: any) =>
handleParameterChange(e, parameter.name || "") handleParameterChange(
{
target: {
value: e,
},
},
parameter.name || ""
)
} }
multiple={true} multiple={true}
error={parameter.error || false} error={parameter.error || false}
......
import { memo } from "react"; import { memo } from "react";
import { InputAdornment } from "@mui/material"; import { InputAdornment } from "@mui/material";
// import InputComponent from "@/components/mui/MyInput"; import InputComponent from "@/components/mui/MyInput";
import InputComponent from "@/components/mui/MyInputCopy";
const ProjectMembers = () => { const ProjectMembers = () => {
return ( return (
......
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