Commit 026cab6a authored by chenshouchao's avatar chenshouchao

Merge branch 'feat-20220705-customTemplate' into 'release'

cn-feat: 参数设置部分样式完成, 切换产品时产品id修改, 算子版本字段修改

See merge request sunyihao/bkunyun!92
parents 4ba0aef4 2bfb4ed6
...@@ -17,11 +17,13 @@ class Menus { ...@@ -17,11 +17,13 @@ class Menus {
productList: Array<{ productList: Array<{
name: string; name: string;
path: string; path: string;
id: string;
}> = []; }> = [];
utilityList: Array<{ utilityList: Array<{
name: string; name: string;
path: string; path: string;
id: string;
}> = []; }> = [];
initMenu = (list: projectList) => { initMenu = (list: projectList) => {
...@@ -32,11 +34,13 @@ class Menus { ...@@ -32,11 +34,13 @@ class Menus {
this.productList.push({ this.productList.push({
name: item.name, name: item.name,
path: item.routes[0].path, path: item.routes[0].path,
id: item.id,
}); });
} else if (item.type === "utility") { } else if (item.type === "utility") {
this.utilityList.push({ this.utilityList.push({
name: item.name, name: item.name,
path: item.routes[0].path, path: item.routes[0].path,
id: item.id,
}); });
} }
} }
......
...@@ -17,199 +17,199 @@ import TranSferList from "./components/TransferList"; ...@@ -17,199 +17,199 @@ import TranSferList from "./components/TransferList";
import { getProjectList } from "@/api/project_api"; import { getProjectList } from "@/api/project_api";
import useMyRequest from "@/hooks/useMyRequest"; import useMyRequest from "@/hooks/useMyRequest";
import { import {
setFileServerEndPointLocalStorage, setFileServerEndPointLocalStorage,
getFiletokenAccordingToId, getFiletokenAccordingToId,
} from "@/views/Project/project"; } from "@/views/Project/project";
import style from "./index.module.css"; import style from "./index.module.css";
const ConsoleLayout = observer(() => { const ConsoleLayout = observer(() => {
const { const {
productAnchorEl, productAnchorEl,
utilityAnchorEl, utilityAnchorEl,
productOpen, productOpen,
utilityOpen, utilityOpen,
handleProductClick, handleProductClick,
handleUtilityClick, handleUtilityClick,
handleClose, handleClose,
} = useIndex(); } = useIndex();
const [currentProduct, setCurrentProduct] = useState<{ const [currentProduct, setCurrentProduct] = useState<{
path: string; path: string;
name: string; name: string;
}>(); }>();
const { currentProjectStore } = useStores(); const { currentProjectStore } = useStores();
const { run: runGetProjectList } = useMyRequest(getProjectList, { const { run: runGetProjectList } = useMyRequest(getProjectList, {
onSuccess: (res) => { onSuccess: (res) => {
let list = res.data; let list = res.data;
if (list.length === 0) { if (list.length === 0) {
currentProjectStore.setProjectList([]); currentProjectStore.setProjectList([]);
currentProjectStore.changeProject({}); currentProjectStore.changeProject({});
navigate(currentProduct?.path as string); navigate(currentProduct?.path as string);
} else { } else {
currentProjectStore.setProjectList(list); currentProjectStore.setProjectList(list);
currentProjectStore.changeProject(list[0]); currentProjectStore.changeProject(list[0]);
setFileServerEndPointLocalStorage(list[0].zoneId); setFileServerEndPointLocalStorage(list[0].zoneId);
getFiletokenAccordingToId(list[0].id).then((res) => { getFiletokenAccordingToId(list[0].id).then((res) => {
list[0].filetoken = res; list[0].filetoken = res;
currentProjectStore.changeProject(list[0]); currentProjectStore.changeProject(list[0]);
}); });
navigate(currentProduct?.path as string); navigate(currentProduct?.path as string);
} }
}, },
}); });
// 切换产品 // 切换产品
const getProduct = (item: any) => { const getProduct = (item: any) => {
currentProjectStore.changeProductInfo({ id: item.name, name: item.name }); currentProjectStore.changeProductInfo({ id: item.id, name: item.name });
setCurrentProduct(item); setCurrentProduct(item);
runGetProjectList({ runGetProjectList({
product: item.name, product: item.name,
}); });
}; };
const navigate = useNavigate(); const navigate = useNavigate();
const location = useLocation(); const location = useLocation();
const { permissionStore, menuStore } = useStores(); const { permissionStore, menuStore } = useStores();
useEffect(() => { useEffect(() => {
permissionStore.setSidebarRouters(location.pathname); permissionStore.setSidebarRouters(location.pathname);
}, [location, permissionStore]); }, [location, permissionStore]);
return ( return (
<Box> <Box>
<Box className={style.topApp}> <Box className={style.topApp}>
<Box className={style.topLeftBox}> <Box className={style.topLeftBox}>
<img src={logo} alt="" className={style.logo} /> <img src={logo} alt="" className={style.logo} />
<Button <Button
text={globalText.console} text={globalText.console}
variant={"text"} variant={"text"}
style={{ color: "#565C66" }} style={{ color: "#565C66" }}
click={() => navigate("/home")} click={() => navigate("/home")}
/> />
<Box sx={{ display: "flex", alignItems: "center" }}> <Box sx={{ display: "flex", alignItems: "center" }}>
<Button <Button
text={globalText.product} text={globalText.product}
variant={"text"} variant={"text"}
style={{ color: "#565C66" }} style={{ color: "#565C66" }}
click={handleProductClick} click={handleProductClick}
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}
open={productOpen} open={productOpen}
onClose={handleClose} onClose={handleClose}
classes={{ classes={{
paper: style.menuPaper, paper: style.menuPaper,
}} }}
MenuListProps={{ MenuListProps={{
"aria-labelledby": "product-button", "aria-labelledby": "product-button",
}} }}
> >
{menuStore.productList.map((item) => { {menuStore.productList.map((item) => {
return ( return (
<MenuItem <MenuItem
key={item.path} key={item.path}
classes={{ classes={{
root: style.menuItemRoot, root: style.menuItemRoot,
}} }}
onClick={() => { onClick={() => {
getProduct(item); getProduct(item);
handleClose(); handleClose();
}} }}
> >
{item.name} {item.name}
</MenuItem> </MenuItem>
); );
})} })}
</Menu> </Menu>
</Box> </Box>
</Box> </Box>
<Box className={style.topRightBox}> <Box className={style.topRightBox}>
<MyPopover <MyPopover
content={<TranSferList />} content={<TranSferList />}
transformOrigin={{ transformOrigin={{
vertical: "top", vertical: "top",
horizontal: "right", horizontal: "right",
}} }}
> >
<img <img
className={style.topRightItem} className={style.topRightItem}
src={uploadIcon} src={uploadIcon}
alt="" alt=""
style={{ verticalAlign: "middle" }} style={{ verticalAlign: "middle" }}
/> />
</MyPopover> </MyPopover>
<Box className={style.topRightItem}> <Box className={style.topRightItem}>
<Box <Box
sx={{ display: "flex", alignItems: "center" }} sx={{ display: "flex", alignItems: "center" }}
onClick={handleUtilityClick} onClick={handleUtilityClick}
> >
<Avatar <Avatar
sx={{ sx={{
bgcolor: "#1370FF", bgcolor: "#1370FF",
width: 28, width: 28,
height: 28, height: 28,
fontSize: "14px", fontSize: "14px",
cursor: "pointer", cursor: "pointer",
}} }}
> >
H H
</Avatar> </Avatar>
<ArrowDropDownIcon <ArrowDropDownIcon
classes={{ classes={{
root: cx({ root: cx({
[style.ArrowDropDownIconRoot]: true, [style.ArrowDropDownIconRoot]: true,
[style.ArrowDropDownIconRootOpen]: Boolean(utilityOpen), [style.ArrowDropDownIconRootOpen]: Boolean(utilityOpen),
}), }),
}} }}
/> />
</Box> </Box>
<Menu <Menu
id="utility-menu" id="utility-menu"
anchorEl={utilityAnchorEl} anchorEl={utilityAnchorEl}
open={utilityOpen} open={utilityOpen}
onClose={handleClose} onClose={handleClose}
MenuListProps={{ MenuListProps={{
"aria-labelledby": "utility-button", "aria-labelledby": "utility-button",
}} }}
> >
{menuStore.utilityList.map((item) => { {menuStore.utilityList.map((item) => {
return ( return (
<MenuItem <MenuItem
key={item.path} key={item.path}
onClick={() => { onClick={() => {
navigate(item.path); navigate(item.path);
handleClose(); handleClose();
}} }}
> >
{item.name} {item.name}
</MenuItem> </MenuItem>
); );
})} })}
</Menu> </Menu>
</Box> </Box>
</Box> </Box>
</Box> </Box>
<Box> <Box>
<Outlet></Outlet> <Outlet></Outlet>
</Box> </Box>
</Box> </Box>
); );
}); });
export default ConsoleLayout; export default ConsoleLayout;
...@@ -545,7 +545,7 @@ const ProjectSubmitWork = observer(() => { ...@@ -545,7 +545,7 @@ const ProjectSubmitWork = observer(() => {
<div className={styles.taskInfoLi}> <div className={styles.taskInfoLi}>
<div className={styles.taskInfoParams}>算子版本</div> <div className={styles.taskInfoParams}>算子版本</div>
<div className={styles.taskInfoValue}> <div className={styles.taskInfoValue}>
{patchInfo?.creator || "-"} {patchInfo?.version || "-"}
</div> </div>
</div> </div>
<div className={styles.taskInfoLi}> <div className={styles.taskInfoLi}>
......
...@@ -11,10 +11,10 @@ import React, { memo, useEffect, useMemo, useState } from "react"; ...@@ -11,10 +11,10 @@ import React, { memo, useEffect, useMemo, useState } from "react";
import style from "./index.module.css"; import style from "./index.module.css";
import useMyRequest from "@/hooks/useMyRequest"; import useMyRequest from "@/hooks/useMyRequest";
import { import {
getProject, getProject,
hpczone, hpczone,
updateProject, updateProject,
deleteProject, deleteProject,
} from "@/api/project_api"; } from "@/api/project_api";
import { useStores } from "@/store"; import { useStores } from "@/store";
import { toJS } from "mobx"; import { toJS } from "mobx";
...@@ -29,376 +29,376 @@ import MyDialog from "@/components/mui/MyDialog"; ...@@ -29,376 +29,376 @@ import MyDialog from "@/components/mui/MyDialog";
import { getProjectList } from "../../project"; import { getProjectList } from "../../project";
import { checkIsNumberLetterChinese } from "@/utils/util"; import { checkIsNumberLetterChinese } from "@/utils/util";
import { import {
setFileServerEndPointLocalStorage, setFileServerEndPointLocalStorage,
getFiletokenAccordingToId, getFiletokenAccordingToId,
} from "@/views/Project/project"; } from "@/views/Project/project";
type zoneIdOption = { type zoneIdOption = {
id: string; id: string;
name: string; name: string;
}; };
const BaseInfo = observer(() => { const BaseInfo = observer(() => {
const message = useMessage(); const message = useMessage();
const { currentProjectStore } = useStores(); const { currentProjectStore } = useStores();
const [projectInfo, setProjectInfo] = useState<any>({}); const [projectInfo, setProjectInfo] = useState<any>({});
const [deleteProjectName, setDeleteProjectName] = useState(""); const [deleteProjectName, setDeleteProjectName] = useState("");
const [nameCheck, setNameCheck] = useState({ const [nameCheck, setNameCheck] = useState({
error: false, error: false,
help: "", help: "",
}); });
const currentUserName = JSON.parse( const currentUserName = JSON.parse(
localStorage.getItem("userInfo") || "{}" localStorage.getItem("userInfo") || "{}"
).name; ).name;
// 是否拥有编辑权限 // 是否拥有编辑权限
const hasEditAuth = useMemo(() => { const hasEditAuth = useMemo(() => {
if (!currentUserName) { if (!currentUserName) {
return false; return false;
} else if (!projectInfo.members) { } else if (!projectInfo.members) {
return false; return false;
} else { } else {
return projectInfo.members.some((item: any) => { return projectInfo.members.some((item: any) => {
return ( return (
item.username === currentUserName && item.projectRole === "OWNER" item.username === currentUserName && item.projectRole === "OWNER"
); );
}); });
} }
}, [currentUserName, projectInfo]); }, [currentUserName, projectInfo]);
const { run, loading } = useMyRequest(getProject, { const { run, loading } = useMyRequest(getProject, {
onSuccess: (result: any) => { onSuccess: (result: any) => {
setProjectInfo(result.data); setProjectInfo(result.data);
}, },
}); });
useEffect(() => { useEffect(() => {
run({ run({
id: currentProjectStore.currentProjectInfo.id as string, id: currentProjectStore.currentProjectInfo.id as string,
}); });
}, [currentProjectStore.currentProjectInfo.id, run]); }, [currentProjectStore.currentProjectInfo.id, run]);
const [zoneIdMap, setZoneIdMap] = useState<Map<string, string>>(new Map()); const [zoneIdMap, setZoneIdMap] = useState<Map<string, string>>(new Map());
const [zoneIdOptions, setZoneIdOptions] = useState<Array<zoneIdOption>>([]); const [zoneIdOptions, setZoneIdOptions] = useState<Array<zoneIdOption>>([]);
// 获取计算区信息 // 获取计算区信息
const { run: getZone } = useMyRequest(hpczone, { const { run: getZone } = useMyRequest(hpczone, {
onSuccess: (result: any) => { onSuccess: (result: any) => {
setZoneIdOptions(result); setZoneIdOptions(result);
let zoneMap: Map<string, string> = new Map(); let zoneMap: Map<string, string> = new Map();
result.forEach((item: zoneIdOption) => { result.forEach((item: zoneIdOption) => {
zoneMap.set(item.id, item.name); zoneMap.set(item.id, item.name);
}); });
setZoneIdMap(zoneMap); setZoneIdMap(zoneMap);
}, },
}); });
useEffect(() => { useEffect(() => {
getZone(); getZone();
}, [getZone]); }, [getZone]);
// 项目信息展示数据转换 // 项目信息展示数据转换
const infoList = useMemo(() => { const infoList = useMemo(() => {
return [ return [
{ {
label: "项目名称:", label: "项目名称:",
value: projectInfo.name, value: projectInfo.name,
}, },
{ {
label: "项目描述:", label: "项目描述:",
value: projectInfo.desc, value: projectInfo.desc,
}, },
{ {
label: "计算区:", label: "计算区:",
value: zoneIdMap.get(projectInfo.zoneId) || projectInfo.zoneId, value: zoneIdMap.get(projectInfo.zoneId) || projectInfo.zoneId,
}, },
{ {
label: "创建人:", label: "创建人:",
value: projectInfo.owner, value: projectInfo.owner,
}, },
{ {
label: "扣费账号:", label: "扣费账号:",
value: projectInfo.tenantUser, value: projectInfo.tenantUser,
}, },
]; ];
}, [projectInfo, zoneIdMap]); }, [projectInfo, zoneIdMap]);
const checkName = (name: string, showMessage = false) => { const checkName = (name: string, showMessage = false) => {
let help = ""; let help = "";
if (name) { if (name) {
if (name.length > 30) { if (name.length > 30) {
help = "格式不正确,必须在30字符以内,仅限大小写字母、数字、中文"; help = "格式不正确,必须在30字符以内,仅限大小写字母、数字、中文";
setNameCheck({ setNameCheck({
error: true, error: true,
help, help,
}); });
showMessage && message.error(help); showMessage && message.error(help);
return false; return false;
} else if (checkIsNumberLetterChinese(name)) { } else if (checkIsNumberLetterChinese(name)) {
setNameCheck({ setNameCheck({
error: false, error: false,
help: "", help: "",
}); });
return true; return true;
} else { } else {
help = "格式不正确,必须在30字符以内,仅限大小写字母、数字、中文"; help = "格式不正确,必须在30字符以内,仅限大小写字母、数字、中文";
setNameCheck({ setNameCheck({
error: true, error: true,
help, help,
}); });
showMessage && message.error(help); showMessage && message.error(help);
return false; return false;
} }
} else { } else {
help = "项目名称不能为空"; help = "项目名称不能为空";
setNameCheck({ setNameCheck({
error: true, error: true,
help, help,
}); });
showMessage && message.error(help); showMessage && message.error(help);
return false; return false;
} }
}; };
const nameChange = (e: any) => { const nameChange = (e: any) => {
setProjectInfo({ setProjectInfo({
...projectInfo, ...projectInfo,
name: e.target.value, name: e.target.value,
}); });
checkName(e.target.value); checkName(e.target.value);
// setNameCheck // setNameCheck
}; };
const descChange = (e: any) => { const descChange = (e: any) => {
setProjectInfo({ setProjectInfo({
...projectInfo, ...projectInfo,
desc: e.target.value, desc: e.target.value,
}); });
}; };
const { run: updateProjectRun, loading: updateLoading } = useMyRequest( const { run: updateProjectRun, loading: updateLoading } = useMyRequest(
updateProject, updateProject,
{ {
onSuccess: async (result: any) => { onSuccess: async (result: any) => {
message.success("修改成功"); message.success("修改成功");
const projectList = await getProjectList(); const projectList = await getProjectList();
currentProjectStore.setProjectList(projectList); currentProjectStore.setProjectList(projectList);
currentProjectStore.changeProject(projectInfo); currentProjectStore.changeProject(projectInfo);
}, },
} }
); );
// 修改项目 // 修改项目
const handleClickUpdate = () => { const handleClickUpdate = () => {
if (checkName(projectInfo.name, true)) { if (checkName(projectInfo.name, true)) {
updateProjectRun({ ...projectInfo, product: "CADD" }); updateProjectRun({ ...projectInfo, product: "cadd" });
} else { } else {
return; return;
} }
}; };
const { run: deleteProjectRun, loading: deleteLoading } = useMyRequest( const { run: deleteProjectRun, loading: deleteLoading } = useMyRequest(
deleteProject, deleteProject,
{ {
onSuccess: async (result: any) => { onSuccess: async (result: any) => {
message.success("删除成功"); message.success("删除成功");
DialogRef.current.handleClose(); DialogRef.current.handleClose();
const projectList = await getProjectList(); const projectList = await getProjectList();
currentProjectStore.setProjectList(projectList); currentProjectStore.setProjectList(projectList);
// 项目删完了 // 项目删完了
if (projectList.length === 0) { if (projectList.length === 0) {
currentProjectStore.changeProject({}); currentProjectStore.changeProject({});
localStorage.setItem("fileServerEndPoint", ""); localStorage.setItem("fileServerEndPoint", "");
setProjectInfo({}); setProjectInfo({});
} else { } else {
projectList[0].filetoken = getFiletokenAccordingToId( projectList[0].filetoken = getFiletokenAccordingToId(
projectList[0].id projectList[0].id
); );
currentProjectStore.changeProject(projectList[0]); currentProjectStore.changeProject(projectList[0]);
setFileServerEndPointLocalStorage(projectList[0].zoneId); setFileServerEndPointLocalStorage(projectList[0].zoneId);
getFiletokenAccordingToId(projectList[0].id).then((res) => { getFiletokenAccordingToId(projectList[0].id).then((res) => {
projectList[0].filetoken = res; projectList[0].filetoken = res;
currentProjectStore.changeProject(projectList[0]); currentProjectStore.changeProject(projectList[0]);
}); });
setProjectInfo(projectList[0]); setProjectInfo(projectList[0]);
} }
}, },
} }
); );
let DialogRef: any = React.createRef(); let DialogRef: any = React.createRef();
// 显示删除弹窗 // 显示删除弹窗
const handleClickDelete = () => { const handleClickDelete = () => {
DialogRef.current.handleClickOpen(); DialogRef.current.handleClickOpen();
setDeleteProjectName(""); setDeleteProjectName("");
}; };
const deleteProjectNameChange = (e: any) => { const deleteProjectNameChange = (e: any) => {
setDeleteProjectName(e.target.value); setDeleteProjectName(e.target.value);
}; };
// 删除项目 // 删除项目
const handleSubmitDelete = () => { const handleSubmitDelete = () => {
if ( if (
deleteProjectName === toJS(currentProjectStore.currentProjectInfo.name) deleteProjectName === toJS(currentProjectStore.currentProjectInfo.name)
) { ) {
deleteProjectRun({ id: projectInfo.id }); deleteProjectRun({ id: projectInfo.id });
} else { } else {
message.error("项目名称不匹配"); message.error("项目名称不匹配");
} }
}; };
if (loading) { if (loading) {
return ( return (
<div className={style.loadingBox}> <div className={style.loadingBox}>
<Loading /> <Loading />
</div> </div>
); );
} else if (!hasEditAuth) { } else if (!hasEditAuth) {
return <InformationDisplay infoList={infoList} />; return <InformationDisplay infoList={infoList} />;
} else { } else {
return ( return (
<div className={style.projectInfoList}> <div className={style.projectInfoList}>
<div className={style.projectInfoListLi}> <div className={style.projectInfoListLi}>
<div <div
className={classnames({ className={classnames({
[style.projectInfoListLiLabel]: true, [style.projectInfoListLiLabel]: true,
[style.projectInfoName]: true, [style.projectInfoName]: true,
})} })}
> >
项目名称 项目名称
</div> </div>
<TextField <TextField
required required
error={nameCheck.error} error={nameCheck.error}
id="name" id="name"
variant="outlined" variant="outlined"
value={projectInfo.name} value={projectInfo.name}
onChange={nameChange} onChange={nameChange}
helperText={nameCheck.help} helperText={nameCheck.help}
size="small" size="small"
sx={{ sx={{
width: "560px", width: "560px",
}} }}
/> />
{/* <input {/* <input
value={projectInfo.name} value={projectInfo.name}
className={style.projectInfoListLiValue} className={style.projectInfoListLiValue}
onChange={nameChange} onChange={nameChange}
maxLength={30} maxLength={30}
placeholder="请输入项目名称" placeholder="请输入项目名称"
></input> */} ></input> */}
</div> </div>
<div className={style.projectInfoListLi}> <div className={style.projectInfoListLi}>
<div className={style.projectInfoListLiLabel}>项目描述</div> <div className={style.projectInfoListLiLabel}>项目描述</div>
<textarea <textarea
value={projectInfo.desc} value={projectInfo.desc}
className={classnames({ className={classnames({
[style.projectInfoListLiValue]: true, [style.projectInfoListLiValue]: true,
[style.projectInfoTextarea]: true, [style.projectInfoTextarea]: true,
})} })}
onChange={descChange} onChange={descChange}
placeholder="项目描述限制100字以内" placeholder="项目描述限制100字以内"
maxLength={100} maxLength={100}
></textarea> ></textarea>
</div> </div>
<div className={style.projectInfoListLi}> <div className={style.projectInfoListLi}>
<div className={style.projectInfoListLiLabel}>计算区</div> <div className={style.projectInfoListLiLabel}>计算区</div>
<select <select
value={projectInfo.zoneId} value={projectInfo.zoneId}
disabled disabled
className={classnames({ className={classnames({
[style.projectInfoListLiValue]: true, [style.projectInfoListLiValue]: true,
[style.projectInfoSelect]: true, [style.projectInfoSelect]: true,
[style.disable]: true, [style.disable]: true,
})} })}
> >
{zoneIdOptions.map((option) => ( {zoneIdOptions.map((option) => (
<option key={option.id} value={option.id}> <option key={option.id} value={option.id}>
{option.name} {option.name}
</option> </option>
))} ))}
</select> </select>
</div> </div>
<div className={style.projectInfoListLi}> <div className={style.projectInfoListLi}>
<div className={style.projectInfoListLiLabel}>创建人</div> <div className={style.projectInfoListLiLabel}>创建人</div>
<input <input
value={projectInfo.owner} value={projectInfo.owner}
disabled disabled
className={classnames({ className={classnames({
[style.projectInfoListLiValue]: true, [style.projectInfoListLiValue]: true,
[style.disable]: true, [style.disable]: true,
})} })}
></input> ></input>
</div> </div>
<div className={style.projectInfoListLi}> <div className={style.projectInfoListLi}>
<div className={style.projectInfoListLiLabel}>扣费账号</div> <div className={style.projectInfoListLiLabel}>扣费账号</div>
<input <input
value={projectInfo.tenantUser} value={projectInfo.tenantUser}
disabled disabled
className={classnames({ className={classnames({
[style.projectInfoListLiValue]: true, [style.projectInfoListLiValue]: true,
[style.disable]: true, [style.disable]: true,
})} })}
></input> ></input>
</div> </div>
<div className={style.projectInfoListLi}> <div className={style.projectInfoListLi}>
<LoadingButton <LoadingButton
variant="outlined" variant="outlined"
className={style.updateButton} className={style.updateButton}
onClick={handleClickUpdate} onClick={handleClickUpdate}
loading={updateLoading} loading={updateLoading}
> >
保存修改 保存修改
</LoadingButton> </LoadingButton>
</div> </div>
<div className={style.projectInfoListLi}> <div className={style.projectInfoListLi}>
<div className={style.projectInfoListLiLabel}>删除项目</div> <div className={style.projectInfoListLiLabel}>删除项目</div>
<div className={style.projectInfoListLiText}> <div className={style.projectInfoListLiText}>
删除项目将删除其存储的数据和所有相关资源,并且已删除的项目无法恢复!请谨慎操作! 删除项目将删除其存储的数据和所有相关资源,并且已删除的项目无法恢复!请谨慎操作!
</div> </div>
<Button <Button
variant="contained" variant="contained"
className={style.updateButton} className={style.updateButton}
onClick={handleClickDelete} onClick={handleClickDelete}
style={{ style={{
backgroundColor: "#fff", backgroundColor: "#fff",
color: "#FF4E4E", color: "#FF4E4E",
border: "1px solid #FF4E4E", border: "1px solid #FF4E4E",
}} }}
> >
删除项目 删除项目
</Button> </Button>
</div> </div>
<MyDialog <MyDialog
handleSubmit={handleSubmitDelete} handleSubmit={handleSubmitDelete}
onRef={DialogRef} onRef={DialogRef}
title="删除项目" title="删除项目"
submitloading={deleteLoading} submitloading={deleteLoading}
submitStyle={{ background: "#FF4E4E", color: "#fff" }} submitStyle={{ background: "#FF4E4E", color: "#fff" }}
> >
<div className={style.deleteBox}> <div className={style.deleteBox}>
<div className={style.deleteText1}> <div className={style.deleteText1}>
您要删除本项目。已删除的项目将无法恢复!您真的确定吗? 您要删除本项目。已删除的项目将无法恢复!您真的确定吗?
</div> </div>
<div className={style.deleteText2}> <div className={style.deleteText2}>
此操作可能会导致数据丢失。为防止意外操作,我们要求您确认您的操作。 此操作可能会导致数据丢失。为防止意外操作,我们要求您确认您的操作。
</div> </div>
<div className={style.deleteText3}> <div className={style.deleteText3}>
请输入“ 请输入“
<span className={style.deleteProjectName}> <span className={style.deleteProjectName}>
{currentProjectStore.currentProjectInfo.name} {currentProjectStore.currentProjectInfo.name}
</span> </span>
”以确认此操作。 ”以确认此操作。
</div> </div>
<input <input
value={deleteProjectName} value={deleteProjectName}
className={style.deleteProjectInput} className={style.deleteProjectInput}
onChange={deleteProjectNameChange} onChange={deleteProjectNameChange}
maxLength={30} maxLength={30}
placeholder="请输入项目名称" placeholder="请输入项目名称"
></input> ></input>
</div> </div>
</MyDialog> </MyDialog>
</div> </div>
); );
} }
}); });
export default memo(BaseInfo); export default memo(BaseInfo);
...@@ -28,6 +28,7 @@ export interface IParameter { ...@@ -28,6 +28,7 @@ export interface IParameter {
choices: Array<IChoice>; choices: Array<IChoice>;
error?: boolean; error?: boolean;
helperText?: string; helperText?: string;
parameterGroup?: string;
} }
export type IExecutionStatus = "Pending" | "Running" | "Done" | "Failed"; export type IExecutionStatus = "Pending" | "Running" | "Done" | "Failed";
...@@ -36,6 +37,7 @@ export interface ITask { ...@@ -36,6 +37,7 @@ export interface ITask {
id: string; id: string;
title: string; title: string;
description: string; description: string;
version?: string;
position: { position: {
x: number; x: number;
y: number; y: number;
......
...@@ -8,7 +8,7 @@ export const templateConfigJson = { ...@@ -8,7 +8,7 @@ export const templateConfigJson = {
languageVersion: "draft-2", languageVersion: "draft-2",
tags: ["Docking", "Gromax"], tags: ["Docking", "Gromax"],
source: "BASE64_ENCODED_WDL/CWL", source: "BASE64_ENCODED_WDL/CWL",
productId: "CADD", productId: "cadd",
id: "123", id: "123",
tasks: [ tasks: [
{ {
...@@ -160,7 +160,7 @@ export const templateConfigJson = { ...@@ -160,7 +160,7 @@ export const templateConfigJson = {
// languageVersion: "1.0", // languageVersion: "1.0",
// tags: ["Docking", "Gromax"], // tags: ["Docking", "Gromax"],
// source: "", // source: "",
// productId: "CADD", // productId: "cadd",
// updateTime: "20220622", // updateTime: "20220622",
// tasks: [ // tasks: [
// { // {
...@@ -514,7 +514,7 @@ export const templateConfigJson = { ...@@ -514,7 +514,7 @@ export const templateConfigJson = {
// languageVersion: "draft-2", // languageVersion: "draft-2",
// tags: ["Docking", "Gromax"], // tags: ["Docking", "Gromax"],
// source: "BASE64_ENCODED_WDL/CWL", // source: "BASE64_ENCODED_WDL/CWL",
// productId: "CADD", // productId: "cadd",
// tasks: [ // tasks: [
// { // {
// id: "批式算子ID1", // id: "批式算子ID1",
......
...@@ -9,214 +9,214 @@ import { getProjectList } from "../../project"; ...@@ -9,214 +9,214 @@ import { getProjectList } from "../../project";
import { useStores } from "@/store"; import { useStores } from "@/store";
import { checkIsNumberLetterChinese } from "@/utils/util"; import { checkIsNumberLetterChinese } from "@/utils/util";
import { import {
setFileServerEndPointLocalStorage, setFileServerEndPointLocalStorage,
getFiletokenAccordingToId, getFiletokenAccordingToId,
} from "@/views/Project/project"; } from "@/views/Project/project";
type zoneIdOption = { type zoneIdOption = {
id: string; id: string;
name: string; name: string;
}; };
const AddProject = (props: any) => { const AddProject = (props: any) => {
const { currentProjectStore } = useStores(); const { currentProjectStore } = useStores();
const message = useMessage(); const message = useMessage();
let DialogRef: any = React.createRef(); let DialogRef: any = React.createRef();
const [name, setName] = useState(""); const [name, setName] = useState("");
const [nameCheck, setNameCheck] = useState({ const [nameCheck, setNameCheck] = useState({
error: false, error: false,
help: "", help: "",
}); });
const [desc, setDesc] = useState(""); const [desc, setDesc] = useState("");
const [descCheck, setDescCheck] = useState({ const [descCheck, setDescCheck] = useState({
error: false, error: false,
help: "", help: "",
}); });
const [zoneId, setZoneId] = useState(""); const [zoneId, setZoneId] = useState("");
const [zoneIdOptions, setZoneIdOptions] = useState<Array<zoneIdOption>>([]); const [zoneIdOptions, setZoneIdOptions] = useState<Array<zoneIdOption>>([]);
const [submitloading, setSubmitloading] = useState(false); const [submitloading, setSubmitloading] = useState(false);
useImperativeHandle(props.onRef, () => { useImperativeHandle(props.onRef, () => {
return { return {
handleClickOpen: handleClickOpen, handleClickOpen: handleClickOpen,
}; };
}); });
// 设置计算区 // 设置计算区
const { run } = useMyRequest(hpczone, { const { run } = useMyRequest(hpczone, {
onSuccess: (result: any) => { onSuccess: (result: any) => {
setZoneIdOptions(result); setZoneIdOptions(result);
setZoneId(result[0].id || ""); setZoneId(result[0].id || "");
}, },
}); });
const { run: addProjectRun } = useMyRequest(addProject, { const { run: addProjectRun } = useMyRequest(addProject, {
onBefore: () => { onBefore: () => {
setSubmitloading(true); setSubmitloading(true);
}, },
onSuccess: async (result: any) => { onSuccess: async (result: any) => {
if (result.data) { if (result.data) {
setSubmitloading(false); setSubmitloading(false);
DialogRef.current.handleClose(); DialogRef.current.handleClose();
message.success("新建项目成功"); message.success("新建项目成功");
const projectList = await getProjectList(); const projectList = await getProjectList();
currentProjectStore.setProjectList(projectList); currentProjectStore.setProjectList(projectList);
let project: any = {}; let project: any = {};
projectList.forEach((item: any) => { projectList.forEach((item: any) => {
if (item.name === name) { if (item.name === name) {
project = { ...item }; project = { ...item };
} }
}); });
currentProjectStore.changeProject(project); currentProjectStore.changeProject(project);
setFileServerEndPointLocalStorage(project.zoneId); setFileServerEndPointLocalStorage(project.zoneId);
getFiletokenAccordingToId(project.id).then((res) => { getFiletokenAccordingToId(project.id).then((res) => {
project.filetoken = res; project.filetoken = res;
currentProjectStore.changeProject(project); currentProjectStore.changeProject(project);
}); });
} }
}, },
onError: () => { onError: () => {
setSubmitloading(false); setSubmitloading(false);
}, },
}); });
useEffect(() => { useEffect(() => {
run(); run();
}, [run]); }, [run]);
const handleClickOpen = () => { const handleClickOpen = () => {
DialogRef.current.handleClickOpen(); DialogRef.current.handleClickOpen();
initData(); initData();
}; };
const initData = () => { const initData = () => {
setName(""); setName("");
setDesc(""); setDesc("");
if (zoneIdOptions.length > 0) { if (zoneIdOptions.length > 0) {
setZoneId(zoneIdOptions[0].id); setZoneId(zoneIdOptions[0].id);
} }
}; };
const checkName = (name: string) => { const checkName = (name: string) => {
if (name) { if (name) {
if (name.length > 30) { if (name.length > 30) {
setNameCheck({ setNameCheck({
error: true, error: true,
help: "格式不正确,必须在30字符以内,仅限大小写字母、数字、中文", help: "格式不正确,必须在30字符以内,仅限大小写字母、数字、中文",
}); });
} else if (checkIsNumberLetterChinese(name)) { } else if (checkIsNumberLetterChinese(name)) {
setNameCheck({ setNameCheck({
error: false, error: false,
help: "", help: "",
}); });
} else { } else {
setNameCheck({ setNameCheck({
error: true, error: true,
help: "格式不正确,必须在30字符以内,仅限大小写字母、数字、中文", help: "格式不正确,必须在30字符以内,仅限大小写字母、数字、中文",
}); });
} }
} else { } else {
setNameCheck({ setNameCheck({
error: true, error: true,
help: "项目名称不能为空", help: "项目名称不能为空",
}); });
} }
}; };
const handleNameChange = (e: any) => { const handleNameChange = (e: any) => {
const name = e.target.value; const name = e.target.value;
setName(name); setName(name);
checkName(name); checkName(name);
}; };
const handleZoneIdChange = (e: any) => { const handleZoneIdChange = (e: any) => {
setZoneId(e.target.value); setZoneId(e.target.value);
}; };
const handleDescChange = (e: any) => { const handleDescChange = (e: any) => {
const desc = e.target.value; const desc = e.target.value;
setDesc(desc); setDesc(desc);
if (desc.length > 100) { if (desc.length > 100) {
setDescCheck({ setDescCheck({
error: true, error: true,
help: "格式不正确,必须在100字符以内", help: "格式不正确,必须在100字符以内",
}); });
} else { } else {
setDescCheck({ setDescCheck({
error: false, error: false,
help: "", help: "",
}); });
} }
}; };
const handleSubmit = () => { const handleSubmit = () => {
checkName(name); checkName(name);
if (!nameCheck.error && !descCheck.error && zoneId) { if (!nameCheck.error && !descCheck.error && zoneId) {
addProjectRun({ addProjectRun({
name, name,
desc, desc,
zoneId, zoneId,
product: "CADD", product: "cadd",
}); });
} else { } else {
return; return;
} }
}; };
const handleFromBox = (e: React.SyntheticEvent) => { const handleFromBox = (e: React.SyntheticEvent) => {
e.nativeEvent.stopImmediatePropagation(); e.nativeEvent.stopImmediatePropagation();
}; };
return ( return (
<MyDialog <MyDialog
handleSubmit={handleSubmit} handleSubmit={handleSubmit}
onRef={DialogRef} onRef={DialogRef}
title="新建项目" title="新建项目"
submitloading={submitloading} submitloading={submitloading}
> >
<div className={style.formBox} onClick={handleFromBox}> <div className={style.formBox} onClick={handleFromBox}>
<TextField <TextField
required required
error={nameCheck.error} error={nameCheck.error}
id="name" id="name"
label="项目名称" label="项目名称"
variant="outlined" variant="outlined"
value={name} value={name}
onChange={handleNameChange} onChange={handleNameChange}
helperText={nameCheck.help} helperText={nameCheck.help}
size="small" size="small"
/> />
<TextField <TextField
id="zoneId" id="zoneId"
select select
required required
label="计算区" label="计算区"
value={zoneId} value={zoneId}
onChange={handleZoneIdChange} onChange={handleZoneIdChange}
variant="outlined" variant="outlined"
onClick={handleFromBox} onClick={handleFromBox}
size="small" size="small"
> >
{zoneIdOptions && {zoneIdOptions &&
zoneIdOptions.map((option) => ( zoneIdOptions.map((option) => (
<MenuItem key={option.id} value={option.id}> <MenuItem key={option.id} value={option.id}>
{option.name} {option.name}
</MenuItem> </MenuItem>
))} ))}
</TextField> </TextField>
<TextField <TextField
value={desc} value={desc}
error={descCheck.error} error={descCheck.error}
id="desc" id="desc"
label="项目描述" label="项目描述"
multiline multiline
rows={4} rows={4}
placeholder="请输入项目描述" placeholder="请输入项目描述"
onChange={handleDescChange} onChange={handleDescChange}
helperText={descCheck.help} helperText={descCheck.help}
size="small" size="small"
/> />
</div> </div>
</MyDialog> </MyDialog>
); );
}; };
export default AddProject; export default AddProject;
...@@ -13,7 +13,7 @@ import { ...@@ -13,7 +13,7 @@ import {
} from "@/api/project_api"; } from "@/api/project_api";
export const getProjectList = async () => { export const getProjectList = async () => {
const res = await getProjectListApi({ product: "CADD" }); const res = await getProjectListApi({ product: "cadd" });
return res.data; return res.data;
}; };
......
.parameterSetting {
background-color: #fff;
height: calc(100vh - 140px);
width: 360px;
box-sizing: border-box;
overflow-y: scroll;
padding: 0 24px;
}
.taskInfo {
margin-bottom: 20px;
position: relative;
}
.taskTitle {
color: rgba(30, 38, 51, 1);
font-size: 16px;
line-height: 24px;
margin-bottom: 8px;
font-weight: 600;
}
.taskVersion {
color: rgba(138, 144, 153, 1);
font-size: 12px;
line-height: 20px;
margin-bottom: 8px;
}
.taskDescription {
font-size: 12px;
color: rgba(86, 92, 102, 1);
line-height: 20px;
position: relative;
max-height: 60px;
overflow: hidden;
}
.taskDescriptionAll {
font-size: 12px;
color: rgba(86, 92, 102, 1);
line-height: 20px;
position: relative;
}
.taskDescriptionHeight {
font-size: 12px;
color: rgba(86, 92, 102, 1);
line-height: 20px;
position: absolute;
top: 0;
visibility: hidden;
max-height: 80px;
overflow: hidden;
}
.descButton {
position: absolute;
bottom: 0;
right: 0;
color: rgba(19, 112, 255, 1);
padding-left: 30px;
background-image: linear-gradient(
to right,
rgba(255, 255, 255, 0) 0%,
rgba(255, 255, 255, 1) 50%,
rgba(255, 255, 255, 1) 100%
);
cursor: pointer;
}
.noData {
height: calc(100vh - 140px);
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
.noDataImg {
margin-bottom: 8px;
}
.noDataText {
font-size: 14px;
line-height: 22px;
color: rgba(138, 144, 153, 1);
}
import styles from "./index.module.css";
import {
ITask,
IParameter,
} from "../../../Project/ProjectSubmitWork/interface";
import noTemplate from "@/assets/project/noTemplate.svg";
import { useEffect, useMemo, useRef, useState } from "react";
import classNames from "classnames";
type IParameterSettingProps = {
templateConfigInfo: ITask[];
taskId: string;
};
const ParameterSetting = (props: IParameterSettingProps) => {
const { templateConfigInfo, taskId } = props;
const [descRef, setDescRef] = useState<any>(useRef());
const [descHeight, setDescHeight] = useState(0);
const [isShowAllDese, setIsShowAllDese] = useState(false);
useEffect(() => {
const div = document.getElementById("descHeight");
if (div) {
setDescHeight(div.offsetHeight);
}
}, [descRef]);
const taskInfo: ITask | null = useMemo(() => {
if (!taskId) {
return null;
} else {
const randerTaskArr = templateConfigInfo.filter(
(task) => task.id === taskId
);
if (randerTaskArr.length > 0) {
return randerTaskArr[0];
} else {
return null;
}
}
}, [templateConfigInfo, taskId]);
// 输入参数
const inParameters: Array<IParameter> = useMemo(() => {
if (!taskInfo) {
return [];
} else {
return taskInfo.parameters.filter(
(parameter) => parameter.parameterGroup === "in"
);
}
}, [taskInfo]);
// 输出参数
const outParameters: Array<IParameter> = useMemo(() => {
if (!taskInfo) {
return [];
} else {
return taskInfo.parameters.filter(
(parameter) => parameter.parameterGroup === "out"
);
}
}, [taskInfo]);
// 基础参数
const basisParameters: Array<IParameter> = useMemo(() => {
if (!taskInfo) {
return [];
} else {
return taskInfo.parameters.filter(
(parameter) => parameter.parameterGroup === "basis"
);
}
}, [taskInfo]);
// 高级选项
const seniorParameters: Array<IParameter> = useMemo(() => {
if (!taskInfo) {
return [];
} else {
return taskInfo.parameters.filter(
(parameter) => parameter.parameterGroup === "senior"
);
}
}, [taskInfo]);
// 硬件配置
const hardwareParameters: Array<IParameter> = useMemo(() => {
if (!taskInfo) {
return [];
} else {
return taskInfo.parameters.filter(
(parameter) => parameter.parameterGroup === "hardware"
);
}
}, [taskInfo]);
return (
<div className={styles.parameterSetting}>
{/* <div className={styles.taskInfo}>
<div className={styles.taskTitle}>taskTitle</div>
<div className={styles.taskVersion}>version</div>
<div
className={styles.taskDescriptionHeight}
id="descHeight"
ref={descRef}
>
埃里克梵蒂冈和艰苦拉萨规定了卡号是德国埃里克梵蒂冈和艰苦拉萨规定了卡号是德国埃里克梵蒂冈和艰苦拉萨规定了卡号是德国埃里克梵蒂冈和艰苦拉萨规定了卡号是德国埃里克梵蒂冈和艰苦拉萨规定了卡号是德国埃里克梵蒂冈和艰苦拉萨规定了卡号是德国
</div>
<div
className={classNames({
[styles.taskDescriptionAll]: isShowAllDese,
[styles.taskDescription]: !isShowAllDese,
})}
>
埃里克梵蒂冈和艰苦拉萨规定了卡号是德国埃里克梵蒂冈和艰苦拉萨规定了卡号是德国埃里克梵蒂冈和艰苦拉萨规定了卡号是德国埃里克梵蒂冈和艰苦拉萨规定了卡号是德国埃里克梵蒂冈和艰苦拉萨规定了卡号是德国埃里克梵蒂冈和艰苦拉萨规定了卡号是德国
{descHeight > 60 && (
<span
className={styles.descButton}
onClick={() => setIsShowAllDese(!isShowAllDese)}
>
{isShowAllDese ? "收起" : "展开"}
</span>
)}
</div>
</div> */}
{taskInfo && (
<div className={styles.taskInfo}>
<div className={styles.taskTitle}>{taskInfo.title || "-"}</div>
<div className={styles.taskVersion}>
版本:{taskInfo.version || "-"}
</div>
<div
className={styles.taskDescriptionHeight}
id="descHeight"
ref={descRef}
>
{taskInfo.description || "-"}
</div>
<div
className={classNames({
[styles.taskDescriptionAll]: isShowAllDese,
[styles.taskDescription]: !isShowAllDese,
})}
>
{taskInfo.description || "-"}
{descHeight > 60 && (
<span
className={styles.descButton}
onClick={() => setIsShowAllDese(!isShowAllDese)}
>
{isShowAllDese ? "收起" : "展开"}
</span>
)}
</div>
</div>
)}
{/* {!taskInfo && (
<div className={styles.noData}>
<img src={noTemplate} alt="" className={styles.noDataImg} />
<span className={styles.noDataText}>选中任意算子进行参数设置</span>
</div>
)} */}
</div>
);
};
export default ParameterSetting;
...@@ -15,10 +15,10 @@ import RadioGroupOfButtonStyle from "@/components/CommonComponents/RadioGroupOfB ...@@ -15,10 +15,10 @@ import RadioGroupOfButtonStyle from "@/components/CommonComponents/RadioGroupOfB
import ButtonComponent from "@/components/mui/Button"; import ButtonComponent from "@/components/mui/Button";
import OperatorList from "./components/OperatorList"; import OperatorList from "./components/OperatorList";
import Flow from "../Project/components/Flow"; import Flow from "../Project/components/Flow";
import ParameterSetting from "./components/ParameterSetting";
import { ITask } from "../Project/ProjectSubmitWork/interface"; import { ITask } from "../Project/ProjectSubmitWork/interface";
import styles from "./index.module.css"; import styles from "./index.module.css";
import { style } from "@mui/system";
const radioOptions = [ const radioOptions = [
{ {
...@@ -102,7 +102,12 @@ const WorkFlowEdit = (props: IProps) => { ...@@ -102,7 +102,12 @@ const WorkFlowEdit = (props: IProps) => {
/> />
</div> </div>
)} )}
{leftContentType !== "list" && <div>123</div>} {leftContentType !== "list" && (
<ParameterSetting
templateConfigInfo={templateConfigInfo}
taskId={""}
/>
)}
</div> </div>
<div id="workFlowEditRight"> <div id="workFlowEditRight">
<Flow tasks={templateConfigInfo} /> <Flow tasks={templateConfigInfo} />
......
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