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;