From a747f4a071514837cdac553d86c228c996c74514 Mon Sep 17 00:00:00 2001 From: Lucas Di Pentima Date: Tue, 26 Jan 2021 11:27:52 -0300 Subject: [PATCH] 17266: Handles onChange event separate on the property editor. When changing the property value field, on every event a vocabulary match is attempted just in case the user submits the form by hitting . The bug happened because the vocabulary matching was only relying on the onBlur event, that doesn't fire in this case. Arvados-DCO-1.1-Signed-off-by: Lucas Di Pentima --- .../property-field-common.tsx | 20 +----------- .../property-key-field.tsx | 31 ++++++++++++++++--- .../property-value-field.tsx | 29 +++++++++++++++-- .../resource-properties-form.tsx | 1 + 4 files changed, 55 insertions(+), 26 deletions(-) diff --git a/src/views-components/resource-properties-form/property-field-common.tsx b/src/views-components/resource-properties-form/property-field-common.tsx index 90a6a30114..2e3f17c306 100644 --- a/src/views-components/resource-properties-form/property-field-common.tsx +++ b/src/views-components/resource-properties-form/property-field-common.tsx @@ -2,13 +2,11 @@ // // SPDX-License-Identifier: AGPL-3.0 -import { ChangeEvent } from 'react'; import { connect } from 'react-redux'; -import { change, WrappedFieldMetaProps, WrappedFieldInputProps, WrappedFieldProps, reset } from 'redux-form'; +import { change, WrappedFieldMetaProps, WrappedFieldInputProps, WrappedFieldProps } from 'redux-form'; import { Vocabulary, PropFieldSuggestion } from '~/models/vocabulary'; import { RootState } from '~/store/store'; import { getVocabulary } from '~/store/vocabulary/vocabulary-selectors'; -import { PROPERTY_KEY_FIELD_ID } from './property-key-field'; export interface VocabularyProp { vocabulary: Vocabulary; @@ -70,19 +68,3 @@ export const handleSelect = ( dispatch(change(formName, fieldName, item.id)); } }; - -export const handleChange = ( - fieldName: string, - formName: string, - { onChange }: WrappedFieldInputProps, - { dispatch }: WrappedFieldMetaProps) => - (value: ChangeEvent) => { - if (fieldName === PROPERTY_KEY_FIELD_ID) { - // Properties' values are dependant on the keys, if any value is - // pre-existant, a change on the property key should mean that the - // previous value is invalid. - dispatch(reset(formName)); - } - onChange(value); - dispatch(change(formName, fieldName, value)); - }; \ No newline at end of file diff --git a/src/views-components/resource-properties-form/property-key-field.tsx b/src/views-components/resource-properties-form/property-key-field.tsx index 0c3a49bea2..de8a1140ea 100644 --- a/src/views-components/resource-properties-form/property-key-field.tsx +++ b/src/views-components/resource-properties-form/property-key-field.tsx @@ -3,11 +3,18 @@ // SPDX-License-Identifier: AGPL-3.0 import * as React from 'react'; -import { WrappedFieldProps, Field, FormName } from 'redux-form'; +import { WrappedFieldProps, Field, FormName, reset, change, WrappedFieldInputProps, WrappedFieldMetaProps } from 'redux-form'; import { memoize } from 'lodash'; import { Autocomplete } from '~/components/autocomplete/autocomplete'; import { Vocabulary, getTags, getTagKeyID } from '~/models/vocabulary'; -import { handleSelect, handleBlur, connectVocabulary, VocabularyProp, ValidationProp, buildProps, handleChange } from '~/views-components/resource-properties-form/property-field-common'; +import { + handleSelect, + handleBlur, + connectVocabulary, + VocabularyProp, + ValidationProp, + buildProps +} from '~/views-components/resource-properties-form/property-field-common'; import { TAG_KEY_VALIDATION } from '~/validators/validators'; import { escapeRegExp } from '~/common/regexp.ts'; import { ChangeEvent } from 'react'; @@ -33,8 +40,9 @@ const PropertyKeyInput = ({ vocabulary, ...props }: WrappedFieldProps & Vocabula suggestions={getSuggestions(props.input.value, vocabulary)} onSelect={handleSelect(PROPERTY_KEY_FIELD_ID, data.form, props.input, props.meta)} onBlur={handleBlur(PROPERTY_KEY_FIELD_ID, data.form, props.meta, props.input, getTagKeyID(props.input.value, vocabulary))} - onChange={(value: ChangeEvent) => { - handleChange(PROPERTY_KEY_FIELD_ID, data.form, props.input, props.meta)(value); + onChange={(e: ChangeEvent) => { + const newValue = e.currentTarget.value; + handleChange(data.form, props.input, props.meta, newValue); }} {...buildProps(props)} /> @@ -56,3 +64,18 @@ const getSuggestions = (value: string, vocabulary: Vocabulary) => { const re = new RegExp(escapeRegExp(value), "i"); return getTags(vocabulary).filter(tag => re.test(tag.label) && tag.label !== value); }; + +const handleChange = ( + formName: string, + { onChange }: WrappedFieldInputProps, + { dispatch }: WrappedFieldMetaProps, + value: string) => { + // Properties' values are dependant on the keys, if any value is + // pre-existant, a change on the property key should mean that the + // previous value is invalid, so we better reset the whole form before + // setting the new tag key. + dispatch(reset(formName)); + + onChange(value); + dispatch(change(formName, PROPERTY_KEY_FIELD_NAME, value)); + }; \ No newline at end of file diff --git a/src/views-components/resource-properties-form/property-value-field.tsx b/src/views-components/resource-properties-form/property-value-field.tsx index 9ce9d52163..d0044e18c7 100644 --- a/src/views-components/resource-properties-form/property-value-field.tsx +++ b/src/views-components/resource-properties-form/property-value-field.tsx @@ -3,14 +3,22 @@ // SPDX-License-Identifier: AGPL-3.0 import * as React from 'react'; -import { WrappedFieldProps, Field, formValues, FormName } from 'redux-form'; +import { WrappedFieldProps, Field, formValues, FormName, WrappedFieldInputProps, WrappedFieldMetaProps, change } from 'redux-form'; import { compose } from 'redux'; import { Autocomplete } from '~/components/autocomplete/autocomplete'; import { Vocabulary, isStrictTag, getTagValues, getTagValueID } from '~/models/vocabulary'; import { PROPERTY_KEY_FIELD_ID, PROPERTY_KEY_FIELD_NAME } from '~/views-components/resource-properties-form/property-key-field'; -import { handleSelect, handleBlur, VocabularyProp, ValidationProp, connectVocabulary, buildProps, handleChange } from '~/views-components/resource-properties-form/property-field-common'; +import { + handleSelect, + handleBlur, + VocabularyProp, + ValidationProp, + connectVocabulary, + buildProps +} from '~/views-components/resource-properties-form/property-field-common'; import { TAG_VALUE_VALIDATION } from '~/validators/validators'; import { escapeRegExp } from '~/common/regexp.ts'; +import { ChangeEvent } from 'react'; interface PropertyKeyProp { propertyKeyId: string; @@ -53,7 +61,11 @@ const PropertyValueInput = ({ vocabulary, propertyKeyId, propertyKeyName, ...pro suggestions={getSuggestions(props.input.value, propertyKeyId, vocabulary)} onSelect={handleSelect(PROPERTY_VALUE_FIELD_ID, data.form, props.input, props.meta)} onBlur={handleBlur(PROPERTY_VALUE_FIELD_ID, data.form, props.meta, props.input, getTagValueID(propertyKeyId, props.input.value, vocabulary))} - onChange={handleChange(PROPERTY_VALUE_FIELD_ID, data.form, props.input, props.meta)} + onChange={(e: ChangeEvent) => { + const newValue = e.currentTarget.value; + const tagValueID = getTagValueID(propertyKeyId, newValue, vocabulary); + handleChange(data.form, tagValueID, props.input, props.meta, newValue); + }} {...buildProps(props)} /> )} />; @@ -73,3 +85,14 @@ const getSuggestions = (value: string, tagName: string, vocabulary: Vocabulary) const re = new RegExp(escapeRegExp(value), "i"); return getTagValues(tagName, vocabulary).filter(v => re.test(v.label) && v.label !== value); }; + +const handleChange = ( + formName: string, + tagValueID: string, + { onChange }: WrappedFieldInputProps, + { dispatch }: WrappedFieldMetaProps, + value: string) => { + onChange(value); + dispatch(change(formName, PROPERTY_VALUE_FIELD_NAME, value)); + dispatch(change(formName, PROPERTY_VALUE_FIELD_ID, tagValueID)); + }; \ No newline at end of file diff --git a/src/views-components/resource-properties-form/resource-properties-form.tsx b/src/views-components/resource-properties-form/resource-properties-form.tsx index 0632b97cd5..c8d0959a11 100644 --- a/src/views-components/resource-properties-form/resource-properties-form.tsx +++ b/src/views-components/resource-properties-form/resource-properties-form.tsx @@ -30,6 +30,7 @@ export const ResourcePropertiesForm = ({ handleSubmit, submitting, invalid, clas