summaryrefslogtreecommitdiffstats
path: root/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin
diff options
context:
space:
mode:
Diffstat (limited to 'ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin')
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/admin-routing.module.ts30
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/admin.component.html1
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/admin.component.scss0
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/admin.component.spec.ts27
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/admin.component.ts13
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/admin.module.ts46
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/admin.service.spec.ts130
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/admin.service.ts124
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/cache-admin/cache-admin.component.html50
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/cache-admin/cache-admin.component.scss68
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/cache-admin/cache-admin.component.spec.ts73
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/cache-admin/cache-admin.component.ts65
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/menus/menus.component.html48
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/menus/menus.component.scss70
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/menus/menus.component.spec.ts74
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/menus/menus.component.ts203
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/menus/menus.module.ts56
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/menus/menus.service.ts198
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/menus/new-menu/new-menu.component.html137
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/menus/new-menu/new-menu.component.scss71
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/menus/new-menu/new-menu.component.spec.ts165
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/menus/new-menu/new-menu.component.ts267
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/role-functions/new-role-function/new-role-function.component.html101
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/role-functions/new-role-function/new-role-function.component.scss40
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/role-functions/new-role-function/new-role-function.component.spec.ts69
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/role-functions/new-role-function/new-role-function.component.ts174
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/role-functions/role-function.ts52
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/role-functions/role-functions.component.html48
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/role-functions/role-functions.component.scss63
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/role-functions/role-functions.component.spec.ts99
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/role-functions/role-functions.component.ts126
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/role-functions/role-functions.service.ts57
-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
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/usage/usage.component.html49
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/usage/usage.component.scss64
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/usage/usage.component.spec.ts70
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/usage/usage.component.ts82
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/usage/usage.module.ts51
46 files changed, 4181 insertions, 0 deletions
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/admin-routing.module.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/admin-routing.module.ts
new file mode 100644
index 00000000..87d01fa2
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/admin-routing.module.ts
@@ -0,0 +1,30 @@
+import {NgModule} from '@angular/core';
+import {RouterModule, Routes} from '@angular/router';
+import {RoleFunctionsComponent} from './role-functions/role-functions.component';
+import {UsageComponent} from './usage/usage.component';
+import {CacheAdminComponent} from './cache-admin/cache-admin.component';
+import {RolesComponent} from './roles/roles.component';
+import {MenusComponent} from './menus/menus.component';
+import {AdminComponent} from './admin.component';
+
+const routes: Routes = [
+ {
+ path: '',
+ component: AdminComponent,
+ children: [
+ {path: 'role_function_list', component: RoleFunctionsComponent},
+ {path: 'usage_list', component: UsageComponent},
+ {path: 'cache_admin', component: CacheAdminComponent},
+ {path: 'admin', component: RolesComponent},
+ {path: 'admin_menu_edit', component: MenusComponent},
+ ]
+ }
+];
+
+@NgModule({
+ imports: [RouterModule.forChild(routes)],
+ exports: [RouterModule]
+})
+export class AdminRouting {
+
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/admin.component.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/admin.component.html
new file mode 100644
index 00000000..0680b43f
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/admin.component.html
@@ -0,0 +1 @@
+<router-outlet></router-outlet>
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/admin.component.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/admin.component.scss
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/admin.component.scss
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/admin.component.spec.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/admin.component.spec.ts
new file mode 100644
index 00000000..e93ac925
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/admin.component.spec.ts
@@ -0,0 +1,27 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { AdminComponent } from './admin.component';
+import { RouterTestingModule } from '@angular/router/testing';
+
+describe('AdminComponent', () => {
+ let component: AdminComponent;
+ let fixture: ComponentFixture<AdminComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ AdminComponent ],
+ imports: [ RouterTestingModule ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(AdminComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/admin.component.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/admin.component.ts
new file mode 100644
index 00000000..ad5498c6
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/admin.component.ts
@@ -0,0 +1,13 @@
+import { Component, OnInit } from '@angular/core';
+
+@Component({
+ selector: 'app-admin',
+ templateUrl: './admin.component.html',
+ styleUrls: ['./admin.component.scss']
+})
+export class AdminComponent implements OnInit {
+ constructor() { }
+ ngOnInit() {
+ }
+
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/admin.module.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/admin.module.ts
new file mode 100644
index 00000000..ba546647
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/admin.module.ts
@@ -0,0 +1,46 @@
+import { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { AdminComponent } from './admin.component';
+import {CacheAdminComponent} from './cache-admin/cache-admin.component';
+import {MenusModule} from './menus/menus.module';
+import {UsageModule} from './usage/usage.module';
+import {FormsModule} from '@angular/forms';
+import {
+ MatExpansionModule,
+ MatFormFieldModule,
+ MatPaginatorModule,
+ MatRadioModule,
+ MatSlideToggleModule,
+ MatTableModule,
+ MatInputModule
+} from '@angular/material';
+import {RdpModule} from 'portalsdk-tag-lib';
+import {AdminRouting} from './admin-routing.module';
+import {RoleFunctionsComponent} from './role-functions/role-functions.component';
+import {RolesComponent} from './roles/roles.component';
+import {NewRoleComponent} from './roles/new-role/new-role.component'
+import { UserService } from '../shared/services/user/user.service';
+
+@NgModule({
+ declarations: [AdminComponent, CacheAdminComponent, RoleFunctionsComponent, RolesComponent, NewRoleComponent],
+ imports: [
+ CommonModule,
+ MenusModule,
+ UsageModule,
+ FormsModule,
+ MatRadioModule,
+ RdpModule,
+ AdminRouting,
+ MatExpansionModule,
+ MatFormFieldModule,
+ MatTableModule,
+ MatSlideToggleModule,
+ MatPaginatorModule,
+ MatInputModule
+ ],
+ entryComponents: [NewRoleComponent],
+ exports: [
+ ],
+ providers: [UserService]
+})
+export class AdminModule { }
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/admin.service.spec.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/admin.service.spec.ts
new file mode 100644
index 00000000..d23489be
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/admin.service.spec.ts
@@ -0,0 +1,130 @@
+import { TestBed, async } from '@angular/core/testing';
+import { AdminService } from './admin.service';
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { environment } from 'src/environments/environment';
+
+describe('AdminService', () => {
+
+ let service:AdminService;
+
+ beforeEach(() =>{
+ TestBed.configureTestingModule({
+ imports:[HttpClientTestingModule],
+ providers: [AdminService]
+ })
+ service = TestBed.get(AdminService);
+ });
+
+ it('should be created', () => {
+ const service: AdminService = TestBed.get(AdminService);
+ expect(service).toBeTruthy();
+ });
+
+ it('should get getUserPagination', () => {
+ service.getRoleFunctionList().subscribe((resp) => {
+ expect(resp).toBe(environment.roleFunctionList);
+ });
+ })
+
+ it('should test saveRoleFunction',()=>{
+ service.saveRoleFunction("roleData").subscribe((resp)=>{
+ expect(resp).toBe(environment.addRoleFunction);
+ })
+ })
+
+ it('should test getUsageList',()=>{
+ service.getUsageList().subscribe((resp) => {
+ expect(resp).toBe(environment.usageList);
+ })
+ })
+
+ it('should test getCacheRegions',()=>{
+ service.getCacheRegions().subscribe((resp) => {
+ expect(resp).toBe(environment.cachedRegions);
+ })
+ })
+
+ it('should test getRole',()=>{
+ service.getRole(1).subscribe((resp) => {
+ expect(resp).toBe(environment.cachedRegions);
+ })
+ })
+
+ it('should test getRole',()=>{
+ service.getRole(1).subscribe((resp) => {
+ expect(resp).toBe(environment.getRole);
+ })
+ })
+
+ it('should test getFnMenuItems',()=>{
+ service.getFnMenuItems().subscribe((resp) => {
+ expect(resp).toBe(environment.getFnMenuItems);
+ })
+ })
+
+ it('should test updateFnMenuItem',()=>{
+ let menuObj: any
+ service.updateFnMenuItem(menuObj).subscribe((resp) => {
+ expect(resp).toBe(environment.updateFnMenuItem);
+ })
+ })
+
+ it('should test getFunctionCdList',()=>{
+ service.getFunctionCdList().subscribe((resp) => {
+ expect(resp).toBe(environment.getFunctionCdList);
+ })
+ })
+
+
+ it('should test getParentData',()=>{
+ service.getParentData().subscribe((resp) => {
+ expect(resp).toBe(environment.getParentList);
+ })
+ })
+
+ it('should test deleteRole',()=>{
+ let roleData: any
+ service.deleteRole(roleData).subscribe((resp) => {
+ expect(resp).toBe(environment.deleteRole);
+ })
+ })
+
+ it('should test deleteRoleFunction',()=>{
+ let roleData: any
+ service.deleteRoleFunction(roleData).subscribe((resp) => {
+ expect(resp).toBe(environment.deleteRoleFunction);
+ })
+ })
+
+ it('should test removeRoleFunction',()=>{
+ let roleFunc:any;
+ let roleId:any;
+ service.removeRoleFunction(roleFunc,roleId).subscribe((resp) => {
+ expect(resp).toBe(environment.removeRoleFunction+roleId);
+ })
+ })
+
+ it('should test saveRole',()=>{
+ let roleObj:any;
+ let roleId:any;
+ service.saveRole(roleObj,roleId).subscribe((resp) => {
+ expect(resp).toBe(environment.saveRole+roleId);
+ })
+ })
+
+ it('should test deleteMenu',()=>{
+ let fnMenuItem: any
+ service.deleteMenu(fnMenuItem).subscribe((resp) => {
+ expect(resp).toBe(environment.deleteMenu);
+ })
+ })
+
+
+ it('should test getCacheRegionDetails',()=>{
+ let cacheName:any
+ service.getCacheRegionDetails(cacheName).subscribe((resp) => {
+ expect(resp).toBe(environment.getRegion);
+ })
+ })
+
+});
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/admin.service.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/admin.service.ts
new file mode 100644
index 00000000..2a7135ad
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/admin.service.ts
@@ -0,0 +1,124 @@
+/*
+ * ============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 { Injectable } from '@angular/core';
+import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http';
+import { JsonPipe } from '@angular/common';
+import { environment } from '../../environments/environment';
+import { Observable } from 'rxjs';
+
+@Injectable({
+ providedIn: 'root'
+})
+
+export class AdminService {
+
+ constructor(private http:HttpClient) { }
+
+ getRoleFunctionList(){
+ return this.http.get(environment.roleFunctionList);
+ }
+
+ saveRoleFunction(roleData:string){
+ return this.http.post(environment.addRoleFunction,roleData);
+ }
+
+ getUsageList()
+ {
+ return this.http.get(environment.usageList);
+
+ }
+
+ getCacheRegions(){
+ return this.http.get(environment.cachedRegions);
+
+ }
+
+ getRole(roleId){
+ return this.http.get(environment.getRole+'?role_id=' + roleId);
+
+ }
+ getFnMenuItems()
+ {
+ return this.http.get(environment.getFnMenuItems);
+ }
+
+ updateFnMenuItem(menuObj: any): Observable<any> {
+ let updateMenuURL = environment.updateFnMenuItem;
+ return this.http.post(updateMenuURL, menuObj)
+ }
+
+ getFunctionCdList(): Observable<any>{
+ let getFunctionCdListURL = environment.getFunctionCdList;
+ return this.http.get(getFunctionCdListURL);
+ }
+
+ getParentData(): Observable<any>{
+ let getParentDataURL = environment.getParentList;
+ return this.http.get(getParentDataURL);
+ }
+
+ deleteRole(roleData:any){
+ return this.http.post(environment.deleteRole,JSON.stringify({role: roleData}));
+ }
+
+ deleteRoleFunction(roleFunc:any)
+ {
+ return this.http.post(environment.deleteRoleFunction,roleFunc);
+
+ }
+
+ removeRoleFunction(roleFunc:any, roleId:any){
+ let removeRoleFunctionURL = environment.removeRoleFunction+roleId;
+ return this.http.post(removeRoleFunctionURL,JSON.stringify({roleFunction:roleFunc}));
+ }
+
+ saveRole(roleObj:any, roleId:any){
+ let saveRoleURL = environment.saveRole+roleId;
+ return this.http.post(saveRoleURL,JSON.stringify(roleObj));
+ }
+
+ deleteMenu(fnMenuItem:any){
+ return this.http.post(environment.deleteMenu,JSON.stringify({fnMenuItem: fnMenuItem}));
+ }
+
+ getCacheRegionDetails(cacheName:any){
+ return this.http.get(environment.getRegion+'?cacheName='+cacheName);
+
+ }
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/cache-admin/cache-admin.component.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/cache-admin/cache-admin.component.html
new file mode 100644
index 00000000..8aba64c9
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/cache-admin/cache-admin.component.html
@@ -0,0 +1,50 @@
+<div id="page-content" style=" width: 100%">
+
+ <div>
+ <h1 class="heading-page" id="CacheRegions">Cache Regions</h1>
+ </div>
+
+ <div style="margin-right:20px; text-align:justify; text-align-last:auto;">
+ <p>
+ These are the regions which are currently defined in the cache. 'Items' and 'Bytes' refer to the elements currently in memory (not spooled).
+ You can clear all items for a region by clicking on the Clear icon next to the desired region below. You can also <a href="admin#/jcs_admin" ng-click="clearAllFuncPopUp();">clear all regions</a>
+ which empties the entire cache.</p>
+ </div>
+
+
+
+ <mat-accordion displayMode="flat" multi class="mat-table">
+ <section matSort class="mat-header-row">
+ <span class="mat-header-cell" >Cache Name</span>
+ <span class="mat-header-cell" ># of Items</span>
+ <span class="mat-header-cell" >Bytes</span>
+ <span class="mat-header-cell" >Status</span>
+ <span class="mat-header-cell" >Memory Hits</span>
+ <span class="mat-header-cell">Aux Hits</span>
+ <span class="mat-header-cell" >Not Expired MissesFound Misses</span>
+ <span class="mat-header-cell" >Expired Misses</span>
+ <span class="mat-header-cell" >Clear?</span>
+ <span class="mat-header-cell" >Items</span>
+
+ </section>
+
+ <mat-expansion-panel *ngFor="let item of regions">
+ <mat-expansion-panel-header >
+ <span class="mat-cell"><a href="javascript:;" (click)="showRegionDetails(item.cacheName)">{{item.cacheName}}</a></span>
+ <span class="mat-cell">{{item.byteCount}}</span>
+ <span class="mat-cell">{{item.status}}</span>
+ <span class="mat-cell">{{item.hitCountRam}}</span>
+ <span class="mat-cell">{{item.hitCountAux}}</span>
+ <span class="mat-cell">{{item.missCountNotFound}}</span>
+ <span class="mat-cell">{{item.missCountExpired}}</span>
+ <span class="mat-cell">{{item.hitCountRam}}</span>
+ <span class="mat-cell">clear</span>
+ <span class="mat-cell">delete</span>
+
+ </mat-expansion-panel-header>
+ <div><pre>{{item.items | json }}</pre></div>
+ </mat-expansion-panel>
+
+ </mat-accordion>
+
+ \ No newline at end of file
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/cache-admin/cache-admin.component.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/cache-admin/cache-admin.component.scss
new file mode 100644
index 00000000..39ba7164
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/cache-admin/cache-admin.component.scss
@@ -0,0 +1,68 @@
+table {
+ width: 100%;
+}
+
+.mat-form-field {
+ font-size: 14px;
+ width: 100%;
+}
+
+td, th {
+ width: 25%;
+}
+
+
+.mat-accordion .mat-header-row {
+ padding-left: 1.5rem;
+ padding-right: 2rem;
+ border-bottom: none;
+}
+
+
+//copied from https://github.com/angular/material2/blob/master/src/lib/table/table.scss
+$mat-header-row-height: 56px;
+$mat-row-height: 48px;
+$mat-row-horizontal-padding: 24px;
+
+
+.mat-header-row {
+ min-height: $mat-header-row-height;
+}
+
+.mat-row {
+ min-height: $mat-row-height;
+}
+
+.mat-row, .mat-header-row {
+ display: flex;
+ border-bottom-width: 1px;
+ border-bottom-style: solid;
+ align-items: center;
+ padding: 0 $mat-row-horizontal-padding;
+ box-sizing: border-box;
+
+ // Workaround for https://goo.gl/pFmjJD in IE 11. Adds a pseudo
+ // element that will stretch the row the correct height. See:
+ // https://connect.microsoft.com/IE/feedback/details/802625
+ &::after {
+ display: inline-block;
+ min-height: inherit;
+ content: '';
+ }
+}
+
+:host::ng-deep .mat-cell, .mat-header-cell {
+ flex: 1;
+ overflow: hidden;
+ word-wrap: break-word;
+ font-weight: bold;
+ font-size: 14px;
+ color: #343a40;
+}
+
+.mat-expansion-panel {
+ margin: 0;
+ border-radius: 4px;
+ overflow: hidden;
+ transition: margin 225ms cubic-bezier(.4,0,.2,1),box-shadow 280ms cubic-bezier(.4,0,.2,1);
+} \ No newline at end of file
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/cache-admin/cache-admin.component.spec.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/cache-admin/cache-admin.component.spec.ts
new file mode 100644
index 00000000..01ec7a92
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/cache-admin/cache-admin.component.spec.ts
@@ -0,0 +1,73 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
+import { CacheAdminComponent } from './cache-admin.component';
+import { MatExpansionModule } from '@angular/material';
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { AdminService } from '../admin.service';
+import { Observable } from 'rxjs/Observable';
+import 'rxjs/add/observable/of';
+import { CookieService } from 'ngx-cookie-service';
+import { BrowserDynamicTestingModule } from '@angular/platform-browser-dynamic/testing';
+import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
+import { SuccessModalComponent } from '../../modals/success-modal/success-modal.component';
+
+
+describe('CacheAdminComponent', () => {
+ let component: CacheAdminComponent;
+ let fixture: ComponentFixture<CacheAdminComponent>;
+ let adminService:AdminService;
+
+ var stubData1={"data":'{"data":"cachedRegions"}'};
+ var stubData2={"data":"stubData2"};
+
+ beforeEach(async(() => {
+
+ TestBed.configureTestingModule({
+ declarations: [
+ CacheAdminComponent,
+ SuccessModalComponent,
+ ],
+ schemas: [CUSTOM_ELEMENTS_SCHEMA],
+ imports:[
+ MatExpansionModule,
+ HttpClientTestingModule,
+ NgbModule.forRoot()
+ ],
+ providers:[CookieService,AdminService],
+ })
+ TestBed.overrideModule(BrowserDynamicTestingModule,{
+ set:{
+ entryComponents:[SuccessModalComponent]
+ }
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(CacheAdminComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ adminService=TestBed.get(AdminService);
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+
+ describe('it should test ngOnInit method',()=>{
+ it('should test ngOnInit',()=>{
+ let spy=spyOn(adminService,'getCacheRegions').and.returnValue(Observable.of(stubData1));
+ component.ngOnInit();
+ expect(spy).toHaveBeenCalled();
+ })
+ })
+
+ it('it should test showRegionDetails method',()=>{
+ let spy=spyOn(adminService,'getCacheRegionDetails').and.returnValue(Observable.of(stubData2));
+ component.showRegionDetails("string");
+ expect(spy).toHaveBeenCalled();
+ })
+
+});
+
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/cache-admin/cache-admin.component.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/cache-admin/cache-admin.component.ts
new file mode 100644
index 00000000..d9f5ca80
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/cache-admin/cache-admin.component.ts
@@ -0,0 +1,65 @@
+import {Component, OnInit, ViewChild} from '@angular/core';
+import { AdminService } from '../admin.service';
+import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
+import { SuccessModalComponent } from 'src/app/modals/success-modal/success-modal.component';
+
+
+@Component({
+ selector: 'app-cache-admin',
+ templateUrl: './cache-admin.component.html',
+ styleUrls: ['./cache-admin.component.scss']
+})
+export class CacheAdminComponent implements OnInit {
+
+ constructor(public adminService:AdminService,private ngModal: NgbModal) {
+
+ }
+
+ response: any;
+ regions:any;
+ message;any;
+
+ ngOnInit() {
+
+ let result = this.adminService.getCacheRegions();
+ result.subscribe(data => {
+ this.response = data;
+ this.regions = JSON.parse(this.response.data);
+ });
+
+ }
+
+
+ showRegionDetails(item: any) {
+ let response;
+
+ this.adminService.getCacheRegionDetails(item).subscribe(data => {
+ response = data;
+
+
+ let message = response.data;
+ let msgParsed = JSON.stringify(message);
+
+
+
+ if(message!=null && message!=''){
+ var status = response.status;
+ var htmlstring = message.toString();
+ var htmlStrReplace = htmlstring.replace(/['"]+/g, '');
+ var htmlStrReplaceSplit = htmlStrReplace.split('\n');
+ var dataStr = htmlStrReplace.replace(/\\n/g, "\n");
+ this.message = dataStr;
+
+ }
+
+
+
+ });
+ const modalRef = this.ngModal.open(SuccessModalComponent);
+ modalRef.componentInstance.message = this.message;
+
+
+ }
+
+}
+
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/menus/menus.component.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/menus/menus.component.html
new file mode 100644
index 00000000..25ae9665
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/menus/menus.component.html
@@ -0,0 +1,48 @@
+<!--
+ ============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">Admin Menu Items</h3>
+ </div>
+ <div ng-show="showLoader" class="span loader-container">
+ <i class="icon-primary-spinner" role="img" aria-label="Please wait while we load your content"></i>
+ </div>
+ <span class="ecomp-spinner" *ngIf="showSpinner"></span>
+ <rdp-data-table [data]="tableData" [settings]="settings"></rdp-data-table>
+ </div>
+</div> \ No newline at end of file
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/menus/menus.component.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/menus/menus.component.scss
new file mode 100644
index 00000000..4e88eeb8
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/menus/menus.component.scss
@@ -0,0 +1,70 @@
+/*
+ * ============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============================================
+ *
+ *
+ */
+
+ table {
+ width: 100%;
+}
+
+.mat-form-field {
+ font-size: 14px;
+ width: 100%;
+}
+
+td, th {
+ width: 25%;
+}
+
+td[_ngcontent-c4], th[_ngcontent-c4] {
+ width: 7%;
+}
+
+::ng-deep .mat-form-field[_ngcontent-c4][_ngcontent-c4] {
+ font-size: 14px;
+ width: 20%;
+ float: left;
+}
+
+rdp-data-table{
+ overflow-x : scroll;
+}
+
+: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/menus/menus.component.spec.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/menus/menus.component.spec.ts
new file mode 100644
index 00000000..49fee828
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/menus/menus.component.spec.ts
@@ -0,0 +1,74 @@
+import { async, ComponentFixture, TestBed, inject } from '@angular/core/testing';
+import { MatTableModule } from '@angular/material/table';
+import { MatPaginatorModule } from '@angular/material/paginator';
+import { MatSortModule } from '@angular/material/sort';
+import { NoopAnimationsModule } from '@angular/platform-browser/animations';
+import { BrowserDynamicTestingModule } from '@angular/platform-browser-dynamic/testing';
+import { NgbModule, NgbModal } from '@ng-bootstrap/ng-bootstrap';
+
+import { MenusComponent } from './menus.component';
+import { AdminService } from '../admin.service';
+import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { MenusService } from './menus.service';
+import { CookieService } from 'ngx-cookie-service';
+import { MockBackend } from '@angular/http/testing';
+import { BaseRequestOptions, Http } from '@angular/http';
+import 'rxjs/add/observable/of';
+import { Observable } from 'rxjs/Observable';
+import { InformationModalComponent } from '../../modals/information-modal/information-modal.component';
+
+describe('MenusComponent', () => {
+ let component: MenusComponent;
+ let fixture: ComponentFixture<MenusComponent>;
+ let modalService: any;
+ let adminService:any;
+ var stubData={"data":'{"fnMenuItems":{"tableData":{"element":{"active":1}}}}'};
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ schemas:[CUSTOM_ELEMENTS_SCHEMA],
+ declarations: [ MenusComponent,
+ InformationModalComponent ],
+ imports: [ MatTableModule,
+ MatPaginatorModule,
+ MatSortModule,
+ HttpClientTestingModule,
+ NoopAnimationsModule,
+ NgbModule.forRoot()
+ ],
+ providers:[MenusService,CookieService]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(async() => {
+ fixture = TestBed.createComponent(MenusComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ modalService = TestBed.get(NgbModal);
+ adminService=TestBed.get(AdminService);
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ describe('test getMenus',()=>{
+ it('should test getMenus',()=>{
+ let spy=spyOn(adminService,'getParentData').and.returnValue(Observable.of('you object'))
+ component.getParentData();
+ expect(spy).toHaveBeenCalled();
+ })
+ })
+
+ describe('testing getFunctionCDselectData',()=>{
+ it('should test getFunctionCDselectData',()=>{
+ let spy=spyOn(adminService,'getFunctionCdList').and.returnValue(Observable.of(1,1));
+ component.getFunctionCDselectData();
+ expect(spy).toHaveBeenCalled();
+ })
+ })
+
+
+});
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/menus/menus.component.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/menus/menus.component.ts
new file mode 100644
index 00000000..c6fbc8c4
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/menus/menus.component.ts
@@ -0,0 +1,203 @@
+/*
+ * ============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 { Component, OnInit, ViewChild } from '@angular/core';
+import { MatTableDataSource } from '@angular/material/table';
+import { MatPaginator } from '@angular/material/paginator';
+import { MatSort } from '@angular/material/sort';
+import { AdminService } from '../admin.service';
+import { NgbModal, ModalDismissReasons, NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
+import { InformationModalComponent } from 'src/app/modals/information-modal/information-modal.component';
+import { NewMenuComponent } from './new-menu/new-menu.component';
+import { Column, DataTableSettings, RdpCrudInterface , ColumnTypes} from 'portalsdk-tag-lib';
+import { element } from '@angular/core/src/render3';
+import { MenusService } from './menus.service';
+
+@Component({
+ selector: 'app-menus',
+ templateUrl: './menus.component.html',
+ styleUrls: ['./menus.component.scss']
+})
+export class MenusComponent implements OnInit {
+
+ constructor(public adminService: AdminService, private ngModal: NgbModal, public menuService : MenusService) { }
+
+ // menuHeaders = ["menuId", "label", "paretId", "sortOrder", "action", "functionCd", "active", "servlet", "queryString", "externalUrl", "target", "menuSetCode", "separator", "imageSrc", "Edit", "Delete"];
+
+ response: any;
+ result: any;
+ functionalMenuRes: any;
+ tableData;
+ dataSource: MatTableDataSource<[]>;
+ closeResult: string;
+ isEditMode: boolean;
+ showSpinner: boolean;
+
+ public settings;
+ public columns: any = [];
+
+ activeStatusOptions = [
+ {id: '0', name: 'Y'},
+ {id: '1', name: 'N'}
+ ];
+ separatorStatusOptions = [
+ {id: '0', name: 'Y'},
+ {id: '1', name: 'N'}
+ ];
+ functionCDselectData = [];
+ parentListSelectData = [];
+ parentList = [];
+
+ @ViewChild(MatPaginator, {}) paginator: MatPaginator;
+ @ViewChild(MatSort, {}) sort: MatSort;
+
+ ngOnInit() {
+ this.showSpinner = false;
+ this.getParentData();
+ this.getFunctionCDselectData();
+ this.getMenus();
+ }
+
+ getMenus() {
+ console.log(">>>>>>>>>>>>>>> GetMenus calles >>>>>>>>>>>>>>")
+ this.showSpinner = true;
+ let response;
+ this.response = this.adminService.getFnMenuItems();
+ this.response.subscribe(data => {
+ response = data;
+
+ this.functionalMenuRes = JSON.parse(response.data);
+ this.tableData = this.functionalMenuRes.fnMenuItems;
+ this.tableData.forEach(element => {
+ if (element.active) { element.active = "Y"; }
+ else { element.active = "N"; }
+ if (element.separator) { element.separator = "Y"; }
+ else { element.separator = "N"; }
+ });
+
+ //rdp table data
+ let menuIdColumn = new Column("id", "Menu ID", ColumnTypes.TEXT, true, null);
+ menuIdColumn.isColumnDisabled = true;
+ this.columns.push(menuIdColumn);
+
+ let label = new Column("label", "Label", ColumnTypes.TEXT, true, null);
+ label.setIsColumnMandatory = true;
+ this.columns.push(label);
+
+ let parent = new Column("parentId", "ParentId", ColumnTypes.DROPDOWN, true, this.parentList);
+ parent.setIsColumnMandatory = true;
+ this.columns.push(parent);
+
+ let sortOrder = new Column("sortOrder", "Sort Order", ColumnTypes.TEXT, true, null);
+ sortOrder.setIsColumnMandatory = true;
+ this.columns.push(sortOrder);
+
+ let action = new Column("action", "Action", ColumnTypes.TEXT, true, null);
+ action.setIsColumnMandatory = true;
+ this.columns.push(action);
+
+ let functionCd = new Column("functionCd", "Function", ColumnTypes.DROPDOWN, true, this.functionCDselectData);
+ functionCd.setIsColumnMandatory = true;
+ this.columns.push(functionCd);
+
+ let active = new Column("active", "Active", ColumnTypes.DROPDOWN, true, this.activeStatusOptions);
+ active.setIsColumnMandatory = true;
+ this.columns.push(active);
+
+ this.columns.push(new Column("servlet", "Servlet", ColumnTypes.TEXT, true, null));
+ this.columns.push(new Column("queryString", " Query String", ColumnTypes.TEXT, true, null));
+ this.columns.push(new Column("externalUrl", "External URL", ColumnTypes.TEXT, true, null));
+ this.columns.push(new Column("target", "Target", ColumnTypes.TEXT, true, null));
+
+ let menuSetCode = new Column("menuSetCode", "Menu Set Code", ColumnTypes.TEXT, false, null);
+ menuSetCode.setIsColumnMandatory = true;
+ this.columns.push(menuSetCode);
+
+ let separator = new Column("separator", "Separator", ColumnTypes.DROPDOWN, false, this.separatorStatusOptions);
+ separator.setIsColumnMandatory = true;
+ this.columns.push(separator);
+ this.columns.push(new Column("imageSrc", "Image Source", ColumnTypes.TEXT, true, null));
+
+ this.settings = new DataTableSettings()
+ this.settings.columns = this.columns;
+ this.settings.isPaginationEnabled = true;
+ this.settings.paginationsSize = "5";
+ this.settings.isReadOnly = false;
+ this.settings.isTableSearchEnabled = true;
+ this.settings.applicationService = this.menuService;
+
+ this.showSpinner = false;
+
+ });
+ }
+
+ getFunctionCDselectData = function () {
+ this.adminService.getFunctionCdList()
+ .subscribe(_data => {
+ this.result = _data;
+ if (_data) {
+
+ for(let i = 0; i< _data.length; i++){
+ this.functionCDselectData.push({id: i, name: _data[i]});
+ }
+ }
+ }, error => {
+ this.showSpinner = false;
+ console.log(error);
+ this.openConfirmationModal("", "Function Code Data not available !");
+ });
+ }
+
+ getParentData() {
+ this.adminService.getParentData()
+ .subscribe(_data => {
+ this.result = _data;
+ if (_data) {
+ for(let i = 0; i< _data.length; i++){
+ this.parentList.push({id: _data[i][0], name: _data[i][1]});
+ }
+ console.log("Actual parent list : ", this.parentList);
+ this.menuService.getParentList(this.parentList);
+ }
+ }, error => {
+ this.showSpinner = false;
+ console.log(error);
+ });
+ }
+
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/menus/menus.module.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/menus/menus.module.ts
new file mode 100644
index 00000000..99268e9f
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/menus/menus.module.ts
@@ -0,0 +1,56 @@
+/*
+ * ============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 { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { MenusComponent } from './menus.component';
+import { MaterialModule } from 'src/app/material-module';
+import { FormsModule, ReactiveFormsModule } from '@angular/forms';
+import { MatFormFieldModule } from '@angular/material/form-field';
+import { NewMenuComponent } from './new-menu/new-menu.component';
+import {RdpModule} from 'portalsdk-tag-lib';
+
+@NgModule({
+ declarations: [MenusComponent, NewMenuComponent],
+ imports: [
+ CommonModule, FormsModule, ReactiveFormsModule, MatFormFieldModule, RdpModule
+ ],
+ exports: [MenusComponent],
+ bootstrap: [MenusComponent]
+})
+export class MenusModule { }
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/menus/menus.service.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/menus/menus.service.ts
new file mode 100644
index 00000000..912b65bb
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/menus/menus.service.ts
@@ -0,0 +1,198 @@
+
+/*
+ * ============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 { Injectable } from '@angular/core';
+import { HttpClient } from '@angular/common/http';
+import { RdpCrudInterface } from 'portalsdk-tag-lib';
+import { environment } from 'src/environments/environment';
+import { AdminService } from '../admin.service';
+import { BehaviorSubject } from 'rxjs';
+
+@Injectable({
+ providedIn: 'root'
+})
+export class MenusService implements RdpCrudInterface {
+
+ public statusResponse = new BehaviorSubject("");
+ public updatedData = new BehaviorSubject<any>({});
+
+ loadTableData(filter: any, sortActive: any, sortDirection: any, pageIndex: any, pageSize: any): import("rxjs").Observable<any[]> {
+ throw new Error("Method not implemented.");
+ }
+ getTotalRowCount() {
+ throw new Error("Method not implemented.");
+ }
+
+ parentDataList: any;
+ constructor(private http: HttpClient, private adminService: AdminService) {
+
+ }
+
+
+ menu = {
+ action: null,
+ active: false,
+ activeAsString: "false",
+ auditTrail: null,
+ auditUserId: null,
+ childMenus: [],
+ created: null,
+ createdId: null,
+ externalUrl: null,
+ functionCd: null,
+ id: null,
+ imageSrc: null,
+ label: null,
+ menuLevel: null,
+ menuSetCode: null,
+ modified: null,
+ modifiedId: null,
+ parentId: null,
+ parentIdAsString: null,
+ parentMenu: null,
+ queryString: null,
+ rowNum: null,
+ separator: false,
+ separatorAsString: false,
+ servlet: null,
+ sortOrder: null,
+ target: null
+ };
+
+ add(data: any) {
+ console.log("Add method is getting called from AppServie data:: ", data);
+ }
+
+
+ update(data: any) {
+ data.active = this.updateStatus(data.active);
+ data.separator = this.updateStatus(data.separator);
+ let keys = Object.keys(data);
+ let menuCache = this.menu;
+ keys.forEach(element => {
+ if (data[element] != null || data[element] != undefined) {
+ if (element == 'parentId') {
+ if (isNaN(data[element])) {
+ menuCache[element] = this.updateParentNameToID(data[element]);
+ } else{
+ menuCache[element] = data[element];
+ }
+ console.log("Parent Id to update : ", menuCache[element]);
+ } else {
+ menuCache[element] = data[element];
+ }
+ }
+ });
+ let result = { availableFnMenuItem: menuCache };
+ let postData = JSON.stringify(result);
+ console.log("postData >>>>>>", postData);
+ this.adminService.updateFnMenuItem(postData)
+ .subscribe(_data => {
+ console.log("Response : ", _data);
+ this.statusResponse.next("200");
+ menuCache = this.menu;
+ }, error => {
+ console.log("Error : ", error);
+ menuCache = this.menu;
+ });
+
+ }
+
+ delete(data: any) {
+ console.log("Delete method is getting called from AppServie data::>> " + JSON.stringify(data));
+ console.log(data.active);
+ data.active = this.updateStatus(data.active);
+ data.separator = this.updateStatus(data.separator);
+ this.adminService.deleteMenu(data).subscribe(response => {
+ console.log("Response ", response);
+ this.statusResponse.next("200");
+ }, error => {
+ console.log("Error : ", error);
+ })
+ }
+
+ private updateStatus(data) {
+ if (data == 'N') {
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ private updateBooleanValue(data) {
+ if (data) {
+ return 'Y';
+ } else {
+ return 'N';
+ }
+ }
+
+ parentList: any;
+
+ getParentList(list) {
+ this.parentList = list;
+ }
+
+ private updateParentNameToID(data) {
+ let val;
+ this.parentList.forEach(ele => {
+ if (ele['name'] == data) {
+ val = ele['id'];
+ }
+ });
+ console.log("ParentId value ", val);
+ return val;
+ }
+
+ get() {
+ console.log("get method is getting called from MenuServie data:: ");
+ let response = this.adminService.getFnMenuItems();
+ let resp;
+ response.subscribe(res => {
+ resp = res;
+ let responseData = JSON.parse(resp.data).fnMenuItems;
+ responseData.forEach(element => {
+ element.active = this.updateBooleanValue(element.active);
+ element.separator = this.updateBooleanValue(element.separator);
+ })
+ this.updatedData.next(responseData);
+ })
+ }
+
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/menus/new-menu/new-menu.component.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/menus/new-menu/new-menu.component.html
new file mode 100644
index 00000000..6a5426a8
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/menus/new-menu/new-menu.component.html
@@ -0,0 +1,137 @@
+<!--
+ ============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">{{(isEditMode) ? 'Edit Menu Item' : 'Add New Menu Item'}}</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">
+ <div class="elementsContainer">
+ <div class="groupItem">
+ <label class="item-label">*Label:</label><br>
+ <input [(ngModel)]="menu.label" type="text" name="label" id="label">
+ </div>
+ <div class="groupItem">
+ <label class="item-label">*Parent:</label><br>
+ <!-- <input [(ngModel)]="menu.parentId" type="text" name="parentId" id="parent"> -->
+ <select class="form-field" name="parentSelect" id="parentSelect" [(ngModel)]="menu.parentId">
+ <option>{{getParentLabel(menu.parentId, parentListSelectData)}}</option>
+ <option *ngFor="let option of parentListSelectData" value="{{option[0]}}">{{option[1]}}</option>
+ </select>
+ </div>
+ <div class="groupItem">
+ <label class="item-label">*Sort Order</label><br>
+ <input [(ngModel)]="menu.sortOrder" type="text" name="sortOrder" id="sortOrder">
+ </div>
+ <div class="groupItem">
+ <label class="item-label">*Action</label><br>
+ <input [(ngModel)]="menu.action" type="text" name="action" id="action">
+ </div>
+ </div>
+
+ <br>
+
+ <div class="elementsContainer">
+ <div class="groupItem">
+ <label class="item-label"><b>*</b>Function:</label><br>
+ <select class="form-field" name="repeatSelect" id="repeatSelect" [(ngModel)]="menu.functionCd">
+ <option>{{menu.functionCd}}</option>
+ <option *ngFor="let item of functionCDselectData" value="{{item}}" >{{item}}</option>
+ </select>
+ </div>
+ <div class="groupItem">
+ <label class="item-label"><b>*</b>Active:</label><br>
+ <select class="form-field" name="selectActive" ng-model="menu.active">
+ <option *ngFor="let active of activeStatusOptions" value="{{active.value}}">{{active.title}}</option>
+ </select>
+ </div>
+ <div class="groupItem">
+ <label class="item-label">Servlet:</label><br>
+ <input [(ngModel)]="menu.servlet" type="text" name="servlet" id="servlet">
+ </div>
+ <div class="groupItem">
+ <label class="item-label">Query String:</label><br>
+ <input [(ngModel)]="menu.queryString" type="text" name="queryString" id="queryString">
+ </div>
+ </div>
+
+ <br>
+
+ <div class="elementsContainer">
+ <div class="groupItem">
+ <label class="item-label">External URL:</label><br>
+ <input [(ngModel)]="menu.externalUrl" type="text" name="externalURL" id="externalURL">
+ </div>
+ <div class="groupItem">
+ <label class="item-label">Target:</label><br>
+ <input [(ngModel)]="menu.target" type="text" name="target" id="target">
+ </div>
+ <div class="groupItem">
+ <label class="item-label"><b>*</b>Menu Set Code:</label><br>
+ <input [(ngModel)]="menu.menuSetCode" type="text" name="menuSetCode" id="menuSetCode">
+ </div>
+ <div class="groupItem">
+ <label class="item-label"><b>*</b>Separator:</label><br>
+ <select class="form-field" name="select" ng-model="menu.separator">
+ <option *ngFor="let separator of separatorStatusOptions" value="{{separator.value}}">{{separator.title}}</option>
+ </select>
+ </div>
+ </div>
+
+ <br>
+
+ <div class="elementsContainer">
+ <div class="groupItem">
+ <label class="item-label">Image Source:</label><br>
+ <input [(ngModel)]="menu.imageSrc" type="text" name="imageSource" id="imageSource">
+ </div>
+ </div>
+
+ </div>
+ <!--Modal Footer goes Here-->
+ <div class="modal-footer">
+ <button type="button" class="btn btn-primary" (click)="updateFnMenu()">Save</button> &nbsp;
+ <button type="button" class="btn btn-primary" (click)="activeModal.close('Close')">Cancel</button>
+ </div>
+</div>
+ \ No newline at end of file
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/menus/new-menu/new-menu.component.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/menus/new-menu/new-menu.component.scss
new file mode 100644
index 00000000..a8b5f966
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/menus/new-menu/new-menu.component.scss
@@ -0,0 +1,71 @@
+/*
+ * ============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============================================
+ *
+ *
+ */
+
+::ng-deep .modal-dialog {
+ max-width: 1200px;
+ width: 883px;
+ overflow-x: auto;
+ overflow-y: auto;
+}
+
+table {
+ width: 100%;
+}
+
+body {
+ font-family: Roboto, Arial, sans-serif;
+ margin: 0;
+}
+
+.elementsContainer{
+ display: inline-flex;
+}
+
+.groupItem{
+ margin-right: 11px;
+ margin-bottom: 10px;
+}
+
+.form-field{
+ height: 30px;
+ width: 198px
+}
+
+.item-label{
+ margin-bottom: 1px;
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/menus/new-menu/new-menu.component.spec.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/menus/new-menu/new-menu.component.spec.ts
new file mode 100644
index 00000000..650f09a6
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/menus/new-menu/new-menu.component.spec.ts
@@ -0,0 +1,165 @@
+/*
+ * ============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 {FormsModule} from '@angular/forms';
+import { NewMenuComponent } from './new-menu.component';
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { NgbActiveModal, NgbModalModule } from '@ng-bootstrap/ng-bootstrap';
+import { RouterTestingModule } from '@angular/router/testing';
+import { CookieService } from 'ngx-cookie-service';
+import { AdminService } from '../../admin.service';
+import 'rxjs/add/operator/toPromise';
+import { ConfirmationModalComponent } from 'src/app/modals/confirmation-modal/confirmation-modal.component';
+import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
+import 'rxjs/add/observable/of';
+import { Observable } from 'rxjs/Observable';
+import 'rxjs/add/operator/catch';
+import 'rxjs/add/observable/throw';
+import { BrowserDynamicTestingModule } from '@angular/platform-browser-dynamic/testing';
+
+
+describe('NewMenuComponent', () => {
+ let component: NewMenuComponent;
+ let fixture: ComponentFixture<NewMenuComponent>;
+ let adminService:AdminService;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ NewMenuComponent,ConfirmationModalComponent ],
+ imports:[
+ FormsModule,
+ HttpClientTestingModule,
+ RouterTestingModule,
+ NgbModalModule,
+ BrowserAnimationsModule
+ ],
+ providers:[
+ AdminService,
+ NgbActiveModal,
+ CookieService
+ ],
+ })
+ TestBed.overrideModule(BrowserDynamicTestingModule,{
+ set:{
+ entryComponents:[ConfirmationModalComponent ]
+ }
+ })
+ .compileComponents();
+
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(NewMenuComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ adminService=TestBed.get(AdminService);
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('testing ngOnInit method for if condition',()=>{
+ component.selectedMenu=1;
+ component.ngOnInit();
+ expect(component.menu).toEqual(component.selectedMenu);
+ })
+
+ it('testing ngOnInit method for else condition',()=>{
+ component.selectedMenu=0;
+ component.ngOnInit();
+ expect(component.menu.menuSetCode).toEqual('APP');
+ })
+
+ it('testing sortItems method',()=>{
+ let prop: any;
+ component.sortItems(prop);
+
+ })
+
+ it('testing getParentLabel method',()=>{
+ component.getParentLabel(1,"data");
+ })
+
+
+ it('should test getParentData method1 ',()=>{
+ const children="children";
+ let spy=spyOn(adminService,'getParentData').and.returnValue(Observable.of('you object'));
+ component.getParentData();
+ expect(spy).toHaveBeenCalled();
+ })
+
+ it('should test getParentData method2 error part ',()=>{
+ const children="children";
+ let spy=spyOn(adminService,'getParentData').and.returnValue(Observable.throw({status:404}));
+ component.getParentData();
+ expect(spy).toHaveBeenCalled();
+ })
+
+ describe('should test getLeftMenuItems',()=>{
+ it('testing getLeftMenuItems',()=>{
+ component.getLeftMenuItems();
+ })
+ })
+
+ it('testing getFunctionCDselectData method1',()=>{
+ let spy=spyOn(adminService,'getFunctionCdList').and.returnValue(Observable.of('your object'));
+ component.getFunctionCDselectData();
+ expect(spy).toHaveBeenCalled();
+ expect(component.result).toEqual('your object');
+ expect(component.functionCDselectData).toEqual('your object');
+ })
+
+ describe('should test getFunctionCDselectData method2',()=>{
+ it('testing getFunctionCDselectData',()=>{
+ let spy= spyOn(adminService,'getFunctionCdList').and.returnValue(Observable.throw({status:404}))
+ component.getFunctionCDselectData();
+ expect(spy).toHaveBeenCalled();
+ expect(component.showSpinner).toEqual(false);
+ })
+ })
+
+ it('should test updateFnMenu method',()=>{
+ component.menu.label!=null;
+ component.updateFnMenu();
+ })
+
+});
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/menus/new-menu/new-menu.component.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/menus/new-menu/new-menu.component.ts
new file mode 100644
index 00000000..6e5b0c1a
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/menus/new-menu/new-menu.component.ts
@@ -0,0 +1,267 @@
+/*
+ * ============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 { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
+import { NgbActiveModal, NgbModal } from '@ng-bootstrap/ng-bootstrap';
+import { AdminService } from '../../admin.service';
+import { SidebarComponent } from 'src/app/layout/components/sidebar/sidebar.component';
+import { Router } from '@angular/router';
+import { SidebarService } from 'src/app/shared/services';
+import { ConfirmationModalComponent } from 'src/app/modals/confirmation-modal/confirmation-modal.component';
+import { CookieService } from 'ngx-cookie-service';
+
+@Component({
+ selector: 'app-new-menu',
+ templateUrl: './new-menu.component.html',
+ styleUrls: ['./new-menu.component.scss']
+})
+export class NewMenuComponent implements OnInit {
+
+ menu = {
+ action: null,
+ active: false,
+ activeAsString: "false",
+ auditTrail: null,
+ auditUserId: null,
+ childMenus: [],
+ created: null,
+ createdId: null,
+ externalUrl: null,
+ functionCd: null,
+ id: null,
+ imageSrc: null,
+ label: null,
+ menuLevel: null,
+ menuSetCode: null,
+ modified: null,
+ modifiedId: null,
+ parentId: null,
+ parentIdAsString: null,
+ parentMenu: null,
+ queryString: null,
+ rowNum: null,
+ separator: false,
+ separatorAsString: false,
+ servlet: null,
+ sortOrder: null,
+ target: null
+ }
+ showSpinner: boolean;
+ result: any;
+ //menu: any;
+ @Input() selectedMenu: any;
+ @Input() isEditMode: boolean;
+ @Output() passEntry: EventEmitter<any> = new EventEmitter();
+
+ statusOptions = [
+ {index: 0, value: 'true', title: 'Y'},
+ {index: 1, value: 'false', title: 'N'}
+ ];
+ selectedValue = this.statusOptions[0];
+ separator = {
+ availableOptions:[
+ {value: 'true', name: 'Y'},
+ {value: 'false', name: 'N'}
+ ],
+ selectedOption: {value: 'true', name: 'Y'}
+ }
+
+ activeStatusOptions = [
+ {index: 0, value: 'true', title: 'Y'},
+ {index: 1, value: 'false', title: 'N'}
+ ];
+ activeSelectedValue = this.activeStatusOptions[0];
+
+ separatorStatusOptions = [
+ {index: 0, value: 'true', title: 'Y'},
+ {index: 1, value: 'false', title: 'N'}
+ ];
+ separatorSelectedValue = this.separatorStatusOptions[1];
+
+ active = {
+ availableOptions:[
+ {value: 'true', name: 'Y'},
+ {value: 'false', name: 'N'}
+ ],
+ selectedOption: {value: 'true', name: 'Y'}
+ };
+
+ functionCDselectData = [];
+ parentListSelectData = [];
+ childListSelectData = [];
+
+ constructor(public adminService: AdminService, public activeModal: NgbActiveModal,
+ public ngmodel: NgbModal, public router: Router, public sidebarService: SidebarService,public cookieService:CookieService) { }
+
+ ngOnInit() {
+ if(this.selectedMenu){
+ this.menu = this.selectedMenu;
+ }else{
+ this.menu.menuSetCode='APP';
+ }
+ this.getFunctionCDselectData();
+ this.getParentData();
+ }
+
+ getParentData(){
+ this.showSpinner = true;
+ this.adminService.getParentData()
+ .subscribe( _data => {
+ this.result = _data;
+ if(_data){
+ this.parentListSelectData= _data; // data from server
+ let menuItems = this.parentListSelectData;
+ var heirarchicalMenuItems = [];
+ var children = [];
+ for ( var i=0; i<menuItems.length; i++){
+ for(var j=0; j<menuItems.length; j++){
+ if(menuItems[j][2]==menuItems[i][0])
+ children.push(
+ {
+ menuId: menuItems[j][0],
+ label: menuItems[j][1]
+ }
+ );
+ }
+ if(children.length!=0){
+ heirarchicalMenuItems.push(
+ {
+ menuId: menuItems[i][0],
+ label: menuItems[i][1],
+ children: children.sort(this.sortItems("label"))
+ }
+
+ );
+ }
+ children = [];
+ }
+ heirarchicalMenuItems.sort(this.sortItems("label"));
+ this.childListSelectData = heirarchicalMenuItems;
+ }
+ }, error => {
+ this.showSpinner = false;
+ console.log(error);
+ });
+ }
+
+ sortItems(prop){
+ return function(a, b) {
+ if (a[prop] > b[prop]) {
+ return 1;
+ } else if (a[prop] < b[prop]) {
+ return -1;
+ }
+ return 0;
+ }
+ }
+
+ getParentLabel(parentId, parentListSelectData){
+ var element;
+ element = parentListSelectData[0];
+ for (var i=0; i<parentListSelectData.length; i++){
+ element = parentListSelectData[i];
+ if (element[0] == parentId)
+ return element[1];
+ else "---";
+ }
+ }
+
+ updateFnMenu(){
+ this.showSpinner = true;
+ if( this.menu && this.menu.imageSrc == "" ) this.menu.imageSrc = "N/A";
+ if( this.menu && this.menu.target == "" ) this.menu.target = "N/A";
+ if( this.menu && this.menu.externalUrl == "" ) this.menu.externalUrl = "N/A";
+ if( this.menu && this.menu.queryString == "" ) this.menu.queryString = "N/A";
+ if( this.menu && this.menu.servlet == "" ) this.menu.servlet = "N/A";
+
+ let validationRule = /^\S{3,}$/;
+ let selectedFunction = this.menu.functionCd;
+ var selectedFunctionText = this.menu.functionCd; //selectedFunction.options[selectedFunction.selectedIndex].text;
+
+ if((this.menu.label == null || this.menu.label == "" || (this.menu.label && this.menu.label.trim().length == 0) ) ||
+ this.menu.parentId == null || this.menu.parentId == "" || this.menu.action == null || this.menu.action == "" ||
+ selectedFunctionText == null || selectedFunctionText == "" || this.menu.sortOrder == null || this.menu.sortOrder == "" ||
+ this.menu.menuSetCode == null ||this.menu.menuSetCode == ""){
+
+ this.openConfirmationModal('','Please provide all the mandatory (*) fields inputs !');
+ return;
+ }else{
+ this.menu.parentId=parseFloat(this.menu.parentId);
+ let data ={availableFnMenuItem: this.menu};
+ let postData = JSON.stringify(data);
+ this.adminService.updateFnMenuItem(postData)
+ .subscribe( _data => {
+ this.result = _data;
+ this.passEntry.emit(this.result);
+ this.ngmodel.dismissAll();
+ }, error => {
+ this.showSpinner = false;
+ console.log(error);
+ this.openConfirmationModal("Error",error);
+ });
+ this.getLeftMenuItems();
+ }
+
+ }
+
+ getLeftMenuItems(){
+ let sidebarComponent = new SidebarComponent(this.router, this.sidebarService,this.cookieService);
+ sidebarComponent.ngOnInit();
+ }
+
+ getFunctionCDselectData = function(){
+ this.adminService.getFunctionCdList()
+ .subscribe( _data => {
+ this.result = _data;
+ if(_data){
+ this.functionCDselectData = _data;
+ }
+ }, error => {
+ this.showSpinner = false;
+ console.log(error);
+ this.openConfirmationModal("","Function Code Data not available !");
+ });
+ }
+
+ openConfirmationModal(_title: string, _message: string) {
+ const modalInfoRef = this.ngmodel.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/role-functions/new-role-function/new-role-function.component.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/role-functions/new-role-function/new-role-function.component.html
new file mode 100644
index 00000000..888deca8
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/role-functions/new-role-function/new-role-function.component.html
@@ -0,0 +1,101 @@
+<!--
+ ============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">
+ <div class="modal-header">
+ <h4 class="modal-title">{{title}}</h4>
+ <button type="button" class="close" aria-label="Close" (click)="activeModal.dismiss('Cross')">
+ <span aria-hidden="true">&times;</span>
+ </button>
+ </div>
+ <div class="modal-body">
+ <span class="ecomp-spinner" *ngIf="showSpinner"></span>
+ <form>
+ <fieldset class="form-group">
+ <div class="row">
+ <legend class="col-form-label col-sm-2 pt-0">Type</legend>
+ <div class="col-sm-10">
+ <div class="form-check">
+ {{selectedType}}
+ <mat-radio-group aria-labelledby="example-radio-group-label" class="example-radio-group"
+ [(ngModel)]="selectedType" name="type">
+ <mat-radio-button class="example-radio-button" [disabled]="editDisable" *ngFor="let type of typeOptions" [value]="type">
+ {{type}} &nbsp;
+ </mat-radio-button>
+ </mat-radio-group>
+ </div>
+ </div>
+ </div>
+ </fieldset>
+ <div *ngIf="selectedType === 'other'" class="form-group row">
+ <label for="inputOtherType" class="col-sm-2 col-form-label"></label>
+ <div class="col-sm-10">
+ <input type="text" class="form-control" [disabled]="editDisable" [(ngModel)]="otherTypeValue" name="type2" id="inputOtherType"
+ placeholder="Type">
+ </div>
+ </div>
+ <div class="form-group row">
+ <label for="inputInstance" class="col-sm-2 col-form-label">Instance</label>
+ <div class="col-sm-10">
+ <input type="text" class="form-control" [disabled]="editDisable" [(ngModel)]="roleFunction.code" name="code" id="inputInstance"
+ placeholder="Instance">
+ </div>
+ </div>
+ <div class="form-group row">
+ <label for="inputAction" class="col-sm-2 col-form-label">Action</label>
+ <div class="col-sm-10">
+ <input type="text" class="form-control" [disabled]="editDisable" [(ngModel)]="roleFunction.action" name="action" id="inputAction"
+ placeholder="Action">
+ </div>
+ </div>
+ <div class="form-group row">
+ <label for="inputName" class="col-sm-2 col-form-label">Name</label>
+ <div class="col-sm-10">
+ <input type="text" class="form-control" [(ngModel)]="roleFunction.name" name="name" id="inputName"
+ placeholder="Name">
+ </div>
+ </div>
+ </form>
+ </div>
+ <div class="modal-footer">
+ <button type="button" class="btn btn-primary"
+ [disabled]="(selectedType === 'other' && otherTypeValue.length === 0 ) || (roleFunction.code.length === 0 || roleFunction.action.length === 0 || roleFunction.name.length === 0)"
+ (click)="saveRoleFunction()">Save</button> &nbsp;
+ <button type="button" class="btn btn-primary" (click)="activeModal.close('Close')">Cancel</button>
+ </div>
+ </div> \ No newline at end of file
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/role-functions/new-role-function/new-role-function.component.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/role-functions/new-role-function/new-role-function.component.scss
new file mode 100644
index 00000000..56cb1aa3
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/role-functions/new-role-function/new-role-function.component.scss
@@ -0,0 +1,40 @@
+/*-
+ * ============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============================================
+ *
+ *
+ */
+ .ecomp-spinner{
+ z-index: 9999;
+} \ No newline at end of file
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/role-functions/new-role-function/new-role-function.component.spec.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/role-functions/new-role-function/new-role-function.component.spec.ts
new file mode 100644
index 00000000..ecc0947d
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/role-functions/new-role-function/new-role-function.component.spec.ts
@@ -0,0 +1,69 @@
+/*-
+ * ============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 { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { NewRoleFunctionComponent } from './new-role-function.component';
+import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
+import { FormsModule } from '@angular/forms';
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
+
+describe('NewRoleFunctionComponent', () => {
+ let component: NewRoleFunctionComponent;
+ let fixture: ComponentFixture<NewRoleFunctionComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ schemas:[CUSTOM_ELEMENTS_SCHEMA],
+ declarations: [ NewRoleFunctionComponent ],
+ imports:[FormsModule,HttpClientTestingModule],
+ providers:[NgbActiveModal]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(NewRoleFunctionComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ // it('should create', () => {
+ // expect(component).toBeTruthy();
+ // });
+});
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/role-functions/new-role-function/new-role-function.component.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/role-functions/new-role-function/new-role-function.component.ts
new file mode 100644
index 00000000..d0be5145
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/role-functions/new-role-function/new-role-function.component.ts
@@ -0,0 +1,174 @@
+/*-
+ * ============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 } from '@angular/core';
+import { NgbActiveModal, NgbModal } from '@ng-bootstrap/ng-bootstrap';
+import { InformationModalComponent } from 'src/app/modals/information-modal/information-modal.component';
+import { RoleFunction } from '../role-function';
+import { HttpClient } from '@angular/common/http';
+import { AdminService } from '../../admin.service';
+import { ConfirmationModalComponent } from 'src/app/modals/confirmation-modal/confirmation-modal.component';
+
+@Component({
+ selector: 'app-new-role-function',
+ templateUrl: './new-role-function.component.html',
+ styleUrls: ['./new-role-function.component.scss']
+})
+export class NewRoleFunctionComponent implements OnInit {
+
+ @Input() title: string;
+ @Input() appId: any;
+ @Input() dialogState: number;
+ @Input() currentRoleFunctions: any;
+ @Input() editRoleFunction: RoleFunction;
+ @Output() passBackRoleFunctionPopup: EventEmitter<any> = new EventEmitter();
+ roleFunction: RoleFunction;
+ otherTypeValue: string;
+ typeOptions: string[] = ['menu', 'url', 'other'];
+ api = '';
+ isEditing: any;
+ editDisable: boolean;
+ showSpinner: boolean;
+ selectedType: string;
+ createOrUpdate: string;
+ constructor(public adminService: AdminService, public activeModal: NgbActiveModal, public ngbModal: NgbModal, public http: HttpClient) { }
+
+ ngOnInit() {
+ this.createOrUpdate = 'create';
+ this.selectedType = 'menu';
+ this.roleFunction = new RoleFunction(this.selectedType, '', '*', '');
+ this.otherTypeValue = '';
+ if (this.editRoleFunction) {
+ this.createOrUpdate = 'update';
+ this.editDisable = true;
+ if (this.editRoleFunction.type !== 'menu' && this.editRoleFunction.type !== 'url') {
+ this.selectedType = 'other';
+ this.otherTypeValue = this.editRoleFunction.type;
+ }else{
+ this.selectedType = this.editRoleFunction.type;
+ }
+ this.roleFunction = new RoleFunction(this.editRoleFunction.type, this.editRoleFunction.code, this.editRoleFunction.action, this.editRoleFunction.name);
+ }
+ }
+
+ saveRoleFunction() {
+ if (/[^a-zA-Z0-9\-\.\_]/.test(this.roleFunction.type)) {
+ this.openConfirmationModal('Confirmation', 'Type can only contain alphanumeric characters, dots(.) and underscores(_)');
+ return;
+ }
+ if (this.roleFunction.action !== '*' && /[^a-zA-Z0-9\-\.\_]/.test(this.roleFunction.action)) {
+ this.openConfirmationModal('Confirmation', 'Action can only contain alphanumeric characters, hyphens(-), dots(.) and underscores(_) and single asterisk character(*)');
+ return;
+ }
+ if (/[^a-zA-Z0-9\-\:\_\./*]/.test(this.roleFunction.code)) {
+ this.openConfirmationModal('Confirmation', 'Instance can only contain alphanumeric characters, hyphens(-), dots(.), colons(:), forwardSlash(/) , asterisk(*) and underscores(_)');
+ return;
+ }
+ const modalInfoRef = this.ngbModal.open(InformationModalComponent);
+ modalInfoRef.componentInstance.title = 'Confirmation';
+ modalInfoRef.componentInstance.message = 'You are about to ' + this.createOrUpdate + ' the role function ' + this.roleFunction.name + '. Do you want to continue?';
+ modalInfoRef.result.then((_res) => {
+ if (_res === 'Ok') {
+ this.showSpinner = true;
+ var exists = false, x;
+ for (x in this.currentRoleFunctions) {
+ if (this.currentRoleFunctions[x].type == this.roleFunction.type
+ && this.currentRoleFunctions[x].code == this.roleFunction.code
+ && this.currentRoleFunctions[x].action == this.roleFunction.action
+ && this.currentRoleFunctions[x].name == this.roleFunction.name) {
+ this.openConfirmationModal('Confirmation', "Role Function already exist.");
+ exists = true;
+ this.showSpinner = false;
+ break;
+ }
+ if (!this.editDisable) {
+ if (this.currentRoleFunctions[x].type == this.roleFunction.type
+ && this.currentRoleFunctions[x].code == this.roleFunction.code
+ && this.currentRoleFunctions[x].action == this.roleFunction.action
+ ) {
+ this.openConfirmationModal('Confirmation', "Please make sure code, type and action is unique. Please create a role function with a different code or type or action to proceed.");
+ exists = true;
+ this.showSpinner = false;
+ break;
+ }
+ }
+ }
+
+ if (this.selectedType === 'other'){
+ this.roleFunction.type = this.otherTypeValue;
+ }else{
+ this.roleFunction.type = this.selectedType;
+ }
+
+ if (!exists && this.roleFunction.name.trim() != '' && this.roleFunction.code.trim() != '') {
+ var postData = this.roleFunction;
+ //console.log("saveRoleFunction post data :: ",postData);
+ this.adminService.saveRoleFunction(JSON.stringify(postData))
+ .subscribe(_data => {
+ this.showSpinner = false;
+ //console.log("saveRoleFunction response",_data);
+ if (this.editRoleFunction) {
+ this.editRoleFunction.name = this.roleFunction.name;
+ this.passBackRoleFunctionPopup.emit(this.editRoleFunction);
+ } else{
+ this.passBackRoleFunctionPopup.emit(this.roleFunction);
+ }
+ if (this.editRoleFunction) {
+ this.openConfirmationModal('Success', "Role function updated successfully.");
+ }else{
+ this.openConfirmationModal('Success', "Role function created successfully.");
+ }
+ }, error =>{
+ //console.log(error);
+ this.showSpinner = false;
+ this.openConfirmationModal('Error', error.message);
+ });
+ }
+ }
+ }, (_dismiss) => {
+
+ })
+ }
+
+
+ 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/role-functions/role-function.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/role-functions/role-function.ts
new file mode 100644
index 00000000..9a00995b
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/role-functions/role-function.ts
@@ -0,0 +1,52 @@
+/*-
+ * ============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============================================
+ *
+ *
+ */
+
+export class RoleFunction {
+ type: string;
+ code: string;
+ action: string;
+ name: string;
+
+ //constructor
+ constructor(type: string, code: string, action: string, name: string) {
+ this.type = type;
+ this.code = code;
+ this.action = action;
+ this.name = name;
+ }
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/role-functions/role-functions.component.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/role-functions/role-functions.component.html
new file mode 100644
index 00000000..460f69b3
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/role-functions/role-functions.component.html
@@ -0,0 +1,48 @@
+<!--
+ ============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 class="role-function-title">
+ <h3 class="heading-page" id="roleFunction"> Role Functions </h3>
+ <span class= "heading-small" *ngIf="isAppCentralized=='true'"><b>Please go to portal to Manage Role Function.</b></span>
+ </div>
+ <span class="ecomp-spinner" *ngIf="showSpinner"></span>
+
+ <rdp-data-table [data]="tableData" [settings]="settings"></rdp-data-table>
+</div>
+ \ No newline at end of file
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/role-functions/role-functions.component.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/role-functions/role-functions.component.scss
new file mode 100644
index 00000000..ec7b2cac
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/role-functions/role-functions.component.scss
@@ -0,0 +1,63 @@
+/*-
+ * ============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============================================
+ *
+ *
+ */
+ table {
+ width: 100%;
+}
+
+td, th {
+ width: 25%;
+}
+
+td[_ngcontent-c4], th[_ngcontent-c4] {
+ width: 15%;
+}
+
+.icon-trash{
+ cursor: pointer;
+}
+
+::ng-deep .mat-form-field-infix {
+ width: 250px;
+ margin-left: 10px;
+}
+
+: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/role-functions/role-functions.component.spec.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/role-functions/role-functions.component.spec.ts
new file mode 100644
index 00000000..dab6af2b
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/role-functions/role-functions.component.spec.ts
@@ -0,0 +1,99 @@
+/*-
+ * ============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, inject } from '@angular/core/testing';
+
+import { RoleFunctionsComponent } from './role-functions.component';
+import { CUSTOM_ELEMENTS_SCHEMA} from '@angular/core';
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { RdpModule } from 'portalsdk-tag-lib';
+import { FormsModule} from '@angular/forms';
+import { AdminService } from '../admin.service';
+import { MatSelectModule} from '@angular/material';
+import { Observable } from 'rxjs';
+import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
+import { UserService } from '../../shared/services/user/user.service';
+
+describe('RoleFunctionsComponent', () => {
+ let component: RoleFunctionsComponent;
+ let fixture: ComponentFixture<RoleFunctionsComponent>;
+ let userService:UserService;
+ let adminService:AdminService;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ schemas: [CUSTOM_ELEMENTS_SCHEMA],
+ declarations: [ RoleFunctionsComponent ],
+ imports: [HttpClientTestingModule,BrowserAnimationsModule,
+ RdpModule,
+ FormsModule,
+ ],
+ providers:[MatSelectModule]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ TestBed.configureTestingModule({
+ providers:[AdminService]
+ })
+ fixture = TestBed.createComponent(RoleFunctionsComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ userService=TestBed.get(UserService);
+ adminService=TestBed.get(AdminService);
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ describe('test for subscribe in ngOnInit',()=>{
+ it('should test ngOnInit method',()=>{
+ let spy=spyOn(userService,'getFunctionalMenuStaticDetailSession').and.returnValue(Observable.of('you object'));
+ component.ngOnInit();
+ expect(spy).toHaveBeenCalled();
+ })
+ })
+ it('Admin service injection check', inject([AdminService],(injectService:AdminService) =>{
+ expect(injectService).toBe(adminService);
+ }));
+
+
+});
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/role-functions/role-functions.component.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/role-functions/role-functions.component.ts
new file mode 100644
index 00000000..3b97be51
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/role-functions/role-functions.component.ts
@@ -0,0 +1,126 @@
+/*-
+ * ============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, Directive, Input, Output, EventEmitter, ViewChildren, QueryList, PipeTransform, ViewChild } from '@angular/core';
+import { AdminService } from '../admin.service';
+import {UserService} from '../../shared/services/user/user.service'
+import { User } from 'src/app/shared/services/user/user';
+import { of, Observable } from 'rxjs';
+import { RoleFunction } from './role-function';
+import { MatTableDataSource } from '@angular/material/table';
+import { MatPaginator } from '@angular/material/paginator';
+import { MatSort } from '@angular/material/sort';
+import { InformationModalComponent } from 'src/app/modals/information-modal/information-modal.component';
+import { NgbModal, ModalDismissReasons } from '@ng-bootstrap/ng-bootstrap';
+import { NewRoleFunctionComponent } from './new-role-function/new-role-function.component';
+import { Column, DataTableSettings, ColumnTypes } from 'portalsdk-tag-lib';
+import { RoleFunctionsService } from './role-functions.service';
+
+@Component({
+ selector: 'app-role-functions',
+ templateUrl: './role-functions.component.html',
+ styleUrls: ['./role-functions.component.scss']
+})
+export class RoleFunctionsComponent implements OnInit {
+
+ tableData: Array<RoleFunction> = [];
+ response: any;
+ result: any;
+ function: RoleFunction;
+ isEditMode: boolean = false;
+ availableRoleFunctions: any;
+ showSpinner: boolean;
+
+ isAppCentralized: any;
+ user: User;
+ closeResult: string;
+
+ roleFunctionHeaders = ["name", "code", "type", "action", "edit", "delete"];
+ dataSource: MatTableDataSource<RoleFunction>;
+
+ constructor(public adminService: AdminService,
+ public userService: UserService,
+ private ngModal: NgbModal,
+ private roleFunctionService: RoleFunctionsService) { }
+
+ @ViewChild(MatPaginator, {}) paginator: MatPaginator;
+ @ViewChild(MatSort, {}) sort: MatSort;
+
+ public settings;
+ public columns: any = [];
+ typeOptions: string[] = ['menu', 'url', 'other'];
+
+ ngOnInit() {
+ this.showSpinner = false;
+ this.availableRoleFunctions = [];
+ this.getRoleFunctions();
+ let result = this.userService.getFunctionalMenuStaticDetailSession();
+ result.subscribe(user => {
+ this.user = user;
+ this.isAppCentralized = this.user.isAppCentralized;
+ });
+ }
+
+ getRoleFunctions() {
+ this.showSpinner = true;
+ let response;
+ this.response = this.adminService.getRoleFunctionList();
+ this.response.subscribe(data => {
+ response = data;
+ this.result = JSON.parse(response.data);
+ this.availableRoleFunctions = this.result.availableRoleFunctions;
+ this.tableData = JSON.parse(this.result.availableRoleFunctions);
+ //console.log("Table data : ", this.tableData);
+ this.columns.push(new Column("name", "Name", ColumnTypes.TEXT, true, null));
+ this.columns.push(new Column("code", "Code", ColumnTypes.TEXT, true, null));
+ this.columns.push(new Column("type", "Type", ColumnTypes.RADIO, true, this.typeOptions));
+ this.columns.push(new Column("action", "Action", ColumnTypes.TEXT, true, null));
+
+ this.settings = new DataTableSettings()
+ this.settings.columns = this.columns;
+ this.settings.isPaginationEnabled = true;
+ this.settings.paginationsSize = "5";
+ this.settings.isReadOnly = false;
+ this.settings.isTableSearchEnabled = true;
+ this.settings.applicationService = this.roleFunctionService;
+ this.showSpinner = false;
+
+ });
+
+ }
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/role-functions/role-functions.service.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/role-functions/role-functions.service.ts
new file mode 100644
index 00000000..bd44a63d
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/role-functions/role-functions.service.ts
@@ -0,0 +1,57 @@
+import { Injectable } from '@angular/core';
+import { RdpCrudInterface } from 'portalsdk-tag-lib';
+import { AdminService } from '../admin.service';
+import { BehaviorSubject } from 'rxjs';
+
+@Injectable({
+ providedIn: 'root'
+})
+export class RoleFunctionsService implements RdpCrudInterface {
+
+ public statusResponse = new BehaviorSubject("");
+ public updatedData = new BehaviorSubject<any>({});
+
+ loadTableData(filter: any, sortActive: any, sortDirection: any, pageIndex: any, pageSize: any): import("rxjs").Observable<any[]> {
+ throw new Error("Method not implemented.");
+ }
+ getTotalRowCount() {
+ throw new Error("Method not implemented.");
+ }
+
+ constructor(private adminService: AdminService) { }
+
+ add(data: any) {
+ //console.log("Add method is getting called from RoleFunctionService data:: ", data);
+ }
+
+
+ update(data: any): any {
+ console.log("Update method is getting called from RoleFunctionService data:: ", data);
+ return this.adminService.saveRoleFunction(data).subscribe(response => {
+ //console.log("Success Response ", response);
+ this.statusResponse.next("200");
+ }, error => {
+ console.log("Error ", error);
+ })
+ }
+
+ delete(data: any) {
+ //console.log("Delete method is getting called from RoleFunctionService data::>> " + JSON.stringify(data));
+ this.adminService.deleteRoleFunction(data).subscribe(response => {
+ //console.log("Repsonse : ", response);
+ this.statusResponse.next("200");
+
+ })
+ }
+
+ get() {
+ let response = this.adminService.getRoleFunctionList();
+ let editedData;
+ response.subscribe(res => {
+ editedData = res;
+ let data = JSON.parse(JSON.parse(editedData.data).availableRoleFunctions);
+ //console.log("Get Method called : ", data);
+ this.updatedData.next(data);
+ })
+ }
+}
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 { }
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/usage/usage.component.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/usage/usage.component.html
new file mode 100644
index 00000000..ac56a13f
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/usage/usage.component.html
@@ -0,0 +1,49 @@
+<!--
+ ============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>
+ <h3 class="heading-page" id="Usage">Current Usage</h3>
+ </div>
+ <p class="heading-small">
+ The following table shows all current user sessions. Click the icon to end a user's session.
+ </p>
+ <!-- RDP datatable -->
+ <rdp-data-table [data]="users" [settings]="settings"></rdp-data-table>
+ </div>
+</div> \ No newline at end of file
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/usage/usage.component.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/usage/usage.component.scss
new file mode 100644
index 00000000..8712b3b2
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/usage/usage.component.scss
@@ -0,0 +1,64 @@
+/*
+ * ============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============================================
+ *
+ *
+ */
+
+ 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%;
+}
+
+: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/usage/usage.component.spec.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/usage/usage.component.spec.ts
new file mode 100644
index 00000000..01f31669
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/usage/usage.component.spec.ts
@@ -0,0 +1,70 @@
+/*
+ * ============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 { UsageComponent } from './usage.component';
+import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+
+describe('UsageComponent', () => {
+ let component: UsageComponent;
+ let fixture: ComponentFixture<UsageComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ UsageComponent ],
+ schemas:[CUSTOM_ELEMENTS_SCHEMA],
+ imports:[HttpClientTestingModule]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(UsageComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/usage/usage.component.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/usage/usage.component.ts
new file mode 100644
index 00000000..d5121909
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/usage/usage.component.ts
@@ -0,0 +1,82 @@
+/*
+ * ============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 { Component, OnInit } from '@angular/core';
+import { AdminService } from '../admin.service';
+import { Column, DataTableSettings, ColumnTypes } from 'portalsdk-tag-lib';
+
+@Component({
+ selector: 'app-usage',
+ templateUrl: './usage.component.html',
+ styleUrls: ['./usage.component.scss']
+})
+export class UsageComponent implements OnInit {
+
+ response: any;
+ result: any;
+ users: any;
+ public settings;
+ public columns: any = [];
+
+ constructor(public adminService: AdminService) { }
+
+ ngOnInit() {
+ this.adminService.getUsageList()
+ .subscribe(data => {
+ this.response = data;
+ this.users = JSON.parse(this.response.data);
+ //adding Current Session property to each users
+ this.users.forEach(element => {
+ Object.assign(element, {"currentSession":"Current Session"});
+ });
+ this.columns.push(new Column("id", "User Id", ColumnTypes.TEXT, false, null));
+ this.columns.push(new Column("lastName", "User Name",ColumnTypes.TEXT, false, null));
+ this.columns.push(new Column("email", "Email", ColumnTypes.TEXT, false, null));
+ this.columns.push(new Column("lastAccess", " Last Access Time (minutes)", ColumnTypes.TEXT, false, null));
+ this.columns.push(new Column("remaining", "Time Remaining (minutes)", ColumnTypes.TEXT, false, null));
+ this.columns.push(new Column("currentSession", "Expire User Session?", ColumnTypes.TEXT, false, null));
+
+ this.settings = new DataTableSettings()
+ this.settings.columns = this.columns;
+ this.settings.isPaginationEnabled = false;
+ this.settings.isReadOnly = true;
+ this.settings.isTableSearchEnabled = false;
+ });
+ }
+
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/usage/usage.module.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/usage/usage.module.ts
new file mode 100644
index 00000000..6043d5df
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/usage/usage.module.ts
@@ -0,0 +1,51 @@
+/*
+ * ============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 { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { UsageComponent } from './usage.component';
+import { RdpModule } from 'portalsdk-tag-lib';
+
+@NgModule({
+ declarations: [UsageComponent],
+ imports: [
+ CommonModule,
+ RdpModule
+ ]
+})
+export class UsageModule { }