Fix LinkML class mapping display and linking
All checks were successful
Deploy Frontend / build-and-deploy (push) Successful in 2m10s

This commit is contained in:
kempersc 2026-02-18 12:43:14 +01:00
parent d153873d20
commit a202c61435
5 changed files with 88 additions and 3 deletions

View file

@ -1,5 +1,5 @@
{
"generated": "2026-02-18T10:29:31.898Z",
"generated": "2026-02-18T11:39:46.457Z",
"schemaRoot": "/schemas/20251121/linkml",
"totalFiles": 2183,
"categoryCounts": {

View file

@ -247,6 +247,16 @@
color: #92400e;
}
.schema-popup__mapping-badge--narrow {
background: #cffafe;
color: #155e75;
}
.schema-popup__mapping-badge--broad {
background: #f1f5f9;
color: #0f172a;
}
/* Actions */
.schema-popup__actions {
margin-top: 16px;

View file

@ -71,6 +71,8 @@ interface ElementInfo {
mappings?: {
exact?: string[];
close?: string[];
narrow?: string[];
broad?: string[];
related?: string[];
};
}
@ -691,6 +693,8 @@ export const SchemaElementPopup: React.FC<SchemaElementPopupProps> = ({
{elementInfo.mappings && (
(elementInfo.mappings.exact?.length ||
elementInfo.mappings.close?.length ||
elementInfo.mappings.narrow?.length ||
elementInfo.mappings.broad?.length ||
elementInfo.mappings.related?.length) ? (
<div className="schema-popup__section">
<span className="schema-popup__section-label">Mappings</span>
@ -705,6 +709,16 @@ export const SchemaElementPopup: React.FC<SchemaElementPopupProps> = ({
{elementInfo.mappings.close.length} close
</span>
) : null}
{elementInfo.mappings.narrow?.length ? (
<span className="schema-popup__mapping-badge schema-popup__mapping-badge--narrow">
{elementInfo.mappings.narrow.length} narrow
</span>
) : null}
{elementInfo.mappings.broad?.length ? (
<span className="schema-popup__mapping-badge schema-popup__mapping-badge--broad">
{elementInfo.mappings.broad.length} broad
</span>
) : null}
{elementInfo.mappings.related?.length ? (
<span className="schema-popup__mapping-badge schema-popup__mapping-badge--related">
{elementInfo.mappings.related.length} related

View file

@ -51,8 +51,12 @@ export interface LinkMLClass {
abstract?: boolean;
slots?: string[];
slot_usage?: Record<string, Partial<LinkMLSlot>>;
// SKOS semantic mappings for ontology alignment
exact_mappings?: string[];
close_mappings?: string[];
narrow_mappings?: string[];
broad_mappings?: string[];
related_mappings?: string[];
comments?: string[];
// Aliases and multilingual metadata
aliases?: string[];

View file

@ -2671,7 +2671,7 @@ const LinkMLViewerPage: React.FC = () => {
{cls.exact_mappings.map(mapping => (
<button
key={mapping}
className="linkml-viewer__tag linkml-viewer__tag--mapping linkml-viewer__tag--clickable"
className="linkml-viewer__tag linkml-viewer__tag--mapping linkml-viewer__tag--exact linkml-viewer__tag--clickable"
onClick={() => setOntologyPopupCurie(mapping)}
title={`View ontology term: ${mapping}`}
>
@ -2688,7 +2688,58 @@ const LinkMLViewerPage: React.FC = () => {
{cls.close_mappings.map(mapping => (
<button
key={mapping}
className="linkml-viewer__tag linkml-viewer__tag--close linkml-viewer__tag--clickable"
className="linkml-viewer__tag linkml-viewer__tag--mapping linkml-viewer__tag--close linkml-viewer__tag--clickable"
onClick={() => setOntologyPopupCurie(mapping)}
title={`View ontology term: ${mapping}`}
>
{mapping}
</button>
))}
</div>
</div>
)}
{cls.narrow_mappings && cls.narrow_mappings.length > 0 && (
<div className="linkml-viewer__mappings">
<span className="linkml-viewer__label">{t('narrowMappings')}</span>
<div className="linkml-viewer__tag-list">
{cls.narrow_mappings.map(mapping => (
<button
key={mapping}
className="linkml-viewer__tag linkml-viewer__tag--mapping linkml-viewer__tag--narrow linkml-viewer__tag--clickable"
onClick={() => setOntologyPopupCurie(mapping)}
title={`View ontology term: ${mapping}`}
>
{mapping}
</button>
))}
</div>
</div>
)}
{cls.broad_mappings && cls.broad_mappings.length > 0 && (
<div className="linkml-viewer__mappings">
<span className="linkml-viewer__label">{t('broadMappings')}</span>
<div className="linkml-viewer__tag-list">
{cls.broad_mappings.map(mapping => (
<button
key={mapping}
className="linkml-viewer__tag linkml-viewer__tag--mapping linkml-viewer__tag--broad linkml-viewer__tag--clickable"
onClick={() => setOntologyPopupCurie(mapping)}
title={`View ontology term: ${mapping}`}
>
{mapping}
</button>
))}
</div>
</div>
)}
{cls.related_mappings && cls.related_mappings.length > 0 && (
<div className="linkml-viewer__mappings">
<span className="linkml-viewer__label">{t('relatedMappings')}</span>
<div className="linkml-viewer__tag-list">
{cls.related_mappings.map(mapping => (
<button
key={mapping}
className="linkml-viewer__tag linkml-viewer__tag--mapping linkml-viewer__tag--related linkml-viewer__tag--clickable"
onClick={() => setOntologyPopupCurie(mapping)}
title={`View ontology term: ${mapping}`}
>
@ -4005,6 +4056,9 @@ const LinkMLViewerPage: React.FC = () => {
if (cls.class_uri?.toLowerCase().includes(searchLower)) return true;
if (cls.exact_mappings?.some(m => m.toLowerCase().includes(searchLower))) return true;
if (cls.close_mappings?.some(m => m.toLowerCase().includes(searchLower))) return true;
if (cls.narrow_mappings?.some(m => m.toLowerCase().includes(searchLower))) return true;
if (cls.broad_mappings?.some(m => m.toLowerCase().includes(searchLower))) return true;
if (cls.related_mappings?.some(m => m.toLowerCase().includes(searchLower))) return true;
if (cls.slots?.some(s => s.toLowerCase().includes(searchLower))) return true;
return false;
};
@ -4042,6 +4096,9 @@ const LinkMLViewerPage: React.FC = () => {
if (slot.slot_uri?.toLowerCase().includes(searchLower)) return true;
if (slot.exact_mappings?.some(m => m.toLowerCase().includes(searchLower))) return true;
if (slot.close_mappings?.some(m => m.toLowerCase().includes(searchLower))) return true;
if (slot.narrow_mappings?.some(m => m.toLowerCase().includes(searchLower))) return true;
if (slot.broad_mappings?.some(m => m.toLowerCase().includes(searchLower))) return true;
if (slot.related_mappings?.some(m => m.toLowerCase().includes(searchLower))) return true;
return false;
};