Commit 50746e14 authored by wuyongsheng's avatar wuyongsheng

Merge branch 'master' into 'staging'

Master

See merge request !128
parents 453a73cf 181bec6a
<?xml version="1.0" encoding="UTF-8"?>
<svg width="15px" height="15px" viewBox="0 0 15 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>矩形备份 7</title>
<g id="上线UI" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<rect id="矩形备份-7" stroke="#565C66" fill="#1E2633" x="0.5" y="0.5" width="14" height="14" rx="2"></rect>
</g>
</svg>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<svg width="15px" height="15px" viewBox="0 0 15 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>编组 64</title>
<g id="上线UI" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="编组-64">
<rect id="矩形备份-28" fill="#1370FF" x="0" y="0" width="15" height="15" rx="2"></rect>
<polyline id="路径-26" stroke="#FFFFFF" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" points="3.5 7.83740166 6.77434245 10.5 11.5 4.5"></polyline>
</g>
</g>
</svg>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<svg width="15px" height="15px" viewBox="0 0 15 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>矩形备份 22</title>
<g id="上线UI" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<rect id="矩形备份-22" stroke="#565C66" fill="#000000" x="0.5" y="0.5" width="14" height="14" rx="2"></rect>
</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>编组 58备份 7</title>
<g id="上线UI" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="编组-58备份-7">
<rect id="矩形" x="0" y="0" width="16" height="16"></rect>
<g id="编组-50" transform="translate(1.000000, 1.605109)" stroke="#C2C6CC" stroke-width="1.5">
<line x1="0" y1="2.39431484" x2="14" y2="2.39431484" id="路径-16"></line>
<path d="M3.37934347,2.39431484 L3.37934347,1 C3.37934347,0.44771525 3.82705872,1.01453063e-16 4.37934347,0 L9.63329305,0 C10.1855778,-1.01453063e-16 10.6332931,0.44771525 10.6332931,1 L10.6332931,2.39431484 L10.6332931,2.39431484" id="路径-17"></path>
<path d="M2.45321216,3.89402686 L2.45321216,11.9292428 C2.45321216,12.4815275 2.90092741,12.9292428 3.45321216,12.9292428 L10.4872657,12.9292428 C11.0395505,12.9292428 11.4872657,12.4815275 11.4872657,11.9292428 L11.4872657,3.89402686 L11.4872657,3.89402686" id="路径-20"></path>
<line x1="5.49894415" y1="3.89402686" x2="5.49894415" y2="10.3954667" id="路径-21"></line>
<line x1="8.49836822" y1="3.89402686" x2="8.49836822" y2="10.3954667" id="路径-22"></line>
</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>编组 58备份</title>
<g id="上线UI" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="编组-58备份">
<rect id="矩形" x="0" y="0" width="16" height="16"></rect>
<g id="编组-50" transform="translate(1.000000, 1.605109)" stroke="#DDE1E6" stroke-width="1.5">
<line x1="0" y1="2.39431484" x2="14" y2="2.39431484" id="路径-16"></line>
<path d="M3.37934347,2.39431484 L3.37934347,1 C3.37934347,0.44771525 3.82705872,1.01453063e-16 4.37934347,0 L9.63329305,0 C10.1855778,-1.01453063e-16 10.6332931,0.44771525 10.6332931,1 L10.6332931,2.39431484 L10.6332931,2.39431484" id="路径-17"></path>
<path d="M2.45321216,3.89402686 L2.45321216,11.9292428 C2.45321216,12.4815275 2.90092741,12.9292428 3.45321216,12.9292428 L10.4872657,12.9292428 C11.0395505,12.9292428 11.4872657,12.4815275 11.4872657,11.9292428 L11.4872657,3.89402686 L11.4872657,3.89402686" id="路径-20"></path>
<line x1="5.49894415" y1="3.89402686" x2="5.49894415" y2="10.3954667" id="路径-21"></line>
<line x1="8.49836822" y1="3.89402686" x2="8.49836822" y2="10.3954667" id="路径-22"></line>
</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>编组 58备份 7</title>
<g id="上线UI" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="编组-58备份-7">
<rect id="矩形" x="0" y="0" width="16" height="16"></rect>
<g id="编组-50" transform="translate(1.000000, 1.605109)" stroke="#565C66" stroke-width="1.5">
<line x1="0" y1="2.39431484" x2="14" y2="2.39431484" id="路径-16"></line>
<path d="M3.37934347,2.39431484 L3.37934347,1 C3.37934347,0.44771525 3.82705872,1.01453063e-16 4.37934347,0 L9.63329305,0 C10.1855778,-1.01453063e-16 10.6332931,0.44771525 10.6332931,1 L10.6332931,2.39431484 L10.6332931,2.39431484" id="路径-17"></path>
<path d="M2.45321216,3.89402686 L2.45321216,11.9292428 C2.45321216,12.4815275 2.90092741,12.9292428 3.45321216,12.9292428 L10.4872657,12.9292428 C11.0395505,12.9292428 11.4872657,12.4815275 11.4872657,11.9292428 L11.4872657,3.89402686 L11.4872657,3.89402686" id="路径-20"></path>
<line x1="5.49894415" y1="3.89402686" x2="5.49894415" y2="10.3954667" id="路径-21"></line>
<line x1="8.49836822" y1="3.89402686" x2="8.49836822" y2="10.3954667" id="路径-22"></line>
</g>
</g>
</g>
</svg>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<svg width="40px" height="40px" viewBox="0 0 40 40" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>编组 13备份</title>
<defs>
<linearGradient x1="50%" y1="-4.26048086e-13%" x2="50%" y2="100%" id="linearGradient-1">
<stop stop-color="#26AAF9" offset="0%"></stop>
<stop stop-color="#1370FF" offset="100%"></stop>
</linearGradient>
</defs>
<g id="上线UI" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="编组-13备份">
<rect id="矩形" fill="url(#linearGradient-1)" x="0" y="0" width="40" height="40" rx="4"></rect>
<g id="编组-4备份-4" transform="translate(9.000000, 9.000000)">
<g id="矩形-2">
<rect id="矩形" x="0" y="0" width="22" height="22"></rect>
</g>
<path d="M18.14,3 L3.86,3 C3.385,3 3,3.3852 3,3.86 L3,6.54 C3,7.015 3.385,7.4 3.86,7.4 L18.14,7.4 C18.615,7.4 19,7.015 19,6.54 L19,3.86 C19,3.3852 18.615,3 18.14,3 Z M17.28,5.68 L9.28,5.68 C9.298916,5.6446 9.30956773,5.6036 9.30956773,5.56 L9.30956773,4.84 C9.30956773,4.7964 9.298916,4.7554 9.28,4.72 L17.28,4.72 L17.28,5.68 Z M18.14,8.8 L3.86,8.8 C3.385,8.8 3,9.1852 3,9.66 L3,12.34 C3,12.815 3.385,13.2 3.86,13.2 L18.14,13.2 C18.615,13.2 19,12.815 19,12.34 L19,9.66 C19,9.1852 18.615,8.8 18.14,8.8 Z M17.28,11.48 L9.28,11.48 C9.298916,11.4446 9.30956773,11.4036 9.30956773,11.36 L9.30956773,10.64 C9.30956773,10.5964 9.298916,10.5554 9.28,10.52 L17.28,10.52 L17.28,11.48 Z M18.14,14.6 L3.86,14.6 C3.385,14.6 3,14.9852 3,15.46 L3,18.14 C3,18.615 3.385,19 3.86,19 L18.14,19 C18.615,19 19,18.615 19,18.14 L19,15.46 C19,14.9852 18.615,14.6 18.14,14.6 Z M17.28,17.28 L9.28,17.28 C9.298916,17.2446 9.30956773,17.2036 9.30956773,17.16 L9.30956773,16.44 C9.30956773,16.3964 9.298916,16.3554 9.28,16.32 L17.28,16.32 L17.28,17.28 Z" id="形状" fill="#FFFFFF" fill-rule="nonzero"></path>
</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>编组 22备份</title>
<g id="上线UI" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="编组-22备份">
<rect id="矩形" x="0" y="0" width="16" height="16"></rect>
<g id="编组-57" transform="translate(1.500000, 0.500000)" stroke="#565C66" stroke-linejoin="round" stroke-width="1.5">
<polyline id="路径" points="2.61444632e-13 10.5038375 0 14 13 14 13 10.5"></polyline>
<polyline id="路径" points="11 6 6.5 10.5 2 6"></polyline>
<line x1="6.49585" y1="0" x2="6.5" y2="10" id="路径"></line>
</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>编组 22备份</title>
<g id="上线UI" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="编组-22备份">
<rect id="矩形" x="0" y="0" width="16" height="16"></rect>
<g id="编组-57" transform="translate(1.500000, 0.500000)" stroke="#8A9099" stroke-linejoin="round" stroke-width="1.5">
<polyline id="路径" points="2.61444632e-13 10.5038375 0 14 13 14 13 10.5"></polyline>
<polyline id="路径" points="11 6 6.5 10.5 2 6"></polyline>
<line x1="6.49585" y1="0" x2="6.5" y2="10" id="路径"></line>
</g>
</g>
</g>
</svg>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<svg width="40px" height="40px" viewBox="0 0 40 40" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>编组 7备份 3</title>
<defs>
<linearGradient x1="50%" y1="-4.26048086e-13%" x2="50%" y2="100%" id="linearGradient-1">
<stop stop-color="#75EBCB" offset="0%"></stop>
<stop stop-color="#0DD09B" offset="100%"></stop>
</linearGradient>
</defs>
<g id="上线UI" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="编组-7备份-3">
<rect id="矩形备份" fill="url(#linearGradient-1)" x="0" y="0" width="40" height="40" rx="4"></rect>
<g id="编组-7备份-14" transform="translate(9.000000, 9.000000)">
<rect id="矩形" x="0" y="0" width="22" height="22"></rect>
<g id="编组-6" transform="translate(3.928571, 2.357143)">
<path d="M1.2,0 L9.49020093,0 L9.49020093,0 L14.1428571,4.65265622 L14.1428571,16.0857143 C14.1428571,16.748456 13.6055988,17.2857143 12.9428571,17.2857143 L1.2,17.2857143 C0.5372583,17.2857143 -3.6292676e-16,16.748456 0,16.0857143 L0,1.2 C-8.11624501e-17,0.5372583 0.5372583,-3.22345535e-16 1.2,0 Z" id="矩形" fill="#FFFFFF"></path>
<g id="编组-4" transform="translate(3.535714, 7.142857)" stroke="#0DD09B" stroke-width="1.2">
<line x1="7.85086282e-15" y1="6.39285714" x2="7.07142857" y2="6.39285714" id="路径-15备份-2"></line>
<line x1="7.85086282e-15" y1="3.39285714" x2="7.07142857" y2="3.39285714" id="路径-15备份-3"></line>
<line x1="7.85086282e-15" y1="0.392857143" x2="7.07142857" y2="0.392857143" id="路径-15备份-4"></line>
</g>
<path d="M9.49020093,0 L14.1428571,4.65265622 L10.6902009,4.65265622 C10.0274592,4.65265622 9.49020093,4.11539792 9.49020093,3.45265622 L9.49020093,0 L9.49020093,0 Z" id="路径-9" fill="#9AF8E5"></path>
</g>
</g>
</g>
</g>
</svg>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<svg width="18px" height="18px" viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>编组 65备份</title>
<g id="上线UI" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="编组-65备份">
<rect id="矩形" x="0" y="0" width="18" height="18"></rect>
<g id="1.Base基础/Icon图标/查看备份" transform="translate(1.000000, 1.000000)">
<rect id="矩形" x="0" y="0" width="16" height="16"></rect>
<g id="编组-58" transform="translate(0.500000, 1.488632)" stroke="#565C66" stroke-width="1.62830815">
<g id="编组">
<line x1="0" y1="0.5" x2="12.4755135" y2="0.5" id="路径"></line>
<line x1="0" y1="6.18590274" x2="4.99389897" y2="6.18590274" id="路径"></line>
<line x1="0" y1="11.8718055" x2="5.66782353" y2="11.8718055" id="路径"></line>
<line x1="13.0860211" y1="10.7189929" x2="15.2967853" y2="13.4172047" id="路径"></line>
<path d="M10.6064141,3.72994425 C11.6910045,3.72994425 12.6717682,4.15682942 13.3821406,4.84341174 C14.1027218,5.53986092 14.5458693,6.50270675 14.5458693,7.56473415 C14.5458693,8.62676155 14.1027218,9.58960738 13.3821406,10.2860566 C12.6717682,10.9726389 11.6910045,11.3995241 10.6064141,11.3995241 C9.52182361,11.3995241 8.54105997,10.9726389 7.83068751,10.2860566 C7.11010631,9.58960738 6.66695888,8.62676155 6.66695888,7.56473415 C6.66695888,6.50270675 7.11010631,5.53986092 7.83068751,4.84341174 C8.54105997,4.15682942 9.52182361,3.72994425 10.6064141,3.72994425 Z" id="路径"></path>
</g>
</g>
</g>
</g>
</g>
</svg>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<svg width="18px" height="18px" viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>编组 65</title>
<g id="上线UI" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="编组-65">
<rect id="矩形" x="0" y="0" width="18" height="18"></rect>
<g id="1.Base基础/Icon图标/查看备份" transform="translate(1.000000, 1.000000)">
<rect id="矩形" x="0" y="0" width="16" height="16"></rect>
<g id="编组-58" transform="translate(0.500000, 1.488632)" stroke="#8A9099" stroke-width="1.62830815">
<g id="编组">
<line x1="0" y1="0.5" x2="12.4755135" y2="0.5" id="路径"></line>
<line x1="0" y1="6.18590274" x2="4.99389897" y2="6.18590274" id="路径"></line>
<line x1="0" y1="11.8718055" x2="5.66782353" y2="11.8718055" id="路径"></line>
<line x1="13.0860211" y1="10.7189929" x2="15.2967853" y2="13.4172047" id="路径"></line>
<path d="M10.6064141,3.72994425 C11.6910045,3.72994425 12.6717682,4.15682942 13.3821406,4.84341174 C14.1027218,5.53986092 14.5458693,6.50270675 14.5458693,7.56473415 C14.5458693,8.62676155 14.1027218,9.58960738 13.3821406,10.2860566 C12.6717682,10.9726389 11.6910045,11.3995241 10.6064141,11.3995241 C9.52182361,11.3995241 8.54105997,10.9726389 7.83068751,10.2860566 C7.11010631,9.58960738 6.66695888,8.62676155 6.66695888,7.56473415 C6.66695888,6.50270675 7.11010631,5.53986092 7.83068751,4.84341174 C8.54105997,4.15682942 9.52182361,3.72994425 10.6064141,3.72994425 Z" id="路径"></path>
</g>
</g>
</g>
</g>
</g>
</svg>
\ No newline at end of file
...@@ -122,7 +122,7 @@ const theme = createTheme({ ...@@ -122,7 +122,7 @@ const theme = createTheme({
minWidth: "60px", minWidth: "60px",
}, },
sizeMedium: { sizeMedium: {
"& p": { fontSize: "14px" }, "& p": { fontSize: "14px", lineHeight: "20px" },
height: "32px", height: "32px",
padding: "0 16px", padding: "0 16px",
minWidth: "68px", minWidth: "68px",
......
...@@ -7,6 +7,7 @@ import { ...@@ -7,6 +7,7 @@ import {
DialogTitle, DialogTitle,
} from "@mui/material"; } from "@mui/material";
import CloseIcon from "@mui/icons-material/Close"; import CloseIcon from "@mui/icons-material/Close";
import { ThemeProvider, createTheme } from "@mui/material/styles";
import MyButton from "./MyButton"; import MyButton from "./MyButton";
...@@ -51,8 +52,27 @@ export interface IDialogProps { ...@@ -51,8 +52,27 @@ export interface IDialogProps {
| "info" | "info"
| "warning"; //按钮颜色风格 | "warning"; //按钮颜色风格
loading?: boolean; // 确认按钮是否处于loading状态 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 MyDialog: React.FunctionComponent<IDialogProps> = (props) => {
const { const {
title, title,
...@@ -74,6 +94,7 @@ const MyDialog: React.FunctionComponent<IDialogProps> = (props) => { ...@@ -74,6 +94,7 @@ const MyDialog: React.FunctionComponent<IDialogProps> = (props) => {
clickMaskClose = false, clickMaskClose = false,
loading = false, loading = false,
okColor = "primary", okColor = "primary",
isText = false,
} = props; } = props;
const handelClose = ( const handelClose = (
...@@ -91,7 +112,7 @@ const MyDialog: React.FunctionComponent<IDialogProps> = (props) => { ...@@ -91,7 +112,7 @@ const MyDialog: React.FunctionComponent<IDialogProps> = (props) => {
return footerRender ? ( return footerRender ? (
footerRender() footerRender()
) : ( ) : (
<DialogActions style={{ padding: "0 24px 16px 24px" }}> <DialogActions style={{ padding: "16px 24px 16px 24px" }}>
{showCancel ? ( {showCancel ? (
<MyButton <MyButton
text={cancelText || "取消"} text={cancelText || "取消"}
...@@ -127,7 +148,16 @@ const MyDialog: React.FunctionComponent<IDialogProps> = (props) => { ...@@ -127,7 +148,16 @@ const MyDialog: React.FunctionComponent<IDialogProps> = (props) => {
loading, loading,
showConfirm, showConfirm,
]); ]);
const contentPadding = useMemo(() => {
if (isText) {
return "8px 24px 24px"; // 文本
} else {
return "8px 24px 12px"; // 表单
}
}, [isText]);
return ( return (
<ThemeProvider theme={theme}>
<Dialog <Dialog
open={open} open={open}
onClose={handelClose} onClose={handelClose}
...@@ -172,9 +202,12 @@ const MyDialog: React.FunctionComponent<IDialogProps> = (props) => { ...@@ -172,9 +202,12 @@ const MyDialog: React.FunctionComponent<IDialogProps> = (props) => {
</div> </div>
</DialogTitle> </DialogTitle>
)} )}
<DialogContent style={{ minWidth: 388 }}>{children}</DialogContent> <DialogContent style={{ minWidth: 388, padding: contentPadding }}>
{children}
</DialogContent>
{Footer} {Footer}
</Dialog> </Dialog>
</ThemeProvider>
); );
}; };
......
...@@ -60,12 +60,22 @@ const theme = createTheme({ ...@@ -60,12 +60,22 @@ const theme = createTheme({
styleOverrides: { styleOverrides: {
root: { root: {
color: "rgba(209, 214, 222, 1)", color: "rgba(209, 214, 222, 1)",
"&.MuiCheckbox-indeterminate": {
color: "rgba(19, 112, 255, 1)",
},
"&.Mui-checked": { "&.Mui-checked": {
color: "rgba(19, 112, 255, 1)", color: "rgba(19, 112, 255, 1)",
}, },
}, },
}, },
}, },
MuiPaper: {
styleOverrides: {
root: {
boxShadow: "0px 3px 10px 0px rgba(0,24,57,0.14)",
},
},
},
}, },
}); });
...@@ -83,6 +93,7 @@ type IMyMultipleMenuProps = { ...@@ -83,6 +93,7 @@ type IMyMultipleMenuProps = {
selectAllText?: string; // 全选的文字 selectAllText?: string; // 全选的文字
showHiddenIcon?: boolean; // 是否显示 展开收起箭头 showHiddenIcon?: boolean; // 是否显示 展开收起箭头
iconColor?: string; // 展开收起箭头的颜色 iconColor?: string; // 展开收起箭头的颜色
topContent?: any; // 在全选上面的元素 在全选上面 常用于解释说明
}; };
const MyMultipleMenu = (props: IMyMultipleMenuProps) => { const MyMultipleMenu = (props: IMyMultipleMenuProps) => {
...@@ -95,6 +106,7 @@ const MyMultipleMenu = (props: IMyMultipleMenuProps) => { ...@@ -95,6 +106,7 @@ const MyMultipleMenu = (props: IMyMultipleMenuProps) => {
selectAllText = "全部", selectAllText = "全部",
showHiddenIcon = true, showHiddenIcon = true,
iconColor, iconColor,
topContent = null,
} = props; } = props;
// 下拉框展示的相对位置参考元素 // 下拉框展示的相对位置参考元素
const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null); const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);
...@@ -175,6 +187,7 @@ const MyMultipleMenu = (props: IMyMultipleMenuProps) => { ...@@ -175,6 +187,7 @@ const MyMultipleMenu = (props: IMyMultipleMenuProps) => {
"aria-labelledby": "basic-button", "aria-labelledby": "basic-button",
}} }}
> >
{topContent}
{showSelectAll && ( {showSelectAll && (
<MenuItem onClick={() => handleMenuAllClick()} key="indeterminate"> <MenuItem onClick={() => handleMenuAllClick()} key="indeterminate">
<Checkbox <Checkbox
......
...@@ -26,7 +26,7 @@ export type sortState = { ...@@ -26,7 +26,7 @@ export type sortState = {
interface IMyTableProps { interface IMyTableProps {
rows: Array<any>; // 表格数据 rows: Array<any>; // 表格数据
headCells: Array<any>; // 表头配置 headCells: Array<any>; // 表头配置
key?: string; // 表格数据的key tableKey?: string; // 表格数据的key
loading?: boolean; // 是否正在加载数据 loading?: boolean; // 是否正在加载数据
hasCheckbox?: boolean; // 是否有复选框 hasCheckbox?: boolean; // 是否有复选框
selectItems?: Array<any>; // 选中的项 selectItems?: Array<any>; // 选中的项
...@@ -50,7 +50,7 @@ const MyTable = (props: IMyTableProps) => { ...@@ -50,7 +50,7 @@ const MyTable = (props: IMyTableProps) => {
const { const {
rows, rows,
headCells, headCells,
key = "id", tableKey = "id",
loading = false, loading = false,
hasCheckbox = false, hasCheckbox = false,
selectItems = [], selectItems = [],
...@@ -168,8 +168,12 @@ const MyTable = (props: IMyTableProps) => { ...@@ -168,8 +168,12 @@ const MyTable = (props: IMyTableProps) => {
MuiCheckbox: { MuiCheckbox: {
styleOverrides: { styleOverrides: {
root: { root: {
color: "rgba(209, 214, 222, 1)",
"&.MuiCheckbox-indeterminate .MuiSvgIcon-root": {
color: "rgba(19, 112, 255, 1)",
},
"&.Mui-checked .MuiSvgIcon-root": { "&.Mui-checked .MuiSvgIcon-root": {
color: "rgba(19, 110, 250, 1)", color: "rgba(19, 112, 255, 1)",
}, },
}, },
}, },
...@@ -204,12 +208,12 @@ const MyTable = (props: IMyTableProps) => { ...@@ -204,12 +208,12 @@ const MyTable = (props: IMyTableProps) => {
const onSelectAllClick = useCallback( const onSelectAllClick = useCallback(
(e: any) => { (e: any) => {
if (e.target.checked) { if (e.target.checked) {
setSelectItems && setSelectItems(rows.map((row) => row[key])); setSelectItems && setSelectItems(rows.map((row) => row[tableKey]));
} else { } else {
setSelectItems && setSelectItems([]); setSelectItems && setSelectItems([]);
} }
}, },
[setSelectItems, key, rows] [setSelectItems, tableKey, rows]
); );
const onSelectRowClick = useCallback( const onSelectRowClick = useCallback(
...@@ -359,8 +363,8 @@ const MyTable = (props: IMyTableProps) => { ...@@ -359,8 +363,8 @@ const MyTable = (props: IMyTableProps) => {
} }
return ( return (
<TableBody> <TableBody>
{rows.map((row) => ( {rows.map((row, rowIndex) => (
<TableRow key={row[key]}> <TableRow key={row[tableKey] || rowIndex}>
{hasCheckbox && ( {hasCheckbox && (
<TableCell <TableCell
align="left" align="left"
...@@ -368,10 +372,11 @@ const MyTable = (props: IMyTableProps) => { ...@@ -368,10 +372,11 @@ const MyTable = (props: IMyTableProps) => {
> >
<Checkbox <Checkbox
checked={ checked={
selectItems.filter((selectItem) => selectItem === row[key]) selectItems.filter(
.length > 0 (selectItem) => selectItem === row[tableKey]
).length > 0
} }
onChange={(e) => onSelectRowClick(e, row[key])} onChange={(e) => onSelectRowClick(e, row[tableKey])}
/> />
</TableCell> </TableCell>
)} )}
...@@ -393,7 +398,15 @@ const MyTable = (props: IMyTableProps) => { ...@@ -393,7 +398,15 @@ const MyTable = (props: IMyTableProps) => {
</div> </div>
</MyTooltip> </MyTooltip>
)} )}
{!headCell.showOverflowTooltip && <>{row[headCell.id]}</>} {!headCell.showOverflowTooltip && (
<div
style={{
width: headCell.width ? Number(headCell.width) - 32 : "",
}}
>
{row[headCell.id]}
</div>
)}
</TableCell> </TableCell>
))} ))}
</TableRow> </TableRow>
...@@ -402,7 +415,7 @@ const MyTable = (props: IMyTableProps) => { ...@@ -402,7 +415,7 @@ const MyTable = (props: IMyTableProps) => {
); );
}, [ }, [
rows, rows,
key, tableKey,
hasCheckbox, hasCheckbox,
selectItems, selectItems,
onSelectRowClick, onSelectRowClick,
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
*/ */
import { Tooltip, TooltipProps } from "@mui/material"; import { Tooltip, TooltipProps } from "@mui/material";
import { ThemeProvider, createTheme } from "@mui/material/styles"; import { ThemeProvider, createTheme } from "@mui/material/styles";
import { useMemo } from "react";
interface IMyTooltipProps extends Omit<TooltipProps, "title"> { interface IMyTooltipProps extends Omit<TooltipProps, "title"> {
title?: string | boolean; title?: string | boolean;
...@@ -20,6 +21,7 @@ const theme = createTheme({ ...@@ -20,6 +21,7 @@ const theme = createTheme({
tooltip: { tooltip: {
backgroundColor: "rgba(7, 19, 38, .8)", backgroundColor: "rgba(7, 19, 38, .8)",
color: "#fff", color: "#fff",
padding: 0,
}, },
arrow: { arrow: {
"&:before": { "&:before": {
...@@ -34,12 +36,31 @@ const theme = createTheme({ ...@@ -34,12 +36,31 @@ const theme = createTheme({
const MyTooltip = (props: IMyTooltipProps) => { const MyTooltip = (props: IMyTooltipProps) => {
const { title = false, children, placement = "top", ...other } = props; const { title = false, children, placement = "top", ...other } = props;
const randerTitle = useMemo(() => {
if (title) {
return (
<div
style={{
maxHeight: "36vh",
overflow: "overlay",
padding: "8px 16px",
}}
>
{title}
</div>
);
} else {
return "";
}
}, [title]);
return ( return (
<ThemeProvider theme={theme}> <ThemeProvider theme={theme}>
<Tooltip <Tooltip
// interactive={true} // interactive={true}
arrow arrow
title={title || ''} title={randerTitle}
placement={placement} placement={placement}
{...other} {...other}
> >
......
import {useEffect,useState} from 'react'
interface WindowSize{
width:number
height:number
}
function useWindowSize():WindowSize{
const [windowSize,setWindowSize]=useState<WindowSize>({
width:0,
height:0,
})
useEffect(()=>{
const handler=()=>{
setWindowSize({
width:window.innerWidth,
height:window.innerHeight
})
}
handler()
window.addEventListener('resize',handler)
return ()=>{
window.removeEventListener('resize',handler)
}
},[])
return windowSize
}
export default useWindowSize
\ No newline at end of file
...@@ -77,11 +77,19 @@ const FileItem = observer((props: IProps) => { ...@@ -77,11 +77,19 @@ const FileItem = observer((props: IProps) => {
if (text === "查看文件") { if (text === "查看文件") {
if ( if (
location?.state?.pathName !== fileItemInfo?.path || location?.state?.pathName !== fileItemInfo?.path ||
location?.pathname !== "/product/cadd/projectData" location?.pathname !==
`/product/${
currentProjectStore.currentProductInfo.id || "cadd"
}/projectData`
) { ) {
navigate(`/product/cadd/projectData`, { navigate(
`/product/${
currentProjectStore.currentProductInfo.id || "cadd"
}/projectData`,
{
state: { pathName: fileItemInfo?.path }, state: { pathName: fileItemInfo?.path },
}); }
);
} }
} }
}; };
......
...@@ -10,6 +10,7 @@ import useMyRequest from "@/hooks/useMyRequest"; ...@@ -10,6 +10,7 @@ import useMyRequest from "@/hooks/useMyRequest";
import { useStores } from "@/store"; import { useStores } from "@/store";
import { toJS } from "mobx"; import { toJS } from "mobx";
import { ITask } from "@/views/Project/ProjectSubmitWork/interface"; import { ITask } from "@/views/Project/ProjectSubmitWork/interface";
import { observer } from "mobx-react-lite";
type IProps = { type IProps = {
operatorList: ITask[]; operatorList: ITask[];
...@@ -17,7 +18,7 @@ type IProps = { ...@@ -17,7 +18,7 @@ type IProps = {
setInputActive: any; setInputActive: any;
}; };
const OperatorList = (props: IProps) => { const OperatorList = observer((props: IProps) => {
const { operatorList, setOperatorList, setInputActive } = props; // 流程图中流算子列表 const { operatorList, setOperatorList, setInputActive } = props; // 流程图中流算子列表
const { currentProjectStore } = useStores(); const { currentProjectStore } = useStores();
const [list, setList] = useState<ITask[]>([]); // 算子列表 const [list, setList] = useState<ITask[]>([]); // 算子列表
...@@ -249,6 +250,6 @@ const OperatorList = (props: IProps) => { ...@@ -249,6 +250,6 @@ const OperatorList = (props: IProps) => {
</div> </div>
</div> </div>
); );
}; });
export default OperatorList; export default OperatorList;
...@@ -24,10 +24,15 @@ ...@@ -24,10 +24,15 @@
font-size: 14px; font-size: 14px;
line-height: 22px; line-height: 22px;
border-left: 3px solid #f7f8fa; border-left: 3px solid #f7f8fa;
font-weight: 400;
display: flex;
justify-content: flex-start;
align-items: center;
} }
.listItem:hover { .listItem:hover {
background-color: #eef1f5; background-color: #eef1f5;
border-left: 3px solid #eef1f5; border-left: 3px solid #eef1f5;
font-weight: 500;
} }
.routerIcon { .routerIcon {
vertical-align: middle; vertical-align: middle;
...@@ -39,4 +44,5 @@ ...@@ -39,4 +44,5 @@
border-left: 3px solid #1370ff; border-left: 3px solid #1370ff;
color: #1370ff; color: #1370ff;
background-color: #e6eaf0; background-color: #e6eaf0;
font-weight: 500;
} }
...@@ -80,9 +80,7 @@ const MenuLayout = observer(() => { ...@@ -80,9 +80,7 @@ const MenuLayout = observer(() => {
} }
alt="" alt=""
/> />
<span style={{ verticalAlign: "middle", fontWeight: "500" }}> <span style={{ verticalAlign: "middle" }}>{item.name}</span>
{item.name}
</span>
</li> </li>
); );
} }
......
...@@ -110,7 +110,7 @@ const AddFolder = (props: IAddFolderProps) => { ...@@ -110,7 +110,7 @@ const AddFolder = (props: IAddFolderProps) => {
onConfirm={handleAddSubmit} onConfirm={handleAddSubmit}
title="新建文件夹" title="新建文件夹"
> >
<div style={{ padding: "12px 0" }}> <div>
<MyInput <MyInput
sx={{ sx={{
width: "388px", width: "388px",
...@@ -125,7 +125,12 @@ const AddFolder = (props: IAddFolderProps) => { ...@@ -125,7 +125,12 @@ const AddFolder = (props: IAddFolderProps) => {
helperText={fileNameCheck.help} helperText={fileNameCheck.help}
InputProps={{ InputProps={{
endAdornment: ( endAdornment: (
<InputAdornment position="end" style={{ color: fileName.length >= 30 ? "#d32f2f" : "#C2C6CC" }}> <InputAdornment
position="end"
style={{
color: fileName.length >= 30 ? "#d32f2f" : "#C2C6CC",
}}
>
{fileName.length}/30 {fileName.length}/30
</InputAdornment> </InputAdornment>
), ),
......
...@@ -49,8 +49,8 @@ const DeleteDialog = (props: IDeleteFileProps) => { ...@@ -49,8 +49,8 @@ const DeleteDialog = (props: IDeleteFileProps) => {
if (currentOperateFile) { if (currentOperateFile) {
return [currentOperateFile]; return [currentOperateFile];
} else { } else {
return showList.filter((item: any) => { return selectIds.map((item) => {
return selectIds.indexOf(item.name) !== -1; return showList[item];
}); });
} }
}, [currentOperateFile, selectIds, showList]); }, [currentOperateFile, selectIds, showList]);
...@@ -90,6 +90,7 @@ const DeleteDialog = (props: IDeleteFileProps) => { ...@@ -90,6 +90,7 @@ const DeleteDialog = (props: IDeleteFileProps) => {
onClose={() => setDeleteDialogOpen(false)} onClose={() => setDeleteDialogOpen(false)}
onConfirm={handleSubmit} onConfirm={handleSubmit}
okColor="error" okColor="error"
isText={true}
> >
{currentOperateFile {currentOperateFile
? "确认删除该数据吗?" ? "确认删除该数据吗?"
......
...@@ -102,9 +102,11 @@ const MoveFile = (props: IMoveFileProps) => { ...@@ -102,9 +102,11 @@ const MoveFile = (props: IMoveFileProps) => {
moveFolderArr = []; moveFolderArr = [];
} }
} else { } else {
moveFolderArr = showList.filter((item: any) => { moveFolderArr = selectIds
return selectIds.indexOf(item.name) !== -1 && item.type === "directory"; .map((item) => {
}); return showList[item];
})
.filter((item) => item.type === "directory");
} }
pathArr = moveFolderArr.map((item: any) => { pathArr = moveFolderArr.map((item: any) => {
return path === "/" ? `/${item.name}` : `${path}/${item.name}`; return path === "/" ? `/${item.name}` : `${path}/${item.name}`;
...@@ -147,8 +149,8 @@ const MoveFile = (props: IMoveFileProps) => { ...@@ -147,8 +149,8 @@ const MoveFile = (props: IMoveFileProps) => {
if (currentOperateFile) { if (currentOperateFile) {
return [currentOperateFile]; return [currentOperateFile];
} else { } else {
return showList.filter((item: any) => { return selectIds.map((item) => {
return selectIds.indexOf(item.name) !== -1; return showList[item];
}); });
} }
}, [currentOperateFile, selectIds, showList]); }, [currentOperateFile, selectIds, showList]);
......
...@@ -11,7 +11,8 @@ ...@@ -11,7 +11,8 @@
margin: 0 16px 16px 0; margin: 0 16px 16px 0;
border: 1px solid rgba(235, 237, 240, 1); border: 1px solid rgba(235, 237, 240, 1);
border-radius: 4px; border-radius: 4px;
min-height: 275px; min-height: 339px;
max-height: 339px;
box-sizing: border-box; box-sizing: border-box;
position: relative; position: relative;
cursor: pointer; cursor: pointer;
...@@ -32,11 +33,11 @@ ...@@ -32,11 +33,11 @@
margin-bottom: 0; margin-bottom: 0;
} }
.datasetLiTop { .datasetLiTop {
height: 55%; height: 185px;
box-sizing: border-box; box-sizing: border-box;
} }
.datasetLiBottom { .datasetLiBottom {
height: 45%; height: 152px;
box-sizing: border-box; box-sizing: border-box;
background-color: RGBA(247, 248, 250, 1); background-color: RGBA(247, 248, 250, 1);
display: flex; display: flex;
...@@ -66,8 +67,8 @@ ...@@ -66,8 +67,8 @@
line-height: 22px; line-height: 22px;
} }
.datasetLiDataLi { .datasetLiDataLi {
height: 20px; height: 28px;
line-height: 20px; line-height: 28px;
color: rgba(30, 38, 51, 1); color: rgba(30, 38, 51, 1);
font-size: 12px; font-size: 12px;
padding: 0 16px; padding: 0 16px;
...@@ -94,3 +95,21 @@ ...@@ -94,3 +95,21 @@
.nullBox { .nullBox {
visibility: hidden; visibility: hidden;
} }
.blackCheckBox {
position: absolute;
top: 16px;
right: 20px;
z-index: 1;
width: 15px;
height: 15px;
background-image: url(../../../../../../assets/project/blackCheckBox.svg);
}
.blackCheckBoxActive {
background-image: url(../../../../../../assets/project/blackCheckBoxActive.svg);
}
.blackCheckBox:hover {
background-image: url(../../../../../../assets/project/blackCheckBoxHover.svg);
}
.blackCheckBoxActive:hover {
background-image: url(../../../../../../assets/project/blackCheckBoxActive.svg);
}
...@@ -73,9 +73,6 @@ const DatasetCardTable = (props: IDatasetCardTableProps) => { ...@@ -73,9 +73,6 @@ const DatasetCardTable = (props: IDatasetCardTableProps) => {
)} )}
</div> </div>
<div className={style.datasetLiBottom}> <div className={style.datasetLiBottom}>
<div className={style.datasetLiTitle} title={item.smiles}>
{item.smiles}
</div>
{showData.length !== 0 && ( {showData.length !== 0 && (
<div className={style.datasetLiDataList}> <div className={style.datasetLiDataList}>
{Object.keys(item) {Object.keys(item)
...@@ -117,19 +114,13 @@ const DatasetCardTable = (props: IDatasetCardTableProps) => { ...@@ -117,19 +114,13 @@ const DatasetCardTable = (props: IDatasetCardTableProps) => {
/> />
)} )}
{graphicDimension === "3D" && ( {graphicDimension === "3D" && (
<Checkbox <div
size="small" className={classNames({
sx={{ [style.blackCheckBox]: true,
padding: "0px", [style.blackCheckBoxActive]: selectItems.includes(
position: "absolute", item.id
top: "16px", ),
right: "20px", })}
zIndex: 1,
background: "RGBA(30, 38, 51, 1)",
border: "1px solid #565C66",
borderRadius: "2px",
}}
checked={selectItems.includes(item.id)}
/> />
)} )}
</div> </div>
......
import { useMemo } from "react"; import { useEffect, useMemo, useState } from "react";
import MyTable from "@/components/mui/MyTableNew"; import MyTable from "@/components/mui/MyTableNew";
import { sortState } from "@/components/mui/MyTableNew"; import { sortState } from "@/components/mui/MyTableNew";
...@@ -22,12 +22,19 @@ const DatasetTable = (props: IDatasetTableProps) => { ...@@ -22,12 +22,19 @@ const DatasetTable = (props: IDatasetTableProps) => {
setSortState, setSortState,
loading, loading,
} = props; } = props;
const [innerWidth, setInnerWidth] = useState(window.innerWidth);
useEffect(() => {
window.addEventListener("resize", () => {
setInnerWidth(window.innerWidth);
});
}, []);
const headCells = useMemo(() => { const headCells = useMemo(() => {
let width = let width =
showData.length === 0 showData.length === 0
? window.innerWidth - 112 ? innerWidth - 112
: `${(window.innerWidth - 112) / showData.length}`; : `${(innerWidth - 112) / showData.length}`;
return showData.map((item, index) => { return showData.map((item) => {
return { return {
id: item, id: item,
label: item, label: item,
...@@ -36,7 +43,7 @@ const DatasetTable = (props: IDatasetTableProps) => { ...@@ -36,7 +43,7 @@ const DatasetTable = (props: IDatasetTableProps) => {
sort: true, sort: true,
}; };
}); });
}, [showData]); }, [showData, innerWidth]);
return ( return (
<MyTable <MyTable
rows={list} rows={list}
......
...@@ -8,10 +8,16 @@ ...@@ -8,10 +8,16 @@
height: 100%; height: 100%;
} }
.datasetBoxShowFoot { .datasetBoxShowFoot {
padding-bottom: 64px; padding-bottom: 76px;
} }
.top { .top {
margin-bottom: 16px; position: relative;
margin: 0 -32px;
padding: 0 32px 16px;
}
.topBoxShadow {
box-shadow: 0 5px 4px -4px rgb(0, 0, 0, 0.12);
z-index: 10;
} }
.title { .title {
line-height: 22px; line-height: 22px;
...@@ -60,15 +66,26 @@ ...@@ -60,15 +66,26 @@
.searchBox { .searchBox {
width: 662px; width: 662px;
background-color: #fff; background-color: #fff;
padding: 20px 24px 24px; padding: 20px 0 24px 24px;
box-sizing: border-box; box-sizing: border-box;
} }
.deleteIcon { .deleteIcon {
cursor: pointer; cursor: pointer;
width: 16px;
height: 16px;
background-image: url(../../../../assets/project/delete.svg);
background-repeat: no-repeat;
}
.deleteIcon:hover {
background-image: url(../../../../assets/project/deleteHover.svg);
} }
.deleteIconDisabled { .deleteIconDisabled {
background-image: url(../../../../assets/project/deleteDisable.svg);
cursor: not-allowed; cursor: not-allowed;
} }
.deleteIconDisabled:hover {
background-image: url(../../../../assets/project/deleteDisable.svg);
}
.searchTop { .searchTop {
margin-bottom: 12px; margin-bottom: 12px;
} }
...@@ -90,7 +107,9 @@ ...@@ -90,7 +107,9 @@
width: 180px; width: 180px;
} }
.searchList { .searchList {
margin-bottom: 24px; margin-bottom: 8px;
max-height: 300px;
overflow-y: overlay;
} }
.searchLi { .searchLi {
display: flex; display: flex;
...@@ -102,6 +121,7 @@ ...@@ -102,6 +121,7 @@
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
padding-right: 24px;
} }
.searchFooterLeft { .searchFooterLeft {
color: rgba(19, 112, 255, 1); color: rgba(19, 112, 255, 1);
...@@ -115,21 +135,24 @@ ...@@ -115,21 +135,24 @@
.selectShowData { .selectShowData {
font-size: 14px; font-size: 14px;
color: rgba(30, 38, 51, 1); color: rgba(30, 38, 51, 1);
cursor: pointer;
} }
.table { .table {
flex: 1; flex: 1;
overflow-y: overlay; overflow-y: overlay;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
margin: 0 -32px;
padding: 0 32px;
} }
.foot { .foot {
position: absolute; position: absolute;
z-index: 1;
bottom: 0; bottom: 0;
background-color: #fff; background-color: #fff;
width: calc(100vw - 64px); width: calc(100vw - 64px);
box-sizing: border-box; box-sizing: border-box;
height: 76px; height: 76px;
padding: 0 32px;
margin: 0 32px; margin: 0 32px;
display: flex; display: flex;
justify-content: flex-end; justify-content: flex-end;
...@@ -138,3 +161,10 @@ ...@@ -138,3 +161,10 @@
.borderTop { .borderTop {
border-top: 1px solid rgba(240, 242, 245, 1); border-top: 1px solid rgba(240, 242, 245, 1);
} }
.topContent {
padding: 4px 16px;
color: rgba(138, 144, 153, 1);
line-height: 20px;
font-size: 12px;
}
...@@ -69,6 +69,20 @@ const SeeDataset = observer((props: ISeeDatasetProps) => { ...@@ -69,6 +69,20 @@ const SeeDataset = observer((props: ISeeDatasetProps) => {
const [downloadOpen, setDownloadOpen] = useState(false); // 下载弹窗显示控制 const [downloadOpen, setDownloadOpen] = useState(false); // 下载弹窗显示控制
const [firstGetList, setFirstGetList] = useState(true); // 第一次请求列表 const [firstGetList, setFirstGetList] = useState(true); // 第一次请求列表
// 滚轮是否到顶,判断是否显示阴影
const [isTop, setIsTop] = useState(true);
// 滚动滚轮时监听是否到顶
const onscroll = (e: any) => {
if (e.target.scrollTop <= 0) {
console.log(1);
setIsTop(true);
} else {
console.log(2);
setIsTop(false);
}
};
// 页码改变 // 页码改变
const pageChange = (value: number) => { const pageChange = (value: number) => {
getList(value - 1); getList(value - 1);
...@@ -200,6 +214,7 @@ const SeeDataset = observer((props: ISeeDatasetProps) => { ...@@ -200,6 +214,7 @@ const SeeDataset = observer((props: ISeeDatasetProps) => {
// 显示数据变化 // 显示数据变化
const handleSetShowData = (e: any) => { const handleSetShowData = (e: any) => {
if (e.length === 0) { if (e.length === 0) {
setShowData([dataTypes[0].value]);
return; return;
} }
setShowData(e); setShowData(e);
...@@ -282,15 +297,13 @@ const SeeDataset = observer((props: ISeeDatasetProps) => { ...@@ -282,15 +297,13 @@ const SeeDataset = observer((props: ISeeDatasetProps) => {
onChange={(e) => handleQueryChange(e, index)} onChange={(e) => handleQueryChange(e, index)}
sx={{ marginRight: "16px", width: "180px" }} sx={{ marginRight: "16px", width: "180px" }}
></MyInput> ></MyInput>
<img <div
onClick={() => handleDeleteQuery(index)} onClick={() => handleDeleteQuery(index)}
src={jobDel}
alt=""
className={classNames({ className={classNames({
[style.deleteIcon]: true, [style.deleteIcon]: true,
[style.deleteIconDisabled]: querylist.length === 1, [style.deleteIconDisabled]: querylist.length === 1,
})} })}
/> ></div>
</div> </div>
); );
})} })}
...@@ -331,7 +344,12 @@ const SeeDataset = observer((props: ISeeDatasetProps) => { ...@@ -331,7 +344,12 @@ const SeeDataset = observer((props: ISeeDatasetProps) => {
[style.datasetBoxShowFoot]: true, [style.datasetBoxShowFoot]: true,
})} })}
> >
<div className={style.top}> <div
className={classNames({
[style.top]: true,
[style.topBoxShadow]: !isTop,
})}
>
<div className={style.title}>{name}</div> <div className={style.title}>{name}</div>
<div className={style.screens}> <div className={style.screens}>
<div className={style.screensLeft}> <div className={style.screensLeft}>
...@@ -395,6 +413,9 @@ const SeeDataset = observer((props: ISeeDatasetProps) => { ...@@ -395,6 +413,9 @@ const SeeDataset = observer((props: ISeeDatasetProps) => {
setValue={(e: any) => handleSetShowData(e)} setValue={(e: any) => handleSetShowData(e)}
showSelectAll={true} showSelectAll={true}
iconColor="rgba(138, 144, 153, 1)" iconColor="rgba(138, 144, 153, 1)"
topContent={
<div className={style.topContent}>至少勾选一项</div>
}
> >
<span className={style.selectShowData}> <span className={style.selectShowData}>
选择显示数据({showData.length}) 选择显示数据({showData.length})
...@@ -432,7 +453,7 @@ const SeeDataset = observer((props: ISeeDatasetProps) => { ...@@ -432,7 +453,7 @@ const SeeDataset = observer((props: ISeeDatasetProps) => {
</div> </div>
</div> </div>
</div> </div>
<div className={style.table}> <div className={style.table} onScroll={onscroll}>
{tableType === "table" && ( {tableType === "table" && (
<DatasetTable <DatasetTable
list={list} list={list}
......
...@@ -14,6 +14,9 @@ ...@@ -14,6 +14,9 @@
margin-bottom: 14px; margin-bottom: 14px;
font-weight: 600; font-weight: 600;
} }
.tableBox {
height: 350px;
}
.dropBox { .dropBox {
cursor: pointer; cursor: pointer;
height: 300px; height: 300px;
......
...@@ -8,7 +8,7 @@ import style from "./index.module.css"; ...@@ -8,7 +8,7 @@ import style from "./index.module.css";
import MyDialog from "@/components/mui/MyDialog"; import MyDialog from "@/components/mui/MyDialog";
import { uuid } from "@/utils/util"; import { uuid } from "@/utils/util";
import { useMessage } from "@/components/MySnackbar"; import { useMessage } from "@/components/MySnackbar";
import MyTable from "@/components/mui/MyTable"; import MyTable from "@/components/mui/MyTableNew";
import fileIcon from "@/assets/project/fileIcon.svg"; import fileIcon from "@/assets/project/fileIcon.svg";
import noFile from "@/assets/project/noFile.svg"; import noFile from "@/assets/project/noFile.svg";
import uploaderIcon from "@/assets/project/uploaderIcon.svg"; import uploaderIcon from "@/assets/project/uploaderIcon.svg";
...@@ -149,9 +149,9 @@ const UpLoaderFile = observer((props: IMoveFileProps) => { ...@@ -149,9 +149,9 @@ const UpLoaderFile = observer((props: IMoveFileProps) => {
}, [uploaderDialogOpen]); }, [uploaderDialogOpen]);
const fileListHeadCells = [ const fileListHeadCells = [
{ id: "name", numeric: false, label: "名称", width: "60%" }, { id: "name", label: "名称", width: 300 },
{ id: "size", numeric: false, label: "大小", width: "25%" }, { id: "size", label: "大小", width: 120 },
{ id: "caozuo", numeric: false, label: "操作", width: "15%" }, { id: "caozuo", label: "操作", width: 100 },
]; ];
const renderName = (item: any) => { const renderName = (item: any) => {
...@@ -163,7 +163,7 @@ const UpLoaderFile = observer((props: IMoveFileProps) => { ...@@ -163,7 +163,7 @@ const UpLoaderFile = observer((props: IMoveFileProps) => {
); );
}; };
const renderSize = (item: any) => { const renderSize = (item: any) => {
return <span>{item.size ? storageUnitFromB(Number(item.size)) : "-"}</span>; return `${item.size ? storageUnitFromB(Number(item.size)) : "-"}`;
}; };
const handleRowDelete = (index: number) => { const handleRowDelete = (index: number) => {
...@@ -175,7 +175,7 @@ const UpLoaderFile = observer((props: IMoveFileProps) => { ...@@ -175,7 +175,7 @@ const UpLoaderFile = observer((props: IMoveFileProps) => {
return ( return (
<MyButton <MyButton
text="删除" text="删除"
style={{ position: "relative", left: "-18px" }} style={{ position: "relative", left: "-18px", height: "22px" }}
variant="text" variant="text"
size="small" size="small"
color="error" color="error"
...@@ -224,25 +224,14 @@ const UpLoaderFile = observer((props: IMoveFileProps) => { ...@@ -224,25 +224,14 @@ const UpLoaderFile = observer((props: IMoveFileProps) => {
</div> </div>
<div className={style.tableBox}> <div className={style.tableBox}>
<MyTable <MyTable
rowHover={true} fixedHead={true}
stickyHeader={true}
rows={fileList.map((item: any, index: number) => ({ rows={fileList.map((item: any, index: number) => ({
...item, ...item,
name: renderName(item), name: renderName(item),
size: renderSize(item), size: renderSize(item),
caozuo: renderButtons(item, index), caozuo: renderButtons(item, index),
}))} }))}
rowsPerPage={"99"}
headCells={fileListHeadCells} headCells={fileListHeadCells}
footer={false}
// headTableCellStyle={{
// fontSize: "12px",
// lineHeight: "20px",
// color: "#8A9099",
// }}
tableContainerStyle={{
maxHeight: "300px",
}}
/> />
</div> </div>
{fileList.length === 0 && ( {fileList.length === 0 && (
......
.projectData { .projectData {
position: relative; position: relative;
height: calc(100vh - 57px);
} }
.projectDataStickyTop { .projectDataStickyTop {
height: 100%;
padding: 28px 24px 64px; padding: 28px 24px 64px;
position: relative; position: relative;
display: flex;
flex-direction: column;
box-sizing: border-box;
}
.projectDataStickyTopPadding {
padding: 28px 24px 24px;
} }
.projectDataTitle { .projectDataTitle {
font-size: 18px; font-size: 18px;
...@@ -15,6 +23,11 @@ ...@@ -15,6 +23,11 @@
.projectDataHeader { .projectDataHeader {
position: relative; position: relative;
} }
.tableBox {
/* flex: 1; */
height: calc(100% - 146px);
}
.projectDataButtonAndSearch { .projectDataButtonAndSearch {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
......
...@@ -2,12 +2,11 @@ import React, { useState, useCallback, useEffect, useMemo } from "react"; ...@@ -2,12 +2,11 @@ import React, { useState, useCallback, useEffect, useMemo } from "react";
import style from "./index.module.css"; import style from "./index.module.css";
import classnames from "classnames"; import classnames from "classnames";
import { IconButton } from "@mui/material"; import { IconButton } from "@mui/material";
import MyTable from "@/components/mui/MyTable"; import MyTable from "@/components/mui/MyTableNew";
import dataSetIcon from "@/assets/project/dataSetIcon.svg"; import dataSetIcon from "@/assets/project/dataSetIcon.svg";
import refresh from "@/assets/project/refresh.svg"; import refresh from "@/assets/project/refresh.svg";
import fileIcon from "@/assets/project/fileIcon.svg"; import fileIcon from "@/assets/project/fileIcon.svg";
import folderIcon from "@/assets/project/folderIcon.svg"; import folderIcon from "@/assets/project/folderIcon.svg";
import noFile from "@/assets/project/noFile.svg";
import AddFolder from "./AddFolder"; import AddFolder from "./AddFolder";
import MoveFile from "./MoveFile"; import MoveFile from "./MoveFile";
import DeleteDialog from "./DeleteDialog"; import DeleteDialog from "./DeleteDialog";
...@@ -73,6 +72,11 @@ const ProjectData = observer(() => { ...@@ -73,6 +72,11 @@ const ProjectData = observer(() => {
setPath(locationInfo?.pathName || "/"); setPath(locationInfo?.pathName || "/");
}, [location]); }, [location]);
// 切换文件数据集时情况勾选项
useEffect(() => {
setSelectIds([]);
}, [activeTab]);
// 列表展示的数据 // 列表展示的数据
const showList = useMemo(() => { const showList = useMemo(() => {
if (activeTab === "file") { if (activeTab === "file") {
...@@ -86,12 +90,24 @@ const ProjectData = observer(() => { ...@@ -86,12 +90,24 @@ const ProjectData = observer(() => {
fileList.push(item); fileList.push(item);
} }
}); });
return [...folderList, ...fileList]; let arr = [...folderList, ...fileList];
return arr.map((item, index) => {
return {
...item,
id: index,
};
});
} else { } else {
const folderList = list.filter((item: any) => { const folderList = list.filter((item: any) => {
return item.type === "directory"; return item.type === "directory";
}); });
return [...folderList, ...dataSetList]; let arr = [...folderList, ...dataSetList];
return arr.map((item, index) => {
return {
...item,
id: index,
};
});
} }
}, [list, dataSetList, activeTab]); }, [list, dataSetList, activeTab]);
...@@ -256,45 +272,16 @@ const ProjectData = observer(() => { ...@@ -256,45 +272,16 @@ const ProjectData = observer(() => {
}; };
// table配置 // table配置
const versionsHeadCells = useMemo(() => { const versionsHeadCells = [
if (showCheckBox) { { id: "name", label: "名称" },
return [ { id: "size", label: "大小", width: 200 },
{ id: "checkbox" },
{ id: "name", numeric: false, label: "名称", width: "25%" },
{ id: "size", numeric: false, label: "大小", width: "25%", sort: true },
{
id: "mtime",
numeric: false,
label: "创建时间",
width: "25%",
sort: true,
},
{ id: "caozuo", numeric: false, label: "操作", width: "25%" },
];
} else {
return [
{ id: "name", numeric: false, label: "名称", width: "25%" },
{ id: "size", numeric: false, label: "大小", width: "25%", sort: true },
{ {
id: "mtime", id: "mtime",
numeric: false,
label: "创建时间", label: "创建时间",
width: "25%", width: 200,
sort: true,
}, },
{ id: "caozuo", numeric: false, label: "操作", width: "25%" }, { id: "caozuo", label: "操作", width: 200 },
]; ];
}
}, [showCheckBox]);
// 点击复选框
const hanldeCheckbox = (e: any) => {
const selectarr = e.map((item: any) => {
let andIndex = item.indexOf("&index=");
return item.slice(5, andIndex);
});
setSelectIds(selectarr);
};
// 文件夹下钻 // 文件夹下钻
const handleViewFolders = (item: any) => { const handleViewFolders = (item: any) => {
...@@ -312,7 +299,6 @@ const ProjectData = observer(() => { ...@@ -312,7 +299,6 @@ const ProjectData = observer(() => {
// 查看数据集 // 查看数据集
const handleSeeDataset = (item: any) => { const handleSeeDataset = (item: any) => {
console.log(item);
setSeeDatasetName(item.name); setSeeDatasetName(item.name);
setShowSeeDataset(true); setShowSeeDataset(true);
}; };
...@@ -373,6 +359,7 @@ const ProjectData = observer(() => { ...@@ -373,6 +359,7 @@ const ProjectData = observer(() => {
position: "relative", position: "relative",
left: "-10px", left: "-10px",
minWidth: "10px", minWidth: "10px",
height: "22px",
padding: "0 10px", padding: "0 10px",
visibility: visibility:
item.type !== "dataSet" && item.type !== "directory" item.type !== "dataSet" && item.type !== "directory"
...@@ -391,6 +378,7 @@ const ProjectData = observer(() => { ...@@ -391,6 +378,7 @@ const ProjectData = observer(() => {
position: "relative", position: "relative",
left: "-10px", left: "-10px",
minWidth: "10px", minWidth: "10px",
height: "22px",
padding: "0 10px", padding: "0 10px",
}} }}
variant="text" variant="text"
...@@ -410,6 +398,7 @@ const ProjectData = observer(() => { ...@@ -410,6 +398,7 @@ const ProjectData = observer(() => {
position: "relative", position: "relative",
left: "-10px", left: "-10px",
minWidth: "10px", minWidth: "10px",
height: "22px",
padding: "0 10px", padding: "0 10px",
}} }}
variant="text" variant="text"
...@@ -529,7 +518,13 @@ const ProjectData = observer(() => { ...@@ -529,7 +518,13 @@ const ProjectData = observer(() => {
if (currentProjectStore.currentProjectInfo.name) { if (currentProjectStore.currentProjectInfo.name) {
return ( return (
<div className={style.projectData}> <div className={style.projectData}>
<div className={style.projectDataStickyTop}> {/* <div className={style.projectDataStickyTop}> */}
<div
className={classnames({
[style.projectDataStickyTop]: true,
[style.projectDataStickyTopPadding]: selectIds.length === 0,
})}
>
<div className={style.projectDataTitle}>项目数据</div> <div className={style.projectDataTitle}>项目数据</div>
<div className={style.projectDataHeader}> <div className={style.projectDataHeader}>
<div className={style.projectDataButtonAndSearch}> <div className={style.projectDataButtonAndSearch}>
...@@ -593,32 +588,22 @@ const ProjectData = observer(() => { ...@@ -593,32 +588,22 @@ const ProjectData = observer(() => {
</div> </div>
</div> </div>
</div> </div>
<div className={style.tableBox}>
<MyTable <MyTable
footer={false} fixedHead={true}
rowHover={true} hasCheckbox={showCheckBox}
onRef={tableRef}
stickyHeader={true}
initSelected={selectIds}
headCells={versionsHeadCells} headCells={versionsHeadCells}
rowsPerPage={"99"} selectItems={selectIds}
checkboxData={(e: any) => { setSelectItems={setSelectIds}
hanldeCheckbox(e);
}}
rows={showList.map((item: any, index: number) => ({ rows={showList.map((item: any, index: number) => ({
...item, ...item,
id: `name=${item.name}&index=${index}`,
name: renderName(item), name: renderName(item),
size: renderSize(item), size: renderSize(item),
mtime: renderMtime(item), mtime: renderMtime(item),
caozuo: renderButtons(item), caozuo: renderButtons(item),
}))} }))}
/> />
{showList.length === 0 && (
<div className={style.noDataBox}>
<img className={style.noDataImg} src={noFile} alt="" />
<span className={style.noDataText}>暂无数据</span>
</div> </div>
)}
</div> </div>
{selectIds.length > 0 && ( {selectIds.length > 0 && (
<div className={style.projectDataStickyBox}> <div className={style.projectDataStickyBox}>
...@@ -635,7 +620,6 @@ const ProjectData = observer(() => { ...@@ -635,7 +620,6 @@ const ProjectData = observer(() => {
/> />
<MyButton <MyButton
text={`批量移动 (${selectIds.length})`} text={`批量移动 (${selectIds.length})`}
// color="neutral"
variant="contained" variant="contained"
style={{ marginRight: "24px" }} style={{ marginRight: "24px" }}
onClick={() => { onClick={() => {
......
...@@ -58,10 +58,11 @@ ...@@ -58,10 +58,11 @@
overflow: hidden; overflow: hidden;
} }
.middleDynamic{ .middleDynamic {
display: flex; display: flex;
position: absolute; position: absolute;
left: 0; left: 0;
transition: left .4s ease-in-out;
} }
.logTitle { .logTitle {
...@@ -78,6 +79,10 @@ ...@@ -78,6 +79,10 @@
border-right: 1px solid #10141A; border-right: 1px solid #10141A;
} }
.logTitle:hover {
background-color: #23272E;
}
.logName { .logName {
max-width: 90px; max-width: 90px;
overflow: hidden; overflow: hidden;
...@@ -129,3 +134,11 @@ ...@@ -129,3 +134,11 @@
height: 76px; height: 76px;
padding-right: 24px; padding-right: 24px;
} }
.gradientBox {
position: absolute;
right: 49px;
width: 28px;
height: 32px;
background: linear-gradient(90deg, rgba(29, 33, 38, 0) 0%, #1D2126 100%);
}
\ No newline at end of file
import { useState, useCallback, useEffect, useMemo } from "react"; import { useState, useCallback, useEffect, useMemo } from "react";
import classnames from "classnames"; import classnames from "classnames";
import style from "./index.module.css"; import style from "./index.module.css";
import CloseIcon from "@mui/icons-material/Close";
import MyButton from "@/components/mui/MyButton"; import MyButton from "@/components/mui/MyButton";
import MyTooltip from "@/components/mui/MyTooltip";
import InsertDriveFileOutlinedIcon from "@mui/icons-material/InsertDriveFileOutlined"; import InsertDriveFileOutlinedIcon from "@mui/icons-material/InsertDriveFileOutlined";
import CloudEController from "@/api/fileserver/CloudEController"; import CloudEController from "@/api/fileserver/CloudEController";
import { useStores } from "@/store"; import { useStores } from "@/store";
...@@ -10,6 +10,7 @@ import { toJS } from "mobx"; ...@@ -10,6 +10,7 @@ import { toJS } from "mobx";
import FullScreenDrawer from "@/components/CommonComponents/FullScreenDrawer"; import FullScreenDrawer from "@/components/CommonComponents/FullScreenDrawer";
import ChevronLeftIcon from '@mui/icons-material/ChevronLeft'; import ChevronLeftIcon from '@mui/icons-material/ChevronLeft';
import ChevronRightIcon from '@mui/icons-material/ChevronRight'; import ChevronRightIcon from '@mui/icons-material/ChevronRight';
import useWindowSize from '@/hooks/useWindowSize'
type LogViewProps = { type LogViewProps = {
...@@ -20,6 +21,7 @@ type LogViewProps = { ...@@ -20,6 +21,7 @@ type LogViewProps = {
const LogView = (props: LogViewProps) => { const LogView = (props: LogViewProps) => {
const { logs, setShowLogView } = props; const { logs, setShowLogView } = props;
const { currentProjectStore } = useStores(); const { currentProjectStore } = useStores();
const { width, height } = useWindowSize();
const fileToken = toJS(currentProjectStore.currentProjectInfo.filetoken); const fileToken = toJS(currentProjectStore.currentProjectInfo.filetoken);
const projectId = toJS(currentProjectStore.currentProjectInfo.id); const projectId = toJS(currentProjectStore.currentProjectInfo.id);
// 当前选择的日志 // 当前选择的日志
...@@ -29,6 +31,13 @@ const LogView = (props: LogViewProps) => { ...@@ -29,6 +31,13 @@ const LogView = (props: LogViewProps) => {
// 当前日志路径 // 当前日志路径
const [logPath, setLogPath] = useState('') const [logPath, setLogPath] = useState('')
const [displacement, setDisplacement] = useState(0)
const [middleDynamicWidth, setMiddleDynamicWidth] = useState(0)
const [leftButtonColor, setLeftButtonColor] = useState('#585D62')
const [rightButtonColor, setRightButtonColor] = useState('#585D62')
useEffect(() => { useEffect(() => {
setLogPath(logs[logCurrent]?.logPath) setLogPath(logs[logCurrent]?.logPath)
}, [logs]); }, [logs]);
...@@ -54,6 +63,29 @@ const LogView = (props: LogViewProps) => { ...@@ -54,6 +63,29 @@ const LogView = (props: LogViewProps) => {
setLogPath(logs[logCurrent]?.logPath) setLogPath(logs[logCurrent]?.logPath)
}, [logCurrent]); }, [logCurrent]);
//获取盒子的总宽度,用于滑动效果判断
useEffect(() => {
const box = document.getElementById('middleDynamic')
setMiddleDynamicWidth(box ? box.offsetWidth : 0)
}, [])
useEffect(() => {
if (middleDynamicWidth < width - 97) {
setLeftButtonColor('#585D62')
setRightButtonColor('#585D62')
}
if (displacement === 0) {
setLeftButtonColor('#585D62')
} else {
setLeftButtonColor('#C0C5CD')
}
if (middleDynamicWidth > width - 97 && displacement !== -middleDynamicWidth + width - 97) {
setRightButtonColor('#C0C5CD')
} else {
setRightButtonColor('#585D62')
}
}, [width, middleDynamicWidth, displacement])
// 下载当前日志 // 下载当前日志
const handleDownLoad = () => { const handleDownLoad = () => {
const path = logPath.slice(12) const path = logPath.slice(12)
...@@ -64,16 +96,49 @@ const LogView = (props: LogViewProps) => { ...@@ -64,16 +96,49 @@ const LogView = (props: LogViewProps) => {
); );
} }
const rightClick = () => {
if (middleDynamicWidth < width - 97) {
return
}
if (-displacement > middleDynamicWidth - width * 1.8 + 97) {
setDisplacement(-middleDynamicWidth + width - 97)
return
}
const newDisplacement = displacement - width * 0.8;
setDisplacement(newDisplacement)
}
const leftClick = () => {
if (-displacement < width * 0.8) {
setDisplacement(0)
return
}
const newDisplacement = displacement + width * 0.8;
setDisplacement(newDisplacement)
}
return ( return (
<FullScreenDrawer handleClose={setShowLogView} zIndex={1002}> <FullScreenDrawer handleClose={setShowLogView} zIndex={1002}>
<div className={style.logViewBox}> <div className={style.logViewBox}>
<div className={style.logViewContentMask}></div> <div className={style.logViewContentMask}></div>
<div className={style.logViewTop}> <div className={style.logViewTop}>
<div className={style.leftButton}><ChevronLeftIcon /></div> <div
className={style.leftButton}
onClick={leftClick}
style={{ color: leftButtonColor, cursor: leftButtonColor === '#585D62' ? 'default' : 'pointer' }}
>
<ChevronLeftIcon />
</div>
<div className={style.middleFixed}> <div className={style.middleFixed}>
<div className={style.middleDynamic}> <div className={style.middleDynamic} id='middleDynamic' style={{ left: `${displacement}px` }}>
{logs.map((item: any, index: number) => { {logs.map((item: any, index: number) => {
return <div return <MyTooltip
title={item.logName}
placement="bottom"
arrow={false}
enterDelay={1000}
>
<div
key={index} key={index}
onClick={() => { setLogCurrent(index) }} onClick={() => { setLogCurrent(index) }}
className={classnames({ className={classnames({
...@@ -83,10 +148,18 @@ const LogView = (props: LogViewProps) => { ...@@ -83,10 +148,18 @@ const LogView = (props: LogViewProps) => {
<InsertDriveFileOutlinedIcon className={style.fileIcon} /> <InsertDriveFileOutlinedIcon className={style.fileIcon} />
<span className={style.logName}>{item.logName}</span> <span className={style.logName}>{item.logName}</span>
</div> </div>
</MyTooltip>
})} })}
</div> </div>
</div> </div>
<div className={style.rightButton}><ChevronRightIcon /></div> <div className={style.gradientBox}></div>
<div
className={style.rightButton}
onClick={rightClick}
style={{ color: rightButtonColor, cursor: rightButtonColor === '#585D62' ? 'default' : 'pointer' }}
>
<ChevronRightIcon />
</div>
</div> </div>
<div className={style.logViewContent}> <div className={style.logViewContent}>
{logText} {logText}
......
import styles from "../index.module.css";
import { ITaskInfo } from "../../ProjectSubmitWork/interface";
import jobSue from "@/assets/project/jobSue.svg";
import jobStop from "@/assets/project/jobStop.svg";
import jobRun from "@/assets/project/jobRun.svg";
import jobFail from "@/assets/project/jobFail.svg";
import taskResultsFileIcon from "@/assets/project/taskResultsFileIcon.svg";
import taskResultsDatasetIcon from "@/assets/project/taskResultsDatasetIcon.svg";
import { IState } from "../../ProjectSubmitWork/interface";
import classNames from "classnames";
type ITaskInfoProps = {
workFlowJobInfo: ITaskInfo;
randerOutputs1: Array<any>;
handleDownLoadOutput: any;
handleShowPopper: any;
setGoToProjectDataPath: any;
setShowLogView: any;
state: IState | undefined;
name: any;
};
const stateMap = {
SUBMITTED: "正在启动",
RUNNING: "正在运行",
ABORTED: "运行终止",
FAILED: "运行失败",
SUCCEEDED: "运行成功",
};
const TaskInfo = (props: ITaskInfoProps) => {
const {
workFlowJobInfo,
randerOutputs1,
handleDownLoadOutput,
handleShowPopper,
setGoToProjectDataPath,
setShowLogView,
state,
name,
} = props;
return (
<div className={styles.taskInfo}>
<div className={styles.title}>
任务结果
<span className={styles.taskResultsNum}>{randerOutputs1.length}</span>
</div>
{workFlowJobInfo?.outputs &&
Object.keys(workFlowJobInfo?.outputs).length > 0 && (
<div className={styles.taskResults}>
{randerOutputs1.map((item, index) => {
return (
<div key={index} className={styles.outputLi}>
<div className={styles.outputLiLeft}>
<img
className={classNames({
[styles.outputLiLeftImg]: true,
[styles.outputLiLeftImgBoxShadow2]:
item.type === "file",
})}
src={
item.type === "file"
? taskResultsFileIcon
: taskResultsDatasetIcon
}
alt=""
/>
<div className={styles.outputLiLeftContent}>
<div className={styles.outputItemName}>{item.name}</div>
<div className={styles.outputLiSize}>{item.size}</div>
</div>
</div>
<div
onClick={(e: any) => {
handleDownLoadOutput(item);
}}
className={classNames({
[styles.outputLiRight]: true,
[styles.seeDataset]: item.type !== "file",
[styles.downloadFile]: item.type === "file",
})}
></div>
</div>
);
})}
</div>
)}
{(!workFlowJobInfo?.outputs ||
Object.keys(workFlowJobInfo?.outputs).length === 0) && (
<div className={styles.notResults}>暂无结果文件</div>
)}
<div className={styles.title}>任务信息</div>
<div className={styles.taskInfoLi}>
<div className={styles.taskInfoParams}>任务名称</div>
<div className={styles.taskInfoValue} title={name}>
{name || "-"}
</div>
</div>
<div className={styles.taskInfoLi}>
<div className={styles.taskInfoParams}>任务ID</div>
<div className={styles.taskInfoValue} title={workFlowJobInfo?.id}>
{workFlowJobInfo?.id || "-"}
</div>
</div>
<div className={styles.taskInfoLi}>
<div className={styles.taskInfoParams}>输出路径</div>
<div
className={classNames({
[styles.taskInfoValue]: true,
[styles.taskInfoValueClick]: true,
})}
onClick={(e: any) => {
handleShowPopper(
e,
"即将跳转至项目数据内该任务的输出路径,确认继续吗?",
"bottom"
);
setGoToProjectDataPath(workFlowJobInfo?.outputPath as string);
}}
>
{workFlowJobInfo?.outputPath || "-"}
</div>
</div>
<div className={styles.taskInfoLi}>
<div className={styles.taskInfoParams}>运行状态</div>
<div className={styles.taskInfoValue}>
{state === "SUCCEEDED" && (
<img className={styles.taskInfoValueIcon} src={jobSue} alt="" />
)}
{["SUBMITTED", "RUNNING"].includes(state || "") && (
<img className={styles.taskInfoValueIcon} src={jobRun} alt="" />
)}
{state === "ABORTED" && (
<img className={styles.taskInfoValueIcon} src={jobStop} alt="" />
)}
{state === "FAILED" && (
<img className={styles.taskInfoValueIcon} src={jobFail} alt="" />
)}
{state ? stateMap[state] : "-"}
</div>
</div>
<div className={styles.taskInfoLi}>
<div className={styles.taskInfoParams}>源模板</div>
<div className={styles.taskInfoValue}>
{workFlowJobInfo?.specTitle || "-"}
</div>
</div>
<div className={styles.taskInfoLi}>
<div className={styles.taskInfoParams}>源模板版本</div>
<div className={styles.taskInfoValue}>
{workFlowJobInfo?.specVersion || "-"}
</div>
</div>
<div className={styles.taskInfoLi}>
<div className={styles.taskInfoParams}>花费(元)</div>
<div className={styles.taskInfoValue}>
{workFlowJobInfo?.jobCost || "-"}
</div>
</div>
<div className={styles.taskInfoLi}>
<div className={styles.taskInfoParams}>创建人</div>
<div className={styles.taskInfoValue}>
{workFlowJobInfo?.creator || "-"}
</div>
</div>
<div className={styles.taskInfoLi}>
<div className={styles.taskInfoParams}>创建时间</div>
<div className={styles.taskInfoValue}>
{workFlowJobInfo?.createTime || "-"}
</div>
</div>
<div className={styles.taskInfoLi}>
<div className={styles.taskInfoParams}>运行时间</div>
<div className={styles.taskInfoValue}>
{workFlowJobInfo?.costTime || "-"}
</div>
</div>
<div className={styles.taskInfoLi}>
<div className={styles.taskInfoParams}>日志文件</div>
<div className={styles.taskInfoValue}>
{workFlowJobInfo?.logPath && (
<>
<span
className={styles.taskInfoDownload}
onClick={() => setShowLogView(true)}
>
查看
</span>
</>
)}
{!workFlowJobInfo?.logPath && "-"}
</div>
</div>
</div>
);
};
export default TaskInfo;
...@@ -70,37 +70,79 @@ ...@@ -70,37 +70,79 @@
font-weight: 600; font-weight: 600;
margin-bottom: 16px; margin-bottom: 16px;
} }
.taskResultsNum {
color: rgba(19, 112, 255, 1);
line-height: 24px;
font-size: 16px;
margin-left: 8px;
}
.taskResults { .taskResults {
padding: 24px; padding: 20px 24px 20px 20px;
background-color: rgba(247, 248, 250, 1); background-color: rgba(247, 248, 250, 1);
margin-bottom: 24px; margin-bottom: 24px;
border-radius: 4px;
} }
.outputLi { .outputLi {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
margin: 6px 0; margin-bottom: 20px;
}
.outputLi:last-child {
margin-bottom: 0;
} }
.outputLiLeft { .outputLiLeft {
cursor: pointer;
display: flex; display: flex;
align-items: center; align-items: center;
color: rgba(19, 112, 255, 1); color: rgba(19, 112, 255, 1);
font-size: 14px; font-size: 14px;
} }
.outputLiLeftImg {
box-shadow: 0px 5px 11px -5px rgba(19, 110, 250, 0.64);
}
.outputLiLeftImgBoxShadow2 {
box-shadow: 0px 5px 11px -5px rgba(13, 204, 152, 0.64);
}
.outputItemName { .outputItemName {
max-width: 172px; max-width: 172px;
white-space: nowrap; white-space: nowrap;
display: block; display: block;
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
line-height: 22px;
font-size: 14px;
font-weight: 600;
color: rgba(30, 38, 51, 1);
margin-bottom: 4px;
}
.outputLiSize {
line-height: 20px;
font-size: 12px;
color: rgba(138, 144, 153, 1);
} }
.outputLiLeftImg { .outputLiLeftImg {
margin-right: 12px; margin-right: 16px;
width: 40px;
height: 40px;
} }
.outputLiRight { .outputLiRight {
color: rgba(138, 144, 153, 1); cursor: pointer;
font-size: 12px; }
.seeDataset {
width: 18px;
height: 18px;
background-image: url(../../../assets/project/taskResultsSeeIcon.svg);
}
.seeDataset:hover {
background-image: url(../../../assets/project/taskResultsSeeHoverIcon.svg);
}
.downloadFile {
width: 16px;
height: 16px;
background-image: url(../../../assets/project/taskResultsDownloadIcon.svg);
}
.downloadFile:hover {
background-image: url(../../../assets/project/taskResultsDownloadHoverIcon.svg);
} }
.notResults { .notResults {
background-color: rgba(247, 248, 250, 1); background-color: rgba(247, 248, 250, 1);
......
...@@ -13,6 +13,7 @@ import classNames from "classnames"; ...@@ -13,6 +13,7 @@ import classNames from "classnames";
import { useLocation, useNavigate } from "react-router-dom"; import { useLocation, useNavigate } from "react-router-dom";
import MyButton from "@/components/mui/MyButton"; import MyButton from "@/components/mui/MyButton";
import TaskInfo from "./TaskInfo";
import useMyRequest from "@/hooks/useMyRequest"; import useMyRequest from "@/hooks/useMyRequest";
import { import {
fetchWorkFlowJob, fetchWorkFlowJob,
...@@ -21,15 +22,12 @@ import { ...@@ -21,15 +22,12 @@ import {
} from "@/api/project_api"; } from "@/api/project_api";
import { IResponse } from "@/api/http"; import { IResponse } from "@/api/http";
import jobSue from "@/assets/project/jobSue.svg"; import jobSue from "@/assets/project/jobSue.svg";
import jobStop from "@/assets/project/jobStop.svg";
import jobRun from "@/assets/project/jobRun.svg"; import jobRun from "@/assets/project/jobRun.svg";
import fullScreen from "@/assets/project/fullScreen.svg"; import fullScreen from "@/assets/project/fullScreen.svg";
import partialScreen from "@/assets/project/partialScreen.svg"; import partialScreen from "@/assets/project/partialScreen.svg";
import goback from "@/assets/project/goback.svg"; import goback from "@/assets/project/goback.svg";
import CloudEController from "@/api/fileserver/CloudEController"; import CloudEController from "@/api/fileserver/CloudEController";
import jobFail from "@/assets/project/jobFail.svg"; import jobFail from "@/assets/project/jobFail.svg";
import fileIcon from "@/assets/project/fileIcon.svg";
import dataSetIcon from "@/assets/project/dataSetIcon.svg";
import { useStores } from "@/store"; import { useStores } from "@/store";
import { ITaskInfo } from "../ProjectSubmitWork/interface"; import { ITaskInfo } from "../ProjectSubmitWork/interface";
import Flow from "../components/Flow"; import Flow from "../components/Flow";
...@@ -51,14 +49,6 @@ import MyTooltip from "@/components/mui/MyTooltip"; ...@@ -51,14 +49,6 @@ import MyTooltip from "@/components/mui/MyTooltip";
import styles from "./index.module.css"; import styles from "./index.module.css";
const stateMap = {
SUBMITTED: "正在启动",
RUNNING: "正在运行",
ABORTED: "运行终止",
FAILED: "运行失败",
SUCCEEDED: "运行成功",
};
const statusMap = { const statusMap = {
Done: "运行完成", Done: "运行完成",
Running: "正在运行", Running: "正在运行",
...@@ -197,25 +187,16 @@ const ProjectSubmitWork = observer(() => { ...@@ -197,25 +187,16 @@ const ProjectSubmitWork = observer(() => {
const goToProjectData = (path: string) => { const goToProjectData = (path: string) => {
path = path.slice(12); path = path.slice(12);
if (path) { if (path) {
navigate(`/product/cadd/projectData`, { navigate(`/product/${productId || "cadd"}/projectData`, {
state: { pathName: path }, state: { pathName: path },
}); });
} else { } else {
navigate(`/product/cadd/projectData`, { navigate(`/product/${productId || "cadd"}/projectData`, {
state: { pathName: "/" }, state: { pathName: "/" },
}); });
} }
}; };
// 通过文件路径获取文件所在文件夹路径 如 输入 /ProjectData/task_a.out 输出/ProjectData/
// const getFolderPath = (path: string) => {
// const lastIndex = path.lastIndexOf("/");
// if (lastIndex !== -1) {
// path = path.slice(0, lastIndex);
// }
// return path;
// };
// 下载任务结果 // 下载任务结果
const handleDownLoadOutput = (item: any) => { const handleDownLoadOutput = (item: any) => {
// 是文件下载 // 是文件下载
...@@ -236,13 +217,13 @@ const ProjectSubmitWork = observer(() => { ...@@ -236,13 +217,13 @@ const ProjectSubmitWork = observer(() => {
/** 返回事件 */ /** 返回事件 */
const onBack = useCallback(() => { const onBack = useCallback(() => {
if (locationInfo.from === "projectOverview") { if (locationInfo.from === "projectOverview") {
navigate("/product/cadd/projectOverview"); navigate(`/product/${productId || "cadd"}/projectOverview`);
} else { } else {
navigate("/product/cadd/projectWorkbench", { navigate(`/product/${productId || "cadd"}/projectWorkbench`, {
state: { type: "workbenchList" }, state: { type: "workbenchList" },
}); });
} }
}, [navigate, locationInfo.from]); }, [navigate, locationInfo.from, productId]);
const getOutouts = (outputs: any) => { const getOutouts = (outputs: any) => {
if (outputs) { if (outputs) {
...@@ -483,174 +464,17 @@ const ProjectSubmitWork = observer(() => { ...@@ -483,174 +464,17 @@ const ProjectSubmitWork = observer(() => {
{fullScreenShow ? null : ( {fullScreenShow ? null : (
<div className={styles.swFormBox}> <div className={styles.swFormBox}>
{!activeFlowIndex && ( {!activeFlowIndex && (
<div className={styles.taskInfo}> <TaskInfo
<div className={styles.title}>任务结果</div> workFlowJobInfo={workFlowJobInfo as ITaskInfo}
{workFlowJobInfo?.outputs && randerOutputs1={randerOutputs1}
Object.keys(workFlowJobInfo?.outputs).length > 0 && ( handleDownLoadOutput={handleDownLoadOutput}
<div className={styles.taskResults}> handleShowPopper={handleShowPopper}
{randerOutputs1.map((item, index) => { setGoToProjectDataPath={setGoToProjectDataPath}
return ( setShowLogView={setShowLogView}
<div key={index} className={styles.outputLi}> state={state}
<div name={name}
className={styles.outputLiLeft}
onClick={(e: any) => {
handleDownLoadOutput(item);
}}
>
<img
className={styles.outputLiLeftImg}
src={
item.type === "file" ? fileIcon : dataSetIcon
}
alt=""
/>
<span className={styles.outputItemName}>
{item.name}
</span>
</div>
<span className={styles.outputLiRight}>
{item.size}
</span>
</div>
);
})}
</div>
)}
{(!workFlowJobInfo?.outputs ||
Object.keys(workFlowJobInfo?.outputs).length === 0) && (
<div className={styles.notResults}>暂无结果文件</div>
)}
<div className={styles.title}>任务信息</div>
<div className={styles.taskInfoLi}>
<div className={styles.taskInfoParams}>任务名称</div>
<div className={styles.taskInfoValue} title={name}>
{name || "-"}
</div>
</div>
<div className={styles.taskInfoLi}>
<div className={styles.taskInfoParams}>任务ID</div>
<div
className={styles.taskInfoValue}
title={workFlowJobInfo?.id}
>
{workFlowJobInfo?.id || "-"}
</div>
</div>
<div className={styles.taskInfoLi}>
<div className={styles.taskInfoParams}>输出路径</div>
<div
className={classNames({
[styles.taskInfoValue]: true,
[styles.taskInfoValueClick]: true,
})}
onClick={(e: any) => {
handleShowPopper(
e,
"即将跳转至项目数据内该任务的输出路径,确认继续吗?",
"bottom"
);
setGoToProjectDataPath(
workFlowJobInfo?.outputPath as string
);
}}
>
{workFlowJobInfo?.outputPath || "-"}
</div>
</div>
<div className={styles.taskInfoLi}>
<div className={styles.taskInfoParams}>运行状态</div>
<div className={styles.taskInfoValue}>
{state === "SUCCEEDED" && (
<img
className={styles.taskInfoValueIcon}
src={jobSue}
alt=""
/>
)}
{["SUBMITTED", "RUNNING"].includes(state || "") && (
<img
className={styles.taskInfoValueIcon}
src={jobRun}
alt=""
/> />
)} )}
{state === "ABORTED" && (
<img
className={styles.taskInfoValueIcon}
src={jobStop}
alt=""
/>
)}
{state === "FAILED" && (
<img
className={styles.taskInfoValueIcon}
src={jobFail}
alt=""
/>
)}
{state ? stateMap[state] : "-"}
</div>
</div>
<div className={styles.taskInfoLi}>
<div className={styles.taskInfoParams}>源模板</div>
<div className={styles.taskInfoValue}>
{workFlowJobInfo?.specTitle || "-"}
</div>
</div>
<div className={styles.taskInfoLi}>
<div className={styles.taskInfoParams}>源模板版本</div>
<div className={styles.taskInfoValue}>
{workFlowJobInfo?.specVersion || "-"}
</div>
</div>
<div className={styles.taskInfoLi}>
<div className={styles.taskInfoParams}>花费(元)</div>
<div className={styles.taskInfoValue}>
{workFlowJobInfo?.jobCost || "-"}
</div>
</div>
<div className={styles.taskInfoLi}>
<div className={styles.taskInfoParams}>创建人</div>
<div className={styles.taskInfoValue}>
{workFlowJobInfo?.creator || "-"}
</div>
</div>
<div className={styles.taskInfoLi}>
<div className={styles.taskInfoParams}>创建时间</div>
<div className={styles.taskInfoValue}>
{workFlowJobInfo?.createTime || "-"}
</div>
</div>
<div className={styles.taskInfoLi}>
<div className={styles.taskInfoParams}>运行时间</div>
<div className={styles.taskInfoValue}>
{workFlowJobInfo?.costTime || "-"}
</div>
</div>
<div className={styles.taskInfoLi}>
<div className={styles.taskInfoParams}>日志文件</div>
<div className={styles.taskInfoValue}>
{workFlowJobInfo?.logPath && (
<>
{/* <span
className={styles.taskInfoDownload}
onClick={() => handleDownLoad(workFlowJobInfo?.logPath)}
>
下载
</span> */}
<span
className={styles.taskInfoDownload}
onClick={() => setShowLogView(true)}
>
查看
</span>
</>
)}
{!workFlowJobInfo?.logPath && "-"}
</div>
</div>
</div>
)}
{activeFlowIndex && ( {activeFlowIndex && (
<div className={styles.suanziInfo}> <div className={styles.suanziInfo}>
<MyTooltip> <MyTooltip>
...@@ -778,12 +602,7 @@ const ProjectSubmitWork = observer(() => { ...@@ -778,12 +602,7 @@ const ProjectSubmitWork = observer(() => {
projectId={projectId as string} projectId={projectId as string}
></SeeDataset> ></SeeDataset>
)} )}
{showLogView && ( {showLogView && <LogView logs={logs} setShowLogView={handleClose} />}
<LogView
logs={logs}
setShowLogView={handleClose}
/>
)}
</div> </div>
); );
}); });
......
...@@ -2,6 +2,9 @@ import { useMemo, useCallback, useEffect, useState } from "react"; ...@@ -2,6 +2,9 @@ import { useMemo, useCallback, useEffect, useState } from "react";
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
import MyProgress from "@/components/mui/MyProgress"; import MyProgress from "@/components/mui/MyProgress";
import style from "./index.module.css"; import style from "./index.module.css";
import { useStores } from "@/store";
import { toJS } from "mobx";
import { observer } from "mobx-react-lite";
import runTime from "../../../../assets/project/runTime.svg"; import runTime from "../../../../assets/project/runTime.svg";
import jobCostImg from "../../../../assets/project/jobCost.svg"; import jobCostImg from "../../../../assets/project/jobCost.svg";
...@@ -38,6 +41,8 @@ const TaskCard = (props: TaskCardProps) => { ...@@ -38,6 +41,8 @@ const TaskCard = (props: TaskCardProps) => {
} = props; } = props;
const navigate = useNavigate(); const navigate = useNavigate();
const [displayTitleBlue, setDisplayTitleBlue] = useState<boolean>(false); const [displayTitleBlue, setDisplayTitleBlue] = useState<boolean>(false);
const { currentProjectStore } = useStores();
const productId = toJS(currentProjectStore.currentProductInfo.id); // 产品ID
const randerOutputs = useMemo(() => { const randerOutputs = useMemo(() => {
if (outputs) { if (outputs) {
...@@ -68,13 +73,13 @@ const TaskCard = (props: TaskCardProps) => { ...@@ -68,13 +73,13 @@ const TaskCard = (props: TaskCardProps) => {
path = path.slice(0, lastIndex); path = path.slice(0, lastIndex);
} }
path = path.slice(12); path = path.slice(12);
navigate(`/product/cadd/projectData`, { navigate(`/product/${productId || "cadd"}/projectData`, {
state: { pathName: path || "/", dataType: type }, state: { pathName: path || "/", dataType: type },
}); });
}; };
// 跳转详情页 // 跳转详情页
const gotoDetail = (id: string) => { const gotoDetail = (id: string) => {
navigate(`/product/cadd/projectJobDetail`, { navigate(`/product/${productId || "cadd"}/projectJobDetail`, {
state: { taskId: id, from: "projectOverview" }, state: { taskId: id, from: "projectOverview" },
}); });
}; };
......
...@@ -67,7 +67,9 @@ ...@@ -67,7 +67,9 @@
color: #1e2633; color: #1e2633;
margin-right: 8px; margin-right: 8px;
} }
.red{
color: rgba(255, 78, 78, 1);
}
.verticalLine { .verticalLine {
height: 32px; height: 32px;
border-right: 1px solid #ebedf0; border-right: 1px solid #ebedf0;
......
...@@ -169,7 +169,10 @@ const ProjectOverview = observer(() => { ...@@ -169,7 +169,10 @@ const ProjectOverview = observer(() => {
项目剩余预算 项目剩余预算
</div> </div>
<div> <div>
<span className={style.numberDisplay}> <span className={classNames({
[style.numberDisplay]: true,
[style.red]:overviewInfo.projectRemainingBudget?.toFixed(2) < 100
})}>
{overviewInfo.projectRemainingBudget?.toFixed(2)} {overviewInfo.projectRemainingBudget?.toFixed(2)}
</span> </span>
......
...@@ -40,6 +40,7 @@ const BaseInfo = observer(() => { ...@@ -40,6 +40,7 @@ const BaseInfo = observer(() => {
const message = useMessage(); const message = useMessage();
const { currentProjectStore } = useStores(); const { currentProjectStore } = useStores();
const fileToken = toJS(currentProjectStore.currentProjectInfo.filetoken); const fileToken = toJS(currentProjectStore.currentProjectInfo.filetoken);
const productId = toJS(currentProjectStore.currentProductInfo.id); // 产品ID
const [projectInfo, setProjectInfo] = useState<any>({}); const [projectInfo, setProjectInfo] = useState<any>({});
const [deleteProjectName, setDeleteProjectName] = useState(""); const [deleteProjectName, setDeleteProjectName] = useState("");
const [nameCheck, setNameCheck] = useState({ const [nameCheck, setNameCheck] = useState({
...@@ -258,7 +259,7 @@ const BaseInfo = observer(() => { ...@@ -258,7 +259,7 @@ const BaseInfo = observer(() => {
{ {
onSuccess: async (result: any) => { onSuccess: async (result: any) => {
message.success("修改成功"); message.success("修改成功");
const projectList = await getProjectList(); const projectList = await getProjectList(productId);
currentProjectStore.setProjectList(projectList); currentProjectStore.setProjectList(projectList);
projectInfo.filetoken = fileToken; projectInfo.filetoken = fileToken;
currentProjectStore.changeProject(projectInfo); currentProjectStore.changeProject(projectInfo);
...@@ -272,7 +273,7 @@ const BaseInfo = observer(() => { ...@@ -272,7 +273,7 @@ const BaseInfo = observer(() => {
checkName(projectInfo.name, true) && checkName(projectInfo.name, true) &&
checkBudget(projectInfo.projectBudget, true) checkBudget(projectInfo.projectBudget, true)
) { ) {
updateProjectRun({ ...projectInfo, product: "cadd" }); updateProjectRun({ ...projectInfo, product: `${productId || "cadd"}` });
} else { } else {
return; return;
} }
...@@ -282,7 +283,7 @@ const BaseInfo = observer(() => { ...@@ -282,7 +283,7 @@ const BaseInfo = observer(() => {
onSuccess: async (result: any) => { onSuccess: async (result: any) => {
message.success("删除成功"); message.success("删除成功");
setDialogOpen(false); setDialogOpen(false);
const projectList = await getProjectList(); const projectList = await getProjectList(productId);
currentProjectStore.setProjectList(projectList); currentProjectStore.setProjectList(projectList);
// 项目删完了 // 项目删完了
currentProjectStore.changeProject({}); currentProjectStore.changeProject({});
......
...@@ -9,15 +9,17 @@ ...@@ -9,15 +9,17 @@
import { toJS } from "mobx"; import { toJS } from "mobx";
import { observer } from "mobx-react-lite"; import { observer } from "mobx-react-lite";
import _ from "lodash"; import _ from "lodash";
import { memo, useCallback, useEffect, useMemo, useState } from "react"; import { memo, useCallback, useEffect, useState } from "react";
import { Box, OutlinedInput } from "@mui/material"; import { Box } from "@mui/material";
import Dialog from "@/components/mui/MyDialog"; import Dialog from "@/components/mui/MyDialog";
import useMyRequest from "@/hooks/useMyRequest"; import useMyRequest from "@/hooks/useMyRequest";
import { useStores } from "@/store"; import { useStores } from "@/store";
import { useMessage } from "@/components/MySnackbar"; import { useMessage } from "@/components/MySnackbar";
import MyBorderlessSelect, { IOption } from "@/components/mui/MyBorderlessSelect"; import MyBorderlessSelect, {
import MyTable from "@/components/mui/MyTable"; IOption,
} from "@/components/mui/MyBorderlessSelect";
import MyTable from "@/components/mui/MyTableNew";
import SearchInput from "@/components/BusinessComponents/SearchInput"; import SearchInput from "@/components/BusinessComponents/SearchInput";
import { import {
addProjectUser, addProjectUser,
...@@ -35,7 +37,6 @@ const AddMember = observer((props: IProps) => { ...@@ -35,7 +37,6 @@ const AddMember = observer((props: IProps) => {
const { addMemberDialog, setAddMemberDialog, getTableList } = props; const { addMemberDialog, setAddMemberDialog, getTableList } = props;
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([]);
...@@ -54,17 +55,18 @@ const AddMember = observer((props: IProps) => { ...@@ -54,17 +55,18 @@ const AddMember = observer((props: IProps) => {
[tableData] [tableData]
); );
const columns = useMemo(() => { const columns = [
return [ { id: "username", label: "项目成员", width: 200 },
{ id: "checkbox", width: 50 },
{ id: "username", label: "项目成员", width: 160 },
{ {
id: "projectRole", id: "projectRole",
label: "项目权限", label: "项目权限",
width: 160, width: 100,
render: (item: string, row: any, index: number) => { },
];
const randerRole = (item: any, index: number) => {
const defaultValue = selectOptions.filter( const defaultValue = selectOptions.filter(
(every) => every.value === item (every) => every.value === item.projectRole
); );
return ( return (
<MyBorderlessSelect <MyBorderlessSelect
...@@ -72,12 +74,10 @@ const AddMember = observer((props: IProps) => { ...@@ -72,12 +74,10 @@ const AddMember = observer((props: IProps) => {
onChange={(val) => changePermission(val, index)} onChange={(val) => changePermission(val, index)}
options={selectOptions} options={selectOptions}
size="small" size="small"
sx={{ position: "relative", left: "-13px" }}
/> />
); );
}, };
},
];
}, [changePermission, selectOptions]);
/** 过滤表格数据 */ /** 过滤表格数据 */
useEffect(() => { useEffect(() => {
...@@ -93,11 +93,14 @@ const AddMember = observer((props: IProps) => { ...@@ -93,11 +93,14 @@ const AddMember = observer((props: IProps) => {
}, [projectMember, tableData]); }, [projectMember, tableData]);
// 获取表格数据接口 // 获取表格数据接口
const { run: getProjectUsersList } = useMyRequest(fetchProjectUsersList, { const { run: getProjectUsersList, loading } = useMyRequest(
fetchProjectUsersList,
{
onSuccess: (res: any) => { onSuccess: (res: any) => {
setTableData(res?.data); setTableData(res?.data);
}, },
}); }
);
// 获取项目权限 // 获取项目权限
const { run: getProjectPower } = useMyRequest(fetchProjectPower, { const { run: getProjectPower } = useMyRequest(fetchProjectPower, {
...@@ -120,6 +123,7 @@ const AddMember = observer((props: IProps) => { ...@@ -120,6 +123,7 @@ const AddMember = observer((props: IProps) => {
useEffect(() => { useEffect(() => {
if (addMemberDialog) { if (addMemberDialog) {
setProjectMember("");
getProjectPower(); getProjectPower();
} }
}, [addMemberDialog, getProjectPower]); }, [addMemberDialog, getProjectPower]);
...@@ -173,23 +177,22 @@ const AddMember = observer((props: IProps) => { ...@@ -173,23 +177,22 @@ const AddMember = observer((props: IProps) => {
placeholder="搜索项目成员" placeholder="搜索项目成员"
sx={{ mb: 2 }} sx={{ mb: 2 }}
/> />
<div style={{ overflow: "overlay", maxHeight: 400 }}> <div style={{ height: "320px" }}>
<MyTable <MyTable
noDataText={ noDataText={
projectMember ? `暂无 "${projectMember}" 搜索结果` : undefined projectMember ? `暂无 "${projectMember}" 搜索结果` : undefined
} }
tableContainerStyle={{ height: 346 }} tableKey="username"
checkboxData={(val: string[]) => setCheckData(val)} hasCheckbox={true}
param="username" selectItems={checkData}
disabledParam={"enabled"} setSelectItems={setCheckData}
rowHover={true} fixedHead={true}
stickyHeader={true} rows={filterTableData.map((item: any, idnex) => ({
rows={filterTableData} ...item,
rowsPerPage="99" projectRole: randerRole(item, idnex),
}))}
headCells={columns} headCells={columns}
footer={false} loading={loading}
tableStyle={{ minWidth: "auto" }}
borderBottom="none"
/> />
</div> </div>
</Box> </Box>
......
...@@ -10,3 +10,6 @@ ...@@ -10,3 +10,6 @@
margin-left: 32px; margin-left: 32px;
cursor: pointer; cursor: pointer;
} }
.tableBox {
height: calc(100vh - 300px);
}
...@@ -7,15 +7,12 @@ ...@@ -7,15 +7,12 @@
* @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 { memo, useCallback, useEffect, useMemo, useState } from "react"; import { memo, useCallback, useEffect, useMemo, useState } from "react";
import _ from "lodash";
import OutlinedInput from "@mui/material/OutlinedInput";
import { Box } from "@mui/material"; import { Box } from "@mui/material";
import SearchIcon from "@mui/icons-material/Search";
import Add from "@mui/icons-material/Add"; import Add from "@mui/icons-material/Add";
import { toJS } from "mobx"; import { toJS } from "mobx";
import { observer } from "mobx-react"; import { observer } from "mobx-react";
import MyTable from "@/components/mui/MyTable"; import MyTable from "@/components/mui/MyTableNew";
import { IResponse, useHttp } from "@/api/http"; import { IResponse, useHttp } from "@/api/http";
import RemoveItem from "./components/RemoveItem"; import RemoveItem from "./components/RemoveItem";
import ChangePermission from "./components/ChangePermission"; import ChangePermission from "./components/ChangePermission";
...@@ -52,26 +49,15 @@ const ProjectMembers = observer(() => { ...@@ -52,26 +49,15 @@ const ProjectMembers = observer(() => {
const [projectName, setProjectMember] = useState(""); const [projectName, setProjectMember] = useState("");
/** 过滤后数据 */ /** 过滤后数据 */
const [filterTableData, setFilterTableData] = useState([]); const [filterTableData, setFilterTableData] = useState([]);
const [loading, setLoading] = useState(false);
const columns = useMemo(() => { const randerOperation = (item: any) => {
const val: any = [ return item?.projectRole === "OWNER" ? null : (
{ id: "username", label: "成员名称" },
{ id: "projectRoleDesc", label: "项目权限" },
{ id: "phone", label: "联系方式" },
...(projectRole !== "OWNER"
? []
: [
{
id: "operation",
label: "操作",
width: 160,
render: (item: any, row: any) => {
return row?.projectRole === "OWNER" ? null : (
<> <>
<span <span
style={{ color: "#1370FF", cursor: "pointer" }} style={{ color: "#1370FF", cursor: "pointer" }}
onClick={() => { onClick={() => {
onPermissionBtn(row); onPermissionBtn(item);
}} }}
> >
更改权限 更改权限
...@@ -79,17 +65,28 @@ const ProjectMembers = observer(() => { ...@@ -79,17 +65,28 @@ const ProjectMembers = observer(() => {
<span <span
className={styles.removeItemBox} className={styles.removeItemBox}
onClick={() => { onClick={() => {
onRemoveItemBtn(row.username); onRemoveItemBtn(item.username);
}} }}
> >
移出项目 移出项目
</span> </span>
</> </>
); );
}, };
},
]), const columns = useMemo(() => {
let val: any = [
{ id: "username", label: "成员名称", width: 200 },
{ id: "projectRoleDesc", label: "项目权限", width: 200 },
{ id: "phone", label: "联系方式" },
]; ];
if (projectRole === "OWNER") {
val.push({
id: "operation",
label: "操作",
width: 180,
});
}
return val; return val;
}, [projectRole]); }, [projectRole]);
...@@ -97,14 +94,19 @@ const ProjectMembers = observer(() => { ...@@ -97,14 +94,19 @@ const ProjectMembers = observer(() => {
const getTableList = useCallback(() => { const getTableList = useCallback(() => {
const projectInfo = toJS(currentProjectStore?.currentProjectInfo); const projectInfo = toJS(currentProjectStore?.currentProjectInfo);
if (!projectInfo?.id) return; if (!projectInfo?.id) return;
setLoading(true);
http http
.get<IResponse<any>>("/cpp/project/get", { .get<IResponse<any>>("/cpp/project/get", {
params: { id: projectInfo?.id || "" }, params: { id: projectInfo?.id || "" },
}) })
.then((res) => { .then((res) => {
setLoading(false);
const { data = {} } = res; const { data = {} } = res;
setTableData(data?.members || []); setTableData(data?.members || []);
setProjectRole(data?.projectRole || ""); setProjectRole(data?.projectRole || "");
})
.catch(() => {
setLoading(false);
}); });
}, [currentProjectStore?.currentProjectInfo, http]); }, [currentProjectStore?.currentProjectInfo, http]);
...@@ -147,7 +149,7 @@ const ProjectMembers = observer(() => { ...@@ -147,7 +149,7 @@ const ProjectMembers = observer(() => {
if (e.keyCode === 13) { if (e.keyCode === 13) {
setProjectMember(e.target.value); setProjectMember(e.target.value);
} }
} };
return ( return (
<> <>
...@@ -159,7 +161,7 @@ const ProjectMembers = observer(() => { ...@@ -159,7 +161,7 @@ const ProjectMembers = observer(() => {
/> />
{currentProjectStore?.currentProjectInfo?.projectRole === "OWNER" ? ( {currentProjectStore?.currentProjectInfo?.projectRole === "OWNER" ? (
<MyButton <MyButton
text='添加成员' text="添加成员"
style={{ backgroundColor: "#1370FF " }} style={{ backgroundColor: "#1370FF " }}
variant="contained" variant="contained"
onClick={onAddMember} onClick={onAddMember}
...@@ -168,16 +170,18 @@ const ProjectMembers = observer(() => { ...@@ -168,16 +170,18 @@ const ProjectMembers = observer(() => {
/> />
) : null} ) : null}
</Box> </Box>
<div className={styles.tableBox}>
<MyTable <MyTable
rowHover={true} fixedHead={true}
stickyHeader={true} rows={filterTableData.map((item: any, index) => ({
rows={filterTableData} ...item,
rowsPerPage={"99"} operation: randerOperation(item),
}))}
tableKey="username"
headCells={columns} headCells={columns}
footer={false} loading={loading}
tableStyle={{ minWidth: "auto" }}
borderBottom={"none"}
/> />
</div>
<RemoveItem <RemoveItem
removeDialog={removeDialog} removeDialog={removeDialog}
setRemoveDialog={setRemoveDialog} setRemoveDialog={setRemoveDialog}
...@@ -188,11 +192,13 @@ const ProjectMembers = observer(() => { ...@@ -188,11 +192,13 @@ const ProjectMembers = observer(() => {
getTableList={getTableList} getTableList={getTableList}
setPermissionDialog={setPermissionDialog} setPermissionDialog={setPermissionDialog}
/> />
{addMemberDialog && (
<AddMember <AddMember
addMemberDialog={addMemberDialog} addMemberDialog={addMemberDialog}
setAddMemberDialog={setAddMemberDialog} setAddMemberDialog={setAddMemberDialog}
getTableList={getTableList} getTableList={getTableList}
/> />
)}
</> </>
); );
}); });
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +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 { memo, useMemo } from "react"; import { memo, useMemo } from "react";
import { useLocation } from "react-router-dom";
import { Box } from "@mui/system"; import { Box } from "@mui/system";
import { useStores } from "@/store/index"; import { useStores } from "@/store/index";
...@@ -20,6 +21,7 @@ import usePass from "@/hooks/usePass"; ...@@ -20,6 +21,7 @@ import usePass from "@/hooks/usePass";
const ProjectSetting = observer(() => { const ProjectSetting = observer(() => {
const { currentProjectStore } = useStores(); const { currentProjectStore } = useStores();
const isPass = usePass(); const isPass = usePass();
const location: any = useLocation();
const tabList = useMemo(() => { const tabList = useMemo(() => {
return [ return [
{ {
...@@ -54,7 +56,10 @@ const ProjectSetting = observer(() => { ...@@ -54,7 +56,10 @@ const ProjectSetting = observer(() => {
</span> </span>
</div> </div>
<Box sx={{ width: "100%", typography: "body1" }}> <Box sx={{ width: "100%", typography: "body1" }}>
<Tabs tabList={tabList} /> <Tabs
tabList={tabList}
defaultValue={location?.state?.type || "projectMember"}
/>
</Box> </Box>
</div> </div>
); );
......
...@@ -34,6 +34,7 @@ const ProjectSubmitWork = observer(() => { ...@@ -34,6 +34,7 @@ const ProjectSubmitWork = observer(() => {
const Message = useMessage(); const Message = useMessage();
const { currentProjectStore } = useStores(); const { currentProjectStore } = useStores();
const projectId = toJS(currentProjectStore.currentProjectInfo.id); const projectId = toJS(currentProjectStore.currentProjectInfo.id);
const productId = toJS(currentProjectStore.currentProductInfo.id); // 产品ID
const [templateConfigInfo, setTemplateConfigInfo] = const [templateConfigInfo, setTemplateConfigInfo] =
useState<ITemplateConfig>(); useState<ITemplateConfig>();
const location: any = useLocation(); const location: any = useLocation();
...@@ -46,7 +47,7 @@ const ProjectSubmitWork = observer(() => { ...@@ -46,7 +47,7 @@ const ProjectSubmitWork = observer(() => {
// 前往工作台 // 前往工作台
const goToWorkbench = (toWorkbenchList = false) => { const goToWorkbench = (toWorkbenchList = false) => {
navigate("/product/cadd/projectWorkbench", { navigate(`/product/${productId || "cadd"}/projectWorkbench`, {
state: { type: toWorkbenchList ? "workbenchList" : "" }, state: { type: toWorkbenchList ? "workbenchList" : "" },
}); });
}; };
......
...@@ -132,4 +132,4 @@ export interface ITaskInfo extends ITemplateConfig { ...@@ -132,4 +132,4 @@ export interface ITaskInfo extends ITemplateConfig {
outputs?: any; // 结果文件 outputs?: any; // 结果文件
} }
type IState = "SUCCEEDED" | "RUNNING" | "ABORTED" | "FAILED"; export type IState = "SUCCEEDED" | "RUNNING" | "ABORTED" | "FAILED";
...@@ -10,11 +10,13 @@ import { memo, useMemo } from "react"; ...@@ -10,11 +10,13 @@ import { memo, useMemo } from "react";
import { Box } from "@mui/system"; import { Box } from "@mui/system";
import { observer } from "mobx-react-lite"; import { observer } from "mobx-react-lite";
import { useLocation } from "react-router-dom"; import { useLocation } from "react-router-dom";
import { useStores } from "@/store/index";
import WorkbenchTemplate from "./workbenchTemplate"; import WorkbenchTemplate from "./workbenchTemplate";
import WorkbenchList from "./workbenchList"; import WorkbenchList from "./workbenchList";
import Tabs from "@/components/mui/Tabs"; import Tabs from "@/components/mui/Tabs";
import usePass from "@/hooks/usePass"; import usePass from "@/hooks/usePass";
import NoProject from "@/components/BusinessComponents/NoProject";
import Template from "@/assets/project/workbenchTemplate.svg"; import Template from "@/assets/project/workbenchTemplate.svg";
import TemplateSelect from "@/assets/project/workbenchTemplate_select.svg"; import TemplateSelect from "@/assets/project/workbenchTemplate_select.svg";
import TemplateHover from "@/assets/project/workbenchTemplate_hover.svg"; import TemplateHover from "@/assets/project/workbenchTemplate_hover.svg";
...@@ -23,6 +25,7 @@ import ListHover from "@/assets/project/workbenchList_hover.svg"; ...@@ -23,6 +25,7 @@ import ListHover from "@/assets/project/workbenchList_hover.svg";
import ListSelect from "@/assets/project/workbenchList_select.svg"; import ListSelect from "@/assets/project/workbenchList_select.svg";
const ProjectWorkbench = observer(() => { const ProjectWorkbench = observer(() => {
const { currentProjectStore } = useStores();
const isPass = usePass(); const isPass = usePass();
const location: any = useLocation(); const location: any = useLocation();
...@@ -48,7 +51,7 @@ const ProjectWorkbench = observer(() => { ...@@ -48,7 +51,7 @@ const ProjectWorkbench = observer(() => {
}, },
]; ];
}, [isPass]); }, [isPass]);
if (currentProjectStore.currentProjectInfo.name) {
return ( return (
<div style={{ padding: "28px 24px 24px" }}> <div style={{ padding: "28px 24px 24px" }}>
<div style={{ display: "flex", alignItems: "center" }}> <div style={{ display: "flex", alignItems: "center" }}>
...@@ -72,6 +75,9 @@ const ProjectWorkbench = observer(() => { ...@@ -72,6 +75,9 @@ const ProjectWorkbench = observer(() => {
</Box> </Box>
</div> </div>
); );
} else {
return <NoProject />;
}
}); });
export default memo(ProjectWorkbench); export default memo(ProjectWorkbench);
...@@ -7,18 +7,15 @@ ...@@ -7,18 +7,15 @@
* @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 { memo, useCallback, useEffect, useState } from "react"; import { memo, useCallback, useEffect, useState } from "react";
import _ from "lodash";
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
import { Box, Typography } from "@mui/material"; import { Box, Typography } from "@mui/material";
import OutlinedInput from "@mui/material/OutlinedInput"; import OutlinedInput from "@mui/material/OutlinedInput";
import { TablePagination } from "@mui/material";
import MyPagination from "@/components/mui/MyPagination"; import MyPagination from "@/components/mui/MyPagination";
import MySelect from "@/components/mui/MySelect"; import MySelect from "@/components/mui/MySelect";
import SimpleDialog from "./components/simpleDialog"; import SimpleDialog from "./components/simpleDialog";
import { useStores } from "@/store"; import { useStores } from "@/store";
import useMyRequest from "@/hooks/useMyRequest"; import useMyRequest from "@/hooks/useMyRequest";
import ActionsComponent from "../../../../components/Material.Ui/Table/ActionsComponent";
import runTime from "../../../../assets/project/runTime.svg"; import runTime from "../../../../assets/project/runTime.svg";
import jobCost from "../../../../assets/project/jobCost.svg"; import jobCost from "../../../../assets/project/jobCost.svg";
import jobSue from "../../../../assets/project/jobSue.svg"; import jobSue from "../../../../assets/project/jobSue.svg";
...@@ -77,6 +74,7 @@ const ProjectMembers = observer(() => { ...@@ -77,6 +74,7 @@ const ProjectMembers = observer(() => {
const { currentProjectStore } = useStores(); const { currentProjectStore } = useStores();
const projectId = toJS(currentProjectStore.currentProjectInfo.id); const projectId = toJS(currentProjectStore.currentProjectInfo.id);
const productId = toJS(currentProjectStore.currentProductInfo.id); // 产品ID
const isPass = usePass(); const isPass = usePass();
const [jobName, setJobName] = useState(""); const [jobName, setJobName] = useState("");
const [jobList, setJobList] = useState([]); const [jobList, setJobList] = useState([]);
...@@ -287,11 +285,11 @@ const ProjectMembers = observer(() => { ...@@ -287,11 +285,11 @@ const ProjectMembers = observer(() => {
/** 点击每一行 */ /** 点击每一行 */
const rowClick = useCallback( const rowClick = useCallback(
(id: string) => { (id: string) => {
navigate(`/product/cadd/projectJobDetail`, { navigate(`/product/${productId || "cadd"}/projectJobDetail`, {
state: { taskId: id, from: "workbenchList" }, state: { taskId: id, from: "workbenchList" },
}); });
}, },
[navigate] [navigate, productId]
); );
// 回车搜索 // 回车搜索
...@@ -312,7 +310,8 @@ const ProjectMembers = observer(() => { ...@@ -312,7 +310,8 @@ const ProjectMembers = observer(() => {
<SearchInput <SearchInput
onKeyUp={handleKeyWordChangeKeyUp} onKeyUp={handleKeyWordChangeKeyUp}
onBlur={handleKeyWordChangeBlur} onBlur={handleKeyWordChangeBlur}
sx={{ width: 340 }} /> sx={{ width: 340 }}
/>
{/* <Box className={styles.tabHeaderSelect}> {/* <Box className={styles.tabHeaderSelect}>
<TextField <TextField
select select
......
...@@ -4,11 +4,9 @@ import classNames from "classnames"; ...@@ -4,11 +4,9 @@ import classNames from "classnames";
import { Box, Typography } from "@mui/material"; import { Box, Typography } from "@mui/material";
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 MyButton from "@/components/mui/MyButton";
import OutlinedInput from "@mui/material/OutlinedInput"; import OutlinedInput from "@mui/material/OutlinedInput";
import MySwitch from "@/components/mui/MySwitch"; import MySwitch from "@/components/mui/MySwitch";
import FullScreenDrawer from "@/components/CommonComponents/FullScreenDrawer"; import FullScreenDrawer from "@/components/CommonComponents/FullScreenDrawer";
import Checkbox from "@mui/material/Checkbox";
import useMyRequest from "@/hooks/useMyRequest"; import useMyRequest from "@/hooks/useMyRequest";
import AddIcon from "@mui/icons-material/Add"; import AddIcon from "@mui/icons-material/Add";
import WorkFlowEdit from "@/views/WorkFlowEdit"; 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 { useStores } from "@/store";
import { observer } from "mobx-react-lite";
import { toJS } from "mobx";
import { useNavigate } from "react-router-dom";
const RemindBudgetDialog = observer((props: any) => {
const navigate = useNavigate();
const { rbOpen, rbClose, goToProjectSubmitWork, id, isParentUser, isOwner } =
props;
const { currentProjectStore } = useStores();
const productId = toJS(currentProjectStore.currentProductInfo.id); // 产品ID
const goToprojectSetting = () => {
navigate(`/product/${productId || "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) => { ...@@ -13,6 +13,7 @@ const SimpleDialog = (props: any) => {
onConfirm={onConfirm} onConfirm={onConfirm}
title={title} title={title}
okColor="error" okColor="error"
isText={true}
> >
<Box> <Box>
<Typography sx={{ fontSize: "14px", fontWeight: "400" }}> <Typography sx={{ fontSize: "14px", fontWeight: "400" }}>
......
...@@ -6,28 +6,50 @@ ...@@ -6,28 +6,50 @@
* @FilePath: /bkunyun/src/views/Project/ProjectWorkbench/workbenchTemplate/components/templateBox.tsx * @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 * @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 styles from "../index.module.css";
import { Box, Typography } from "@mui/material"; import { Box, Typography } from "@mui/material";
import MyButton from "@/components/mui/MyButton"; import MyButton from "@/components/mui/MyButton";
import usePass from "@/hooks/usePass"; import usePass from "@/hooks/usePass";
import RemindBudgetDialog from "./RemindBudgetDialog";
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
import { toJS } from "mobx";
import { useStores } from "@/store";
import { observer } from "mobx-react-lite";
const TemplateBox = (props: any) => { const TemplateBox = observer((props: any) => {
const info = props.data; const info = props.data;
const { isParentUser, isOwner, greaterThan100 } = props;
const { currentProjectStore } = useStores();
const productId = toJS(currentProjectStore.currentProductInfo.id); // 产品ID
const isPass = usePass(); const isPass = usePass();
const navigate = useNavigate(); const navigate = useNavigate();
const [rbOpen, setRbOpen] = useState(false);
const [id, setId] = useState("");
const addTemplateBlock = useCallback( const goToProjectSubmitWork = useCallback(
(id: string) => { (id: string) => {
navigate(`/product/cadd/projectSubmitWork`, { navigate(`/product/${productId || "cadd"}/projectSubmitWork`, {
state: { id }, state: { id },
}); });
}, },
[navigate] [navigate, productId]
);
const handleJudgeBudget = useCallback(
(id: string) => {
setId(id);
if (greaterThan100) {
goToProjectSubmitWork(id);
} else {
setRbOpen(true);
}
},
[goToProjectSubmitWork, setRbOpen, setId, greaterThan100]
); );
return ( return (
<>
<Box className={styles.template}> <Box className={styles.template}>
<Box className={styles.templateBlock}> <Box className={styles.templateBlock}>
<Box> <Box>
...@@ -105,14 +127,25 @@ const TemplateBox = (props: any) => { ...@@ -105,14 +127,25 @@ const TemplateBox = (props: any) => {
<MyButton <MyButton
size="medium" size="medium"
text="使用模版" text="使用模版"
onClick={() => addTemplateBlock(info.id)} onClick={() => handleJudgeBudget(info.id)}
style={{ marginLeft: "12px" }} style={{ marginLeft: "12px" }}
/> />
)} )}
</Box> </Box>
</Box> </Box>
</Box> </Box>
{rbOpen && (
<RemindBudgetDialog
rbOpen={rbOpen}
rbClose={() => setRbOpen(false)}
id={id}
goToProjectSubmitWork={goToProjectSubmitWork}
isParentUser={isParentUser}
isOwner={isOwner}
></RemindBudgetDialog>
)}
</>
); );
}; });
export default memo(TemplateBox); export default memo(TemplateBox);
...@@ -10,8 +10,8 @@ import { memo, useEffect, useState } from "react"; ...@@ -10,8 +10,8 @@ import { memo, useEffect, useState } from "react";
import { Box, Typography } from "@mui/material"; import { Box, Typography } from "@mui/material";
import { toJS } from "mobx"; import { toJS } from "mobx";
import { observer } from "mobx-react-lite"; 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 MyButton from "@/components/mui/MyButton";
import SearchInput from "@/components/BusinessComponents/SearchInput"; import SearchInput from "@/components/BusinessComponents/SearchInput";
...@@ -24,11 +24,15 @@ import { ...@@ -24,11 +24,15 @@ import {
getWorkbenchTemplate, getWorkbenchTemplate,
deleteWorkbenchTemplate, deleteWorkbenchTemplate,
} from "@/api/workbench_api"; } from "@/api/workbench_api";
import { getOverviewInfo, getProject } from "@/api/project_api";
import usePass from "@/hooks/usePass"; import usePass from "@/hooks/usePass";
import { useStores } from "@/store"; import { useStores } from "@/store";
import styles from "./index.module.css"; import styles from "./index.module.css";
const userInfo = getLoaclStorageOfKey("userInfo");
const ProjectMembers = observer(() => { const ProjectMembers = observer(() => {
const { currentProjectStore } = useStores(); const { currentProjectStore } = useStores();
const projectIdData = toJS(currentProjectStore.currentProjectInfo.id); const projectIdData = toJS(currentProjectStore.currentProjectInfo.id);
...@@ -109,6 +113,49 @@ const ProjectMembers = observer(() => { ...@@ -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 ( return (
<Box className={styles.headerBox}> <Box className={styles.headerBox}>
<Box className={styles.tabBox}> <Box className={styles.tabBox}>
...@@ -116,7 +163,7 @@ const ProjectMembers = observer(() => { ...@@ -116,7 +163,7 @@ const ProjectMembers = observer(() => {
{isPass("PROJECT_WORKBENCH_FLOES_ADD", "MANAGER") && ( {isPass("PROJECT_WORKBENCH_FLOES_ADD", "MANAGER") && (
<MyButton <MyButton
text={"管理工作流模板"} text={"管理工作流模板"}
startIcon={<FormatListBulletedRoundedIcon fontSize="small"/>} startIcon={<FormatListBulletedRoundedIcon fontSize="small" />}
onClick={addTemplateBlock} onClick={addTemplateBlock}
size={"medium"} size={"medium"}
/> />
...@@ -147,7 +194,14 @@ const ProjectMembers = observer(() => { ...@@ -147,7 +194,14 @@ const ProjectMembers = observer(() => {
templateList.length > 0 && templateList.length > 0 &&
templateList.map((item, key) => { templateList.map((item, key) => {
return ( return (
<TemplateBox key={key} data={item} startDialog={startDialog} /> <TemplateBox
key={key}
data={item}
startDialog={startDialog}
isParentUser={isParentUser}
isOwner={isOwner}
greaterThan100={greaterThan100}
/>
); );
})} })}
</Box> </Box>
......
...@@ -10,6 +10,8 @@ import { useMessage } from "@/components/MySnackbar"; ...@@ -10,6 +10,8 @@ import { useMessage } from "@/components/MySnackbar";
import { getProjectList } from "../../project"; import { getProjectList } from "../../project";
import { useStores } from "@/store"; import { useStores } from "@/store";
import { checkIsNumberLetterChinese } from "@/utils/util"; import { checkIsNumberLetterChinese } from "@/utils/util";
import { observer } from "mobx-react-lite";
import { toJS } from "mobx";
import { import {
setFileServerEndPointLocalStorage, setFileServerEndPointLocalStorage,
getFiletokenAccordingToId, getFiletokenAccordingToId,
...@@ -27,12 +29,13 @@ type IAddProjectProps = { ...@@ -27,12 +29,13 @@ type IAddProjectProps = {
setAddOpen: any; setAddOpen: any;
}; };
const AddProject = (props: IAddProjectProps) => { const AddProject = observer((props: IAddProjectProps) => {
const { addOpen, setAddOpen } = props; const { addOpen, setAddOpen } = props;
const { currentProjectStore } = useStores(); const { currentProjectStore } = useStores();
const navigate = useNavigate(); const navigate = useNavigate();
const message = useMessage(); const message = useMessage();
const [name, setName] = useState(""); const [name, setName] = useState("");
const productId = toJS(currentProjectStore.currentProductInfo.id); // 产品ID
const [nameCheck, setNameCheck] = useState({ const [nameCheck, setNameCheck] = useState({
error: false, error: false,
help: "", help: "",
...@@ -62,7 +65,7 @@ const AddProject = (props: IAddProjectProps) => { ...@@ -62,7 +65,7 @@ const AddProject = (props: IAddProjectProps) => {
setAddOpen(false); setAddOpen(false);
setLoading(false); setLoading(false);
message.success("新建项目成功"); message.success("新建项目成功");
const projectList = await getProjectList(); const projectList = await getProjectList(productId);
currentProjectStore.setProjectList(projectList); currentProjectStore.setProjectList(projectList);
let project: any = {}; let project: any = {};
projectList.forEach((item: any) => { projectList.forEach((item: any) => {
...@@ -75,7 +78,7 @@ const AddProject = (props: IAddProjectProps) => { ...@@ -75,7 +78,7 @@ const AddProject = (props: IAddProjectProps) => {
project.filetoken = res; project.filetoken = res;
currentProjectStore.changeProject(project); currentProjectStore.changeProject(project);
}); });
navigate(`/product/cadd/projectOverview`); navigate(`/product/${productId || "cadd"}/projectOverview`);
} }
}, },
onError: () => { onError: () => {
...@@ -157,7 +160,7 @@ const AddProject = (props: IAddProjectProps) => { ...@@ -157,7 +160,7 @@ const AddProject = (props: IAddProjectProps) => {
name, name,
desc, desc,
zoneId, zoneId,
product: "cadd", product: productId || "cadd",
}); });
} else { } else {
return; return;
...@@ -232,6 +235,6 @@ const AddProject = (props: IAddProjectProps) => { ...@@ -232,6 +235,6 @@ const AddProject = (props: IAddProjectProps) => {
</div> </div>
</MyDialog> </MyDialog>
); );
}; });
export default AddProject; export default AddProject;
...@@ -12,8 +12,8 @@ import { ...@@ -12,8 +12,8 @@ import {
getDataFileToken, getDataFileToken,
} from "@/api/project_api"; } from "@/api/project_api";
export const getProjectList = async () => { export const getProjectList = async (id = 'cadd') => {
const res = await getProjectListApi({ product: "cadd" }); const res = await getProjectListApi({ product: id });
return res.data; return res.data;
}; };
......
...@@ -64,7 +64,7 @@ const SaveCustomTemplate = (props: IProps) => { ...@@ -64,7 +64,7 @@ const SaveCustomTemplate = (props: IProps) => {
}); });
// 自定义模板保存方法 // 自定义模板保存方法
const { run: saveUserSpecRun } = useMyRequest(saveUserSpec, { const { run: saveUserSpecRun, loading } = useMyRequest(saveUserSpec, {
onSuccess: (res) => { onSuccess: (res) => {
Message.success("保存成功!"); Message.success("保存成功!");
onBack && onBack(); onBack && onBack();
...@@ -220,6 +220,7 @@ const SaveCustomTemplate = (props: IProps) => { ...@@ -220,6 +220,7 @@ const SaveCustomTemplate = (props: IProps) => {
title="保存自定义模板" title="保存自定义模板"
onClose={handleCloseDialog} onClose={handleCloseDialog}
onConfirm={handleOncofirm} onConfirm={handleOncofirm}
loading={loading}
> >
<div className={styles.saveBox}> <div className={styles.saveBox}>
<MyInput <MyInput
......
...@@ -117,27 +117,26 @@ const MyTableDemo = () => { ...@@ -117,27 +117,26 @@ const MyTableDemo = () => {
{ {
id: "a", id: "a",
label: "属性a", label: "属性a",
width: "150", width: 150,
}, },
{ {
id: "b", id: "b",
label: "属性b", label: "属性b",
width: "250", width: 150,
}, },
{ {
id: "c", id: "c",
label: "属性c", label: "属性c",
width: "350", width: 150,
}, },
{ {
id: "d", id: "d",
label: "属性d", label: "属性d",
width: "250",
}, },
{ {
id: "caozuo", id: "caozuo",
label: "操作", label: "操作",
width: "250", width: 150,
}, },
]; ];
...@@ -145,13 +144,13 @@ const MyTableDemo = () => { ...@@ -145,13 +144,13 @@ const MyTableDemo = () => {
{ {
id: "a", id: "a",
label: "属性a", label: "属性a",
width: "200", width: 200,
showOverflowTooltip: true, showOverflowTooltip: true,
}, },
{ {
id: "b", id: "b",
label: "属性b", label: "属性b",
width: "200", width: 200,
}, },
{ {
id: "c", id: "c",
...@@ -161,7 +160,7 @@ const MyTableDemo = () => { ...@@ -161,7 +160,7 @@ const MyTableDemo = () => {
{ {
id: "d", id: "d",
label: "属性d", label: "属性d",
width: "200", width: 200,
}, },
]; ];
...@@ -169,24 +168,23 @@ const MyTableDemo = () => { ...@@ -169,24 +168,23 @@ const MyTableDemo = () => {
{ {
id: "a", id: "a",
label: "属性a", label: "属性a",
width: "25%", width: 200,
sort: true, sort: true,
}, },
{ {
id: "b", id: "b",
label: "属性b", label: "属性b",
width: "25%", width: 200,
sort: true, sort: true,
}, },
{ {
id: "c", id: "c",
label: "属性c", label: "属性c",
width: "25%", width: 200,
}, },
{ {
id: "d", id: "d",
label: "属性d", label: "属性d",
width: "25%",
}, },
]; ];
......
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