From eb7ef654abb226c72f493f0dd634be92cb9bd2b8 Mon Sep 17 00:00:00 2001
From: Xiao Gui <xgui3783@gmail.com>
Date: Fri, 7 Jul 2023 14:14:17 +0200
Subject: [PATCH] expmt: feature filter

---
 .../region/region/rich/region.rich.style.css  |  7 +-
 .../readmore/readmoreCmp/readmore.style.css   |  4 +-
 .../readmoreCmp/readmore.template.html        |  2 +-
 src/features/entry/entry.component.ts         | 11 ++-
 .../entry/entry.flattened.component.html      | 89 +++++++++++++++++++
 .../entry/entry.flattened.component.scss      | 12 +++
 .../feature-view/feature-view.component.scss  |  5 ++
 src/features/grpFeatToTotal.pipe.ts           | 18 ++++
 src/features/module.ts                        |  5 ++
 .../ngLayerCtl/ngLayerCtrl.style.css          |  5 ++
 10 files changed, 152 insertions(+), 6 deletions(-)
 create mode 100644 src/features/grpFeatToTotal.pipe.ts

diff --git a/src/atlasComponents/sapiViews/core/region/region/rich/region.rich.style.css b/src/atlasComponents/sapiViews/core/region/region/rich/region.rich.style.css
index a897b1ea9..2f9290a93 100644
--- a/src/atlasComponents/sapiViews/core/region/region/rich/region.rich.style.css
+++ b/src/atlasComponents/sapiViews/core/region/region/rich/region.rich.style.css
@@ -9,4 +9,9 @@
   max-height: 16rem;
   overflow-x: hidden;
   overflow-y: scroll;
-}
\ No newline at end of file
+}
+
+readmore-component
+{
+  width: 100%;
+}
diff --git a/src/components/readmore/readmoreCmp/readmore.style.css b/src/components/readmore/readmoreCmp/readmore.style.css
index f49a4a951..d717c128a 100644
--- a/src/components/readmore/readmoreCmp/readmore.style.css
+++ b/src/components/readmore/readmoreCmp/readmore.style.css
@@ -36,9 +36,9 @@ div.readmore-content
   
   background: linear-gradient(
     to bottom,
-    rgba(200,200,200, 0),
+    rgba(255,255,255, 0),
     70%,
-    rgba(200,200,200, 1)
+    rgba(255,255,255, 1)
   );
 }
 
diff --git a/src/components/readmore/readmoreCmp/readmore.template.html b/src/components/readmore/readmoreCmp/readmore.template.html
index 2315e05ad..bfbaf04be 100644
--- a/src/components/readmore/readmoreCmp/readmore.template.html
+++ b/src/components/readmore/readmoreCmp/readmore.template.html
@@ -22,4 +22,4 @@
       class = "fas">
     </i>
   </button>
-</div>
\ No newline at end of file
+</div>
diff --git a/src/features/entry/entry.component.ts b/src/features/entry/entry.component.ts
index d81efe9ce..4a4dfe791 100644
--- a/src/features/entry/entry.component.ts
+++ b/src/features/entry/entry.component.ts
@@ -1,4 +1,4 @@
-import { AfterViewInit, Component, OnDestroy, QueryList, ViewChildren } from '@angular/core';
+import { AfterViewInit, Component, OnDestroy, QueryList, TemplateRef, ViewChildren } from '@angular/core';
 import { select, Store } from '@ngrx/store';
 import { debounceTime, distinctUntilChanged, map, scan, shareReplay, switchMap, take, withLatestFrom } from 'rxjs/operators';
 import { IDS, SAPI } from 'src/atlasComponents/sapi';
@@ -11,6 +11,7 @@ import { combineLatest, concat, forkJoin, merge, of, Subject, Subscription } fro
 import { DsExhausted, IsAlreadyPulling, PulledDataSource } from 'src/util/pullable';
 import { TranslatedFeature } from '../list/list.directive';
 import { SPECIES_ENUM } from 'src/util/constants';
+import { MatDialog } from '@angular/material/dialog';
 
 const categoryAcc = <T extends Record<string, unknown>>(categories: T[]) => {
   const returnVal: Record<string, T[]> = {}
@@ -37,7 +38,7 @@ export class EntryComponent extends FeatureBase implements AfterViewInit, OnDest
   @ViewChildren(CategoryAccDirective)
   catAccDirs: QueryList<CategoryAccDirective>
 
-  constructor(private sapi: SAPI, private store: Store) {
+  constructor(private sapi: SAPI, private store: Store, private dialog: MatDialog) {
     super()
   }
 
@@ -216,4 +217,10 @@ export class EntryComponent extends FeatureBase implements AfterViewInit, OnDest
   pullAll(){
     this.#pullAll.next(null)
   }
+
+  openDialog(tmpl: TemplateRef<unknown>, data?: unknown) {
+    this.dialog.open(tmpl, {
+      data
+    })
+  }
 }
diff --git a/src/features/entry/entry.flattened.component.html b/src/features/entry/entry.flattened.component.html
index 900633de8..a160569b3 100644
--- a/src/features/entry/entry.flattened.component.html
+++ b/src/features/entry/entry.flattened.component.html
@@ -80,6 +80,93 @@
 
             <div class="mat-chip-inner-container">
 
+                <ng-template sxplrExperimentalFlag [experimental]="true" #filterExmpt="sxplrExperimentalFlag" [ngIf]="filterExmpt.show$ | async">
+                <button mat-stroked-button
+                    matTooltip="Filters"
+                    [color]="(filterFeatureCls.unchecked$ | async).length > 0 ? 'primary' : 'default'"
+                    (click)="openDialog(filterDialog)">
+                    <i class="fas fa-filter"></i>
+                    <span class="sxplr-ml-1">Filter</span>
+                    <ng-template [ngIf]="(filterFeatureCls.unchecked$ | async).length > 0">
+                        ({{ (filterFeatureCls.unchecked$ | async).length }})
+                    </ng-template>
+                </button>
+
+                <div class="text-muted">
+                    <ng-template [ngTemplateOutlet]="filterTallyTmpl">
+                    </ng-template>
+                </div>
+                
+                <ng-template #filterDialog>
+                    <h1 mat-dialog-title>
+                        Filter data features
+                    </h1>
+                    <div mat-dialog-content>
+                        <ng-template [ngIf]="!(filterFeatureCls.items) || !(filterFeatureCls.checked$)">
+                            No items to filter
+                        </ng-template>
+
+                        <!-- select all checkbox -->
+                        <mat-selection-list>
+                            <mat-list-option [selected]="(filterFeatureCls.unchecked$ | async).length === 0"
+                                (click)="listOption.selected ? filterList.selectAll() : filterList.deselectAll()"
+                                #listOption>
+                                <span class="text-muted">(all)</span>
+                            </mat-list-option>
+                        </mat-selection-list>
+
+                        <mat-divider></mat-divider>
+
+                        <!-- individual selector -->
+                        <mat-selection-list #filterList="matSelectionList">
+                            <ng-template ngFor [ngForOf]="filterFeatureCls.items" let-item>
+                                <ng-template [ngIf]="item.meta.total > 0">
+                                    <mat-list-option [selected]="filterFeatureCls.checked$ | async | grpFeatToName | includes : item.meta.displayName"
+                                        (selectedChange)="filterFeatureCls.setValue(item, $event)">
+                                        <div>
+                                            <span>
+                                                {{ item.meta.displayName }}
+                                            </span>
+                                            <span class="text-muted">
+                                                ({{ item.meta.total }})
+                                            </span>
+                                        </div>
+                                    </mat-list-option>
+                                </ng-template>
+                            </ng-template>
+                        </mat-selection-list>
+
+                        <mat-divider></mat-divider>
+                        
+                        <div class="text-muted sxplr-mr-2 filter-tally">
+                            <ng-template [ngTemplateOutlet]="filterTallyTmpl"></ng-template>
+                        </div>
+                        
+                    </div>
+                    
+                    <div mat-dialog-actions align="end">
+                        <button mat-flat-button color="primary" (click)="filterList.selectAll()">
+                            Reset
+                        </button>
+                        <button mat-button mat-dialog-close cdkFocusInitial>
+                            Close
+                        </button>
+                    </div>
+                </ng-template>
+
+                <ng-template #filterTallyTmpl>
+                    <ng-template [ngIf]="(filterFeatureCls.unchecked$ | async).length === 0" [ngIfElse]="partialTmpl">
+                        Showing all {{ categoryAcc.total$ | async }} features
+                    </ng-template>
+                    <ng-template #partialTmpl>
+                        Showing {{ filterFeatureCls.checked$ | async | grpFeatTally }} / {{ categoryAcc.total$ | async }} features
+                    </ng-template>
+                </ng-template>
+
+                </ng-template>
+
+
+                <ng-template sxplrExperimentalFlag [deprecated]="true" [ngIf]="filterDep.show$ | async" #filterDep="sxplrExperimentalFlag">
                 <button mat-icon-button matTooltip="Reset filter"
                     (click)="filterFeatureCls.setAll(true)">
                     <i class="fas fa-filter"></i>
@@ -123,6 +210,8 @@
 
                     </ng-template>
                 </ng-template>
+                </ng-template>
+
             </div>
         </div>
 
diff --git a/src/features/entry/entry.flattened.component.scss b/src/features/entry/entry.flattened.component.scss
index 34b69d51f..690e23771 100644
--- a/src/features/entry/entry.flattened.component.scss
+++ b/src/features/entry/entry.flattened.component.scss
@@ -9,6 +9,11 @@ cdk-virtual-scroll-viewport button
     height: 36px;
     display: block;
 }
+:host-context([experimental=true])
+.mat-chip-container
+{
+    overflow-x: unset!important;
+}
 
 .mat-chip-container
 {
@@ -21,6 +26,7 @@ cdk-virtual-scroll-viewport button
 .mat-chip-inner-container
 {
     display: inline-flex;
+    align-items: center;
 }
 
 .mat-chip-inner-container button
@@ -28,3 +34,9 @@ cdk-virtual-scroll-viewport button
     white-space: nowrap;
     margin: 0.2rem 0.4rem;
 }
+
+.filter-tally
+{
+    display: flex;
+    flex-direction: row-reverse;
+}
diff --git a/src/features/feature-view/feature-view.component.scss b/src/features/feature-view/feature-view.component.scss
index d767661ba..05abcbea2 100644
--- a/src/features/feature-view/feature-view.component.scss
+++ b/src/features/feature-view/feature-view.component.scss
@@ -22,3 +22,8 @@ kg-dataset-dumb-line
     display: block;
     max-height: 24rem;
 }
+
+readmore-component
+{
+    width: 100%;
+}
diff --git a/src/features/grpFeatToTotal.pipe.ts b/src/features/grpFeatToTotal.pipe.ts
new file mode 100644
index 000000000..bddce57eb
--- /dev/null
+++ b/src/features/grpFeatToTotal.pipe.ts
@@ -0,0 +1,18 @@
+import { Pipe, PipeTransform } from "@angular/core";
+
+interface MetaHasTotal {
+  meta: {
+    total: number
+  }
+}
+
+@Pipe({
+  name: 'grpFeatTally',
+  pure: true
+})
+
+export class GroupFeatureTallyPipe implements PipeTransform{
+  public transform(groupFeats: MetaHasTotal[]): number {
+    return groupFeats.map(f => f.meta.total).reduce((v, acc) => v + acc, 0)
+  }
+}
diff --git a/src/features/module.ts b/src/features/module.ts
index 72a2cd93c..28557b3f7 100644
--- a/src/features/module.ts
+++ b/src/features/module.ts
@@ -29,6 +29,8 @@ import { GroupFeaturesToName } from "./grpFeatToName.pipe";
 import { ExperimentalModule } from "src/experimental/experimental.module";
 import { MatTabsModule } from "@angular/material/tabs";
 import { ReadmoreModule } from "src/components/readmore";
+import { MatDialogModule } from "@angular/material/dialog";
+import { GroupFeatureTallyPipe } from "./grpFeatToTotal.pipe";
 
 @NgModule({
   imports: [
@@ -52,6 +54,8 @@ import { ReadmoreModule } from "src/components/readmore";
     ExperimentalModule,
     MatTabsModule,
     ReadmoreModule,
+    MatDialogModule,
+    
   ],
   declarations: [
     EntryComponent,
@@ -66,6 +70,7 @@ import { ReadmoreModule } from "src/components/readmore";
     FeatureNamePipe,
     TransformPdToDsPipe,
     GroupFeaturesToName,
+    GroupFeatureTallyPipe,
   ],
   exports: [
     EntryComponent,
diff --git a/src/viewerModule/nehuba/ngLayerCtlModule/ngLayerCtl/ngLayerCtrl.style.css b/src/viewerModule/nehuba/ngLayerCtlModule/ngLayerCtl/ngLayerCtrl.style.css
index ea70c88ed..ff992909a 100644
--- a/src/viewerModule/nehuba/ngLayerCtlModule/ngLayerCtl/ngLayerCtrl.style.css
+++ b/src/viewerModule/nehuba/ngLayerCtlModule/ngLayerCtl/ngLayerCtrl.style.css
@@ -25,3 +25,8 @@ spinner-cmp:has(+ .hydrated)
 {
     display: none;
 }
+
+ng-layer-tune
+{
+    width: 100%;
+}
-- 
GitLab