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