github.com/minio/console@v1.4.1/web-app/src/screens/Console/Groups/UsersSelectors.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 import get from "lodash/get"; 19 import { api } from "api"; 20 import { errorToHandler } from "api/errors"; 21 import { Box, DataTable, Grid, ProgressBar } from "mds"; 22 23 import { usersSort } from "../../../utils/sortFunctions"; 24 import { setModalErrorSnackMessage } from "../../../systemSlice"; 25 import { useAppDispatch } from "../../../store"; 26 import SearchBox from "../Common/SearchBox"; 27 28 interface IGroupsProps { 29 selectedUsers: string[]; 30 setSelectedUsers: any; 31 editMode?: boolean; 32 } 33 34 const UsersSelectors = ({ 35 selectedUsers, 36 setSelectedUsers, 37 editMode = false, 38 }: IGroupsProps) => { 39 const dispatch = useAppDispatch(); 40 //Local States 41 const [records, setRecords] = useState<any[]>([]); 42 const [loading, isLoading] = useState<boolean>(false); 43 const [filter, setFilter] = useState<string>(""); 44 45 const fetchUsers = useCallback(() => { 46 api.users 47 .listUsers() 48 .then((res) => { 49 let users = get(res.data, "users", []); 50 51 if (!users) { 52 users = []; 53 } 54 55 setRecords(users.sort(usersSort)); 56 isLoading(false); 57 }) 58 .catch((err) => { 59 dispatch(setModalErrorSnackMessage(errorToHandler(err.error))); 60 isLoading(false); 61 }); 62 }, [dispatch]); 63 64 //Effects 65 useEffect(() => { 66 isLoading(true); 67 }, []); 68 69 useEffect(() => { 70 if (loading) { 71 fetchUsers(); 72 } 73 }, [loading, fetchUsers]); 74 75 const selUsers = !selectedUsers ? [] : selectedUsers; 76 77 //Fetch Actions 78 const selectionChanged = (e: React.ChangeEvent<HTMLInputElement>) => { 79 const targetD = e.target; 80 const value = targetD.value; 81 const checked = targetD.checked; 82 83 let elements: string[] = [...selUsers]; // We clone the selectedGroups array 84 85 if (checked) { 86 // If the user has checked this field we need to push this to selectedGroupsList 87 elements.push(value); 88 } else { 89 // User has unchecked this field, we need to remove it from the list 90 elements = elements.filter((element) => element !== value); 91 } 92 setSelectedUsers(elements); 93 94 return elements; 95 }; 96 97 const filteredRecords = records.filter((elementItem) => 98 elementItem.accessKey.includes(filter), 99 ); 100 101 return ( 102 <Grid item xs={12} className={"inputItem"}> 103 <Box> 104 {loading && <ProgressBar />} 105 {records?.length > 0 ? ( 106 <Fragment> 107 <Grid item xs={12} className={"inputItem"}> 108 <SearchBox 109 label={editMode ? "Edit Members" : "Assign Users"} 110 placeholder="Filter Users" 111 onChange={setFilter} 112 value={filter} 113 /> 114 </Grid> 115 <DataTable 116 columns={[{ label: "Access Key", elementKey: "accessKey" }]} 117 onSelect={selectionChanged} 118 selectedItems={selUsers} 119 isLoading={loading} 120 records={filteredRecords} 121 entityName="Users" 122 idField="accessKey" 123 customPaperHeight={"200px"} 124 /> 125 </Fragment> 126 ) : ( 127 <Box 128 sx={{ 129 textAlign: "center", 130 padding: "10px 0", 131 }} 132 > 133 No Users to display 134 </Box> 135 )} 136 </Box> 137 </Grid> 138 ); 139 }; 140 141 export default UsersSelectors;