github.com/minio/console@v1.4.1/web-app/src/screens/Console/Users/AddUserScreen.tsx (about) 1 // This file is part of MinIO Console Server 2 // Copyright (c) 2022 MinIO, Inc. 3 // 4 // This program is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Affero General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // This program is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Affero General Public License for more details. 13 // 14 // You should have received a copy of the GNU Affero General Public License 15 // along with this program. If not, see <http://www.gnu.org/licenses/>. 16 17 import React, { Fragment, useEffect } from "react"; 18 import { 19 BackLink, 20 Button, 21 CreateUserIcon, 22 FormLayout, 23 Grid, 24 PageLayout, 25 ProgressBar, 26 } from "mds"; 27 import { createUserAsync, resetFormAsync } from "./thunk/AddUsersThunk"; 28 import { modalStyleUtils } from "../Common/FormComponents/common/styleLibrary"; 29 30 import { IAM_PAGES } from "../../../common/SecureComponent/permissions"; 31 import { useNavigate } from "react-router-dom"; 32 import { setErrorSnackMessage, setHelpName } from "../../../systemSlice"; 33 import { AppState, useAppDispatch } from "../../../store"; 34 import { useSelector } from "react-redux"; 35 import { 36 setAddLoading, 37 setSelectedGroups, 38 setSendEnabled, 39 } from "./AddUsersSlice"; 40 import AddUserHelpBox from "./AddUserHelpBox"; 41 import PageHeaderWrapper from "../Common/PageHeaderWrapper/PageHeaderWrapper"; 42 import HelpMenu from "../HelpMenu"; 43 import PolicySelectors from "../Policies/PolicySelectors"; 44 import UserSelector from "./UserSelector"; 45 import PasswordSelector from "./PasswordSelector"; 46 import GroupsSelectors from "./GroupsSelectors"; 47 48 const AddUser = () => { 49 const dispatch = useAppDispatch(); 50 const selectedPolicies = useSelector( 51 (state: AppState) => state.createUser.selectedPolicies, 52 ); 53 const selectedGroups = useSelector( 54 (state: AppState) => state.createUser.selectedGroups, 55 ); 56 const addLoading = useSelector( 57 (state: AppState) => state.createUser.addLoading, 58 ); 59 const sendEnabled = useSelector( 60 (state: AppState) => state.createUser.sendEnabled, 61 ); 62 const secretKeylength = useSelector( 63 (state: AppState) => state.createUser.secretKeylength, 64 ); 65 const navigate = useNavigate(); 66 dispatch(setSendEnabled()); 67 68 const saveRecord = (event: React.FormEvent) => { 69 event.preventDefault(); 70 if (secretKeylength < 8) { 71 dispatch( 72 setErrorSnackMessage({ 73 errorMessage: "Passwords must be at least 8 characters long", 74 detailedError: "", 75 }), 76 ); 77 dispatch(setAddLoading(false)); 78 return; 79 } 80 if (addLoading) { 81 return; 82 } 83 dispatch(setAddLoading(true)); 84 dispatch(createUserAsync()) 85 .unwrap() // <-- async Thunk returns a promise, that can be 'unwrapped') 86 .then(() => navigate(`${IAM_PAGES.USERS}`)); 87 }; 88 89 useEffect(() => { 90 dispatch(setHelpName("add_user")); 91 // eslint-disable-next-line react-hooks/exhaustive-deps 92 }, []); 93 94 return ( 95 <Fragment> 96 <Grid item xs={12}> 97 <PageHeaderWrapper 98 label={ 99 <BackLink 100 label={"Users"} 101 onClick={() => navigate(IAM_PAGES.USERS)} 102 /> 103 } 104 actions={<HelpMenu />} 105 /> 106 <PageLayout> 107 <FormLayout 108 title={"Create User"} 109 icon={<CreateUserIcon />} 110 helpBox={<AddUserHelpBox />} 111 > 112 <form 113 noValidate 114 autoComplete="off" 115 onSubmit={(e: React.FormEvent<HTMLFormElement>) => { 116 saveRecord(e); 117 }} 118 > 119 <UserSelector /> 120 <PasswordSelector /> 121 <PolicySelectors selectedPolicy={selectedPolicies} /> 122 <GroupsSelectors 123 selectedGroups={selectedGroups} 124 setSelectedGroups={(elements: string[]) => { 125 dispatch(setSelectedGroups(elements)); 126 }} 127 /> 128 {addLoading && ( 129 <Grid item xs={12}> 130 <ProgressBar /> 131 </Grid> 132 )} 133 134 <Grid item xs={12} sx={modalStyleUtils.modalButtonBar}> 135 <Button 136 id={"clear-add-user"} 137 type="button" 138 variant="regular" 139 onClick={(e) => { 140 dispatch(resetFormAsync()); 141 }} 142 label={"Clear"} 143 /> 144 145 <Button 146 id={"save-user"} 147 type="submit" 148 variant="callAction" 149 color="primary" 150 disabled={addLoading || !sendEnabled} 151 label={"Save"} 152 /> 153 </Grid> 154 </form> 155 </FormLayout> 156 </PageLayout> 157 </Grid> 158 </Fragment> 159 ); 160 }; 161 162 export default AddUser;