]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/dashboard: Custom Directive for verifying if user is read_only 37241/head
authorNizamudeen <nia@redhat.com>
Tue, 14 Apr 2020 06:53:09 +0000 (12:23 +0530)
committerNizamudeen A <nia@redhat.com>
Mon, 28 Sep 2020 07:18:37 +0000 (12:48 +0530)
This commit introduces two new Custom Directives: `FormInputDisableDirective` and `FormScopeDirective`.
By using the `cdFormScope` attribute of the directive we can customize the behaviour of the modal components.

Fixes: https://tracker.ceph.com/issues/43527
Signed-off-by: Nizamudeen <nia@redhat.com>
(cherry picked from commit f6e1ed657125e0f394e80da5dfeb51617304d091)

Conflicts:
      src/pybind/mgr/dashboard/frontend/src/app/shared/directives/directives.module.ts
 - Import the FormInputDisableDirective and FormScopeDirective to the directive.module imports and exports
      src/pybind/mgr/dashboard/frontend/src/app/shared/directives/form-input-disable.directive.spec.ts
 - Changed TestBed.inject(...) to TestBed.get(...) to match the syntax for the nautilus TS version
      src/pybind/mgr/dashboard/frontend/src/app/shared/directives/form-input-disable.directive.ts
 - Changed some of the operators to match the nautilus TS version

src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html
src/pybind/mgr/dashboard/frontend/src/app/shared/directives/directives.module.ts
src/pybind/mgr/dashboard/frontend/src/app/shared/directives/form-input-disable.directive.spec.ts [new file with mode: 0644]
src/pybind/mgr/dashboard/frontend/src/app/shared/directives/form-input-disable.directive.ts [new file with mode: 0644]
src/pybind/mgr/dashboard/frontend/src/app/shared/directives/form-scope.directive.spec.ts [new file with mode: 0644]
src/pybind/mgr/dashboard/frontend/src/app/shared/directives/form-scope.directive.ts [new file with mode: 0644]

index 13ed7dfea77962f5059db38958d0c5db97bd8e97..3128f8201ce9f22116e0e94a063c5ad24cada3b7 100644 (file)
@@ -6,7 +6,8 @@
     <form name="osdFlagsForm"
           #formDir="ngForm"
           [formGroup]="osdFlagsForm"
-          novalidate>
+          novalidate
+          cdFormScope="osd">
       <div class="modal-body osd-modal">
         <div class="checkbox checkbox-primary"
              *ngFor="let flag of flags; let last = last">
index 9f447db83415bd8cafcb6dae21d419f8847a8d9a..1077fba3e5b4a6811b7805cd9dc6ab05a7adb49d 100644 (file)
@@ -6,7 +6,8 @@
     <form class="form-horizontal"
           #formDir="ngForm"
           [formGroup]="osdPgScrubForm"
-          novalidate>
+          novalidate
+          cdFormScope="osd">
       <div class="modal-body osd-modal">
         <!-- Basic -->
         <cd-config-option [optionNames]="basicOptions"
index c06d1b99684fab48a5c3e1da20ef13640b0933af..91d7da00e276663da51fd382c60cce2667b60597 100755 (executable)
@@ -6,7 +6,8 @@
     <form class="form-horizontal"
           #formDir="ngForm"
           [formGroup]="osdRecvSpeedForm"
-          novalidate>
+          novalidate
+          cdFormScope="osd">
       <div class="modal-body">
         <!-- Priority -->
         <div class="form-group"
index 1ed763052b2e8547a93294d9e1c92bb987e1cdea..8724ce478888229314cc21bab1b5c6315789f174 100644 (file)
@@ -4,6 +4,8 @@ import { AutofocusDirective } from './autofocus.directive';
 import { Copy2ClipboardButtonDirective } from './copy2clipboard-button.directive';
 import { DimlessBinaryPerSecondDirective } from './dimless-binary-per-second.directive';
 import { DimlessBinaryDirective } from './dimless-binary.directive';
+import { FormInputDisableDirective } from './form-input-disable.directive';
+import { FormScopeDirective } from './form-scope.directive';
 import { IopsDirective } from './iops.directive';
 import { MillisecondsDirective } from './milliseconds.directive';
 import { PasswordButtonDirective } from './password-button.directive';
@@ -19,7 +21,9 @@ import { TrimDirective } from './trim.directive';
     PasswordButtonDirective,
     TrimDirective,
     MillisecondsDirective,
-    IopsDirective
+    IopsDirective,
+    FormInputDisableDirective,
+    FormScopeDirective
   ],
   exports: [
     AutofocusDirective,
@@ -29,8 +33,9 @@ import { TrimDirective } from './trim.directive';
     PasswordButtonDirective,
     TrimDirective,
     MillisecondsDirective,
-    IopsDirective
-  ],
-  providers: []
+    IopsDirective,
+    FormInputDisableDirective,
+    FormScopeDirective
+  ]
 })
 export class DirectivesModule {}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/form-input-disable.directive.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/form-input-disable.directive.spec.ts
new file mode 100644 (file)
index 0000000..c526353
--- /dev/null
@@ -0,0 +1,75 @@
+import { Component, DebugElement, Input } from '@angular/core';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { By } from '@angular/platform-browser';
+
+import { configureTestBed } from '../../../testing/unit-test-helper';
+import { Permission } from '../models/permissions';
+import { AuthStorageService } from '../services/auth-storage.service';
+import { FormInputDisableDirective } from './form-input-disable.directive';
+import { FormScopeDirective } from './form-scope.directive';
+
+@Component({
+  template: `
+    <form cdFormScope="osd">
+      <input type="checkbox" />
+    </form>
+  `
+})
+export class FormDisableComponent {}
+
+class MockFormScopeDirective {
+  @Input() cdFormScope = 'osd';
+}
+
+describe('FormInputDisableDirective', () => {
+  let fakePermissions: Permission;
+  let authStorageService: AuthStorageService;
+  let directive: FormInputDisableDirective;
+  let fixture: ComponentFixture<FormDisableComponent>;
+  let inputElement: DebugElement;
+  configureTestBed({
+    declarations: [FormScopeDirective, FormInputDisableDirective, FormDisableComponent]
+  });
+
+  beforeEach(() => {
+    directive = new FormInputDisableDirective(
+      new MockFormScopeDirective(),
+      new AuthStorageService(),
+      null
+    );
+
+    fakePermissions = {
+      create: false,
+      update: false,
+      read: false,
+      delete: false
+    };
+    authStorageService = TestBed.get(AuthStorageService);
+    spyOn(authStorageService, 'getPermissions').and.callFake(() => ({
+      osd: fakePermissions
+    }));
+
+    fixture = TestBed.createComponent(FormDisableComponent);
+    inputElement = fixture.debugElement.query(By.css('input'));
+  });
+
+  afterEach(() => {
+    directive = null;
+  });
+
+  it('should create an instance', () => {
+    expect(directive).toBeTruthy();
+  });
+
+  it('should disable the input if update permission is false', () => {
+    fixture.detectChanges();
+    expect(inputElement.nativeElement.disabled).toBeTruthy();
+  });
+
+  it('should not disable the input if update permission is true', () => {
+    fakePermissions.update = true;
+    fakePermissions.read = false;
+    fixture.detectChanges();
+    expect(inputElement.nativeElement.disabled).toBeFalsy();
+  });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/form-input-disable.directive.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/form-input-disable.directive.ts
new file mode 100644 (file)
index 0000000..4fcfe65
--- /dev/null
@@ -0,0 +1,30 @@
+import { AfterViewInit, Directive, ElementRef, Optional } from '@angular/core';
+
+import { Permissions } from '../models/permissions';
+import { AuthStorageService } from '../services/auth-storage.service';
+import { FormScopeDirective } from './form-scope.directive';
+
+@Directive({
+  selector:
+    'input:not([cdNoFormInputDisable]), select:not([cdNoFormInputDisable]), [cdFormInputDisable]'
+})
+export class FormInputDisableDirective implements AfterViewInit {
+  permissions: Permissions;
+  service_name: keyof Permissions;
+
+  constructor(
+    @Optional() private formScope: FormScopeDirective,
+    private authStorageService: AuthStorageService,
+    private elementRef: ElementRef
+  ) {}
+
+  ngAfterViewInit() {
+    this.permissions = this.authStorageService.getPermissions();
+    if (this.formScope !== null) {
+      this.service_name = this.formScope.cdFormScope;
+    }
+    if (this.service_name && !this.permissions[this.service_name].update) {
+      this.elementRef.nativeElement.disabled = true;
+    }
+  }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/form-scope.directive.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/form-scope.directive.spec.ts
new file mode 100644 (file)
index 0000000..2cf882e
--- /dev/null
@@ -0,0 +1,8 @@
+import { FormScopeDirective } from './form-scope.directive';
+
+describe('UpdateOnlyDirective', () => {
+  it('should create an instance', () => {
+    const directive = new FormScopeDirective();
+    expect(directive).toBeTruthy();
+  });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/form-scope.directive.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/form-scope.directive.ts
new file mode 100644 (file)
index 0000000..8ae3f84
--- /dev/null
@@ -0,0 +1,8 @@
+import { Directive, Input } from '@angular/core';
+
+@Directive({
+  selector: '[cdFormScope]'
+})
+export class FormScopeDirective {
+  @Input() cdFormScope: any;
+}