Browse Source

fix(admin-ui): Fix form change detection in collection filters

Michael Bromley 3 years ago
parent
commit
0938be00e1

+ 9 - 5
packages/admin-ui/src/lib/catalog/src/components/collection-detail/collection-detail.component.ts

@@ -33,7 +33,7 @@ import {
     UpdateCollectionInput,
 } from '@vendure/admin-ui/core';
 import { normalizeString } from '@vendure/common/lib/normalize-string';
-import { combineLatest, Observable, of } from 'rxjs';
+import { combineLatest, merge, Observable, of, Subject } from 'rxjs';
 import { debounceTime, filter, map, mergeMap, switchMap, take } from 'rxjs/operators';
 
 import { CollectionContentsComponent } from '../collection-contents/collection-contents.component';
@@ -57,6 +57,7 @@ export class CollectionDetailComponent
     livePreview = false;
     parentId$: Observable<string | undefined>;
     readonly updatePermission = [Permission.UpdateCatalog, Permission.UpdateCollection];
+    private filterRemoved$ = new Subject<void>();
     @ViewChild('collectionContents') contentsComponent: CollectionContentsComponent;
 
     constructor(
@@ -91,14 +92,14 @@ export class CollectionDetailComponent
             this.allFilters = res.collectionFilters;
         });
         const filtersFormArray = this.detailForm.get('filters') as FormArray;
-        this.updatedFilters$ = filtersFormArray.statusChanges.pipe(
+        this.updatedFilters$ = merge(filtersFormArray.statusChanges, this.filterRemoved$).pipe(
             debounceTime(200),
             filter(() => filtersFormArray.touched),
-            map(status =>
-                this.mapOperationsToInputs(this.filters, filtersFormArray.value).filter(filter => {
+            map(() =>
+                this.mapOperationsToInputs(this.filters, filtersFormArray.value).filter(_filter => {
                     // ensure all the arguments have valid values. E.g. a newly-added
                     // filter will not yet have valid values
-                    for (const arg of filter.arguments) {
+                    for (const arg of _filter.arguments) {
                         if (arg.value === '') {
                             return false;
                         }
@@ -172,7 +173,10 @@ export class CollectionDetailComponent
         const filtersArray = this.detailForm.get('filters') as FormArray;
         if (index !== -1) {
             filtersArray.removeAt(index);
+            filtersArray.markAsDirty();
+            filtersArray.markAsTouched();
             this.filters.splice(index, 1);
+            this.filterRemoved$.next();
         }
     }
 

+ 8 - 7
packages/admin-ui/src/lib/core/src/shared/dynamic-form-inputs/combination-mode-form-input/combination-mode-form-input.component.ts

@@ -1,4 +1,4 @@
-import { ChangeDetectionStrategy, Component, Optional } from '@angular/core';
+import { ChangeDetectionStrategy, Component, OnInit, Optional } from '@angular/core';
 import { FormControl } from '@angular/forms';
 import { DefaultFormComponentConfig, DefaultFormComponentId } from '@vendure/common/lib/shared-types';
 import { Observable, of } from 'rxjs';
@@ -20,22 +20,23 @@ import { ConfigurableInputComponent } from '../../components/configurable-input/
     styleUrls: ['./combination-mode-form-input.component.scss'],
     changeDetection: ChangeDetectionStrategy.OnPush,
 })
-export class CombinationModeFormInputComponent implements FormInputComponent {
+export class CombinationModeFormInputComponent implements FormInputComponent, OnInit {
     static readonly id: DefaultFormComponentId = 'combination-mode-form-input';
     readonly: boolean;
     formControl: FormControl;
     config: DefaultFormComponentConfig<'combination-mode-form-input'>;
     selectable$: Observable<boolean>;
 
-    constructor(@Optional() private configurableInputComponent: ConfigurableInputComponent) {
-        const selectable$ = configurableInputComponent
-            ? configurableInputComponent.positionChange$.pipe(map(position => 0 < position))
-            : of(true);
+    constructor(@Optional() private configurableInputComponent: ConfigurableInputComponent) {}
 
+    ngOnInit() {
+        const selectable$ = this.configurableInputComponent
+            ? this.configurableInputComponent.positionChange$.pipe(map(position => 0 < position))
+            : of(true);
         this.selectable$ = selectable$.pipe(
             tap(selectable => {
                 if (!selectable) {
-                    this.setCombinationModeAnd();
+                    this.formControl.setValue(true, { emitEvent: false });
                 }
             }),
         );