From 17597594b0693c8fbfaa9180ac5629ad1dd8c1e9 Mon Sep 17 00:00:00 2001
From: Xiao Gui <xgui3783@gmail.com>
Date: Tue, 21 Mar 2023 14:27:30 +0100
Subject: [PATCH] chore: update threesurfer chore: introduce min width for
 smart chip feat: improve perf mesh loading fix: reset panel mode/panel order

---
 deploy/csp/index.js                           |   2 +-
 .../pureDumb/pureATPSelector.style.scss       |   5 +
 .../smartChip/component/smartChip.style.scss  |   5 +
 .../component/smartChip.template.html         |   2 +-
 src/index.html                                |   2 +-
 src/state/atlasSelection/effects.ts           |   2 +-
 .../nehuba/config.service/util.ts             |   2 +-
 .../layerCtrl.service/layerCtrl.effects.ts    |   6 +-
 .../nehuba/mesh.service/mesh.service.ts       | 167 +++++++++++-------
 src/viewerModule/nehuba/viewerCtrl/effects.ts |  14 +-
 10 files changed, 129 insertions(+), 78 deletions(-)

diff --git a/deploy/csp/index.js b/deploy/csp/index.js
index 4acafa2eb..10c756eac 100644
--- a/deploy/csp/index.js
+++ b/deploy/csp/index.js
@@ -112,7 +112,7 @@ module.exports = {
           'unpkg.com/kg-dataset-previewer@1.2.0/', // preview component
           'https://unpkg.com/d3@6.2.0/', // required for preview component
           'https://unpkg.com/mathjax@3.1.2/', // math jax
-          'https://unpkg.com/three-surfer@0.0.11/dist/bundle.js', // for threeSurfer (freesurfer support in browser)
+          'https://unpkg.com/three-surfer@0.0.13/dist/bundle.js', // for threeSurfer (freesurfer support in browser)
           'https://unpkg.com/ng-layer-tune@0.0.6/dist/ng-layer-tune/', // needed for ng layer control
           'https://unpkg.com/hbp-connectivity-component@0.6.5/', // needed for connectivity component
           (req, res) => res.locals.nonce ? `'nonce-${res.locals.nonce}'` : null,
diff --git a/src/atlasComponents/sapiViews/core/rich/ATPSelector/pureDumb/pureATPSelector.style.scss b/src/atlasComponents/sapiViews/core/rich/ATPSelector/pureDumb/pureATPSelector.style.scss
index f5c72a7f8..f19870a13 100644
--- a/src/atlasComponents/sapiViews/core/rich/ATPSelector/pureDumb/pureATPSelector.style.scss
+++ b/src/atlasComponents/sapiViews/core/rich/ATPSelector/pureDumb/pureATPSelector.style.scss
@@ -19,6 +19,11 @@
   margin-left: 0.2rem;
 }
 
+sxplr-smart-chip
+{
+  min-width: 10rem;
+}
+
 sxplr-smart-chip:not(:last-child)
 {
   margin-left: -2.5rem;
diff --git a/src/components/smartChip/component/smartChip.style.scss b/src/components/smartChip/component/smartChip.style.scss
index a360f49e8..ecd483246 100644
--- a/src/components/smartChip/component/smartChip.style.scss
+++ b/src/components/smartChip/component/smartChip.style.scss
@@ -19,6 +19,11 @@
   align-items: center;
 }
 
+.smart-chip.body
+{
+  width: 100%;
+}
+
 .smart-chip
 {
   opacity: 1.0;
diff --git a/src/components/smartChip/component/smartChip.template.html b/src/components/smartChip/component/smartChip.template.html
index a4b6d51cf..96964d1be 100644
--- a/src/components/smartChip/component/smartChip.template.html
+++ b/src/components/smartChip/component/smartChip.template.html
@@ -4,7 +4,7 @@
   matRipple
   [matRippleDisabled]="noMenuFlag"
   [ngClass]="smartChipClass"
-  class="mat-body smart-chip sxplr-custom-cmp text">
+  class="mat-body smart-chip body sxplr-custom-cmp text">
   <ng-template [ngTemplateOutlet]="contentTmpl?.templateRef || fallbackContentTmpl">
   </ng-template>
 </div>
diff --git a/src/index.html b/src/index.html
index 447426b28..8b04e68c0 100644
--- a/src/index.html
+++ b/src/index.html
@@ -13,7 +13,7 @@
   <link rel="icon" type="image/png" href="assets/favicons/favicon-128-light.png"/>
   <script src="extra_js.js"></script>
   <script src="https://unpkg.com/kg-dataset-previewer@1.2.0/dist/kg-dataset-previewer/kg-dataset-previewer.js" defer></script>
-  <script src="https://unpkg.com/three-surfer@0.0.11/dist/bundle.js" defer></script>
+  <script src="https://unpkg.com/three-surfer@0.0.13/dist/bundle.js" defer></script>
   <script type="module" src="https://unpkg.com/ng-layer-tune@0.0.6/dist/ng-layer-tune/ng-layer-tune.esm.js"></script>
   <script type="module" src="https://unpkg.com/hbp-connectivity-component@0.6.5/dist/connectivity-component/connectivity-component.js" ></script>
   <script defer src="https://unpkg.com/mathjax@3.1.2/es5/tex-svg.js"></script>
diff --git a/src/state/atlasSelection/effects.ts b/src/state/atlasSelection/effects.ts
index cc372b388..673a54d0f 100644
--- a/src/state/atlasSelection/effects.ts
+++ b/src/state/atlasSelection/effects.ts
@@ -1,7 +1,7 @@
 import { Injectable } from "@angular/core";
 import { Actions, createEffect, ofType } from "@ngrx/effects";
 import { forkJoin, merge, NEVER, Observable, of } from "rxjs";
-import { catchError, filter, map, mapTo, switchMap, switchMapTo, take, withLatestFrom } from "rxjs/operators";
+import { filter, map, mapTo, switchMap, switchMapTo, take, withLatestFrom } from "rxjs/operators";
 import { SAPI, SAPIRegion } from "src/atlasComponents/sapi";
 import * as mainActions from "../actions"
 import { select, Store } from "@ngrx/store";
diff --git a/src/viewerModule/nehuba/config.service/util.ts b/src/viewerModule/nehuba/config.service/util.ts
index 25b90e91c..fa76f139a 100644
--- a/src/viewerModule/nehuba/config.service/util.ts
+++ b/src/viewerModule/nehuba/config.service/util.ts
@@ -311,7 +311,7 @@ export function getNehubaConfig(space: SxplrTemplate): NehubaConfig {
 
   // enable surface parcellation
   // otherwise, on segmentation selection, the unselected meshes will also be invisible
-  const surfaceParcellation = space["@id"] === 'minds/core/referencespace/v1.0.0/7f39f7be-445b-47c0-9791-e971c0b6d992'
+  const surfaceParcellation = space.id === 'minds/core/referencespace/v1.0.0/7f39f7be-445b-47c0-9791-e971c0b6d992'
   return {
     "configName": "",
     "globals": {
diff --git a/src/viewerModule/nehuba/layerCtrl.service/layerCtrl.effects.ts b/src/viewerModule/nehuba/layerCtrl.service/layerCtrl.effects.ts
index 5c5a85fd3..68f181a86 100644
--- a/src/viewerModule/nehuba/layerCtrl.service/layerCtrl.effects.ts
+++ b/src/viewerModule/nehuba/layerCtrl.service/layerCtrl.effects.ts
@@ -3,7 +3,7 @@ import { createEffect } from "@ngrx/effects";
 import { select, Store } from "@ngrx/store";
 import { forkJoin, from, of } from "rxjs";
 import { switchMap, withLatestFrom, filter, catchError, map, debounceTime, shareReplay, distinctUntilChanged, startWith, pairwise, tap } from "rxjs/operators";
-import { Feature, NgSegLayerSpec, SxplrAtlas, SxplrParcellation, SxplrTemplate, VoiFeature } from "src/atlasComponents/sapi/sxplrTypes";
+import { Feature, NgLayerSpec, NgPrecompMeshSpec, NgSegLayerSpec, SxplrAtlas, SxplrParcellation, SxplrTemplate, VoiFeature } from "src/atlasComponents/sapi/sxplrTypes";
 import { SAPI } from "src/atlasComponents/sapi"
 import { atlasAppearance, atlasSelection, userInteraction } from "src/state";
 import { arrayEqual } from "src/util/array";
@@ -153,7 +153,7 @@ export class LayerCtrlEffects {
       forkJoin({
         tmplNgLayers: this.sapi.getVoxelTemplateImage(template).pipe(
           map(templateImages => {
-            const returnObj = {}
+            const returnObj: Record<string, NgLayerSpec> = {}
             for (const img of templateImages) {
               returnObj[QuickHash.GetHash(img.source)] = img
             }
@@ -162,7 +162,7 @@ export class LayerCtrlEffects {
         ),
         tmplAuxNgLayers: this.sapi.getVoxelAuxMesh(template).pipe(
           map(auxMeshes => {
-            const returnObj = {}
+            const returnObj: Record<string, NgPrecompMeshSpec> = {}
             for (const img of auxMeshes) {
               returnObj[QuickHash.GetHash(`${img.source}_auxMesh`)] = img
             }
diff --git a/src/viewerModule/nehuba/mesh.service/mesh.service.ts b/src/viewerModule/nehuba/mesh.service/mesh.service.ts
index 4ad0dbf18..29a40e94c 100644
--- a/src/viewerModule/nehuba/mesh.service/mesh.service.ts
+++ b/src/viewerModule/nehuba/mesh.service/mesh.service.ts
@@ -1,12 +1,11 @@
 import { Injectable, OnDestroy } from "@angular/core";
 import { select, Store } from "@ngrx/store";
-import { combineLatest, merge, Observable, of } from "rxjs";
-import { map, switchMap, tap } from "rxjs/operators";
+import { combineLatest, Observable, of } from "rxjs";
+import { map, switchMap } from "rxjs/operators";
 import { IMeshesToLoad } from '../constants'
 import { selectorAuxMeshes } from "../store";
 import { LayerCtrlEffects } from "../layerCtrl.service/layerCtrl.effects";
 import { atlasSelection } from "src/state";
-import { Tree } from "src/components/flatHierarchy/treeView/treeControl"
 import { BaseService } from "../base.service/base.service";
 
 /**
@@ -32,79 +31,115 @@ export class NehubaMeshService implements OnDestroy {
 
   public auxMeshes$ = this.effect.onATPDebounceNgLayers$.pipe(
     map(({ tmplAuxNgLayers }) => tmplAuxNgLayers),
-    tap(v => console.log('mesh.service', v))
   )
 
-  public loadMeshes$: Observable<IMeshesToLoad> = merge(
-    combineLatest([
-      this.baseService.completeNgIdLabelRegionMap$,
-      this.store$.pipe(
-        select(atlasSelection.selectors.selectedParcAllRegions),
-      ),
-      this.store$.pipe(
-        select(atlasSelection.selectors.selectedRegions),
-      ),
-      
-    ]).pipe(
-      switchMap(([record, regions, selectedRegions]) => {
-        const ngIdRecord: Record<string, number[]> = {}
-        
-        const tree = new Tree(
-          regions,
-          (c, p) => (c.parentIds.some( id => p.id === id))
-        )
-        
-        const selectedRegionFlag = selectedRegions.length > 0
-        const selectedRegionNameSet = new Set(selectedRegions.map(r => r.name))
-
-        for (const [ngId, labelToRegion] of Object.entries(record)) {
-          for (const [label, region] of Object.entries(labelToRegion)) {
-            if (selectedRegionFlag && !selectedRegionNameSet.has(region.name)) {
-              continue
-            }
-            if (!ngIdRecord[ngId]) {
-              ngIdRecord[ngId] = []
-            }
-            ngIdRecord[ngId].push(Number(label))
+  #allSegmentMeshes$ = this.baseService.completeNgIdLabelRegionMap$.pipe(
+    map(record => {
+      const ngIdRecord: Record<string, number[]> = {}
+
+      for (const [ngId, labelToRegion] of Object.entries(record)) {
+        for (const [label, _region] of Object.entries(labelToRegion)) {
+          if (!ngIdRecord[ngId]) {
+            ngIdRecord[ngId] = []
           }
+          ngIdRecord[ngId].push(Number(label))
         }
+      }
 
-        const arr: IMeshesToLoad[] = []
+      const arr: IMeshesToLoad[] = []
 
-        for (const ngId in ngIdRecord) {
-          const labelIndicies = ngIdRecord[ngId]
-          arr.push({
-            labelIndicies,
-            layer: { name: ngId }
-          })
-        }
-  
-        return of(...arr)
-      })
-    ),
+      for (const ngId in ngIdRecord) {
+        const labelIndicies = ngIdRecord[ngId]
+        arr.push({
+          labelIndicies,
+          layer: { name: ngId }
+        })
+      }
+
+      return arr
+    })
+  )
+
+  #selectedSegmentMeshes$ = combineLatest([
+    this.baseService.completeNgIdLabelRegionMap$,
     this.store$.pipe(
-      select(selectorAuxMeshes),
-      switchMap(auxMeshes => {
-        const obj: Record<string, number[]> = {}
-        const arr: IMeshesToLoad[] = []
-        for (const mesh of auxMeshes) {
-          if (!obj[mesh.ngId]) {
-            obj[mesh.ngId] = []
+      select(atlasSelection.selectors.selectedRegions),
+    ),
+  ]).pipe(
+    switchMap(([record, selectedRegions]) => {
+      const ngIdRecord: Record<string, number[]> = {}
+      
+      const selectedRegionNameSet = new Set(selectedRegions.map(r => r.name))
+
+      for (const [ngId, labelToRegion] of Object.entries(record)) {
+        for (const [label, region] of Object.entries(labelToRegion)) {
+          if (!ngIdRecord[ngId]) {
+            ngIdRecord[ngId] = []
           }
-          if (mesh.visible) {
-            obj[mesh.ngId].push(...mesh.labelIndicies)
+          if (!selectedRegionNameSet.has(region.name)) {
+            continue
           }
+          ngIdRecord[ngId].push(Number(label))
+        }
+      }
+
+      const arr: IMeshesToLoad[] = []
+
+      for (const ngId in ngIdRecord) {
+        const labelIndicies = ngIdRecord[ngId]
+        arr.push({
+          labelIndicies,
+          layer: { name: ngId }
+        })
+      }
+
+      return of(arr)
+    })
+  )
+
+  #auxMesh$ = this.store$.pipe(
+    select(selectorAuxMeshes),
+    switchMap(auxMeshes => {
+      const obj: Record<string, number[]> = {}
+      const arr: IMeshesToLoad[] = []
+      for (const mesh of auxMeshes) {
+        if (!obj[mesh.ngId]) {
+          obj[mesh.ngId] = []
         }
-        for (const key in obj) {
-          arr.push({
-            layer: {
-              name: key
-            },
-            labelIndicies: obj[key]
-          })
+        if (mesh.visible) {
+          obj[mesh.ngId].push(...mesh.labelIndicies)
         }
-        return of(...arr)
-      })
-    )
+      }
+      for (const key in obj) {
+        arr.push({
+          layer: {
+            name: key
+          },
+          labelIndicies: obj[key]
+        })
+      }
+      return of(arr)
+    })
+  )
+
+  public loadMeshes$: Observable<IMeshesToLoad> = combineLatest([
+    this.#allSegmentMeshes$,
+    this.#selectedSegmentMeshes$,
+    this.#auxMesh$,
+  ]).pipe(
+    switchMap(([ allSegMesh, selectedSegMesh, auxmesh ]) => {
+      const hasSegSelected = selectedSegMesh.some(v => v.labelIndicies.length !== 0)
+      const hasAuxMesh = auxmesh.length > 0
+      const meshesToLoad: IMeshesToLoad[] = []
+      if (!hasSegSelected) {
+        meshesToLoad.push(
+          ...(hasAuxMesh ? selectedSegMesh : allSegMesh),
+          ...auxmesh,
+        )
+      } else {
+        meshesToLoad.push(...selectedSegMesh, ...auxmesh)
+      }
+      return of(...meshesToLoad)
+    })
   )
 }
diff --git a/src/viewerModule/nehuba/viewerCtrl/effects.ts b/src/viewerModule/nehuba/viewerCtrl/effects.ts
index 1e62acc8e..fd10b9db4 100644
--- a/src/viewerModule/nehuba/viewerCtrl/effects.ts
+++ b/src/viewerModule/nehuba/viewerCtrl/effects.ts
@@ -1,16 +1,22 @@
 import { Injectable } from "@angular/core";
 import { createEffect } from "@ngrx/effects";
 import { Store } from "@ngrx/store";
-import { mapTo } from "rxjs/operators";
+import { of } from "rxjs";
+import { mapTo, switchMap } from "rxjs/operators";
 import { atlasSelection, userInterface } from "src/state";
 
 @Injectable()
 export class ViewerCtrlEffects {
   onTemplateChangeResetLayout$ = createEffect(() => this.store$.pipe(
     atlasSelection.fromRootStore.distinctATP(),
-    mapTo(userInterface.actions.setPanelMode({
-      panelMode: "FOUR_PANEL"
-    }))
+    switchMap(() => of(
+      userInterface.actions.setPanelMode({
+        panelMode: "FOUR_PANEL"
+      }),
+      userInterface.actions.setPanelOrder({
+        order: '0123'
+      }),
+    ))
   ))
 
   constructor(private store$: Store){}
-- 
GitLab