Skip to content

Commit 2ad401e

Browse files
committed
adding popover component
1 parent 5c1fed5 commit 2ad401e

File tree

8 files changed

+152
-169
lines changed

8 files changed

+152
-169
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "phenoboard",
3-
"version": "0.5.102",
3+
"version": "0.5.103",
44
"scripts": {
55
"ng": "ng",
66
"start": "nx serve phenoboard --port 1420",

src-tauri/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "phenoboard"
3-
version = "0.5.102"
3+
version = "0.5.103"
44
description = "Curate cohorts of GA4GH Phenopackets"
55
authors = ["Peter N Robinson"]
66
edition = "2021"

src-tauri/tauri.conf.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"$schema": "https://schema.tauri.app/config/2",
33
"productName": "phenoboard",
4-
"version": "0.5.102",
4+
"version": "0.5.103",
55
"identifier": "org.p2gx.phenoboard",
66
"build": {
77
"beforeDevCommand": "npx nx serve phenoboard --configuration=development --no-cloud",

src/app/pttemplate/pttemplate.component.css

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -300,11 +300,7 @@ button[mat-icon-button] {
300300
transform: scale(0.97);
301301
}
302302

303-
.allele-count-grid {
304-
display: grid;
305-
grid-template-columns: repeat(4, 1.5rem);
306-
gap: 5px;
307-
}
303+
308304

309305
.allele-btn {
310306
width: 1.75rem;

src/app/pttemplate/pttemplate.component.html

Lines changed: 94 additions & 135 deletions
Original file line numberDiff line numberDiff line change
@@ -8,84 +8,82 @@
88

99
<!-- String input section -->
1010
<div class="mt-4">
11-
1211
<app-cohort-metadata
1312
[cohortData]="cohortData()!"
1413
(resetCohortMetadata)="handleReset()"
1514
(updateAcronym)="handleAcronym($any($event))"
1615
(updateMoi)="handleMoi($any($event))">
17-
</app-cohort-metadata>
16+
</app-cohort-metadata>
1817

19-
<div class="mt-4 flex items-center gap-2">
20-
<label for="hpoFilter" class="text-sm text-gray-700">Filter HPO columns:</label>
21-
<select
22-
id="hpoFilter"
23-
class="border rounded p-1 text-sm"
24-
[value]="selectedTopLevelHpo()"
25-
(change)="selectedTopLevelHpo.set($any($event.target).value)"
26-
>
27-
<option value="">Show all</option>
28-
@for (groupKey of hpoGroupKeys(); track groupKey) {
29-
<option [value]="groupKey">{{ groupKey }}</option>
30-
}
31-
</select>
32-
<app-help-button
33-
title="Filter HPO columns"
34-
[lines]="[
35-
'Filter to the columns shown in the display to the indicated top-level HPO category.',
36-
'The categories correspond to top-level HPO terms (direct children of <i>Phenotypic abnormality</i>).',
37-
'Choose <i>Show all</i> to restore the original view.'
38-
]" />
39-
</div>
18+
<div class="mt-4 flex items-center gap-2">
19+
<label for="hpoFilter" class="text-sm text-gray-700">Filter HPO columns:</label>
20+
<select
21+
id="hpoFilter"
22+
class="border rounded p-1 text-sm"
23+
[value]="selectedTopLevelHpo()"
24+
(change)="selectedTopLevelHpo.set($any($event.target).value)"
25+
>
26+
<option value="">Show all</option>
27+
@for (groupKey of hpoGroupKeys(); track groupKey) {
28+
<option [value]="groupKey">{{ groupKey }}</option>
29+
}
30+
</select>
31+
<app-help-button
32+
title="Filter HPO columns"
33+
[lines]="[
34+
'Filter to the columns shown in the display to the indicated top-level HPO category.',
35+
'The categories correspond to top-level HPO terms (direct children of <i>Phenotypic abnormality</i>).',
36+
'Choose <i>Show all</i> to restore the original view.'
37+
]" />
38+
</div>
4039

4140
<!-- Table with one row per phenopacket -->
4241
@if (cohortData(); as cohort){
4342
<div class="pt-table-container">
4443
<div class="top-scroll-mirror overflow-x-auto invisible-scrollbar">
45-
<div class="h-1" [style.width]="tableWidth"></div>
46-
</div>
47-
<div class="overflow-y-auto max-h-[600px] max-w-7xl">
48-
<table class="pt-table">
49-
<thead class="sticky top-0 z-10 bg-white shadow-sm border-b border-gray-200">
50-
<tr>
51-
<th class="narrow-column bottom-align">Individual ID</th>
52-
@if(showAlleleColumn){
53-
<th class="narrow-column bottom-align">
54-
Alleles
55-
</th>
56-
}
57-
<!-- The following creates the series of headers for the HPO columns.
58-
The function shouldDisplayHpoColumn allows the user to focus on 1-10 columns at a time-->
59-
@if (cohort) {
60-
@for (header of cohort.hpoHeaders; track header.hpoId; let i = $index) {
61-
@if (visibleColumnMask()[i]) {
62-
<th
63-
class="rotate-header hpo-col hpo-col-th"
64-
(mouseenter)="onHeaderMouseEnter(i)"
65-
(mouseleave)="onHeaderMouseLeave()"
66-
>
67-
<div class="rotated-text" [ngClass]="{ 'hover-underline': true }">
68-
{{ header.hpoLabel }}
69-
</div>
70-
<!-- Popup shown on hover -->
71-
@if(isHeaderHovered(i)) {
72-
<div class="hpo-popup">
73-
<a
74-
[href]="'https://hpo.jax.org/browse/term/' + header.hpoId"
75-
target="_blank"
76-
rel="noopener"
77-
>
78-
🔗 {{ header.hpoId }}
79-
</a>
44+
<div class="h-1" [style.width]="tableWidth"></div>
45+
</div>
46+
<div class="overflow-y-auto max-h-[600px] max-w-7xl">
47+
<table class="pt-table">
48+
<thead class="sticky top-0 z-10 bg-white shadow-sm border-b border-gray-200">
49+
<tr>
50+
<th class="narrow-column bottom-align">Individual ID</th>
51+
52+
<th class="narrow-column bottom-align">
53+
Alleles
54+
</th>
55+
<!-- The following creates the series of headers for the HPO columns.
56+
The function shouldDisplayHpoColumn allows the user to focus on 1-10 columns at a time-->
57+
@if (cohort) {
58+
@for (header of cohort.hpoHeaders; track header.hpoId; let i = $index) {
59+
@if (visibleColumnMask()[i]) {
60+
<th
61+
class="rotate-header hpo-col hpo-col-th"
62+
(mouseenter)="onHeaderMouseEnter(i)"
63+
(mouseleave)="onHeaderMouseLeave()"
64+
>
65+
<div class="rotated-text" [ngClass]="{ 'hover-underline': true }">
66+
{{ header.hpoLabel }}
8067
</div>
81-
}
82-
</th>
68+
<!-- Popup shown on hover -->
69+
@if(isHeaderHovered(i)) {
70+
<div class="hpo-popup">
71+
<a
72+
[href]="'https://hpo.jax.org/browse/term/' + header.hpoId"
73+
target="_blank"
74+
rel="noopener"
75+
>
76+
🔗 {{ header.hpoId }}
77+
</a>
78+
</div>
79+
}
80+
</th>
81+
}
8382
}
8483
}
85-
}
86-
</tr>
87-
</thead>
88-
<tbody>
84+
</tr>
85+
</thead>
86+
<tbody>
8987
@for (row of tableVM(); track row.id; let rowIndex = $index) {
9088
<tr [class.bg-red-50]="!row.hasObservedHpo">
9189
<!-- First column: PMID/title/individual_id/comment -->
@@ -136,19 +134,20 @@
136134
</td>
137135

138136
<!-- Second column for gene/allele -->
139-
@if(showAlleleColumn){
140-
<td class="relative narrow-column">
141-
@if (row.alleles.length === 0) {
142-
<button
143-
class="allele-btn allele-btn-add"
144-
title="Add allele"
145-
(click)="toggleAddAllelePopover(row.id, $event)">
146-
+
147-
</button>
148-
}
149-
@for (allele of row.alleles; track allele.key) {
150-
<div class="allele-row flex items-center gap-x-3">
151-
<div class="flex items-center gap-x-1 allele-content">
137+
138+
139+
<td class="relative narrow-column">
140+
@if (row.alleles.length === 0) {
141+
<button cdkOverlayOrigin #originEmpty="cdkOverlayOrigin"
142+
class="allele-btn allele-btn-add" (click)="openAddAlleleRowId = row.id">+</button>
143+
144+
<app-popover [trigger]="originEmpty" [isOpen]="openAddAlleleRowId === row.id">
145+
<ng-container *ngTemplateOutlet="alleleMenuContent"></ng-container>
146+
</app-popover>
147+
}
148+
@for (allele of row.alleles; track allele.key) {
149+
<div class="allele-row flex items-center gap-x-3">
150+
<div class="flex items-center gap-x-1 allele-content">
152151
<span
153152
class="inline-block w-3 h-3 rounded-full"
154153
[ngClass]="allele.validated ? 'bg-green-500' : 'bg-red-500'"
@@ -158,11 +157,8 @@
158157
{{ allele.shortDisplay }}
159158
</span>
160159
</div>
161-
162-
<!-- Right side: actions -->
163-
<div class="flex items-center gap-x-2">
164-
<div class="allele-count-grid">
165-
<button
160+
<div class="allele-count-grid">
161+
<button
166162
class="allele-btn allele-btn-count"
167163
[ngClass]="{ 'selected-count': allele.count === 1 }"
168164
(click)="onAlleleCountChange(allele.key, row.id, 1)">1</button>
@@ -172,61 +168,24 @@
172168
<button
173169
class="allele-btn allele-btn-delete"
174170
(click)="onAlleleCountChange(allele.key, row.id, 0)">🗑️</button>
175-
<button
176-
class="allele-btn allele-btn-add"
177-
title="Add allele"
178-
(click)="toggleAddAllelePopover(row.id, $event)">
179-
+
180-
</button>
181-
</div>
182-
</div>
183-
</div>
184-
} <!-- for gene -->
185-
<!-- Popover -->
186-
@if(openAddAlleleRowId === row.id) {
187-
@if (openAddAlleleRowId === row.id) {
188-
<div
189-
class="absolute bg-white border border-gray-300 shadow-md rounded-lg p-2 z-50"
190-
style="top: 100%; right: 0; width: 220px;"
191-
>
192-
<div class="grid grid-cols-2 gap-2">
193-
<button
194-
type="button"
195-
class="allele-tile"
196-
(click)="addAllele(row.id, VariantKind.HGVS); closeAddAllelePopover()"
197-
>
198-
HGVS
199-
</button>
200-
201-
<button
202-
type="button"
203-
class="allele-tile"
204-
(click)="addAllele(row.id, VariantKind.SV); closeAddAllelePopover()"
205-
>
206-
SV
207-
</button>
208-
209-
<button
210-
type="button"
211-
class="allele-tile"
212-
(click)="addAllele(row.id, VariantKind.INTERGENIC); closeAddAllelePopover()"
213-
>
214-
Intergenic
215-
</button>
216-
217-
<button
218-
type="button"
219-
class="allele-tile"
220-
(click)="addAllele(row.id, VariantKind.INTERGENIC); closeAddAllelePopover()"
221-
>
222-
Mitochondrial
223-
</button>
224-
</div>
171+
<button cdkOverlayOrigin #originList="cdkOverlayOrigin"
172+
class="allele-btn allele-btn-add" (click)="openAddAlleleRowId = row.id">+</button>
173+
<app-popover [trigger]="originList" [isOpen]="openAddAlleleRowId === row.id">
174+
<ng-container *ngTemplateOutlet="alleleMenuContent"></ng-container>
175+
</app-popover>
225176
</div>
226-
}
177+
</div>
227178
}
228-
</td>
229-
}<!-- isShowAllele -->
179+
180+
<ng-template #alleleMenuContent>
181+
<div class="grid grid-cols-2 gap-2 w-[220px]">
182+
<button type="button" class="allele-tile" (click)="addAllele(row.id, VariantKind.HGVS); openAddAlleleRowId = null">HGVS</button>
183+
<button type="button" class="allele-tile" (click)="addAllele(row.id, VariantKind.SV); openAddAlleleRowId = null">SV</button>
184+
<button type="button" class="allele-tile" (click)="addAllele(row.id, VariantKind.INTERGENIC); openAddAlleleRowId = null">Intergenic</button>
185+
<button type="button" class="allele-tile" (click)="addAllele(row.id, VariantKind.SV); openAddAlleleRowId = null">Mito</button>
186+
</div>
187+
</ng-template>
188+
</td>
230189

231190
<!-- The values of the HPO columns-->
232191
@for (cell of row.hpoCells; track $index; let hpoIndex = $index) {

0 commit comments

Comments
 (0)