github.com/minio/console@v1.4.1/web-app/src/screens/Console/Users/ChangeUserGroups.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  
    19  import {
    20    AddMembersToGroupIcon,
    21    Button,
    22    FormLayout,
    23    Grid,
    24    Box,
    25    ProgressBar,
    26  } from "mds";
    27  import { modalStyleUtils } from "../Common/FormComponents/common/styleLibrary";
    28  import { ErrorResponseHandler } from "../../../common/types";
    29  import { encodeURLString } from "../../../common/utils";
    30  import { setModalErrorSnackMessage } from "../../../systemSlice";
    31  import { useAppDispatch } from "../../../store";
    32  import api from "../../../common/api";
    33  import GroupsSelectors from "./GroupsSelectors";
    34  import ModalWrapper from "../Common/ModalWrapper/ModalWrapper";
    35  
    36  interface IChangeUserGroupsContentProps {
    37    closeModalAndRefresh: () => void;
    38    selectedUser: string;
    39    open: boolean;
    40  }
    41  
    42  const ChangeUserGroups = ({
    43    closeModalAndRefresh,
    44    selectedUser,
    45    open,
    46  }: IChangeUserGroupsContentProps) => {
    47    const dispatch = useAppDispatch();
    48    const [addLoading, setAddLoading] = useState<boolean>(false);
    49    const [accessKey, setAccessKey] = useState<string>("");
    50    const [secretKey, setSecretKey] = useState<string>("");
    51    const [enabled, setEnabled] = useState<boolean>(false);
    52    const [selectedGroups, setSelectedGroups] = useState<string[]>([]);
    53  
    54    const getUserInformation = useCallback(() => {
    55      if (!selectedUser) {
    56        return null;
    57      }
    58  
    59      api
    60        .invoke("GET", `/api/v1/user/${encodeURLString(selectedUser)}`)
    61        .then((res) => {
    62          setAddLoading(false);
    63          setAccessKey(res.accessKey);
    64          setSelectedGroups(res.memberOf || []);
    65          setEnabled(res.status === "enabled");
    66        })
    67        .catch((err: ErrorResponseHandler) => {
    68          setAddLoading(false);
    69          dispatch(setModalErrorSnackMessage(err));
    70        });
    71    }, [selectedUser, dispatch]);
    72  
    73    useEffect(() => {
    74      if (selectedUser === null) {
    75        setAccessKey("");
    76        setSecretKey("");
    77        setSelectedGroups([]);
    78      } else {
    79        getUserInformation();
    80      }
    81    }, [selectedUser, getUserInformation]);
    82  
    83    const saveRecord = (event: React.FormEvent) => {
    84      event.preventDefault();
    85  
    86      if (addLoading) {
    87        return;
    88      }
    89      setAddLoading(true);
    90      if (selectedUser !== null) {
    91        api
    92          .invoke("PUT", `/api/v1/user/${encodeURLString(selectedUser)}`, {
    93            status: enabled ? "enabled" : "disabled",
    94            groups: selectedGroups,
    95          })
    96          .then((_) => {
    97            setAddLoading(false);
    98            closeModalAndRefresh();
    99          })
   100          .catch((err: ErrorResponseHandler) => {
   101            setAddLoading(false);
   102            dispatch(setModalErrorSnackMessage(err));
   103          });
   104      } else {
   105        api
   106          .invoke("POST", "/api/v1/users", {
   107            accessKey,
   108            secretKey,
   109            groups: selectedGroups,
   110          })
   111          .then((_) => {
   112            setAddLoading(false);
   113            closeModalAndRefresh();
   114          })
   115          .catch((err: ErrorResponseHandler) => {
   116            setAddLoading(false);
   117            dispatch(setModalErrorSnackMessage(err));
   118          });
   119      }
   120    };
   121  
   122    const resetForm = () => {
   123      if (selectedUser !== null) {
   124        setSelectedGroups([]);
   125        return;
   126      }
   127      setAccessKey("");
   128      setSecretKey("");
   129      setSelectedGroups([]);
   130    };
   131  
   132    const sendEnabled =
   133      accessKey.trim() !== "" &&
   134      ((secretKey.trim() !== "" && selectedUser === null) ||
   135        selectedUser !== null);
   136    return (
   137      <ModalWrapper
   138        onClose={() => {
   139          closeModalAndRefresh();
   140        }}
   141        modalOpen={open}
   142        title={"Set Groups"}
   143        titleIcon={<AddMembersToGroupIcon />}
   144      >
   145        <Fragment>
   146          <form
   147            noValidate
   148            autoComplete="off"
   149            onSubmit={(e: React.FormEvent<HTMLFormElement>) => {
   150              saveRecord(e);
   151            }}
   152          >
   153            <FormLayout withBorders={false} containerPadding={false}>
   154              <GroupsSelectors
   155                selectedGroups={selectedGroups}
   156                setSelectedGroups={(elements: string[]) => {
   157                  setSelectedGroups(elements);
   158                }}
   159              />
   160            </FormLayout>
   161            <Box sx={modalStyleUtils.modalButtonBar}>
   162              <Button
   163                id={"clear-change-user-groups"}
   164                type="button"
   165                variant="regular"
   166                onClick={resetForm}
   167                label={"Clear"}
   168              />
   169  
   170              <Button
   171                id={"save-user-groups"}
   172                type="submit"
   173                variant="callAction"
   174                disabled={addLoading || !sendEnabled}
   175                label={"Save"}
   176              />
   177            </Box>
   178            {addLoading && (
   179              <Grid item xs={12}>
   180                <ProgressBar />
   181              </Grid>
   182            )}
   183          </form>
   184        </Fragment>
   185      </ModalWrapper>
   186    );
   187  };
   188  
   189  export default ChangeUserGroups;