diff --git a/e2e/disease-compare.spec.ts b/e2e/disease-compare.spec.ts index ad475949..899d1c3f 100644 --- a/e2e/disease-compare.spec.ts +++ b/e2e/disease-compare.spec.ts @@ -119,6 +119,9 @@ test.describe('a disease pathway, and its comparison with the normal one', () => } }); + // Well inside the slide, which the waits around it put at about 600ms. + const SAYS_AT_ONCE = 200; + test('a second click while it slides out brings it back', async ({ page }) => { await open(page, DISEASE); await compareButton(page).click(); @@ -127,10 +130,13 @@ test.describe('a disease pathway, and its comparison with the normal one', () => await expect(compareButton(page)).toHaveText(/Close comparison/); await compareButton(page).click(); // At once -- not once the slide has finished -- it says what it will do. - expect(await compareButton(page).textContent()).toMatch(/Compare with normal/); + // "At once" is the next frame, not the instant the click returns: under + // load, change detection may not have run by then. SAYS_AT_ONCE is well + // inside the slide, so this still fails if the label waits for it. + await expect(compareButton(page)).toHaveText(/Compare with normal/, { timeout: SAYS_AT_ONCE }); // And a click before the slide is over reverses it. await compareButton(page).click(); - expect(await compareButton(page).textContent()).toMatch(/Close comparison/); + await expect(compareButton(page)).toHaveText(/Close comparison/, { timeout: SAYS_AT_ONCE }); await page.waitForTimeout(800); await expect(handle(page)).toBeVisible(); await expect.poll(() => layerStart(page)).toBeGreaterThan(200); diff --git a/projects/pathway-browser/src/app/deltasignal/deltasignal-logic-graph.component.ts b/projects/pathway-browser/src/app/deltasignal/deltasignal-logic-graph.component.ts index 5e2171b9..4f624b56 100644 --- a/projects/pathway-browser/src/app/deltasignal/deltasignal-logic-graph.component.ts +++ b/projects/pathway-browser/src/app/deltasignal/deltasignal-logic-graph.component.ts @@ -5,7 +5,6 @@ import { effect, ElementRef, inject, - NgZone, OnDestroy, signal, untracked, @@ -31,7 +30,6 @@ const GRAPH_LIMIT = 40; }) export class DeltaSignalLogicGraphComponent implements OnDestroy { private readonly service = inject(DeltaSignalService); - private readonly zone = inject(NgZone); private readonly container = viewChild>('graphContainer'); private cy?: Core; private observedElement?: HTMLDivElement; @@ -116,7 +114,8 @@ export class DeltaSignalLogicGraphComponent implements OnDestroy { }); this.cy.on('tap', 'node', (event) => { const selected = nodes.find((node) => node.uuid === event.target.id()) ?? null; - this.zone.run(() => this.selected.set(selected)); + // A signal: zoneless change detection sees the set, with no zone to enter. + this.selected.set(selected); }); this.cy .layout({ diff --git a/projects/pathway-browser/src/app/details/common/external-reference/external-reference.component.html b/projects/pathway-browser/src/app/details/common/external-reference/external-reference.component.html index 3c025baf..8a7d0904 100644 --- a/projects/pathway-browser/src/app/details/common/external-reference/external-reference.component.html +++ b/projects/pathway-browser/src/app/details/common/external-reference/external-reference.component.html @@ -6,7 +6,7 @@
{{ property.label || '' | titlecase }}
@if (isArray(property.value) && !isString(property.value[0])) { @for (item of property.value; track item.dbId) { diff --git a/projects/pathway-browser/src/app/details/common/external-reference/external-reference.component.ts b/projects/pathway-browser/src/app/details/common/external-reference/external-reference.component.ts index c5a3d951..eab8293f 100644 --- a/projects/pathway-browser/src/app/details/common/external-reference/external-reference.component.ts +++ b/projects/pathway-browser/src/app/details/common/external-reference/external-reference.component.ts @@ -2,7 +2,7 @@ import { Component, computed, input, inject } from '@angular/core'; import { ReferenceEntity } from '../../../model/graph/reference-entity/reference-entity.model'; import { EntityService } from '../../../services/entity.service'; import { isArray, isString } from 'lodash'; -import { NgClass, TitleCasePipe } from '@angular/common'; +import { TitleCasePipe } from '@angular/common'; import { StructureViewerComponent } from '../../tabs/molecule-tab/structure-viewer/structure-viewer.component'; import { DatabaseIdentifier } from '../../../model/graph/database-identifier.model'; import { MatIconButton } from '@angular/material/button'; @@ -17,15 +17,7 @@ import { MoleculeType } from '../../tabs/molecule-tab/molecule-tab.component'; selector: 'cr-external-reference', templateUrl: './external-reference.component.html', styleUrl: './external-reference.component.scss', - imports: [ - TitleCasePipe, - NgClass, - MatIcon, - MatIconButton, - MatTooltip, - NgClass, - StructureViewerComponent, - ], + imports: [TitleCasePipe, MatIcon, MatIconButton, MatTooltip, StructureViewerComponent], }) export class ExternalReferenceComponent { private entity = inject(EntityService); diff --git a/projects/pathway-browser/src/app/details/common/object-tree/object-tree.component.html b/projects/pathway-browser/src/app/details/common/object-tree/object-tree.component.html index 326126a1..dd09ea3d 100644 --- a/projects/pathway-browser/src/app/details/common/object-tree/object-tree.component.html +++ b/projects/pathway-browser/src/app/details/common/object-tree/object-tree.component.html @@ -26,7 +26,7 @@ @let connector = getAllConnectors(treeNodeRef._getSetSize(), node, index, treeNodeRef.level)[index];
@@ -150,7 +150,7 @@ : { type: 'is', shape: 'L' };
diff --git a/projects/pathway-browser/src/app/details/common/object-tree/object-tree.component.ts b/projects/pathway-browser/src/app/details/common/object-tree/object-tree.component.ts index bc316b8c..6c023f92 100644 --- a/projects/pathway-browser/src/app/details/common/object-tree/object-tree.component.ts +++ b/projects/pathway-browser/src/app/details/common/object-tree/object-tree.component.ts @@ -39,7 +39,6 @@ import { DataStateService } from '../../../services/data-state.service'; import type { Relationship } from '../../../model/graph/relationship.model'; import { cloneDeep, isArray } from 'lodash'; import { UrlStateService } from '../../../services/url-state.service'; -import { NgClass } from '@angular/common'; import { MatTooltip } from '@angular/material/tooltip'; import { MatIcon } from '@angular/material/icon'; import { ExtractCompartmentPipe } from '../../../pipes/extract-compartment.pipe'; @@ -59,7 +58,6 @@ type Connector = { type: string; shape: 'L' | 'I' | 'T' } | null; ExpressionTagComponent, MatTree, MatNestedTreeNode, - NgClass, MatTooltip, MatIcon, MatTreeNodeOutlet, diff --git a/projects/pathway-browser/src/app/details/tabs/description-tab/description-tab.component.html b/projects/pathway-browser/src/app/details/tabs/description-tab/description-tab.component.html index c6e386d4..3a7c83b4 100644 --- a/projects/pathway-browser/src/app/details/tabs/description-tab/description-tab.component.html +++ b/projects/pathway-browser/src/app/details/tabs/description-tab/description-tab.component.html @@ -373,7 +373,7 @@

Disease status

{{ author.firstname }} {{ author.surname }} diff --git a/projects/pathway-browser/src/app/details/tabs/description-tab/description-tab.component.ts b/projects/pathway-browser/src/app/details/tabs/description-tab/description-tab.component.ts index ef300ac9..38774438 100644 --- a/projects/pathway-browser/src/app/details/tabs/description-tab/description-tab.component.ts +++ b/projects/pathway-browser/src/app/details/tabs/description-tab/description-tab.component.ts @@ -54,7 +54,7 @@ import { SpeciesService } from '../../../services/species.service'; import { Summation } from '../../../model/graph/summation.model'; import { FigureService } from './figure/figure.service'; type HasModifiedResidue = Relationship.HasModifiedResidue; -import { KeyValuePipe, NgClass, NgTemplateOutlet } from '@angular/common'; +import { KeyValuePipe, NgTemplateOutlet } from '@angular/common'; import { ActivatedRoute, Router, RouterLink } from '@angular/router'; import { SortByTextPipe } from '../../../pipes/sort-by-text.pipe'; import { IncludeRefPipe } from '../../../pipes/include-ref.pipe'; @@ -88,7 +88,6 @@ import type { Event as ReactomeEvent } from '../../../model/graph/event/event.mo standalone: true, imports: [ NgTemplateOutlet, - NgClass, KeyValuePipe, RouterLink, SortByTextPipe, diff --git a/projects/pathway-browser/src/app/diagram/diagram.component.ts b/projects/pathway-browser/src/app/diagram/diagram.component.ts index bb4b5766..531eef6a 100644 --- a/projects/pathway-browser/src/app/diagram/diagram.component.ts +++ b/projects/pathway-browser/src/app/diagram/diagram.component.ts @@ -12,7 +12,6 @@ import { signal, viewChild, inject, - HostListener, untracked, } from '@angular/core'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; @@ -81,6 +80,11 @@ const FIT_PADDING = 100; @UntilDestroy({ checkProperties: true }) @Component({ selector: 'cr-diagram', + host: { + '(window:pointermove)': 'onWindowPointerMove($event)', + '(window:pointerup)': 'endThumbnailDrag()', + '(window:pointercancel)': 'endThumbnailDrag()', + }, templateUrl: './diagram.component.html', styleUrls: ['./diagram.component.scss'], standalone: true, @@ -749,13 +753,10 @@ export class DiagramComponent implements AfterViewInit, OnDestroy { this.panFromThumbnail(event); } - @HostListener('window:pointermove', ['$event']) onWindowPointerMove(event: PointerEvent) { if (this.thumbnailDragging) this.panFromThumbnail(event); } - @HostListener('window:pointerup') - @HostListener('window:pointercancel') endThumbnailDrag() { this.thumbnailDragging = false; } diff --git a/projects/pathway-browser/src/app/diagram/entity-popup/entity-popup.component.ts b/projects/pathway-browser/src/app/diagram/entity-popup/entity-popup.component.ts index d0373aa5..cdc3ca9c 100644 --- a/projects/pathway-browser/src/app/diagram/entity-popup/entity-popup.component.ts +++ b/projects/pathway-browser/src/app/diagram/entity-popup/entity-popup.component.ts @@ -2,7 +2,6 @@ import { HttpClient } from '@angular/common/http'; import { Component, ElementRef, - HostListener, computed, effect, inject, @@ -135,6 +134,11 @@ const TYPE_ORDER: string[] = [ */ @Component({ selector: 'cr-entity-popup', + host: { + '(document:keydown.escape)': 'onEscape()', + '(document:click)': 'onDocumentPointer($event)', + '(document:contextmenu)': 'onDocumentPointer($event)', + }, standalone: true, imports: [MatIcon, MatTooltip, DecimalPipe], templateUrl: './entity-popup.component.html', @@ -528,15 +532,12 @@ export class EntityPopupComponent { this.pinned.update((v) => !v); } - @HostListener('document:keydown.escape') onEscape(): void { if (this.target()) this.dismissed.emit(); } // A right-click elsewhere fires `contextmenu` rather than `click`, so both // are needed to dismiss reliably. - @HostListener('document:click', ['$event']) - @HostListener('document:contextmenu', ['$event']) onDocumentPointer(event: Event): void { if (!this.target() || this.pinned()) return; if (this.host.nativeElement.contains(event.target as Node)) return; diff --git a/projects/pathway-browser/src/app/event-hierarchy/event-hierarchy.component.html b/projects/pathway-browser/src/app/event-hierarchy/event-hierarchy.component.html index cf38ea04..6eb8b978 100644 --- a/projects/pathway-browser/src/app/event-hierarchy/event-hierarchy.component.html +++ b/projects/pathway-browser/src/app/event-hierarchy/event-hierarchy.component.html @@ -53,7 +53,7 @@ [crReveal]="node.stId === revealTarget()" class="leaf-node" (click)="$event.stopPropagation()" - [ngClass]="{ 'has-sibling': hasRootSiblingForLeafNode(node) }" + [class.has-sibling]="hasRootSiblingForLeafNode(node)" [attr.st-id]="node.stId" > @@ -66,7 +66,7 @@
@@ -35,7 +35,7 @@ mat-button [disabled]="hasEHLD()" (click)="getInteractors(INTACT_RESOURCE)" - [ngClass]="{ 'active-button': currentResource().type === ResourceType.STATIC }" + [class.active-button]="currentResource().type === ResourceType.STATIC" > @if (screenIsSmall || !infoTooltip()) { diff --git a/projects/reactome-gsa-form/src/lib/utilities/method-parameter/method-parameter.component.ts b/projects/reactome-gsa-form/src/lib/utilities/method-parameter/method-parameter.component.ts index 5ff0505b..af82e815 100644 --- a/projects/reactome-gsa-form/src/lib/utilities/method-parameter/method-parameter.component.ts +++ b/projects/reactome-gsa-form/src/lib/utilities/method-parameter/method-parameter.component.ts @@ -18,7 +18,7 @@ import { map, Observable } from 'rxjs'; import { UntilDestroy } from '@ngneat/until-destroy'; import { Parameter } from '../../model/parameter.model'; import { LetDirective } from '@ngrx/component'; -import { NgClass } from '@angular/common'; + import { MatTooltip } from '@angular/material/tooltip'; import { MatIcon } from '@angular/material/icon'; import { MatFormField, MatError } from '@angular/material/form-field'; @@ -33,7 +33,6 @@ import { MatInput } from '@angular/material/input'; styleUrls: ['./method-parameter.component.scss'], imports: [ LetDirective, - NgClass, MatTooltip, MatIcon, MatFormField, diff --git a/projects/reactome-gsa-form/src/lib/utilities/scrollable/scrollable.component.html b/projects/reactome-gsa-form/src/lib/utilities/scrollable/scrollable.component.html index 2f6b9b37..6b4a8284 100644 --- a/projects/reactome-gsa-form/src/lib/utilities/scrollable/scrollable.component.html +++ b/projects/reactome-gsa-form/src/lib/utilities/scrollable/scrollable.component.html @@ -2,7 +2,7 @@ #scrollable (scroll)="scrolling()" cdkScrollable - [ngClass]="{ + [class]="{ 'overflow-hide': tourVisible | async, 'tour-active': tour.on, 'small-screen': (height.medium$ | async) !== true, @@ -10,7 +10,7 @@ id="scroll-container-{{ name() }}" class="center-vertical width-hundred relative flex-container align-center justify-center scrollbar fill-height" > -
+
@if (shadows.top()) {
} diff --git a/projects/reactome-gsa-form/src/lib/utilities/scrollable/scrollable.component.ts b/projects/reactome-gsa-form/src/lib/utilities/scrollable/scrollable.component.ts index 3f987bc3..1de95225 100644 --- a/projects/reactome-gsa-form/src/lib/utilities/scrollable/scrollable.component.ts +++ b/projects/reactome-gsa-form/src/lib/utilities/scrollable/scrollable.component.ts @@ -14,7 +14,7 @@ import { map } from 'rxjs'; import { TourUtilsService } from '../../services/tour-utils.service'; import { HeightService } from '../../services/height.service'; import { CdkScrollable } from '@angular/cdk/scrolling'; -import { NgClass, AsyncPipe } from '@angular/common'; +import { AsyncPipe } from '@angular/common'; @UntilDestroy() @Component({ @@ -22,7 +22,7 @@ import { NgClass, AsyncPipe } from '@angular/common'; templateUrl: './scrollable.component.html', styleUrls: ['./scrollable.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush, - imports: [CdkScrollable, NgClass, AsyncPipe], + imports: [CdkScrollable, AsyncPipe], }) export class ScrollableComponent implements AfterViewInit, OnDestroy { private scrollService = inject(ScrollService); diff --git a/projects/reactome-table/src/lib/component/table/table.component.html b/projects/reactome-table/src/lib/component/table/table.component.html index f48dbe61..b4568154 100644 --- a/projects/reactome-table/src/lib/component/table/table.component.html +++ b/projects/reactome-table/src/lib/component/table/table.component.html @@ -44,7 +44,7 @@ [style.height.px]="start.height" [style.width.px]="start.width" [style.z-index]="inputLevel$ | async" - [ngClass]="startClasses$ | async" + [class]="startClasses$ | async" class="flying-rename" /> } @@ -123,7 +123,7 @@ @if (y !== 0) { @for (cell of row; track $index; let x = $index) { @if (x === 0 && settings.showRows) { - +
@if (settings.deleteRow) {