Quellcode durchsuchen

feat(admin-ui): Add & remove FacetValue to ProductCategory

Michael Bromley vor 7 Jahren
Ursprung
Commit
4629f0251a

+ 1 - 1
admin-ui/src/app/catalog/components/facet-detail/facet-detail.component.html

@@ -92,7 +92,7 @@
         </table>
 
         <div>
-            <button type="button" class="btn btn-primary" (click)="addFacetValue()">
+            <button type="button" class="btn btn-secondary" (click)="addFacetValue()">
                 <clr-icon shape="add"></clr-icon>
                 {{ 'catalog.add-facet-value' | translate }}
             </button>

+ 16 - 0
admin-ui/src/app/catalog/components/product-category-detail/product-category-detail.component.html

@@ -60,4 +60,20 @@
             ></vdr-product-assets>
         </div>
     </div>
+    <div class="clr-row">
+        <div class="clr-col">
+            <h3>{{ 'catalog.facets' | translate }}</h3>
+            <div class="facets">
+                <vdr-facet-value-chip
+                    *ngFor="let facetValue of (facetValues$ | async)"
+                    [facetValue]="facetValue"
+                    (remove)="removeValueFacet(facetValue.id)"
+                ></vdr-facet-value-chip>
+            </div>
+            <button class="btn btn-secondary" (click)="addFacetValue()">
+                <clr-icon shape="plus"></clr-icon>
+                {{ 'catalog.add-facet' | translate }}
+            </button>
+        </div>
+    </div>
 </form>

+ 85 - 17
admin-ui/src/app/catalog/components/product-category-detail/product-category-detail.component.ts

@@ -1,24 +1,36 @@
 import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core';
 import { FormBuilder, FormGroup, Validators } from '@angular/forms';
 import { ActivatedRoute, Router } from '@angular/router';
-import { combineLatest, forkJoin, Observable } from 'rxjs';
-import { mergeMap, take } from 'rxjs/operators';
+import { combineLatest, Observable } from 'rxjs';
+import {
+    filter,
+    map,
+    mergeMap,
+    shareReplay,
+    startWith,
+    switchMap,
+    take,
+    withLatestFrom,
+} from 'rxjs/operators';
 import {
     CreateProductCategoryInput,
-    CreateProductInput,
+    FacetValue,
+    FacetWithValues,
     LanguageCode,
     ProductCategory,
     UpdateProductCategoryInput,
-    UpdateProductInput,
 } from 'shared/generated-types';
 import { CustomFieldConfig } from 'shared/shared-types';
 
 import { BaseDetailComponent } from '../../../common/base-detail.component';
 import { createUpdatedTranslatable } from '../../../common/utilities/create-updated-translatable';
+import { flattenFacetValues } from '../../../common/utilities/flatten-facet-values';
 import { _ } from '../../../core/providers/i18n/mark-for-extraction';
 import { NotificationService } from '../../../core/providers/notification/notification.service';
 import { DataService } from '../../../data/providers/data.service';
 import { ServerConfigService } from '../../../data/server-config';
+import { ModalService } from '../../../shared/providers/modal/modal.service';
+import { ApplyFacetDialogComponent } from '../apply-facet-dialog/apply-facet-dialog.component';
 
 @Component({
     selector: 'vdr-product-category-detail',
@@ -31,6 +43,8 @@ export class ProductCategoryDetailComponent extends BaseDetailComponent<ProductC
     customFields: CustomFieldConfig[];
     categoryForm: FormGroup;
     assetChanges: { assetIds?: string[]; featuredAssetId?: string } = {};
+    facetValues$: Observable<FacetValue.Fragment[]>;
+    private facets$: Observable<FacetWithValues.Fragment[]>;
 
     constructor(
         router: Router,
@@ -40,12 +54,14 @@ export class ProductCategoryDetailComponent extends BaseDetailComponent<ProductC
         private dataService: DataService,
         private formBuilder: FormBuilder,
         private notificationService: NotificationService,
+        private modalService: ModalService,
     ) {
         super(route, router, serverConfigService);
         this.customFields = this.getCustomFieldConfig('ProductCategory');
         this.categoryForm = this.formBuilder.group({
             name: ['', Validators.required],
             description: '',
+            facetValueIds: [[]],
             customFields: this.formBuilder.group(
                 this.customFields.reduce((hash, field) => ({ ...hash, [field.name]: '' }), {}),
             ),
@@ -54,6 +70,23 @@ export class ProductCategoryDetailComponent extends BaseDetailComponent<ProductC
 
     ngOnInit() {
         this.init();
+        this.facets$ = this.dataService.facet
+            .getFacets(9999999, 0)
+            .mapSingle(data => data.facets.items)
+            .pipe(shareReplay(1));
+
+        const facetValues$ = this.facets$.pipe(map(facets => flattenFacetValues(facets)));
+        const facetValueIds$ = this.entity$.pipe(
+            filter(category => !!(category && category.facetValues)),
+            take(1),
+            switchMap(category => this.categoryForm.valueChanges),
+            startWith(this.categoryForm.value),
+            map(formValue => formValue.facetValueIds),
+        );
+
+        this.facetValues$ = combineLatest(facetValueIds$, facetValues$).pipe(
+            map(([ids, facetValues]) => ids.map(id => facetValues.find(fv => fv.id === id))),
+        );
     }
 
     ngOnDestroy() {
@@ -68,6 +101,42 @@ export class ProductCategoryDetailComponent extends BaseDetailComponent<ProductC
         return !!Object.values(this.assetChanges).length;
     }
 
+    addFacetValue() {
+        this.facets$
+            .pipe(
+                take(1),
+                mergeMap(facets =>
+                    this.modalService.fromComponent(ApplyFacetDialogComponent, {
+                        size: 'md',
+                        locals: { facets },
+                    }),
+                ),
+                map(facetValues => facetValues && facetValues.map(v => v.id)),
+                withLatestFrom(this.entity$),
+            )
+            .subscribe(([facetValueIds, category]) => {
+                if (facetValueIds) {
+                    const existingFacetValueIds = this.categoryForm.value.facetValueIds;
+                    const uniqueFacetValueIds = Array.from(
+                        new Set([...existingFacetValueIds, ...facetValueIds]),
+                    );
+                    this.categoryForm.patchValue({
+                        facetValueIds: uniqueFacetValueIds,
+                    });
+                    this.categoryForm.markAsDirty();
+                    this.changeDetector.markForCheck();
+                }
+            });
+    }
+
+    removeValueFacet(id: string) {
+        const facetValueIds = this.categoryForm.value.facetValueIds.filter(fvid => fvid !== id);
+        this.categoryForm.patchValue({
+            facetValueIds,
+        });
+        this.categoryForm.markAsDirty();
+    }
+
     create() {
         if (!this.categoryForm.dirty) {
             return;
@@ -103,18 +172,12 @@ export class ProductCategoryDetailComponent extends BaseDetailComponent<ProductC
                 take(1),
                 mergeMap(([category, languageCode]) => {
                     const updateOperations: Array<Observable<any>> = [];
-
-                    if (this.categoryForm.dirty || this.assetsChanged()) {
-                        const input = this.getUpdatedCategory(
-                            category,
-                            this.categoryForm,
-                            languageCode,
-                        ) as UpdateProductCategoryInput;
-                        if (input) {
-                            updateOperations.push(this.dataService.product.updateProductCategory(input));
-                        }
-                    }
-                    return forkJoin(updateOperations);
+                    const input = this.getUpdatedCategory(
+                        category,
+                        this.categoryForm,
+                        languageCode,
+                    ) as UpdateProductCategoryInput;
+                    return this.dataService.product.updateProductCategory(input);
                 }),
             )
             .subscribe(
@@ -142,6 +205,7 @@ export class ProductCategoryDetailComponent extends BaseDetailComponent<ProductC
             this.categoryForm.patchValue({
                 name: currentTranslation.name,
                 description: currentTranslation.description,
+                facetValueIds: category.facetValues.map(fv => fv.id),
             });
 
             if (this.customFields.length) {
@@ -182,6 +246,10 @@ export class ProductCategoryDetailComponent extends BaseDetailComponent<ProductC
                 description: category.description || '',
             },
         });
-        return { ...updatedCategory, ...this.assetChanges };
+        return {
+            ...updatedCategory,
+            ...this.assetChanges,
+            facetValueIds: this.categoryForm.value.facetValueIds,
+        };
     }
 }

+ 4 - 0
admin-ui/src/app/data/definitions/product-definitions.ts

@@ -317,6 +317,10 @@ export const GET_PRODUCT_CATEGORY_LIST = gql`
                     id
                     code
                     name
+                    facet {
+                        id
+                        name
+                    }
                 }
                 parent {
                     id

+ 15 - 2
admin-ui/src/app/data/providers/product-data.service.ts

@@ -201,7 +201,13 @@ export class ProductDataService {
         return this.baseDataService.mutate<CreateProductCategory.Mutation, CreateProductCategory.Variables>(
             CREATE_PRODUCT_CATEGORY,
             {
-                input: pick(input, ['translations', 'assetIds', 'featuredAssetId', 'customFields']),
+                input: pick(input, [
+                    'translations',
+                    'assetIds',
+                    'featuredAssetId',
+                    'facetValueIds',
+                    'customFields',
+                ]),
             },
         );
     }
@@ -210,7 +216,14 @@ export class ProductDataService {
         return this.baseDataService.mutate<UpdateProductCategory.Mutation, UpdateProductCategory.Variables>(
             UPDATE_PRODUCT_CATEGORY,
             {
-                input: pick(input, ['id', 'translations', 'assetIds', 'featuredAssetId', 'customFields']),
+                input: pick(input, [
+                    'id',
+                    'translations',
+                    'assetIds',
+                    'featuredAssetId',
+                    'facetValueIds',
+                    'customFields',
+                ]),
             },
         );
     }

+ 7 - 0
shared/generated-types.ts

@@ -5357,6 +5357,13 @@ export namespace GetProductCategoryList {
         id: string;
         code: string;
         name: string;
+        facet: Facet;
+    };
+
+    export type Facet = {
+        __typename?: 'Facet';
+        id: string;
+        name: string;
     };
 
     export type Parent = {