mirror of
				https://github.com/Telecominfraproject/wlan-cloud-owprov-ui.git
				synced 2025-10-30 18:17:46 +00:00 
			
		
		
		
	Merge pull request #137 from stephb9959/main
[WIFI-10916] Added icons field to passpoint config
This commit is contained in:
		
							
								
								
									
										4
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										4
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							| @@ -1,12 +1,12 @@ | ||||
| { | ||||
|   "name": "wlan-cloud-owprov-ui", | ||||
|   "version": "2.7.0(20)", | ||||
|   "version": "2.7.1(1)", | ||||
|   "lockfileVersion": 2, | ||||
|   "requires": true, | ||||
|   "packages": { | ||||
|     "": { | ||||
|       "name": "wlan-cloud-owprov-ui", | ||||
|       "version": "2.7.0(20)", | ||||
|       "version": "2.7.1(1)", | ||||
|       "license": "ISC", | ||||
|       "dependencies": { | ||||
|         "@chakra-ui/icons": "^1.1.1", | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|   "name": "wlan-cloud-owprov-ui", | ||||
|   "version": "2.7.0(20)", | ||||
|   "version": "2.7.1(1)", | ||||
|   "description": "", | ||||
|   "main": "index.tsx", | ||||
|   "scripts": { | ||||
|   | ||||
| @@ -510,6 +510,7 @@ | ||||
| 		"invalid_file_content": "Ungültiger Dateiinhalt, bitte bestätigen Sie, dass es sich um ein gültiges Format handelt", | ||||
| 		"invalid_fqdn_host": "Ungültiger FQDN-Hostname", | ||||
| 		"invalid_hostname": "Ungültiger Hostname: Er darf nur aus alphanumerischen Zeichen und Bindestrichen bestehen", | ||||
| 		"invalid_icon_lang": "Ungültige Sprache, sollte aus 3 Buchstaben bestehen (eng, fre, ger, ita usw.)", | ||||
| 		"invalid_ieee": "Für dieses Verschlüsselungsprotokoll muss ieee80211w entweder „optional“ oder „erforderlich“ sein.", | ||||
| 		"invalid_interfaces": "Ungültige Schnittstellen-JSON-Zeichenfolge. Bitte bestätigen Sie, dass Ihr Wert gültiges JSON ist und Schnittstellen als einzigen Schlüssel hat und dass der Schnittstellenwert ein Array ist. Beispiel: {\"interfaces\": []}", | ||||
| 		"invalid_ipv4": "Ungültige IPv4-Adresse (Bsp.: 192.168.0.1 oder 192.168.0.1/16", | ||||
|   | ||||
| @@ -510,6 +510,7 @@ | ||||
| 		"invalid_file_content": "Invalid file content, please confirm that it is of the valid format", | ||||
| 		"invalid_fqdn_host": "Invalid FQDN hostname", | ||||
| 		"invalid_hostname": "Invalid hostname: it needs to be composed of alphanumeric characters and dashes only", | ||||
| 		"invalid_icon_lang": "Invalid language, it should be in a 3-letter format (eng, fre, ger, ita, etc.)", | ||||
| 		"invalid_ieee": "For this encryption protocol,  ieee80211w needs to be either 'optional' or 'required'", | ||||
| 		"invalid_interfaces": "Invalid Interfaces JSON string. Please confirm that your value is: valid JSON and has interfaces as its only key and that the interfaces value is an array. Example: {\"interfaces\": []}", | ||||
| 		"invalid_ipv4": "Invalid IPv4 address (ex.: 192.168.0.1 or 192.168.0.1/16", | ||||
|   | ||||
| @@ -510,6 +510,7 @@ | ||||
| 		"invalid_file_content": "Contenido de archivo no válido, confirme que tiene un formato válido", | ||||
| 		"invalid_fqdn_host": "Nombre de host FQDN no válido", | ||||
| 		"invalid_hostname": "Nombre de host no válido: debe estar compuesto solo de caracteres alfanuméricos y guiones", | ||||
| 		"invalid_icon_lang": "Idioma no válido, debe estar en un formato de 3 letras (eng, fre, ger, ita, etc.)", | ||||
| 		"invalid_ieee": "Para este protocolo de encriptación, ieee80211w debe ser 'opcional' u 'requerido'", | ||||
| 		"invalid_interfaces": "Cadena JSON de interfaces no válida. Confirme que su valor es: JSON válido y tiene interfaces como su única clave y que el valor de las interfaces es una matriz. Ejemplo: {\"interfaces\": []}", | ||||
| 		"invalid_ipv4": "Dirección IPv4 no válida (ej.: 192.168.0.1 o 192.168.0.1/16", | ||||
|   | ||||
| @@ -510,6 +510,7 @@ | ||||
| 		"invalid_file_content": "Contenu de fichier non valide, veuillez confirmer qu'il est au format valide", | ||||
| 		"invalid_fqdn_host": "Nom d'hôte FQDN non valide", | ||||
| 		"invalid_hostname": "Nom d'hôte non valide : il doit être composé uniquement de caractères alphanumériques et de tirets", | ||||
| 		"invalid_icon_lang": "Langue non valide, elle doit être dans un format à 3 lettres (eng, fre, ger, ita, etc.)", | ||||
| 		"invalid_ieee": "Pour ce protocole de cryptage, ieee80211w doit être soit 'facultatif' soit 'obligatoire'", | ||||
| 		"invalid_interfaces": "Chaîne JSON d'interfaces non valide. Veuillez confirmer que votre valeur est : JSON valide et a des interfaces comme seule clé et que la valeur des interfaces est un tableau. Exemple : {\"interfaces\": []}", | ||||
| 		"invalid_ipv4": "Adresse IPv4 invalide (ex. : 192.168.0.1 ou 192.168.0.1/16", | ||||
|   | ||||
| @@ -510,6 +510,7 @@ | ||||
| 		"invalid_file_content": "Conteúdo de arquivo inválido. Confirme se está no formato válido", | ||||
| 		"invalid_fqdn_host": "Nome de host FQDN inválido", | ||||
| 		"invalid_hostname": "Nome de host inválido: precisa ser composto apenas de caracteres alfanuméricos e traços", | ||||
| 		"invalid_icon_lang": "Idioma inválido, deve estar em formato de 3 letras (eng, fre, ger, ita, etc.)", | ||||
| 		"invalid_ieee": "Para este protocolo de criptografia, ieee80211w precisa ser 'opcional' ou 'obrigatório'", | ||||
| 		"invalid_interfaces": "Sequência JSON de interfaces inválida. Confirme se seu valor é: JSON válido e tem interfaces como sua única chave e que o valor de interfaces é uma matriz. Exemplo: {\"interfaces\": []}", | ||||
| 		"invalid_ipv4": "Endereço IPv4 inválido (ex.: 192.168.0.1 ou 192.168.0.1/16", | ||||
|   | ||||
| @@ -87,7 +87,7 @@ const NotesTable = ({ name, isDisabled }) => { | ||||
|       </InputGroup> | ||||
|       <DataTable | ||||
|         columns={columns} | ||||
|         data={notes.sort((a, b) => b.created - a.created)} | ||||
|         data={notes?.sort((a, b) => b.created - a.created)} | ||||
|         obj={t('common.notes')} | ||||
|         minHeight="200px" | ||||
|       /> | ||||
|   | ||||
							
								
								
									
										80
									
								
								src/components/FormFields/ImageField/Input.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								src/components/FormFields/ImageField/Input.tsx
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,80 @@ | ||||
| /* eslint-disable react/no-unused-prop-types */ | ||||
| /* eslint-disable react/destructuring-assignment */ | ||||
| import * as React from 'react'; | ||||
| import { Box, FormControl, FormLabel, Image, Input } from '@chakra-ui/react'; | ||||
| import { v4 as uuid } from 'uuid'; | ||||
|  | ||||
| type Props = { | ||||
|   name: string; | ||||
|   height?: number; | ||||
|   width?: number; | ||||
|   typeName: string; | ||||
|   typeValue: string; | ||||
|   label?: string; | ||||
|   isDisabled?: boolean; | ||||
|   displayImage?: boolean; | ||||
|   isRequired?: boolean; | ||||
|   emptyIsUndefined?: boolean; | ||||
|   isHidden?: boolean; | ||||
|   definitionKey?: string; | ||||
|   hideLabel?: boolean; | ||||
|   value?: string; | ||||
|   onChange: (value: string) => void; | ||||
|   onTypeChange: (fileType: string) => void; | ||||
| }; | ||||
| const ImageFieldInput = (props: Props) => { | ||||
|   const [fileKey, setFileKey] = React.useState(uuid()); | ||||
|  | ||||
|   let fileReader: FileReader | undefined; | ||||
|  | ||||
|   const handleStringFileRead = () => { | ||||
|     if (fileReader) { | ||||
|       const content = fileReader.result; | ||||
|       if (content && typeof content === 'string') { | ||||
|         const split = content.split('base64,'); | ||||
|         if (split[1]) { | ||||
|           props.onChange(split[1] as string); | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   }; | ||||
|  | ||||
|   const changeFile = (e: React.ChangeEvent<HTMLInputElement>) => { | ||||
|     const file = e.target.files ? e.target.files[0] : undefined; | ||||
|     if (file) { | ||||
|       props.onTypeChange(file.type); | ||||
|       fileReader = new FileReader(); | ||||
|       fileReader.onloadend = handleStringFileRead; | ||||
|       fileReader.readAsDataURL(file); | ||||
|     } | ||||
|   }; | ||||
|  | ||||
|   React.useEffect(() => { | ||||
|     if (props.value === '') setFileKey(uuid()); | ||||
|   }, [props.value]); | ||||
|  | ||||
|   return ( | ||||
|     <> | ||||
|       <Box mb={2}> | ||||
|         <FormControl hidden={props.isHidden} isDisabled={props.isDisabled} w="50%"> | ||||
|           <FormLabel>{props.label ?? props.name}</FormLabel> | ||||
|           <Input borderRadius="15px" pt={1} fontSize="sm" type="file" onChange={changeFile} key={fileKey} /> | ||||
|         </FormControl> | ||||
|       </Box> | ||||
|       <Box mb={2}> | ||||
|         {props.value && ( | ||||
|           <Image | ||||
|             height={props.height !== undefined ? `${props.height}px` : 200} | ||||
|             width={props.width !== undefined ? `${props.width}px` : 200} | ||||
|             ml="auto" | ||||
|             mr="auto" | ||||
|             src={`data:${props.typeValue ?? 'image/png'};base64,${props.value}`} | ||||
|             alt="New Image" | ||||
|           /> | ||||
|         )} | ||||
|       </Box> | ||||
|     </> | ||||
|   ); | ||||
| }; | ||||
|  | ||||
| export default React.memo(ImageFieldInput); | ||||
							
								
								
									
										56
									
								
								src/components/FormFields/ImageField/index.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								src/components/FormFields/ImageField/index.tsx
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,56 @@ | ||||
| /* eslint-disable react/destructuring-assignment */ | ||||
| import useFastField from 'hooks/useFastField'; | ||||
| import * as React from 'react'; | ||||
| import ImageFieldInput from './Input'; | ||||
|  | ||||
| type Props = { | ||||
|   name: string; | ||||
|   typeName: string; | ||||
|   heightName: string; | ||||
|   widthName: string; | ||||
|   label?: string; | ||||
|   isDisabled?: boolean; | ||||
|   displayImage?: boolean; | ||||
|   isRequired?: boolean; | ||||
|   emptyIsUndefined?: boolean; | ||||
|   isHidden?: boolean; | ||||
|   definitionKey?: string; | ||||
|   hideLabel?: boolean; | ||||
| }; | ||||
| const ImageField = (props: Props) => { | ||||
|   const image = useFastField<string | undefined>({ | ||||
|     name: props.name, | ||||
|   }); | ||||
|   const imageType = useFastField<string | undefined>({ | ||||
|     name: props.typeName, | ||||
|   }); | ||||
|   const height = useFastField<number | undefined>({ | ||||
|     name: props.heightName, | ||||
|   }); | ||||
|   const width = useFastField<string | undefined>({ | ||||
|     name: props.widthName, | ||||
|   }); | ||||
|  | ||||
|   const onChange = (value: string) => { | ||||
|     image.onChange(value); | ||||
|   }; | ||||
|   const onTypeChange = (fileType: string) => { | ||||
|     if (props.typeName) { | ||||
|       imageType.onChange(fileType); | ||||
|     } | ||||
|   }; | ||||
|  | ||||
|   return ( | ||||
|     <ImageFieldInput | ||||
|       {...props} | ||||
|       value={image.value} | ||||
|       onChange={onChange} | ||||
|       onTypeChange={onTypeChange} | ||||
|       typeValue={imageType.value} | ||||
|       height={height.value} | ||||
|       width={width.value} | ||||
|     /> | ||||
|   ); | ||||
| }; | ||||
|  | ||||
| export default React.memo(ImageField); | ||||
| @@ -122,7 +122,7 @@ const _NotesField: React.FC<NotesFieldProps> = ({ name = 'notes', isDisabled, ha | ||||
|       </InputGroup> | ||||
|       <DataTable | ||||
|         columns={columns} | ||||
|         data={notes.sort((a: Note, b: Note) => b.created - a.created)} | ||||
|         data={notes?.sort((a: Note, b: Note) => b.created - a.created)} | ||||
|         obj={hasDeleteButton ? undefined : t('common.notes')} | ||||
|         minHeight="200px" | ||||
|       /> | ||||
|   | ||||
| @@ -1,11 +1,16 @@ | ||||
| import React from 'react'; | ||||
| import { Flex, Heading, SimpleGrid } from '@chakra-ui/react'; | ||||
| import { Flex, Heading, Image, NumberInputField, SimpleGrid } from '@chakra-ui/react'; | ||||
| import PropTypes from 'prop-types'; | ||||
| import DisplayNumberField from 'components/DisplayFields/DisplayNumberField'; | ||||
| import DisplayObjectArrayField from 'components/DisplayFields/DisplayObjectArrayField'; | ||||
| import DisplaySelectField from 'components/DisplayFields/DisplaySelectField'; | ||||
| import DisplayStringField from 'components/DisplayFields/DisplayStringField'; | ||||
| import DisplayToggleField from 'components/DisplayFields/DisplayToggleField'; | ||||
| import FastCreatableSelectInput from 'components/FormFields/CreatableSelectField/FastCreatableSelectInput'; | ||||
| import ImageField from 'components/FormFields/ImageField'; | ||||
| import StringField from 'components/FormFields/StringField'; | ||||
| import NumberField from 'components/FormFields/NumberField'; | ||||
| import { INTERFACE_PASSPOINT_ICONS_SCHEMA } from '../../interfacesConstants'; | ||||
|  | ||||
| const propTypes = { | ||||
|   data: PropTypes.instanceOf(Object).isRequired, | ||||
| @@ -20,6 +25,66 @@ const LockedPasspoint = ({ data }) => { | ||||
|     isDisabled: true, | ||||
|   }); | ||||
|  | ||||
|   const iconCell = React.useCallback( | ||||
|     (src, fileType) => ( | ||||
|       <Image boxSize={100} mx="auto" my="auto" src={`data:${fileType ?? 'image/png'};base64,${src}`} alt="New Image" /> | ||||
|     ), | ||||
|     [], | ||||
|   ); | ||||
|   const iconFields = React.useMemo( | ||||
|     () => ( | ||||
|       <> | ||||
|         <SimpleGrid minChildWidth="180px" gap={4} mb={4}> | ||||
|           <NumberInputField name="width" label="width" w="140px" emptyIsUndefined isRequired unit="px" /> | ||||
|           <NumberField name="height" label="height" w="140px" isRequired unit="px" /> | ||||
|           <StringField name="language" label="language" w="100px" isRequired /> | ||||
|         </SimpleGrid> | ||||
|         <ImageField name="icon" heightName="height" widthName="width" typeName="type" /> | ||||
|       </> | ||||
|     ), | ||||
|     [], | ||||
|   ); | ||||
|   const iconCols = React.useMemo( | ||||
|     () => [ | ||||
|       { | ||||
|         id: 'icon', | ||||
|         Header: 'icon', | ||||
|         Footer: '', | ||||
|         Cell: ({ cell }) => iconCell(cell.row.original.icon, cell.row.original.type), | ||||
|         accessor: 'icon', | ||||
|       }, | ||||
|       { | ||||
|         id: 'type', | ||||
|         Header: 'type', | ||||
|         Footer: '', | ||||
|         accessor: 'type', | ||||
|         customWidth: '100px', | ||||
|       }, | ||||
|       { | ||||
|         id: 'width', | ||||
|         Header: 'width', | ||||
|         Footer: '', | ||||
|         accessor: 'width', | ||||
|         customWidth: '150px', | ||||
|       }, | ||||
|       { | ||||
|         id: 'height', | ||||
|         Header: 'height', | ||||
|         Footer: '', | ||||
|         accessor: 'height', | ||||
|         customWidth: '100px', | ||||
|       }, | ||||
|       { | ||||
|         id: 'language', | ||||
|         Header: 'language', | ||||
|         Footer: '', | ||||
|         accessor: 'language', | ||||
|         customWidth: '100px', | ||||
|       }, | ||||
|     ], | ||||
|     [], | ||||
|   ); | ||||
|  | ||||
|   if (!data) return null; | ||||
|  | ||||
|   return ( | ||||
| @@ -89,6 +154,15 @@ const LockedPasspoint = ({ data }) => { | ||||
|             emptyIsUndefined | ||||
|           /> | ||||
|           <FastCreatableSelectInput {...fieldProps('connection-capability')} /> | ||||
|           <DisplayObjectArrayField | ||||
|             {...fieldProps('icons')} | ||||
|             fields={iconFields} | ||||
|             columns={iconCols} | ||||
|             schema={INTERFACE_PASSPOINT_ICONS_SCHEMA} | ||||
|             isDisabled | ||||
|             emptyIsUndefined | ||||
|             isRequired | ||||
|           /> | ||||
|         </SimpleGrid> | ||||
|       )} | ||||
|     </> | ||||
|   | ||||
| @@ -1,10 +1,13 @@ | ||||
| import React from 'react'; | ||||
| import { Heading, SimpleGrid, Switch, Text } from '@chakra-ui/react'; | ||||
| import { Heading, Image, SimpleGrid, Switch, Text } from '@chakra-ui/react'; | ||||
| import ToggleField from 'components/FormFields/ToggleField'; | ||||
| import CreatableSelectField from 'components/FormFields/CreatableSelectField'; | ||||
| import NumberField from 'components/FormFields/NumberField'; | ||||
| import SelectField from 'components/FormFields/SelectField'; | ||||
| import StringField from 'components/FormFields/StringField'; | ||||
| import ObjectArrayFieldModal from 'components/FormFields/ObjectArrayFieldModal'; | ||||
| import ImageField from 'components/FormFields/ImageField'; | ||||
| import { INTERFACE_PASSPOINT_ICONS_SCHEMA } from '../../../interfacesConstants'; | ||||
|  | ||||
| interface Props { | ||||
|   isDisabled?: boolean; | ||||
| @@ -23,6 +26,77 @@ const PassPointForm: React.FC<Props> = ({ isDisabled, namePrefix, isEnabled, onT | ||||
|     isDisabled, | ||||
|   }); | ||||
|  | ||||
|   const iconCell = React.useCallback( | ||||
|     (src: string, fileType: string) => ( | ||||
|       <Image boxSize={100} mx="auto" my="auto" src={`data:${fileType ?? 'image/png'};base64,${src}`} alt="New Image" /> | ||||
|     ), | ||||
|     [], | ||||
|   ); | ||||
|   const iconFields = React.useMemo( | ||||
|     () => ( | ||||
|       <> | ||||
|         <SimpleGrid minChildWidth="180px" gap={4} mb={4}> | ||||
|           <NumberField name="width" label="width" w="140px" emptyIsUndefined isRequired unit="px" /> | ||||
|           <NumberField name="height" label="height" w="140px" isRequired unit="px" /> | ||||
|           <StringField name="language" label="language" isRequired /> | ||||
|         </SimpleGrid> | ||||
|         <ImageField name="icon" heightName="height" widthName="width" typeName="type" /> | ||||
|       </> | ||||
|     ), | ||||
|     [], | ||||
|   ); | ||||
|   const iconCols = React.useMemo( | ||||
|     () => [ | ||||
|       { | ||||
|         id: 'icon', | ||||
|         Header: 'icon', | ||||
|         Footer: '', | ||||
|         Cell: ({ | ||||
|           cell, | ||||
|         }: { | ||||
|           cell: { | ||||
|             row: { | ||||
|               original: { | ||||
|                 icon: string; | ||||
|                 type: string; | ||||
|               }; | ||||
|             }; | ||||
|           }; | ||||
|         }) => iconCell(cell.row.original.icon, cell.row.original.type), | ||||
|         accessor: 'icon', | ||||
|       }, | ||||
|       { | ||||
|         id: 'type', | ||||
|         Header: 'type', | ||||
|         Footer: '', | ||||
|         accessor: 'type', | ||||
|         customWidth: '100px', | ||||
|       }, | ||||
|       { | ||||
|         id: 'width', | ||||
|         Header: 'width', | ||||
|         Footer: '', | ||||
|         accessor: 'width', | ||||
|         customWidth: '150px', | ||||
|       }, | ||||
|       { | ||||
|         id: 'height', | ||||
|         Header: 'height', | ||||
|         Footer: '', | ||||
|         accessor: 'height', | ||||
|         customWidth: '100px', | ||||
|       }, | ||||
|       { | ||||
|         id: 'language', | ||||
|         Header: 'language', | ||||
|         Footer: '', | ||||
|         accessor: 'language', | ||||
|         customWidth: '100px', | ||||
|       }, | ||||
|     ], | ||||
|     [], | ||||
|   ); | ||||
|  | ||||
|   return ( | ||||
|     <> | ||||
|       <Heading size="md" display="flex"> | ||||
| @@ -106,6 +180,14 @@ const PassPointForm: React.FC<Props> = ({ isDisabled, namePrefix, isEnabled, onT | ||||
|             emptyIsUndefined | ||||
|           /> | ||||
|           <CreatableSelectField {...fieldProps('connection-capability')} emptyIsUndefined placeholder="17:5060:0" /> | ||||
|           <ObjectArrayFieldModal | ||||
|             {...fieldProps('icons')} | ||||
|             fields={iconFields} | ||||
|             // @ts-ignore | ||||
|             columns={iconCols} | ||||
|             schema={INTERFACE_PASSPOINT_ICONS_SCHEMA} | ||||
|             emptyIsUndefined | ||||
|           /> | ||||
|         </SimpleGrid> | ||||
|       )} | ||||
|     </> | ||||
|   | ||||
| @@ -5,6 +5,7 @@ import { | ||||
|   testIpv6, | ||||
|   testLeaseTime, | ||||
|   testLength, | ||||
|   testRegex, | ||||
|   testSelectPorts, | ||||
|   testUcMac, | ||||
| } from 'constants/formTests'; | ||||
| @@ -74,6 +75,26 @@ export const CREATE_INTERFACE_SCHEMA = (t) => | ||||
|     role: string().required(t('form.required')).default('upstream'), | ||||
|   }); | ||||
|  | ||||
| export const INTERFACE_PASSPOINT_ICONS_SCHEMA = (t, useDefault = false) => { | ||||
|   const shape = object() | ||||
|     .shape({ | ||||
|       width: number().required(t('form.required')).moreThan(-1).lessThan(65535).integer().default(64), | ||||
|       height: number().required(t('form.required')).moreThan(-1).lessThan(65535).integer().default(64), | ||||
|       icon: string().required(t('form.required')).default(''), | ||||
|       language: string() | ||||
|         .required(t('form.required')) | ||||
|         .test('test-passpoint-icon-lang', t('form.invalid_icon_lang'), (v) => testRegex(v, '^[a-z][a-z][a-z]$')) | ||||
|         .default('eng'), | ||||
|     }) | ||||
|     .default({ | ||||
|       width: 64, | ||||
|       height: 64, | ||||
|       language: 'eng', | ||||
|     }); | ||||
|  | ||||
|   return useDefault ? shape : shape.nullable().default(undefined); | ||||
| }; | ||||
|  | ||||
| export const INTERFACE_SSID_PASS_POINT_SCHEMA = (t, useDefault = false) => { | ||||
|   const shape = object() | ||||
|     .shape({ | ||||
|   | ||||
| @@ -49,8 +49,8 @@ const EditConfigurationForm = ({ editing, configuration, formRef }) => { | ||||
|   }); | ||||
|  | ||||
|   const getEntity = () => { | ||||
|     if (configuration.entity !== '') return `ent:${configuration.entity}`; | ||||
|     if (configuration.venue !== '') return `ven:${configuration.venue}`; | ||||
|     if (configuration?.entity !== '') return `ent:${configuration?.entity}`; | ||||
|     if (configuration?.venue !== '') return `ven:${configuration?.venue}`; | ||||
|     return `ent:0000-0000-0000`; | ||||
|   }; | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Charles Bourque
					Charles Bourque