diff --git a/src/atlasComponents/sapiViews/core/region/module.ts b/src/atlasComponents/sapiViews/core/region/module.ts index 6e9140d0b5968e384f4f08907246dd6b9a621a30..ff07e4b2565b1a0270d8e1b635db8f3b9995d155 100644 --- a/src/atlasComponents/sapiViews/core/region/module.ts +++ b/src/atlasComponents/sapiViews/core/region/module.ts @@ -10,6 +10,11 @@ import { SapiViewsUtilModule } from "../../util/module"; import { SapiViewsCoreRegionRegionListItem } from "./region/listItem/region.listItem.component"; import { SapiViewsCoreRegionRegionBase } from "./region/region.base.directive"; import { SapiViewsCoreRegionRegionRich } from "./region/rich/region.rich.component"; +import { MatTabsModule } from "@angular/material/tabs"; +import { ExperimentalModule } from "src/experimental/experimental.module"; +import { MatListModule } from "@angular/material/list"; +import { DialogModule } from "src/ui/dialogInfo"; +import { SapiViewsCoreParcellationModule } from "../parcellation"; @NgModule({ imports: [ @@ -21,6 +26,11 @@ import { SapiViewsCoreRegionRegionRich } from "./region/rich/region.rich.compone StrictLocalModule, FeatureModule, ReadmoreModule, + MatTabsModule, + ExperimentalModule, + MatListModule, + DialogModule, + SapiViewsCoreParcellationModule, ], declarations: [ SapiViewsCoreRegionRegionListItem, 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 cc72755c1f242e656b9c092e87026e4ab2c1ed66..71cf69e3738177cbba79df9316926f60d872825a 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 @@ -15,10 +15,20 @@ <ng-template [ngTemplateOutlet]="headerTmpl"></ng-template> + <ng-template sxplrExperimentalFlag [experimental]="true" #subtitleExpm="sxplrExperimentalFlag" [ngIf]="subtitleExpm.show$ | async"> + <mat-card-subtitle> + <span class="muted-text"> + Brain region + </span> + </mat-card-subtitle> + </ng-template> + <mat-card-title class="sxplr-custom-cmp text"> {{ region.name }} </mat-card-title> + + <ng-template sxplrExperimentalFlag [deprecated]="true" #subtitleDep="sxplrExperimentalFlag" [ngIf]="subtitleDep.show$ | async"> <mat-card-subtitle> {{ parcellation.name }} </mat-card-subtitle> @@ -54,19 +64,21 @@ </a> </mat-card-subtitle> - + </ng-template> </div> </mat-card> <!-- desc --> + <ng-template sxplrExperimentalFlag [deprecated]="true" #subtitleDep="sxplrExperimentalFlag" [ngIf]="subtitleDep.show$ | async"> <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> + </ng-template> - + <ng-template sxplrExperimentalFlag [deprecated]="true" #headerDep="sxplrExperimentalFlag" [ngIf]="headerDep.show$ | async"> <!-- header for regional feature --> <mat-card> <mat-card-header> @@ -86,4 +98,76 @@ [region]="region" #featureEntryCmp="featureEntryCmp"> </sxplr-feature-entry> + </ng-template> + + <ng-template sxplrExperimentalFlag [experimental]="true" #tabExpmpt="sxplrExperimentalFlag" [ngIf]="tabExpmpt.show$ | async"> + <mat-tab-group> + + <!-- Overview --> + <mat-tab label="Overview"> + + <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> + + <mat-action-list class="overview-container"> + + <button + mat-list-item + sxplr-dialog + [sxplr-dialog-size]="null" + [sxplr-dialog-data]="{ + title: parcellation.name, + descMd: parcellation.desc, + actions: parcellation | parcellationDoiPipe + }"> + <mat-icon mat-list-icon fontSet="fas" fontIcon="fa-brain"></mat-icon> + <div mat-line class="overview-content">{{ parcellation.name }}</div> + </button> + + <ng-template [ngIf]="regionPosition"> + <button mat-list-item (click)="navigateTo(regionPosition)"> + <mat-icon mat-list-icon fontSet="fas" fontIcon="fa-map-marker"></mat-icon> + <div mat-line class="overview-content">{{ regionPosition | numbers | addUnitAndJoin : 'mm' }}</div> + </button> + </ng-template> + + <ng-template ngFor [ngForOf]="dois$ | async" let-doi> + <a mat-list-item [href]="doi" target="_blank"> + <mat-icon mat-list-icon fontSet="fas" fontIcon="fa-external-link-alt"></mat-icon> + <div mat-line>{{ doi }}</div> + </a> + </ng-template> + </mat-action-list> + </mat-tab> + + <!-- FeatureTab --> + <mat-tab> + <ng-template mat-tab-label> + <span> + Features + </span> + <ng-template [ngIf]="featureEntryCmp.totals$ | async" let-total> + <span class="text-muted"> + ({{ total }}) + </span> + </ng-template> + <ng-template [ngIf]="featureEntryCmp.busyTallying$ | async"> + <spinner-cmp></spinner-cmp> + </ng-template> + </ng-template> + + <sxplr-feature-entry + [template]="template" + [parcellation]="parcellation" + [region]="region" + #featureEntryCmp="featureEntryCmp"> + </sxplr-feature-entry> + </mat-tab> + </mat-tab-group> + </ng-template> + </ng-template> diff --git a/src/extra_styles.css b/src/extra_styles.css index 38120840830934317ea6c65d369467f99202f362..19b81c9407afc0482478b0a522ef473c0b381964 100644 --- a/src/extra_styles.css +++ b/src/extra_styles.css @@ -902,3 +902,13 @@ how-to-cite img { place-self: center; } + +.overview-container +{ + margin-top: 1rem; +} + +.overview-content +{ + white-space: normal!important; +} diff --git a/src/features/entry/entry.component.ts b/src/features/entry/entry.component.ts index e4cfbe75e126083681838c1fe815bca654737345..d81efe9ce63c1740c499fbd295b7edff767fcb0a 100644 --- a/src/features/entry/entry.component.ts +++ b/src/features/entry/entry.component.ts @@ -1,6 +1,6 @@ import { AfterViewInit, Component, OnDestroy, QueryList, ViewChildren } from '@angular/core'; import { select, Store } from '@ngrx/store'; -import { debounceTime, distinctUntilChanged, map, scan, shareReplay, switchMap, withLatestFrom } from 'rxjs/operators'; +import { debounceTime, distinctUntilChanged, map, scan, shareReplay, switchMap, take, withLatestFrom } from 'rxjs/operators'; import { IDS, SAPI } from 'src/atlasComponents/sapi'; import { Feature } from 'src/atlasComponents/sapi/sxplrTypes'; import { FeatureBase } from '../base'; @@ -73,7 +73,9 @@ export class EntryComponent extends FeatureBase implements AfterViewInit, OnDest switchMap(arr => concat( of(true), forkJoin( - arr.map(dir => dir.total$) + arr.map(dir => dir.total$.pipe( + take(1) + )) ).pipe( map(() => false) ) diff --git a/src/features/feature-view/feature-view.component.html b/src/features/feature-view/feature-view.component.html index f213457ecc229d9aa0db1712d3f949c3b11e4ecb..40a8ed6373e965aaa39db9e84dd7701fa111e2d9 100644 --- a/src/features/feature-view/feature-view.component.html +++ b/src/features/feature-view/feature-view.component.html @@ -12,13 +12,31 @@ <mat-card *ngIf="feature" class="mat-elevation-z4 sxplr-z-4"> + + <ng-template [ngTemplateOutlet]="headerTmpl"></ng-template> + + <ng-template sxplrExperimentalFlag #subtitleExmpt="sxplrExperimentalFlag" [experimental]="true" [ngIf]="subtitleExmpt.show$ | async"> + <mat-card-subtitle> + <ng-template [ngIf]="feature.category"> + <span class="sxplr-m-a sxplr-pr-1"> + <ng-template [ngIf]="feature.category !== 'Unknown category'" [ngIfElse]="fallbackTmpl"> + {{ feature.category }} feature + </ng-template> + <ng-template #fallbackTmpl> + Other feature + </ng-template> + </span> + </ng-template> + </mat-card-subtitle> + </ng-template> + <mat-card-title> - <ng-template [ngTemplateOutlet]="headerTmpl"></ng-template> <div class="feature-title"> {{ feature.name }} </div> </mat-card-title> + <ng-template sxplrExperimentalFlag [deprecated]="true" [ngIf]="subtitleDep.show$ | async" #subtitleDep="sxplrExperimentalFlag"> <mat-card-subtitle class="sxplr-d-inline-flex sxplr-align-items-stretch"> <ng-template [ngIf]="feature.category"> <mat-icon class="sxplr-m-a" fontSet="fas" fontIcon="fa-database"></mat-icon> @@ -27,7 +45,7 @@ {{ feature.category }} </ng-template> <ng-template #fallbackTmpl> - Generic + Other </ng-template> </span> </ng-template> @@ -82,8 +100,117 @@ </ng-template> </mat-card-subtitle> + </ng-template> + </mat-card> +<ng-template sxplrExperimentalFlag #newPanelExpmt="sxplrExperimentalFlag" [experimental]="true" [ngIf]="newPanelExpmt.show$ | async"> +<mat-tab-group> + <mat-tab label="Overview"> + <readmore-component> + <markdown-dom class="sxplr-m-2 sxplr-muted" [markdown]="feature.desc"> + </markdown-dom> + </readmore-component> + + <mat-action-list class="overview-container"> + + <ng-template [ngIf]="warnings$ | async" let-warnings> + <ng-template ngFor [ngForOf]="warnings" let-warning> + <button mat-list-item> + <mat-icon mat-list-icon fontSet="fas" fontIcon="fa-map-marker"></mat-icon> + <div mat-line class="overview-content">{{ warning }}</div> + </button> + </ng-template> + </ng-template> + + <!-- doi --> + <ng-template ngFor [ngForOf]="feature.link" let-url> + <a [href]="url.href" mat-list-item target="_blank"> + <mat-icon mat-list-icon fontSet="fas" fontIcon="fa-external-link-alt"></mat-icon> + <div mat-line>{{ url.text || url.href }}</div> + </a> + </ng-template> + + <!-- additional links --> + <ng-template ngFor [ngForOf]="additionalLinks$ | async" let-url> + <a [href]="url" mat-list-item target="_blank"> + <mat-icon mat-list-icon fontSet="fas" fontIcon="fa-external-link-alt"></mat-icon> + <div mat-line>{{ url }}</div> + </a> + </ng-template> + + </mat-action-list> + </mat-tab> + + <mat-tab *ngIf="busy$ | async"> + <ng-template matTabLabel=""> + <spinner-cmp></spinner-cmp> + </ng-template> + </mat-tab> + + <!-- radar special view --> + <ng-template [ngIf]="polar$ | async" let-polar> + <mat-tab label="Preview"> + <kg-dataset-dumb-radar + [radar]="polar" + [attr.kg-ds-prv-darkmode]="darktheme$ | async"> + </kg-dataset-dumb-radar> + </mat-tab> + </ng-template> + + <!-- line special view --> + <ng-template [ngIf]="linear$ | async" let-linear> + <mat-tab label="Preview"> + <kg-dataset-dumb-line + [profileBs]="linear" + [attr.kg-ds-prv-darkmode]="darktheme$ | async"> + </kg-dataset-dumb-line> + </mat-tab> + </ng-template> + + <!-- tabular special view --> + <!-- suppress tabuular view if linear or polar is visible --> + <ng-template [ngIf]="!(linear$ | async) && !(polar$ | async)"> + <ng-template [ngIf]="tabular$ | async" let-tabular> + + <mat-tab label="Preview"> + <table class="feature-detail" mat-table [dataSource]="tabular | transformPdToDs"> + + <ng-container *ngFor="let column of columns$ | async" + [matColumnDef]="column"> + <th mat-header-cell *matHeaderCellDef> + {{ column }} + </th> + <td mat-cell *matCellDef="let element"> + {{ element[column] }} + </td> + </ng-container> + + <tr mat-header-row *matHeaderRowDef="columns$ | async"></tr> + <tr mat-row *matRowDef="let row; columns: columns$ | async;"></tr> + </table> + </mat-tab> + </ng-template> + </ng-template> + + <!-- voi special view --> + <ng-template [ngIf]="voi$ | async" let-voi> + <mat-tab label="Volume Control"> + <ng-layer-ctl + [ng-layer-ctl-name]="voi.ngVolume.url" + [ng-layer-ctl-src]="voi.ngVolume.url" + [ng-layer-ctl-transform]="voi.ngVolume.transform" + [ng-layer-ctl-info]="voi.ngVolume.info" + [ng-layer-ctl-opacity]="1.0" + [ng-layer-ctrl-show]="true"> + </ng-layer-ctl> + </mat-tab> + </ng-template> + +</mat-tab-group> +</ng-template> + +<ng-template sxplrExperimentalFlag #oldpanelDep="sxplrExperimentalFlag" [deprecated]="true" [ngIf]="oldpanelDep.show$ | async"> <mat-card *ngIf="feature" class="sxplr-z-0"> <mat-card-content> <!-- TODO fix feature typing! with proper translate fn --> @@ -142,3 +269,4 @@ [ng-layer-ctrl-show]="true"> </ng-layer-ctl> </ng-template> +</ng-template> \ No newline at end of file diff --git a/src/features/module.ts b/src/features/module.ts index 5cda100c6b993c838076043348603b31365ba3e0..72a2cd93c51915508149421645586af6f5fed638 100644 --- a/src/features/module.ts +++ b/src/features/module.ts @@ -26,6 +26,9 @@ import { ListDirective } from "./list/list.directive"; import { MatChipsModule } from "@angular/material/chips"; import { FeatureFilterDirective } from "./feature.filter.directive"; import { GroupFeaturesToName } from "./grpFeatToName.pipe"; +import { ExperimentalModule } from "src/experimental/experimental.module"; +import { MatTabsModule } from "@angular/material/tabs"; +import { ReadmoreModule } from "src/components/readmore"; @NgModule({ imports: [ @@ -46,6 +49,9 @@ import { GroupFeaturesToName } from "./grpFeatToName.pipe"; MatTableModule, NgLayerCtlModule, MatChipsModule, + ExperimentalModule, + MatTabsModule, + ReadmoreModule, ], declarations: [ EntryComponent,