@glossarist/concept-browser 0.7.24 → 0.7.26

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@glossarist/concept-browser",
3
- "version": "0.7.24",
3
+ "version": "0.7.26",
4
4
  "description": "Vue SPA for browsing Glossarist terminology datasets with cross-reference resolution, graph visualization, and multi-language support",
5
5
  "type": "module",
6
6
  "bin": {
@@ -46,7 +46,18 @@ export class AdapterFactory {
46
46
  await Promise.all(needManifest.map(a => a.loadManifest().catch(() => {})));
47
47
  }
48
48
 
49
+ // Register all datasets' URI patterns eagerly so cross-dataset refs resolve
50
+ for (const adapter of adapters) {
51
+ if (adapter.manifest) {
52
+ this.registerUriPatterns(adapter.registerId, adapter.manifest);
53
+ }
54
+ }
55
+ for (const adapter of this.adapters.values()) {
56
+ adapter.setUrnMap(this.urnMap);
57
+ }
58
+
49
59
  return adapters;
60
+
50
61
  }
51
62
 
52
63
  getAdapter(registerId: string): DatasetAdapter | undefined {
@@ -57,6 +68,29 @@ export class AdapterFactory {
57
68
  return [...this.adapters.values()];
58
69
  }
59
70
 
71
+
72
+ private registerUriPatterns(registerId: string, manifest: Manifest): void {
73
+ const uriPatterns = [
74
+ manifest.datasetUri,
75
+ ...(manifest.uriAliases ?? []),
76
+ manifest.uriBase ? `${manifest.uriBase}/${registerId}/*` : undefined,
77
+ ].filter(Boolean) as string[];
78
+ this.resolver.registerDataset(registerId, uriPatterns);
79
+
80
+ if (manifest.ref) {
81
+ this.resolver.registerSourceRef(manifest.ref, registerId, manifest.datasetUri);
82
+ }
83
+ for (const alias of manifest.refAliases ?? []) {
84
+ this.resolver.registerSourceRef(alias, registerId, manifest.datasetUri);
85
+ }
86
+
87
+ if (manifest.datasetUri) this.urnMap.set(manifest.datasetUri, registerId);
88
+ for (const alias of manifest.uriAliases ?? []) {
89
+ const base = alias.endsWith('*') ? alias.slice(0, -1) : alias;
90
+ if (base.startsWith('urn:')) this.urnMap.set(base, registerId);
91
+ }
92
+ }
93
+
60
94
  async loadDataset(registerId: string): Promise<DatasetAdapter> {
61
95
  const adapter = this.adapters.get(registerId);
62
96
  if (!adapter) throw new Error(`Unknown dataset: ${registerId}`);
@@ -143,6 +143,17 @@ async function navigateRelated(ref: { source: string | null; id: string | null }
143
143
  router.push({ name: 'concept', params: { registerId: target.registerId, conceptId: target.conceptId } });
144
144
  }
145
145
 
146
+ function relatedLabel(dr: { content?: string; ref?: { source: string | null; id: string | null } | null }): string {
147
+ if (dr.content) return dr.content;
148
+ const resolved = dr.ref ? getResolvedRef(dr.ref).target : null;
149
+ if (resolved) {
150
+ const m = store.manifests.get(resolved.registerId);
151
+ const dsLabel = m?.shortname || m?.title || resolved.registerId;
152
+ return `${resolved.conceptId} (${dsLabel})`;
153
+ }
154
+ return dr.ref ? `${dr.ref.id || ''} (${dr.ref.source || ''})`.trim() : '';
155
+ }
156
+
146
157
  // Cross-reference resolver: generates clickable links for inline refs
147
158
 
148
159
  const { ensureBibLoaded, bibResolver, figResolver } = useRenderOptions(() => props.registerId);
@@ -670,8 +681,8 @@ const nonVerbalReps = computed(() => {
670
681
  <div v-if="d.related?.length" class="mt-0.5 space-y-0.5">
671
682
  <div v-for="(dr, dri) in d.related" :key="'dr'+dri" class="text-xs text-ink-400 flex items-center gap-1.5">
672
683
  <span class="badge text-[9px] bg-gray-50 text-gray-600">{{ relationshipLabel(dr.type) }}</span>
673
- <button v-if="getResolvedRef(dr.ref).target" @click="navigateRelated(dr.ref!)" class="concept-link">{{ dr.content || (dr.ref ? `${dr.ref.source || ''} ${dr.ref.id || ''}`.trim() : '') }}</button>
674
- <span v-else>{{ dr.content || (dr.ref ? `${dr.ref.source || ''} ${dr.ref.id || ''}`.trim() : '') }}</span>
684
+ <button v-if="getResolvedRef(dr.ref).target" @click="navigateRelated(dr.ref!)" class="concept-link">{{ relatedLabel(dr) }}</button>
685
+ <span v-else>{{ relatedLabel(dr) }}</span>
675
686
  </div>
676
687
  </div>
677
688
  </div>
@@ -30,6 +30,7 @@ const containerRef = ref<HTMLDivElement | null>(null);
30
30
  const selectedNode = ref<GraphNode | null>(null);
31
31
  const detailCloseRef = ref<HTMLButtonElement | null>(null);
32
32
  const labelMode = ref<'designation' | 'identifier'>('designation');
33
+ const showDomains = ref(true);
33
34
 
34
35
  // Dataset enable/disable state
35
36
  const registerEnabled = reactive<Record<string, boolean>>({});
@@ -74,7 +75,8 @@ const enabledRegisters = computed(() => {
74
75
 
75
76
  const visibleNodes = computed(() => {
76
77
  const enabled = enabledRegisters.value;
77
- return props.nodes.filter(n => enabled.has(n.register));
78
+ const domains = showDomains.value;
79
+ return props.nodes.filter(n => enabled.has(n.register) && (domains || n.nodeType !== 'domain'));
78
80
  });
79
81
 
80
82
  const visibleNodeUris = computed(() => {
@@ -549,6 +551,14 @@ function selectedNodeColor(): string {
549
551
  </div>
550
552
  </div>
551
553
 
554
+ <!-- Domain/section toggle -->
555
+ <div class="flex items-center gap-2 mt-3">
556
+ <label class="flex items-center gap-1.5 cursor-pointer text-xs text-ink-500">
557
+ <input type="checkbox" v-model="showDomains" @change="rebuildGraph()" class="rounded border-ink-200 text-ink-800 focus:ring-ink-400 w-3.5 h-3.5" />
558
+ {{ t('graph.showDomains') }}
559
+ </label>
560
+ </div>
561
+
552
562
  <div v-if="nodeCount === 0" class="text-xs text-ink-300 mt-3 leading-relaxed">
553
563
  {{ props.edges.length > 0 ? t('graph.enableDatasets') : t('graph.browseToPopulate') }}
554
564
  </div>
@@ -157,6 +157,7 @@ graph.stubStatus: stub
157
157
  graph.collapseControls: Collapse controls
158
158
  graph.expandControls: Expand controls
159
159
  graph.loading: Loading graph data...
160
+ graph.showDomains: Show domains/sections
160
161
 
161
162
  # Sidebar provenance
162
163
  sidebar.provenance: Provenance
@@ -157,6 +157,7 @@ graph.stubStatus: non chargé
157
157
  graph.collapseControls: Réduire les contrôles
158
158
  graph.expandControls: Développer les contrôles
159
159
  graph.loading: Chargement des données du graphe...
160
+ graph.showDomains: Afficher les domaines/sections
160
161
 
161
162
  # Sidebar provenance
162
163
  sidebar.provenance: Provenance
@@ -9,7 +9,7 @@ import { useI18n } from '../i18n';
9
9
  const store = useVocabularyStore();
10
10
  const router = useRouter();
11
11
  const { getStyle } = useDsStyle();
12
- const { config: siteConfig, localizedTitle, localizedSubtitle, localizedDescription } = useSiteConfig();
12
+ const { config: siteConfig, localizedTitle, localizedSubtitle, localizedDescription, localizedDatasetField } = useSiteConfig();
13
13
  const { t } = useI18n();
14
14
  const exploring = ref(false);
15
15
 
@@ -121,7 +121,7 @@ function goToGraph() { router.push({ name: 'graph' }); }
121
121
  </h2>
122
122
  </div>
123
123
  <p v-if="filteredDatasets[0].manifest.description" class="text-sm text-ink-400 mb-4 line-clamp-2 leading-relaxed pl-6">
124
- {{ filteredDatasets[0].manifest.description }}
124
+ {{ localizedDatasetField(filteredDatasets[0].id, 'description', filteredDatasets[0].manifest.description) }}
125
125
  </p>
126
126
  <div class="flex items-center gap-3 pl-6 mb-4">
127
127
  <span :style="{ color: getStyle(filteredDatasets[0].id).color }" class="text-sm font-semibold tabular-nums">{{ filteredDatasets[0].manifest.conceptCount.toLocaleString() }}</span>
@@ -164,7 +164,7 @@ function goToGraph() { router.push({ name: 'graph' }); }
164
164
  </div>
165
165
 
166
166
  <p class="text-sm text-ink-400 mb-5 line-clamp-2 leading-relaxed pl-[22px]">
167
- {{ ds.manifest.description }}
167
+ {{ localizedDatasetField(ds.id, 'description', ds.manifest.description) }}
168
168
  </p>
169
169
 
170
170
  <div class="flex items-center gap-3 pl-[22px] mb-3">