Commit 865e50bc authored by chenshouchao's avatar chenshouchao

feat: 弹窗组件替换

parent ef0601fd
import React, { useState, useCallback, useEffect, useMemo } from "react"; import React, { useState, useCallback, useEffect, useMemo } from "react";
import style from "./index.module.css"; import style from "./index.module.css";
import MyDialog from "../../mui/Dialog"; import MyDialog from "../../mui/MyDialog";
import { useStores } from "@/store"; import { useStores } from "@/store";
import { observer } from "mobx-react-lite"; import { observer } from "mobx-react-lite";
import { toJS } from "mobx"; import { toJS } from "mobx";
......
...@@ -3,33 +3,30 @@ import noData from "@/assets/project/noData.svg"; ...@@ -3,33 +3,30 @@ import noData from "@/assets/project/noData.svg";
import { Button } from "@mui/material"; import { Button } from "@mui/material";
import AddIcon from "@mui/icons-material/Add"; import AddIcon from "@mui/icons-material/Add";
import AddProject from "@/views/Project/components/AddProject"; import AddProject from "@/views/Project/components/AddProject";
import React from "react"; import React, { useState } from "react";
const NoProject = () => { const NoProject = () => {
let addProjectRef: any = React.createRef(); // 新建弹窗显示控制
const [addOpen, setAddOpen] = useState(false);
const handleClickOpen = () => { return (
addProjectRef.current.handleClickOpen(); <div className={style.noProject}>
}; <img src={noData} alt="" className={style.noDataImg} />
<div className={style.text1}>当前产品暂无项目</div>
return ( <div className={style.text2}>请先创建项目</div>
<div className={style.noProject}> <Button
<img src={noData} alt="" className={style.noDataImg} /> variant="contained"
<div className={style.text1}>当前产品暂无项目</div> size="large"
<div className={style.text2}>请先创建项目</div> className={style.button}
<Button startIcon={<AddIcon />}
variant="contained" onClick={() => setAddOpen(true)}
size="large" style={{ backgroundColor: "#1370ff", color: "#fff" }}
className={style.button} >
startIcon={<AddIcon />} 创建项目
onClick={handleClickOpen} </Button>
style={{ backgroundColor: "#1370ff", color: "#fff" }} <AddProject addOpen={addOpen} setAddOpen={setAddOpen} />
> </div>
创建项目 );
</Button>
<AddProject onRef={addProjectRef} />
</div>
);
}; };
export default NoProject; export default NoProject;
import {
Button,
Dialog,
DialogActions,
DialogContent,
IconButton,
DialogTitle,
} from "@mui/material";
import LoadingButton from "@mui/lab/LoadingButton";
import CloseIcon from "@mui/icons-material/Close";
import { useState } from "react";
import { useImperativeHandle } from "react";
const MyDialog = (props: any) => {
const [open, setOpen] = useState(false);
const {
title,
handleSubmit,
submitloading,
submitStyle = { backgroundColor: "#1370FF" },
showCloseButton = true,
submitText = "确定",
} = props;
const handleClickOpen = () => {
setOpen(true);
};
const handleClose = (event: any = {}, reason: any = "other") => {
// 点击弹窗外不关闭弹窗
if (reason === "backdropClick") {
return;
}
setOpen(false);
};
useImperativeHandle(props.onRef, () => {
return {
handleClickOpen: handleClickOpen,
handleClose: handleClose,
};
});
return (
<Dialog
open={open}
onClose={handleClose}
className="aaa"
aria-labelledby="form-dialog-title"
sx={{
"& .MuiDialog-container": {
"& .MuiPaper-root": {
// 设置最大宽度, 实际宽度让子元素撑大
maxWidth: "1920px",
},
},
}}
>
{title && (
<DialogTitle id="form-dialog-title" sx={{ fontWeight: "600" }}>
{title}
</DialogTitle>
)}
<DialogContent
sx={{
minWidth: "400px",
}}
>
{props.children}
<IconButton
aria-label="delete"
style={{ position: "absolute", top: "10px", right: "12px" }}
onClick={handleClose}
>
<CloseIcon style={{ color: "#C2C6CC" }} />
</IconButton>
</DialogContent>
<DialogActions style={{ padding: "16px 24px" }}>
{showCloseButton && (
<Button
onClick={handleClose}
color="inherit"
variant="contained"
style={{ color: "#1E2633", backgroundColor: "#fff" }}
size="small"
>
取消
</Button>
)}
<LoadingButton
loading={submitloading}
onClick={handleSubmit}
color="primary"
variant="contained"
style={submitStyle}
size="small"
>
{submitText}
</LoadingButton>
</DialogActions>
</Dialog>
);
};
export default MyDialog;
import React from "react";
import {
Button,
Dialog,
DialogActions,
DialogContent,
DialogTitle,
} from "@mui/material";
import CloseIcon from "@mui/icons-material/Close";
export interface IDialogProps {
/** 自定义类名 */
className?: string;
/** 自定义样式 */
style?: React.CSSProperties;
/** 弹窗的标题 */
title?: string;
/** 是否显示弹窗 */
open: boolean;
isHideHeader?: boolean;
/** 是否隐藏弹窗底部按钮部分 */
isHideFooter?: boolean;
/** 自定义底部按钮 */
footerRender?: () => React.ReactNode;
/** 是否显示取消按钮 */
showCancel?: boolean;
/** 是否显示确定按钮 */
showConfirm?: boolean;
/** 关闭弹窗时的回调函数 */
onClose?: () => void;
/** 点击确定按钮时的回调函数 */
onConfirm?: () => void;
/** 取消按钮文案 */
cancelText?: string;
/** 确认按钮文案 */
okText?: string;
/** 是否禁用确认按钮 */
disabledConfirm?: boolean;
children: React.ReactNode;
/** 点击遮罩是否关闭 默认为false*/
clickMaskClose?: boolean;
}
const MyDialog: React.FunctionComponent<IDialogProps> = (props) => {
const {
title,
open,
style,
onClose,
onConfirm,
isHideFooter,
isHideHeader,
children,
footerRender,
className,
showCancel = true,
/** 是否显示确定按钮 */
showConfirm = true,
cancelText,
okText,
disabledConfirm,
clickMaskClose = false,
} = props;
const handelClose = (
event: {},
reason: "backdropClick" | "escapeKeyDown"
) => {
if (reason === "backdropClick" && !clickMaskClose) {
return;
}
onClose && onClose();
};
const Footer = () => {
if (isHideFooter) return null;
return footerRender ? (
footerRender()
) : (
<DialogActions style={{ padding: "0 24px 24px 24px" }}>
{showCancel ? (
<Button onClick={onClose} variant="outlined" size="small">
{cancelText || "取消"}
</Button>
) : null}
{showConfirm ? (
<Button
onClick={onConfirm}
variant="contained"
size="small"
disabled={disabledConfirm}
>
{okText || "确定"}
</Button>
) : null}
</DialogActions>
);
};
return (
<Dialog
open={open}
onClose={handelClose}
style={style}
className={className}
aria-labelledby="alert-dialog-title"
aria-describedby="alert-dialog-description"
sx={{
"& .MuiDialog-container": {
"& .MuiPaper-root": {
// 设置最大宽度, 实际宽度让子元素撑大
maxWidth: "1920px",
},
},
}}
>
{isHideHeader ? null : (
<DialogTitle id="alert-dialog-title">
<div
style={{
display: "flex",
justifyContent: "space-between",
alignItems: "center",
}}
>
<span>{title}</span>
<CloseIcon
onClick={onClose}
style={{ color: "#C2C6CC", cursor: "pointer" }}
/>
</div>
</DialogTitle>
)}
<DialogContent style={{ minWidth: 400 }}>{children}</DialogContent>
{Footer()}
</Dialog>
);
};
export default MyDialog;
import React from "react";
import { import {
Button, Button,
Dialog, Dialog,
DialogActions, DialogActions,
DialogContent, DialogContent,
IconButton, DialogTitle,
DialogTitle,
} from "@mui/material"; } from "@mui/material";
import LoadingButton from "@mui/lab/LoadingButton";
import CloseIcon from "@mui/icons-material/Close"; import CloseIcon from "@mui/icons-material/Close";
import { useState } from "react"; export interface IDialogProps {
import { useImperativeHandle } from "react"; /** 自定义类名 */
const MyDialog = (props: any) => { className?: string;
const [open, setOpen] = useState(false); /** 自定义样式 */
const { style?: React.CSSProperties;
title, /** 弹窗的标题 */
handleSubmit, title?: string;
submitloading, /** 是否显示弹窗 */
submitStyle = { backgroundColor: "#1370FF" }, open: boolean;
showCloseButton = true, isHideHeader?: boolean;
submitText = "确定", /** 是否隐藏弹窗底部按钮部分 */
} = props; isHideFooter?: boolean;
/** 自定义底部按钮 */
const handleClickOpen = () => { footerRender?: () => React.ReactNode;
setOpen(true); /** 是否显示取消按钮 */
}; showCancel?: boolean;
/** 是否显示确定按钮 */
showConfirm?: boolean;
/** 关闭弹窗时的回调函数 */
onClose?: () => void;
/** 点击确定按钮时的回调函数 */
onConfirm?: () => void;
/** 取消按钮文案 */
cancelText?: string;
/** 确认按钮文案 */
okText?: string;
/** 是否禁用确认按钮 */
disabledConfirm?: boolean;
children: React.ReactNode;
/** 点击遮罩是否关闭 默认为false*/
clickMaskClose?: boolean;
/** 确认按钮样式*/
okSx?: any;
}
const handleClose = (event: any = {}, reason: any = "other") => { const MyDialog: React.FunctionComponent<IDialogProps> = (props) => {
// 点击弹窗外不关闭弹窗 const {
if (reason === "backdropClick") { title,
return; open,
} style,
setOpen(false); onClose,
}; onConfirm,
isHideFooter,
isHideHeader,
children,
footerRender,
className,
showCancel = true,
/** 是否显示确定按钮 */
showConfirm = true,
cancelText,
okText,
disabledConfirm,
clickMaskClose = false,
okSx = {},
} = props;
useImperativeHandle(props.onRef, () => { const handelClose = (
return { event: {},
handleClickOpen: handleClickOpen, reason: "backdropClick" | "escapeKeyDown"
handleClose: handleClose, ) => {
}; if (reason === "backdropClick" && !clickMaskClose) {
}); return;
}
onClose && onClose();
};
return ( const Footer = () => {
<Dialog if (isHideFooter) return null;
open={open} return footerRender ? (
onClose={handleClose} footerRender()
className="aaa" ) : (
aria-labelledby="form-dialog-title" <DialogActions style={{ padding: "0 24px 24px 24px" }}>
sx={{ {showCancel ? (
"& .MuiDialog-container": { <Button onClick={onClose} variant="outlined" size="small">
"& .MuiPaper-root": { {cancelText || "取消"}
// 设置最大宽度, 实际宽度让子元素撑大 </Button>
maxWidth: "1920px", ) : null}
}, {showConfirm ? (
}, <Button
}} onClick={onConfirm}
> variant="contained"
{title && ( size="small"
<DialogTitle id="form-dialog-title" sx={{ fontWeight: "600" }}> disabled={disabledConfirm}
{title} sx={{ ...okSx }}
</DialogTitle> >
)} {okText || "确定"}
<DialogContent </Button>
sx={{ ) : null}
minWidth: "400px", </DialogActions>
}} );
> };
{props.children} return (
<IconButton <Dialog
aria-label="delete" open={open}
style={{ position: "absolute", top: "10px", right: "12px" }} onClose={handelClose}
onClick={handleClose} style={style}
> className={className}
<CloseIcon style={{ color: "#C2C6CC" }} /> aria-labelledby="alert-dialog-title"
</IconButton> aria-describedby="alert-dialog-description"
</DialogContent> sx={{
<DialogActions style={{ padding: "16px 24px" }}> "& .MuiDialog-container": {
{showCloseButton && ( "& .MuiPaper-root": {
<Button // 设置最大宽度, 实际宽度让子元素撑大
onClick={handleClose} maxWidth: "1920px",
color="inherit" },
variant="contained" },
style={{ color: "#1E2633", backgroundColor: "#fff" }} }}
size="small" >
> {isHideHeader ? null : (
取消 <DialogTitle id="alert-dialog-title">
</Button> <div
)} style={{
<LoadingButton display: "flex",
loading={submitloading} justifyContent: "space-between",
onClick={handleSubmit} alignItems: "center",
color="primary" }}
variant="contained" >
style={submitStyle} <span>{title}</span>
size="small" <CloseIcon
> onClick={onClose}
{submitText} style={{ color: "#C2C6CC", cursor: "pointer" }}
</LoadingButton> />
</DialogActions> </div>
</Dialog> </DialogTitle>
); )}
<DialogContent style={{ minWidth: 400 }}>{children}</DialogContent>
{Footer()}
</Dialog>
);
}; };
export default MyDialog; export default MyDialog;
import React, { useState, useEffect } from "react"; import React, { useState, useEffect } from "react";
import { TextField, Button } from "@mui/material"; import { TextField, Button } from "@mui/material";
import MyDialog from "@/components/mui/Dialog"; import MyDialog from "@/components/mui/MyDialog";
import { checkIsNumberLetterChinese } from "@/utils/util"; import { checkIsNumberLetterChinese } from "@/utils/util";
import { useMessage } from "@/components/MySnackbar"; import { useMessage } from "@/components/MySnackbar";
import CloudEController from "@/api/fileserver/CloudEController"; import CloudEController from "@/api/fileserver/CloudEController";
......
import React, { useMemo } from "react"; import React, { useMemo } from "react";
import MyDialog from "@/components/mui/Dialog"; import MyDialog from "@/components/mui/MyDialog";
import { useMessage } from "@/components/MySnackbar"; import { useMessage } from "@/components/MySnackbar";
import { getDataFileDelPackage } from "@/api/project_api"; import { getDataFileDelPackage } from "@/api/project_api";
import useMyRequest from "@/hooks/useMyRequest"; import useMyRequest from "@/hooks/useMyRequest";
......
import React, { useState, useCallback, useMemo, useEffect } from "react"; import React, { useState, useCallback, useMemo, useEffect } from "react";
import style from "./index.module.css"; import style from "./index.module.css";
import MyDialog from "@/components/mui/Dialog"; import MyDialog from "@/components/mui/MyDialog";
import folderIcon from "@/assets/project/folderIcon.svg"; import folderIcon from "@/assets/project/folderIcon.svg";
import bigFolderIcon from "@/assets/project/bigFolderIcon.svg"; import bigFolderIcon from "@/assets/project/bigFolderIcon.svg";
import { useMessage } from "@/components/MySnackbar"; import { useMessage } from "@/components/MySnackbar";
......
import React, { useState, useCallback, useMemo, useEffect } from "react"; import React, { useState, useCallback, useMemo, useEffect } from "react";
import style from "./index.module.css"; import style from "./index.module.css";
import MyDialog from "@/components/mui/Dialog"; import MyDialog from "@/components/mui/MyDialog";
import { Button } from "@mui/material"; import { Button } from "@mui/material";
import { uuid } from "@/utils/util"; import { uuid } from "@/utils/util";
import { useMessage } from "@/components/MySnackbar"; import { useMessage } from "@/components/MySnackbar";
......
...@@ -50,6 +50,8 @@ const BaseInfo = observer(() => { ...@@ -50,6 +50,8 @@ const BaseInfo = observer(() => {
const currentUserName = JSON.parse( const currentUserName = JSON.parse(
localStorage.getItem("userInfo") || "{}" localStorage.getItem("userInfo") || "{}"
).name; ).name;
// 弹窗显示控制
const [dialogOpen, setDialogOpen] = useState(false);
// 是否拥有编辑权限 // 是否拥有编辑权限
const hasEditAuth = useMemo(() => { const hasEditAuth = useMemo(() => {
if (!currentUserName) { if (!currentUserName) {
...@@ -193,41 +195,29 @@ const BaseInfo = observer(() => { ...@@ -193,41 +195,29 @@ const BaseInfo = observer(() => {
} }
}; };
const { run: deleteProjectRun, loading: deleteLoading } = useMyRequest( const { run: deleteProjectRun } = useMyRequest(deleteProject, {
deleteProject, onSuccess: async (result: any) => {
{ message.success("删除成功");
onSuccess: async (result: any) => { setDialogOpen(false);
message.success("删除成功"); const projectList = await getProjectList();
DialogRef.current.handleClose(); currentProjectStore.setProjectList(projectList);
const projectList = await getProjectList(); // 项目删完了
currentProjectStore.setProjectList(projectList); if (projectList.length === 0) {
// 项目删完了 currentProjectStore.changeProject({});
if (projectList.length === 0) { localStorage.setItem("fileServerEndPoint", "");
currentProjectStore.changeProject({}); setProjectInfo({});
localStorage.setItem("fileServerEndPoint", ""); } else {
setProjectInfo({}); projectList[0].filetoken = getFiletokenAccordingToId(projectList[0].id);
} else { currentProjectStore.changeProject(projectList[0]);
projectList[0].filetoken = getFiletokenAccordingToId( setFileServerEndPointLocalStorage(projectList[0].zoneId);
projectList[0].id getFiletokenAccordingToId(projectList[0].id).then((res) => {
); projectList[0].filetoken = res;
currentProjectStore.changeProject(projectList[0]); currentProjectStore.changeProject(projectList[0]);
setFileServerEndPointLocalStorage(projectList[0].zoneId); });
getFiletokenAccordingToId(projectList[0].id).then((res) => { setProjectInfo(projectList[0]);
projectList[0].filetoken = res; }
currentProjectStore.changeProject(projectList[0]); },
}); });
setProjectInfo(projectList[0]);
}
},
}
);
let DialogRef: any = React.createRef();
// 显示删除弹窗
const handleClickDelete = () => {
DialogRef.current.handleClickOpen();
setDeleteProjectName("");
};
const deleteProjectNameChange = (e: any) => { const deleteProjectNameChange = (e: any) => {
setDeleteProjectName(e.target.value); setDeleteProjectName(e.target.value);
...@@ -356,7 +346,7 @@ const BaseInfo = observer(() => { ...@@ -356,7 +346,7 @@ const BaseInfo = observer(() => {
<Button <Button
variant="contained" variant="contained"
className={style.updateButton} className={style.updateButton}
onClick={handleClickDelete} onClick={() => setDialogOpen(true)}
style={{ style={{
backgroundColor: "#fff", backgroundColor: "#fff",
color: "#FF4E4E", color: "#FF4E4E",
...@@ -367,11 +357,11 @@ const BaseInfo = observer(() => { ...@@ -367,11 +357,11 @@ const BaseInfo = observer(() => {
</Button> </Button>
</div> </div>
<MyDialog <MyDialog
handleSubmit={handleSubmitDelete} open={dialogOpen}
onRef={DialogRef} onConfirm={handleSubmitDelete}
onClose={() => setDialogOpen(false)}
title="删除项目" title="删除项目"
submitloading={deleteLoading} okSx={{ 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}>
......
...@@ -11,7 +11,7 @@ import { observer } from "mobx-react-lite"; ...@@ -11,7 +11,7 @@ import { observer } from "mobx-react-lite";
import _ from "lodash"; import _ from "lodash";
import Table from "@/components/Material.Ui/Table"; import Table from "@/components/Material.Ui/Table";
import Dialog from "@/components/mui/Dialog"; import Dialog from "@/components/mui/MyDialog";
import { memo, useCallback, useEffect, useMemo, useState } from "react"; import { memo, useCallback, useEffect, useMemo, useState } from "react";
import { Box, OutlinedInput } from "@mui/material"; import { Box, OutlinedInput } from "@mui/material";
import SearchIcon from "@mui/icons-material/Search"; import SearchIcon from "@mui/icons-material/Search";
...@@ -20,180 +20,180 @@ import { useStores } from "@/store"; ...@@ -20,180 +20,180 @@ import { useStores } from "@/store";
import { useMessage } from "@/components/MySnackbar"; import { useMessage } from "@/components/MySnackbar";
import MySelect, { IOption } from "@/components/mui/MySelect"; import MySelect, { IOption } from "@/components/mui/MySelect";
interface IProps { interface IProps {
setAddMemberDialog: (val: boolean) => void; setAddMemberDialog: (val: boolean) => void;
addMemberDialog: boolean; addMemberDialog: boolean;
getTableList: () => void; getTableList: () => void;
} }
const AddMember = observer((props: IProps) => { const AddMember = observer((props: IProps) => {
const { addMemberDialog, setAddMemberDialog, getTableList } = props; const { addMemberDialog, setAddMemberDialog, getTableList } = props;
const http = useHttp(); const http = useHttp();
const { currentProjectStore } = useStores(); const { currentProjectStore } = useStores();
const [tableData, setTableData] = useState([]); const [tableData, setTableData] = useState([]);
const [projectMember, setProjectMember] = useState(""); const [projectMember, setProjectMember] = useState("");
const [filterTableData, setFilterTableData] = useState([]); const [filterTableData, setFilterTableData] = useState([]);
const [checkData, setCheckData] = useState<string[]>([]); const [checkData, setCheckData] = useState<string[]>([]);
const [selectOptions, setSelectOptions] = useState<IOption[]>([]); const [selectOptions, setSelectOptions] = useState<IOption[]>([]);
const Message = useMessage(); const Message = useMessage();
const changePermission = useCallback( const changePermission = useCallback(
(val: IOption, index: number) => { (val: IOption, index: number) => {
const tableDataIndex = tableData[index] as any; const tableDataIndex = tableData[index] as any;
const newVal = { ...tableDataIndex, projectRole: val.value }; const newVal = { ...tableDataIndex, projectRole: val.value };
const newTableData = _.cloneDeep(tableData); const newTableData = _.cloneDeep(tableData);
newTableData.splice(index, 1, newVal); newTableData.splice(index, 1, newVal);
setTableData(newTableData); setTableData(newTableData);
}, },
[tableData] [tableData]
); );
const columns = useMemo(() => { const columns = useMemo(() => {
return [ return [
{ id: "checkbox", width: 50 }, { id: "checkbox", width: 50 },
{ id: "username", label: "项目成员", width: 160 }, { id: "username", label: "项目成员", width: 160 },
{ {
id: "projectRole", id: "projectRole",
label: "项目权限", label: "项目权限",
width: 160, width: 160,
render: (item: string, row: any, index: number) => { render: (item: string, row: any, index: number) => {
const defaultValue = selectOptions.filter( const defaultValue = selectOptions.filter(
(every) => every.value === item (every) => every.value === item
); );
return ( return (
<MySelect <MySelect
input={<OutlinedInput />} input={<OutlinedInput />}
value={ value={
defaultValue?.length defaultValue?.length
? defaultValue[0] ? defaultValue[0]
: { value: "VIEWER", label: "查看者" } : { value: "VIEWER", label: "查看者" }
} }
onChange={(val) => changePermission(val, index)} onChange={(val) => changePermission(val, index)}
options={selectOptions} options={selectOptions}
size="small" size="small"
/> />
); );
}, },
}, },
]; ];
}, [changePermission, selectOptions]); }, [changePermission, selectOptions]);
useEffect(() => { useEffect(() => {
if (addMemberDialog) { if (addMemberDialog) {
http.get<IResponse<any>>("/cpp/project/listroles").then((res) => { http.get<IResponse<any>>("/cpp/project/listroles").then((res) => {
const arr = []; const arr = [];
const { data } = res; const { data } = res;
for (const key in data) { for (const key in data) {
arr.push({ arr.push({
label: String(data[key]), label: String(data[key]),
value: key, value: key,
}); });
} }
setSelectOptions(arr); setSelectOptions(arr);
}); });
} }
}, [addMemberDialog, http]); }, [addMemberDialog, http]);
/** 过滤表格数据 */ /** 过滤表格数据 */
useEffect(() => { useEffect(() => {
if (!!projectMember) { if (!!projectMember) {
const newVal = const newVal =
tableData.filter((item: any) => { tableData.filter((item: any) => {
return item?.username?.includes(projectMember); return item?.username?.includes(projectMember);
}) || []; }) || [];
setFilterTableData(newVal || []); setFilterTableData(newVal || []);
} else { } else {
setFilterTableData(tableData); setFilterTableData(tableData);
} }
}, [projectMember, tableData]); }, [projectMember, tableData]);
/** 获取表格数据 */ /** 获取表格数据 */
useEffect(() => { useEffect(() => {
if (!addMemberDialog) return; if (!addMemberDialog) return;
const projectInfo = toJS(currentProjectStore?.currentProjectInfo); const projectInfo = toJS(currentProjectStore?.currentProjectInfo);
http http
.get<IResponse<any>>("/cpp/project/listusers", { .get<IResponse<any>>("/cpp/project/listusers", {
params: { id: projectInfo?.id || "" }, params: { id: projectInfo?.id || "" },
}) })
.then((res) => { .then((res) => {
setTableData(res?.data); setTableData(res?.data);
}); });
}, [currentProjectStore?.currentProjectInfo, http, addMemberDialog]); }, [currentProjectStore?.currentProjectInfo, http, addMemberDialog]);
const onClose = (event: any = {}, reason: any = "other") => { const onClose = (event: any = {}, reason: any = "other") => {
// 点击弹窗外不关闭弹窗 // 点击弹窗外不关闭弹窗
if (reason === "backdropClick") { if (reason === "backdropClick") {
return; return;
} }
setAddMemberDialog(false); setAddMemberDialog(false);
}; };
const onConfirm = () => { const onConfirm = () => {
const projectInfo = toJS(currentProjectStore?.currentProjectInfo); const projectInfo = toJS(currentProjectStore?.currentProjectInfo);
const params = tableData.filter((item: any) => { const params = tableData.filter((item: any) => {
return checkData.includes(item?.username); return checkData.includes(item?.username);
}); });
if (params.length) { if (params.length) {
http http
.put<IResponse<any>>( .put<IResponse<any>>(
`/cpp/project/updatemember?id=${projectInfo?.id || ""}`, `/cpp/project/updatemember?id=${projectInfo?.id || ""}`,
params params
) )
.then((res) => { .then((res) => {
const { errorCode } = res; const { errorCode } = res;
if (errorCode === 0) { if (errorCode === 0) {
Message.success("新增成功!"); Message.success("新增成功!");
getTableList(); getTableList();
setAddMemberDialog(false); setAddMemberDialog(false);
} }
}); });
} else { } else {
Message.warning("请先选择项目成员!"); Message.warning("请先选择项目成员!");
} }
}; };
return ( return (
<> <>
<Dialog <Dialog
open={addMemberDialog} open={addMemberDialog}
onClose={onClose} onClose={onClose}
onConfirm={onConfirm} onConfirm={onConfirm}
title="添加成员" title="添加成员"
> >
<Box> <Box>
<Box sx={{ mb: 2 }}> <Box sx={{ mb: 2 }}>
<OutlinedInput <OutlinedInput
onChange={(e: any) => { onChange={(e: any) => {
_.debounce(() => { _.debounce(() => {
setProjectMember(e.target.value); setProjectMember(e.target.value);
}, 200)(); }, 200)();
}} }}
placeholder="搜索项目成员" placeholder="搜索项目成员"
size="small" size="small"
sx={{ width: "100%", height: 32 }} sx={{ width: "100%", height: 32 }}
endAdornment={<SearchIcon style={{ color: "#8A9099" }} />} endAdornment={<SearchIcon style={{ color: "#8A9099" }} />}
/> />
</Box> </Box>
<div style={{ overflowY: "scroll", maxHeight: 400 }}> <div style={{ overflowY: "scroll", maxHeight: 400 }}>
<Table <Table
checkboxData={(val: string[]) => setCheckData(val)} checkboxData={(val: string[]) => setCheckData(val)}
param="username" param="username"
disabledparam={"enabled"} disabledparam={"enabled"}
rowHover={true} rowHover={true}
stickyheader={true} stickyheader={true}
rows={filterTableData} rows={filterTableData}
rowsPerPage="99" rowsPerPage="99"
headCells={columns} headCells={columns}
footer={false} footer={false}
tableStyle={{ minWidth: "auto" }} tableStyle={{ minWidth: "auto" }}
borderBottom="none" borderBottom="none"
/> />
</div> </div>
</Box> </Box>
</Dialog> </Dialog>
</> </>
); );
}); });
export default memo(AddMember); export default memo(AddMember);
...@@ -12,7 +12,7 @@ import { observer } from "mobx-react-lite"; ...@@ -12,7 +12,7 @@ import { observer } from "mobx-react-lite";
import { toJS } from "mobx"; import { toJS } from "mobx";
import MySelect, { IOption } from "@/components/mui/MySelect"; import MySelect, { IOption } from "@/components/mui/MySelect";
import Dialog from "@/components/mui/Dialog"; import Dialog from "@/components/mui/MyDialog";
import { IResponse, useHttp } from "@/api/http"; import { IResponse, useHttp } from "@/api/http";
import { useStores } from "@/store/index"; import { useStores } from "@/store/index";
import { IDialogInfo } from "../interface"; import { IDialogInfo } from "../interface";
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
*/ */
// import Dialog from "@/components/Material.Ui/Dialog"; // import Dialog from "@/components/Material.Ui/Dialog";
import { IResponse, useHttp } from "@/api/http"; import { IResponse, useHttp } from "@/api/http";
import Dialog from "@/components/mui/Dialog"; import Dialog from "@/components/mui/MyDialog";
import { useMessage } from "@/components/MySnackbar"; import { useMessage } from "@/components/MySnackbar";
import { useStores } from "@/store"; import { useStores } from "@/store";
import { toJS } from "mobx"; import { toJS } from "mobx";
...@@ -17,50 +17,50 @@ import { memo } from "react"; ...@@ -17,50 +17,50 @@ import { memo } from "react";
import { IDialogInfo } from "../interface"; import { IDialogInfo } from "../interface";
interface IProps { interface IProps {
setRemoveDialog: (val: IDialogInfo) => void; setRemoveDialog: (val: IDialogInfo) => void;
removeDialog: IDialogInfo; removeDialog: IDialogInfo;
getTableList: () => void; getTableList: () => void;
} }
const RemoveItem = observer((props: IProps) => { const RemoveItem = observer((props: IProps) => {
const { removeDialog, setRemoveDialog, getTableList } = props; const { removeDialog, setRemoveDialog, getTableList } = props;
const http = useHttp(); const http = useHttp();
const Message = useMessage(); const Message = useMessage();
const { currentProjectStore } = useStores(); const { currentProjectStore } = useStores();
const onClose = () => { const onClose = () => {
setRemoveDialog({ isShow: false, username: "" }); setRemoveDialog({ isShow: false, username: "" });
}; };
const onConfirm = () => { const onConfirm = () => {
const projectInfo = toJS(currentProjectStore?.currentProjectInfo); const projectInfo = toJS(currentProjectStore?.currentProjectInfo);
http http
.del<IResponse<any>>( .del<IResponse<any>>(
`/cpp/project/removemember?id=${projectInfo?.id || ""}&username=${ `/cpp/project/removemember?id=${projectInfo?.id || ""}&username=${
removeDialog.username || "" removeDialog.username || ""
}` }`
) )
.then((res) => { .then((res) => {
const { errorCode } = res; const { errorCode } = res;
if (errorCode === 0) { if (errorCode === 0) {
Message.success("移出成功!"); Message.success("移出成功!");
getTableList(); getTableList();
setRemoveDialog({ isShow: false, username: "" }); setRemoveDialog({ isShow: false, username: "" });
} }
}); });
}; };
return ( return (
<> <>
<Dialog <Dialog
open={removeDialog?.isShow} open={removeDialog?.isShow}
onClose={onClose} onClose={onClose}
onConfirm={onConfirm} onConfirm={onConfirm}
title="移出项目" title="移出项目"
> >
<div>确认移出该成员吗?</div> <div>确认移出该成员吗?</div>
</Dialog> </Dialog>
</> </>
); );
}); });
export default memo(RemoveItem); export default memo(RemoveItem);
import { memo } from "react"; import { memo } from "react";
import { Box, Typography } from "@mui/material"; import { Box, Typography } from "@mui/material";
import Dialog from "@/components/mui/Dialog"; import Dialog from "@/components/mui/MyDialog";
const SimpleDialog = (props: any) => { const SimpleDialog = (props: any) => {
const { openDialog, closeDialog, onConfirm, text, title } = props; const { openDialog, closeDialog, onConfirm, text, title } = props;
......
...@@ -2,7 +2,7 @@ import { memo, useCallback, useEffect, useMemo, useState } from "react"; ...@@ -2,7 +2,7 @@ import { memo, useCallback, useEffect, useMemo, useState } from "react";
import styles from "../index.module.css"; import styles from "../index.module.css";
import { Box, Typography } from "@mui/material"; import { Box, Typography } from "@mui/material";
import Button from "@/components/mui/Button"; import Button from "@/components/mui/Button";
import Dialog from "@/components/mui/Dialog"; import Dialog from "@/components/mui/MyDialog";
import OutlinedInput from "@mui/material/OutlinedInput"; import OutlinedInput from "@mui/material/OutlinedInput";
import RadioGroupOfButtonStyle from "@/components/CommonComponents/RadioGroupOfButtonStyle"; import RadioGroupOfButtonStyle from "@/components/CommonComponents/RadioGroupOfButtonStyle";
import SearchIcon from "@mui/icons-material/Search"; import SearchIcon from "@mui/icons-material/Search";
......
import { memo } from "react"; import { memo } from "react";
import { Box, Typography } from "@mui/material"; import { Box, Typography } from "@mui/material";
import Dialog from "@/components/mui/Dialog"; import Dialog from "@/components/mui/MyDialog";
const SimpleDialog = (props: any) => { const SimpleDialog = (props: any) => {
const { openDialog, closeDialog, onConfirm, text, title } = props; const { openDialog, closeDialog, onConfirm, text, title } = props;
......
import style from "./index.module.css"; import style from "./index.module.css";
import { TextField, MenuItem } from "@mui/material"; import { TextField, MenuItem } from "@mui/material";
import MyDialog from "@/components/mui/MyDialog"; import MyDialog from "@/components/mui/MyDialog";
import React, { useState, useEffect, useImperativeHandle } from "react"; import React, { useState, useEffect } from "react";
import useMyRequest from "@/hooks/useMyRequest"; import useMyRequest from "@/hooks/useMyRequest";
import { hpczone, addProject } from "@/api/project_api"; import { hpczone, addProject } from "@/api/project_api";
import { useMessage } from "@/components/MySnackbar"; import { useMessage } from "@/components/MySnackbar";
...@@ -18,10 +18,15 @@ type zoneIdOption = { ...@@ -18,10 +18,15 @@ type zoneIdOption = {
name: string; name: string;
}; };
const AddProject = (props: any) => { type IAddProjectProps = {
addOpen: boolean;
setAddOpen: any;
};
const AddProject = (props: IAddProjectProps) => {
const { addOpen, setAddOpen } = props;
const { currentProjectStore } = useStores(); const { currentProjectStore } = useStores();
const message = useMessage(); const message = useMessage();
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,
...@@ -34,12 +39,6 @@ const AddProject = (props: any) => { ...@@ -34,12 +39,6 @@ const AddProject = (props: any) => {
}); });
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);
useImperativeHandle(props.onRef, () => {
return {
handleClickOpen: handleClickOpen,
};
});
// 设置计算区 // 设置计算区
const { run } = useMyRequest(hpczone, { const { run } = useMyRequest(hpczone, {
...@@ -49,13 +48,9 @@ const AddProject = (props: any) => { ...@@ -49,13 +48,9 @@ const AddProject = (props: any) => {
}, },
}); });
const { run: addProjectRun } = useMyRequest(addProject, { const { run: addProjectRun } = useMyRequest(addProject, {
onBefore: () => {
setSubmitloading(true);
},
onSuccess: async (result: any) => { onSuccess: async (result: any) => {
if (result.data) { if (result.data) {
setSubmitloading(false); setAddOpen(false);
DialogRef.current.handleClose();
message.success("新建项目成功"); message.success("新建项目成功");
const projectList = await getProjectList(); const projectList = await getProjectList();
currentProjectStore.setProjectList(projectList); currentProjectStore.setProjectList(projectList);
...@@ -74,7 +69,7 @@ const AddProject = (props: any) => { ...@@ -74,7 +69,7 @@ const AddProject = (props: any) => {
} }
}, },
onError: () => { onError: () => {
setSubmitloading(false); setAddOpen(false);
}, },
}); });
...@@ -82,18 +77,15 @@ const AddProject = (props: any) => { ...@@ -82,18 +77,15 @@ const AddProject = (props: any) => {
run(); run();
}, [run]); }, [run]);
const handleClickOpen = () => { useEffect(() => {
DialogRef.current.handleClickOpen(); if (addOpen) {
initData(); setName("");
}; setDesc("");
if (zoneIdOptions.length > 0) {
const initData = () => { setZoneId(zoneIdOptions[0].id);
setName(""); }
setDesc("");
if (zoneIdOptions.length > 0) {
setZoneId(zoneIdOptions[0].id);
} }
}; }, [addOpen, setZoneId, zoneIdOptions]);
const checkName = (name: string) => { const checkName = (name: string) => {
if (name) { if (name) {
...@@ -167,10 +159,10 @@ const AddProject = (props: any) => { ...@@ -167,10 +159,10 @@ const AddProject = (props: any) => {
return ( return (
<MyDialog <MyDialog
handleSubmit={handleSubmit} open={addOpen}
onRef={DialogRef} onConfirm={handleSubmit}
onClose={() => setAddOpen(false)}
title="新建项目" title="新建项目"
submitloading={submitloading}
> >
<div className={style.formBox} onClick={handleFromBox}> <div className={style.formBox} onClick={handleFromBox}>
<TextField <TextField
......
...@@ -8,92 +8,92 @@ import React, { useEffect, useState } from "react"; ...@@ -8,92 +8,92 @@ import React, { useEffect, useState } from "react";
import { observer } from "mobx-react-lite"; import { observer } from "mobx-react-lite";
import AddProject from "../AddProject"; import AddProject from "../AddProject";
import { import {
setFileServerEndPointLocalStorage, setFileServerEndPointLocalStorage,
getFiletokenAccordingToId, getFiletokenAccordingToId,
} from "@/views/Project/project"; } from "@/views/Project/project";
const CurrentProject = observer(() => { const CurrentProject = observer(() => {
const { currentProjectStore } = useStores(); const { currentProjectStore } = useStores();
let addProjectRef: any = React.createRef(); const [projectListOpen, setProjectListOpen] = useState(false);
const [projectListOpen, setProjectListOpen] = useState(false); const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);
// const [addProjectOpen, setAddProjectOpen] = useState(false);
const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);
// 结合handleShowProjectList中的event.nativeEvent.stopImmediatePropagation();实现点击空白区域隐藏项目列表 useEffect(() => {
useEffect(() => { document.addEventListener("click", (e) => {
document.addEventListener("click", (e) => { setProjectListOpen(false);
setProjectListOpen(false); });
}); }, []);
}, []);
const handleShowProjectList = (event: React.MouseEvent<HTMLElement>) => { const handleShowProjectList = (event: React.MouseEvent<HTMLElement>) => {
event.nativeEvent.stopImmediatePropagation(); event.nativeEvent.stopImmediatePropagation();
setAnchorEl(event.currentTarget); setAnchorEl(event.currentTarget);
setProjectListOpen((previousOpen) => !previousOpen); setProjectListOpen((previousOpen) => !previousOpen);
}; };
const canBeOpen = projectListOpen && Boolean(anchorEl); const canBeOpen = projectListOpen && Boolean(anchorEl);
const id = canBeOpen ? "spring-popper" : undefined; const id = canBeOpen ? "spring-popper" : undefined;
const handleChangeCurrentProject = (project: any) => { const handleChangeCurrentProject = (project: any) => {
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);
}); });
setProjectListOpen(!projectListOpen); setProjectListOpen(!projectListOpen);
}; };
const openAddProject = () => { const openAddProject = () => {
addProjectRef.current.handleClickOpen(); setAddOpen(true);
setProjectListOpen(false); setProjectListOpen(false);
}; };
return ( // 新建弹窗显示控制
<div> const [addOpen, setAddOpen] = useState(false);
<div
className={style.currentProject} return (
aria-describedby={id} <div>
onClick={handleShowProjectList} <div
> className={style.currentProject}
<img src={logo} alt="" className={style.logo} /> aria-describedby={id}
<div className={style.info}> onClick={handleShowProjectList}
<div className={style.productName}> >
{currentProjectStore.currentProductInfo.name} <img src={logo} alt="" className={style.logo} />
</div> <div className={style.info}>
<div <div className={style.productName}>
className={style.projectName} {currentProjectStore.currentProductInfo.name}
title={currentProjectStore.currentProjectInfo.name} </div>
> <div
{currentProjectStore.currentProjectInfo.name || "暂无项目"} className={style.projectName}
</div> title={currentProjectStore.currentProjectInfo.name}
</div> >
<ArrowForwardIosIcon {currentProjectStore.currentProjectInfo.name || "暂无项目"}
className={style.showProjectList} </div>
style={{ fontSize: 12 }} </div>
/> <ArrowForwardIosIcon
</div> className={style.showProjectList}
<AddProject onRef={addProjectRef} /> style={{ fontSize: 12 }}
<Popper />
id={id} </div>
open={projectListOpen} <AddProject addOpen={addOpen} setAddOpen={setAddOpen} />
anchorEl={anchorEl} <Popper
placement="right-start" id={id}
transition open={projectListOpen}
style={{ zIndex: 100 }} anchorEl={anchorEl}
> placement="right-start"
{({ TransitionProps }) => ( transition
<Fade {...TransitionProps} timeout={350}> style={{ zIndex: 100 }}
<div> >
<ProjectListPopper {({ TransitionProps }) => (
handleClickOpen={openAddProject} <Fade {...TransitionProps} timeout={350}>
handleChangeCurrentProject={handleChangeCurrentProject} <div>
/> <ProjectListPopper
</div> handleClickOpen={openAddProject}
</Fade> handleChangeCurrentProject={handleChangeCurrentProject}
)} />
</Popper> </div>
</div> </Fade>
); )}
</Popper>
</div>
);
}); });
export default CurrentProject; export default CurrentProject;
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/ */
import { saveUserSpec } from "@/api/workbench_api"; import { saveUserSpec } from "@/api/workbench_api";
import MyDialog from "@/components/mui/Dialog"; import MyDialog from "@/components/mui/MyDialog";
import MyInput from "@/components/mui/MyInput"; import MyInput from "@/components/mui/MyInput";
import { checkIsNumberLetterChinese } from "@/utils/util"; import { checkIsNumberLetterChinese } from "@/utils/util";
import { useState } from "react"; import { useState } from "react";
......
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