1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
5 import { isObject, has, every } from 'lodash/fp';
7 export interface Vocabulary {
9 tags: Record<string, Tag>;
12 export interface Label {
17 export interface TagValue {
21 export interface Tag {
24 values?: Record<string, TagValue>;
27 export interface PropFieldSuggestion {
33 const VOCABULARY_VALIDATORS = [
39 export const isVocabulary = (value: any) =>
40 every(validator => validator(value), VOCABULARY_VALIDATORS);
42 export const isStrictTag = (tagKeyID: string, vocabulary: Vocabulary) => {
43 const tag = vocabulary.tags[tagKeyID];
44 return tag ? tag.strict : false;
47 export const getTagValueID = (tagKeyID:string, tagValueLabel:string, vocabulary: Vocabulary) =>
48 (tagKeyID && vocabulary.tags[tagKeyID] && vocabulary.tags[tagKeyID].values)
49 ? Object.keys(vocabulary.tags[tagKeyID].values!).find(
50 k => vocabulary.tags[tagKeyID].values![k].labels.find(
51 l => l.label.toLowerCase() === tagValueLabel.toLowerCase()) !== undefined) || ''
54 export const getTagValueLabel = (tagKeyID:string, tagValueID:string, vocabulary: Vocabulary) =>
55 vocabulary.tags[tagKeyID] &&
56 vocabulary.tags[tagKeyID].values &&
57 vocabulary.tags[tagKeyID].values![tagValueID] &&
58 vocabulary.tags[tagKeyID].values![tagValueID].labels.length > 0
59 ? vocabulary.tags[tagKeyID].values![tagValueID].labels[0].label
62 const compare = (a: PropFieldSuggestion, b: PropFieldSuggestion) => {
63 if (a.label < b.label) {return -1;}
64 if (a.label > b.label) {return 1;}
68 export const getTagValues = (tagKeyID: string, vocabulary: Vocabulary): PropFieldSuggestion[] => {
69 const tag = vocabulary.tags[tagKeyID];
70 return tag && tag.values
71 ? Object.keys(tag.values).map(
72 tagValueID => tag.values![tagValueID].labels && tag.values![tagValueID].labels.length > 0
73 ? tag.values![tagValueID].labels.map(
74 lbl => Object.assign({}, {"id": tagValueID, "label": lbl.label}))
75 : [{"id": tagValueID, "label": tagValueID}])
76 .reduce((prev, curr) => [...prev, ...curr], [])
81 export const getPreferredTagValues = (tagKeyID: string, vocabulary: Vocabulary, withSynonyms?: boolean): PropFieldSuggestion[] => {
82 const tag = vocabulary.tags[tagKeyID];
83 return tag && tag.values
84 ? Object.keys(tag.values).map(
85 tagValueID => tag.values![tagValueID].labels && tag.values![tagValueID].labels.length > 0
88 "label": tag.values![tagValueID].labels[0].label,
89 "description": tag.values![tagValueID].labels[0].label + (
90 withSynonyms && tag.values![tagValueID].labels.length > 1
91 ? ` (${tag.values![tagValueID].labels.slice(1).map(l => l.label).join(', ')})`
93 : {"id": tagValueID, "label": tagValueID})
98 export const getTags = ({ tags }: Vocabulary): PropFieldSuggestion[] => {
99 return tags && Object.keys(tags)
100 ? Object.keys(tags).map(
101 tagID => tags[tagID].labels && tags[tagID].labels.length > 0
102 ? tags[tagID].labels.map(
103 lbl => Object.assign({}, {"id": tagID, "label": lbl.label}))
104 : [{"id": tagID, "label": tagID}])
105 .reduce((prev, curr) => [...prev, ...curr], [])
110 export const getPreferredTags = ({ tags }: Vocabulary, withSynonyms?: boolean): PropFieldSuggestion[] => {
111 return tags && Object.keys(tags)
112 ? Object.keys(tags).map(
113 tagID => tags[tagID].labels && tags[tagID].labels.length > 0
116 "label": tags[tagID].labels[0].label,
117 "description": tags[tagID].labels[0].label + (
118 withSynonyms && tags[tagID].labels.length > 1
119 ? ` (${tags[tagID].labels.slice(1).map(lbl => lbl.label).join(', ')})`
122 : {"id": tagID, "label": tagID})
127 export const getTagKeyID = (tagKeyLabel:string, vocabulary: Vocabulary) =>
128 Object.keys(vocabulary.tags).find(
129 k => vocabulary.tags[k].labels.find(
130 l => l.label.toLowerCase() === tagKeyLabel.toLowerCase()) !== undefined
133 export const getTagKeyLabel = (tagKeyID:string, vocabulary: Vocabulary) =>
134 vocabulary.tags[tagKeyID] && vocabulary.tags[tagKeyID].labels.length > 0
135 ? vocabulary.tags[tagKeyID].labels[0].label