Skip to content

Commit

Permalink
Fe map fields name validation (#4257)
Browse files Browse the repository at this point in the history
* fe validation of unique property name

* minor errors fixed
  • Loading branch information
JulianWielga authored Apr 27, 2023
1 parent 281a3e4 commit 18a0748
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 24 deletions.
4 changes: 2 additions & 2 deletions designer/client/src/components/graph/node-modal/IdField.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {allValid, mandatoryValueValidator, uniqueValueValidator, Validator} from "./editors/Validators"
import {allValid, mandatoryValueValidator, uniqueScenarioValueValidator, Validator} from "./editors/Validators"
import Field, {FieldType} from "./editors/field/Field"
import React, {useMemo} from "react"
import {useDiffMark} from "./PathsToMark"
Expand Down Expand Up @@ -36,7 +36,7 @@ export function IdField({
const nodes = useSelector(getProcessNodesIds)
const otherNodes = useMemo(() => nodes.filter(n => n !== node.id), [node.id, nodes])

const validators = (additionalValidators || []).concat(mandatoryValueValidator, uniqueValueValidator(otherNodes))
const validators = (additionalValidators || []).concat(mandatoryValueValidator, uniqueScenarioValueValidator(otherNodes))
const [isMarked] = useDiffMark()
const propName = `id`
const value = useMemo(() => node[FAKE_NAME_PROP_NAME] ?? node[propName], [node, propName])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,9 +126,8 @@ export function NodeTypeDetailsContent({
dispatch(nodeValidationDataClear(node.id))
}, [dispatch, node.id])


if (showValidation) {
useEffect(() => {
useEffect(() => {
if (showValidation) {
dispatch(validateNodeData(processId, {
//see NODES_CONNECTED/NODES_DISCONNECTED
outgoingEdges: edges.filter(e => e.to != ""),
Expand All @@ -137,8 +136,8 @@ export function NodeTypeDetailsContent({
branchVariableTypes: getBranchVariableTypes(node.id),
variableTypes,
}))
}, [dispatch, edges, getBranchVariableTypes, node, processId, processProperties, variableTypes])
}
}
}, [dispatch, edges, getBranchVariableTypes, node, processId, processProperties, showValidation, variableTypes])

useEffect(() => {
setEditedNode((node) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,21 @@ export const mandatoryValueValidator: Validator = {
validatorType: ValidatorType.Frontend,
}

export const uniqueValueValidator: (values: string[]) => Validator = values => ({
isValid: value => !values.includes(value),
message: () => i18next.t("uniqueValueValidator.message", "This field has to be unique across scenario"),
const uniqueValueValidator: (otherValues: string[]) => Validator = otherValues => ({
isValid: value => !otherValues.includes(value),
message: () => i18next.t("uniqueValueValidator.message", "This field has to be unique"),
description: () => i18next.t("validator.unique.description", "Please fill field with unique value"),
handledErrorType: HandledErrorType.UniqueParameter,
validatorType: ValidatorType.Frontend,
})
export const uniqueListValueValidator = (list: string[], currentIndex: number): Validator => ({
...uniqueValueValidator(list.filter((v, i) => i !== currentIndex)),
message: () => i18next.t("uniqueListValueValidator.message", "This field has to be unique across list"),
})
export const uniqueScenarioValueValidator: typeof uniqueValueValidator = otherValues => ({
...uniqueValueValidator(otherValues),
message: () => i18next.t("uniqueScenarioValueValidator.message", "This field has to be unique across scenario"),
})

export const fixedValueValidator = (possibleValues: Array<PossibleValue>): Validator => ({
isValid: value => possibleValues.map(pv => pv.expression).includes(value),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {Field, TypedObjectTypingResult, VariableTypes} from "../../../../../type
import {FieldsRow} from "../../subprocess-input-definition/FieldsRow"
import {Items} from "../../subprocess-input-definition/Items"
import {NodeRowFields} from "../../subprocess-input-definition/NodeRowFields"
import {Error, mandatoryValueValidator} from "../Validators"
import {Error, mandatoryValueValidator, uniqueListValueValidator, Validator} from "../Validators"
import MapKey from "./MapKey"
import MapValue from "./MapValue"
import {isEqual} from "lodash"
Expand Down Expand Up @@ -49,10 +49,8 @@ export function Map<F extends Field>(props: MapProps<F>): JSX.Element {
}
}, [props.fields, fields])

const validators = useMemo(() => [mandatoryValueValidator], [])

const Item = useCallback(
({index, item}: { index: number, item }) => {
({index, item, validators}: { index: number, item , validators: Validator[]}) => {
const path = `${namespace}[${index}]`
return (
<FieldsRow index={index}>
Expand All @@ -78,11 +76,17 @@ export function Map<F extends Field>(props: MapProps<F>): JSX.Element {
)
},
// "variableTypes" ignored for reason
[isMarked, namespace, setProperty, readOnly, showValidation, validators],
[isMarked, namespace, setProperty, readOnly, showValidation],
)

const items = useMemo(
() => fields?.map(appendTypeInfo).map((item, index) => ({item, el: <Item key={index} index={index} item={item}/>})),
() => fields?.map(appendTypeInfo).map((item, index, list) => {
const validators = [
mandatoryValueValidator,
uniqueListValueValidator(list.map((v) => v.name), index),
]
return {item, el: <Item key={index} index={index} item={item} validators={validators}/>}
}),
[Item, appendTypeInfo, fields],
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@ interface Props {
}

export function NodeGroupContent({node, edges, onChange}: Props): JSX.Element {
const errors = node.type ? // for properties node `type` is undefined
useSelector((state: RootState) => getNodeErrors(state, node.id)) : useSelector(getPropertiesErrors)
const errors = useSelector((state: RootState) => {
return node.type ? getNodeErrors(state, node.id) : getPropertiesErrors(state)
})

return (
<div className={css({height: "100%", display: "grid", gridTemplateRows: "auto 1fr"})}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {isEqual} from "lodash"
import React, {useCallback, useMemo} from "react"
import {Parameter} from "../../../../types"
import MapKey from "../editors/map/MapKey"
import {mandatoryValueValidator} from "../editors/Validators"
import {mandatoryValueValidator, uniqueListValueValidator, Validator} from "../editors/Validators"
import {DndItems} from "./DndItems"
import {FieldsRow} from "./FieldsRow"
import {NodeRowFields} from "./NodeRowFields"
Expand Down Expand Up @@ -31,16 +31,14 @@ function FieldsSelect(props: FieldsSelectProps): JSX.Element {
const {addField, fields, label, onChange, namespace, options, readOnly, removeField, showValidation} = props
const [isMarked] = useDiffMark()

const validators = useMemo(() => [mandatoryValueValidator], [])

const getCurrentOption = useCallback(field => {
const fallbackValue = {label: field?.typ?.refClazzName, value: field?.typ?.refClazzName}
const foundValue = options.find((item) => isEqual(field?.typ?.refClazzName, item.value))
return foundValue || fallbackValue
}, [options])

const Item = useCallback(
({index, item}: {index: number, item}) => {
({index, item, validators}: { index: number, item, validators: Validator[] }) => {
const path = `${namespace}[${index}]`
return (
<FieldsRow index={index}>
Expand All @@ -62,13 +60,20 @@ function FieldsSelect(props: FieldsSelectProps): JSX.Element {
</FieldsRow>
)
},
[getCurrentOption, isMarked, namespace, onChange, options, readOnly, showValidation, validators],
[getCurrentOption, isMarked, namespace, onChange, options, readOnly, showValidation],
)

const changeOrder = useCallback(value => onChange(namespace, value), [namespace, onChange])

const items = useMemo(
() => fields.map((item, index) => ({item, el: <Item key={index} index={index} item={item}/>})),
() => fields.map((item, index, list) => {
const validators = [
mandatoryValueValidator,
uniqueListValueValidator(list.map((v) => v.name), index),
]

return {item, el: <Item key={index} index={index} item={item} validators={validators}/>}
}),
[Item, fields],
)

Expand Down

0 comments on commit 18a0748

Please sign in to comment.