Browse Source

fix(admin-ui): Correctly display configurable money values

Michael Bromley 6 years ago
parent
commit
3546071b26

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

@@ -80,6 +80,7 @@
                     [facets]="facets$ | async"
                     [operation]="filter"
                     [formControlName]="i"
+                    [activeChannel]="activeChannel$ | async"
                 ></vdr-configurable-input>
             </ng-container>
 

+ 5 - 0
admin-ui/src/app/catalog/components/collection-detail/collection-detail.component.ts

@@ -19,6 +19,7 @@ import {
     ConfigurableOperationInput,
     CreateCollectionInput,
     FacetWithValues,
+    GetActiveChannel,
     LanguageCode,
     UpdateCollectionInput,
 } from '../../../common/generated-types';
@@ -44,6 +45,7 @@ export class CollectionDetailComponent extends BaseDetailComponent<Collection.Fr
     filters: ConfigurableOperation[] = [];
     allFilters: ConfigurableOperation[] = [];
     facets$: Observable<FacetWithValues.Fragment[]>;
+    activeChannel$: Observable<GetActiveChannel.ActiveChannel>;
     @ViewChild('collectionContents') contentsComponent: CollectionContentsComponent;
 
     constructor(
@@ -79,6 +81,9 @@ export class CollectionDetailComponent extends BaseDetailComponent<Collection.Fr
         this.dataService.collection.getCollectionFilters().single$.subscribe(res => {
             this.allFilters = res.collectionFilters;
         });
+        this.activeChannel$ = this.dataService.settings
+            .getActiveChannel()
+            .mapStream(data => data.activeChannel);
     }
 
     ngOnDestroy() {

+ 2 - 0
admin-ui/src/app/marketing/components/promotion-detail/promotion-detail.component.html

@@ -32,6 +32,7 @@
                     [facets]="facets$ | async"
                     [operation]="condition"
                     [formControlName]="i"
+                    [activeChannel]="activeChannel$ | async"
                 ></vdr-configurable-input>
             </ng-container>
 
@@ -64,6 +65,7 @@
                 [facets]="facets$ | async"
                 [operation]="action"
                 [formControlName]="i"
+                [activeChannel]="activeChannel$ | async"
             ></vdr-configurable-input>
             <div>
                 <clr-dropdown>

+ 5 - 0
admin-ui/src/app/marketing/components/promotion-detail/promotion-detail.component.ts

@@ -10,6 +10,7 @@ import {
     ConfigurableOperationInput,
     CreatePromotionInput,
     FacetWithValues,
+    GetActiveChannel,
     LanguageCode,
     Promotion,
     UpdatePromotionInput,
@@ -32,6 +33,7 @@ export class PromotionDetailComponent extends BaseDetailComponent<Promotion.Frag
     conditions: ConfigurableOperation[] = [];
     actions: ConfigurableOperation[] = [];
     facets$: Observable<FacetWithValues.Fragment[]>;
+    activeChannel$: Observable<GetActiveChannel.ActiveChannel>;
 
     private allConditions: ConfigurableOperation[];
     private allActions: ConfigurableOperation[];
@@ -65,6 +67,9 @@ export class PromotionDetailComponent extends BaseDetailComponent<Promotion.Frag
             this.allActions = data.adjustmentOperations.actions;
             this.allConditions = data.adjustmentOperations.conditions;
         });
+        this.activeChannel$ = this.dataService.settings
+            .getActiveChannel()
+            .mapStream(data => data.activeChannel);
     }
 
     ngOnDestroy() {

+ 2 - 0
admin-ui/src/app/settings/components/shipping-method-detail/shipping-method-detail.component.html

@@ -36,6 +36,7 @@
             <vdr-configurable-input
                 *ngIf="selectedChecker"
                 [operation]="selectedChecker"
+                [activeChannel]="activeChannel$ | async"
                 (remove)="selectedChecker = null"
                 formControlName="checker"
             ></vdr-configurable-input>
@@ -65,6 +66,7 @@
             <vdr-configurable-input
                 *ngIf="selectedCalculator"
                 [operation]="selectedCalculator"
+                [activeChannel]="activeChannel$ | async"
                 (remove)="selectedCalculator = null"
                 formControlName="calculator"
             ></vdr-configurable-input>

+ 8 - 2
admin-ui/src/app/settings/components/shipping-method-detail/shipping-method-detail.component.ts

@@ -1,14 +1,15 @@
 import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core';
 import { FormBuilder, FormGroup, Validators } from '@angular/forms';
 import { ActivatedRoute, Router } from '@angular/router';
+import { Observable } from 'rxjs';
 import { mergeMap, take } from 'rxjs/operators';
-import { normalizeString } from 'shared/normalize-string';
 
 import { BaseDetailComponent } from '../../../common/base-detail.component';
 import {
     ConfigurableOperation,
     ConfigurableOperationInput,
     CreateShippingMethodInput,
+    GetActiveChannel,
     ShippingMethod,
     UpdateShippingMethodInput,
 } from '../../../common/generated-types';
@@ -30,6 +31,7 @@ export class ShippingMethodDetailComponent extends BaseDetailComponent<ShippingM
     calculators: ConfigurableOperation[] = [];
     selectedChecker?: ConfigurableOperation;
     selectedCalculator?: ConfigurableOperation;
+    activeChannel$: Observable<GetActiveChannel.ActiveChannel>;
 
     constructor(
         router: Router,
@@ -56,6 +58,10 @@ export class ShippingMethodDetailComponent extends BaseDetailComponent<ShippingM
             this.calculators = data.shippingCalculators;
             this.changeDetector.markForCheck();
         });
+
+        this.activeChannel$ = this.dataService.settings
+            .getActiveChannel()
+            .mapStream(data => data.activeChannel);
     }
 
     ngOnDestroy(): void {
@@ -146,7 +152,7 @@ export class ShippingMethodDetailComponent extends BaseDetailComponent<ShippingM
             code: operation.code,
             arguments: Object.values(formValueOperations.args || {}).map((value, j) => ({
                 name: operation.args[j].name,
-                value: value.toString(),
+                value: value.hasOwnProperty('value') ? (value as any).value : value.toString(),
                 type: operation.args[j].type,
             })),
         };

+ 2 - 1
admin-ui/src/app/shared/components/configurable-input/configurable-input.component.html

@@ -3,7 +3,7 @@
     <div class="card-block" *ngIf="operation.args?.length">
         <form [formGroup]="form" *ngIf="operation" class="operation-inputs">
             <div *ngFor="let arg of operation.args" class="arg-row">
-                <label>{{ arg.name | titlecase }}</label>
+                <label>{{ arg.name | sentenceCase }}</label>
                 <div *ngIf="arg.type === 'boolean'" class="checkbox">
                     <input type="checkbox" [formControlName]="arg.name" [id]="arg.name" />
                     <label [for]="arg.name"></label>
@@ -30,6 +30,7 @@
                 <vdr-currency-input
                     *ngIf="arg.type === ConfigArgType.MONEY"
                     [formControlName]="arg.name"
+                    [currencyCode]="activeChannel?.currencyCode"
                 ></vdr-currency-input>
                 <vdr-percentage-suffix-input
                     *ngIf="arg.type === ConfigArgType.PERCENTAGE"

+ 7 - 1
admin-ui/src/app/shared/components/configurable-input/configurable-input.component.ts

@@ -22,7 +22,12 @@ import {
 } from '@angular/forms';
 import { Subscription } from 'rxjs';
 
-import { ConfigArgType, ConfigurableOperation, FacetWithValues } from '../../../common/generated-types';
+import {
+    ConfigArgType,
+    ConfigurableOperation,
+    FacetWithValues,
+    GetActiveChannel,
+} from '../../../common/generated-types';
 import { interpolateDescription } from '../../../common/utilities/interpolate-description';
 
 /**
@@ -49,6 +54,7 @@ import { interpolateDescription } from '../../../common/utilities/interpolate-de
 export class ConfigurableInputComponent implements OnChanges, OnDestroy, ControlValueAccessor, Validator {
     @Input() operation: ConfigurableOperation;
     @Input() facets: FacetWithValues.Fragment[] = [];
+    @Input() activeChannel: GetActiveChannel.ActiveChannel;
     @Output() remove = new EventEmitter<ConfigurableOperation>();
     argValues: { [name: string]: any } = {};
     onChange: (val: any) => void;

+ 23 - 0
admin-ui/src/app/shared/pipes/sentence-case.pipe.spec.ts

@@ -0,0 +1,23 @@
+import { SentenceCasePipe } from './sentence-case.pipe';
+
+describe('SentenceCasePipe:', () => {
+    let sentenceCasePipe: SentenceCasePipe;
+    beforeEach(() => (sentenceCasePipe = new SentenceCasePipe()));
+
+    it('works with multiple words', () => {
+        expect(sentenceCasePipe.transform('foo bar baz')).toBe('Foo bar baz');
+        expect(sentenceCasePipe.transform('fOo BAR baZ')).toBe('Foo bar baz');
+    });
+
+    it('splits camelCase', () => {
+        expect(sentenceCasePipe.transform('fooBarBaz')).toBe('Foo bar baz');
+        expect(sentenceCasePipe.transform('FooBarbaz')).toBe('Foo barbaz');
+    });
+
+    it('unexpected input', () => {
+        expect(sentenceCasePipe.transform(null as any)).toBe(null);
+        expect(sentenceCasePipe.transform(undefined as any)).toBe(undefined);
+        expect(sentenceCasePipe.transform([] as any)).toEqual([]);
+        expect(sentenceCasePipe.transform(123 as any)).toEqual(123);
+    });
+});

+ 24 - 0
admin-ui/src/app/shared/pipes/sentence-case.pipe.ts

@@ -0,0 +1,24 @@
+import { Pipe, PipeTransform } from '@angular/core';
+
+/**
+ * Formats a string into sentence case (first letter of first word uppercase).
+ */
+@Pipe({ name: 'sentenceCase' })
+export class SentenceCasePipe implements PipeTransform {
+    transform(value: any): any {
+        if (typeof value === 'string') {
+            let lower: string;
+            if (isCamelCase(value)) {
+                lower = value.replace(/([a-z])([A-Z])/g, '$1 $2').toLowerCase();
+            } else {
+                lower = value.toLowerCase();
+            }
+            return lower.charAt(0).toUpperCase() + lower.slice(1);
+        }
+        return value;
+    }
+}
+
+function isCamelCase(value: string): boolean {
+    return /^[a-zA-Z]+[A-Z][a-zA-Z]+$/.test(value);
+}

+ 2 - 0
admin-ui/src/app/shared/shared.module.ts

@@ -41,6 +41,7 @@ import { TitleInputComponent } from './components/title-input/title-input.compon
 import { BackgroundColorFromDirective } from './directives/background-color-from.directive';
 import { CurrencyNamePipe } from './pipes/currency-name.pipe';
 import { FileSizePipe } from './pipes/file-size.pipe';
+import { SentenceCasePipe } from './pipes/sentence-case.pipe';
 import { ModalService } from './providers/modal/modal.service';
 import { CanDeactivateDetailGuard } from './providers/routing/can-deactivate-detail-guard';
 
@@ -88,6 +89,7 @@ const DECLARATIONS = [
     RichTextEditorComponent,
     SimpleDialogComponent,
     TitleInputComponent,
+    SentenceCasePipe,
 ];
 
 @NgModule({