Skip to content

Commit

Permalink
Merge pull request #238 from Complex-Portal/show-loading-on-navigator
Browse files Browse the repository at this point in the history
Show loading spinner while processing the components
  • Loading branch information
jmedinaebi authored Oct 17, 2024
2 parents 8a51426 + 18463c5 commit 06857d8
Show file tree
Hide file tree
Showing 7 changed files with 65 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,12 @@
<div class="buttons">
<cp-complex-navigator-buttons [orthologsGroupsAvailable]="orthologGroupsAvailable"/>
</div>
<cp-table-structure [complexSearch]="complexSearch()"
[navigatorComponents]="navigatorComponents"
(onComplexRemovedFromBasket)="onComplexRemovedFromBasket.emit($event)">
</cp-table-structure>
@if (!!navigatorComponents && navigatorComponents.length > 0) {
<cp-table-structure [complexSearch]="complexSearch()"
[navigatorComponents]="navigatorComponents"
(onComplexRemovedFromBasket)="onComplexRemovedFromBasket.emit($event)">
</cp-table-structure>
} @else {
<cp-progress-spinner></cp-progress-spinner>
}
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,11 @@ export class ComplexNavigatorComponent implements AfterViewInit {
anyChange = output<void>();

numberOfColumns = computed(() => this.complexSearch().elements.length);
navigatorComponentsWithoutGrouping = computed(() => this.createNavigatorComplexes(this.complexSearch().elements, this.components()));
navigatorComponentsWithoutGrouping = computed(() => {
// We set navigatorComponents as an empty list here to show the loading spinner while creating the components and ortholog groups
this.navigatorComponents = [];
return this.createNavigatorComplexes(this.complexSearch().elements, this.components());
});
navigatorComponentsGroupedByOrthologs = computed(() => this.createOrthologGroups(this.navigatorComponentsWithoutGrouping()));

@ViewChild('parent') parent: ElementRef<HTMLDivElement>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
<tr>
<th class="interactorsHeader">
Components
<div class="shadow right" [class.visible]="shadowVisible()"></div>
<div class="shadow right" [class.visible]="shadowLeftVisible()"></div>
</th>
@for (complex of complexes(); track complex.complexAC) {
@for (complex of complexes(); track $index) {
<th [class.predicted]="complex.predictedComplex" class="horizontal">
<div>
<a [routerLink]="['/complex', complex.complexAC]"
Expand Down Expand Up @@ -46,9 +46,9 @@
<thead class="tableHeadOverflow">
<tr class="rotate">
<th class="spaceHolderHeaderOverflow">
<div class="shadow right" [class.visible]="shadowVisible()"></div>
<div class="shadow right" [class.visible]="shadowLeftVisible()"></div>
</th>
@for (complex of complexes(); track complex.complexAC) {
@for (complex of complexes(); track $index) {
<th class="rotate"
[style.transform]="state.transform()"
[style.height.px]="state.displayedHeight()"
Expand Down Expand Up @@ -81,9 +81,9 @@
<tr>
<th class="interactorsHeader overflow">
Components
<div class="shadow right" [class.visible]="shadowVisible()"></div>
<div class="shadow right" [class.visible]="shadowLeftVisible()"></div>
</th>
@for (complex of complexes(); track complex.complexAC) {
@for (complex of complexes(); track $index) {
<th class="iconOrganism" [class.predicted]="complex.predictedComplex">
<div>
@if (isInBasket(complex.complexAC)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,11 @@ export class TableHeaderComponent {
complexes = input.required<Complex[]>();
onComplexRemovedFromBasket = output<string>();

shadowVisible = input<boolean>(false);
shadowLeftVisible = input<boolean>(false);

constructor(private basketService: BasketService, public state: NavigatorStateService) {
}


anyPredictedComplex(): boolean {
return this.complexes().some(c => c.predictedComplex);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
<div class="shadow right" [class.visible]="shadowVisible()"></div>
</td>
<!-- Interactors' stoichiometry -->
@for (complex of navigatorComplexes; track complex.complex.complexAC) {
@for (complex of navigatorComplexes; track $index) {
<td class="intStoich"
[class.predicted]="complex.complex.predictedComplex">
<cp-table-main-interactor
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<div class="complexNavigatorTable">
<div class="header" [style.top.px]="scrollStart()">
<div class="scroller" (scroll)="syncScroll(header, body)" #header>
<cp-table-header [complexes]="sortedComplexes()" [shadowVisible]="shadowLeftVisible"
<cp-table-header [complexes]="sortedComplexes()" [shadowLeftVisible]="shadowLeftVisible"
(onComplexRemovedFromBasket)="onComplexRemovedFromBasket.emit($event)">
</cp-table-header>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,20 @@
import {AfterViewInit, Component, computed, ElementRef, input, output, ViewChild} from '@angular/core';
import {
AfterViewInit,
Component,
computed,
ElementRef,
HostListener,
input,
output,
ViewChild
} from '@angular/core';
import {ComplexSearchResult} from '../../../shared/model/complex-results/complex-search.model';
import {Complex} from '../../../shared/model/complex-results/complex.model';
import * as tf from '@tensorflow/tfjs';
import {groupByPropertyToArray} from '../../../complex-portal-utils';
import {findComponentInComplex} from '../complex-navigator-utils';
import {INavigatorComponent} from './model/navigator-component.model';
import {NavigatorComponentSorting, NavigatorStateService} from '../service/state/complex-navigator-display.service';
import {NavigatorStateService} from '../service/state/complex-navigator-display.service';

@Component({
selector: 'cp-table-structure',
Expand Down Expand Up @@ -34,9 +43,10 @@ export class TableStructureComponent implements AfterViewInit {
}

ngAfterViewInit(): void {
const header = this.headerDiv.nativeElement;
this.setHorizontalShadowVisibility(header);
window.addEventListener('scroll', () => this.shadowTopVisible = header.getBoundingClientRect().top <= this.scrollStart());
if (!!this.headerDiv) {
setTimeout(() => this.setHorizontalShadowVisibility());
window.addEventListener('scroll', () => this.setVerticalShadowVisibility());
}
}

private calculateSimilarity(complex1: Complex, complex2: Complex, navigatorComponents: INavigatorComponent[]) {
Expand Down Expand Up @@ -89,13 +99,14 @@ export class TableStructureComponent implements AfterViewInit {
}));
return this.getSortedIndexFromChainedSimilarity(tf.tensor2d(sm)).map(i => group[i]);
});

// After the complexes have been sorted, we then set the index appearing for all components
// so they are properly sorted later
navigatorComponents.forEach(component => {
component.indexAppearing = sortedComplexesList.findIndex(complex => complex.componentAcs?.has(component.identifier)) || 0;
});
}

// After the complexes have been sorted, we then set the index appearing for all components
// so they are properly sorted later
navigatorComponents.forEach(component => {
component.indexAppearing = sortedComplexesList.findIndex(complex => complex.componentAcs?.has(component.identifier)) || 0;
});
return sortedComplexesList;
}

Expand Down Expand Up @@ -154,12 +165,30 @@ export class TableStructureComponent implements AfterViewInit {
source.scrolling = true;
target.scrollTo({left: source.scrollLeft, behavior: 'instant'});

this.setHorizontalShadowVisibility(source);
this.setHorizontalShadowVisibility();
}

@HostListener('window:resize', ['$event'])
setHorizontalShadowVisibility() {
this.shadowRightVisible = this.isShadowRightVisible();
this.shadowLeftVisible = this.isShadowLeftVisible();
}

private setVerticalShadowVisibility() {
this.shadowTopVisible = this.isShadowTopVisible();
}

private isShadowRightVisible(): boolean {
const header = this.headerDiv.nativeElement;
return header.scrollLeft + header.offsetWidth + this.scrollDetectionMargin <= header.scrollWidth;
}

private isShadowLeftVisible(): boolean {
return this.headerDiv.nativeElement.scrollLeft >= this.scrollDetectionMargin;
}

private setHorizontalShadowVisibility(source: HTMLDivElement) {
this.shadowRightVisible = source.scrollLeft + source.offsetWidth + this.scrollDetectionMargin <= source.scrollWidth;
this.shadowLeftVisible = source.scrollLeft >= this.scrollDetectionMargin;
private isShadowTopVisible(): boolean {
return this.headerDiv.nativeElement.getBoundingClientRect().top <= this.scrollStart();
}
}

Expand Down

0 comments on commit 06857d8

Please sign in to comment.