github.com/minio/console@v1.4.1/web-app/src/screens/Console/Users/ChangeUserGroups.tsx (about) 1 // This file is part of MinIO Console Server 2 // Copyright (c) 2021 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, { useCallback, useEffect, useState, Fragment } from "react"; 18 19 import { 20 AddMembersToGroupIcon, 21 Button, 22 FormLayout, 23 Grid, 24 Box, 25 ProgressBar, 26 } from "mds"; 27 import { modalStyleUtils } from "../Common/FormComponents/common/styleLibrary"; 28 import { ErrorResponseHandler } from "../../../common/types"; 29 import { encodeURLString } from "../../../common/utils"; 30 import { setModalErrorSnackMessage } from "../../../systemSlice"; 31 import { useAppDispatch } from "../../../store"; 32 import api from "../../../common/api"; 33 import GroupsSelectors from "./GroupsSelectors"; 34 import ModalWrapper from "../Common/ModalWrapper/ModalWrapper"; 35 36 interface IChangeUserGroupsContentProps { 37 closeModalAndRefresh: () => void; 38 selectedUser: string; 39 open: boolean; 40 } 41 42 const ChangeUserGroups = ({ 43 closeModalAndRefresh, 44 selectedUser, 45 open, 46 }: IChangeUserGroupsContentProps) => { 47 const dispatch = useAppDispatch(); 48 const [addLoading, setAddLoading] = useState<boolean>(false); 49 const [accessKey, setAccessKey] = useState<string>(""); 50 const [secretKey, setSecretKey] = useState<string>(""); 51 const [enabled, setEnabled] = useState<boolean>(false); 52 const [selectedGroups, setSelectedGroups] = useState<string[]>([]); 53 54 const getUserInformation = useCallback(() => { 55 if (!selectedUser) { 56 return null; 57 } 58 59 api 60 .invoke("GET", `/api/v1/user/${encodeURLString(selectedUser)}`) 61 .then((res) => { 62 setAddLoading(false); 63 setAccessKey(res.accessKey); 64 setSelectedGroups(res.memberOf || []); 65 setEnabled(res.status === "enabled"); 66 }) 67 .catch((err: ErrorResponseHandler) => { 68 setAddLoading(false); 69 dispatch(setModalErrorSnackMessage(err)); 70 }); 71 }, [selectedUser, dispatch]); 72 73 useEffect(() => { 74 if (selectedUser === null) { 75 setAccessKey(""); 76 setSecretKey(""); 77 setSelectedGroups([]); 78 } else { 79 getUserInformation(); 80 } 81 }, [selectedUser, getUserInformation]); 82 83 const saveRecord = (event: React.FormEvent) => { 84 event.preventDefault(); 85 86 if (addLoading) { 87 return; 88 } 89 setAddLoading(true); 90 if (selectedUser !== null) { 91 api 92 .invoke("PUT", `/api/v1/user/${encodeURLString(selectedUser)}`, { 93 status: enabled ? "enabled" : "disabled", 94 groups: selectedGroups, 95 }) 96 .then((_) => { 97 setAddLoading(false); 98 closeModalAndRefresh(); 99 }) 100 .catch((err: ErrorResponseHandler) => { 101 setAddLoading(false); 102 dispatch(setModalErrorSnackMessage(err)); 103 }); 104 } else { 105 api 106 .invoke("POST", "/api/v1/users", { 107 accessKey, 108 secretKey, 109 groups: selectedGroups, 110 }) 111 .then((_) => { 112 setAddLoading(false); 113 closeModalAndRefresh(); 114 }) 115 .catch((err: ErrorResponseHandler) => { 116 setAddLoading(false); 117 dispatch(setModalErrorSnackMessage(err)); 118 }); 119 } 120 }; 121 122 const resetForm = () => { 123 if (selectedUser !== null) { 124 setSelectedGroups([]); 125 return; 126 } 127 setAccessKey(""); 128 setSecretKey(""); 129 setSelectedGroups([]); 130 }; 131 132 const sendEnabled = 133 accessKey.trim() !== "" && 134 ((secretKey.trim() !== "" && selectedUser === null) || 135 selectedUser !== null); 136 return ( 137 <ModalWrapper 138 onClose={() => { 139 closeModalAndRefresh(); 140 }} 141 modalOpen={open} 142 title={"Set Groups"} 143 titleIcon={<AddMembersToGroupIcon />} 144 > 145 <Fragment> 146 <form 147 noValidate 148 autoComplete="off" 149 onSubmit={(e: React.FormEvent<HTMLFormElement>) => { 150 saveRecord(e); 151 }} 152 > 153 <FormLayout withBorders={false} containerPadding={false}> 154 <GroupsSelectors 155 selectedGroups={selectedGroups} 156 setSelectedGroups={(elements: string[]) => { 157 setSelectedGroups(elements); 158 }} 159 /> 160 </FormLayout> 161 <Box sx={modalStyleUtils.modalButtonBar}> 162 <Button 163 id={"clear-change-user-groups"} 164 type="button" 165 variant="regular" 166 onClick={resetForm} 167 label={"Clear"} 168 /> 169 170 <Button 171 id={"save-user-groups"} 172 type="submit" 173 variant="callAction" 174 disabled={addLoading || !sendEnabled} 175 label={"Save"} 176 /> 177 </Box> 178 {addLoading && ( 179 <Grid item xs={12}> 180 <ProgressBar /> 181 </Grid> 182 )} 183 </form> 184 </Fragment> 185 </ModalWrapper> 186 ); 187 }; 188 189 export default ChangeUserGroups;