Skip to content
Snippets Groups Projects
Commit b6e64eda authored by Xiao Gui's avatar Xiao Gui
Browse files

chore: clarify docker build script

chore: remove unused imports
chore: unified some directive output var
chore: region inheritance
chore: moved plugin to separate top lvl icon
chore: single/double click logic more robust
bugfix: autcomplete regino list does not refresh unless user starts typing
parent dbff287b
No related branches found
No related tags found
No related merge requests found
Showing
with 310 additions and 213 deletions
FROM node:10 as builder FROM node:10 as builder
ARG BACKEND_URL ARG BACKEND_URL
ENV BACKEND_URL=$BACKEND_URL ENV BACKEND_URL=${BACKEND_URL}
ARG USE_LOGO
ENV USE_LOGO=${USE_LOGO:-hbp}
COPY . /iv COPY . /iv
WORKDIR /iv WORKDIR /iv
ENV VERSION=devNext ARG VERSION
ENV VERSION=${VERSION:-devNext}
RUN apt update && apt upgrade -y && apt install brotli
RUN npm i RUN npm i
RUN npm run build-aot RUN npm run build-aot
...@@ -26,8 +28,6 @@ RUN for f in $(find . -type f); do gzip < $f > $f.gz && brotli < $f > $f.br; don ...@@ -26,8 +28,6 @@ RUN for f in $(find . -type f); do gzip < $f > $f.gz && brotli < $f > $f.br; don
# prod container # prod container
FROM node:10-alpine FROM node:10-alpine
ARG PORT
ENV PORT=$PORT
ENV NODE_ENV=production ENV NODE_ENV=production
RUN apk --no-cache add ca-certificates RUN apk --no-cache add ca-certificates
...@@ -45,6 +45,4 @@ COPY --from=compressor /iv ./public ...@@ -45,6 +45,4 @@ COPY --from=compressor /iv ./public
COPY --from=compressor /iv/res/json ./res COPY --from=compressor /iv/res/json ./res
RUN npm i RUN npm i
EXPOSE $PORT
ENTRYPOINT [ "node", "server.js" ] ENTRYPOINT [ "node", "server.js" ]
\ No newline at end of file
...@@ -6,8 +6,7 @@ import { ...@@ -6,8 +6,7 @@ import {
OnInit, OnInit,
TemplateRef, TemplateRef,
AfterViewInit, AfterViewInit,
Renderer2, Renderer2
ElementRef
} from "@angular/core"; } from "@angular/core";
import { Store, select, ActionsSubject } from "@ngrx/store"; import { Store, select, ActionsSubject } from "@ngrx/store";
import { import {
...@@ -15,10 +14,9 @@ import { ...@@ -15,10 +14,9 @@ import {
isDefined, isDefined,
FETCHED_SPATIAL_DATA, FETCHED_SPATIAL_DATA,
UPDATE_SPATIAL_DATA, UPDATE_SPATIAL_DATA,
safeFilter, safeFilter
CHANGE_NAVIGATION, generateLabelIndexId
} from "../services/stateStore.service"; } from "../services/stateStore.service";
import {Observable, Subscription, combineLatest, interval, merge, of, Observer} from "rxjs"; import {Observable, Subscription, combineLatest, interval, merge, of } from "rxjs";
import { import {
map, map,
filter, filter,
...@@ -26,8 +24,6 @@ import { ...@@ -26,8 +24,6 @@ import {
delay, delay,
concatMap, concatMap,
withLatestFrom, withLatestFrom,
switchMapTo,
takeUntil, take, tap, mapTo
} from "rxjs/operators"; } from "rxjs/operators";
import { AtlasViewerDataService } from "./atlasViewer.dataService.service"; import { AtlasViewerDataService } from "./atlasViewer.dataService.service";
import { WidgetServices } from "./widgetUnit/widgetService.service"; import { WidgetServices } from "./widgetUnit/widgetService.service";
...@@ -43,15 +39,14 @@ import { AGREE_COOKIE, AGREE_KG_TOS, SHOW_KG_TOS, SHOW_BOTTOM_SHEET } from "src/ ...@@ -43,15 +39,14 @@ import { AGREE_COOKIE, AGREE_KG_TOS, SHOW_KG_TOS, SHOW_BOTTOM_SHEET } from "src/
import { TabsetComponent } from "ngx-bootstrap/tabs"; import { TabsetComponent } from "ngx-bootstrap/tabs";
import { LocalFileService } from "src/services/localFile.service"; import { LocalFileService } from "src/services/localFile.service";
import { MatDialog, MatDialogRef, MatSnackBar, MatSnackBarRef, MatBottomSheet, MatBottomSheetRef } from "@angular/material"; import { MatDialog, MatDialogRef, MatSnackBar, MatSnackBarRef, MatBottomSheet, MatBottomSheetRef } from "@angular/material";
import {ADD_TO_REGIONS_SELECTION_WITH_IDS} from "src/services/state/viewerState.store";
import {VIEWER_STATE_ACTION_TYPES} from "src/services/effect/effect";
import {RegionMenuComponent} from "src/ui/regionToolsMenu/regionMenu.component";
/** /**
* TODO * TODO
* check against auxlillary mesh indicies, to only filter out aux indicies * check against auxlillary mesh indicies, to only filter out aux indicies
*/ */
const filterFn = (segment) => typeof segment.segment !== 'string' const filterFn = (segment) => typeof segment.segment !== 'string'
const compareFn = (it, item) => it.name === item.name
@Component({ @Component({
selector: 'atlas-viewer', selector: 'atlas-viewer',
...@@ -65,6 +60,8 @@ const filterFn = (segment) => typeof segment.segment !== 'string' ...@@ -65,6 +60,8 @@ const filterFn = (segment) => typeof segment.segment !== 'string'
}) })
export class AtlasViewer implements OnDestroy, OnInit, AfterViewInit { export class AtlasViewer implements OnDestroy, OnInit, AfterViewInit {
public compareFn = compareFn
@ViewChild('cookieAgreementComponent', {read: TemplateRef}) cookieAgreementComponent : TemplateRef<any> @ViewChild('cookieAgreementComponent', {read: TemplateRef}) cookieAgreementComponent : TemplateRef<any>
@ViewChild('kgToS', {read: TemplateRef}) kgTosComponent: TemplateRef<any> @ViewChild('kgToS', {read: TemplateRef}) kgTosComponent: TemplateRef<any>
......
...@@ -43,12 +43,7 @@ layout-floating-container ...@@ -43,12 +43,7 @@ layout-floating-container
[fixedMouseContextualContainerDirective] [fixedMouseContextualContainerDirective]
{ {
width: 15rem; max-width: 20vw;
}
[fixedMouseContextualContainerDirective] div[body]
{
overflow: hidden;
} }
div[imageContainer] div[imageContainer]
......
...@@ -42,8 +42,8 @@ ...@@ -42,8 +42,8 @@
[currentOnHoverObs$]="iavMouseHoverEl.currentOnHoverObs$" [currentOnHoverObs$]="iavMouseHoverEl.currentOnHoverObs$"
[currentOnHover]="iavMouseHoverEl.currentOnHoverObs$ | async" [currentOnHover]="iavMouseHoverEl.currentOnHoverObs$ | async"
iav-captureClickListenerDirective iav-captureClickListenerDirective
(mouseDownEmitter)="mouseDownNehuba($event)" (iav-captureClickListenerDirective-onMousedown)="mouseDownNehuba($event)"
(mapClicked)="mouseUpNehuba($event)"> (iav-captureClickListenerDirective-onClick)="mouseUpNehuba($event)">
</ui-nehuba-container> </ui-nehuba-container>
<div class="z-index-10 position-absolute pe-none w-100 h-100"> <div class="z-index-10 position-absolute pe-none w-100 h-100">
...@@ -129,23 +129,19 @@ ...@@ -129,23 +129,19 @@
<!-- TODO Potentially implementing plugin contextual info --> <!-- TODO Potentially implementing plugin contextual info -->
</div> </div>
<panel-component class="shadow p-0 m-0" fixedMouseContextualContainerDirective> <div fixedMouseContextualContainerDirective>
<div body class="pe-all" *ngIf="(onhoverSegmentsForFixed$ | async) as onHoverSegments"> <ng-container *ngIf="(onhoverSegmentsForFixed$ | async) as onHoverSegments">
<mat-card *ngIf="onHoverSegments.length > 0 && regionToolsMenuVisible" class="d-flex flex-column p-0"> <ng-container *ngFor="let onHoverRegion of onHoverSegments; let first = first">
<div *ngFor="let onHoverRegion of onHoverSegments; let first = first"
class="border-dark rounded">
<mat-divider *ngIf="!first"></mat-divider>
<region-menu #regionToolsMenu <region-menu
[selectedRegions$]="selectedRegions$" class="pe-all"
[region]="onHoverRegion"> [region]="onHoverRegion"
</region-menu> [isSelected]="selectedRegions$ | async | includes : onHoverRegion : compareFn">
</region-menu>
</div> </ng-container>
</mat-card> </ng-container>
</div> </div>
</panel-component>
</layout-floating-container> </layout-floating-container>
......
...@@ -414,6 +414,11 @@ markdown-dom pre code ...@@ -414,6 +414,11 @@ markdown-dom pre code
overflow-x:hidden!important; overflow-x:hidden!important;
} }
.overflow-y-hidden
{
overflow-y:hidden!important;
}
.muted .muted
{ {
opacity : 0.5!important; opacity : 0.5!important;
...@@ -626,11 +631,6 @@ mat-icon[fontset="far"] ...@@ -626,11 +631,6 @@ mat-icon[fontset="far"]
min-height: 2rem; min-height: 2rem;
} }
.min-h-8
{
min-height: 4rem;
}
.w-30vw .w-30vw
{ {
width: 30vw!important; width: 30vw!important;
......
import { Store } from "@ngrx/store";
import { Input } from "@angular/core";
import { VIEWERSTATE_CONTROLLER_ACTION_TYPES } from "../viewerStateController/viewerState.base";
export class RegionBase{
@Input()
public region: any
@Input()
public isSelected: boolean = false
constructor(private store$: Store<any>){
}
navigateToRegion(){
const { region } = this
this.store$.dispatch({
type: VIEWERSTATE_CONTROLLER_ACTION_TYPES.NAVIGATETO_REGION,
payload: { region }
})
}
toggleRegionSelected(){
const { region } = this
this.store$.dispatch({
type: VIEWERSTATE_CONTROLLER_ACTION_TYPES.TOGGLE_REGION_SELECT,
payload: { region }
})
}
}
\ No newline at end of file
import { Component, Input } from "@angular/core";
import { RegionBase } from '../region.base'
import { Store } from "@ngrx/store";
@Component({
selector: 'region-list-simple-view',
templateUrl: './regionListSimpleView.template.html',
styleUrls: [
'./regionListSimpleView.style.css'
]
})
export class RegionListSimpleViewComponent extends RegionBase{
@Input()
showBrainIcon: boolean = false
@Input()
showDesc: boolean = false
constructor(store$: Store<any>){
super(store$)
}
}
\ No newline at end of file
<!-- selected brain region -->
<div class="flex-grow-1 flex-shrink-1 pt-2 pb-2 d-flex flex-row align-items-center flex-nowrap">
<i *ngIf="showBrainIcon" class="flex-grow-0 flex-shrink-0 fas fa-brain mr-2"></i>
<small class="flex-grow-1 flex-shrink-1 ">
{{ region.name }}
</small>
<button mat-icon-button
*ngIf="region.position"
class="flex-grow-0 flex-shrink-0"
(click)="navigateToRegion()" >
<i *ngIf="isSelected" class="fas fa-map-marked-alt"></i>
</button>
<button mat-icon-button
class="flex-grow-0 flex-shrink-0"
(click)="toggleRegionSelected()" >
<i *ngIf="isSelected" class="fas fa-trash"></i>
<i *ngIf="!isSelected" class="fas fa-plus"></i>
</button>
</div>
<mat-divider *ngIf="showDesc && region.description"></mat-divider>
<small *ngIf="showDesc && region.description">
{{ region.description }}
</small>
\ No newline at end of file
import { Component } from "@angular/core";
import { Store } from "@ngrx/store";
import { RegionBase } from '../region.base'
@Component({
selector: 'region-menu',
templateUrl: './regionMenu.template.html',
styleUrls: ['./regionMenu.style.css']
})
export class RegionMenuComponent extends RegionBase {
constructor(store$: Store<any>) {
super(store$)
}
}
\ No newline at end of file
.regionDescriptionTextClass{ .regionDescriptionTextClass
max-height:100px; {
transition: max-height 0.15s ease-out; max-height:100px;
transition: max-height 0.15s ease-out;
} }
.regionDescriptionTextOpened { .regionDescriptionTextOpened
max-height: 310px; {
transition: max-height 0.25s ease-in; max-height: 310px;
transition: max-height 0.25s ease-in;
} }
[fixedMouseContextualContainerDirective] [fixedMouseContextualContainerDirective]
{ {
width: 15rem; width: 15rem;
} }
[fixedMouseContextualContainerDirective] div[body] [fixedMouseContextualContainerDirective] div[body]
{ {
overflow: hidden; overflow: hidden;
} }
<mat-card>
<mat-card-subtitle>
{{ region.name }}
</mat-card-subtitle>
<mat-card-content>
{{ region.description }}
</mat-card-content>
<mat-card-actions class="d-flex flex-row">
<button mat-button
(click)="toggleRegionSelected()"
[color]="isSelected ? 'primary': 'basic'">
<i class="far" [ngClass]="{'fa-check-square': isSelected, 'fa-square': !isSelected}"></i>
<span>
Selected
</span>
</button>
<button mat-button (click)="navigateToRegion()">
<i class="fas fa-map-marked-alt"></i>
<span>
Navigate
</span>
</button>
</mat-card-actions>
</mat-card>
\ No newline at end of file
import { Component } from '@angular/core'
import { RegionBase } from '../region.base'
import { Store } from '@ngrx/store'
@Component({
selector: 'simple-region',
templateUrl: './regionSimple.template.html',
styleUrls: [
'./regionSimple.style.css'
]
})
export class SimpleRegionComponent extends RegionBase{
constructor(store$: Store<any>){
super(store$)
}
}
\ No newline at end of file
<div class="d-flex flex-row">
<small class="text-truncate flex-shrink-1 flex-grow-1">
{{ region.name }}
</small>
<div class="flex-grow-0 flex-shrink-0 d-flex flex-row">
<!-- if has position defined -->
<button *ngIf="region.position"
iav-stop="click"
(click)="navigateToRegion()"
mat-icon-button>
<i class="fas fa-map-marked-alt"></i>
</button>
<!-- region selected -->
<button mat-icon-button
iav-stop="click"
(click)="toggleRegionSelected()"
[color]="isSelected ? 'primary' : 'basic'">
<i class="far"
[ngClass]="{'fa-check-square': isSelected, 'fa-square': !isSelected}">
</i>
</button>
</div>
</div>
\ No newline at end of file
<mat-action-list> <mat-action-list>
<button mat-list-item <button mat-menu-item
*ngFor="let plugin of pluginServices.fetchedPluginManifests" *ngFor="let plugin of pluginServices.fetchedPluginManifests"
[matTooltip]="plugin.displayName ? plugin.displayName : plugin.name"
(click)="clickPlugin(plugin)"> (click)="clickPlugin(plugin)">
<mat-icon fontSet="fas" fontIcon="fa-cube"></mat-icon>
{{ plugin.displayName ? plugin.displayName : plugin.name }} {{ plugin.displayName ? plugin.displayName : plugin.name }}
</button> </button>
</mat-action-list> </mat-action-list>
import {AfterViewInit, Component, Input, ViewChild} from "@angular/core";
import {Observable} from "rxjs";
import {map, withLatestFrom} from "rxjs/operators";
import {FixedMouseContextualContainerDirective} from "src/util/directives/FixedMouseContextualContainerDirective.directive";
import {VIEWER_STATE_ACTION_TYPES} from "src/services/effect/effect";
import {CHANGE_NAVIGATION, generateLabelIndexId} from "src/services/stateStore.service";
import {ADD_TO_REGIONS_SELECTION_WITH_IDS} from "src/services/state/viewerState.store";
import {Store} from "@ngrx/store";
@Component({
selector: 'region-menu',
templateUrl: './regionMenu.template.html',
styleUrls: ['./regionMenu.style.css']
})
export class RegionMenuComponent {
@Input() selectedRegions$: any
@Input() region: any
regionToolsMenuVisible = false
collapsedRegionDescription = false
constructor(private store$: Store<any>) {}
toggleRegionWithId(ngId, labelIndex, removeFlag: any){
if (removeFlag) {
this.store$.dispatch({
type: VIEWER_STATE_ACTION_TYPES.DESELECT_REGIONS_WITH_ID,
deselecRegionIds: [generateLabelIndexId({ ngId, labelIndex })]
})
} else {
this.store$.dispatch({
type: ADD_TO_REGIONS_SELECTION_WITH_IDS,
selectRegionIds : [generateLabelIndexId({ ngId, labelIndex })]
})
}
}
regionIsSelected(selectedRegions, ngId, labelIndex) {
return selectedRegions.map(sr => generateLabelIndexId({ ngId: sr.ngId, labelIndex: sr.labelIndex })).includes(generateLabelIndexId({ ngId, labelIndex }))
}
navigateTo(position){
this.store$.dispatch({
type: CHANGE_NAVIGATION,
navigation: {
position,
animation: {}
}
})
}
}
\ No newline at end of file
<div class="text-nowrap text-truncate mt-2 ml-2 mr-2 overflow-hidden" [matTooltip]="region.name"
matTooltipShowDelay="1000">{{region.name}}</div>
<!-- ToDo implement it with Descriptions-->
<!-- <div > &lt;!&ndash;*ngIf="!region.description && !region.description.length"&ndash;&gt;-->
<!-- <div class="row m-2 position-relative overflow-hidden"-->
<!-- [class.regionDescriptionTextOpened] = "collapsedRegionDescription"-->
<!-- [class.overflow-y-auto] = "collapsedRegionDescription"-->
<!-- [class.regionDescriptionTextClass] = "!collapsedRegionDescription"-->
<!-- [class.linear-gradient-fade] = "(+regionDescriptionText.scrollHeight > +regionDescriptionText.clientHeight) && !collapsedRegionDescription"-->
<!-- #regionDescriptionText>-->
<!-- {{region.description}}-->
<!-- </div>-->
<!-- <div (click)="collapsedRegionDescription = true"-->
<!-- *ngIf="+regionDescriptionText.scrollHeight > +regionDescriptionText.clientHeight && !collapsedRegionDescription"-->
<!-- class="w-100 d-flex justify-content-center align-items-center mt-n2 cursorPointer"><i-->
<!-- class="fas fa-angle-down m-1"></i> Read More-->
<!-- </div>-->
<!-- <div (click)="collapsedRegionDescription = false"-->
<!-- *ngIf="collapsedRegionDescription"-->
<!-- class="w-100 d-flex justify-content-center align-items-center mt-n2 cursorPointer"><i-->
<!-- class="fas fa-angle-up m-1"></i> Collapse-->
<!-- </div>-->
<!-- </div>-->
<div class="d-flex align-items-center justify-content-between">
<button mat-button
style="font-size: 12px"
class="p-0 w-100"
*ngIf="(selectedRegions$ | async) as selectedRegions"
(click)="toggleRegionWithId(region.ngId, region.labelIndex, regionIsSelected(selectedRegions, region.ngId, region.labelIndex)); regionToolsMenuVisible = false; collapsedRegionDescription = false">
<span class="fa-stack fa-1x">
<i class="fas fa-hand-pointer fa-stack-1x"></i>
<i class="fas fa-slash fa-stack-1x fa-inverse"
*ngIf="regionIsSelected(selectedRegions, region.ngId, region.labelIndex)"></i>
</span>
<span [innerText]="regionIsSelected(selectedRegions, region.ngId, region.labelIndex)? 'Deselect' : 'Select'"></span>
</button>
<button mat-button
style="font-size: 12px"
class="p-0 w-100"
(click)="navigateTo(region.position); regionToolsMenuVisible = false; collapsedRegionDescription = false">
<i class="fas fa-crosshairs"></i> Navigate
</button>
<!-- ToDo Change other buttons font size to 10 if this button is available and remove w-100 classes-->
<!-- <button mat-button-->
<!-- style="font-size: 10px"-->
<!-- class="p-0 mr-1">-->
<!-- <i class="fab fa-connectdevelop"></i> Connectivity-->
<!-- </button>-->
</div>
\ No newline at end of file
...@@ -5,9 +5,9 @@ import { LayerBrowser } from "../layerbrowser/layerbrowser.component"; ...@@ -5,9 +5,9 @@ import { LayerBrowser } from "../layerbrowser/layerbrowser.component";
import { Observable, Subscription } from "rxjs"; import { Observable, Subscription } from "rxjs";
import { Store, select } from "@ngrx/store"; import { Store, select } from "@ngrx/store";
import { map, startWith, scan, filter, mapTo } from "rxjs/operators"; import { map, startWith, scan, filter, mapTo } from "rxjs/operators";
import { VIEWERSTATE_CONTROLLER_ACTION_TYPES } from "../viewerStateController/viewerState.base";
import { trackRegionBy } from '../viewerStateController/regionHierachy/regionHierarchy.component' import { trackRegionBy } from '../viewerStateController/regionHierachy/regionHierarchy.component'
import { AtlasViewerConstantsServices } from "src/atlasViewer/atlasViewer.constantService.service"; import { AtlasViewerConstantsServices } from "src/atlasViewer/atlasViewer.constantService.service";
import { SELECT_REGIONS } from "src/services/stateStore.service";
@Component({ @Component({
selector: 'search-side-nav', selector: 'search-side-nav',
...@@ -93,10 +93,10 @@ export class SearchSideNav implements OnInit, OnDestroy { ...@@ -93,10 +93,10 @@ export class SearchSideNav implements OnInit, OnDestroy {
}) })
} }
removeRegion(region: any){ public deselectAllRegions(){
this.store$.dispatch({ this.store$.dispatch({
type: VIEWERSTATE_CONTROLLER_ACTION_TYPES.SINGLE_CLICK_ON_REGIONHIERARCHY, type: SELECT_REGIONS,
payload: { region } selectRegions: []
}) })
} }
......
...@@ -83,65 +83,85 @@ ...@@ -83,65 +83,85 @@
</div> </div>
<!-- show when regions are selected --> <!-- show when regions are selected -->
<div *ngIf="regionsSelected.length > 0" class="h-100"> <div *ngIf="regionsSelected.length > 0" class="h-100 d-flex flex-column">
<!-- single region --> <!-- header -->
<ng-template [ngIf]="regionsSelected.length === 1" [ngIfElse]="multiRegionTemplate"> <div class="flex-grow-0 flex-shrink-0">
<ng-container *ngTemplateOutlet="header">
<small class="text-muted"> </ng-container>
Region selected </div>
</small>
<!-- body (region descriptor or multi region list) -->
<!-- selected brain region --> <div class="flex-grow-1 flex-shrink-1">
<div class="pt-2 pb-2 d-flex flex-row align-items-center flex-nowrap"> <ng-container *ngTemplateOutlet="body">
<i class="fas fa-brain mr-2"></i> </ng-container>
</div>
<small>
{{ regionsSelected[0].name }}
</small>
<button (click)="removeRegion(regionsSelected[0])" mat-icon-button>
<i class="fas fa-trash"></i>
</button>
</div>
</ng-template>
<!-- multi region -->
<ng-template #multiRegionTemplate>
<div class="h-100 d-flex flex-column">
<small class="d-block text-muted flex-shrink-0 flex-grow-0">
{{ regionsSelected.length }} regions selected
</small>
<cdk-virtual-scroll-viewport
class="flex-grow-1 flex-shrink-1"
itemSize="55"
maxBufferPx="600"
minBufferPx="300">
<div *cdkVirtualFor="let region of regionsSelected; trackBy: trackByFn ; let index = index"
class="region-wrapper d-flex flex-column" >
<!-- divider if index !== 0 -->
<mat-divider class="flex-grow-0 flex-shrink-0" *ngIf="index !== 0"></mat-divider>
<!-- selected brain region -->
<div class="flex-grow-1 flex-shrink-1 pt-2 pb-2 d-flex flex-row align-items-center flex-nowrap">
<i class="flex-grow-0 flex-shrink-0 fas fa-brain mr-2"></i>
<small class="flex-grow-1 flex-shrink-1 ">
{{ region.name }}
</small>
<button mat-icon-button
class="flex-grow-0 flex-shrink-0"
(click)="removeRegion(region)" >
<i class="fas fa-trash"></i>
</button>
</div>
</div>
</cdk-virtual-scroll-viewport>
</div>
</ng-template>
</div> </div>
</div> </div>
<ng-template #header>
<div class="d-flex flex-row align-items-center">
<small *ngIf="regionsSelected.length === 1" class="text-muted position-relative">
Region selected
</small>
<small *ngIf="regionsSelected.length > 1" class="text-muted position-relative">
{{ regionsSelected.length }} regions selected
</small>
<div class="position-relative d-flex align-items-center">
<button mat-icon-button
class="position-absolute"
(click)="deselectAllRegions()"
matTooltip="Clear all regions"
color="primary">
<i class="fas fa-times-circle"></i>
</button>
</div>
</div>
</ng-template>
<ng-template #body>
<!-- single region -->
<ng-template [ngIf]="regionsSelected.length === 1" [ngIfElse]="multiRegionTemplate">
<!-- selected brain region -->
<region-list-simple-view
class="position-relative"
[showBrainIcon]="true"
[region]="regionsSelected[0]"
[isSelected]="true"
[showDesc]="true">
</region-list-simple-view>
</ng-template>
<!-- multi region -->
<ng-template #multiRegionTemplate>
<div class="h-100 d-flex flex-column">
<cdk-virtual-scroll-viewport
class="flex-grow-1 flex-shrink-1"
itemSize="55"
maxBufferPx="600"
minBufferPx="300">
<div *cdkVirtualFor="let region of regionsSelected; trackBy: trackByFn ; let first = first"
class="region-wrapper d-flex flex-column" >
<!-- divider if not first -->
<mat-divider class="flex-grow-0 flex-shrink-0" *ngIf="!first"></mat-divider>
<!-- selected brain region -->
<region-list-simple-view
class="d-block w-100 h-100"
[showBrainIcon]="true"
[region]="region"
[isSelected]="true">
</region-list-simple-view>
</div>
</cdk-virtual-scroll-viewport>
</div>
</ng-template>
</ng-template>
</ng-container> </ng-container>
</ng-template> </ng-template>
\ No newline at end of file
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment