]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/dashboard: Custom Directive for verifying if user is read_only 34545/head
authorNizamudeen <nia@redhat.com>
Tue, 14 Apr 2020 06:53:09 +0000 (12:23 +0530)
committernizamial09 <nia@redhat.com>
Tue, 15 Sep 2020 15:26:40 +0000 (20:56 +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.

Signed-off-by: Nizamudeen <nia@redhat.com>
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 f3094d44501f0bb309507289c255ff439fcd85a9..f98bc7011de4fadec1ce3cc4c973c26e149f64a1 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="custom-control custom-checkbox"
              *ngFor="let flag of flags; let last = last">
index 4e9e3eefd8e4a58f79e2189651135150e7228199..14b51cc67073a8655a16df63884c8ab3bc78682c 100644 (file)
@@ -5,7 +5,8 @@
   <ng-container class="modal-content">
     <form #formDir="ngForm"
           [formGroup]="osdPgScrubForm"
-          novalidate>
+          novalidate
+          cdFormScope="osd">
       <div class="modal-body osd-modal">
         <!-- Basic -->
         <cd-config-option [optionNames]="basicOptions"
index 726159778a0a2a5158f347c650b4da9ec590cba4..892df49b9abe3573ced4f66e6d0bae7d96135090 100755 (executable)
@@ -5,7 +5,8 @@
   <ng-container class="modal-content">
     <form #formDir="ngForm"
           [formGroup]="osdRecvSpeedForm"
-          novalidate>
+          novalidate
+          cdFormScope="osd">
       <div class="modal-body">
         <!-- Priority -->
         <div class="form-group row">
index 3b011043c7379e26b01b826309bc13ac069b5423..ad065577c97d1baeddf97caf302bb2064d9731cb 100644 (file)
@@ -4,7 +4,9 @@ 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 { FormLoadingDirective } from './form-loading.directive';
+import { FormScopeDirective } from './form-scope.directive';
 import { IopsDirective } from './iops.directive';
 import { MillisecondsDirective } from './milliseconds.directive';
 import { PasswordButtonDirective } from './password-button.directive';
@@ -23,7 +25,9 @@ import { TrimDirective } from './trim.directive';
     MillisecondsDirective,
     IopsDirective,
     FormLoadingDirective,
-    StatefulTabDirective
+    StatefulTabDirective,
+    FormInputDisableDirective,
+    FormScopeDirective
   ],
   exports: [
     AutofocusDirective,
@@ -35,7 +39,9 @@ import { TrimDirective } from './trim.directive';
     MillisecondsDirective,
     IopsDirective,
     FormLoadingDirective,
-    StatefulTabDirective
+    StatefulTabDirective,
+    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..0aca140
--- /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.inject(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..fe0e591
--- /dev/null
@@ -0,0 +1,27 @@
+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;
+
+  constructor(
+    @Optional() private formScope: FormScopeDirective,
+    private authStorageService: AuthStorageService,
+    private elementRef: ElementRef
+  ) {}
+
+  ngAfterViewInit() {
+    this.permissions = this.authStorageService.getPermissions();
+    const service_name = this.formScope?.cdFormScope;
+    if (service_name && !this.permissions?.[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;
+}