Commit 21d75bb6 authored by wuyongsheng's avatar wuyongsheng

feat: 添加项目成员优化

parent ca0fc530
......@@ -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
};
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-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
*/
......
......@@ -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-05-31 10:18:13
* @LastEditors: 吴永生 15770852798@163.com
* @LastEditTime: 2022-08-22 15:33:02
* @LastEditTime: 2022-09-01 16:35:02
* @FilePath: /bkunyun/src/views/Project/ProjectSetting/index.tsx
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
......@@ -87,29 +87,26 @@ const ProjectMembers = observer(() => {
const [jobData, setJobData] = useState("");
const [openDialog, setOpenDialog] = useState(false);
const [dialogType, setDialogType] = useState("del");
const [loading, setLoading] = useState(false)
const [loading, setLoading] = useState(false);
// 获取作业列表
const { run: getWorkflowJobInfo } = useMyRequest(
getWorkflowJobList,
{
onSuccess: (result: any) => {
setLoading(false)
setJobList(result.data.content);
setCount(result.data.totalElements);
timer && clearTimeout(timer as number);
timer = null;
timer = setTimeout(() => {
getWorkflowJobInfo({
projectId: currentProjectStore.currentProjectInfo.id as string,
page: page,
size: size,
name: jobName,
state: currency === "ALL" ? "" : currency,
});
}, 60000);
},
}
);
const { run: getWorkflowJobInfo } = useMyRequest(getWorkflowJobList, {
onSuccess: (result: any) => {
setLoading(false);
setJobList(result.data.content);
setCount(result.data.totalElements);
timer && clearTimeout(timer as number);
timer = null;
timer = setTimeout(() => {
getWorkflowJobInfo({
projectId: currentProjectStore.currentProjectInfo.id as string,
page: page,
size: size,
name: jobName,
state: currency === "ALL" ? "" : currency,
});
}, 60000);
},
});
useEffect(() => {
return () => {
......@@ -298,7 +295,7 @@ const ProjectMembers = observer(() => {
const handleKeyWordChangeKeyUp = (e: any) => {
if (e.keyCode === 13) {
setJobName(e.target.value);
setLoading(true)
setLoading(true);
}
};
......@@ -367,7 +364,7 @@ const ProjectMembers = observer(() => {
name: jobName,
state: currency === "ALL" ? "" : currency,
});
setLoading(true)
setLoading(true);
}}
>
<img alt="" src={onload} />
......@@ -375,124 +372,128 @@ const ProjectMembers = observer(() => {
</Box>
<Box className={styles.body} style={{ position: "relative" }}>
<MyCircularProgress loading={loading} />
{jobList.length === 0 && !loading && (
<Box
sx={{
display: "flex",
alignItems: "center",
flexDirection: "column",
minHeight: "calc(100vh - 376px)",
justifyContent: "center",
}}
>
<img alt="" src={noData} />
<Typography
sx={{ fontSize: "12px", fontWeight: "400", color: "#8A9099" }}
<MyCircularProgress loading={loading}>
{jobList.length === 0 && !loading && (
<Box
sx={{
display: "flex",
alignItems: "center",
flexDirection: "column",
minHeight: "calc(100vh - 376px)",
justifyContent: "center",
}}
>
暂无任务
</Typography>
</Box>
)}
{jobList.length > 0 &&
jobList.map((item: any, key) => {
return (
<Box className={styles.tabBox} onClick={() => rowClick(item.id)}>
<Box className={styles.tabBoxInfo}>
<div className={styles.tabBoxTitle}>{item.name}</div>
<Box className={styles.tabBoxDescInfo}>
<div
className={styles.tabBoxDesc}
style={{ marginRight: "24px" }}
>
创建时间:{moment(item.createTime).format("YYYY-MM-DD")}
</div>
<div className={styles.tabBoxDesc}>
创建人:{item.creator}
<img alt="" src={noData} />
<Typography
sx={{ fontSize: "12px", fontWeight: "400", color: "#8A9099" }}
>
暂无任务
</Typography>
</Box>
)}
{jobList.length > 0 &&
jobList.map((item: any, key) => {
return (
<Box
className={styles.tabBox}
onClick={() => rowClick(item.id)}
>
<Box className={styles.tabBoxInfo}>
<div className={styles.tabBoxTitle}>{item.name}</div>
<Box className={styles.tabBoxDescInfo}>
<div
className={styles.tabBoxDesc}
style={{ marginRight: "24px" }}
>
创建时间:{moment(item.createTime).format("YYYY-MM-DD")}
</div>
<div className={styles.tabBoxDesc}>
创建人:{item.creator}
</div>
</Box>
</Box>
<Box className={styles.tabBoxMiddle}>
<img alt="" src={runTime} />
<div className={styles.tabBoxTime}>{item.costTime}</div>
</Box>
<Box className={styles.tabBoxMiddle}>
<img alt="" src={jobCost} />
<div className={styles.tabBoxTime}>
{item.jobCost ? item.jobCost.toFixed(2) : "--"}
</div>
</Box>
</Box>
<Box className={styles.tabBoxMiddle}>
<img alt="" src={runTime} />
<div className={styles.tabBoxTime}>{item.costTime}</div>
</Box>
<Box className={styles.tabBoxMiddle}>
<img alt="" src={jobCost} />
<div className={styles.tabBoxTime}>
{item.jobCost ? item.jobCost.toFixed(2) : "--"}
</div>
</Box>
<Box className={styles.tabBoxJobStatus}>
<img alt="" src={renderStatusIcon(item.state)} />
<div className={styles.tabBoxStatusText}>
{renderStatusText(item.state)}
</div>
<Box sx={{ width: "100%" }}>
<MyProgress
color={renderProgressColor(item.state)}
value={(item.completeNum / item.totalNum) * 100}
sx={{
marginRight: "16px",
<Box className={styles.tabBoxJobStatus}>
<img alt="" src={renderStatusIcon(item.state)} />
<div className={styles.tabBoxStatusText}>
{renderStatusText(item.state)}
</div>
<Box sx={{ width: "100%" }}>
<MyProgress
color={renderProgressColor(item.state)}
value={(item.completeNum / item.totalNum) * 100}
sx={{
marginRight: "16px",
}}
/>
</Box>
<div
style={{
color: renderTextColor(item.state),
margin: "0px",
}}
/>
className={styles.tabBoxStatusText}
>
{item.completeNum + "/" + item.totalNum}
</div>
</Box>
<div
style={{
color: renderTextColor(item.state),
margin: "0px",
}}
className={styles.tabBoxStatusText}
>
{item.completeNum + "/" + item.totalNum}
</div>
</Box>
{(item.state === "RUNNING" || item.state === "SUBMITTED") &&
isPass("PROJECT_WORKBENCH_JOBS_STOP", "USER") && (
<Box className={styles.tabBoxJobOperate}>
{currentProjectStore.currentProjectInfo.projectRole ===
"USER" &&
{(item.state === "RUNNING" || item.state === "SUBMITTED") &&
isPass("PROJECT_WORKBENCH_JOBS_STOP", "USER") && (
<Box className={styles.tabBoxJobOperate}>
{currentProjectStore.currentProjectInfo.projectRole ===
"USER" &&
item.creator !==
JSON.parse(localStorage.getItem("userInfo") || "{}")
?.name ? (
""
) : (
JSON.parse(localStorage.getItem("userInfo") || "{}")
?.name ? (
""
) : (
<img
alt=""
src={jobStop}
style={{ cursor: "pointer" }}
onClick={(event) => {
event.stopPropagation();
event.nativeEvent.stopImmediatePropagation();
setJobData(item.id);
setOpenDialog(true);
setDialogType("stop");
}}
/>
)}
</Box>
)}
{item.state !== "RUNNING" &&
item.state !== "SUBMITTED" &&
isPass("PROJECT_WORKBENCH_JOBS_DELETE", "MANAGER") && (
<Box className={styles.tabBoxJobOperate}>
<img
alt=""
src={jobStop}
src={jobDel}
style={{ cursor: "pointer" }}
onClick={(event) => {
event.stopPropagation();
event.nativeEvent.stopImmediatePropagation();
setJobData(item.id);
setOpenDialog(true);
setDialogType("stop");
setDialogType("del");
}}
/>
)}
</Box>
)}
{item.state !== "RUNNING" &&
item.state !== "SUBMITTED" &&
isPass("PROJECT_WORKBENCH_JOBS_DELETE", "MANAGER") && (
<Box className={styles.tabBoxJobOperate}>
<img
alt=""
src={jobDel}
style={{ cursor: "pointer" }}
onClick={(event) => {
event.stopPropagation();
event.nativeEvent.stopImmediatePropagation();
setJobData(item.id);
setOpenDialog(true);
setDialogType("del");
}}
/>
</Box>
)}
</Box>
);
})}
</Box>
)}
</Box>
);
})}
</MyCircularProgress>
</Box>
<TablePagination
......
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