@glossarist/concept-browser 0.4.11 → 0.4.14
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.
- package/package.json +2 -2
- package/scripts/generate-ontology-schema.mjs +312 -10
- package/src/adapters/ontology-schema.ts +89 -4
- package/src/components/AppSidebar.vue +281 -43
- package/src/components/ConceptDetail.vue +17 -9
- package/src/components/ConceptRdfView.vue +3 -3
- package/src/components/GraphPanel.vue +19 -0
- package/src/composables/use-ontology-nav.ts +183 -13
- package/src/config/types.ts +1 -0
- package/src/config/use-site-config.ts +1 -1
- package/src/data/ontology-schema.json +1721 -153
- package/src/router/index.ts +10 -0
- package/src/views/AboutView.vue +1 -1
- package/src/views/ContributorsView.vue +1 -1
- package/src/views/NewsView.vue +1 -1
- package/src/views/OntologySchemaView.vue +331 -14
- package/src/views/PageView.vue +1 -1
- package/src/views/ResolveView.vue +1 -1
- package/src/views/StatsView.vue +1 -1
|
@@ -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
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
expandedClasses.value = s;
|
|
100
|
+
interface IndividualGroup {
|
|
101
|
+
key: string;
|
|
102
|
+
label: string;
|
|
103
|
+
concepts: { id: string; prefLabel: string }[];
|
|
41
104
|
}
|
|
42
105
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
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
|
-
|
|
50
|
-
|
|
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
|
-
|
|
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
|
}
|
package/src/config/types.ts
CHANGED
|
@@ -27,7 +27,7 @@ export interface RuntimeSiteConfig {
|
|
|
27
27
|
social?: Record<string, string>;
|
|
28
28
|
nav?: { label: string; route: string }[];
|
|
29
29
|
footerNav?: { label: string; route: string }[];
|
|
30
|
-
defaults?: { language?: string; languageOrder?: string[] };
|
|
30
|
+
defaults?: { language?: string; languageOrder?: string[]; mainLanguages?: string[] };
|
|
31
31
|
email?: string;
|
|
32
32
|
pages?: PageConfig[];
|
|
33
33
|
contributors?: { name: string; role?: string; organization?: string; url?: string; email?: string }[];
|