diff options
author | KAPIL SINGAL <ks220y@att.com> | 2020-02-02 19:27:46 +0000 |
---|---|---|
committer | Gerrit Code Review <gerrit@onap.org> | 2020-02-02 19:27:46 +0000 |
commit | 1584ac712f243707197128b3e3d344e435bd2f31 (patch) | |
tree | 70ed41e168dd155a85010167a81a932967097345 /sdnr/wt/odlux/apps/configurationApp/src/components | |
parent | 33b86ad077a2e472df5d4ed15227298a238eb8ae (diff) | |
parent | 05ef023752abdb4f1e072332496dc7c6eaff8965 (diff) |
Merge "SDN-R add updated odlux"
Diffstat (limited to 'sdnr/wt/odlux/apps/configurationApp/src/components')
9 files changed, 782 insertions, 0 deletions
diff --git a/sdnr/wt/odlux/apps/configurationApp/src/components/baseProps.ts b/sdnr/wt/odlux/apps/configurationApp/src/components/baseProps.ts new file mode 100644 index 000000000..ec49191ce --- /dev/null +++ b/sdnr/wt/odlux/apps/configurationApp/src/components/baseProps.ts @@ -0,0 +1,21 @@ +/** + * ============LICENSE_START======================================================================== + * ONAP : ccsdk feature sdnr wt odlux + * ================================================================================================= + * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved. + * ================================================================================================= + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + * ============LICENSE_END========================================================================== + */ + +import { ViewElement } from "../models/uiModels"; + +export type baseProps = { value: ViewElement, inputValue: string, readOnly: boolean, disabled: boolean, onChange(newValue: string): void };
\ No newline at end of file diff --git a/sdnr/wt/odlux/apps/configurationApp/src/components/ifWhenTextInput.tsx b/sdnr/wt/odlux/apps/configurationApp/src/components/ifWhenTextInput.tsx new file mode 100644 index 000000000..67358885c --- /dev/null +++ b/sdnr/wt/odlux/apps/configurationApp/src/components/ifWhenTextInput.tsx @@ -0,0 +1,61 @@ +/** + * ============LICENSE_START======================================================================== + * ONAP : ccsdk feature sdnr wt odlux + * ================================================================================================= + * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved. + * ================================================================================================= + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + * ============LICENSE_END========================================================================== + */ + +import { ViewElementBase } from "models/uiModels"; +import { TextField, InputAdornment, Input, Tooltip, Divider, IconButton, InputBase, Paper, makeStyles, Theme, createStyles, FormControl, InputLabel, FormHelperText } from "@material-ui/core"; +import * as React from 'react'; +import { faAdjust } from "@fortawesome/free-solid-svg-icons"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { InputProps } from "@material-ui/core/Input"; + +const useStyles = makeStyles((theme: Theme) => + createStyles({ + iconDark: { + color: '#ff8800' + }, + iconLight: { + color: 'orange' + }, + padding: { + paddingLeft: 10, + paddingRight: 10 + }, + }), +); + +type ifwhenProps = { element: ViewElementBase, id: any, label: any, style: any, helperText: string, error: boolean, toogleTooltip(value: boolean): void, [x: string]: any }; + +export const IfWhenTextInput = (props: ifwhenProps) => { + + const { element, toogleTooltip, id, label, helperText: errorText, error, style, ...otherProps } = props; + const classes = useStyles(); + + + const ifFeature = element.ifFeature ? <Tooltip onMouseMove={e => props.toogleTooltip(false)} onMouseOut={e => props.toogleTooltip(true)} title={element.ifFeature}><InputAdornment position="start"><FontAwesomeIcon icon={faAdjust} className={classes.iconDark}></FontAwesomeIcon></InputAdornment></Tooltip> : null; + const whenFeature = element.when ? (<Tooltip className={classes.padding} onMouseMove={e => props.toogleTooltip(false)} onMouseOut={e => props.toogleTooltip(true)} title={element.when}> + <InputAdornment className={classes.padding} position="end"><FontAwesomeIcon icon={faAdjust} className={classes.iconLight}></FontAwesomeIcon></InputAdornment></Tooltip>) : null; + + return ( + <FormControl error={error} style={style}> + <InputLabel htmlFor={id} >{label}</InputLabel> + <Input {...otherProps} id={id} endAdornment={<div>{ifFeature}{whenFeature}</div>} /> + <FormHelperText>{errorText}</FormHelperText> + </FormControl> + + ); +}
\ No newline at end of file diff --git a/sdnr/wt/odlux/apps/configurationApp/src/components/uiElementBoolean.tsx b/sdnr/wt/odlux/apps/configurationApp/src/components/uiElementBoolean.tsx new file mode 100644 index 000000000..cc141ee35 --- /dev/null +++ b/sdnr/wt/odlux/apps/configurationApp/src/components/uiElementBoolean.tsx @@ -0,0 +1,58 @@ +/** + * ============LICENSE_START======================================================================== + * ONAP : ccsdk feature sdnr wt odlux + * ================================================================================================= + * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved. + * ================================================================================================= + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + * ============LICENSE_END========================================================================== + */ + +import { ViewElementBoolean } from "../models/uiModels"; +import * as React from "react" +import { MenuItem, FormHelperText, Select, FormControl, InputLabel } from "@material-ui/core"; +import { baseProps } from "./baseProps"; + +type booleanInputProps = baseProps; + +export const UiElementBoolean = (props: booleanInputProps) => { + + const element = props.value as ViewElementBoolean; + + let error = ""; + const value = String(props.inputValue).toLowerCase(); + if (element.mandatory && value !== "true" && value !== "false") { + error = "Error"; + } + return (!props.readOnly || element.id != null + ? (<FormControl style={{ width: 485, marginLeft: 20, marginRight: 20 }}> + <InputLabel htmlFor={`select-${element.id}`} >{element.label}</InputLabel> + <Select + required={!!element.mandatory} + error={!!error} + onChange={(e) => { props.onChange(e.target.value as any) }} + readOnly={props.readOnly} + disabled={props.disabled} + value={value} + inputProps={{ + name: element.id, + id: `select-${element.id}`, + }} + > + <MenuItem value={'true'}>{element.trueValue || 'True'}</MenuItem> + <MenuItem value={'false'}>{element.falseValue || 'False'}</MenuItem> + + </Select> + <FormHelperText>{error}</FormHelperText> + </FormControl>) + : null + ); +}
\ No newline at end of file diff --git a/sdnr/wt/odlux/apps/configurationApp/src/components/uiElementNumber.tsx b/sdnr/wt/odlux/apps/configurationApp/src/components/uiElementNumber.tsx new file mode 100644 index 000000000..cf462052e --- /dev/null +++ b/sdnr/wt/odlux/apps/configurationApp/src/components/uiElementNumber.tsx @@ -0,0 +1,77 @@ +/** + * ============LICENSE_START======================================================================== + * ONAP : ccsdk feature sdnr wt odlux + * ================================================================================================= + * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved. + * ================================================================================================= + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + * ============LICENSE_END========================================================================== + */ + +import { ViewElementNumber } from "models/uiModels"; +import { Tooltip, InputAdornment } from "@material-ui/core"; +import * as React from 'react'; +import { baseProps } from "./baseProps"; +import { IfWhenTextInput } from "./ifWhenTextInput"; +import { checkRange } from "./verifyer"; + +type numberInputProps = baseProps; + +export const UiElementNumber = (props: numberInputProps) => { + + + const [error, setError] = React.useState(false); + const [helperText, setHelperText] = React.useState(""); + const [isTooltipVisible, setTooltipVisibility] = React.useState(true); + + const element = props.value as ViewElementNumber; + + const verifyValue = (data: string) => { + + if (data.trim().length > 0) { + const num = Number(data); + if (!isNaN(num)) { + const result = checkRange(element, num); + if (result.length > 0) { + setError(true); + setHelperText(result); + } else { + setError(false); + setHelperText(""); + } + } else { + setError(true); + setHelperText("Input is not a number."); + } + } else { + setError(false); + setHelperText(""); + } + + props.onChange(data); + } + + return ( + <Tooltip title={isTooltipVisible ? element.description || '' : ''}> + <IfWhenTextInput element={element} toogleTooltip={(val: boolean) => setTooltipVisibility(val)} + spellCheck={false} autoFocus margin="dense" + id={element.id} label={element.label} type="text" value={props.inputValue} + style={{ width: 485, marginLeft: 20, marginRight: 20 }} + onChange={(e: any) => { verifyValue(e.target.value) }} + error={error} + readOnly={props.readOnly} + disabled={props.disabled} + helperText={helperText} + startAdornment={element.units != null ? <InputAdornment position="start">{element.units}</InputAdornment> : undefined} + /> + </Tooltip> + ); +}
\ No newline at end of file diff --git a/sdnr/wt/odlux/apps/configurationApp/src/components/uiElementReference.tsx b/sdnr/wt/odlux/apps/configurationApp/src/components/uiElementReference.tsx new file mode 100644 index 000000000..2760eee50 --- /dev/null +++ b/sdnr/wt/odlux/apps/configurationApp/src/components/uiElementReference.tsx @@ -0,0 +1,48 @@ +/** + * ============LICENSE_START======================================================================== + * ONAP : ccsdk feature sdnr wt odlux + * ================================================================================================= + * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved. + * ================================================================================================= + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + * ============LICENSE_END========================================================================== + */ + +import React from 'react'; +import { Tooltip, Button, FormControl, Theme, createStyles, makeStyles } from '@material-ui/core'; + +import { ViewElement } from '../models/uiModels'; + +const useStyles = makeStyles((theme: Theme) => createStyles({ + button: { + "justifyContent": "left" + }, +})); + +type UIElementReferenceProps = { + element: ViewElement; + disabled: boolean; + onOpenReference(element: ViewElement): void; +}; + +export const UIElementReference: React.FC<UIElementReferenceProps> = (props) => { + const classes = useStyles(); + const { element } = props; + return ( + <FormControl key={element.id} style={{ width: 485, marginLeft: 20, marginRight: 20 }}> + <Tooltip title={element.description || ''}> + <Button className={classes.button} color="secondary" disabled={props.disabled} onClick={() => { + props.onOpenReference(element); + }}>{element.label}</Button> + </Tooltip> + </FormControl> + ); +}
\ No newline at end of file diff --git a/sdnr/wt/odlux/apps/configurationApp/src/components/uiElementSelection.tsx b/sdnr/wt/odlux/apps/configurationApp/src/components/uiElementSelection.tsx new file mode 100644 index 000000000..d46076338 --- /dev/null +++ b/sdnr/wt/odlux/apps/configurationApp/src/components/uiElementSelection.tsx @@ -0,0 +1,59 @@ +/** + * ============LICENSE_START======================================================================== + * ONAP : ccsdk feature sdnr wt odlux + * ================================================================================================= + * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved. + * ================================================================================================= + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + * ============LICENSE_END========================================================================== + */ + +import * as React from 'react'; +import { baseProps } from './baseProps'; +import { ViewElementSelection } from '../models/uiModels' +import { FormControl, InputLabel, Select, FormHelperText, MenuItem } from '@material-ui/core'; + + + +type selectionProps = baseProps; + +export const UiElementSelection = (props: selectionProps) => { + + const element = props.value as ViewElementSelection; + + let error = ""; + const value = String(props.inputValue).toLowerCase(); + if (element.mandatory && !!value) { + error = "Error"; + } + + return (props.readOnly || props.inputValue != null + ? (<FormControl style={{ width: 485, marginLeft: 20, marginRight: 20 }}> + <InputLabel htmlFor={`select-${element.id}`} >{element.label}</InputLabel> + <Select + required={!!element.mandatory} + error={!!error} + onChange={(e) => { props.onChange(e.target.value as string) }} + readOnly={props.readOnly} + disabled={props.disabled} + value={value.toString().toLowerCase()} + inputProps={{ + name: element.id, + id: `select-${element.id}`, + }} + > + {element.options.map(option => (<MenuItem key={option.key} title={option.description} value={option.key}>{option.key}</MenuItem>))} + </Select> + <FormHelperText>{error}</FormHelperText> + </FormControl>) + : null + ); +}
\ No newline at end of file diff --git a/sdnr/wt/odlux/apps/configurationApp/src/components/uiElementString.tsx b/sdnr/wt/odlux/apps/configurationApp/src/components/uiElementString.tsx new file mode 100644 index 000000000..43c60b502 --- /dev/null +++ b/sdnr/wt/odlux/apps/configurationApp/src/components/uiElementString.tsx @@ -0,0 +1,84 @@ +/** + * ============LICENSE_START======================================================================== + * ONAP : ccsdk feature sdnr wt odlux + * ================================================================================================= + * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved. + * ================================================================================================= + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + * ============LICENSE_END========================================================================== + */ + +import { Tooltip, TextField } from "@material-ui/core"; +import { ViewElementString } from "../models/uiModels"; +import * as React from "react" +import { baseProps } from "./baseProps"; +import { IfWhenTextInput } from "./ifWhenTextInput"; +import { checkRange, checkPattern } from "./verifyer"; + +type stringEntryProps = baseProps & { isKey: boolean }; + +export const UiElementString = (props: stringEntryProps) => { + + const [isError, setError] = React.useState(false); + const [helperText, setHelperText] = React.useState(""); + const [isTooltipVisible, setTooltipVisibility] = React.useState(true); + + const element = props.value as ViewElementString; + + const verifyValues = (data: string) => { + + if (data.trim().length > 0) { + + let errorMessage = ""; + const result = checkRange(element, data.length); + + if (result.length > 0) + errorMessage += result; + + + const patternResult = checkPattern(element.pattern, data) + + if (patternResult.error) { + errorMessage += patternResult.error; + } + + if (errorMessage.length > 0) { + setError(true); + setHelperText(errorMessage); + } else { + setError(false); + setHelperText(""); + } + } else { + setError(false); + setHelperText(""); + } + + + props.onChange(data); + + } + + return ( + <Tooltip title={isTooltipVisible ? element.description || '' : ''}> + <IfWhenTextInput element={element} toogleTooltip={(val: boolean) => setTooltipVisibility(val)} + spellCheck={false} autoFocus margin="dense" + id={element.id} label={props.isKey ? "🔑 " + element.label : element.label} type="text" value={props.inputValue} + style={{ width: 485, marginLeft: 20, marginRight: 20 }} + onChange={(e: any) => { verifyValues(e.target.value) }} + error={isError} + readOnly={props.readOnly} + disabled={props.disabled} + helperText={helperText} + /> + </Tooltip> + ); +}
\ No newline at end of file diff --git a/sdnr/wt/odlux/apps/configurationApp/src/components/uiElementUnion.tsx b/sdnr/wt/odlux/apps/configurationApp/src/components/uiElementUnion.tsx new file mode 100644 index 000000000..dc158c05a --- /dev/null +++ b/sdnr/wt/odlux/apps/configurationApp/src/components/uiElementUnion.tsx @@ -0,0 +1,94 @@ +/** + * ============LICENSE_START======================================================================== + * ONAP : ccsdk feature sdnr wt odlux + * ================================================================================================= + * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved. + * ================================================================================================= + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + * ============LICENSE_END========================================================================== + */ + +import * as React from 'react' +import { baseProps } from './baseProps'; +import { Tooltip } from '@material-ui/core'; +import { IfWhenTextInput } from './ifWhenTextInput'; +import { ViewElementUnion, isViewElementString, isViewElementNumber, isViewElementObject, ViewElementNumber } from '../models/uiModels'; +import { checkRange, checkPattern } from './verifyer'; + +type UiElementUnionProps = { isKey: boolean } & baseProps; + +export const UIElementUnion = (props: UiElementUnionProps) => { + + const [isError, setError] = React.useState(false); + const [helperText, setHelperText] = React.useState(""); + const [isTooltipVisible, setTooltipVisibility] = React.useState(true); + + const element = props.value as ViewElementUnion; + + const verifyValues = (data: string) => { + + debugger; + let foundObjectElements = 0; + let errorMessage = ""; + let isPatternCorrect = null; + + for (let i = 0; i < element.elements.length; i++) { + const unionElement = element.elements[i]; + + if (isViewElementNumber(unionElement)) { + + errorMessage = checkRange(unionElement, Number(data)); + + } else if (isViewElementString(unionElement)) { + errorMessage += checkRange(unionElement, data.length); + isPatternCorrect = checkPattern(unionElement.pattern, data).isValid; + + + } else if (isViewElementObject(unionElement)) { + foundObjectElements++; + } + + if (isPatternCorrect || errorMessage.length === 0) { + break; + } + } + + if (errorMessage.length > 0 || isPatternCorrect !== null && !isPatternCorrect) { + setError(true); + setHelperText("Input is wrong."); + } else { + setError(false); + setHelperText(""); + } + + if (foundObjectElements > 0 && foundObjectElements != element.elements.length) { + throw new Error(`The union element ${element.id} can't be changed.`); + + } else { + props.onChange(data); + } + }; + + + + return <Tooltip title={isTooltipVisible ? element.description || '' : ''}> + <IfWhenTextInput element={element} toogleTooltip={(val: boolean) => setTooltipVisibility(val)} + spellCheck={false} autoFocus margin="dense" + id={element.id} label={props.isKey ? "🔑 " + element.label : element.label} type="text" value={props.inputValue} + onChange={(e: any) => { verifyValues(e.target.value) }} + error={isError} + style={{ width: 485, marginLeft: 20, marginRight: 20 }} + readOnly={props.readOnly} + disabled={props.disabled} + helperText={helperText} + /> + </Tooltip>; +}
\ No newline at end of file diff --git a/sdnr/wt/odlux/apps/configurationApp/src/components/verifyer.ts b/sdnr/wt/odlux/apps/configurationApp/src/components/verifyer.ts new file mode 100644 index 000000000..0a95cd8ca --- /dev/null +++ b/sdnr/wt/odlux/apps/configurationApp/src/components/verifyer.ts @@ -0,0 +1,280 @@ +/** + * ============LICENSE_START======================================================================== + * ONAP : ccsdk feature sdnr wt odlux + * ================================================================================================= + * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved. + * ================================================================================================= + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + * ============LICENSE_END========================================================================== + */ + +import { Expression, YangRange, Operator, ViewElementNumber, ViewElementString, isViewElementNumber, isViewElementString } from '../models/uiModels'; + +export type validated = { isValid: boolean, error?: string } + +export type validatedRange = { isValid: boolean, error?: string }; + + +const rangeErrorStartNumber = "The entered number must be"; +const rangeErrorinnerMinTextNumber = "greater or equals than"; +const rangeErrorinnerMaxTextNumber = "less or equals than"; +const rangeErrorEndTextNumber = "."; + +const rangeErrorStartString = "The entered text must have"; +const rangeErrorinnerMinTextString = "no more than"; +const rangeErrorinnerMaxTextString = "less than"; +const rangeErrorEndTextString = " characters."; + +let errorMessageStart = ""; +let errorMessageMiddleMinPart = ""; +let errorMessageMiddleMaxPart = ""; +let errorMessageEnd = ""; + + +export function checkRange(element: ViewElementNumber | ViewElementString, data: number): string { + + //let test1: Operator<YangRange> = { operation: "AND", arguments: [{ operation: "OR", arguments: [{ operation: "AND", arguments: [new RegExp("^z", "g"), new RegExp("z$", "g")] }, new RegExp("^abc", "g"), new RegExp("^123", "g")] }, new RegExp("^def", "g"), new RegExp("^ppp", "g"), new RegExp("^aaa", "g")] }; + //let test1: Operator<YangRange> = { operation: "AND", arguments: [{ operation: "OR", arguments: [{ operation: "AND", arguments: [{ min: -5, max: 10 }, { min: -30, max: -20 }] }, { min: 8, max: 15 }] }] }; + //let test1: Operator<YangRange> = { operation: "OR", arguments: [{ operation: "OR", arguments: [{ min: -50, max: -40 }] }, { min: -30, max: -20 }, { min: 8, max: 15 }] }; + //let test1: Operator<YangRange> = { operation: "AND", arguments: [{ operation: "OR", arguments: [{ min: -5, max: 10 }, { min: 17, max: 23 }] }] }; + + const number = data; + + var expression = undefined; + + if (isViewElementString(element)) { + expression = element.length; + + errorMessageStart = rangeErrorStartString; + errorMessageMiddleMaxPart = rangeErrorinnerMaxTextString; + errorMessageMiddleMinPart = rangeErrorinnerMinTextString; + errorMessageEnd = rangeErrorEndTextString; + + } else if (isViewElementNumber(element)) { + expression = element.range; + + errorMessageStart = rangeErrorStartNumber; + errorMessageMiddleMaxPart = rangeErrorinnerMaxTextNumber; + errorMessageMiddleMinPart = rangeErrorinnerMinTextNumber; + errorMessageEnd = rangeErrorEndTextNumber; + } + + if (expression) { + if (isYangOperator(expression)) { + + const errorMessage = getRangeErrorMessages(expression, data); + return errorMessage; + + } else + if (isYangRange(expression)) { + + if (!isNaN(expression.min)) { + if (number < expression.min) { + return `${errorMessageStart} ${errorMessageMiddleMinPart} ${expression.min}${errorMessageEnd}`; + } + } + + if (!isNaN(expression.max)) { + if (number > expression.max) { + return `${errorMessageStart} ${errorMessageMiddleMaxPart} ${expression.max}${errorMessageEnd}`; + } + } + } + } + + + return ""; +} + +function isYangRange(val: YangRange | Operator<YangRange>): val is YangRange { + return (val as YangRange).min !== undefined; +} + +function isYangOperator(val: YangRange | Operator<YangRange>): val is Operator<YangRange> { + return (val as Operator<YangRange>).operation !== undefined; +} + +function getRangeErrorMessagesRecursively(value: Operator<YangRange>, data: number): string[] { + let currentItteration: string[] = []; + console.log(value); + + // itterate over all elements + for (let i = 0; i < value.arguments.length; i++) { + const element = value.arguments[i]; + + let min = undefined; + let max = undefined; + + let isNumberCorrect = false; + + if (isYangRange(element)) { + + //check found min values + if (!isNaN(element.min)) { + if (data < element.min) { + min = element.min; + } else { + isNumberCorrect = true; + } + } + + // check found max values + if (!isNaN(element.max)) { + if (data > element.max) { + max = element.max; + } else { + isNumberCorrect = true; + } + } + + // construct error messages + if (min != undefined) { + currentItteration.push(`${value.operation.toLocaleLowerCase()} ${errorMessageMiddleMinPart} ${min}`); + } else if (max != undefined) { + currentItteration.push(`${value.operation.toLocaleLowerCase()} ${errorMessageMiddleMaxPart} ${max}`); + + } + + } else if (isYangOperator(element)) { + + //get errormessages from expression + const result = getRangeErrorMessagesRecursively(element, data); + if (result.length === 0) { + isNumberCorrect = true; + } + currentItteration = currentItteration.concat(result); + } + + // if its an OR operation, the number has been checked and min/max are empty (thus not violated) + // delete everything found (because at least one found is correct, therefore all are correct) and break from loop + if (min === undefined && max === undefined && isNumberCorrect && value.operation === "OR") { + + currentItteration.splice(0, currentItteration.length); + break; + } + } + + return currentItteration; +} + +function getRangeErrorMessages(value: Operator<YangRange>, data: number): string { + + const currentItteration = getRangeErrorMessagesRecursively(value, data); + + // build complete error message from found parts + let errormessage = ""; + if (currentItteration.length > 1) { + + currentItteration.forEach((element, index) => { + if (index === 0) { + errormessage = createStartMessage(element); + } else if (index === currentItteration.length - 1) { + errormessage += ` ${element}${errorMessageEnd}`; + } else { + errormessage += `, ${element}` + } + }); + } else if (currentItteration.length == 1) { + errormessage = `${createStartMessage(currentItteration[0])}${errorMessageEnd}`; + } + + return errormessage; +} + +function createStartMessage(element: string) { + + //remove leading or or and from text + if (element.startsWith("and")) + element = element.replace("and", ""); + else if (element.startsWith("or")) + element = element.replace("or", ""); + + return `${errorMessageStart} ${element}`; +} + +export const checkPattern = (expression: RegExp | Operator<RegExp> | undefined, data: string): validated => { + + if (expression) { + if (isRegExp(expression)) { + const isValid = expression.test(data); + if (!isValid) + return { isValid: isValid, error: "The input is in a wrong format." }; + + } else if (isRegExpOperator(expression)) { + const result = isPatternValid(expression, data); + + if (!result) { + return { isValid: false, error: "The input is in a wrong format." }; + } + } + } + + return { isValid: true } +} + +function getRegexRecursively(value: Operator<RegExp>, data: string): boolean[] { + let currentItteration: boolean[] = []; + for (let i = 0; i < value.arguments.length; i++) { + const element = value.arguments[i]; + if (isRegExp(element)) { + // if regex is found, add it to list + currentItteration.push(element.test(data)) + } else if (isRegExpOperator(element)) { + //if RegexExpression is found, try to get regex from it + currentItteration = currentItteration.concat(getRegexRecursively(element, data)); + } + } + + if (value.operation === "OR") { + // if one is true, all are true, all found items can be discarded + let result = currentItteration.find(element => element); + if (result) { + return []; + } + } + return currentItteration; +} + +function isPatternValid(value: Operator<RegExp>, data: string): boolean { + + + // get all regex + const result = getRegexRecursively(value, data); + console.log(value); + + + if (value.operation === "AND") { + // if AND operation is executed... + // no element can be false + const check = result.find(element => element !== true); + if (check) + return false; + else + return true; + } else { + // if OR operation is executed... + // ... just one element must be true + const check = result.find(element => element === true); + if (check) + return true; + else + return false; + + } +} + +function isRegExp(val: RegExp | Operator<RegExp>): val is RegExp { + return (val as RegExp).source !== undefined; +} + +function isRegExpOperator(val: RegExp | Operator<RegExp>): val is Operator<RegExp> { + return (val as Operator<RegExp>).operation !== undefined; +}
\ No newline at end of file |