summaryrefslogtreecommitdiffstats
path: root/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/roles
diff options
context:
space:
mode:
Diffstat (limited to 'ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/roles')
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/roles/new-role/new-role.component.html106
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/roles/new-role/new-role.component.scss74
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/roles/new-role/new-role.component.spec.ts132
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/roles/new-role/new-role.component.ts250
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/roles/roles.component.html104
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/roles/roles.component.scss120
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/roles/roles.component.spec.ts99
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/roles/roles.component.ts216
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/roles/roles.module.ts19
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">&times;</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> &nbsp;
+ <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 { }