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([
- {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([
- {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([
- {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
+import { escapeRegExp } from 'common/regexp';
import { isObject, has, every } from 'lodash/fp';
export interface Vocabulary {
export interface PropFieldSuggestion {
id: string;
label: string;
- description?: string;
+ synonyms?: string[];
}
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 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,
- "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": []})
.sort(compare)
: [];
};
: [];
};
-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,
- "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": []})
.sort(compare)
: [];
};
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
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 = (