From a740233dd63f6fc469ef6d9cc81183cee8c6a1d9 Mon Sep 17 00:00:00 2001 From: Xiao Gui <xgui3783@gmail.com> Date: Mon, 6 Mar 2023 11:44:52 +0100 Subject: [PATCH] feat: added desc and external link to rich region chore: updated sapi schema --- src/atlasComponents/sapi/schemaV3.ts | 14 ++++- .../sapiViews/core/region/module.ts | 2 + .../region/region/region.base.directive.ts | 27 +++++++-- .../region/region.features.directive.ts | 12 ---- .../region/rich/region.rich.component.ts | 43 +++++++++++++- .../region/rich/region.rich.template.html | 56 +++---------------- .../readmoreCmp/readmore.component.ts | 2 +- 7 files changed, 86 insertions(+), 70 deletions(-) diff --git a/src/atlasComponents/sapi/schemaV3.ts b/src/atlasComponents/sapi/schemaV3.ts index 5bb8bbb1a..14b6ccf20 100644 --- a/src/atlasComponents/sapi/schemaV3.ts +++ b/src/atlasComponents/sapi/schemaV3.ts @@ -481,11 +481,11 @@ export interface components { /** @Type */ "@type": string /** Index */ - index: (string)[] + index: string[] /** Dtype */ dtype: string /** Columns */ - columns: (string)[] + columns: string[] /** Ndim */ ndim: number /** Data */ @@ -622,6 +622,12 @@ export interface components { */ ontologyIdentifier?: (string)[] } + /** + * ImageTypes + * @description An enumeration. + * @enum {unknown} + */ + ImageTypes: "BlockfaceVolumeOfInterest" | "CellBodyStainedVolumeOfInterest" | "CellbodyStainedSection" | "MRIVolumeOfInterest" | "PLIVolumeOfInterest" | "SegmentedVolumeOfInterest" /** LocationModel */ LocationModel: { /** @Type */ @@ -1189,6 +1195,8 @@ export interface components { })) | undefined } space: components["schemas"]["SiibraAtIdModel"] + /** Datasets */ + datasets: (components["schemas"]["EbrainsDatasetModel"])[] } /** Coordinates */ api__models__openminds__SANDS__v3__atlas__parcellationEntityVersion__Coordinates: { @@ -1739,6 +1747,7 @@ export interface operations { query: { space_id: string bbox?: string + type?: components["schemas"]["ImageTypes"] page?: number size?: number } @@ -1764,6 +1773,7 @@ export interface operations { query: { space_id: string bbox?: string + type?: components["schemas"]["ImageTypes"] } path: { feature_id: string diff --git a/src/atlasComponents/sapiViews/core/region/module.ts b/src/atlasComponents/sapiViews/core/region/module.ts index faee32dfa..9794ca566 100644 --- a/src/atlasComponents/sapiViews/core/region/module.ts +++ b/src/atlasComponents/sapiViews/core/region/module.ts @@ -1,6 +1,7 @@ import { CommonModule } from "@angular/common"; import { NgModule } from "@angular/core"; import { MarkdownModule } from "src/components/markdown"; +import { ReadmoreModule } from "src/components/readmore"; import { SpinnerModule } from "src/components/spinner"; import { FeatureModule } from "src/features"; import { AngularMaterialModule } from "src/sharedModules"; @@ -23,6 +24,7 @@ import { SapiViewsCoreRegionRegionRich } from "./region/rich/region.rich.compone MarkdownModule, StrictLocalModule, FeatureModule, + ReadmoreModule, ], declarations: [ SapiViewsCoreRegionRegionListItem, diff --git a/src/atlasComponents/sapiViews/core/region/region/region.base.directive.ts b/src/atlasComponents/sapiViews/core/region/region/region.base.directive.ts index 3ed4511d0..a2204a080 100644 --- a/src/atlasComponents/sapiViews/core/region/region/region.base.directive.ts +++ b/src/atlasComponents/sapiViews/core/region/region/region.base.directive.ts @@ -1,11 +1,11 @@ -import { Directive, EventEmitter, Input, OnDestroy, Output } from "@angular/core"; +import { Directive, EventEmitter, Input, Output, SimpleChanges } from "@angular/core"; import { SxplrAtlas, SxplrParcellation, SxplrRegion, SxplrTemplate } from "src/atlasComponents/sapi/sxplrTypes"; import { translateV3Entities } from "src/atlasComponents/sapi/translateV3" import { rgbToHsl } from 'common/util' import { SAPI } from "src/atlasComponents/sapi/sapi.service"; -import { BehaviorSubject, Subject } from "rxjs"; +import { BehaviorSubject, combineLatest } from "rxjs"; import { SAPIRegion } from "src/atlasComponents/sapi/core"; -import { switchMap } from "rxjs/operators"; +import { map, switchMap } from "rxjs/operators"; @Directive({ selector: `[sxplr-sapiviews-core-region]`, @@ -28,11 +28,10 @@ export class SapiViewsCoreRegionRegionBase { @Output('sxplr-sapiviews-core-region-navigate-to') onNavigateTo = new EventEmitter<number[]>() - protected region$ = new Subject<SxplrRegion>() + protected region$ = new BehaviorSubject<SxplrRegion>(null) private _region: SxplrRegion @Input('sxplr-sapiviews-core-region-region') set region(val: SxplrRegion) { - this.region$.next(val) if (!this.shouldFetchDetail || !val) { @@ -60,6 +59,24 @@ export class SapiViewsCoreRegionRegionBase { return this._region } + private ATP$ = new BehaviorSubject<{ + atlas: SxplrAtlas + template: SxplrTemplate + parcellation: SxplrParcellation + }>(null) + + protected ATPR$ = combineLatest([ + this.ATP$, + this.region$ + ]).pipe( + map(([ atp, region ]) => ({ ...atp, region })) + ) + + ngOnChanges(sc: SimpleChanges): void { + const { atlas, template, parcellation } = this + this.ATP$.next({ atlas, template, parcellation }) + } + regionRgbString: string = `rgb(200, 200, 200)` regionDarkmode = false // in mm!! diff --git a/src/atlasComponents/sapiViews/core/region/region/region.features.directive.ts b/src/atlasComponents/sapiViews/core/region/region/region.features.directive.ts index b5629e7fa..b7019d477 100644 --- a/src/atlasComponents/sapiViews/core/region/region/region.features.directive.ts +++ b/src/atlasComponents/sapiViews/core/region/region/region.features.directive.ts @@ -12,18 +12,6 @@ import { SapiViewsCoreRegionRegionBase } from "./region.base.directive"; export class SapiViewsCoreRegionRegionalFeatureDirective extends SapiViewsCoreRegionRegionBase implements OnChanges{ - private ATPR$ = new BehaviorSubject<{ - atlas: SxplrAtlas - template: SxplrTemplate - parcellation: SxplrParcellation - region: SxplrRegion - }>(null) - - ngOnChanges(sc: SimpleChanges): void { - const { atlas, template, parcellation, region } = this - this.ATPR$.next({ atlas, template, parcellation, region }) - } - constructor(sapi: SAPI){ super(sapi) } diff --git a/src/atlasComponents/sapiViews/core/region/region/rich/region.rich.component.ts b/src/atlasComponents/sapiViews/core/region/region/rich/region.rich.component.ts index 7b0785d59..9db77ddb3 100644 --- a/src/atlasComponents/sapiViews/core/region/region/rich/region.rich.component.ts +++ b/src/atlasComponents/sapiViews/core/region/region/rich/region.rich.component.ts @@ -1,4 +1,4 @@ -import { Observable, Subject } from "rxjs"; +import { concat, Observable, of, Subject } from "rxjs"; import { Component, EventEmitter, Inject, Output } from "@angular/core"; import { DARKTHEME } from "src/util/injectionTokens"; import { SapiViewsCoreRegionRegionBase } from "../region.base.directive"; @@ -6,6 +6,8 @@ import { ARIA_LABELS, CONST } from 'common/constants' import { Feature } from "src/atlasComponents/sapi/sxplrTypes"; import { SAPI } from "src/atlasComponents/sapi/sapi.service"; import { environment } from "src/environments/environment"; +import { map, shareReplay, switchMap } from "rxjs/operators"; +import { PathReturn } from "src/atlasComponents/sapi/typeV3"; @Component({ selector: 'sxplr-sapiviews-core-region-region-rich', @@ -51,4 +53,43 @@ export class SapiViewsCoreRegionRegionRich extends SapiViewsCoreRegionRegionBase activePanelTitles$: Observable<string[]> = new Subject() + private regionalStatisticalMaps$ = this.ATPR$.pipe( + switchMap(({ parcellation, template, region }) => + concat( + of([] as PathReturn<"/map">["volumes"]), + this.sapi.getMap(parcellation.id, template.id, "STATISTICAL").pipe( + map(v => { + const mapIndices = v.indices[region.name] + return mapIndices.map(mapIdx => v.volumes[mapIdx.volume]) + }) + ) + ) + ), + shareReplay(1) + ) + + public dois$ = this.regionalStatisticalMaps$.pipe( + map(sms => { + const returnUrls: string[] = [] + for (const sm of sms) { + for (const ds of sm.datasets) { + for (const url of ds.urls) { + returnUrls.push(url.url) + } + + } + } + return returnUrls + }) + ) + + public desc$ = this.regionalStatisticalMaps$.pipe( + map(sm => { + for (const ds of (sm?.[0]?.datasets) || []) { + if (ds.description) { + return ds.description + } + } + }), + ) } diff --git a/src/atlasComponents/sapiViews/core/region/region/rich/region.rich.template.html b/src/atlasComponents/sapiViews/core/region/region/rich/region.rich.template.html index a8814bb6a..1b617e21e 100644 --- a/src/atlasComponents/sapiViews/core/region/region/rich/region.rich.template.html +++ b/src/atlasComponents/sapiViews/core/region/region/rich/region.rich.template.html @@ -40,7 +40,7 @@ </button> <!-- explore doi --> - <a *ngFor="let doi of dois" + <a *ngFor="let doi of dois$ | async" [href]="doi | parseDoi" sxplr-hide-when-local [matTooltip]="ARIA_LABELS.EXPLORE_DATASET_IN_KG" @@ -54,32 +54,12 @@ </div> </mat-card> - - <!-- kg regional features list --> - <ng-template #kgRegionalFeatureList> - <div sxplr-sapiviews-core-region-regional-feature - [sxplr-sapiviews-core-region-atlas]="atlas" - [sxplr-sapiviews-core-region-template]="template" - [sxplr-sapiviews-core-region-parcellation]="parcellation" - [sxplr-sapiviews-core-region-region]="region" - #rfDir="sapiViewsRegionalFeature" - class="feature-list-container" - > - - <spinner-cmp *ngIf="rfDir.busy$ | async"></spinner-cmp> - - <!-- <sxplr-sapiviews-features-entry-list-item - *ngFor="let feat of rfDir.listOfFeatures$ | async | orderFilterFeatures" - [sxplr-sapiviews-features-entry-list-item-feature]="feat" - (click)="handleRegionalFeatureClicked(feat)"> - </sxplr-sapiviews-features-entry-list-item> --> - </div> - - </ng-template> - - <ng-template #regionDesc> - <markdown-dom class="sxplr-muted" [markdown]="region?.desc || 'No description provided.'"> - </markdown-dom> + <!-- desc --> + <ng-template [ngIf]="(desc$ | async) || region.desc" let-desc> + <readmore-component> + <markdown-dom class="sxplr-m-2 sxplr-muted" [markdown]="desc"> + </markdown-dom> + </readmore-component> </ng-template> <sxplr-feature-entry @@ -90,31 +70,9 @@ <mat-accordion class="d-block mt-2"> - <!-- desc --> - <ng-container *ngTemplateOutlet="ngMatAccordionTmpl; context: { - title: CONST.DESCRIPTION, - iconClass: 'fas fa-info', - content: regionDesc, - desc: '', - iconTooltip: 'Description', - iavNgIf: !!region?.desc - }"> - - </ng-container> - <!-- only show dynamic data when strict-local is set to false --> <ng-template [ngIf]="!environment.STRICT_LOCAL"> - <!-- feature list --> - <!-- <ng-container *ngTemplateOutlet="ngMatAccordionTmpl; context: { - title: CONST.REGIONAL_FEATURES, - iconClass: 'fas fa-database', - content: kgRegionalFeatureList, - desc: '', - iconTooltip: 'Regional Features', - iavNgIf: true - }"> - </ng-container> --> <!-- connectivity --> <ng-template #sxplrSapiviewsFeaturesConnectivityBrowser> diff --git a/src/components/readmore/readmoreCmp/readmore.component.ts b/src/components/readmore/readmoreCmp/readmore.component.ts index 914f7c092..2d460afb8 100644 --- a/src/components/readmore/readmoreCmp/readmore.component.ts +++ b/src/components/readmore/readmoreCmp/readmore.component.ts @@ -11,7 +11,7 @@ import { readmoreAnimations } from "./readmore.animations"; }) export class ReadmoreComponent implements OnChanges, AfterContentChecked { - @Input() public collapsedHeight: number = 45 + @Input() public collapsedHeight: number = 85 @Input() public show: boolean = false @Input() public animationLength: number = 180 @ViewChild('contentContainer', { read: ElementRef, static: true }) public contentContainer: ElementRef -- GitLab