github.com/minio/console@v1.4.1/web-app/src/screens/Console/EventDestinations/AddEventDestination.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  import get from "lodash/get";
    19  import { BackLink, Button, FormLayout, Grid, InputBox, PageLayout } from "mds";
    20  import { useNavigate, useParams } from "react-router-dom";
    21  import { api } from "api";
    22  import { errorToHandler } from "api/errors";
    23  import {
    24    destinationList,
    25    notificationEndpointsFields,
    26    notifyMysql,
    27    notifyPostgres,
    28    removeEmptyFields,
    29  } from "./utils";
    30  import { IElementValue } from "../Configurations/types";
    31  import { IAM_PAGES } from "../../../common/SecureComponent/permissions";
    32  import {
    33    setErrorSnackMessage,
    34    setHelpName,
    35    setServerNeedsRestart,
    36  } from "../../../systemSlice";
    37  import { useAppDispatch } from "../../../store";
    38  import { setDestinationLoading } from "./destinationsSlice";
    39  import withSuspense from "../Common/Components/withSuspense";
    40  import PageHeaderWrapper from "../Common/PageHeaderWrapper/PageHeaderWrapper";
    41  import TargetTitle from "./TargetTitle";
    42  import HelpMenu from "../HelpMenu";
    43  
    44  const ConfMySql = withSuspense(
    45    React.lazy(() => import("./CustomForms/ConfMySql")),
    46  );
    47  
    48  const ConfTargetGeneric = withSuspense(
    49    React.lazy(() => import("./ConfTargetGeneric")),
    50  );
    51  
    52  const ConfPostgres = withSuspense(
    53    React.lazy(() => import("./CustomForms/ConfPostgres")),
    54  );
    55  
    56  interface IAddNotificationEndpointProps {
    57    saveAndRefresh: any;
    58  }
    59  
    60  const AddEventDestination = ({
    61    saveAndRefresh,
    62  }: IAddNotificationEndpointProps) => {
    63    const dispatch = useAppDispatch();
    64    const navigate = useNavigate();
    65    const params = useParams();
    66  
    67    //Local States
    68    const [valuesArr, setValueArr] = useState<IElementValue[]>([]);
    69    const [identifier, setIdentifier] = useState<string>("");
    70    const [saving, setSaving] = useState<boolean>(false);
    71    const service = params.service || "";
    72  
    73    //Effects
    74    useEffect(() => {
    75      if (saving) {
    76        const payload = {
    77          key_values: removeEmptyFields(valuesArr),
    78        };
    79        api.configs
    80          .setConfig(`${service}:${identifier}`, payload)
    81          .then(() => {
    82            setSaving(false);
    83            dispatch(setServerNeedsRestart(true));
    84            dispatch(setDestinationLoading(true));
    85            navigate(IAM_PAGES.EVENT_DESTINATIONS);
    86          })
    87          .catch((err) => {
    88            setSaving(false);
    89            dispatch(setErrorSnackMessage(errorToHandler(err.error)));
    90          });
    91      }
    92    }, [
    93      saving,
    94      service,
    95      valuesArr,
    96      saveAndRefresh,
    97      dispatch,
    98      navigate,
    99      identifier,
   100    ]);
   101  
   102    //Fetch Actions
   103    const submitForm = (event: React.FormEvent) => {
   104      event.preventDefault();
   105      setSaving(true);
   106    };
   107  
   108    const onValueChange = useCallback(
   109      (newValue: IElementValue[]) => {
   110        setValueArr(newValue);
   111      },
   112      [setValueArr],
   113    );
   114  
   115    let srvComponent;
   116    switch (service) {
   117      case notifyPostgres: {
   118        srvComponent = <ConfPostgres onChange={onValueChange} />;
   119        break;
   120      }
   121      case notifyMysql: {
   122        srvComponent = <ConfMySql onChange={onValueChange} />;
   123        break;
   124      }
   125      default: {
   126        const fields = get(notificationEndpointsFields, service, []);
   127  
   128        srvComponent = (
   129          <ConfTargetGeneric fields={fields} onChange={onValueChange} />
   130        );
   131      }
   132    }
   133  
   134    const targetElement = destinationList.find(
   135      (element) => element.actionTrigger === service,
   136    );
   137  
   138    useEffect(() => {
   139      dispatch(setHelpName("add_notification_endpoint"));
   140      // eslint-disable-next-line react-hooks/exhaustive-deps
   141    }, []);
   142  
   143    return (
   144      <Fragment>
   145        <PageHeaderWrapper
   146          label={
   147            <Fragment>
   148              <BackLink
   149                label="Event Destinations"
   150                onClick={() => navigate(IAM_PAGES.EVENT_DESTINATIONS_ADD)}
   151              />
   152            </Fragment>
   153          }
   154          actions={<HelpMenu />}
   155        />
   156  
   157        <PageLayout>
   158          <form noValidate onSubmit={submitForm}>
   159            {service !== "" && (
   160              <Fragment>
   161                <Grid item xs={12}>
   162                  {targetElement && (
   163                    <TargetTitle
   164                      logoSrc={targetElement.logo}
   165                      title={targetElement ? targetElement.targetTitle : ""}
   166                    />
   167                  )}
   168                </Grid>
   169                <FormLayout>
   170                  <InputBox
   171                    id={"identifier-field"}
   172                    name={"identifier-field"}
   173                    label={"Identifier"}
   174                    value={identifier}
   175                    onChange={(e) => setIdentifier(e.target.value)}
   176                    tooltip={"Unique descriptive string for this destination"}
   177                    placeholder="Enter Destination Identifier"
   178                    required
   179                  />
   180                  <Grid item xs={12}>
   181                    {srvComponent}
   182                  </Grid>
   183                  <Grid
   184                    item
   185                    xs={12}
   186                    sx={{
   187                      display: "flex",
   188                      justifyContent: "flex-end",
   189                      marginTop: 15,
   190                    }}
   191                  >
   192                    <Button
   193                      id={"save-notification-target"}
   194                      type="submit"
   195                      variant="callAction"
   196                      disabled={saving || identifier.trim() === ""}
   197                      label={"Save Event Destination"}
   198                    />
   199                  </Grid>
   200                </FormLayout>
   201              </Fragment>
   202            )}
   203          </form>
   204        </PageLayout>
   205      </Fragment>
   206    );
   207  };
   208  
   209  export default AddEventDestination;