Commit 03e84843 authored by wuyongsheng's avatar wuyongsheng

Merge branch 'feat-20220801' into 'release'

Feat 20220801

See merge request !82
parents 82f9cbc7 5a740a66
......@@ -2,7 +2,7 @@
* @Author: 吴永生#A02208 yongsheng.wu@wholion.com
* @Date: 2022-06-13 09:56:57
* @LastEditors: 吴永生 15770852798@163.com
* @LastEditTime: 2022-08-15 17:10:49
* @LastEditTime: 2022-09-01 15:30:28
* @FilePath: /bkunyun/src/api/api_manager.ts
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
......@@ -45,6 +45,9 @@ const RESTAPI = {
API_TASK_OVERVIEW_LIST:`${BACKEND_API_URI_PREFIX}/cpp/workflowJobInformation`, // 查询任务概览
API_OPERATOR_LISTSTREAMACTORS:`${BACKEND_API_URI_PREFIX}/cpp/workflow/liststreamactors`, // 获取流算子列表,可用于模糊查询,返回所有版本流算子
API_SAVE_BATCHACTOR:`${BACKEND_API_URI_PREFIX}/cpp/workflow/savebatchactor`, // 保存批算子
API_PROJECT_USERS_LIST:`${BACKEND_API_URI_PREFIX}/cpp/project/listusers`, // 获取项目成员
API_ADD_PROJECT_USER:`${BACKEND_API_URI_PREFIX}/cpp/project/updatemember`, // 添加项目成员
API_GET_PROJECT_POWER:`${BACKEND_API_URI_PREFIX}/cpp/project/listroles`, // 获取项目权限
};
export default RESTAPI;
......@@ -318,6 +318,34 @@ const saveBatchActor = (params: saveBatchParams) => {
});
};
// 获取项目成员
const fetchProjectUsersList = (params: {id: string}) => {
return request({
url: Api.API_PROJECT_USERS_LIST,
method: "get",
params,
});
};
// 修改项目成员信息
const addProjectUser = (id: string, params: any) => {
return request({
url: `${Api.API_ADD_PROJECT_USER}?id=${id}`,
method: "put",
data: params,
});
};
// 获取项目权限
const fetchProjectPower = (params: {id: string}) => {
return request({
url: Api.API_GET_PROJECT_POWER,
method: "get",
params,
});
};
export {
current,
menu,
......@@ -342,5 +370,8 @@ export {
getTaskOverview,
getOperatorList,
saveBatchActor,
fetchFlowOutputNumber
fetchFlowOutputNumber,
fetchProjectUsersList,
addProjectUser,
fetchProjectPower
};
<?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>编组 4</title>
<g id="上线UI" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="切换产品" transform="translate(-337.000000, -190.000000)">
<g id="编组-37" transform="translate(223.000000, 172.000000)">
<g id="编组-34" transform="translate(0.000000, 8.000000)">
<g id="编组-4" transform="translate(114.000000, 10.000000)">
<rect id="矩形" x="0" y="0" width="16" height="16"></rect>
<polyline id="路径-26" stroke="#1370FF" stroke-width="1.5" stroke-linejoin="round" points="4 8.33740166 7.27434245 11 12 5"></polyline>
</g>
</g>
</g>
</g>
</g>
</svg>
\ No newline at end of file
<?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>编组 12备份</title>
<g id="上线UI" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="编组-12备份">
<rect id="矩形" x="0" y="0" width="16" height="16"></rect>
<polygon id="路径-53备份-2" fill="#8A9099" points="4.5 6 11.5 6 8 11"></polygon>
</g>
</g>
</svg>
\ No newline at end of file
......@@ -7,7 +7,7 @@ main::-webkit-scrollbar {
div::-webkit-scrollbar-track,
main::-webkit-scrollbar-track {
background-color: #fff;
background-color: transparent;
-webkit-border-radius: 3em;
-moz-border-radius: 3em;
border-radius: 3em;
......
......@@ -103,7 +103,7 @@ const MyDialog: React.FunctionComponent<IDialogProps> = (props) => {
disabled={disabledConfirm}
isLoadingButton={true}
loading={loading}
style={{ marginLeft: '12px', ...okSx }}
style={{ marginLeft: "12px", ...okSx }}
/>
) : null}
</DialogActions>
......@@ -122,16 +122,13 @@ const MyDialog: React.FunctionComponent<IDialogProps> = (props) => {
"& .MuiPaper-root": {
// 设置最大宽度, 实际宽度让子元素撑大
maxWidth: "1920px",
borderRadius: "8px"
borderRadius: "8px",
},
},
}}
>
{isHideHeader ? null : (
<DialogTitle
id="alert-dialog-title"
sx={{ padding: "20px 24px" }}
>
<DialogTitle id="alert-dialog-title" sx={{ padding: "20px 24px" }}>
<div
style={{
display: "flex",
......@@ -140,10 +137,19 @@ const MyDialog: React.FunctionComponent<IDialogProps> = (props) => {
fontWeight: 600,
}}
>
<span style={{ fontSize: 16, lineHeight: '24px', color: '#1E2633' }}>{title}</span>
<span
style={{ fontSize: 16, lineHeight: "24px", color: "#1E2633" }}
>
{title}
</span>
<CloseIcon
onClick={onClose}
sx={{ color: "#C2C6CC", cursor: "pointer", ":hover": { background: "#f0f2f5", borderRadius: '2px' } }}
sx={{
fontSize: "18px",
color: "#C2C6CC",
cursor: "pointer",
":hover": { background: "#f0f2f5", borderRadius: "2px" },
}}
/>
</div>
</DialogTitle>
......
......@@ -66,6 +66,7 @@ const MyInput = (props: MyInputProps) => {
styleOverrides: {
root: {
top: "-9px",
fontSize: "14px",
},
shrink: {
top: 0,
......
/*
* @Author: 吴永生#A02208 yongsheng.wu@wholion.com
* @Date: 2022-06-11 09:33:46
* @LastEditors: 吴永生#A02208 yongsheng.wu@wholion.com
* @LastEditTime: 2022-06-16 14:21:00
* @LastEditors: 吴永生 15770852798@163.com
* @LastEditTime: 2022-09-01 19:34:26
* @FilePath: /bkunyun/src/components/mui/MyPopover.tsx
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
import * as React from "react";
import { useRef, useEffect, useState } from "react";
import Popover, { PopoverProps } from "@mui/material/Popover";
import Typography from "@mui/material/Typography";
......@@ -17,10 +17,15 @@ interface IProps extends Omit<PopoverProps, "open"> {
children: React.ReactNode;
/** 显示内容 */
content: React.ReactNode;
/** 是否打开 */
open?: boolean;
/** open 修改 */
changeOpen: (val: boolean) => void;
}
const MyPopover = (props: IProps) => {
const [anchorEl, setAnchorEl] = React.useState<any | null>(null);
const [anchorEl, setAnchorEl] = useState<any | null>(null);
const ref = useRef(null);
const {
trigger = "click",
......@@ -28,26 +33,37 @@ const MyPopover = (props: IProps) => {
content,
anchorOrigin,
transformOrigin,
open = false,
changeOpen,
} = props;
const handlePopoverOpen = (event: any) => {
changeOpen(true);
setAnchorEl(event.currentTarget);
};
const handelClick = (event: any) => {
changeOpen(true);
setAnchorEl(event?.currentTarget);
};
const handlePopoverClose = () => {
changeOpen(false);
setAnchorEl(null);
};
const open = Boolean(anchorEl);
useEffect(() => {
if (open) {
setAnchorEl(ref.current);
}
}, [open]);
const id = open ? "simple-popover" : undefined;
return (
<div>
<Typography
ref={ref}
aria-owns={id}
onClick={trigger === "click" ? handelClick : undefined}
onMouseEnter={trigger === "hover" ? handlePopoverOpen : undefined}
......
This diff is collapsed.
......@@ -2,7 +2,7 @@
* @Author: 吴永生 15770852798@163.com
* @Date: 2022-07-26 10:23:43
* @LastEditors: 吴永生 15770852798@163.com
* @LastEditTime: 2022-07-26 11:53:00
* @LastEditTime: 2022-09-01 16:00:34
* @FilePath: /bkunyun/src/components/mui/MyTable/interface.ts
* @Description: 这是默认设置,请设置`customMade`,打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
......@@ -32,7 +32,7 @@ export interface ITableProps {
/** 每行双击事件 */
onDoubleClick?: any,
/** 是否loading */
load?: boolean,
loading?: boolean,
/** table size */
size?: any,
/** 选中的checkbox数据 */
......@@ -71,4 +71,6 @@ export interface ITableProps {
onRef?: any;
/** 手型 */
cursor?: string
/** 没有数据文案 */
noDataText?: string
}
\ No newline at end of file
......@@ -2,7 +2,7 @@
* @Author: 吴永生#A02208 yongsheng.wu@wholion.com
* @Date: 2022-05-31 10:18:13
* @LastEditors: 吴永生 15770852798@163.com
* @LastEditTime: 2022-09-01 11:20:24
* @LastEditTime: 2022-09-01 19:34:35
* @FilePath: /bkunyun/src/views/Project/ProjectSetting/index.tsx
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
......
......@@ -9,6 +9,13 @@ const roleList: any[] = [
{ OWNER: 4 }
]
export const roleMap = {
VIEWER: '查看者',
USER: '研究员',
MANAGER: '管理员',
OWNER: '所有者',
}
const usePass = () => {
const { permissionStore } = useStores();
const { currentProjectStore } = useStores();
......
......@@ -18,6 +18,7 @@ type projectInfo = {
type productInfo = {
id?: string;
name?: string;
path?: string;
};
/** 用户信息 */
......
/*
* @Author: 吴永生#A02208 yongsheng.wu@wholion.com
* @Date: 2022-06-13 17:00:19
* @LastEditors: 吴永生#A02208 yongsheng.wu@wholion.com
* @LastEditTime: 2022-06-16 09:43:42
* @LastEditors: 吴永生 15770852798@163.com
* @LastEditTime: 2022-09-01 19:34:46
* @FilePath: /bkunyun/src/store/modules/upload.ts
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
......@@ -24,7 +24,9 @@ class FileList {
/** 文件上传列表 */
fileList: IUploadInfo[] = [];
/** 是否打开传输列表 */
openFileList: boolean = false
// setFileList (val: IUploadInfo[]) {
// this.fileList = val
......@@ -39,6 +41,10 @@ class FileList {
this.newFileList = val
}
/** 打开关闭文件列表 */
setOpenFileList = (val: boolean) => {
this.openFileList = val
}
/** 设置文件上传信息 */
setUploadInfo = (id: string, val: IUploadInfo) => {
......
......@@ -88,12 +88,12 @@ const FileItem = observer((props: IProps) => {
const speed = useMemo(() => {
let val = 0;
const time = Math.floor((itemInfo?.endTime - itemInfo.startTime) / 1000);
const time = Math.floor((itemInfo?.endTime - itemInfo?.startTime) / 1000);
if (time > 0) {
val = Math.floor(itemInfo?.bytesUploaded / time);
}
return val;
}, [itemInfo?.bytesUploaded, itemInfo?.endTime, itemInfo.startTime]);
}, [itemInfo?.bytesUploaded, itemInfo?.endTime, itemInfo?.startTime]);
return (
<div className={styles.itemBox}>
<div className={styles.leftBox}>
......
......@@ -2,7 +2,7 @@
* @Author: 吴永生#A02208 yongsheng.wu@wholion.com
* @Date: 2022-06-10 18:05:21
* @LastEditors: 吴永生 15770852798@163.com
* @LastEditTime: 2022-09-01 14:09:28
* @LastEditTime: 2022-09-01 15:54:33
* @FilePath: /bkunyun/src/views/ConsoleLayout/components/TransferList/index.tsx
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
......
......@@ -13,10 +13,70 @@
}
.logo {
padding: 0px 16px 0px 20px;
padding: 0px 32px 0px 20px;
margin-top: -10px;
}
.menuBox {
line-height: 57px;
height: 57px;
font-size: 14px;
color: rgba(86, 92, 102, 1);
margin-right: 24px;
cursor: pointer;
position: relative;
}
.menuTitle:hover {
color: #1e2633;
}
.menuBox:hover .productList {
display: block;
}
.triangle {
width: 16px;
height: 16px;
position: relative;
top: 4px;
transition: width 1s;
-webkit-transition: width 1s;
}
.menuBox:hover .triangle {
transform: rotateX(180deg);
}
.productList {
position: absolute;
top: 57px;
left: -16px;
padding: 8px 0;
display: none;
background: #ffffff;
box-shadow: 0px 3px 10px 0px rgba(0, 24, 57, 0.14);
border-radius: 4px;
z-index: 1002;
}
.productLi {
min-width: 142px;
height: 36px;
padding: 7px 50px 7px 16px;
font-size: 14px;
color: rgba(30, 38, 51, 1);
line-height: 22px;
cursor: pointer;
position: relative;
box-sizing: border-box;
}
.productLi:hover {
color: rgba(19, 112, 255, 1);
}
.productLiActive {
color: rgba(19, 112, 255, 1);
}
.selectActive {
width: 16px;
height: 16px;
position: absolute;
top: 10px;
right: 12px;
}
.uploadIconBox {
width: 32px;
height: 32px;
......@@ -39,16 +99,14 @@
}
.topRightItem {
margin-right: 20px;
margin-right: 24px;
}
.ArrowDropDownIconRoot {
.topRightTriangle {
color: #8a9099;
transition: all 0.2s !important;
transform: rotate(0);
}
.ArrowDropDownIconRootOpen {
.topRightTriangleOpen {
color: #8a9099;
transform: rotate(180deg);
}
......
import React, { useEffect, useState } from "react";
import { Outlet, useLocation, useNavigate } from "react-router-dom";
import cx from "classnames";
import { observer } from "mobx-react-lite";
import ArrowDropDownIcon from "@mui/icons-material/ArrowDropDown";
import Avatar from "@mui/material/Avatar";
import { Box, Menu, MenuItem } from "@mui/material";
import classNames from "classnames";
import uploadIcon from "@/assets/img/uploadIcon.svg";
import triangle from "@/assets/project/triangle.svg";
import selectActive from "@/assets/project/selectActive.svg";
import globalText from "@/utils/globalText_CN";
import useIndex from "./useIndex";
import { useStores } from "@/store/index";
import MyButton from "@/components/mui/MyButton";
import logo from "@/assets/img/logo.svg";
import MyPopover from "@/components/mui/MyPopover";
import TranSferList from "./components/TransferList";
import { getProjectList } from "@/api/project_api";
import useMyRequest from "@/hooks/useMyRequest";
import { toJS } from "mobx";
import {
setFileServerEndPointLocalStorage,
getFiletokenAccordingToId,
......@@ -25,29 +25,19 @@ import {
import style from "./index.module.css";
const ConsoleLayout = observer(() => {
const {
productAnchorEl,
utilityAnchorEl,
productOpen,
utilityOpen,
handleProductClick,
handleUtilityClick,
handleClose,
} = useIndex();
const { utilityAnchorEl, utilityOpen, handleUtilityClick, handleClose } =
useIndex();
const [currentProduct, setCurrentProduct] = useState<{
path: string;
name: string;
}>();
const { currentProjectStore } = useStores();
const { currentProjectStore, fileListStore } = useStores();
const { openFileList, setOpenFileList } = fileListStore;
const productInfo = toJS(currentProjectStore.currentProductInfo);
const { run: runGetProjectList } = useMyRequest(getProjectList, {
onSuccess: (res) => {
let list = res.data;
if (list.length === 0) {
currentProjectStore.setProjectList([]);
currentProjectStore.changeProject({});
navigate(currentProduct?.path as string);
navigate(productInfo?.path as string);
} else {
currentProjectStore.setProjectList(list);
currentProjectStore.changeProject(list[0]);
......@@ -56,15 +46,18 @@ const ConsoleLayout = observer(() => {
list[0].filetoken = res;
currentProjectStore.changeProject(list[0]);
});
navigate(currentProduct?.path as string);
navigate(productInfo?.path as string);
}
},
});
// 切换产品
const getProduct = (item: any) => {
currentProjectStore.changeProductInfo({ id: item.id, name: item.name });
setCurrentProduct(item);
currentProjectStore.changeProductInfo({
id: item.id,
name: item.name,
path: item.path,
});
runGetProjectList({
product: item.id,
});
......@@ -83,62 +76,54 @@ const ConsoleLayout = observer(() => {
<Box className={style.topApp}>
<Box className={style.topLeftBox}>
<img src={logo} alt="" className={style.logo} />
<MyButton
{/* <MyButton
text={globalText.console}
variant={"text"}
style={{ color: "#565C66" }}
onClick={() => navigate("/home")}
/>
/> */}
<div className={style.menuBox} onClick={() => navigate("/home")}>
<div className={style.menuTitle}>{globalText.console}</div>
</div>
<Box sx={{ display: "flex", alignItems: "center" }}>
<MyButton
text={globalText.product}
variant={"text"}
style={{ color: "#565C66", paddingLeft: '8px' }}
onClick={handleProductClick}
dropValue={productOpen}
drop={true}
/>
{/* <ArrowDropDownIcon classes={{
root: cx({
[style.ArrowDropDownIconRoot]: true,
[style.ArrowDropDownIconRootOpen]: Boolean(productOpen)
})
}} /> */}
<Menu
id="product-menu"
anchorEl={productAnchorEl}
open={productOpen}
onClose={handleClose}
classes={{
paper: style.menuPaper,
}}
MenuListProps={{
"aria-labelledby": "product-button",
}}
>
<div className={style.menuBox}>
<div className={style.menuTitle}>
<span>{globalText.product}</span>
<img className={style.triangle} src={triangle} alt="" />
</div>
<div className={style.productList}>
{menuStore.productList.map((item) => {
return (
<MenuItem
<div
key={item.path}
classes={{
root: style.menuItemRoot,
}}
className={classNames({
[style.productLi]: true,
[style.productLiActive]: productInfo.path === item.path,
})}
onClick={() => {
getProduct(item);
handleClose();
}}
>
{item.name}
</MenuItem>
{productInfo.path === item.path && (
<img
className={style.selectActive}
src={selectActive}
alt=""
/>
)}
</div>
);
})}
</Menu>
</Box>
</div>
</div>
</Box>
<Box className={style.topRightBox}>
<MyPopover
open={openFileList}
changeOpen={(val) => setOpenFileList(val)}
content={<TranSferList />}
transformOrigin={{
vertical: "top",
......@@ -152,7 +137,6 @@ const ConsoleLayout = observer(() => {
style={{ verticalAlign: "middle" }}
/>
</div>
</MyPopover>
<Box className={style.topRightItem}>
<Box
......@@ -170,13 +154,13 @@ const ConsoleLayout = observer(() => {
>
H
</Avatar>
<ArrowDropDownIcon
classes={{
root: cx({
[style.ArrowDropDownIconRoot]: true,
[style.ArrowDropDownIconRootOpen]: Boolean(utilityOpen),
}),
}}
<img
className={classNames({
[style.topRightTriangle]: true,
[style.topRightTriangleOpen]: Boolean(utilityOpen),
})}
src={triangle}
alt=""
/>
</Box>
......@@ -213,4 +197,4 @@ const ConsoleLayout = observer(() => {
);
});
export default ConsoleLayout;
\ No newline at end of file
export default ConsoleLayout;
.parentBox {
height: calc(100vh - 57px);
position: relative;
}
.centerBox {
position: absolute;
top: 40%;
left: 50%;
transform: translate(-50%, -50%);
}
.centerImg{
width: 186px;
height: 114px;
}
.centerText {
font-size: 14px;
color: #565C66;
line-height: 22px;
margin-top: 20px;
text-align: center;
}
.bottomText {
font-size: 14px;
color: #8A9099;
line-height: 22px;
position: absolute;
left: 50%;
transform: translateX(-50%);
bottom: 20px;
}
\ No newline at end of file
import React from "react";
import style from "./index.module.css";
import building from "@/assets/img/building.png";
const Home = () => {
return <div>Home</div>;
return <div className={style.parentBox}>
<div className={style.centerBox}>
<img src={building} className={style.centerImg} />
<div className={style.centerText}>平台正在努力建设中…</div>
</div>
<div className={style.bottomText}>平台当前为beta版本,非最终品质</div>
</div>
};
export default Home;
......@@ -135,6 +135,7 @@ const UpLoaderFile = observer((props: IMoveFileProps) => {
};
}) || [];
toJS(fileListStore?.setNewFileList)(newFileList);
fileListStore?.setOpenFileList(true);
if (newFileList?.length) {
getFileToken(newFileList);
}
......@@ -172,14 +173,14 @@ const UpLoaderFile = observer((props: IMoveFileProps) => {
const renderButtons = (item: any, index: number) => {
return (
<MyButton
text='删除'
style={{ position: "relative", left: "-18px" }}
variant="text"
size="small"
color="error"
onClick={() => handleRowDelete(index)}
/>
<MyButton
text="删除"
style={{ position: "relative", left: "-18px" }}
variant="text"
size="small"
color="error"
onClick={() => handleRowDelete(index)}
/>
);
};
......
......@@ -602,10 +602,9 @@ const ProjectData = observer(() => {
{selectIds.length > 0 && (
<div className={style.projectDataStickyBox}>
<MyButton
text={`批量删除(${selectIds.length})`}
text={`批量删除 (${selectIds.length})`}
color="error"
variant="outlined"
size="small"
style={{ marginRight: "12px" }}
onClick={() => {
setCurrentOperateFile(null);
......@@ -614,10 +613,9 @@ const ProjectData = observer(() => {
disabled={!isPass("PROJECT_DATA_DELETE", "USER")}
/>
<MyButton
text={`批量移动(${selectIds.length})`}
text={`批量移动 (${selectIds.length})`}
// color="neutral"
variant="contained"
size="small"
style={{ marginRight: "24px" }}
onClick={() => {
setCurrentOperateFile(null);
......
......@@ -72,7 +72,7 @@
.taskProgress {
height: 32px;
margin: 12px 0;
margin: 12px 0 16px;
}
.progressInfo {
......@@ -120,6 +120,7 @@
.result {
box-sizing: border-box;
font-size: 12px;
align-items: center;
color: #1e2633;
cursor: pointer;
height: 30px;
......@@ -152,6 +153,12 @@
}
.outputLeftImg {
vertical-align: middle;
vertical-align: top;
margin-right: 8px;
}
.outputTitle {
display: inline-block;
height: 22px;
line-height: 22px;
}
......@@ -48,7 +48,7 @@ const TaskCard = (props: TaskCardProps) => {
}, [outputs])
// 结果文件跳转
const goToProjectData = (info: any) => {
let { path = '' , type = '' } = info
let { path = '', type = '' } = info
const lastIndex = path.lastIndexOf("/");
// /projectData
// dataType
......@@ -69,6 +69,8 @@ const TaskCard = (props: TaskCardProps) => {
// 渲染状态图标
const renderStatusIcon = (data: string) => {
switch (data) {
case "SUBMITTED":
return jobRun
case "RUNNING":
return jobRun
case "ABORTED":
......@@ -85,7 +87,7 @@ const TaskCard = (props: TaskCardProps) => {
const renderStatusText = (data: string) => {
switch (data) {
case "SUBMITTED":
return "正在启动";
return "正在启动";
case "RUNNING":
return '正在运行'
case "ABORTED":
......@@ -101,6 +103,8 @@ const TaskCard = (props: TaskCardProps) => {
// 渲染字体颜色
const renderTextColor = (data: string) => {
switch (data) {
case "SUBMITTED":
return "#1370FF";
case "RUNNING":
return "#1370FF";
case "ABORTED":
......@@ -116,6 +120,8 @@ const TaskCard = (props: TaskCardProps) => {
// 渲染状态框背景颜色
const renderBackgroundColor = (data: string) => {
switch (data) {
case "SUBMITTED":
return "#EBF3FF";
case "RUNNING":
return "#EBF3FF";
case "ABORTED":
......@@ -131,6 +137,8 @@ const TaskCard = (props: TaskCardProps) => {
//渲染进度条颜色
const renderProgressColor = useCallback((data: any) => {
switch (data) {
case "SUBMITTED":
return "info";
case "RUNNING":
return "info";
case "ABORTED":
......@@ -182,7 +190,8 @@ const TaskCard = (props: TaskCardProps) => {
}
alt=""
/>
{item?.name}</div>
<span className={style.outputTitle}>{item?.name}</span>
</div>
})}
</div>
}
......
.topFixed {
position: sticky;
top: 0;
z-index: 10;
background-color: #fff;
}
.basicInformation {
display: flex;
justify-content: space-between;
margin: 24px 24px 0 24px;
padding-bottom: 20px;
border-bottom: 1px solid #EDEFF2;
display: flex;
justify-content: space-between;
margin: 0 24px;
padding: 24px 0 20px;
border-bottom: 1px solid #edeff2;
}
.basicInformationRight {
display: flex;
align-items: center;
font-size: 12px;
display: flex;
align-items: center;
font-size: 12px;
}
.titleBox {
display: flex;
align-items: flex-end;
display: flex;
align-items: flex-end;
}
.projectName {
margin-left: 12px;
font-size: 18px;
line-height: 26px;
font-weight: 600;
margin-left: 12px;
font-size: 18px;
line-height: 26px;
font-weight: 600;
}
.otherInformation {
display: flex;
font-size: 12px;
margin-top: 16px;
display: flex;
font-size: 12px;
margin-top: 16px;
}
.informationcolor {
color: #8A9099;
color: #8a9099;
}
.otherInformationBox {
margin-right: 24px;
color: #565C66;
margin-right: 24px;
color: #565c66;
}
.otherInformationBoxRight{
line-height: 22px;
margin-bottom: 4px;
color: #565C66;
.otherInformationBoxRight {
line-height: 22px;
margin-bottom: 4px;
color: #565c66;
}
.numberDisplay {
font-size: 20px;
font-weight: 600;
color: #1E2633;
margin-right: 8px;
font-size: 20px;
font-weight: 600;
color: #1e2633;
margin-right: 8px;
}
.verticalLine {
height: 32px;
border-right: 1px solid #EBEDF0;
margin-left: 28px;
margin-right: 28px;
height: 32px;
border-right: 1px solid #ebedf0;
margin-left: 28px;
margin-right: 28px;
}
.searchBox {
display: flex;
justify-content: space-between;
margin: 24px 24px 0 24px;
display: flex;
justify-content: space-between;
margin: 24px 24px 0 24px;
padding-bottom: 20px;
}
.searchLineLeft {
display: flex;
align-items: center;
display: flex;
align-items: center;
}
.taskOverview {
font-size: 16px;
font-weight: 500;
margin-right: 18px;
font-size: 16px;
font-weight: 500;
margin-right: 18px;
}
.projectDataSearch {
padding-left: 12px;
padding-right: 8px;
border-radius: 4px;
border: 1px solid #ebedf0;
padding-left: 12px;
padding-right: 8px;
border-radius: 4px;
border: 1px solid #ebedf0;
}
.taskDisplay {
position: relative;
margin: 20px 24px;
padding-bottom: 16px;
overflow: hidden;
background: #F7F8FA;
border-radius: 8px;
min-height: calc(100vh - 291px);
position: relative;
margin: 0 24px 20px;
padding-bottom: 16px;
overflow: hidden;
background: #f7f8fa;
border-radius: 8px;
min-height: calc(100vh - 291px);
}
.noDataBox {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.noDataText {
margin-top: 8px;
font-size: 14px;
line-height: 22px;
color: #8a9099;
margin-top: 8px;
font-size: 14px;
line-height: 22px;
color: #8a9099;
}
.loadingBox {
width: 100%;
display: flex;
justify-content: center;
align-items: center;
height: calc(100vh - 100px);
}
\ No newline at end of file
width: 100%;
display: flex;
justify-content: center;
align-items: center;
height: calc(100vh - 100px);
}
This diff is collapsed.
......@@ -2,7 +2,7 @@
* @Author: 吴永生#A02208 yongsheng.wu@wholion.com
* @Date: 2022-05-31 10:18:13
* @LastEditors: 吴永生 15770852798@163.com
* @LastEditTime: 2022-09-01 14:09:34
* @LastEditTime: 2022-09-01 16:14:10
* @FilePath: /bkunyun/src/views/Project/ProjectSetting/index.tsx
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
......@@ -13,12 +13,17 @@ import { memo, useCallback, useEffect, useMemo, useState } from "react";
import { Box, OutlinedInput } from "@mui/material";
import Dialog from "@/components/mui/MyDialog";
import { IResponse, useHttp } from "@/api/http";
import useMyRequest from "@/hooks/useMyRequest";
import { useStores } from "@/store";
import { useMessage } from "@/components/MySnackbar";
import MySelect, { IOption } from "@/components/mui/MySelect";
import MyTable from "@/components/mui/MyTable";
import SearchInput from "@/components/BusinessComponents/SearchInput";
import {
addProjectUser,
fetchProjectPower,
fetchProjectUsersList,
} from "@/api/project_api";
interface IProps {
setAddMemberDialog: (val: boolean) => void;
......@@ -29,7 +34,6 @@ interface IProps {
const AddMember = observer((props: IProps) => {
const { addMemberDialog, setAddMemberDialog, getTableList } = props;
const http = useHttp();
const { currentProjectStore } = useStores();
const [tableData, setTableData] = useState([]);
......@@ -76,14 +80,6 @@ const AddMember = observer((props: IProps) => {
];
}, [changePermission, selectOptions]);
useEffect(() => {
if (addMemberDialog) {
http.get<IResponse<any>>("/cpp/project/listroles").then((res) => {
setSelectOptions(res.data);
});
}
}, [addMemberDialog, http]);
/** 过滤表格数据 */
useEffect(() => {
if (!!projectMember) {
......@@ -97,18 +93,48 @@ const AddMember = observer((props: IProps) => {
}
}, [projectMember, tableData]);
// 获取表格数据接口
const { run: getProjectUsersList } = useMyRequest(fetchProjectUsersList, {
onSuccess: (res: any) => {
setTableData(res?.data);
},
});
// 获取项目权限
const { run: getProjectPower } = useMyRequest(fetchProjectPower, {
onSuccess: (res: any) => {
setSelectOptions(res.data);
},
});
// 添加项目成员
const { run: saveProjectUser } = useMyRequest(addProjectUser, {
onSuccess: (res: any) => {
const { errorCode } = res;
if (errorCode === 0) {
Message.success("新增成功!");
getTableList();
setAddMemberDialog(false);
}
},
});
useEffect(() => {
if (addMemberDialog) {
getProjectPower();
}
}, [addMemberDialog, getProjectPower]);
/** 获取表格数据 */
useEffect(() => {
if (!addMemberDialog) return;
const projectInfo = toJS(currentProjectStore?.currentProjectInfo);
http
.get<IResponse<any>>("/cpp/project/listusers", {
params: { id: projectInfo?.id || "" },
})
.then((res) => {
setTableData(res?.data);
});
}, [currentProjectStore?.currentProjectInfo, http, addMemberDialog]);
getProjectUsersList({ id: projectInfo?.id || "" });
}, [
currentProjectStore?.currentProjectInfo,
addMemberDialog,
getProjectUsersList,
]);
const onClose = (event: any = {}, reason: any = "other") => {
// 点击弹窗外不关闭弹窗
......@@ -124,19 +150,7 @@ const AddMember = observer((props: IProps) => {
return checkData.includes(item?.username);
});
if (params.length) {
http
.put<IResponse<any>>(
`/cpp/project/updatemember?id=${projectInfo?.id || ""}`,
params
)
.then((res) => {
const { errorCode } = res;
if (errorCode === 0) {
Message.success("新增成功!");
getTableList();
setAddMemberDialog(false);
}
});
saveProjectUser(projectInfo?.id || "", params);
} else {
Message.info("请先选择项目成员!");
}
......@@ -162,6 +176,9 @@ const AddMember = observer((props: IProps) => {
/>
<div style={{ overflow: "overlay", maxHeight: 400 }}>
<MyTable
noDataText={
projectMember ? `暂无 "${projectMember}" 搜索结果` : undefined
}
tableContainerStyle={{ height: 346 }}
checkboxData={(val: string[]) => setCheckData(val)}
param="username"
......
......@@ -2,7 +2,7 @@
* @Author: 吴永生#A02208 yongsheng.wu@wholion.com
* @Date: 2022-06-21 20:03:56
* @LastEditors: 吴永生 15770852798@163.com
* @LastEditTime: 2022-08-17 10:58:02
* @LastEditTime: 2022-09-01 14:39:36
* @FilePath: /bkunyun/src/views/Project/ProjectSubmitWork/index.tsx
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
......@@ -223,6 +223,7 @@ const ProjectSubmitWork = observer(() => {
promotedParameters,
});
} else {
handleCancel();
Message.error("请完善算子信息后提交任务");
}
};
......
......@@ -108,3 +108,8 @@
background: #f0f2f5;
border-radius: 4px;
}
.pagination {
padding: 19px 0;
display: flex;
justify-content: end;
}
......@@ -38,6 +38,7 @@
flex: 1;
margin-right: 16px;
margin-bottom: 16px;
transition: box-shadow .2s cubic-bezier(0, 0, 1, 1);
}
.templateLiCustom {
......@@ -113,4 +114,4 @@
display: flex;
justify-content: flex-end;
/* margin-top: 16px; */
}
}
\ No newline at end of file
import { memo } from "react";
import { Box, Typography } from "@mui/material";
import Dialog from "@/components/mui/MyDialog";
import MyDialog from "@/components/mui/MyDialog";
const SimpleDialog = (props: any) => {
const { openDialog, closeDialog, onConfirm, text, title } = props;
return (
<>
<Dialog
<MyDialog
open={openDialog}
onClose={closeDialog}
onConfirm={onConfirm}
title={title}
okSx={{ background: "#FF4E4E", color: "#fff" }}
>
<Box>
<Typography sx={{ fontSize: "14px", fontWeight: "400" }}>
{text}
</Typography>
</Box>
</Dialog>
</MyDialog>
</>
);
};
......
......@@ -32,7 +32,6 @@
.templateBlock {
height: 194px;
background: #ffffff;
box-shadow: 0px 3px 10px 0px rgba(0, 24, 57, 0.04);
border-radius: 4px;
border: 1px solid #ebedf0;
padding: 16px 20px;
......@@ -43,6 +42,9 @@
position: relative;
box-sizing: border-box;
}
.templateBlock:hover {
box-shadow: 6px 8px 22px 0px rgba(0, 24, 57, 0.08);
}
@media screen and (max-width: 1220px) {
.template {
......
......@@ -2,14 +2,6 @@
width: calc(100vw - 220px);
height: calc(100vh - 57px);
background-color: rgba(0, 0, 0, 0.5);
/* width: 260px;
height: calc(100vh - 57px); */
/* width: 260px;
height: calc(100vh - 57px);
background-color: #fff;
border-right: 1px solid #ebedf0;
display: flex;
flex-direction: column; */
}
.mainBox {
......@@ -25,10 +17,11 @@
.searchBox {
box-sizing: border-box;
height: 56px;
padding: 17px;
padding: 12px 8px 12px 24px;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
}
.searchButton {
width: 22px;
......@@ -48,8 +41,11 @@
}
.add {
padding: 0 15px;
width: 22px;
height: 22px;
width: 32px;
height: 32px;
}
.add:hover {
border-radius: 4px;
}
.addIcon {
color: #1e2633;
......@@ -59,6 +55,12 @@
overflow-y: overlay;
border-top: 1px solid #f0f2f5;
}
.noProjectBox {
color: #edeff2;
height: 48px;
line-height: 48px;
text-align: center;
}
.projectli {
cursor: pointer;
}
......@@ -96,13 +98,14 @@
overflow: hidden;
}
.projectOwnerTime {
font-size: 12px;
display: flex;
justify-content: space-between;
}
.projectOwner {
font-size: 12px;
color: #565c66;
line-height: 20px;
font-size: 14px;
margin-right: 32px;
max-width: 60px;
white-space: nowrap;
......@@ -113,5 +116,5 @@
.projectTime {
color: #8a9099;
line-height: 20px;
font-size: 14px;
font-size: 12px;
}
......@@ -2,7 +2,7 @@
* @Author: 吴永生 15770852798@163.com
* @Date: 2022-08-02 11:43:28
* @LastEditors: 吴永生 15770852798@163.com
* @LastEditTime: 2022-08-30 19:32:05
* @LastEditTime: 2022-09-01 19:49:39
* @FilePath: /bkunyun/src/views/Project/components/ProjectListPopper/index.tsx
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
......@@ -14,8 +14,8 @@ import AddIcon from "@mui/icons-material/Add";
import classNames from "classnames";
import { useStores } from "@/store/index";
import moment from "moment";
import React, { useMemo, useState } from "react";
import { useClickAway } from 'ahooks';
import React, { useMemo, useState } from "react";
import { useClickAway } from "ahooks";
import { toJS } from "mobx";
import { observer } from "mobx-react-lite";
......@@ -31,26 +31,52 @@ const ProjectListPopper = observer((props: any) => {
setName(e.target.value);
};
const getPower = (projectRole: string) => {
if (projectRole === "VIEWER") {
return "查看者";
} else if (projectRole === "USER") {
return "研究员";
} else if (projectRole === "MANAGER") {
return "管理员";
} else if (projectRole === "OWNER") {
return "所有者";
} else {
return "";
}
};
const list = useMemo(() => {
return projectList.filter((item: any) => {
return item.name?.indexOf(name) !== -1;
});
return projectList
.filter((item: any) => {
return item.name?.indexOf(name) !== -1;
})
.map((item) => {
return {
...item,
power: getPower(item.projectRole || ""),
};
});
}, [projectList, name]);
console.log(list);
const handleProjectBox = (e: React.SyntheticEvent) => {
setProjectListOpen(false);
};
useClickAway(
() => {
setProjectListOpen(false);
},
() => document.getElementById('use-click-projectList-mainBox'),
);
() => {
setProjectListOpen(false);
},
() => document.getElementById("use-click-projectList-mainBox")
);
return (
<div className={style.projectBox} onClick={handleProjectBox}>
<div className={style.mainBox} id="use-click-projectList-mainBox" onClick={(e: any)=>e.stopPropagation()}>
<div
className={style.mainBox}
id="use-click-projectList-mainBox"
onClick={(e: any) => e.stopPropagation()}
>
<div className={style.searchBox}>
<IconButton
type="submit"
......@@ -59,7 +85,7 @@ const ProjectListPopper = observer((props: any) => {
>
<SearchIcon
className={style.searchIcon}
style={{ color: "rgba(153, 153, 153, 1)" }}
style={{ color: "#8A9099", fontSize: "22px" }}
/>
</IconButton>
<InputBase
......@@ -68,6 +94,11 @@ const ProjectListPopper = observer((props: any) => {
inputProps={{ "aria-label": "请输入项目名称" }}
value={name}
onChange={nameChange}
sx={{
fontSize: "14px",
// color: "rgba(194, 198, 204, 1)",
height: "22px",
}}
/>
<IconButton
onClick={handleClickOpen}
......@@ -79,33 +110,41 @@ const ProjectListPopper = observer((props: any) => {
</IconButton>
</div>
<div className={style.projectlist}>
{list.map((item: any) => {
return (
<div
className={classNames({
[style.projectli]: true,
[style.projectliActive]: item.id === currentProjectId,
})}
key={item.id}
onClick={() => handleChangeCurrentProject(item)}
>
<div className={style.projectliBorderBox}>
<img src={smallLogo} alt="" className={style.projectliLogo} />
<div className={style.projectliInfo}>
<div className={style.projectName}>{item.name}</div>
<div className={style.projectOwnerTime}>
<span className={style.projectOwner} title={item.owner}>
{item.owner}
</span>
<span className={style.projectTime}>
{moment(item.createdAt).format("YYYY-MM-DD")}
</span>
{list.length ? (
list.map((item: any) => {
return (
<div
className={classNames({
[style.projectli]: true,
[style.projectliActive]: item.id === currentProjectId,
})}
key={item.id}
onClick={() => handleChangeCurrentProject(item)}
>
<div className={style.projectliBorderBox}>
<img
src={smallLogo}
alt=""
className={style.projectliLogo}
/>
<div className={style.projectliInfo}>
<div className={style.projectName}>{item.name}</div>
<div className={style.projectOwnerTime}>
<span className={style.projectOwner} title={item.owner}>
{item.power}
</span>
<span className={style.projectTime}>
{moment(item.createdAt).format("YYYY-MM-DD")}
</span>
</div>
</div>
</div>
</div>
</div>
);
})}
);
})
) : (
<div className={style.noProjectBox}>暂无相关项目</div>
)}
</div>
</div>
</div>
......
import _ from "lodash";
import { useCallback, useMemo, useRef, useState } from "react";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import classNames from "classnames";
import {
......@@ -36,8 +36,9 @@ const ParameterSetting = (props: IParameterSettingProps) => {
const [fileSelectType, setFileSelectType] = useState<FileSelectType>("path");
const [parameterName, setParameterName] = useState(""); // 当前算子中的parameters中正在编辑饿parameter(参数)
const resizeRef = useRef<HTMLDivElement>(null);
const size = useSize(resizeRef) ;
const [activeParamsTab, setActiveParamsTab] = useState<string>("");
const size = useSize(resizeRef);
// 文件夹路线选择器弹窗
const handleFileSelectOnClose = () => {
......@@ -497,15 +498,13 @@ const ParameterSetting = (props: IParameterSettingProps) => {
}, [basisParameters, seniorParameters, hardwareParameters, randerParameters]);
// 激活的参数组tab
const activeParamsTab = useMemo(() => {
useEffect(() => {
if (basisParameters.length !== 0) {
return "basis";
setActiveParamsTab("basis");
} else if (seniorParameters.length !== 0) {
return "senior";
setActiveParamsTab("senior");
} else if (hardwareParameters.length !== 0) {
return "hardware";
} else {
return "";
setActiveParamsTab("hardware");
}
}, [basisParameters, seniorParameters, hardwareParameters]);
......@@ -648,11 +647,15 @@ const ParameterSetting = (props: IParameterSettingProps) => {
<Tabs
tabList={paramsTabList}
value={activeParamsTab}
// defaultValue={activeParamsTab}
onChange={(val) => setActiveParamsTab(val)}
allowNullValue={true}
tabPanelSx={{ padding: "7px 0" }}
/>
{basisParameters.length === 0 && seniorParameters.length === 0 && hardwareParameters.length === 0 && (<div className={styles.noParameters}>暂无可设置参数</div>)}
{basisParameters.length === 0 &&
seniorParameters.length === 0 &&
hardwareParameters.length === 0 && (
<div className={styles.noParameters}>暂无可设置参数</div>
)}
</div>
)}
{!taskInfo && (
......
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