Newer
Older
<div class="position-absolute w-100 h-100">
<ng-container *ngTemplateOutlet="viewerTmpl">
</ng-container>
</div>
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
<!-- master draw container -->
<mat-drawer-container
*ngIf="viewerLoaded"
iav-switch
[iav-switch-state]="!(onlyShowMiniTray$ | async)"
#showFullSidenavSwitch="iavSwitch"
class="position-absolute w-100 h-100 mat-drawer-content-overflow-visible invisible"
[hasBackdrop]="false">
<!-- master drawer -->
<mat-drawer
mode="side"
#drawer="matDrawer"
[opened]="!(onlyShowMiniTray$ | async)"
[@openClose]="showFullSidenavSwitch && (showFullSidenavSwitch.switchState$ | async) ? 'open' : 'closed'"
(@openClose.start)="$event.toState === 'open' && drawer.open()"
(@openClose.done)="$event.toState === 'closed' && drawer.close()"
[autoFocus]="false"
[disableClose]="true"
class="iv-custom-comp darker-bg p-0 pe-all col-10 col-sm-10 col-md-5 col-lg-4 col-xl-3 col-xxl-2 z-index-10">
<!-- entry template -->
<ng-template [ngIf]="viewerMode$ | async" let-mode [ngIfElse]="regularTmpl">
<ng-template [ngTemplateOutlet]="alternateModeDrawerTmpl"
[ngTemplateOutletContext]="{
mode: mode
}"></ng-template>
</ng-template>
<!-- regular mode -->
<ng-template #regularTmpl>
<ng-template
[ngTemplateOutlet]="regularModeDrawerTmpl"
[ngTemplateOutletContext]="{
drawer: drawer,
showFullSidenavSwitch: showFullSidenavSwitch
}">
</ng-template>
</ng-template>
</mat-drawer>
<!-- master content -->
<mat-drawer-content class="visible pe-none position-relative">
<iav-layout-fourcorners>
<!-- top left -->
<div iavLayoutFourCornersTopLeft class="ws-no-wrap">
<!-- special mode -->
<ng-template [ngIf]="viewerMode$ | async" let-mode [ngIfElse]="defaultTopLeftTmpl">
<ng-template [ngTemplateOutlet]="specialModeTopLeftTmpl"
[ngTemplateOutletContext]="{
mode: mode,
toggleMatDrawer: drawer.toggle.bind(drawer)
}">
</ng-template>
<!-- default mode top left tmpl -->
<ng-template #defaultTopLeftTmpl>
<ng-template [ngTemplateOutlet]="defaultMainContentTopLeft"
[ngTemplateOutletContext]="{
isOpen: drawer.opened,
drawer: drawer,
showFullSidenavSwitch: showFullSidenavSwitch
}">
</ng-template>
</ng-template>
</div>
<!-- top right -->
<div iavLayoutFourCornersTopRight class="ws-no-wrap">
<!-- exit special mode -->
<ng-template [ngIf]="viewerMode$ | async" let-mode [ngIfElse]="defaultTopRightTmpl">
<ng-template [ngTemplateOutlet]="specialTopRightTmpl"
[ngTemplateOutletContext]="{
mode: mode
</ng-template>
</ng-template>
<!-- default mode top right tmpl -->
<ng-template #defaultTopRightTmpl>
<ng-template [ngTemplateOutlet]="minDefaultMainContentTopRight">
</ng-template>
</ng-template>
</div>
<!-- bottom left -->
<div iavLayoutFourCornersBottomLeft class="ws-no-wrap d-inline-flex w-100vw pe-none align-items-center mb-4">
<!-- special bottom left -->
<ng-template [ngIf]="viewerMode$ | async" let-mode [ngIfElse]="localBottomLeftTmpl"></ng-template>
<!-- default mode bottom left tmpl -->
<ng-template #localBottomLeftTmpl>
<!-- not the most elegant, but it's a hard problem to solve -->
<!-- on the one hand, showFullSidenavSwitch can be of two states -->
<!-- and drawer.opened can be of two states -->
<ng-template [ngTemplateOutlet]="bottomLeftTmpl"
[ngTemplateOutletContext]="{
showFullSideNav: (showFullSidenavSwitch.switchState$ | async)
? drawer.open.bind(drawer)
: showFullSidenavSwitch.open.bind(showFullSidenavSwitch)
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
</iav-layout-fourcorners>
</mat-drawer-content>
</mat-drawer-container>
<!-- alternate mode drawer tmpl -->
<ng-template #alternateModeDrawerTmpl let-mode="mode">
<ng-container [ngSwitch]="mode">
<annotation-list *ngSwitchCase="ARIA_LABELS.VIEWER_MODE_ANNOTATING">
</annotation-list>
<key-frame-controller *ngSwitchCase="ARIA_LABELS.VIEWER_MODE_KEYFRAME">
</key-frame-controller>
<span *ngSwitchDefault>View mode {{ mode }} does not have side nav registered.</span>
</ng-container>
</ng-template>
<!-- regular mode drawer tmpl -->
<ng-template #regularModeDrawerTmpl
let-drawer="drawer"
let-showFullSidenavSwitch="showFullSidenavSwitch">
<!-- check if preview volume -->
<ng-template [ngIf]="overlaySidenav$ | async" let-overlaySideNav>
<!-- back btn -->
<button mat-button
(click)="clearPreviewingDataset()"
[attr.aria-label]="ARIA_LABELS.CLOSE"
class="position-absolute z-index-10 m-2">
<i class="fas fa-chevron-left"></i>
<span class="ml-1">
Back
</span>
</button>
<ng-template #genericInfoVCR>
</ng-template>
</ng-template>
<div [ngClass]="{
'invisible overflow-hidden h-0': overlaySidenav$ | async,
'h-100': !(overlaySidenav$ | async)
}" class="pe-all position-relative d-flex flex-column">
<!-- if pli voi is visible, show pli template
otherwise show region tmpl -->
<ng-template
[ngTemplateOutlet]="(selectedFeature$ | async)
? selectedFeatureTmpl
: sidenavRegionTmpl"
[ngTemplateOutletContext]="{
drawer: drawer,
showFullSidenavSwitch: showFullSidenavSwitch,
feature: selectedFeature$ | async
}">
</ng-template>
</div>
</ng-template>
<!-- minimal default drawer content -->
<ng-template #minSearchTray
let-showFullSidenav="showFullSidenav"
let-drawer="drawer">
<div class="mt-2 d-inline-block vw-col-10 vw-col-sm-10 vw-col-md-5 vw-col-lg-4 vw-col-xl-3 vw-col-xxl-2"
iav-switch
[iav-switch-state]="true"
#minTrayVisSwitch="iavSwitch"
[ngClass]="{
'vw-col-10-nm vw-col-sm-10-nm vw-col-md-5-nm vw-col-lg-4-nm vw-col-xl-3-nm vw-col-xxl-2-nm': !(minTrayVisSwitch.switchState$ | async),
'transition-margin-left': !drawer.opened
}">
<!-- collapsed side bar view -->
<div class="h-0 w-100 region-text-search-autocomplete-position">
<ng-container *ngTemplateOutlet="autocompleteTmpl; context: { showTour: true }">
</ng-container>
<div *ngIf="!((selectedRegions$ | async)[0])" class="p-2 w-100">
<ng-container *ngTemplateOutlet="spatialFeatureListViewTmpl"></ng-container>
</div>
</div>
<!-- such a gross implementation -->
<!-- TODO fix this -->
<div class="mt-1-n w-100 pl-2 pr-2 m-1px">
class="explore-btn pe-all w-100"
[ngClass]="{
'darktheme': iavRegion.rgbDarkmode === true,
'lighttheme': iavRegion.rgbDarkmode === false
}"
[style.backgroundColor]="iavRegion?.rgbString || 'accent'">
<span class="text iv-custom-comp">
Explore
</span>
<div class="hidden"
iav-region
[region]="(selectedRegions$ | async) && (selectedRegions$ | async)[0]"
#iavRegion="iavRegion">
</div>
</button>
<!-- tab toggling hide/show of min search tray -->
<div class="tab-toggle-container d-inline-block v-align-top">
<ng-container *ngTemplateOutlet="tabTmpl; context: {
isOpen: minTrayVisSwitch.switchState$ | async,
regionSelected: selectedRegions$ | async,
click: minTrayVisSwitch.toggle.bind(minTrayVisSwitch),
badge: (spatialFeatureBbox.features$ | async).length || null
<!-- top left -->
<!-- default top left -->
<ng-template #defaultMainContentTopLeft
let-isOpen="isOpen"
let-drawer="drawer"
let-showFullSidenavSwitch="showFullSidenavSwitch">
<!-- min search tray -->
<ng-template [ngIf]="!(showFullSidenavSwitch.switchState$ | async)">
<ng-template
[ngTemplateOutlet]="minSearchTray"
[ngTemplateOutletContext]="{
showFullSidenav: showFullSidenavSwitch.open.bind(showFullSidenavSwitch),
drawer: drawer
}">
</ng-template>
</ng-template>
<!-- pullable tab top left corner -->
<div *ngIf="showFullSidenavSwitch.switchState$ | async"
class="v-align-top pe-all tab-toggle-container d-inline-block"
(click)="drawer.toggle()"
quick-tour
[quick-tour-description]="quickTourRegionSearch.description"
[quick-tour-order]="quickTourRegionSearch.order">
<ng-container *ngTemplateOutlet="tabTmpl; context: {
isOpen: isOpen,
regionSelected: selectedRegions$ | async
}">
</ng-container>
</div>
<!-- status panel for (for nehuba viewer) -->
<iav-cmp-viewer-nehuba-status *ngIf="(useViewer$ | async) === 'nehuba'"
class="pe-all mt-2 muted-7 d-inline-block v-align-top">
</iav-cmp-viewer-nehuba-status>
</ng-template>
<!-- special mode top left -->
<ng-template #specialModeTopLeftTmpl
let-mode="mode"
let-toggleMatDrawer="toggleMatDrawer">
<ng-container [ngSwitch]="mode">
<!-- annotating top left -->
<ng-template [ngSwitchCase]="ARIA_LABELS.VIEWER_MODE_ANNOTATING">
<ng-container *ngTemplateOutlet="tabTmpl_defaultTmpl; context: {
matColor: 'primary',
fontIcon: 'fa-list',
tooltip: 'Annotation list',
click: toggleMatDrawer,
badge: toolPanel?.annBadges$ | async
}">
</ng-container>
<annotating-tools-panel class="z-index-10 d-block"
#toolPanel="annoToolsPanel">
</annotating-tools-panel>
</ng-template>
<ng-template [ngSwitchCase]="ARIA_LABELS.VIEWER_MODE_KEYFRAME">
<ng-container *ngTemplateOutlet="tabTmpl_defaultTmpl; context: {
matColor: 'primary',
fontIcon: 'fa-play',
tooltip: 'Annotation list',
click: toggleMatDrawer
}">
</ng-container>
</ng-template>
</ng-container>
</div>
</ng-template>
<!-- top right -->
<!-- default top right -->
<ng-template #minDefaultMainContentTopRight>
<!-- signin banner at top right corner -->
<top-menu-cmp class="mt-3 mr-2 d-inline-block"
[ismobile]="ismobile"
[viewerLoaded]="viewerLoaded">
</top-menu-cmp>
<atlas-dropdown-selector
class="v-align-top pt-2 pe-all mt-2 iv-custom-comp bg card m-2 mat-elevation-z2 d-inline-block"
quick-tour
[quick-tour-description]="quickTourAtlasSelector.description"
[quick-tour-order]="quickTourAtlasSelector.order">
</atlas-dropdown-selector>
<ng-template #specialTopRightTmpl let-mode="mode">
<mat-card class="mat-card-sm pe-all m-4">
<span>
{{ mode }}
</span>
<button mat-icon-button
color="warn"
(click)="exitSpecialViewMode()">
<i class="fas fa-times"></i>
</button>
</mat-card>
</ng-template>
<!-- bottom left -->
<ng-template #bottomLeftTmpl let-showFullSideNav="showFullSideNav">
<!-- atlas selector -->
<atlas-layer-selector *ngIf="viewerLoaded && !(isStandaloneVolumes$ | async)"
#alSelector="atlasLayerSelector"
(iav-outsideClick)="alSelector.selectorExpanded = false">
</atlas-layer-selector>
<!-- chips -->
<div *ngIf="parcellationSelected$ | async"
class="d-inline-block flex-grow-1 flex-shrink-1 pe-none overflow-x-auto overflow-y-hidden">
<viewer-state-breadcrumb class="d-inline-block pe-all" (on-item-click)="showFullSideNav()">
</viewer-state-breadcrumb>
</div>
<!-- viewer tmpl -->
<ng-template #viewerTmpl>
<div class="position-absolute w-100 h-100 z-index-1">
<ng-container [ngSwitch]="useViewer$ | async">
<!-- nehuba viewer -->
<iav-cmp-viewer-nehuba-glue class="d-block w-100 h-100 position-absolute left-0 top-0"
*ngSwitchCase="'nehuba'"
(viewerEvent)="handleViewerEvent($event)"
[selectedTemplate]="templateSelected$ | async"
[selectedParcellation]="parcellationSelected$ | async"
#iavCmpViewerNehubaGlue="iavCmpViewerNehubaGlue">
</iav-cmp-viewer-nehuba-glue>
<!-- three surfer (free surfer viewer) -->
<three-surfer-glue-cmp class="d-block w-100 h-100 position-absolute left-0 top-0"
*ngSwitchCase="'threeSurfer'"
(viewerEvent)="handleViewerEvent($event)"
[selectedTemplate]="templateSelected$ | async"
[selectedParcellation]="parcellationSelected$ | async">
</three-surfer-glue-cmp>
<!-- if not supported, show not supported message -->
<div *ngSwitchCase="'notsupported'">Template not supported by any of the viewers</div>
<!-- by default, show splash screen -->
<div *ngSwitchDefault>
<ui-splashscreen class="position-absolute left-0 top-0">
</ui-splashscreen>
</ng-container>
<!-- <div class="h-100 w-100 overflow-hidden position-relative"
ctx-menu-host
[ctx-menu-host-tmpl]="viewerCtxMenuTmpl">
</div> -->
</div>
<ng-template #autocompleteTmpl let-showTour="showTour">
<div class="iv-custom-comp bg card ml-2 mr-2 mat-elevation-z8 pe-all">
<region-text-search-autocomplete class="w-100 pt-2 flex-shrink-0 flex-grow-0">
</region-text-search-autocomplete>
<div class="w-100 h-100 position-absolute pe-none" *ngIf="showTour">
</div>
</ng-template>
<!-- template for rendering tab -->
<ng-template #tabTmpl
let-isOpen="isOpen"
let-regionSelected="regionSelected"
let-iavAdditionallayers="iavAdditionallayers"
let-click="click"
let-badge="badge">
<!-- if mat drawer is open -->
<ng-template [ngIf]="isOpen" [ngIfElse]="tabTmpl_closedTmpl">
<ng-template [ngTemplateOutlet]="tabTmpl_defaultTmpl"
[ngTemplateOutletContext]="{
matColor: 'basic',
fontIcon: 'fa-chevron-left',
click: click,
badge: badge
</ng-template>
<!-- if matdrawer is closed -->
<ng-template #tabTmpl_closedTmpl>
<!-- if additional layers are being shown -->
<ng-template [ngIf]="iavAdditionallayers?.length > 0" [ngIfElse]="tabTmpl_noAdditionalLayers">
<ng-container *ngTemplateOutlet="tabTmpl_defaultTmpl; context: {
matColor: 'accent',
fontIcon: 'fa-database',
tooltip: 'Explore dataset preview',
click: click
}">
</ng-container>
</ng-template>
<!-- if additional layers not not being shown -->
<ng-template #tabTmpl_noAdditionalLayers>
<!-- if region selected > 0 -->
<ng-template [ngIf]="regionSelected?.length > 0" [ngIfElse]="tabTmpl_nothingSelected">
<div class="hidden"
iav-region
[region]="regionSelected[0]"
#tabTmpl_iavRegion="iavRegion">
</div>
<ng-container *ngTemplateOutlet="tabTmpl_defaultTmpl; context: {
matColor: 'accent',
customColor: tabTmpl_iavRegion.rgbString,
customColorDarkmode: tabTmpl_iavRegion.rgbDarkmode,
fontIcon: 'fa-brain',
tooltip: 'Explore ' + tabTmpl_iavRegion.region.name,
click: click
}">
</ng-container>
</ng-template>
<!-- nothing is selected -->
<ng-template #tabTmpl_nothingSelected>
<ng-container *ngTemplateOutlet="tabTmpl_defaultTmpl; context: {
matColor: 'primary',
fontIcon: 'fa-sitemap',
click: click,
badge: badge
}">
</ng-container>
</ng-template>
</ng-template>
</ng-template>
</ng-template>
let-matColor="matColor"
let-fontIcon="fontIcon"
let-customColor="customColor"
let-customColorDarkmode="customColorDarkmode"
let-tooltip="tooltip"
<!-- (click)="sideNavMasterSwitch.toggle()" -->
<button mat-raised-button
[attr.aria-label]="ARIA_LABELS.TOGGLE_SIDE_PANEL"
[matTooltip]="tooltip"
class="pe-all tab-toggle"
[ngClass]="{
'darktheme': customColorDarkmode === true,
'lighttheme': customColorDarkmode === false
}"
(click)="click && click()"
[style.backgroundColor]="customColor"
[color]="(!customColor && matColor) ? matColor : null"
[matBadge]="badge"
[matBadgeColor]="badgeColor || 'warn'">
<span [ngClass]="{'iv-custom-comp text': !!customColor}">
<i class="fas" [ngClass]="fontIcon || 'fa-question'"></i>
</span>
<ng-template #sidenavRegionTmpl
let-drawer="drawer"
let-showFullSidenavSwitch="showFullSidenavSwitch">
<!-- region search autocomplete -->
<!-- [@openCloseAnchor]="sideNavFullLeftSwitch.switchState ? 'open' : 'closed'" -->
<div class="h-0 w-100 region-text-search-autocomplete-position">
<ng-container *ngTemplateOutlet="autocompleteTmpl">
</ng-container>
</div>
<div class="flex-shrink-1 flex-grow-1 d-flex flex-column"
[ngClass]="{'region-populated': (selectedRegions$ | async).length > 0 }">
<!-- region detail -->
<ng-container *ngIf="selectedRegions$ | async as selectedRegions; else selectRegionErrorTmpl">
<!-- single-region-wrapper -->
<ng-template [ngIf]="selectedRegions.length === 1" [ngIfElse]="multiRegionWrapperTmpl">
<!-- a series of bugs result in requiring this hacky -->
<!-- see https://github.com/HumanBrainProject/interactive-viewer/issues/698 -->
<ng-container *ngTemplateOutlet="singleRegionTmpl; context: { region: selectedRegions[0] }">
<!-- multi region wrapper -->
<ng-template #multiRegionWrapperTmpl>
<ng-container *ngTemplateOutlet="multiRegionTmpl; context: {
regions: selectedRegions
}">
</ng-container>
<!-- This is a wrapper for multiregion consisting of {{ selectedRegions.length }} regions -->
</ng-template>
<!-- place holder if length === 0 -->
<ng-container *ngIf="selectedRegions.length === 0">
<ng-container *ngTemplateOutlet="singleRegionTmpl; context: { region: false }">
</ng-container>
</ng-container>
</ng-container>
<div class="spacer">
</div>
</div>
<!-- collapse btn -->
<ng-template [ngTemplateOutlet]="collapseBtn"
[ngTemplateOutletContext]="{
collapse: showFullSidenavSwitch.close.bind(showFullSidenavSwitch)
}">
</ng-template>
</ng-template>
<!-- single region tmpl -->
<ng-template #singleRegionTmpl let-region="region">
<!-- region detail -->
[atlas]="selectedAtlas$ | async"
[template]="templateSelected$ | async"
[parcellation]="parcellationSelected$ | async"
class="flex-grow-1 bs-border-box mat-elevation-z4">
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
</ng-template>
<!-- expansion tmpl -->
<ng-template #ngMatAccordionTmpl
let-title="title"
let-desc="desc"
let-iconClass="iconClass"
let-iconTooltip="iconTooltip"
let-iavNgIf="iavNgIf"
let-content="content">
<mat-expansion-panel
[attr.data-opened]="expansionPanel.expanded"
[attr.data-mat-expansion-title]="title"
hideToggle
*ngIf="iavNgIf"
#expansionPanel="matExpansionPanel">
<mat-expansion-panel-header>
<!-- title -->
<mat-panel-title>
{{ title }}
</mat-panel-title>
<!-- desc + icon -->
<mat-panel-description class="d-flex align-items-center justify-content-end"
[matTooltip]="iconTooltip">
<span class="mr-3">{{ desc }}</span>
<span class="accordion-icon d-inline-flex justify-content-center">
<i [class]="iconClass"></i>
</span>
</mat-panel-description>
</mat-expansion-panel-header>
<!-- content -->
<ng-template matExpansionPanelContent>
<ng-container *ngTemplateOutlet="content; context: { expansionPanel: expansionPanel }">
</ng-container>
</ng-template>
<!-- misc dataset (e.g. PLI) -->
<!-- <ng-template #sidenavDsPreviewTmpl let-file="file" let-filename="filename" let-datasetId="datasetId">
<div class="w-100 flex-grow-1 d-flex flex-column">
<ng-container *ngTemplateOutlet="collapseBtn">
</ng-container>
</div>
<!-- select region error... for whatever reason -->
<ng-template #selectRegionErrorTmpl>
SELECT REGION ERROR
</ng-template>
<!-- multi region tmpl -->
<ng-template #multiRegionTmpl let-regions="regions">
<ng-template [ngIf]="regions.length > 0" [ngIfElse]="regionPlaceholderTmpl">
<region-menu
[region]="{ name: CONST.MULTI_REGION_SELECTION }"
class="bs-border-box ml-15px-n mr-15px-n mat-elevation-z4">
</region-menu>
<!-- other regions detail accordion -->
<mat-accordion class="bs-border-box ml-15px-n mr-15px-n mt-2">
<!-- Multi regions include -->
<ng-template #multiRegionInclTmpl>
<mat-chip *ngFor="let r of regions"
iav-region
[region]="r"
class="m-1"
[ngClass]="{
'darktheme':regionDirective.rgbDarkmode === true,
'lighttheme': regionDirective.rgbDarkmode === false
}"
[style.backgroundColor]="regionDirective.rgbString"
#regionDirective="iavRegion">
<span class="iv-custom-comp text text-truncate d-inline">
{{ r.name }}
</span>
</mat-chip>
<ng-container *ngTemplateOutlet="ngMatAccordionTmpl; context: {
title: 'Brain regions',
desc: regions.length,
iconClass: 'fas fa-brain',
iavNgIf: true,
content: multiRegionInclTmpl
}">
</ng-container>
</mat-accordion>
</ng-template>
</ng-template>
<!-- collapse btn -->
<ng-template #collapseBtn let-collapse="collapse">
<div class="h-0 w-100 collapse-position d-flex flex-column justify-content-end align-items-center">
<button mat-raised-button class="mat-elevation-z8"
[attr.aria-label]="ARIA_LABELS.COLLAPSE"
color="basic">
<i class="fas fa-chevron-up"></i>
<span>
collapse
</span>
</button>
</div>
</ng-template>
<!-- region tmpl placeholder -->
<ng-template #regionPlaceholderTmpl>
<div class="placeholder-region-detail bs-border-box ml-15px-n mr-15px-n mat-elevation-z4">
<span class="text-muted">
Select a region by clicking on the viewer or search from above
</span>
</div>
<!-- context menu template -->
<ng-template #viewerCtxMenuTmpl let-tmplRefs="tmplRefs">
[iav-key-listener]="[{type: 'keydown', target: 'document', capture: true}]"
(iav-key-event)="disposeCtxMenu()"
(iav-outsideClick)="disposeCtxMenu()">
<mat-card-content *ngFor="let tmplRef of tmplRefs"
class="m-0"
[ngStyle]="{order: tmplRef.order || 0}">
<mat-divider></mat-divider>
<!-- template provided -->
<ng-template [ngIf]="tmplRef.tmpl"
[ngIfElse]="fallbackTmpl"
[ngTemplateOutlet]="tmplRef.tmpl"
[ngTemplateOutletContext]="{$implicit: tmplRef.data}">
</ng-template>
<!-- template not provided -->
<ng-template #fallbackTmpl>
{{ tmplRef.data.message || 'test' }}
</ng-template>
</mat-card-content>
</mat-card>
</ng-template>
<!-- viewer status ctx menu -->
<ng-template #viewerStatusCtxMenu let-data>
<mat-list>
<!-- ref space & position -->
<ng-container [ngSwitch]="data.context.viewerType">
<!-- volumetric i.e. nehuba -->
<ng-container *ngSwitchCase="'nehuba'">
<mat-list-item>
<span mat-line>
{{ data.context.payload.mouse.real | nmToMm | numbers | addUnitAndJoin : '' }} (mm)
</span>
<span mat-line class="text-muted">
<i class="fas fa-map"></i>
<span>
{{ data.metadata.template.displayName || data.metadata.template.name }}
</span>
</span>
</mat-list-item>
</ng-container>
<ng-container *ngSwitchCase="'threeSurfer'">
<mat-list-item *ngIf="data?.context?.payload?.faceIndex && data?.context?.payload?.vertexIndices">
<span mat-line>
face#{{ data.context.payload.faceIndex }}
</span>
<span mat-line>
vertices#{{ data.context.payload.vertexIndices | addUnitAndJoin : '' }}
</span>
<span mat-line class="text-muted">
<i class="fas fa-map"></i>
<span>
{{ data.context.payload.fsversion }}
</span>
</span>
</mat-list-item>
</ng-container>
<ng-container *ngSwitchDefault>
DEFAULT
</ng-container>
</ng-container>
<ng-template #viewerStatusRegionCtxMenu let-data>
<!-- hovered ROIs -->
<mat-list>
<mat-list-item *ngFor="let region of data.metadata.hoveredRegions; let first = first">
<mat-divider class="top-0" *ngIf="!first"></mat-divider>
<ng-container *ngTemplateOutlet="viewerStateSapiRegionTmpl; context: { $implicit: region }">
</ng-container>
</mat-list>
</ng-template>
<!-- sapi region tmpl -->
<ng-template #viewerStateSapiRegionTmpl let-region>
<span mat-line>
{{ region.name }}
</span>
<span mat-line class="text-muted">
<i class="fas fa-brain"></i>
<span>
Brain region
</span>
</span>
<!-- lookup region -->
<button mat-icon-button
(click)="selectRoi(region)"
ctx-menu-dismiss>
<i class="fas fa-search"></i>
</button>
</ng-template>
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
<!-- feature tmpls -->
<ng-template #sapiBaseFeatureTmpl
let-backCb="backCb"
let-title="title"
let-subtitle="subtitle"
let-urls="urls"
let-description="description"
let-contentTmpl="contentTmpl">
<!-- back btn -->
<button mat-button
*ngIf="backCb"
(click)="backCb()"
[attr.aria-label]="ARIA_LABELS.CLOSE"
class="position-absolute z-index-10 m-2">
<i class="fas fa-chevron-left"></i>
<span class="ml-1">
Back
</span>
</button>
<mat-card class="sapi-container">
<!-- title must exist -->
<mat-card-title>
{{ title }}
</mat-card-title>
<mat-card-subtitle class="d-inline-flex align-items-center flex-wrap">
<mat-icon fontSet="fas" fontIcon="fa-database"></mat-icon>
<span *ngIf="subtitle">
{{ subtitle }}
</span>
<ng-template [ngIf]="urls">
<mat-divider vertical="true" class="ml-2 h-2rem"></mat-divider>
<a [href]="url.doi | doiParserPipe"
*ngFor="let url of urls"
mat-icon-button
matTooltip="Explore in EBRAINS Knowledge Graph"
target="_blank">
<i class="fas fa-external-link-alt"></i>
</a>
</ng-template>
</mat-card-subtitle>
<small *ngIf="description"
class="d-block text-muted iv-custom-comp darker-bg">
{{ description }}
</small>
<mat-card-content>
<ng-container *ngTemplateOutlet="contentTmpl">
</ng-container>
</mat-card-content>
</mat-card>
</ng-template>
<!-- general feature tmpl -->
<ng-template let-feature="feature" #selectedFeatureTmpl>
<!-- TODO differentiate between features (spatial, regional etc) -->
<!-- spatial feature tmpl -->
<ng-container *ngTemplateOutlet="sapiBaseFeatureTmpl; context: {
backCb: clearSelectedFeature.bind(this),
title: feature.name,
subtitle: 'Spatial feature',
description: feature.description,
urls: feature.url,
contentTmpl: sapiVOITmpl
}">
</ng-container>
<ng-template #sapiVOITmpl>
<ng-layer-ctl *ngFor="let vol of feature.volumes"
class="d-block"
[ng-layer-ctl-name]="vol.name"
[ng-layer-ctl-src]="vol.url"
[ng-layer-ctl-transform]="vol | getProperty : 'detail' | getProperty: 'neuroglancer/precomputed' | getProperty : 'transform'">
</ng-layer-ctl>
</ng-template>
</ng-template>
<ng-template #spatialFeatureListViewTmpl>
<div *ngIf="spatialFeatureBbox.busy$ | async; else notBusyTmpl" class="fs-200">
<spinner-cmp></spinner-cmp>
<ng-template #notBusyTmpl>
<mat-card *ngIf="(spatialFeatureBbox.features$ | async).length > 0" class="pe-all mat-elevation-z4">
</mat-card-title>
<mat-card-subtitle class="overflow-hidden">
<ng-template let-bbox [ngIf]="spatialFeatureBbox.bbox$ | async" [ngIfElse]="bboxFallbackTmpl">
Bounding box: {{ bbox[0] | numbers | json }} - {{ bbox[1] | numbers | json }} mm
</ng-template>
<ng-template #bboxFallbackTmpl>
Found nearby
</ng-template>
</mat-card-subtitle>
<mat-divider></mat-divider>
<div *ngFor="let feature of spatialFeatureBbox.features$ | async"
mat-ripple
(click)="showSpatialDataset(feature)"
class="iv-custom-comp hoverable w-100 overflow-hidden text-overflow-ellipses">
{{ feature.name }}
</div>
</mat-card>
</ng-template>
</ng-template>
<div class="d-none"
sii-xp-spatial-feat-bbox
[sii-xp-spatial-feat-bbox-atlas-id]="selectedAtlas$ | async | getProperty : '@id'"
[sii-xp-spatial-feat-bbox-space-id]="templateSelected$ | async | getProperty : '@id'"
[sii-xp-spatial-feat-bbox-bbox-spec]="viewerCtx$ | async | nehubaVCtxToBbox"
#spatialFeatureBbox="siiXpSpatialFeatBbox">
</div>