Skip to content

Commit e76d9fa

Browse files
feat: label the entity type with a chip + give the Overview its own divider header
Two related polish items on the description tab (which is what /content/detail renders, and also the PathwayBrowser's right-hand detail panel). 1. A small "PATHWAY" / "REACTION" / "PROTEIN" / etc. chip beside the entity name in the header. Maps the common Reactome schema classes to friendlier labels (EntityWithAccessionedSequence -> Protein, SimpleEntity -> Small Molecule, ReactionLikeEvent variants -> Reaction, etc.); falls back to a CamelCase split for anything not in the map. Considered putting it in the breadcrumb but a non-clickable crumb is unconventional, so we went with the chip. 2. Drop the `i > 0` skip on the section divider loop so the Overview section gets its own "Overview" label like every other section (Composition, Cross-References, Authorship, ...). Moves the OVERVIEW anchor off the page header and onto the divider so sidebar TOC clicks land on the section header rather than the page title. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent b47e206 commit e76d9fa

3 files changed

Lines changed: 52 additions & 11 deletions

File tree

projects/pathway-browser/src/app/details/tabs/description-tab/description-tab.component.html

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
<div id="details" #details>
1515
<div class="content">
1616
<!-- Header -->
17-
<div class="header" [id]=DataKeys.OVERVIEW>
17+
<div class="header">
1818
<div class="label">
1919
<mat-icon
2020
class="custom-icon"
@@ -30,6 +30,9 @@
3030
</mat-slide-toggle>
3131
}
3232
</span>
33+
@if (typeLabel()) {
34+
<span class="type-chip">{{ typeLabel() }}</span>
35+
}
3336
</div>
3437
<div class="details-button">
3538
<a mat-button [routerLink]="`${CONTENT_DETAIL}/${obj().stId}`" target="_blank">
@@ -40,17 +43,14 @@
4043
</div>
4144
@for (element of elements; track element.key; let i = $index) {
4245
@if (element.isPresent ? element.isPresent() : obj()[element.key]) {
43-
<!-- Avoid overview label -->
44-
@if (i > 0) {
45-
<div class="divider-container" [id]="element.key">
46-
<div class="divider-name-container">
47-
<ng-container *ngTemplateOutlet="dividerTemplate; context: { $implicit: element.label }"></ng-container>
48-
</div>
49-
<div class="divider-line-container">
50-
<mat-divider class="divider"></mat-divider>
51-
</div>
46+
<div class="divider-container" [id]="element.key">
47+
<div class="divider-name-container">
48+
<ng-container *ngTemplateOutlet="dividerTemplate; context: { $implicit: element.label }"></ng-container>
5249
</div>
53-
}
50+
<div class="divider-line-container">
51+
<mat-divider class="divider"></mat-divider>
52+
</div>
53+
</div>
5454
@if (!element.manual) {
5555
<cr-controller-tree [type]="element.key" [data]="obj()[element.key]"
5656
[depthControl]="element.hasDepthControl ?? false" [scope]="element.scope || 'entity'"

projects/pathway-browser/src/app/details/tabs/description-tab/description-tab.component.scss

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,18 @@
7979
padding-right: 2px;
8080
}
8181

82+
& .type-chip {
83+
flex-shrink: 0;
84+
font-size: 12px;
85+
font-weight: 600;
86+
letter-spacing: 0.3px;
87+
text-transform: uppercase;
88+
padding: 2px 8px;
89+
border-radius: 10px;
90+
background: var(--secondary-container, rgba(0, 110, 144, 0.12));
91+
color: var(--on-secondary-container, var(--primary));
92+
line-height: 1.4;
93+
}
8294
}
8395

8496
.details-button {

projects/pathway-browser/src/app/details/tabs/description-tab/description-tab.component.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,35 @@ export class DescriptionTabComponent implements OnDestroy {
194194
});
195195

196196
readonly symbol = computed(() => this.getSymbol(this.obj()));
197+
198+
// Human-friendly schema-class label rendered as a chip beside the
199+
// entity name in the description-tab header (e.g. "Pathway",
200+
// "Reaction", "Protein"). Maps the few Reactome schema classes whose
201+
// raw name is jargon; falls back to splitting CamelCase otherwise.
202+
private static readonly TYPE_LABELS: Record<string, string> = {
203+
TopLevelPathway: 'Pathway',
204+
Pathway: 'Pathway',
205+
Reaction: 'Reaction',
206+
BlackBoxEvent: 'Reaction',
207+
Polymerisation: 'Reaction',
208+
Depolymerisation: 'Reaction',
209+
FailedReaction: 'Reaction',
210+
ReactionLikeEvent: 'Reaction',
211+
EntityWithAccessionedSequence: 'Protein',
212+
SimpleEntity: 'Small Molecule',
213+
ChemicalDrug: 'Drug',
214+
ProteinDrug: 'Drug',
215+
RNADrug: 'Drug',
216+
OtherEntity: 'Other Entity',
217+
};
218+
readonly typeLabel = computed(() => {
219+
const sc = (this.obj() as DatabaseObject & { schemaClass?: string }).schemaClass;
220+
if (!sc) return '';
221+
if (DescriptionTabComponent.TYPE_LABELS[sc]) {
222+
return DescriptionTabComponent.TYPE_LABELS[sc];
223+
}
224+
return sc.replace(/([a-z])([A-Z])/g, '$1 $2');
225+
});
197226
readonly literatureRefs: Signal<LiteratureReference[]> = computed(() =>
198227
getProperty(this.obj(), DataKeys.LITERATURE_REFERENCE)
199228
);

0 commit comments

Comments
 (0)