diff options
Diffstat (limited to 'ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/roles')
9 files changed, 1120 insertions, 0 deletions
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/roles/new-role/new-role.component.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/roles/new-role/new-role.component.html new file mode 100644 index 00000000..f3a7f8ea --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/roles/new-role/new-role.component.html @@ -0,0 +1,106 @@ +<!-- + ============LICENSE_START========================================== + ONAP Portal SDK + =================================================================== + Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + =================================================================== + + Unless otherwise specified, all software contained herein is licensed + under the Apache License, Version 2.0 (the "License"); + you may not use this software except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + Unless otherwise specified, all documentation contained herein is licensed + under the Creative Commons License, Attribution 4.0 Intl. (the "License"); + you may not use this documentation except in compliance with the License. + You may obtain a copy of the License at + + https://creativecommons.org/licenses/by/4.0/ + + Unless required by applicable law or agreed to in writing, documentation + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + ============LICENSE_END============================================ + + --> +<div class="container"> + <!--Modal Headers--> + <div class="modal-header"> + <h4 class="modal-title">Role</h4> + <button type="button" class="close" aria-label="Close" (click)="activeModal.dismiss('Cross')"> + <span aria-hidden="true">×</span> + </button> + </div> + + <!--Modal Body goes here--> + <div class="modal-body"> + <span class="ecomp-spinner" *ngIf="showSpinner"></span> + <div class="role-properties-main"> + <form id="role-details-form" name="roleDetails" novalidate autocomplete="off" method="post"> + <div class="elementsDiv"> + <div class="item required role-name"> + <div class="item-label">Name :</div> + <input id="role-details-input-name" class="table-search-field" + type="text" name="rolename" + [(ngModel)]="role.name" + ng-pattern="/^[\w -]*$/" maxlength="100" required /> + </div> + <div> + <div class="item-label">Priority :</div> + <input id="role-details-input-priority" class="table-search-field" + type="text" + ng-change="accountAddDetails.updateUsername()" name="priority" + [(ngModel)]="role.priority"/> + </div> + </div> + </form> + </div> + + <!-- Role Functions List--> + <div *ngIf="isEditMode" class="role-functions-title">Role Functions</div> + <div *ngIf="isEditMode" class="rolefunctionTable"> + <table mat-table [dataSource]="roleFunctionDataSource"> + <ng-container matColumnDef="roleFunctionName"> + <th mat-header-cell *matHeaderCellDef id="heading1">Function Name</th> + <td mat-cell *matCellDef="let rowData"> {{rowData.name}} </td> + </ng-container> + + <!--<ng-container matColumnDef="remove"> + <th mat-header-cell *matHeaderCellDef id="heading1">Remove</th> + <td id="rowheader_t1_{{i}}" mat-cell *matCellDef="let rowData; let i=index;"> + <span class="icon-trash" id="{{i}}-button-role-remove" (click)="delRoleFunctionConfirmPopUp(rowData,role.id)"> + <i class="icon ion-md-trash"></i> + </span> + </td> + </ng-container>--> + + <!-- Active Column --> + <ng-container matColumnDef="active"> + <th id="col3" mat-header-cell *matHeaderCellDef>Active ?</th> + <td id="rowheader_t1_{{i}}-userId" mat-cell *matCellDef="let element; let i=index;"> + <mat-slide-toggle [(ngModel)]="element.selected" (change)="toggleRoleFunction(element)"></mat-slide-toggle> + </td> + </ng-container> + + <tr mat-header-row *matHeaderRowDef="roleFunctionTableHeaders"></tr> + <tr mat-row *matRowDef="let rowData; columns: roleFunctionTableHeaders;"> + </table> + </div> + </div> + <!--Modal Footer goes Here--> + <div class="modal-footer"> + <button type="button" class="btn btn-primary" (click)="saveChanges()">Save</button> + <button type="button" class="btn btn-primary" (click)="activeModal.close('Close')">Cancel</button> + </div> +</div> diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/roles/new-role/new-role.component.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/roles/new-role/new-role.component.scss new file mode 100644 index 00000000..972094c7 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/roles/new-role/new-role.component.scss @@ -0,0 +1,74 @@ +/*- + * ============LICENSE_START========================================== + * ONAP Portal SDK + * =================================================================== + * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * + * Unless otherwise specified, all software contained herein is licensed + * under the Apache License, Version 2.0 (the "License"); + * you may not use this software except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Unless otherwise specified, all documentation contained herein is licensed + * under the Creative Commons License, Attribution 4.0 Intl. (the "License"); + * you may not use this documentation except in compliance with the License. + * You may obtain a copy of the License at + * + * https://creativecommons.org/licenses/by/4.0/ + * + * Unless required by applicable law or agreed to in writing, documentation + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ============LICENSE_END============================================ + * + * + */ + + ::ng-deep .modal-dialog { + max-width: 700px; + width: 700px; + overflow-x: auto; + overflow-y: auto; +} + +::ng-deep .mat-column-roleFunctionName { + width: 38em !important; +} + + +.role-properties-main input[type="text"] { + width: 18em; +} + +.role-properties-main .role-name{ + margin-right: 35px; +} + +.elementsDiv{ + display: inline-flex; +} + +.role-functions-title{ + margin-top: 2em; +} + +.manageRoleFunction{ + margin-top: 2em; +} + +.rolefunctionTable{ + overflow-y: auto; + height: 440px; +} diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/roles/new-role/new-role.component.spec.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/roles/new-role/new-role.component.spec.ts new file mode 100644 index 00000000..4eca8263 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/roles/new-role/new-role.component.spec.ts @@ -0,0 +1,132 @@ +/*- + * ============LICENSE_START========================================== + * ONAP Portal SDK + * =================================================================== + * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Modification Copyright © 2020 IBM. + * =================================================================== + * + * Unless otherwise specified, all software contained herein is licensed + * under the Apache License, Version 2.0 (the "License"); + * you may not use this software except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Unless otherwise specified, all documentation contained herein is licensed + * under the Creative Commons License, Attribution 4.0 Intl. (the "License"); + * you may not use this documentation except in compliance with the License. + * You may obtain a copy of the License at + * + * https://creativecommons.org/licenses/by/4.0/ + * + * Unless required by applicable law or agreed to in writing, documentation + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ============LICENSE_END============================================ + * + * + */ + +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import {FormsModule} from '@angular/forms'; +import { NewRoleComponent } from './new-role.component'; +import { MatTableModule } from '@angular/material' +import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; +import { HttpClientTestingModule } from '@angular/common/http/testing'; +import { NgbActiveModal, NgbModule } from '@ng-bootstrap/ng-bootstrap'; +import { ConfirmationModalComponent } from 'src/app/modals/confirmation-modal/confirmation-modal.component'; +import { BrowserDynamicTestingModule } from '@angular/platform-browser-dynamic/testing'; +import { AdminService } from '../../admin.service'; +import { Observable } from 'rxjs'; +import { InformationModalComponent } from 'src/app/modals/information-modal/information-modal.component'; + +describe('NewRoleComponent', () => { + let component: NewRoleComponent; + let fixture: ComponentFixture<NewRoleComponent>; + let role1 = ""; + let adminService:AdminService; + var _element={ + "selected":false, + "code":"code", + "type":"type", + "action":"action" + }; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + providers: [NgbActiveModal,AdminService], + schemas: [CUSTOM_ELEMENTS_SCHEMA] , + declarations: [ + NewRoleComponent, + ConfirmationModalComponent, + InformationModalComponent + ], + imports: [ + FormsModule, + MatTableModule, + HttpClientTestingModule, + NgbModule.forRoot() + ] + }) + TestBed.overrideModule(BrowserDynamicTestingModule,{ + set:{ + entryComponents:[ConfirmationModalComponent,InformationModalComponent] + } + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(NewRoleComponent); + component = fixture.componentInstance; + component.role = role1; + fixture.detectChanges(); + adminService=TestBed.get(AdminService); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + it('should test delRoleFunctionConfirmPopUp method',()=>{ + component.delRoleFunctionConfirmPopUp("abc","def"); + }) + + it('should test else condition in saveChanges method',()=>{ + spyOn(adminService,'saveRole').and.returnValue(Observable.of('your object')); + component.saveChanges() + }) + + it('should test toggleRoleFunction method',()=>{ + component.finalSelectedRoleFunctions="Indrijeet kuma"; + component.ociavailableRoleFunctions="i"; + component.finalSelectedRoleFunctions="k"; + component.toggleRoleFunction(_element) + }) + + it('should test populateTableData method',()=>{ + component.populateTableData("populateTableData"); + expect(component.roleFunctionDataSource.sort).toEqual(component.sort); + expect(component.roleFunctionDataSource.paginator).toEqual(component.paginator) + }) + + it('should test isRoleAlreadyExist method',()=>{ + component.availableRoles={"name":["currentRoleName"]}; + component.isRoleAlreadyExist("currentRoleName") + }) + + it('it should test openConfirmationModal method',()=>{ + component.openConfirmationModal("test","value"); + }) +});
\ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/roles/new-role/new-role.component.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/roles/new-role/new-role.component.ts new file mode 100644 index 00000000..6b1470fa --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/roles/new-role/new-role.component.ts @@ -0,0 +1,250 @@ +/*- + * ============LICENSE_START========================================== + * ONAP Portal SDK + * =================================================================== + * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * + * Unless otherwise specified, all software contained herein is licensed + * under the Apache License, Version 2.0 (the "License"); + * you may not use this software except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Unless otherwise specified, all documentation contained herein is licensed + * under the Creative Commons License, Attribution 4.0 Intl. (the "License"); + * you may not use this documentation except in compliance with the License. + * You may obtain a copy of the License at + * + * https://creativecommons.org/licenses/by/4.0/ + * + * Unless required by applicable law or agreed to in writing, documentation + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ============LICENSE_END============================================ + * + * + */ + +import { Component, OnInit, Input, Output, EventEmitter, ViewChild } from '@angular/core'; +import { NgbActiveModal, NgbModal } from '@ng-bootstrap/ng-bootstrap'; +import { AdminService } from '../../admin.service'; +import { UserService } from 'src/app/shared/services/user/user.service'; +import { MatSort } from '@angular/material/sort'; +import { MatPaginator } from '@angular/material/paginator'; +import { MatTableDataSource } from '@angular/material'; +import { InformationModalComponent } from 'src/app/modals/information-modal/information-modal.component'; +import { ConfirmationModalComponent } from 'src/app/modals/confirmation-modal/confirmation-modal.component'; + + +@Component({ + selector: 'app-new-role', + templateUrl: './new-role.component.html', + styleUrls: ['./new-role.component.scss'] +}) +export class NewRoleComponent implements OnInit { + + showSpinner: boolean; + result: any; + @Input() role: any; + @Input() isEditMode: boolean; + @Input() availableRoles : any; + @Input() ociavailableRoleFunctions: any; + roleFunctionTableHeaders: Array<string> = []; + roleFunctions: Array<Object> = []; + roleFunctionsLenght: any; + finalSelectedRoleFunctions: any; + availableRoleFunctions: any; + @Output() passEntry: EventEmitter<any> = new EventEmitter(); + @ViewChild(MatPaginator, {}) paginator: MatPaginator; + @ViewChild(MatSort, {}) sort: MatSort; + roleFunctionDataSource = new MatTableDataSource(this.roleFunctions); + + constructor(public adminService:AdminService, public userService: UserService, public activeModal: NgbActiveModal, public ngbModal: NgbModal) { } + + ngOnInit() { + this.roleFunctionTableHeaders = ["roleFunctionName","active"]; + this.finalSelectedRoleFunctions = []; + this.availableRoleFunctions = []; + if(this.isEditMode && this.ociavailableRoleFunctions && this.ociavailableRoleFunctions.length > 0){ + this.availableRoleFunctions = this.setSelectedRoleFucntions(this.ociavailableRoleFunctions); + this.populateTableData(this.availableRoleFunctions) + } + } + + setSelectedRoleFucntions(ociavailableRoleFunctions: any) { + for (var i = 0; i < this.ociavailableRoleFunctions.length; i++) { + var availableRoleFunction = this.ociavailableRoleFunctions[i]; + availableRoleFunction['selected'] = false; + for (var j = 0; j < this.role.roleFunctions.length; j++) { + if (availableRoleFunction.code === this.role.roleFunctions[j].code + && availableRoleFunction.type === this.role.roleFunctions[j].type + && availableRoleFunction.action === this.role.roleFunctions[j].action) { + availableRoleFunction.selected = true; + } + } + this.availableRoleFunctions.push(availableRoleFunction); + } + return this.availableRoleFunctions; + } + + + toggleRoleFunction(_element) { + if (this.ociavailableRoleFunctions) { + for (var i = 0; i < this.ociavailableRoleFunctions.length; i++) { + var availableRoleFunction = this.ociavailableRoleFunctions[i]; + if (availableRoleFunction.selected && !this.finalSelectedRoleFunctions.includes(availableRoleFunction)) { + this.finalSelectedRoleFunctions.push(availableRoleFunction); + } + } + } + if (!_element.selected) { + for (var i = 0; i < this.finalSelectedRoleFunctions.length; i++) { + var availableRoleFunction = this.finalSelectedRoleFunctions[i]; + if (availableRoleFunction.code == _element.code + && availableRoleFunction.type == _element.type + && availableRoleFunction.action == _element.action) { + this.finalSelectedRoleFunctions.splice(i, 1); + } + } + } + } + + delRoleFunctionConfirmPopUp(roleFunction: any, roleId: any){ + const modalRef = this.ngbModal.open(InformationModalComponent); + modalRef.componentInstance.title = "Confirmation"; + modalRef.componentInstance.message = 'You are about to delete this Role Function : ' + roleFunction.name+ '. Click OK to continue.'; + modalRef.result.then((result) => { + if (result === 'Ok') { + let temproleFunctions = this.role.roleFunctions; + let index = 0; + for(let i=0; i<temproleFunctions.length; i++){ + if(temproleFunctions[i].code == roleFunction.code){ + break; + } + index = index + 1; + }; + temproleFunctions.splice(index,1); + this.populateTableData(temproleFunctions); + this.adminService.removeRoleFunction(roleFunction , roleId) + .subscribe(_data => { + this.result = _data + this.passEntry.emit(this.result); + }, error =>{ + this.openConfirmationModal('Error', error.message); + }); + } + }, (resut) => { + this.openConfirmationModal('Error', resut); + return; + }) + } + + populateTableData(roleFunctionsList: any){ + this.roleFunctionDataSource = new MatTableDataSource(roleFunctionsList); + this.roleFunctionDataSource.sort = this.sort; + this.roleFunctionDataSource.paginator = this.paginator; + } + + //Add Or Update Account. + saveChanges(){ + if(this.isEditMode){ + if (this.role.priority && this.role.priority != '' && isNaN(parseInt(this.role.priority))) { + let errorMsg = 'Priority must be an integer.'; + this.openConfirmationModal('Error', errorMsg); + } + //update the role object + this.showSpinner = true + this.role.roleFunctions = this.finalSelectedRoleFunctions; + let postData={ + role: this.role, + childRoles: this.role.childRoles, + roleFunctions : this.role.roleFunctions + }; + this.adminService.saveRole(postData, this.role.id) + .subscribe(_data => { + this.showSpinner = false; + this.result = _data + this.passEntry.emit(this.result); + this.ngbModal.dismissAll(); + }, error =>{ + this.openConfirmationModal('Error', error.message); + }); + }else{ + //create new Role Object + if (this.role.priority && this.role.priority != '' && isNaN(parseInt(this.role.priority))) { + let errorMsg = 'Priority must be an integer.'; + this.openConfirmationModal('Error', errorMsg); + } + let newRoleObj = { + 'id':null, + 'created':null, + 'modified':null, + 'createdId':null, + 'modifiedId':null, + 'rowNum':null, + 'auditUserId':null, + 'auditTrail':null, + 'name':this.role.name, + 'active':true, + 'priority':this.role.priority, + 'roleFunctions':null, + 'childRoles':null, + 'toggleActiveAltText':"Click to Activate Role ", + 'toggleActiveImage':" / static fusion images inactive.png ", + 'editUrl':" role.htm ? role_id = null", + }; + if(this.isRoleAlreadyExist(this.role.name)){ + //msg Role already exit + let errorMsg = "Role Name " + this.role.name +" is already present." + this.openConfirmationModal('Error', errorMsg); + }else{ + this.showSpinner = true + newRoleObj.childRoles = []; + newRoleObj.roleFunctions = []; + let postData={ + role: newRoleObj, + childRoles: newRoleObj.childRoles, + roleFunctions : newRoleObj.roleFunctions + }; + this.adminService.saveRole(postData, newRoleObj.id) + .subscribe(_data => { + this.showSpinner = false; + this.result = _data + this.passEntry.emit(this.result); + this.ngbModal.dismissAll(); + }, error =>{ + this.openConfirmationModal('Error', error.message); + }); + } + } + } + + isRoleAlreadyExist(currentRoleName: any){ + let roles = this.availableRoles; + if(roles && roles.length > 0){ + for(let i=0; i<roles.length; i++){ + if(roles[i].name === currentRoleName){ + return true; + } + } + } + return false; + } + + openConfirmationModal(_title: string, _message: string) { + const modalInfoRef = this.ngbModal.open(ConfirmationModalComponent); + modalInfoRef.componentInstance.title = _title; + modalInfoRef.componentInstance.message = _message; + } +} diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/roles/roles.component.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/roles/roles.component.html new file mode 100644 index 00000000..7d845fee --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/roles/roles.component.html @@ -0,0 +1,104 @@ +<!-- + ============LICENSE_START========================================== + ONAP Portal SDK + =================================================================== + Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + =================================================================== + + Unless otherwise specified, all software contained herein is licensed + under the Apache License, Version 2.0 (the "License"); + you may not use this software except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + Unless otherwise specified, all documentation contained herein is licensed + under the Creative Commons License, Attribution 4.0 Intl. (the "License"); + you may not use this documentation except in compliance with the License. + You may obtain a copy of the License at + + https://creativecommons.org/licenses/by/4.0/ + + Unless required by applicable law or agreed to in writing, documentation + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + ============LICENSE_END============================================ + + --> + + <div class="main-container"> + <div id="page-content"> + <div class="ecomp-main-view-title"> + <h3 class="heading-page">Roles</h3> + <span class= "heading-small" *ngIf="isAppCentralized=='true'"><b>Please go to portal to Manage Roles.</b></span> + </div> + + <span class="ecomp-spinner" *ngIf="showSpinner"></span> + + <div class="table-search-div"> + <mat-form-field> + <input matInput type="text" (keyup)="applyFilter($event.target.value)" placeholder="Search in entire table"> + </mat-form-field> + + <button type="button" *ngIf="isAppCentralized=='false'" class="btn btn-primary new-role-button" (click)="openAddNewRoleModal('')"> + <i class="icon ion-md-person-add"></i>Add New Role + </button> + </div> + + <table mat-table [dataSource]="dataSource" matSort> + <ng-container matColumnDef="name"> + <th mat-header-cell *matHeaderCellDef mat-sort-header id="heading1"> Name</th> + <td mat-cell *matCellDef="let rowData"> {{rowData.name}} </td> + </ng-container> + + <ng-container matColumnDef="priority"> + <th mat-header-cell *matHeaderCellDef id="heading2"> Priority</th> + <td mat-cell *matCellDef="let rowData"> {{rowData.priority}} </td> + </ng-container> + + <ng-container matColumnDef="Edit"> + <th mat-header-cell *matHeaderCellDef id="heading3">{{roleHeaders[2]}} </th> + <td id="rowheader_t1_{{i}}" mat-cell *matCellDef="let rowData; let i=index;"> + <span class="icon-trash" id="{{i}}-button-role-edit" + (click)="openAddNewRoleModal(rowData)"> + <i class="ion ion-md-create"></i> + </span> + </td> + </ng-container> + + <ng-container matColumnDef="Active?"> + <th mat-header-cell *matHeaderCellDef id="heading4"> {{roleHeaders[3]}} </th> + <td mat-cell *matCellDef="let rowData"> + <mat-slide-toggle [(ngModel)]="rowData.active" (change)="toggleRole(rowData)"></mat-slide-toggle> + </td> + </ng-container> + + <ng-container matColumnDef="Delete?"> + <th mat-header-cell *matHeaderCellDef id="heading6"> {{roleHeaders[4]}} </th> + <td id="rowheader_t1_{{i}}" mat-cell *matCellDef="let rowData; let i=index;"> + <span class="icon-trash" id="{{i}}-button-role-remove" + (click)="delRoleConfirmPopUp(rowData)"> + <i class="icon ion-md-trash"></i> + </span> + </td> + </ng-container> + <tr mat-header-row *matHeaderRowDef="roleHeaders"></tr> + <tr mat-row *matRowDef="let rowData; columns: roleHeaders;"> + </table> + <mat-paginator [pageSizeOptions]="[5, 10, 25, 100]"></mat-paginator> + <span class="ecomp-spinner" *ngIf="showSpinner"></span> + <div> + <a (click)="getFunctions()" id="functions-link">Manage Role Functions</a><br><br> + </div> + </div> + </div> +
\ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/roles/roles.component.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/roles/roles.component.scss new file mode 100644 index 00000000..1a4d76ae --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/roles/roles.component.scss @@ -0,0 +1,120 @@ +/* + * ============LICENSE_START========================================== + * ONAP Portal SDK + * =================================================================== + * Copyright © 2019 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * + * Unless otherwise specified, all software contained herein is licensed + * under the Apache License, Version 2.0 (the "License"); + * you may not use this software except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Unless otherwise specified, all documentation contained herein is licensed + * under the Creative Commons License, Attribution 4.0 Intl. (the "License"); + * you may not use this documentation except in compliance with the License. + * You may obtain a copy of the License at + * + * https://creativecommons.org/licenses/by/4.0/ + * + * Unless required by applicable law or agreed to in writing, documentation + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ============LICENSE_END============================================ + * + * + */ + + @import '~@angular/material/prebuilt-themes/deeppurple-amber.css'; +table { + width: 100%; +} + +.mat-form-field { + font-size: 14px; + width: 100%; +} + +td, th { + width: 25%; +} +.mat-form-field[_ngcontent-c4] { + font-size: 14px; + width: 20%; + float: right; +} + +td[_ngcontent-c4], th[_ngcontent-c4] { + width: 15%; +} + +.example-h2 { + margin: 10px; +} + +.example-section { + display: flex; + align-content: center; + align-items: center; + height: 60px; +} + +.example-margin { + margin: 10px; +} +body { + font-family: Roboto, Arial, sans-serif; + margin: 0; +} + +.basic-container { + padding: 30px; +} + +.version-info { + font-size: 8pt; + float: right; +} + +.icon-trash{ + cursor: pointer; +} + +.new-role-button{ + margin-left: 15px; + float: right; +} +#functions-link{ + cursor: pointer; text-decoration: underline; color: #007bff; +} + +:host::ng-deep .mat-form-field-wrapper{ + width: 28%; + float: right; + padding-top: 14px; +} + +.table-search-div{ + display: flex; +} + +.new-role-button{ + height: 38px; +} + +:host::ng-deep .mat-header-cell{ + font-weight: bold; + font-size: 14px; + color: #343a40; +}
\ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/roles/roles.component.spec.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/roles/roles.component.spec.ts new file mode 100644 index 00000000..ab27b353 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/roles/roles.component.spec.ts @@ -0,0 +1,99 @@ +/* + * ============LICENSE_START========================================== + * ONAP Portal SDK + * =================================================================== + * Copyright © 2019 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * + * Modification Copyright © 2020 IBM. + * =================================================================== + * + * Unless otherwise specified, all software contained herein is licensed + * under the Apache License, Version 2.0 (the "License"); + * you may not use this software except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Unless otherwise specified, all documentation contained herein is licensed + * under the Creative Commons License, Attribution 4.0 Intl. (the "License"); + * you may not use this documentation except in compliance with the License. + * You may obtain a copy of the License at + * + * https://creativecommons.org/licenses/by/4.0/ + * + * Unless required by applicable law or agreed to in writing, documentation + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ============LICENSE_END============================================ + * + * + */ + +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { RolesComponent } from './roles.component'; +import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; +import { MatTableModule } from '@angular/material'; +import { HttpClientTestingModule } from '@angular/common/http/testing'; +import { Observable } from 'rxjs'; +import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; +import { BrowserDynamicTestingModule } from '@angular/platform-browser-dynamic/testing'; +import { RouterTestingModule } from '@angular/router/testing'; +import { UserService } from '../../shared/services/user/user.service'; +import { InformationModalComponent } from '../../modals/information-modal/information-modal.component'; + +describe('RolesComponent', () => { + let component: RolesComponent; + let fixture: ComponentFixture<RolesComponent>; + let userService: UserService; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + schemas: [CUSTOM_ELEMENTS_SCHEMA], + declarations: [ + RolesComponent, + InformationModalComponent, + ], + imports:[ + MatTableModule, + HttpClientTestingModule, + NgbModule.forRoot(), + RouterTestingModule + ] + }) + TestBed.overrideModule(BrowserDynamicTestingModule,{ + set:{ + entryComponents:[InformationModalComponent] + } + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(RolesComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + userService=TestBed.get(UserService); + }); + + it('should test subscribe inside ngOnInit method',()=>{ + let spy=spyOn(userService,'getFunctionalMenuStaticDetailSession').and.returnValue(Observable.of('your data')) + component.ngOnInit(); + expect(spy).toHaveBeenCalled(); + }) + + it('should test delRoleConfirmPopUp method',()=>{ + component.delRoleConfirmPopUp('dummyargument'); + + }) +}); diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/roles/roles.component.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/roles/roles.component.ts new file mode 100644 index 00000000..8032aa18 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/roles/roles.component.ts @@ -0,0 +1,216 @@ +/*- + * ============LICENSE_START========================================== + * ONAP Portal SDK + * =================================================================== + * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * + * Unless otherwise specified, all software contained herein is licensed + * under the Apache License, Version 2.0 (the "License"); + * you may not use this software except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Unless otherwise specified, all documentation contained herein is licensed + * under the Creative Commons License, Attribution 4.0 Intl. (the "License"); + * you may not use this documentation except in compliance with the License. + * You may obtain a copy of the License at + * + * https://creativecommons.org/licenses/by/4.0/ + * + * Unless required by applicable law or agreed to in writing, documentation + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ============LICENSE_END============================================ + * + * + */ +import { Component, OnInit, ViewChild } from '@angular/core'; +import { AdminService } from '../admin.service'; +import { MatTableDataSource } from '@angular/material/table'; +import { MatSort } from '@angular/material/sort'; +import { MatPaginator } from '@angular/material/paginator'; +import { User } from 'src/app/shared/services/user/user'; +import { UserService } from 'src/app/shared/services/user/user.service'; +import { NgbModal, ModalDismissReasons } from '@ng-bootstrap/ng-bootstrap'; +import { InformationModalComponent } from 'src/app/modals/information-modal/information-modal.component'; +import { NewRoleComponent } from './new-role/new-role.component'; +import { Router } from '@angular/router'; + + +@Component({ + selector: 'app-roles', + templateUrl: './roles.component.html', + styleUrls: ['./roles.component.scss'] +}) +export class RolesComponent implements OnInit { + tableData: Array<object> = []; + roleHeaders: Array<string> = []; + constructor(public adminService:AdminService,public userService: UserService,private ngbModal: NgbModal,private _router: Router) { } + roleId; + response:any; + result:any; + roleInfo:any; + roleData:any; + ociavailableRoleFunctions; + availableRoleFunctions; + availableRoles; + dataSource: MatTableDataSource<[]>; + user:User; + isAppCentralized; + closeResult: string; + isEditMode: boolean = false; + showSpinner:boolean; + + @ViewChild(MatPaginator, {}) paginator: MatPaginator; + @ViewChild(MatSort, {}) sort: MatSort; + + + ngOnInit() { + this.roleHeaders = ["name","priority","Edit","Active?","Delete?"]; + this.showSpinner = false; + this.roleId=undefined; + this.getRole(this.roleId); + let result = this.userService.getFunctionalMenuStaticDetailSession(); + let user; + result.subscribe(user => { + this.user = user; + this.isAppCentralized = this.user.isAppCentralized; + }); + } + + getRole(roleId:any){ + this.showSpinner = true; + this.response = this.adminService.getRole(roleId); + this.response.subscribe(data => { + this.result = data; + this.roleInfo = JSON.parse(this.result.data); + this.roleData =JSON.parse(this.roleInfo.role); + this.ociavailableRoleFunctions =JSON.parse(this.roleInfo.availableRoleFunctions); + this.availableRoleFunctions=[]; + for( let availableFun of this.ociavailableRoleFunctions){ + let availableRoleFunction = availableFun; + availableRoleFunction.selected = false; + for( let availableFunc of this.roleData.roleFunctions){ + if(availableFun.code === availableFunc.code){ + availableRoleFunction.selected = true; + } + } + this.availableRoleFunctions.push(availableRoleFunction); + } + this.availableRoles=JSON.parse(this.roleInfo.availableRoles); + this.dataSource = new MatTableDataSource(this.availableRoles); + this.dataSource.paginator = this.paginator; + this.dataSource.sort = this.sort; + this.showSpinner = false; + }); + } + + delRoleConfirmPopUp(item: any) { + const modalRef = this.ngbModal.open(InformationModalComponent); + modalRef.componentInstance.title = 'Confirmation'; + let response; + modalRef.componentInstance.message = `Are you sure you want to delete ${item.name} ?`; + modalRef.result.then((result) => { + if (result === 'Ok') { + this.adminService.deleteRole(item).subscribe(data => { + this.showSpinner = true; + response = data; + this.availableRoles = response.availableRoles; + this.dataSource = new MatTableDataSource(this.availableRoles); + this.dataSource.paginator = this.paginator; + this.dataSource.sort = this.sort; + this.showSpinner = false; + }) + } + }, (reason) => { + this.closeResult = `Dismissed ${this.getDismissReason(reason)}`; + }); + } + + private getDismissReason(reason: any): string { + if (reason === ModalDismissReasons.ESC) { + return 'by pressing ESC'; + } else if (reason === ModalDismissReasons.BACKDROP_CLICK) { + return 'by clicking on a backdrop'; + } else { + return `with: ${reason}`; + } + + } + + /** + * openAddNewRoleModal + * @param rowData + */ + openAddNewRoleModal(rowData: any){ + const modalRef = this.ngbModal.open(NewRoleComponent, { size: 'lg' }); + modalRef.componentInstance.title = 'Role Details'; + modalRef.componentInstance.availableRoles = this.availableRoles; + modalRef.componentInstance.ociavailableRoleFunctions = this.ociavailableRoleFunctions; + if(rowData != 'undefined' && rowData){ + modalRef.componentInstance.role = rowData; + this.isEditMode = true; + modalRef.componentInstance.isEditMode = true; + }else{ + modalRef.componentInstance.role = {}; + this.isEditMode = false; + modalRef.componentInstance.isEditMode = false; + } + modalRef.componentInstance.passEntry.subscribe((receivedEntry: any) => { + if(receivedEntry){ + this.availableRoles = []; + this.getRole(this.roleId); + } + }); + } + + toggleRole(_element) { + let activeOrInactive = (_element.active) ? 'activate' : 'inactivate'; + const modalInfoRef = this.ngbModal.open(InformationModalComponent); + modalInfoRef.componentInstance.title = 'Confirmation'; + modalInfoRef.componentInstance.message = 'You are about to ' + activeOrInactive + ' the role ' + _element.name + '. Do you want to continue?'; + modalInfoRef.result.then((_res) => { + if (_res === 'Ok') { + this.showSpinner = true; + let postData={ + role: _element, + childRoles: _element.childRoles, + roleFunctions : _element.roleFunctions + }; + this.adminService.saveRole(postData, _element.id) + .subscribe( _data => { + this.showSpinner = false; + }, (response) => { + _element.active = !_element.active; + const modalErrorRef = this.ngbModal.open(InformationModalComponent); + modalErrorRef.componentInstance.title = 'Error'; + modalErrorRef.componentInstance.message = 'Error while saving. ' + response.restCallStatus; + }); + } else { + _element.active = !_element.active; + } + + }, (result) => { + + }) + } + + applyFilter(filterValue: string) { + this.dataSource.filter = filterValue.trim().toLowerCase(); + } + + getFunctions() { + this._router.navigate(['v2/admin/role_function_list']); +} +}
\ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/roles/roles.module.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/roles/roles.module.ts new file mode 100644 index 00000000..5986e863 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/roles/roles.module.ts @@ -0,0 +1,19 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { RolesComponent } from './roles.component'; +import {NewRoleComponent} from './new-role/new-role.component'; +import {MatFormFieldModule, MatPaginatorModule, MatSlideToggleModule, MatTableModule} from '@angular/material'; +import {FormsModule} from '@angular/forms'; + +@NgModule({ + declarations: [RolesComponent, NewRoleComponent], + imports: [ + CommonModule, + MatTableModule, + MatFormFieldModule, + MatSlideToggleModule, + MatPaginatorModule, + FormsModule + ] +}) +export class RolesModule { } |