Просмотр исходного кода

feat(admin-ui): Add translationVars to NotificationService methods

Michael Bromley 7 лет назад
Родитель
Сommit
d58d36c8b3

+ 1 - 1
admin-ui/src/app/core/components/notification/notification.component.html

@@ -8,6 +8,6 @@
         'warning': type === 'warning'
         'warning': type === 'warning'
      }">
      }">
     <clr-icon [attr.shape]="getIcon()" size="24"></clr-icon>
     <clr-icon [attr.shape]="getIcon()" size="24"></clr-icon>
-    {{ message | translate }}
+    {{ message | translate:translationVars }}
 </div>
 </div>
 
 

+ 1 - 0
admin-ui/src/app/core/components/notification/notification.component.ts

@@ -11,6 +11,7 @@ export class NotificationComponent {
     @ViewChild('wrapper') wrapper: ElementRef;
     @ViewChild('wrapper') wrapper: ElementRef;
     offsetTop = 0;
     offsetTop = 0;
     message = '';
     message = '';
+    translationVars: { [key: string]: string | number } = {};
     type: NotificationType = 'info';
     type: NotificationType = 'info';
     isVisible = true;
     isVisible = true;
     private onClickFn: () => void = () => {
     private onClickFn: () => void = () => {

+ 14 - 0
admin-ui/src/app/core/providers/i18n/i18n.service.mock.ts

@@ -0,0 +1,14 @@
+import { MockOf } from '../../../../testing/testing-types';
+import { LanguageCode } from '../../../data/types/gql-generated-types';
+
+import { I18nService } from './i18n.service';
+
+export class MockI18nService implements MockOf<I18nService> {
+    setLanguage(language: LanguageCode) {
+        // blank
+    }
+
+    translate(key: string | string[], params?: any) {
+        return key as string;
+    }
+}

+ 5 - 1
admin-ui/src/app/core/providers/i18n/i18n.service.ts

@@ -7,7 +7,11 @@ import { LanguageCode } from '../../../data/types/gql-generated-types';
 @Injectable()
 @Injectable()
 export class I18nService {
 export class I18nService {
     constructor(private ngxTranslate: TranslateService) {
     constructor(private ngxTranslate: TranslateService) {
-        ngxTranslate.setDefaultLang(getDefaultLanguage());
+        // For some unknown reason, calling `setDefaultLang(getDefaultLanguage())`
+        // produces a stack overflow in some cases, wheras assigning an intermediate
+        // var does not. ¯\_(ツ)_/¯
+        const defaultLang = getDefaultLanguage();
+        ngxTranslate.setDefaultLang(defaultLang);
     }
     }
 
 
     /**
     /**

+ 7 - 1
admin-ui/src/app/core/providers/notification/notification.service.spec.ts

@@ -5,6 +5,8 @@ import { BrowserDynamicTestingModule } from '@angular/platform-browser-dynamic/t
 import { TestingCommonModule } from '../../../../testing/testing-common.module';
 import { TestingCommonModule } from '../../../../testing/testing-common.module';
 import { NotificationComponent } from '../../components/notification/notification.component';
 import { NotificationComponent } from '../../components/notification/notification.component';
 import { OverlayHostComponent } from '../../components/overlay-host/overlay-host.component';
 import { OverlayHostComponent } from '../../components/overlay-host/overlay-host.component';
+import { I18nService } from '../i18n/i18n.service';
+import { MockI18nService } from '../i18n/i18n.service.mock';
 import { OverlayHostService } from '../overlay-host/overlay-host.service';
 import { OverlayHostService } from '../overlay-host/overlay-host.service';
 
 
 import { NotificationService } from './notification.service';
 import { NotificationService } from './notification.service';
@@ -14,7 +16,11 @@ describe('NotificationService:', () => {
         TestBed.configureTestingModule({
         TestBed.configureTestingModule({
             imports: [TestingCommonModule],
             imports: [TestingCommonModule],
             declarations: [NotificationComponent, OverlayHostComponent, TestComponent],
             declarations: [NotificationComponent, OverlayHostComponent, TestComponent],
-            providers: [NotificationService, OverlayHostService],
+            providers: [
+                NotificationService,
+                OverlayHostService,
+                { provide: I18nService, useClass: MockI18nService },
+            ],
             schemas: [CUSTOM_ELEMENTS_SCHEMA],
             schemas: [CUSTOM_ELEMENTS_SCHEMA],
         });
         });
         // TODO: it looks like there will be an easier way to declare the entryComponents,
         // TODO: it looks like there will be an easier way to declare the entryComponents,

+ 27 - 5
admin-ui/src/app/core/providers/notification/notification.service.ts

@@ -3,10 +3,12 @@ import { ComponentFactoryResolver, ComponentRef, Injectable, ViewContainerRef }
 import { OverlayHostService } from '../overlay-host/overlay-host.service';
 import { OverlayHostService } from '../overlay-host/overlay-host.service';
 
 
 import { NotificationComponent } from '../../components/notification/notification.component';
 import { NotificationComponent } from '../../components/notification/notification.component';
+import { I18nService } from '../i18n/i18n.service';
 
 
 export type NotificationType = 'info' | 'success' | 'error' | 'warning';
 export type NotificationType = 'info' | 'success' | 'error' | 'warning';
 export interface ToastConfig {
 export interface ToastConfig {
     message: string;
     message: string;
+    translationVars?: { [key: string]: string | number };
     type?: NotificationType;
     type?: NotificationType;
     duration?: number;
     duration?: number;
 }
 }
@@ -22,7 +24,11 @@ export class NotificationService {
     private hostView: ViewContainerRef;
     private hostView: ViewContainerRef;
     private openToastRefs: Array<{ ref: ComponentRef<NotificationComponent>; timerId: any }> = [];
     private openToastRefs: Array<{ ref: ComponentRef<NotificationComponent>; timerId: any }> = [];
 
 
-    constructor(private resolver: ComponentFactoryResolver, overlayHostService: OverlayHostService) {
+    constructor(
+        private i18nService: I18nService,
+        private resolver: ComponentFactoryResolver,
+        overlayHostService: OverlayHostService,
+    ) {
         overlayHostService.getHostView().then(view => {
         overlayHostService.getHostView().then(view => {
             this.hostView = view;
             this.hostView = view;
         });
         });
@@ -31,9 +37,10 @@ export class NotificationService {
     /**
     /**
      * Display a success toast notification
      * Display a success toast notification
      */
      */
-    success(message: string): void {
+    success(message: string, translationVars?: { [key: string]: string | number }): void {
         this.notify({
         this.notify({
             message,
             message,
+            translationVars,
             type: 'success',
             type: 'success',
         });
         });
     }
     }
@@ -41,9 +48,10 @@ export class NotificationService {
     /**
     /**
      * Display an info toast notification
      * Display an info toast notification
      */
      */
-    info(message: string): void {
+    info(message: string, translationVars?: { [key: string]: string | number }): void {
         this.notify({
         this.notify({
             message,
             message,
+            translationVars,
             type: 'info',
             type: 'info',
         });
         });
     }
     }
@@ -51,9 +59,10 @@ export class NotificationService {
     /**
     /**
      * Display a warning toast notification
      * Display a warning toast notification
      */
      */
-    warning(message: string): void {
+    warning(message: string, translationVars?: { [key: string]: string | number }): void {
         this.notify({
         this.notify({
             message,
             message,
+            translationVars,
             type: 'warning',
             type: 'warning',
         });
         });
     }
     }
@@ -61,9 +70,10 @@ export class NotificationService {
     /**
     /**
      * Display an error toast notification
      * Display an error toast notification
      */
      */
-    error(message: string): void {
+    error(message: string, translationVars?: { [key: string]: string | number }): void {
         this.notify({
         this.notify({
             message,
             message,
+            translationVars,
             type: 'error',
             type: 'error',
             duration: 20000,
             duration: 20000,
         });
         });
@@ -86,6 +96,7 @@ export class NotificationService {
         const dismissFn = this.createDismissFunction(ref);
         const dismissFn = this.createDismissFunction(ref);
         toast.type = config.type || 'info';
         toast.type = config.type || 'info';
         toast.message = config.message;
         toast.message = config.message;
+        toast.translationVars = this.translateTranslationVars(config.translationVars || {});
         toast.registerOnClickFn(dismissFn);
         toast.registerOnClickFn(dismissFn);
 
 
         let timerId;
         let timerId;
@@ -130,4 +141,15 @@ export class NotificationService {
             cumulativeHeight += toast.getHeight() + 6;
             cumulativeHeight += toast.getHeight() + 6;
         });
         });
     }
     }
+
+    private translateTranslationVars(translationVars: {
+        [key: string]: string | number;
+    }): { [key: string]: string | number } {
+        for (const [key, val] of Object.entries(translationVars)) {
+            if (typeof val === 'string') {
+                translationVars[key] = this.i18nService.translate(val);
+            }
+        }
+        return translationVars;
+    }
 }
 }