]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/dashboard: Show success notification in RGW forms 26482/head
authorVolker Theile <vtheile@suse.com>
Mon, 18 Feb 2019 10:42:09 +0000 (11:42 +0100)
committerVolker Theile <vtheile@suse.com>
Fri, 22 Feb 2019 15:27:02 +0000 (16:27 +0100)
Display success notifications in the RGW user and bucket form.

Signed-off-by: Volker Theile <vtheile@suse.com>
src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts
src/pybind/mgr/dashboard/frontend/src/locale/messages.xlf

index b4dcd25b50b9ed50c14459da6373ee9274a0e22c..22d9710604d4c30b61069e81d4583c5335baa860 100644 (file)
@@ -1,36 +1,41 @@
 import { HttpClientTestingModule } from '@angular/common/http/testing';
 import { ComponentFixture, TestBed } from '@angular/core/testing';
 import { FormControl, ReactiveFormsModule } from '@angular/forms';
+import { Router } from '@angular/router';
 import { RouterTestingModule } from '@angular/router/testing';
 
+import { ToastModule } from 'ng2-toastr';
 import { of as observableOf } from 'rxjs';
 
-import { configureTestBed } from '../../../../testing/unit-test-helper';
+import { configureTestBed, i18nProviders } from '../../../../testing/unit-test-helper';
 import { RgwBucketService } from '../../../shared/api/rgw-bucket.service';
+import { NotificationType } from '../../../shared/enum/notification-type.enum';
+import { NotificationService } from '../../../shared/services/notification.service';
 import { SharedModule } from '../../../shared/shared.module';
 import { RgwBucketFormComponent } from './rgw-bucket-form.component';
 
 describe('RgwBucketFormComponent', () => {
   let component: RgwBucketFormComponent;
   let fixture: ComponentFixture<RgwBucketFormComponent>;
-  let queryResult: Array<string> = [];
-
-  class MockRgwBucketService extends RgwBucketService {
-    enumerate() {
-      return observableOf(queryResult);
-    }
-  }
+  let rwgBucketService: RgwBucketService;
 
   configureTestBed({
     declarations: [RgwBucketFormComponent],
-    imports: [HttpClientTestingModule, ReactiveFormsModule, RouterTestingModule, SharedModule],
-    providers: [{ provide: RgwBucketService, useClass: MockRgwBucketService }]
+    imports: [
+      HttpClientTestingModule,
+      ReactiveFormsModule,
+      RouterTestingModule,
+      SharedModule,
+      ToastModule.forRoot()
+    ],
+    providers: [i18nProviders]
   });
 
   beforeEach(() => {
     fixture = TestBed.createComponent(RgwBucketFormComponent);
     component = fixture.componentInstance;
     fixture.detectChanges();
+    rwgBucketService = TestBed.get(RgwBucketService);
   });
 
   it('should create', () => {
@@ -77,7 +82,7 @@ describe('RgwBucketFormComponent', () => {
     });
 
     it('should validate name (4/4)', () => {
-      queryResult = ['abcd'];
+      spyOn(rwgBucketService, 'enumerate').and.returnValue(observableOf(['abcd']));
       const validatorFn = component.bucketNameValidator();
       const ctrl = new FormControl('abcd');
       ctrl.markAsDirty();
@@ -91,4 +96,36 @@ describe('RgwBucketFormComponent', () => {
       }
     });
   });
+
+  describe('submit form', () => {
+    let notificationService: NotificationService;
+
+    beforeEach(() => {
+      spyOn(TestBed.get(Router), 'navigate').and.stub();
+      notificationService = TestBed.get(NotificationService);
+      spyOn(notificationService, 'show');
+    });
+
+    it('tests create success notification', () => {
+      spyOn(rwgBucketService, 'create').and.returnValue(observableOf([]));
+      component.editing = false;
+      component.bucketForm.markAsDirty();
+      component.submit();
+      expect(notificationService.show).toHaveBeenCalledWith(
+        NotificationType.success,
+        'Created Object Gateway bucket ""'
+      );
+    });
+
+    it('tests update success notification', () => {
+      spyOn(rwgBucketService, 'update').and.returnValue(observableOf([]));
+      component.editing = true;
+      component.bucketForm.markAsDirty();
+      component.submit();
+      expect(notificationService.show).toHaveBeenCalledWith(
+        NotificationType.success,
+        'Updated Object Gateway bucket ""'
+      );
+    });
+  });
 });
index 893a68e57123a31e886455e1cfb065fb06725a70..0bbf47e64342dbdc4df64be9580466208e6634ab 100644 (file)
@@ -2,12 +2,15 @@ import { Component, OnInit } from '@angular/core';
 import { AbstractControl, AsyncValidatorFn, ValidationErrors, Validators } from '@angular/forms';
 import { ActivatedRoute, Router } from '@angular/router';
 
+import { I18n } from '@ngx-translate/i18n-polyfill';
 import * as _ from 'lodash';
 
 import { RgwBucketService } from '../../../shared/api/rgw-bucket.service';
 import { RgwUserService } from '../../../shared/api/rgw-user.service';
+import { NotificationType } from '../../../shared/enum/notification-type.enum';
 import { CdFormBuilder } from '../../../shared/forms/cd-form-builder';
 import { CdFormGroup } from '../../../shared/forms/cd-form-group';
+import { NotificationService } from '../../../shared/services/notification.service';
 
 @Component({
   selector: 'cd-rgw-bucket-form',
@@ -26,7 +29,9 @@ export class RgwBucketFormComponent implements OnInit {
     private router: Router,
     private formBuilder: CdFormBuilder,
     private rgwBucketService: RgwBucketService,
-    private rgwUserService: RgwUserService
+    private rgwUserService: RgwUserService,
+    private notificationService: NotificationService,
+    private i18n: I18n
   ) {
     this.createForm();
   }
@@ -81,6 +86,7 @@ export class RgwBucketFormComponent implements OnInit {
     // Exit immediately if the form isn't dirty.
     if (this.bucketForm.pristine) {
       this.goToListView();
+      return;
     }
     const bidCtl = this.bucketForm.get('bid');
     const ownerCtl = this.bucketForm.get('owner');
@@ -89,6 +95,10 @@ export class RgwBucketFormComponent implements OnInit {
       const idCtl = this.bucketForm.get('id');
       this.rgwBucketService.update(bidCtl.value, idCtl.value, ownerCtl.value).subscribe(
         () => {
+          this.notificationService.show(
+            NotificationType.success,
+            this.i18n('Updated Object Gateway bucket "{{bid}}"', { bid: bidCtl.value })
+          );
           this.goToListView();
         },
         () => {
@@ -100,6 +110,10 @@ export class RgwBucketFormComponent implements OnInit {
       // Add
       this.rgwBucketService.create(bidCtl.value, ownerCtl.value).subscribe(
         () => {
+          this.notificationService.show(
+            NotificationType.success,
+            this.i18n('Created Object Gateway bucket "{{bid}}"', { bid: bidCtl.value })
+          );
           this.goToListView();
         },
         () => {
index 6e183172da8e706aaeacf39729ad915a403cdb22..a4d5038dff6ab4597f404440763b940b102dfc7c 100644 (file)
@@ -1,13 +1,17 @@
 import { HttpClientTestingModule } from '@angular/common/http/testing';
 import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
 import { FormControl, ReactiveFormsModule } from '@angular/forms';
+import { Router } from '@angular/router';
 import { RouterTestingModule } from '@angular/router/testing';
 
+import { ToastModule } from 'ng2-toastr';
 import { BsModalService } from 'ngx-bootstrap/modal';
 import { of as observableOf } from 'rxjs';
 
-import { configureTestBed, FormHelper } from '../../../../testing/unit-test-helper';
+import { configureTestBed, FormHelper, i18nProviders } from '../../../../testing/unit-test-helper';
 import { RgwUserService } from '../../../shared/api/rgw-user.service';
+import { NotificationType } from '../../../shared/enum/notification-type.enum';
+import { NotificationService } from '../../../shared/services/notification.service';
 import { SharedModule } from '../../../shared/shared.module';
 import { RgwUserS3Key } from '../models/rgw-user-s3-key';
 import { RgwUserFormComponent } from './rgw-user-form.component';
@@ -20,8 +24,14 @@ describe('RgwUserFormComponent', () => {
 
   configureTestBed({
     declarations: [RgwUserFormComponent],
-    imports: [HttpClientTestingModule, ReactiveFormsModule, RouterTestingModule, SharedModule],
-    providers: [BsModalService]
+    imports: [
+      HttpClientTestingModule,
+      ReactiveFormsModule,
+      RouterTestingModule,
+      SharedModule,
+      ToastModule.forRoot()
+    ],
+    providers: [BsModalService, i18nProviders]
   });
 
   beforeEach(() => {
@@ -135,7 +145,15 @@ describe('RgwUserFormComponent', () => {
     }));
   });
 
-  describe('onSubmit', () => {
+  describe('submit form', () => {
+    let notificationService: NotificationService;
+
+    beforeEach(() => {
+      spyOn(TestBed.get(Router), 'navigate').and.stub();
+      notificationService = TestBed.get(NotificationService);
+      spyOn(notificationService, 'show');
+    });
+
     it('should be able to clear the mail field on update', () => {
       spyOn(rgwUserService, 'update');
       component.editing = true;
@@ -148,5 +166,27 @@ describe('RgwUserFormComponent', () => {
         suspended: false
       });
     });
+
+    it('tests create success notification', () => {
+      spyOn(rgwUserService, 'create').and.returnValue(observableOf([]));
+      component.editing = false;
+      formHelper.setValue('suspended', true, true);
+      component.onSubmit();
+      expect(notificationService.show).toHaveBeenCalledWith(
+        NotificationType.success,
+        'Created Object Gateway user ""'
+      );
+    });
+
+    it('tests update success notification', () => {
+      spyOn(rgwUserService, 'update').and.returnValue(observableOf([]));
+      component.editing = true;
+      formHelper.setValue('suspended', true, true);
+      component.onSubmit();
+      expect(notificationService.show).toHaveBeenCalledWith(
+        NotificationType.success,
+        'Updated Object Gateway user ""'
+      );
+    });
   });
 });
index f1f873d9965a3b40dfa9e90e39225619dc4c905b..a573dbdc1ca6c2b7603e7ab8cd014f13a96b28fe 100644 (file)
@@ -2,15 +2,18 @@ import { Component, OnInit } from '@angular/core';
 import { AbstractControl, ValidationErrors, 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 as observableForkJoin, Observable } from 'rxjs';
 
 import { RgwUserService } from '../../../shared/api/rgw-user.service';
+import { NotificationType } from '../../../shared/enum/notification-type.enum';
 import { CdFormBuilder } from '../../../shared/forms/cd-form-builder';
 import { CdFormGroup } from '../../../shared/forms/cd-form-group';
 import { CdValidators, isEmptyInputValue } from '../../../shared/forms/cd-validators';
 import { FormatterService } from '../../../shared/services/formatter.service';
+import { NotificationService } from '../../../shared/services/notification.service';
 import { RgwUserCapability } from '../models/rgw-user-capability';
 import { RgwUserS3Key } from '../models/rgw-user-s3-key';
 import { RgwUserSubuser } from '../models/rgw-user-subuser';
@@ -42,7 +45,9 @@ export class RgwUserFormComponent implements OnInit {
     private route: ActivatedRoute,
     private router: Router,
     private rgwUserService: RgwUserService,
-    private bsModalService: BsModalService
+    private bsModalService: BsModalService,
+    private notificationService: NotificationService,
+    private i18n: I18n
   ) {
     this.createForm();
     this.listenToChanges();
@@ -225,9 +230,11 @@ export class RgwUserFormComponent implements OnInit {
   }
 
   onSubmit() {
+    let notificationTitle: string;
     // Exit immediately if the form isn't dirty.
     if (this.userForm.pristine) {
       this.goToListView();
+      return;
     }
     const uid = this.userForm.getValue('uid');
     if (this.editing) {
@@ -236,10 +243,12 @@ export class RgwUserFormComponent implements OnInit {
         const args = this._getUpdateArgs();
         this.submitObservables.push(this.rgwUserService.update(uid, args));
       }
+      notificationTitle = this.i18n('Updated Object Gateway user "{{uid}}"', { uid: uid });
     } else {
       // Add
       const args = this._getCreateArgs();
       this.submitObservables.push(this.rgwUserService.create(args));
+      notificationTitle = this.i18n('Created Object Gateway user "{{uid}}"', { uid: uid });
     }
     // Check if user quota has been modified.
     if (this._isUserQuotaDirty()) {
@@ -254,6 +263,7 @@ export class RgwUserFormComponent implements OnInit {
     // Finally execute all observables.
     observableForkJoin(this.submitObservables).subscribe(
       () => {
+        this.notificationService.show(NotificationType.success, notificationTitle);
         this.goToListView();
       },
       () => {
index 13dad708dbe6b207f500d46592ebe4ed21231eb3..f9cbfa1ea3810f1338225802791cdd62b0a2bdec 100644 (file)
           <context context-type="linenumber">1</context>
         </context-group>
       </trans-unit>
+      <trans-unit id="364cc3f92837b6000e686aab6d03bd2ad8007b50" datatype="html">
+        <source>Updated Object Gateway bucket &quot;<x id="INTERPOLATION" equiv-text="{{bid}}"/>&quot;</source>
+        <context-group purpose="location">
+          <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.ts</context>
+          <context context-type="linenumber">1</context>
+        </context-group>
+      </trans-unit>
+      <trans-unit id="2d7a43674f0bbc131c9e555ec16ac37fa0445d76" datatype="html">
+        <source>Created Object Gateway bucket &quot;<x id="INTERPOLATION" equiv-text="{{bid}}"/>&quot;</source>
+        <context-group purpose="location">
+          <context context-type="sourcefile">src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.ts</context>
+          <context context-type="linenumber">1</context>
+        </context-group>
+      </trans-unit>
       <trans-unit id="44939fd05cedfd077db886528b755e77d5fa3885" datatype="html">
         <source>bucket</source>
         <context-group purpose="location">
           <context context-type="linenumber">1</context>
         </context-group>
       </trans-unit>
+      <trans-unit id="854a763265e92f91ba3ccee1a0e8d823be584f7c" datatype="html">
+        <source>Updated Object Gateway user &quot;<x id="INTERPOLATION" equiv-text="{{uid}}"/>&quot;</source>
+        <context-group purpose="location">
+          <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts</context>
+          <context context-type="linenumber">1</context>
+        </context-group>
+      </trans-unit>
+      <trans-unit id="84ab3fd641e65e39cffee0ec722a059ed284229e" datatype="html">
+        <source>Created Object Gateway user &quot;<x id="INTERPOLATION" equiv-text="{{uid}}"/>&quot;</source>
+        <context-group purpose="location">
+          <context context-type="sourcefile">src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts</context>
+          <context context-type="linenumber">1</context>
+        </context-group>
+      </trans-unit>
       <trans-unit id="0914cbe18bae204217e1851be6d2d24d86e74605" datatype="html">
         <source>user</source>
         <context-group purpose="location">