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