Commit 7ea52091 authored by chenshouchao's avatar chenshouchao

Merge branch 'feat-20220705-customTemplate' into 'release'

cn-Feat 20220705 custom template

See merge request sunyihao/bkunyun!97
parents 95bf189b 0c38f37f
...@@ -4,7 +4,7 @@ import axios from "axios"; ...@@ -4,7 +4,7 @@ import axios from "axios";
// import { Actions, Constants } from '../../../../commons/utils/constants' // import { Actions, Constants } from '../../../../commons/utils/constants'
// import MessageUtil from '../../../../commons/utils/MessageUtil' // import MessageUtil from '../../../../commons/utils/MessageUtil'
// import ApiUtils from '../../../../commons/utils/ApiUtils' // import ApiUtils from '../../../../commons/utils/ApiUtils'
import { APIOPTION, urlToken, ZONEID } from "./raysyncApi"; import { APIOPTION, urlToken } from "./raysyncApi";
// import UserStore from '../../../../console/common/stores/UserStore' // import UserStore from '../../../../console/common/stores/UserStore'
import { ApiUtils } from "./utils"; import { ApiUtils } from "./utils";
import Base64 from "crypto-js/enc-base64"; import Base64 from "crypto-js/enc-base64";
......
...@@ -28,18 +28,18 @@ const APIPORT = function () { ...@@ -28,18 +28,18 @@ const APIPORT = function () {
}; };
// 当前计算区 // 当前计算区
let currentRegion = localStorage.getItem("current-region"); // let currentRegion = localStorage.getItem("current-region");
let currentRegionJson = currentRegion && JSON.parse(currentRegion); // let currentRegionJson = currentRegion && JSON.parse(currentRegion);
let user = getLoaclStorageOfKey("userinfo"); // let user = getLoaclStorageOfKey("userinfo");
// 文件路径 // 文件路径
const FILEPATH = // const FILEPATH =
currentRegionJson && // currentRegionJson &&
currentRegionJson.location && // currentRegionJson.location &&
currentRegionJson.location === "ON_PREMISE" && // currentRegionJson.location === "ON_PREMISE" &&
localStorage.getItem("userinfo") // localStorage.getItem("userinfo")
? `/home/${user.name}` // ? `/home/${user.name}`
: "/home/cloudam"; // : "/home/cloudam";
const FILEPATH_SHARE = "/share"; const FILEPATH_SHARE = "/share";
// 工作日志 // 工作日志
...@@ -104,7 +104,7 @@ const getType = function () { ...@@ -104,7 +104,7 @@ const getType = function () {
export { export {
API, API,
APIPORT, APIPORT,
FILEPATH, // FILEPATH,
FILEPATH_SHARE, FILEPATH_SHARE,
APIOPTION, APIOPTION,
APIJOBLOGPOINT, APIJOBLOGPOINT,
......
...@@ -128,7 +128,6 @@ export class Http { ...@@ -128,7 +128,6 @@ export class Http {
if ( if (
newConfig?.headers['Content-Type'] === "application/x-www-form-urlencoded" newConfig?.headers['Content-Type'] === "application/x-www-form-urlencoded"
) { ) {
console.log(222)
newConfig.data = qs.stringify(data); newConfig.data = qs.stringify(data);
} }
return newConfig return newConfig
......
...@@ -9,7 +9,6 @@ import Paper from "@mui/material/Paper"; ...@@ -9,7 +9,6 @@ import Paper from "@mui/material/Paper";
import Checkbox from "@mui/material/Checkbox"; import Checkbox from "@mui/material/Checkbox";
// import Spin from "./Spin"; // import Spin from "./Spin";
import EnhancedTableToolbarComponent from "./Table/EnhancedTableToolbar"
import EnhancedTableHeadComponent from "./Table/EnhancedTableHead" import EnhancedTableHeadComponent from "./Table/EnhancedTableHead"
import { getComparator, stableSort, useStyles } from "./Table/function"; import { getComparator, stableSort, useStyles } from "./Table/function";
import ActionsComponent from "./Table/ActionsComponent" import ActionsComponent from "./Table/ActionsComponent"
...@@ -20,11 +19,10 @@ export default function EnhancedTable(props) { ...@@ -20,11 +19,10 @@ export default function EnhancedTable(props) {
const classes = useStyles; const classes = useStyles;
const [order, setOrder] = React.useState("asc"); const [order, setOrder] = React.useState("asc");
const [orderBy, setOrderBy] = React.useState(""); const [orderBy, setOrderBy] = React.useState("");
const { headCells, rows, footer = true, elevation1, tableStyle, tablecellstyle, tableContainerStyle, stickyheader, TableHeadClasses, onRowClick, defaultRow, minHeight = '', borderBottom = '', onDoubleClick, const { headCells, rows, footer = true, elevation1, tableStyle, tablecellstyle, tableContainerStyle, stickyheader, 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 = '', tableBoySx } = props; load, size, checkboxData, rowsPerPage = 10, initSelected, page = 0, changePage = function () { }, toolbar, count, param, disabledparam = "id", headTableCellCheckbox, RowHeight = '', CellWidth = '', rowHover, TableNodataPadding = '', TableNodataLineHeight = '', tableBoySx } = props;
const [selected, setSelected] = React.useState(initSelected || []); const [selected, setSelected] = React.useState(initSelected || []);
const [rowsPerPageOptions, setRowsPerPageOptions] = React.useState(initSelected || [5, 10, 20, 50, { value: -1, label: 'All' }]); const [rowsPerPageOptions] = React.useState(initSelected || [5, 10, 20, 50, { value: -1, label: 'All' }]);
// const [spin, setSpin] = React.useState(false)
const [onRow, setOnRow] = React.useState('') const [onRow, setOnRow] = React.useState('')
// 重置复选框选中选项 // 重置复选框选中选项
...@@ -63,10 +61,6 @@ export default function EnhancedTable(props) { ...@@ -63,10 +61,6 @@ export default function EnhancedTable(props) {
setSelected([]); setSelected([]);
checkboxData([]); checkboxData([]);
}; };
// React.useEffect(() => {
// setSpin(load)
// }, [load]);
const handleClick = (event, name) => { const handleClick = (event, name) => {
const selectedIndex = selected.indexOf(name); const selectedIndex = selected.indexOf(name);
let newSelected = []; let newSelected = [];
...@@ -97,7 +91,7 @@ export default function EnhancedTable(props) { ...@@ -97,7 +91,7 @@ export default function EnhancedTable(props) {
const isSelected = (name) => selected.indexOf(name) !== -1; const isSelected = (name) => selected.indexOf(name) !== -1;
const emptyRows = rowsPerPage - Math.min(rowsPerPage, rows.length - page * rowsPerPage); // const emptyRows = rowsPerPage - Math.min(rowsPerPage, rows.length - page * rowsPerPage);
const renderTableCellValue = useCallback(((item, row, index)=>{ const renderTableCellValue = useCallback(((item, row, index)=>{
if( if(
...@@ -209,11 +203,6 @@ export default function EnhancedTable(props) { ...@@ -209,11 +203,6 @@ export default function EnhancedTable(props) {
</TableRow> </TableRow>
); );
})} })}
{/* {emptyRows > 0 && (
<TableRow style={{ height: (dense ? 33 : 53) * emptyRows }}>
<TableCell colSpan={6} />
</TableRow>
)} */}
</TableBody> </TableBody>
</Table> </Table>
</TableContainer> </TableContainer>
......
import React, { FC } from "react"; import React from "react";
import { Props } from "ahooks/lib/useControllableValue";
import { makeStyles } from "tss-react/mui"; import { makeStyles } from "tss-react/mui";
import { Typography, Menu, MenuItem, IconButton, Button } from "@mui/material"; import { Typography, Menu, MenuItem, Button } from "@mui/material";
import ArrowDropDownIcon from '@mui/icons-material/ArrowDropDown'; import ArrowDropDownIcon from "@mui/icons-material/ArrowDropDown";
type ButtonTagProps = { type ButtonTagProps = {
text: string;//文本内容 text: string; //文本内容
variant?: "text" | 'contained' | 'outlined';//按钮样式 variant?: "text" | "contained" | "outlined"; //按钮样式
click?: any;//点击事件 click?: any; //点击事件
select?: any[];//选择按钮的下拉列表 select?: any[]; //选择按钮的下拉列表
fontSize?: string;//按钮文字大小 fontSize?: string; //按钮文字大小
dropValue?: boolean;//选择的值 dropValue?: boolean; //选择的值
drop?: boolean;//是否开启选择 drop?: boolean; //是否开启选择
color?: "inherit" | "primary" | "secondary" | undefined,//按钮颜色风格 color?: "inherit" | "primary" | "secondary" | undefined; //按钮颜色风格
btnStyle?: any,//按钮自定义样式类 btnStyle?: any; //按钮自定义样式类
size?: "large" | "medium" | "small",//按钮尺寸 size?: "large" | "medium" | "small"; //按钮尺寸
disabled?: boolean,//是否禁用 disabled?: boolean; //是否禁用
style?: any,//按钮自定义样式 style?: any; //按钮自定义样式
img?: JSX.Element;//图标按钮中的图标 img?: JSX.Element; //图标按钮中的图标
selectCallBack?: (item: any, key: number) => void//选择按钮的回调 selectCallBack?: (item: any, key: number) => void; //选择按钮的回调
} };
const ButtonComponent = (props: ButtonTagProps) => { const ButtonComponent = (props: ButtonTagProps) => {
const { size, disabled, variant, color, img, btnStyle = {}, select, selectCallBack } = props; const {
const { classes, cx } = useStyles({}); size,
const [anchorEl, setAnchorEl] = React.useState(null); disabled,
variant,
color,
img,
btnStyle = {},
select,
selectCallBack,
} = props;
const { classes, cx } = useStyles({});
const [anchorEl, setAnchorEl] = React.useState(null);
const handleClick = (event: { currentTarget: React.SetStateAction<null>; }) => setAnchorEl(event.currentTarget); const handleClick = (event: { currentTarget: React.SetStateAction<null> }) =>
const defultClick = (event: { stoppropagation: () => any; }) => event && event.stoppropagation && event.stoppropagation() setAnchorEl(event.currentTarget);
const handleCloseOption = (item: any, key: number) => { const defultClick = (event: { stoppropagation: () => any }) =>
setAnchorEl(null); event && event.stoppropagation && event.stoppropagation();
selectCallBack && selectCallBack(item, key) const handleCloseOption = (item: any, key: number) => {
} setAnchorEl(null);
const handleClose = () => setAnchorEl(null); selectCallBack && selectCallBack(item, key);
};
const handleClose = () => setAnchorEl(null);
return (
<>
<Button
size={size || "medium"}
variant={variant || "contained"}
color={color || "primary"}
disableRipple={true}
disableFocusRipple={true}
disabled={disabled || false}
classes={{
root: btnStyle.root || classes.root,
// disabled: btnStyle.disabled || classes.disabled,
containedSecondary:
btnStyle.containedSecondary || classes.containedSecondary,
outlined: btnStyle.outlined || classes.outlined,
outlinedSecondary:
btnStyle.outlinedSecondary || classes.outlinedSecondary,
text: btnStyle.text || classes.text,
textPrimary: btnStyle.textPrimary || classes.textPrimary,
textSecondary: btnStyle.textSecondary || classes.textSecondary,
sizeSmall: btnStyle.sizeSmall || classes.sizeSmall,
sizeLarge: btnStyle.sizeLarge || classes.sizeLarge,
}}
style={{ ...props.style }}
onClick={props.select ? handleClick : props.click || defultClick}
>
{img || ""}
<Typography style={{ fontSize: props.fontSize || "14px" }}>
{props.text}
</Typography>
{((props.select && props.select.length > 0) || props.drop) && (
<ArrowDropDownIcon
classes={{
root: cx({
[classes.ArrowDropDownIconRoot]: true,
[classes.ArrowDropDownIconRootOpen]: Boolean(
props.dropValue || anchorEl
),
}),
}}
/>
)}
</Button>
<Menu
id="simple-menu"
anchorEl={anchorEl}
keepMounted
open={Boolean(anchorEl)}
onClose={handleClose}
>
{select &&
select.length > 0 &&
select.map((item, key) => {
return (
<MenuItem
key={key}
classes={{ root: classes.menuItemRoot }}
onClick={() => handleCloseOption(item, key)}
>
{item.name || ""}
</MenuItem>
);
})}
</Menu>
</>
);
};
return ( const useStyles = makeStyles<{}>()((theme) => ({
<> root: {
<Button backgroundColor: "#136EFA",
size={size || "medium"} boxShadow: "none !important",
variant={variant || 'contained'} color: "#ffffff",
color={color || "primary"} "&:hover": { backgroundColor: "#0055D9" },
disableRipple={true} },
disableFocusRipple={true} containedSecondary: {
disabled={disabled || false} backgroundColor: "#D62C1F",
classes={{ boxShadow: "none !important",
root: btnStyle.root || classes.root, "&:hover": { backgroundColor: "#D82C1F" },
// disabled: btnStyle.disabled || classes.disabled, },
containedSecondary: btnStyle.containedSecondary || classes.containedSecondary, outlined: {
outlined: btnStyle.outlined || classes.outlined, backgroundColor: "#FFFFFF",
outlinedSecondary: btnStyle.outlinedSecondary || classes.outlinedSecondary, border: "1px solid #136EFA",
text: btnStyle.text || classes.text, boxShadow: "none !important",
textPrimary: btnStyle.textPrimary || classes.textPrimary, color: "#136EFA",
textSecondary: btnStyle.textSecondary || classes.textSecondary, "&:hover": { backgroundColor: "rgba(19, 110, 250, 0.1)" },
sizeSmall: btnStyle.sizeSmall || classes.sizeSmall, },
sizeLarge: btnStyle.sizeLarge || classes.sizeLarge, outlinedSecondary: {
border: "1px solid #D62C1F",
color: "#D62C1F",
"&:hover": {
border: "1px solid #D62C1F",
backgroundColor: "rgba(214, 44, 31, 0.1)",
},
},
label: { "& p": { fontSize: "13px" } },
text: { backgroundColor: "transparent", boxShadow: "none !important" },
textPrimary: { color: "#136EFA", "&:hover": { backgroundColor: "#E8F1FF" } },
textSecondary: {
color: "#F44335",
"&:hover": { backgroundColor: "rgba(244, 67, 53, 0.1)" },
},
sizeSmall: { "& p": { fontSize: "12px" } },
sizeLarge: { "& p": { fontSize: "14px" } },
menuItemRoot: {},
ArrowDropDownIconRoot: {
color: "#8A9099",
transition: "all 0.2s !important",
transform: "rotate(0)",
},
ArrowDropDownIconRootOpen: { color: "#8A9099", transform: "rotate(180deg)" },
}));
}} export default ButtonComponent;
style={{ ...props.style }}
onClick={props.select ? handleClick : (props.click || defultClick)}
>
{img || ''}
<Typography style={{ fontSize: props.fontSize || "14px" }}>{props.text}</Typography>
{
(props.select && props.select.length > 0 || props.drop) && <ArrowDropDownIcon classes={{
root: cx({
[classes.ArrowDropDownIconRoot]: true,
[classes.ArrowDropDownIconRootOpen]: Boolean(props.dropValue || anchorEl)
})
}} />
}
</Button>
<Menu
id="simple-menu"
anchorEl={anchorEl}
keepMounted
open={Boolean(anchorEl)}
onClose={handleClose}
>
{
select && select.length > 0 && select.map((item, key) => {
return (
<MenuItem
key={key}
classes={{ root: classes.menuItemRoot }}
onClick={() => handleCloseOption(item, key)}>
{item.name || ""}
</MenuItem>
)
})
}
</Menu>
</>
)
}
const useStyles = makeStyles<{}>()(
(theme, { }) => ({
root: { backgroundColor: "#136EFA", boxShadow: "none !important", color: "#ffffff", "&:hover": { backgroundColor: "#0055D9" } },
containedSecondary: { backgroundColor: "#D62C1F", boxShadow: "none !important", "&:hover": { backgroundColor: "#D82C1F" } },
outlined: { backgroundColor: '#FFFFFF', border: "1px solid #136EFA", boxShadow: "none !important", color: "#136EFA", "&:hover": { backgroundColor: "rgba(19, 110, 250, 0.1)" } },
outlinedSecondary: { border: "1px solid #D62C1F", color: "#D62C1F", "&:hover": { border: "1px solid #D62C1F", backgroundColor: "rgba(214, 44, 31, 0.1)" } },
label: { "& p": { fontSize: "13px" } },
text: { backgroundColor: 'transparent', boxShadow: "none !important" },
textPrimary: { color: "#136EFA", "&:hover": { backgroundColor: "#E8F1FF" } },
textSecondary: { color: "#F44335", "&:hover": { backgroundColor: "rgba(244, 67, 53, 0.1)" } },
sizeSmall: { "& p": { fontSize: "12px" } },
sizeLarge: { "& p": { fontSize: "14px" } },
menuItemRoot: {},
ArrowDropDownIconRoot: { color: "#8A9099", transition: "all 0.2s !important", transform: "rotate(0)" },
ArrowDropDownIconRootOpen: { color: "#8A9099", transform: "rotate(180deg)" },
})
);
export default ButtonComponent;
\ No newline at end of file
...@@ -21,7 +21,7 @@ const theme = createTheme({ ...@@ -21,7 +21,7 @@ const theme = createTheme({
MuiMenu: { MuiMenu: {
styleOverrides: { styleOverrides: {
root: { root: {
maxHeight: "260px", // maxHeight: "260px",
overflowY: "scroll", overflowY: "scroll",
}, },
}, },
...@@ -87,7 +87,9 @@ const MyMenu = (props: IMyMenuProps) => { ...@@ -87,7 +87,9 @@ const MyMenu = (props: IMyMenuProps) => {
key={index} key={index}
> >
<span>{option.label}</span> <span>{option.label}</span>
{value === option.value && <CheckIcon />} {value === option.value && (
<CheckIcon sx={{ marginLeft: "12px" }} />
)}
</MenuItem> </MenuItem>
); );
})} })}
......
...@@ -4,74 +4,72 @@ import ArrowDropDownIcon from "@mui/icons-material/ArrowDropDown"; ...@@ -4,74 +4,72 @@ import ArrowDropDownIcon from "@mui/icons-material/ArrowDropDown";
import TreeItem from "@mui/lab/TreeItem"; import TreeItem from "@mui/lab/TreeItem";
interface TreeItemType { interface TreeItemType {
id: string; id: string;
name: string; name: string;
disabled?: boolean; disabled?: boolean;
subdirs?: readonly TreeItemType[]; subdirs?: readonly TreeItemType[];
} }
type MyTreeViewProps = { type MyTreeViewProps = {
treeData: Array<TreeItemType>; treeData: Array<TreeItemType>;
onNodeFocus?: (event: object, value: string) => void; // 点击某一项的回调 onNodeFocus?: (event: object, value: string) => void; // 点击某一项的回调
onNodeSelect?: (event: object, value: Array<any> | string) => void; // 点击某一项的回调 onNodeSelect?: (event: object, value: Array<any> | string) => void; // 点击某一项的回调
onNodeToggle?: (event: object, nodeIds: Array<any>) => void; // 点击某一项的回调 onNodeToggle?: (event: object, nodeIds: Array<any>) => void; // 点击某一项的回调
renderLabel?: (node: any) => React.ReactNode; renderLabel?: (node: any) => React.ReactNode;
treeViewSx?: any; treeViewSx?: any;
defaultExpanded?: Array<string>; defaultExpanded?: Array<string>;
idKey?: string; idFunc?: (node: any) => string;
idFunc?: (node: any) => string;
}; };
interface RenderTree { interface RenderTree {
id: string | number; id: string | number;
name: string; name: string;
disabled?: boolean; disabled?: boolean;
subdirs?: readonly RenderTree[]; subdirs?: readonly RenderTree[];
} }
const MyTreeView = (props: MyTreeViewProps) => { const MyTreeView = (props: MyTreeViewProps) => {
const { const {
treeData = [], treeData = [],
renderLabel, renderLabel,
treeViewSx, treeViewSx,
onNodeFocus, onNodeFocus,
onNodeSelect, onNodeSelect,
onNodeToggle, onNodeToggle,
defaultExpanded, defaultExpanded,
idKey, idFunc,
idFunc, } = props;
} = props;
const renderTreeObj = (nodes: RenderTree, index: number) => ( const renderTreeObj = (nodes: RenderTree, index: number) => (
<TreeItem <TreeItem
key={nodes.id || `${nodes.name}${index}`} key={nodes.id || `${nodes.name}${index}`}
nodeId={String( nodeId={String(
idFunc ? idFunc(nodes) : nodes.id || `${nodes.name}${index}` idFunc ? idFunc(nodes) : nodes.id || `${nodes.name}${index}`
)} )}
label={renderLabel === undefined ? nodes.name : renderLabel(nodes)} label={renderLabel === undefined ? nodes.name : renderLabel(nodes)}
disabled={nodes?.disabled ? true : false} disabled={nodes?.disabled ? true : false}
> >
{Array.isArray(nodes.subdirs) {Array.isArray(nodes.subdirs)
? nodes.subdirs.map((node, i) => renderTreeObj(node, i)) ? nodes.subdirs.map((node, i) => renderTreeObj(node, i))
: null} : null}
</TreeItem> </TreeItem>
); );
return ( return (
<TreeView <TreeView
defaultCollapseIcon={<ArrowRightIcon />} defaultCollapseIcon={<ArrowRightIcon />}
defaultExpandIcon={<ArrowDropDownIcon />} defaultExpandIcon={<ArrowDropDownIcon />}
onNodeFocus={onNodeFocus} onNodeFocus={onNodeFocus}
onNodeSelect={onNodeSelect} onNodeSelect={onNodeSelect}
onNodeToggle={onNodeToggle} onNodeToggle={onNodeToggle}
defaultExpanded={defaultExpanded} defaultExpanded={defaultExpanded}
sx={{ ...treeViewSx }} sx={{ ...treeViewSx }}
> >
{treeData.map((treeItem, index) => { {treeData.map((treeItem, index) => {
return renderTreeObj(treeItem, index); return renderTreeObj(treeItem, index);
})} })}
</TreeView> </TreeView>
); );
}; };
export default MyTreeView; export default MyTreeView;
...@@ -75,7 +75,7 @@ const usePass = () => { ...@@ -75,7 +75,7 @@ const usePass = () => {
} }
return false; return false;
}, },
[permissionStore.allRoutes] [permissionStore.allRoutes, currentProjectStore]
); );
return isPass; return isPass;
......
...@@ -7,35 +7,48 @@ import { Provider } from "mobx-react"; ...@@ -7,35 +7,48 @@ import { Provider } from "mobx-react";
import { stores } from "@/store/index"; import { stores } from "@/store/index";
import { MySnackbarProvider } from "@/components/MySnackbar"; import { MySnackbarProvider } from "@/components/MySnackbar";
import "@/mocks/index"; import "@/mocks/index";
import './assets/style/public.css' import "./assets/style/public.css";
import { createTheme, ThemeProvider, styled } from '@mui/material/styles'; import { createTheme, ThemeProvider } from "@mui/material/styles";
const root = ReactDOM.createRoot( const root = ReactDOM.createRoot(
document.getElementById("root") as HTMLElement document.getElementById("root") as HTMLElement
); );
const theme = createTheme({ const theme = createTheme({
typography: { typography: {
fontFamily: ['Roboto', 'Helvetica', 'Tahoma', 'Arial', '"PingFang SC"', '"Hiragino Sans GB"', '"Heiti SC"', '"WenQuanYi Micro Hei"', 'sans-serif', '"Apple Color Emoji"', '"Segoe UI Emoji"', '"Segoe UI Symbol"'].join(','), fontFamily: [
}, "Roboto",
palette: { "Helvetica",
primary: { main: '#136EFA' }, "Tahoma",
secondary: { main: '#F44335' } "Arial",
} '"PingFang SC"',
'"Hiragino Sans GB"',
'"Heiti SC"',
'"WenQuanYi Micro Hei"',
"sans-serif",
'"Apple Color Emoji"',
'"Segoe UI Emoji"',
'"Segoe UI Symbol"',
].join(","),
},
palette: {
primary: { main: "#136EFA" },
secondary: { main: "#F44335" },
},
}); });
root.render( root.render(
<React.StrictMode> <React.StrictMode>
<ThemeProvider theme={theme}> <ThemeProvider theme={theme}>
<Provider {...stores}> <Provider {...stores}>
<MySnackbarProvider <MySnackbarProvider
alertSx={{ boxShadow: "0px 2px 4px 0px rgb(0 0 0 / 8%)" }} alertSx={{ boxShadow: "0px 2px 4px 0px rgb(0 0 0 / 8%)" }}
> >
<MyRouter></MyRouter> <MyRouter></MyRouter>
</MySnackbarProvider> </MySnackbarProvider>
</Provider> </Provider>
</ThemeProvider> </ThemeProvider>
</React.StrictMode> </React.StrictMode>
); );
// If you want to start measuring performance in your app, pass a function // If you want to start measuring performance in your app, pass a function
......
...@@ -36,6 +36,6 @@ export const verifyLettersNumbersCertainChars5 = (str: string) => { ...@@ -36,6 +36,6 @@ export const verifyLettersNumbersCertainChars5 = (str: string) => {
if (getTrueLength(str) > 127) { if (getTrueLength(str) > 127) {
return false; return false;
} }
let validString = /^[\u4e00-\u9fa5_0-9a-zA-Z\/-_.]+$/; let validString = /^[\u4e00-\u9fa5_0-9a-zA-Z/-_.]+$/;
return validString.test(str); return validString.test(str);
}; };
\ No newline at end of file
import React, { useState, useImperativeHandle, useMemo } from "react"; import React, { useImperativeHandle, useMemo } from "react";
import MyDialog from "@/components/mui/MyDialog"; import MyDialog from "@/components/mui/MyDialog";
import { useMessage } from "@/components/MySnackbar"; import { useMessage } from "@/components/MySnackbar";
...@@ -7,177 +7,177 @@ import { getDataFileDel, getDataFileDelPackage } from "@/api/project_api"; ...@@ -7,177 +7,177 @@ import { getDataFileDel, getDataFileDelPackage } from "@/api/project_api";
import useMyRequest from "@/hooks/useMyRequest"; import useMyRequest from "@/hooks/useMyRequest";
const DeleteDialog = (props: any) => { const DeleteDialog = (props: any) => {
const { const {
path, path,
projectId, projectId,
fileToken, fileToken,
currentOperateFile, currentOperateFile,
selectIds, selectIds,
refresh, refresh,
showList, showList,
} = props; } = props;
const Message = useMessage(); const Message = useMessage();
let deleteFileDialogRef: any = React.createRef(); let deleteFileDialogRef: any = React.createRef();
const showDialog = () => { const showDialog = () => {
deleteFileDialogRef.current.handleClickOpen(); deleteFileDialogRef.current.handleClickOpen();
}; };
useImperativeHandle(props.onRef, () => { useImperativeHandle(props.onRef, () => {
return { return {
showDialog: showDialog, showDialog: showDialog,
}; };
}); });
const { run: getDataFileDelRun } = useMyRequest(getDataFileDel, { const { run: getDataFileDelRun } = useMyRequest(getDataFileDel, {
onSuccess: (res: any) => { onSuccess: (res: any) => {
successDelete(); successDelete();
}, },
}); });
const { run: getDataFileDelPackageRun } = useMyRequest( const { run: getDataFileDelPackageRun } = useMyRequest(
getDataFileDelPackage, getDataFileDelPackage,
{ {
onSuccess: (res: any) => { onSuccess: (res: any) => {
successDelete(); successDelete();
}, },
} }
); );
const successDelete = () => { const successDelete = () => {
Message.success("删除成功!"); Message.success("删除成功!");
deleteFileDialogRef?.current?.handleClose(); deleteFileDialogRef?.current?.handleClose();
refresh(); refresh();
}; };
const deletePathProvidedToDataSet = useMemo(() => { const deletePathProvidedToDataSet = useMemo(() => {
return path === "/" ? "/" : `${path}/`; return path === "/" ? "/" : `${path}/`;
}, [path]); }, [path]);
const deletePathProvidedFileServer = useMemo(() => { const deletePathProvidedFileServer = useMemo(() => {
return path === "/" ? `${path}` : `${path}/`; return path === "/" ? `${path}` : `${path}/`;
}, [path]); }, [path]);
// 删除 // 删除
const handleSubmit = () => { const handleSubmit = () => {
if (!currentOperateFile) { if (!currentOperateFile) {
// 批量删除 // 批量删除
// 要删除的数据集 // 要删除的数据集
const datSetDeleteList = showList.filter((item: any) => { const datSetDeleteList = showList.filter((item: any) => {
return selectIds.indexOf(item.name) !== -1 && item.type === "dataSet"; return selectIds.indexOf(item.name) !== -1 && item.type === "dataSet";
}); });
// 要删除的文件夹 // 要删除的文件夹
const folderDeleteList = showList.filter((item: any) => { const folderDeleteList = showList.filter((item: any) => {
return selectIds.indexOf(item.name) !== -1 && item.type === "directory"; return selectIds.indexOf(item.name) !== -1 && item.type === "directory";
}); });
// 要删除的文件 // 要删除的文件
const fileDeleteList = showList.filter((item: any) => { const fileDeleteList = showList.filter((item: any) => {
return ( return (
selectIds.indexOf(item.name) !== -1 && selectIds.indexOf(item.name) !== -1 &&
item.type !== "dataSet" && item.type !== "dataSet" &&
item.type !== "directory" item.type !== "directory"
); );
}); });
if (datSetDeleteList.length > 0) { if (datSetDeleteList.length > 0) {
dataSetsDelete(datSetDeleteList); dataSetsDelete(datSetDeleteList);
} }
if (folderDeleteList.length > 0) { if (folderDeleteList.length > 0) {
foldersDelete(folderDeleteList); foldersDelete(folderDeleteList);
} }
if (fileDeleteList.length > 0) { if (fileDeleteList.length > 0) {
filesDelete(fileDeleteList); filesDelete(fileDeleteList);
} }
} else { } else {
if (currentOperateFile.type === "dataSet") { if (currentOperateFile.type === "dataSet") {
dataSetDelete(); dataSetDelete();
} else if (currentOperateFile.type === "directory") { } else if (currentOperateFile.type === "directory") {
folerDelete(); folerDelete();
} else { } else {
fileDelete(); fileDelete();
} }
} }
}; };
// 删除单个数据集 // 删除单个数据集
const dataSetDelete = () => { const dataSetDelete = () => {
getDataFileDelRun({ getDataFileDelRun({
projectId: projectId as string, projectId: projectId as string,
names: currentOperateFile.name, names: currentOperateFile.name,
path: deletePathProvidedToDataSet, path: deletePathProvidedToDataSet,
}); });
}; };
// 删除单个文件夹 // 删除单个文件夹
const folerDelete = () => { const folerDelete = () => {
fileDelete(); fileDelete();
const names = currentOperateFile.name; const names = currentOperateFile.name;
dataSetInFolerDelete(names); dataSetInFolerDelete(names);
}; };
// 删除文件夹中的数据集 // 删除文件夹中的数据集
const dataSetInFolerDelete = (names: string) => { const dataSetInFolerDelete = (names: string) => {
getDataFileDelPackageRun({ getDataFileDelPackageRun({
projectId: projectId as string, projectId: projectId as string,
names, names,
path: deletePathProvidedToDataSet, path: deletePathProvidedToDataSet,
}); });
}; };
// 删除单个文件 // 删除单个文件
const fileDelete = () => { const fileDelete = () => {
CloudEController.JobOutFileDel( CloudEController.JobOutFileDel(
`${deletePathProvidedFileServer}${currentOperateFile.name}`, `${deletePathProvidedFileServer}${currentOperateFile.name}`,
fileToken as string, fileToken as string,
projectId as string projectId as string
)?.then((res) => { )?.then((res) => {
successDelete(); successDelete();
}); });
}; };
// 删除多个数据集 // 删除多个数据集
const dataSetsDelete = (datSetDeleteList: Array<any>) => { const dataSetsDelete = (datSetDeleteList: Array<any>) => {
getDataFileDelRun({ getDataFileDelRun({
projectId: projectId as string, projectId: projectId as string,
names: datSetDeleteList.map((item: any) => item.name).join(","), names: datSetDeleteList.map((item: any) => item.name).join(","),
path: deletePathProvidedToDataSet, path: deletePathProvidedToDataSet,
}); });
}; };
// 删除多个文件夹 // 删除多个文件夹
const foldersDelete = (folderDeleteList: Array<any>) => { const foldersDelete = (folderDeleteList: Array<any>) => {
filesDelete(folderDeleteList); filesDelete(folderDeleteList);
const names = folderDeleteList.map((item: any) => item.name).join(","); const names = folderDeleteList.map((item: any) => item.name).join(",");
dataSetInFolerDelete(names); dataSetInFolerDelete(names);
}; };
// 删除多个文件 // 删除多个文件
const filesDelete = (fileDeleteList: Array<any>) => { const filesDelete = (fileDeleteList: Array<any>) => {
const deletePath = fileDeleteList const deletePath = fileDeleteList
.map((item: any) => { .map((item: any) => {
return `${deletePathProvidedFileServer}${item.name}`; return `${deletePathProvidedFileServer}${item.name}`;
}) })
.join(" "); .join(" ");
CloudEController.JobOutFileDel( CloudEController.JobOutFileDel(
deletePath, deletePath,
fileToken as string, fileToken as string,
projectId as string projectId as string
)?.then((res) => { )?.then((res) => {
successDelete(); successDelete();
}); });
}; };
const submitloading = false; const submitloading = false;
return ( return (
<MyDialog <MyDialog
handleSubmit={handleSubmit} handleSubmit={handleSubmit}
onRef={deleteFileDialogRef} onRef={deleteFileDialogRef}
title="提示" title="提示"
submitloading={submitloading} submitloading={submitloading}
> >
{currentOperateFile {currentOperateFile
? "确认删除该数据吗?" ? "确认删除该数据吗?"
: `确认删除这${selectIds.length}条数据吗?`} : `确认删除这${selectIds.length}条数据吗?`}
</MyDialog> </MyDialog>
); );
}; };
export default DeleteDialog; export default DeleteDialog;
import React, { import React, {
useState, useState,
useImperativeHandle, useImperativeHandle,
useCallback, useCallback,
useMemo, useMemo,
useEffect, useEffect,
} from "react"; } from "react";
import style from "./index.module.css"; import style from "./index.module.css";
...@@ -19,344 +19,341 @@ import classNames from "classnames"; ...@@ -19,344 +19,341 @@ import classNames from "classnames";
import _ from "lodash"; import _ from "lodash";
const MoveFile = (props: any) => { const MoveFile = (props: any) => {
const { const {
path, path,
projectId, projectId,
fileToken, fileToken,
currentOperateFile, currentOperateFile,
selectIds, selectIds,
refresh, refresh,
showList, showList,
} = props; } = props;
const Message = useMessage(); const Message = useMessage();
const [newPath, setNewPath] = useState("/"); const [newPath, setNewPath] = useState("/");
const [rootActive, setRootActive] = useState(true); const [rootActive, setRootActive] = useState(true);
const [moveFileSubmitloading, setMoveFileSubmitloading] = useState(false); const [moveFileSubmitloading, setMoveFileSubmitloading] = useState(false);
const [treeData, setTreeData] = useState<any>([]); const [treeData, setTreeData] = useState<any>([]);
const [renderTreeData, setRenderTreeData] = useState<any>([]); const [renderTreeData, setRenderTreeData] = useState<any>([]);
const [moveFileDialogRef, setMoveFileDialogRef] = useState<any>( const [moveFileDialogRef] = useState<any>(React.createRef());
React.createRef() // 要移动的文件夹 之后用来隐藏文件夹树中同路径的文件夹
); const [moveFolderPathArr, setMoveFolderPathArr] = useState<Array<string>>([]);
// 要移动的文件夹 之后用来隐藏文件夹树中同路径的文件夹
const [moveFolderPathArr, setMoveFolderPathArr] = useState<Array<string>>([]);
const getTree = useCallback(() => { const getTree = useCallback(() => {
if (fileToken && projectId) { if (fileToken && projectId) {
return CloudEController.JobOutFileDirtree( return CloudEController.JobOutFileDirtree(
"/", "/",
fileToken, fileToken,
projectId, projectId,
false false
)?.then((res) => { )?.then((res) => {
if (Array.isArray(res.data)) { if (Array.isArray(res.data)) {
let arr = res.data; let arr = res.data;
setTreeData(arr); setTreeData(arr);
} else { } else {
setTreeData([]); setTreeData([]);
} }
}); });
} }
}, [fileToken, projectId]); }, [fileToken, projectId]);
const getDisabledRepeatFolder = useCallback( const getDisabledRepeatFolder = useCallback(
(folderTree: any, samePathFolederArr: Array<string>) => { (folderTree: any, samePathFolederArr: Array<string>) => {
const arr = _.cloneDeep(folderTree); const arr = _.cloneDeep(folderTree);
const disabledRepeatFolder = (tree: any, repeatPath: Array<string>) => { const disabledRepeatFolder = (tree: any, repeatPath: Array<string>) => {
tree.forEach((item: any, index: number) => { tree.forEach((item: any, index: number) => {
if (repeatPath.indexOf(`${item.dir.substr(1)}${item.name}`) !== -1) { if (repeatPath.indexOf(`${item.dir.substr(1)}${item.name}`) !== -1) {
item.disabled = true; item.disabled = true;
} else { } else {
item.disabled = false; item.disabled = false;
if (item.subdirs.length > 0) { if (item.subdirs.length > 0) {
disabledRepeatFolder(item.subdirs, repeatPath); disabledRepeatFolder(item.subdirs, repeatPath);
} }
} }
}); });
}; };
disabledRepeatFolder(arr, samePathFolederArr); disabledRepeatFolder(arr, samePathFolederArr);
return arr; return arr;
}, },
[] []
); );
useEffect(() => { useEffect(() => {
const tree = getDisabledRepeatFolder(treeData, moveFolderPathArr); const tree = getDisabledRepeatFolder(treeData, moveFolderPathArr);
setRenderTreeData(tree); setRenderTreeData(tree);
}, [moveFolderPathArr, getDisabledRepeatFolder, treeData]); }, [moveFolderPathArr, getDisabledRepeatFolder, treeData]);
useEffect(() => { useEffect(() => {
let moveFolderArr: any = []; let moveFolderArr: any = [];
let pathArr = []; let pathArr = [];
if (currentOperateFile) { if (currentOperateFile) {
if (currentOperateFile.type === "directory") { if (currentOperateFile.type === "directory") {
moveFolderArr = [currentOperateFile]; moveFolderArr = [currentOperateFile];
} else { } else {
moveFolderArr = []; moveFolderArr = [];
} }
} else { } else {
moveFolderArr = showList.filter((item: any) => { moveFolderArr = showList.filter((item: any) => {
return selectIds.indexOf(item.name) !== -1 && item.type === "directory"; return selectIds.indexOf(item.name) !== -1 && 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}`;
}); });
setMoveFolderPathArr(pathArr); setMoveFolderPathArr(pathArr);
}, [selectIds, showList, currentOperateFile, path]); }, [selectIds, showList, currentOperateFile, path]);
const showDialog = () => { const showDialog = () => {
moveFileDialogRef.current.handleClickOpen(); moveFileDialogRef.current.handleClickOpen();
getTree(); getTree();
}; };
useImperativeHandle(props.onRef, () => { useImperativeHandle(props.onRef, () => {
return { return {
showDialog: showDialog, showDialog: showDialog,
}; };
}); });
const { run: getDataFileMoveRun } = useMyRequest(getDataFileMove, { const { run: getDataFileMoveRun } = useMyRequest(getDataFileMove, {
onSuccess: (res: any) => { onSuccess: (res: any) => {
successMove(); successMove();
}, },
}); });
const { run: getDataFileMovePackageRun } = useMyRequest( const { run: getDataFileMovePackageRun } = useMyRequest(
getDataFileMovePackage, getDataFileMovePackage,
{ {
onSuccess: (res: any) => { onSuccess: (res: any) => {
successMove(); successMove();
}, },
} }
); );
// 提供给fileserver相关接口的newpath 直接用newPath就可以了 // 提供给fileserver相关接口的newpath 直接用newPath就可以了
// const newPathProvidedToFileServer = useMemo(() => { // const newPathProvidedToFileServer = useMemo(() => {
// return newPath // return newPath
// }, [newPath]) // }, [newPath])
// 提供给数据集相关接口的newpath // 提供给数据集相关接口的newpath
const newPathProvidedToDataSet = useMemo(() => { const newPathProvidedToDataSet = useMemo(() => {
return newPath === "/" ? "/" : `${newPath}/`; return newPath === "/" ? "/" : `${newPath}/`;
}, [newPath]); }, [newPath]);
// 提供给fileserver相关接口的oldpath // 提供给fileserver相关接口的oldpath
const oldPathProvidedToFileServer = useMemo(() => { const oldPathProvidedToFileServer = useMemo(() => {
return `${path}${path === "/" ? "" : "/"}`; return `${path}${path === "/" ? "" : "/"}`;
}, [path]); }, [path]);
// 提供给数据集相关接口的oldpath // 提供给数据集相关接口的oldpath
const oldPathProvidedToDataSet = useMemo(() => { const oldPathProvidedToDataSet = useMemo(() => {
return path === "/" ? "/" : `${path}/`; return path === "/" ? "/" : `${path}/`;
}, [path]); }, [path]);
// 移动成功后的操作 // 移动成功后的操作
const successMove = () => { const successMove = () => {
Message.success("移动成功!"); Message.success("移动成功!");
setMoveFileSubmitloading(false); setMoveFileSubmitloading(false);
moveFileDialogRef?.current?.handleClose(); moveFileDialogRef?.current?.handleClose();
refresh(); refresh();
}; };
// 移动失败后的操作 // 移动失败后的操作
const erroeMove = (error: any) => { const erroeMove = (error: any) => {
if (error?.response?.status === 405) { if (error?.response?.status === 405) {
Message.error("因目标路径存在同名文件,数据移动失败。"); Message.error("因目标路径存在同名文件,数据移动失败。");
} else { } else {
Message.error("文件服务发生错误,数据移动失败。"); Message.error("文件服务发生错误,数据移动失败。");
} }
setMoveFileSubmitloading(false); setMoveFileSubmitloading(false);
}; };
// 移动 // 移动
const handleMoveFileSubmit = () => { const handleMoveFileSubmit = () => {
if (!newPath) { if (!newPath) {
Message.error("请选择移动到哪个目录"); Message.error("请选择移动到哪个目录");
} else if (newPath === path) { } else if (newPath === path) {
Message.error("指定的目标路径为数据原路径,无需移动。"); Message.error("指定的目标路径为数据原路径,无需移动。");
} else { } else {
setMoveFileSubmitloading(true); setMoveFileSubmitloading(true);
if (!currentOperateFile) { if (!currentOperateFile) {
// 批量移动 // 批量移动
// 要移动的数据集 // 要移动的数据集
const datSetMoveList = showList.filter((item: any) => { const datSetMoveList = showList.filter((item: any) => {
return selectIds.indexOf(item.name) !== -1 && item.type === "dataSet"; return selectIds.indexOf(item.name) !== -1 && item.type === "dataSet";
}); });
// 要移动的文件夹 // 要移动的文件夹
const folderMoveList = showList.filter((item: any) => { const folderMoveList = showList.filter((item: any) => {
return ( return (
selectIds.indexOf(item.name) !== -1 && item.type === "directory" selectIds.indexOf(item.name) !== -1 && item.type === "directory"
); );
}); });
// 要移动的文件 // 要移动的文件
const fileMoveList = showList.filter((item: any) => { const fileMoveList = showList.filter((item: any) => {
return ( return (
selectIds.indexOf(item.name) !== -1 && selectIds.indexOf(item.name) !== -1 &&
item.type !== "dataSet" && item.type !== "dataSet" &&
item.type !== "directory" item.type !== "directory"
); );
}); });
if (datSetMoveList.length > 0) { if (datSetMoveList.length > 0) {
dataSetsMove(datSetMoveList); dataSetsMove(datSetMoveList);
} }
if (folderMoveList.length > 0) { if (folderMoveList.length > 0) {
foldersMove(folderMoveList); foldersMove(folderMoveList);
} }
if (fileMoveList.length > 0) { if (fileMoveList.length > 0) {
filesMove(fileMoveList)?.then((res) => { filesMove(fileMoveList)?.then((res) => {
successMove(); successMove();
}); });
} }
} else { } else {
if (currentOperateFile.type === "dataSet") { if (currentOperateFile.type === "dataSet") {
dataSetMove(); dataSetMove();
} else if (currentOperateFile.type === "directory") { } else if (currentOperateFile.type === "directory") {
folerMove(); folerMove();
} else { } else {
fileMove()?.then((res) => { fileMove()?.then((res) => {
successMove(); successMove();
}); });
} }
} }
} }
}; };
// 单文件移动 // 单文件移动
const fileMove = () => { const fileMove = () => {
const oldPathToFileServer = `${oldPathProvidedToFileServer}${currentOperateFile.name}`; const oldPathToFileServer = `${oldPathProvidedToFileServer}${currentOperateFile.name}`;
return CloudEController.JobFileMove( return CloudEController.JobFileMove(
newPath, newPath,
oldPathToFileServer, oldPathToFileServer,
"", "",
fileToken, fileToken,
projectId projectId
); );
}; };
// 多文件移动 // 多文件移动
const filesMove = (fileMoveList: Array<any>) => { const filesMove = (fileMoveList: Array<any>) => {
const oldPaths = fileMoveList.map((item: any) => { const oldPaths = fileMoveList.map((item: any) => {
return `${oldPathProvidedToFileServer}${item.name}`; return `${oldPathProvidedToFileServer}${item.name}`;
}); });
return CloudEController.JobFileBatchMove( return CloudEController.JobFileBatchMove(
newPath, newPath,
oldPaths, oldPaths,
"", "",
fileToken, fileToken,
projectId projectId
); );
}; };
// 单文件夹移动 // 单文件夹移动
const folerMove = () => { const folerMove = () => {
fileMove() fileMove()
?.then((res) => { ?.then((res) => {
const names = currentOperateFile.name; const names = currentOperateFile.name;
dataSetInFolerMove(names); dataSetInFolerMove(names);
}) })
.catch((error) => { .catch((error) => {
console.log(error); console.log(error);
erroeMove(error); erroeMove(error);
}); });
}; };
// 移动文件夹中的数据集 // 移动文件夹中的数据集
const dataSetInFolerMove = (names: string) => { const dataSetInFolerMove = (names: string) => {
getDataFileMovePackageRun({ getDataFileMovePackageRun({
projectId: projectId as string, projectId: projectId as string,
names, names,
spath: oldPathProvidedToDataSet, spath: oldPathProvidedToDataSet,
dpath: newPathProvidedToDataSet, dpath: newPathProvidedToDataSet,
}); });
}; };
// 多文件夹移动 // 多文件夹移动
const foldersMove = (folderMoveList: Array<any>) => { const foldersMove = (folderMoveList: Array<any>) => {
filesMove(folderMoveList) filesMove(folderMoveList)
?.then((res) => { ?.then((res) => {
const names = folderMoveList.map((item: any) => item.name).join(","); const names = folderMoveList.map((item: any) => item.name).join(",");
dataSetInFolerMove(names); dataSetInFolerMove(names);
}) })
.catch((error) => { .catch((error) => {
console.log(error); console.log(error);
erroeMove(error); erroeMove(error);
}); });
}; };
// 单数据集移动 // 单数据集移动
const dataSetMove = () => { const dataSetMove = () => {
getDataFileMoveRun({ getDataFileMoveRun({
projectId: projectId as string, projectId: projectId as string,
names: currentOperateFile.name, names: currentOperateFile.name,
spath: oldPathProvidedToDataSet, spath: oldPathProvidedToDataSet,
dpath: newPathProvidedToDataSet, dpath: newPathProvidedToDataSet,
}); });
}; };
// 多数据集移动 // 多数据集移动
const dataSetsMove = (datSetMoveList: Array<any>) => { const dataSetsMove = (datSetMoveList: Array<any>) => {
getDataFileMoveRun({ getDataFileMoveRun({
projectId: projectId as string, projectId: projectId as string,
names: datSetMoveList.map((item: any) => item.name).join(","), names: datSetMoveList.map((item: any) => item.name).join(","),
spath: oldPathProvidedToFileServer, spath: oldPathProvidedToFileServer,
dpath: newPath === "/" ? "/" : `${newPath}/`, dpath: newPath === "/" ? "/" : `${newPath}/`,
}); });
}; };
const renderLabel = (node: any) => { const renderLabel = (node: any) => {
return ( return (
<span className={style.treeLabel}> <span className={style.treeLabel}>
<img className={style.labelFolderIcon} src={folderIcon} alt="" /> <img className={style.labelFolderIcon} src={folderIcon} alt="" />
<span className={style.treeLabelText}>{node.name}</span> <span className={style.treeLabelText}>{node.name}</span>
</span> </span>
); );
}; };
const onNodeSelect = (a: any, b: any) => { const onNodeSelect = (a: any, b: any) => {
setNewPath(b); setNewPath(b);
setRootActive(false); setRootActive(false);
}; };
// 给路径去掉第一个'/'然后结尾加上文件名 方便后面直接使用 // 给路径去掉第一个'/'然后结尾加上文件名 方便后面直接使用
const idFunc = (item: any) => { const idFunc = (item: any) => {
return `${item.dir.substr(1)}${item.name}`; return `${item.dir.substr(1)}${item.name}`;
}; };
const handleRoot = () => { const handleRoot = () => {
setNewPath("/"); setNewPath("/");
setRootActive(true); setRootActive(true);
}; };
return ( return (
<MyDialog <MyDialog
handleSubmit={handleMoveFileSubmit} handleSubmit={handleMoveFileSubmit}
onRef={moveFileDialogRef} onRef={moveFileDialogRef}
title="移动至" title="移动至"
submitloading={moveFileSubmitloading} submitloading={moveFileSubmitloading}
> >
<div <div
className={classNames({ className={classNames({
[style.rootTitle]: true, [style.rootTitle]: true,
[style.rootTitleActive]: rootActive, [style.rootTitleActive]: rootActive,
})} })}
onClick={handleRoot} onClick={handleRoot}
> >
<img className={style.bigFolderIcon} src={bigFolderIcon} alt="" /> <img className={style.bigFolderIcon} src={bigFolderIcon} alt="" />
ProjectData ProjectData
</div> </div>
<MyTreeView <MyTreeView
// treeData={treeData} treeData={renderTreeData}
treeData={renderTreeData} renderLabel={renderLabel}
renderLabel={renderLabel} onNodeSelect={onNodeSelect}
onNodeSelect={onNodeSelect} idFunc={idFunc}
idFunc={idFunc} treeViewSx={{
treeViewSx={{ width: 400,
width: 400, overflow: "hidden",
overflow: "hidden", }}
}} ></MyTreeView>
></MyTreeView> </MyDialog>
</MyDialog> );
);
}; };
export default MoveFile; export default MoveFile;
...@@ -28,726 +28,724 @@ import { useLocation } from "react-router-dom"; ...@@ -28,726 +28,724 @@ import { useLocation } from "react-router-dom";
import { getDataFind, getDataFileSearch } from "@/api/project_api"; import { getDataFind, getDataFileSearch } from "@/api/project_api";
const theme = createTheme({ const theme = createTheme({
palette: { palette: {
neutral: { neutral: {
main: "#1370FF", main: "#1370FF",
contrastText: "#fff", contrastText: "#fff",
}, },
}, },
}); });
declare module "@mui/material/styles" { declare module "@mui/material/styles" {
interface Palette { interface Palette {
neutral: Palette["primary"]; neutral: Palette["primary"];
} }
interface PaletteOptions { interface PaletteOptions {
neutral?: PaletteOptions["primary"]; neutral?: PaletteOptions["primary"];
} }
} }
declare module "@mui/material/Button" { declare module "@mui/material/Button" {
interface ButtonPropsColorOverrides { interface ButtonPropsColorOverrides {
neutral: true; neutral: true;
} }
} }
const ProjectData = observer(() => { const ProjectData = observer(() => {
const isPass = usePass(); const isPass = usePass();
const { currentProjectStore } = useStores(); const { currentProjectStore } = useStores();
const fileToken = toJS(currentProjectStore.currentProjectInfo.filetoken); const fileToken = toJS(currentProjectStore.currentProjectInfo.filetoken);
const projectId = toJS(currentProjectStore.currentProjectInfo.id); const projectId = toJS(currentProjectStore.currentProjectInfo.id);
/** 路由信息 */ /** 路由信息 */
const location = useLocation(); const location = useLocation();
// 当前文件路径 // 当前文件路径
const [path, setPath] = useState<String>("/"); const [path, setPath] = useState<String>("/");
const [tableLoadding, setTableLoadding] = useState(false); const [tableLoadding, setTableLoadding] = useState(false);
// 防止用户连续点击文件夹造成路径显示错误 // 防止用户连续点击文件夹造成路径显示错误
const [debounce, setDebounce] = useState(false); const [debounce, setDebounce] = useState(false);
// 点击操作列中的按钮 会设置当前点击的文件 // 点击操作列中的按钮 会设置当前点击的文件
const [currentOperateFile, setCurrentOperateFile] = useState<any>(null); const [currentOperateFile, setCurrentOperateFile] = useState<any>(null);
// 1文件 2数据集 // 1文件 2数据集
const [activeTab, setActiveTab] = useState(1); const [activeTab, setActiveTab] = useState(1);
// 复选框选中的文件名称数组 // 复选框选中的文件名称数组
const [selectIds, setSelectIds] = useState<Array<string>>([]); const [selectIds, setSelectIds] = useState<Array<string>>([]);
const [keyWord, setKeyWord] = useState(""); const [keyWord, setKeyWord] = useState("");
// 文件夹、文件列表 // 文件夹、文件列表
const [list, setList] = useState<any>([]); const [list, setList] = useState<any>([]);
// 数据集列表 不带文件 // 数据集列表 不带文件
const [dataSetList, setDataSetList] = useState<any>([]); const [dataSetList, setDataSetList] = useState<any>([]);
let tableRef: any = React.createRef(); let tableRef: any = React.createRef();
// 是否显示复选框 用户搜索文件后不显示 其他情况显示 // 是否显示复选框 用户搜索文件后不显示 其他情况显示
const [showCheckBox, setShowCheckBox] = useState<boolean>(true); const [showCheckBox, setShowCheckBox] = useState<boolean>(true);
// 切换文件、数据集 // 切换文件、数据集
const handleChangeListType = (e: number) => { const handleChangeListType = (e: number) => {
if (isPass("PROJECT_DATA_TYPECHANAGE")) { if (isPass("PROJECT_DATA_TYPECHANAGE")) {
setActiveTab(e); setActiveTab(e);
setSelectIds([]); setSelectIds([]);
tableRef?.current?.initSelectedFunc([]); tableRef?.current?.initSelectedFunc([]);
} }
}; };
useEffect(() => { useEffect(() => {
const locationInfo: any = location?.state; const locationInfo: any = location?.state;
setPath(locationInfo?.pathName || "/"); setPath(locationInfo?.pathName || "/");
}, [location]); }, [location]);
// 列表展示的数据 // 列表展示的数据
const showList = useMemo(() => { const showList = useMemo(() => {
if (activeTab === 1) { if (activeTab === 1) {
// 做排序 文件夹在前 // 做排序 文件夹在前
let folderList: any = []; let folderList: any = [];
let fileList: any = []; let fileList: any = [];
list.forEach((item: any) => { list.forEach((item: any) => {
if (item.type === "directory") { if (item.type === "directory") {
folderList.push(item); folderList.push(item);
} else { } else {
fileList.push(item); fileList.push(item);
} }
}); });
return [...folderList, ...fileList]; return [...folderList, ...fileList];
} 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]; return [...folderList, ...dataSetList];
} }
}, [list, dataSetList, activeTab]); }, [list, dataSetList, activeTab]);
// 是否全是文件夹 // 是否全是文件夹
const isAllDirectory = useMemo(() => { const isAllDirectory = useMemo(() => {
return showList.every((li: any) => { return showList.every((li: any) => {
return li.type === "directory"; return li.type === "directory";
}); });
}, [showList]); }, [showList]);
// 全(文件、文件夹、数据集)列表 // 全(文件、文件夹、数据集)列表
const allList = useMemo(() => { const allList = useMemo(() => {
return [...list, ...dataSetList]; return [...list, ...dataSetList];
}, [list, dataSetList]); }, [list, dataSetList]);
// 全局搜索数据集 // 全局搜索数据集
const { run: getDataFileSearchRun } = useMyRequest(getDataFileSearch, { const { run: getDataFileSearchRun } = useMyRequest(getDataFileSearch, {
onSuccess: (res: any) => { onSuccess: (res: any) => {
const dataSetList = res.data.map((item: any) => { const dataSetList = res.data.map((item: any) => {
return { return {
...item, ...item,
type: "dataSet", type: "dataSet",
}; };
}); });
setDataSetList(dataSetList); setDataSetList(dataSetList);
setSelectIds([]); setSelectIds([]);
setDebounce(false); setDebounce(false);
tableRef?.current?.initSelectedFunc([]); tableRef?.current?.initSelectedFunc([]);
setShowCheckBox(false); setShowCheckBox(false);
}, },
}); });
// 获取某路径下的数据集 // 获取某路径下的数据集
const { run: getDataFindRun } = useMyRequest(getDataFind, { const { run: getDataFindRun } = useMyRequest(getDataFind, {
onSuccess: (res: any) => { onSuccess: (res: any) => {
const dataSetList = res.data.map((item: any) => { const dataSetList = res.data.map((item: any) => {
return { return {
...item, ...item,
type: "dataSet", type: "dataSet",
}; };
}); });
setDataSetList(dataSetList); setDataSetList(dataSetList);
setSelectIds([]); setSelectIds([]);
setDebounce(false); setDebounce(false);
tableRef?.current?.initSelectedFunc([]); tableRef?.current?.initSelectedFunc([]);
setShowCheckBox(true); setShowCheckBox(true);
}, },
}); });
// 获取某路径下的数据集 // 获取某路径下的数据集
const getDataSetList = useCallback(() => { const getDataSetList = useCallback(() => {
if (keyWord) { if (keyWord) {
return; return;
} else if (projectId) { } else if (projectId) {
return getDataFindRun({ return getDataFindRun({
projectId: projectId as string, projectId: projectId as string,
path: path === "/" ? "/" : `${path}/`, path: path === "/" ? "/" : `${path}/`,
}); });
} }
}, [keyWord, path, projectId, getDataFindRun]); }, [keyWord, path, projectId, getDataFindRun]);
// 全局搜索数据集 // 全局搜索数据集
const getDataSetListSearch = useCallback(() => { const getDataSetListSearch = useCallback(() => {
if (keyWord && projectId) { if (keyWord && projectId) {
return getDataFileSearchRun({ return getDataFileSearchRun({
projectId: projectId as string, projectId: projectId as string,
name: keyWord, name: keyWord,
}); });
} else { } else {
return getDataSetList(); return getDataSetList();
} }
}, [keyWord, projectId, getDataFileSearchRun, getDataSetList]); }, [keyWord, projectId, getDataFileSearchRun, getDataSetList]);
useEffect(() => { useEffect(() => {
getDataSetList(); getDataSetList();
}, [getDataSetList]); }, [getDataSetList]);
const getList = useCallback(() => { const getList = useCallback(() => {
if (keyWord) { if (keyWord) {
return; return;
} else if (fileToken && projectId) { } else if (fileToken && projectId) {
setTableLoadding(true); setTableLoadding(true);
return CloudEController.JobOutFileList( return CloudEController.JobOutFileList(
path, path,
fileToken, fileToken,
projectId, projectId,
false false
)?.then((res) => { )?.then((res) => {
setTableLoadding(false); setTableLoadding(false);
if (Array.isArray(res.data)) { if (Array.isArray(res.data)) {
setList(res.data); setList(res.data);
} else { } else {
setList([]); setList([]);
} }
setSelectIds([]); setSelectIds([]);
setDebounce(false); setDebounce(false);
setShowCheckBox(true); setShowCheckBox(true);
}); });
} }
}, [fileToken, path, projectId, keyWord]); }, [fileToken, path, projectId, keyWord]);
useEffect(() => { useEffect(() => {
getList(); getList();
}, [getList]); }, [getList]);
// 全局搜索文件列表 // 全局搜索文件列表
const searchFileList = useCallback(() => { const searchFileList = useCallback(() => {
if (!keyWord) { if (!keyWord) {
getList(); getList();
} else { } else {
if (fileToken && projectId) { if (fileToken && projectId) {
setTableLoadding(true); setTableLoadding(true);
setPath("/"); setPath("/");
return CloudEController.JobSearchFileList( return CloudEController.JobSearchFileList(
keyWord, keyWord,
"/", "/",
fileToken, fileToken,
projectId, projectId,
false false
)?.then((res) => { )?.then((res) => {
setTableLoadding(false); setTableLoadding(false);
if (Array.isArray(res.data)) { if (Array.isArray(res.data)) {
setList(res.data); setList(res.data);
} else { } else {
setList([]); setList([]);
} }
setSelectIds([]); setSelectIds([]);
setDebounce(false); setDebounce(false);
setShowCheckBox(false); setShowCheckBox(false);
}); });
} }
} }
}, [fileToken, projectId, keyWord, getList]); }, [fileToken, projectId, keyWord, getList]);
// 刷新 // 刷新
const handleRefresh = () => { const handleRefresh = () => {
if (isPass("PROJECT_DATA_REFRESH", "USER")) { if (isPass("PROJECT_DATA_REFRESH", "USER")) {
tableRef?.current?.initSelectedFunc([]); tableRef?.current?.initSelectedFunc([]);
setSelectIds([]); setSelectIds([]);
if (keyWord) { if (keyWord) {
searchFileList(); searchFileList();
getDataSetListSearch(); getDataSetListSearch();
} else { } else {
getList(); getList();
getDataSetList(); getDataSetList();
} }
} }
}; };
// 搜索值改变 // 搜索值改变
const handleKeyWordChange = (e: any) => { const handleKeyWordChange = (e: any) => {
if (e.target.value.length > 30) { if (e.target.value.length > 30) {
return; return;
} }
setKeyWord(e.target.value); setKeyWord(e.target.value);
}; };
// 按回车搜索 // 按回车搜索
const handleKeyWordChangeKeyUp = (e: any) => { const handleKeyWordChangeKeyUp = (e: any) => {
if (e.keyCode === 13) { if (e.keyCode === 13) {
searchFileList(); searchFileList();
getDataSetListSearch(); getDataSetListSearch();
} }
}; };
// todo name sort // todo name sort
// table配置 // table配置
const versionsHeadCells = useMemo(() => { const versionsHeadCells = useMemo(() => {
if (showCheckBox) { if (showCheckBox) {
return [ return [
{ id: "checkbox" }, { id: "checkbox" },
{ id: "name", numeric: false, label: "名称", width: "25%" }, { id: "name", numeric: false, label: "名称", width: "25%" },
{ id: "size", numeric: false, label: "大小", width: "25%", sort: true }, { id: "size", numeric: false, label: "大小", width: "25%", sort: true },
{ {
id: "mtime", id: "mtime",
numeric: false, numeric: false,
label: "创建时间", label: "创建时间",
width: "25%", width: "25%",
sort: true, sort: true,
}, },
{ id: "caozuo", numeric: false, label: "操作", width: "25%" }, { id: "caozuo", numeric: false, label: "操作", width: "25%" },
]; ];
} else { } else {
return [ return [
{ id: "name", numeric: false, label: "名称", width: "25%" }, { id: "name", numeric: false, label: "名称", width: "25%" },
{ id: "size", numeric: false, label: "大小", width: "25%", sort: true }, { id: "size", numeric: false, label: "大小", width: "25%", sort: true },
{ {
id: "mtime", id: "mtime",
numeric: false, numeric: false,
label: "创建时间", label: "创建时间",
width: "25%", width: "25%",
sort: true, sort: true,
}, },
{ id: "caozuo", numeric: false, label: "操作", width: "25%" }, { id: "caozuo", numeric: false, label: "操作", width: "25%" },
]; ];
} }
}, [showCheckBox]); }, [showCheckBox]);
// 点击复选框 // 点击复选框
const hanldeCheckbox = (e: any) => { const hanldeCheckbox = (e: any) => {
const selectarr = e.map((item: any) => { const selectarr = e.map((item: any) => {
let andIndex = item.indexOf("&index="); let andIndex = item.indexOf("&index=");
return item.slice(5, andIndex); return item.slice(5, andIndex);
}); });
setSelectIds(selectarr); setSelectIds(selectarr);
}; };
// 文件夹下钻 // 文件夹下钻
const handleViewFolders = (item: any) => { const handleViewFolders = (item: any) => {
if (debounce) { if (debounce) {
return; return;
} else { } else {
setDebounce(true); setDebounce(true);
if (path === "/") { if (path === "/") {
setPath(`/${item.name}`); setPath(`/${item.name}`);
} else { } else {
setPath(`${path}/${item.name}`); setPath(`${path}/${item.name}`);
} }
} }
}; };
// table配置 // table配置
const renderName = (item: any) => { const renderName = (item: any) => {
if (item.type === "directory") { if (item.type === "directory") {
return ( return (
<span <span
className={classnames({ className={classnames({
[style.folderIconBox]: true, [style.folderIconBox]: true,
[style.folderPointer]: true, [style.folderPointer]: true,
})} })}
onClick={() => handleViewFolders(item)} onClick={() => handleViewFolders(item)}
> >
<img className={style.folderIcon} src={folderIcon} alt="" /> <img className={style.folderIcon} src={folderIcon} alt="" />
{item.name} {item.name}
</span> </span>
); );
} else if (item.type === "dataSet") { } else if (item.type === "dataSet") {
return ( return (
<span className={style.folderIconBox}> <span className={style.folderIconBox}>
<img className={style.folderIcon} src={dataSetIcon} alt="" /> <img className={style.folderIcon} src={dataSetIcon} alt="" />
{item.name} {item.name}
</span> </span>
); );
} else { } else {
return ( return (
<span className={style.folderIconBox}> <span className={style.folderIconBox}>
<img className={style.folderIcon} src={fileIcon} alt="" /> <img className={style.folderIcon} src={fileIcon} alt="" />
{item.name} {item.name}
</span> </span>
); );
} }
}; };
// table配置 // table配置
const renderSize = (item: any) => { const renderSize = (item: any) => {
if (item.type === "dataSet") { if (item.type === "dataSet") {
return `${item.size}条`; return `${item.size}条`;
} }
return `${item.size ? storageUnitFromB(Number(item.size)) : "-"}`; return `${item.size ? storageUnitFromB(Number(item.size)) : "-"}`;
}; };
// table配置 // table配置
const renderMtime = (item: any) => { const renderMtime = (item: any) => {
return String(moment(item.mtime).format("YYYY-MM-DD HH:mm:ss")); return String(moment(item.mtime).format("YYYY-MM-DD HH:mm:ss"));
}; };
// table配置 // table配置
const renderButtons = (item: any) => { const renderButtons = (item: any) => {
return ( return (
<span style={{ whiteSpace: "nowrap" }}> <span style={{ whiteSpace: "nowrap" }}>
{!isAllDirectory && ( {!isAllDirectory && (
<Button <Button
sx={{ sx={{
position: "relative", position: "relative",
left: "-4px", left: "-4px",
minWidth: "10px", minWidth: "10px",
marginRight: "10px", marginRight: "10px",
visibility: visibility:
item.type !== "dataSet" && item.type !== "directory" item.type !== "dataSet" && item.type !== "directory"
? "visible" ? "visible"
: "hidden", : "hidden",
}} }}
variant="text" variant="text"
size="small" size="small"
disabled={selectIds.length > 0 || !isPass("PROJECT_DATA_DOWNLOAD")} disabled={selectIds.length > 0 || !isPass("PROJECT_DATA_DOWNLOAD")}
onClick={() => hanleDownloadFile(item)} onClick={() => hanleDownloadFile(item)}
> >
下载 下载
</Button> </Button>
)} )}
<Button <Button
sx={{ sx={{
position: "relative", position: "relative",
left: "-4px", left: "-4px",
minWidth: "10px", minWidth: "10px",
marginRight: "10px", marginRight: "10px",
}} }}
variant="text" variant="text"
size="small" size="small"
onClick={() => hanleShowMoveFileDialog(item)} onClick={() => hanleShowMoveFileDialog(item)}
disabled={ disabled={
selectIds.length > 0 || !isPass("PROJECT_DATA_MOVE", "USER") selectIds.length > 0 || !isPass("PROJECT_DATA_MOVE", "USER")
} }
> >
移动至 移动至
</Button> </Button>
<Button <Button
sx={{ sx={{
position: "relative", position: "relative",
left: "-4px", left: "-4px",
minWidth: "10px", minWidth: "10px",
marginRight: "10px", marginRight: "10px",
}} }}
variant="text" variant="text"
size="small" size="small"
color="error" color="error"
onClick={() => hanleShowDeleteDialogRef(item)} onClick={() => hanleShowDeleteDialogRef(item)}
disabled={ disabled={
selectIds.length > 0 || !isPass("PROJECT_DATA_DELETE", "USER") selectIds.length > 0 || !isPass("PROJECT_DATA_DELETE", "USER")
} }
> >
删除 删除
</Button> </Button>
</span> </span>
); );
}; };
// 文件上传 // 文件上传
let UpLoaderFileRef: any = React.createRef(); let UpLoaderFileRef: any = React.createRef();
const hanleShowUpLoaderFileDialog = () => { const hanleShowUpLoaderFileDialog = () => {
UpLoaderFileRef.current.showDialog(); UpLoaderFileRef.current.showDialog();
}; };
// 新增文件 // 新增文件
let addFolderRef: any = React.createRef(); let addFolderRef: any = React.createRef();
const hanleShowAddFolderDialog = () => { const hanleShowAddFolderDialog = () => {
addFolderRef.current.showDialog(); addFolderRef.current.showDialog();
}; };
// 下载文件 // 下载文件
const hanleDownloadFile = (item: any) => { const hanleDownloadFile = (item: any) => {
console.log(item); const downloadPath =
const downloadPath = path === "/" ? `/${item.name}` : `${path}/${item.name}`;
path === "/" ? `/${item.name}` : `${path}/${item.name}`; CloudEController.JobFileDownload(
console.log(downloadPath); downloadPath,
CloudEController.JobFileDownload( fileToken as string,
downloadPath, projectId as string
fileToken as string, );
projectId as string };
);
}; // 文件移动
let moveFileRef: any = React.createRef();
// 文件移动
let moveFileRef: any = React.createRef(); const hanleShowMoveFileDialog = (item: any) => {
setCurrentOperateFile(item);
const hanleShowMoveFileDialog = (item: any) => { moveFileRef.current.showDialog();
setCurrentOperateFile(item); };
moveFileRef.current.showDialog();
}; // 删除弹窗
let deleteDialogRef: any = React.createRef();
// 删除弹窗 const hanleShowDeleteDialogRef = (item: any) => {
let deleteDialogRef: any = React.createRef(); setCurrentOperateFile(item);
const hanleShowDeleteDialogRef = (item: any) => { deleteDialogRef.current.showDialog();
setCurrentOperateFile(item); };
deleteDialogRef.current.showDialog();
}; // 批量移动
const handleBatchMove = () => {
// 批量移动 setCurrentOperateFile(null);
const handleBatchMove = () => { moveFileRef.current.showDialog();
setCurrentOperateFile(null); };
moveFileRef.current.showDialog();
}; // 批量删除
const handleBatchDelete = () => {
// 批量删除 setCurrentOperateFile(null);
const handleBatchDelete = () => { deleteDialogRef.current.showDialog();
setCurrentOperateFile(null); };
deleteDialogRef.current.showDialog();
}; // 前端展示的文件路径
const showPath = useMemo(() => {
// 前端展示的文件路径 if (path === "/") {
const showPath = useMemo(() => { return <span className={style.showPathSpan}>ProjectData</span>;
if (path === "/") { } else {
return <span className={style.showPathSpan}>ProjectData</span>; const pathArr = path.split("/");
} else { if (pathArr.length <= 4) {
const pathArr = path.split("/"); return pathArr.map((item, index) => {
if (pathArr.length <= 4) { return (
return pathArr.map((item, index) => { <span
return ( key={index}
<span onClick={() =>
key={index} setPath(
onClick={() => pathArr.slice(0, index + 1).join("/") === ""
setPath( ? "/"
pathArr.slice(0, index + 1).join("/") === "" : pathArr.slice(0, index + 1).join("/")
? "/" )
: pathArr.slice(0, index + 1).join("/") }
) className={classnames({
} [style.showPathSpan]: true,
className={classnames({ [style.showPathSpanActive]: index === pathArr.length - 1,
[style.showPathSpan]: true, })}
[style.showPathSpanActive]: index === pathArr.length - 1, >
})} {index === 0 ? "ProjectData" : item}{" "}
> {index === pathArr.length - 1 ? null : (
{index === 0 ? "ProjectData" : item}{" "} <i className={style.showPathI}>{">"}</i>
{index === pathArr.length - 1 ? null : ( )}
<i className={style.showPathI}>{">"}</i> </span>
)} );
</span> });
); } else {
}); return pathArr.map((item, index) => {
} else { return (
return pathArr.map((item, index) => { <span
return ( key={index}
<span onClick={() => {
key={index} if (index === 1) {
onClick={() => { return;
if (index === 1) { }
return; setPath(
} pathArr.slice(0, index + 1).join("/") === ""
setPath( ? "/"
pathArr.slice(0, index + 1).join("/") === "" : pathArr.slice(0, index + 1).join("/")
? "/" );
: pathArr.slice(0, index + 1).join("/") }}
); className={classnames({
}} [style.showPathSpan]: true,
className={classnames({ [style.showPathSpanActive]: index === pathArr.length - 1,
[style.showPathSpan]: true, })}
[style.showPathSpanActive]: index === pathArr.length - 1, >
})} {index === 0
> ? "ProjectData"
{index === 0 : index > pathArr.length - 4
? "ProjectData" ? item
: index > pathArr.length - 4 : ""}
? item {/* && index > pathArr.length - 4 */}
: ""} {index === pathArr.length - 1 ||
{/* && index > pathArr.length - 4 */} (index <= pathArr.length - 4 && index > 0) ? null : (
{index === pathArr.length - 1 || <i className={style.showPathI}>{">"}</i>
(index <= pathArr.length - 4 && index > 0) ? null : ( )}
<i className={style.showPathI}>{">"}</i> {index === 1 && "..."}
)} {index === 1 && <i className={style.showPathI}>{">"}</i>}
{index === 1 && "..."} </span>
{index === 1 && <i className={style.showPathI}>{">"}</i>} );
</span> });
); }
}); }
} }, [path]);
}
}, [path]); if (currentProjectStore.currentProjectInfo.name) {
return (
if (currentProjectStore.currentProjectInfo.name) { <ThemeProvider theme={theme}>
return ( <div className={style.projectData}>
<ThemeProvider theme={theme}> <div className={style.projectDataStickyTop}>
<div className={style.projectData}> <div className={style.projectDataTitle}>项目数据</div>
<div className={style.projectDataStickyTop}> <div className={style.projectDataHeader}>
<div className={style.projectDataTitle}>项目数据</div> <div className={style.projectDataButtonAndSearch}>
<div className={style.projectDataHeader}> <div className={style.projectDataButtonBox}>
<div className={style.projectDataButtonAndSearch}> <Button
<div className={style.projectDataButtonBox}> color="neutral"
<Button variant="contained"
color="neutral" size="small"
variant="contained" style={{ marginRight: "12px" }}
size="small" onClick={hanleShowUpLoaderFileDialog}
style={{ marginRight: "12px" }} disabled={
onClick={hanleShowUpLoaderFileDialog} selectIds.length !== 0 ||
disabled={ !isPass("PROJECT_DATA_UPLOAD", "USER")
selectIds.length !== 0 || }
!isPass("PROJECT_DATA_UPLOAD", "USER") >
} 上传文件
> </Button>
上传文件 <Button
</Button> color="neutral"
<Button variant="outlined"
color="neutral" size="small"
variant="outlined" onClick={hanleShowAddFolderDialog}
size="small" disabled={
onClick={hanleShowAddFolderDialog} selectIds.length !== 0 ||
disabled={ !isPass("PROJECT_DATA_ADDDIR", "USER")
selectIds.length !== 0 || }
!isPass("PROJECT_DATA_ADDDIR", "USER") >
} 新建文件夹
> </Button>
新建文件夹 </div>
</Button> <div className={style.projectDataSearch}>
</div> <InputBase
<div className={style.projectDataSearch}> className={style.searchInput}
<InputBase placeholder="输入关键词搜索"
className={style.searchInput} inputProps={{ "aria-label": "输入关键词搜索" }}
placeholder="输入关键词搜索" value={keyWord}
inputProps={{ "aria-label": "输入关键词搜索" }} onChange={handleKeyWordChange}
value={keyWord} style={{ width: "280px", fontSize: "14px" }}
onChange={handleKeyWordChange} onKeyUp={handleKeyWordChangeKeyUp}
style={{ width: "280px", fontSize: "14px" }} />
onKeyUp={handleKeyWordChangeKeyUp} <IconButton
/> type="submit"
<IconButton className={style.searchButton}
type="submit" aria-label="search"
className={style.searchButton} size="small"
aria-label="search" style={{ padding: "4px" }}
size="small" onClick={handleRefresh}
style={{ padding: "4px" }} >
onClick={handleRefresh} <SearchIcon
> className={style.searchIcon}
<SearchIcon style={{ color: "#999" }}
className={style.searchIcon} />
style={{ color: "#999" }} </IconButton>
/> </div>
</IconButton> </div>
</div> <div className={style.projectDataPathAndTabs}>
</div> <div className={style.projectDataPath}>{showPath}</div>
<div className={style.projectDataPathAndTabs}> <div className={style.projectDataTabsAndBtton}>
<div className={style.projectDataPath}>{showPath}</div> <div className={style.projectDataTabs}>
<div className={style.projectDataTabsAndBtton}> <div
<div className={style.projectDataTabs}> className={classnames({
<div [style.projectDataTab]: true,
className={classnames({ [style.projectDataTabActive]: activeTab === 1,
[style.projectDataTab]: true, })}
[style.projectDataTabActive]: activeTab === 1, // onClick={() => setActiveTab(1)}
})} onClick={() => handleChangeListType(1)}
// onClick={() => setActiveTab(1)} >
onClick={() => handleChangeListType(1)} 文件
> </div>
文件 <div
</div> className={classnames({
<div [style.projectDataTab]: true,
className={classnames({ [style.projectDataTabActive]: activeTab !== 1,
[style.projectDataTab]: true, })}
[style.projectDataTabActive]: activeTab !== 1, // onClick={() => setActiveTab(2)}
})} onClick={() => handleChangeListType(2)}
// onClick={() => setActiveTab(2)} >
onClick={() => handleChangeListType(2)} 数据集
> </div>
数据集 </div>
</div> <IconButton
</div> aria-label="refreshIcon"
<IconButton size="small"
aria-label="refreshIcon" onClick={handleRefresh}
size="small" disabled={!isPass("PROJECT_DATA_REFRESH", "USER")}
onClick={handleRefresh} >
disabled={!isPass("PROJECT_DATA_REFRESH", "USER")} <RefreshIcon />
> </IconButton>
<RefreshIcon /> </div>
</IconButton> </div>
</div> </div>
</div> <Table
</div> footer={false}
<Table rowHover={true}
footer={false} onRef={tableRef}
rowHover={true} nopadding={true}
onRef={tableRef} stickyheader={true}
nopadding={true} load={tableLoadding}
stickyheader={true} initSelected={selectIds}
load={tableLoadding} headCells={versionsHeadCells}
initSelected={selectIds} rowsPerPage={"99"}
headCells={versionsHeadCells} checkboxData={(e: any) => {
rowsPerPage={"99"} hanldeCheckbox(e);
checkboxData={(e: any) => { }}
hanldeCheckbox(e); rows={showList.map((item: any, index: number) => ({
}} ...item,
rows={showList.map((item: any, index: number) => ({ id: `name=${item.name}&index=${index}`,
...item, name: renderName(item),
id: `name=${item.name}&index=${index}`, size: renderSize(item),
name: renderName(item), mtime: renderMtime(item),
size: renderSize(item), caozuo: renderButtons(item),
mtime: renderMtime(item), }))}
caozuo: renderButtons(item), ></Table>
}))} {showList.length === 0 && (
></Table> <div className={style.noDataBox}>
{showList.length === 0 && ( <img className={style.noDataImg} src={noFile} alt="" />
<div className={style.noDataBox}> <span className={style.noDataText}>暂未开启模板</span>
<img className={style.noDataImg} src={noFile} alt="" /> </div>
<span className={style.noDataText}>暂未开启模板</span> )}
</div> </div>
)} {selectIds.length > 0 && (
</div> <div className={style.projectDataStickyBox}>
{selectIds.length > 0 && ( <Button
<div className={style.projectDataStickyBox}> color="error"
<Button variant="outlined"
color="error" size="small"
variant="outlined" style={{ marginRight: "12px" }}
size="small" onClick={handleBatchDelete}
style={{ marginRight: "12px" }} disabled={!isPass("PROJECT_DATA_DELETE", "USER")}
onClick={handleBatchDelete} >
disabled={!isPass("PROJECT_DATA_DELETE", "USER")} 批量删除({selectIds.length}
> </Button>
批量删除({selectIds.length} <Button
</Button> color="neutral"
<Button variant="contained"
color="neutral" size="small"
variant="contained" style={{ marginRight: "24px" }}
size="small" onClick={handleBatchMove}
style={{ marginRight: "24px" }} disabled={!isPass("PROJECT_DATA_MOVE", "USER")}
onClick={handleBatchMove} >
disabled={!isPass("PROJECT_DATA_MOVE", "USER")} 批量移动({selectIds.length}
> </Button>
批量移动({selectIds.length} </div>
</Button> )}
</div> <DeleteDialog
)} onRef={deleteDialogRef}
<DeleteDialog path={path}
onRef={deleteDialogRef} fileToken={fileToken}
path={path} projectId={projectId}
fileToken={fileToken} currentOperateFile={currentOperateFile}
projectId={projectId} selectIds={selectIds}
currentOperateFile={currentOperateFile} refresh={handleRefresh}
selectIds={selectIds} showList={showList}
refresh={handleRefresh} ></DeleteDialog>
showList={showList} <UpLoaderFile
></DeleteDialog> onRef={UpLoaderFileRef}
<UpLoaderFile path={path}
onRef={UpLoaderFileRef} list={allList}
path={path} ></UpLoaderFile>
list={allList} <AddFolder
></UpLoaderFile> onRef={addFolderRef}
<AddFolder list={allList}
onRef={addFolderRef} path={path}
list={allList} refresh={handleRefresh}
path={path} fileToken={fileToken}
refresh={handleRefresh} projectId={projectId}
fileToken={fileToken} ></AddFolder>
projectId={projectId} <MoveFile
></AddFolder> onRef={moveFileRef}
<MoveFile path={path}
onRef={moveFileRef} fileToken={fileToken}
path={path} projectId={projectId}
fileToken={fileToken} currentOperateFile={currentOperateFile}
projectId={projectId} selectIds={selectIds}
currentOperateFile={currentOperateFile} refresh={handleRefresh}
selectIds={selectIds} showList={showList}
refresh={handleRefresh} ></MoveFile>
showList={showList} </div>
></MoveFile> </ThemeProvider>
</div> );
</ThemeProvider> } else {
); return <NoProject />;
} else { }
return <NoProject />;
}
}); });
export default ProjectData; export default ProjectData;
...@@ -164,7 +164,7 @@ const ProjectSubmitWork = observer(() => { ...@@ -164,7 +164,7 @@ const ProjectSubmitWork = observer(() => {
}; };
const getDataSetSize = async (item: any, index: number) => { const getDataSetSize = async (item: any, index: number) => {
let path = item.path.slice(13); let path = item.path.slice(12);
const lastIndex = path.lastIndexOf("/"); const lastIndex = path.lastIndexOf("/");
if (lastIndex === -1) { if (lastIndex === -1) {
path = "/"; path = "/";
...@@ -184,7 +184,7 @@ const ProjectSubmitWork = observer(() => { ...@@ -184,7 +184,7 @@ const ProjectSubmitWork = observer(() => {
}; };
const getFileSize = (item: any, index: number) => { const getFileSize = (item: any, index: number) => {
let path = item.path.slice(13); let path = item.path.slice(12);
const lastIndex = path.lastIndexOf("/"); const lastIndex = path.lastIndexOf("/");
if (lastIndex === -1) { if (lastIndex === -1) {
path = "/"; path = "/";
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/ */
// import Dialog from "@/components/Material.Ui/Dialog"; // import Dialog from "@/components/Material.Ui/Dialog";
import { memo, useEffect, useMemo, useState } from "react"; import { memo, useEffect, useState } from "react";
import { observer } from "mobx-react-lite"; import { observer } from "mobx-react-lite";
import { toJS } from "mobx"; import { toJS } from "mobx";
...@@ -19,91 +19,91 @@ import { IDialogInfo } from "../interface"; ...@@ -19,91 +19,91 @@ import { IDialogInfo } from "../interface";
import { useMessage } from "@/components/MySnackbar"; import { useMessage } from "@/components/MySnackbar";
interface IProps { interface IProps {
setPermissionDialog: (val: IDialogInfo) => void; setPermissionDialog: (val: IDialogInfo) => void;
permissionDialog: IDialogInfo; permissionDialog: IDialogInfo;
getTableList: () => void; getTableList: () => void;
} }
const ChangePermission = observer((props: IProps) => { const ChangePermission = observer((props: IProps) => {
const { permissionDialog, setPermissionDialog, getTableList } = props; const { permissionDialog, setPermissionDialog, getTableList } = props;
const { currentProjectStore } = useStores(); const { currentProjectStore } = useStores();
const Message = useMessage(); const Message = useMessage();
const http = useHttp(); const http = useHttp();
const [selectOptions, setSelectOptions] = useState<IOption[]>([]); const [selectOptions, setSelectOptions] = useState<IOption[]>([]);
const [selectValue, setSelectValue] = useState<IOption | undefined>(); const [selectValue, setSelectValue] = useState<IOption | undefined>();
useEffect(() => { useEffect(() => {
if (permissionDialog?.isShow) { if (permissionDialog?.isShow) {
http.get<IResponse<any>>("/cpp/project/listroles").then((res) => { http.get<IResponse<any>>("/cpp/project/listroles").then((res) => {
const arr = []; const arr = [];
const { data } = res; const { data } = res;
for (const key in data) { for (const key in data) {
arr.push({ arr.push({
label: String(data[key]), label: String(data[key]),
value: key, value: key,
}); });
} }
setSelectOptions(arr); setSelectOptions(arr);
}); });
} }
}, [http, permissionDialog]); }, [http, permissionDialog]);
const changePermission = (val: any) => { const changePermission = (val: any) => {
setSelectValue(val); setSelectValue(val);
}; };
const onClose = () => { const onClose = () => {
setPermissionDialog({ isShow: false, username: "" }); setPermissionDialog({ isShow: false, username: "" });
}; };
const onConfirm = () => { const onConfirm = () => {
const projectInfo = toJS(currentProjectStore?.currentProjectInfo); const projectInfo = toJS(currentProjectStore?.currentProjectInfo);
http http
.put<IResponse<any>>( .put<IResponse<any>>(
`/cpp/project/updateuserrole?id=${projectInfo?.id || ""}&username=${ `/cpp/project/updateuserrole?id=${projectInfo?.id || ""}&username=${
permissionDialog.username permissionDialog.username
}&role=${selectValue?.value}` }&role=${selectValue?.value}`
) )
.then((res) => { .then((res) => {
const { errorCode } = res; const { errorCode } = res;
if (errorCode === 0) { if (errorCode === 0) {
Message.success("更改成功!"); Message.success("更改成功!");
getTableList(); getTableList();
setPermissionDialog({ isShow: false, username: "" }); setPermissionDialog({ isShow: false, username: "" });
} }
}); });
}; };
useEffect(() => { useEffect(() => {
const defaultValue = selectOptions.filter( const defaultValue = selectOptions.filter(
(every) => every.value === permissionDialog?.projectRole (every) => every.value === permissionDialog?.projectRole
); );
if (defaultValue?.length) { if (defaultValue?.length) {
setSelectValue(defaultValue[0]); setSelectValue(defaultValue[0]);
} else { } else {
setSelectValue({ value: "VIEWER", label: "查看者" }); setSelectValue({ value: "VIEWER", label: "查看者" });
} }
}, [permissionDialog, selectOptions]); }, [permissionDialog, selectOptions]);
return ( return (
<> <>
<Dialog <Dialog
open={permissionDialog?.isShow} open={permissionDialog?.isShow}
onClose={onClose} onClose={onClose}
onConfirm={onConfirm} onConfirm={onConfirm}
title="更改权限" title="更改权限"
> >
<div style={{ marginTop: 12 }}> <div style={{ marginTop: 12 }}>
<MySelect <MySelect
title="项目权限" title="项目权限"
value={selectValue} value={selectValue}
onChange={changePermission} onChange={changePermission}
options={selectOptions} options={selectOptions}
size="small" size="small"
/> />
</div> </div>
</Dialog> </Dialog>
</> </>
); );
}); });
export default memo(ChangePermission); export default memo(ChangePermission);
...@@ -24,7 +24,6 @@ import styles from "./index.module.css"; ...@@ -24,7 +24,6 @@ import styles from "./index.module.css";
import { IDialogInfo } from "./interface"; import { IDialogInfo } from "./interface";
import { toJS } from "mobx"; import { toJS } from "mobx";
import { useStores } from "@/store"; import { useStores } from "@/store";
import { isProjectOwner } from "@/utils/util";
import { observer } from "mobx-react"; import { observer } from "mobx-react";
const ProjectMembers = observer(() => { const ProjectMembers = observer(() => {
...@@ -104,7 +103,6 @@ const ProjectMembers = observer(() => { ...@@ -104,7 +103,6 @@ const ProjectMembers = observer(() => {
.then((res) => { .then((res) => {
const { data = {} } = res; const { data = {} } = res;
setTableData(data?.members || []); setTableData(data?.members || []);
console.log(data?.projectRole, data?.projectRole);
setProjectRole(data?.projectRole || ""); setProjectRole(data?.projectRole || "");
}); });
}, [currentProjectStore?.currentProjectInfo, http]); }, [currentProjectStore?.currentProjectInfo, http]);
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* @FilePath: /bkunyun/src/views/Project/ProjectSetting/index.tsx * @FilePath: /bkunyun/src/views/Project/ProjectSetting/index.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, useState, useMemo } from "react"; import { memo, useMemo } from "react";
import { Box } from "@mui/system"; import { Box } from "@mui/system";
import { useStores } from "@/store/index"; import { useStores } from "@/store/index";
...@@ -18,39 +18,39 @@ import BaseInfo from "./BaseInfo"; ...@@ -18,39 +18,39 @@ import BaseInfo from "./BaseInfo";
import Tabs from "@/components/mui/Tabs"; import Tabs from "@/components/mui/Tabs";
const ProjectSetting = observer(() => { const ProjectSetting = observer(() => {
const { currentProjectStore } = useStores(); const { currentProjectStore } = useStores();
const tabList = useMemo(() => { const tabList = useMemo(() => {
return [ return [
{ {
label: "项目成员", label: "项目成员",
value: "projectMember", value: "projectMember",
component: <ProjectMembers />, component: <ProjectMembers />,
}, },
{ {
label: "基础信息", label: "基础信息",
value: "baseInfo", value: "baseInfo",
component: <BaseInfo />, component: <BaseInfo />,
}, },
]; ];
}, []); }, []);
if (currentProjectStore.currentProjectInfo.name) { if (currentProjectStore.currentProjectInfo.name) {
return ( return (
<div style={{ padding: 24 }}> <div style={{ padding: 24 }}>
<div style={{ display: "flex", alignItems: "center" }}> <div style={{ display: "flex", alignItems: "center" }}>
<img src={projectImg} alt="项目logo" /> <img src={projectImg} alt="项目logo" />
<span style={{ marginLeft: 12 }}> <span style={{ marginLeft: 12 }}>
{currentProjectStore.currentProjectInfo.name} {currentProjectStore.currentProjectInfo.name}
</span> </span>
</div> </div>
<Box sx={{ width: "100%", typography: "body1" }}> <Box sx={{ width: "100%", typography: "body1" }}>
<Tabs tabList={tabList} /> <Tabs tabList={tabList} />
</Box> </Box>
</div> </div>
); );
} else { } else {
return <NoProject />; return <NoProject />;
} }
}); });
export default memo(ProjectSetting); export default memo(ProjectSetting);
import { ITemplateConfig, IRenderTasks, IRenderTask } from "../interface"; import { ITemplateConfig, IRenderTasks } from "../interface";
import styles from "./index.module.css"; import styles from "./index.module.css";
import MyInput from "@/components/mui/MyInput"; import MyInput from "@/components/mui/MyInput";
import Tooltip from "@mui/material/Tooltip"; import Tooltip from "@mui/material/Tooltip";
import classnames from "classnames"; import classnames from "classnames";
import { useState, useMemo, useImperativeHandle, useCallback } from "react"; import { useState, useMemo, useImperativeHandle } from "react";
import FileSelect from "@/components/FileSelect"; import FileSelect from "@/components/FileSelect";
import moment from "moment"; import moment from "moment";
import MySelect, { optionsTransform } from "../components/MySelect"; import MySelect, { optionsTransform } from "../components/MySelect";
import MyCheckBox from "@/components/mui/MyCheckBox"; import MyCheckBox from "@/components/mui/MyCheckBox";
import MyRadio from "@/components/mui/MyRadio"; import MyRadio from "@/components/mui/MyRadio";
import _ from "lodash";
import { getCheckResult } from "../util"; import { getCheckResult } from "../util";
import fileSelectIcon from "@/assets/project/fileSelect.svg"; import fileSelectIcon from "@/assets/project/fileSelect.svg";
import questionMark from "@/assets/project/questionMark.svg"; import questionMark from "@/assets/project/questionMark.svg";
......
...@@ -26,11 +26,12 @@ import fullScreen from "@/assets/project/fullScreen.svg"; ...@@ -26,11 +26,12 @@ import fullScreen from "@/assets/project/fullScreen.svg";
import partialScreen from "@/assets/project/partialScreen.svg"; import partialScreen from "@/assets/project/partialScreen.svg";
import { useMessage } from "@/components/MySnackbar"; import { useMessage } from "@/components/MySnackbar";
import { useStores } from "@/store"; import { useStores } from "@/store";
import { observer } from "mobx-react-lite";
import MyPopconfirm from "@/components/mui/MyPopconfirm"; import MyPopconfirm from "@/components/mui/MyPopconfirm";
import styles from "./index.module.css"; import styles from "./index.module.css";
const ProjectSubmitWork = () => { 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);
...@@ -291,6 +292,6 @@ const ProjectSubmitWork = () => { ...@@ -291,6 +292,6 @@ const ProjectSubmitWork = () => {
/> />
</div> </div>
); );
}; });
export default ProjectSubmitWork; export default ProjectSubmitWork;
...@@ -70,7 +70,6 @@ export type IDomType = ...@@ -70,7 +70,6 @@ export type IDomType =
| "dataset" | "dataset"
| "file" | "file"
| "input" | "input"
| "file"
| "select" | "select"
| "multipleselect" | "multipleselect"
| "radio" | "radio"
......
import { memo } from "react";
import { memo, useCallback, useEffect, useMemo, useState } from "react";
import styles from "../index.module.css";
import { Box, Typography } from "@mui/material"; import { Box, Typography } from "@mui/material";
import Button from "@mui/material/Button";
import Dialog from "@/components/mui/Dialog"; import Dialog from "@/components/mui/Dialog";
const SimpleDialog = (props: any) => { const SimpleDialog = (props: any) => {
const { openDialog, closeDialog, onConfirm, text, title } = props; const { openDialog, closeDialog, onConfirm, text, title } = props;
return ( return (
< > <>
<Dialog <Dialog
open={openDialog} open={openDialog}
onClose={closeDialog} onClose={closeDialog}
onConfirm={onConfirm} onConfirm={onConfirm}
title={title} title={title}
> >
<Box> <Box>
<Typography sx={{ fontSize: '14px', fontWeight: '400' }}>{text}</Typography> <Typography sx={{ fontSize: "14px", fontWeight: "400" }}>
</Box> {text}
</Dialog> </Typography>
</> </Box>
); </Dialog>
</>
);
}; };
export default memo(SimpleDialog); export default memo(SimpleDialog);
...@@ -7,18 +7,20 @@ ...@@ -7,18 +7,20 @@
* @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 SearchIcon from "@mui/icons-material/Search"; import SearchIcon from "@mui/icons-material/Search";
import LinearProgress, { linearProgressClasses } from '@mui/material/LinearProgress'; import LinearProgress, {
import { TablePagination } from '@mui/material'; linearProgressClasses,
import TextField from '@mui/material/TextField'; } from "@mui/material/LinearProgress";
import MenuItem from '@mui/material/MenuItem'; import { TablePagination } from "@mui/material";
import TextField from "@mui/material/TextField";
import SimpleDialog from "./components/simpleDialog" import MenuItem from "@mui/material/MenuItem";
import SimpleDialog from "./components/simpleDialog";
import { useStores } from "@/store"; import { useStores } from "@/store";
import { observer } from "mobx-react-lite";
import useMyRequest from "@/hooks/useMyRequest"; import useMyRequest from "@/hooks/useMyRequest";
import ActionsComponent from "../../../../components/Material.Ui/Table/ActionsComponent" import ActionsComponent from "../../../../components/Material.Ui/Table/ActionsComponent"
import runTime from '../../../../assets/project/runTime.svg' import runTime from '../../../../assets/project/runTime.svg'
...@@ -32,38 +34,38 @@ import jobDel from '../../../../assets/project/jobDel.svg' ...@@ -32,38 +34,38 @@ import jobDel from '../../../../assets/project/jobDel.svg'
import noData from '../../../../assets/project/noTemplate.svg' import noData from '../../../../assets/project/noTemplate.svg'
import onload from '../../../../assets/project/onload.svg' import onload from '../../../../assets/project/onload.svg'
import { import {
getWorkflowJobList, getWorkflowJobList,
deleteWorkflowJob, deleteWorkflowJob,
cancelWorkflowJob cancelWorkflowJob,
} from "@/api/workbench_api"; } from "@/api/workbench_api";
import { toJS } from "mobx"; import { toJS } from "mobx";
import { observer } from "mobx-react-lite"; import { observer } from "mobx-react-lite";
import usePass from "@/hooks/usePass"; import usePass from "@/hooks/usePass";
import styles from "./index.module.css"; import styles from "./index.module.css";
import { toJS } from "mobx";
const currencies = [ const currencies = [
{ {
value: 'ALL', value: "ALL",
label: '全部', label: "全部",
}, },
{ {
value: 'RUNNING', value: "RUNNING",
label: '正在运行', label: "正在运行",
}, },
{ {
value: 'SUCCEEDED', value: "SUCCEEDED",
label: '运行成功', label: "运行成功",
}, },
{ {
value: 'FAILED', value: "FAILED",
label: '运行失败', label: "运行失败",
}, },
{ {
value: 'ABORTED', value: "ABORTED",
label: '运行终止', label: "运行终止",
}, },
]; ];
let timer: string | number | NodeJS.Timeout | null | undefined = null let timer: string | number | NodeJS.Timeout | null | undefined = null
...@@ -134,27 +136,37 @@ const ProjectMembers = observer(() => { ...@@ -134,27 +136,37 @@ const ProjectMembers = observer(() => {
setJobName(data.length > 30 ? data.slice(0, 30) : data); setJobName(data.length > 30 ? data.slice(0, 30) : data);
} }
const handleChange = (event: any) => { // 删除作业
setCurrency(event.target.value); const { run: delWorkflowJob } = useMyRequest(deleteWorkflowJob, {
}; onSuccess: (result: any) => {
setOpenDialog(false);
/** 关闭弹窗 */ getWorkflowJobInfo({
const closeDialog = () => { projectId: projectId as string,
setOpenDialog(false); page: page,
}; size: size,
name: jobName,
/** 弹窗确认 */ state: currency === "ALL" ? "" : currency,
const onConfirm = () => { });
if (dialogType === "del") { },
delWorkflowJob({ });
id: jobData
}) // 删除作业
} else { const { run: cancelWorkflowJobInfo } = useMyRequest(cancelWorkflowJob, {
cancelWorkflowJobInfo({ onSuccess: (result: any) => {
jobid: jobData setOpenDialog(false);
}) getWorkflowJobInfo({
} projectId: projectId as string,
}; page: page,
size: size,
name: jobName,
state: currency === "ALL" ? "" : currency,
});
},
});
const searchChange = (data: any) => {
setJobName(data.length > 30 ? data.slice(0, 30) : data);
};
useEffect(() => { useEffect(() => {
getWorkflowJobInfo({ getWorkflowJobInfo({
...@@ -166,85 +178,76 @@ const ProjectMembers = observer(() => { ...@@ -166,85 +178,76 @@ const ProjectMembers = observer(() => {
}); });
}, [projectId, getWorkflowJobInfo]); }, [projectId, getWorkflowJobInfo]);
const handleChangePage = (event: any, newPage: any) => { /** 关闭弹窗 */
setPage(newPage) const closeDialog = () => {
getWorkflowJobInfo({ setOpenDialog(false);
projectId: currentProjectStore.currentProjectInfo.id as string, };
page: newPage,
size: size, /** 弹窗确认 */
name: jobName, const onConfirm = () => {
state: currency === 'ALL' ? "" : currency if (dialogType === "del") {
}); delWorkflowJob({
} id: jobData,
});
const handleChangeRowsPerPage = (event: any) => { } else {
setRowsPerPage(event.target.value) cancelWorkflowJobInfo({
setSize(event.target.value) jobid: jobData,
getWorkflowJobInfo({ });
projectId: currentProjectStore.currentProjectInfo.id as string, }
page: page, };
size: event.target.value,
name: jobName, useEffect(() => {
state: currency === 'ALL' ? "" : currency getWorkflowJobInfo({
}); projectId: projectId as string,
} page: page,
size: size,
useEffect(() => { name: jobName,
setTimeout(() => { state: currency === "ALL" ? "" : currency,
getWorkflowJobInfo({ });
projectId: currentProjectStore.currentProjectInfo.id as string, }, [
page: page, currentProjectStore.currentProjectInfo.id,
size: size, getWorkflowJobInfo,
name: jobName, projectId,
state: currency === 'ALL' ? "" : currency page,
}); size,
}, 300) jobName,
}, [jobName, currency]); currency,
]);
const renderStatusIcon = (data: string) => {
switch (data) { const handleChangePage = (event: any, newPage: any) => {
case "RUNNING": setPage(newPage);
return jobRun getWorkflowJobInfo({
case "ABORTED": projectId: projectId as string,
return jobCadence page: newPage,
case "FAILED": size: size,
return jobFail name: jobName,
case "SUCCEEDED": state: currency === "ALL" ? "" : currency,
return jobSue });
default: };
return jobCadence
} const handleChangeRowsPerPage = (event: any) => {
} setRowsPerPage(event.target.value);
setSize(event.target.value);
const renderStatusText = (data: string) => { getWorkflowJobInfo({
switch (data) { projectId: projectId as string,
case "RUNNING": page: page,
return '正在运行' size: event.target.value,
case "ABORTED": name: jobName,
return '运行终止' state: currency === "ALL" ? "" : currency,
case "FAILED": });
return '运行失败' };
case "SUCCEEDED":
return '运行成功' useEffect(() => {
default: setTimeout(() => {
return '未知' getWorkflowJobInfo({
} projectId: projectId as string,
} page: page,
size: size,
const renderProgress = (data: any) => { name: jobName,
switch (data) { state: currency === "ALL" ? "" : currency,
case "RUNNING": });
return '#1370FF' }, 300);
case "ABORTED": }, [jobName, currency, projectId, getWorkflowJobInfo, page, size]);
return '#C2C6CC'
case "FAILED":
return '#FF4E4E'
case "SUCCEEDED":
return '#0DD09B'
default:
return '#C2C6CC'
}
}
/** 点击每一行 */ /** 点击每一行 */
const rowClick = useCallback( const rowClick = useCallback(
...@@ -256,8 +259,20 @@ const ProjectMembers = observer(() => { ...@@ -256,8 +259,20 @@ const ProjectMembers = observer(() => {
[navigate], [navigate],
); );
return ( const renderStatusText = (data: string) => {
<Box className={styles.headerBox}> switch (data) {
case "RUNNING":
return "正在运行";
case "ABORTED":
return "运行终止";
case "FAILED":
return "运行失败";
case "SUCCEEDED":
return "运行成功";
default:
return "未知";
}
};
<Box className={styles.tabHeader}> <Box className={styles.tabHeader}>
...@@ -314,7 +329,19 @@ const ProjectMembers = observer(() => { ...@@ -314,7 +329,19 @@ const ProjectMembers = observer(() => {
<img alt="" src={onload} /> <img alt="" src={onload} />
</Box> </Box>
</Box> return (
<Box className={styles.headerBox}>
<Box className={styles.tabHeader}>
<OutlinedInput
onChange={(e: any) => {
searchChange(e.target.value);
}}
value={jobName}
placeholder="输入关键词搜索"
size="small"
sx={{ width: 340, height: 32 }}
endAdornment={<SearchIcon style={{ color: "#8A9099" }} />}
/>
<Box className={styles.body}> <Box className={styles.body}>
{ {
...@@ -403,25 +430,36 @@ const ProjectMembers = observer(() => { ...@@ -403,25 +430,36 @@ const ProjectMembers = observer(() => {
} }
</Box> </Box>
<TablePagination <Box className={styles.tabBoxJobOperate}>
rowsPerPageOptions={[5, 10, 20, 50]} <img
labelRowsPerPage={'每页行数:'} alt=""
ActionsComponent={ActionsComponent} src={item.state === "RUNNING" ? jobStop : jobDel}
component="div" style={{ cursor: "pointer" }}
count={count || jobList.length} onClick={(event) => {
rowsPerPage={rowsPerPage || 10} event.stopPropagation();
page={page} event.nativeEvent.stopImmediatePropagation();
onPageChange={handleChangePage}// setJobData(item.id);
onRowsPerPageChange={handleChangeRowsPerPage}// setOpenDialog(true);
/> setDialogType(item.state === "RUNNING" ? "stop" : "del");
}}
<SimpleDialog />
text={dialogType === "del" ? '任务被删除后将无法恢复,确认继续吗?' : '正在运行的任务终止后将无法重新运行,确认继续吗?'} </Box>
title={dialogType === "del" ? '删除任务' : '终止任务'} </Box>
openDialog={openDialog} );
closeDialog={closeDialog} })}
onConfirm={onConfirm} </Box>
/>
<TablePagination
rowsPerPageOptions={[5, 10, 20, 50]}
labelRowsPerPage={"每页行数:"}
ActionsComponent={ActionsComponent}
component="div"
count={count || jobList.length}
rowsPerPage={rowsPerPage || 10}
page={page}
onPageChange={handleChangePage} //
onRowsPerPageChange={handleChangeRowsPerPage} //
/>
</Box > </Box >
); );
......
import { memo, useEffect, useState, useMemo } from "react"; import { useEffect, useState, useMemo } from "react";
import style from "./index.module.css"; import style from "./index.module.css";
import classNames from "classnames"; import classNames from "classnames";
import CloseOutlinedIcon from "@mui/icons-material/CloseOutlined"; import CloseOutlinedIcon from "@mui/icons-material/CloseOutlined";
...@@ -44,9 +44,7 @@ const AddTemplate = observer((props: IAddTemplateProps) => { ...@@ -44,9 +44,7 @@ const AddTemplate = observer((props: IAddTemplateProps) => {
const productId = toJS(currentProjectStore.currentProductInfo.id); const productId = toJS(currentProjectStore.currentProductInfo.id);
const { setShowAddTemplate, getTemplateInfo } = props; const { setShowAddTemplate, getTemplateInfo } = props;
const handleSearch = (value: string) => { const handleSearch = (value: string) => {};
console.log(value);
};
/** 可增加模板列表 */ /** 可增加模板列表 */
const [addTemplateList, setAddTemplateList] = useState([]); const [addTemplateList, setAddTemplateList] = useState([]);
...@@ -83,7 +81,6 @@ const AddTemplate = observer((props: IAddTemplateProps) => { ...@@ -83,7 +81,6 @@ const AddTemplate = observer((props: IAddTemplateProps) => {
}); });
const handleAddTemplate = () => { const handleAddTemplate = () => {
console.log("handleAddTemplate");
addTemplate({ addTemplate({
projectId: projectId as string, projectId: projectId as string,
workflowSpecIds: selectTemplateData, workflowSpecIds: selectTemplateData,
...@@ -93,7 +90,6 @@ const AddTemplate = observer((props: IAddTemplateProps) => { ...@@ -93,7 +90,6 @@ const AddTemplate = observer((props: IAddTemplateProps) => {
// 添加工作流模板-获取模板列表 // 添加工作流模板-获取模板列表
const { run: getAddTemplateList } = useMyRequest(getAddWorkbenchTemplate, { const { run: getAddTemplateList } = useMyRequest(getAddWorkbenchTemplate, {
onSuccess: (result: any) => { onSuccess: (result: any) => {
console.log(result);
setAddTemplateList(result.data); setAddTemplateList(result.data);
// setOpenAddTemplate(true); // setOpenAddTemplate(true);
}, },
......
import { memo } from "react";
import { memo, useCallback, useEffect, useMemo, useState } from "react";
import styles from "../index.module.css";
import { Box, Typography } from "@mui/material"; import { Box, Typography } from "@mui/material";
import Button from "@mui/material/Button";
import Dialog from "@/components/mui/Dialog"; import Dialog from "@/components/mui/Dialog";
const SimpleDialog = (props: any) => { const SimpleDialog = (props: any) => {
const { openDialog, closeDialog, onConfirm, text, title } = props; const { openDialog, closeDialog, onConfirm, text, title } = props;
return ( return (
< > <>
<Dialog <Dialog
open={openDialog} open={openDialog}
onClose={closeDialog} onClose={closeDialog}
onConfirm={onConfirm} onConfirm={onConfirm}
title={title} title={title}
> >
<Box> <Box>
<Typography sx={{ fontSize: '14px', fontWeight: '400' }}>{text}</Typography> <Typography sx={{ fontSize: "14px", fontWeight: "400" }}>
</Box> {text}
</Dialog> </Typography>
</> </Box>
); </Dialog>
</>
);
}; };
export default memo(SimpleDialog); export default memo(SimpleDialog);
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* @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, useEffect, useMemo, useState } from "react"; import { memo, useCallback } from "react";
import styles from "../index.module.css"; import styles from "../index.module.css";
import { Box, Typography } from "@mui/material"; import { Box, Typography } from "@mui/material";
import Button from "@/components/mui/Button"; import Button from "@/components/mui/Button";
...@@ -14,82 +14,82 @@ import usePass from "@/hooks/usePass"; ...@@ -14,82 +14,82 @@ import usePass from "@/hooks/usePass";
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
const TemplateBox = (props: any) => { const TemplateBox = (props: any) => {
const info = props.data; const info = props.data;
const isPass = usePass(); const isPass = usePass();
const navigate = useNavigate(); const navigate = useNavigate();
const addTemplateBlock = useCallback( const addTemplateBlock = useCallback(
(id: string) => { (id: string) => {
navigate(`/product/cadd/projectSubmitWork`, { navigate(`/product/cadd/projectSubmitWork`, {
state: { id }, state: { id },
}); });
}, },
[navigate] [navigate]
); );
return ( return (
<Box className={styles.templateBlock}> <Box className={styles.templateBlock}>
<Box> <Box>
<Typography <Typography
sx={{ sx={{
fontSize: "14px", fontSize: "14px",
fontWeight: "600", fontWeight: "600",
color: "#1E2633", color: "#1E2633",
marginBottom: "4px", marginBottom: "4px",
overflow: "hidden", overflow: "hidden",
textOverflow: "ellipsis", textOverflow: "ellipsis",
}} }}
> >
{info.title} {info.title}
</Typography> </Typography>
<Box sx={{ display: "flex", marginBottom: "8px" }}> <Box sx={{ display: "flex", marginBottom: "8px" }}>
<Typography <Typography
sx={{ sx={{
fontSize: "12px", fontSize: "12px",
fontWeight: "400", fontWeight: "400",
color: "#1370FF", color: "#1370FF",
marginRight: "24px", marginRight: "24px",
}} }}
> >
版本:{info.version} 版本:{info.version}
</Typography> </Typography>
<Typography <Typography
sx={{ fontSize: "12px", fontWeight: "400", color: "#1370FF" }} sx={{ fontSize: "12px", fontWeight: "400", color: "#1370FF" }}
> >
更新时间:{info.updateTime} 更新时间:{info.updateTime}
</Typography> </Typography>
</Box> </Box>
<Typography className={styles.templateDescText}> <Typography className={styles.templateDescText}>
{info.description} {info.description}
</Typography> </Typography>
</Box> </Box>
<Box <Box
sx={{ sx={{
display: "flex", display: "flex",
justifyContent: "end", justifyContent: "end",
}} }}
> >
{isPass("PROJECT_WORKBENCH_FLOES_USE", "MANAGER") && ( {isPass("PROJECT_WORKBENCH_FLOES_USE", "MANAGER") && (
<Button <Button
size={"small"} size={"small"}
text={"删除模版"} text={"删除模版"}
click={() => { click={() => {
props.startDialog(info.id); props.startDialog(info.id);
}} }}
style={{ backgroundColor: "#F0F2F5", color: "#565C66" }} style={{ backgroundColor: "#F0F2F5", color: "#565C66" }}
/> />
)} )}
{isPass("PROJECT_WORKBENCH_FLOES_USE", "USER") && ( {isPass("PROJECT_WORKBENCH_FLOES_USE", "USER") && (
<Button <Button
size={"small"} size={"small"}
text={"使用模版"} text={"使用模版"}
click={() => addTemplateBlock(info.id)} click={() => addTemplateBlock(info.id)}
style={{ marginLeft: "12px" }} style={{ marginLeft: "12px" }}
/> />
)} )}
</Box> </Box>
</Box> </Box>
); );
}; };
export default memo(TemplateBox); export default memo(TemplateBox);
.headerBox { .headerBox {
margin-bottom: 20px; margin-bottom: 20px;
} }
.removeItemBox { .removeItemBox {
color: #ff4e4e; color: #ff4e4e;
margin-left: 32px; margin-left: 32px;
cursor: pointer; cursor: pointer;
} }
.tabBox { .tabBox {
width: 100%; width: 100%;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
margin-bottom: 24px; margin-bottom: 24px;
} }
.templateBlock { .templateBlock {
width: 21.4876%; width: 21.4876%;
height: 160px; height: 160px;
background: #FFFFFF; background: #ffffff;
border-radius: 4px; border-radius: 4px;
border: 1px solid #EBEDF0; border: 1px solid #ebedf0;
padding: 16px 20px; padding: 16px 20px;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: space-between; justify-content: space-between;
margin: 8px; margin: 8px;
} }
.addTemplateMask { .addTemplateMask {
background: rgb(56, 56, 56, 0.7); background: rgb(56, 56, 56, 0.7);
position: absolute; position: absolute;
z-index: 800; z-index: 800;
top: 0%; top: 0%;
left: 0%; left: 0%;
width: 100%; width: 100%;
height: 100%; height: 100%;
display: flex; display: flex;
align-items: end; align-items: flex-end;
flex-direction: column; flex-direction: column;
} }
.addTemplateBlock { .addTemplateBlock {
background: #FFFFFF; background: #ffffff;
z-index: 900; z-index: 900;
border-radius: 16px 0px 0px 0px; border-radius: 16px 0px 0px 0px;
height: 100%; height: 100%;
width: 100%; width: 100%;
} }
.addTemplateBox { .addTemplateBox {
width: 16.8751%; width: 16.8751%;
height: 114px; height: 114px;
background: #FFFFFF; background: #ffffff;
border-radius: 4px; border-radius: 4px;
border: 1px solid #F0F2F5; border: 1px solid #f0f2f5;
padding: 16px 20px; padding: 16px 20px;
margin: 8px; margin: 8px;
cursor: pointer; cursor: pointer;
} }
.addTemplateBox:hover { .addTemplateBox:hover {
box-shadow: 6px 8px 22px 0px rgba(0, 24, 57, 0.08); box-shadow: 6px 8px 22px 0px rgba(0, 24, 57, 0.08);
} }
.templateDescText { .templateDescText {
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
-webkit-box-orient: vertical; -webkit-box-orient: vertical;
-webkit-line-clamp: 3; -webkit-line-clamp: 3;
display: -webkit-box; display: -webkit-box;
height: 54px; height: 54px;
font-size: 12px !important; font-size: 12px !important;
font-weight: 400 !important; font-weight: 400 !important;
color: #8A9099 !important; color: #8a9099 !important;
} }
.addNewTemplate { .addNewTemplate {
width: 380px; width: 380px;
height: 194px; height: 194px;
background: #FFFFFF; background: #ffffff;
border-radius: 4px; border-radius: 4px;
border: 1px solid #EBEDF0; border: 1px solid #ebedf0;
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
flex-direction: column; flex-direction: column;
cursor: pointer; cursor: pointer;
} }
\ No newline at end of file
...@@ -12,21 +12,17 @@ import OutlinedInput from "@mui/material/OutlinedInput"; ...@@ -12,21 +12,17 @@ import OutlinedInput from "@mui/material/OutlinedInput";
import SearchIcon from "@mui/icons-material/Search"; import SearchIcon from "@mui/icons-material/Search";
import { toJS } from "mobx"; import { toJS } from "mobx";
import { observer } from "mobx-react-lite"; import { observer } from "mobx-react-lite";
// import Button from "@mui/material/Button";
import Add from "@mui/icons-material/Add"; import Add from "@mui/icons-material/Add";
import Button from "@/components/mui/Button"; import Button from "@/components/mui/Button";
import useMyRequest from "@/hooks/useMyRequest"; import useMyRequest from "@/hooks/useMyRequest";
import TemplateBox from "./components/templateBox"; import TemplateBox from "./components/templateBox";
import SimpleDialog from "./components/simpleDialog"; import SimpleDialog from "./components/simpleDialog";
// import AddTemplate from "./components/addTemplate";
import AddTemplate from "./components/AddTemplate/index"; import AddTemplate from "./components/AddTemplate/index";
import noData from "../../../../assets/project/noTemplate.svg"; import noData from "../../../../assets/project/noTemplate.svg";
import { import {
getWorkbenchTemplate, getWorkbenchTemplate,
deleteWorkbenchTemplate, deleteWorkbenchTemplate,
getAddWorkbenchTemplate,
addWorkbenchTemplate,
} from "@/api/workbench_api"; } from "@/api/workbench_api";
import usePass from "@/hooks/usePass"; import usePass from "@/hooks/usePass";
import { useStores } from "@/store"; import { useStores } from "@/store";
...@@ -47,12 +43,6 @@ const ProjectMembers = observer(() => { ...@@ -47,12 +43,6 @@ const ProjectMembers = observer(() => {
const [templateId, setTemplateId] = useState(""); const [templateId, setTemplateId] = useState("");
/** 简单弹窗(删除模板) */ /** 简单弹窗(删除模板) */
const [openDialog, setOpenDialog] = useState(false); const [openDialog, setOpenDialog] = useState(false);
/** 增加模板 */
const [openAddTemplate, setOpenAddTemplate] = useState(false);
/** 可增加模板列表 */
const [addTemplateList, setAddTemplateList] = useState([]);
/** 已选择增加的模板列表 */
const [selectTemplateData, setSelectTemplateData] = useState<string[]>([]);
const [showAddTemplate, setShowAddTemplate] = useState(false); const [showAddTemplate, setShowAddTemplate] = useState(false);
// 获取模板列表 // 获取模板列表
...@@ -73,35 +63,12 @@ const ProjectMembers = observer(() => { ...@@ -73,35 +63,12 @@ const ProjectMembers = observer(() => {
}, },
}); });
// 添加工作流模板-获取模板列表
const { run: getAddTemplateList } = useMyRequest(getAddWorkbenchTemplate, {
onSuccess: (result: any) => {
setAddTemplateList(result.data);
setOpenAddTemplate(true);
},
});
// 项目管理员-添加工作流模板-提交
const { run: addTemplate } = useMyRequest(addWorkbenchTemplate, {
onSuccess: (result: any) => {
setOpenAddTemplate(false);
getTemplateInfo({
projectId: currentProjectStore.currentProjectInfo.id as string,
});
setSelectTemplateData([]);
},
});
useEffect(() => { useEffect(() => {
getTemplateInfo({ getTemplateInfo({
projectId: currentProjectStore.currentProjectInfo.id as string, projectId: currentProjectStore.currentProjectInfo.id as string,
}); });
}, [currentProjectStore.currentProjectInfo.id, getTemplateInfo]); }, [currentProjectStore.currentProjectInfo.id, getTemplateInfo]);
useEffect(() => {
console.log("projectIdData: ", projectIdData);
}, [projectIdData]);
/** 删除模板 */ /** 删除模板 */
const deleteTemplate = () => { const deleteTemplate = () => {
delTemplate({ delTemplate({
...@@ -124,44 +91,6 @@ const ProjectMembers = observer(() => { ...@@ -124,44 +91,6 @@ const ProjectMembers = observer(() => {
/** 增加模板 */ /** 增加模板 */
const addTemplateBlock = () => { const addTemplateBlock = () => {
setShowAddTemplate(true); setShowAddTemplate(true);
// getAddTemplateList({
// projectId: currentProjectStore.currentProjectInfo.id as string,
// productId: "cadd",
// });
};
/** 关闭增加模板 */
const closeAddTemplateBlock = () => {
setOpenAddTemplate(false);
setSelectTemplateData([]);
};
/** 增加模板操作 */
const addTemplateCallback = () => {
addTemplate({
projectId: currentProjectStore.currentProjectInfo.id as string,
workflowSpecIds: selectTemplateData,
});
};
/** 搜索模板 */
const searchTemplateNameCallback = (data: any) => {
getAddTemplateList({
projectId: currentProjectStore.currentProjectInfo.id as string,
productId: "cadd",
title: data,
});
};
const templateSelectCallback = (data: string) => {
let list: string[] = [...selectTemplateData];
if (selectTemplateData.filter((e) => e === data).length > 0) {
list = list.filter((e) => e !== data);
setSelectTemplateData(list);
} else {
list.push(data);
setSelectTemplateData(list);
}
}; };
const searchChange = (data: any) => { const searchChange = (data: any) => {
...@@ -171,11 +100,11 @@ const ProjectMembers = observer(() => { ...@@ -171,11 +100,11 @@ const ProjectMembers = observer(() => {
useEffect(() => { useEffect(() => {
setTimeout(() => { setTimeout(() => {
getTemplateInfo({ getTemplateInfo({
projectId: currentProjectStore.currentProjectInfo.id as string, projectId: projectIdData as string,
title: templateName, title: templateName,
}); });
}, 300); }, 300);
}, [templateName]); }, [templateName, getTemplateInfo, projectIdData]);
return ( return (
<Box className={styles.headerBox}> <Box className={styles.headerBox}>
...@@ -256,16 +185,6 @@ const ProjectMembers = observer(() => { ...@@ -256,16 +185,6 @@ const ProjectMembers = observer(() => {
</Box> </Box>
)} )}
{/* <AddTemplate
openAddTemplate={openAddTemplate}
closeAddTemplateBlock={closeAddTemplateBlock}
addTemplateList={addTemplateList}
templateSelectCallback={templateSelectCallback}
selectTemplateData={selectTemplateData}
addTemplateCallback={addTemplateCallback}
searchTemplateNameCallback={searchTemplateNameCallback}
/> */}
{showAddTemplate && ( {showAddTemplate && (
<AddTemplate <AddTemplate
setShowAddTemplate={setShowAddTemplate} setShowAddTemplate={setShowAddTemplate}
......
...@@ -155,7 +155,7 @@ const Flow = (props: IProps) => { ...@@ -155,7 +155,7 @@ const Flow = (props: IProps) => {
const lineArr: IEdge[] = []; const lineArr: IEdge[] = [];
tasks?.length && tasks?.length &&
tasks.forEach((item) => { tasks.forEach((item) => {
lineArr.push(...item.edges); item.edges?.length && lineArr.push(...item.edges);
}); });
/** 所有的输入节点ID */ /** 所有的输入节点ID */
const isInput = lineArr?.some((item) => item.target === id); const isInput = lineArr?.some((item) => item.target === id);
...@@ -223,6 +223,7 @@ const Flow = (props: IProps) => { ...@@ -223,6 +223,7 @@ const Flow = (props: IProps) => {
const val: any = []; const val: any = [];
tasks?.length && tasks?.length &&
tasks.forEach((item) => { tasks.forEach((item) => {
console.log(item, "item");
val.push({ val.push({
id: item.id, id: item.id,
type: item.type === "BATCH" ? "batchNode" : "flowNode", type: item.type === "BATCH" ? "batchNode" : "flowNode",
...@@ -249,7 +250,10 @@ const Flow = (props: IProps) => { ...@@ -249,7 +250,10 @@ const Flow = (props: IProps) => {
padding: isFlowNode(item.id) ? "20px" : "12px 20px", padding: isFlowNode(item.id) ? "20px" : "12px 20px",
}, },
}, },
position: { x: Number(item.position.x), y: Number(item.position.y) }, position: {
x: Number(item.position?.x) || 0,
y: Number(item.position?.y) || 0,
},
...(item.type === "BATCH" ? { style: { zIndex: -1 } } : {}), ...(item.type === "BATCH" ? { style: { zIndex: -1 } } : {}),
...(item.parentNode ? { parentNode: item.parentNode } : {}), ...(item.parentNode ? { parentNode: item.parentNode } : {}),
...(item.type === "BATCH" ? { extent: "parent" } : {}), ...(item.type === "BATCH" ? { extent: "parent" } : {}),
...@@ -270,13 +274,14 @@ const Flow = (props: IProps) => { ...@@ -270,13 +274,14 @@ const Flow = (props: IProps) => {
const val: ILine[] = []; const val: ILine[] = [];
tasks?.length && tasks?.length &&
tasks.forEach((item) => { tasks.forEach((item) => {
item.edges.forEach((every) => { item?.edges?.length &&
const newLine = { item?.edges.forEach((every) => {
...every, const newLine = {
batchId: item.parentNode ? item.parentNode : item.id, ...every,
}; batchId: item.parentNode ? item.parentNode : item.id,
val.push(newLine); };
}, []); val.push(newLine);
}, []);
}); });
return val.map((item: ILine) => { return val.map((item: ILine) => {
const newSelectId = selectedNodeId ? selectedNodeId : inSideNodeId; const newSelectId = selectedNodeId ? selectedNodeId : inSideNodeId;
...@@ -340,7 +345,7 @@ const Flow = (props: IProps) => { ...@@ -340,7 +345,7 @@ const Flow = (props: IProps) => {
<ReactFlow <ReactFlow
nodes={nodes} nodes={nodes}
edges={edges} edges={edges}
fitView={flowType === "default" ? false : true} fitView={flowType === "default" ? true : false}
proOptions={{ hideAttribution: true, account: "" }} proOptions={{ hideAttribution: true, account: "" }}
nodeTypes={nodeTypes} nodeTypes={nodeTypes}
onPaneClick={handlePaneClick} onPaneClick={handlePaneClick}
......
...@@ -6,14 +6,12 @@ import { observer } from "mobx-react-lite"; ...@@ -6,14 +6,12 @@ import { observer } from "mobx-react-lite";
import { toJS } from "mobx"; import { toJS } from "mobx";
import cloneDeep from "lodash/cloneDeep"; import cloneDeep from "lodash/cloneDeep";
import { mockData } from "./mock";
import { IOperatorItemProps, IOperatorListProps } from "./interface"; import { IOperatorItemProps, IOperatorListProps } from "./interface";
import { ITask } from "@/views/Project/ProjectSubmitWork/interface"; import { ITask } from "@/views/Project/ProjectSubmitWork/interface";
import useMyRequest from "@/hooks/useMyRequest"; import useMyRequest from "@/hooks/useMyRequest";
import { IResponse } from "@/api/http"; import { IResponse } from "@/api/http";
import { fetchOperatorList } from "@/api/workbench_api"; import { fetchOperatorList } from "@/api/workbench_api";
import { useStores } from "@/store"; import { useStores } from "@/store";
import { uuid } from "@/utils/util";
import styles from "./index.module.css"; import styles from "./index.module.css";
import MyMenu from "@/components/mui/MyMenu"; import MyMenu from "@/components/mui/MyMenu";
...@@ -26,19 +24,66 @@ import MyMenu from "@/components/mui/MyMenu"; ...@@ -26,19 +24,66 @@ import MyMenu from "@/components/mui/MyMenu";
* @FilePath: /bkunyun/src/views/WorkFlowEdit/components/OperatorList/index.tsx * @FilePath: /bkunyun/src/views/WorkFlowEdit/components/OperatorList/index.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
*/ */
let count = 1;
const OperatorItem = (props: IOperatorItemProps) => { const OperatorItem = (props: IOperatorItemProps) => {
const { const {
info: { title, description, tags }, info: { title, description, tags },
setTemplateConfigInfo, setTemplateConfigInfo,
templateConfigInfo, templateConfigInfo,
setOperatorListData,
operatorListData,
info,
} = props; } = props;
const [isDragStyle, setIsDragStyle] = useState<boolean>(false); const [isDragStyle, setIsDragStyle] = useState<boolean>(false);
/** 拖拽开始 */ /** 拖拽开始 */
const onDragStart = useCallback(() => { const onDragStart = useCallback(() => {
setIsDragStyle(true); setIsDragStyle(true);
count++;
}, []); }, []);
/** 通过id查找相对的批流数组 */
const getBatchFlowArr = useCallback(
(id: string) => {
const newVal = operatorListData.filter((item) => {
return item.id === id || item.parentNode === id;
});
return newVal;
},
[operatorListData]
);
/** 生成批流副本 */
const getCopyBatchFlowArr = useCallback(
(arr: ITask[], x: number, y: number) => {
const newVal = arr.map((item) => {
const newEdges =
item?.edges &&
item?.edges.map((every) => {
return {
...every,
source: `${every.source}_${count}`,
target: `${every.target}_${count}`,
};
});
return {
...item,
id: `${item.id}_${count}`,
parentNode: item.parentNode ? `${item.parentNode}_${count}` : "",
position: {
x: item.type === "BATCH" ? x : item.position?.x,
y: item.type === "BATCH" ? y : item.position?.y,
},
edges: newEdges.length ? newEdges : item?.edges,
};
});
return newVal;
},
[]
);
/** 拖拽结束 */ /** 拖拽结束 */
const onDragEnd = useCallback( const onDragEnd = useCallback(
(e: React.DragEvent<HTMLDivElement>) => { (e: React.DragEvent<HTMLDivElement>) => {
...@@ -55,27 +100,25 @@ const OperatorItem = (props: IOperatorItemProps) => { ...@@ -55,27 +100,25 @@ const OperatorItem = (props: IOperatorItemProps) => {
clientX < lowerRightX && clientX < lowerRightX &&
clientY < lowerRightY clientY < lowerRightY
) { ) {
console.log( const batchFlowArr = getBatchFlowArr(info.id);
const newBatchFlowArr = getCopyBatchFlowArr(
batchFlowArr,
clientX - upperLeftPointX, clientX - upperLeftPointX,
clientY - upperLeftPointY, clientY - upperLeftPointY
"0000000"
); );
const newVal = [ const newVal = cloneDeep(templateConfigInfo);
...cloneDeep(templateConfigInfo), newVal.push(...newBatchFlowArr);
{
...props.info,
uuid: uuid(),
position: {
x: clientX - upperLeftPointX,
y: clientY - upperLeftPointY,
},
},
];
setTemplateConfigInfo(newVal); setTemplateConfigInfo(newVal);
} }
setIsDragStyle(false); setIsDragStyle(false);
}, },
[props.info, setTemplateConfigInfo, templateConfigInfo] [
getBatchFlowArr,
getCopyBatchFlowArr,
info.id,
setTemplateConfigInfo,
templateConfigInfo,
]
); );
return ( return (
...@@ -105,7 +148,14 @@ const OperatorItem = (props: IOperatorItemProps) => { ...@@ -105,7 +148,14 @@ const OperatorItem = (props: IOperatorItemProps) => {
</span> </span>
); );
})} })}
<MyMenu options={[]} value="dd"> <MyMenu
options={[
{ label: "1.1.0", value: "1.1.0" },
{ label: "1.2.0", value: "1.2.0" },
{ label: "1.3.0", value: "1.3.0" },
]}
value="1.1.0"
>
<div>ddd</div> <div>ddd</div>
</MyMenu> </MyMenu>
</div> </div>
...@@ -146,7 +196,6 @@ const OperatorList = observer((props: IOperatorListProps) => { ...@@ -146,7 +196,6 @@ const OperatorList = observer((props: IOperatorListProps) => {
}); });
} }
}; };
return ( return (
<div className={styles.operatorListBox}> <div className={styles.operatorListBox}>
<div className={styles.searchBox}> <div className={styles.searchBox}>
...@@ -163,12 +212,14 @@ const OperatorList = observer((props: IOperatorListProps) => { ...@@ -163,12 +212,14 @@ const OperatorList = observer((props: IOperatorListProps) => {
</div> </div>
<div className={styles.listBox}> <div className={styles.listBox}>
{operatorListData {operatorListData
// .filter((item) => item.type === "BATCH") .filter((item) => item.type === "BATCH")
.map((item) => { .map((item) => {
return ( return (
<OperatorItem <OperatorItem
key={item.id} key={item.id}
info={item} info={item}
setOperatorListData={setOperatorListData}
operatorListData={operatorListData}
templateConfigInfo={templateConfigInfo} templateConfigInfo={templateConfigInfo}
setTemplateConfigInfo={setTemplateConfigInfo} setTemplateConfigInfo={setTemplateConfigInfo}
/> />
......
...@@ -4,14 +4,16 @@ import { ITask } from "@/views/Project/ProjectSubmitWork/interface" ...@@ -4,14 +4,16 @@ import { ITask } from "@/views/Project/ProjectSubmitWork/interface"
* @Author: 吴永生#A02208 yongsheng.wu@wholion.com * @Author: 吴永生#A02208 yongsheng.wu@wholion.com
* @Date: 2022-07-06 15:32:11 * @Date: 2022-07-06 15:32:11
* @LastEditors: 吴永生#A02208 yongsheng.wu@wholion.com * @LastEditors: 吴永生#A02208 yongsheng.wu@wholion.com
* @LastEditTime: 2022-07-07 16:22:08 * @LastEditTime: 2022-07-08 16:05:21
* @FilePath: /bkunyun/src/views/WorkFlowEdit/components/OperatorList/interface.ts * @FilePath: /bkunyun/src/views/WorkFlowEdit/components/OperatorList/interface.ts
* @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
*/ */
export interface IOperatorItemProps { export interface IOperatorItemProps {
info: ITask info: ITask
setTemplateConfigInfo: (val: ITask[]) => void; setTemplateConfigInfo: (val: ITask[]) => void;
templateConfigInfo: ITask[] templateConfigInfo: ITask[];
setOperatorListData: (val: ITask[]) => void;
operatorListData: ITask[]
} }
export interface IOperatorListProps { export interface IOperatorListProps {
......
...@@ -61,6 +61,63 @@ ...@@ -61,6 +61,63 @@
); );
cursor: pointer; cursor: pointer;
} }
.inOutBox {
margin-bottom: 20px;
}
.paramsTitle {
color: rgba(30, 38, 51, 1);
font-size: 14px;
line-height: 22px;
font-weight: 600;
margin-bottom: 12px;
display: flex;
justify-content: flex-start;
align-items: center;
}
.paramsTitleDesc {
margin-left: 8px;
}
.paramsList {
background-color: rgba(247, 248, 250, 1);
border-radius: 4px;
padding: 16px 20px;
}
.parameterBox {
margin-bottom: 12px;
}
.parameterBox:last-child {
margin-bottom: 0;
}
.parameterTop {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 8px;
}
.parameterleft {
}
.parameterName {
color: rgba(30, 38, 51, 1);
font-size: 14px;
line-height: 22px;
font-weight: 600;
}
.required::after {
content: "*";
color: rgba(255, 78, 78, 1);
margin-left: 4px;
}
.parameterdataType {
color: rgba(138, 144, 153, 1);
font-size: 12px;
line-height: 20px;
}
.noData { .noData {
height: calc(100vh - 140px); height: calc(100vh - 140px);
display: flex; display: flex;
......
...@@ -4,7 +4,17 @@ import { ...@@ -4,7 +4,17 @@ import {
IParameter, IParameter,
} from "../../../Project/ProjectSubmitWork/interface"; } from "../../../Project/ProjectSubmitWork/interface";
import noTemplate from "@/assets/project/noTemplate.svg"; import noTemplate from "@/assets/project/noTemplate.svg";
import { useEffect, useMemo, useRef, useState } from "react"; import { useEffect, useMemo, useState } from "react";
import MyInput from "@/components/mui/MyInput";
import Tooltip from "@mui/material/Tooltip";
import MyCheckBox from "@/components/mui/MyCheckBox";
// import MySelect, { optionsTransform } from "../components/MySelect";
import MySelect, {
optionsTransform,
} from "../../../Project/ProjectSubmitWork/components/MySelect";
import MyRadio from "@/components/mui/MyRadio";
import questionMark from "@/assets/project/questionMark.svg";
import fileSelectIcon from "@/assets/project/fileSelect.svg";
import classNames from "classnames"; import classNames from "classnames";
type IParameterSettingProps = { type IParameterSettingProps = {
...@@ -12,19 +22,99 @@ type IParameterSettingProps = { ...@@ -12,19 +22,99 @@ type IParameterSettingProps = {
taskId: string; taskId: string;
}; };
const templateConfigInfo = [
{
id: "id",
title: "title",
description:
"阿斯蒂芬吉林集安拉开圣诞节疯狂拉升阶段阿斯蒂芬吉林集安拉开圣诞节疯狂拉升阶段阿斯蒂芬吉林集安拉开圣诞节疯狂拉升阶段阿斯蒂芬吉林集安拉开圣诞节疯狂拉升阶段阿斯蒂芬吉林集安拉开圣诞节疯狂拉升阶段阿斯蒂芬吉林集安拉开圣诞节疯狂拉升阶段",
version: "version",
position: {
x: 10,
y: 100,
},
tags: ["string[]"],
type: "BATCH",
parentNode: "string",
parameters: [
{
hidden: true,
id: "",
name: "smi_in",
required: true,
defaultValue: null,
domType: "select",
classType: "STRING",
classTypeName: "String",
value: "",
description: "",
language: "",
languageVersion: "",
tags: [],
source: "string",
productId: "",
tasks: [],
validators: [
{
message: "请选择smi文件作为输入",
regex: "^.[s][m][i]$",
},
],
choices: [],
parameterGroup: "in",
},
{
hidden: true,
id: "",
name: "smi_in",
required: true,
defaultValue: null,
domType: "select",
classType: "STRING",
classTypeName: "String",
value: "",
description: "",
language: "",
languageVersion: "",
tags: [],
source: "string",
productId: "",
tasks: [],
validators: [
{
message: "请选择smi文件作为输入",
regex: "^.[s][m][i]$",
},
],
choices: [],
parameterGroup: "out",
},
],
edges: [],
isCheck: false,
executionStatus: "Pending",
},
];
const taskId = "id";
const ParameterSetting = (props: IParameterSettingProps) => { const ParameterSetting = (props: IParameterSettingProps) => {
const { templateConfigInfo, taskId } = props; // const { templateConfigInfo, taskId } = props;
const [descRef, setDescRef] = useState<any>(useRef());
const [descHeight, setDescHeight] = useState(0); const [descHeight, setDescHeight] = useState(0);
const [isShowAllDese, setIsShowAllDese] = useState(false); const [isShowAllDese, setIsShowAllDese] = useState(false);
const [fileSelectOpen, setFileSelectOpen] = useState(false); // 选择输出路径的弹窗显示控制
const [fileSelectObject, setFileSelectObject] = useState({
taskId: "",
parameterName: "",
});
const div = document.getElementById("descHeight");
useEffect(() => { useEffect(() => {
const div = document.getElementById("descHeight");
if (div) { if (div) {
setDescHeight(div.offsetHeight); setDescHeight(div.offsetHeight);
} }
}, [descRef]); }, [div]);
const taskInfo: ITask | null = useMemo(() => { const taskInfo: ITask | null = useMemo(() => {
if (!taskId) { if (!taskId) {
...@@ -34,7 +124,7 @@ const ParameterSetting = (props: IParameterSettingProps) => { ...@@ -34,7 +124,7 @@ const ParameterSetting = (props: IParameterSettingProps) => {
(task) => task.id === taskId (task) => task.id === taskId
); );
if (randerTaskArr.length > 0) { if (randerTaskArr.length > 0) {
return randerTaskArr[0]; return randerTaskArr[0] as ITask;
} else { } else {
return null; return null;
} }
...@@ -51,6 +141,7 @@ const ParameterSetting = (props: IParameterSettingProps) => { ...@@ -51,6 +141,7 @@ const ParameterSetting = (props: IParameterSettingProps) => {
); );
} }
}, [taskInfo]); }, [taskInfo]);
console.log(inParameters);
// 输出参数 // 输出参数
const outParameters: Array<IParameter> = useMemo(() => { const outParameters: Array<IParameter> = useMemo(() => {
...@@ -63,79 +154,198 @@ const ParameterSetting = (props: IParameterSettingProps) => { ...@@ -63,79 +154,198 @@ const ParameterSetting = (props: IParameterSettingProps) => {
} }
}, [taskInfo]); }, [taskInfo]);
// 基础参数 // // 基础参数
const basisParameters: Array<IParameter> = useMemo(() => { // const basisParameters: Array<IParameter> = useMemo(() => {
if (!taskInfo) { // if (!taskInfo) {
return []; // return [];
} else { // } else {
return taskInfo.parameters.filter( // return taskInfo.parameters.filter(
(parameter) => parameter.parameterGroup === "basis" // (parameter) => parameter.parameterGroup === "basis"
); // );
} // }
}, [taskInfo]); // }, [taskInfo]);
// 高级选项 // // 高级选项
const seniorParameters: Array<IParameter> = useMemo(() => { // const seniorParameters: Array<IParameter> = useMemo(() => {
if (!taskInfo) { // if (!taskInfo) {
return []; // return [];
} else { // } else {
return taskInfo.parameters.filter( // return taskInfo.parameters.filter(
(parameter) => parameter.parameterGroup === "senior" // (parameter) => parameter.parameterGroup === "senior"
); // );
} // }
}, [taskInfo]); // }, [taskInfo]);
// 硬件配置 // // 硬件配置
const hardwareParameters: Array<IParameter> = useMemo(() => { // const hardwareParameters: Array<IParameter> = useMemo(() => {
if (!taskInfo) { // if (!taskInfo) {
return []; // return [];
} else { // } else {
return taskInfo.parameters.filter( // return taskInfo.parameters.filter(
(parameter) => parameter.parameterGroup === "hardware" // (parameter) => parameter.parameterGroup === "hardware"
); // );
} // }
}, [taskInfo]); // }, [taskInfo]);
const handleOpenFileSelect = (
taskId: string = "",
parameterName: string = ""
) => {
setFileSelectObject({
taskId,
parameterName,
});
setFileSelectOpen(true);
};
const handleParameterChange = (
e: any,
taskId: string,
parameterName: string
) => {
console.log(e.target.value, taskId, parameterName);
// setParameter(e.target.value, taskId, parameterName);
};
const renderInput = (parameter: IParameter) => {
return (
<div>
{parameter.domType.toLowerCase() === "file" && (
<MyInput
value={parameter.value || ""}
InputProps={{
endAdornment: (
<img
onClick={() => handleOpenFileSelect(taskId, parameter.name)}
src={fileSelectIcon}
alt=""
className={styles.fileSelectImg}
/>
),
}}
placeholder="请选择"
error={parameter.error || false}
helperText={parameter.helperText}
></MyInput>
)}
{parameter.domType.toLowerCase() === "path" && (
<MyInput
value={parameter.value || ""}
InputProps={{
endAdornment: (
<img
onClick={() => handleOpenFileSelect(taskId, parameter.name)}
src={fileSelectIcon}
alt=""
className={styles.fileSelectImg}
/>
),
}}
placeholder="请选择"
error={parameter.error || false}
helperText={parameter.helperText}
></MyInput>
)}
{parameter.domType.toLowerCase() === "dataset" && (
<MyInput
value={parameter.value || ""}
InputProps={{
endAdornment: (
<img
onClick={() => handleOpenFileSelect(taskId, parameter.name)}
src={fileSelectIcon}
alt=""
className={styles.fileSelectImg}
/>
),
}}
placeholder="请选择"
error={parameter.error || false}
helperText={parameter.helperText}
></MyInput>
)}
{parameter.domType.toLowerCase() === "input" && (
<MyInput
value={parameter.value || ""}
onChange={(e: any) =>
handleParameterChange(e, taskId, parameter.name || "")
}
placeholder="请输入"
error={parameter.error || false}
helperText={parameter.helperText}
></MyInput>
)}
{parameter.domType.toLowerCase() === "select" && (
<MySelect
value={parameter.value}
onChange={(e: any) =>
handleParameterChange(e, taskId, parameter.name || "")
}
error={parameter.error || false}
helpertext={parameter.helperText}
options={optionsTransform(parameter?.choices || [], "label")}
></MySelect>
)}
{parameter.domType.toLowerCase() === "multipleselect" && (
<MySelect
value={parameter.value}
onChange={(e: any) =>
handleParameterChange(e, taskId, parameter.name || "")
}
multiple={true}
error={parameter.error || false}
helpertext={parameter.helperText}
options={optionsTransform(parameter.choices, "label")}
></MySelect>
)}
{parameter.domType.toLowerCase() === "radio" && (
<MyRadio
value={parameter.value}
onChange={(e: any) =>
handleParameterChange(e, taskId, parameter.name || "")
}
options={optionsTransform(parameter.choices, "label")}
error={parameter.error || false}
helperText={parameter.helperText}
></MyRadio>
)}
{parameter.domType.toLowerCase() === "checkbox" && (
<MyCheckBox
value={parameter.value}
onChange={(e: any) =>
handleParameterChange(
{
target: {
value: e,
},
},
taskId,
parameter.name || ""
)
}
options={optionsTransform(parameter.choices, "label")}
error={parameter.error || false}
helperText={parameter.helperText}
></MyCheckBox>
)}
{parameter.description && (
<Tooltip title={parameter.description} placement="top">
<img className={styles.parameterDesc} src={questionMark} alt="" />
</Tooltip>
)}
</div>
);
};
return ( return (
<div className={styles.parameterSetting}> <div className={styles.parameterSetting}>
{/* <div className={styles.taskInfo}>
<div className={styles.taskTitle}>taskTitle</div>
<div className={styles.taskVersion}>version</div>
<div
className={styles.taskDescriptionHeight}
id="descHeight"
ref={descRef}
>
埃里克梵蒂冈和艰苦拉萨规定了卡号是德国埃里克梵蒂冈和艰苦拉萨规定了卡号是德国埃里克梵蒂冈和艰苦拉萨规定了卡号是德国埃里克梵蒂冈和艰苦拉萨规定了卡号是德国埃里克梵蒂冈和艰苦拉萨规定了卡号是德国埃里克梵蒂冈和艰苦拉萨规定了卡号是德国
</div>
<div
className={classNames({
[styles.taskDescriptionAll]: isShowAllDese,
[styles.taskDescription]: !isShowAllDese,
})}
>
埃里克梵蒂冈和艰苦拉萨规定了卡号是德国埃里克梵蒂冈和艰苦拉萨规定了卡号是德国埃里克梵蒂冈和艰苦拉萨规定了卡号是德国埃里克梵蒂冈和艰苦拉萨规定了卡号是德国埃里克梵蒂冈和艰苦拉萨规定了卡号是德国埃里克梵蒂冈和艰苦拉萨规定了卡号是德国
{descHeight > 60 && (
<span
className={styles.descButton}
onClick={() => setIsShowAllDese(!isShowAllDese)}
>
{isShowAllDese ? "收起" : "展开"}
</span>
)}
</div>
</div> */}
{taskInfo && ( {taskInfo && (
<div className={styles.taskInfo}> <div className={styles.taskInfo}>
<div className={styles.taskTitle}>{taskInfo.title || "-"}</div> <div className={styles.taskTitle}>{taskInfo.title || "-"}</div>
<div className={styles.taskVersion}> <div className={styles.taskVersion}>
版本:{taskInfo.version || "-"} 版本:{taskInfo.version || "-"}
</div> </div>
<div <div className={styles.taskDescriptionHeight} id="descHeight">
className={styles.taskDescriptionHeight}
id="descHeight"
ref={descRef}
>
{taskInfo.description || "-"} {taskInfo.description || "-"}
</div> </div>
<div <div
...@@ -156,12 +366,88 @@ const ParameterSetting = (props: IParameterSettingProps) => { ...@@ -156,12 +366,88 @@ const ParameterSetting = (props: IParameterSettingProps) => {
</div> </div>
</div> </div>
)} )}
{/* {!taskInfo && ( {inParameters.length > 0 && (
<div className={styles.inOutBox}>
<div className={styles.paramsTitle}>
输入
<Tooltip
title="当某个输入项为启用状态时,代表该输入将由模板使用者在使用的时候填写赋值;当为关闭状态时,代表该输入不需要使用者来填写赋值,而是将其它流程的结果传入。"
placement="top"
>
<img
className={styles.paramsTitleDesc}
src={questionMark}
alt=""
/>
</Tooltip>
</div>
<div className={styles.paramsList}>
{inParameters.map((parameter, index) => {
return (
<div className={styles.parameterBox} key={index}>
<div className={styles.parameterTop}>
<div className={styles.parameterleft}>
<div
className={classNames({
[styles.parameterName]: true,
[styles.required]: parameter.required,
})}
>
{parameter.name}
</div>
<div className={styles.parameterdataType}>
{parameter.classTypeName}
</div>
</div>
<div className={styles.parameterRight}>
{parameter.hidden}
</div>
</div>
{renderInput(parameter)}
</div>
);
})}
</div>
</div>
)}
{outParameters.length > 0 && (
<div className={styles.inOutBox}>
<div className={styles.paramsTitle}>输出</div>
<div className={styles.paramsList}>
{inParameters.map((parameter, index) => {
return (
<div className={styles.parameterBox} key={index}>
<div className={styles.parameterTop}>
<div className={styles.parameterleft}>
<div
className={classNames({
[styles.parameterName]: true,
[styles.required]: parameter.required,
})}
>
{parameter.name}
</div>
<div className={styles.parameterdataType}>
{parameter.classTypeName}
</div>
</div>
<div className={styles.parameterRight}>
{parameter.hidden}
</div>
</div>
{renderInput(parameter)}
</div>
);
})}
</div>
</div>
)}
{!taskInfo && (
<div className={styles.noData}> <div className={styles.noData}>
<img src={noTemplate} alt="" className={styles.noDataImg} /> <img src={noTemplate} alt="" className={styles.noDataImg} />
<span className={styles.noDataText}>选中任意算子进行参数设置</span> <span className={styles.noDataText}>选中任意算子进行参数设置</span>
</div> </div>
)} */} )}
</div> </div>
); );
}; };
......
import { useMessage } from "@/components/MySnackbar"; import { useMessage } from "@/components/MySnackbar";
import usePass from "@/hooks/usePass"; // import usePass from "@/hooks/usePass";
import { operation, route } from "@/router"; import { operation, route } from "@/router";
import { Button } from "@mui/material"; import { Button } from "@mui/material";
import { Box } from "@mui/system"; import { Box } from "@mui/system";
import { useEffect } from "react"; import { useEffect } from "react";
const Demo = ({ const Demo = ({
childrenRoutes, childrenRoutes,
}: { }: {
childrenRoutes?: Array<route | operation>; childrenRoutes?: Array<route | operation>;
}) => { }) => {
const message = useMessage(); const message = useMessage();
const isPass = usePass(); // const isPass = usePass();
useEffect(() => { useEffect(() => {
console.log(isPass("PROJECT_OVERIVEW_CREATE"), "11111111111"); // console.log(isPass("PROJECT_OVERIVEW_CREATE"), "11111111111");
console.log(isPass("PROJECT_SUMMARY_MEMBER"), "2222222"); // console.log(isPass("PROJECT_SUMMARY_MEMBER"), "2222222");
console.log(isPass("test"), "33333"); // console.log(isPass("test"), "33333");
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
}, []); }, []);
return ( return (
<Box> <Box>
<Box>{JSON.stringify(childrenRoutes)}</Box> <Box>{JSON.stringify(childrenRoutes)}</Box>
<Box>{JSON.stringify(process.env.NODE_ENV)}</Box> <Box>{JSON.stringify(process.env.NODE_ENV)}</Box>
<Button onClick={() => message.success("测试测试")}>message测试</Button> <Button onClick={() => message.success("测试测试")}>message测试</Button>
</Box> </Box>
); );
}; };
export default Demo; export default Demo;
import { memo, useCallback, useEffect, useMemo, useState } from "react"; import { memo } from "react";
import _ from "lodash"; import DeleteIcon from "@mui/icons-material/Delete";
import { IResponse, useHttp } from "@/api/http";
import { useStores } from "@/store";
import DeleteIcon from '@mui/icons-material/Delete';
import Button from "@/components/mui/Button"; import Button from "@/components/mui/Button";
const ProjectMembers = () => { const ProjectMembers = () => {
const http = useHttp(); return (
<>
const { currentProjectStore } = useStores(); <Button size={"large"} text={"确定"} />
&nbsp;&nbsp;
useEffect(() => { <Button text={"确定"} />
&nbsp;&nbsp;
}, []); <Button size={"small"} text={"确定"} />
<br />
<br />
return ( <Button size={"large"} text={"确定"} disabled />
<> &nbsp;&nbsp;
<Button size={"large"} text={'确定'} /> <Button text={"确定"} disabled />
&nbsp;&nbsp; &nbsp;&nbsp;
<Button text={'确定'} /> <Button size={"small"} text={"确定"} disabled />
&nbsp;&nbsp; <br />
<Button size={"small"} text={'确定'} /> <br />
<br /><br /> <Button size={"large"} color={"secondary"} text={"确定"} />
<Button size={"large"} text={'确定'} disabled /> &nbsp;&nbsp;
&nbsp;&nbsp; <Button color={"secondary"} text={"确定"} />
<Button text={'确定'} disabled /> &nbsp;&nbsp;
&nbsp;&nbsp; <Button size={"small"} color={"secondary"} text={"确定"} />
<Button size={"small"} text={'确定'} disabled /> <br /> <br />
<br /><br /> <Button
<Button size={"large"} color={"secondary"} text={'确定'} /> text={"确定"}
&nbsp;&nbsp; size={"large"}
<Button color={"secondary"} text={'确定'} /> style={{ color: "aqua", background: "burlywood" }}
&nbsp;&nbsp; />
<Button size={"small"} color={"secondary"} text={'确定'} /> &nbsp;&nbsp;
<br /> <br /> <Button
<Button text={'确定'} size={"large"} style={{ color: "aqua", background: "burlywood" }} /> text={"确定"}
&nbsp;&nbsp; style={{ color: "aqua", background: "burlywood" }}
<Button text={'确定'} style={{ color: "aqua", background: "burlywood" }} /> />
&nbsp;&nbsp; &nbsp;&nbsp;
<Button text={'确定'} size={"small"} style={{ color: "aqua", background: "burlywood" }} /> <Button
<br /> <br /> text={"确定"}
outlined size={"small"}
<br /> style={{ color: "aqua", background: "burlywood" }}
<Button size={"large"} variant={"outlined"} text={'确定'} /> />
&nbsp;&nbsp; <br /> <br />
<Button variant={"outlined"} text={'确定'} /> outlined
&nbsp;&nbsp; <br />
<Button size={"small"} variant={"outlined"} text={'确定'} /> <Button size={"large"} variant={"outlined"} text={"确定"} />
<br /> <br /> &nbsp;&nbsp;
<Button size={"large"} variant={"outlined"} disabled text={'确定'} /> <Button variant={"outlined"} text={"确定"} />
&nbsp;&nbsp; &nbsp;&nbsp;
<Button variant={"outlined"} disabled text={'确定'} /> <Button size={"small"} variant={"outlined"} text={"确定"} />
&nbsp;&nbsp; <br /> <br />
<Button size={"small"} variant={"outlined"} disabled text={'确定'} /> <Button size={"large"} variant={"outlined"} disabled text={"确定"} />
<br /> <br /> &nbsp;&nbsp;
<Button size={"large"} variant={"outlined"} color={"secondary"} text={'确定'} /> <Button variant={"outlined"} disabled text={"确定"} />
&nbsp;&nbsp; &nbsp;&nbsp;
<Button variant={"outlined"} color={"secondary"} text={'确定'} /> <Button size={"small"} variant={"outlined"} disabled text={"确定"} />
&nbsp;&nbsp; <br /> <br />
<Button size={"small"} variant={"outlined"} color={"secondary"} text={'确定'} /> <Button
<br /> <br /> size={"large"}
<Button text={'确定'} size={"large"} variant={"outlined"} style={{ color: "aqua", background: "burlywood" }} /> variant={"outlined"}
&nbsp;&nbsp; color={"secondary"}
<Button text={'确定'} variant={"outlined"} style={{ color: "aqua", background: "burlywood" }} /> text={"确定"}
&nbsp;&nbsp; />
<Button text={'确定'} size={"small"} variant={"outlined"} style={{ color: "aqua", background: "burlywood" }} /> &nbsp;&nbsp;
<br /> <br /> <Button variant={"outlined"} color={"secondary"} text={"确定"} />
text &nbsp;&nbsp;
<br /> <Button
<Button size={"large"} variant={"text"} text={'确定确定确定确定确定确定'} /> size={"small"}
&nbsp;&nbsp; variant={"outlined"}
<Button variant={"text"} text={'确定确定确定确定确定确定'} /> color={"secondary"}
&nbsp;&nbsp; text={"确定"}
<Button size={"small"} variant={"text"} text={'确定确定确定确定确定确定'} /> />
<br /> <br /> <br />
<Button size={"large"} disabled variant={"text"} text={'确定确定确定确定确定确定'} /> <Button
&nbsp;&nbsp; text={"确定"}
<Button variant={"text"} disabled text={'确定确定确定确定确定确定'} /> size={"large"}
&nbsp;&nbsp; variant={"outlined"}
<Button size={"small"} disabled variant={"text"} text={'确定确定确定确定确定确定'} /> style={{ color: "aqua", background: "burlywood" }}
<br /> />
<Button size={"large"} color={"secondary"} variant={"text"} text={'确定确定确定确定确定确定'} /> &nbsp;&nbsp;
&nbsp;&nbsp; <Button
<Button variant={"text"} color={"secondary"} text={'确定确定确定确定确定确定'} /> text={"确定"}
&nbsp;&nbsp; variant={"outlined"}
<Button size={"small"} color={"secondary"} variant={"text"} text={'确定确定确定确定确定确定'} /> style={{ color: "aqua", background: "burlywood" }}
<br /> <br /> />
img &nbsp;&nbsp;
<br /> <Button
<Button text={'确定确定确定确定确定确定'} img={<DeleteIcon />} /> text={"确定"}
<br /> <br /> size={"small"}
select variant={"outlined"}
<br /> style={{ color: "aqua", background: "burlywood" }}
<Button />
text={'更多'} <br /> <br />
select={ text
[ <br />
{ name: "1111111" }, <Button
{ name: "1111111" }, size={"large"}
{ name: "1111111" }, variant={"text"}
{ name: "1111111", color: "red" }, text={"确定确定确定确定确定确定"}
] />
} /> &nbsp;&nbsp;
<Button <Button variant={"text"} text={"确定确定确定确定确定确定"} />
text={'更多'} &nbsp;&nbsp;
color={"secondary"} variant={"text"} <Button
select={ size={"small"}
[ variant={"text"}
{ name: "1111111" }, text={"确定确定确定确定确定确定"}
{ name: "1111111" }, />
{ name: "1111111" }, <br />
{ name: "1111111", color: "red" }, <Button
] size={"large"}
} /> disabled
variant={"text"}
text={"确定确定确定确定确定确定"}
</> />
); &nbsp;&nbsp;
<Button variant={"text"} disabled text={"确定确定确定确定确定确定"} />
&nbsp;&nbsp;
<Button
size={"small"}
disabled
variant={"text"}
text={"确定确定确定确定确定确定"}
/>
<br />
<Button
size={"large"}
color={"secondary"}
variant={"text"}
text={"确定确定确定确定确定确定"}
/>
&nbsp;&nbsp;
<Button
variant={"text"}
color={"secondary"}
text={"确定确定确定确定确定确定"}
/>
&nbsp;&nbsp;
<Button
size={"small"}
color={"secondary"}
variant={"text"}
text={"确定确定确定确定确定确定"}
/>
<br /> <br />
img
<br />
<Button text={"确定确定确定确定确定确定"} img={<DeleteIcon />} />
<br /> <br />
select
<br />
<Button
text={"更多"}
select={[
{ name: "1111111" },
{ name: "1111111" },
{ name: "1111111" },
{ name: "1111111", color: "red" },
]}
/>
<Button
text={"更多"}
color={"secondary"}
variant={"text"}
select={[
{ name: "1111111" },
{ name: "1111111" },
{ name: "1111111" },
{ name: "1111111", color: "red" },
]}
/>
</>
);
}; };
export default memo(ProjectMembers); export default memo(ProjectMembers);
import { memo, useCallback, useEffect, useMemo, useState } from "react"; import { memo } from "react";
import _ from "lodash"; import { InputAdornment } from "@mui/material";
import { IResponse, useHttp } from "@/api/http";
import { useStores } from "@/store";
import DeleteIcon from '@mui/icons-material/Delete';
import { InputAdornment } from '@mui/material';
import InputComponent from "@/components/mui/Input"; import InputComponent from "@/components/mui/Input";
const ProjectMembers = () => { const ProjectMembers = () => {
const http = useHttp(); return (
<>
const { currentProjectStore } = useStores(); <InputComponent
fullWidth={false}
useEffect(() => { label={"test"}
defaultValue={"sssssssss"}
}, []); size={"large"}
/>
&nbsp;&nbsp;&nbsp;&nbsp;
return ( <InputComponent
<> fullWidth={false}
label={"test"}
<InputComponent error={true}
fullWidth={false} helperText={"你还急急急靠靠靠靠靠靠靠靠靠靠靠靠靠靠"}
label={"test"} />
defaultValue={"sssssssss"} &nbsp;&nbsp;&nbsp;&nbsp;
size={'large'} <InputComponent
/> fullWidth={false}
&nbsp;&nbsp;&nbsp;&nbsp; label={"test"}
<InputComponent size={"small"}
fullWidth={false} disabled
label={"test"} />
error={true} &nbsp;&nbsp;&nbsp;&nbsp;
helperText={"你还急急急靠靠靠靠靠靠靠靠靠靠靠靠靠靠"} <InputComponent fullWidth={false} label={"xsmall"} size={"xsmall"} />
/>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;
<InputComponent <InputComponent
fullWidth={false} fullWidth={false}
label={"test"} placeholder={"测试机哦"}
size={'small'} endAdornment={
disabled <InputAdornment position="end">11&nbsp;&nbsp;</InputAdornment>
/>&nbsp;&nbsp;&nbsp;&nbsp; }
<InputComponent />
fullWidth={false} &nbsp;&nbsp;&nbsp;&nbsp;
label={"xsmall"} <InputComponent
size={'xsmall'} fullWidth={false}
/>&nbsp;&nbsp;&nbsp;&nbsp; size={"small"}
<InputComponent placeholder={"xxxxxx"}
fullWidth={false} endAdornment={
placeholder={"测试机哦"} <InputAdornment position="end">11&nbsp;&nbsp;</InputAdornment>
endAdornment={<InputAdornment position="end">11&nbsp;&nbsp;</InputAdornment>} }
/>&nbsp;&nbsp;&nbsp;&nbsp; />
<InputComponent fullWidth={false} size={"small"} placeholder={"xxxxxx"} endAdornment={<InputAdornment position="end">11&nbsp;&nbsp;</InputAdornment>} /> <br /> <br />
<br /> <br /> <InputComponent
<InputComponent fullWidth={true}
fullWidth={true} select={{
select={ json: [
{ { value: "1", label: "2" },
json: [{value:'1',label:"2"},{value:'3',label:"4"}] { value: "3", label: "4" },
} ],
} }}
/> />
<br /><br /> <br />
{/* <SelectComponent <br />
{/* <SelectComponent
option={json} option={json}
/> />
<br /><br /> <br /><br />
...@@ -72,10 +69,10 @@ const ProjectMembers = () => { ...@@ -72,10 +69,10 @@ const ProjectMembers = () => {
option={json} option={json}
size={"small"} size={"small"}
/> */} /> */}
<br /><br /> <br />
<br />
</> </>
); );
}; };
export default memo(ProjectMembers); export default memo(ProjectMembers);
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