diff --git a/docs/releases/v2.13.2.md b/docs/releases/v2.13.2.md index d0fe9ede6a3a32e3400acf75ac3f3ddb41d4db6b..0c9d3d19b4fa71b02a7999c2e81cfea408483c8e 100644 --- a/docs/releases/v2.13.2.md +++ b/docs/releases/v2.13.2.md @@ -1,5 +1,9 @@ # v2.13.2 +## Features + +- added visual display of errors relating to siibra-api + ## Bugfixes - fixed displaying annotation in `saneurl` diff --git a/src/atlasComponents/sapi/sapi.service.ts b/src/atlasComponents/sapi/sapi.service.ts index 7cd9209fb6299e521aebf324cc1e55265efbbfda..52e4f79f886e207176e3146ea3839674cc36a051 100644 --- a/src/atlasComponents/sapi/sapi.service.ts +++ b/src/atlasComponents/sapi/sapi.service.ts @@ -5,7 +5,7 @@ import { getExportNehuba, noop } from "src/util/fn"; import { MatSnackBar } from "@angular/material/snack-bar"; import { AtlasWorkerService } from "src/atlasViewer/atlasViewer.workerService.service"; import { EnumColorMapName } from "src/util/colorMaps"; -import { forkJoin, from, NEVER, Observable, of, throwError } from "rxjs"; +import { BehaviorSubject, forkJoin, from, NEVER, Observable, of, throwError } from "rxjs"; import { environment } from "src/environments/environment" import { translateV3Entities @@ -110,15 +110,6 @@ export class SAPI{ BS_ENDPOINT_CACHED_VALUE = new Observable<string>(obs => { (async () => { - const backupPr = new Promise<string>(rs => { - for (const endpt of backupEndpoints) { - SAPI.VerifyEndpoint(endpt) - .then(flag => { - if (flag) rs(endpt) - }) - .catch(noop) - } - }) try { const url = await Promise.race([ SAPI.VerifyEndpoint(mainEndpoint), @@ -129,12 +120,23 @@ export class SAPI{ try { const url = await Promise.race([ - backupPr, + /** + * find the first endpoint of the backup endpoints + */ + new Promise<string>(rs => { + for (const endpt of backupEndpoints) { + SAPI.VerifyEndpoint(endpt) + .then(flag => { + if (flag) rs(endpt) + }) + .catch(noop) + } + }), new Promise<string>((_, rj) => setTimeout(() => rj(`5s timeout`), 5000)) ]) obs.next(url) } catch (e) { - SAPI.ErrorMessage = `No usabe mirror found` + SAPI.ErrorMessage = `No usabe siibra-api endpoints found. Tried: ${mainEndpoint}, ${backupEndpoints.join(",")}` } } finally { obs.complete() @@ -147,7 +149,10 @@ export class SAPI{ return BS_ENDPOINT_CACHED_VALUE } - static ErrorMessage = null + static ErrorMessage$ = new BehaviorSubject<string>(null) + static set ErrorMessage(val: string){ + this.ErrorMessage$.next(val) + } getParcRegions(parcId: string) { const param = { @@ -593,9 +598,6 @@ export class SAPI{ private snackbar: MatSnackBar, private workerSvc: AtlasWorkerService, ){ - if (SAPI.ErrorMessage) { - this.snackbar.open(SAPI.ErrorMessage, 'Dismiss', { duration: 5000 }) - } } /** diff --git a/src/atlasViewer/atlasViewer.component.ts b/src/atlasViewer/atlasViewer.component.ts index c127379a8ee112b36de6e104eaa8da3c62eb04b2..1fc4e3a606a4ae87698701fd2e0e60fb38f6ae75 100644 --- a/src/atlasViewer/atlasViewer.component.ts +++ b/src/atlasViewer/atlasViewer.component.ts @@ -27,6 +27,7 @@ import { DOCUMENT } from "@angular/common"; import { userPreference } from "src/state" import { DARKTHEME } from "src/util/injectionTokens"; import { EnumQuickTourSeverity } from "src/ui/quickTour/constrants"; +import { SAPI } from "src/atlasComponents/sapi"; @Component({ @@ -44,6 +45,8 @@ export class AtlasViewer implements OnDestroy, OnInit, AfterViewInit { public CONST = CONST + sapiError$ = SAPI.ErrorMessage$ + @ViewChild('cookieAgreementComponent', {read: TemplateRef}) public cookieAgreementComponent: TemplateRef<any> @ViewChild(MouseHoverDirective) private mouseOverNehuba: MouseHoverDirective diff --git a/src/atlasViewer/atlasViewer.template.html b/src/atlasViewer/atlasViewer.template.html index 864976bc6901450056408aecc096df0c0254e7ce..cade469e7db2cd56594c21a6b6aa06f069722f48 100644 --- a/src/atlasViewer/atlasViewer.template.html +++ b/src/atlasViewer/atlasViewer.template.html @@ -1,7 +1,10 @@ <ng-container *ngIf="meetsRequirement; else doesNotMeetReqTemplate"> - <ng-container *ngTemplateOutlet="viewerBody"> - </ng-container> + <ng-template [ngIf]="sapiError$ | async" let-data [ngIfElse]="viewerBody"> + <ng-template [ngTemplateOutlet]="errorTmpl" [ngTemplateOutletContext]="{ message: data }"> + </ng-template> + </ng-template> + </ng-container> <!-- cookie --> @@ -56,3 +59,8 @@ <ng-template #emptyArrowTmpl> </ng-template> + +<ng-template #errorTmpl let-message="message"> + <not-supported-component [errorString]="message"> + </not-supported-component> +</ng-template> diff --git a/src/notSupportedCmp/notSupported.component.ts b/src/notSupportedCmp/notSupported.component.ts index 6562a46a650f2c2c8b01caa6b1fc174d7251157f..f17b70e3fa288c434c047c76efc2f201e621105b 100644 --- a/src/notSupportedCmp/notSupported.component.ts +++ b/src/notSupportedCmp/notSupported.component.ts @@ -1,4 +1,4 @@ -import { Component } from "@angular/core"; +import { Component, Input } from "@angular/core"; import { interval, merge, of } from "rxjs"; import { map } from "rxjs/operators"; import { UNSUPPORTED_INTERVAL, UNSUPPORTED_PREVIEW } from "src/util/constants"; @@ -13,6 +13,14 @@ import { MIN_REQ_EXPLAINER } from 'src/util/constants' }) export class NotSupportedCmp{ + + /** + * default error is webgl + * custom error message can be inputed to override default message + */ + @Input() + errorString="webgl" + public unsupportedPreviews: any[] = UNSUPPORTED_PREVIEW public unsupportedPreviewIdx: number = 0 public MIN_REQ_EXPLAINER = MIN_REQ_EXPLAINER diff --git a/src/notSupportedCmp/notSupported.template.html b/src/notSupportedCmp/notSupported.template.html index db0d8020b24ace07d3e798df155ba118074aaecb..c46e667a4c2d8b8a40496cccc1a36f2e22afdad1 100644 --- a/src/notSupportedCmp/notSupported.template.html +++ b/src/notSupportedCmp/notSupported.template.html @@ -1,5 +1,5 @@ <div class="jumbotron bg-light text-center mb-0"> - <div> + <div *ngIf="errorString === 'webgl' else otherErrorTmpl"> <h1 class="mb-3"> <i class="fas fa-exclamation-triangle"></i> Unsupported browser detected </h1> @@ -21,6 +21,12 @@ </div> </div> + + <ng-template #otherErrorTmpl> + <h1 class="mb-3"> + <i class="fas fa-exclamation-triangle"></i> {{ errorString }} + </h1> + </ng-template> </div> <ng-container *ngFor="let preview of unsupportedPreviews; let idx = index"> <div [hidden]="idx !== unsupportedPreviewIdx" class="text-center mb-3 image-container" @@ -31,4 +37,4 @@ </div> </div> </div> -</ng-container> \ No newline at end of file +</ng-container>