Migrated Groups Module components to mds (#2923)
Signed-off-by: Benjamin Perez <benjamin@bexsoft.net>
This commit is contained in:
@@ -358,12 +358,6 @@ export const objectBrowserCommon = {
|
||||
// ** According to W3 spec, default minimum values for flex width flex-grow is "auto" (https://drafts.csswg.org/css-flexbox/#min-size-auto). So in this case we need to enforce the use of an absolute width.
|
||||
// "The preferred width of a box element child containing text content is currently the text without line breaks, leading to very unintuitive width and flex calculations → declare a width on a box element child with more than a few words (ever wonder why flexbox demos are all “1,2,3”?)"
|
||||
|
||||
export const selectorsCommon = {
|
||||
multiSelectTable: {
|
||||
height: 200,
|
||||
},
|
||||
};
|
||||
|
||||
export const settingsCommon: any = {
|
||||
settingsFormContainer: {
|
||||
padding: 38,
|
||||
|
||||
@@ -1,26 +1,31 @@
|
||||
import React, { useState } from "react";
|
||||
import UsersSelectors from "./UsersSelectors";
|
||||
import ModalWrapper from "../Common/ModalWrapper/ModalWrapper";
|
||||
import PredefinedList from "../Common/FormComponents/PredefinedList/PredefinedList";
|
||||
import Grid from "@mui/material/Grid";
|
||||
import { AddMembersToGroupIcon, Button } from "mds";
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2023 MinIO, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import { Theme } from "@mui/material/styles";
|
||||
import createStyles from "@mui/styles/createStyles";
|
||||
import {
|
||||
formFieldStyles,
|
||||
modalBasic,
|
||||
modalStyleUtils,
|
||||
} from "../Common/FormComponents/common/styleLibrary";
|
||||
import withStyles from "@mui/styles/withStyles";
|
||||
import React, { useState } from "react";
|
||||
import { AddMembersToGroupIcon, Button, FormLayout, Grid, ReadBox } from "mds";
|
||||
import { modalStyleUtils } from "../Common/FormComponents/common/styleLibrary";
|
||||
import { encodeURLString } from "../../../common/utils";
|
||||
import { setModalErrorSnackMessage } from "../../../systemSlice";
|
||||
import { useAppDispatch } from "../../../store";
|
||||
import { api } from "api";
|
||||
import { errorToHandler } from "api/errors";
|
||||
import UsersSelectors from "./UsersSelectors";
|
||||
import ModalWrapper from "../Common/ModalWrapper/ModalWrapper";
|
||||
|
||||
type UserPickerModalProps = {
|
||||
classes?: any;
|
||||
title?: string;
|
||||
preSelectedUsers?: string[];
|
||||
selectedGroup?: string;
|
||||
@@ -30,21 +35,7 @@ type UserPickerModalProps = {
|
||||
groupStatus?: string;
|
||||
};
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
userSelector: {
|
||||
"& .MuiPaper-root": {
|
||||
padding: 0,
|
||||
marginBottom: 15,
|
||||
},
|
||||
},
|
||||
...modalStyleUtils,
|
||||
...formFieldStyles,
|
||||
...modalBasic,
|
||||
});
|
||||
|
||||
const AddGroupMember = ({
|
||||
classes,
|
||||
title = "",
|
||||
groupStatus = "enabled",
|
||||
preSelectedUsers = [],
|
||||
@@ -77,21 +68,17 @@ const AddGroupMember = ({
|
||||
title={title}
|
||||
titleIcon={<AddMembersToGroupIcon />}
|
||||
>
|
||||
<Grid container>
|
||||
<Grid item xs={12}>
|
||||
<div className={classes.formFieldRow}>
|
||||
<PredefinedList label={`Selected Group`} content={selectedGroup} />
|
||||
</div>
|
||||
<div className={classes.userSelector}>
|
||||
<UsersSelectors
|
||||
selectedUsers={selectedUsers}
|
||||
setSelectedUsers={setSelectedUsers}
|
||||
editMode={!selectedGroup}
|
||||
/>
|
||||
</div>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.modalButtonBar}>
|
||||
<FormLayout withBorders={false} containerPadding={false}>
|
||||
<ReadBox label={`Selected Group`} sx={{ width: "100%" }}>
|
||||
{selectedGroup}
|
||||
</ReadBox>
|
||||
<UsersSelectors
|
||||
selectedUsers={selectedUsers}
|
||||
setSelectedUsers={setSelectedUsers}
|
||||
editMode={!selectedGroup}
|
||||
/>
|
||||
</FormLayout>
|
||||
<Grid item xs={12} sx={modalStyleUtils.modalButtonBar}>
|
||||
<Button
|
||||
id={"reset-add-group-member"}
|
||||
type="button"
|
||||
@@ -116,4 +103,4 @@ const AddGroupMember = ({
|
||||
);
|
||||
};
|
||||
|
||||
export default withStyles(styles)(AddGroupMember);
|
||||
export default AddGroupMember;
|
||||
|
||||
@@ -15,40 +15,29 @@
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Fragment, useEffect, useState } from "react";
|
||||
import { Theme } from "@mui/material/styles";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import createStyles from "@mui/styles/createStyles";
|
||||
import withStyles from "@mui/styles/withStyles";
|
||||
import {
|
||||
formFieldStyles,
|
||||
modalStyleUtils,
|
||||
} from "../Common/FormComponents/common/styleLibrary";
|
||||
import Grid from "@mui/material/Grid";
|
||||
import { modalStyleUtils } from "../Common/FormComponents/common/styleLibrary";
|
||||
import { LinearProgress } from "@mui/material";
|
||||
import { BackLink, Button, CreateGroupIcon, FormLayout, PageLayout } from "mds";
|
||||
import InputBoxWrapper from "../Common/FormComponents/InputBoxWrapper/InputBoxWrapper";
|
||||
import AddGroupHelpBox from "./AddGroupHelpBox";
|
||||
import UsersSelectors from "./UsersSelectors";
|
||||
import { IAM_PAGES } from "../../../common/SecureComponent/permissions";
|
||||
|
||||
import { setErrorSnackMessage, setHelpName } from "../../../systemSlice";
|
||||
import { useAppDispatch } from "../../../store";
|
||||
import PageHeaderWrapper from "../Common/PageHeaderWrapper/PageHeaderWrapper";
|
||||
import HelpMenu from "../HelpMenu";
|
||||
import {
|
||||
BackLink,
|
||||
Button,
|
||||
CreateGroupIcon,
|
||||
FormLayout,
|
||||
Grid,
|
||||
InputBox,
|
||||
PageLayout,
|
||||
} from "mds";
|
||||
import { api } from "api";
|
||||
import { errorToHandler } from "api/errors";
|
||||
import { IAM_PAGES } from "../../../common/SecureComponent/permissions";
|
||||
import { setErrorSnackMessage, setHelpName } from "../../../systemSlice";
|
||||
import { useAppDispatch } from "../../../store";
|
||||
import AddGroupHelpBox from "./AddGroupHelpBox";
|
||||
import UsersSelectors from "./UsersSelectors";
|
||||
import PageHeaderWrapper from "../Common/PageHeaderWrapper/PageHeaderWrapper";
|
||||
import HelpMenu from "../HelpMenu";
|
||||
|
||||
interface IAddGroupProps {
|
||||
classes: any;
|
||||
}
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
...formFieldStyles,
|
||||
...modalStyleUtils,
|
||||
});
|
||||
|
||||
const AddGroupScreen = ({ classes }: IAddGroupProps) => {
|
||||
const AddGroupScreen = () => {
|
||||
const dispatch = useAppDispatch();
|
||||
const navigate = useNavigate();
|
||||
const [groupName, setGroupName] = useState<string>("");
|
||||
@@ -101,73 +90,64 @@ const AddGroupScreen = ({ classes }: IAddGroupProps) => {
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<Grid item xs={12}>
|
||||
<PageHeaderWrapper
|
||||
label={
|
||||
<BackLink
|
||||
label={"Groups"}
|
||||
onClick={() => navigate(IAM_PAGES.GROUPS)}
|
||||
<PageHeaderWrapper
|
||||
label={
|
||||
<BackLink
|
||||
label={"Groups"}
|
||||
onClick={() => navigate(IAM_PAGES.GROUPS)}
|
||||
/>
|
||||
}
|
||||
actions={<HelpMenu />}
|
||||
/>
|
||||
<PageLayout>
|
||||
<FormLayout
|
||||
title={"Create Group"}
|
||||
icon={<CreateGroupIcon />}
|
||||
helpBox={<AddGroupHelpBox />}
|
||||
>
|
||||
<form noValidate autoComplete="off" onSubmit={setSaving}>
|
||||
<InputBox
|
||||
id="group-name"
|
||||
name="group-name"
|
||||
label="Group Name"
|
||||
autoFocus={true}
|
||||
value={groupName}
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setGroupName(e.target.value);
|
||||
}}
|
||||
/>
|
||||
}
|
||||
actions={<HelpMenu />}
|
||||
/>
|
||||
<PageLayout>
|
||||
<FormLayout
|
||||
title={"Create Group"}
|
||||
icon={<CreateGroupIcon />}
|
||||
helpBox={<AddGroupHelpBox />}
|
||||
>
|
||||
<form noValidate autoComplete="off" onSubmit={setSaving}>
|
||||
<Grid container>
|
||||
<Grid item xs={12} className={classes.formFieldRow}>
|
||||
<InputBoxWrapper
|
||||
id="group-name"
|
||||
name="group-name"
|
||||
label="Group Name"
|
||||
autoFocus={true}
|
||||
value={groupName}
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setGroupName(e.target.value);
|
||||
}}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.userSelector}>
|
||||
<UsersSelectors
|
||||
selectedUsers={selectedUsers}
|
||||
setSelectedUsers={setSelectedUsers}
|
||||
editMode={true}
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.modalButtonBar}>
|
||||
<Button
|
||||
id={"clear-group"}
|
||||
type="button"
|
||||
variant="regular"
|
||||
style={classes.spacerRight}
|
||||
onClick={resetForm}
|
||||
label={"Clear"}
|
||||
/>
|
||||
<UsersSelectors
|
||||
selectedUsers={selectedUsers}
|
||||
setSelectedUsers={setSelectedUsers}
|
||||
editMode={true}
|
||||
/>
|
||||
<Grid item xs={12} sx={modalStyleUtils.modalButtonBar}>
|
||||
<Button
|
||||
id={"clear-group"}
|
||||
type="button"
|
||||
variant="regular"
|
||||
onClick={resetForm}
|
||||
label={"Clear"}
|
||||
/>
|
||||
|
||||
<Button
|
||||
id={"save-group"}
|
||||
type="submit"
|
||||
variant="callAction"
|
||||
disabled={saving || !validGroup}
|
||||
label={"Save"}
|
||||
/>
|
||||
<Button
|
||||
id={"save-group"}
|
||||
type="submit"
|
||||
variant="callAction"
|
||||
disabled={saving || !validGroup}
|
||||
label={"Save"}
|
||||
/>
|
||||
</Grid>
|
||||
{saving && (
|
||||
<Grid item xs={12}>
|
||||
<LinearProgress />
|
||||
</Grid>
|
||||
{saving && (
|
||||
<Grid item xs={12}>
|
||||
<LinearProgress />
|
||||
</Grid>
|
||||
)}
|
||||
</form>
|
||||
</FormLayout>
|
||||
</PageLayout>
|
||||
</Grid>
|
||||
)}
|
||||
</form>
|
||||
</FormLayout>
|
||||
</PageLayout>
|
||||
</Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
export default withStyles(styles)(AddGroupScreen);
|
||||
export default AddGroupScreen;
|
||||
|
||||
@@ -14,17 +14,14 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React from "react";
|
||||
|
||||
import { DialogContentText } from "@mui/material";
|
||||
|
||||
import React, { Fragment } from "react";
|
||||
import { ErrorResponseHandler } from "../../../common/types";
|
||||
import ConfirmDialog from "../Common/ModalWrapper/ConfirmDialog";
|
||||
import useApi from "../Common/Hooks/useApi";
|
||||
import { ConfirmDeleteIcon } from "mds";
|
||||
import { encodeURLString } from "../../../common/utils";
|
||||
import { setErrorSnackMessage } from "../../../systemSlice";
|
||||
import { useAppDispatch } from "../../../store";
|
||||
import ConfirmDialog from "../Common/ModalWrapper/ConfirmDialog";
|
||||
import useApi from "../Common/Hooks/useApi";
|
||||
|
||||
interface IDeleteGroup {
|
||||
selectedGroups: string[];
|
||||
@@ -72,11 +69,12 @@ const DeleteGroup = ({
|
||||
onConfirm={onDeleteGroups}
|
||||
onClose={onClose}
|
||||
confirmationContent={
|
||||
<DialogContentText>
|
||||
Are you sure you want to delete the following {selectedGroups.length}{" "}
|
||||
group{selectedGroups.length > 1 ? "s?" : "?"}
|
||||
<Fragment>
|
||||
Are you sure you want to delete the following{" "}
|
||||
{selectedGroups.length === 1 ? "" : selectedGroups.length} group
|
||||
{selectedGroups.length > 1 ? "s?" : "?"}
|
||||
{renderGroups}
|
||||
</DialogContentText>
|
||||
</Fragment>
|
||||
}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
import React, { Fragment, useEffect } from "react";
|
||||
import { IAM_PAGES } from "../../../common/SecureComponent/permissions";
|
||||
import { BackLink } from "mds";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import PageHeaderWrapper from "../Common/PageHeaderWrapper/PageHeaderWrapper";
|
||||
import HelpMenu from "../HelpMenu";
|
||||
import { useAppDispatch } from "../../../store";
|
||||
import { setHelpName } from "../../../systemSlice";
|
||||
|
||||
const GroupDetailsHeader = () => {
|
||||
const navigate = useNavigate();
|
||||
|
||||
const dispatch = useAppDispatch();
|
||||
useEffect(() => {
|
||||
dispatch(setHelpName("group_details"));
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
return (
|
||||
<PageHeaderWrapper
|
||||
label={
|
||||
<Fragment>
|
||||
<BackLink
|
||||
label={"Groups"}
|
||||
onClick={() => navigate(IAM_PAGES.GROUPS)}
|
||||
/>
|
||||
</Fragment>
|
||||
}
|
||||
actions={<HelpMenu />}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default GroupDetailsHeader;
|
||||
@@ -15,7 +15,6 @@
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Fragment, useEffect, useState } from "react";
|
||||
import { Theme } from "@mui/material/styles";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import {
|
||||
AddIcon,
|
||||
@@ -26,22 +25,14 @@ import {
|
||||
IAMPoliciesIcon,
|
||||
PageLayout,
|
||||
UsersIcon,
|
||||
DataTable,
|
||||
Grid,
|
||||
Box,
|
||||
} from "mds";
|
||||
import createStyles from "@mui/styles/createStyles";
|
||||
import withStyles from "@mui/styles/withStyles";
|
||||
import Grid from "@mui/material/Grid";
|
||||
import { Box, LinearProgress } from "@mui/material";
|
||||
|
||||
import { LinearProgress } from "@mui/material";
|
||||
import { api } from "api";
|
||||
import { stringSort } from "../../../utils/sortFunctions";
|
||||
import {
|
||||
actionsTray,
|
||||
containerForHeader,
|
||||
searchField,
|
||||
tableStyles,
|
||||
} from "../Common/FormComponents/common/styleLibrary";
|
||||
import TableWrapper from "../Common/TableWrapper/TableWrapper";
|
||||
import AButton from "../Common/AButton/AButton";
|
||||
import SearchBox from "../Common/SearchBox";
|
||||
import { actionsTray } from "../Common/FormComponents/common/styleLibrary";
|
||||
import {
|
||||
applyPolicyPermissions,
|
||||
CONSOLE_UI_RESOURCE,
|
||||
@@ -56,44 +47,23 @@ import {
|
||||
hasPermission,
|
||||
SecureComponent,
|
||||
} from "../../../common/SecureComponent";
|
||||
|
||||
import { errorToHandler } from "../../../api/errors";
|
||||
import withSuspense from "../Common/Components/withSuspense";
|
||||
|
||||
import { encodeURLString } from "../../../common/utils";
|
||||
|
||||
import { setErrorSnackMessage, setHelpName } from "../../../systemSlice";
|
||||
import { useAppDispatch } from "../../../store";
|
||||
import TooltipWrapper from "../Common/TooltipWrapper/TooltipWrapper";
|
||||
import PageHeaderWrapper from "../Common/PageHeaderWrapper/PageHeaderWrapper";
|
||||
import HelpMenu from "../HelpMenu";
|
||||
import { api } from "api";
|
||||
import { errorToHandler } from "api/errors";
|
||||
import AButton from "../Common/AButton/AButton";
|
||||
import SearchBox from "../Common/SearchBox";
|
||||
|
||||
const DeleteGroup = withSuspense(React.lazy(() => import("./DeleteGroup")));
|
||||
const SetPolicy = withSuspense(
|
||||
React.lazy(() => import("../Policies/SetPolicy"))
|
||||
);
|
||||
|
||||
interface IGroupsProps {
|
||||
classes: any;
|
||||
openGroupModal: any;
|
||||
}
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
tableBlock: {
|
||||
...tableStyles.tableBlock,
|
||||
marginTop: 15,
|
||||
},
|
||||
...actionsTray,
|
||||
searchField: {
|
||||
...searchField.searchField,
|
||||
maxWidth: 380,
|
||||
},
|
||||
...containerForHeader,
|
||||
});
|
||||
|
||||
const Groups = ({ classes }: IGroupsProps) => {
|
||||
const Groups = () => {
|
||||
const dispatch = useAppDispatch();
|
||||
const navigate = useNavigate();
|
||||
|
||||
@@ -230,8 +200,8 @@ const Groups = ({ classes }: IGroupsProps) => {
|
||||
<PageHeaderWrapper label={"Groups"} actions={<HelpMenu />} />
|
||||
|
||||
<PageLayout>
|
||||
<Grid container spacing={1}>
|
||||
<Grid item xs={12} className={classes.actionsTray}>
|
||||
<Grid container>
|
||||
<Grid item xs={12} sx={actionsTray.actionsTray}>
|
||||
<SecureComponent
|
||||
resource={CONSOLE_UI_RESOURCE}
|
||||
scopes={displayGroupsPermissions}
|
||||
@@ -240,8 +210,8 @@ const Groups = ({ classes }: IGroupsProps) => {
|
||||
<SearchBox
|
||||
placeholder={"Search Groups"}
|
||||
onChange={setFilter}
|
||||
overrideClass={classes.searchField}
|
||||
value={filter}
|
||||
sx={{ maxWidth: 380 }}
|
||||
/>
|
||||
</SecureComponent>
|
||||
<Box
|
||||
@@ -334,15 +304,15 @@ const Groups = ({ classes }: IGroupsProps) => {
|
||||
<Fragment>
|
||||
{records.length > 0 && (
|
||||
<Fragment>
|
||||
<Grid item xs={12} className={classes.tableBlock}>
|
||||
<Grid item xs={12} sx={{ marginBottom: 15 }}>
|
||||
<SecureComponent
|
||||
resource={CONSOLE_UI_RESOURCE}
|
||||
scopes={displayGroupsPermissions}
|
||||
errorProps={{ disabled: true }}
|
||||
>
|
||||
<TableWrapper
|
||||
<DataTable
|
||||
itemActions={tableActions}
|
||||
columns={[{ label: "Name", elementKey: "" }]}
|
||||
columns={[{ label: "Name" }]}
|
||||
isLoading={loading}
|
||||
selectedItems={checkedGroups}
|
||||
onSelect={
|
||||
@@ -354,7 +324,7 @@ const Groups = ({ classes }: IGroupsProps) => {
|
||||
/>
|
||||
</SecureComponent>
|
||||
</Grid>
|
||||
<Grid item xs={12} marginTop={"25px"}>
|
||||
<Grid item xs={12}>
|
||||
<HelpBox
|
||||
title={"Groups"}
|
||||
iconComponent={<GroupsIcon />}
|
||||
@@ -382,12 +352,7 @@ const Groups = ({ classes }: IGroupsProps) => {
|
||||
</Fragment>
|
||||
)}
|
||||
{records.length === 0 && (
|
||||
<Grid
|
||||
container
|
||||
justifyContent={"center"}
|
||||
alignContent={"center"}
|
||||
alignItems={"center"}
|
||||
>
|
||||
<Grid container>
|
||||
<Grid item xs={8}>
|
||||
<HelpBox
|
||||
title={"Groups"}
|
||||
@@ -429,4 +394,4 @@ const Groups = ({ classes }: IGroupsProps) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default withStyles(styles)(Groups);
|
||||
export default Groups;
|
||||
|
||||
@@ -1,34 +1,40 @@
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2023 MinIO, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Fragment, useEffect, useState } from "react";
|
||||
import { Theme } from "@mui/material/styles";
|
||||
import { useNavigate, useParams } from "react-router-dom";
|
||||
import {
|
||||
AddIcon,
|
||||
BackLink,
|
||||
Box,
|
||||
Button,
|
||||
DataTable,
|
||||
Grid,
|
||||
GroupsIcon,
|
||||
IAMPoliciesIcon,
|
||||
PageLayout,
|
||||
ScreenTitle,
|
||||
SectionTitle,
|
||||
Switch,
|
||||
Tabs,
|
||||
TrashIcon,
|
||||
} from "mds";
|
||||
import createStyles from "@mui/styles/createStyles";
|
||||
import {
|
||||
actionsTray,
|
||||
containerForHeader,
|
||||
searchField,
|
||||
spacingUtils,
|
||||
tableStyles,
|
||||
} from "../Common/FormComponents/common/styleLibrary";
|
||||
|
||||
import withStyles from "@mui/styles/withStyles";
|
||||
import { Grid } from "@mui/material";
|
||||
import ScreenTitle from "../Common/ScreenTitle/ScreenTitle";
|
||||
import TableWrapper from "../Common/TableWrapper/TableWrapper";
|
||||
import SetPolicy from "../Policies/SetPolicy";
|
||||
import AddGroupMember from "./AddGroupMember";
|
||||
import DeleteGroup from "./DeleteGroup";
|
||||
import VerticalTabs from "../Common/VerticalTabs/VerticalTabs";
|
||||
import FormSwitchWrapper from "../Common/FormComponents/FormSwitchWrapper/FormSwitchWrapper";
|
||||
import PanelTitle from "../Common/PanelTitle/PanelTitle";
|
||||
import SearchBox from "../Common/SearchBox";
|
||||
import { api } from "api";
|
||||
import { errorToHandler } from "api/errors";
|
||||
import { Group } from "api/consoleApi";
|
||||
import {
|
||||
addUserToGroupPermissions,
|
||||
CONSOLE_UI_RESOURCE,
|
||||
@@ -47,83 +53,34 @@ import {
|
||||
hasPermission,
|
||||
SecureComponent,
|
||||
} from "../../../common/SecureComponent";
|
||||
import GroupDetailsHeader from "./GroupDetailsHeader";
|
||||
|
||||
import { decodeURLString, encodeURLString } from "../../../common/utils";
|
||||
import { setHelpName, setModalErrorSnackMessage } from "../../../systemSlice";
|
||||
import { useAppDispatch } from "../../../store";
|
||||
import { setSelectedPolicies } from "../Users/AddUsersSlice";
|
||||
import SetPolicy from "../Policies/SetPolicy";
|
||||
import AddGroupMember from "./AddGroupMember";
|
||||
import DeleteGroup from "./DeleteGroup";
|
||||
import SearchBox from "../Common/SearchBox";
|
||||
import TooltipWrapper from "../Common/TooltipWrapper/TooltipWrapper";
|
||||
import { api } from "api";
|
||||
import { errorToHandler } from "api/errors";
|
||||
import { Group } from "api/consoleApi";
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
pageContainer: {
|
||||
border: "1px solid #EAEAEA",
|
||||
width: "100%",
|
||||
},
|
||||
statusLabel: {
|
||||
fontSize: ".8rem",
|
||||
marginRight: ".7rem",
|
||||
},
|
||||
statusValue: {
|
||||
fontWeight: "bold",
|
||||
fontSize: ".9rem",
|
||||
marginRight: ".7rem",
|
||||
},
|
||||
searchField: {
|
||||
...searchField.searchField,
|
||||
maxWidth: 280,
|
||||
},
|
||||
...tableStyles,
|
||||
...spacingUtils,
|
||||
actionsTray: {
|
||||
...actionsTray.actionsTray,
|
||||
|
||||
alignItems: "center",
|
||||
"& h1": {
|
||||
flex: 1,
|
||||
},
|
||||
"& button": {
|
||||
marginLeft: ".8rem",
|
||||
},
|
||||
"@media (max-width: 900px)": {
|
||||
justifyContent: "flex-end",
|
||||
"& h1": {
|
||||
display: "none",
|
||||
},
|
||||
"& button": {
|
||||
whiteSpace: "nowrap",
|
||||
textOverflow: "ellipsis",
|
||||
},
|
||||
},
|
||||
},
|
||||
...containerForHeader,
|
||||
});
|
||||
|
||||
interface IGroupDetailsProps {
|
||||
classes: any;
|
||||
}
|
||||
import HelpMenu from "../HelpMenu";
|
||||
import PageHeaderWrapper from "../Common/PageHeaderWrapper/PageHeaderWrapper";
|
||||
|
||||
export const formatPolicy = (policy: string = ""): string[] => {
|
||||
if (policy.length <= 0) return [];
|
||||
return policy.split(",");
|
||||
};
|
||||
|
||||
const GroupsDetails = ({ classes }: IGroupDetailsProps) => {
|
||||
const GroupsDetails = () => {
|
||||
const dispatch = useAppDispatch();
|
||||
const navigate = useNavigate();
|
||||
const params = useParams();
|
||||
|
||||
const [groupDetails, setGroupDetails] = useState<Group>({});
|
||||
|
||||
/*Modals*/
|
||||
const [policyOpen, setPolicyOpen] = useState<boolean>(false);
|
||||
const [usersOpen, setUsersOpen] = useState<boolean>(false);
|
||||
const [deleteOpen, setDeleteOpen] = useState<boolean>(false);
|
||||
const [memberFilter, setMemberFilter] = useState<string>("");
|
||||
const [currentTab, setCurrentTab] = useState<string>("members");
|
||||
|
||||
const groupName = decodeURLString(params.groupName || "");
|
||||
|
||||
@@ -140,7 +97,7 @@ const GroupsDetails = ({ classes }: IGroupDetailsProps) => {
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(setHelpName("groups_members"));
|
||||
dispatch(setHelpName("group_details"));
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
|
||||
@@ -207,73 +164,70 @@ const GroupsDetails = ({ classes }: IGroupDetailsProps) => {
|
||||
}
|
||||
|
||||
const groupsTabContent = (
|
||||
<React.Fragment>
|
||||
<div
|
||||
className={classes.actionsTray}
|
||||
onMouseMove={() => {
|
||||
dispatch(setHelpName("groups_members"));
|
||||
}}
|
||||
>
|
||||
<PanelTitle>Members</PanelTitle>
|
||||
<SearchBox
|
||||
placeholder={"Search members"}
|
||||
onChange={(searchText) => {
|
||||
setMemberFilter(searchText);
|
||||
}}
|
||||
overrideClass={classes.searchField}
|
||||
value={memberFilter}
|
||||
/>
|
||||
<SecureComponent
|
||||
resource={CONSOLE_UI_RESOURCE}
|
||||
scopes={addUserToGroupPermissions}
|
||||
errorProps={{ disabled: true }}
|
||||
>
|
||||
<TooltipWrapper
|
||||
tooltip={
|
||||
canEditGroupMembers
|
||||
? memberActionText
|
||||
: permissionTooltipHelper(
|
||||
createGroupPermissions,
|
||||
"edit Group membership"
|
||||
)
|
||||
}
|
||||
<Box
|
||||
onMouseMove={() => {
|
||||
dispatch(setHelpName("groups_members"));
|
||||
}}
|
||||
>
|
||||
<SectionTitle
|
||||
separator
|
||||
sx={{ marginBottom: 15 }}
|
||||
actions={
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
gap: 10,
|
||||
}}
|
||||
>
|
||||
<Button
|
||||
id={"add-user-group"}
|
||||
label={memberActionText}
|
||||
variant="callAction"
|
||||
icon={<AddIcon />}
|
||||
onClick={() => {
|
||||
setUsersOpen(true);
|
||||
<SearchBox
|
||||
placeholder={"Search members"}
|
||||
onChange={(searchText) => {
|
||||
setMemberFilter(searchText);
|
||||
}}
|
||||
value={memberFilter}
|
||||
sx={{
|
||||
maxWidth: 280,
|
||||
}}
|
||||
disabled={!canEditGroupMembers}
|
||||
/>
|
||||
</TooltipWrapper>
|
||||
</SecureComponent>
|
||||
</div>
|
||||
|
||||
<SecureComponent
|
||||
resource={CONSOLE_UI_RESOURCE}
|
||||
scopes={addUserToGroupPermissions}
|
||||
errorProps={{ disabled: true }}
|
||||
>
|
||||
<TooltipWrapper
|
||||
tooltip={
|
||||
canEditGroupMembers
|
||||
? memberActionText
|
||||
: permissionTooltipHelper(
|
||||
createGroupPermissions,
|
||||
"edit Group membership"
|
||||
)
|
||||
}
|
||||
>
|
||||
<Button
|
||||
id={"add-user-group"}
|
||||
label={memberActionText}
|
||||
variant="callAction"
|
||||
icon={<AddIcon />}
|
||||
onClick={() => {
|
||||
setUsersOpen(true);
|
||||
}}
|
||||
disabled={!canEditGroupMembers}
|
||||
/>
|
||||
</TooltipWrapper>
|
||||
</SecureComponent>
|
||||
</Box>
|
||||
}
|
||||
>
|
||||
Members
|
||||
</SectionTitle>
|
||||
<Grid item xs={12}>
|
||||
<SecureComponent
|
||||
resource={CONSOLE_UI_RESOURCE}
|
||||
scopes={listUsersPermissions}
|
||||
errorProps={{ disabled: true }}
|
||||
>
|
||||
<TableWrapper
|
||||
itemActions={[
|
||||
{
|
||||
type: "view",
|
||||
onClick: (userName) => {
|
||||
navigate(`${IAM_PAGES.USERS}/${encodeURLString(userName)}`);
|
||||
},
|
||||
disableButtonFunction: () => !viewUser,
|
||||
},
|
||||
]}
|
||||
columns={[{ label: "Access Key", elementKey: "" }]}
|
||||
selectedItems={[]}
|
||||
isLoading={false}
|
||||
records={filteredMembers}
|
||||
entityName="Users"
|
||||
idField=""
|
||||
<TooltipWrapper
|
||||
tooltip={
|
||||
viewUser
|
||||
? ""
|
||||
@@ -282,59 +236,68 @@ const GroupsDetails = ({ classes }: IGroupDetailsProps) => {
|
||||
"view User details"
|
||||
)
|
||||
}
|
||||
/>
|
||||
>
|
||||
<DataTable
|
||||
itemActions={[
|
||||
{
|
||||
type: "view",
|
||||
onClick: (userName) => {
|
||||
navigate(`${IAM_PAGES.USERS}/${encodeURLString(userName)}`);
|
||||
},
|
||||
disableButtonFunction: () => !viewUser,
|
||||
},
|
||||
]}
|
||||
columns={[{ label: "Access Key" }]}
|
||||
selectedItems={[]}
|
||||
isLoading={false}
|
||||
records={filteredMembers}
|
||||
entityName="Users"
|
||||
/>
|
||||
</TooltipWrapper>
|
||||
</SecureComponent>
|
||||
</Grid>
|
||||
</React.Fragment>
|
||||
</Box>
|
||||
);
|
||||
|
||||
const policiesTabContent = (
|
||||
<React.Fragment>
|
||||
<div
|
||||
className={classes.actionsTray}
|
||||
<Fragment>
|
||||
<Box
|
||||
onMouseMove={() => {
|
||||
dispatch(setHelpName("groups_policies"));
|
||||
}}
|
||||
>
|
||||
<PanelTitle>Policies</PanelTitle>
|
||||
<TooltipWrapper
|
||||
tooltip={
|
||||
canSetPolicies
|
||||
? "Set Policies"
|
||||
: permissionTooltipHelper(
|
||||
setGroupPoliciesPermissions,
|
||||
"assign Policies"
|
||||
)
|
||||
<SectionTitle
|
||||
separator
|
||||
sx={{ marginBottom: 15 }}
|
||||
actions={
|
||||
<TooltipWrapper
|
||||
tooltip={
|
||||
canSetPolicies
|
||||
? "Set Policies"
|
||||
: permissionTooltipHelper(
|
||||
setGroupPoliciesPermissions,
|
||||
"assign Policies"
|
||||
)
|
||||
}
|
||||
>
|
||||
<Button
|
||||
id={"set-policies"}
|
||||
label={`Set Policies`}
|
||||
variant="callAction"
|
||||
icon={<IAMPoliciesIcon />}
|
||||
onClick={() => {
|
||||
setPolicyOpen(true);
|
||||
}}
|
||||
disabled={!canSetPolicies}
|
||||
/>
|
||||
</TooltipWrapper>
|
||||
}
|
||||
>
|
||||
<Button
|
||||
id={"set-policies"}
|
||||
label={`Set Policies`}
|
||||
variant="callAction"
|
||||
icon={<IAMPoliciesIcon />}
|
||||
onClick={() => {
|
||||
setPolicyOpen(true);
|
||||
}}
|
||||
disabled={!canSetPolicies}
|
||||
/>
|
||||
</TooltipWrapper>
|
||||
</div>
|
||||
Policies
|
||||
</SectionTitle>
|
||||
</Box>
|
||||
<Grid item xs={12}>
|
||||
<TableWrapper
|
||||
itemActions={[
|
||||
{
|
||||
type: "view",
|
||||
onClick: (policy) => {
|
||||
navigate(`${IAM_PAGES.POLICIES}/${encodeURLString(policy)}`);
|
||||
},
|
||||
disableButtonFunction: () => !canViewPolicy,
|
||||
},
|
||||
]}
|
||||
columns={[{ label: "Policy", elementKey: "" }]}
|
||||
isLoading={false}
|
||||
records={groupPolicies}
|
||||
entityName="Policies"
|
||||
idField=""
|
||||
<TooltipWrapper
|
||||
tooltip={
|
||||
canViewPolicy
|
||||
? ""
|
||||
@@ -343,95 +306,29 @@ const GroupsDetails = ({ classes }: IGroupDetailsProps) => {
|
||||
"view Policy details"
|
||||
)
|
||||
}
|
||||
/>
|
||||
</Grid>
|
||||
</React.Fragment>
|
||||
);
|
||||
return (
|
||||
<React.Fragment>
|
||||
<GroupDetailsHeader />
|
||||
|
||||
<PageLayout className={classes.pageContainer}>
|
||||
<Grid item xs={12}>
|
||||
<ScreenTitle
|
||||
icon={
|
||||
<Fragment>
|
||||
<GroupsIcon width={40} />
|
||||
</Fragment>
|
||||
}
|
||||
title={groupName}
|
||||
subTitle={null}
|
||||
actions={
|
||||
<Fragment>
|
||||
<span className={classes.statusLabel}>Group Status:</span>
|
||||
<span id="group-status" className={classes.statusValue}>
|
||||
{isGroupEnabled ? "Enabled" : "Disabled"}
|
||||
</span>
|
||||
<TooltipWrapper
|
||||
tooltip={
|
||||
hasPermission(
|
||||
CONSOLE_UI_RESOURCE,
|
||||
enableDisableGroupPermissions,
|
||||
true
|
||||
)
|
||||
? ""
|
||||
: permissionTooltipHelper(
|
||||
enableDisableGroupPermissions,
|
||||
"enable or disable Groups"
|
||||
)
|
||||
}
|
||||
>
|
||||
<SecureComponent
|
||||
resource={CONSOLE_UI_RESOURCE}
|
||||
scopes={enableDisableGroupPermissions}
|
||||
errorProps={{ disabled: true }}
|
||||
matchAll
|
||||
>
|
||||
<FormSwitchWrapper
|
||||
indicatorLabels={["Enabled", "Disabled"]}
|
||||
checked={isGroupEnabled}
|
||||
value={"group_enabled"}
|
||||
id="group-status"
|
||||
name="group-status"
|
||||
onChange={() => {
|
||||
toggleGroupStatus(!isGroupEnabled);
|
||||
}}
|
||||
switchOnly
|
||||
/>
|
||||
</SecureComponent>
|
||||
</TooltipWrapper>
|
||||
|
||||
<div className={classes.spacerLeft}>
|
||||
<TooltipWrapper tooltip={"Delete Group"}>
|
||||
<Button
|
||||
id={"delete-user-group"}
|
||||
variant="secondary"
|
||||
icon={<TrashIcon />}
|
||||
onClick={() => {
|
||||
setDeleteOpen(true);
|
||||
}}
|
||||
/>
|
||||
</TooltipWrapper>
|
||||
</div>
|
||||
</Fragment>
|
||||
}
|
||||
>
|
||||
<DataTable
|
||||
itemActions={[
|
||||
{
|
||||
type: "view",
|
||||
onClick: (policy) => {
|
||||
navigate(`${IAM_PAGES.POLICIES}/${encodeURLString(policy)}`);
|
||||
},
|
||||
disableButtonFunction: () => !canViewPolicy,
|
||||
},
|
||||
]}
|
||||
columns={[{ label: "Policy" }]}
|
||||
isLoading={false}
|
||||
records={groupPolicies}
|
||||
entityName="Policies"
|
||||
/>
|
||||
</Grid>
|
||||
</TooltipWrapper>
|
||||
</Grid>
|
||||
</Fragment>
|
||||
);
|
||||
|
||||
<Grid item xs={12}>
|
||||
<VerticalTabs>
|
||||
{{
|
||||
tabConfig: { label: "Members" },
|
||||
content: groupsTabContent,
|
||||
}}
|
||||
{{
|
||||
tabConfig: { label: "Policies" },
|
||||
content: policiesTabContent,
|
||||
}}
|
||||
</VerticalTabs>
|
||||
</Grid>
|
||||
</PageLayout>
|
||||
{/*Modals*/}
|
||||
return (
|
||||
<Fragment>
|
||||
{policyOpen ? (
|
||||
<SetPolicy
|
||||
open={policyOpen}
|
||||
@@ -472,9 +369,110 @@ const GroupsDetails = ({ classes }: IGroupDetailsProps) => {
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{/*Modals*/}
|
||||
</React.Fragment>
|
||||
<PageHeaderWrapper
|
||||
label={
|
||||
<Fragment>
|
||||
<BackLink
|
||||
label={"Groups"}
|
||||
onClick={() => navigate(IAM_PAGES.GROUPS)}
|
||||
/>
|
||||
</Fragment>
|
||||
}
|
||||
actions={<HelpMenu />}
|
||||
/>
|
||||
<PageLayout>
|
||||
<Grid item xs={12}>
|
||||
<ScreenTitle
|
||||
icon={
|
||||
<Fragment>
|
||||
<GroupsIcon width={40} />
|
||||
</Fragment>
|
||||
}
|
||||
title={groupName}
|
||||
subTitle={null}
|
||||
bottomBorder
|
||||
actions={
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
fontSize: 14,
|
||||
alignItems: "center",
|
||||
gap: 15,
|
||||
}}
|
||||
>
|
||||
<span>Group Status:</span>
|
||||
<span id="group-status-label" style={{ fontWeight: "bold" }}>
|
||||
{isGroupEnabled ? "Enabled" : "Disabled"}
|
||||
</span>
|
||||
<TooltipWrapper
|
||||
tooltip={
|
||||
hasPermission(
|
||||
CONSOLE_UI_RESOURCE,
|
||||
enableDisableGroupPermissions,
|
||||
true
|
||||
)
|
||||
? ""
|
||||
: permissionTooltipHelper(
|
||||
enableDisableGroupPermissions,
|
||||
"enable or disable Groups"
|
||||
)
|
||||
}
|
||||
>
|
||||
<SecureComponent
|
||||
resource={CONSOLE_UI_RESOURCE}
|
||||
scopes={enableDisableGroupPermissions}
|
||||
errorProps={{ disabled: true }}
|
||||
matchAll
|
||||
>
|
||||
<Switch
|
||||
indicatorLabels={["Enabled", "Disabled"]}
|
||||
checked={isGroupEnabled}
|
||||
value={"group_enabled"}
|
||||
id="group-status"
|
||||
name="group-status"
|
||||
onChange={() => {
|
||||
toggleGroupStatus(!isGroupEnabled);
|
||||
}}
|
||||
switchOnly
|
||||
/>
|
||||
</SecureComponent>
|
||||
</TooltipWrapper>
|
||||
|
||||
<TooltipWrapper tooltip={"Delete Group"}>
|
||||
<Button
|
||||
id={"delete-user-group"}
|
||||
variant="secondary"
|
||||
icon={<TrashIcon />}
|
||||
onClick={() => {
|
||||
setDeleteOpen(true);
|
||||
}}
|
||||
/>
|
||||
</TooltipWrapper>
|
||||
</Box>
|
||||
}
|
||||
sx={{ marginBottom: 15 }}
|
||||
/>
|
||||
</Grid>
|
||||
|
||||
<Grid item xs={12}>
|
||||
<Tabs
|
||||
options={[
|
||||
{
|
||||
tabConfig: { id: "members", label: "Members" },
|
||||
content: groupsTabContent,
|
||||
},
|
||||
{
|
||||
tabConfig: { id: "policies", label: "Policies" },
|
||||
content: policiesTabContent,
|
||||
},
|
||||
]}
|
||||
currentTabOrPath={currentTab}
|
||||
onTabClick={setCurrentTab}
|
||||
/>
|
||||
</Grid>
|
||||
</PageLayout>
|
||||
</Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
export default withStyles(styles)(GroupsDetails);
|
||||
export default GroupsDetails;
|
||||
|
||||
@@ -14,71 +14,24 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { useCallback, useEffect, useState } from "react";
|
||||
import { Theme } from "@mui/material/styles";
|
||||
import createStyles from "@mui/styles/createStyles";
|
||||
import withStyles from "@mui/styles/withStyles";
|
||||
import { LinearProgress } from "@mui/material";
|
||||
import React, { useCallback, useEffect, useState, Fragment } from "react";
|
||||
import get from "lodash/get";
|
||||
import Paper from "@mui/material/Paper";
|
||||
import Grid from "@mui/material/Grid";
|
||||
import { usersSort } from "../../../utils/sortFunctions";
|
||||
import {
|
||||
actionsTray,
|
||||
selectorsCommon,
|
||||
tableStyles,
|
||||
} from "../Common/FormComponents/common/styleLibrary";
|
||||
|
||||
import TableWrapper from "../Common/TableWrapper/TableWrapper";
|
||||
import SearchBox from "../Common/SearchBox";
|
||||
|
||||
import { setModalErrorSnackMessage } from "../../../systemSlice";
|
||||
import { useAppDispatch } from "../../../store";
|
||||
import { api } from "api";
|
||||
import { errorToHandler } from "api/errors";
|
||||
import { Box, DataTable, Grid } from "mds";
|
||||
import { LinearProgress } from "@mui/material";
|
||||
import { usersSort } from "../../../utils/sortFunctions";
|
||||
import { setModalErrorSnackMessage } from "../../../systemSlice";
|
||||
import { useAppDispatch } from "../../../store";
|
||||
import SearchBox from "../Common/SearchBox";
|
||||
|
||||
interface IGroupsProps {
|
||||
classes: any;
|
||||
selectedUsers: string[];
|
||||
setSelectedUsers: any;
|
||||
editMode?: boolean;
|
||||
}
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
paper: {
|
||||
display: "flex",
|
||||
overflow: "auto",
|
||||
flexDirection: "column",
|
||||
// paddingTop: 15,
|
||||
boxShadow: "none",
|
||||
border: 0,
|
||||
},
|
||||
|
||||
tableBlock: {
|
||||
...tableStyles.tableBlock,
|
||||
},
|
||||
searchBox: {
|
||||
flex: 1,
|
||||
},
|
||||
...actionsTray,
|
||||
actionsTitle: {
|
||||
fontSize: 14,
|
||||
alignSelf: "center",
|
||||
minWidth: 160,
|
||||
marginRight: 10,
|
||||
},
|
||||
noFound: {
|
||||
textAlign: "center",
|
||||
padding: theme.spacing(3),
|
||||
border: "1px solid #EAEAEA",
|
||||
fontSize: ".9rem",
|
||||
},
|
||||
...selectorsCommon,
|
||||
});
|
||||
|
||||
const UsersSelectors = ({
|
||||
classes,
|
||||
selectedUsers,
|
||||
setSelectedUsers,
|
||||
editMode = false,
|
||||
@@ -146,44 +99,43 @@ const UsersSelectors = ({
|
||||
);
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<Grid item xs={12}>
|
||||
<Paper className={classes.paper}>
|
||||
{loading && <LinearProgress />}
|
||||
{records !== null && records.length > 0 ? (
|
||||
<React.Fragment>
|
||||
<Grid item xs={12} className={classes.actionsTray}>
|
||||
<label className={classes.actionsTitle}>
|
||||
{editMode ? "Edit Members" : "Assign Users"}
|
||||
</label>
|
||||
<div className={classes.searchBox}>
|
||||
<SearchBox
|
||||
placeholder="Filter Users"
|
||||
onChange={setFilter}
|
||||
value={filter}
|
||||
/>
|
||||
</div>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.tableBlock}>
|
||||
<TableWrapper
|
||||
columns={[{ label: "Access Key", elementKey: "accessKey" }]}
|
||||
onSelect={selectionChanged}
|
||||
selectedItems={selUsers}
|
||||
isLoading={loading}
|
||||
records={filteredRecords}
|
||||
entityName="Users"
|
||||
idField="accessKey"
|
||||
customPaperHeight={classes.multiSelectTable}
|
||||
/>
|
||||
</Grid>
|
||||
</React.Fragment>
|
||||
) : (
|
||||
<div className={classes.noFound}>No Users to display</div>
|
||||
)}
|
||||
</Paper>
|
||||
</Grid>
|
||||
</React.Fragment>
|
||||
<Grid item xs={12} className={"inputItem"}>
|
||||
<Box>
|
||||
{loading && <LinearProgress />}
|
||||
{records?.length > 0 ? (
|
||||
<Fragment>
|
||||
<Grid item xs={12} className={"inputItem"}>
|
||||
<SearchBox
|
||||
label={editMode ? "Edit Members" : "Assign Users"}
|
||||
placeholder="Filter Users"
|
||||
onChange={setFilter}
|
||||
value={filter}
|
||||
/>
|
||||
</Grid>
|
||||
<DataTable
|
||||
columns={[{ label: "Access Key", elementKey: "accessKey" }]}
|
||||
onSelect={selectionChanged}
|
||||
selectedItems={selUsers}
|
||||
isLoading={loading}
|
||||
records={filteredRecords}
|
||||
entityName="Users"
|
||||
idField="accessKey"
|
||||
customPaperHeight={"200px"}
|
||||
/>
|
||||
</Fragment>
|
||||
) : (
|
||||
<Box
|
||||
sx={{
|
||||
textAlign: "center",
|
||||
padding: "10px 0",
|
||||
}}
|
||||
>
|
||||
No Users to display
|
||||
</Box>
|
||||
)}
|
||||
</Box>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
|
||||
export default withStyles(styles)(UsersSelectors);
|
||||
export default UsersSelectors;
|
||||
|
||||
@@ -16,59 +16,28 @@
|
||||
|
||||
import React, { Fragment, useEffect, useState } from "react";
|
||||
import get from "lodash/get";
|
||||
import { Theme } from "@mui/material/styles";
|
||||
import { Button } from "mds";
|
||||
import createStyles from "@mui/styles/createStyles";
|
||||
import withStyles from "@mui/styles/withStyles";
|
||||
import { useSelector } from "react-redux";
|
||||
import { Button, FormLayout, ReadBox, Grid } from "mds";
|
||||
import { LinearProgress } from "@mui/material";
|
||||
import Grid from "@mui/material/Grid";
|
||||
import {
|
||||
modalBasic,
|
||||
spacingUtils,
|
||||
tableStyles,
|
||||
} from "../Common/FormComponents/common/styleLibrary";
|
||||
import { User } from "../Users/types";
|
||||
|
||||
import { ErrorResponseHandler } from "../../../common/types";
|
||||
import ModalWrapper from "../Common/ModalWrapper/ModalWrapper";
|
||||
import api from "../../../common/api";
|
||||
import PolicySelectors from "./PolicySelectors";
|
||||
import PredefinedList from "../Common/FormComponents/PredefinedList/PredefinedList";
|
||||
import { encodeURLString } from "../../../common/utils";
|
||||
import { setModalErrorSnackMessage } from "../../../systemSlice";
|
||||
import { AppState, useAppDispatch } from "../../../store";
|
||||
|
||||
import { useSelector } from "react-redux";
|
||||
import { modalStyleUtils } from "../Common/FormComponents/common/styleLibrary";
|
||||
import { User } from "../Users/types";
|
||||
import { setSelectedPolicies } from "../Users/AddUsersSlice";
|
||||
import ModalWrapper from "../Common/ModalWrapper/ModalWrapper";
|
||||
import PolicySelectors from "./PolicySelectors";
|
||||
import api from "../../../common/api";
|
||||
|
||||
interface ISetPolicyProps {
|
||||
classes: any;
|
||||
closeModalAndRefresh: () => void;
|
||||
selectedUser: User | null;
|
||||
selectedGroups: string[] | null;
|
||||
open: boolean;
|
||||
}
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
...modalBasic,
|
||||
...spacingUtils,
|
||||
tableBlock: {
|
||||
...tableStyles.tableBlock,
|
||||
marginTop: 15,
|
||||
},
|
||||
buttonContainer: {
|
||||
display: "flex",
|
||||
justifyContent: "flex-end",
|
||||
marginTop: ".9rem",
|
||||
"& button": {
|
||||
marginLeft: 8,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const SetPolicy = ({
|
||||
classes,
|
||||
closeModalAndRefresh,
|
||||
selectedUser,
|
||||
selectedGroups,
|
||||
@@ -158,41 +127,34 @@ const SetPolicy = ({
|
||||
modalOpen={open}
|
||||
title="Set Policies"
|
||||
>
|
||||
<Grid container>
|
||||
<FormLayout withBorders={false} containerPadding={false}>
|
||||
{(selectedGroups?.length === 1 || selectedUser != null) && (
|
||||
<Fragment>
|
||||
<Grid item xs={12}>
|
||||
<PredefinedList
|
||||
label={`Selected ${selectedGroups !== null ? "Group" : "User"}`}
|
||||
content={selectedGroups !== null ? selectedGroups[0] : userName}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<PredefinedList
|
||||
label={"Current Policy"}
|
||||
content={actualPolicy.join(", ")}
|
||||
/>
|
||||
</Grid>
|
||||
<ReadBox
|
||||
label={`Selected ${selectedGroups !== null ? "Group" : "User"}`}
|
||||
sx={{ width: "100%" }}
|
||||
>
|
||||
{selectedGroups !== null ? selectedGroups[0] : userName}
|
||||
</ReadBox>
|
||||
<ReadBox label={"Current Policy"} sx={{ width: "100%" }}>
|
||||
{actualPolicy.join(", ")}
|
||||
</ReadBox>
|
||||
</Fragment>
|
||||
)}
|
||||
{selectedGroups && selectedGroups?.length > 1 && (
|
||||
<PredefinedList
|
||||
label={"Selected Groups"}
|
||||
content={selectedGroups.join(", ")}
|
||||
/>
|
||||
<ReadBox label={"Selected Groups"} sx={{ width: "100%" }}>
|
||||
{selectedGroups.join(", ")}
|
||||
</ReadBox>
|
||||
)}
|
||||
<Grid item xs={12}>
|
||||
<div className={classes.tableBlock}>
|
||||
<PolicySelectors selectedPolicy={selectedPolicy} />
|
||||
</div>
|
||||
<PolicySelectors selectedPolicy={selectedPolicy} />
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.buttonContainer}>
|
||||
</FormLayout>
|
||||
<Grid item xs={12} sx={modalStyleUtils.modalButtonBar}>
|
||||
<Button
|
||||
id={"reset"}
|
||||
type="button"
|
||||
variant="regular"
|
||||
className={classes.spacerRight}
|
||||
onClick={resetSelection}
|
||||
label={"Reset"}
|
||||
/>
|
||||
@@ -215,4 +177,4 @@ const SetPolicy = ({
|
||||
);
|
||||
};
|
||||
|
||||
export default withStyles(styles)(SetPolicy);
|
||||
export default SetPolicy;
|
||||
|
||||
@@ -15,8 +15,6 @@
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Fragment, useEffect, useState } from "react";
|
||||
|
||||
import { Theme } from "@mui/material/styles";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import {
|
||||
AddIcon,
|
||||
@@ -29,23 +27,12 @@ import {
|
||||
DataTable,
|
||||
Grid,
|
||||
} from "mds";
|
||||
import createStyles from "@mui/styles/createStyles";
|
||||
import withStyles from "@mui/styles/withStyles";
|
||||
import api from "../../../common/api";
|
||||
import { LinearProgress } from "@mui/material";
|
||||
import { User, UsersList } from "./types";
|
||||
import { usersSort } from "../../../utils/sortFunctions";
|
||||
import {
|
||||
actionsTray,
|
||||
containerForHeader,
|
||||
searchField,
|
||||
tableStyles,
|
||||
} from "../Common/FormComponents/common/styleLibrary";
|
||||
import { actionsTray } from "../Common/FormComponents/common/styleLibrary";
|
||||
import { ErrorResponseHandler } from "../../../common/types";
|
||||
import { encodeURLString } from "../../../common/utils";
|
||||
import AButton from "../Common/AButton/AButton";
|
||||
import SearchBox from "../Common/SearchBox";
|
||||
import withSuspense from "../Common/Components/withSuspense";
|
||||
import {
|
||||
addUserToGroupPermissions,
|
||||
CONSOLE_UI_RESOURCE,
|
||||
@@ -57,6 +44,10 @@ import {
|
||||
S3_ALL_RESOURCES,
|
||||
viewUserPermissions,
|
||||
} from "../../../common/SecureComponent/permissions";
|
||||
import api from "../../../common/api";
|
||||
import AButton from "../Common/AButton/AButton";
|
||||
import SearchBox from "../Common/SearchBox";
|
||||
import withSuspense from "../Common/Components/withSuspense";
|
||||
|
||||
import {
|
||||
hasPermission,
|
||||
@@ -71,24 +62,7 @@ import HelpMenu from "../HelpMenu";
|
||||
const DeleteUser = withSuspense(React.lazy(() => import("./DeleteUser")));
|
||||
const AddToGroup = withSuspense(React.lazy(() => import("./BulkAddToGroup")));
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
...actionsTray,
|
||||
...searchField,
|
||||
searchField: {
|
||||
...searchField.searchField,
|
||||
marginRight: "auto",
|
||||
maxWidth: 380,
|
||||
},
|
||||
...tableStyles,
|
||||
...containerForHeader,
|
||||
});
|
||||
|
||||
interface IUsersProps {
|
||||
classes: any;
|
||||
}
|
||||
|
||||
const ListUsers = ({ classes }: IUsersProps) => {
|
||||
const ListUsers = () => {
|
||||
const dispatch = useAppDispatch();
|
||||
const navigate = useNavigate();
|
||||
|
||||
@@ -219,12 +193,15 @@ const ListUsers = ({ classes }: IUsersProps) => {
|
||||
|
||||
<PageLayout>
|
||||
<Grid container>
|
||||
<Grid item xs={12} className={classes.actionsTray}>
|
||||
<Grid item xs={12} sx={actionsTray.actionsTray}>
|
||||
<SearchBox
|
||||
placeholder={"Search Users"}
|
||||
onChange={setFilter}
|
||||
overrideClass={classes.searchField}
|
||||
value={filter}
|
||||
sx={{
|
||||
marginRight: "auto",
|
||||
maxWidth: 380,
|
||||
}}
|
||||
/>
|
||||
<SecureComponent
|
||||
resource={CONSOLE_UI_RESOURCE}
|
||||
@@ -352,12 +329,7 @@ const ListUsers = ({ classes }: IUsersProps) => {
|
||||
<Fragment>
|
||||
{records.length > 0 && (
|
||||
<Fragment>
|
||||
<Grid
|
||||
item
|
||||
xs={12}
|
||||
className={classes.tableBlock}
|
||||
sx={{ marginBottom: 15 }}
|
||||
>
|
||||
<Grid item xs={12} sx={{ marginBottom: 15 }}>
|
||||
<SecureComponent
|
||||
scopes={[IAM_SCOPES.ADMIN_LIST_USERS]}
|
||||
resource={CONSOLE_UI_RESOURCE}
|
||||
@@ -496,4 +468,4 @@ const ListUsers = ({ classes }: IUsersProps) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default withStyles(styles)(ListUsers);
|
||||
export default ListUsers;
|
||||
|
||||
@@ -371,7 +371,7 @@ const UserDetails = () => {
|
||||
disabled: !canAssignGroup,
|
||||
},
|
||||
content: (
|
||||
<React.Fragment>
|
||||
<Fragment>
|
||||
<Box
|
||||
onMouseMove={() =>
|
||||
dispatch(setHelpName("user_details_groups"))
|
||||
@@ -423,7 +423,7 @@ const UserDetails = () => {
|
||||
idField="group"
|
||||
/>
|
||||
</Grid>
|
||||
</React.Fragment>
|
||||
</Fragment>
|
||||
),
|
||||
},
|
||||
{
|
||||
|
||||
@@ -52,7 +52,7 @@ export const assignPoliciesButton = Selector("button").withAttribute(
|
||||
//----------------------------------------------------
|
||||
// Switches
|
||||
//----------------------------------------------------
|
||||
export const switchInput = Selector(".MuiSwitch-input");
|
||||
export const switchInput = Selector("#group-status").sibling("span");
|
||||
export const deleteAllVersions =
|
||||
Selector("#delete-versions").sibling("span.switchRail");
|
||||
|
||||
@@ -84,11 +84,10 @@ export const filterUserInput = searchResourceInput.withAttribute(
|
||||
"placeholder",
|
||||
"Filter Users"
|
||||
);
|
||||
export const groupUserCheckbox = Selector(".ReactVirtualized__Table__row span")
|
||||
.withText(constants.TEST_USER_NAME)
|
||||
.parent(1)
|
||||
.find(".ReactVirtualized__Grid input")
|
||||
.withAttribute("type", "checkbox");
|
||||
export const groupUserCheckbox = Selector(".ReactVirtualized__Table__row input")
|
||||
.withAttribute("type", "checkbox")
|
||||
.withAttribute("value", constants.TEST_USER_NAME)
|
||||
.sibling("span");
|
||||
|
||||
//----------------------------------------------------
|
||||
// Dropdowns and options
|
||||
@@ -103,7 +102,7 @@ export const bucketDropdownOptionFor = (modifier) => {
|
||||
//----------------------------------------------------
|
||||
// Text
|
||||
//----------------------------------------------------
|
||||
export const groupStatusText = Selector("#group-status");
|
||||
export const groupStatusText = Selector("#group-status-label");
|
||||
|
||||
//----------------------------------------------------
|
||||
// Tables, table headers and content
|
||||
|
||||
Reference in New Issue
Block a user