Commit 387dff16 authored by chenshouchao's avatar chenshouchao

feat: 迭代优化、预算不足提醒

parent 76f010d7
......@@ -7,6 +7,7 @@ import {
DialogTitle,
} from "@mui/material";
import CloseIcon from "@mui/icons-material/Close";
import { ThemeProvider, createTheme } from "@mui/material/styles";
import MyButton from "./MyButton";
......@@ -51,8 +52,27 @@ export interface IDialogProps {
| "info"
| "warning"; //按钮颜色风格
loading?: boolean; // 确认按钮是否处于loading状态
isText?: boolean; // 是否文本弹窗
}
const theme = createTheme({
// 0px 12px 15px -7px rgb(0 0 0 / 11%), 0px 24px 38px 3px rgb(0 0 0 / 9%), 0px 9px 46px 8px rgb(0 0 0 / 9%)
// .css-1t1j96h-MuiPaper-root-MuiDialog-paper
components: {
MuiPaper: {
styleOverrides: {
root: {
"&.MuiDialog-paper": {
boxShadow:
"0px 12px 15px -7px rgb(0 0 0 / 11%), 0px 24px 38px 3px rgb(0 0 0 / 9%), 0px 9px 46px 8px rgb(0 0 0 / 9%)",
},
},
},
},
},
});
const MyDialog: React.FunctionComponent<IDialogProps> = (props) => {
const {
title,
......@@ -74,6 +94,7 @@ const MyDialog: React.FunctionComponent<IDialogProps> = (props) => {
clickMaskClose = false,
loading = false,
okColor = "primary",
isText = false,
} = props;
const handelClose = (
......@@ -91,7 +112,7 @@ const MyDialog: React.FunctionComponent<IDialogProps> = (props) => {
return footerRender ? (
footerRender()
) : (
<DialogActions style={{ padding: "0 24px 16px 24px" }}>
<DialogActions style={{ padding: "16px 24px 16px 24px" }}>
{showCancel ? (
<MyButton
text={cancelText || "取消"}
......@@ -127,54 +148,66 @@ const MyDialog: React.FunctionComponent<IDialogProps> = (props) => {
loading,
showConfirm,
]);
const contentPadding = useMemo(() => {
if (isText) {
return "8px 24px 24px"; // 文本
} else {
return "8px 24px 12px"; // 表单
}
}, [isText]);
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",
borderRadius: "8px",
<ThemeProvider theme={theme}>
<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",
borderRadius: "8px",
},
},
},
}}
>
{isHideHeader ? null : (
<DialogTitle id="alert-dialog-title" sx={{ padding: "20px 24px" }}>
<div
style={{
display: "flex",
justifyContent: "space-between",
alignItems: "center",
fontWeight: 600,
}}
>
<span
style={{ fontSize: 16, lineHeight: "24px", color: "#1E2633" }}
>
{title}
</span>
<CloseIcon
onClick={onClose}
sx={{
fontSize: "18px",
color: "#C2C6CC",
cursor: "pointer",
":hover": { background: "#f0f2f5", borderRadius: "2px" },
}}
>
{isHideHeader ? null : (
<DialogTitle id="alert-dialog-title" sx={{ padding: "20px 24px" }}>
<div
style={{
display: "flex",
justifyContent: "space-between",
alignItems: "center",
fontWeight: 600,
}}
/>
</div>
</DialogTitle>
)}
<DialogContent style={{ minWidth: 388 }}>{children}</DialogContent>
{Footer}
</Dialog>
>
<span
style={{ fontSize: 16, lineHeight: "24px", color: "#1E2633" }}
>
{title}
</span>
<CloseIcon
onClick={onClose}
sx={{
fontSize: "18px",
color: "#C2C6CC",
cursor: "pointer",
":hover": { background: "#f0f2f5", borderRadius: "2px" },
}}
/>
</div>
</DialogTitle>
)}
<DialogContent style={{ minWidth: 388, padding: contentPadding }}>
{children}
</DialogContent>
{Footer}
</Dialog>
</ThemeProvider>
);
};
......
......@@ -110,7 +110,7 @@ const AddFolder = (props: IAddFolderProps) => {
onConfirm={handleAddSubmit}
title="新建文件夹"
>
<div style={{ padding: "12px 0" }}>
<div>
<MyInput
sx={{
width: "388px",
......@@ -125,7 +125,12 @@ const AddFolder = (props: IAddFolderProps) => {
helperText={fileNameCheck.help}
InputProps={{
endAdornment: (
<InputAdornment position="end" style={{ color: fileName.length >= 30 ? "#d32f2f" : "#C2C6CC" }}>
<InputAdornment
position="end"
style={{
color: fileName.length >= 30 ? "#d32f2f" : "#C2C6CC",
}}
>
{fileName.length}/30
</InputAdornment>
),
......
......@@ -90,6 +90,7 @@ const DeleteDialog = (props: IDeleteFileProps) => {
onClose={() => setDeleteDialogOpen(false)}
onConfirm={handleSubmit}
okColor="error"
isText={true}
>
{currentOperateFile
? "确认删除该数据吗?"
......
......@@ -67,7 +67,9 @@
color: #1e2633;
margin-right: 8px;
}
.red{
color: rgba(255, 78, 78, 1);
}
.verticalLine {
height: 32px;
border-right: 1px solid #ebedf0;
......
......@@ -169,7 +169,10 @@ const ProjectOverview = observer(() => {
项目剩余预算
</div>
<div>
<span className={style.numberDisplay}>
<span className={classNames({
[style.numberDisplay]: true,
[style.red]:overviewInfo.projectRemainingBudget?.toFixed(2) < 100
})}>
{overviewInfo.projectRemainingBudget?.toFixed(2)}
</span>
......
......@@ -7,6 +7,7 @@
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
import { memo, useMemo } from "react";
import { useLocation } from "react-router-dom";
import { Box } from "@mui/system";
import { useStores } from "@/store/index";
......@@ -20,6 +21,7 @@ import usePass from "@/hooks/usePass";
const ProjectSetting = observer(() => {
const { currentProjectStore } = useStores();
const isPass = usePass();
const location: any = useLocation();
const tabList = useMemo(() => {
return [
{
......@@ -54,7 +56,10 @@ const ProjectSetting = observer(() => {
</span>
</div>
<Box sx={{ width: "100%", typography: "body1" }}>
<Tabs tabList={tabList} />
<Tabs
tabList={tabList}
defaultValue={location?.state?.type || "projectMember"}
/>
</Box>
</div>
);
......
......@@ -4,11 +4,9 @@ import classNames from "classnames";
import { Box, Typography } from "@mui/material";
import RadioGroupOfButtonStyle from "@/components/CommonComponents/RadioGroupOfButtonStyle";
import SearchIcon from "@mui/icons-material/Search";
import MyButton from "@/components/mui/MyButton";
import OutlinedInput from "@mui/material/OutlinedInput";
import MySwitch from "@/components/mui/MySwitch";
import FullScreenDrawer from "@/components/CommonComponents/FullScreenDrawer";
import Checkbox from "@mui/material/Checkbox";
import useMyRequest from "@/hooks/useMyRequest";
import AddIcon from "@mui/icons-material/Add";
import WorkFlowEdit from "@/views/WorkFlowEdit";
......
.content {
width: 400px;
font-size: 14px;
line-height: 22px;
color: rgba(30, 38, 51, 1);
}
import MyDialog from "@/components/mui/MyDialog";
import MyButton from "@/components/mui/MyButton";
import { DialogActions } from "@mui/material";
import style from "./index.module.css";
import { useNavigate } from "react-router-dom";
const RemindBudgetDialog = (props: any) => {
const navigate = useNavigate();
const { rbOpen, rbClose, goToProjectSubmitWork, id, isParentUser, isOwner } =
props;
const goToprojectSetting = () => {
navigate(`/product/cadd/projectSetting`, {
state: { type: "baseInfo" },
});
};
const footerRender = () => {
return (
<DialogActions style={{ padding: "16px 24px 16px 24px" }}>
<MyButton
text="继续使用"
onClick={() => goToProjectSubmitWork(id)}
variant="outlined"
color="secondary"
/>
{isParentUser && isOwner && (
<MyButton
text="添加预算"
onClick={() => goToprojectSetting()}
variant="contained"
style={{ marginLeft: "12px" }}
/>
)}
</DialogActions>
);
};
return (
<>
<MyDialog
open={rbOpen}
onClose={rbClose}
title="项目剩余预算不足提示"
footerRender={footerRender}
isText={true}
>
<div className={style.content}>
当前项目剩余预算不足100元,存在余额不足的风险,可能导致无法启动任务或中断运行中的任务,建议您先添加项目预算或联系项目所有者添加预算!
</div>
</MyDialog>
</>
);
};
export default RemindBudgetDialog;
......@@ -13,6 +13,7 @@ const SimpleDialog = (props: any) => {
onConfirm={onConfirm}
title={title}
okColor="error"
isText={true}
>
<Box>
<Typography sx={{ fontSize: "14px", fontWeight: "400" }}>
......
......@@ -6,19 +6,23 @@
* @FilePath: /bkunyun/src/views/Project/ProjectWorkbench/workbenchTemplate/components/templateBox.tsx
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
import { memo, useCallback } from "react";
import { memo, useCallback, useState } from "react";
import styles from "../index.module.css";
import { Box, Typography } from "@mui/material";
import MyButton from "@/components/mui/MyButton";
import usePass from "@/hooks/usePass";
import RemindBudgetDialog from "./RemindBudgetDialog.tsx";
import { useNavigate } from "react-router-dom";
const TemplateBox = (props: any) => {
const info = props.data;
const { isParentUser, isOwner, greaterThan100 } = props;
const isPass = usePass();
const navigate = useNavigate();
const [rbOpen, setRbOpen] = useState(false);
const [id, setId] = useState("");
const addTemplateBlock = useCallback(
const goToProjectSubmitWork = useCallback(
(id: string) => {
navigate(`/product/cadd/projectSubmitWork`, {
state: { id },
......@@ -27,91 +31,115 @@ const TemplateBox = (props: any) => {
[navigate]
);
const handleJudgeBudget = useCallback(
(id: string) => {
setId(id);
if (!greaterThan100) {
goToProjectSubmitWork(id);
} else {
setRbOpen(true);
}
},
[goToProjectSubmitWork, setRbOpen, setId, greaterThan100]
);
return (
<Box className={styles.template}>
<Box className={styles.templateBlock}>
<Box>
<Box
sx={{
display: "flex",
justifyContent: "space-between",
alignItems: "center",
}}
>
<Typography
<>
<Box className={styles.template}>
<Box className={styles.templateBlock}>
<Box>
<Box
sx={{
fontSize: "14px",
fontWeight: "600",
color: "#1E2633",
marginBottom: "4px",
overflow: "hidden",
textOverflow: "ellipsis",
display: "flex",
justifyContent: "space-between",
alignItems: "center",
}}
>
{info.title}
</Typography>
{info.creator !== "root" && (
<Box
<Typography
sx={{
fontSize: "14px",
fontWeight: "600",
color: "#1E2633",
marginBottom: "4px",
overflow: "hidden",
textOverflow: "ellipsis",
}}
>
{info.title}
</Typography>
{info.creator !== "root" && (
<Box
sx={{
backgroundColor: "rgba(227, 250, 236, 1)",
color: "rgba(2, 171, 131, 1)",
lineHeight: "20px",
padding: "1px 9px",
fontSize: "12px",
}}
>
自定义
</Box>
)}
</Box>
<Box sx={{ display: "flex", marginBottom: "8px" }}>
<Typography
sx={{
backgroundColor: "rgba(227, 250, 236, 1)",
color: "rgba(2, 171, 131, 1)",
lineHeight: "20px",
padding: "1px 9px",
fontSize: "12px",
fontWeight: "400",
color: "#1370FF",
marginRight: "24px",
}}
>
自定义
</Box>
)}
</Box>
<Box sx={{ display: "flex", marginBottom: "8px" }}>
<Typography
sx={{
fontSize: "12px",
fontWeight: "400",
color: "#1370FF",
marginRight: "24px",
}}
>
版本:{info.version}
</Typography>
<Typography
sx={{ fontSize: "12px", fontWeight: "400", color: "#1370FF" }}
>
更新时间:{info.updatedTime}
版本:{info.version}
</Typography>
<Typography
sx={{ fontSize: "12px", fontWeight: "400", color: "#1370FF" }}
>
更新时间:{info.updatedTime}
</Typography>
</Box>
<Typography className={styles.templateDescText}>
{info.description ? info.description : "此模板暂无描述。"}
</Typography>
</Box>
<Typography className={styles.templateDescText}>
{info.description ? info.description : "此模板暂无描述。"}
</Typography>
</Box>
<Box
sx={{
display: "flex",
justifyContent: "end",
}}
>
{isPass("PROJECT_WORKBENCH_FLOES_USE", "MANAGER") && (
<MyButton
size="medium"
text="删除模版"
onClick={() => {
props.startDialog(info.id);
}}
style={{ backgroundColor: "#F0F2F5", color: "#565C66" }}
/>
)}
{isPass("PROJECT_WORKBENCH_FLOES_USE", "USER") && (
<MyButton
size="medium"
text="使用模版"
onClick={() => addTemplateBlock(info.id)}
style={{ marginLeft: "12px" }}
/>
)}
<Box
sx={{
display: "flex",
justifyContent: "end",
}}
>
{isPass("PROJECT_WORKBENCH_FLOES_USE", "MANAGER") && (
<MyButton
size="medium"
text="删除模版"
onClick={() => {
props.startDialog(info.id);
}}
style={{ backgroundColor: "#F0F2F5", color: "#565C66" }}
/>
)}
{isPass("PROJECT_WORKBENCH_FLOES_USE", "USER") && (
<MyButton
size="medium"
text="使用模版"
onClick={() => handleJudgeBudget(info.id)}
style={{ marginLeft: "12px" }}
/>
)}
</Box>
</Box>
</Box>
</Box>
{rbOpen && (
<RemindBudgetDialog
rbOpen={rbOpen}
rbClose={() => setRbOpen(false)}
id={id}
goToProjectSubmitWork={goToProjectSubmitWork}
isParentUser={isParentUser}
isOwner={isOwner}
></RemindBudgetDialog>
)}
</>
);
};
......
......@@ -10,8 +10,8 @@ import { memo, useEffect, useState } from "react";
import { Box, Typography } from "@mui/material";
import { toJS } from "mobx";
import { observer } from "mobx-react-lite";
import FormatListBulletedRoundedIcon from '@mui/icons-material/FormatListBulletedRounded';
import FormatListBulletedRoundedIcon from "@mui/icons-material/FormatListBulletedRounded";
import { getLoaclStorageOfKey } from "@/api/fileserver/utils";
import MyButton from "@/components/mui/MyButton";
import SearchInput from "@/components/BusinessComponents/SearchInput";
......@@ -24,11 +24,15 @@ import {
getWorkbenchTemplate,
deleteWorkbenchTemplate,
} from "@/api/workbench_api";
import { getOverviewInfo, getProject } from "@/api/project_api";
import usePass from "@/hooks/usePass";
import { useStores } from "@/store";
import styles from "./index.module.css";
const userInfo = getLoaclStorageOfKey("userInfo");
const ProjectMembers = observer(() => {
const { currentProjectStore } = useStores();
const projectIdData = toJS(currentProjectStore.currentProjectInfo.id);
......@@ -109,6 +113,49 @@ const ProjectMembers = observer(() => {
}
};
// 项目剩余预算是否大于100 Greater than 100
const [greaterThan100, setGreaterThan100] = useState(false);
// 获取概览基本信息 用于获取项目剩余预算 projectRemainingBudget
const { run: getOverview } = useMyRequest(getOverviewInfo, {
onSuccess: (result: any) => {
if (result.data.projectRemainingBudget > 100) {
setGreaterThan100(true);
} else {
setGreaterThan100(false);
}
},
});
useEffect(() => {
if (currentProjectStore.currentProjectInfo.id) {
getOverview({
id: currentProjectStore.currentProjectInfo.id as string,
});
}
}, [currentProjectStore.currentProjectInfo.id, getOverview]);
// 用户是否为父用户
const [isParentUser] = useState(!userInfo.parent ? true : false);
// 当前用户是否为项目的所有者
const [isOwner, setIsOwner] = useState(false);
const { run: getProjectFn } = useMyRequest(getProject, {
onSuccess: (result: any) => {
if (result.data.projectRole === "OWNER") {
setIsOwner(true);
} else {
setIsOwner(false);
}
},
});
useEffect(() => {
getProjectFn({
id: currentProjectStore.currentProjectInfo.id as string,
});
}, [currentProjectStore.currentProjectInfo.id, getProjectFn]);
return (
<Box className={styles.headerBox}>
<Box className={styles.tabBox}>
......@@ -116,7 +163,7 @@ const ProjectMembers = observer(() => {
{isPass("PROJECT_WORKBENCH_FLOES_ADD", "MANAGER") && (
<MyButton
text={"管理工作流模板"}
startIcon={<FormatListBulletedRoundedIcon fontSize="small"/>}
startIcon={<FormatListBulletedRoundedIcon fontSize="small" />}
onClick={addTemplateBlock}
size={"medium"}
/>
......@@ -147,7 +194,14 @@ const ProjectMembers = observer(() => {
templateList.length > 0 &&
templateList.map((item, key) => {
return (
<TemplateBox key={key} data={item} startDialog={startDialog} />
<TemplateBox
key={key}
data={item}
startDialog={startDialog}
isParentUser={isParentUser}
isOwner={isOwner}
greaterThan100={greaterThan100}
/>
);
})}
</Box>
......
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