Arvados-DCO-1.1-Signed-off-by: Lucas Di Pentima <lucas.dipentima@curii.com>
const preferredTagKeys = Vocabulary.getPreferredTags(vocabulary);
// Alphabetically ordered by label
expect(preferredTagKeys).toEqual([
const preferredTagKeys = Vocabulary.getPreferredTags(vocabulary);
// Alphabetically ordered by label
expect(preferredTagKeys).toEqual([
- {id: "IDKEYANIMALS", label: "Animal", description: "Animal"},
- {id: "IDKEYCOMMENT", label: "IDKEYCOMMENT"},
- {id: "IDKEYSIZES", label: "Sizes", description: "Sizes"},
+ {id: "IDKEYANIMALS", label: "Animal", synonyms: []},
+ {id: "IDKEYCOMMENT", label: "IDKEYCOMMENT", synonyms: []},
+ {id: "IDKEYSIZES", label: "Sizes", synonyms: []},
- it('returns the list of preferred tag keys with synonyms', () => {
- const preferredTagKeys = Vocabulary.getPreferredTags(vocabulary, true);
+ it('returns the list of preferred tag keys with matching synonyms', () => {
+ const preferredTagKeys = Vocabulary.getPreferredTags(vocabulary, 'creat');
// Alphabetically ordered by label
expect(preferredTagKeys).toEqual([
// Alphabetically ordered by label
expect(preferredTagKeys).toEqual([
- {id: "IDKEYANIMALS", label: "Animal", description: "Animal (Creature, Beast)"},
- {id: "IDKEYCOMMENT", label: "IDKEYCOMMENT"},
- {id: "IDKEYSIZES", label: "Sizes", description: "Sizes"},
+ {id: "IDKEYANIMALS", label: "Animal", synonyms: ["Creature"]},
+ {id: "IDKEYCOMMENT", label: "IDKEYCOMMENT", synonyms: []},
+ {id: "IDKEYSIZES", label: "Sizes", synonyms: []},
const preferredTagValues = Vocabulary.getPreferredTagValues('IDKEYSIZES', vocabulary);
// Alphabetically ordered by label
expect(preferredTagValues).toEqual([
const preferredTagValues = Vocabulary.getPreferredTagValues('IDKEYSIZES', vocabulary);
// Alphabetically ordered by label
expect(preferredTagValues).toEqual([
- {id: "IDVALSIZES4", label: "IDVALSIZES4"},
- {id: "IDVALSIZES3", label: "Large", description: "Large"},
- {id: "IDVALSIZES2", label: "Medium", description: "Medium"},
- {id: "IDVALSIZES1", label: "Small", description: "Small"},
+ {id: "IDVALSIZES4", label: "IDVALSIZES4", synonyms: []},
+ {id: "IDVALSIZES3", label: "Large", synonyms: []},
+ {id: "IDVALSIZES2", label: "Medium", synonyms: []},
+ {id: "IDVALSIZES1", label: "Small", synonyms: []},
- it('returns the preferred tag values with synonyms for a given key', () => {
- const preferredTagValues = Vocabulary.getPreferredTagValues('IDKEYSIZES', vocabulary, true);
+ it('returns the preferred tag values with matching synonyms for a given key', () => {
+ const preferredTagValues = Vocabulary.getPreferredTagValues('IDKEYSIZES', vocabulary, 'litt');
// Alphabetically ordered by label
expect(preferredTagValues).toEqual([
// Alphabetically ordered by label
expect(preferredTagValues).toEqual([
- {id: "IDVALSIZES4", label: "IDVALSIZES4"},
- {id: "IDVALSIZES3", label: "Large", description: "Large (L)"},
- {id: "IDVALSIZES2", label: "Medium", description: "Medium (M)"},
- {id: "IDVALSIZES1", label: "Small", description: "Small (S, Little)"},
+ {id: "IDVALSIZES4", label: "IDVALSIZES4", synonyms: []},
+ {id: "IDVALSIZES3", label: "Large", synonyms: []},
+ {id: "IDVALSIZES2", label: "Medium", synonyms: []},
+ {id: "IDVALSIZES1", label: "Small", synonyms: ["Little"]},
//
// SPDX-License-Identifier: AGPL-3.0
//
// SPDX-License-Identifier: AGPL-3.0
+import { escapeRegExp } from 'common/regexp';
import { isObject, has, every } from 'lodash/fp';
export interface Vocabulary {
import { isObject, has, every } from 'lodash/fp';
export interface Vocabulary {
export interface PropFieldSuggestion {
id: string;
label: string;
export interface PropFieldSuggestion {
id: string;
label: string;
}
const VOCABULARY_VALIDATORS = [
}
const VOCABULARY_VALIDATORS = [
-export const getPreferredTagValues = (tagKeyID: string, vocabulary: Vocabulary, withSynonyms?: boolean): PropFieldSuggestion[] => {
+export const getPreferredTagValues = (tagKeyID: string, vocabulary: Vocabulary, withMatch?: string): PropFieldSuggestion[] => {
const tag = vocabulary.tags[tagKeyID];
const tag = vocabulary.tags[tagKeyID];
+ const regex = !!withMatch ? new RegExp(escapeRegExp(withMatch), 'i') : undefined;
return tag && tag.values
? Object.keys(tag.values).map(
tagValueID => tag.values![tagValueID].labels && tag.values![tagValueID].labels.length > 0
? {
"id": tagValueID,
"label": tag.values![tagValueID].labels[0].label,
return tag && tag.values
? Object.keys(tag.values).map(
tagValueID => tag.values![tagValueID].labels && tag.values![tagValueID].labels.length > 0
? {
"id": tagValueID,
"label": tag.values![tagValueID].labels[0].label,
- "description": tag.values![tagValueID].labels[0].label + (
- withSynonyms && tag.values![tagValueID].labels.length > 1
- ? ` (${tag.values![tagValueID].labels.slice(1).map(l => l.label).join(', ')})`
- : '')}
- : {"id": tagValueID, "label": tagValueID})
+ "synonyms": !!withMatch && tag.values![tagValueID].labels.length > 1
+ ? tag.values![tagValueID].labels.slice(1)
+ .filter(l => !!regex ? regex.test(l.label) : true)
+ .map(l => l.label)
+ : []
+ }
+ : {"id": tagValueID, "label": tagValueID, "synonyms": []})
-export const getPreferredTags = ({ tags }: Vocabulary, withSynonyms?: boolean): PropFieldSuggestion[] => {
+export const getPreferredTags = ({ tags }: Vocabulary, withMatch?: string): PropFieldSuggestion[] => {
+ const regex = !!withMatch ? new RegExp(escapeRegExp(withMatch), 'i') : undefined;
return tags && Object.keys(tags)
? Object.keys(tags).map(
tagID => tags[tagID].labels && tags[tagID].labels.length > 0
? {
"id": tagID,
"label": tags[tagID].labels[0].label,
return tags && Object.keys(tags)
? Object.keys(tags).map(
tagID => tags[tagID].labels && tags[tagID].labels.length > 0
? {
"id": tagID,
"label": tags[tagID].labels[0].label,
- "description": tags[tagID].labels[0].label + (
- withSynonyms && tags[tagID].labels.length > 1
- ? ` (${tags[tagID].labels.slice(1).map(lbl => lbl.label).join(', ')})`
- : ''
- )}
- : {"id": tagID, "label": tagID})
+ "synonyms": !!withMatch && tags[tagID].labels.length > 1
+ ? tags[tagID].labels.slice(1)
+ .filter(l => !!regex ? regex.test(l.label) : true)
+ .map(lbl => lbl.label)
+ : []
+ }
+ : {"id": tagID, "label": tagID, "synonyms": []})
{...buildProps(props)}
label='Key'
suggestions={getSuggestions(props.input.value, vocabulary)}
{...buildProps(props)}
label='Key'
suggestions={getSuggestions(props.input.value, vocabulary)}
- renderSuggestion={(s: PropFieldSuggestion) => (s.description || s.label)}
+ renderSuggestion={
+ (s: PropFieldSuggestion) => 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
onSelect={handleSelect(PROPERTY_KEY_FIELD_ID, data.form, props.input, props.meta)}
onBlur={() => {
// Case-insensitive search for the key in the vocabulary
const getSuggestions = (value: string, vocabulary: Vocabulary): PropFieldSuggestion[] => {
const re = new RegExp(escapeRegExp(value), "i");
const getSuggestions = (value: string, vocabulary: Vocabulary): PropFieldSuggestion[] => {
const re = new RegExp(escapeRegExp(value), "i");
- return getPreferredTags(vocabulary, value !== '').filter(
- tag => re.test((tag.description || tag.label)) && tag.label !== value);
+ return getPreferredTags(vocabulary, value).filter(
+ tag => (tag.label !== value && re.test(tag.label)) ||
+ (tag.synonyms && tag.synonyms.some(s => re.test(s))));
};
const handleChange = (
};
const handleChange = (
label='Value'
disabled={props.disabled}
suggestions={getSuggestions(props.input.value, propertyKeyId, vocabulary)}
label='Value'
disabled={props.disabled}
suggestions={getSuggestions(props.input.value, propertyKeyId, vocabulary)}
- renderSuggestion={(s: PropFieldSuggestion) => (s.description || s.label)}
+ renderSuggestion={
+ (s: PropFieldSuggestion) => s.synonyms && s.synonyms.length > 0
+ ? `${s.label} (${s.synonyms.join('; ')})`
+ : s.label
+ }
onSelect={handleSelect(PROPERTY_VALUE_FIELD_ID, data.form, props.input, props.meta)}
onBlur={() => {
// Case-insensitive search for the value in the vocabulary
onSelect={handleSelect(PROPERTY_VALUE_FIELD_ID, data.form, props.input, props.meta)}
onBlur={() => {
// Case-insensitive search for the value in the vocabulary
const getSuggestions = (value: string, tagName: string, vocabulary: Vocabulary) => {
const re = new RegExp(escapeRegExp(value), "i");
const getSuggestions = (value: string, tagName: string, vocabulary: Vocabulary) => {
const re = new RegExp(escapeRegExp(value), "i");
- return getPreferredTagValues(tagName, vocabulary, value !== '').filter(
- v => re.test((v.description || v.label)) && v.label !== value);
+ return getPreferredTagValues(tagName, vocabulary, value).filter(
+ val => (val.label !== value && re.test(val.label)) ||
+ (val.synonyms && val.synonyms.some(s => re.test(s))));
};
const handleChange = (
};
const handleChange = (