Reduce renders in User Name when adding a user (#2106)
This commit is contained in:
committed by
GitHub
parent
e68bc08fed
commit
5d591b18d9
@@ -36,11 +36,12 @@ import TableWrapper from "../Common/TableWrapper/TableWrapper";
|
||||
import SearchBox from "../Common/SearchBox";
|
||||
import { setModalErrorSnackMessage } from "../../../systemSlice";
|
||||
import { useAppDispatch } from "../../../store";
|
||||
import { setSelectedPolicies } from "../Users/AddUsersSlice";
|
||||
|
||||
|
||||
interface ISelectPolicyProps {
|
||||
classes: any;
|
||||
selectedPolicy?: string[];
|
||||
setSelectedPolicy: any;
|
||||
}
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
@@ -77,7 +78,6 @@ const styles = (theme: Theme) =>
|
||||
const PolicySelectors = ({
|
||||
classes,
|
||||
selectedPolicy = [],
|
||||
setSelectedPolicy,
|
||||
}: ISelectPolicyProps) => {
|
||||
const dispatch = useAppDispatch();
|
||||
// Local State
|
||||
@@ -129,7 +129,7 @@ const PolicySelectors = ({
|
||||
// remove empty values
|
||||
elements = elements.filter((element) => element !== "");
|
||||
|
||||
setSelectedPolicy(elements);
|
||||
dispatch(setSelectedPolicies(elements));
|
||||
};
|
||||
|
||||
const filteredRecords = records.filter((elementItem) =>
|
||||
|
||||
@@ -173,7 +173,6 @@ const SetPolicy = ({
|
||||
<div className={classes.tableBlock}>
|
||||
<PolicySelectors
|
||||
selectedPolicy={selectedPolicy}
|
||||
setSelectedPolicy={setSelectedPolicy}
|
||||
/>
|
||||
</div>
|
||||
</Grid>
|
||||
|
||||
@@ -14,13 +14,15 @@
|
||||
// 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, useState } from "react";
|
||||
import UserSelector from "./UserSelector";
|
||||
import React, { Fragment } from "react";
|
||||
import { Theme } from "@mui/material/styles";
|
||||
import createStyles from "@mui/styles/createStyles";
|
||||
import withStyles from "@mui/styles/withStyles";
|
||||
import {createUserAsync, resetFormAsync} from "./thunk/AddUsersThunk";
|
||||
import {
|
||||
formFieldStyles,
|
||||
modalStyleUtils,
|
||||
formFieldStyles,
|
||||
modalStyleUtils,
|
||||
} from "../Common/FormComponents/common/styleLibrary";
|
||||
import Grid from "@mui/material/Grid";
|
||||
import { Button, LinearProgress } from "@mui/material";
|
||||
@@ -37,200 +39,180 @@ import GroupsSelectors from "./GroupsSelectors";
|
||||
import RemoveRedEyeIcon from "@mui/icons-material/RemoveRedEye";
|
||||
import VisibilityOffIcon from "@mui/icons-material/VisibilityOff";
|
||||
import { IAM_PAGES } from "../../../common/SecureComponent/permissions";
|
||||
import { ErrorResponseHandler } from "../../../../src/common/types";
|
||||
import api from "../../../../src/common/api";
|
||||
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import FormLayout from "../Common/FormLayout";
|
||||
import AddUserHelpBox from "./AddUserHelpBox";
|
||||
import { setErrorSnackMessage } from "../../../systemSlice";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { useAppDispatch } from "../../../store";
|
||||
|
||||
import { useSelector} from "react-redux";
|
||||
import {AppState} from "../../../store";
|
||||
import {
|
||||
setSelectedGroups,
|
||||
setAddLoading,
|
||||
setShowPassword,
|
||||
setSecretKey,
|
||||
setSendEnabled,
|
||||
} from "./AddUsersSlice";
|
||||
interface IAddUserProps {
|
||||
classes: any;
|
||||
classes: any;
|
||||
}
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
bottomContainer: {
|
||||
display: "flex",
|
||||
flexGrow: 1,
|
||||
alignItems: "center",
|
||||
margin: "auto",
|
||||
justifyContent: "center",
|
||||
"& div": {
|
||||
width: 150,
|
||||
"@media (max-width: 900px)": {
|
||||
flexFlow: "column",
|
||||
createStyles({
|
||||
bottomContainer: {
|
||||
display: "flex",
|
||||
flexGrow: 1,
|
||||
alignItems: "center",
|
||||
margin: "auto",
|
||||
justifyContent: "center",
|
||||
"& div": {
|
||||
width: 150,
|
||||
"@media (max-width: 900px)": {
|
||||
flexFlow: "column",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
...formFieldStyles,
|
||||
...modalStyleUtils,
|
||||
});
|
||||
...formFieldStyles,
|
||||
...modalStyleUtils,
|
||||
});
|
||||
|
||||
const AddUser = ({ classes }: IAddUserProps) => {
|
||||
const dispatch = useAppDispatch();
|
||||
const navigate = useNavigate();
|
||||
const dispatch = useAppDispatch();
|
||||
const showPassword = useSelector(
|
||||
(state: AppState) => state.createUser.showPassword
|
||||
)
|
||||
const selectedPolicies = useSelector(
|
||||
(state: AppState) => state.createUser.selectedPolicies
|
||||
)
|
||||
const selectedGroups = useSelector(
|
||||
(state: AppState) => state.createUser.selectedGroups
|
||||
)
|
||||
const secretKey = useSelector(
|
||||
(state: AppState) => state.createUser.secretKey
|
||||
)
|
||||
const addLoading = useSelector(
|
||||
(state: AppState) => state.createUser.addLoading
|
||||
)
|
||||
const sendEnabled = useSelector(
|
||||
(state: AppState) => state.createUser.sendEnabled
|
||||
)
|
||||
const navigate = useNavigate();
|
||||
dispatch(setSendEnabled());
|
||||
const saveRecord = (event: React.FormEvent) => {
|
||||
event.preventDefault();
|
||||
if (secretKey.length < 8) {
|
||||
dispatch(
|
||||
setErrorSnackMessage({
|
||||
errorMessage: "Passwords must be at least 8 characters long",
|
||||
detailedError: "",
|
||||
})
|
||||
);
|
||||
dispatch(setAddLoading(false));
|
||||
return;
|
||||
}
|
||||
if (addLoading) {
|
||||
return;
|
||||
}
|
||||
dispatch(setAddLoading(true));
|
||||
dispatch(createUserAsync())
|
||||
.unwrap() // <-- async Thunk returns a promise, that can be 'unwrapped')
|
||||
.then(() => navigate(`${IAM_PAGES.USERS}`))
|
||||
};
|
||||
|
||||
const [addLoading, setAddLoading] = useState<boolean>(false);
|
||||
const [accessKey, setAccessKey] = useState<string>("");
|
||||
const [secretKey, setSecretKey] = useState<string>("");
|
||||
const [selectedGroups, setSelectedGroups] = useState<string[]>([]);
|
||||
const [selectedPolicies, setSelectedPolicies] = useState<string[]>([]);
|
||||
const [showPassword, setShowPassword] = useState<boolean>(false);
|
||||
return (
|
||||
<Fragment>
|
||||
<Grid item xs={12}>
|
||||
<PageHeader label={<BackLink to={IAM_PAGES.USERS} label={"Users"} />} />
|
||||
<PageLayout>
|
||||
<FormLayout
|
||||
title={"Create User"}
|
||||
icon={<CreateUserIcon />}
|
||||
helpbox={<AddUserHelpBox />}
|
||||
>
|
||||
<form
|
||||
noValidate
|
||||
autoComplete="off"
|
||||
onSubmit={(e: React.FormEvent<HTMLFormElement>) => {
|
||||
saveRecord(e);
|
||||
}}
|
||||
>
|
||||
<Grid item xs={12}>
|
||||
<div className={classes.formFieldRow}>
|
||||
<UserSelector classes={classes} />
|
||||
</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>) => {
|
||||
dispatch(setSecretKey(e.target.value));
|
||||
}}
|
||||
autoComplete="current-password"
|
||||
overlayIcon={
|
||||
showPassword ? (
|
||||
<VisibilityOffIcon />
|
||||
) : (
|
||||
<RemoveRedEyeIcon />
|
||||
)
|
||||
}
|
||||
overlayAction={() => dispatch(setShowPassword(!showPassword))}
|
||||
/>
|
||||
</div>
|
||||
<Grid container item spacing="20">
|
||||
<Grid item xs={12}>
|
||||
<PolicySelectors
|
||||
selectedPolicy={selectedPolicies}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<GroupsSelectors
|
||||
selectedGroups={selectedGroups}
|
||||
setSelectedGroups={(elements: string[]) => {
|
||||
dispatch(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={(e) => {
|
||||
dispatch(resetFormAsync());
|
||||
}}
|
||||
>
|
||||
Clear
|
||||
</Button>
|
||||
|
||||
const sendEnabled = accessKey.trim() !== "";
|
||||
|
||||
const saveRecord = (event: React.FormEvent) => {
|
||||
event.preventDefault();
|
||||
|
||||
if (secretKey.length < 8) {
|
||||
dispatch(
|
||||
setErrorSnackMessage({
|
||||
errorMessage: "Passwords must be at least 8 characters long",
|
||||
detailedError: "",
|
||||
})
|
||||
);
|
||||
setAddLoading(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (addLoading) {
|
||||
return;
|
||||
}
|
||||
setAddLoading(true);
|
||||
api
|
||||
.invoke("POST", "/api/v1/users", {
|
||||
accessKey,
|
||||
secretKey,
|
||||
groups: selectedGroups,
|
||||
policies: selectedPolicies,
|
||||
})
|
||||
.then((res) => {
|
||||
setAddLoading(false);
|
||||
navigate(`${IAM_PAGES.USERS}`);
|
||||
})
|
||||
.catch((err: ErrorResponseHandler) => {
|
||||
setAddLoading(false);
|
||||
dispatch(setErrorSnackMessage(err));
|
||||
});
|
||||
};
|
||||
|
||||
const resetForm = () => {
|
||||
setSelectedGroups([]);
|
||||
setAccessKey("");
|
||||
setSecretKey("");
|
||||
setSelectedPolicies([]);
|
||||
setShowPassword(false);
|
||||
};
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<Grid item xs={12}>
|
||||
<PageHeader label={<BackLink to={IAM_PAGES.USERS} label={"Users"} />} />
|
||||
<PageLayout>
|
||||
<FormLayout
|
||||
title={"Create User"}
|
||||
icon={<CreateUserIcon />}
|
||||
helpbox={<AddUserHelpBox />}
|
||||
>
|
||||
<form
|
||||
noValidate
|
||||
autoComplete="off"
|
||||
onSubmit={(e: React.FormEvent<HTMLFormElement>) => {
|
||||
saveRecord(e);
|
||||
}}
|
||||
>
|
||||
<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>
|
||||
</form>
|
||||
</FormLayout>
|
||||
</PageLayout>
|
||||
</Grid>
|
||||
</Fragment>
|
||||
);
|
||||
<Button
|
||||
type="submit"
|
||||
variant="contained"
|
||||
color="primary"
|
||||
disabled={addLoading || !sendEnabled}
|
||||
>
|
||||
Save
|
||||
</Button>
|
||||
</Grid>
|
||||
</form>
|
||||
</FormLayout>
|
||||
</PageLayout>
|
||||
</Grid>
|
||||
</Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
export default withStyles(styles)(AddUser);
|
||||
export default withStyles(styles)(AddUser);
|
||||
105
portal-ui/src/screens/Console/Users/AddUsersSlice.tsx
Normal file
105
portal-ui/src/screens/Console/Users/AddUsersSlice.tsx
Normal file
@@ -0,0 +1,105 @@
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2022 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 { createSlice, PayloadAction } from "@reduxjs/toolkit";
|
||||
import {
|
||||
createUserAsync,
|
||||
resetFormAsync,
|
||||
} from "./thunk/AddUsersThunk";
|
||||
|
||||
export interface ICreateUser {
|
||||
userName: string;
|
||||
secretKey: string;
|
||||
selectedGroups: string[];
|
||||
selectedPolicies: string[];
|
||||
showPassword: boolean;
|
||||
sendEnabled: boolean;
|
||||
addLoading: boolean;
|
||||
apinoerror: boolean;
|
||||
}
|
||||
|
||||
const initialState: ICreateUser = {
|
||||
addLoading: false,
|
||||
showPassword: false,
|
||||
sendEnabled: false,
|
||||
apinoerror: false,
|
||||
userName: "",
|
||||
secretKey: "",
|
||||
selectedGroups: [],
|
||||
selectedPolicies: [],
|
||||
};
|
||||
|
||||
export const createUserSlice = createSlice({
|
||||
name: "createUser",
|
||||
initialState,
|
||||
reducers: {
|
||||
setAddLoading: (state, action: PayloadAction<boolean>) => {
|
||||
state.addLoading = action.payload;
|
||||
},
|
||||
setUserName: (state, action: PayloadAction<string>) => {
|
||||
state.userName = action.payload;
|
||||
},
|
||||
setSelectedGroups: (state, action: PayloadAction<string[]>) => {
|
||||
state.selectedGroups = action.payload;
|
||||
},
|
||||
setSecretKey: (state, action: PayloadAction<string>) => {
|
||||
state.secretKey = action.payload;
|
||||
},
|
||||
setSelectedPolicies: (state, action: PayloadAction<string[]>) => {
|
||||
state.selectedPolicies = action.payload;
|
||||
},
|
||||
setShowPassword: (state, action: PayloadAction<boolean>) => {
|
||||
state.showPassword = action.payload;
|
||||
},
|
||||
setSendEnabled: (state) => {
|
||||
state.sendEnabled = state.userName.trim() !== "";
|
||||
},
|
||||
setApinoerror: (state, action: PayloadAction<boolean>) => {
|
||||
state.apinoerror = action.payload;
|
||||
},
|
||||
},
|
||||
extraReducers: (builder) => {
|
||||
builder
|
||||
.addCase(resetFormAsync.fulfilled, (state, action) => {
|
||||
state.userName = "";
|
||||
state.selectedGroups = [];
|
||||
state.secretKey = "";
|
||||
state.selectedPolicies = [];
|
||||
state.showPassword = false;
|
||||
})
|
||||
.addCase(createUserAsync.pending, (state, action) => {
|
||||
state.addLoading = true;
|
||||
})
|
||||
.addCase(createUserAsync.rejected, (state, action) => {
|
||||
state.addLoading = false;
|
||||
})
|
||||
.addCase(createUserAsync.fulfilled, (state, action) => {
|
||||
state.apinoerror = true;
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
export const {
|
||||
setUserName,
|
||||
setSelectedGroups,
|
||||
setSecretKey,
|
||||
setSelectedPolicies,
|
||||
setShowPassword,
|
||||
setAddLoading,
|
||||
setSendEnabled,
|
||||
setApinoerror,
|
||||
} = createUserSlice.actions;
|
||||
|
||||
export default createUserSlice.reducer;
|
||||
@@ -110,7 +110,6 @@ const SetUserPolicies = ({
|
||||
<Grid item xs={12}>
|
||||
<PolicySelectors
|
||||
selectedPolicy={selectedPolicy}
|
||||
setSelectedPolicy={setSelectedPolicy}
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
51
portal-ui/src/screens/Console/Users/UserSelector.tsx
Normal file
51
portal-ui/src/screens/Console/Users/UserSelector.tsx
Normal file
@@ -0,0 +1,51 @@
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2022 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 } from "react";
|
||||
import InputBoxWrapper from "../Common/FormComponents/InputBoxWrapper/InputBoxWrapper";
|
||||
import { setUserName } from "./AddUsersSlice";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import {AppState} from "../../../store";
|
||||
|
||||
interface IAddUserProps2 {
|
||||
classes: any;
|
||||
}
|
||||
|
||||
const UserSelector = ({ classes }: IAddUserProps2 ) => {
|
||||
const dispatch = useDispatch();
|
||||
const userName = useSelector(
|
||||
(state: AppState) => state.createUser.userName
|
||||
)
|
||||
return (
|
||||
<Fragment>
|
||||
<InputBoxWrapper
|
||||
className={classes.spacerBottom}
|
||||
classes={{
|
||||
inputLabel: classes.sizedLabel,
|
||||
}}
|
||||
id="accesskey-input"
|
||||
name="accesskey-input"
|
||||
label="User Name"
|
||||
value={userName}
|
||||
autoFocus={true}
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
dispatch(setUserName(e.target.value));
|
||||
}}
|
||||
/>
|
||||
</Fragment>
|
||||
);
|
||||
};
|
||||
export default UserSelector;
|
||||
68
portal-ui/src/screens/Console/Users/thunk/AddUsersThunk.tsx
Normal file
68
portal-ui/src/screens/Console/Users/thunk/AddUsersThunk.tsx
Normal file
@@ -0,0 +1,68 @@
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2022 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 { createAsyncThunk } from "@reduxjs/toolkit";
|
||||
import {
|
||||
setSelectedGroups,
|
||||
setUserName,
|
||||
setSecretKey,
|
||||
setSelectedPolicies,
|
||||
setShowPassword,
|
||||
setAddLoading,
|
||||
} from "../AddUsersSlice";
|
||||
import {AppState} from "../../../../store";
|
||||
import api from "../../../../common/api";
|
||||
import {ErrorResponseHandler} from "../../../../common/types";
|
||||
import {setErrorSnackMessage} from "../../../../systemSlice";
|
||||
import history from "../../../../history";
|
||||
import {IAM_PAGES} from "../../../../common/SecureComponent/permissions";
|
||||
|
||||
export const resetFormAsync = createAsyncThunk(
|
||||
"resetForm/resetFormAsync",
|
||||
async (_, { dispatch }) => {
|
||||
dispatch(setSelectedGroups([]));
|
||||
dispatch(setUserName(""));
|
||||
dispatch(setSecretKey(""));
|
||||
dispatch(setSelectedPolicies([]));
|
||||
dispatch(setShowPassword(false));
|
||||
}
|
||||
);
|
||||
|
||||
export const createUserAsync = createAsyncThunk(
|
||||
"createTenant/createNamespaceAsync",
|
||||
async (_, { getState, rejectWithValue, dispatch }) => {
|
||||
const state = getState() as AppState;
|
||||
const accessKey = state.createUser.userName
|
||||
const secretKey = state.createUser.secretKey
|
||||
const selectedGroups = state.createUser.selectedGroups
|
||||
const selectedPolicies = state.createUser.selectedPolicies
|
||||
return api
|
||||
.invoke("POST", "/api/v1/users", {
|
||||
accessKey,
|
||||
secretKey,
|
||||
groups: selectedGroups,
|
||||
policies: selectedPolicies,
|
||||
})
|
||||
.then((res) => {
|
||||
dispatch(setAddLoading(false));
|
||||
history.push(`${IAM_PAGES.USERS}`);
|
||||
})
|
||||
.catch((err: ErrorResponseHandler) => {
|
||||
dispatch(setAddLoading(false));
|
||||
dispatch(setErrorSnackMessage(err));
|
||||
});
|
||||
}
|
||||
);
|
||||
@@ -28,6 +28,7 @@ import objectBrowserReducer from "./screens/Console/ObjectBrowser/objectBrowserS
|
||||
import tenantsReducer from "./screens/Console/Tenants/tenantsSlice";
|
||||
import dashboardReducer from "./screens/Console/Dashboard/dashboardSlice";
|
||||
import createTenantReducer from "./screens/Console/Tenants/AddTenant/createTenantSlice";
|
||||
import createUserReducer from "./screens/Console/Users/AddUsersSlice";
|
||||
import addPoolReducer from "./screens/Console/Tenants/TenantDetails/Pools/AddPool/addPoolSlice";
|
||||
import editPoolReducer from "./screens/Console/Tenants/TenantDetails/Pools/EditPool/editPoolSlice";
|
||||
|
||||
@@ -45,6 +46,7 @@ const rootReducer = combineReducers({
|
||||
// Operator Reducers
|
||||
tenants: tenantsReducer,
|
||||
createTenant: createTenantReducer,
|
||||
createUser: createUserReducer,
|
||||
addPool: addPoolReducer,
|
||||
editPool: editPoolReducer,
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user