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;