feat: add view, edit roles and permission component (#632)
- Add view roles and permission - Edit roles and permission - Edit role description Fixes: #176
This commit is contained in:
@@ -0,0 +1,8 @@
|
|||||||
|
<h1 mat-dialog-title>Disable</h1>
|
||||||
|
<div mat-dialog-content>
|
||||||
|
<p>Are you sure you want to disable {{ data.disableContext }} ?</p>
|
||||||
|
</div>
|
||||||
|
<mat-dialog-actions align="end">
|
||||||
|
<button mat-raised-button mat-dialog-close>Cancel</button>
|
||||||
|
<button mat-raised-button color="warn" [mat-dialog-close]="{ disable: true }">Confirm</button>
|
||||||
|
</mat-dialog-actions>
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { DisableDialogComponent } from './disable-dialog.component';
|
||||||
|
|
||||||
|
describe('DisableDialogComponent', () => {
|
||||||
|
let component: DisableDialogComponent;
|
||||||
|
let fixture: ComponentFixture<DisableDialogComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ DisableDialogComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(DisableDialogComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
/** Angular Imports */
|
||||||
|
import { Component, OnInit, Inject } from '@angular/core';
|
||||||
|
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disable dialog component.
|
||||||
|
*/
|
||||||
|
@Component({
|
||||||
|
selector: 'mifosx-disable-dialog',
|
||||||
|
templateUrl: './disable-dialog.component.html',
|
||||||
|
styleUrls: ['./disable-dialog.component.scss']
|
||||||
|
})
|
||||||
|
export class DisableDialogComponent implements OnInit {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {MatDialogRef} dialogRef Component reference to dialog.
|
||||||
|
* @param {any} data Provides a disableContext.
|
||||||
|
*/
|
||||||
|
constructor(public dialogRef: MatDialogRef<DisableDialogComponent>,
|
||||||
|
@Inject(MAT_DIALOG_DATA) public data: any) { }
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
<h1 mat-dialog-title>Enable</h1>
|
||||||
|
<div mat-dialog-content>
|
||||||
|
<p>Are you sure you want to enable {{ data.enableContext }} ?</p>
|
||||||
|
</div>
|
||||||
|
<mat-dialog-actions align="end">
|
||||||
|
<button mat-raised-button mat-dialog-close>Cancel</button>
|
||||||
|
<button mat-raised-button color="warn" [mat-dialog-close]="{ enable: true }">Confirm</button>
|
||||||
|
</mat-dialog-actions>
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { EnableDialogComponent } from './enable-dialog.component';
|
||||||
|
|
||||||
|
describe('EnableDialogComponent', () => {
|
||||||
|
let component: EnableDialogComponent;
|
||||||
|
let fixture: ComponentFixture<EnableDialogComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ EnableDialogComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(EnableDialogComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
/** Angular Imports */
|
||||||
|
import { Component, OnInit, Inject } from '@angular/core';
|
||||||
|
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable dialog component.
|
||||||
|
*/
|
||||||
|
@Component({
|
||||||
|
selector: 'mifosx-enable-dialog',
|
||||||
|
templateUrl: './enable-dialog.component.html',
|
||||||
|
styleUrls: ['./enable-dialog.component.scss']
|
||||||
|
})
|
||||||
|
export class EnableDialogComponent implements OnInit {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {MatDialogRef} dialogRef Component reference to dialog.
|
||||||
|
* @param {any} data Provides a enableContext.
|
||||||
|
*/
|
||||||
|
constructor(public dialogRef: MatDialogRef<EnableDialogComponent>,
|
||||||
|
@Inject(MAT_DIALOG_DATA) public data: any) { }
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -12,6 +12,8 @@ import { FooterComponent } from './footer/footer.component';
|
|||||||
import { LanguageSelectorComponent } from './language-selector/language-selector.component';
|
import { LanguageSelectorComponent } from './language-selector/language-selector.component';
|
||||||
import { ThemePickerComponent } from './theme-picker/theme-picker.component';
|
import { ThemePickerComponent } from './theme-picker/theme-picker.component';
|
||||||
import { ChangePasswordDialogComponent } from './change-password-dialog/change-password-dialog.component';
|
import { ChangePasswordDialogComponent } from './change-password-dialog/change-password-dialog.component';
|
||||||
|
import { EnableDialogComponent } from './enable-dialog/enable-dialog.component';
|
||||||
|
import { DisableDialogComponent } from './disable-dialog/disable-dialog.component';
|
||||||
|
|
||||||
/** Custom Modules */
|
/** Custom Modules */
|
||||||
import { IconsModule } from './icons.module';
|
import { IconsModule } from './icons.module';
|
||||||
@@ -37,7 +39,9 @@ import { MaterialModule } from './material.module';
|
|||||||
FooterComponent,
|
FooterComponent,
|
||||||
LanguageSelectorComponent,
|
LanguageSelectorComponent,
|
||||||
ThemePickerComponent,
|
ThemePickerComponent,
|
||||||
ChangePasswordDialogComponent
|
ChangePasswordDialogComponent,
|
||||||
|
EnableDialogComponent,
|
||||||
|
DisableDialogComponent
|
||||||
],
|
],
|
||||||
exports: [
|
exports: [
|
||||||
FileUploadComponent,
|
FileUploadComponent,
|
||||||
@@ -53,7 +57,9 @@ import { MaterialModule } from './material.module';
|
|||||||
entryComponents: [
|
entryComponents: [
|
||||||
FormDialogComponent,
|
FormDialogComponent,
|
||||||
DeleteDialogComponent,
|
DeleteDialogComponent,
|
||||||
ChangePasswordDialogComponent
|
ChangePasswordDialogComponent,
|
||||||
|
EnableDialogComponent,
|
||||||
|
DisableDialogComponent
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class SharedModule { }
|
export class SharedModule { }
|
||||||
|
|||||||
@@ -0,0 +1,37 @@
|
|||||||
|
<div class="container">
|
||||||
|
|
||||||
|
<mat-card>
|
||||||
|
|
||||||
|
<form [formGroup]="roleForm" (ngSubmit)="submit()">
|
||||||
|
|
||||||
|
<mat-card-content>
|
||||||
|
|
||||||
|
<div fxLayout="column">
|
||||||
|
|
||||||
|
<mat-form-field>
|
||||||
|
<mat-label>Role Name</mat-label>
|
||||||
|
<input matInput disabled formControlName="name">
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<mat-form-field>
|
||||||
|
<mat-label>Role Description</mat-label>
|
||||||
|
<input matInput required formControlName="description">
|
||||||
|
<mat-error *ngIf="roleForm.controls.description.hasError('required')">
|
||||||
|
Description is <strong>required</strong>
|
||||||
|
</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</mat-card-content>
|
||||||
|
|
||||||
|
<mat-card-actions fxLayout="row" fxLayout.xs="column" fxLayoutAlign="center" fxLayoutGap="5px">
|
||||||
|
<button type="button" mat-raised-button [routerLink]="['../../']">Cancel</button>
|
||||||
|
<button mat-raised-button color="primary" [disabled]="!roleForm.valid || roleForm.pristine">Submit</button>
|
||||||
|
</mat-card-actions>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</mat-card>
|
||||||
|
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
.container {
|
||||||
|
max-width: 37rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.roleName {
|
||||||
|
line-height: 3rem;
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { EditRoleComponent } from './edit-role.component';
|
||||||
|
|
||||||
|
describe('EditRoleComponent', () => {
|
||||||
|
let component: EditRoleComponent;
|
||||||
|
let fixture: ComponentFixture<EditRoleComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ EditRoleComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(EditRoleComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
/** Angular Imports */
|
||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
|
||||||
|
import { ActivatedRoute, Router } from '@angular/router';
|
||||||
|
|
||||||
|
/** Custom Services */
|
||||||
|
import { SystemService } from '../../system.service';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Edit Role Description Component.
|
||||||
|
*/
|
||||||
|
@Component({
|
||||||
|
selector: 'mifosx-edit-role',
|
||||||
|
templateUrl: './edit-role.component.html',
|
||||||
|
styleUrls: ['./edit-role.component.scss'],
|
||||||
|
})
|
||||||
|
export class EditRoleComponent implements OnInit {
|
||||||
|
/** Role Form */
|
||||||
|
roleForm: FormGroup;
|
||||||
|
/** Role Data */
|
||||||
|
roleData: any;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the code data from `resolve`.
|
||||||
|
* @param {FormBuilder} formBuilder Form Builder.
|
||||||
|
* @param {SystemService} systemService System Service.
|
||||||
|
* @param {ActivatedRoute} route Activated Route.
|
||||||
|
* @param {Router} router Router for navigation.
|
||||||
|
*/
|
||||||
|
constructor(
|
||||||
|
private formBuilder: FormBuilder,
|
||||||
|
private systemService: SystemService,
|
||||||
|
private route: ActivatedRoute,
|
||||||
|
private router: Router
|
||||||
|
) {
|
||||||
|
this.route.data.subscribe((data: { role: any }) => {
|
||||||
|
this.roleData = data.role;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates and sets the role form.
|
||||||
|
*/
|
||||||
|
ngOnInit() {
|
||||||
|
this.createRoleForm();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates and sets role form.
|
||||||
|
*/
|
||||||
|
createRoleForm() {
|
||||||
|
this.roleForm = this.formBuilder.group({
|
||||||
|
name: [{ value: this.roleData.name, disabled: true }, Validators.required],
|
||||||
|
description: [this.roleData.description, Validators.required],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Submits the role form and updates role description,
|
||||||
|
* if successful redirects to view updated roles and permissions.
|
||||||
|
*/
|
||||||
|
submit() {
|
||||||
|
this.systemService.updateRole(this.roleForm.value, this.roleData.id).subscribe(() => {
|
||||||
|
this.router.navigate(['../../'], { relativeTo: this.route });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -37,8 +37,17 @@
|
|||||||
</td>
|
</td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
|
<ng-container matColumnDef="actions">
|
||||||
|
<th mat-header-cell *matHeaderCellDef>Actions</th>
|
||||||
|
<td mat-cell *matCellDef="let role;" >
|
||||||
|
<button *ngIf="role.name !== 'Super user'" mat-icon-button color="primary" (click)="routeEdit($event)" [routerLink]="[role.id, 'edit']">
|
||||||
|
<fa-icon icon="edit"> Edit </fa-icon>
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||||
<tr mat-row *matRowDef="let row; columns: displayedColumns;" class="select-row"></tr>
|
<tr mat-row *matRowDef="let row; columns: displayedColumns;" [routerLink]="[row.id]" class="select-row"></tr>
|
||||||
|
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ export class RolesAndPermissionsComponent implements OnInit {
|
|||||||
/** Role data. */
|
/** Role data. */
|
||||||
roleData: any;
|
roleData: any;
|
||||||
/** Columns to be displayed in roles and permissions table. */
|
/** Columns to be displayed in roles and permissions table. */
|
||||||
displayedColumns: string[] = ['name', 'description', 'disabled'];
|
displayedColumns: string[] = ['name', 'description', 'disabled', 'actions'];
|
||||||
/** Data source for roles and permissions table. */
|
/** Data source for roles and permissions table. */
|
||||||
dataSource: MatTableDataSource<any>;
|
dataSource: MatTableDataSource<any>;
|
||||||
|
|
||||||
@@ -53,6 +53,14 @@ export class RolesAndPermissionsComponent implements OnInit {
|
|||||||
this.setRoles();
|
this.setRoles();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stops the propagation to view roles and permissions
|
||||||
|
* @param event Mouse Event
|
||||||
|
*/
|
||||||
|
routeEdit(event: MouseEvent) {
|
||||||
|
event.stopPropagation();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the data source, paginator and sorter for roles and permissions table.
|
* Initializes the data source, paginator and sorter for roles and permissions table.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -0,0 +1,99 @@
|
|||||||
|
<div fxLayout="row" fxLayoutAlign="end" fxLayoutGap="2%" fxLayout.lt-md="column" class="container m-b-20">
|
||||||
|
<button mat-raised-button color="primary" (click)="editRoles(); backupCheckValues();" [disabled]="rolePermissionService.name === 'Super user'">
|
||||||
|
<fa-icon icon="edit"></fa-icon>
|
||||||
|
Edit Role
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button *ngIf="!isRoleEnable(rolePermissionService.disabled)" mat-raised-button color="danger" (click)="disableRolesConfirmation()" [disabled]="rolePermissionService.name === 'Super user'">
|
||||||
|
<fa-icon icon="lock"></fa-icon>
|
||||||
|
Disable Role
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button *ngIf="isRoleEnable(rolePermissionService.disabled)" mat-raised-button color="primary" (click)="enableRolesConfirmation()" [disabled]="rolePermissionService.name === 'Super user'">
|
||||||
|
<fa-icon icon="lock-open"></fa-icon>
|
||||||
|
Enable Role
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button mat-raised-button color="warn" (click)="deleteRole()" [disabled]="rolePermissionService.name === 'Super user'">
|
||||||
|
<fa-icon icon="trash"></fa-icon>
|
||||||
|
Delete Role
|
||||||
|
</button>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
|
||||||
|
<mat-card>
|
||||||
|
|
||||||
|
<div fxFlexFill>
|
||||||
|
<span fxFlex="30%">Name:</span>
|
||||||
|
<span fxFlex="70%">{{ rolePermissionService.name }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div fxFlexFill>
|
||||||
|
<span fxFlex="30%">Description:</span>
|
||||||
|
<span fxFlex="70%">{{ rolePermissionService.description }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<mat-divider></mat-divider>
|
||||||
|
|
||||||
|
<ng-container>
|
||||||
|
|
||||||
|
<div fxLayout="row" class="permissionSelected">
|
||||||
|
<div fxFlex="75">
|
||||||
|
<h3>
|
||||||
|
Permissions: <strong>{{ formatName(previousGrouping) }}</strong>
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div fxFlex= "25" fxLayout="row" fxLayout.xs="column" fxLayoutAlign="end" fxLayoutGap="5px" *ngIf="!isDisabled" class="selectDeselect">
|
||||||
|
<button mat-raised-button color="primary" (click)="selectAll()">Select All</button>
|
||||||
|
<button mat-raised-button color="default" (click)="deselectAll()">Deselect All</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div fxLayout="row">
|
||||||
|
|
||||||
|
<div fxFlex="30" fxLayout="column">
|
||||||
|
<mat-list>
|
||||||
|
<mat-list-item [ngClass]="selectedItem == grouping ? 'active' : 'inactive'" *ngFor="let grouping of groupings" (click)="showPermissions(grouping)">
|
||||||
|
<span class="groupingName">
|
||||||
|
{{ formatName(grouping) }}
|
||||||
|
</span>
|
||||||
|
</mat-list-item>
|
||||||
|
</mat-list>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div fxFlex="70" fxLayout="column" class="listPermission">
|
||||||
|
|
||||||
|
<form [formGroup]="formGroup" (submit)="submit()">
|
||||||
|
|
||||||
|
<div *ngFor="let permission of permissions.permissions" class="displayPermissions">
|
||||||
|
<div formArrayName="roster">
|
||||||
|
<div [formGroupName]="permission.id">
|
||||||
|
<mat-checkbox name="cp" id="{{ permission.code }}" formControlName="selected"
|
||||||
|
>
|
||||||
|
{{ permissionName(permission.code) }}
|
||||||
|
</mat-checkbox>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<div fxLayout="row" fxLayout.xs="column" fxLayoutAlign="center" fxLayoutGap="5px" *ngIf="!isDisabled">
|
||||||
|
<mat-card-actions>
|
||||||
|
<button type="button" mat-raised-button (click)="cancel(); restoreCheckboxes();">Cancel</button>
|
||||||
|
<button mat-raised-button color="primary" (click)="submit()">Submit</button>
|
||||||
|
</mat-card-actions>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</mat-card>
|
||||||
|
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
.displayPermissions {
|
||||||
|
padding-top: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat-list-item {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mat-list-base .mat-list-item .mat-list-item-content {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.active {
|
||||||
|
background-color: #f2f2f2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.groupingName {
|
||||||
|
padding: 0px 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.listPermission {
|
||||||
|
padding-left: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.permissionSelected {
|
||||||
|
margin-top: 10px;
|
||||||
|
height: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.inactive {
|
||||||
|
transition: all .2s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.inactive:hover {
|
||||||
|
transform: scale(1.1);
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { ViewRoleComponent } from './view-role.component';
|
||||||
|
|
||||||
|
describe('ViewRoleComponent', () => {
|
||||||
|
let component: ViewRoleComponent;
|
||||||
|
let fixture: ComponentFixture<ViewRoleComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ ViewRoleComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(ViewRoleComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,301 @@
|
|||||||
|
/** Angular Imports */
|
||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
import { ActivatedRoute, Router } from '@angular/router';
|
||||||
|
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
|
||||||
|
import { MatDialog } from '@angular/material';
|
||||||
|
import { SystemService } from '../../system.service';
|
||||||
|
import * as _ from 'lodash';
|
||||||
|
|
||||||
|
/** Custom Components */
|
||||||
|
import { DeleteDialogComponent } from '../../../shared/delete-dialog/delete-dialog.component';
|
||||||
|
import { DisableDialogComponent } from '../../../shared/disable-dialog/disable-dialog.component';
|
||||||
|
import { EnableDialogComponent } from '../../../shared/enable-dialog/enable-dialog.component';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* View Role and Permissions Component
|
||||||
|
*/
|
||||||
|
@Component({
|
||||||
|
selector: 'mifosx-view-role',
|
||||||
|
templateUrl: './view-role.component.html',
|
||||||
|
styleUrls: ['./view-role.component.scss']
|
||||||
|
})
|
||||||
|
export class ViewRoleComponent implements OnInit {
|
||||||
|
|
||||||
|
/** Role Permissions Data */
|
||||||
|
rolePermissionService: any;
|
||||||
|
/** Stores the current grouping */
|
||||||
|
currentGrouping: string;
|
||||||
|
/** Stores the previous grouping */
|
||||||
|
previousGrouping = '';
|
||||||
|
/** Stores Grouping Data */
|
||||||
|
groupings: string[] = [];
|
||||||
|
/** Stores the selected role */
|
||||||
|
selectedItem = '';
|
||||||
|
/** Checks if its disabled */
|
||||||
|
isDisabled: Boolean = true;
|
||||||
|
/** Checks if there is any change in data */
|
||||||
|
checkboxesChanged: Boolean = false;
|
||||||
|
/** Stores backup values */
|
||||||
|
bValuesOnly: string[] = [];
|
||||||
|
/** Role ID */
|
||||||
|
roleId: any;
|
||||||
|
/** Creates permission form */
|
||||||
|
formGroup: FormGroup;
|
||||||
|
/** Creates Backup form */
|
||||||
|
backupform: FormGroup;
|
||||||
|
/** Temporarily stores Permission data */
|
||||||
|
tempPermissionUIData: {
|
||||||
|
permissions: { code: string }[]
|
||||||
|
}[];
|
||||||
|
/** Stores permissions */
|
||||||
|
permissions: {
|
||||||
|
permissions: { code: string, id: number }[]
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the roledetails data from `resolve`.
|
||||||
|
* @param {ActivatedRoute} route Activated Route.
|
||||||
|
* @param {SystemService} systemService System Service.
|
||||||
|
* @param {Router} router Router for navigation.
|
||||||
|
* @param {FormBuilder} formBuilder Form Builder.
|
||||||
|
* @param {MatDialog} dialog Shared Dialog Boxes.
|
||||||
|
*/
|
||||||
|
constructor(private route: ActivatedRoute,
|
||||||
|
private systemService: SystemService,
|
||||||
|
private router: Router,
|
||||||
|
private formBuilder: FormBuilder,
|
||||||
|
public dialog: MatDialog) {
|
||||||
|
this.route.data.subscribe((data: { roledetails: any }) => {
|
||||||
|
this.rolePermissionService = data.roledetails;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Groups all the data on init
|
||||||
|
*/
|
||||||
|
ngOnInit() {
|
||||||
|
this.permissions = {
|
||||||
|
permissions: []
|
||||||
|
};
|
||||||
|
this.createForm();
|
||||||
|
this.groupRules();
|
||||||
|
this.selectedItem = 'special';
|
||||||
|
this.showPermissions('special');
|
||||||
|
this.route.params.subscribe((routeParams: any) => {
|
||||||
|
this.roleId = routeParams.id;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* creates the form to display and edit permissions
|
||||||
|
*/
|
||||||
|
createForm() {
|
||||||
|
this.formGroup = this.formBuilder.group({
|
||||||
|
roster: this.formBuilder.array(this.rolePermissionService.permissionUsageData.map((elem: any) => this.createMemberGroup(elem)))
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
createMemberGroup(permission: any): FormGroup {
|
||||||
|
return this.formBuilder.group({
|
||||||
|
...permission,
|
||||||
|
...{
|
||||||
|
code: [permission.code, Validators.required],
|
||||||
|
selected: [{ value: permission.selected, disabled: true }, Validators.required]
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Groups the permissions based on rules
|
||||||
|
*/
|
||||||
|
groupRules() {
|
||||||
|
this.tempPermissionUIData = [{
|
||||||
|
permissions: []
|
||||||
|
}];
|
||||||
|
for (const i in this.rolePermissionService.permissionUsageData) {
|
||||||
|
if (this.rolePermissionService.permissionUsageData[i]) {
|
||||||
|
if (this.rolePermissionService.permissionUsageData[i].grouping !== this.currentGrouping) {
|
||||||
|
this.currentGrouping = this.rolePermissionService.permissionUsageData[i].grouping;
|
||||||
|
this.groupings.push(this.currentGrouping);
|
||||||
|
this.tempPermissionUIData[this.currentGrouping] = { permissions: [] };
|
||||||
|
}
|
||||||
|
const temp = { code: this.rolePermissionService.permissionUsageData[i].code, id: i, selected: this.rolePermissionService.permissionUsageData[i].selected };
|
||||||
|
this.tempPermissionUIData[this.currentGrouping].permissions.push(temp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Displays the permission for selected role
|
||||||
|
* @param grouping Selected Role
|
||||||
|
*/
|
||||||
|
showPermissions(grouping: string) {
|
||||||
|
this.permissions = this.tempPermissionUIData[grouping];
|
||||||
|
this.selectedItem = grouping;
|
||||||
|
this.previousGrouping = grouping;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Formats the Role Name
|
||||||
|
* @param string String
|
||||||
|
*/
|
||||||
|
formatName(string: any) {
|
||||||
|
if (string.indexOf('portfolio_') > -1) {
|
||||||
|
string = string.replace('portfolio_', '');
|
||||||
|
}
|
||||||
|
if (string.indexOf('transaction_') > -1) {
|
||||||
|
const temp = string.split('_');
|
||||||
|
string = temp[1] + ' ' + temp[0].charAt(0).toUpperCase() + temp[0].slice(1) + 's';
|
||||||
|
}
|
||||||
|
string = string.charAt(0).toUpperCase() + string.slice(1);
|
||||||
|
return string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Formats the permission from permission code
|
||||||
|
* @param name String
|
||||||
|
*/
|
||||||
|
permissionName(name: any) {
|
||||||
|
name = name || '';
|
||||||
|
// replace '_' with ' '
|
||||||
|
name = name.replace(/_/g, ' ');
|
||||||
|
// for reorts replace read with view
|
||||||
|
if (this.previousGrouping === 'report') {
|
||||||
|
name = name.replace(/READ/g, 'View');
|
||||||
|
}
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Backups the valued
|
||||||
|
*/
|
||||||
|
backupCheckValues() {
|
||||||
|
this.backupform = _.cloneDeep(this.formGroup) as FormGroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restores the checkboxes to previous data on clicking cancel
|
||||||
|
*/
|
||||||
|
restoreCheckboxes() {
|
||||||
|
this.formGroup = _.cloneDeep(this.backupform) as FormGroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
isRoleEnable(value: any) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
editRoles() {
|
||||||
|
this.isDisabled = false;
|
||||||
|
this.formGroup.controls.roster.enable();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cancel the changes
|
||||||
|
*/
|
||||||
|
cancel() {
|
||||||
|
this.isDisabled = true;
|
||||||
|
this.formGroup.controls.roster.disable();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Submits the modified permissions
|
||||||
|
*/
|
||||||
|
submit() {
|
||||||
|
const value = this.formGroup.get('roster').value;
|
||||||
|
const data = {};
|
||||||
|
const permissionData = {
|
||||||
|
permissions: {}
|
||||||
|
};
|
||||||
|
for (let i = 0; i < value.length; i++ ) {
|
||||||
|
data[value[i].code] = value[i].selected;
|
||||||
|
}
|
||||||
|
permissionData.permissions = data;
|
||||||
|
this.formGroup.controls.roster.disable();
|
||||||
|
this.checkboxesChanged = false;
|
||||||
|
this.isDisabled = true;
|
||||||
|
this.systemService.updateRolePermission(this.roleId, permissionData).subscribe((response: any) => {
|
||||||
|
console.log('response: ', response);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Selects all the permission of a particular role
|
||||||
|
*/
|
||||||
|
selectAll() {
|
||||||
|
for (let i = 0; i < this.permissions.permissions.length; i++) {
|
||||||
|
this.formGroup.controls.roster['controls'][this.permissions.permissions[i].id].patchValue({
|
||||||
|
selected: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deselects all the permissions of a particular role
|
||||||
|
*/
|
||||||
|
deselectAll() {
|
||||||
|
for (let i = 0; i < this.permissions.permissions.length; i++) {
|
||||||
|
this.formGroup.controls.roster['controls'][this.permissions.permissions[i].id].patchValue({
|
||||||
|
selected: false
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes the Role and redirects to Roles and Permissions.
|
||||||
|
*/
|
||||||
|
deleteRole() {
|
||||||
|
const deleteRoleDialogRef = this.dialog.open(DeleteDialogComponent, {
|
||||||
|
data: { deleteContext: `role ${this.roleId}` }
|
||||||
|
});
|
||||||
|
deleteRoleDialogRef.afterClosed().subscribe((response: any) => {
|
||||||
|
if (response.delete) {
|
||||||
|
this.systemService.deleteRole(this.roleId)
|
||||||
|
.subscribe(() => {
|
||||||
|
this.router.navigate(['/system/roles-and-permissions']);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enables the Role and redirects to Roles and Permissions.
|
||||||
|
*/
|
||||||
|
enableRolesConfirmation() {
|
||||||
|
const enableRoleDialogRef = this.dialog.open(EnableDialogComponent, {
|
||||||
|
data: { enableContext: `role ${this.roleId}` }
|
||||||
|
});
|
||||||
|
enableRoleDialogRef.afterClosed().subscribe((response: any) => {
|
||||||
|
if (response.enable) {
|
||||||
|
this.systemService.enableRole(this.roleId)
|
||||||
|
.subscribe(() => {
|
||||||
|
this.router.navigate(['/system/roles-and-permissions']);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disables the Role and redirects to Roles and Permissions.
|
||||||
|
*/
|
||||||
|
disableRolesConfirmation() {
|
||||||
|
const deleteRoleDialogRef = this.dialog.open(DisableDialogComponent, {
|
||||||
|
data: { disableContext: `role ${this.roleId}` }
|
||||||
|
});
|
||||||
|
deleteRoleDialogRef.afterClosed().subscribe((response: any) => {
|
||||||
|
if (response.disable) {
|
||||||
|
this.systemService.disableRole(this.roleId)
|
||||||
|
.subscribe(() => {
|
||||||
|
this.router.navigate(['/system/roles-and-permissions']);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
/** Angular Imports */
|
||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { Resolve, ActivatedRouteSnapshot } from '@angular/router';
|
||||||
|
|
||||||
|
/** rxjs Imports */
|
||||||
|
import { Observable } from 'rxjs';
|
||||||
|
|
||||||
|
/** Custom Services */
|
||||||
|
import { SystemService } from '../../system.service';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Roles and Permission data resolver.
|
||||||
|
*/
|
||||||
|
@Injectable()
|
||||||
|
export class ViewRoleResolver implements Resolve<Object> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {SystemService} systemService System service.
|
||||||
|
*/
|
||||||
|
constructor(private systemService: SystemService) { }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the roles and permissions data.
|
||||||
|
* @returns {Observable<any>}
|
||||||
|
*/
|
||||||
|
resolve(route: ActivatedRouteSnapshot): Observable<any> {
|
||||||
|
const id = route.paramMap.get('id');
|
||||||
|
return this.systemService.getRole(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -44,6 +44,8 @@ import { CreateReportComponent } from './manage-reports/create-report/create-rep
|
|||||||
import { ViewReportComponent } from './manage-reports/view-report/view-report.component';
|
import { ViewReportComponent } from './manage-reports/view-report/view-report.component';
|
||||||
import { AuditTrailsComponent } from './audit-trails/audit-trails.component';
|
import { AuditTrailsComponent } from './audit-trails/audit-trails.component';
|
||||||
import { ViewAuditComponent } from './audit-trails/view-audit/view-audit.component';
|
import { ViewAuditComponent } from './audit-trails/view-audit/view-audit.component';
|
||||||
|
import { ViewRoleComponent } from './roles-and-permissions/view-role/view-role.component';
|
||||||
|
import { EditRoleComponent } from './roles-and-permissions/edit-role/edit-role.component';
|
||||||
|
|
||||||
/** Custom Resolvers */
|
/** Custom Resolvers */
|
||||||
import { CodesResolver } from './codes/codes.resolver';
|
import { CodesResolver } from './codes/codes.resolver';
|
||||||
@@ -75,6 +77,7 @@ import { ViewSchedulerJobComponent } from './manage-scheduler-jobs/view-schedule
|
|||||||
import { ViewSchedulerJobResolver } from './manage-scheduler-jobs/view-scheduler-job/view-scheduler-job.resolver';
|
import { ViewSchedulerJobResolver } from './manage-scheduler-jobs/view-scheduler-job/view-scheduler-job.resolver';
|
||||||
import { EditSchedulerJobComponent } from './manage-scheduler-jobs/edit-scheduler-job/edit-scheduler-job.component';
|
import { EditSchedulerJobComponent } from './manage-scheduler-jobs/edit-scheduler-job/edit-scheduler-job.component';
|
||||||
import { ManageSchedulerJobResolver } from './manage-scheduler-jobs/manage-scheduler-job.resolver';
|
import { ManageSchedulerJobResolver } from './manage-scheduler-jobs/manage-scheduler-job.resolver';
|
||||||
|
import { ViewRoleResolver } from './roles-and-permissions/view-role/view-role.resolver';
|
||||||
|
|
||||||
const routes: Routes = [
|
const routes: Routes = [
|
||||||
Route.withShell([
|
Route.withShell([
|
||||||
@@ -322,8 +325,30 @@ const routes: Routes = [
|
|||||||
path: 'add',
|
path: 'add',
|
||||||
component: AddRoleComponent,
|
component: AddRoleComponent,
|
||||||
data: { title: extract('Add Role'), breadcrumb: 'Add' }
|
data: { title: extract('Add Role'), breadcrumb: 'Add' }
|
||||||
}
|
},
|
||||||
]
|
{
|
||||||
|
path: ':id',
|
||||||
|
data: { title: extract('View Role'), routeParamBreadcrumb: 'id' },
|
||||||
|
runGuardsAndResolvers: 'always',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: '',
|
||||||
|
component: ViewRoleComponent,
|
||||||
|
resolve: {
|
||||||
|
roledetails: ViewRoleResolver,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'edit',
|
||||||
|
component: EditRoleComponent,
|
||||||
|
data: { title: extract('Edit Role'), breadcrumb: 'Edit', routeParamBreadcrumb: false },
|
||||||
|
resolve: {
|
||||||
|
role: ViewRoleResolver,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'surveys',
|
path: 'surveys',
|
||||||
@@ -530,7 +555,8 @@ const routes: Routes = [
|
|||||||
AuditTrailSearchTemplateResolver,
|
AuditTrailSearchTemplateResolver,
|
||||||
AuditTrailResolver,
|
AuditTrailResolver,
|
||||||
ViewSchedulerJobResolver,
|
ViewSchedulerJobResolver,
|
||||||
ManageSchedulerJobResolver
|
ManageSchedulerJobResolver,
|
||||||
|
ViewRoleResolver
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class SystemRoutingModule { }
|
export class SystemRoutingModule { }
|
||||||
|
|||||||
@@ -45,6 +45,8 @@ import { EditHookComponent } from './manage-hooks/edit-hook/edit-hook.component'
|
|||||||
import { ViewHookComponent } from './manage-hooks/view-hook/view-hook.component';
|
import { ViewHookComponent } from './manage-hooks/view-hook/view-hook.component';
|
||||||
import { CreateHookComponent } from './manage-hooks/create-hook/create-hook.component';
|
import { CreateHookComponent } from './manage-hooks/create-hook/create-hook.component';
|
||||||
import { ColumnDialogComponent } from './manage-data-tables/column-dialog/column-dialog.component';
|
import { ColumnDialogComponent } from './manage-data-tables/column-dialog/column-dialog.component';
|
||||||
|
import { ViewRoleComponent } from './roles-and-permissions/view-role/view-role.component';
|
||||||
|
import { EditRoleComponent } from './roles-and-permissions/edit-role/edit-role.component';
|
||||||
|
|
||||||
/** Dialog Component Imports */
|
/** Dialog Component Imports */
|
||||||
import { ReportParameterDialogComponent } from './manage-reports/report-parameter-dialog/report-parameter-dialog.component';
|
import { ReportParameterDialogComponent } from './manage-reports/report-parameter-dialog/report-parameter-dialog.component';
|
||||||
@@ -100,7 +102,9 @@ import { EditSchedulerJobComponent } from './manage-scheduler-jobs/edit-schedule
|
|||||||
AuditTrailsComponent,
|
AuditTrailsComponent,
|
||||||
ViewAuditComponent,
|
ViewAuditComponent,
|
||||||
ViewSchedulerJobComponent,
|
ViewSchedulerJobComponent,
|
||||||
EditSchedulerJobComponent
|
EditSchedulerJobComponent,
|
||||||
|
ViewRoleComponent,
|
||||||
|
EditRoleComponent
|
||||||
],
|
],
|
||||||
entryComponents: [
|
entryComponents: [
|
||||||
ReportParameterDialogComponent,
|
ReportParameterDialogComponent,
|
||||||
|
|||||||
@@ -79,6 +79,39 @@ export class SystemService {
|
|||||||
return this.http.get('/roles');
|
return this.http.get('/roles');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {Observable<any>} Fetches Roles and Permissions
|
||||||
|
*/
|
||||||
|
getRole(roleId: any): Observable<any> {
|
||||||
|
return this.http.get(`/roles/${roleId}/permissions`);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param role Role.
|
||||||
|
* @param roleId Role ID.
|
||||||
|
* @returns {Observable<any>}
|
||||||
|
*/
|
||||||
|
updateRole(role: any, roleId: string): Observable<any> {
|
||||||
|
return this.http.put(`/roles/${roleId}`, role);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param roleID Role ID.
|
||||||
|
* @param roleValueChanges Role value changes.
|
||||||
|
* @returns {Observable<any>}
|
||||||
|
*/
|
||||||
|
updateRolePermission(roleId: any, roleValueChanges: any): Observable<any> {
|
||||||
|
return this.http.put(`/roles/${roleId}/permissions`, roleValueChanges);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param roleId Role ID.
|
||||||
|
* @returns {Observable<any>}
|
||||||
|
*/
|
||||||
|
deleteRole(roleId: string): Observable<any> {
|
||||||
|
return this.http.delete(`/roles/${roleId}`);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {any} role Role to be created.
|
* @param {any} role Role to be created.
|
||||||
* @returns {Observable<any>}
|
* @returns {Observable<any>}
|
||||||
@@ -87,6 +120,24 @@ export class SystemService {
|
|||||||
return this.http.post('/roles', role);
|
return this.http.post('/roles', role);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param roleId Role ID.
|
||||||
|
* @returns {Observable<any>}
|
||||||
|
*/
|
||||||
|
enableRole(roleId: string): Observable<any> {
|
||||||
|
const httpParams = new HttpParams().set('command', 'enable');
|
||||||
|
return this.http.post(`/roles/${roleId}`, {} , { params: httpParams });
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param roleId Role ID.
|
||||||
|
* @returns {Observable<any>}
|
||||||
|
*/
|
||||||
|
disableRole(roleId: string): Observable<any> {
|
||||||
|
const httpParams = new HttpParams().set('command', 'disable');
|
||||||
|
return this.http.post(`/roles/${roleId}`, {}, { params: httpParams });
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @returns {Observable<any>} Fetches Codes.
|
* @returns {Observable<any>} Fetches Codes.
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user