From 9f7d2bce8dbb113f207f8c8a0e206a09e8ee1bdb Mon Sep 17 00:00:00 2001
From: Xiao Gui <xgui3783@gmail.com>
Date: Mon, 19 Nov 2018 11:46:09 +0100
Subject: [PATCH] refactor: reduce dom nodes

---
 src/atlasViewer/atlasViewer.component.ts      |  5 +-
 .../atlasViewer.constantService.service.ts    |  5 +
 src/atlasViewer/atlasViewer.style.css         | 22 ++---
 src/atlasViewer/atlasViewer.template.html     | 57 +++++-------
 .../pluginUnit/pluginUnit.component.ts        | 10 +-
 .../pluginUnit/pluginUnit.template.html       |  2 -
 src/components/dropdown/dropdown.style.css    |  3 +-
 .../dropdown/dropdown.template.html           | 50 +++++-----
 src/components/flatTree/flatTree.component.ts |  4 +
 .../flatTree/flatTree.template.html           | 74 ++++++++-------
 src/components/panel/panel.component.ts       | 13 +++
 src/components/panel/panel.style.css          | 20 ++--
 src/components/panel/panel.template.html      | 55 ++++++-----
 src/layouts/mainside/mainside.style.css       |  5 +-
 src/layouts/mainside/mainside.template.html   | 34 +++----
 src/ui/banner/banner.style.css                |  7 +-
 src/ui/banner/banner.template.html            | 92 +++++++++----------
 src/ui/datasetViewer/datasetViewer.style.css  |  6 +-
 .../datasetViewer/datasetViewer.template.html |  2 +
 src/ui/layerbrowser/layerbrowser.style.css    |  4 -
 .../layerbrowser/layerbrowser.template.html   | 88 +++++++++---------
 .../nehubaContainer.template.html             |  1 +
 .../nehubaViewer/nehubaViewer.style.css       | 11 +++
 .../nehubaViewer/nehubaViewer.template.html   |  4 +-
 ...templateParcellationCitations.component.ts |  2 +-
 25 files changed, 285 insertions(+), 291 deletions(-)

diff --git a/src/atlasViewer/atlasViewer.component.ts b/src/atlasViewer/atlasViewer.component.ts
index 4bbf3551b..f455d1ccd 100644
--- a/src/atlasViewer/atlasViewer.component.ts
+++ b/src/atlasViewer/atlasViewer.component.ts
@@ -37,7 +37,6 @@ export class AtlasViewer implements OnDestroy, OnInit, AfterViewInit {
   @ViewChild('dockedContainer', { read: ViewContainerRef }) dockedContainer: ViewContainerRef
   @ViewChild('floatingContainer', { read: ViewContainerRef }) floatingContainer: ViewContainerRef
   @ViewChild('databrowser', { read: ElementRef }) databrowser: ElementRef
-  @ViewChild('temporaryContainer', { read: ViewContainerRef }) temporaryContainer: ViewContainerRef
   @ViewChild('toastContainer', { read: ViewContainerRef }) toastContainer: ViewContainerRef
   @ViewChild('floatingMouseContextualContainer', { read: ViewContainerRef }) floatingMouseContextualContainer: ViewContainerRef
   @ViewChild('pluginFactory', { read: ViewContainerRef }) pluginViewContainerRef: ViewContainerRef
@@ -71,6 +70,10 @@ export class AtlasViewer implements OnDestroy, OnInit, AfterViewInit {
   public ngLayers : NgLayerInterface[]
   private disposeHandler : any
 
+  get toggleMessage(){
+    return this.constantsService.toggleMessage
+  }
+
   constructor(
     private toastService:ToastService,
     private pluginService: PluginServices,
diff --git a/src/atlasViewer/atlasViewer.constantService.service.ts b/src/atlasViewer/atlasViewer.constantService.service.ts
index 2173492c3..99f66f51f 100644
--- a/src/atlasViewer/atlasViewer.constantService.service.ts
+++ b/src/atlasViewer/atlasViewer.constantService.service.ts
@@ -104,6 +104,11 @@ the atlas viewer requires **webgl2.0**, and the \`EXT_color_buffer_float\` exten
     return [400,100]
   } 
 
+  /**
+   * message when user on hover a segment or landmark
+   */
+  public toggleMessage: string = 'double click to toggle select'
+
   constructor(private store : Store<ViewerStateInterface>){
 
     const ua = window && window.navigator && window.navigator.userAgent
diff --git a/src/atlasViewer/atlasViewer.style.css b/src/atlasViewer/atlasViewer.style.css
index f1e509854..9d26e67c1 100644
--- a/src/atlasViewer/atlasViewer.style.css
+++ b/src/atlasViewer/atlasViewer.style.css
@@ -58,7 +58,7 @@ layout-floating-container
   overflow:hidden;
 }
 
-div[toastContainer]
+[toastContainer]
 {
   pointer-events: none;
   position : absolute;
@@ -69,7 +69,7 @@ div[toastContainer]
   flex-direction: column;
 }
 
-div[toastContainer] > *
+[toastContainer] > *
 {
   flex : 0 0 auto;
 }
@@ -88,32 +88,25 @@ div[floatingMouseContextualContainer]
   height: 0px;
 }
 
-div[contextualInnerContainer]
+div[contextualBlock]
 {
-  margin-top :1em;
-  margin-left :1em;
+  margin: 1.3em 1.5em;
+  white-space: nowrap;
   display:inline-block;
   width:auto;
 }
 
-div[contextualInnerContainer]
+div[contextualBlock]
 {
   background-color:rgba(200,200,200,0.8);
 }
 
-:host-context([darktheme="true"]) div[contextualInnerContainer]
+:host-context([darktheme="true"]) div[contextualBlock]
 {
   background-color : rgba(30,30,30,0.8);
   color : rgba(250,250,250,0.8);
 }
 
-div[contextualBlock]
-{
-  margin: 0.3em 0.5em;
-  white-space: nowrap;
-}
-
-
 :host-context([darktheme="false"]) div[resizeSliver] > span.tabContainer
 {
   background-color:rgba(235,235,235,0.8);
@@ -225,6 +218,7 @@ span.tabContainer.active-tab:before
 [mobileMenu]
 {
   min-height:50em;
+  margin-top: 1em;
 }
 
 [mobileMenu] > *
diff --git a/src/atlasViewer/atlasViewer.template.html b/src/atlasViewer/atlasViewer.template.html
index e5e89a779..0e5250ccd 100644
--- a/src/atlasViewer/atlasViewer.template.html
+++ b/src/atlasViewer/atlasViewer.template.html
@@ -24,15 +24,13 @@
           <div heading>
             Menu
           </div>
-          <div body>
-            <div mobileMenu>
-              <atlas-banner>
+          <div mobileMenu body>
+            <atlas-banner>
 
-              </atlas-banner>
-              <template-parcellation-citation-container mobileTemplateCitation>
-  
-              </template-parcellation-citation-container>
-            </div>
+            </atlas-banner>
+            <template-parcellation-citation-container mobileTemplateCitation>
+
+            </template-parcellation-citation-container>
           </div>
         </panel-component>
       </div>
@@ -43,10 +41,8 @@
           <div heading>
             Data Browser
           </div>
-          <div body>
-            <data-browser>
-            </data-browser>
-          </div>
+          <data-browser body>
+          </data-browser>
         </panel-component>
       </div>
 
@@ -56,11 +52,8 @@
           <div heading>
             Layer Browser
           </div>
-          <div body>
-            <layer-browser >
-            </layer-browser>
-            
-          </div>
+          <layer-browser body>
+          </layer-browser>
         </panel-component>
       </div>
 
@@ -70,10 +63,8 @@
           <div heading>
             Tools Browser
           </div>
-          <div body>          
-            <plugin-banner>
-            </plugin-banner>
-          </div>
+          <plugin-banner body>          
+          </plugin-banner>
         </panel-component>
       </div>
 
@@ -83,9 +74,7 @@
       </div>
       
       <!-- Docked Container-->
-      <div dockedContainer>
-        <ng-template #dockedContainer>
-        </ng-template>
+      <div dockedContainer #dockedContainer>
       </div>
     </div>
 
@@ -163,16 +152,17 @@
 
     </ng-template>
     <div [style.transform] = "floatingMouseContextualContainerTransform" floatingMouseContextualContainer>
-      <div *ngIf = "onhoverLandmark$ | async" contextualInnerContainer>
-        <div contextualBlock>
-          {{ onhoverLandmark$ | async }} <i><small class = "mute-text">dbl click to toggle select</small></i>
-        </div>
+      <div 
+        *ngIf = "onhoverLandmark$ | async" 
+        contextualBlock>
+        {{ onhoverLandmark$ | async }} <i><small class = "mute-text">{{ toggleMessage }}</small></i>
       </div>
-      <div *ngIf = "onhoverSegment$ | async as onhoverSegment" contextualInnerContainer>
-        <div *ngIf = "onhoverSegment !== ''" contextualBlock>
-          {{ onhoverSegment }} <i><small class = "mute-text">dbl click to toggle select</small></i>
-        </div>
+      <div 
+        *ngIf = "(onhoverSegment$ | async) !== ''" 
+        contextualBlock>
+        {{ onhoverSegment$ | async }} <i><small class = "mute-text">{{ toggleMessage }}</small></i>
       </div>
+      <!-- TODO Potentially implementing plugin contextual info -->
     </div>
     <div toastContainer>
       <ng-template #toastContainer>
@@ -180,9 +170,6 @@
     </div>
   </layout-floating-container>
 
-  <ng-template #temporaryContainer>
-  </ng-template>
-
   <ng-template #pluginFactory>
   </ng-template>
 
diff --git a/src/atlasViewer/pluginUnit/pluginUnit.component.ts b/src/atlasViewer/pluginUnit/pluginUnit.component.ts
index 15e462404..8afdef862 100644
--- a/src/atlasViewer/pluginUnit/pluginUnit.component.ts
+++ b/src/atlasViewer/pluginUnit/pluginUnit.component.ts
@@ -1,4 +1,4 @@
-import { Component, ElementRef, ViewChild, OnDestroy } from "@angular/core";
+import { Component, ElementRef, OnDestroy, HostBinding } from "@angular/core";
 
 
 @Component({
@@ -7,8 +7,14 @@ import { Component, ElementRef, ViewChild, OnDestroy } from "@angular/core";
 
 export class PluginUnit implements OnDestroy{
   
-  @ViewChild('pluginContainer',{read:ElementRef}) 
   elementRef:ElementRef
+  
+  @HostBinding('attr.pluginContainer')
+  pluginContainer = true
+
+  constructor(er:ElementRef){
+    this.elementRef = er
+  }
 
   ngOnDestroy(){
     console.log('plugin being destroyed')
diff --git a/src/atlasViewer/pluginUnit/pluginUnit.template.html b/src/atlasViewer/pluginUnit/pluginUnit.template.html
index 4896a25f9..e69de29bb 100644
--- a/src/atlasViewer/pluginUnit/pluginUnit.template.html
+++ b/src/atlasViewer/pluginUnit/pluginUnit.template.html
@@ -1,2 +0,0 @@
-<div pluginContainer #pluginContainer>
-</div>
\ No newline at end of file
diff --git a/src/components/dropdown/dropdown.style.css b/src/components/dropdown/dropdown.style.css
index df852e545..0d08444ec 100644
--- a/src/components/dropdown/dropdown.style.css
+++ b/src/components/dropdown/dropdown.style.css
@@ -1,6 +1,7 @@
-div[dropdowncontainer]
+:host
 {
   position:relative;
+  display:block;
 }
 
 ul.dropdown-menu
diff --git a/src/components/dropdown/dropdown.template.html b/src/components/dropdown/dropdown.template.html
index fe2253165..97207b21f 100644
--- a/src/components/dropdown/dropdown.template.html
+++ b/src/components/dropdown/dropdown.template.html
@@ -1,28 +1,24 @@
-<div 
-  dropdowncontainer>
+<span
+  class = "btn btn-default"
+  [innerHTML] = "activeDisplay(selectedItem)"
+  hoverable
+  #dropdownToggle
+  dropdownToggle>
+</span>
 
-  <span
-    class = "btn btn-default"
-    [innerHTML] = "activeDisplay(selectedItem)"
-    hoverable
-    #dropdownToggle
-    dropdownToggle>
-  </span>
-  
-  <ul 
-    class="dropdown-menu"
-    role="menu"
-    [@showState] = "openState ? 'show' : 'hide'">
-    <li 
-      *ngFor="let input of inputArray" 
-      [ngClass]="selectedItem === input ? 'selected' : 'notselected'" 
-      (click)="itemSelected.emit(input); openState = false" 
-      role="menuitem">
-      
-      <span 
-        class="dropdown-item" 
-        [innerHTML] = "listDisplay(input)">
-      </span>
-    </li>
-  </ul>
-</div>
\ No newline at end of file
+<ul 
+  class="dropdown-menu"
+  role="menu"
+  [@showState] = "openState ? 'show' : 'hide'">
+  <li 
+    *ngFor="let input of inputArray" 
+    [ngClass]="selectedItem === input ? 'selected' : 'notselected'" 
+    (click)="itemSelected.emit(input); openState = false" 
+    role="menuitem">
+    
+    <span 
+      class="dropdown-item" 
+      [innerHTML] = "listDisplay(input)">
+    </span>
+  </li>
+</ul>
\ No newline at end of file
diff --git a/src/components/flatTree/flatTree.component.ts b/src/components/flatTree/flatTree.component.ts
index e3c19238b..b82ec4f5b 100644
--- a/src/components/flatTree/flatTree.component.ts
+++ b/src/components/flatTree/flatTree.component.ts
@@ -1,6 +1,10 @@
 import { EventEmitter, Component, Input, Output, ChangeDetectionStrategy, ElementRef, OnDestroy, ChangeDetectorRef, ViewChildren, QueryList, AfterViewChecked, AfterViewInit, OnInit } from "@angular/core";
 import { FlattenedTreeInterface } from "./flattener.pipe";
 
+/**
+ * TODO to be replaced by virtual scrolling when ivy is in stable
+ */
+
 @Component({
   selector : 'flat-tree-component',
   templateUrl : './flatTree.template.html',
diff --git a/src/components/flatTree/flatTree.template.html b/src/components/flatTree/flatTree.template.html
index b695100bf..de7151e12 100644
--- a/src/components/flatTree/flatTree.template.html
+++ b/src/components/flatTree/flatTree.template.html
@@ -1,46 +1,44 @@
-<div class="container">
-  <div *ngFor = "let flattenedItems of (inputItem | flattenTreePipe : findChildren | filterRowsByVisbilityPipe : findChildren : searchFilter | appendSiblingFlagPipe | clusteringPipe : clusterNumber ); let index = index" clusterContainer>
+<div *ngFor = "let flattenedItems of (inputItem | flattenTreePipe : findChildren | filterRowsByVisbilityPipe : findChildren : searchFilter | appendSiblingFlagPipe | clusteringPipe : clusterNumber ); let index = index" clusterContainer>
 
-    <div [attr.clusterindex] = "index" flatTreeStart #flatTreeStart>
-    </div>
+  <div [attr.clusterindex] = "index" flatTreeStart #flatTreeStart>
+  </div>
 
-    <div *ngIf = "showCluster(index)">
-      <div
-        *ngFor = "let flattenedItem of flattenedItems"
-        [ngClass] = "getClass(flattenedItem.flattenedTreeLevel)"
-        [attr.flattenedtreelevel] = "flattenedItem.flattenedTreeLevel" 
-        [attr.collapsed] = "flattenedItem.collapsed ? flattenedItem.collapsed : false"
-        [attr.lvlId] = "flattenedItem.lvlId"
-        [hidden] = "collapseRow(flattenedItem) "
-        renderNode>
-      
-        <span class = "padding-block-container">
-          <span
-            [attr.hidemargin] = "block"
-            *ngFor = "let block of flattenedItem.siblingFlags"
-            class = "padding-block">
-      
-          </span>
-        </span>
-        <span 
-          *ngIf = "findChildren(flattenedItem).length > 0; else noChildren"
-          (click) = "$event.stopPropagation(); toggleCollapse(flattenedItem)" >
-          <i [ngClass] = "isCollapsed(flattenedItem) ? 'glyphicon-chevron-right' : 'glyphicon-chevron-down'" class="glyphicon"></i>
-        </span>
-        <ng-template #noChildren>
-          <i class="glyphicon glyphicon-none">
-      
-          </i>
-        </ng-template>
+  <div *ngIf = "showCluster(index)">
+    <div
+      *ngFor = "let flattenedItem of flattenedItems"
+      [ngClass] = "getClass(flattenedItem.flattenedTreeLevel)"
+      [attr.flattenedtreelevel] = "flattenedItem.flattenedTreeLevel" 
+      [attr.collapsed] = "flattenedItem.collapsed ? flattenedItem.collapsed : false"
+      [attr.lvlId] = "flattenedItem.lvlId"
+      [hidden] = "collapseRow(flattenedItem) "
+      renderNode>
+    
+      <span class = "padding-block-container">
         <span
-          (click) = "treeNodeClick.emit({event:$event,inputItem:flattenedItem})"
-          class = "render-node-text"
-          [innerHtml] = "flattenedItem | renderPipe : renderNode ">
+          *ngFor = "let block of flattenedItem.siblingFlags"
+          [attr.hidemargin] = "block"
+          class = "padding-block">
+    
         </span>
-      </div>
+      </span>
+      <span 
+        *ngIf = "findChildren(flattenedItem).length > 0; else noChildren"
+        (click) = "$event.stopPropagation(); toggleCollapse(flattenedItem)" >
+        <i [ngClass] = "isCollapsed(flattenedItem) ? 'glyphicon-chevron-right' : 'glyphicon-chevron-down'" class="glyphicon"></i>
+      </span>
+      <ng-template #noChildren>
+        <i class="glyphicon glyphicon-none">
+    
+        </i>
+      </ng-template>
+      <span
+        (click) = "treeNodeClick.emit({event:$event,inputItem:flattenedItem})"
+        class = "render-node-text"
+        [innerHtml] = "flattenedItem | renderPipe : renderNode ">
+      </span>
     </div>
+  </div>
 
-    <div [attr.clusterindex] = "index" flatTreeEnd #flatTreeEnd>
-    </div>
+  <div [attr.clusterindex] = "index" flatTreeEnd #flatTreeEnd>
   </div>
 </div>
\ No newline at end of file
diff --git a/src/components/panel/panel.component.ts b/src/components/panel/panel.component.ts
index d3fdea331..04c869d4f 100644
--- a/src/components/panel/panel.component.ts
+++ b/src/components/panel/panel.component.ts
@@ -11,6 +11,9 @@ import { ParseAttributeDirective } from "../parseAttribute.directive";
   animations : [
     panelAnimations
   ],
+  host: {
+    '[class]': 'getClassNames'
+  },
   changeDetection:ChangeDetectionStrategy.OnPush
 })
 
@@ -34,12 +37,22 @@ export class PanelComponent extends ParseAttributeDirective implements AfterCont
     super()
   }
 
+  get getClassNames(){
+    return `panel ${this.containerClass === '' ? 'panel-default' : this.containerClass}`
+  }
+
   ngAfterContentChecked(){
+    /**
+     * TODO check performance implication. 
+     * setting height forces a repaint (?)
+     */
     this.fullHeight = (this.efPanelBody ? this.efPanelBody.nativeElement.offsetHeight : 0) +
       (this.efPanelFooter ? this.efPanelFooter.nativeElement.offsetHeight : 0)
     this.cdr.detectChanges()
   }
 
+  @HostBinding('class.panel-default')
+
   set fullHeight(num:number){
     this._fullHeight = num
   }
diff --git a/src/components/panel/panel.style.css b/src/components/panel/panel.style.css
index 2163a4923..8cf87fc19 100644
--- a/src/components/panel/panel.style.css
+++ b/src/components/panel/panel.style.css
@@ -3,13 +3,10 @@
   font-size:92%;
   overflow:hidden;
   box-shadow: 0px 4px 16px -4px rgba(0,0,0,0.2);
-}
-
-.panel
-{
   border-radius : 0;
   border:none;
   margin:0;
+  background:none;
 }
 
 [bodyFooterContainer]
@@ -17,7 +14,7 @@
   overflow:hidden;
 }
 
-.panel > .panel-heading
+:host > .panel-heading
 {
   border-radius : 0;
   padding: 0;
@@ -25,31 +22,26 @@
   border:none;
 }
 
-.panel > [bodyFooterContainer] > .panel-body,
-.panel > [bodyFooterContainer] > .panel-footer
+:host > [bodyFooterContainer] > .panel-body,
+:host > [bodyFooterContainer] > .panel-footer
 {
   margin-top:0px;
   padding: 0px;
   border:none;
 }
 
-div.panel
-{
-  background:none;
-}
-
 div.panel-body
 {
   background-color:rgba(245,245,245,0.8);
 }
 
-:host-context([darktheme="true"]) div.panel-default div.panel-heading
+:host-context([darktheme="true"]).panel-default div.panel-heading
 {
   background-color:rgba(45,45,45,0.9);
   color:rgba(250,250,250,0.9);
 }
 
-:host-context([darktheme="true"]) div.panel-success div.panel-heading
+:host-context([darktheme="true"]).panel-success div.panel-heading
 {
   background-color:rgba(60,118,61,0.9);
   color:rgba(223,240,216  ,0.9);
diff --git a/src/components/panel/panel.template.html b/src/components/panel/panel.template.html
index bbdf5f62b..7f7c1af41 100644
--- a/src/components/panel/panel.template.html
+++ b/src/components/panel/panel.template.html
@@ -1,36 +1,35 @@
-<div class = "panel" 
-  [ngClass] = "containerClass === '' ?  'panel-default' : containerClass">
+<div
+  *ngIf = "showHeading"
+  class = "panel-heading"
+  (click) = "toggleCollapseBody($event)"
+  hoverable>
+
+  <ng-content select="[heading]">
+  </ng-content>
+
+</div>
+
+<!-- While wrapping body and footer in a diffrent div adds a lot of overhead, it enables nice transition effects -->
+<div 
+  bodyFooterContainer>
   <div
-    *ngIf = "showHeading"
-    class = "panel-heading"
-    (click) = "toggleCollapseBody($event)"
-    hoverable>
+    *ngIf = "showBody"
+    class = "panel-body"
+    [@collapseState] = "{ value : collapseBody ? 'collapsed' : 'visible', params : { fullHeight : fullHeight } }"
+    #panelBody>
 
-    <ng-content select="[heading]">
+    <ng-content select="[body]">
     </ng-content>
 
   </div>
-  <div 
-    bodyFooterContainer>
-    <div
-      *ngIf = "showBody"
-      class = "panel-body"
-      [@collapseState] = "{ value : collapseBody ? 'collapsed' : 'visible', params : { fullHeight : fullHeight } }"
-      #panelBody>
-
-      <ng-content select="[body]">
-      </ng-content>
-
-    </div>
-    <div
-      *ngIf = "showFooter"
-      class = "panel-footer"
-      [@collapseState] = "{ value : collapseBody ? 'collapsed' : 'visible', params : { fullHeight : fullHeight } }"
-      #panelFooter>
-      
-      <ng-content select="[footer]">
-      </ng-content>
+  <div
+    *ngIf = "showFooter"
+    class = "panel-footer"
+    [@collapseState] = "{ value : collapseBody ? 'collapsed' : 'visible', params : { fullHeight : fullHeight } }"
+    #panelFooter>
+    
+    <ng-content select="[footer]">
+    </ng-content>
 
-    </div>
   </div>
 </div>
\ No newline at end of file
diff --git a/src/layouts/mainside/mainside.style.css b/src/layouts/mainside/mainside.style.css
index 7b4888e5b..da85c4123 100644
--- a/src/layouts/mainside/mainside.style.css
+++ b/src/layouts/mainside/mainside.style.css
@@ -1,5 +1,6 @@
-div[container]
+:host
 {
+  display:block;
   width:100%;
   height:100%;
   display:flex;
@@ -15,8 +16,6 @@ div[maincontent]
 
 div[resizeSliver]
 {
-  /* width : 2.0em;
-  height: 4em; */
   margin-top : 2em;
   width:0em;
 }
diff --git a/src/layouts/mainside/mainside.template.html b/src/layouts/mainside/mainside.template.html
index b3da941e8..ae93b37bc 100644
--- a/src/layouts/mainside/mainside.template.html
+++ b/src/layouts/mainside/mainside.template.html
@@ -1,18 +1,18 @@
-<div container>
-  <div maincontent>
-    <ng-content select="[maincontent]">
-    </ng-content>
-  </div>
-  <div resizeSliver>
-    <ng-content select = "[resizeSliver]">
-    </ng-content>
-  </div>
-  <div 
-    [@collapseSide] = "{ value : showSide ? 'visible' : 'collapsed' , params : { sideWidth : sideWidth, animationTiming : animationFlag ? 180 : 0 } }"
-    (@collapseSide.start) = "animationStart()"
-    (@collapseSide.done) = "animationEnd()"
-    sidecontent>
-    <ng-content select="[sidecontent]">
-    </ng-content>
-  </div>
+<div maincontent>
+  <ng-content select="[maincontent]">
+  </ng-content>
+</div>
+
+<div resizeSliver>
+  <ng-content select = "[resizeSliver]">
+  </ng-content>
+</div>
+
+<div 
+  [@collapseSide] = "{ value : showSide ? 'visible' : 'collapsed' , params : { sideWidth : sideWidth, animationTiming : animationFlag ? 180 : 0 } }"
+  (@collapseSide.start) = "animationStart()"
+  (@collapseSide.done) = "animationEnd()"
+  sidecontent>
+  <ng-content select="[sidecontent]">
+  </ng-content>
 </div>
\ No newline at end of file
diff --git a/src/ui/banner/banner.style.css b/src/ui/banner/banner.style.css
index 3df7fe3bc..63e7f18e3 100644
--- a/src/ui/banner/banner.style.css
+++ b/src/ui/banner/banner.style.css
@@ -1,16 +1,13 @@
 :host
 {
   display:block;
-}
-
-div[container]
-{
   display:flex;
   flex-direction: row;
   flex-wrap : wrap;
 }
 
-dropdown-component, div[container] > div[searchRegionPopover]
+dropdown-component,
+:host > div[searchRegionPopover]
 {
   margin-left:1em;
   margin-bottom: 0.4em;
diff --git a/src/ui/banner/banner.template.html b/src/ui/banner/banner.template.html
index 3cf7350f8..44201ed94 100644
--- a/src/ui/banner/banner.template.html
+++ b/src/ui/banner/banner.template.html
@@ -1,54 +1,52 @@
-<div container>
-  <dropdown-component
-    (itemSelected) = "selectTemplate($event)"
-    [activeDisplay] = "displayActiveTemplate"
-    [selectedItem] = "selectedTemplate"
-    [inputArray] = "loadedTemplates$ | async | filterNull">
-  
-  </dropdown-component>
-  
-  <dropdown-component
-    *ngIf = "selectedTemplate"
-    (itemSelected) = "selectParcellation($event)"
-    [activeDisplay] = "displayActiveParcellation"
-    [selectedItem] = "selectedParcellation"
-    [inputArray] = "selectedTemplate.parcellations">
-  </dropdown-component>
+<dropdown-component
+  (itemSelected) = "selectTemplate($event)"
+  [activeDisplay] = "displayActiveTemplate"
+  [selectedItem] = "selectedTemplate"
+  [inputArray] = "loadedTemplates$ | async | filterNull">
 
+</dropdown-component>
+
+<dropdown-component
+  *ngIf = "selectedTemplate"
+  (itemSelected) = "selectParcellation($event)"
+  [activeDisplay] = "displayActiveParcellation"
+  [selectedItem] = "selectedParcellation"
+  [inputArray] = "selectedTemplate.parcellations">
+</dropdown-component>
+
+<div 
+  *ngIf = "selectedTemplate"
+  #searchRegionPopover
+  searchRegionPopover>
+
+  <input 
+    (keydown.esc) = "showRegionTree = false; $event.target.blur(); searchTerm = ''"
+    (focus) = "showRegionTree = true"
+    [value] = "searchTerm"
+    (input) = "changeSearchTerm($event)"
+    class = "form-control" 
+    type="text" 
+    placeholder="Regions"/>
+    
   <div 
-    *ngIf = "selectedTemplate"
-    #searchRegionPopover
-    searchRegionPopover>
+    [@showState]
+    *ngIf = "showRegionTree" 
+    hideScrollbarContainer>
 
-    <input 
-      (keydown.esc) = "showRegionTree = false; $event.target.blur(); searchTerm = ''"
-      (focus) = "showRegionTree = true"
-      [value] = "searchTerm"
-      (input) = "changeSearchTerm($event)"
-      class = "form-control" 
-      type="text" 
-      placeholder="Regions"/>
+    <div treeContainer #treeContainer>
+      <div treeHeader>
+        <span>{{ selectedRegions.length }} {{ selectedRegions.length > 1 ? 'regions' : 'region' }} selected</span> 
+        <span (click) = "clearRegions($event)" *ngIf = "selectedRegions.length > 0" class = "btn btn-link">clear all</span>
+      </div>
       
-    <div 
-      [@showState]
-      *ngIf = "showRegionTree" 
-      hideScrollbarContainer>
-
-      <div treeContainer #treeContainer>
-        <div treeHeader>
-          <span>{{ selectedRegions.length }} {{ selectedRegions.length > 1 ? 'regions' : 'region' }} selected</span> 
-          <span (click) = "clearRegions($event)" *ngIf = "selectedRegions.length > 0" class = "btn btn-link">clear all</span>
-        </div>
+      <flat-tree-component 
+        [flatTreeViewPort] = "treeContainer"
+        (treeNodeClick) = "handleClickRegion($event)"
+        [inputItem] = "aggregatedRegionTree"
+        [renderNode] = "displayTreeNode.bind(this)"
+        [searchFilter] = "filterTreeBySearch.bind(this)">
         
-        <flat-tree-component 
-          [flatTreeViewPort] = "treeContainer"
-          (treeNodeClick) = "handleClickRegion($event)"
-          [inputItem] = "aggregatedRegionTree"
-          [renderNode] = "displayTreeNode.bind(this)"
-          [searchFilter] = "filterTreeBySearch.bind(this)">
-          
-        </flat-tree-component>
-      </div>
+      </flat-tree-component>
     </div>
   </div>
-</div>
+</div>
\ No newline at end of file
diff --git a/src/ui/datasetViewer/datasetViewer.style.css b/src/ui/datasetViewer/datasetViewer.style.css
index 59294f4b3..f95c2e97a 100644
--- a/src/ui/datasetViewer/datasetViewer.style.css
+++ b/src/ui/datasetViewer/datasetViewer.style.css
@@ -1,11 +1,7 @@
-div[title]
-{
-  margin: 0.5rem;
-}
-
 flat-tree-component
 {
   overflow: hidden;
+  white-space: nowrap;
 }
 
 :host-context([darktheme="true"]) hr
diff --git a/src/ui/datasetViewer/datasetViewer.template.html b/src/ui/datasetViewer/datasetViewer.template.html
index eb385d627..9c31a987c 100644
--- a/src/ui/datasetViewer/datasetViewer.template.html
+++ b/src/ui/datasetViewer/datasetViewer.template.html
@@ -21,9 +21,11 @@
   </flat-tree-component>
   <hr />
 </div>
+
 <ng-template #defaultDisplay>
   Nothing to display ...
 </ng-template>
+
 <ng-template #noKgID>
   kgID not specified.
 </ng-template>
diff --git a/src/ui/layerbrowser/layerbrowser.style.css b/src/ui/layerbrowser/layerbrowser.style.css
index 0b744a400..2babcd853 100644
--- a/src/ui/layerbrowser/layerbrowser.style.css
+++ b/src/ui/layerbrowser/layerbrowser.style.css
@@ -1,10 +1,6 @@
 :host
 {
   padding: 0 0.2em;
-}
-
-div[container]
-{
   display: flex;
   flex-direction: column-reverse;
 }
diff --git a/src/ui/layerbrowser/layerbrowser.template.html b/src/ui/layerbrowser/layerbrowser.template.html
index 2dc961729..b88d2e18b 100644
--- a/src/ui/layerbrowser/layerbrowser.template.html
+++ b/src/ui/layerbrowser/layerbrowser.template.html
@@ -1,53 +1,51 @@
-<div container>
-  <div 
-    class="layerContainer"
-    *ngFor = "let ngLayer of ngLayers">
+<div 
+  class="layerContainer"
+  *ngFor = "let ngLayer of ngLayers">
 
-    <div>
-      <i 
-        container = "body"
-        placement = "bottom"
-        [tooltip] = "checkLocked(ngLayer) ? 'base layer cannot be hidden' : 'toggle visibility'"
-        (click) = "checkLocked(ngLayer) ? null : toggleVisibility(ngLayer)"
-        class = "glyphicon" 
-        [ngClass] = "checkLocked(ngLayer) ? 'glyphicon-lock muted' :ngLayer.visible ? 'glyphicon-eye-open' : 'glyphicon-eye-close'">
+  <div>
+    <i 
+      container = "body"
+      placement = "bottom"
+      [tooltip] = "checkLocked(ngLayer) ? 'base layer cannot be hidden' : 'toggle visibility'"
+      (click) = "checkLocked(ngLayer) ? null : toggleVisibility(ngLayer)"
+      class = "glyphicon" 
+      [ngClass] = "checkLocked(ngLayer) ? 'glyphicon-lock muted' :ngLayer.visible ? 'glyphicon-eye-open' : 'glyphicon-eye-close'">
 
-      </i>
-    </div>
-    <div>
-      <i 
-        container = "body"
-        placement = "bottom"
-        [tooltip] = "ngLayer.type === 'segmentation' ? segmentationTooltip() : 'only segmentation layer can hide/show segments'"
-        (click) = "forceSegment.hide();toggleForceShowSegment(ngLayer)"
-        class = "glyphicon" 
-        #forceSegment = "bs-tooltip"
-        [ngClass] = "ngLayer.type === 'segmentation' ? ('glyphicon-th-large ' + segmentationAdditionalClass) : 'glyphicon-lock muted' ">
+    </i>
+  </div>
+  <div>
+    <i 
+      container = "body"
+      placement = "bottom"
+      [tooltip] = "ngLayer.type === 'segmentation' ? segmentationTooltip() : 'only segmentation layer can hide/show segments'"
+      (click) = "forceSegment.hide();toggleForceShowSegment(ngLayer)"
+      class = "glyphicon" 
+      #forceSegment = "bs-tooltip"
+      [ngClass] = "ngLayer.type === 'segmentation' ? ('glyphicon-th-large ' + segmentationAdditionalClass) : 'glyphicon-lock muted' ">
 
-      </i>
-    </div>
-    <div>
-      <i 
-        (click) = "removeLayer(ngLayer)"
-        container = "body"
-        placement = "bottom"
-        [tooltip] = "checkLocked(ngLayer) ? 'base layers cannot be removed' : 'remove layer'"
-        class = "glyphicon"
-        [ngClass] = "checkLocked(ngLayer) ? 'glyphicon-lock muted' : 'glyphicon-remove-circle'">
+    </i>
+  </div>
+  <div>
+    <i 
+      (click) = "removeLayer(ngLayer)"
+      container = "body"
+      placement = "bottom"
+      [tooltip] = "checkLocked(ngLayer) ? 'base layers cannot be removed' : 'remove layer'"
+      class = "glyphicon"
+      [ngClass] = "checkLocked(ngLayer) ? 'glyphicon-lock muted' : 'glyphicon-remove-circle'">
 
-      </i>
-    </div>
+    </i>
+  </div>
 
-    <panel-component
-      [ngClass] = "{'muted-text muted' : !classVisible(ngLayer)}">
+  <panel-component
+    [ngClass] = "{'muted-text muted' : !classVisible(ngLayer)}">
 
-      <div heading>
-        {{ ngLayer.name | getLayerNameFromDatasets : (fetchedDataEntries$ | async) }} : {{ ngLayer.type }}
-      </div>
+    <div heading>
+      {{ ngLayer.name | getLayerNameFromDatasets : (fetchedDataEntries$ | async) }} : {{ ngLayer.type }}
+    </div>
 
-      <div bodyy>
-        {{ ngLayer.source }}
-      </div>
-    </panel-component>
-  </div>
+    <div bodyy>
+      {{ ngLayer.source }}
+    </div>
+  </panel-component>
 </div>
\ No newline at end of file
diff --git a/src/ui/nehubaContainer/nehubaContainer.template.html b/src/ui/nehubaContainer/nehubaContainer.template.html
index b3158ad21..4157818ad 100644
--- a/src/ui/nehubaContainer/nehubaContainer.template.html
+++ b/src/ui/nehubaContainer/nehubaContainer.template.html
@@ -128,6 +128,7 @@
     </div>
   </div>
 </layout-floating-container>
+
 <mobile-overlay 
   *ngIf = "isMobile && viewerLoaded" 
   [tunableProperties] = "tunableMobileProperties" 
diff --git a/src/ui/nehubaContainer/nehubaViewer/nehubaViewer.style.css b/src/ui/nehubaContainer/nehubaViewer/nehubaViewer.style.css
index d28e3a33b..a67e6b395 100644
--- a/src/ui/nehubaContainer/nehubaViewer/nehubaViewer.style.css
+++ b/src/ui/nehubaContainer/nehubaViewer/nehubaViewer.style.css
@@ -1,4 +1,15 @@
 div#neuroglancer-container
 {
   height:100%;
+  width: 100%;
+}
+
+[placeholder]
+{
+  height:100%;
+  width: 100%;
+  justify-content: center;
+  align-items: center;
+  display:flex;
+  flex-direction: column;
 }
\ No newline at end of file
diff --git a/src/ui/nehubaContainer/nehubaViewer/nehubaViewer.template.html b/src/ui/nehubaContainer/nehubaViewer/nehubaViewer.template.html
index a17ab3e39..4af0dd0b5 100644
--- a/src/ui/nehubaContainer/nehubaViewer/nehubaViewer.template.html
+++ b/src/ui/nehubaContainer/nehubaViewer/nehubaViewer.template.html
@@ -1,7 +1,7 @@
 <div id = "neuroglancer-container">
-  <div *ngIf = "constantService.loadExportNehubaPromise ? !(constantService.loadExportNehubaPromise | async) : true">
+  <div placeholder *ngIf = "constantService.loadExportNehubaPromise ? !(constantService.loadExportNehubaPromise | async) : true">
     <h1 tyle = "text-align:center;">
-      Loading Nehuba Viewer ...
+      loading nehuba viewer
     </h1>
     <h1 style = "text-align:center;">
       <span class = "homeAnimationDots loadingAnimationDots">&bull;</span>
diff --git a/src/ui/templateParcellationCitations/templateParcellationCitations.component.ts b/src/ui/templateParcellationCitations/templateParcellationCitations.component.ts
index 4754fe01f..edffccf8e 100644
--- a/src/ui/templateParcellationCitations/templateParcellationCitations.component.ts
+++ b/src/ui/templateParcellationCitations/templateParcellationCitations.component.ts
@@ -2,7 +2,7 @@ import { Component } from "@angular/core";
 import { Observable } from "rxjs";
 import { ViewerStateInterface, isDefined, safeFilter } from "../../services/stateStore.service";
 import { Store, select } from "@ngrx/store";
-import { filter, switchMap, map } from "rxjs/operators";
+import { switchMap, map } from "rxjs/operators";
 
 @Component({
   selector : 'template-parcellation-citation-container',
-- 
GitLab