@glossarist/concept-browser 0.4.12 → 0.4.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,8 +2,21 @@ import { ref, computed } from 'vue';
2
2
  import {
3
3
  getClass,
4
4
  getClassTree,
5
+ getAllShapes,
6
+ getObjectProperties,
7
+ getDatatypeProperties,
8
+ getAnnotationProperties,
9
+ getOntology,
10
+ getStats,
5
11
  type OwlClass,
12
+ type OwlShape,
13
+ type OwlProperty,
14
+ type AnnotationProperty,
15
+ type OwlOntology,
16
+ ENTITY_TYPE_META,
17
+ type EntityType,
6
18
  } from '../adapters/ontology-schema';
19
+ import taxonomyData from '../data/taxonomies.json';
7
20
 
8
21
  export function slugToCompact(slug: string): string {
9
22
  return slug.replace(/-/g, ':');
@@ -15,6 +28,57 @@ export function compactToSlug(compact: string): string {
15
28
 
16
29
  const expandedClasses = ref(new Set<string>(['gloss:Designation']));
17
30
 
31
+ const collapsedSections = ref(new Set<string>([
32
+ 'objectProperty',
33
+ 'datatypeProperty',
34
+ 'shape',
35
+ 'taxonomy',
36
+ 'namedIndividual',
37
+ 'annotationProperty',
38
+ ]));
39
+
40
+ const searchQuery = ref('');
41
+
42
+ function toggleExpand(cls: OwlClass) {
43
+ const s = new Set(expandedClasses.value);
44
+ if (s.has(cls.compact)) s.delete(cls.compact);
45
+ else s.add(cls.compact);
46
+ expandedClasses.value = s;
47
+ }
48
+
49
+ function toggleSection(key: string) {
50
+ const s = new Set(collapsedSections.value);
51
+ if (s.has(key)) s.delete(key);
52
+ else s.add(key);
53
+ collapsedSections.value = s;
54
+ }
55
+
56
+ function expandAllSections() {
57
+ collapsedSections.value = new Set();
58
+ }
59
+
60
+ function collapseAllSections() {
61
+ collapsedSections.value = new Set(['objectProperty', 'datatypeProperty', 'shape', 'taxonomy', 'class', 'namedIndividual', 'annotationProperty']);
62
+ }
63
+
64
+ function childClasses(parentId: string): OwlClass[] {
65
+ const cls = getClass(parentId);
66
+ if (!cls) return [];
67
+ return cls.children.map(id => getClass(id)).filter((c): c is OwlClass => !!c);
68
+ }
69
+
70
+ function hasChildren(cls: OwlClass): boolean {
71
+ return cls.children.length > 0;
72
+ }
73
+
74
+ const treeRoots = getClassTree();
75
+ const allShapes = getAllShapes();
76
+ const objectProperties = getObjectProperties();
77
+ const datatypeProperties = getDatatypeProperties();
78
+ const annotationProperties = getAnnotationProperties();
79
+ const ontology = getOntology();
80
+ const stats = getStats();
81
+
18
82
  const taxonomyKeys = [
19
83
  'conceptStatus', 'entryStatus', 'normativeStatus', 'sourceType', 'sourceStatus',
20
84
  'relationshipType', 'designationType', 'termType', 'grammarGender', 'grammarNumber',
@@ -33,24 +97,53 @@ const taxonomyLabels: Record<string, string> = {
33
97
  grammarNumber: 'Grammar Number',
34
98
  };
35
99
 
36
- function toggleExpand(cls: OwlClass) {
37
- const s = new Set(expandedClasses.value);
38
- if (s.has(cls.compact)) s.delete(cls.compact);
39
- else s.add(cls.compact);
40
- expandedClasses.value = s;
100
+ interface IndividualGroup {
101
+ key: string;
102
+ label: string;
103
+ concepts: { id: string; prefLabel: string }[];
41
104
  }
42
105
 
43
- function childClasses(parentId: string): OwlClass[] {
44
- const cls = getClass(parentId);
45
- if (!cls) return [];
46
- return cls.children.map(id => getClass(id)).filter((c): c is OwlClass => !!c);
47
- }
106
+ const groupedIndividuals = computed<IndividualGroup[]>(() => {
107
+ return taxonomyKeys.map(key => {
108
+ const tax = (taxonomyData as Record<string, any>)[key];
109
+ if (!tax) return { key, label: taxonomyLabels[key] || key, concepts: [] };
110
+ const concepts = Object.values(tax.concepts as Record<string, any>).map((c: any) => ({
111
+ id: c.id,
112
+ prefLabel: c.prefLabel,
113
+ }));
114
+ return { key, label: tax.schemeLabel || taxonomyLabels[key] || key, concepts };
115
+ });
116
+ });
48
117
 
49
- function hasChildren(cls: OwlClass): boolean {
50
- return cls.children.length > 0;
118
+ const totalIndividuals = computed(() =>
119
+ groupedIndividuals.value.reduce((sum, g) => sum + g.concepts.length, 0),
120
+ );
121
+
122
+ const valuesToTaxonomy: Record<string, string> = {
123
+ 'gloss:status': 'conceptStatus',
124
+ 'gloss:entstatus': 'entryStatus',
125
+ 'gloss:norm': 'normativeStatus',
126
+ 'gloss:sourceType': 'sourceType',
127
+ 'gloss:sourceStatus': 'sourceStatus',
128
+ 'gloss:rel': 'relationshipType',
129
+ 'gloss:desigType': 'designationType',
130
+ 'gloss:termType': 'termType',
131
+ 'gloss:gender': 'grammarGender',
132
+ 'gloss:number': 'grammarNumber',
133
+ };
134
+
135
+ function taxonomyKeyForValuesFrom(valuesFrom: string | null): string | null {
136
+ if (!valuesFrom) return null;
137
+ return valuesToTaxonomy[valuesFrom] ?? null;
51
138
  }
52
139
 
53
- const treeRoots = getClassTree();
140
+ function getShapesForTaxonomy(taxonomyKey: string): OwlShape[] {
141
+ const targetScheme = Object.entries(valuesToTaxonomy).find(([, v]) => v === taxonomyKey)?.[0];
142
+ if (!targetScheme) return [];
143
+ return allShapes.filter(s =>
144
+ s.constraints.some(c => c.valuesFrom === targetScheme),
145
+ );
146
+ }
54
147
 
55
148
  const allNavItems = computed(() => {
56
149
  const items: { id: string; label: string; depth: number }[] = [];
@@ -66,15 +159,92 @@ const allNavItems = computed(() => {
66
159
  return items;
67
160
  });
68
161
 
162
+ function matchesSearch(text: string, query: string): boolean {
163
+ return text.toLowerCase().includes(query.toLowerCase());
164
+ }
165
+
166
+ const searchResults = computed(() => {
167
+ const q = searchQuery.value.trim();
168
+ if (!q) return null;
169
+
170
+ const matchedClasses: OwlClass[] = [];
171
+ const matchedObjectProps: OwlProperty[] = [];
172
+ const matchedDatatypeProps: OwlProperty[] = [];
173
+ const matchedShapes: OwlShape[] = [];
174
+ const matchedIndividuals: { group: string; id: string; prefLabel: string }[] = [];
175
+ const matchedAnnotationProps: AnnotationProperty[] = [];
176
+
177
+ // Walk all classes (tree + leaves)
178
+ function walkAll(classes: OwlClass[]) {
179
+ for (const cls of classes) {
180
+ if (matchesSearch(cls.label, q) || matchesSearch(cls.compact, q)) {
181
+ matchedClasses.push(cls);
182
+ }
183
+ walkAll(childClasses(cls.compact));
184
+ }
185
+ }
186
+ walkAll(treeRoots);
187
+
188
+ for (const p of objectProperties) {
189
+ if (matchesSearch(p.label, q) || matchesSearch(p.compact, q)) matchedObjectProps.push(p);
190
+ }
191
+ for (const p of datatypeProperties) {
192
+ if (matchesSearch(p.label, q) || matchesSearch(p.compact, q)) matchedDatatypeProps.push(p);
193
+ }
194
+ for (const s of allShapes) {
195
+ if (matchesSearch(s.label, q) || matchesSearch(s.compact, q)) matchedShapes.push(s);
196
+ }
197
+ for (const g of groupedIndividuals.value) {
198
+ for (const c of g.concepts) {
199
+ if (matchesSearch(c.prefLabel, q) || matchesSearch(c.id, q)) {
200
+ matchedIndividuals.push({ group: g.key, id: c.id, prefLabel: c.prefLabel });
201
+ }
202
+ }
203
+ }
204
+ for (const ap of annotationProperties) {
205
+ if (matchesSearch(ap.label, q) || matchesSearch(ap.compact, q)) matchedAnnotationProps.push(ap);
206
+ }
207
+
208
+ const total = matchedClasses.length + matchedObjectProps.length + matchedDatatypeProps.length + matchedShapes.length + matchedIndividuals.length + matchedAnnotationProps.length;
209
+
210
+ return {
211
+ total,
212
+ classes: matchedClasses,
213
+ objectProperties: matchedObjectProps,
214
+ datatypeProperties: matchedDatatypeProps,
215
+ shapes: matchedShapes,
216
+ individuals: matchedIndividuals,
217
+ annotationProperties: matchedAnnotationProps,
218
+ };
219
+ });
220
+
69
221
  export function useOntologyNav() {
70
222
  return {
71
223
  expandedClasses,
224
+ collapsedSections,
225
+ searchQuery,
72
226
  taxonomyKeys,
73
227
  taxonomyLabels,
74
228
  treeRoots,
229
+ allShapes,
230
+ objectProperties,
231
+ datatypeProperties,
232
+ annotationProperties,
233
+ ontology,
234
+ stats,
235
+ groupedIndividuals,
236
+ totalIndividuals,
75
237
  allNavItems,
238
+ searchResults,
239
+ valuesToTaxonomy,
240
+ taxonomyKeyForValuesFrom,
241
+ getShapesForTaxonomy,
76
242
  toggleExpand,
243
+ toggleSection,
244
+ expandAllSections,
245
+ collapseAllSections,
77
246
  childClasses,
78
247
  hasChildren,
248
+ ENTITY_TYPE_META,
79
249
  };
80
250
  }