Browse Source

feat(admin-ui): Filter Collection contents by name

Michael Bromley 6 years ago
parent
commit
331dd44627

+ 15 - 7
admin-ui/src/app/catalog/components/collection-list/collection-list.component.html

@@ -15,14 +15,22 @@
 
     <div class="collection-contents" [class.expanded]="activeCollectionId$ | async">
         <div class="contents-header">
-            <div class="collection-title">
-                {{ activeCollectionTitle$ | async }} ({{
-                    'common.results-count' | translate: { count: contentsTotalItems$ | async }
-                }})
+            <div class="header-title-row">
+                <div class="collection-title">
+                    {{ activeCollectionTitle$ | async }} ({{
+                        'common.results-count' | translate: { count: contentsTotalItems$ | async }
+                    }})
+                </div>
+                <button type="button" class="close-button" (click)="closeContents()">
+                    <clr-icon shape="close"></clr-icon>
+                </button>
             </div>
-            <button type="button" class="close-button" (click)="closeContents()">
-                <clr-icon shape="close"></clr-icon>
-            </button>
+            <input
+                type="text"
+                [placeholder]="'catalog.filter-by-name' | translate"
+                class="clr-input"
+                [formControl]="filterTermControl"
+            />
         </div>
         <vdr-data-table
             [items]="contents$ | async"

+ 8 - 5
admin-ui/src/app/catalog/components/collection-list/collection-list.component.scss

@@ -31,9 +31,6 @@
         }
 
         .contents-header {
-            display: flex;
-            justify-content: space-between;
-            align-items: center;
             background-color: $color-grey-1;
             position: sticky;
             top: 0;
@@ -41,8 +38,10 @@
             z-index: 1;
             border-bottom: 1px solid $color-grey-3;
 
-            .collection-title {
-
+            .header-title-row {
+                display: flex;
+                justify-content: space-between;
+                align-items: center;
             }
 
             .close-button {
@@ -51,6 +50,10 @@
                 border: none;
                 cursor: pointer;
             }
+
+            .clr-input {
+                width: 100%;
+            }
         }
         ::ng-deep table {
             margin-top: -1px;

+ 20 - 3
admin-ui/src/app/catalog/components/collection-list/collection-list.component.ts

@@ -1,7 +1,16 @@
 import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
+import { FormControl } from '@angular/forms';
 import { ActivatedRoute, Router } from '@angular/router';
 import { combineLatest, Observable, of } from 'rxjs';
-import { distinctUntilChanged, map, startWith, switchMap, takeUntil } from 'rxjs/operators';
+import {
+    debounceTime,
+    distinctUntilChanged,
+    map,
+    startWith,
+    switchMap,
+    takeUntil,
+    tap,
+} from 'rxjs/operators';
 import { GetCollectionContents, GetCollectionList } from 'shared/generated-types';
 
 import { BaseListComponent } from '../../../common/base-list.component';
@@ -25,6 +34,7 @@ export class CollectionListComponent
     contentsCurrentPage$: Observable<number>;
     activeCollectionId$: Observable<string | null>;
     activeCollectionTitle$: Observable<string>;
+    filterTermControl = new FormControl('');
 
     constructor(
         private dataService: DataService,
@@ -59,18 +69,25 @@ export class CollectionListComponent
             distinctUntilChanged(),
         );
 
+        const filterTerm$ = this.filterTermControl.valueChanges.pipe(
+            debounceTime(250),
+            tap(() => this.setContentsPageNumber(1)),
+            startWith(''),
+        );
+
         const collection$ = combineLatest(
             this.activeCollectionId$,
             this.contentsCurrentPage$,
             this.contentsItemsPerPage$,
+            filterTerm$,
         ).pipe(
             takeUntil(this.destroy$),
-            switchMap(([id, currentPage, itemsPerPage]) => {
+            switchMap(([id, currentPage, itemsPerPage, filterTerm]) => {
                 if (id) {
                     const take = itemsPerPage;
                     const skip = (currentPage - 1) * itemsPerPage;
                     return this.dataService.collection
-                        .getCollectionContents(id, take, skip)
+                        .getCollectionContents(id, take, skip, filterTerm)
                         .mapSingle(data => data.collection);
                 } else {
                     return of(null);

+ 6 - 1
admin-ui/src/app/data/providers/collection-data.service.ts

@@ -1,6 +1,7 @@
 import { from } from 'rxjs';
 import { bufferCount, concatMap } from 'rxjs/operators';
 import {
+    CollectionFilterParameter,
     CreateCollection,
     CreateCollectionInput,
     GetCollection,
@@ -97,7 +98,10 @@ export class CollectionDataService {
         );
     }
 
-    getCollectionContents(id: string, take: number = 10, skip: number = 0) {
+    getCollectionContents(id: string, take: number = 10, skip: number = 0, filterTerm?: string) {
+        const filter = filterTerm
+            ? ({ name: { contains: filterTerm } } as CollectionFilterParameter)
+            : undefined;
         return this.baseDataService.query<GetCollectionContents.Query, GetCollectionContents.Variables>(
             GET_COLLECTION_CONTENTS,
             {
@@ -105,6 +109,7 @@ export class CollectionDataService {
                 options: {
                     skip,
                     take,
+                    filter,
                 },
             },
         );

+ 1 - 0
admin-ui/src/i18n-messages/en.json

@@ -41,6 +41,7 @@
     "facet": "Facet",
     "facet-values": "Facet values",
     "filter-by-group-name": "Filter by group name",
+    "filter-by-name": "Filter by name",
     "filters": "Filters",
     "generate-product-variants": "Generate product variants",
     "generate-variants-default-only": "This product does not have options",