Skip to content

Commit 59acaca

Browse files
made it so that the search puts the modified forms with the protein
1 parent 7d4a582 commit 59acaca

4 files changed

Lines changed: 393 additions & 70 deletions

File tree

projects/website-angular/src/app/search/search.component.html

Lines changed: 122 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -273,16 +273,23 @@ <h2>Please report to us and we will get back shortly.</h2>
273273
<app-tile variant="light">
274274
<div class="result-group">
275275
<button class="group-header" (click)="toggleGroup(group.typeName)">
276-
<h2>{{ group.typeName }} ({{ group.entriesCount }})</h2>
276+
@if (group.typeName === 'Protein' && !proteinLoading && uniqueProteins.length) {
277+
<h2>{{ group.typeName }} — {{ uniqueProteins.length }} protein{{ uniqueProteins.length === 1 ? '' : 's' }}, {{ proteinTotalForms }} form{{ proteinTotalForms === 1 ? '' : 's' }}</h2>
278+
} @else {
279+
<h2>{{ group.typeName }} ({{ group.entriesCount }})</h2>
280+
}
277281
<span class="group-toggle">{{ collapsedGroups[group.typeName] ? '+' : '−' }}</span>
278282
</button>
279283
@if (!collapsedGroups[group.typeName]) {
280-
<div class="group-entries">
281-
@for (entry of group.entries; track entry.dbId) {
284+
<div class="group-entries" [class.loading]="groupLoading[group.typeName] || (group.typeName === 'Protein' && proteinLoading)">
285+
@if (group.typeName === 'Protein' && proteinLoading) {
286+
<div class="protein-loading-msg">Loading all protein forms...</div>
287+
}
288+
@for (entry of getGroupPageEntries(group); track entry.dbId) {
282289
<div class="search-entry">
283290
<div class="entry-header">
284291
<a class="entry-name" [routerLink]="getDetailLink(entry)" [innerHTML]="entry.referenceName || entry.name"></a>
285-
<span class="entry-id">{{ entry.stId }}</span>
292+
<span class="entry-id">{{ entry.id || entry.stId }}</span>
286293
</div>
287294
@if (entry.species?.length) {
288295
<div class="entry-species">
@@ -304,9 +311,63 @@ <h2>{{ group.typeName }} ({{ group.entriesCount }})</h2>
304311
Reference: <a [href]="entry.referenceURL" target="_blank" rel="noopener"><span [innerHTML]="entry.referenceName"></span> ({{ entry.referenceIdentifier }})</a>
305312
</div>
306313
}
314+
@if (entry.type === 'Protein' && entry.referenceIdentifier && getProteinFormCount(entry) > 1) {
315+
<button class="forms-toggle" (click)="toggleForms(entry)">
316+
<span class="material-symbols-rounded">{{ isFormsExpanded(entry) ? 'expand_less' : 'expand_more' }}</span>
317+
{{ getProteinFormCount(entry) }} modified form{{ getProteinFormCount(entry) === 1 ? '' : 's' }}
318+
</button>
319+
@if (isFormsExpanded(entry)) {
320+
<div class="protein-forms">
321+
@for (form of getProteinForms(entry); track form.dbId) {
322+
<div class="protein-form-entry">
323+
<a class="form-name" [routerLink]="getDetailLink(form)" [innerHTML]="form.name"></a>
324+
<span class="form-id">{{ form.id || form.stId }}</span>
325+
@if (form.compartmentNames?.length) {
326+
<span class="form-compartment">{{ form.compartmentNames.join(', ') }}</span>
327+
}
328+
</div>
329+
}
330+
</div>
331+
}
332+
}
307333
</div>
308334
}
309335
</div>
336+
@if (getGroupTotalPages(group) > 1 && !(group.typeName === 'Protein' && proteinLoading)) {
337+
<nav class="group-pagination">
338+
<button
339+
class="page-btn"
340+
[disabled]="getGroupPage(group) === 0"
341+
(click)="goToGroupPage(group, 0)"
342+
>First</button>
343+
<button
344+
class="page-btn"
345+
[disabled]="getGroupPage(group) === 0"
346+
(click)="goToGroupPage(group, getGroupPage(group) - 1)"
347+
>Prev</button>
348+
@for (p of getGroupPageNumbers(group); track $index) {
349+
@if (p === '...') {
350+
<span class="page-ellipsis">...</span>
351+
} @else {
352+
<button
353+
class="page-btn"
354+
[class.active]="p === getGroupPage(group)"
355+
(click)="goToGroupPage(group, +p)"
356+
>{{ +p + 1 }}</button>
357+
}
358+
}
359+
<button
360+
class="page-btn"
361+
[disabled]="getGroupPage(group) === getGroupTotalPages(group) - 1"
362+
(click)="goToGroupPage(group, getGroupPage(group) + 1)"
363+
>Next</button>
364+
<button
365+
class="page-btn"
366+
[disabled]="getGroupPage(group) === getGroupTotalPages(group) - 1"
367+
(click)="goToGroupPage(group, getGroupTotalPages(group) - 1)"
368+
>Last</button>
369+
</nav>
370+
}
310371
}
311372
</div>
312373
</app-tile>
@@ -319,7 +380,7 @@ <h2>{{ group.typeName }} ({{ group.entriesCount }})</h2>
319380
<div class="search-entry">
320381
<div class="entry-header">
321382
<a class="entry-name" [routerLink]="getDetailLink(entry)" [innerHTML]="entry.referenceName || entry.name"></a>
322-
<span class="entry-id">{{ entry.stId }}</span>
383+
<span class="entry-id">{{ entry.id || entry.stId }}</span>
323384
</div>
324385
@if (entry.species?.length) {
325386
<div class="entry-species">
@@ -341,46 +402,69 @@ <h2>{{ group.typeName }} ({{ group.entriesCount }})</h2>
341402
Reference: <a [href]="entry.referenceURL" target="_blank" rel="noopener"><span [innerHTML]="entry.referenceName"></span> ({{ entry.referenceIdentifier }})</a>
342403
</div>
343404
}
405+
@if (entry.type === 'Protein' && entry.referenceIdentifier && getProteinFormCount(entry) > 1) {
406+
<button class="forms-toggle" (click)="toggleForms(entry)">
407+
<span class="material-symbols-rounded">{{ isFormsExpanded(entry) ? 'expand_less' : 'expand_more' }}</span>
408+
{{ getProteinFormCount(entry) }} modified form{{ getProteinFormCount(entry) === 1 ? '' : 's' }}
409+
</button>
410+
@if (isFormsExpanded(entry)) {
411+
<div class="protein-forms">
412+
@for (form of getProteinForms(entry); track form.dbId) {
413+
<div class="protein-form-entry">
414+
<a class="form-name" [routerLink]="getDetailLink(form)" [innerHTML]="form.name"></a>
415+
<span class="form-id">{{ form.id || form.stId }}</span>
416+
@if (form.compartmentNames?.length) {
417+
<span class="form-compartment">{{ form.compartmentNames.join(', ') }}</span>
418+
}
419+
</div>
420+
}
421+
</div>
422+
}
423+
}
344424
</div>
345425
}
346426
</div>
347427
</app-tile>
348-
}
349-
}
350428

351-
<!-- Pagination -->
352-
@if (totalPages > 1) {
353-
<nav class="pagination">
354-
<button
355-
class="page-btn"
356-
[disabled]="currentPage === 0"
357-
(click)="goToPage(0)"
358-
>First</button>
359-
<button
360-
class="page-btn"
361-
[disabled]="currentPage === 0"
362-
(click)="goToPage(currentPage - 1)"
363-
>Prev</button>
429+
<!-- Pagination (ungrouped view only) -->
430+
@if (totalPages > 1) {
431+
<nav class="pagination">
432+
<button
433+
class="page-btn"
434+
[disabled]="currentPage === 0"
435+
(click)="goToPage(0)"
436+
>First</button>
437+
<button
438+
class="page-btn"
439+
[disabled]="currentPage === 0"
440+
(click)="goToPage(currentPage - 1)"
441+
>Prev</button>
364442

365-
@for (p of getPageNumbers(); track p) {
366-
<button
367-
class="page-btn"
368-
[class.active]="p === currentPage"
369-
(click)="goToPage(p)"
370-
>{{ p + 1 }}</button>
371-
}
443+
@for (p of getPageNumbers(); track $index) {
444+
@if (p === '...') {
445+
<span class="page-ellipsis">...</span>
446+
} @else {
447+
<button
448+
class="page-btn"
449+
[class.active]="p === currentPage"
450+
(click)="goToPage(+p)"
451+
>{{ +p + 1 }}</button>
452+
}
453+
}
372454

373-
<button
374-
class="page-btn"
375-
[disabled]="currentPage === totalPages - 1"
376-
(click)="goToPage(currentPage + 1)"
377-
>Next</button>
378-
<button
379-
class="page-btn"
380-
[disabled]="currentPage === totalPages - 1"
381-
(click)="goToPage(totalPages - 1)"
382-
>Last</button>
383-
</nav>
455+
<button
456+
class="page-btn"
457+
[disabled]="currentPage === totalPages - 1"
458+
(click)="goToPage(currentPage + 1)"
459+
>Next</button>
460+
<button
461+
class="page-btn"
462+
[disabled]="currentPage === totalPages - 1"
463+
(click)="goToPage(totalPages - 1)"
464+
>Last</button>
465+
</nav>
466+
}
467+
}
384468
}
385469
}
386470
</div>

projects/website-angular/src/app/search/search.component.scss

Lines changed: 105 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,11 @@ $border-radius: 8px;
227227

228228
.group-entries {
229229
margin-top: 16px;
230+
231+
&.loading {
232+
opacity: 0.5;
233+
pointer-events: none;
234+
}
230235
}
231236

232237
.search-entry {
@@ -333,6 +338,84 @@ $border-radius: 8px;
333338
}
334339
}
335340

341+
// Collapsible protein forms
342+
.forms-toggle {
343+
display: inline-flex;
344+
align-items: center;
345+
gap: 2px;
346+
margin-top: 6px;
347+
padding: 2px 8px 2px 2px;
348+
border: none;
349+
background: none;
350+
color: var(--on-surface-variant);
351+
font-size: 0.8rem;
352+
cursor: pointer;
353+
border-radius: 4px;
354+
355+
.material-symbols-rounded {
356+
font-size: 18px;
357+
}
358+
359+
&:hover {
360+
color: var(--primary);
361+
background: rgba(0, 0, 0, 0.04);
362+
363+
:host-context(.dark) & {
364+
background: rgba(255, 255, 255, 0.06);
365+
}
366+
}
367+
}
368+
369+
.protein-forms {
370+
margin-top: 4px;
371+
margin-left: 16px;
372+
padding-left: 12px;
373+
border-left: 2px solid rgba(0, 0, 0, 0.1);
374+
max-height: 400px;
375+
overflow-y: auto;
376+
377+
:host-context(.dark) & {
378+
border-left-color: rgba(255, 255, 255, 0.1);
379+
}
380+
}
381+
382+
.protein-form-entry {
383+
display: flex;
384+
align-items: baseline;
385+
gap: 8px;
386+
flex-wrap: wrap;
387+
padding: 4px 0;
388+
font-size: 0.85rem;
389+
}
390+
391+
.form-name {
392+
color: var(--primary);
393+
text-decoration: none;
394+
395+
&:hover {
396+
text-decoration: underline;
397+
}
398+
}
399+
400+
.form-id {
401+
font-size: 0.75rem;
402+
color: var(--on-surface-variant);
403+
font-family: monospace;
404+
}
405+
406+
.form-compartment {
407+
font-size: 0.75rem;
408+
color: var(--on-surface-variant);
409+
font-style: italic;
410+
}
411+
412+
.protein-loading-msg {
413+
padding: 12px 0;
414+
color: var(--on-surface-variant);
415+
font-size: 0.85rem;
416+
font-style: italic;
417+
}
418+
336419
// Search bar at top
337420
.search-top {
338421
max-width: 700px;
@@ -935,7 +1018,21 @@ $border-radius: 8px;
9351018
}
9361019

9371020

938-
// Pagination
1021+
// Per-group pagination
1022+
.group-pagination {
1023+
display: flex;
1024+
align-items: center;
1025+
gap: 4px;
1026+
margin-top: 12px;
1027+
padding-top: 12px;
1028+
border-top: 1px solid rgba(0, 0, 0, 0.06);
1029+
1030+
:host-context(.dark) & {
1031+
border-top-color: rgba(255, 255, 255, 0.06);
1032+
}
1033+
}
1034+
1035+
// Global pagination
9391036
.pagination {
9401037
display: flex;
9411038
justify-content: center;
@@ -945,6 +1042,13 @@ $border-radius: 8px;
9451042
padding: 16px 0;
9461043
}
9471044

1045+
.page-ellipsis {
1046+
padding: 6px 4px;
1047+
color: var(--on-surface-variant);
1048+
font-size: 0.85rem;
1049+
user-select: none;
1050+
}
1051+
9481052
.page-btn {
9491053
padding: 6px 12px;
9501054
border: 1px solid var(--primary);

0 commit comments

Comments
 (0)