Browse Source

feat(admin-ui): Split ProductDetail into tabs

Michael Bromley 7 years ago
parent
commit
ab64882c74

+ 62 - 52
admin-ui/src/app/catalog/components/product-detail/product-detail.component.html

@@ -21,63 +21,73 @@
 
 <form class="form" [formGroup]="productForm" *ngIf="product$ | async as product">
 
-    <div class="clr-row">
-        <div class="clr-col">
-    <section class="form-block" formGroupName="product">
-        <vdr-form-field [label]="'catalog.product-name' | translate" for="name">
-            <input id="name" type="text" formControlName="name" (input)="updateSlug($event.target.value)">
-        </vdr-form-field>
-        <vdr-form-field [label]="'catalog.slug' | translate" for="slug">
-            <input id="slug" type="text" formControlName="slug">
-        </vdr-form-field>
-        <vdr-rich-text-editor formControlName="description"
-                              [label]="'common.description' | translate"></vdr-rich-text-editor>
+    <clr-tabs>
+        <clr-tab>
+            <button clrTabLink  (click)="navigateToTab('details')">{{ 'catalog.product-details' | translate }}</button>
+            <clr-tab-content *clrIfActive="(activeTab$ | async) === 'details'">
+                <div class="clr-row">
+                    <div class="clr-col">
+                        <section class="form-block" formGroupName="product">
+                            <vdr-form-field [label]="'catalog.product-name' | translate" for="name">
+                                <input id="name" type="text" formControlName="name" (input)="updateSlug($event.target.value)">
+                            </vdr-form-field>
+                            <vdr-form-field [label]="'catalog.slug' | translate" for="slug">
+                                <input id="slug" type="text" formControlName="slug">
+                            </vdr-form-field>
+                            <vdr-rich-text-editor formControlName="description"
+                                                  [label]="'common.description' | translate"></vdr-rich-text-editor>
 
-        <section formGroupName="customFields" *ngIf="customFields.length">
-            <label>{{ 'common.custom-fields' | translate }}</label>
-            <ng-container *ngFor="let customField of customFields">
-                <vdr-custom-field-control *ngIf="customFieldIsSet(customField.name)"
-                                          [customFieldsFormGroup]="productForm.get(['product', 'customFields'])"
-                                          [customField]="customField"></vdr-custom-field-control>
-            </ng-container>
-        </section>
-    </section>
-        </div>
-        <div class="clr-col-md-auto">
-            <vdr-product-assets [assets]="product.assets"
-                                [featuredAsset]="product.featuredAsset"
-                                (change)="assetChanges = $event"></vdr-product-assets>
-        </div>
-    </div>
+                            <section formGroupName="customFields" *ngIf="customFields.length">
+                                <label>{{ 'common.custom-fields' | translate }}</label>
+                                <ng-container *ngFor="let customField of customFields">
+                                    <vdr-custom-field-control *ngIf="customFieldIsSet(customField.name)"
+                                                              [customFieldsFormGroup]="productForm.get(['product', 'customFields'])"
+                                                              [customField]="customField"></vdr-custom-field-control>
+                                </ng-container>
+                            </section>
+                        </section>
+                    </div>
+                    <div class="clr-col-md-auto">
+                        <vdr-product-assets [assets]="product.assets"
+                                            [featuredAsset]="product.featuredAsset"
+                                            (change)="assetChanges = $event"></vdr-product-assets>
+                    </div>
+                </div>
+            </clr-tab-content>
+        </clr-tab>
+        <clr-tab>
+            <button clrTabLink (click)="navigateToTab('variants')">{{ 'catalog.product-variants' | translate }}</button>
+            <clr-tab-content *clrIfActive="(activeTab$ | async) === 'variants'">
+                <section class="form-block" *ngIf="!(isNew$ | async)">
+                    <vdr-generate-product-variants *ngIf="(variants$ | async)?.length === 0; else variants"
+                                                   [product]="product"></vdr-generate-product-variants>
 
-    <section class="form-block" *ngIf="!(isNew$ | async)">
+                    <ng-template #variants>
+                        <vdr-form-item *ngIf="product?.optionGroups.length"
+                                       [label]="'catalog.product-option-groups' | translate">
+                            <div class="option-groups-list">
+                                <div *ngFor="let optionGroup of product?.optionGroups"
+                                     class="option-group">
+                                    <vdr-chip>{{ optionGroup.name }} ({{ optionGroup.code }})</vdr-chip>
+                                </div>
+                            </div>
+                        </vdr-form-item>
 
-        <label>{{ 'catalog.product-variants' | translate }}</label>
+                        <vdr-product-variants-list [variants]="variants$ | async"
+                                                   [productVariantsFormArray]="productForm.get('variants')"
+                                                   [taxCategories]="taxCategories$ | async"
+                                                   #productVariantsList>
+                            <button class="btn btn-sm btn-secondary" (click)="selectFacetValue(productVariantsList.selectedVariantIds)">
+                                {{ 'catalog.apply-facets' | translate }}
+                            </button>
+                        </vdr-product-variants-list>
+                    </ng-template>
 
-        <vdr-generate-product-variants *ngIf="(variants$ | async)?.length === 0; else variants"
-                                       [product]="product"></vdr-generate-product-variants>
+                </section>
+            </clr-tab-content>
+        </clr-tab>
+    </clr-tabs>
 
-        <ng-template #variants>
-            <vdr-form-item *ngIf="product?.optionGroups.length"
-                           [label]="'catalog.product-option-groups' | translate">
-                <div class="option-groups-list">
-                    <div *ngFor="let optionGroup of product?.optionGroups"
-                         class="option-group">
-                        <vdr-chip>{{ optionGroup.name }} ({{ optionGroup.code }})</vdr-chip>
-                    </div>
-                </div>
-            </vdr-form-item>
-
-            <vdr-product-variants-list [variants]="variants$ | async"
-                                       [productVariantsFormArray]="productForm.get('variants')"
-                                       [taxCategories]="taxCategories$ | async"
-                                       #productVariantsList>
-                <button class="btn btn-sm btn-secondary" (click)="selectFacetValue(productVariantsList.selectedVariantIds)">
-                    {{ 'catalog.apply-facets' | translate }}
-                </button>
-            </vdr-product-variants-list>
-        </ng-template>
 
-    </section>
 
 </form>

+ 14 - 0
admin-ui/src/app/catalog/components/product-detail/product-detail.component.ts

@@ -1,3 +1,4 @@
+import { Location } from '@angular/common';
 import { ChangeDetectionStrategy, Component, OnDestroy, OnInit } from '@angular/core';
 import { FormArray, FormBuilder, FormGroup, Validators } from '@angular/forms';
 import { ActivatedRoute, Router } from '@angular/router';
@@ -24,6 +25,8 @@ import { ServerConfigService } from '../../../data/server-config';
 import { ModalService } from '../../../shared/providers/modal/modal.service';
 import { ApplyFacetDialogComponent } from '../apply-facet-dialog/apply-facet-dialog.component';
 
+export type TabName = 'details' | 'variants';
+
 @Component({
     selector: 'vdr-product-detail',
     templateUrl: './product-detail.component.html',
@@ -32,6 +35,7 @@ import { ApplyFacetDialogComponent } from '../apply-facet-dialog/apply-facet-dia
 })
 export class ProductDetailComponent extends BaseDetailComponent<ProductWithVariants.Fragment>
     implements OnInit, OnDestroy {
+    activeTab$: Observable<TabName>;
     product$: Observable<ProductWithVariants.Fragment>;
     variants$: Observable<ProductWithVariants.Variants[]>;
     taxCategories$: Observable<TaxCategory.Fragment[]>;
@@ -48,6 +52,7 @@ export class ProductDetailComponent extends BaseDetailComponent<ProductWithVaria
         private formBuilder: FormBuilder,
         private modalService: ModalService,
         private notificationService: NotificationService,
+        private location: Location,
     ) {
         super(route, router, serverConfigService);
         this.customFields = this.getCustomFieldConfig('Product');
@@ -72,12 +77,21 @@ export class ProductDetailComponent extends BaseDetailComponent<ProductWithVaria
         this.taxCategories$ = this.dataService.settings
             .getTaxCategories()
             .mapSingle(data => data.taxCategories);
+        this.activeTab$ = this.route.queryParamMap.pipe(map(qpm => qpm.get('tab') as any));
     }
 
     ngOnDestroy() {
         this.destroy();
     }
 
+    navigateToTab(tabName: TabName) {
+        this.router.navigate(['./'], {
+            queryParams: { tab: tabName },
+            relativeTo: this.route,
+            queryParamsHandling: 'merge',
+        });
+    }
+
     customFieldIsSet(name: string): boolean {
         return !!this.productForm.get(['product', 'customFields', name]);
     }

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

@@ -51,7 +51,7 @@
     "price": "Price",
     "price-includes-tax-at": "Price includes tax at { rate }%",
     "price-with-tax-in-default-zone": "Price with { rate }% tax: { price }",
-    "product": "Product",
+    "product-details": "Product details",
     "product-name": "Product name",
     "product-option-groups": "Option groups",
     "product-variants": "Product variants",