2022-10-23 17:29:17 +00:00
import React , { useState } from 'react' ;
2022-01-25 04:04:35 +00:00
import {
2022-10-25 02:55:23 +00:00
Box ,
Flex ,
Input ,
Center ,
InputGroup ,
InputRightElement ,
Tag ,
TagLabel ,
TagRightIcon ,
Select ,
Textarea ,
Switch ,
Text ,
MenuButton ,
MenuList ,
MenuItemOption ,
MenuOptionGroup ,
Button ,
Menu ,
2022-01-25 04:04:35 +00:00
} from '@chakra-ui/react' ;
import {
2022-10-25 02:55:23 +00:00
FaRegClone ,
FaRegEye ,
FaRegEyeSlash ,
FaPlus ,
FaTimes ,
FaAngleDown ,
2022-01-25 04:04:35 +00:00
} from 'react-icons/fa' ;
import {
2022-10-25 02:55:23 +00:00
ArrayInputOperations ,
ArrayInputType ,
SelectInputType ,
HiddenInputType ,
TextInputType ,
TextAreaInputType ,
SwitchInputType ,
DateInputType ,
MultiSelectInputType ,
2022-01-25 04:04:35 +00:00
} from '../constants' ;
import { copyTextToClipboard } from '../utils' ;
const InputField = ( {
2022-10-25 02:55:23 +00:00
inputType ,
variables ,
setVariables ,
fieldVisibility ,
setFieldVisibility ,
availableRoles ,
2023-04-23 12:01:24 +00:00
// This prop is added to improve the user experience for the boolean ENV variable having `DISABLE_` prefix, as those values need to be considered in inverted form.
hasReversedValue ,
2022-10-25 02:55:23 +00:00
. . . downshiftProps
2022-01-25 04:04:35 +00:00
} : any ) = > {
2022-10-25 02:55:23 +00:00
const props = {
size : 'sm' ,
. . . downshiftProps ,
} ;
const [ availableUserRoles , setAvailableUserRoles ] =
useState < string [ ] > ( availableRoles ) ;
const [ inputFieldVisibility , setInputFieldVisibility ] = useState <
Record < string , boolean >
> ( {
ROLES : false ,
DEFAULT_ROLES : false ,
PROTECTED_ROLES : false ,
ALLOWED_ORIGINS : false ,
roles : false ,
} ) ;
const [ inputData , setInputData ] = useState < Record < string , string > > ( {
ROLES : '' ,
DEFAULT_ROLES : '' ,
PROTECTED_ROLES : '' ,
ALLOWED_ORIGINS : '' ,
roles : '' ,
} ) ;
const updateInputHandler = (
type : string ,
operation : any ,
role : string = '' ,
) = > {
if ( operation === ArrayInputOperations . APPEND ) {
if ( inputData [ type ] !== '' ) {
setVariables ( {
. . . variables ,
[ type ] : [ . . . variables [ type ] , inputData [ type ] ] ,
} ) ;
setInputData ( { . . . inputData , [ type ] : '' } ) ;
}
setInputFieldVisibility ( { . . . inputFieldVisibility , [ type ] : false } ) ;
}
if ( operation === ArrayInputOperations . REMOVE ) {
let updatedEnvVars = variables [ type ] . filter (
( item : string ) = > item !== role ,
) ;
setVariables ( {
. . . variables ,
[ type ] : updatedEnvVars ,
} ) ;
}
} ;
if ( Object . values ( TextInputType ) . includes ( inputType ) ) {
return (
< InputGroup size = "sm" >
< Input
{ . . . props }
value = { variables [ inputType ] ? variables [ inputType ] : '' }
onChange = { (
event : Event & {
target : HTMLInputElement ;
} ,
) = >
setVariables ( {
. . . variables ,
[ inputType ] : event . target . value ,
} )
}
/ >
< InputRightElement
children = { < FaRegClone color = "#bfbfbf" / > }
cursor = "pointer"
onClick = { ( ) = > copyTextToClipboard ( variables [ inputType ] ) }
/ >
< / InputGroup >
) ;
}
if ( Object . values ( HiddenInputType ) . includes ( inputType ) ) {
return (
< InputGroup size = "sm" >
< Input
{ . . . props }
value = { variables [ inputType ] || '' }
onChange = { (
event : Event & {
target : HTMLInputElement ;
} ,
) = >
setVariables ( {
. . . variables ,
[ inputType ] : event . target . value ,
} )
}
type = { ! fieldVisibility [ inputType ] ? 'password' : 'text' }
/ >
< InputRightElement
right = "15px"
children = {
< Flex >
{ fieldVisibility [ inputType ] ? (
< Center
w = "25px"
margin = "0 1.5%"
cursor = "pointer"
onClick = { ( ) = >
setFieldVisibility ( {
. . . fieldVisibility ,
[ inputType ] : false ,
} )
}
>
< FaRegEyeSlash color = "#bfbfbf" / >
< / Center >
) : (
< Center
w = "25px"
margin = "0 1.5%"
cursor = "pointer"
onClick = { ( ) = >
setFieldVisibility ( {
. . . fieldVisibility ,
[ inputType ] : true ,
} )
}
>
< FaRegEye color = "#bfbfbf" / >
< / Center >
) }
< Center
w = "25px"
margin = "0 1.5%"
cursor = "pointer"
onClick = { ( ) = > copyTextToClipboard ( variables [ inputType ] ) }
>
< FaRegClone color = "#bfbfbf" / >
< / Center >
< / Flex >
}
/ >
< / InputGroup >
) ;
}
if ( Object . values ( ArrayInputType ) . includes ( inputType ) ) {
return (
< Flex
border = "1px solid #e2e8f0"
w = "100%"
borderRadius = { 5 }
paddingTop = "0.5%"
overflowX = { variables [ inputType ] . length > 3 ? 'scroll' : 'hidden' }
overflowY = "hidden"
justifyContent = "start"
alignItems = "center"
>
{ variables [ inputType ] . map ( ( role : string , index : number ) = > (
< Box key = { index } margin = "0.5%" role = "group" >
< Tag
size = "sm"
variant = "outline"
colorScheme = "gray"
minW = "fit-content"
>
< TagLabel cursor = "default" > { role } < / TagLabel >
< TagRightIcon
boxSize = "12px"
as = { FaTimes }
display = "none"
cursor = "pointer"
_groupHover = { { display : 'block' } }
onClick = { ( ) = >
updateInputHandler (
inputType ,
ArrayInputOperations . REMOVE ,
role ,
)
}
/ >
< / Tag >
< / Box >
) ) }
{ inputFieldVisibility [ inputType ] ? (
< Box ml = "1%" mb = "0.75%" >
< Input
type = "text"
size = "xs"
minW = "150px"
placeholder = "add a new value"
value = { inputData [ inputType ] || '' }
onChange = { ( e : any ) = > {
setInputData ( { . . . inputData , [ inputType ] : e . target . value } ) ;
} }
onBlur = { ( ) = >
updateInputHandler ( inputType , ArrayInputOperations . APPEND )
}
onKeyPress = { ( event ) = > {
if ( event . key === 'Enter' ) {
updateInputHandler ( inputType , ArrayInputOperations . APPEND ) ;
}
} }
/ >
< / Box >
) : (
< Box
marginLeft = "0.5%"
cursor = "pointer"
onClick = { ( ) = >
setInputFieldVisibility ( {
. . . inputFieldVisibility ,
[ inputType ] : true ,
} )
}
>
< Tag
size = "sm"
variant = "outline"
colorScheme = "gray"
minW = "fit-content"
>
< FaPlus / >
< / Tag >
< / Box >
) }
< / Flex >
) ;
}
if ( Object . values ( SelectInputType ) . includes ( inputType ) ) {
const { options , . . . rest } = props ;
return (
< Select
size = "sm"
{ . . . rest }
value = { variables [ inputType ] ? variables [ inputType ] : '' }
onChange = { ( e ) = >
setVariables ( { . . . variables , [ inputType ] : e . target . value } )
}
>
{ Object . entries ( options ) . map ( ( [ key , value ] : any ) = > (
< option value = { value } key = { key } >
{ key }
< / option >
) ) }
< / Select >
) ;
}
if ( Object . values ( MultiSelectInputType ) . includes ( inputType ) ) {
return (
< Flex w = "100%" style = { { position : 'relative' } } >
< Flex
border = "1px solid #e2e8f0"
w = "100%"
borderRadius = "var(--chakra-radii-sm)"
p = "1% 0 0 2.5%"
overflowX = { variables [ inputType ] . length > 3 ? 'scroll' : 'hidden' }
overflowY = "hidden"
justifyContent = "space-between"
alignItems = "center"
>
< Flex justifyContent = "start" alignItems = "center" w = "100%" wrap = "wrap" >
{ variables [ inputType ] . map ( ( role : string , index : number ) = > (
< Box key = { index } margin = "0.5%" role = "group" >
< Tag
size = "sm"
variant = "outline"
colorScheme = "gray"
minW = "fit-content"
>
< TagLabel cursor = "default" > { role } < / TagLabel >
< TagRightIcon
boxSize = "12px"
as = { FaTimes }
display = "none"
cursor = "pointer"
_groupHover = { { display : 'block' } }
onClick = { ( ) = >
updateInputHandler (
inputType ,
ArrayInputOperations . REMOVE ,
role ,
)
}
/ >
< / Tag >
< / Box >
) ) }
< / Flex >
< Menu matchWidth = { true } >
< MenuButton px = "10px" py = "7.5px" >
< FaAngleDown / >
< / MenuButton >
< MenuList
position = "absolute"
top = "0"
right = "0"
zIndex = "10"
maxH = "150"
overflowX = "scroll"
>
< MenuOptionGroup
title = { undefined }
value = { variables [ inputType ] }
type = "checkbox"
onChange = { ( values : string [ ] | string ) = > {
setVariables ( {
. . . variables ,
[ inputType ] : values ,
} ) ;
} }
>
{ availableUserRoles . map ( ( role ) = > {
return (
< MenuItemOption
key = { ` multiselect-menu- ${ role } ` }
value = { role }
>
{ role }
< / MenuItemOption >
) ;
} ) }
< / MenuOptionGroup >
< / MenuList >
< / Menu >
< / Flex >
< / Flex >
) ;
}
if ( Object . values ( TextAreaInputType ) . includes ( inputType ) ) {
return (
< Textarea
{ . . . props }
size = "lg"
fontSize = { 14 }
value = { variables [ inputType ] ? variables [ inputType ] : '' }
onChange = { (
event : Event & {
target : HTMLInputElement ;
} ,
) = >
setVariables ( {
. . . variables ,
[ inputType ] : event . target . value ,
} )
}
/ >
) ;
}
if ( Object . values ( SwitchInputType ) . includes ( inputType ) ) {
return (
< Flex w = "25%" justifyContent = "space-between" >
< Text h = "75%" fontWeight = "bold" marginRight = "2" >
Off
< / Text >
< Switch
size = "md"
2023-04-23 12:01:24 +00:00
isChecked = {
hasReversedValue ? ! variables [ inputType ] : variables [ inputType ]
}
2022-10-25 02:55:23 +00:00
onChange = { ( ) = > {
setVariables ( {
. . . variables ,
[ inputType ] : ! variables [ inputType ] ,
} ) ;
} }
/ >
< Text h = "75%" fontWeight = "bold" marginLeft = "2" >
On
< / Text >
< / Flex >
) ;
}
if ( Object . values ( DateInputType ) . includes ( inputType ) ) {
return (
< Flex border = "1px solid #e2e8f0" w = "100%" h = "33px" padding = "1%" >
< input
type = "date"
style = { { width : '100%' , paddingLeft : '2.5%' } }
value = { variables [ inputType ] ? variables [ inputType ] : '' }
onChange = { ( e ) = >
setVariables ( { . . . variables , [ inputType ] : e . target . value } )
}
/ >
< / Flex >
) ;
}
return null ;
2022-01-25 04:04:35 +00:00
} ;
export default InputField ;