import React , { ChangeEvent } from "react" ; import { iAssertionRow , iField } from "@shared/types/assertionRow" ; import { DeleteIcon } from "electron-app/src/ui/icons" ; import { css } from "@emotion/react" ; import { SelectBox } from "@dyson/components/molecules/Select/Select" ; import { Input } from "@dyson/components/atoms/input/Input" ; interface iAssertionFormTableProps { rowItems : Array < iAssertionRow > ; fields : Array < iField > ; operations : Array < ASSERTION_OPERATION_TYPE > ; onFieldChange ? : ( selectedFieldName : string , rowId : string ) => void ; onOperationChange ? : ( selectedOperation : ASSERTION_OPERATION_TYPE , rowId : string ) => void ; onValidationChange ? : ( newValidation : string , rowId : string ) => void ; deleteValidationRow ? : ( rowIndex : string ) => void ; } export enum ASSERTION_OPERATION_TYPE { MATCHES = "MATCHES" , CONTAINS = "CONTAINS" , REGEX = "REGEX" } function checkIfValidationPasses ( fieldValue , validationValue , operation ) { switch ( operation ) { case ASSERTION_OPERATION_TYPE . MATCHES : return fieldValue === validationValue ; case ASSERTION_OPERATION_TYPE . CONTAINS : return fieldValue . includes ( validationValue ) ; case ASSERTION_OPERATION_TYPE . REGEX : { try { const rgx = new RegExp ( validationValue ) ; if ( rgx . test ( fieldValue ) ) { return true ; } else { throw new Error ( "Regex didn't match" ) ; } } catch ( err ) { return false ; } } default : throw new Error ( "Unknown Validation Operation" ) ; } } const reactSelectDefaultStyles = { option : ( provided , state ) => ( { ... provided , fontSize : 14 , } ) , control : ( provided , state ) => ( { ... provided , minHeight : 32 , maxHeight : 32 , padding : 0 , } ) , singleValue : ( provided ) => ( { ... provided , fontSize : 14 , } ) , valueContainer : ( provided ) => ( { ... provided , top : "-0.2rem" , width : "70rem" } ) , } ; const DropdownOption = ( { label } ) => { return ( < div css = { { padding : "7rem 8rem" , width : "100%" , cursor : "default" } } > { label } < /div>); } ; const AssertionFormTable = ( props ) => { const { rowItems , fields , operations , onFieldChange , onOperationChange , onValidationChange , deleteValidationRow } = props ; const renderFieldInput = ( selectedField , rowId ) => { const getFieldOptions = ( ) => { const options = [ ] ; fields . forEach ( ( field ) => { options . push ( { value : field . name , label : field . name , component : < DropdownOption label = { field . name } / > , inactive : false } ) ; } ) ; return options ; } ; const fieldOptions = getFieldOptions ( ) ; const selectedOption = fieldOptions . find ( ( option ) => option . value === selectedField ) ; const handleOnFieldChange = ( option ) => { if ( onFieldChange ) { onFieldChange ( option [ 0 ] , rowId ) ; } } ; return ( < SelectBox isSearchable = { true } css = { css `input {outline: none;} .selectBox { padding: 14rem; height: 34rem; } .selectBox__value { margin-right: 10rem; font-size: 13rem; } width: 160rem;` } size = { "large" } selected = { [ selectedOption ] } values = { fieldOptions } callback = { handleOnFieldChange } / > ) ; } ; const renderFieldOperationInput = ( selectedOperation , rowId ) => { const getOperationOptions = ( ) => { const options = [ ] ; operations . forEach ( ( operation ) => { options . push ( { value : operation , label : operation , component : < DropdownOption label = { operation } / > , inactive : false } ) ; } ) ; return options ; } ; const operationOptions = getOperationOptions ( ) ; const selectedOption = operationOptions . find ( ( option ) => option . value === selectedOperation ) ; const handleOnOperationChange = ( selectedOptions ) => { if ( onOperationChange ) { onOperationChange ( selectedOptions [ 0 ] as any , rowId ) ; } } ; return ( < SelectBox isSearchable = { true } css = { css `input{ outline: none } .selectBox { padding: 14rem; height: 34rem; } .selectBox__value { margin-right: 10rem; font-size: 13rem; } width: 100%;` } size = { "large" } selected = { [ selectedOption ] } values = { operationOptions } callback = { handleOnOperationChange } / > ) ; } ; const renderValidationInput = ( validationValue , rowId ) => { const handleInputChange = ( event ) => { if ( onValidationChange ) { onValidationChange ( event . target . value , rowId ) ; } } ; return ( < Input css = { inputStyle } placeholder = { "Enter Value" } size = { "medium" } initialValue = { validationValue } onChange = { handleInputChange } / > ) ; } ; const handleDeleteRow = ( rowIndex ) => { if ( deleteValidationRow ) deleteValidationRow ( rowIndex ) ; } ; const rowOut = rowItems . map ( ( row , index ) => { const isValidationCorrect = checkIfValidationPasses ( row . field . value , row . validation , row . operation as ASSERTION_OPERATION_TYPE ) ; return ( < div key = { row . id } css = { css `display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 4rem; margin-bottom: 25rem;` } > < div style = { inputTableItemFieldContainerStyle } > < DeleteIcon onClick = { handleDeleteRow . bind ( this , row . id ) } style = { { height : "10rem" , marginTop : "11rem" } } containerStyle = { { marginRight : "18rem" } } /> { renderFieldInput ( row . field . name , row . id ) } < /div> < div > { renderFieldOperationInput ( row . operation as ASSERTION_OPERATION_TYPE , row . id ) } < /div> < div css = { css `display: flex; align-items: center; justify-content: center;` } > < div > { renderValidationInput ( row . validation , row . id ) } < /div> < img src = { isValidationCorrect ? "./static/assets/icons/correct.svg" : "./static/assets/icons/cross.svg" } style = { { marginLeft : "18rem" , height : "15rem" } } /> < /div> < /div>); } ) ; return < div style = { containerStyle } css = { css `&::-webkit-scrollbar { display: none; }` } > { rowOut } < /div>; } ; const containerStyle = { width : "100%" , textAlign : "left" , borderSpacing : "0 0.75rem" , marginBottom : "20rem" , maxHeight : "400rem" , overflowY : "overlay" , } ; const inputTableItemFieldContainerStyle = { fontFamily : "Gilroy" , minWidth : "7rem" , color : "#000" , fontStyle : "normal" , fontSize : "0.82rem" , display : "flex" , } ; const inputTableGridOptionValueInputStyle = { padding : "6px 16px" , borderRadius : "0.25rem" , width : "100%" , fontSize : 14 , } ; const inputStyle = css `
	outline: none;
` ; export { AssertionFormTable } ;