Skip to content

Commit de6b93c

Browse files
committed
Display images mapped to selected term in ontology tab
1 parent 7dadea6 commit de6b93c

3 files changed

Lines changed: 114 additions & 1 deletion

File tree

src/app/components/ontology-editor/ontology-editor.component.css

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,6 @@
165165
border: 1px solid var(--color-border);
166166
border-radius: var(--radius-md);
167167
background: color-mix(in srgb, var(--color-bg-elevated) 88%, transparent);
168-
box-shadow: var(--shadow-sm);
169168
}
170169

171170
.selected-term-header {
@@ -222,6 +221,64 @@
222221
color: var(--color-text-secondary);
223222
}
224223

224+
.term-images-card {
225+
padding: var(--space-4);
226+
border: 1px solid var(--color-border);
227+
border-radius: var(--radius-md);
228+
background: color-mix(in srgb, var(--color-bg-elevated) 88%, transparent);
229+
}
230+
231+
.term-images-header {
232+
display: flex;
233+
align-items: center;
234+
justify-content: space-between;
235+
gap: var(--space-2);
236+
margin-bottom: var(--space-3);
237+
}
238+
239+
.term-images-header h4 {
240+
margin: 0;
241+
font-size: var(--font-size-md);
242+
}
243+
244+
.term-images-list {
245+
display: flex;
246+
flex-direction: column;
247+
gap: var(--space-2);
248+
}
249+
250+
.term-image-item {
251+
display: flex;
252+
align-items: flex-start;
253+
justify-content: space-between;
254+
gap: var(--space-3);
255+
padding: var(--space-2) var(--space-3);
256+
border: 1px solid var(--color-border);
257+
border-radius: var(--radius-sm);
258+
background: var(--color-bg-elevated);
259+
}
260+
261+
.term-image-content {
262+
min-width: 0;
263+
}
264+
265+
.term-image-name {
266+
margin: 0;
267+
font-weight: var(--font-weight-medium);
268+
}
269+
270+
.term-image-description {
271+
margin: var(--space-1) 0 0;
272+
font-size: var(--font-size-sm);
273+
color: var(--color-text-secondary);
274+
}
275+
276+
.term-images-empty {
277+
margin: 0;
278+
font-size: var(--font-size-sm);
279+
color: var(--color-text-secondary);
280+
}
281+
225282
.term-edit {
226283
display: flex;
227284
flex-direction: column;

src/app/components/ontology-editor/ontology-editor.component.html

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,43 @@ <h3>
190190
</div>
191191
</div>
192192
</div>
193+
194+
@if (!isCreating() && selectedTerm()) {
195+
<section
196+
class="term-images-card"
197+
role="region"
198+
aria-label="Images mapped to selected term"
199+
>
200+
<div class="term-images-header">
201+
<h4>Mapped images</h4>
202+
<span class="badge badge-accent">
203+
{{ selectedTermImages().length }}
204+
</span>
205+
</div>
206+
207+
@if (selectedTermImages().length > 0) {
208+
<div class="term-images-list" role="list">
209+
@for (image of selectedTermImages(); track image.name) {
210+
<article class="term-image-item" role="listitem">
211+
<div class="term-image-content">
212+
<p class="term-image-name">{{ image.name }}</p>
213+
@if (image.description) {
214+
<p class="term-image-description">{{ image.description }}</p>
215+
}
216+
</div>
217+
@if (image.status) {
218+
<span class="badge">{{ image.status }}</span>
219+
}
220+
</article>
221+
}
222+
</div>
223+
} @else {
224+
<p class="term-images-empty">
225+
No images mapped to this term yet.
226+
</p>
227+
}
228+
</section>
229+
}
193230
} @else {
194231
<div class="empty-editor">
195232
<svg width="64" height="64" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">

src/app/components/ontology-editor/ontology-editor.component.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { FormsModule } from '@angular/forms';
1010
import { DataStateService } from '../../services/data-state.service';
1111
import { OntologyTreeComponent } from './ontology-tree.component';
1212
import { TermStanza } from '../../models/ontology';
13+
import { MetadataItem } from '../../models/metadata.model';
1314

1415
@Component({
1516
selector: 'app-ontology-editor',
@@ -56,6 +57,24 @@ export class OntologyEditorComponent {
5657
protected readonly selectedTerm = this.dataState.selectedTerm;
5758
protected readonly selectedTermId = this.dataState.selectedTermId;
5859

60+
protected readonly selectedTermImages = computed<MetadataItem[]>(() => {
61+
const selectedId = this.selectedTermId();
62+
if (!selectedId) return [];
63+
64+
const metadataByName = new Map(
65+
this.dataState.metadata().map((item) => [item.name, item])
66+
);
67+
68+
const uniqueNames = new Set(
69+
this.dataState.getMappingsForTerm(selectedId).map((mapping) => mapping.name)
70+
);
71+
72+
return Array.from(uniqueNames)
73+
.map((name) => metadataByName.get(name))
74+
.filter((item): item is MetadataItem => !!item)
75+
.sort((a, b) => a.name.localeCompare(b.name));
76+
});
77+
5978
protected readonly createParentHierarchy = computed(() => {
6079
const ontology = this.dataState.ontology();
6180
const parentId = this.createParentId();

0 commit comments

Comments
 (0)