github.com/minio/console@v1.4.1/web-app/src/screens/Console/IDP/IDPConfigurations.tsx (about)

     1  // This file is part of MinIO Console Server
     2  // Copyright (c) 2022 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, useEffect, useState } from "react";
    18  import { AddIcon, Button, PageLayout, RefreshIcon, Grid, DataTable } from "mds";
    19  import { useNavigate } from "react-router-dom";
    20  import { api } from "api";
    21  import { errorToHandler } from "api/errors";
    22  import { useAppDispatch } from "../../../store";
    23  import {
    24    CONSOLE_UI_RESOURCE,
    25    IAM_SCOPES,
    26  } from "../../../common/SecureComponent/permissions";
    27  import {
    28    hasPermission,
    29    SecureComponent,
    30  } from "../../../common/SecureComponent";
    31  import { setErrorSnackMessage, setHelpName } from "../../../systemSlice";
    32  import { actionsTray } from "../Common/FormComponents/common/styleLibrary";
    33  import TooltipWrapper from "../Common/TooltipWrapper/TooltipWrapper";
    34  import DeleteIDPConfigurationModal from "./DeleteIDPConfigurationModal";
    35  import PageHeaderWrapper from "../Common/PageHeaderWrapper/PageHeaderWrapper";
    36  import HelpMenu from "../HelpMenu";
    37  
    38  type IDPConfigurationsProps = {
    39    idpType: string;
    40  };
    41  
    42  const IDPConfigurations = ({ idpType }: IDPConfigurationsProps) => {
    43    const dispatch = useAppDispatch();
    44    const navigate = useNavigate();
    45  
    46    const [deleteOpen, setDeleteOpen] = useState<boolean>(false);
    47    const [selectedIDP, setSelectedIDP] = useState<string>("");
    48    const [loading, setLoading] = useState<boolean>(false);
    49    const [records, setRecords] = useState<any[]>([]);
    50  
    51    const deleteIDP = hasPermission(CONSOLE_UI_RESOURCE, [
    52      IAM_SCOPES.ADMIN_CONFIG_UPDATE,
    53    ]);
    54  
    55    const viewIDP = hasPermission(CONSOLE_UI_RESOURCE, [
    56      IAM_SCOPES.ADMIN_CONFIG_UPDATE,
    57    ]);
    58  
    59    const displayIDPs = hasPermission(CONSOLE_UI_RESOURCE, [
    60      IAM_SCOPES.ADMIN_CONFIG_UPDATE,
    61    ]);
    62  
    63    useEffect(() => {
    64      fetchRecords();
    65    }, []);
    66  
    67    useEffect(() => {
    68      if (loading) {
    69        if (displayIDPs) {
    70          api.idp
    71            .listConfigurations(idpType)
    72            .then((res) => {
    73              setLoading(false);
    74              if (res.data.results) {
    75                setRecords(
    76                  res.data.results.map((r: any) => {
    77                    r.name = r.name === "_" ? "Default" : r.name;
    78                    r.enabled = r.enabled === true ? "Enabled" : "Disabled";
    79                    return r;
    80                  }),
    81                );
    82              }
    83            })
    84            .catch((err) => {
    85              setLoading(false);
    86              dispatch(setErrorSnackMessage(errorToHandler(err.error)));
    87            });
    88        } else {
    89          setLoading(false);
    90        }
    91      }
    92    }, [loading, setLoading, setRecords, dispatch, displayIDPs, idpType]);
    93  
    94    const fetchRecords = () => {
    95      setLoading(true);
    96    };
    97  
    98    const confirmDeleteIDP = (idp: string) => {
    99      setDeleteOpen(true);
   100      idp = idp === "Default" ? "_" : idp;
   101      setSelectedIDP(idp);
   102    };
   103  
   104    const viewAction = (idp: any) => {
   105      let name = idp.name === "Default" ? "_" : idp.name;
   106      navigate(`/identity/idp/${idpType}/configurations/${name}`);
   107    };
   108  
   109    const closeDeleteModalAndRefresh = async (refresh: boolean) => {
   110      setDeleteOpen(false);
   111  
   112      if (refresh) {
   113        fetchRecords();
   114      }
   115    };
   116  
   117    const tableActions = [
   118      {
   119        type: "view",
   120        onClick: viewAction,
   121        disableButtonFunction: () => !viewIDP,
   122      },
   123      {
   124        type: "delete",
   125        onClick: confirmDeleteIDP,
   126        sendOnlyId: true,
   127        disableButtonFunction: (idp: string) => !deleteIDP || idp === "Default",
   128      },
   129    ];
   130  
   131    useEffect(() => {
   132      dispatch(setHelpName("idp_configs"));
   133      // eslint-disable-next-line react-hooks/exhaustive-deps
   134    }, []);
   135  
   136    return (
   137      <Fragment>
   138        {deleteOpen && (
   139          <DeleteIDPConfigurationModal
   140            deleteOpen={deleteOpen}
   141            idp={selectedIDP}
   142            idpType={idpType}
   143            closeDeleteModalAndRefresh={closeDeleteModalAndRefresh}
   144          />
   145        )}
   146        <PageHeaderWrapper
   147          label={`${idpType.toUpperCase()} Configurations`}
   148          actions={<HelpMenu />}
   149        />
   150        <PageLayout>
   151          <Grid container>
   152            <Grid
   153              item
   154              xs={12}
   155              sx={{
   156                ...actionsTray.actionsTray,
   157                justifyContent: "flex-end",
   158                gap: 8,
   159              }}
   160            >
   161              <SecureComponent
   162                scopes={[IAM_SCOPES.ADMIN_CONFIG_UPDATE]}
   163                resource={CONSOLE_UI_RESOURCE}
   164                errorProps={{ disabled: true }}
   165              >
   166                <TooltipWrapper tooltip={"Refresh"}>
   167                  <Button
   168                    id={"refresh-keys"}
   169                    variant="regular"
   170                    icon={<RefreshIcon />}
   171                    onClick={() => setLoading(true)}
   172                  />
   173                </TooltipWrapper>
   174              </SecureComponent>
   175              <SecureComponent
   176                scopes={[IAM_SCOPES.ADMIN_CONFIG_UPDATE]}
   177                resource={CONSOLE_UI_RESOURCE}
   178                errorProps={{ disabled: true }}
   179              >
   180                <TooltipWrapper tooltip={`Create ${idpType} configuration`}>
   181                  <Button
   182                    id={"create-idp"}
   183                    label={"Create Configuration"}
   184                    variant={"callAction"}
   185                    icon={<AddIcon />}
   186                    onClick={() =>
   187                      navigate(`/identity/idp/${idpType}/configurations/add-idp`)
   188                    }
   189                  />
   190                </TooltipWrapper>
   191              </SecureComponent>
   192            </Grid>
   193            <Grid item xs={12}>
   194              <SecureComponent
   195                scopes={[IAM_SCOPES.ADMIN_CONFIG_UPDATE]}
   196                resource={CONSOLE_UI_RESOURCE}
   197                errorProps={{ disabled: true }}
   198              >
   199                <DataTable
   200                  itemActions={tableActions}
   201                  columns={[
   202                    { label: "Name", elementKey: "name" },
   203                    { label: "Type", elementKey: "type" },
   204                    { label: "Enabled", elementKey: "enabled" },
   205                  ]}
   206                  isLoading={loading}
   207                  records={records}
   208                  entityName="Keys"
   209                  idField="name"
   210                />
   211              </SecureComponent>
   212            </Grid>
   213          </Grid>
   214        </PageLayout>
   215      </Fragment>
   216    );
   217  };
   218  
   219  export default IDPConfigurations;