]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/dashboard: Use I18N in TypeScript strings
authorTiago Melo <tmelo@suse.com>
Tue, 30 Oct 2018 18:17:32 +0000 (18:17 +0000)
committerTiago Melo <tmelo@suse.com>
Wed, 14 Nov 2018 18:53:03 +0000 (18:53 +0000)
Signed-off-by: Tiago Melo <tmelo@suse.com>
91 files changed:
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi/iscsi.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi/iscsi.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/mirroring.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/mirroring.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-images/rbd-images.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-list/rbd-list.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-list/rbd-list.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-snapshot-form/rbd-snapshot-form.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-restore-modal/rbd-trash-restore-modal.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-list/cephfs-list.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-list/cephfs-list.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/configuration/configuration.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/configuration/configuration.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/hosts.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/hosts.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/monitor/monitor.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/monitor/monitor.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-list/osd-list.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-list/osd-list.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health/health.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health/health.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/mds-summary.pipe.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/mds-summary.pipe.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/mgr-summary.pipe.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/mgr-summary.pipe.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/mon-summary.pipe.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/mon-summary.pipe.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/osd-summary.pipe.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/osd-summary.pipe.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/performance-counter/performance-counter/performance-counter.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/performance-counter/table-performance-counter/table-performance-counter.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/performance-counter/table-performance-counter/table-performance-counter.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-tooltips.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-form/pool-form-data.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-form/pool-form.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-form/pool-form.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-list/pool-list.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-list/pool-list.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-501/rgw-501.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts
src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-details/role-details.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-details/role-details.component.ts
src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-form/role-form.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-form/role-form.component.ts
src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-list/role-list.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-list/role-list.component.ts
src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-form/user-form.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-form/user-form.component.ts
src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-list/user-list.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-list/user-list.component.ts
src/pybind/mgr/dashboard/frontend/src/app/core/navigation/navigation/navigation.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/core/navigation/notifications/notifications.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/core/navigation/task-manager/task-manager.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/shared/components/grafana/grafana.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/shared/components/info-panel/info-panel.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/shared/components/info-panel/info-panel.component.ts
src/pybind/mgr/dashboard/frontend/src/app/shared/services/api-interceptor.service.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/shared/services/notification.service.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/shared/services/task-list.service.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/shared/services/task-message.service.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/shared/services/task-message.service.ts
src/pybind/mgr/dashboard/frontend/src/app/shared/services/task-wrapper.service.spec.ts
src/pybind/mgr/dashboard/frontend/src/testing/unit-test-helper.ts

index 983051e55621f1fb8304cff4ec15eafe0fd300db..45648292795d8540a777c9788b572ab69a7df437 100644 (file)
@@ -3,7 +3,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
 
 import { of } from 'rxjs';
 
-import { configureTestBed } from '../../../../testing/unit-test-helper';
+import { configureTestBed, i18nProviders } from '../../../../testing/unit-test-helper';
 import { TcmuIscsiService } from '../../../shared/api/tcmu-iscsi.service';
 import { CephShortVersionPipe } from '../../../shared/pipes/ceph-short-version.pipe';
 import { DimlessPipe } from '../../../shared/pipes/dimless.pipe';
@@ -36,7 +36,8 @@ describe('IscsiComponent', () => {
       FormatterService,
       RelativeDatePipe,
       ListPipe,
-      { provide: TcmuIscsiService, useValue: fakeService }
+      { provide: TcmuIscsiService, useValue: fakeService },
+      i18nProviders
     ]
   });
 
index b12c7974e5750113074192bad90d1eb3b44c9c62..0b9195ec417b5ef98b3fe5eedc5a25c4144812ae 100644 (file)
@@ -1,5 +1,7 @@
 import { Component } from '@angular/core';
 
+import { I18n } from '@ngx-translate/i18n-polyfill';
+
 import { TcmuIscsiService } from '../../../shared/api/tcmu-iscsi.service';
 import { CellTemplate } from '../../../shared/enum/cell-template.enum';
 import { CephShortVersionPipe } from '../../../shared/pipes/ceph-short-version.pipe';
@@ -23,70 +25,71 @@ export class IscsiComponent {
     cephShortVersionPipe: CephShortVersionPipe,
     dimlessPipe: DimlessPipe,
     relativeDatePipe: RelativeDatePipe,
-    listPipe: ListPipe
+    listPipe: ListPipe,
+    private i18n: I18n
   ) {
     this.daemonsColumns = [
       {
-        name: 'Hostname',
+        name: this.i18n('Hostname'),
         prop: 'server_hostname'
       },
       {
-        name: '# Active/Optimized',
+        name: this.i18n('# Active/Optimized'),
         prop: 'optimized_paths'
       },
       {
-        name: '# Active/Non-Optimized',
+        name: this.i18n('# Active/Non-Optimized'),
         prop: 'non_optimized_paths'
       },
       {
-        name: 'Version',
+        name: this.i18n('Version'),
         prop: 'version',
         pipe: cephShortVersionPipe
       }
     ];
     this.imagesColumns = [
       {
-        name: 'Pool',
+        name: this.i18n('Pool'),
         prop: 'pool_name'
       },
       {
-        name: 'Image',
+        name: this.i18n('Image'),
         prop: 'name'
       },
       {
-        name: 'Active/Optimized',
+        name: this.i18n('Active/Optimized'),
         prop: 'optimized_paths',
         pipe: listPipe
       },
       {
-        name: 'Active/Non-Optimized',
+        name: this.i18n('Active/Non-Optimized'),
         prop: 'non_optimized_paths',
         pipe: listPipe
       },
       {
-        name: 'Read Bytes',
+        name: this.i18n('Read Bytes'),
         prop: 'stats_history.rd_bytes',
         cellTransformation: CellTemplate.sparkline
       },
       {
-        name: 'Write Bytes',
+        name: this.i18n('Write Bytes'),
         prop: 'stats_history.wr_bytes',
         cellTransformation: CellTemplate.sparkline
       },
       {
-        name: 'Read Ops',
+        name: this.i18n('Read Ops'),
         prop: 'stats.rd',
         pipe: dimlessPipe,
         cellTransformation: CellTemplate.perSecond
       },
       {
-        name: 'Write Ops',
+        name: this.i18n('Write Ops'),
         prop: 'stats.wr',
         pipe: dimlessPipe,
         cellTransformation: CellTemplate.perSecond
       },
       {
-        name: 'A/O Since',
+        name: this.i18n('A/O Since'),
         prop: 'optimized_since',
         pipe: relativeDatePipe
       }
index 43647a46ad67be0cbc58acb2464f0d15644f0083..cec99ebf5ea570e497d62d217d8f85151e9cbd46 100644 (file)
@@ -5,7 +5,7 @@ import { BsDropdownModule } from 'ngx-bootstrap/dropdown';
 import { ProgressbarModule } from 'ngx-bootstrap/progressbar';
 import { TabsModule } from 'ngx-bootstrap/tabs';
 
-import { configureTestBed } from '../../../../testing/unit-test-helper';
+import { configureTestBed, i18nProviders } from '../../../../testing/unit-test-helper';
 import { SharedModule } from '../../../shared/shared.module';
 import { MirrorHealthColorPipe } from '../mirror-health-color.pipe';
 import { MirroringComponent } from './mirroring.component';
@@ -22,7 +22,8 @@ describe('MirroringComponent', () => {
       TabsModule.forRoot(),
       ProgressbarModule.forRoot(),
       HttpClientTestingModule
-    ]
+    ],
+    providers: i18nProviders
   });
 
   beforeEach(() => {
index 11586e8a12b8c2af7b89ffacc47f9078bbaeebbc..c39ba3a36eb4f18a514c2b136342a517997147fb 100644 (file)
@@ -1,5 +1,7 @@
 import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core';
 
+import { I18n } from '@ngx-translate/i18n-polyfill';
+
 import { RbdMirroringService } from '../../../shared/api/rbd-mirroring.service';
 import { ViewCacheStatus } from '../../../shared/enum/view-cache-status.enum';
 import { CephShortVersionPipe } from '../../../shared/pipes/ceph-short-version.pipe';
@@ -45,78 +47,79 @@ export class MirroringComponent implements OnInit {
 
   constructor(
     private rbdMirroringService: RbdMirroringService,
-    private cephShortVersionPipe: CephShortVersionPipe
+    private cephShortVersionPipe: CephShortVersionPipe,
+    private i18n: I18n
   ) {}
 
   ngOnInit() {
     this.daemons.columns = [
-      { prop: 'instance_id', name: 'Instance', flexGrow: 2 },
-      { prop: 'id', name: 'ID', flexGrow: 2 },
-      { prop: 'server_hostname', name: 'Hostname', flexGrow: 2 },
+      { prop: 'instance_id', name: this.i18n('Instance'), flexGrow: 2 },
+      { prop: 'id', name: this.i18n('ID'), flexGrow: 2 },
+      { prop: 'server_hostname', name: this.i18n('Hostname'), flexGrow: 2 },
       {
         prop: 'version',
-        name: 'Version',
+        name: this.i18n('Version'),
         pipe: this.cephShortVersionPipe,
         flexGrow: 2
       },
       {
         prop: 'health',
-        name: 'Health',
+        name: this.i18n('Health'),
         cellTemplate: this.healthTmpl,
         flexGrow: 1
       }
     ];
 
     this.pools.columns = [
-      { prop: 'name', name: 'Name', flexGrow: 2 },
-      { prop: 'mirror_mode', name: 'Mode', flexGrow: 2 },
-      { prop: 'leader_id', name: 'Leader', flexGrow: 2 },
-      { prop: 'image_local_count', name: '# Local', flexGrow: 2 },
-      { prop: 'image_remote_count', name: '# Remote', flexGrow: 2 },
+      { prop: 'name', name: this.i18n('Name'), flexGrow: 2 },
+      { prop: 'mirror_mode', name: this.i18n('Mode'), flexGrow: 2 },
+      { prop: 'leader_id', name: this.i18n('Leader'), flexGrow: 2 },
+      { prop: 'image_local_count', name: this.i18n('# Local'), flexGrow: 2 },
+      { prop: 'image_remote_count', name: this.i18n('# Remote'), flexGrow: 2 },
       {
         prop: 'health',
-        name: 'Health',
+        name: this.i18n('Health'),
         cellTemplate: this.healthTmpl,
         flexGrow: 1
       }
     ];
 
     this.image_error.columns = [
-      { prop: 'pool_name', name: 'Pool', flexGrow: 2 },
-      { prop: 'name', name: 'Image', flexGrow: 2 },
-      { prop: 'description', name: 'Issue', flexGrow: 4 },
+      { prop: 'pool_name', name: this.i18n('Pool'), flexGrow: 2 },
+      { prop: 'name', name: this.i18n('Image'), flexGrow: 2 },
+      { prop: 'description', name: this.i18n('Issue'), flexGrow: 4 },
       {
         prop: 'state',
-        name: 'State',
+        name: this.i18n('State'),
         cellTemplate: this.stateTmpl,
         flexGrow: 1
       }
     ];
 
     this.image_syncing.columns = [
-      { prop: 'pool_name', name: 'Pool', flexGrow: 2 },
-      { prop: 'name', name: 'Image', flexGrow: 2 },
+      { prop: 'pool_name', name: this.i18n('Pool'), flexGrow: 2 },
+      { prop: 'name', name: this.i18n('Image'), flexGrow: 2 },
       {
         prop: 'progress',
-        name: 'Progress',
+        name: this.i18n('Progress'),
         cellTemplate: this.progressTmpl,
         flexGrow: 2
       },
       {
         prop: 'state',
-        name: 'State',
+        name: this.i18n('State'),
         cellTemplate: this.syncTmpl,
         flexGrow: 1
       }
     ];
 
     this.image_ready.columns = [
-      { prop: 'pool_name', name: 'Pool', flexGrow: 2 },
-      { prop: 'name', name: 'Image', flexGrow: 2 },
-      { prop: 'description', name: 'Description', flexGrow: 4 },
+      { prop: 'pool_name', name: this.i18n('Pool'), flexGrow: 2 },
+      { prop: 'name', name: this.i18n('Image'), flexGrow: 2 },
+      { prop: 'description', name: this.i18n('Description'), flexGrow: 4 },
       {
         prop: 'state',
-        name: 'State',
+        name: this.i18n('State'),
         cellTemplate: this.stateTmpl,
         flexGrow: 1
       }
index 0dfdafadc1c8502f243e60aa12f559ae0419507a..06dc9fb5e14bc70b07afbf8969ce163c453db18e 100644 (file)
@@ -7,7 +7,7 @@ import { RouterTestingModule } from '@angular/router/testing';
 import { ToastModule } from 'ng2-toastr';
 
 import { ActivatedRouteStub } from '../../../../testing/activated-route-stub';
-import { configureTestBed } from '../../../../testing/unit-test-helper';
+import { configureTestBed, i18nProviders } from '../../../../testing/unit-test-helper';
 import { RbdService } from '../../../shared/api/rbd.service';
 import { SharedModule } from '../../../shared/shared.module';
 import { RbdFormMode } from './rbd-form-mode.enum';
@@ -31,7 +31,8 @@ describe('RbdFormComponent', () => {
       {
         provide: ActivatedRoute,
         useValue: new ActivatedRouteStub({ pool: 'foo', name: 'bar', snap: undefined })
-      }
+      },
+      i18nProviders
     ]
   });
 
index 08f1a8d6c719c5034963e0e3988f4e3b6ee82103..911456de88ba3d20b8a86ab43408c42a40fec095 100644 (file)
@@ -2,6 +2,7 @@ import { Component, OnInit } from '@angular/core';
 import { FormControl, ValidatorFn, Validators } from '@angular/forms';
 import { ActivatedRoute, Router } from '@angular/router';
 
+import { I18n } from '@ngx-translate/i18n-polyfill';
 import * as _ from 'lodash';
 import { Observable } from 'rxjs';
 
@@ -81,42 +82,43 @@ export class RbdFormComponent implements OnInit {
     private rbdService: RbdService,
     private formatter: FormatterService,
     private taskWrapper: TaskWrapperService,
-    private dimlessBinaryPipe: DimlessBinaryPipe
+    private dimlessBinaryPipe: DimlessBinaryPipe,
+    private i18n: I18n
   ) {
     this.poolPermission = this.authStorageService.getPermissions().pool;
     this.features = {
       'deep-flatten': {
-        desc: 'Deep flatten',
+        desc: this.i18n('Deep flatten'),
         requires: null,
         allowEnable: false,
         allowDisable: true
       },
       layering: {
-        desc: 'Layering',
+        desc: this.i18n('Layering'),
         requires: null,
         allowEnable: false,
         allowDisable: false
       },
       'exclusive-lock': {
-        desc: 'Exclusive lock',
+        desc: this.i18n('Exclusive lock'),
         requires: null,
         allowEnable: true,
         allowDisable: true
       },
       'object-map': {
-        desc: 'Object map (requires exclusive-lock)',
+        desc: this.i18n('Object map (requires exclusive-lock)'),
         requires: 'exclusive-lock',
         allowEnable: true,
         allowDisable: true
       },
       journaling: {
-        desc: 'Journaling (requires exclusive-lock)',
+        desc: this.i18n('Journaling (requires exclusive-lock)'),
         requires: 'exclusive-lock',
         allowEnable: true,
         allowDisable: true
       },
       'fast-diff': {
-        desc: 'Fast diff (requires object-map)',
+        desc: this.i18n('Fast diff (requires object-map)'),
         requires: 'object-map',
         allowEnable: true,
         allowDisable: true
index 99697264f726f2135faca6700e1bc6907aa7bd64..7ea4874507232cae290621bd698b5b4a4a535191 100644 (file)
@@ -6,7 +6,7 @@ import { ToastModule } from 'ng2-toastr';
 import { TabsModule } from 'ngx-bootstrap/tabs';
 import { TooltipModule } from 'ngx-bootstrap/tooltip';
 
-import { configureTestBed } from '../../../../testing/unit-test-helper';
+import { configureTestBed, i18nProviders } from '../../../../testing/unit-test-helper';
 import { TaskListService } from '../../../shared/services/task-list.service';
 import { SharedModule } from '../../../shared/shared.module';
 import { RbdDetailsComponent } from '../rbd-details/rbd-details.component';
@@ -35,7 +35,7 @@ describe('RbdImagesComponent', () => {
       ToastModule.forRoot(),
       TooltipModule.forRoot()
     ],
-    providers: [TaskListService]
+    providers: [TaskListService, i18nProviders]
   });
 
   beforeEach(() => {
index cddb711503c72df70eb5555113b62173b2e2fe0c..e9631eabdf7720a3d9933840b7ae14f6db6a76be 100644 (file)
@@ -11,7 +11,11 @@ import { TabsModule } from 'ngx-bootstrap/tabs';
 import { TooltipModule } from 'ngx-bootstrap/tooltip';
 import { BehaviorSubject, of } from 'rxjs';
 
-import { configureTestBed, PermissionHelper } from '../../../../testing/unit-test-helper';
+import {
+  configureTestBed,
+  i18nProviders,
+  PermissionHelper
+} from '../../../../testing/unit-test-helper';
 import { RbdService } from '../../../shared/api/rbd.service';
 import { TableActionsComponent } from '../../../shared/datatable/table-actions/table-actions.component';
 import { ViewCacheStatus } from '../../../shared/enum/view-cache-status.enum';
@@ -47,7 +51,7 @@ describe('RbdListComponent', () => {
       HttpClientTestingModule
     ],
     declarations: [RbdListComponent, RbdDetailsComponent, RbdSnapshotListComponent],
-    providers: [TaskListService]
+    providers: [TaskListService, i18nProviders]
   });
 
   beforeEach(() => {
index 6593096d649736160d7227d060d795fdfa3ebe88..97051ca5cea52a1ce60a221f9c9c1e32feee5d7a 100644 (file)
@@ -1,5 +1,6 @@
 import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core';
 
+import { I18n } from '@ngx-translate/i18n-polyfill';
 import * as _ from 'lodash';
 import { BsModalRef, BsModalService } from 'ngx-bootstrap/modal';
 
@@ -75,7 +76,8 @@ export class RbdListComponent implements OnInit {
     private dimlessPipe: DimlessPipe,
     private modalService: BsModalService,
     private taskWrapper: TaskWrapperService,
-    private taskListService: TaskListService
+    private taskListService: TaskListService,
+    private i18n: I18n
   ) {
     this.permission = this.authStorageService.getPermissions().rbdImage;
     const getImageUri = () =>
@@ -86,19 +88,19 @@ export class RbdListComponent implements OnInit {
       icon: 'fa-plus',
       routerLink: () => '/block/rbd/add',
       canBePrimary: (selection: CdTableSelection) => !selection.hasSingleSelection,
-      name: 'Add'
+      name: this.i18n('Add')
     };
     const editAction: CdTableAction = {
       permission: 'update',
       icon: 'fa-pencil',
       routerLink: () => `/block/rbd/edit/${getImageUri()}`,
-      name: 'Edit'
+      name: this.i18n('Edit')
     };
     const deleteAction: CdTableAction = {
       permission: 'delete',
       icon: 'fa-times',
       click: () => this.deleteRbdModal(),
-      name: 'Delete'
+      name: this.i18n('Delete')
     };
     const copyAction: CdTableAction = {
       permission: 'create',
@@ -107,7 +109,7 @@ export class RbdListComponent implements OnInit {
         !selection.hasSingleSelection || selection.first().cdExecuting,
       icon: 'fa-copy',
       routerLink: () => `/block/rbd/copy/${getImageUri()}`,
-      name: 'Copy'
+      name: this.i18n('Copy')
     };
     const flattenAction: CdTableAction = {
       permission: 'update',
@@ -115,13 +117,13 @@ export class RbdListComponent implements OnInit {
         !selection.hasSingleSelection || selection.first().cdExecuting || !selection.first().parent,
       icon: 'fa-chain-broken',
       click: () => this.flattenRbdModal(),
-      name: 'Flatten'
+      name: this.i18n('Flatten')
     };
     const moveAction: CdTableAction = {
       permission: 'delete',
       icon: 'fa-trash-o',
       click: () => this.trashRbdModal(),
-      name: 'Move to Trash'
+      name: this.i18n('Move to Trash')
     };
     this.tableActions = [
       addAction,
@@ -136,53 +138,53 @@ export class RbdListComponent implements OnInit {
   ngOnInit() {
     this.columns = [
       {
-        name: 'Name',
+        name: this.i18n('Name'),
         prop: 'name',
         flexGrow: 2,
         cellTransformation: CellTemplate.executing
       },
       {
-        name: 'Pool',
+        name: this.i18n('Pool'),
         prop: 'pool_name',
         flexGrow: 2
       },
       {
-        name: 'Size',
+        name: this.i18n('Size'),
         prop: 'size',
         flexGrow: 1,
         cellClass: 'text-right',
         pipe: this.dimlessBinaryPipe
       },
       {
-        name: 'Objects',
+        name: this.i18n('Objects'),
         prop: 'num_objs',
         flexGrow: 1,
         cellClass: 'text-right',
         pipe: this.dimlessPipe
       },
       {
-        name: 'Object size',
+        name: this.i18n('Object size'),
         prop: 'obj_size',
         flexGrow: 1,
         cellClass: 'text-right',
         pipe: this.dimlessBinaryPipe
       },
       {
-        name: 'Provisioned',
+        name: this.i18n('Provisioned'),
         prop: 'disk_usage',
         cellClass: 'text-center',
         flexGrow: 1,
         pipe: this.dimlessBinaryPipe
       },
       {
-        name: 'Total provisioned',
+        name: this.i18n('Total provisioned'),
         prop: 'total_disk_usage',
         cellClass: 'text-center',
         flexGrow: 1,
         pipe: this.dimlessBinaryPipe
       },
       {
-        name: 'Parent',
+        name: this.i18n('Parent'),
         prop: 'parent',
         flexGrow: 2,
         cellTemplate: this.parentTpl
index 2e881b49275a115eb53b752363e762181d8f9592..9dea478ef8a7018221885693374ce588a98284b4 100644 (file)
@@ -6,7 +6,7 @@ import { RouterTestingModule } from '@angular/router/testing';
 import { ToastModule } from 'ng2-toastr';
 import { BsModalRef, BsModalService } from 'ngx-bootstrap/modal';
 
-import { configureTestBed } from '../../../../testing/unit-test-helper';
+import { configureTestBed, i18nProviders } from '../../../../testing/unit-test-helper';
 import { ApiModule } from '../../../shared/api/api.module';
 import { ComponentsModule } from '../../../shared/components/components.module';
 import { AuthStorageService } from '../../../shared/services/auth-storage.service';
@@ -28,7 +28,7 @@ describe('RbdSnapshotFormComponent', () => {
       RouterTestingModule
     ],
     declarations: [RbdSnapshotFormComponent],
-    providers: [BsModalRef, BsModalService, AuthStorageService]
+    providers: [BsModalRef, BsModalService, AuthStorageService, i18nProviders]
   });
 
   beforeEach(() => {
index 39a8d10d09f625d91b3cf5f3a866deb3720068c6..41861135fe271c975fc68e1c17e0481b6c7091e4 100644 (file)
@@ -7,7 +7,11 @@ import { ToastModule } from 'ng2-toastr';
 import { BsModalRef, BsModalService } from 'ngx-bootstrap/modal';
 import { Subject, throwError as observableThrowError } from 'rxjs';
 
-import { configureTestBed, PermissionHelper } from '../../../../testing/unit-test-helper';
+import {
+  configureTestBed,
+  i18nProviders,
+  PermissionHelper
+} from '../../../../testing/unit-test-helper';
 import { ApiModule } from '../../../shared/api/api.module';
 import { RbdService } from '../../../shared/api/rbd.service';
 import { ComponentsModule } from '../../../shared/components/components.module';
@@ -50,7 +54,11 @@ describe('RbdSnapshotListComponent', () => {
       RouterTestingModule,
       PipesModule
     ],
-    providers: [{ provide: AuthStorageService, useValue: fakeAuthStorageService }, TaskListService]
+    providers: [
+      { provide: AuthStorageService, useValue: fakeAuthStorageService },
+      TaskListService,
+      i18nProviders
+    ]
   });
 
   beforeEach(() => {
index f6d3cbd7067bac5cea3ca1667a664c7a90324cdc..8958dea84b2dc6539c840a1f8a3b156059ea0f10 100644 (file)
@@ -1,5 +1,6 @@
 import { Component, Input, OnChanges, OnInit, TemplateRef, ViewChild } from '@angular/core';
 
+import { I18n } from '@ngx-translate/i18n-polyfill';
 import * as moment from 'moment';
 import { BsModalRef, BsModalService } from 'ngx-bootstrap/modal';
 import { of } from 'rxjs';
@@ -72,7 +73,8 @@ export class RbdSnapshotListComponent implements OnInit, OnChanges {
     private taskManagerService: TaskManagerService,
     private notificationService: NotificationService,
     private summaryService: SummaryService,
-    private taskListService: TaskListService
+    private taskListService: TaskListService,
+    private i18n: I18n
   ) {
     this.permission = this.authStorageService.getPermissions().rbdImage;
     const actions = new RbdSnapshotActionsModel();
@@ -95,34 +97,34 @@ export class RbdSnapshotListComponent implements OnInit, OnChanges {
   ngOnInit() {
     this.columns = [
       {
-        name: 'Name',
+        name: this.i18n('Name'),
         prop: 'name',
         cellTransformation: CellTemplate.executing,
         flexGrow: 2
       },
       {
-        name: 'Size',
+        name: this.i18n('Size'),
         prop: 'size',
         flexGrow: 1,
         cellClass: 'text-right',
         pipe: this.dimlessBinaryPipe
       },
       {
-        name: 'Provisioned',
+        name: this.i18n('Provisioned'),
         prop: 'disk_usage',
         flexGrow: 1,
         cellClass: 'text-right',
         pipe: this.dimlessBinaryPipe
       },
       {
-        name: 'State',
+        name: this.i18n('State'),
         prop: 'is_protected',
         flexGrow: 1,
         cellClass: 'text-center',
         cellTemplate: this.protectTpl
       },
       {
-        name: 'Created',
+        name: this.i18n('Created'),
         prop: 'timestamp',
         flexGrow: 1,
         pipe: this.cdDatePipe
@@ -253,8 +255,8 @@ export class RbdSnapshotListComponent implements OnInit, OnChanges {
   rollbackModal() {
     const snapshotName = this.selection.selected[0].name;
     const initialState = {
-      titleText: 'RBD snapshot rollback',
-      buttonText: 'Rollback',
+      titleText: this.i18n('RBD snapshot rollback'),
+      buttonText: this.i18n('Rollback'),
       bodyTpl: this.rollbackTpl,
       bodyData: {
         snapName: `${this.poolName}/${this.rbdName}@${snapshotName}`
@@ -271,7 +273,7 @@ export class RbdSnapshotListComponent implements OnInit, OnChanges {
     const snapshotName = this.selection.selected[0].name;
     this.modalRef = this.modalService.show(CriticalConfirmationModalComponent, {
       initialState: {
-        itemDescription: 'RBD snapshot',
+        itemDescription: this.i18n('RBD snapshot'),
         submitAction: () => this._asyncTask('deleteSnapshot', 'rbd/snap/delete', snapshotName)
       }
     });
index c256c8739f93de3d07098e9776700467f7a89fab..5f8126aa428f83ef388108953d0ee24f3c1e4bd0 100644 (file)
@@ -6,7 +6,7 @@ import { ToastModule } from 'ng2-toastr';
 import { of } from 'rxjs';
 
 import { By } from '@angular/platform-browser';
-import { configureTestBed } from '../../../../testing/unit-test-helper';
+import { configureTestBed, i18nProviders } from '../../../../testing/unit-test-helper';
 import { RbdService } from '../../../shared/api/rbd.service';
 import { CdTableSelection } from '../../../shared/models/cd-table-selection';
 import { ExecutingTask } from '../../../shared/models/executing-task';
@@ -24,7 +24,7 @@ describe('RbdTrashListComponent', () => {
   configureTestBed({
     declarations: [RbdTrashListComponent],
     imports: [SharedModule, HttpClientTestingModule, RouterTestingModule, ToastModule.forRoot()],
-    providers: [TaskListService]
+    providers: [TaskListService, i18nProviders]
   });
 
   beforeEach(() => {
index ac6059d5bbc35b8f84effa4b0aca3aa98ce6a75c..71f32dbeb284505a57589e2190973d9283610ada 100644 (file)
@@ -1,5 +1,6 @@
 import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core';
 
+import { I18n } from '@ngx-translate/i18n-polyfill';
 import * as _ from 'lodash';
 import * as moment from 'moment';
 import { BsModalRef, BsModalService } from 'ngx-bootstrap/modal';
@@ -52,7 +53,8 @@ export class RbdTrashListComponent implements OnInit {
     private modalService: BsModalService,
     private cdDatePipe: CdDatePipe,
     private taskListService: TaskListService,
-    private taskWrapper: TaskWrapperService
+    private taskWrapper: TaskWrapperService,
+    private i18n: I18n
   ) {
     this.permission = this.authStorageService.getPermissions().rbdImage;
 
@@ -60,13 +62,13 @@ export class RbdTrashListComponent implements OnInit {
       permission: 'update',
       icon: 'fa-undo',
       click: () => this.restoreModal(),
-      name: 'Restore'
+      name: this.i18n('Restore')
     };
     const deleteAction: CdTableAction = {
       permission: 'delete',
       icon: 'fa-times',
       click: () => this.deleteModal(),
-      name: 'Delete'
+      name: this.i18n('Delete')
     };
     this.tableActions = [restoreAction, deleteAction];
   }
@@ -74,29 +76,29 @@ export class RbdTrashListComponent implements OnInit {
   ngOnInit() {
     this.columns = [
       {
-        name: 'ID',
+        name: this.i18n('ID'),
         prop: 'id',
         flexGrow: 1,
         cellTransformation: CellTemplate.executing
       },
       {
-        name: 'Name',
+        name: this.i18n('Name'),
         prop: 'name',
         flexGrow: 1
       },
       {
-        name: 'Pool',
+        name: this.i18n('Pool'),
         prop: 'pool_name',
         flexGrow: 1
       },
       {
-        name: 'Status',
+        name: this.i18n('Status'),
         prop: 'deferment_end_time',
         flexGrow: 1,
         cellTemplate: this.expiresTpl
       },
       {
-        name: 'Deleted At',
+        name: this.i18n('Deleted At'),
         prop: 'deletion_time',
         flexGrow: 1,
         pipe: this.cdDatePipe
index beea09718e811eae7a2a685bab04600bc41dffc9..737d6b5b66225dce64b47750e3232dc13f401eb0 100644 (file)
@@ -8,7 +8,7 @@ import { ToastModule } from 'ng2-toastr';
 import { BsDatepickerModule } from 'ngx-bootstrap/datepicker';
 import { BsModalRef, BsModalService } from 'ngx-bootstrap/modal';
 
-import { configureTestBed } from '../../../../testing/unit-test-helper';
+import { configureTestBed, i18nProviders } from '../../../../testing/unit-test-helper';
 import { NotificationService } from '../../../shared/services/notification.service';
 import { SharedModule } from '../../../shared/shared.module';
 import { RbdTrashMoveModalComponent } from './rbd-trash-move-modal.component';
@@ -28,7 +28,7 @@ describe('RbdTrashMoveModalComponent', () => {
       BsDatepickerModule.forRoot()
     ],
     declarations: [RbdTrashMoveModalComponent],
-    providers: [BsModalRef, BsModalService]
+    providers: [BsModalRef, BsModalService, i18nProviders]
   });
 
   beforeEach(() => {
index c4ce343d4efdac29e6e0f5ff62c6b2174e12b9bc..749236c0da0632d9ea9719526235cae986278973 100644 (file)
@@ -6,7 +6,7 @@ import { RouterTestingModule } from '@angular/router/testing';
 import { ToastModule } from 'ng2-toastr';
 import { BsModalRef } from 'ngx-bootstrap/modal';
 
-import { configureTestBed } from '../../../../testing/unit-test-helper';
+import { configureTestBed, i18nProviders } from '../../../../testing/unit-test-helper';
 import { Permission } from '../../../shared/models/permissions';
 import { NotificationService } from '../../../shared/services/notification.service';
 import { SharedModule } from '../../../shared/shared.module';
@@ -26,7 +26,7 @@ describe('RbdTrashPurgeModalComponent', () => {
       RouterTestingModule
     ],
     declarations: [RbdTrashPurgeModalComponent],
-    providers: [BsModalRef]
+    providers: [BsModalRef, i18nProviders]
   });
 
   beforeEach(() => {
index 06e4d1a33ea7e3ba89cb2ed765d86c5f0a617c89..3689b2a18cbb86004af6135eb0e5616920701d26 100644 (file)
@@ -6,7 +6,7 @@ import { RouterTestingModule } from '@angular/router/testing';
 import { ToastModule } from 'ng2-toastr';
 import { BsModalRef } from 'ngx-bootstrap/modal';
 
-import { configureTestBed } from '../../../../testing/unit-test-helper';
+import { configureTestBed, i18nProviders } from '../../../../testing/unit-test-helper';
 import { NotificationService } from '../../../shared/services/notification.service';
 import { SharedModule } from '../../../shared/shared.module';
 import { RbdTrashRestoreModalComponent } from './rbd-trash-restore-modal.component';
@@ -24,7 +24,7 @@ describe('RbdTrashRestoreModalComponent', () => {
       SharedModule,
       RouterTestingModule
     ],
-    providers: [BsModalRef]
+    providers: [BsModalRef, i18nProviders]
   });
 
   beforeEach(() => {
index 9cc2b82a2c290b2c92bb377f8080b4af830d1151..4b5ab9a16bc9e330ea1441236f68d081410acd34 100644 (file)
@@ -4,7 +4,7 @@ import { RouterTestingModule } from '@angular/router/testing';
 
 import { BsDropdownModule } from 'ngx-bootstrap/dropdown';
 
-import { configureTestBed } from '../../../../testing/unit-test-helper';
+import { configureTestBed, i18nProviders } from '../../../../testing/unit-test-helper';
 import { SharedModule } from '../../../shared/shared.module';
 import { CephfsClientsComponent } from './cephfs-clients.component';
 
@@ -19,7 +19,8 @@ describe('CephfsClientsComponent', () => {
       SharedModule,
       HttpClientTestingModule
     ],
-    declarations: [CephfsClientsComponent]
+    declarations: [CephfsClientsComponent],
+    providers: i18nProviders
   });
 
   beforeEach(() => {
index 093563155fb46b6778e752cb3d39992bdd88a635..af8181ac385148645bd2291d14955fab047d2fb9 100644 (file)
@@ -1,5 +1,7 @@
 import { Component, Input, OnInit } from '@angular/core';
 
+import { I18n } from '@ngx-translate/i18n-polyfill';
+
 import { CephfsService } from '../../../shared/api/cephfs.service';
 import { ViewCacheStatus } from '../../../shared/enum/view-cache-status.enum';
 
@@ -15,17 +17,17 @@ export class CephfsClientsComponent implements OnInit {
   clients: any;
   viewCacheStatus: ViewCacheStatus;
 
-  constructor(private cephfsService: CephfsService) {}
+  constructor(private cephfsService: CephfsService, private i18n: I18n) {}
 
   ngOnInit() {
     this.clients = {
       columns: [
-        { prop: 'id' },
-        { prop: 'type' },
-        { prop: 'state' },
-        { prop: 'version' },
-        { prop: 'hostname', name: 'Host' },
-        { prop: 'root' }
+        { prop: 'id', name: this.i18n('id') },
+        { prop: 'type', name: this.i18n('type') },
+        { prop: 'state', name: this.i18n('state') },
+        { prop: 'version', name: this.i18n('version') },
+        { prop: 'hostname', name: this.i18n('Host') },
+        { prop: 'root', name: this.i18n('root') }
       ],
       data: []
     };
index 07862a062b8c38c3974d7a269b490df9600ef7de..256db87fa448d09fa954468d2cb2cdf51c366467 100644 (file)
@@ -7,7 +7,7 @@ import { BsDropdownModule } from 'ngx-bootstrap/dropdown';
 import { ProgressbarModule } from 'ngx-bootstrap/progressbar';
 import { TabsModule } from 'ngx-bootstrap/tabs';
 
-import { configureTestBed } from '../../../../testing/unit-test-helper';
+import { configureTestBed, i18nProviders } from '../../../../testing/unit-test-helper';
 import { SharedModule } from '../../../shared/shared.module';
 import { CephfsDetailComponent } from './cephfs-detail.component';
 
@@ -36,7 +36,8 @@ describe('CephfsDetailComponent', () => {
       TabsModule.forRoot(),
       HttpClientTestingModule
     ],
-    declarations: [CephfsDetailComponent, CephfsChartStubComponent, CephfsClientsStubComponent]
+    declarations: [CephfsDetailComponent, CephfsChartStubComponent, CephfsClientsStubComponent],
+    providers: i18nProviders
   });
 
   beforeEach(() => {
index e536e455037d5131fecbbf92cab8620f31ebff9e..a5ef1733c69d8e9818f503619a2eb36020f7272c 100644 (file)
@@ -1,5 +1,6 @@
 import { Component, Input, OnChanges, OnInit, TemplateRef, ViewChild } from '@angular/core';
 
+import { I18n } from '@ngx-translate/i18n-polyfill';
 import * as _ from 'lodash';
 
 import { CephfsService } from '../../../shared/api/cephfs.service';
@@ -38,7 +39,8 @@ export class CephfsDetailComponent implements OnChanges, OnInit {
   constructor(
     private cephfsService: CephfsService,
     private dimlessBinary: DimlessBinaryPipe,
-    private dimless: DimlessPipe
+    private dimless: DimlessPipe,
+    private i18n: I18n
   ) {}
 
   ngOnChanges() {
@@ -60,23 +62,23 @@ export class CephfsDetailComponent implements OnChanges, OnInit {
   ngOnInit() {
     this.ranks = {
       columns: [
-        { prop: 'rank' },
-        { prop: 'state' },
-        { prop: 'mds', name: 'Daemon' },
-        { prop: 'activity', cellTemplate: this.activityTmpl },
-        { prop: 'dns', name: 'Dentries', pipe: this.dimless },
-        { prop: 'inos', name: 'Inodes', pipe: this.dimless }
+        { prop: 'rank', name: this.i18n('Rank') },
+        { prop: 'state', name: this.i18n('State') },
+        { prop: 'mds', name: this.i18n('Daemon') },
+        { prop: 'activity', name: this.i18n('Activity'), cellTemplate: this.activityTmpl },
+        { prop: 'dns', name: this.i18n('Dentries'), pipe: this.dimless },
+        { prop: 'inos', name: this.i18n('Inodes'), pipe: this.dimless }
       ],
       data: []
     };
 
     this.pools = {
       columns: [
-        { prop: 'pool' },
-        { prop: 'type' },
-        { prop: 'size', pipe: this.dimlessBinary },
+        { prop: 'pool', name: this.i18n('Pool') },
+        { prop: 'type', name: this.i18n('Type') },
+        { prop: 'size', name: this.i18n('Size'), pipe: this.dimlessBinary },
         {
-          name: 'Usage',
+          name: this.i18n('Usage'),
           cellTemplate: this.poolUsageTpl,
           comparator: (valueA, valueB, rowA, rowB, sortDirection) => {
             const valA = rowA.used / rowA.avail;
@@ -107,7 +109,7 @@ export class CephfsDetailComponent implements OnChanges, OnInit {
       });
       this.standbys = [
         {
-          key: 'Standby daemons',
+          key: this.i18n('Standby daemons'),
           value: data.standbys.map((value) => value.name).join(', ')
         }
       ];
index 2f85abc49af5f093c20830273517c245b8f355c3..111a6a468361f7a3633e3fe49d22499bf317ea0f 100644 (file)
@@ -2,7 +2,7 @@ import { HttpClientTestingModule } from '@angular/common/http/testing';
 import { Component, Input } from '@angular/core';
 import { ComponentFixture, TestBed } from '@angular/core/testing';
 
-import { configureTestBed } from '../../../../testing/unit-test-helper';
+import { configureTestBed, i18nProviders } from '../../../../testing/unit-test-helper';
 import { CdTableSelection } from '../../../shared/models/cd-table-selection';
 import { SharedModule } from '../../../shared/shared.module';
 import { CephfsListComponent } from './cephfs-list.component';
@@ -19,7 +19,8 @@ describe('CephfsListComponent', () => {
 
   configureTestBed({
     imports: [SharedModule, HttpClientTestingModule],
-    declarations: [CephfsListComponent, CephfsDetailStubComponent]
+    declarations: [CephfsListComponent, CephfsDetailStubComponent],
+    providers: i18nProviders
   });
 
   beforeEach(() => {
index 346d90f75d10353a9fb7ca14e5bd330252feab99..d58357d4ba8aea32f4ad14172deea67409e86acd 100644 (file)
@@ -1,5 +1,7 @@
 import { Component, OnInit } from '@angular/core';
 
+import { I18n } from '@ngx-translate/i18n-polyfill';
+
 import { CephfsService } from '../../../shared/api/cephfs.service';
 import { CdTableColumn } from '../../../shared/models/cd-table-column';
 import { CdTableFetchDataContext } from '../../../shared/models/cd-table-fetch-data-context';
@@ -15,22 +17,22 @@ export class CephfsListComponent implements OnInit {
   filesystems: any = [];
   selection = new CdTableSelection();
 
-  constructor(private cephfsService: CephfsService) {}
+  constructor(private cephfsService: CephfsService, private i18n: I18n) {}
 
   ngOnInit() {
     this.columns = [
       {
-        name: 'Name',
+        name: this.i18n('Name'),
         prop: 'mdsmap.fs_name',
         flexGrow: 2
       },
       {
-        name: 'Created',
+        name: this.i18n('Created'),
         prop: 'mdsmap.created',
         flexGrow: 2
       },
       {
-        name: 'Enabled',
+        name: this.i18n('Enabled'),
         prop: 'mdsmap.enabled',
         flexGrow: 1
       }
index 763c47f58eddd86c8e9534a098a2b3803c3b2cc5..0016b478696ccaf1f30af43d9a25a19f189bdd81 100755 (executable)
@@ -2,7 +2,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
 
 import { TabsModule } from 'ngx-bootstrap/tabs';
 
-import { configureTestBed } from '../../../../../testing/unit-test-helper';
+import { configureTestBed, i18nProviders } from '../../../../../testing/unit-test-helper';
 import { DataTableModule } from '../../../../shared/datatable/datatable.module';
 import { ConfigurationDetailsComponent } from './configuration-details.component';
 
@@ -12,7 +12,8 @@ describe('ConfigurationDetailsComponent', () => {
 
   configureTestBed({
     declarations: [ConfigurationDetailsComponent],
-    imports: [DataTableModule, TabsModule.forRoot()]
+    imports: [DataTableModule, TabsModule.forRoot()],
+    providers: [i18nProviders]
   });
 
   beforeEach(() => {
index 5ab66d78f8647d798c0884d6f90ab4fe2fa1c27f..25876369667461ec45ca5d4a9fc835a363c4d91b 100755 (executable)
@@ -1,5 +1,6 @@
 import { Component, Input, OnChanges } from '@angular/core';
 
+import { I18n } from '@ngx-translate/i18n-polyfill';
 import * as _ from 'lodash';
 
 import { CdTableSelection } from '../../../../shared/models/cd-table-selection';
@@ -14,17 +15,17 @@ export class ConfigurationDetailsComponent implements OnChanges {
   selection: CdTableSelection;
   selectedItem: any;
   flags = {
-    runtime: 'The value can be updated at runtime.',
-    no_mon_update:
-      'Daemons/clients do not pull this value from the monitor config database. ' +
-      `We disallow setting this option via 'ceph config set ...'. This option should be ` +
-      'configured via ceph.conf or via the command line.',
-    startup: 'Option takes effect only during daemon startup.',
-    cluster_create: 'Option only affects cluster creation.',
-    create: 'Option only affects daemon creation.'
+    runtime: this.i18n('The value can be updated at runtime.'),
+    no_mon_update: this.i18n(`Daemons/clients do not pull this value from the
+      monitor config database. We disallow setting this option via 'ceph config
+      set ...'. This option should be configured via ceph.conf or via the
+      command line.`),
+    startup: this.i18n('Option takes effect only during daemon startup.'),
+    cluster_create: this.i18n('Option only affects cluster creation.'),
+    create: this.i18n('Option only affects daemon creation.')
   };
 
-  constructor() {}
+  constructor(private i18n: I18n) {}
 
   ngOnChanges() {
     if (this.selection.hasSelection) {
index 2d369db25b3b1ada40417eb6d3671b6f027b5f7f..6a67cd77c1c9b264561c5086a5c8162cb297c3b2 100644 (file)
@@ -6,7 +6,7 @@ import { RouterTestingModule } from '@angular/router/testing';
 
 import { ToastModule } from 'ng2-toastr';
 
-import { configureTestBed } from '../../../../../testing/unit-test-helper';
+import { configureTestBed, i18nProviders } from '../../../../../testing/unit-test-helper';
 import { SharedModule } from '../../../../shared/shared.module';
 import { ConfigurationFormComponent } from './configuration-form.component';
 import { ConfigFormModel } from './configuration-form.model';
@@ -27,7 +27,8 @@ describe('ConfigurationFormComponent', () => {
     providers: [
       {
         provide: ActivatedRoute
-      }
+      },
+      i18nProviders
     ]
   });
 
index 65972f395dc592a87be2fa3d57933e3593f1e8d8..87275ad2e6e6bdf3f840230f0f84d8ec8a52d2ff 100644 (file)
@@ -2,6 +2,7 @@ import { Component, OnInit } from '@angular/core';
 import { FormControl, FormGroup, ValidatorFn, Validators } from '@angular/forms';
 import { ActivatedRoute, Router } from '@angular/router';
 
+import { I18n } from '@ngx-translate/i18n-polyfill';
 import * as _ from 'lodash';
 
 import { ConfigurationService } from '../../../../shared/api/configuration.service';
@@ -32,7 +33,8 @@ export class ConfigurationFormComponent implements OnInit {
     private route: ActivatedRoute,
     private router: Router,
     private configService: ConfigurationService,
-    private notificationService: NotificationService
+    private notificationService: NotificationService,
+    private i18n: I18n
   ) {
     this.createForm();
   }
@@ -69,63 +71,74 @@ export class ConfigurationFormComponent implements OnInit {
       {
         name: 'uint64_t',
         inputType: 'number',
-        humanReadable: 'Positive integer value',
+        humanReadable: this.i18n('Positive integer value'),
         defaultMin: 0,
-        patternHelpText: 'The entered value needs to be a positive number.',
+        patternHelpText: this.i18n('The entered value needs to be a positive number.'),
         isNumberType: true,
         allowsNegative: false
       },
       {
         name: 'int64_t',
         inputType: 'number',
-        humanReadable: 'Integer value',
-        patternHelpText: 'The entered value needs to be a number.',
+        humanReadable: this.i18n('Integer value'),
+        patternHelpText: this.i18n('The entered value needs to be a number.'),
         isNumberType: true,
         allowsNegative: true
       },
       {
         name: 'size_t',
         inputType: 'number',
-        humanReadable: 'Positive integer value (size)',
+        humanReadable: this.i18n('Positive integer value (size)'),
         defaultMin: 0,
-        patternHelpText: 'The entered value needs to be a positive number.',
+        patternHelpText: this.i18n('The entered value needs to be a positive number.'),
         isNumberType: true,
         allowsNegative: false
       },
       {
         name: 'secs',
         inputType: 'number',
-        humanReadable: 'Positive integer value (secs)',
+        humanReadable: this.i18n('Positive integer value (secs)'),
         defaultMin: 1,
-        patternHelpText: 'The entered value needs to be a positive number.',
+        patternHelpText: this.i18n('The entered value needs to be a positive number.'),
         isNumberType: true,
         allowsNegative: false
       },
       {
         name: 'double',
         inputType: 'number',
-        humanReadable: 'Decimal value',
-        patternHelpText: 'The entered value needs to be a number or decimal.',
+        humanReadable: this.i18n('Decimal value'),
+        patternHelpText: this.i18n('The entered value needs to be a number or decimal.'),
         isNumberType: true,
         allowsNegative: true
       },
-      { name: 'std::string', inputType: 'text', humanReadable: 'Text', isNumberType: false },
+      {
+        name: 'std::string',
+        inputType: 'text',
+        humanReadable: this.i18n('Text'),
+        isNumberType: false
+      },
       {
         name: 'entity_addr_t',
         inputType: 'text',
-        humanReadable: 'IPv4 or IPv6 address',
-        patternHelpText: 'The entered value needs to be a valid IP address.',
+        humanReadable: this.i18n('IPv4 or IPv6 address'),
+        patternHelpText: this.i18n('The entered value needs to be a valid IP address.'),
         isNumberType: false
       },
       {
         name: 'uuid_d',
         inputType: 'text',
-        humanReadable: 'UUID',
-        patternHelpText:
-          'The entered value is not a valid UUID, e.g.: 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8',
+        humanReadable: this.i18n('UUID'),
+        patternHelpText: this.i18n(
+          'The entered value is not a valid UUID, e.g.: 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8'
+        ),
         isNumberType: false
       },
-      { name: 'bool', inputType: 'checkbox', humanReadable: 'Boolean value', isNumberType: false }
+      {
+        name: 'bool',
+        inputType: 'checkbox',
+        humanReadable: this.i18n('Boolean value'),
+        isNumberType: false
+      }
     ];
 
     let currentType = null;
@@ -271,8 +284,8 @@ export class ConfigurationFormComponent implements OnInit {
         () => {
           this.notificationService.show(
             NotificationType.success,
-            'Config option ' + request.name + ' has been updated.',
-            'Update config option'
+            this.i18n('Config option {{name}} has been updated.', { name: request.name }),
+            this.i18n('Update config option')
           );
           this.router.navigate(['/configuration']);
         },
index 956d8ab6d9a7590dddca7a3877c5ab5f35e8d73b..b58ef58c938598cfc98b1a2d6ed2b3f97456a3ad 100644 (file)
@@ -5,7 +5,7 @@ import { RouterTestingModule } from '@angular/router/testing';
 
 import { TabsModule } from 'ngx-bootstrap/tabs';
 
-import { configureTestBed } from '../../../../testing/unit-test-helper';
+import { configureTestBed, i18nProviders } from '../../../../testing/unit-test-helper';
 import { SharedModule } from '../../../shared/shared.module';
 import { ConfigurationDetailsComponent } from './configuration-details/configuration-details.component';
 import { ConfigurationComponent } from './configuration.component';
@@ -22,7 +22,8 @@ describe('ConfigurationComponent', () => {
       TabsModule.forRoot(),
       HttpClientTestingModule,
       RouterTestingModule
-    ]
+    ],
+    providers: i18nProviders
   });
 
   beforeEach(() => {
index 65e95b4f5bc8fbc9c900c9d0086813756d18b064..3f33a43b4e664b2007f166bbfb7b719283e74225 100644 (file)
@@ -1,5 +1,7 @@
 import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core';
 
+import { I18n } from '@ngx-translate/i18n-polyfill';
+
 import { ConfigurationService } from '../../../shared/api/configuration.service';
 import { CdTableAction } from '../../../shared/models/cd-table-action';
 import { CdTableColumn } from '../../../shared/models/cd-table-column';
@@ -21,7 +23,7 @@ export class ConfigurationComponent implements OnInit {
   selection = new CdTableSelection();
   filters = [
     {
-      label: 'Level',
+      label: this.i18n('Level'),
       prop: 'level',
       value: 'basic',
       options: ['basic', 'advanced', 'dev'],
@@ -38,7 +40,7 @@ export class ConfigurationComponent implements OnInit {
       }
     },
     {
-      label: 'Service',
+      label: this.i18n('Service'),
       prop: 'services',
       value: 'any',
       options: ['any', 'mon', 'mgr', 'osd', 'mds', 'common', 'mds_client', 'rgw'],
@@ -51,7 +53,7 @@ export class ConfigurationComponent implements OnInit {
       }
     },
     {
-      label: 'Source',
+      label: this.i18n('Source'),
       prop: 'source',
       value: 'any',
       options: ['any', 'mon'],
@@ -76,7 +78,8 @@ export class ConfigurationComponent implements OnInit {
 
   constructor(
     private authStorageService: AuthStorageService,
-    private configurationService: ConfigurationService
+    private configurationService: ConfigurationService,
+    private i18n: I18n
   ) {
     this.permission = this.authStorageService.getPermissions().configOpt;
     const getConfigOptUri = () =>
@@ -85,22 +88,22 @@ export class ConfigurationComponent implements OnInit {
       permission: 'update',
       icon: 'fa-pencil',
       routerLink: () => `/configuration/edit/${getConfigOptUri()}`,
-      name: 'Edit'
+      name: this.i18n('Edit')
     };
     this.tableActions = [editAction];
   }
 
   ngOnInit() {
     this.columns = [
-      { canAutoResize: true, prop: 'name' },
-      { prop: 'desc', name: 'Description', cellClass: 'wrap' },
+      { canAutoResize: true, prop: 'name', name: this.i18n('Name') },
+      { prop: 'desc', name: this.i18n('Description'), cellClass: 'wrap' },
       {
         prop: 'value',
-        name: 'Current value',
+        name: this.i18n('Current value'),
         cellClass: 'wrap',
         cellTemplate: this.confValTpl
       },
-      { prop: 'default', cellClass: 'wrap' }
+      { prop: 'default', name: this.i18n('Default'), cellClass: 'wrap' }
     ];
   }
 
index dad77a63f06c4e498e292955d06d492623bf323c..d1264d52e8ad41c4ba643308fcee5254f9fabd68 100644 (file)
@@ -5,7 +5,7 @@ import { RouterTestingModule } from '@angular/router/testing';
 import { BsDropdownModule } from 'ngx-bootstrap/dropdown';
 import { TabsModule } from 'ngx-bootstrap/tabs';
 
-import { configureTestBed } from '../../../../testing/unit-test-helper';
+import { configureTestBed, i18nProviders } from '../../../../testing/unit-test-helper';
 import { HostService } from '../../../shared/api/host.service';
 import { Permissions } from '../../../shared/models/permissions';
 import { AuthStorageService } from '../../../shared/services/auth-storage.service';
@@ -32,7 +32,7 @@ describe('HostsComponent', () => {
       BsDropdownModule.forRoot(),
       RouterTestingModule
     ],
-    providers: [{ provide: AuthStorageService, useValue: fakeAuthStorageService }],
+    providers: [{ provide: AuthStorageService, useValue: fakeAuthStorageService }, i18nProviders],
     declarations: [HostsComponent, HostDetailsComponent]
   });
 
index d88af19ca00fd8da8f2f000262faa4ba31bdd879..61c74f476803220e89f670089bc15b9e29b7fb2f 100644 (file)
@@ -1,5 +1,7 @@
 import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core';
 
+import { I18n } from '@ngx-translate/i18n-polyfill';
+
 import { HostService } from '../../../shared/api/host.service';
 import { CdTableColumn } from '../../../shared/models/cd-table-column';
 import { CdTableFetchDataContext } from '../../../shared/models/cd-table-fetch-data-context';
@@ -27,7 +29,8 @@ export class HostsComponent implements OnInit {
   constructor(
     private authStorageService: AuthStorageService,
     private hostService: HostService,
-    private cephShortVersionPipe: CephShortVersionPipe
+    private cephShortVersionPipe: CephShortVersionPipe,
+    private i18n: I18n
   ) {
     this.permissions = this.authStorageService.getPermissions();
   }
@@ -35,18 +38,18 @@ export class HostsComponent implements OnInit {
   ngOnInit() {
     this.columns = [
       {
-        name: 'Hostname',
+        name: this.i18n('Hostname'),
         prop: 'hostname',
         flexGrow: 1
       },
       {
-        name: 'Services',
+        name: this.i18n('Services'),
         prop: 'services',
         flexGrow: 3,
         cellTemplate: this.servicesTpl
       },
       {
-        name: 'Version',
+        name: this.i18n('Version'),
         prop: 'ceph_version',
         flexGrow: 1,
         pipe: this.cephShortVersionPipe
index a405a62662f4faafa25a7b0adccb53925091aebb..497ca3b6e081daffd011352cdf711b0beb5725ac 100644 (file)
@@ -1,7 +1,7 @@
 import { NO_ERRORS_SCHEMA } from '@angular/core';
 import { ComponentFixture, TestBed } from '@angular/core/testing';
 
-import { configureTestBed } from '../../../../testing/unit-test-helper';
+import { configureTestBed, i18nProviders } from '../../../../testing/unit-test-helper';
 import { MonitorService } from '../../../shared/api/monitor.service';
 import { MonitorComponent } from './monitor.component';
 
@@ -14,7 +14,7 @@ describe('MonitorComponent', () => {
   configureTestBed({
     declarations: [MonitorComponent],
     schemas: [NO_ERRORS_SCHEMA],
-    providers: [{ provide: MonitorService, useValue: fakeService }]
+    providers: [{ provide: MonitorService, useValue: fakeService }, i18nProviders]
   });
 
   beforeEach(() => {
index 0231e0c22ca48e8501fb67bb5807f8925c69b0e9..6050ded5097e74a7d395c21d4f146878114e29d8 100644 (file)
@@ -1,5 +1,7 @@
 import { Component } from '@angular/core';
 
+import { I18n } from '@ngx-translate/i18n-polyfill';
+
 import { MonitorService } from '../../../shared/api/monitor.service';
 import { CellTemplate } from '../../../shared/enum/cell-template.enum';
 
@@ -19,15 +21,15 @@ export class MonitorComponent {
     width: '50%'
   };
 
-  constructor(private monitorService: MonitorService) {
+  constructor(private monitorService: MonitorService, private i18n: I18n) {
     this.inQuorum = {
       columns: [
-        { prop: 'name', name: 'Name', cellTransformation: CellTemplate.routerLink },
-        { prop: 'rank', name: 'Rank' },
-        { prop: 'public_addr', name: 'Public Address' },
+        { prop: 'name', name: this.i18n('Name'), cellTransformation: CellTemplate.routerLink },
+        { prop: 'rank', name: this.i18n('Rank') },
+        { prop: 'public_addr', name: this.i18n('Public Address') },
         {
           prop: 'cdOpenSessions',
-          name: 'Open Sessions',
+          name: this.i18n('Open Sessions'),
           cellTransformation: CellTemplate.sparkline
         }
       ],
@@ -36,9 +38,9 @@ export class MonitorComponent {
 
     this.notInQuorum = {
       columns: [
-        { prop: 'name', name: 'Name', cellTransformation: CellTemplate.routerLink },
-        { prop: 'rank', name: 'Rank' },
-        { prop: 'public_addr', name: 'Public Address' }
+        { prop: 'name', name: this.i18n('Name'), cellTransformation: CellTemplate.routerLink },
+        { prop: 'rank', name: this.i18n('Rank') },
+        { prop: 'public_addr', name: this.i18n('Public Address') }
       ],
       data: []
     };
index 32247d557b9078b6bebca89436e6652b63e023a9..b74f80f1853c2e3699b5da86c784f2049b9035bd 100644 (file)
@@ -6,7 +6,7 @@ import * as _ from 'lodash';
 import { ToastModule } from 'ng2-toastr';
 import { BsModalRef, ModalModule } from 'ngx-bootstrap/modal';
 
-import { configureTestBed } from '../../../../../testing/unit-test-helper';
+import { configureTestBed, i18nProviders } from '../../../../../testing/unit-test-helper';
 import { NotificationType } from '../../../../shared/enum/notification-type.enum';
 import { NotificationService } from '../../../../shared/services/notification.service';
 import { SharedModule } from '../../../../shared/shared.module';
@@ -33,7 +33,7 @@ describe('OsdFlagsModalComponent', () => {
       ToastModule.forRoot()
     ],
     declarations: [OsdFlagsModalComponent],
-    providers: [BsModalRef]
+    providers: [BsModalRef, i18nProviders]
   });
 
   beforeEach(() => {
index f195df1ecf65f4d979dbe4adac79c9ca76bdd048..c78b49137a0891413e7bd100011a71e34c95c92d 100644 (file)
@@ -1,6 +1,7 @@
 import { Component, OnInit } from '@angular/core';
 import { FormGroup } from '@angular/forms';
 
+import { I18n } from '@ngx-translate/i18n-polyfill';
 import * as _ from 'lodash';
 import { BsModalRef } from 'ngx-bootstrap/modal';
 
@@ -19,78 +20,83 @@ export class OsdFlagsModalComponent implements OnInit {
   allFlags = {
     noin: {
       code: 'noin',
-      name: 'No In',
+      name: this.i18n('No In'),
       value: false,
-      description: 'OSDs that were previously marked out will not be marked back in when they start'
+      description: this.i18n(
+        'OSDs that were previously marked out will not be marked back in when they start'
+      )
     },
     noout: {
       code: 'noout',
-      name: 'No Out',
+      name: this.i18n('No Out'),
       value: false,
-      description: 'OSDs will not automatically be marked out after the configured interval'
+      description: this.i18n(
+        'OSDs will not automatically be marked out after the configured interval'
+      )
     },
     noup: {
       code: 'noup',
-      name: 'No Up',
+      name: this.i18n('No Up'),
       value: false,
-      description: 'OSDs are not allowed to start'
+      description: this.i18n('OSDs are not allowed to start')
     },
     nodown: {
       code: 'nodown',
-      name: 'No Down',
+      name: this.i18n('No Down'),
       value: false,
-      description:
+      description: this.i18n(
         'OSD failure reports are being ignored, such that the monitors will not mark OSDs down'
+      )
     },
     pause: {
       code: 'pause',
-      name: 'Pause',
+      name: this.i18n('Pause'),
       value: false,
-      description: 'Pauses reads and writes'
+      description: this.i18n('Pauses reads and writes')
     },
     noscrub: {
       code: 'noscrub',
-      name: 'No Scrub',
+      name: this.i18n('No Scrub'),
       value: false,
-      description: 'Scrubbing is disabled'
+      description: this.i18n('Scrubbing is disabled')
     },
     'nodeep-scrub': {
       code: 'nodeep-scrub',
-      name: 'No Deep Scrub',
+      name: this.i18n('No Deep Scrub'),
       value: false,
-      description: 'Deep Scrubbing is disabled'
+      description: this.i18n('Deep Scrubbing is disabled')
     },
     nobackfill: {
       code: 'nobackfill',
-      name: 'No Backfill',
+      name: this.i18n('No Backfill'),
       value: false,
-      description: 'Backfilling of PGs is suspended'
+      description: this.i18n('Backfilling of PGs is suspended')
     },
     norecover: {
       code: 'norecover',
-      name: 'No Recover',
+      name: this.i18n('No Recover'),
       value: false,
-      description: 'Recovery of PGs is suspended'
+      description: this.i18n('Recovery of PGs is suspended')
     },
     sortbitwise: {
       code: 'sortbitwise',
-      name: 'Bitwise Sort',
+      name: this.i18n('Bitwise Sort'),
       value: false,
-      description: 'Use bitwise sort',
+      description: this.i18n('Use bitwise sort'),
       disabled: true
     },
     purged_snapdirs: {
       code: 'purged_snapdirs',
-      name: 'Purged Snapdirs',
+      name: this.i18n('Purged Snapdirs'),
       value: false,
-      description: 'OSDs have converted snapsets',
+      description: this.i18n('OSDs have converted snapsets'),
       disabled: true
     },
     recovery_deletes: {
       code: 'recovery_deletes',
-      name: 'Recovery Deletes',
+      name: this.i18n('Recovery Deletes'),
       value: false,
-      description: 'Deletes performed during recovery instead of peering',
+      description: this.i18n('Deletes performed during recovery instead of peering'),
       disabled: true
     }
   };
@@ -100,7 +106,8 @@ export class OsdFlagsModalComponent implements OnInit {
   constructor(
     public bsModalRef: BsModalRef,
     private osdService: OsdService,
-    private notificationService: NotificationService
+    private notificationService: NotificationService,
+    private i18n: I18n
   ) {}
 
   ngOnInit() {
@@ -126,8 +133,8 @@ export class OsdFlagsModalComponent implements OnInit {
       () => {
         this.notificationService.show(
           NotificationType.success,
-          'OSD Flags were updated successfully.',
-          'OSD Flags'
+          this.i18n('OSD Flags were updated successfully.'),
+          this.i18n('OSD Flags')
         );
         this.bsModalRef.hide();
       },
index 02a17796dd684a3e93cbce101c68245cf9f58bb7..53fb10e29a319b1943e8a034b59a39c89821ae15 100644 (file)
@@ -8,7 +8,11 @@ import { BsModalService } from 'ngx-bootstrap/modal';
 import { TabsModule } from 'ngx-bootstrap/tabs';
 import { EMPTY, of } from 'rxjs';
 
-import { configureTestBed, PermissionHelper } from '../../../../../testing/unit-test-helper';
+import {
+  configureTestBed,
+  i18nProviders,
+  PermissionHelper
+} from '../../../../../testing/unit-test-helper';
 import { OsdService } from '../../../../shared/api/osd.service';
 import { ConfirmationModalComponent } from '../../../../shared/components/confirmation-modal/confirmation-modal.component';
 import { CriticalConfirmationModalComponent } from '../../../../shared/components/critical-confirmation-modal/critical-confirmation-modal.component';
@@ -78,7 +82,8 @@ describe('OsdListComponent', () => {
     providers: [
       { provide: AuthStorageService, useValue: fakeAuthStorageService },
       TableActionsComponent,
-      BsModalService
+      BsModalService,
+      i18nProviders
     ]
   });
 
index bfa255662a4a8e206853feef2d92c28471ea6b82..1aadc0219ebe066f1cc3a5a18ed1a2b2c766b479 100644 (file)
@@ -1,5 +1,6 @@
 import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core';
 
+import { I18n } from '@ngx-translate/i18n-polyfill';
 import { BsModalRef, BsModalService } from 'ngx-bootstrap/modal';
 import { Observable } from 'rxjs';
 
@@ -55,81 +56,87 @@ export class OsdListComponent implements OnInit {
     private authStorageService: AuthStorageService,
     private osdService: OsdService,
     private dimlessBinaryPipe: DimlessBinaryPipe,
-    private modalService: BsModalService
+    private modalService: BsModalService,
+    private i18n: I18n
   ) {
     this.permission = this.authStorageService.getPermissions().osd;
     this.tableActions = [
       {
-        name: 'Scrub',
+        name: this.i18n('Scrub'),
         permission: 'update',
         icon: 'fa-stethoscope',
         click: () => this.scrubAction(false),
         disable: () => !this.hasOsdSelected
       },
       {
-        name: 'Deep Scrub',
+        name: this.i18n('Deep Scrub'),
         permission: 'update',
         icon: 'fa-cog',
         click: () => this.scrubAction(true),
         disable: () => !this.hasOsdSelected
       },
       {
-        name: 'Reweight',
+        name: this.i18n('Reweight'),
         permission: 'update',
         click: () => this.reweight(),
         disable: () => !this.hasOsdSelected,
         icon: 'fa-balance-scale'
       },
       {
-        name: 'Mark Out',
+        name: this.i18n('Mark Out'),
         permission: 'update',
-        click: () => this.showConfirmationModal('out', this.osdService.markOut),
+        click: () => this.showConfirmationModal(this.i18n('out'), this.osdService.markOut),
         disable: () => this.isNotSelectedOrInState('out'),
         icon: 'fa-arrow-left'
       },
       {
-        name: 'Mark In',
+        name: this.i18n('Mark In'),
         permission: 'update',
-        click: () => this.showConfirmationModal('in', this.osdService.markIn),
+        click: () => this.showConfirmationModal(this.i18n('in'), this.osdService.markIn),
         disable: () => this.isNotSelectedOrInState('in'),
         icon: 'fa-arrow-right'
       },
       {
-        name: 'Mark Down',
+        name: this.i18n('Mark Down'),
         permission: 'update',
-        click: () => this.showConfirmationModal('down', this.osdService.markDown),
+        click: () => this.showConfirmationModal(this.i18n('down'), this.osdService.markDown),
         disable: () => this.isNotSelectedOrInState('down'),
         icon: 'fa-arrow-down'
       },
       {
-        name: 'Mark Lost',
+        name: this.i18n('Mark Lost'),
         permission: 'delete',
         click: () =>
           this.showCriticalConfirmationModal(
-            'Mark',
-            'OSD lost',
-            'marked lost',
+            this.i18n('Mark'),
+            this.i18n('OSD lost'),
+            this.i18n('marked lost'),
             this.osdService.markLost
           ),
         disable: () => this.isNotSelectedOrInState('up'),
         icon: 'fa-unlink'
       },
       {
-        name: 'Remove',
+        name: this.i18n('Remove'),
         permission: 'delete',
         click: () =>
-          this.showCriticalConfirmationModal('Remove', 'OSD', 'removed', this.osdService.remove),
+          this.showCriticalConfirmationModal(
+            this.i18n('Remove'),
+            this.i18n('OSD'),
+            this.i18n('removed'),
+            this.osdService.remove
+          ),
         disable: () => this.isNotSelectedOrInState('up'),
         icon: 'fa-remove'
       },
       {
-        name: 'Destroy',
+        name: this.i18n('Destroy'),
         permission: 'delete',
         click: () =>
           this.showCriticalConfirmationModal(
-            'destroy',
-            'OSD',
-            'destroyed',
+            this.i18n('destroy'),
+            this.i18n('OSD'),
+            this.i18n('destroyed'),
             this.osdService.destroy
           ),
         disable: () => this.isNotSelectedOrInState('up'),
@@ -140,24 +147,32 @@ export class OsdListComponent implements OnInit {
 
   ngOnInit() {
     this.columns = [
-      { prop: 'host.name', name: 'Host' },
-      { prop: 'id', name: 'ID', cellTransformation: CellTemplate.bold },
-      { prop: 'collectedStates', name: 'Status', cellTemplate: this.statusColor },
-      { prop: 'stats.numpg', name: 'PGs' },
-      { prop: 'stats.stat_bytes', name: 'Size', pipe: this.dimlessBinaryPipe },
-      { name: 'Usage', cellTemplate: this.osdUsageTpl },
+      { prop: 'host.name', name: this.i18n('Host') },
+      { prop: 'id', name: this.i18n('ID'), cellTransformation: CellTemplate.bold },
+      { prop: 'collectedStates', name: this.i18n('Status'), cellTemplate: this.statusColor },
+      { prop: 'stats.numpg', name: this.i18n('PGs') },
+      { prop: 'stats.stat_bytes', name: this.i18n('Size'), pipe: this.dimlessBinaryPipe },
+      { name: this.i18n('Usage'), cellTemplate: this.osdUsageTpl },
       {
         prop: 'stats_history.out_bytes',
-        name: 'Read bytes',
+        name: this.i18n('Read bytes'),
         cellTransformation: CellTemplate.sparkline
       },
       {
         prop: 'stats_history.in_bytes',
-        name: 'Writes bytes',
+        name: this.i18n('Writes bytes'),
         cellTransformation: CellTemplate.sparkline
       },
-      { prop: 'stats.op_r', name: 'Read ops', cellTransformation: CellTemplate.perSecond },
-      { prop: 'stats.op_w', name: 'Write ops', cellTransformation: CellTemplate.perSecond }
+      {
+        prop: 'stats.op_r',
+        name: this.i18n('Read ops'),
+        cellTransformation: CellTemplate.perSecond
+      },
+      {
+        prop: 'stats.op_w',
+        name: this.i18n('Write ops'),
+        cellTransformation: CellTemplate.perSecond
+      }
     ];
   }
 
@@ -236,8 +251,8 @@ export class OsdListComponent implements OnInit {
   showConfirmationModal(markAction: string, onSubmit: (id: number) => Observable<any>) {
     this.bsModalRef = this.modalService.show(ConfirmationModalComponent, {
       initialState: {
-        titleText: `Mark OSD ${markAction}`,
-        buttonText: `Mark ${markAction}`,
+        titleText: this.i18n('Mark OSD {{markAction}}', { markAction: markAction }),
+        buttonText: this.i18n('Mark {{markAction}}', { markAction: markAction }),
         bodyTpl: this.markOsdConfirmationTpl,
         bodyContext: {
           markActionDescription: markAction
index 5c6888062b4f9f3c1ba95e9322a47944c5bc3190..1fc99668bcb59e6799a217da98687c045692121b 100644 (file)
@@ -4,7 +4,7 @@ import { ReactiveFormsModule } from '@angular/forms';
 
 import { BsModalRef } from 'ngx-bootstrap/modal';
 
-import { configureTestBed } from '../../../../../testing/unit-test-helper';
+import { configureTestBed, i18nProviders } from '../../../../../testing/unit-test-helper';
 import { OsdService } from '../../../../shared/api/osd.service';
 import { NotificationService } from '../../../../shared/services/notification.service';
 import { OsdScrubModalComponent } from './osd-scrub-modal.component';
@@ -38,7 +38,8 @@ describe('OsdScrubModalComponent', () => {
     providers: [
       BsModalRef,
       { provide: OsdService, useValue: fakeService },
-      { provide: NotificationService, useValue: fakeService }
+      { provide: NotificationService, useValue: fakeService },
+      i18nProviders
     ]
   });
 
index 98a367c763f9e86b1e4fbd5425917a8bfcf0ee31..de76ea884e85121700bc9e16ebc9284fd83c659a 100644 (file)
@@ -1,6 +1,7 @@
 import { Component, OnInit } from '@angular/core';
 import { FormGroup } from '@angular/forms';
 
+import { I18n } from '@ngx-translate/i18n-polyfill';
 import { BsModalRef } from 'ngx-bootstrap/modal';
 
 import { OsdService } from '../../../../shared/api/osd.service';
@@ -20,7 +21,8 @@ export class OsdScrubModalComponent implements OnInit {
   constructor(
     public bsModalRef: BsModalRef,
     private osdService: OsdService,
-    private notificationService: NotificationService
+    private notificationService: NotificationService,
+    private i18n: I18n
   ) {}
 
   ngOnInit() {
@@ -36,7 +38,10 @@ export class OsdScrubModalComponent implements OnInit {
 
         this.notificationService.show(
           NotificationType.success,
-          `${operation} was initialized in the following OSD: ${id}`
+          this.i18n('{{operation}} was initialized in the following OSD: {{id}}', {
+            operation: operation,
+            id: id
+          })
         );
 
         this.bsModalRef.hide();
index cfd808aaeb9e0ee41f7ebb98698cf95bb6264734..58cc5db7fd1432995bb5b2097d36a41933795e0e 100644 (file)
@@ -6,7 +6,7 @@ import * as _ from 'lodash';
 import { PopoverModule } from 'ngx-bootstrap/popover';
 import { of } from 'rxjs';
 
-import { configureTestBed } from '../../../../testing/unit-test-helper';
+import { configureTestBed, i18nProviders } from '../../../../testing/unit-test-helper';
 import { DashboardService } from '../../../shared/api/dashboard.service';
 import { SharedModule } from '../../../shared/shared.module';
 import { LogColorPipe } from '../log-color.pipe';
@@ -50,7 +50,8 @@ describe('HealthComponent', () => {
       LogColorPipe,
       PgStatusPipe
     ],
-    schemas: [NO_ERRORS_SCHEMA]
+    schemas: [NO_ERRORS_SCHEMA],
+    providers: i18nProviders
   });
 
   beforeEach(() => {
index 3362bde3da51249bcbd0b4e35c02bb8194d6696b..f2917f6ab6270fcfc3a0aa5db70a5a73a47d6157 100644 (file)
@@ -1,6 +1,7 @@
 import { ViewportScroller } from '@angular/common';
 import { Component, OnDestroy, OnInit } from '@angular/core';
 
+import { I18n } from '@ngx-translate/i18n-polyfill';
 import * as _ from 'lodash';
 
 import { DashboardService } from '../../../shared/api/dashboard.service';
@@ -16,7 +17,8 @@ export class HealthComponent implements OnInit, OnDestroy {
 
   constructor(
     private dashboardService: DashboardService,
-    public viewportScroller: ViewportScroller
+    public viewportScroller: ViewportScroller,
+    private i18n: I18n
   ) {}
 
   ngOnInit() {
@@ -40,9 +42,9 @@ export class HealthComponent implements OnInit, OnDestroy {
     const ratioLabels = [];
     const ratioData = [];
 
-    ratioLabels.push('Writes');
+    ratioLabels.push(this.i18n('Writes'));
     ratioData.push(this.contentData.client_perf.write_op_per_sec);
-    ratioLabels.push('Reads');
+    ratioLabels.push(this.i18n('Reads'));
     ratioData.push(this.contentData.client_perf.read_op_per_sec);
 
     chart.dataset[0].data = ratioData;
@@ -63,13 +65,16 @@ export class HealthComponent implements OnInit, OnDestroy {
     if (chart === 'doughnut') {
       chart.options.cutoutPercentage = 65;
     }
-    chart.labels = [`Used (${percentUsed}%)`, `Avail. (${percentAvailable}%)`];
+    chart.labels = [
+      `${this.i18n('Used')} (${percentUsed}%)`,
+      `${this.i18n('Avail.')} (${percentAvailable}%)`
+    ];
   }
 
   preparePgStatus(chart, data) {
-    const pgCategoryClean = 'Clean';
+    const pgCategoryClean = this.i18n('Clean');
     const pgCategoryCleanStates = ['active', 'clean'];
-    const pgCategoryWarning = 'Warning';
+    const pgCategoryWarning = this.i18n('Warning');
     const pgCategoryWarningStates = [
       'backfill_toofull',
       'backfill_unfound',
@@ -83,8 +88,8 @@ export class HealthComponent implements OnInit, OnDestroy {
       'stale',
       'undersized'
     ];
-    const pgCategoryUnknown = 'Unknown';
-    const pgCategoryWorking = 'Working';
+    const pgCategoryUnknown = this.i18n('Unknown');
+    const pgCategoryWorking = this.i18n('Working');
     const pgCategoryWorkingStates = [
       'activating',
       'backfill_wait',
index bbf33b5ac9a0c812edb3559e7007e9bf6bfa1b85..e8f004e9faaef2583dd954aa2e58e1b5dce4b4be 100644 (file)
@@ -1,7 +1,18 @@
+import { TestBed } from '@angular/core/testing';
+
+import { configureTestBed, i18nProviders } from '../../../testing/unit-test-helper';
 import { MdsSummaryPipe } from './mds-summary.pipe';
 
 describe('MdsSummaryPipe', () => {
-  const pipe = new MdsSummaryPipe();
+  let pipe: MdsSummaryPipe;
+
+  configureTestBed({
+    providers: [MdsSummaryPipe, i18nProviders]
+  });
+
+  beforeEach(() => {
+    pipe = TestBed.get(MdsSummaryPipe);
+  });
 
   it('create an instance', () => {
     expect(pipe).toBeTruthy();
index 9e6eeca6e8ac1500943d3a8ca0c5f2046b3545d6..7c2785111e77f4ac9b0a5b6428e581e4d179d17e 100644 (file)
@@ -1,10 +1,14 @@
 import { Pipe, PipeTransform } from '@angular/core';
+
+import { I18n } from '@ngx-translate/i18n-polyfill';
 import * as _ from 'lodash';
 
 @Pipe({
   name: 'mdsSummary'
 })
 export class MdsSummaryPipe implements PipeTransform {
+  constructor(private i18n: I18n) {}
+
   transform(value: any, args?: any): any {
     if (!value) {
       return '';
@@ -18,9 +22,9 @@ export class MdsSummaryPipe implements PipeTransform {
     });
 
     if (value.standbys && !value.filesystems) {
-      return standbys + ', no filesystems';
+      return standbys + ', ' + this.i18n('no filesystems');
     } else if (value.filesystems.length === 0) {
-      return 'no filesystems';
+      return this.i18n('no filesystems');
     } else {
       _.each(value.filesystems, (fs, i) => {
         _.each(fs.mdsmap.info, (mds, j) => {
@@ -32,7 +36,9 @@ export class MdsSummaryPipe implements PipeTransform {
         });
       });
 
-      return active + ' active, ' + (standbys + standbyReplay) + ' standby';
+      return `${active} ${this.i18n('active')}, ${standbys + standbyReplay} ${this.i18n(
+        'standby'
+      )}`;
     }
   }
 }
index 0800019941b6ac48a26c7b1d5e39746c5069ee71..754511dd5ae0c253f415c168eb888a71024a3b42 100644 (file)
@@ -1,7 +1,19 @@
+import { TestBed } from '@angular/core/testing';
+
+import { configureTestBed, i18nProviders } from '../../../testing/unit-test-helper';
+
 import { MgrSummaryPipe } from './mgr-summary.pipe';
 
 describe('MgrSummaryPipe', () => {
-  const pipe = new MgrSummaryPipe();
+  let pipe: MgrSummaryPipe;
+
+  configureTestBed({
+    providers: [MgrSummaryPipe, i18nProviders]
+  });
+
+  beforeEach(() => {
+    pipe = TestBed.get(MgrSummaryPipe);
+  });
 
   it('create an instance', () => {
     expect(pipe).toBeTruthy();
index cf793e66e4757febf4de32681f3ed5637c15f6a3..f55f0c304e97149c4a6880795da32fc3654ae880 100644 (file)
@@ -1,10 +1,14 @@
 import { Pipe, PipeTransform } from '@angular/core';
+
+import { I18n } from '@ngx-translate/i18n-polyfill';
 import * as _ from 'lodash';
 
 @Pipe({
   name: 'mgrSummary'
 })
 export class MgrSummaryPipe implements PipeTransform {
+  constructor(private i18n: I18n) {}
+
   transform(value: any, args?: any): any {
     if (!value) {
       return '';
@@ -14,7 +18,7 @@ export class MgrSummaryPipe implements PipeTransform {
     result += _.isUndefined(value.active_name) ? 'n/a' : value.active_name;
 
     if (value.standbys.length) {
-      result += ', ' + value.standbys.length + ' standbys';
+      result += ', ' + value.standbys.length + ' ' + this.i18n('standbys');
     }
 
     return result;
index 49f23bcba06a7d8086351ee454270152c6305405..9d193a5e0f6ee784c77a1565845a57b7e1da501e 100644 (file)
@@ -1,7 +1,18 @@
+import { TestBed } from '@angular/core/testing';
+
+import { configureTestBed, i18nProviders } from '../../../testing/unit-test-helper';
 import { MonSummaryPipe } from './mon-summary.pipe';
 
 describe('MonSummaryPipe', () => {
-  const pipe = new MonSummaryPipe();
+  let pipe: MonSummaryPipe;
+
+  configureTestBed({
+    providers: [MonSummaryPipe, i18nProviders]
+  });
+
+  beforeEach(() => {
+    pipe = TestBed.get(MonSummaryPipe);
+  });
 
   it('create an instance', () => {
     expect(pipe).toBeTruthy();
index 6877e2247c7e68d5eb212d913162c6f7f2754acc..48949a04fa849514f3719d5a6b6d163f1bf6c9ff 100644 (file)
@@ -1,17 +1,21 @@
 import { Pipe, PipeTransform } from '@angular/core';
 
+import { I18n } from '@ngx-translate/i18n-polyfill';
+
 @Pipe({
   name: 'monSummary'
 })
 export class MonSummaryPipe implements PipeTransform {
+  constructor(private i18n: I18n) {}
+
   transform(value: any, args?: any): any {
     if (!value) {
       return '';
     }
 
-    let result = value.monmap.mons.length.toString() + ' (quorum ';
-    result += value.quorum.join(', ');
-    result += ')';
+    const result = `${value.monmap.mons.length.toString()} (${this.i18n(
+      'quorum'
+    )} ${value.quorum.join(', ')})`;
 
     return result;
   }
index 92119691bf5652a740d26e47ef3eaba1af3b4011..6332017dd718fee1e0d930a820f6da5732674a2f 100644 (file)
@@ -1,7 +1,17 @@
+import { TestBed } from '@angular/core/testing';
+import { configureTestBed, i18nProviders } from '../../../testing/unit-test-helper';
 import { OsdSummaryPipe } from './osd-summary.pipe';
 
 describe('OsdSummaryPipe', () => {
-  const pipe = new OsdSummaryPipe();
+  let pipe: OsdSummaryPipe;
+
+  configureTestBed({
+    providers: [OsdSummaryPipe, i18nProviders]
+  });
+
+  beforeEach(() => {
+    pipe = TestBed.get(OsdSummaryPipe);
+  });
 
   it('create an instance', () => {
     expect(pipe).toBeTruthy();
index ad34e87bc67856f40ab419f6de582ac1e8310e54..b6a444be67382e61dbc88a491724476b4a92838b 100644 (file)
@@ -1,10 +1,14 @@
 import { Pipe, PipeTransform } from '@angular/core';
+
+import { I18n } from '@ngx-translate/i18n-polyfill';
 import * as _ from 'lodash';
 
 @Pipe({
   name: 'osdSummary'
 })
 export class OsdSummaryPipe implements PipeTransform {
+  constructor(private i18n: I18n) {}
+
   transform(value: any, args?: any): any {
     if (!value) {
       return '';
@@ -23,7 +27,7 @@ export class OsdSummaryPipe implements PipeTransform {
 
     const osdSummary = [
       {
-        content: `${value.osds.length} total`,
+        content: `${value.osds.length} ${this.i18n('total')}`,
         class: ''
       }
     ];
@@ -32,7 +36,7 @@ export class OsdSummaryPipe implements PipeTransform {
       class: 'card-text-line-break'
     });
     osdSummary.push({
-      content: `${upCount} up, ${inCount} in`,
+      content: `${upCount} ${this.i18n('up')}, ${inCount} ${this.i18n('in')}`,
       class: ''
     });
 
@@ -44,9 +48,9 @@ export class OsdSummaryPipe implements PipeTransform {
         class: 'card-text-line-break'
       });
 
-      const downText = downCount > 0 ? `${downCount} down` : '';
+      const downText = downCount > 0 ? `${downCount} ${this.i18n('down')}` : '';
       const separator = downCount > 0 && outCount > 0 ? ', ' : '';
-      const outText = outCount > 0 ? `${outCount} out` : '';
+      const outText = outCount > 0 ? `${outCount} ${this.i18n('out')}` : '';
       osdSummary.push({
         content: `${downText}${separator}${outText}`,
         class: 'card-text-error'
index d725a61b619f9b5e2cb2b196dcd63d21b836b1ff..233599bed421dd9e44016e015f9ddb2938cc5aa3 100644 (file)
@@ -2,7 +2,7 @@ import { HttpClientTestingModule } from '@angular/common/http/testing';
 import { ComponentFixture, TestBed } from '@angular/core/testing';
 import { RouterTestingModule } from '@angular/router/testing';
 
-import { configureTestBed } from '../../../../testing/unit-test-helper';
+import { configureTestBed, i18nProviders } from '../../../../testing/unit-test-helper';
 import { SharedModule } from '../../../shared/shared.module';
 import { TablePerformanceCounterComponent } from '../table-performance-counter/table-performance-counter.component';
 import { PerformanceCounterComponent } from './performance-counter.component';
@@ -13,7 +13,8 @@ describe('PerformanceCounterComponent', () => {
 
   configureTestBed({
     declarations: [PerformanceCounterComponent, TablePerformanceCounterComponent],
-    imports: [RouterTestingModule, SharedModule, HttpClientTestingModule]
+    imports: [RouterTestingModule, SharedModule, HttpClientTestingModule],
+    providers: i18nProviders
   });
 
   beforeEach(() => {
index 4e1cd078968089877cd9311a1c38bd6fb57e2a2e..4a219d8b10390a5d40f7e5e77fbd3213c221ab0e 100644 (file)
@@ -1,7 +1,7 @@
 import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
 import { ComponentFixture, TestBed } from '@angular/core/testing';
 
-import { configureTestBed } from '../../../../testing/unit-test-helper';
+import { configureTestBed, i18nProviders } from '../../../../testing/unit-test-helper';
 import { AppModule } from '../../../app.module';
 import { CdTableFetchDataContext } from '../../../shared/models/cd-table-fetch-data-context';
 import { TablePerformanceCounterComponent } from './table-performance-counter.component';
@@ -12,7 +12,8 @@ describe('TablePerformanceCounterComponent', () => {
   let httpTesting: HttpTestingController;
 
   configureTestBed({
-    imports: [AppModule, HttpClientTestingModule]
+    imports: [AppModule, HttpClientTestingModule],
+    providers: i18nProviders
   });
 
   beforeEach(() => {
index 704afb066c302279f3b4795c9bcb32fd7c14f40b..3d5979582d18d532067793d54c42749abadc79d3 100644 (file)
@@ -1,5 +1,7 @@
 import { Component, Input, OnInit, TemplateRef, ViewChild } from '@angular/core';
 
+import { I18n } from '@ngx-translate/i18n-polyfill';
+
 import { PerformanceCounterService } from '../../../shared/api/performance-counter.service';
 import { CdTableColumn } from '../../../shared/models/cd-table-column';
 import { CdTableFetchDataContext } from '../../../shared/models/cd-table-fetch-data-context';
@@ -31,22 +33,22 @@ export class TablePerformanceCounterComponent implements OnInit {
   @Input()
   serviceId: string;
 
-  constructor(private performanceCounterService: PerformanceCounterService) {}
+  constructor(private performanceCounterService: PerformanceCounterService, private i18n: I18n) {}
 
   ngOnInit() {
     this.columns = [
       {
-        name: 'Name',
+        name: this.i18n('Name'),
         prop: 'name',
         flexGrow: 1
       },
       {
-        name: 'Description',
+        name: this.i18n('Description'),
         prop: 'description',
         flexGrow: 1
       },
       {
-        name: 'Value',
+        name: this.i18n('Value'),
         cellTemplate: this.valueTpl,
         flexGrow: 1
       }
index c74a6bd3715c27120dc26a9acaf75afc61ab8bed..358354dee94550ad5cb902eec342ece83397f3dc 100644 (file)
@@ -1,4 +1,5 @@
 export class ErasureCodeProfileFormTooltips {
+  // TODO: I18N
   // Copied from /srv/cephmgr/ceph-dev/doc/rados/operations/erasure-code.*.rst
   k = `Each object is split in data-chunks parts, each stored on a different OSD.`;
 
index b5819e9c0abe65bb6ec556a268ca4731304e26ed..a8a998c3cec75ed282b68c74187ee0a8a0b648a6 100644 (file)
@@ -7,7 +7,7 @@ import { ToastModule } from 'ng2-toastr';
 import { BsModalRef } from 'ngx-bootstrap/modal';
 import { of } from 'rxjs';
 
-import { configureTestBed, FormHelper } from '../../../../testing/unit-test-helper';
+import { configureTestBed, FormHelper, i18nProviders } from '../../../../testing/unit-test-helper';
 import { ErasureCodeProfileService } from '../../../shared/api/erasure-code-profile.service';
 import { ErasureCodeProfile } from '../../../shared/models/erasure-code-profile';
 import { TaskWrapperService } from '../../../shared/services/task-wrapper.service';
@@ -23,7 +23,7 @@ describe('ErasureCodeProfileFormComponent', () => {
 
   configureTestBed({
     imports: [HttpClientTestingModule, RouterTestingModule, ToastModule.forRoot(), PoolModule],
-    providers: [ErasureCodeProfileService, BsModalRef]
+    providers: [ErasureCodeProfileService, BsModalRef, i18nProviders]
   });
 
   beforeEach(() => {
index c87f2c059e2ac1de7e76552e6cc004f4e5172f7e..0c0e1390ea1eeaad3c09252297f5870545221457 100644 (file)
@@ -1,35 +1,43 @@
 import { Validators } from '@angular/forms';
 
+import { I18n } from '@ngx-translate/i18n-polyfill';
+
 import { SelectBadgesMessages } from '../../../shared/components/select-badges/select-badges-messages.model';
 import { SelectBadgesOption } from '../../../shared/components/select-badges/select-badges-option.model';
 import { Pool } from '../pool';
 
 export class PoolFormData {
-  poolTypes = ['erasure', 'replicated'];
+  poolTypes: string[];
   erasureInfo = false;
   crushInfo = false;
-  applications = {
-    selected: [],
-    available: [
-      new SelectBadgesOption(false, 'cephfs', ''),
-      new SelectBadgesOption(false, 'rbd', ''),
-      new SelectBadgesOption(false, 'rgw', '')
-    ],
-    validators: [Validators.pattern('[A-Za-z0-9_]+'), Validators.maxLength(128)],
-    messages: new SelectBadgesMessages({
-      empty: 'No applications added',
-      selectionLimit: {
-        text: 'Applications limit reached',
-        tooltip: 'A pool can only have up to four applications definitions.'
-      },
-      customValidations: {
-        pattern: `Allowed characters '_a-zA-Z0-9'`,
-        maxlength: 'Maximum length is 128 characters'
-      },
-      filter: 'Filter or add applications',
-      add: 'Add application'
-    })
-  };
+  applications: any;
+
+  constructor(i18n: I18n) {
+    this.poolTypes = ['erasure', 'replicated'];
+    this.applications = {
+      selected: [],
+      available: [
+        new SelectBadgesOption(false, 'cephfs', ''),
+        new SelectBadgesOption(false, 'rbd', ''),
+        new SelectBadgesOption(false, 'rgw', '')
+      ],
+      validators: [Validators.pattern('[A-Za-z0-9_]+'), Validators.maxLength(128)],
+      messages: new SelectBadgesMessages({
+        empty: i18n('No applications added'),
+        selectionLimit: {
+          text: i18n('Applications limit reached'),
+          tooltip: i18n('A pool can only have up to four applications definitions.')
+        },
+        customValidations: {
+          pattern: i18n(`Allowed characters '_a-zA-Z0-9'`),
+          maxlength: i18n('Maximum length is 128 characters')
+        },
+        filter: i18n('Filter or add applications'),
+        add: i18n('Add application')
+      })
+    };
+  }
+
   pgs = 1;
   pool: Pool; // Only available during edit mode
 }
index 5770d240f5ea817f9db772e7b32b62c7a9a0f8e8..6b463693b0a4cb6ecce907a8ebc73abcdf55ee25 100644 (file)
@@ -10,7 +10,7 @@ import { BsModalService } from 'ngx-bootstrap/modal';
 import { TabsModule } from 'ngx-bootstrap/tabs';
 import { of } from 'rxjs';
 
-import { configureTestBed, FormHelper } from '../../../../testing/unit-test-helper';
+import { configureTestBed, FormHelper, i18nProviders } from '../../../../testing/unit-test-helper';
 import { NotFoundComponent } from '../../../core/not-found/not-found.component';
 import { ErasureCodeProfileService } from '../../../shared/api/erasure-code-profile.service';
 import { PoolService } from '../../../shared/api/pool.service';
@@ -134,7 +134,8 @@ describe('PoolFormComponent', () => {
     providers: [
       ErasureCodeProfileService,
       SelectBadgesComponent,
-      { provide: ActivatedRoute, useValue: { params: of({ name: 'somePoolName' }) } }
+      { provide: ActivatedRoute, useValue: { params: of({ name: 'somePoolName' }) } },
+      i18nProviders
     ]
   });
 
index a43198ff222eafdedbf4e3faf413a6079d5beb2c..d951e80789f4ceb5f4b16845b709dc20e1f3129b 100644 (file)
@@ -2,6 +2,7 @@ import { Component, OnInit } from '@angular/core';
 import { FormControl, Validators } from '@angular/forms';
 import { ActivatedRoute, Router } from '@angular/router';
 
+import { I18n } from '@ngx-translate/i18n-polyfill';
 import * as _ from 'lodash';
 import { BsModalService } from 'ngx-bootstrap/modal';
 import { forkJoin, Subscription } from 'rxjs';
@@ -38,7 +39,7 @@ export class PoolFormComponent implements OnInit {
   info: PoolFormInfo;
   routeParamsSubscribe: any;
   editing = false;
-  data = new PoolFormData();
+  data = new PoolFormData(this.i18n);
   externalPgChange = false;
   private modalSubscription: Subscription;
   current = {
@@ -55,7 +56,8 @@ export class PoolFormComponent implements OnInit {
     private formatter: FormatterService,
     private bsModalService: BsModalService,
     private taskWrapper: TaskWrapperService,
-    private ecpService: ErasureCodeProfileService
+    private ecpService: ErasureCodeProfileService,
+    private i18n: I18n
   ) {
     this.editing = this.router.url.startsWith('/pool/edit');
     this.authenticate();
@@ -453,7 +455,7 @@ export class PoolFormComponent implements OnInit {
     this.modalSubscription = this.modalService.onHide.subscribe(() => this.reloadECPs());
     this.modalService.show(CriticalConfirmationModalComponent, {
       initialState: {
-        itemDescription: 'erasure code profile',
+        itemDescription: this.i18n('erasure code profile'),
         submitActionObservable: () =>
           this.taskWrapper.wrapTaskAroundCall({
             task: new FinishedTask('ecp/delete', { name: name }),
index ee8f6c540751d3f06c6223cf36dc51dbe53e8d36..52c6674bdacaf882063f3da554371fbdb93c2d99 100644 (file)
@@ -7,7 +7,7 @@ import { BsModalService } from 'ngx-bootstrap/modal';
 import { TabsModule } from 'ngx-bootstrap/tabs';
 import { of } from 'rxjs';
 
-import { configureTestBed } from '../../../../testing/unit-test-helper';
+import { configureTestBed, i18nProviders } from '../../../../testing/unit-test-helper';
 import { PoolService } from '../../../shared/api/pool.service';
 import { DeletionModalComponent } from '../../../shared/components/deletion-modal/deletion-modal.component';
 import { ExecutingTask } from '../../../shared/models/executing-task';
@@ -30,7 +30,8 @@ describe('PoolListComponent', () => {
       RouterTestingModule,
       TabsModule.forRoot(),
       HttpClientTestingModule
-    ]
+    ],
+    providers: i18nProviders
   });
 
   beforeEach(() => {
index cad9b85a1e147d7f52893bbb71c3e0d47e10e6b2..83b9774d43bf84c083e6f38c40d3ba93e067072e 100644 (file)
@@ -1,5 +1,6 @@
 import { Component, OnInit, ViewChild } from '@angular/core';
 
+import { I18n } from '@ngx-translate/i18n-polyfill';
 import { BsModalRef, BsModalService } from 'ngx-bootstrap/modal';
 
 import { PoolService } from '../../../shared/api/pool.service';
@@ -42,67 +43,73 @@ export class PoolListComponent implements OnInit {
     private taskWrapper: TaskWrapperService,
     private authStorageService: AuthStorageService,
     private taskListService: TaskListService,
-    private modalService: BsModalService
+    private modalService: BsModalService,
+    private i18n: I18n
   ) {
     this.permission = this.authStorageService.getPermissions().pool;
     this.tableActions = [
-      { permission: 'create', icon: 'fa-plus', routerLink: () => '/pool/add', name: 'Add' },
+      {
+        permission: 'create',
+        icon: 'fa-plus',
+        routerLink: () => '/pool/add',
+        name: this.i18n('Add')
+      },
       {
         permission: 'update',
         icon: 'fa-pencil',
         routerLink: () => '/pool/edit/' + this.selection.first().pool_name,
-        name: 'Edit'
+        name: this.i18n('Edit')
       },
       {
         permission: 'delete',
         icon: 'fa-trash-o',
         click: () => this.deletePoolModal(),
-        name: 'Delete'
+        name: this.i18n('Delete')
       }
     ];
     this.columns = [
       {
         prop: 'pool_name',
-        name: 'Name',
+        name: this.i18n('Name'),
         flexGrow: 3,
         cellTransformation: CellTemplate.executing
       },
       {
         prop: 'type',
-        name: 'Type',
+        name: this.i18n('Type'),
         flexGrow: 2
       },
       {
         prop: 'application_metadata',
-        name: 'Applications',
+        name: this.i18n('Applications'),
         flexGrow: 3
       },
       {
         prop: 'pg_placement_num',
-        name: 'Placement Groups',
+        name: this.i18n('Placement Groups'),
         flexGrow: 1,
         cellClass: 'text-right'
       },
       {
         prop: 'size',
-        name: 'Replica Size',
+        name: this.i18n('Replica Size'),
         flexGrow: 1,
         cellClass: 'text-right'
       },
       {
         prop: 'last_change',
-        name: 'Last Change',
+        name: this.i18n('Last Change'),
         flexGrow: 1,
         cellClass: 'text-right'
       },
       {
         prop: 'erasure_code_profile',
-        name: 'Erasure Coded Profile',
+        name: this.i18n('Erasure Coded Profile'),
         flexGrow: 2
       },
       {
         prop: 'crush_rule',
-        name: 'Crush Ruleset',
+        name: this.i18n('Crush Ruleset'),
         flexGrow: 2
       }
     ];
index 75941b9e30bd259ff62cb291386d0849a1ceecad..565caab1563cd9acc58ec1d1c536e41b59729a80 100644 (file)
@@ -2,7 +2,7 @@ import { HttpClientTestingModule } from '@angular/common/http/testing';
 import { ComponentFixture, TestBed } from '@angular/core/testing';
 import { RouterTestingModule } from '@angular/router/testing';
 
-import { configureTestBed } from '../../../../testing/unit-test-helper';
+import { configureTestBed, i18nProviders } from '../../../../testing/unit-test-helper';
 import { SharedModule } from '../../../shared/shared.module';
 import { Rgw501Component } from './rgw-501.component';
 
@@ -12,7 +12,8 @@ describe('Rgw501Component', () => {
 
   configureTestBed({
     declarations: [Rgw501Component],
-    imports: [HttpClientTestingModule, RouterTestingModule, SharedModule]
+    imports: [HttpClientTestingModule, RouterTestingModule, SharedModule],
+    providers: i18nProviders
   });
 
   beforeEach(() => {
index 60f9e0c132781f00ffabd7ebc56ea55369a21cb7..c6bb981d0a339dcd5e8fe249a1c8575c1940c379 100644 (file)
@@ -6,7 +6,11 @@ import { RouterTestingModule } from '@angular/router/testing';
 import { ModalModule } from 'ngx-bootstrap/modal';
 import { TabsModule } from 'ngx-bootstrap/tabs';
 
-import { configureTestBed, PermissionHelper } from '../../../../testing/unit-test-helper';
+import {
+  configureTestBed,
+  i18nProviders,
+  PermissionHelper
+} from '../../../../testing/unit-test-helper';
 import { TableActionsComponent } from '../../../shared/datatable/table-actions/table-actions.component';
 import { SharedModule } from '../../../shared/shared.module';
 import { RgwBucketDetailsComponent } from '../rgw-bucket-details/rgw-bucket-details.component';
@@ -24,7 +28,8 @@ describe('RgwBucketListComponent', () => {
       SharedModule,
       TabsModule.forRoot(),
       HttpClientTestingModule
-    ]
+    ],
+    providers: i18nProviders
   });
 
   beforeEach(() => {
index 170835f05db023c3f036137e1b32c4c33fa870de..3c4e8ce054796cff29d9261eadc822b6469d9567 100644 (file)
@@ -1,5 +1,6 @@
 import { Component, ViewChild } from '@angular/core';
 
+import { I18n } from '@ngx-translate/i18n-polyfill';
 import { BsModalService } from 'ngx-bootstrap/modal';
 import { forkJoin as observableForkJoin, Observable, Subscriber } from 'rxjs';
 
@@ -31,17 +32,18 @@ export class RgwBucketListComponent {
   constructor(
     private authStorageService: AuthStorageService,
     private rgwBucketService: RgwBucketService,
-    private bsModalService: BsModalService
+    private bsModalService: BsModalService,
+    private i18n: I18n
   ) {
     this.permission = this.authStorageService.getPermissions().rgw;
     this.columns = [
       {
-        name: 'Name',
+        name: this.i18n('Name'),
         prop: 'bucket',
         flexGrow: 1
       },
       {
-        name: 'Owner',
+        name: this.i18n('Owner'),
         prop: 'owner',
         flexGrow: 1
       }
@@ -52,19 +54,19 @@ export class RgwBucketListComponent {
       permission: 'create',
       icon: 'fa-plus',
       routerLink: () => '/rgw/bucket/add',
-      name: 'Add'
+      name: this.i18n('Add')
     };
     const editAction: CdTableAction = {
       permission: 'update',
       icon: 'fa-pencil',
       routerLink: () => `/rgw/bucket/edit/${getBucketUri()}`,
-      name: 'Edit'
+      name: this.i18n('Edit')
     };
     const deleteAction: CdTableAction = {
       permission: 'delete',
       icon: 'fa-times',
       click: () => this.deleteAction(),
-      name: 'Delete'
+      name: this.i18n('Delete')
     };
     this.tableActions = [addAction, editAction, deleteAction];
   }
@@ -87,7 +89,9 @@ export class RgwBucketListComponent {
   deleteAction() {
     this.bsModalService.show(CriticalConfirmationModalComponent, {
       initialState: {
-        itemDescription: this.selection.hasSingleSelection ? 'bucket' : 'buckets',
+        itemDescription: this.selection.hasSingleSelection
+          ? this.i18n('bucket')
+          : this.i18n('buckets'),
         submitActionObservable: () => {
           return new Observable((observer: Subscriber<any>) => {
             // Delete all selected data table rows.
index cc1b43c39d89237e8cb269768937ba8d8ca547bf..65b7102c8698f1605aeac0e70f7eaa5f8a4845b5 100644 (file)
@@ -4,7 +4,7 @@ import { RouterTestingModule } from '@angular/router/testing';
 
 import { TabsModule } from 'ngx-bootstrap/tabs';
 
-import { configureTestBed } from '../../../../testing/unit-test-helper';
+import { configureTestBed, i18nProviders } from '../../../../testing/unit-test-helper';
 import { SharedModule } from '../../../shared/shared.module';
 import { PerformanceCounterModule } from '../../performance-counter/performance-counter.module';
 import { RgwDaemonDetailsComponent } from '../rgw-daemon-details/rgw-daemon-details.component';
@@ -22,7 +22,8 @@ describe('RgwDaemonListComponent', () => {
       PerformanceCounterModule,
       SharedModule,
       RouterTestingModule
-    ]
+    ],
+    providers: i18nProviders
   });
 
   beforeEach(() => {
index 281421f788650c4bc3a97bf758e616d4d9ba81cd..d0eaaac9d4390fe537b36fc4303ff143d9c3cd23 100644 (file)
@@ -1,5 +1,7 @@
 import { Component } from '@angular/core';
 
+import { I18n } from '@ngx-translate/i18n-polyfill';
+
 import { RgwDaemonService } from '../../../shared/api/rgw-daemon.service';
 import { CdTableColumn } from '../../../shared/models/cd-table-column';
 import { CdTableFetchDataContext } from '../../../shared/models/cd-table-fetch-data-context';
@@ -18,21 +20,22 @@ export class RgwDaemonListComponent {
 
   constructor(
     private rgwDaemonService: RgwDaemonService,
-    cephShortVersionPipe: CephShortVersionPipe
+    cephShortVersionPipe: CephShortVersionPipe,
+    private i18n: I18n
   ) {
     this.columns = [
       {
-        name: 'ID',
+        name: this.i18n('ID'),
         prop: 'id',
         flexGrow: 2
       },
       {
-        name: 'Hostname',
+        name: this.i18n('Hostname'),
         prop: 'server_hostname',
         flexGrow: 2
       },
       {
-        name: 'Version',
+        name: this.i18n('Version'),
         prop: 'version',
         flexGrow: 1,
         pipe: cephShortVersionPipe
index 825b69203633bd56c3d92749f1bbacbbf32ef32d..d5afbc5285a03707c73c44a2877342dbafbe5aa3 100644 (file)
@@ -4,7 +4,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
 import { BsModalService } from 'ngx-bootstrap/modal';
 import { TabsModule } from 'ngx-bootstrap/tabs';
 
-import { configureTestBed } from '../../../../testing/unit-test-helper';
+import { configureTestBed, i18nProviders } from '../../../../testing/unit-test-helper';
 import { CdTableSelection } from '../../../shared/models/cd-table-selection';
 import { SharedModule } from '../../../shared/shared.module';
 import { RgwUserDetailsComponent } from './rgw-user-details.component';
@@ -16,7 +16,7 @@ describe('RgwUserDetailsComponent', () => {
   configureTestBed({
     declarations: [RgwUserDetailsComponent],
     imports: [HttpClientTestingModule, SharedModule, TabsModule.forRoot()],
-    providers: [BsModalService]
+    providers: [BsModalService, i18nProviders]
   });
 
   beforeEach(() => {
index e31806515045f53fe8ecf7fec052daca3ba71d13..108efc63b9f04b8571e3cdcbc612e7b8e28540d6 100644 (file)
@@ -1,5 +1,6 @@
 import { Component, Input, OnChanges, OnInit, TemplateRef, ViewChild } from '@angular/core';
 
+import { I18n } from '@ngx-translate/i18n-polyfill';
 import * as _ from 'lodash';
 import { BsModalService } from 'ngx-bootstrap/modal';
 
@@ -33,17 +34,21 @@ export class RgwUserDetailsComponent implements OnChanges, OnInit {
   keysColumns: CdTableColumn[] = [];
   keysSelection: CdTableSelection = new CdTableSelection();
 
-  constructor(private rgwUserService: RgwUserService, private bsModalService: BsModalService) {}
+  constructor(
+    private rgwUserService: RgwUserService,
+    private bsModalService: BsModalService,
+    private i18n: I18n
+  ) {}
 
   ngOnInit() {
     this.keysColumns = [
       {
-        name: 'Username',
+        name: this.i18n('Username'),
         prop: 'username',
         flexGrow: 1
       },
       {
-        name: 'Type',
+        name: this.i18n('Type'),
         prop: 'type',
         flexGrow: 1
       }
index c42c10ec54fc7a8285bd583bb37efaabc2e1bfdb..8f05cab50aa31bb95ba748b2aa56b1015eb42849 100644 (file)
@@ -6,7 +6,11 @@ import { RouterTestingModule } from '@angular/router/testing';
 
 import { ModalModule } from 'ngx-bootstrap/modal';
 
-import { configureTestBed, PermissionHelper } from '../../../../testing/unit-test-helper';
+import {
+  configureTestBed,
+  i18nProviders,
+  PermissionHelper
+} from '../../../../testing/unit-test-helper';
 import { TableActionsComponent } from '../../../shared/datatable/table-actions/table-actions.component';
 import { SharedModule } from '../../../shared/shared.module';
 import { RgwUserListComponent } from './rgw-user-list.component';
@@ -18,7 +22,8 @@ describe('RgwUserListComponent', () => {
   configureTestBed({
     declarations: [RgwUserListComponent],
     imports: [RouterTestingModule, HttpClientTestingModule, ModalModule.forRoot(), SharedModule],
-    schemas: [NO_ERRORS_SCHEMA]
+    schemas: [NO_ERRORS_SCHEMA],
+    providers: i18nProviders
   });
 
   beforeEach(() => {
index 29397ebdb965622947b5f4f2a94f2641f9da4d2c..2dacb8390c55b4ad41c5b8e4f254bcb4e5149e80 100644 (file)
@@ -1,5 +1,6 @@
 import { Component, ViewChild } from '@angular/core';
 
+import { I18n } from '@ngx-translate/i18n-polyfill';
 import { BsModalService } from 'ngx-bootstrap/modal';
 import { forkJoin as observableForkJoin, Observable, Subscriber } from 'rxjs';
 
@@ -32,33 +33,34 @@ export class RgwUserListComponent {
   constructor(
     private authStorageService: AuthStorageService,
     private rgwUserService: RgwUserService,
-    private bsModalService: BsModalService
+    private bsModalService: BsModalService,
+    private i18n: I18n
   ) {
     this.permission = this.authStorageService.getPermissions().rgw;
     this.columns = [
       {
-        name: 'Username',
+        name: this.i18n('Username'),
         prop: 'user_id',
         flexGrow: 1
       },
       {
-        name: 'Full name',
+        name: this.i18n('Full name'),
         prop: 'display_name',
         flexGrow: 1
       },
       {
-        name: 'Email address',
+        name: this.i18n('Email address'),
         prop: 'email',
         flexGrow: 1
       },
       {
-        name: 'Suspended',
+        name: this.i18n('Suspended'),
         prop: 'suspended',
         flexGrow: 1,
         cellTransformation: CellTemplate.checkIcon
       },
       {
-        name: 'Max. buckets',
+        name: this.i18n('Max. buckets'),
         prop: 'max_buckets',
         flexGrow: 1
       }
@@ -68,19 +70,19 @@ export class RgwUserListComponent {
       permission: 'create',
       icon: 'fa-plus',
       routerLink: () => '/rgw/user/add',
-      name: 'Add'
+      name: this.i18n('Add')
     };
     const editAction: CdTableAction = {
       permission: 'update',
       icon: 'fa-pencil',
       routerLink: () => `/rgw/user/edit/${getUserUri()}`,
-      name: 'Edit'
+      name: this.i18n('Edit')
     };
     const deleteAction: CdTableAction = {
       permission: 'delete',
       icon: 'fa-times',
       click: () => this.deleteAction(),
-      name: 'Delete'
+      name: this.i18n('Delete')
     };
     this.tableActions = [addAction, editAction, deleteAction];
   }
@@ -103,7 +105,7 @@ export class RgwUserListComponent {
   deleteAction() {
     this.bsModalService.show(CriticalConfirmationModalComponent, {
       initialState: {
-        itemDescription: this.selection.hasSingleSelection ? 'user' : 'users',
+        itemDescription: this.selection.hasSingleSelection ? this.i18n('user') : this.i18n('users'),
         submitActionObservable: (): Observable<any> => {
           return new Observable((observer: Subscriber<any>) => {
             // Delete all selected data table rows.
index 28c0f68ead4cf53122e1fc7f774c073b19659cb4..71ec6fbf7e13c539b1f251f1807ba93b3e035631 100644 (file)
@@ -5,7 +5,7 @@ import { RouterTestingModule } from '@angular/router/testing';
 import { ToastModule } from 'ng2-toastr';
 import { TabsModule } from 'ngx-bootstrap/tabs';
 
-import { configureTestBed } from '../../../../testing/unit-test-helper';
+import { configureTestBed, i18nProviders } from '../../../../testing/unit-test-helper';
 import { CdTableSelection } from '../../../shared/models/cd-table-selection';
 import { SharedModule } from '../../../shared/shared.module';
 import { RoleDetailsComponent } from './role-details.component';
@@ -22,7 +22,8 @@ describe('RoleDetailsComponent', () => {
       RouterTestingModule,
       HttpClientTestingModule
     ],
-    declarations: [RoleDetailsComponent]
+    declarations: [RoleDetailsComponent],
+    providers: i18nProviders
   });
 
   beforeEach(() => {
index a81f4cbda1cf7389b272395f6b61ad4762d61f82..4a8e0268775749eb1a133288e90c01d38c0767b3 100644 (file)
@@ -1,5 +1,6 @@
 import { Component, Input, OnChanges, OnInit } from '@angular/core';
 
+import { I18n } from '@ngx-translate/i18n-polyfill';
 import * as _ from 'lodash';
 
 import { CellTemplate } from '../../../shared/enum/cell-template.enum';
@@ -21,39 +22,39 @@ export class RoleDetailsComponent implements OnChanges, OnInit {
   columns: CdTableColumn[];
   scopes_permissions: Array<any> = [];
 
-  constructor() {}
+  constructor(private i18n: I18n) {}
 
   ngOnInit() {
     this.columns = [
       {
         prop: 'scope',
-        name: 'Scope',
+        name: this.i18n('Scope'),
         flexGrow: 2
       },
       {
         prop: 'read',
-        name: 'Read',
+        name: this.i18n('Read'),
         flexGrow: 1,
         cellClass: 'text-center',
         cellTransformation: CellTemplate.checkIcon
       },
       {
         prop: 'create',
-        name: 'Create',
+        name: this.i18n('Create'),
         flexGrow: 1,
         cellClass: 'text-center',
         cellTransformation: CellTemplate.checkIcon
       },
       {
         prop: 'update',
-        name: 'Update',
+        name: this.i18n('Update'),
         flexGrow: 1,
         cellClass: 'text-center',
         cellTransformation: CellTemplate.checkIcon
       },
       {
         prop: 'delete',
-        name: 'Delete',
+        name: this.i18n('Delete'),
         flexGrow: 1,
         cellClass: 'text-center',
         cellTransformation: CellTemplate.checkIcon
index eb2f1caab20a587f63608f180e8baa081b956907..b80fa441176f477c8adef58b0bbcf5cac3473421 100644 (file)
@@ -8,7 +8,7 @@ import { RouterTestingModule } from '@angular/router/testing';
 import { ToastModule } from 'ng2-toastr';
 import { of } from 'rxjs';
 
-import { configureTestBed, FormHelper } from '../../../../testing/unit-test-helper';
+import { configureTestBed, FormHelper, i18nProviders } from '../../../../testing/unit-test-helper';
 import { RoleService } from '../../../shared/api/role.service';
 import { ScopeService } from '../../../shared/api/scope.service';
 import { CdFormGroup } from '../../../shared/forms/cd-form-group';
@@ -40,7 +40,8 @@ describe('RoleFormComponent', () => {
         ToastModule.forRoot(),
         SharedModule
       ],
-      declarations: [RoleFormComponent, FakeComponent]
+      declarations: [RoleFormComponent, FakeComponent],
+      providers: i18nProviders
     },
     true
   );
index c8dcc71766490aca0cdf6784d62ada248539b545..a1b02c7be2b63e075f8c61c3d24adf260cd23ee1 100644 (file)
@@ -2,6 +2,7 @@ import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core';
 import { FormControl, Validators } from '@angular/forms';
 import { ActivatedRoute, Router } from '@angular/router';
 
+import { I18n } from '@ngx-translate/i18n-polyfill';
 import * as _ from 'lodash';
 import { BsModalRef } from 'ngx-bootstrap/modal';
 import { forkJoin as observableForkJoin } from 'rxjs';
@@ -46,7 +47,8 @@ export class RoleFormComponent implements OnInit {
     private router: Router,
     private roleService: RoleService,
     private scopeService: ScopeService,
-    private notificationService: NotificationService
+    private notificationService: NotificationService,
+    private i18n: I18n
   ) {
     this.createForm();
     this.listenToChanges();
@@ -67,14 +69,14 @@ export class RoleFormComponent implements OnInit {
     this.columns = [
       {
         prop: 'scope',
-        name: 'All',
+        name: this.i18n('All'),
         flexGrow: 2,
         cellTemplate: this.cellScopeCheckboxTpl,
         headerTemplate: this.headerPermissionCheckboxTpl
       },
       {
         prop: 'read',
-        name: 'Read',
+        name: this.i18n('Read'),
         flexGrow: 1,
         cellClass: 'text-center',
         cellTemplate: this.cellPermissionCheckboxTpl,
@@ -82,7 +84,7 @@ export class RoleFormComponent implements OnInit {
       },
       {
         prop: 'create',
-        name: 'Create',
+        name: this.i18n('Create'),
         flexGrow: 1,
         cellClass: 'text-center',
         cellTemplate: this.cellPermissionCheckboxTpl,
@@ -90,7 +92,7 @@ export class RoleFormComponent implements OnInit {
       },
       {
         prop: 'update',
-        name: 'Update',
+        name: this.i18n('Update'),
         flexGrow: 1,
         cellClass: 'text-center',
         cellTemplate: this.cellPermissionCheckboxTpl,
@@ -98,7 +100,7 @@ export class RoleFormComponent implements OnInit {
       },
       {
         prop: 'delete',
-        name: 'Delete',
+        name: this.i18n('Delete'),
         flexGrow: 1,
         cellClass: 'text-center',
         cellTemplate: this.cellPermissionCheckboxTpl,
@@ -267,7 +269,7 @@ export class RoleFormComponent implements OnInit {
       () => {
         this.notificationService.show(
           NotificationType.success,
-          `Created role '${roleFormModel.name}'`
+          this.i18n(`Created role '{{role_name}}'`, { role_name: roleFormModel.name })
         );
         this.router.navigate(['/user-management/roles']);
       },
@@ -283,7 +285,7 @@ export class RoleFormComponent implements OnInit {
       () => {
         this.notificationService.show(
           NotificationType.success,
-          `Updated role '${roleFormModel.name}'`
+          this.i18n(`Updated role '{{role_name}}'`, { role_name: roleFormModel.name })
         );
         this.router.navigate(['/user-management/roles']);
       },
index 4a2a7d3173317d70a8bcb62f182c754d035cebc2..58c0c17a8ab19b7330fce444517704aa6a9b3da3 100644 (file)
@@ -6,7 +6,11 @@ import { RouterTestingModule } from '@angular/router/testing';
 import { ToastModule } from 'ng2-toastr';
 import { TabsModule } from 'ngx-bootstrap/tabs';
 
-import { configureTestBed, PermissionHelper } from '../../../../testing/unit-test-helper';
+import {
+  configureTestBed,
+  i18nProviders,
+  PermissionHelper
+} from '../../../../testing/unit-test-helper';
 import { TableActionsComponent } from '../../../shared/datatable/table-actions/table-actions.component';
 import { SharedModule } from '../../../shared/shared.module';
 import { RoleDetailsComponent } from '../role-details/role-details.component';
@@ -25,7 +29,8 @@ describe('RoleListComponent', () => {
       TabsModule.forRoot(),
       RouterTestingModule,
       HttpClientTestingModule
-    ]
+    ],
+    providers: i18nProviders
   });
 
   beforeEach(() => {
index 2f1836408ef05a5e70e168647c67babd5d24e1aa..007f4bbbea8af2429af5869298389b7d35749cd3 100644 (file)
@@ -1,5 +1,6 @@
 import { Component, OnInit } from '@angular/core';
 
+import { I18n } from '@ngx-translate/i18n-polyfill';
 import { BsModalRef, BsModalService } from 'ngx-bootstrap/modal';
 import { forkJoin } from 'rxjs';
 
@@ -37,14 +38,15 @@ export class RoleListComponent implements OnInit {
     private emptyPipe: EmptyPipe,
     private authStorageService: AuthStorageService,
     private modalService: BsModalService,
-    private notificationService: NotificationService
+    private notificationService: NotificationService,
+    private i18n: I18n
   ) {
     this.permission = this.authStorageService.getPermissions().user;
     const addAction: CdTableAction = {
       permission: 'create',
       icon: 'fa-plus',
       routerLink: () => '/user-management/roles/add',
-      name: 'Add'
+      name: this.i18n('Add')
     };
     const editAction: CdTableAction = {
       permission: 'update',
@@ -52,14 +54,14 @@ export class RoleListComponent implements OnInit {
       disable: () => !this.selection.hasSingleSelection || this.selection.first().system,
       routerLink: () =>
         this.selection.first() && `/user-management/roles/edit/${this.selection.first().name}`,
-      name: 'Edit'
+      name: this.i18n('Edit')
     };
     const deleteAction: CdTableAction = {
       permission: 'delete',
       icon: 'fa-times',
       disable: () => !this.selection.hasSingleSelection || this.selection.first().system,
       click: () => this.deleteRoleModal(),
-      name: 'Delete'
+      name: this.i18n('Delete')
     };
     this.tableActions = [addAction, editAction, deleteAction];
   }
@@ -67,18 +69,18 @@ export class RoleListComponent implements OnInit {
   ngOnInit() {
     this.columns = [
       {
-        name: 'Name',
+        name: this.i18n('Name'),
         prop: 'name',
         flexGrow: 3
       },
       {
-        name: 'Description',
+        name: this.i18n('Description'),
         prop: 'description',
         flexGrow: 5,
         pipe: this.emptyPipe
       },
       {
-        name: 'System Role',
+        name: this.i18n('System Role'),
         prop: 'system',
         cellClass: 'text-center',
         flexGrow: 1,
@@ -105,7 +107,10 @@ export class RoleListComponent implements OnInit {
       () => {
         this.getRoles();
         this.modalRef.hide();
-        this.notificationService.show(NotificationType.success, `Deleted role '${role}'`);
+        this.notificationService.show(
+          NotificationType.success,
+          this.i18n(`Deleted role '{{role_name}}'`, { role_name: role })
+        );
       },
       () => {
         this.modalRef.content.stopLoadingSpinner();
index 690a58e497931e67334477f64c945e4a22112819..47276a8f561c704495d326b7f271d469afe9ee56 100644 (file)
@@ -9,7 +9,7 @@ import { ToastModule } from 'ng2-toastr';
 import { BsModalService } from 'ngx-bootstrap/modal';
 import { of } from 'rxjs';
 
-import { configureTestBed, FormHelper } from '../../../../testing/unit-test-helper';
+import { configureTestBed, FormHelper, i18nProviders } from '../../../../testing/unit-test-helper';
 import { RoleService } from '../../../shared/api/role.service';
 import { UserService } from '../../../shared/api/user.service';
 import { ComponentsModule } from '../../../shared/components/components.module';
@@ -50,7 +50,8 @@ describe('UserFormComponent', () => {
         ToastModule.forRoot(),
         SharedModule
       ],
-      declarations: [UserFormComponent, FakeComponent]
+      declarations: [UserFormComponent, FakeComponent],
+      providers: i18nProviders
     },
     true
   );
index 2b1530d84571ff322401cfb5efb18a0f3cd1a152..bc0da5fd27a320394d16b3d7c03f0a247e273138 100644 (file)
@@ -2,6 +2,7 @@ import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core';
 import { FormControl, Validators } from '@angular/forms';
 import { ActivatedRoute, Router } from '@angular/router';
 
+import { I18n } from '@ngx-translate/i18n-polyfill';
 import * as _ from 'lodash';
 import { BsModalRef, BsModalService } from 'ngx-bootstrap/modal';
 
@@ -46,7 +47,8 @@ export class UserFormComponent implements OnInit {
     private modalService: BsModalService,
     private roleService: RoleService,
     private userService: UserService,
-    private notificationService: NotificationService
+    private notificationService: NotificationService,
+    private i18n: I18n
   ) {
     this.createForm();
   }
@@ -123,7 +125,7 @@ export class UserFormComponent implements OnInit {
       () => {
         this.notificationService.show(
           NotificationType.success,
-          `Created user "${userFormModel.username}"`
+          this.i18n('Created user "{{username}}"', { username: userFormModel.username })
         );
         this.router.navigate(['/user-management/users']);
       },
@@ -136,8 +138,8 @@ export class UserFormComponent implements OnInit {
   editAction() {
     if (this.isUserRemovingNeededRolePermissions()) {
       const initialState = {
-        titleText: 'Update user',
-        buttonText: 'Continue',
+        titleText: this.i18n('Update user'),
+        buttonText: this.i18n('Continue'),
         bodyTpl: this.removeSelfUserReadUpdatePermissionTpl,
         onSubmit: () => {
           this.modalRef.hide();
@@ -192,13 +194,13 @@ export class UserFormComponent implements OnInit {
           this.authService.logout(() => {
             this.notificationService.show(
               NotificationType.info,
-              'You were automatically logged out because your roles have been changed.'
+              this.i18n('You were automatically logged out because your roles have been changed.')
             );
           });
         } else {
           this.notificationService.show(
             NotificationType.success,
-            `Updated user "${userFormModel.username}"`
+            this.i18n('Updated user "{{username}}"', { username: userFormModel.username })
           );
           this.router.navigate(['/user-management/users']);
         }
index 7c02dac59946507c37b9d23406f994156a1bfa75..fcee4c3bd6ee8a4dbbf7b195e1bd86dd0c88b637 100644 (file)
@@ -6,7 +6,11 @@ import { RouterTestingModule } from '@angular/router/testing';
 import { ToastModule } from 'ng2-toastr';
 import { TabsModule } from 'ngx-bootstrap/tabs';
 
-import { configureTestBed, PermissionHelper } from '../../../../testing/unit-test-helper';
+import {
+  configureTestBed,
+  i18nProviders,
+  PermissionHelper
+} from '../../../../testing/unit-test-helper';
 import { TableActionsComponent } from '../../../shared/datatable/table-actions/table-actions.component';
 import { SharedModule } from '../../../shared/shared.module';
 import { UserTabsComponent } from '../user-tabs/user-tabs.component';
@@ -24,7 +28,8 @@ describe('UserListComponent', () => {
       RouterTestingModule,
       HttpClientTestingModule
     ],
-    declarations: [UserListComponent, UserTabsComponent]
+    declarations: [UserListComponent, UserTabsComponent],
+    providers: i18nProviders
   });
 
   beforeEach(() => {
index 1152c7e795db199148513e753cb0c5971976a210..8ef93957cd2a26af63456c3da2e932a37f8b15b8 100644 (file)
@@ -1,5 +1,6 @@
 import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core';
 
+import { I18n } from '@ngx-translate/i18n-polyfill';
 import { BsModalRef, BsModalService } from 'ngx-bootstrap/modal';
 
 import { UserService } from '../../../shared/api/user.service';
@@ -35,27 +36,28 @@ export class UserListComponent implements OnInit {
     private emptyPipe: EmptyPipe,
     private modalService: BsModalService,
     private notificationService: NotificationService,
-    private authStorageService: AuthStorageService
+    private authStorageService: AuthStorageService,
+    private i18n: I18n
   ) {
     this.permission = this.authStorageService.getPermissions().user;
     const addAction: CdTableAction = {
       permission: 'create',
       icon: 'fa-plus',
       routerLink: () => '/user-management/users/add',
-      name: 'Add'
+      name: this.i18n('Add')
     };
     const editAction: CdTableAction = {
       permission: 'update',
       icon: 'fa-pencil',
       routerLink: () =>
         this.selection.first() && `/user-management/users/edit/${this.selection.first().username}`,
-      name: 'Edit'
+      name: this.i18n('Edit')
     };
     const deleteAction: CdTableAction = {
       permission: 'delete',
       icon: 'fa-times',
       click: () => this.deleteUserModal(),
-      name: 'Delete'
+      name: this.i18n('Delete')
     };
     this.tableActions = [addAction, editAction, deleteAction];
   }
@@ -63,24 +65,24 @@ export class UserListComponent implements OnInit {
   ngOnInit() {
     this.columns = [
       {
-        name: 'Username',
+        name: this.i18n('Username'),
         prop: 'username',
         flexGrow: 1
       },
       {
-        name: 'Name',
+        name: this.i18n('Name'),
         prop: 'name',
         flexGrow: 1,
         pipe: this.emptyPipe
       },
       {
-        name: 'Email',
+        name: this.i18n('Email'),
         prop: 'email',
         flexGrow: 1,
         pipe: this.emptyPipe
       },
       {
-        name: 'Roles',
+        name: this.i18n('Roles'),
         prop: 'roles',
         flexGrow: 1,
         cellTemplate: this.userRolesTpl
@@ -103,7 +105,10 @@ export class UserListComponent implements OnInit {
       () => {
         this.getUsers();
         this.modalRef.hide();
-        this.notificationService.show(NotificationType.success, `Deleted user "${username}"`);
+        this.notificationService.show(
+          NotificationType.success,
+          this.i18n('Deleted user "{{username}}"', { username: username })
+        );
       },
       () => {
         this.modalRef.content.stopLoadingSpinner();
@@ -117,8 +122,8 @@ export class UserListComponent implements OnInit {
     if (sessionUsername === username) {
       this.notificationService.show(
         NotificationType.error,
-        `Failed to delete user "${username}"`,
-        `You are currently logged in as "${username}".`
+        this.i18n('Failed to delete user "{{username}}"', { username: username }),
+        this.i18n('You are currently logged in as "{{username}}".', { username: username })
       );
       return;
     }
index 6792cf8e985945d947227e275f78c1050c92c397..29dc31546895bc0e254c5363f667d7f10173e052 100644 (file)
@@ -1,6 +1,6 @@
 import { ComponentFixture, TestBed } from '@angular/core/testing';
 
-import { configureTestBed } from '../../../../testing/unit-test-helper';
+import { configureTestBed, i18nProviders } from '../../../../testing/unit-test-helper';
 import { AppModule } from '../../../app.module';
 import { NavigationComponent } from './navigation.component';
 
@@ -9,7 +9,8 @@ describe('NavigationComponent', () => {
   let fixture: ComponentFixture<NavigationComponent>;
 
   configureTestBed({
-    imports: [AppModule]
+    imports: [AppModule],
+    providers: i18nProviders
   });
 
   beforeEach(() => {
index 0c1706d7f9d2da924a847934b5a45bc08751a67c..5b081d8d7208f3476ebe53065f2b32f57af047e0 100644 (file)
@@ -3,7 +3,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
 import { ToastModule } from 'ng2-toastr';
 import { PopoverModule } from 'ngx-bootstrap/popover';
 
-import { configureTestBed } from '../../../../testing/unit-test-helper';
+import { configureTestBed, i18nProviders } from '../../../../testing/unit-test-helper';
 import { SharedModule } from '../../../shared/shared.module';
 import { NotificationsComponent } from './notifications.component';
 
@@ -13,7 +13,8 @@ describe('NotificationsComponent', () => {
 
   configureTestBed({
     imports: [PopoverModule.forRoot(), SharedModule, ToastModule.forRoot()],
-    declarations: [NotificationsComponent]
+    declarations: [NotificationsComponent],
+    providers: i18nProviders
   });
 
   beforeEach(() => {
index dcc5e6f804c7a28694e24965111b725aba48e143..e1839d520f0277175d2282cf4b11e45d6f6a53bb 100644 (file)
@@ -4,7 +4,7 @@ import { RouterTestingModule } from '@angular/router/testing';
 
 import { PopoverModule } from 'ngx-bootstrap/popover';
 
-import { configureTestBed } from '../../../../testing/unit-test-helper';
+import { configureTestBed, i18nProviders } from '../../../../testing/unit-test-helper';
 import { ExecutingTask } from '../../../shared/models/executing-task';
 import { FinishedTask } from '../../../shared/models/finished-task';
 import { SharedModule } from '../../../shared/shared.module';
@@ -20,7 +20,8 @@ describe('TaskManagerComponent', () => {
 
   configureTestBed({
     imports: [SharedModule, PopoverModule.forRoot(), HttpClientTestingModule, RouterTestingModule],
-    declarations: [TaskManagerComponent]
+    declarations: [TaskManagerComponent],
+    providers: [i18nProviders]
   });
 
   beforeEach(() => {
index 1b000f238e81ebda3b09a33d552bd8695e873251..8bdca309858e1e0e64d7832f3e0355e9ac08fb54 100644 (file)
@@ -4,7 +4,7 @@ import { RouterTestingModule } from '@angular/router/testing';
 
 import { AlertModule } from 'ngx-bootstrap/alert';
 
-import { configureTestBed } from '../../../../testing/unit-test-helper';
+import { configureTestBed, i18nProviders } from '../../../../testing/unit-test-helper';
 import { SettingsService } from '../../../shared/api/settings.service';
 import { SummaryService } from '../../../shared/services/summary.service';
 import { CephReleaseNamePipe } from '../../pipes/ceph-release-name.pipe';
@@ -19,7 +19,7 @@ describe('GrafanaComponent', () => {
   configureTestBed({
     declarations: [GrafanaComponent, InfoPanelComponent, LoadingPanelComponent],
     imports: [AlertModule.forRoot(), HttpClientTestingModule, RouterTestingModule],
-    providers: [CephReleaseNamePipe, SettingsService, SummaryService]
+    providers: [CephReleaseNamePipe, SettingsService, SummaryService, i18nProviders]
   });
 
   beforeEach(() => {
index 5df82fae27d93df9ec090f641328c7465dbc9017..6a28aecb13fc0ae472daf232dd86fbab6f5ab010 100644 (file)
@@ -2,7 +2,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
 
 import { AlertModule } from 'ngx-bootstrap/alert';
 
-import { configureTestBed } from '../../../../testing/unit-test-helper';
+import { configureTestBed, i18nProviders } from '../../../../testing/unit-test-helper';
 import { InfoPanelComponent } from './info-panel.component';
 
 describe('InfoPanelComponent', () => {
@@ -11,7 +11,8 @@ describe('InfoPanelComponent', () => {
 
   configureTestBed({
     declarations: [InfoPanelComponent],
-    imports: [AlertModule.forRoot()]
+    imports: [AlertModule.forRoot()],
+    providers: i18nProviders
   });
 
   beforeEach(() => {
index f6c5d1fdbfa69465f1e9ab0e03193ff5c7511285..ce0ef7ffe2743be75ed43f9707f2d1482a275686 100644 (file)
@@ -1,5 +1,7 @@
 import { Component, Input } from '@angular/core';
 
+import { I18n } from '@ngx-translate/i18n-polyfill';
+
 @Component({
   selector: 'cd-info-panel',
   templateUrl: './info-panel.component.html',
@@ -11,5 +13,7 @@ export class InfoPanelComponent {
    * @type {string}
    */
   @Input()
-  title = 'Information';
+  title = this.i18n('Information');
+
+  constructor(private i18n: I18n) {}
 }
index 7c01b8a303304662c20f9c5b70f7f5f3f0c1be5e..7d569ad6f7de7e609c05999d6616269e549ef1da 100644 (file)
@@ -3,7 +3,7 @@ import { HttpClientTestingModule, HttpTestingController } from '@angular/common/
 import { TestBed } from '@angular/core/testing';
 import { Router } from '@angular/router';
 
-import { configureTestBed } from '../../../testing/unit-test-helper';
+import { configureTestBed, i18nProviders } from '../../../testing/unit-test-helper';
 import { AppModule } from '../../app.module';
 import { ApiInterceptorService } from './api-interceptor.service';
 import { NotificationService } from './notification.service';
@@ -45,7 +45,7 @@ describe('ApiInterceptorService', () => {
 
   configureTestBed({
     imports: [AppModule, HttpClientTestingModule],
-    providers: [NotificationService]
+    providers: [NotificationService, i18nProviders]
   });
 
   beforeEach(() => {
index 56a2bad89f647ab89c011609a1c57b22374949b7..f751d76179437fad3e1bd10cca422ae6071439f3 100644 (file)
@@ -3,7 +3,7 @@ import { fakeAsync, TestBed, tick } from '@angular/core/testing';
 import * as _ from 'lodash';
 import { ToastsManager } from 'ng2-toastr';
 
-import { configureTestBed } from '../../../testing/unit-test-helper';
+import { configureTestBed, i18nProviders } from '../../../testing/unit-test-helper';
 import { NotificationType } from '../enum/notification-type.enum';
 import { FinishedTask } from '../models/finished-task';
 import { NotificationService } from './notification.service';
@@ -21,7 +21,8 @@ describe('NotificationService', () => {
     providers: [
       NotificationService,
       TaskMessageService,
-      { provide: ToastsManager, useValue: toastFakeService }
+      { provide: ToastsManager, useValue: toastFakeService },
+      i18nProviders
     ]
   });
 
index 0761d044aab885cd855455697a24bc15006210f3..0c6465994c0795830d969a6b7fa10986d1e8fe28 100644 (file)
@@ -4,7 +4,7 @@ import { RouterTestingModule } from '@angular/router/testing';
 
 import { of } from 'rxjs';
 
-import { configureTestBed } from '../../../testing/unit-test-helper';
+import { configureTestBed, i18nProviders } from '../../../testing/unit-test-helper';
 import { ExecutingTask } from '../models/executing-task';
 import { SummaryService } from './summary.service';
 import { TaskListService } from './task-list.service';
@@ -24,7 +24,7 @@ describe('TaskListService', () => {
   };
 
   configureTestBed({
-    providers: [TaskListService, TaskMessageService, SummaryService],
+    providers: [TaskListService, TaskMessageService, SummaryService, i18nProviders],
     imports: [HttpClientTestingModule, RouterTestingModule]
   });
 
index 37956f16ac31dcf19172d4f657de438e9fe6741f..b97d065ab3612c53da66ae49bf030226a4a68b8c 100644 (file)
@@ -1,5 +1,8 @@
+import { TestBed } from '@angular/core/testing';
+
 import * as _ from 'lodash';
 
+import { configureTestBed, i18nProviders } from '../../../testing/unit-test-helper';
 import { FinishedTask } from '../models/finished-task';
 import { TaskException } from '../models/task-exception';
 import { TaskMessageOperation, TaskMessageService } from './task-message.service';
@@ -8,8 +11,12 @@ describe('TaskManagerMessageService', () => {
   let service: TaskMessageService;
   let finishedTask: FinishedTask;
 
+  configureTestBed({
+    providers: [TaskMessageService, i18nProviders]
+  });
+
   beforeEach(() => {
-    service = new TaskMessageService();
+    service = TestBed.get(TaskMessageService);
     finishedTask = new FinishedTask();
   });
 
@@ -210,8 +217,8 @@ describe('TaskManagerMessageService', () => {
         finishedTask.name = 'rbd/trash/restore';
         testMessages(
           new TaskMessageOperation('Restoring', 'restore', 'Restored'),
-          `image '${metadata.pool_name}@${metadata.image_id}' \
-        into '${metadata.pool_name}/${metadata.new_image_name}'`
+          `image '${metadata.pool_name}@${metadata.image_id}' ` +
+            `into '${metadata.pool_name}/${metadata.new_image_name}'`
         );
         testErrorCode(
           17,
index 51db2e7a82e960f824575dfd43ecb16315232041..d268744b3bb081fa0544b9e5810af47c70d85b22 100644 (file)
@@ -1,5 +1,7 @@
 import { Injectable } from '@angular/core';
 
+import { I18n } from '@ngx-translate/i18n-polyfill';
+
 import { Components } from '../enum/components.enum';
 import { FinishedTask } from '../models/finished-task';
 import { Task } from '../models/task';
@@ -23,6 +25,7 @@ class TaskMessage {
   errors: (metadata) => object;
 
   failure(metadata): string {
+    // TODO: I18N
     return `Failed to ${this.operation.failure} ${this.involves(metadata)}`;
   }
 
@@ -49,12 +52,15 @@ class TaskMessage {
   providedIn: ServicesModule
 })
 export class TaskMessageService {
-  constructor() {}
+  constructor(private i18n: I18n) {}
 
   defaultMessage = new TaskMessage(
-    new TaskMessageOperation('Executing', 'execute', 'Executed'),
+    new TaskMessageOperation(this.i18n('Executing'), this.i18n('execute'), this.i18n('Executed')),
     (metadata) => {
-      return (metadata && (Components[metadata.component] || metadata.component)) || 'unknown task';
+      return (
+        (metadata && (Components[metadata.component] || metadata.component)) ||
+        this.i18n('unknown task')
+      );
     },
     () => {
       return {};
@@ -62,60 +68,117 @@ export class TaskMessageService {
   );
 
   commonOperations = {
-    create: new TaskMessageOperation('Creating', 'create', 'Created'),
-    update: new TaskMessageOperation('Updating', 'update', 'Updated'),
-    delete: new TaskMessageOperation('Deleting', 'delete', 'Deleted')
+    create: new TaskMessageOperation(
+      this.i18n('Creating'),
+      this.i18n('create'),
+      this.i18n('Created')
+    ),
+    update: new TaskMessageOperation(
+      this.i18n('Updating'),
+      this.i18n('update'),
+      this.i18n('Updated')
+    ),
+    delete: new TaskMessageOperation(
+      this.i18n('Deleting'),
+      this.i18n('delete'),
+      this.i18n('Deleted')
+    )
   };
 
   rbd = {
-    default: (metadata) => `RBD '${metadata.pool_name}/${metadata.image_name}'`,
-    child: (metadata) => `RBD '${metadata.child_pool_name}/${metadata.child_image_name}'`,
-    destination: (metadata) => `RBD '${metadata.dest_pool_name}/${metadata.dest_image_name}'`,
+    default: (metadata) =>
+      this.i18n(`RBD '{{id}}'`, {
+        id: `${metadata.pool_name}/${metadata.image_name}`
+      }),
+    child: (metadata) =>
+      this.i18n(`RBD '{{id}}'`, {
+        id: `${metadata.child_pool_name}/${metadata.child_image_name}`
+      }),
+    destination: (metadata) =>
+      this.i18n(`RBD '{{id}}'`, {
+        id: `${metadata.dest_pool_name}/${metadata.dest_image_name}`
+      }),
     snapshot: (metadata) =>
-      `RBD snapshot '${metadata.pool_name}/${metadata.image_name}@${metadata.snapshot_name}'`
+      this.i18n(`RBD snapshot '{{id}}'`, {
+        id: `${metadata.pool_name}/${metadata.image_name}@${metadata.snapshot_name}`
+      })
   };
 
   messages = {
     // Pool tasks
-    'pool/create': new TaskMessage(this.commonOperations.create, this.pool, (metadata) => ({
-      '17': `Name is already used by ${this.pool(metadata)}.`
-    })),
-    'pool/edit': new TaskMessage(this.commonOperations.update, this.pool, (metadata) => ({
-      '17': `Name is already used by ${this.pool(metadata)}.`
-    })),
-    'pool/delete': new TaskMessage(this.commonOperations.delete, this.pool),
+    'pool/create': new TaskMessage(
+      this.commonOperations.create,
+      (metadata) => this.pool(metadata),
+      (metadata) => ({
+        '17': this.i18n('Name is already used by {{pool_name}}.', {
+          pool_name: this.pool(metadata)
+        })
+      })
+    ),
+    'pool/edit': new TaskMessage(
+      this.commonOperations.update,
+      (metadata) => this.pool(metadata),
+      (metadata) => ({
+        '17': this.i18n('Name is already used by {{pool_name}}.', {
+          pool_name: this.pool(metadata)
+        })
+      })
+    ),
+    'pool/delete': new TaskMessage(this.commonOperations.delete, (metadata) => this.pool(metadata)),
     // Erasure code profile tasks
-    'ecp/create': new TaskMessage(this.commonOperations.create, this.ecp, (metadata) => ({
-      '17': `Name is already used by ${this.ecp(metadata)}.`
-    })),
-    'ecp/delete': new TaskMessage(this.commonOperations.delete, this.ecp),
+    'ecp/create': new TaskMessage(
+      this.commonOperations.create,
+      (metadata) => this.ecp(metadata),
+      (metadata) => ({
+        '17': this.i18n('Name is already used by {{name}}.', {
+          name: this.ecp(metadata)
+        })
+      })
+    ),
+    'ecp/delete': new TaskMessage(this.commonOperations.delete, (metadata) => this.ecp(metadata)),
     // RBD tasks
     'rbd/create': new TaskMessage(this.commonOperations.create, this.rbd.default, (metadata) => ({
-      '17': `Name is already used by ${this.rbd.default(metadata)}.`
+      '17': this.i18n('Name is already used by {{rbd_name}}.', {
+        rbd_name: this.rbd.default(metadata)
+      })
     })),
     'rbd/edit': new TaskMessage(this.commonOperations.update, this.rbd.default, (metadata) => ({
-      '17': `Name is already used by ${this.rbd.default(metadata)}.`
+      '17': this.i18n('Name is already used by {{rbd_name}}.', {
+        rbd_name: this.rbd.default(metadata)
+      })
     })),
     'rbd/delete': new TaskMessage(this.commonOperations.delete, this.rbd.default, (metadata) => ({
-      '39': `${this.rbd.default(metadata)} contains snapshots.`
+      '39': this.i18n('{{rbd_name}} contains snapshots.', {
+        rbd_name: this.rbd.default(metadata)
+      })
     })),
     'rbd/clone': new TaskMessage(
-      new TaskMessageOperation('Cloning', 'clone', 'Cloned'),
+      new TaskMessageOperation(this.i18n('Cloning'), this.i18n('clone'), this.i18n('Cloned')),
       this.rbd.child,
       (metadata) => ({
-        '17': `Name is already used by ${this.rbd.child(metadata)}.`,
-        '22': `Snapshot of ${this.rbd.child(metadata)} must be protected.`
+        '17': this.i18n('Name is already used by {{rbd_name}}.', {
+          rbd_name: this.rbd.child(metadata)
+        }),
+        '22': this.i18n('Snapshot of {{rbd_name}} must be protected.', {
+          rbd_name: this.rbd.child(metadata)
+        })
       })
     ),
     'rbd/copy': new TaskMessage(
-      new TaskMessageOperation('Copying', 'copy', 'Copied'),
+      new TaskMessageOperation(this.i18n('Copying'), this.i18n('copy'), this.i18n('Copied')),
       this.rbd.destination,
       (metadata) => ({
-        '17': `Name is already used by ${this.rbd.destination(metadata)}.`
+        '17': this.i18n('Name is already used by {{rbd_name}}.', {
+          rbd_name: this.rbd.destination(metadata)
+        })
       })
     ),
     'rbd/flatten': new TaskMessage(
-      new TaskMessageOperation('Flattening', 'flatten', 'Flattened'),
+      new TaskMessageOperation(
+        this.i18n('Flattening'),
+        this.i18n('flatten'),
+        this.i18n('Flattened')
+      ),
       this.rbd.default
     ),
     // RBD snapshot tasks
@@ -123,66 +186,90 @@ export class TaskMessageService {
       this.commonOperations.create,
       this.rbd.snapshot,
       (metadata) => ({
-        '17': `Name is already used by ${this.rbd.snapshot(metadata)}.`
+        '17': this.i18n('Name is already used by {{snap_name}}.', {
+          snap_name: this.rbd.snapshot(metadata)
+        })
       })
     ),
     'rbd/snap/edit': new TaskMessage(
       this.commonOperations.update,
       this.rbd.snapshot,
       (metadata) => ({
-        '16': `Cannot unprotect ${this.rbd.snapshot(metadata)} because it contains child images.`
+        '16': this.i18n('Cannot unprotect {{snap_name}} because it contains child images.', {
+          snap_name: this.rbd.snapshot(metadata)
+        })
       })
     ),
     'rbd/snap/delete': new TaskMessage(
       this.commonOperations.delete,
       this.rbd.snapshot,
       (metadata) => ({
-        '16': `Cannot delete ${this.rbd.snapshot(metadata)} because it's protected.`
+        '16': this.i18n(`Cannot delete {{snap_name}} because it's protected.`, {
+          snap_name: this.rbd.snapshot(metadata)
+        })
       })
     ),
     'rbd/snap/rollback': new TaskMessage(
-      new TaskMessageOperation('Rolling back', 'rollback', 'Rolled back'),
+      new TaskMessageOperation(
+        this.i18n('Rolling back'),
+        this.i18n('rollback'),
+        this.i18n('Rolled back')
+      ),
       this.rbd.snapshot
     ),
     // RBD trash tasks
     'rbd/trash/move': new TaskMessage(
-      new TaskMessageOperation('Moving', 'move', 'Moved'),
-      (metadata) => `image '${metadata.pool_name}/${metadata.image_name}' to trash`,
+      new TaskMessageOperation(this.i18n('Moving'), this.i18n('move'), this.i18n('Moved')),
+      (metadata) =>
+        this.i18n(`image '{{id}}' to trash`, {
+          id: `${metadata.pool_name}/${metadata.image_name}`
+        }),
       () => ({
-        2: `Could not find image.`
+        2: this.i18n('Could not find image.')
       })
     ),
     'rbd/trash/restore': new TaskMessage(
-      new TaskMessageOperation('Restoring', 'restore', 'Restored'),
+      new TaskMessageOperation(this.i18n('Restoring'), this.i18n('restore'), this.i18n('Restored')),
       (metadata) =>
-        `image '${metadata.pool_name}@${metadata.image_id}' \
-        into '${metadata.pool_name}/${metadata.new_image_name}'`,
+        this.i18n(`image '{{id}}' into '{{new_id}}'`, {
+          id: `${metadata.pool_name}@${metadata.image_id}`,
+          new_id: `${metadata.pool_name}/${metadata.new_image_name}`
+        }),
       (metadata) => ({
-        17: `Image name '${metadata.pool_name}/${metadata.new_image_name}' is already in use.`
+        17: this.i18n(`Image name '{{id}}' is already in use.`, {
+          id: `${metadata.pool_name}/${metadata.new_image_name}`
+        })
       })
     ),
     'rbd/trash/remove': new TaskMessage(
-      new TaskMessageOperation('Deleting', 'delete', 'Deleted'),
-      (metadata) => `image '${metadata.pool_name}/${metadata.image_name}@${metadata.image_id}'`
+      new TaskMessageOperation(this.i18n('Deleting'), this.i18n('delete'), this.i18n('Deleted')),
+      (metadata) =>
+        this.i18n(`image '{{id}}'`, {
+          id: `${metadata.pool_name}/${metadata.image_name}@${metadata.image_id}`
+        })
     ),
     'rbd/trash/purge': new TaskMessage(
-      new TaskMessageOperation('Purging', 'purge', 'Purged'),
+      new TaskMessageOperation(this.i18n('Purging'), this.i18n('purge'), this.i18n('Purged')),
       (metadata) => {
-        let message = 'all pools';
+        let message = this.i18n('all pools');
         if (metadata.pool_name) {
           message = `'${metadata.pool_name}'`;
         }
-        return `images from ${message}`;
+        return this.i18n('images from {{message}}', {
+          message: message
+        });
       }
     )
   };
 
   pool(metadata) {
-    return `pool '${metadata.pool_name}'`;
+    return this.i18n(`pool '{{pool_name}}'`, {
+      pool_name: metadata.pool_name
+    });
   }
 
   ecp(metadata) {
-    return `erasure code profile '${metadata.name}'`;
+    return this.i18n(`erasure code profile '{{name}}'`, { name: metadata.name });
   }
 
   _getTaskTitle(task: Task) {
index be510a51e6067b3e1cee46d2a0748b70bdffe80a..75968de6904661fa370f08d90653dc9a6a6a1e56 100644 (file)
@@ -5,7 +5,7 @@ import { RouterTestingModule } from '@angular/router/testing';
 import { ToastModule } from 'ng2-toastr';
 import { Observable } from 'rxjs';
 
-import { configureTestBed } from '../../../testing/unit-test-helper';
+import { configureTestBed, i18nProviders } from '../../../testing/unit-test-helper';
 import { FinishedTask } from '../models/finished-task';
 import { SharedModule } from '../shared.module';
 import { NotificationService } from './notification.service';
@@ -18,7 +18,7 @@ describe('TaskWrapperService', () => {
 
   configureTestBed({
     imports: [HttpClientTestingModule, ToastModule.forRoot(), SharedModule, RouterTestingModule],
-    providers: [TaskWrapperService]
+    providers: [TaskWrapperService, i18nProviders]
   });
 
   beforeEach(inject([TaskWrapperService], (wrapper: TaskWrapperService) => {
index bd396d34462c57f1e1f7585f386f2d2096173285..b294aab4e656a4a219cdbc899de5a685ea3a5596 100644 (file)
@@ -1,7 +1,9 @@
+import { LOCALE_ID, TRANSLATIONS, TRANSLATIONS_FORMAT } from '@angular/core';
 import { async, ComponentFixture, TestBed } from '@angular/core/testing';
 import { AbstractControl } from '@angular/forms';
 import { By } from '@angular/platform-browser';
 
+import { I18n } from '@ngx-translate/i18n-polyfill';
 import * as _ from 'lodash';
 
 import { TableActionsComponent } from '../app/shared/datatable/table-actions/table-actions.component';
@@ -179,3 +181,21 @@ export class FormHelper {
     expect(Boolean(fixture.debugElement.query(By.css(css)))).toBe(visibility);
   }
 }
+
+const XLIFF = `<?xml version="1.0" encoding="UTF-8" ?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+  <file source-language="en" datatype="plaintext" original="ng2.template">
+    <body>
+    </body>
+  </file>
+</xliff>
+`;
+
+const i18nProviders = [
+  { provide: TRANSLATIONS_FORMAT, useValue: 'xlf' },
+  { provide: TRANSLATIONS, useValue: XLIFF },
+  { provide: LOCALE_ID, useValue: 'en' },
+  I18n
+];
+
+export { i18nProviders };