Format Add Users/Groups, Fix bug on Add Service Account (#1898)

Signed-off-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>
This commit is contained in:
Daniel Valdivia
2022-04-22 22:36:41 -07:00
committed by GitHub
parent 8a96d8d8a5
commit 8203449d92
3 changed files with 218 additions and 249 deletions

View File

@@ -108,7 +108,9 @@ const Dashboard = React.lazy(() => import("./Dashboard/Dashboard"));
const Account = React.lazy(() => import("./Account/Account")); const Account = React.lazy(() => import("./Account/Account"));
const AccountCreate = React.lazy(() => import("./Account/AddServiceAccountScreen")); const AccountCreate = React.lazy(
() => import("./Account/AddServiceAccountScreen")
);
const Users = React.lazy(() => import("./Users/Users")); const Users = React.lazy(() => import("./Users/Users"));
const Groups = React.lazy(() => import("./Groups/Groups")); const Groups = React.lazy(() => import("./Groups/Groups"));
@@ -122,9 +124,7 @@ const ConfigurationOptions = React.lazy(
const AddPool = React.lazy( const AddPool = React.lazy(
() => import("./Tenants/TenantDetails/Pools/AddPool/AddPool") () => import("./Tenants/TenantDetails/Pools/AddPool/AddPool")
); );
const AddGroupScreen = React.lazy( const AddGroupScreen = React.lazy(() => import("./Groups/AddGroupScreen"));
() => import("./Groups/AddGroupScreen")
);
const SiteReplication = React.lazy( const SiteReplication = React.lazy(
() => import("./Configurations/SiteReplication/SiteReplication") () => import("./Configurations/SiteReplication/SiteReplication")
); );
@@ -411,7 +411,8 @@ const Console = ({
{ {
component: Account, component: Account,
path: IAM_PAGES.ACCOUNT, path: IAM_PAGES.ACCOUNT,
// user has implicit access to service-accounts forceDisplay: true,
// user has implicit access to service-accounts
}, },
{ {
component: AccountCreate, component: AccountCreate,

View File

@@ -14,7 +14,7 @@
// You should have received a copy of the GNU Affero General Public License // 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/>. // along with this program. If not, see <http://www.gnu.org/licenses/>.
import React, { Fragment, useState, useEffect } from "react"; import React, { Fragment, useEffect, useState } from "react";
import { Theme } from "@mui/material/styles"; import { Theme } from "@mui/material/styles";
import createStyles from "@mui/styles/createStyles"; import createStyles from "@mui/styles/createStyles";
import withStyles from "@mui/styles/withStyles"; import withStyles from "@mui/styles/withStyles";
@@ -23,7 +23,7 @@ import {
modalStyleUtils, modalStyleUtils,
} from "../Common/FormComponents/common/styleLibrary"; } from "../Common/FormComponents/common/styleLibrary";
import Grid from "@mui/material/Grid"; import Grid from "@mui/material/Grid";
import { Button, Box, LinearProgress } from "@mui/material"; import { Box, Button, LinearProgress } from "@mui/material";
import PageHeader from "../Common/PageHeader/PageHeader"; import PageHeader from "../Common/PageHeader/PageHeader";
import PageLayout from "../Common/Layout/PageLayout"; import PageLayout from "../Common/Layout/PageLayout";
import history from "../../../../src/history"; import history from "../../../../src/history";
@@ -37,6 +37,7 @@ import { IAM_PAGES } from "../../../common/SecureComponent/permissions";
import { ErrorResponseHandler } from "../../../../src/common/types"; import { ErrorResponseHandler } from "../../../../src/common/types";
import api from "../../../../src/common/api"; import api from "../../../../src/common/api";
import { setErrorSnackMessage } from "../../../../src/actions"; import { setErrorSnackMessage } from "../../../../src/actions";
import SectionTitle from "../Common/SectionTitle";
interface IAddGroupProps { interface IAddGroupProps {
classes: any; classes: any;
@@ -100,16 +101,12 @@ const styles = (theme: Theme) =>
...modalStyleUtils, ...modalStyleUtils,
}); });
const AddGroupScreen = ({ const AddGroupScreen = ({ classes, setErrorSnackMessage }: IAddGroupProps) => {
classes,
setErrorSnackMessage,
}: IAddGroupProps) => {
const [groupName, setGroupName] = useState<string>(""); const [groupName, setGroupName] = useState<string>("");
const [saving, isSaving] = useState<boolean>(false); const [saving, isSaving] = useState<boolean>(false);
const [selectedUsers, setSelectedUsers] = useState<string[]>([]); const [selectedUsers, setSelectedUsers] = useState<string[]>([]);
const [validGroup, setValidGroup] = useState<boolean>(false); const [validGroup, setValidGroup] = useState<boolean>(false);
useEffect(() => { useEffect(() => {
setValidGroup(groupName.trim() !== ""); setValidGroup(groupName.trim() !== "");
}, [groupName, selectedUsers]); }, [groupName, selectedUsers]);
@@ -117,31 +114,24 @@ const AddGroupScreen = ({
useEffect(() => { useEffect(() => {
if (saving) { if (saving) {
const saveRecord = () => { const saveRecord = () => {
api
api .invoke("POST", "/api/v1/groups", {
.invoke("POST", "/api/v1/groups", { group: groupName,
group: groupName, members: selectedUsers,
members: selectedUsers, })
}) .then((res) => {
.then((res) => { isSaving(false);
isSaving(false); history.push(`${IAM_PAGES.GROUPS}`);
history.push(`${IAM_PAGES.GROUPS}`); })
}) .catch((err: ErrorResponseHandler) => {
.catch((err: ErrorResponseHandler) => { isSaving(false);
isSaving(false); setErrorSnackMessage(err);
setErrorSnackMessage(err); });
}); };
}
saveRecord(); saveRecord();
} }
}, [saving, groupName, selectedUsers, setErrorSnackMessage]);
}, [
saving,
groupName,
selectedUsers,
setErrorSnackMessage,
]);
//Fetch Actions //Fetch Actions
const setSaving = (event: React.FormEvent) => { const setSaving = (event: React.FormEvent) => {
@@ -151,12 +141,10 @@ const AddGroupScreen = ({
}; };
const resetForm = () => { const resetForm = () => {
setGroupName(""); setGroupName("");
setSelectedUsers([]); setSelectedUsers([]);
}; };
return ( return (
<Fragment> <Fragment>
<Grid item xs={12}> <Grid item xs={12}>
@@ -164,85 +152,81 @@ const AddGroupScreen = ({
label={<BackLink to={IAM_PAGES.GROUPS} label={"Groups"} />} label={<BackLink to={IAM_PAGES.GROUPS} label={"Groups"} />}
/> />
<PageLayout> <PageLayout>
<Grid <Box
item sx={{
xs={12} display: "grid",
container padding: "25px",
className={classes.title} gap: "25px",
align-items="stretch" gridTemplateColumns: {
md: "2fr 1.2fr",
xs: "1fr",
},
border: "1px solid #eaeaea",
}}
> >
<Grid item className={classes.headIcon}> <Box>
<CreateGroupIcon /> <form noValidate autoComplete="off" onSubmit={setSaving}>
</Grid> <Grid container item spacing="20">
<Grid item className={classes.headTitle}> <Grid item xs={12}>
Create Group <SectionTitle icon={<CreateGroupIcon />}>
</Grid> Create Group
</Grid> </SectionTitle>
</Grid>
<Grid item xs={12}>
<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
type="button"
variant="outlined"
color="primary"
className={classes.spacerRight}
onClick={resetForm}
>
Clear
</Button>
<Grid container align-items="center"> <Button
<Grid item xs={8}> type="submit"
<Box> variant="contained"
<form noValidate autoComplete="off" onSubmit={setSaving}> color="primary"
<Grid container item spacing = "20"> disabled={saving || !validGroup}
>
<Grid item xs={12} > Save
<Grid container> </Button>
<Grid item xs={12} className={classes.formFieldRow}> </Grid>
<InputBoxWrapper </Grid>
id="group-name" {saving && (
name="group-name" <Grid item xs={12}>
label="Group Name" <LinearProgress />
autoFocus={true} </Grid>
value={groupName} )}
onChange={(e: React.ChangeEvent<HTMLInputElement>) => { </Grid>
setGroupName(e.target.value); </form>
}} </Box>
/> <AddGroupHelpBox />
</Grid> </Box>
<Grid item xs={12} className={classes.userSelector}>
<UsersSelectors
selectedUsers={selectedUsers}
setSelectedUsers={setSelectedUsers}
editMode={true}
/>
</Grid>
</Grid>
<Grid item xs={12} className={classes.modalButtonBar}>
<Button
type="button"
variant="outlined"
color="primary"
className={classes.spacerRight}
onClick={resetForm}
>
Clear
</Button>
<Button
type="submit"
variant="contained"
color="primary"
disabled={saving || !validGroup}
>
Save
</Button>
</Grid>
</Grid>
{saving && (
<Grid item xs={12}>
<LinearProgress />
</Grid>
)}
</Grid>
</form>
</Box>
</Grid>
<Grid item xs={4}>
<Box>
<AddGroupHelpBox />
</Box>
</Grid>
</Grid>
</PageLayout> </PageLayout>
</Grid> </Grid>
</Fragment> </Fragment>

View File

@@ -23,7 +23,7 @@ import {
modalStyleUtils, modalStyleUtils,
} from "../Common/FormComponents/common/styleLibrary"; } from "../Common/FormComponents/common/styleLibrary";
import Grid from "@mui/material/Grid"; import Grid from "@mui/material/Grid";
import { Button, LinearProgress, Box } from "@mui/material"; import { Box, Button, LinearProgress } from "@mui/material";
import { CreateUserIcon } from "../../../icons"; import { CreateUserIcon } from "../../../icons";
import PageHeader from "../Common/PageHeader/PageHeader"; import PageHeader from "../Common/PageHeader/PageHeader";
@@ -31,7 +31,6 @@ import PageLayout from "../Common/Layout/PageLayout";
import history from "../../../../src/history"; import history from "../../../../src/history";
import InputBoxWrapper from "../Common/FormComponents/InputBoxWrapper/InputBoxWrapper"; import InputBoxWrapper from "../Common/FormComponents/InputBoxWrapper/InputBoxWrapper";
import AddUserHelpBox from "./AddUserHelpBox";
import PolicySelectors from "../Policies/PolicySelectors"; import PolicySelectors from "../Policies/PolicySelectors";
import BackLink from "../../../common/BackLink"; import BackLink from "../../../common/BackLink";
import GroupsSelectors from "./GroupsSelectors"; import GroupsSelectors from "./GroupsSelectors";
@@ -45,6 +44,8 @@ import { ErrorResponseHandler } from "../../../../src/common/types";
import api from "../../../../src/common/api"; import api from "../../../../src/common/api";
import { setErrorSnackMessage } from "../../../../src/actions"; import { setErrorSnackMessage } from "../../../../src/actions";
import SectionTitle from "../Common/SectionTitle";
import AddUserHelpBox from "../Account/AddServiceAccountHelpBox";
interface IAddUserProps { interface IAddUserProps {
classes: any; classes: any;
@@ -102,10 +103,7 @@ const styles = (theme: Theme) =>
...modalStyleUtils, ...modalStyleUtils,
}); });
const AddUser = ({ const AddUser = ({ classes, setErrorSnackMessage }: IAddUserProps) => {
classes,
setErrorSnackMessage,
}: IAddUserProps) => {
const [addLoading, setAddLoading] = useState<boolean>(false); const [addLoading, setAddLoading] = useState<boolean>(false);
const [accessKey, setAccessKey] = useState<string>(""); const [accessKey, setAccessKey] = useState<string>("");
const [secretKey, setSecretKey] = useState<string>(""); const [secretKey, setSecretKey] = useState<string>("");
@@ -161,134 +159,120 @@ const AddUser = ({
<Grid item xs={12}> <Grid item xs={12}>
<PageHeader label={<BackLink to={IAM_PAGES.USERS} label={"Users"} />} /> <PageHeader label={<BackLink to={IAM_PAGES.USERS} label={"Users"} />} />
<PageLayout> <PageLayout>
<Grid <Box
item sx={{
xs={12} display: "grid",
container padding: "25px",
className={classes.title} gap: "25px",
align-items="baseline" gridTemplateColumns: {
md: "2fr 1.2fr",
xs: "1fr",
},
border: "1px solid #eaeaea",
}}
> >
<Grid item xs={"auto"}> <Box>
<CreateUserIcon /> <form
</Grid> noValidate
<Grid autoComplete="off"
item onSubmit={(e: React.FormEvent<HTMLFormElement>) => {
xs={"auto"} saveRecord(e);
align-self="end" }}
className={classes.headTitle} >
> <Grid container spacing={1}>
Create User <Grid item xs={12}>
</Grid> <SectionTitle icon={<CreateUserIcon />}>
</Grid> Create User
</SectionTitle>
<Grid container align-items="center">
<Grid item xs={8}>
<Box>
<form
noValidate
autoComplete="off"
onSubmit={(e: React.FormEvent<HTMLFormElement>) => {
saveRecord(e);
}}
>
<Grid container>
<Grid item xs={12}>
<div className={classes.formFieldRow}>
<InputBoxWrapper
className={classes.spacerBottom}
classes={{
inputLabel: classes.sizedLabel,
}}
id="accesskey-input"
name="accesskey-input"
label="User Name"
value={accessKey}
autoFocus={true}
onChange={(
e: React.ChangeEvent<HTMLInputElement>
) => {
setAccessKey(e.target.value);
}}
/>
</div>
<div className={classes.formFieldRow}>
<InputBoxWrapper
className={classes.spacerBottom}
classes={{
inputLabel: classes.sizedLabel,
}}
id="standard-multiline-static"
name="standard-multiline-static"
label="Password"
type={showPassword ? "text" : "password"}
value={secretKey}
onChange={(
e: React.ChangeEvent<HTMLInputElement>
) => {
setSecretKey(e.target.value);
}}
autoComplete="current-password"
overlayIcon={
showPassword ? (
<VisibilityOffIcon />
) : (
<RemoveRedEyeIcon />
)
}
overlayAction={() => setShowPassword(!showPassword)}
/>
</div>
<Grid container item spacing="20">
<Grid item xs={12}>
<PolicySelectors
selectedPolicy={selectedPolicies}
setSelectedPolicy={setSelectedPolicies}
/>
</Grid>
<Grid item xs={12}>
<GroupsSelectors
selectedGroups={selectedGroups}
setSelectedGroups={(elements: string[]) => {
setSelectedGroups(elements);
}}
/>
</Grid>
</Grid>
{addLoading && (
<Grid item xs={12}>
<LinearProgress />
</Grid>
)}
</Grid>
<Grid item xs={12} className={classes.modalButtonBar}>
<Button
type="button"
variant="outlined"
color="primary"
onClick={resetForm}
>
Clear
</Button>
<Button
type="submit"
variant="contained"
color="primary"
disabled={addLoading || !sendEnabled}
>
Save
</Button>
</Grid>
</Grid> </Grid>
</form> <Grid item xs={12}>
</Box> <div className={classes.formFieldRow}>
</Grid> <InputBoxWrapper
<Grid item xs={4}> className={classes.spacerBottom}
<Box> classes={{
<AddUserHelpBox /> inputLabel: classes.sizedLabel,
</Box> }}
</Grid> id="accesskey-input"
</Grid> name="accesskey-input"
label="User Name"
value={accessKey}
autoFocus={true}
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
setAccessKey(e.target.value);
}}
/>
</div>
<div className={classes.formFieldRow}>
<InputBoxWrapper
className={classes.spacerBottom}
classes={{
inputLabel: classes.sizedLabel,
}}
id="standard-multiline-static"
name="standard-multiline-static"
label="Password"
type={showPassword ? "text" : "password"}
value={secretKey}
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
setSecretKey(e.target.value);
}}
autoComplete="current-password"
overlayIcon={
showPassword ? (
<VisibilityOffIcon />
) : (
<RemoveRedEyeIcon />
)
}
overlayAction={() => setShowPassword(!showPassword)}
/>
</div>
<Grid container item spacing="20">
<Grid item xs={12}>
<PolicySelectors
selectedPolicy={selectedPolicies}
setSelectedPolicy={setSelectedPolicies}
/>
</Grid>
<Grid item xs={12}>
<GroupsSelectors
selectedGroups={selectedGroups}
setSelectedGroups={(elements: string[]) => {
setSelectedGroups(elements);
}}
/>
</Grid>
</Grid>
{addLoading && (
<Grid item xs={12}>
<LinearProgress />
</Grid>
)}
</Grid>
<Grid item xs={12} className={classes.modalButtonBar}>
<Button
type="button"
variant="outlined"
color="primary"
onClick={resetForm}
>
Clear
</Button>
<Button
type="submit"
variant="contained"
color="primary"
disabled={addLoading || !sendEnabled}
>
Save
</Button>
</Grid>
</Grid>
</form>
</Box>
<AddUserHelpBox />
</Box>
</PageLayout> </PageLayout>
</Grid> </Grid>
</Fragment> </Fragment>