github.com/minio/console@v1.4.1/web-app/src/screens/Console/EventDestinations/ConfTargetGeneric.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, useEffect, useState } from "react";
    18  import {
    19    CommentBox,
    20    ConsoleIcon,
    21    FormLayout,
    22    Grid,
    23    InputBox,
    24    ReadBox,
    25    Switch,
    26    Tooltip,
    27  } from "mds";
    28  import { IElementValue, IOverrideEnv, KVField } from "../Configurations/types";
    29  import CSVMultiSelector from "../Common/FormComponents/CSVMultiSelector/CSVMultiSelector";
    30  
    31  interface IConfGenericProps {
    32    onChange: (newValue: IElementValue[]) => void;
    33    fields: KVField[];
    34    defaultVals?: IElementValue[];
    35    overrideEnv?: IOverrideEnv;
    36  }
    37  
    38  // Function to get defined values,
    39  //we make this because the backed sometimes don't return all the keys when there is an initial configuration
    40  export const valueDef = (
    41    key: string,
    42    type: string,
    43    defaults: IElementValue[],
    44  ) => {
    45    let defValue = type === "on|off" ? "off" : "";
    46  
    47    if (defaults.length > 0) {
    48      const storedConfig = defaults.find((element) => element.key === key);
    49  
    50      if (storedConfig) {
    51        defValue = storedConfig.value || "";
    52      }
    53    }
    54  
    55    return defValue;
    56  };
    57  
    58  const ConfTargetGeneric = ({
    59    onChange,
    60    fields,
    61    defaultVals,
    62    overrideEnv,
    63  }: IConfGenericProps) => {
    64    const [valueHolder, setValueHolder] = useState<IElementValue[]>([]);
    65    const fieldsElements = !fields ? [] : fields;
    66    const defValList = !defaultVals ? [] : defaultVals;
    67  
    68    // Effect to create all the values to hold
    69    useEffect(() => {
    70      const values: IElementValue[] = fields.map((field) => {
    71        const stateInsert: IElementValue = {
    72          key: field.name,
    73          value: valueDef(field.name, field.type, defValList),
    74        };
    75        return stateInsert;
    76      });
    77  
    78      setValueHolder(values);
    79      // eslint-disable-next-line react-hooks/exhaustive-deps
    80    }, [fields, defaultVals]);
    81  
    82    useEffect(() => {
    83      onChange(valueHolder);
    84      // eslint-disable-next-line react-hooks/exhaustive-deps
    85    }, [valueHolder]);
    86  
    87    const setValueElement = (key: string, value: string, index: number) => {
    88      const valuesDup = [...valueHolder];
    89      value = value.trim();
    90      valuesDup[index] = { key, value };
    91  
    92      setValueHolder(valuesDup);
    93    };
    94  
    95    const fieldDefinition = (field: KVField, item: number) => {
    96      const holderItem = valueHolder[item];
    97  
    98      if (holderItem) {
    99        // Override Value with env var, we display generic string component
   100        const override = overrideEnv?.[`${holderItem.key}`];
   101  
   102        if (override) {
   103          return (
   104            <ReadBox
   105              label={field.label}
   106              actionButton={
   107                <Grid
   108                  item
   109                  sx={{
   110                    display: "flex",
   111                    justifyContent: "flex-end",
   112                    paddingRight: "10px",
   113                  }}
   114                >
   115                  <Tooltip
   116                    tooltip={`This value is set from the ${override.overrideEnv} environment variable`}
   117                    placement={"left"}
   118                  >
   119                    <ConsoleIcon style={{ width: 20 }} />
   120                  </Tooltip>
   121                </Grid>
   122              }
   123              sx={{ width: "100%" }}
   124            >
   125              {override.value}
   126            </ReadBox>
   127          );
   128        }
   129      }
   130  
   131      switch (field.type) {
   132        case "on|off":
   133          const value = holderItem ? holderItem.value : "off";
   134  
   135          return (
   136            <Switch
   137              onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
   138                const value = e.target.checked ? "on" : "off";
   139                setValueElement(field.name, value, item);
   140              }}
   141              id={field.name}
   142              name={field.name}
   143              label={field.label}
   144              value={"switch_on"}
   145              tooltip={field.tooltip}
   146              checked={value === "on"}
   147            />
   148          );
   149        case "csv":
   150          return (
   151            <CSVMultiSelector
   152              elements={holderItem ? holderItem.value : ""}
   153              label={field.label}
   154              name={field.name}
   155              onChange={(value: string | string[]) => {
   156                let valCh = "";
   157  
   158                if (Array.isArray(value)) {
   159                  valCh = value.join(",");
   160                } else {
   161                  valCh = value;
   162                }
   163  
   164                setValueElement(field.name, valCh, item);
   165              }}
   166              tooltip={field.tooltip}
   167              commonPlaceholder={field.placeholder}
   168              withBorder={true}
   169            />
   170          );
   171        case "comment":
   172          return (
   173            <CommentBox
   174              id={field.name}
   175              name={field.name}
   176              label={field.label}
   177              tooltip={field.tooltip}
   178              value={holderItem ? holderItem.value : ""}
   179              onChange={(e) => setValueElement(field.name, e.target.value, item)}
   180              placeholder={field.placeholder}
   181            />
   182          );
   183        default:
   184          return (
   185            <InputBox
   186              id={field.name}
   187              name={field.name}
   188              label={field.label}
   189              tooltip={field.tooltip}
   190              value={holderItem ? holderItem.value : ""}
   191              onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
   192                setValueElement(field.name, e.target.value, item)
   193              }
   194              placeholder={field.placeholder}
   195            />
   196          );
   197      }
   198    };
   199  
   200    return (
   201      <FormLayout withBorders={false} containerPadding={false}>
   202        {fieldsElements.map((field, item) => (
   203          <Fragment key={field.name}>{fieldDefinition(field, item)}</Fragment>
   204        ))}
   205      </FormLayout>
   206    );
   207  };
   208  
   209  export default ConfTargetGeneric;