X-Git-Url: https://git.arvados.org/arvados-workbench2.git/blobdiff_plain/9a37cc202448e431064b247d36ac0229a6bfa9b2..e42867f560b3c2f4c09cf6a2c07c964c63714141:/src/views-components/resource-properties-form/property-key-field.tsx
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 3fb2d377..0be4527a 100644
--- a/src/views-components/resource-properties-form/property-key-field.tsx
+++ b/src/views-components/resource-properties-form/property-key-field.tsx
@@ -2,45 +2,101 @@
//
// SPDX-License-Identifier: AGPL-3.0
-import * as React from 'react';
-import { WrappedFieldProps, Field } from 'redux-form';
+import React from 'react';
+import { WrappedFieldProps, Field, FormName, reset, change, WrappedFieldInputProps, WrappedFieldMetaProps } from 'redux-form';
import { memoize } from 'lodash';
-import { Autocomplete } from '~/components/autocomplete/autocomplete';
-import { Vocabulary } from '~/models/vocabulary';
-import { connectVocabulary, VocabularyProp, buildProps } from '~/views-components/resource-properties-form/property-field-common';
-import { TAG_KEY_VALIDATION } from '~/validators/validators';
+import { Autocomplete } from 'components/autocomplete/autocomplete';
+import {
+ Vocabulary,
+ getTags,
+ getTagKeyID,
+ getTagKeyLabel,
+ getPreferredTags,
+ PropFieldSuggestion
+} from 'models/vocabulary';
+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';
+import { ChangeEvent } from 'react';
export const PROPERTY_KEY_FIELD_NAME = 'key';
+export const PROPERTY_KEY_FIELD_ID = 'keyID';
export const PropertyKeyField = connectVocabulary(
- ({ vocabulary }: VocabularyProp) =>
+ ({ vocabulary, skipValidation }: VocabularyProp & ValidationProp) =>
+
);
+ validate={skipValidation ? undefined : getValidation(vocabulary)} />
+
+);
-export const PropertyKeyInput = ({ vocabulary, ...props }: WrappedFieldProps & VocabularyProp) =>
- ;
+const PropertyKeyInput = ({ vocabulary, ...props }: WrappedFieldProps & VocabularyProp) =>
+ (
+ s.synonyms && s.synonyms.length > 0
+ ? `${s.label} (${s.synonyms.join('; ')})`
+ : s.label
+ }
+ onSelect={handleSelect(PROPERTY_KEY_FIELD_ID, data.form, props.input, props.meta)}
+ onBlur={() => {
+ // Case-insensitive search for the key in the vocabulary
+ const foundKeyID = getTagKeyID(props.input.value, vocabulary);
+ if (foundKeyID !== '') {
+ props.input.value = getTagKeyLabel(foundKeyID, vocabulary);
+ }
+ handleBlur(PROPERTY_KEY_FIELD_ID, data.form, props.meta, props.input, foundKeyID)();
+ }}
+ onChange={(e: ChangeEvent) => {
+ const newValue = e.currentTarget.value;
+ handleChange(data.form, props.input, props.meta, newValue);
+ }}
+ />
+ )} />;
const getValidation = memoize(
(vocabulary: Vocabulary) =>
- vocabulary.strict
+ vocabulary.strict_tags
? [...TAG_KEY_VALIDATION, matchTags(vocabulary)]
: TAG_KEY_VALIDATION);
const matchTags = (vocabulary: Vocabulary) =>
(value: string) =>
- getTagsList(vocabulary).find(tag => tag.includes(value))
+ getTags(vocabulary).find(tag => tag.label === value)
? undefined
: 'Incorrect key';
-const getSuggestions = (value: string, vocabulary: Vocabulary) =>
- getTagsList(vocabulary).filter(tag => tag.includes(value) && tag !== value);
+const getSuggestions = (value: string, vocabulary: Vocabulary): PropFieldSuggestion[] => {
+ const re = new RegExp(escapeRegExp(value), "i");
+ return getPreferredTags(vocabulary, value).filter(
+ tag => (tag.label !== value && re.test(tag.label)) ||
+ (tag.synonyms && tag.synonyms.some(s => re.test(s))));
+};
-const getTagsList = ({ tags }: Vocabulary) =>
- Object.keys(tags);
+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