Przeglądaj źródła

fix(admin-ui): Fix filtering of product variant table

Michael Bromley 5 lat temu
rodzic
commit
121b6fcd0c

+ 6 - 1
packages/admin-ui/src/lib/catalog/src/components/product-detail/product-detail.component.ts

@@ -34,6 +34,7 @@ import {
     distinctUntilChanged,
     map,
     mergeMap,
+    shareReplay,
     startWith,
     switchMap,
     take,
@@ -131,7 +132,11 @@ export class ProductDetailComponent extends BaseDetailComponent<ProductWithVaria
         this.init();
         this.product$ = this.entity$;
         const variants$ = this.product$.pipe(map(product => product.variants));
-        const filterTerm$ = this.filterInput.valueChanges.pipe(startWith(''), debounceTime(50));
+        const filterTerm$ = this.filterInput.valueChanges.pipe(
+            startWith(''),
+            debounceTime(50),
+            shareReplay(),
+        );
         this.variants$ = combineLatest(variants$, filterTerm$).pipe(
             map(([variants, term]) => {
                 return term

+ 8 - 8
packages/admin-ui/src/lib/catalog/src/components/product-variants-table/product-variants-table.component.html

@@ -9,8 +9,8 @@
     <vdr-dt-column>{{ 'catalog.stock-on-hand' | translate }}</vdr-dt-column>
     <vdr-dt-column>{{ 'common.enabled' | translate }}</vdr-dt-column>
     <ng-template let-variant="item" let-i="index">
-        <ng-container [formGroup]="formArray.at(i)">
-            <td class="left align-middle" [class.disabled]="!formArray.get([i, 'enabled'])!.value">
+        <ng-container *ngIf="formGroupMap.get(variant.id) as formGroup" [formGroup]="formGroup">
+            <td class="left align-middle" [class.disabled]="!formGroup.get('enabled')!.value">
                 <div class="card-img">
                     <div class="featured-asset">
                         <img
@@ -23,7 +23,7 @@
                     </div>
                 </div>
             </td>
-            <td class="left align-middle" [class.disabled]="!formArray.get([i, 'enabled'])!.value">
+            <td class="left align-middle" [class.disabled]="!formGroup.get('enabled')!.value">
                 <clr-input-container>
                     <input
                         clrInput
@@ -34,7 +34,7 @@
                     />
                 </clr-input-container>
             </td>
-            <td class="left align-middle" [class.disabled]="!formArray.get([i, 'enabled'])!.value">
+            <td class="left align-middle" [class.disabled]="!formGroup.get('enabled')!.value">
                 <clr-input-container>
                     <input
                         clrInput
@@ -48,13 +48,13 @@
             <ng-container *ngFor="let option of variant.options | sort: 'groupId'">
                 <td
                     class="left align-middle"
-                    [class.disabled]="!formArray.get([i, 'enabled'])!.value"
+                    [class.disabled]="!formGroup.get('enabled')!.value"
                     [style.color]="optionGroupName(option.groupId) | stringToColor"
                 >
                     {{ option.name }}
                 </td>
             </ng-container>
-            <td class="left align-middle price" [class.disabled]="!formArray.get([i, 'enabled'])!.value">
+            <td class="left align-middle price" [class.disabled]="!formGroup.get('enabled')!.value">
                 <clr-input-container>
                     <vdr-currency-input
                         clrInput
@@ -64,7 +64,7 @@
                     ></vdr-currency-input>
                 </clr-input-container>
             </td>
-            <td class="left align-middle stock" [class.disabled]="!formArray.get([i, 'enabled'])!.value">
+            <td class="left align-middle stock" [class.disabled]="!formGroup.get('enabled')!.value">
                 <clr-input-container>
                     <input
                         clrInput
@@ -76,7 +76,7 @@
                     />
                 </clr-input-container>
             </td>
-            <td class="left align-middle stock" [class.disabled]="!formArray.get([i, 'enabled'])!.value">
+            <td class="left align-middle stock" [class.disabled]="!formGroup.get('enabled')!.value">
                 <clr-toggle-wrapper>
                     <input
                         type="checkbox"

+ 44 - 4
packages/admin-ui/src/lib/catalog/src/components/product-variants-table/product-variants-table.component.ts

@@ -1,7 +1,15 @@
-import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
-import { FormArray } from '@angular/forms';
-
+import {
+    ChangeDetectionStrategy,
+    ChangeDetectorRef,
+    Component,
+    Input,
+    OnDestroy,
+    OnInit,
+} from '@angular/core';
+import { FormArray, FormGroup } from '@angular/forms';
 import { ProductWithVariants } from '@vendure/admin-ui/core';
+import { Subscription } from 'rxjs';
+import { debounceTime, distinctUntilChanged, map } from 'rxjs/operators';
 
 @Component({
     selector: 'vdr-product-variants-table',
@@ -9,13 +17,45 @@ import { ProductWithVariants } from '@vendure/admin-ui/core';
     styleUrls: ['./product-variants-table.component.scss'],
     changeDetection: ChangeDetectionStrategy.OnPush,
 })
-export class ProductVariantsTableComponent {
+export class ProductVariantsTableComponent implements OnInit, OnDestroy {
     @Input('productVariantsFormArray') formArray: FormArray;
     @Input() variants: ProductWithVariants.Variants[];
     @Input() optionGroups: ProductWithVariants.OptionGroups[];
+    formGroupMap = new Map<string, FormGroup>();
+    private subscription: Subscription;
+
+    constructor(private changeDetector: ChangeDetectorRef) {}
+
+    ngOnInit() {
+        this.subscription = this.formArray.valueChanges
+            .pipe(
+                map(value => value.length),
+                debounceTime(1),
+                distinctUntilChanged(),
+            )
+            .subscribe(() => {
+                this.buildFormGroupMap();
+            });
+
+        this.buildFormGroupMap();
+    }
+
+    ngOnDestroy() {
+        if (this.subscription) {
+            this.subscription.unsubscribe();
+        }
+    }
 
     optionGroupName(optionGroupId: string): string | undefined {
         const group = this.optionGroups.find(g => g.id === optionGroupId);
         return group && group.name;
     }
+
+    private buildFormGroupMap() {
+        this.formGroupMap.clear();
+        for (const controlGroup of this.formArray.controls) {
+            this.formGroupMap.set(controlGroup.value.id, controlGroup as FormGroup);
+        }
+        this.changeDetector.markForCheck();
+    }
 }