Commit 67f85965 authored by 吴永生#A02208's avatar 吴永生#A02208

feat: 项目成员开发

parent 0a8bc331
This diff is collapsed.
......@@ -46,6 +46,7 @@
"jest": "^27.4.3",
"jest-resolve": "^27.4.2",
"jest-watch-typeahead": "^1.0.0",
"lodash": "^4.17.21",
"mini-css-extract-plugin": "^2.4.5",
"mobx": "^6.5.0",
"mobx-react": "^7.4.0",
......
import axios, { AxiosInstance, AxiosResponse, AxiosRequestConfig } from 'axios';
import React, { useContext } from 'react';
import _ from 'lodash';
import localStorageKey from '@/utils/localStorageKey';
import { BACKEND_API_URI_PREFIX } from './api_prefix';
export interface IAxiosRequestConfig extends AxiosRequestConfig {
/** 取消全局错误提示 */
noToastWarn?: boolean;
/** 允许截流 */
allowIntercept?: boolean;
}
export type HttpConfig = IAxiosRequestConfig;
export interface IRequest {
method: <T>(config: AxiosRequestConfig) => Promise<T>;
config: IAxiosRequestConfig;
}
export class Http {
instance: AxiosInstance;
/** 请求方法集合
* key-唯一标识
*/
requestList: {
[key: string]: IRequest[];
} = {};
/** 请求锁 */
isRequesting: { [key: string]: boolean } = {};
constructor(defaultConfig: IAxiosRequestConfig = {}) {
this.instance = axios.create(defaultConfig);
}
/** 更新回调函数数组 */
setRequestList = (key: string, params: IRequest) => {
this.requestList = {
[key]: this.requestList[key] ? [...this.requestList[key], params] : [params],
};
};
/** 处理成功请求
* first-首次请求 last-最后一次请求 key-请求路径
*/
handleSuccess = ({ key, resolve, res: firstRes }: { key: string; resolve: any; res: any }) => {
this.isRequesting[key] = false;
const requestLen = this.requestList[key]?.length || 0;
if (requestLen >= 2) {
const first = this.requestList[key][0];
const last = this.requestList[key][requestLen - 1];
if (!_.isEqual(first.config, last.config)) {
// @ts-ignore
last.method<T>(last.config).then((lastRes: AxiosResponse<any>) => {
resolve(lastRes?.data);
});
} else {
resolve(firstRes.data);
}
} else {
resolve(firstRes.data);
}
this.requestList[key] = [];
};
/** 请求截流
* 当多次发起请求并且第一次请求未结束时,若参数完全一致只允许首次请求,不一致在首次结束后,进行最后一次
*/
requestInterception<T>(config: IAxiosRequestConfig): Promise<T> {
const requestMethod = this.instance.request;
const key: string = config.url || '';
return new Promise((resolve, reject) => {
if (this.isRequesting[key]) {
this.setRequestList(key, { method: requestMethod, config });
} else {
this.isRequesting[key] = true;
this.setRequestList(key, { method: requestMethod, config });
requestMethod<T>(config)
.then((res: AxiosResponse<any>) => {
/** 可以接入日志监控 */
// const { code, msg = '' } = res.data;
// if (code !== 200 && code !== 0) {
// this.handleSentry({
// ...sentryParams,
// msg,
// code,
// });
// }
this.handleSuccess({
res,
key,
resolve,
});
})
.catch((e) => {
/** 可以接入日志监控 */
// this.handleSentry({
// ...sentryParams,
// msg: e.error || '',
// code: e.code || '',
// });
reject(e);
});
}
});
}
request<T>(config: IAxiosRequestConfig) {
const requestMethod = this.instance.request<T>(config);
return requestMethod.then((res) => res.data);
}
getConfig(config?: IAxiosRequestConfig) {
let Authorization: string =
`Bearer ` +
JSON.parse(localStorage.getItem(localStorageKey.TOKEN) || "{}")
?.access_token || "";
return {
headers:{'Content-Type': "application/x-www-form-urlencoded",Authorization, ...config?.headers, },...config
}
}
get<T>(url: string, config?: IAxiosRequestConfig) {
if (config?.allowIntercept) {
return this.requestInterception<T>({ url: `${BACKEND_API_URI_PREFIX}${url}`, method: 'GET', ...this.getConfig(config) });
}
return this.request<T>({ url: `${BACKEND_API_URI_PREFIX}${url}`, method: 'GET', ...this.getConfig(config) });
}
patch<T>(url: string, data?: any, config?: IAxiosRequestConfig) {
return this.request<T>({ method: 'PATCH', url: `${BACKEND_API_URI_PREFIX}${url}`, data, ...this.getConfig(config) });
}
put<T>(url: string, data?: any, config?: IAxiosRequestConfig) {
return this.request<T>({ method: 'PUT', url: `${BACKEND_API_URI_PREFIX}${url}`, data, ...this.getConfig(config) });
}
post<T>(url: string, data?: any, config?: IAxiosRequestConfig) {
if (config?.allowIntercept) {
return this.requestInterception<T>({ method: 'POST', url: `${BACKEND_API_URI_PREFIX}${url}`, data, ...this.getConfig(config) });
}
return this.request<T>({ method: 'POST', url: `${BACKEND_API_URI_PREFIX}${url}`, data, ...this.getConfig(config) });
}
del<T>(url: string, config?: IAxiosRequestConfig) {
return this.request<T>({ method: 'DELETE', url: `${BACKEND_API_URI_PREFIX}${url}`, ...this.getConfig(config) });
}
}
const rawHttp = new Http();
const HttpContext = React.createContext<Http>(rawHttp);
export const HttpProvider = HttpContext.Provider;
export function useHttp(raw?: boolean) {
const httpClient = useContext(HttpContext);
return raw ? rawHttp : httpClient;
}
export default rawHttp;
/*
* @Author: 吴永生#A02208 yongsheng.wu@wholion.com
* @Date: 2022-06-01 16:53:15
* @LastEditors: 吴永生#A02208 yongsheng.wu@wholion.com
* @LastEditTime: 2022-06-04 15:00:09
* @FilePath: /bkunyun/src/components/Material.Ui/Button.jsx
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
import React from "react";
import PropTypes from "prop-types";
import makeStyles from "@material-ui/styles/makeStyles";
import { Typography, Button, Menu, MenuItem } from "@material-ui/core";
import ExpandMoreIcon from '@material-ui/icons/ExpandMore';
import { makeStyles } from "@mui/styles";
import { Typography, Button, Menu, MenuItem } from "@mui/material";
const useStyles = makeStyles({
root: { backgroundColor: "#136EFA", boxShadow: "none !important", color: "#ffffff", "&:hover": { backgroundColor: "#0055D9" } },
containedSecondary: { backgroundColor: "#D62C1F", boxShadow: "none !important", "&:hover": { backgroundColor: "#D82C1F" } },
......@@ -58,7 +65,6 @@ const ButtonComponent = (props) => {
>
{img || ''}
<Typography style={{ fontSize: fontSize }}>{text || ""}</Typography>
{select && <ExpandMoreIcon fontSize={"small"} />}
</Button>
<Menu
id="simple-menu"
......@@ -91,5 +97,7 @@ ButtonComponent.propTypes = {
disabled: PropTypes.bool,
disableElevation: PropTypes.bool,
disableFocusRipple: PropTypes.bool,
text: PropTypes.string,
onClick: propTypes.func.isRequired,
};
export default ButtonComponent;
\ No newline at end of file
import React from "react";
import TextField from '@material-ui/core/TextField';
import MenuItem from '@material-ui/core/MenuItem';
import { makeStyles } from '@material-ui/core/styles';
import TextField from '@mui/material/TextField';
import MenuItem from '@mui/material/MenuItem';
import { makeStyles } from "@mui/styles";
import cx from "classnames"
const useStyles = makeStyles({
MuiOutlinedInputInputLarge: { padding: "13.5px 15px", MozAppearance: 'textfield' },
MuiOutlinedInputInput: { padding: "12px 15px", "&::placeholder": { fontSize: "14px" }, MozAppearance: 'textfield' },
MuiOutlinedInputInput: { padding: "6px 15px", "&::placeholder": { fontSize: "14px" }, MozAppearance: 'textfield' },
MuiOutlinedInputInputSmall: { padding: "10px 15px", "&::placeholder": { fontSize: "13px" }, MozAppearance: 'textfield' },
MuiOutlinedInputInputXsmall: { padding: "8px 15px", "&::placeholder": { fontSize: "12px" }, MozAppearance: 'textfield' },
outlinedLarge: { transform: "translate(14px, 15.5px) scale(1)", fontSize: '14px', fontWeight: '400', color: '#707070' },
......@@ -103,9 +103,11 @@ export default props => {
classes: {
root: classes.root,
input: cx({
width: '320px',
height: '32px',
[classes[resizeBys("MuiOutlinedInputInput")]]: true,
[classes[`SelectProps${textAlign}`]]: textAlign,
[customClass]: customClass
[customClass]: customClass,
}),
notchedOutline: classes.notchedOutline,
error: classes.error,
......
import React, { useState, useEffect } from "react";
import Selectzone from './Selectzone.jsx'
import { Grid, Typography, List, ListItem, ListItemText } from '@material-ui/core';
import { makeStyles } from '@material-ui/core/styles';
import ArrowDropDownIcon from '@material-ui/icons/ArrowDropDown';
import { CLOUDE } from "@/commons/utils/constants"
import { Grid, Typography, List, ListItem, ListItemText } from '@mui/material';
import { makeStyles } from "@mui/styles";
import ArrowDropDownIcon from '@mui/icons-material/ArrowDropDown';
import cx from "classnames"
const useStyles = makeStyles({
wrapHeightLarge: { height: "44px" },
......@@ -52,7 +51,7 @@ export default props => {
const classes = useStyles();
const { value, size, option, callback, noBorder, rootStyle, customSvg, textStyle, sz, startIcon, DropdownboxStyle, DropdownboxitemStyle } = props;
const [open, setOpen] = useState(false)
const [values, setValue] = useState(value || CLOUDE.Options)
const [values, setValue] = useState(value || '请选择')
const handleClick = (event) => {
event.stopPropagation()
setOpen((open) => !open)
......@@ -123,7 +122,7 @@ export default props => {
style={{ ...rootStyle }}
>
{startIcon && startIcon}
<Typography className={classes.text} style={{ ...textStyle }}>{values || CLOUDE.Options}</Typography>
<Typography className={classes.text} style={{ ...textStyle }}>{values || '请选择'}</Typography>
{
customSvg ? (
(
......
/*
* @Author: 吴永生#A02208 yongsheng.wu@wholion.com
* @Date: 2022-06-01 16:53:15
* @LastEditors: 吴永生#A02208 yongsheng.wu@wholion.com
* @LastEditTime: 2022-06-05 16:39:01
* @FilePath: /bkunyun/src/components/Material.Ui/Selectzone.jsx
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
import React, { useState, useEffect } from "react";
import { makeStyles } from '@material-ui/core/styles';
import { makeStyles } from '@mui/styles';
import {
Grid,
ListItemText,
Tooltip,
} from "@material-ui/core";
import icon from '../../../console/cloudelastic/assets/img/templates/icon_about_grey.png'
} from "@mui/material";
import icon from "@/assets/img/icon_about_grey.png";
const useStyles = makeStyles({
popper:{fontSize:'12px'}
})
......
import React from "react";
import Table from "@material-ui/core/Table";
import TableBody from "@material-ui/core/TableBody";
import TableCell from "@material-ui/core/TableCell";
import TableContainer from "@material-ui/core/TableContainer";
import TablePagination from "@material-ui/core/TablePagination";
import TableRow from "@material-ui/core/TableRow";
import Paper from "@material-ui/core/Paper";
import Checkbox from "@material-ui/core/Checkbox";
import Spin from "@/commons/components/Material.Ui/Spin";
import Table from "@mui/material/Table";
import TableBody from "@mui/material/TableBody";
import TableCell from "@mui/material/TableCell";
import TableContainer from "@mui/material/TableContainer";
import TablePagination from "@mui/material/TablePagination";
import TableRow from "@mui/material/TableRow";
import Paper from "@mui/material/Paper";
import Checkbox from "@mui/material/Checkbox";
// import Spin from "./Spin";
import EnhancedTableToolbarComponent from "./Table/EnhancedTableToolbar"
import EnhancedTableHeadComponent from "./Table/EnhancedTableHead"
......@@ -17,14 +17,15 @@ import ActionsComponent from "./Table/ActionsComponent"
import { useEffect } from "react";
export default function EnhancedTable(props) {
const classes = useStyles();
const classes = useStyles;
console.log(classes,11111);
const [order, setOrder] = React.useState("asc");
const [orderBy, setOrderBy] = React.useState("");
const { headCells, rows, footer = true, elevation1, tableStyle,tablecellstyle, tableContainerStyle, stickyheader, TableHeadClasses, onRowClick, defaultRow, minHeight='', borderBottom='', onDoubleClick,
load, size, checkboxData, rowsPerPage = 10, initSelected, page = 0, changePage = function () { }, toolbar, count, param, disabledparam = "id", headTableCellCheckbox ,RowHeight='',CellWidth='',rowHover, TableNodataPadding = '',TableNodataLineHeight=''} = props;
const [selected, setSelected] = React.useState(initSelected || []);
const [rowsPerPageOptions, setRowsPerPageOptions] = React.useState(initSelected || [5, 10, 20, 50, { value: -1, label: 'All' }]);
const [spin, setSpin] = React.useState(false)
// const [spin, setSpin] = React.useState(false)
const [onRow, setOnRow] = React.useState('')
useEffect(() => {
......@@ -52,10 +53,10 @@ export default function EnhancedTable(props) {
setSelected([]);
checkboxData([]);
};
React.useEffect(() => {
// React.useEffect(() => {
setSpin(load)
}, [load]);
// setSpin(load)
// }, [load]);
const handleClick = (event, name) => {
const selectedIndex = selected.indexOf(name);
let newSelected = [];
......@@ -91,7 +92,7 @@ export default function EnhancedTable(props) {
return (
<div className={classes.root}>
<Paper className={classes.paper} classes={{ elevation1: elevation1 || classes.elevation1 }} >
<Spin spin={spin} />
{/* <Spin spin={spin} /> */}
{toolbar && toolbar}
<TableContainer style={{ ...tableContainerStyle }}>
<Table stickyHeader={stickyheader || false} className={classes.table} style={{ ...tableStyle }} aria-labelledby="tableTitle" size={size || "medium"} aria-label="cloudam table header" >
......@@ -111,7 +112,7 @@ export default function EnhancedTable(props) {
{
(rows.length === 0 && !load) && <TableRow>
<TableCell
colSpan={headCells.filter(k => k.id === "checkbox").length === 0 ? headCells.length : headCells.length + 1}
colSpan={headCells?.filter(k => k.id === "checkbox")?.length === 0 ? headCells?.length : headCells?.length + 1}
className={classes.TypographyStyle}
style={{ minHeight: minHeight, height: minHeight, borderBottom: borderBottom ,padding:TableNodataPadding,lineHeight:TableNodataLineHeight}}
>
......@@ -138,7 +139,6 @@ export default function EnhancedTable(props) {
border: onRow === row[param || "id"] ? !row[disabledparam] ? "" : '1px solid #136EFA' : "",
backgroundColor: onRow === row[param || "id"] ? !row[disabledparam] ? "rgba(255, 255, 255, 0.4)" : "rgba(19, 110, 250, 0.1)" : "",
cursor: props.cursor ? (row[props.cursor] ? "pointer" : "auto") : (onRowClick ? !row[disabledparam] ? "no-drop" : "pointer" : "auto"),
opacity: !row[disabledparam] ? 0.3 : 1
}}
role="checkbox"
aria-checked={isItemSelected}
......@@ -162,7 +162,11 @@ export default function EnhancedTable(props) {
classes={{
body: props.bodyTableCell || classes.bodyTableCell
}}
> {row[item.id]} </TableCell>
> {
item.render ? <>{item.render(row,index)}</> :
row[item.id]
}
</TableCell>
)
})
}
......
/*
* @Author: 吴永生#A02208 yongsheng.wu@wholion.com
* @Date: 2022-06-01 16:53:15
* @LastEditors: 吴永生#A02208 yongsheng.wu@wholion.com
* @LastEditTime: 2022-06-02 10:16:28
* @FilePath: /bkunyun/src/components/Material.Ui/Table/ActionsComponent.jsx
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
import React from 'react';
import PropTypes from 'prop-types';
import Button from "@material-ui/core/Button";
import IconButton from '@material-ui/core/IconButton';
import FirstPageIcon from '@material-ui/icons/FirstPage';
import KeyboardArrowLeft from '@material-ui/icons/KeyboardArrowLeft';
import KeyboardArrowRight from '@material-ui/icons/KeyboardArrowRight';
import LastPageIcon from '@material-ui/icons/LastPage';
import makeStyles from "@material-ui/styles/makeStyles";
import Button from "@mui/material/Button";
import IconButton from '@mui/material/IconButton';
import FirstPageIcon from '@mui/icons-material/FirstPage';
import KeyboardArrowLeft from '@mui/icons-material/KeyboardArrowLeft';
import KeyboardArrowRight from '@mui/icons-material/KeyboardArrowRight';
import LastPageIcon from '@mui/icons-material/LastPage';
import { makeStyles } from "@mui/styles";
const useStyles = makeStyles({
firstPageIconStyle: { width: '28px', height: '28px', padding: 0, backgroundColor: '#FFFFFF', borderRadius: '2px', border: '1px solid #D8D8D8', margin: "0 6px" },
KeyboardArrowLeftStyle:{ width: '28px', height: '28px', padding: 0, backgroundColor: '#FFFFFF', borderRadius: '2px', border: '1px solid #D8D8D8', marginRight: "3px" },
......
/*
* @Author: 吴永生#A02208 yongsheng.wu@wholion.com
* @Date: 2022-06-01 16:53:15
* @LastEditors: 吴永生#A02208 yongsheng.wu@wholion.com
* @LastEditTime: 2022-06-02 10:19:08
* @FilePath: /bkunyun/src/components/Material.Ui/Table/EnhancedTableHead.jsx
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
import React from "react";
import TableHead from "@material-ui/core/TableHead";
import TableSortLabel from "@material-ui/core/TableSortLabel";
import TableHead from "@mui/material/TableHead";
import TableSortLabel from "@mui/material/TableSortLabel";
import PropTypes from "prop-types";
import TableRow from "@material-ui/core/TableRow";
import TableCell from "@material-ui/core/TableCell";
import Checkbox from "@material-ui/core/Checkbox";
import { Typography } from "@material-ui/core";
import Tooltip from '@material-ui/core/Tooltip';
import ErrorOutlineIcon from '@material-ui/icons/ErrorOutline';
import TableRow from "@mui/material/TableRow";
import TableCell from "@mui/material/TableCell";
import Checkbox from "@mui/material/Checkbox";
import Typography from "@mui/material/Typography";
import Tooltip from '@mui/material/Tooltip';
import ErrorOutlineIcon from '@mui/icons-material/ErrorOutline';
const EnhancedTableHead = (props) => {
const { classes, onSelectAllClick, order, orderBy, TableHeadClasses, numSelected, rowCount, onRequestSort, headCells, headTableCell, headTableCellCheckbox,RowStyle } = props;
......
/*
* @Author: 吴永生#A02208 yongsheng.wu@wholion.com
* @Date: 2022-06-01 16:53:15
* @LastEditors: 吴永生#A02208 yongsheng.wu@wholion.com
* @LastEditTime: 2022-06-02 10:18:54
* @FilePath: /bkunyun/src/components/Material.Ui/Table/EnhancedTableToolbar.jsx
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
import React from "react";
import { useToolbarStyles } from "./function";
import Toolbar from "@material-ui/core/Toolbar";
import Typography from "@material-ui/core/Typography";
import Toolbar from "@mui/material/Toolbar";
import Typography from "@mui/material/Typography";
import PropTypes from "prop-types";
import clsx from "clsx";
import IconButton from "@material-ui/core/IconButton";
import Tooltip from "@material-ui/core/Tooltip";
import DeleteIcon from "@material-ui/icons/Delete";
import FilterListIcon from "@material-ui/icons/FilterList";
import IconButton from "@mui/material/IconButton";
import Tooltip from "@mui/material/Tooltip";
import DeleteIcon from "@mui/icons-material/Delete";
import FilterListIcon from "@mui/icons-material/FilterList";
const EnhancedTableToolbar = (props) => {
const classes = useToolbarStyles();
const { numSelected } = props;
......
import { lighten, makeStyles } from "@material-ui/core/styles";
import { makeStyles } from "@mui/styles";
/*
*@分割线=======================================================================================================================================
......@@ -7,12 +7,10 @@ import { lighten, makeStyles } from "@material-ui/core/styles";
*@param: {} []
*@MethodAuthor: dawei.liu
*@Date: 2021-07-22 14:42:51
*/
*/
export function descendingComparator(a, b, orderBy) {
if (b[orderBy] < a[orderBy])
return -1;
if (b[orderBy] > a[orderBy])
return 1;
if (b[orderBy] < a[orderBy]) return -1;
if (b[orderBy] > a[orderBy]) return 1;
return 0;
}
/*
......@@ -22,7 +20,7 @@ export function descendingComparator(a, b, orderBy) {
*@param: {} []
*@MethodAuthor: dawei.liu
*@Date: 2021-07-22 14:42:36
*/
*/
export function getComparator(order, orderBy) {
return order === "desc"
? (a, b) => descendingComparator(a, b, orderBy)
......@@ -35,7 +33,7 @@ export function getComparator(order, orderBy) {
*@param: {} []
*@MethodAuthor: dawei.liu
*@Date: 2021-07-22 14:42:24
*/
*/
export function stableSort(array, comparator) {
const stabilizedThis = array.map((el, index) => [el, index]);
stabilizedThis.sort((a, b) => {
......@@ -52,7 +50,7 @@ export function stableSort(array, comparator) {
*@param: {} []
*@MethodAuthor: dawei.liu
*@Date: 2021-07-22 14:41:53
*/
*/
export const useToolbarStyles = makeStyles((theme) => ({
root: {
paddingLeft: theme.spacing(2),
......@@ -62,7 +60,7 @@ export const useToolbarStyles = makeStyles((theme) => ({
theme.palette.type === "light"
? {
color: theme.palette.primary.main,
backgroundColor: lighten(theme.palette.primary.light, 0.85),
backgroundColor: "red",
}
: {
color: theme.palette.text.primary,
......@@ -77,22 +75,73 @@ export const useToolbarStyles = makeStyles((theme) => ({
*@param: {theme} [theme]
*@MethodAuthor: dawei.liu
*@Date: 2021-07-22 14:40:37
*/
*/
export const useStyles = makeStyles((theme) => ({
root: { width: "100%", position: "relative" },
paper: { width: "100%", marginBottom: theme.spacing(2) },
paper: { width: "100%", marginBottom: 8 },
elevation1: { boxShadow: "none", padding: "20px" },
elevationNoPadding: { boxShadow: "none", padding: "0" },
table: { minWidth: 500 },
visuallyHidden: { border: 0, clip: "rect(0 0 0 0)", height: 1, margin: -1, overflow: "hidden", padding: 0, position: "absolute", top: 20, width: 1 },
LinearProgressStyle: { position: "absolute", left: 0, top: "0", width: "100%" },
TypographyStyle: { height: "300px", width: "100%", justifyContent: "center", alignItems: "center", color: "#666", fontSize: "16px", textAlign: "center" },
bodyTableCell: { color: "#222222", fontSize: "12px", borderBottom: "1px solid rgba(34, 34, 34, 0.08)", padding: "10px", paddingLeft: "16px" },
headTableCell: { color: "rgba(34, 34, 34, 0.65)", fontSize: "12px", padding: "16px" },
rootTableContainer: { position: "relative", overflowX: "auto", maxHeight: "700px" },
visuallyHidden: {
border: 0,
clip: "rect(0 0 0 0)",
height: 1,
margin: -1,
overflow: "hidden",
padding: 0,
position: "absolute",
top: 20,
width: 1,
},
LinearProgressStyle: {
position: "absolute",
left: 0,
top: "0",
width: "100%",
},
TypographyStyle: {
height: "300px",
width: "100%",
justifyContent: "center",
alignItems: "center",
color: "#666",
fontSize: "16px",
textAlign: "center",
},
bodyTableCell: {
color: "#222222",
fontSize: "12px",
borderBottom: "1px solid rgba(34, 34, 34, 0.08)",
padding: "10px",
paddingLeft: "16px",
},
headTableCell: {
color: "rgba(34, 34, 34, 0.65)",
fontSize: "12px",
padding: "16px",
},
rootTableContainer: {
position: "relative",
overflowX: "auto",
maxHeight: "700px",
},
TableHeadClasses: { backgroundColor: "rgba(34, 34, 34, 0.03)" },
bodyTableCellRoot: { borderBottom: "1px solid rgba(34, 34, 34, 0.08)", },
TypographyboderStyle: { height: "300px", width: "100%", justifyContent: "center", alignItems: "center", color: "#666", fontSize: "16px", textAlign: "center", borderBottom: "none" },
rootTableboderContainer: { position: "relative", overflowX: "auto", maxHeight: "700px", border: "1px solid rgb(216, 216, 216)" },
cancelHoverStyle:{"&:hover": { background: 'none !important' },}
bodyTableCellRoot: { borderBottom: "1px solid rgba(34, 34, 34, 0.08)" },
TypographyboderStyle: {
height: "300px",
width: "100%",
justifyContent: "center",
alignItems: "center",
color: "#666",
fontSize: "16px",
textAlign: "center",
borderBottom: "none",
},
rootTableboderContainer: {
position: "relative",
overflowX: "auto",
maxHeight: "700px",
border: "1px solid rgb(216, 216, 216)",
},
cancelHoverStyle: { "&:hover": { background: "none !important" } },
}));
import React from "react";
import {
Button,
Dialog,
DialogActions,
DialogContent,
DialogTitle,
} from "@mui/material";
import CloseIcon from "@mui/icons-material/Close";
export interface IDialogProps {
/** 自定义类名 */
className?: string;
/** 自定义样式 */
style?: React.CSSProperties;
/** 弹窗的标题 */
title?: string;
/** 是否显示弹窗 */
open: boolean;
isHideHeader?: boolean;
/** 是否隐藏弹窗底部按钮部分 */
isHideFooter?: boolean;
/** 自定义底部按钮 */
footerRender?: () => React.ReactNode;
/** 是否显示取消按钮 */
showCancel?: boolean;
/** 是否显示确定按钮 */
showConfirm?: boolean;
/** 关闭弹窗时的回调函数 */
onClose?: () => void;
/** 点击确定按钮时的回调函数 */
onConfirm?: () => void;
/** 取消按钮文案 */
cancelText?: string;
/** 确认按钮文案 */
okText?: string;
/** 是否禁用确认按钮 */
disabledConfirm?: boolean;
children: React.ReactNode;
}
export interface IFooter {
isHideFooter?: boolean;
footerRender?: () => React.ReactNode;
showCancel?: boolean;
/** 是否显示确定按钮 */
showConfirm?: boolean;
/** 关闭弹窗时的回调函数 */
onClose?: () => void;
/** 点击确定按钮时的回调函数 */
onConfirm?: () => void;
/** 取消按钮文案 */
cancelText?: string;
/** 确认按钮文案 */
okText?: string;
/** 是否禁用确认按钮 */
disabledConfirm?: boolean;
}
const MyDialog: React.FunctionComponent<IDialogProps> = (props) => {
const {
title,
open,
style,
onClose,
onConfirm,
isHideFooter,
isHideHeader,
children,
footerRender,
className,
showCancel = true,
/** 是否显示确定按钮 */
showConfirm = true,
cancelText,
okText,
disabledConfirm,
} = props;
const Footer = () => {
if (isHideFooter) return null;
return footerRender ? (
footerRender()
) : (
<DialogActions style={{ padding: "0 24px 24px 24px" }}>
{showCancel ? (
<Button onClick={onClose} variant="outlined" size="small">
{cancelText || "取消"}
</Button>
) : null}
{showConfirm ? (
<Button
onClick={onConfirm}
variant="contained"
size="small"
disabled={disabledConfirm}
>
{okText || "确定"}
</Button>
) : null}
</DialogActions>
);
};
return (
<Dialog
open={open}
onClose={onClose}
style={style}
className={className}
aria-labelledby="alert-dialog-title"
aria-describedby="alert-dialog-description"
>
{isHideHeader ? null : (
<DialogTitle id="alert-dialog-title">
<div
style={{
display: "flex",
justifyContent: "space-between",
alignItems: "center",
}}
>
<span>{title}</span>
<CloseIcon
onClick={onClose}
style={{ color: "#C2C6CC", cursor: "pointer" }}
/>
</div>
</DialogTitle>
)}
<DialogContent style={{ minWidth: 400 }}>{children}</DialogContent>
{Footer()}
</Dialog>
);
};
export default MyDialog;
/*
* @Author: 吴永生#A02208 yongsheng.wu@wholion.com
* @Date: 2021-12-04 15:46:25
* @LastEditors: 吴永生#A02208 yongsheng.wu@wholion.com
* @LastEditTime: 2022-06-05 18:06:47
* @FilePath: /lionet-slb-pc/src/components/SearchView/components/Collapse.tsx
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
import * as React from "react";
import Box from "@mui/material/Box";
import InputLabel from "@mui/material/InputLabel";
import MenuItem from "@mui/material/MenuItem";
import FormControl from "@mui/material/FormControl";
import Select, { SelectChangeEvent } from "@mui/material/Select";
interface IOption {
label: string;
value: string;
disabled?: boolean;
}
interface IProps {
value?: IOption;
options: IOption[];
onChange?: (val: IOption) => void;
title?: string;
}
export default function BasicSelect(props: IProps) {
const { value, options, onChange, title } = props;
const handleChange = (event: SelectChangeEvent) => {
const newValue = options?.filter((item) => {
return item.value === event.target.value;
});
if (onChange) {
onChange(newValue[0] || { label: "", value: "" });
}
};
return (
<Box sx={{ minWidth: 120 }}>
<FormControl fullWidth>
<InputLabel id="demo-simple-select-label">
{title || "请选择"}
</InputLabel>
<Select
labelId="demo-simple-select-label"
id="demo-simple-select"
value={value?.value}
label={title || "请选择"}
onChange={handleChange}
>
{options.length
? options?.map((item: IOption) => {
return (
<MenuItem value={item.value} disabled={item?.disabled}>
{item.label}
</MenuItem>
);
})
: null}
</Select>
</FormControl>
</Box>
);
}
/*
* @Author: 吴永生#A02208 yongsheng.wu@wholion.com
* @Date: 2022-06-02 10:38:01
* @LastEditors: 吴永生#A02208 yongsheng.wu@wholion.com
* @LastEditTime: 2022-06-02 13:45:33
* @FilePath: /bkunyun/src/components/mui/Table.tsx
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
import * as React from "react";
import MuiTable from "@mui/material/Table";
import TableBody from "@mui/material/TableBody";
import TableCell from "@mui/material/TableCell";
import TableContainer from "@mui/material/TableContainer";
import TableHead from "@mui/material/TableHead";
import TableRow from "@mui/material/TableRow";
import Paper from "@mui/material/Paper";
import { Box } from "@mui/material";
interface IColumns {
key: string;
title: string;
align?: "left" | "center" | "right";
render?: (value: any, index: number) => void;
}
interface IProps {
columns: IColumns[];
dataSource: any;
}
export default function Table(props: IProps) {
const { columns = [], dataSource = [] } = props;
return (
<TableContainer component={Paper}>
<MuiTable sx={{ minWidth: 650 }} aria-label="simple table">
<TableHead>
<TableRow>
{columns?.map((item: IColumns) => {
return (
<TableCell {...item} key={item.key}>
{item.title}
</TableCell>
);
})}
</TableRow>
</TableHead>
<TableBody>
{dataSource.length ? (
dataSource?.map(() => (
<TableRow
key={Math.random()}
sx={{ "&:last-child td, &:last-child th": { border: 0 } }}
>
{columns?.map((item: IColumns, index: number) => {
if (item.render) {
return <>{item.render(item, index)}</>;
} else {
return (
<TableCell align="right" key={item.key}>
{item.title}
</TableCell>
);
}
})}
</TableRow>
))
) : (
<Box p={2}>暂无数据</Box>
)}
</TableBody>
</MuiTable>
</TableContainer>
);
}
......@@ -2,11 +2,12 @@
* @Author: 吴永生#A02208 yongsheng.wu@wholion.com
* @Date: 2022-05-31 10:18:13
* @LastEditors: 吴永生#A02208 yongsheng.wu@wholion.com
* @LastEditTime: 2022-06-01 14:46:35
* @LastEditTime: 2022-06-02 18:48:15
* @FilePath: /bkunyun/src/views/Project/ProjectSetting/index.tsx
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
import { memo } from "react";
import { isEqual } from "lodash";
import { Box } from "@mui/system";
import Tab from "@mui/material/Tab";
......@@ -52,5 +53,11 @@ const Tabs = (props: IProps) => {
</TabContext>
);
};
const handleEqual = (prvProps: IProps, nextProps: IProps) => {
if (isEqual(prvProps, nextProps)) {
return true;
}
return false;
};
export default memo(Tabs);
export default memo(Tabs, handleEqual);
......@@ -2,7 +2,7 @@
* @Author: 吴永生#A02208 yongsheng.wu@wholion.com
* @Date: 2022-05-31 10:17:23
* @LastEditors: 吴永生#A02208 yongsheng.wu@wholion.com
* @LastEditTime: 2022-05-31 16:39:05
* @LastEditTime: 2022-06-02 17:15:35
* @FilePath: /bkunyun/src/react-app-env.d.ts
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
......@@ -79,3 +79,5 @@ declare module '*.module.sass' {
}
declare module '@mui/lab';
declare module 'lodash';
declare module "@mui/material/Tab"
/*
* @Author: 吴永生#A02208 yongsheng.wu@wholion.com
* @Date: 2022-05-31 10:18:13
* @LastEditors: 吴永生#A02208 yongsheng.wu@wholion.com
* @LastEditTime: 2022-06-04 18:28:31
* @FilePath: /bkunyun/src/views/Project/ProjectSetting/index.tsx
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
import Dialog from "@/components/mui/Dialog";
import { memo } from "react";
interface IProps {
setAddMemberDialog: (val: boolean) => void;
addMemberDialog: boolean;
}
const AddMember = (props: IProps) => {
const { addMemberDialog, setAddMemberDialog } = props;
const onClose = () => {
setAddMemberDialog(false);
};
const onConfirm = () => {
setAddMemberDialog(false);
};
return (
<>
<Dialog
open={addMemberDialog}
onClose={onClose}
onConfirm={onConfirm}
title="移出项目"
>
<div>确认移出该成员吗?</div>
</Dialog>
</>
);
};
export default memo(AddMember);
/*
* @Author: 吴永生#A02208 yongsheng.wu@wholion.com
* @Date: 2022-05-31 10:18:13
* @LastEditors: 吴永生#A02208 yongsheng.wu@wholion.com
* @LastEditTime: 2022-06-05 18:15:22
* @FilePath: /bkunyun/src/views/Project/ProjectSetting/index.tsx
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
// import Dialog from "@/components/Material.Ui/Dialog";
import Select from "@/components/mui/Select";
import Dialog from "@/components/mui/Dialog";
import { memo } from "react";
interface IProps {
setPermissionDialog: (val: boolean) => void;
permissionDialog: boolean;
}
const ChangePermission = (props: IProps) => {
const { permissionDialog, setPermissionDialog } = props;
const onClose = () => {
setPermissionDialog(false);
};
const onConfirm = () => {
setPermissionDialog(false);
};
return (
<>
<Dialog
open={permissionDialog}
onClose={onClose}
onConfirm={onConfirm}
title="更改权限"
>
<Select title="项目权限" options={[]} />
</Dialog>
</>
);
};
export default memo(ChangePermission);
/*
* @Author: 吴永生#A02208 yongsheng.wu@wholion.com
* @Date: 2022-05-31 10:18:13
* @LastEditors: 吴永生#A02208 yongsheng.wu@wholion.com
* @LastEditTime: 2022-06-04 17:54:50
* @FilePath: /bkunyun/src/views/Project/ProjectSetting/index.tsx
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
// import Dialog from "@/components/Material.Ui/Dialog";
import Dialog from "@/components/mui/Dialog";
import { memo } from "react";
interface IProps {
setRemoveDialog: (val: boolean) => void;
removeDialog: boolean;
}
const RemoveItem = (props: IProps) => {
const { removeDialog, setRemoveDialog } = props;
const onClose = () => {
setRemoveDialog(false);
};
const onConfirm = () => {
setRemoveDialog(false);
};
return (
<>
<Dialog
open={removeDialog}
onClose={onClose}
onConfirm={onConfirm}
title="移出项目"
>
<div>确认移出该成员吗?</div>
</Dialog>
</>
);
};
export default memo(RemoveItem);
.headerBox {
display: flex;
justify-content: space-between;
align-items: center;
}
.removeItemBox {
color: #ff4e4e;
margin-left: 32px;
cursor: pointer;
}
......@@ -2,16 +2,136 @@
* @Author: 吴永生#A02208 yongsheng.wu@wholion.com
* @Date: 2022-05-31 10:18:13
* @LastEditors: 吴永生#A02208 yongsheng.wu@wholion.com
* @LastEditTime: 2022-06-01 09:14:02
* @LastEditTime: 2022-06-04 18:33:02
* @FilePath: /bkunyun/src/views/Project/ProjectSetting/index.tsx
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
import { memo } from "react";
import { memo, useEffect, useState } from "react";
import { Box } from "@mui/system";
import { Box } from "@mui/material";
import Button from "@mui/material/Button";
import SearchIcon from "@mui/icons-material/Search";
import Add from "@mui/icons-material/Add";
import Table from "@/components/Material.Ui/Table";
import { useHttp } from "@/api/http";
import Input from "@/components/Material.Ui/Input";
import RemoveItem from "./components/RemoveItem";
import ChangePermission from "./components/ChangePermission";
import AddMember from "./components/AddMember";
import styles from "./index.module.css";
const ProjectMembers = () => {
return <Box>项目成员</Box>;
const http = useHttp();
const columns = [
{ id: "username", label: "成员名称", width: "20%" },
{ id: "projectRoleDesc", label: "项目权限", width: "20%" },
{ id: "phone", label: "联系方式", width: "20%" },
{
id: "operation",
label: "操作",
width: "20%",
render: (item: any) => {
console.log(item, "000000");
return (
<>
<span
style={{ color: "#1370FF", cursor: "pointer" }}
onClick={onPermissionBtn}
>
更改权限
</span>
<span className={styles.removeItemBox} onClick={onRemoveItemBtn}>
移出项目
</span>
</>
);
},
},
];
/** 删除成员 */
const [removeDialog, setRemoveDialog] = useState<boolean>(false);
/** 更改权限 */
const [permissionDialog, setPermissionDialog] = useState<boolean>(false);
/** 添加成员 */
const [addMemberDialog, setAddMemberDialog] = useState<boolean>(false);
useEffect(() => {
http
.get("/cpp/project/list", {
params: { product: "cadd" },
})
.then((res) => {
console.log(res);
});
}, [http]);
/** 点击添加成员 */
const onAddMember = () => {
setAddMemberDialog(true);
};
/** 点击删除成员 */
const onRemoveItemBtn = () => {
setRemoveDialog(true);
};
/** 点击更改权限 */
const onPermissionBtn = () => {
setPermissionDialog(true);
};
return (
<>
<Box className={styles.headerBox}>
<Input
onChange={(e: any) => {
console.log(e);
}}
size="xsmall"
placeholder="搜索项目成员"
endAdornment={<SearchIcon />}
/>
<Button
variant="contained"
onClick={onAddMember}
startIcon={<Add />}
size="small"
>
添加成员
</Button>
</Box>
<Table
rowHover={true}
stickyheader={true}
rows={[
{
username: "wuyongs",
phone: 2323424,
},
]}
rowsPerPage={"99"}
headCells={columns}
nopadding={true}
footer={false}
tableStyle={{ minWidth: "auto" }}
borderBottom={"none"}
/>
<RemoveItem
removeDialog={removeDialog}
setRemoveDialog={setRemoveDialog}
/>
<ChangePermission
permissionDialog={permissionDialog}
setPermissionDialog={setPermissionDialog}
/>
<AddMember
addMemberDialog={addMemberDialog}
setAddMemberDialog={setAddMemberDialog}
/>
</>
);
};
export default memo(ProjectMembers);
......@@ -2,24 +2,37 @@
* @Author: 吴永生#A02208 yongsheng.wu@wholion.com
* @Date: 2022-05-31 10:18:13
* @LastEditors: 吴永生#A02208 yongsheng.wu@wholion.com
* @LastEditTime: 2022-06-01 09:23:16
* @LastEditTime: 2022-06-02 18:43:59
* @FilePath: /bkunyun/src/views/Project/ProjectSetting/index.tsx
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
import { memo, useState } from "react";
import { memo, useState, useMemo } from "react";
import { Box } from "@mui/system";
import projectImg from "@/assets/project/projectIconSmall.svg";
import Tab from "@mui/material/Tab";
import { TabContext, TabList, TabPanel } from "@mui/lab";
import ProjectMembers from "./ProjectMembers";
import BaseInfo from "./BaseInfo";
import Tabs from "@/components/mui/Tabs";
const ProjectSetting = () => {
const [value, setValue] = useState("projectMember");
console.log(setValue, 111);
const changeTabs = (a: any, val: any) => {
const tabList = useMemo(() => {
return [
{
label: "项目成员",
value: "projectMember",
component: <ProjectMembers />,
},
{
label: "基础信息",
value: "baseInfo",
component: <BaseInfo />,
},
];
}, []);
const changeTabs = (val: string) => {
setValue(val);
};
......@@ -31,20 +44,7 @@ const ProjectSetting = () => {
</div>
<Box sx={{ width: "100%", typography: "body1" }}>
<TabContext value={value}>
<Box sx={{ borderBottom: 1, borderColor: "divider" }}>
<TabList onChange={changeTabs} aria-label="lab API tabs example">
<Tab label="项目成员" value="projectMember" />
<Tab label="基础信息" value="baseInfo" />
</TabList>
</Box>
<TabPanel value="projectMember">
<ProjectMembers />
</TabPanel>
<TabPanel value="baseInfo">
<BaseInfo />
</TabPanel>
</TabContext>
<Tabs value={value} onChange={changeTabs} tabList={tabList} />
</Box>
</Box>
);
......
This diff is collapsed.
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