diff options
Diffstat (limited to 'portal-FE-common/src/app/pages')
25 files changed, 2567 insertions, 0 deletions
diff --git a/portal-FE-common/src/app/pages/admins/admins.component.html b/portal-FE-common/src/app/pages/admins/admins.component.html new file mode 100644 index 00000000..a47a6207 --- /dev/null +++ b/portal-FE-common/src/app/pages/admins/admins.component.html @@ -0,0 +1,92 @@ +<!-- + ============LICENSE_START========================================== + ONAP Portal + =================================================================== + 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="onap-main-view-title"> + <h1 class="heading-page">Admins</h1> + </div> + + <mat-form-field> + <mat-label>All Applications</mat-label> + <mat-select> + <mat-option>All Applications</mat-option> + <mat-option *ngFor="let app of availableApps" [value]="app.value" (click)="applyFilterByAppName(app.value)">{{app.title}}</mat-option> + </mat-select> + </mat-form-field> + + <mat-form-field> + <input matInput type="text" (keyup)="applyFilter($event.target.value)" placeholder="Search in entire table"> + </mat-form-field> + <button type="button" class="btn btn-primary" (click)="openAddNewAdminModal()"><i class="icon ion-md-person-add"></i> + Add Admin</button> + <span class="onap-spinner" *ngIf="showSpinner"></span> + <table mat-table [dataSource]="adminsDataSource" matSort> + <!-- First Name Column --> + <ng-container matColumnDef="firstName"> + <th id="col1" mat-header-cell *matHeaderCellDef mat-sort-header> First Name </th> + <td id="rowheader_t1_{{i}}-firstName" mat-cell *matCellDef="let element; let i = index;"> {{element.firstName}} + </td> + </ng-container> + + <!-- Last Name Column --> + <ng-container matColumnDef="lastName"> + <th id="col2" mat-header-cell *matHeaderCellDef mat-sort-header> Last Name </th> + <td id="rowheader_t1_{{i}}-lastName" mat-cell *matCellDef="let element; let i=index;"> {{element.lastName}} + </td> + </ng-container> + + <!-- User ID Column --> + <ng-container matColumnDef="userId"> + <th id="col3" mat-header-cell *matHeaderCellDef mat-sort-header> User ID </th> + <td id="rowheader_t1_{{i}}-userId" mat-cell *matCellDef="let element; let i=index;"> {{element.orgUserId}} + </td> + </ng-container> + + <!-- Applications Column --> + <ng-container matColumnDef="appName"> + <th id="col4" mat-header-cell *matHeaderCellDef> Applications </th> + <td id="rowheader_t1_{{i}}-applications" mat-cell *matCellDef="let element; let i=index;"> + <div *ngFor="let element of element.apps; let i=index;"> {{element.appName}} </div> + </td> + </ng-container> + + <tr [hidden]="adminsData.length === 0" mat-header-row *matHeaderRowDef="displayedColumns"></tr> + <tr mat-row *matRowDef="let row; columns: displayedColumns;" (click)="openExistingAdminModal(row)"></tr> + </table> + <mat-paginator [hidden]="adminsData.length === 0" [pageSizeOptions]="[10, 20]" showFirstLastButtons></mat-paginator> +</div>
\ No newline at end of file diff --git a/portal-FE-common/src/app/pages/admins/admins.component.scss b/portal-FE-common/src/app/pages/admins/admins.component.scss new file mode 100644 index 00000000..a7f4d385 --- /dev/null +++ b/portal-FE-common/src/app/pages/admins/admins.component.scss @@ -0,0 +1,42 @@ +/*- + * ============LICENSE_START========================================== + * ONAP Portal + * =================================================================== + * 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 '../pages.component'; + +.mat-row{ + cursor: pointer; +} diff --git a/portal-FE-common/src/app/pages/admins/admins.component.spec.ts b/portal-FE-common/src/app/pages/admins/admins.component.spec.ts new file mode 100644 index 00000000..563f80ff --- /dev/null +++ b/portal-FE-common/src/app/pages/admins/admins.component.spec.ts @@ -0,0 +1,62 @@ +/*- + * ============LICENSE_START========================================== + * ONAP Portal + * =================================================================== + * 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 { AdminsComponent } from './admins.component'; + +describe('AdminsComponent', () => { + let component: AdminsComponent; + let fixture: ComponentFixture<AdminsComponent>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ AdminsComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(AdminsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/portal-FE-common/src/app/pages/admins/admins.component.ts b/portal-FE-common/src/app/pages/admins/admins.component.ts new file mode 100644 index 00000000..d7a839b5 --- /dev/null +++ b/portal-FE-common/src/app/pages/admins/admins.component.ts @@ -0,0 +1,133 @@ +/*- + * ============LICENSE_START========================================== + * ONAP Portal + * =================================================================== + * 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 { AdminsService, ApplicationsService } from 'src/app/shared/services'; +import { Admins, AllApps } from 'src/app/shared/model'; +import { MatTableDataSource, MatSort, MatPaginator } from '@angular/material'; +import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; +import { NewAdminComponent } from './new-admin/new-admin.component'; + +@Component({ + selector: 'app-admins', + templateUrl: './admins.component.html', + styleUrls: ['./admins.component.scss'] +}) +export class AdminsComponent implements OnInit { + availableApps: Array<{ index: number, title: string, value: string }> = []; + + constructor(private adminsService: AdminsService, private applicationService: ApplicationsService, + public ngModal: NgbModal) { } + + showSpinner = true; + displayedColumns: string[] = ['firstName', 'lastName', 'userId', 'appName']; + adminsData: Admins[] = []; + adminsDataSource = new MatTableDataSource(this.adminsData); + @ViewChild(MatSort) sort: MatSort; + @ViewChild(MatPaginator) paginator: MatPaginator; + ngOnInit() { + this.adminsData = []; + this.getAccoutAdminsData(); + this.getAllApps(); + } + + openAddNewAdminModal() { + const modalRef = this.ngModal.open(NewAdminComponent); + modalRef.componentInstance.title = 'New Admin'; + modalRef.componentInstance.dialogState = 1; + modalRef.componentInstance.disableBack = false; + modalRef.componentInstance.passBackNewAdminPopup.subscribe((_result: any) => { + modalRef.close(); + this.showSpinner = true; + this.getAccoutAdminsData(); + }, (_reason: any) => { + return; + }); + } + + openExistingAdminModal(_adminData: Admins) { + const modalRef = this.ngModal.open(NewAdminComponent); + modalRef.componentInstance.userTitle = `${_adminData.firstName}, ${_adminData.lastName} `+'('+`${_adminData.orgUserId}`+')'; + modalRef.componentInstance.adminModalData = _adminData; + modalRef.componentInstance.dialogState = 2; + modalRef.componentInstance.disableBack = true; + modalRef.componentInstance.passBackNewAdminPopup.subscribe((_result: any) => { + modalRef.close(); + this.showSpinner = true; + this.getAccoutAdminsData(); + }, (_reason: any) => { + return; + }); + } + + applyFilterByAppName(filterValue: string) { + + } + + applyFilter(filterValue: string) { + this.adminsDataSource.filter = filterValue.trim().toLowerCase(); + } + + + getAccoutAdminsData() { + this.adminsService.getAccountAdmins().subscribe((_res: Admins[]) => { + this.showSpinner = false; + this.adminsData = _res; + this.adminsDataSource = new MatTableDataSource(this.adminsData); + this.adminsDataSource.sort = this.sort; + this.adminsDataSource.paginator = this.paginator; + }); + } + + getAllApps() { + this.applicationService.getAvailableApps().subscribe((_res: AllApps[]) => { + var realAppIndex = 1; + for (let i = 1; i <= _res.length; i++) { + if (!_res[i - 1].restrictedApp) { + this.availableApps.push({ + index: realAppIndex, + title: _res[i - 1].title, + value: _res[i - 1].value + }); + realAppIndex = realAppIndex + 1; + } else { + } + } + }); + } + +} diff --git a/portal-FE-common/src/app/pages/admins/new-admin/new-admin.component.html b/portal-FE-common/src/app/pages/admins/new-admin/new-admin.component.html new file mode 100644 index 00000000..c43e4ba1 --- /dev/null +++ b/portal-FE-common/src/app/pages/admins/new-admin/new-admin.component.html @@ -0,0 +1,96 @@ +<!-- + ============LICENSE_START========================================== + ONAP Portal + =================================================================== + 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" *ngIf="dialogState===1"> + <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">×</span> + </button> + </div> + <div class="modal-body"> + <app-search-users [searchTitle]="searchTitleText" [placeHolder]="placeholderText" (passBackSelectedUser)='changeSelectedUser($event)'></app-search-users> + <span class="onap-spinner" *ngIf="isLoading"></span> + </div> + <div class="modal-footer"> + <button type="submit" class="btn btn-primary" [disabled]='!changedSelectedUser' + (click)="getAdminAppsRoles()">Next</button> + <button type="button" class="btn btn-primary" (click)="activeModal.close('Close')">Close</button> + </div> +</div> +<div class="container" *ngIf="dialogState===2"> + <div class="modal-header"> + <h4 class="modal-title">{{userTitle}}</h4> + <button type="button" class="close" aria-label="Close" (click)="activeModal.dismiss('Cross')"> + <span aria-hidden="true">×</span> + </button> + </div> + <div class="modal-body adminApps"> + <div ngbDropdown class="d-inline-block"> + <h4>Administrates:</h4> + <button class="btn btn-outline-primary" id="dropdownBasic1" ngbDropdownToggle>Select Application</button> + <div ngbDropdownMenu aria-labelledby="dropdownBasic1"> + <button *ngFor="let app of adminDropdownApps" (click)="updateDropdown(app, true)" + ngbDropdownItem>{{app.appName}}</button> + </div> + </div> + <!-- User admins list --> + <div class="container adminApps" *ngIf="adminAppsRoles.length > 0"> + <table mat-table [dataSource]="adminsAppsSource"> + <!-- Search Result Column--> + <ng-container matColumnDef="applications"> + <th id="rowheader-result" mat-header-cell *matHeaderCellDef> Applications <span id="i-delete-application" + class="span-remove-title"> Delete </span></th> + <td id="table-data-{{i}}" mat-cell *matCellDef="let element; let i = index;"> + {{element.appName}} <span id="i-delete-application" class="span-remove-admin" + (click)="removeAdminApp(element)"><i class="icon ion-md-trash"></i></span> + </td> + </ng-container> + <tr mat-header-row *matHeaderRowDef="displayedColumns; sticky: true"></tr> + <tr mat-row id="table-row-{{i}}" *matRowDef="let row; columns: displayedColumns; let i = index;"></tr> + </table> + </div> + </div> + <div class="modal-footer"> + <button [hidden]="disableBack" type="submit" class="btn btn-primary" [disabled]='!changedSelectedUser' + (click)="navigateBack()">Back</button> + <button type="submit" class="btn btn-primary" [disabled]='!newAppSelected' + (click)="updateAdminAppsRoles(adminAppsScreen)">Save</button> + <button type="button" class="btn btn-primary" (click)="activeModal.close('Close')">Close</button> + </div> +</div>
\ No newline at end of file diff --git a/portal-FE-common/src/app/pages/admins/new-admin/new-admin.component.scss b/portal-FE-common/src/app/pages/admins/new-admin/new-admin.component.scss new file mode 100644 index 00000000..eb6db14c --- /dev/null +++ b/portal-FE-common/src/app/pages/admins/new-admin/new-admin.component.scss @@ -0,0 +1,58 @@ +/*- + * ============LICENSE_START========================================== + * ONAP Portal + * =================================================================== + * 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============================================ + * + * + */ +.container.adminApps { + overflow-y: auto; + height: 250px; +} + +.dropdown-menu.show { + overflow-y: auto !important; + height: 250px !important; +} +.span-remove-title { + float: right; +} +.span-remove-admin { + float: right; + cursor: pointer; + font-size: 20px; +} + +.onap-spinner{ + z-index: 9999; +}
\ No newline at end of file diff --git a/portal-FE-common/src/app/pages/admins/new-admin/new-admin.component.spec.ts b/portal-FE-common/src/app/pages/admins/new-admin/new-admin.component.spec.ts new file mode 100644 index 00000000..4040b0d3 --- /dev/null +++ b/portal-FE-common/src/app/pages/admins/new-admin/new-admin.component.spec.ts @@ -0,0 +1,62 @@ +/*- + * ============LICENSE_START========================================== + * ONAP Portal + * =================================================================== + * 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 { NewAdminComponent } from './new-admin.component'; + +describe('NewAdminComponent', () => { + let component: NewAdminComponent; + let fixture: ComponentFixture<NewAdminComponent>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ NewAdminComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(NewAdminComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/portal-FE-common/src/app/pages/admins/new-admin/new-admin.component.ts b/portal-FE-common/src/app/pages/admins/new-admin/new-admin.component.ts new file mode 100644 index 00000000..8f80138e --- /dev/null +++ b/portal-FE-common/src/app/pages/admins/new-admin/new-admin.component.ts @@ -0,0 +1,228 @@ +/*- + * ============LICENSE_START========================================== + * ONAP Portal + * =================================================================== + * 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, Output, EventEmitter, Input } from '@angular/core'; +import { AdminsService } from 'src/app/shared/services'; +import { HttpErrorResponse } from '@angular/common/http'; +import { ConfirmationModalComponent } from 'src/app/modals/confirmation-modal/confirmation-modal.component'; +import { NgbModal, NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; +import { PortalAdmin } from 'src/app/shared/model'; +import { MatTableDataSource } from '@angular/material'; +import { InformationModalComponent } from 'src/app/modals/information-modal/information-modal.component'; +import { Router } from '@angular/router'; + +@Component({ + selector: 'app-new-admin', + templateUrl: './new-admin.component.html', + styleUrls: ['./new-admin.component.scss'] +}) +export class NewAdminComponent implements OnInit { + + @Input() dialogState: number; + @Input() userTitle: string; + @Input() disableBack: boolean; + @Input() adminModalData: any; + @Output() passBackNewAdminPopup: EventEmitter<any> = new EventEmitter(); + searchTitleText = 'Enter First Name, Last Name or Org User Id'; + placeholderText = 'Search'; + changedSelectedUser: PortalAdmin; + adminAppsRoles: any; + adminDropdownApps: any; + isLoading: boolean; + newAppSelected: boolean; + adminAppSelectAndUnselectData: any; + displayedColumns: string[] = ['applications']; + adminsAppsSource = new MatTableDataSource(this.adminAppsRoles); + constructor(public router: Router, private adminsService: AdminsService, public ngModal: NgbModal, public activeModal: NgbActiveModal) { } + + ngOnInit() { + this.adminAppsRoles = []; + this.changedSelectedUser = null; + if (this.disableBack){ + this.changedSelectedUser = this.adminModalData; + this.getAdminAppsRoles(); + } + this.adminDropdownApps = []; + this.adminAppSelectAndUnselectData = []; + } + + changeSelectedUser(user: PortalAdmin) { + this.changedSelectedUser = user; + this.userTitle = `${this.changedSelectedUser.firstName}, ` + ` ${this.changedSelectedUser.lastName} ` + ` (${this.changedSelectedUser.orgUserId})`; + } + + getAdminAppsRoles() { + this.isLoading = true; + this.adminsService.getAdminAppsRoles(this.changedSelectedUser.orgUserId).subscribe((_res: any) => { + JSON.stringify(_res); + if (!_res.appsRoles) { + return; + } + this.adminAppsRoles = []; + for (var i = 0; i < _res.appsRoles.length; i++) { + if (!_res.appsRoles[i].restrictedApp && _res.appsRoles[i].isAdmin) { + this.adminAppsRoles.push({ + id: _res.appsRoles[i].id, + appName: _res.appsRoles[i].appName, + isAdmin: _res.appsRoles[i].isAdmin, + restrictedApp: _res.appsRoles[i].restrictedApp + }); + } else if (!_res.appsRoles[i].restrictedApp) { + this.adminDropdownApps.push({ + id: _res.appsRoles[i].id, + appName: _res.appsRoles[i].appName, + isAdmin: _res.appsRoles[i].isAdmin, + restrictedApp: _res.appsRoles[i].restrictedApp + }); + } + } + this.isLoading = false; + this.newAppSelected = false; + this.dialogState = 2; + this.adminsAppsSource = new MatTableDataSource(this.adminAppsRoles); + }); + } + + navigateBack() { + this.dialogState = 1; + } + + removeAdminApp(app: any) { + const modalRef = this.ngModal.open(InformationModalComponent); + modalRef.componentInstance.title = "Confirmation"; + modalRef.componentInstance.message = `Are you sure you want to delete ${app.appName}?`; + modalRef.result.then((result) => { + if (result === 'Ok') { + this.adminAppsRoles.forEach((item: any, index: any) => { + if (item === app) this.adminAppsRoles.splice(index, 1); + }); + //call from delete admin app + this.updateDropdown(app, false); + this.adminsAppsSource = new MatTableDataSource(this.adminAppsRoles); + } + }, (resut) => { + return; + }) + } + + updateDropdown(_newValue: any, isDropdownCall: boolean) { + // app is selected from dropdown + if (isDropdownCall) { + this.adminDropdownApps.forEach((item: any, index: any) => { + if (item === _newValue) this.adminDropdownApps.splice(index, 1); + }); + this.getadminAppSelectAndUnselectedData(_newValue); + _newValue.isAdmin = true; + this.adminAppsRoles.push(_newValue); + this.adminsAppsSource = new MatTableDataSource(this.adminAppsRoles); + } else { // app is removed from the admin list + this.getadminAppSelectAndUnselectedData(_newValue); + _newValue.isAdmin = false; + this.adminDropdownApps.push(_newValue); + } + + // disable save button if nothing new in the admin list + if (this.adminAppSelectAndUnselectData.length > 0) + this.newAppSelected = true; + else + this.newAppSelected = false; + + } + + private getadminAppSelectAndUnselectedData(_newValue: any) { + const index: number = this.adminAppSelectAndUnselectData.indexOf(_newValue); + if (index !== -1) { + this.adminAppSelectAndUnselectData.splice(index, 1); // if found, remove selected app from dropdown in the list + } + else { + this.adminAppSelectAndUnselectData.push(_newValue); + } + } + + remindToAddUserIfNecessary() { + let adminAddedToNewApp = true; + if ((this.adminAppsRoles != null) && (this.adminAppsRoles.length > 0)) { + for (var i = 0; i < this.adminAppSelectAndUnselectData.length; i++) { + var foundApp = false; + for (var j = 0; j < this.adminAppsRoles.length; j++) { + if (this.adminAppsRoles[j] === this.adminAppSelectAndUnselectData[i]) { + foundApp = true; + } + } + if (foundApp === false) { + adminAddedToNewApp = true; + break; + } + } + } else { + adminAddedToNewApp = true; + } + if (adminAddedToNewApp === true) { + const modalRef = this.ngModal.open(InformationModalComponent); + modalRef.componentInstance.title = "Confirmation"; + modalRef.componentInstance.message = 'Add this person as an application user? This allows them to access the application from ONAP Portal. Press OK to go to the Add Users page.'; + modalRef.result.then((_res) => { + if (_res === 'Ok') { + this.router.navigate(['/users']); + } + }); + } + } + + updateAdminAppsRoles() { + const modalRef = this.ngModal.open(InformationModalComponent); + modalRef.componentInstance.title = "Admin Update"; + modalRef.componentInstance.message = 'Are you sure you want to make these admin changes?'; + modalRef.result.then((result) => { + if (result === 'Ok') { + this.adminsService.updateAdminAppsRoles({ orgUserId: this.changedSelectedUser.orgUserId, appsRoles: this.adminAppsRoles }).subscribe(_data => { + this.passBackNewAdminPopup.emit(_data); + this.remindToAddUserIfNecessary(); + }, (_err: HttpErrorResponse) => { + this.passBackNewAdminPopup.emit(_err); + const modalErrorRef = this.ngModal.open(ConfirmationModalComponent); + modalErrorRef.componentInstance.title = "Error"; + if (_err.status) { + modalErrorRef.componentInstance.message = "There was a unknown problem while adding admin to selected application(s)." + "Please try again later. Error Status: " + _err.status; + } + }); + } + }, (reason) => { + return; + }); + } +} diff --git a/portal-FE-common/src/app/pages/functional-menu/functional-menu-dialog/functional-menu-dialog.component.html b/portal-FE-common/src/app/pages/functional-menu/functional-menu-dialog/functional-menu-dialog.component.html new file mode 100644 index 00000000..5e10b78f --- /dev/null +++ b/portal-FE-common/src/app/pages/functional-menu/functional-menu-dialog/functional-menu-dialog.component.html @@ -0,0 +1,100 @@ +<!-- + ============LICENSE_START========================================== + ONAP Portal + =================================================================== + Copyright (C) 2017 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="functionalMenu-details-modal"> + <!--Modal Headers--> + <div class="modal-header"> + <h4 class="modal-title">Functional Menu</h4> + <button type="button" class="close" aria-label="Close" (click)="activeModal.dismiss('Cross')"> + <span aria-hidden="true">×</span> + </button> + </div> + + <!--Modal Body goes here--> + <div class="modal-body"> + <div class="parent"> + <div class="item-label">Parent</div> + <input id="input-parent" class="functionalMenu-height" + [(ngModel)]="nodedetails.menuLocation" [disabled]="isParentDisable" + type="text" name="parent" readonly="readonly" /> + </div> + <div class="title" > + <div class="item-label">Title</div> + <input id="input-title" placeholder="Enter text" class="functionalMenu-height" + [(ngModel)]="nodedetails.name" type="text" autocomplete="off" name="title" maxlength="100" [disabled]="isViewMode"/> + </div> + <div class="url" > + <div class="item-label">URL</div> + <input id="input-title" placeholder="http://" class="functionalMenu-height" + [(ngModel)]="nodedetails.url" type="text" autocomplete="off" name="url" maxlength="100" [disabled]="isViewMode"/> + </div> + <div class="application-select"> + <mat-form-field> + <mat-label>App</mat-label> + <mat-select name="functional-menu-application-select" [disabled]="isViewMode" + [(ngModel)]="nodedetails.selectedAppIndex" + (ngModelChange)="updateSelectedApp(nodedetails.selectedAppIndex)" + [(value)]="selectedApp" + > + <mat-option *ngFor="let d of availableApps" [value]="d.index" >{{d.title}}</mat-option> + </mat-select> + </mat-form-field> + </div> + <div class="role-select" [hidden]="hideRoleField"> + <mat-form-field> + <mat-label>Role</mat-label> + <mat-select name="functional-menu-role-select" [disabled]="isViewMode" + [(ngModel)]="nodedetails.selectedRole" [(value)]="selectedRole" + > + <mat-option *ngFor="let d of availableRoles" [value]="d.roleId" >{{d.rolename}}</mat-option> + </mat-select> + </mat-form-field> + </div> + </div> + + <!--Modal Footer goes Here--> + <div class="modal-footer"> + <button type="button" class="btn btn-primary" (click)="switchToAddMode()">Add</button> + <button type="button" class="btn btn-primary" (click)="switchToEditMode()">Edit</button> + <button type="button" class="btn btn-primary" *ngIf="(isEditMode)" (click)="saveChanges()">Save</button> + <button type="button" class="btn btn-primary" (click)="deleteMenuItem()">Delete</button> + <button type="button" class="btn btn-primary" (click)="activeModal.close('Close')">Cancel</button> + </div> + </div> +</div>
\ No newline at end of file diff --git a/portal-FE-common/src/app/pages/functional-menu/functional-menu-dialog/functional-menu-dialog.component.scss b/portal-FE-common/src/app/pages/functional-menu/functional-menu-dialog/functional-menu-dialog.component.scss new file mode 100644 index 00000000..ba9a1e37 --- /dev/null +++ b/portal-FE-common/src/app/pages/functional-menu/functional-menu-dialog/functional-menu-dialog.component.scss @@ -0,0 +1,63 @@ +/*- + * ============LICENSE_START========================================== + * ONAP Portal + * =================================================================== + * 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: 550px; + width: 550px; + overflow-x: auto; + overflow-y: auto; +} + +::ng-deep .mat-form-field-infix { + display: block; + position: relative; + flex: auto; + min-width: 0; + width: 448px !important; +} + +.container .functionalMenu-details-modal { + padding: 16px; + height: 537px; + overflow: auto; +} + +.functionalMenu-details-modal input[type="text"] { + width: 28em; + margin-bottom: 10px; +}
\ No newline at end of file diff --git a/portal-FE-common/src/app/pages/functional-menu/functional-menu-dialog/functional-menu-dialog.component.spec.ts b/portal-FE-common/src/app/pages/functional-menu/functional-menu-dialog/functional-menu-dialog.component.spec.ts new file mode 100644 index 00000000..de79b9d8 --- /dev/null +++ b/portal-FE-common/src/app/pages/functional-menu/functional-menu-dialog/functional-menu-dialog.component.spec.ts @@ -0,0 +1,63 @@ +/*- + * ============LICENSE_START========================================== + * ONAP Portal + * =================================================================== + * 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 { FunctionalMenuDialogComponent } from './functional-menu-dialog.component'; + +describe('FunctionalMenuDialogComponent', () => { + let component: FunctionalMenuDialogComponent; + let fixture: ComponentFixture<FunctionalMenuDialogComponent>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ FunctionalMenuDialogComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(FunctionalMenuDialogComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/portal-FE-common/src/app/pages/functional-menu/functional-menu-dialog/functional-menu-dialog.component.ts b/portal-FE-common/src/app/pages/functional-menu/functional-menu-dialog/functional-menu-dialog.component.ts new file mode 100644 index 00000000..a1839732 --- /dev/null +++ b/portal-FE-common/src/app/pages/functional-menu/functional-menu-dialog/functional-menu-dialog.component.ts @@ -0,0 +1,446 @@ +/*- + * ============LICENSE_START========================================== + * ONAP Portal + * =================================================================== + * 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 { FunctionalMenuService } from 'src/app/shared/services'; +import { ConfirmationModalComponent } from 'src/app/modals/confirmation-modal/confirmation-modal.component'; +import { InformationModalComponent } from 'src/app/modals/information-modal/information-modal.component'; + +@Component({ + selector: 'app-functional-menu-dialog', + templateUrl: './functional-menu-dialog.component.html', + styleUrls: ['./functional-menu-dialog.component.scss'] +}) +export class FunctionalMenuDialogComponent implements OnInit { + + @Input() nodedata: any; + @Input() operationName: string; + @Output() passEntry: EventEmitter<any> = new EventEmitter(); + isEditMode: boolean = false; + isViewMode: boolean = false; + isAddItemMode: boolean = false; + selectedItem: any; + result: any; + availableRoles: any; + preSelectedRoles: any; + isAllApplications: boolean = false; + availableApps: any + selectedRole: any = []; + selectedApp={ + index:null, + isDisabled: null + }; + selectedAppIndex: any; + menutitle:string; + menuLocation:string; + nodedetails: any; + isParentDisable:boolean =true; + hideRoleField:boolean = true; + conflictMessages = {}; + functionalMenuForm = {}; + + constructor(public functionalMenuService : FunctionalMenuService, public ngbModal: NgbModal, public activeModal: NgbActiveModal) { } + + ngOnInit() { + //console.log("nodedata in dialog ",this.nodedata); + this.nodedetails = Object.assign({}, this.nodedata); + this.isViewMode = true; + this.selectedItem = this.nodedata; + this.selectedRole = []; + this.availableRoles = []; + if(this.nodedata && (this.isViewMode || this.isEditMode) && this.isLeafMenuItem(this.nodedetails)){ + this.selectedApp.index = this.nodedetails.appid; + this.selectedAppIndex=this.nodedetails.appid; + this.getAvailableRoles(this.selectedAppIndex); + } + + if(this.isViewMode || this.isEditMode){ + this.nodedetails.menutitle = this.nodedetails.name; + this.nodedetails.menuLocation = this.isParentMenuItem(this.nodedata) ? this.nodedata.name : this.nodedata.parent.name; + }else{ + this.nodedetails.menutitle = ''; + this.nodedetails.menuLocation = this.nodedata.name; + } + this.nodedetails.selectedAppIndex = (this.selectedItem.appid) ? this.selectedItem.appid : 0; + this.getAvailableApps(); + if(this.selectedItem.appid && this.selectedItem.appid >0){ + this.getAvailableRoles(this.selectedItem.appid); + } + } + + switchToEditMode(){ + //console.log("switchToEditMode :: ",this.nodedata); + this.isViewMode = false; + this.isEditMode = true; + this.isParentDisable =true; + this.nodedetails.name = this.selectedItem.name; + this.nodedetails.url = this.selectedItem.url; + this.nodedetails.selectedAppIndex = (this.selectedItem.appid) ? this.selectedItem.appid : 0; + this.nodedetails.selectedRole = (this.selectedItem.roles) ? this.selectedItem.roles : 0; + } + + switchToAddMode(){ + //console.log("switchToAddMode :: ",this.nodedata); + if(this.selectedItem != null && this.selectedItem.getLevel() >= 4){ + this.openConfirmationModal("","You are not allowed to have a menu item at a level greater than 4."); + return ; + } + //this.isViewMode = false; + this.isViewMode = false; + this.isEditMode = true; + this.isAddItemMode = true; + this.nodedetails.name = ""; + this.nodedetails.url = ""; + this.nodedetails.selectedAppIndex = 0; + this.nodedetails.selectedRole = 0; + } + + /** + * deleteMenuItem + * @param selectedItem + */ + deleteMenuItem(){ + if(this.selectedItem.children!=null && this.selectedItem.children.length>0){ + const modalRef = this.ngbModal.open(ConfirmationModalComponent); + modalRef.componentInstance.title = ""; + modalRef.componentInstance.message = 'You are not allowed to delete a menu item that has children. You can only delete leaf menu items.'; + modalRef.result.then((result) => { }, (resut) => {return;}); + }else{ + const modalRef = this.ngbModal.open(InformationModalComponent); + modalRef.componentInstance.title = "Confirmation"; + modalRef.componentInstance.message = 'Are you sure you want to delete '+ this.selectedItem.name+' ?'; + modalRef.result.then((result) => { + if (result === 'Ok') { + this.functionalMenuService.deleteMenuItem(this.selectedItem.menuId) + .subscribe(_data => { + this.result = _data + this.passEntry.emit(this.result); + let successMsg = "Item Deleted Successfully"; + this.openConfirmationModal("Success",successMsg); + this.ngbModal.dismissAll(); + }, error =>{ + console.log(error); + let deleteErrorMsg = 'There was an error while deleting the item.'+error.message; + this.openConfirmationModal("Error",deleteErrorMsg); + return; + }); + } + }, (resut) => { + + }) + } + } + + updateSelectedApp(appid){ + //console.log("updateSelectedApp called with appId :: ",appid); + if (!appid) { + return; + } + this.getAvailableRoles(appid); + } + + getAvailableRoles(appid){ + //console.log("getAvailableRoles called with appId :: ",appid); + if (appid != null && appid >0) { + this.functionalMenuService.getManagedRolesMenu(appid) + .subscribe(rolesObj => { + this.availableRoles = rolesObj; + if(this.availableRoles && this.availableRoles.length >0){ + this.hideRoleField = false; + } + this.preSelectedRoles = {roles:[]}; + this.preSelectedRoles = {roles:[]}; + + if((this.isEditMode) && this.isMidLevelMenuItem(this.nodedata)){ + // in Edit flow , for Midlevel menu item no need to preSelect. + this.preSelectedRoles = {roles:[]}; + }else if(this.nodedata && this.isEditMode && this.isLeafMenuItem(this.nodedata) && this.nodedata.appid!=appid) { + // in Edit flow , for LeafMenuItem, if appid changed then no need to preSelect. + this.preSelectedRoles = {roles:[]}; + }else{ + if(this.nodedata && this.nodedata.roles){ + for(var i=0; i< this.nodedata.roles.length; i++){ + var role = {"roleId": this.nodedata.roles[i]}; + this.preSelectedRoles.roles.push(role); + } + } + } + + if(this.nodedata.rolesObj){ + for(var i=0; i< this.nodedata.rolesObj.length;i++){ + //this.availableRoles[i].isApplied = false; + for(var j=0;j<this.preSelectedRoles.roles.length;j++){ + if(this.preSelectedRoles.roles[j].roleId==this.availableRoles[i].roleId){ + this.availableRoles[i].isApplied=true; + this.nodedetails.selectedRole = (this.preSelectedRoles.roles[j]) ? this.preSelectedRoles.roles[j] : 0; + break; + } + } + } + } + }, error =>{ + console.log(error); + let errorMsg = 'There was an error while gettting available roles. ' + error.message; + this.openConfirmationModal("",errorMsg); + return; + }); + //console.log("this.availableRoles >>>>>",this.availableRoles); + }else{ + console.log("FunctionalMenuDialogComponent::getAvailableRoles: appid was null or -1"); + } + } + + getAvailableApps(){ + this.isAllApplications = true; + this.functionalMenuService.getAvailableApplications() + .subscribe(apps => { + this.availableApps = apps; + if (this.nodedetails && this.nodedetails.index) { + for (var i = 0; i < this.availableApps.length; i++) { + if (apps[i].index === this.nodedetails.index) { + //console.log("MenuDetailsModalCtrl::getAvailableApps: found app with index: " + this.nodedetails.index); + //console.log("MenuDetailsModalCtrl::getAvailableApps: setting isDisabled to: " + !apps[i].enabled); + this.nodedetails.isDisabled = !apps[i].enabled; + break; + } + } + //console.log("didn't find index: " + this.nodedetails.index); + } + }, error =>{ + console.log(error); + this.isAllApplications = false; + let errorMsg = 'There was a problem retrieving the Applications. '+error.message; + this.openConfirmationModal("Error",errorMsg); + }); + } + + isLeafMenuItem(menu: any){ + return menu.children.length>0 ? false : true; + } + + isMidLevelMenuItem(menu: any){ + return menu.parentMenuId!=null && menu.children.length>0 ? true : false; + } + + isParentMenuItem(menu: any){ + return menu.parentMenuId!=null ? false : true; + }; + + isRoleSelected(){ + var selectedRoleIds=[]; + for(var i=0;i<this.availableRoles.length;i++){ + if(this.availableRoles[i].isApplied){ + selectedRoleIds.push(this.availableRoles[i].roleId); + return true; + } + } + return false; + } + + getDialogTitle = (source) => { + switch (source) { + case 'edit': + return "Functional Menu - Edit"; + case 'view': + return "Functional Menu - View"; + case 'add': + return "Functional Menu - Add"; + default: + return "Functional Menu"; + }; + } + + saveChanges(){ + if(!this.nodedetails.menuLocation || !this.nodedetails.name + || !this.nodedetails.url || !this.nodedetails.selectedAppIndex + || !this.nodedetails.selectedAppIndex || !this.nodedetails.selectedRole){ + this.openConfirmationModal("","All fields are mandatory, please provide inputs for all the fields."); + return; + } + /* + if(!!this.nodedetails.url && (!this.selectedApp || this.selectedAppIndex <=0)) { + this.openConfirmationModal("","Please select the appropriate app, or remove the url"); + return; + }else if(!this.nodedetails.url && (this.selectedApp) && this.selectedApp.index>0){ + this.openConfirmationModal("","Please enter url, or select No Application"); + return; + }else if(!this.nodedetails.menutitle){ + this.openConfirmationModal("","Please enter the Menu title"); + return; + } + */ + + if(this.isAddItemMode){ + if(this.selectedItem != null && this.selectedItem.getLevel() >= 4){ + this.openConfirmationModal("","You are not allowed to have a menu item at a level greater than 4."); + return ; + }else{ + let data = null; + let selectedMenuDetails = null; + this.functionalMenuService.getFunctionalMenu(this.selectedItem.menuId) + .subscribe(_data => { + selectedMenuDetails = _data + if((this.selectedItem.children===null || this.selectedItem.children.length == 0) && (!!selectedMenuDetails.url + || !!selectedMenuDetails.appid || !!selectedMenuDetails.roles)){ + let warning_message = 'Warning: the child menu item "' + + this.selectedItem.name + '" is already configured with an application. You can create a new mid-level menu item.'; + this.openConfirmationModal("",warning_message); + return; + }else{ + if(this.selectedItem){ + var selectedRoleIds=[]; + //console.log("Selected Role ID ; ",this.nodedetails.selectedRole); + if(this.nodedetails.selectedRole){ + selectedRoleIds.push(this.nodedetails.selectedRole); + } + + let applicationid: any = null; + if(!this.nodedata){ + applicationid = null; + }else{ + applicationid = this.nodedata.appid; + } + var newMenuItem = { + menuId:null, // this is a new menu item + column:this.nodedata.column, + text:this.nodedetails.name, + // We are creating this new menu item under the menu item that was clicked on. + parentMenuId:this.nodedata.menuId, + url:(this.nodedetails.url) ? this.nodedetails.url : null, + appid:(this.nodedetails.selectedAppIndex) ? this.nodedetails.selectedAppIndex: null, + roles:selectedRoleIds + }; + //console.log("Add menu Item newMenuItem :: ",newMenuItem) + this.functionalMenuService.saveMenuItem(newMenuItem) + .subscribe(_data => { + this.result = _data + //console.log("add menu item response :: ",_data); + this.passEntry.emit(this.result); + let successMsg = "Item added successfully"; + this.openConfirmationModal("Success",successMsg); + }, error =>{ + console.log(error); + if(error.status === 409){//Conflict + this.handleConflictErrors(error); + } else { + let errorMsg = "There was a problem saving your menu. Please try again later. Error Status: "+error.status + this.openConfirmationModal("",errorMsg); + return; + } + }); + } + } + }, error =>{ + //console.log(error); + let errorMsg = "There was a problem saving your menu. Please try again later. Error Status: "+error.status + this.openConfirmationModal("",errorMsg ); + return; + }); + } + }else{ + //edit mode.. + //console.log('MenuDetailsModalCtrl::saveChanges: Will be saving an edit menu item'); + var selectedRoleIds=[]; + //console.log("Selected Role ID ---->>>> ",this.nodedetails.selectedRole); + if(this.nodedetails.selectedRole){ + selectedRoleIds.push(this.nodedetails.selectedRole); + } + let activeMenuItem = { + menuId:this.nodedata.menuId, + column:this.nodedata.column, + text:this.nodedetails.name, + parentMenuId:this.nodedata.parentMenuId, + url:(this.nodedetails.url) ? this.nodedetails.url : null, + appid: (this.nodedetails.selectedAppIndex) ? this.nodedetails.selectedAppIndex: null, + roles:selectedRoleIds + }; + if ((activeMenuItem.appid==null && activeMenuItem.url=="") || (activeMenuItem.appid==null && activeMenuItem.url=="undefined")) { + activeMenuItem.roles = null; + } + //console.log("Update menu Item activeMenuItem :: ",activeMenuItem); + this.functionalMenuService.saveEditedMenuItem(activeMenuItem) + .subscribe(_data => { + this.result = _data + //console.log("Edit menu item response :: ",_data); + this.passEntry.emit(this.result); + let successMsg = "Item updated successfully"; + this.openConfirmationModal("Success",successMsg); + //this.ngbModal.dismissAll(); + }, error =>{ + //console.log(error); + let errorMsg = "There was a problem updating your menu. Please try again later. Error Status: "+error.status; + this.openConfirmationModal("",errorMsg); + return; + }); + } + } + + //This part handles conflict errors (409) + handleConflictErrors(error){ + if(!error.data){ + return; + } + if(!error.data.length){ //support objects + error.data = [error.data] + } + //console.log('MenuDetailsModalCtrl::handleConflictErrors: err.data = ' + JSON.stringify(error.data)); + if(error.data){ + error.data.forEach(item => { + //set conflict message + this.conflictMessages[item.field.name] = item.errorCode; + //set field as invalid + //console.log('MenuDetailsModalCtrl::handleConflictErrors: fieldName = ' + item.field.name); + this.functionalMenuForm[item.field.name].$setValidity('conflict', false); + }); + } + } + + openConfirmationModal(_title: string, _message: string) { + const modalInfoRef = this.ngbModal.open(ConfirmationModalComponent); + modalInfoRef.componentInstance.title = _title; + modalInfoRef.componentInstance.message = _message; + } + + openInformationModal(_title: string, _message: string){ + const modalInfoRef = this.ngbModal.open(InformationModalComponent); + modalInfoRef.componentInstance.title = _title; + modalInfoRef.componentInstance.message = _message; + return modalInfoRef; + } +} diff --git a/portal-FE-common/src/app/pages/functional-menu/functional-menu.component.html b/portal-FE-common/src/app/pages/functional-menu/functional-menu.component.html new file mode 100644 index 00000000..d898563b --- /dev/null +++ b/portal-FE-common/src/app/pages/functional-menu/functional-menu.component.html @@ -0,0 +1,52 @@ +<!-- + ============LICENSE_START========================================== + ONAP Portal + =================================================================== + 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 id="title" class="w-onap-main-view-title"> + <h1 class="heading-page">Edit Functional Menu</h1> + </div> + <div id="jqTree"></div> + <div class="functional-admin-button-container"> + <button id="regenrate-functionalmenu-btn" + class="btn btn-alt btn-small" + (click)="regenerateFunctionalMenuAncestors()">Regenerate Menu + </button> + <div class="regenerate-functionalmenu-btn-txt"> + <span class="n16r">Click when you are done with your changes.</span> + </div> + </div> +</div> diff --git a/portal-FE-common/src/app/pages/functional-menu/functional-menu.component.scss b/portal-FE-common/src/app/pages/functional-menu/functional-menu.component.scss new file mode 100644 index 00000000..c716252e --- /dev/null +++ b/portal-FE-common/src/app/pages/functional-menu/functional-menu.component.scss @@ -0,0 +1,95 @@ +/*- + * ============LICENSE_START========================================== + * ONAP Portal + * =================================================================== + * 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============================================ + * + * + */ + +.functional-menu-main { + background-color: #fff; + position: fixed; + top: 105px; + left: 0; + right: 0; + bottom: 75px; + padding-top: 10px; + overflow-y: scroll; + padding-left: 0; +} + +.functional-menu-main .functional-menu-container { + position: relative; + padding-right: 0; + padding-left: 0; + padding-bottom: 32px; + background-color: #fff; +} + +.w-ecomp-main-view-title { + color: #191919; + font-family: Omnes-ECOMP-W02-Medium,Arial; + font-size: 24px; + width: 1170px; + padding-bottom: 15px; + margin: auto; +} + +.functional-menu-main .functional-menu-container .tree { + margin: auto; + width: 1170px; + font-size: 16px; +} + +.functional-admin-button-container { + padding-top: 10px; + width: 1170px; + margin: auto; +} + +.btn-small { + padding: 10px 19px 9px 18px; + font-size: 1.5rem; + border-radius: 8px; +} + +.btn-alt { + border-color: #087ac2 transparent #0568ae; + background-color: #0568ae; + background: linear-gradient(to bottom, #087ac2 0%, #0568ae 100%); + color: #ffffff; +} + +.functional-menu-main .regenerate-functionalmenu-btn-txt { + color: #000; +} diff --git a/portal-FE-common/src/app/pages/functional-menu/functional-menu.component.spec.ts b/portal-FE-common/src/app/pages/functional-menu/functional-menu.component.spec.ts new file mode 100644 index 00000000..c5c562ed --- /dev/null +++ b/portal-FE-common/src/app/pages/functional-menu/functional-menu.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { FunctionalMenuComponent } from './functional-menu.component'; + +describe('FunctionalMenuComponent', () => { + let component: FunctionalMenuComponent; + let fixture: ComponentFixture<FunctionalMenuComponent>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ FunctionalMenuComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(FunctionalMenuComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/portal-FE-common/src/app/pages/functional-menu/functional-menu.component.ts b/portal-FE-common/src/app/pages/functional-menu/functional-menu.component.ts new file mode 100644 index 00000000..655b4cb4 --- /dev/null +++ b/portal-FE-common/src/app/pages/functional-menu/functional-menu.component.ts @@ -0,0 +1,192 @@ +/*- + * ============LICENSE_START========================================== + * ONAP Portal + * =================================================================== + * 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 } from '@angular/core'; +import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; +import { FunctionalMenuService } from 'src/app/shared/services'; +import { ConfirmationModalComponent } from 'src/app/modals/confirmation-modal/confirmation-modal.component'; +import { FunctionalMenuDialogComponent } from './functional-menu-dialog/functional-menu-dialog.component'; + + +@Component({ + selector: 'app-functional-menu', + templateUrl: './functional-menu.component.html', + styleUrls: ['./functional-menu.component.scss'] +}) +export class FunctionalMenuComponent implements OnInit { + + result: any; + functionalMenu: any = []; + treedata = []; + isEditMode: boolean; + operationName: string; + self: any; + constructor(public functionalMenuService : FunctionalMenuService, public ngbModal: NgbModal) { } + + ngOnInit() { + this.self = this; + this.functionalMenu = []; + this.getFunctionalMenu(); + + } + + /** + * regenerateFunctionalMenuAncestors + */ + regenerateFunctionalMenuAncestors(){ + this.functionalMenuService.regenerateFunctionalMenuAncestors() + .subscribe(_data => { + this.result = _data + if(this.result){ + const modalRef = this.ngbModal.open(ConfirmationModalComponent); + modalRef.componentInstance.title = ""; + modalRef.componentInstance.message = 'You have successfully regenerated the menu.'; + modalRef.result.then((result) => { }, (resut) => {return;}); + this.getFunctionalMenu(); + } + }, error =>{ + console.log(error); + const modalRef = this.ngbModal.open(ConfirmationModalComponent); + modalRef.componentInstance.title = ""; + modalRef.componentInstance.message = 'There was an error while regenerating the menu.'; + modalRef.result.then((result) => { }, (resut) => {return;}); + }); + } + + /** + * getFunctionalMenu + */ + getFunctionalMenu(){ + let actualData=[]; + this.functionalMenuService.getManagedFunctionalMenu() + .subscribe(_data => { + this.result = _data; + if(this.result){ + for(let i = 0; i < this.result.length; i++){ + this.result[i].children=[]; + this.result[i].label= this.result[i].text; + this.result[i].id= this.result[i].text; + } + //Adding actual child items to children array in res objects + for(let i = 0; i < this.result.length; i++){ + let parentId=this.result[i].menuId; + for(let j = 0; j < this.result.length; j++){ + let childId=this.result[j].parentMenuId; + if(parentId===childId){ + this.result[i].children.push(this.result[j]); + } + } + } + // Sort the top-level menu items in order based on the column + this.result.sort(function(a, b) { + return a.column-b.column; + }); + + // Sort all the children in order based on the column + for(let i = 0; i < this.result.length; i++){ + this.result[i].children.sort(function(a, b){ + return a.column-b.column; + }); + } + + //Forming actual parent items + for(let i = 0; i < this.result.length; i++){ + let parentId= this.result[i].parentMenuId; + if(parentId===null){ + actualData.push( this.result[i]); + } + } + + this.treedata = actualData; + //console.log("this.treedata :: ",this.treedata); + + if(this.treedata){ + this.buildTree(this.treedata,this.ngbModal, this.self); + } + + } + }, error =>{ + console.log(error); + }); + + } + + /** + * buildTree + * @param treedataarray + * @param ngbModal + */ + buildTree(treedataarray,ngbModal: NgbModal , _self){ + //console.log("treedataarray>>>>",treedataarray); + $(function() { + $('#jqTree').tree('loadData', treedataarray); + $('#jqTree').tree({ + data: treedataarray, + autoOpen: false, + dragAndDrop: true, + onCreateLi: function(node, $li) { + ////console.log("node >>",node); + } + }).on( + 'tree.contextmenu', + function(event:any) { + // The clicked node is 'event.node' + var node = event.node; + openMenuDetailsModal(node, "view"); + } + ); + + var openMenuDetailsModal = function(node: any, actionName: string ){ + const modalRef = ngbModal.open(FunctionalMenuDialogComponent, { size: 'lg' }); + modalRef.componentInstance.title = 'Functional Menu ',actionName; + if(node != 'undefined' && node){ + modalRef.componentInstance.nodedata = node; + modalRef.componentInstance.operationName = actionName; + }else{ + modalRef.componentInstance.nodedata = {}; + } + modalRef.componentInstance.passEntry.subscribe((receivedEntry: any) => { + //console.log("receivedEntry>>>>",receivedEntry); + ngbModal.dismissAll(); + if(receivedEntry.httpStatusCode===200){ + _self.getFunctionalMenu(); + } + }); + } + }); + } +} diff --git a/portal-FE-common/src/app/pages/functional-menu/jqTreeContextMenu.js b/portal-FE-common/src/app/pages/functional-menu/jqTreeContextMenu.js new file mode 100644 index 00000000..fa240187 --- /dev/null +++ b/portal-FE-common/src/app/pages/functional-menu/jqTreeContextMenu.js @@ -0,0 +1,195 @@ +(function ($) { + if (!$.fn.tree) { + throw "Error jqTree is not loaded."; + } + + $.fn.jqTreeContextMenu = function (menuElement, callbacks) { + // + // TODO: + // * Make sure the useContextMenu option is set in jqTree, either complain or set it automatically + // * Make menu fade in/out + // + var self = this; + var $el = this; + + // The jQuery object of the menu div. + var $menuEl = menuElement; + + // This hash holds all menu items that should be disabled for a specific node. + var nodeToDisabledMenuItems = {}; + + // Hide the menu div. + $menuEl.hide(); + + // Disable system context menu from beeing displayed. + $el.bind("contextmenu", function (e) { + e.preventDefault(); + return false; + }); + + // Handle the contextmenu event sent from jqTree when user clicks right mouse button. + $el.bind('tree.contextmenu', function (event) { + var x = event.click_event.pageX; + var y = event.click_event.pageY; + var yPadding = 5; + var xPadding = 5; + var menuHeight = $menuEl.height(); + var menuWidth = $menuEl.width(); + var windowHeight = $(window).height(); + var windowWidth = $(window).width(); + + if (menuHeight + y + yPadding > windowHeight) { + // Make sure the whole menu is rendered within the viewport. + y = y - menuHeight; + } + if (menuWidth + x + xPadding > windowWidth) { + // Make sure the whole menu is rendered within the viewport. + x = x - menuWidth; + } + + // Handle disabling and enabling of menu items on specific nodes. + if (Object.keys(nodeToDisabledMenuItems).length > 0) { + if (event.node.name in nodeToDisabledMenuItems) { + var nodeName = event.node.name; + var items = nodeToDisabledMenuItems[nodeName]; + if (items.length === 0) { + $menuEl.find('li').addClass('disabled'); + $menuEl.find('li > a').unbind('click'); + } else { + $menuEl.find('li > a').each(function () { + $(this).closest('li').removeClass('disabled'); + var hrefValue = $(this).attr('href'); + var value = hrefValue.slice(hrefValue.indexOf("#") + 1, hrefValue.length) + if ($.inArray(value, items) > -1) { + $(this).closest('li').addClass('disabled'); + $(this).unbind('click'); + } + }); + } + } else { + $menuEl.find('li.disabled').removeClass('disabled'); + } + } + + // Must call show before we set the offset (offset can not be set on display: none elements). + $menuEl.show(); + + $menuEl.offset({ left: x, top: y }); + + var dismissContextMenu = function () { + $(document).unbind('click.jqtreecontextmenu'); + $el.unbind('tree.click.jqtreecontextmenu'); + $menuEl.hide(); + } + // Make it possible to dismiss context menu by clicking somewhere in the document. + $(document).bind('click.jqtreecontextmenu', function () { + dismissContextMenu(); + }); + + // Dismiss context menu if another node in the tree is clicked. + $el.bind('tree.click.jqtreecontextmenu', function (e) { + dismissContextMenu(); + }); + + // Make selection follow the node that was right clicked on. + var selectedNode = $el.tree('getSelectedNode'); + if (selectedNode !== event.node) { + $el.tree('selectNode', event.node); + } + + // Handle click on menu items, if it's not disabled. + var menuItems = $menuEl.find('li:not(.disabled) a'); + if (menuItems.length !== 0) { + menuItems.unbind('click'); + menuItems.click(function (e) { + e.stopImmediatePropagation(); + dismissContextMenu(); + var hrefAnchor = e.currentTarget.attributes.href.nodeValue; + var funcKey = hrefAnchor.slice(hrefAnchor.indexOf("#") + 1, hrefAnchor.length) + var callbackFn = callbacks[funcKey]; + if (callbackFn) { + callbackFn(event.node); + } + return false; + }); + } + }); + + this.disable = function () { + if (arguments.length === 0) { + // Called as: api.disable() + $menuEl.find('li:not(.disabled)').addClass('disabled'); + $menuEl.find('li a').unbind('click'); + nodeToDisabledMenuItems = {}; + } else if (arguments.length === 1) { + // Called as: api.disable(['edit','remove']) + var items = arguments[0]; + if (typeof items !== 'object') { + return; + } + $menuEl.find('li > a').each(function () { + var hrefValue = $(this).attr('href'); + var value = hrefValue.slice(hrefValue.indexOf("#") + 1, hrefValue.length) + if ($.inArray(value, items) > -1) { + $(this).closest('li').addClass('disabled'); + $(this).unbind('click'); + } + }); + nodeToDisabledMenuItems = {}; + } else if (arguments.length === 2) { + // Called as: api.disable(nodeName, ['edit','remove']) + var nodeName = arguments[0]; + var items = arguments[1]; + nodeToDisabledMenuItems[nodeName] = items; + } + }; + + this.enable = function () { + if (arguments.length === 0) { + // Called as: api.enable() + $menuEl.find('li.disabled').removeClass('disabled'); + nodeToDisabledMenuItems = {}; + } else if (arguments.length === 1) { + // Called as: api.enable(['edit','remove']) + var items = arguments[0]; + if (typeof items !== 'object') { + return; + } + + $menuEl.find('li > a').each(function () { + var hrefValue = $(this).attr('href'); + var value = hrefValue.slice(hrefValue.indexOf("#") + 1, hrefValue.length) + if ($.inArray(value, items) > -1) { + $(this).closest('li').removeClass('disabled'); + } + }); + + nodeToDisabledMenuItems = {}; + } else if (arguments.length === 2) { + // Called as: api.enable(nodeName, ['edit','remove']) + var nodeName = arguments[0]; + var items = arguments[1]; + if (items.length === 0) { + delete nodeToDisabledMenuItems[nodeName]; + } else { + var disabledItems = nodeToDisabledMenuItems[nodeName]; + for (var i = 0; i < items.length; i++) { + var idx = disabledItems.indexOf(items[i]); + if (idx > -1) { + disabledItems.splice(idx, 1); + } + } + if (disabledItems.length === 0) { + delete nodeToDisabledMenuItems[nodeName]; + } else { + nodeToDisabledMenuItems[nodeName] = disabledItems; + } + } + if (Object.keys(nodeToDisabledMenuItems).length === 0) { + $menuEl.find('li.disabled').removeClass('disabled'); + } + } + }; + return this; + }; +} (jQuery)); diff --git a/portal-FE-common/src/app/pages/portal-admins/new-portal-admin/new-portal-admin.component.html b/portal-FE-common/src/app/pages/portal-admins/new-portal-admin/new-portal-admin.component.html new file mode 100644 index 00000000..bdd99730 --- /dev/null +++ b/portal-FE-common/src/app/pages/portal-admins/new-portal-admin/new-portal-admin.component.html @@ -0,0 +1,54 @@ +<!-- + ============LICENSE_START========================================== + ONAP Portal + =================================================================== + 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">×</span> + </button> + </div> + <div class="modal-body"> + <app-search-users [searchTitle]="searchTitleText" [placeHolder]="placeholderText" (passBackSelectedUser)='changeSelectedUser($event)'></app-search-users> + </div> + <div class="modal-footer"> + <button type="submit" class="btn btn-primary" [disabled]='!changedSelectedUser' + (click)="addNewPortalAdmin(changedSelectedUser)">Save</button> + <button type="button" class="btn btn-primary" (click)="activeModal.close('Close')">Cancel</button> + </div> +</div>
\ No newline at end of file diff --git a/portal-FE-common/src/app/pages/portal-admins/new-portal-admin/new-portal-admin.component.scss b/portal-FE-common/src/app/pages/portal-admins/new-portal-admin/new-portal-admin.component.scss new file mode 100644 index 00000000..7a773398 --- /dev/null +++ b/portal-FE-common/src/app/pages/portal-admins/new-portal-admin/new-portal-admin.component.scss @@ -0,0 +1,37 @@ +/*- + * ============LICENSE_START========================================== + * ONAP Portal + * =================================================================== + * 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============================================ + * + * + */
\ No newline at end of file diff --git a/portal-FE-common/src/app/pages/portal-admins/new-portal-admin/new-portal-admin.component.spec.ts b/portal-FE-common/src/app/pages/portal-admins/new-portal-admin/new-portal-admin.component.spec.ts new file mode 100644 index 00000000..cd85fca1 --- /dev/null +++ b/portal-FE-common/src/app/pages/portal-admins/new-portal-admin/new-portal-admin.component.spec.ts @@ -0,0 +1,62 @@ +/*- + * ============LICENSE_START========================================== + * ONAP Portal + * =================================================================== + * 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 { NewPortalAdminComponent } from './new-portal-admin.component'; + +describe('NewPortalAdminComponent', () => { + let component: NewPortalAdminComponent; + let fixture: ComponentFixture<NewPortalAdminComponent>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ NewPortalAdminComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(NewPortalAdminComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/portal-FE-common/src/app/pages/portal-admins/new-portal-admin/new-portal-admin.component.ts b/portal-FE-common/src/app/pages/portal-admins/new-portal-admin/new-portal-admin.component.ts new file mode 100644 index 00000000..d5cde04b --- /dev/null +++ b/portal-FE-common/src/app/pages/portal-admins/new-portal-admin/new-portal-admin.component.ts @@ -0,0 +1,94 @@ +/*- + * ============LICENSE_START========================================== + * ONAP Portal + * =================================================================== + * 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, ModalDismissReasons } from '@ng-bootstrap/ng-bootstrap'; +import { PortalAdmin } from 'src/app/shared/model/PortalAdmin'; +import { PortalAdminsService } from 'src/app/shared/services'; +import { HttpErrorResponse } from '@angular/common/http'; +import { ConfirmationModalComponent } from 'src/app/modals/confirmation-modal/confirmation-modal.component'; +import { InformationModalComponent } from 'src/app/modals/information-modal/information-modal.component'; + +@Component({ + selector: 'app-new-portal-admin', + templateUrl: './new-portal-admin.component.html', + styleUrls: ['./new-portal-admin.component.scss'] +}) +export class NewPortalAdminComponent implements OnInit { + + constructor(public activeModal: NgbActiveModal, private portalAdminsService: PortalAdminsService, + public ngbModal: NgbModal) { } + @Input() title: string; + @Input() id: number; + changedSelectedUser: PortalAdmin; + closeResult: string; + searchTitleText = 'Enter First Name, Last Name or Org User Id'; + placeholderText = 'Search'; + @Output() passBackNewPortalAdmin: EventEmitter<any> = new EventEmitter(); + + ngOnInit() { + } + + changeSelectedUser(user: PortalAdmin) { + this.changedSelectedUser = user; + } + + addNewPortalAdmin(changedSelectedUser: PortalAdmin) { + const modalRef = this.ngbModal.open(InformationModalComponent); + modalRef.componentInstance.title = "Admin Update"; + modalRef.componentInstance.message = `Are you sure you want to add ${changedSelectedUser.firstName} ${changedSelectedUser.lastName} as a Portal Admin?`; + modalRef.result.then((result) => { + if (result === 'Ok') { + this.portalAdminsService.addPortalAdmin(this.changedSelectedUser.orgUserId).subscribe(_data => { + this.passBackNewPortalAdmin.emit(_data); + }, (_err: HttpErrorResponse) => { + this.passBackNewPortalAdmin.emit(_err); + const modalErrorRef = this.ngbModal.open(ConfirmationModalComponent); + modalErrorRef.componentInstance.title = "Error"; + if (_err.status === 409) { //Conflict + modalErrorRef.componentInstance.message = "This user already exists as a portal admin!"; + } else { + modalErrorRef.componentInstance.message = "There was a unknown problem adding the portal admin." + "Please try again later. Error Status: " + _err.status; + } + }); + } + }, (reason) => { + return; + }); + + } +} diff --git a/portal-FE-common/src/app/pages/portal-admins/portal-admins.component.html b/portal-FE-common/src/app/pages/portal-admins/portal-admins.component.html new file mode 100644 index 00000000..26e59e45 --- /dev/null +++ b/portal-FE-common/src/app/pages/portal-admins/portal-admins.component.html @@ -0,0 +1,87 @@ +<!-- + ============LICENSE_START========================================== + ONAP Portal + =================================================================== + 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="onap-main-view-title"> + <h1 class="heading-page">Portal Admins</h1> + </div> + <mat-form-field> + <input matInput type="text" (keyup)="applyFilter($event.target.value)" placeholder="Search in entire table"> + </mat-form-field> + + <button type="button" class="btn btn-primary" (click)="addPortalAdminEntry()"><i class="icon ion-md-person-add"></i> + Add Portal Admin</button> + + <span class="onap-spinner" *ngIf="showSpinner"></span> + <table mat-table [dataSource]="dataSource" matSort> + <!-- First Name Column --> + <ng-container matColumnDef="firstName"> + <th id="col1" mat-header-cell *matHeaderCellDef mat-sort-header> First Name </th> + <td id="rowheader_t1_{{i}}-firstName" mat-cell *matCellDef="let element; let i = index;"> {{element.firstName}} + </td> + </ng-container> + + <!-- Last Name Column --> + <ng-container matColumnDef="lastName"> + <th id="col2" mat-header-cell *matHeaderCellDef mat-sort-header> Last Name </th> + <td id="rowheader_t1_{{i}}-lastName" mat-cell *matCellDef="let element; let i=index;"> {{element.lastName}} + </td> + </ng-container> + + <!-- User ID Column --> + <ng-container matColumnDef="loginId"> + <th id="col3" mat-header-cell *matHeaderCellDef mat-sort-header> User ID </th> + <td id="rowheader_t1_{{$index}}-loginId" mat-cell *matCellDef="let element; let i=index;"> {{element.loginId}} + </td> + </ng-container> + + <!-- Delete Column --> + <ng-container matColumnDef="delete"> + <th id="col4" mat-header-cell *matHeaderCellDef> Delete </th> + <td id="rowheader_t1_{{i}}" mat-cell *matCellDef="let element; let i=index;"> + <span class="icon-trash" id="{{i}}-button-portal-admin-remove" (click)="removePortalAdmin(element)"> + <i class="icon ion-md-trash"></i> + </span> + </td> + </ng-container> + + <tr [hidden]="portalAdmins.length === 0" mat-header-row *matHeaderRowDef="displayedColumns"></tr> + <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr> + </table> + <mat-paginator [hidden]="portalAdmins.length === 0" [pageSizeOptions]="[10, 20]" showFirstLastButtons></mat-paginator> +</div>
\ No newline at end of file diff --git a/portal-FE-common/src/app/pages/portal-admins/portal-admins.component.scss b/portal-FE-common/src/app/pages/portal-admins/portal-admins.component.scss new file mode 100644 index 00000000..4c65595a --- /dev/null +++ b/portal-FE-common/src/app/pages/portal-admins/portal-admins.component.scss @@ -0,0 +1,43 @@ +/*- + * ============LICENSE_START========================================== + * ONAP Portal + * =================================================================== + * 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 '../pages.component'; + +.icon-trash{ + cursor: pointer; + font-size: 20px; +} diff --git a/portal-FE-common/src/app/pages/portal-admins/portal-admins.component.spec.ts b/portal-FE-common/src/app/pages/portal-admins/portal-admins.component.spec.ts new file mode 100644 index 00000000..0e3c969f --- /dev/null +++ b/portal-FE-common/src/app/pages/portal-admins/portal-admins.component.spec.ts @@ -0,0 +1,62 @@ +/*- + * ============LICENSE_START========================================== + * ONAP Portal + * =================================================================== + * 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 { PortalAdminsComponent } from './portal-admins.component'; + +describe('PortalAdminsComponent', () => { + let component: PortalAdminsComponent; + let fixture: ComponentFixture<PortalAdminsComponent>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ PortalAdminsComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(PortalAdminsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/portal-FE-common/src/app/pages/portal-admins/portal-admins.component.ts b/portal-FE-common/src/app/pages/portal-admins/portal-admins.component.ts new file mode 100644 index 00000000..5dfe026d --- /dev/null +++ b/portal-FE-common/src/app/pages/portal-admins/portal-admins.component.ts @@ -0,0 +1,124 @@ +/*- + * ============LICENSE_START========================================== + * ONAP Portal + * =================================================================== + * 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 { OnInit, Component, ViewChild, NgModuleRef } from '@angular/core'; +import { MatSort, MatPaginator } from '@angular/material'; +import { MatTableDataSource } from '@angular/material'; +import { PortalAdminsService } from 'src/app/shared/services'; +import { NgbModal, ModalDismissReasons } from '@ng-bootstrap/ng-bootstrap'; +import { NewPortalAdminComponent } from './new-portal-admin/new-portal-admin.component'; +import { InformationModalComponent } from 'src/app/modals/information-modal/information-modal.component'; +import { PortalAdmin } from 'src/app/shared/model/PortalAdmin'; +import { HttpErrorResponse } from '@angular/common/http'; +import { ConfirmationModalComponent } from 'src/app/modals/confirmation-modal/confirmation-modal.component'; + +@Component({ + selector: 'app-portal-admins', + templateUrl: './portal-admins.component.html', + styleUrls: ['./portal-admins.component.scss'] +}) +export class PortalAdminsComponent implements OnInit { + portalAdmins: PortalAdmin[] = []; + showSpinner = true; + closeResult: string; + constructor(private portalAdminsService: PortalAdminsService, private ngbModal: NgbModal) { } + displayedColumns: string[] = ['firstName', 'lastName', 'loginId', 'delete']; + dataSource = new MatTableDataSource(this.portalAdmins); + @ViewChild(MatSort) sort: MatSort; + @ViewChild(MatPaginator) paginator: MatPaginator; + ngOnInit() { + this.getAllPortalAdmins(); + } + + getAllPortalAdmins() { + this.portalAdminsService.getPortalAdmins().subscribe((_data: PortalAdmin[]) => { + this.showSpinner = false; + // _data is the array of data that you getting from the db. + this.portalAdmins = _data; + this.dataSource = new MatTableDataSource(this.portalAdmins); + this.dataSource.sort = this.sort; + this.dataSource.paginator = this.paginator; + }, (_err: HttpErrorResponse) =>{ + const modalErrorRef = this.ngbModal.open(ConfirmationModalComponent); + modalErrorRef.componentInstance.title = "Error"; + if (_err.status) { //Conflict + modalErrorRef.componentInstance.message = 'Error Status: ' + _err.status + ' There was a unknown problem adding the portal admin.' + 'Please try again later.'; + } + }) + } + + applyFilter(filterValue: string) { + this.dataSource.filter = filterValue.trim().toLowerCase(); + } + + addPortalAdminEntry() { + const modalRef = this.ngbModal.open(NewPortalAdminComponent); + modalRef.componentInstance.title = 'Add Portal Admin'; + modalRef.componentInstance.id = 1; + modalRef.componentInstance.passBackNewPortalAdmin.subscribe((_result: any) => { + modalRef.close(); + this.showSpinner = true; + this.getAllPortalAdmins(); + }) + } + + removePortalAdmin(deletePortalAdmin: any) { + const modalRef = this.ngbModal.open(InformationModalComponent); + modalRef.componentInstance.title = 'Confirmation'; + modalRef.componentInstance.message = `Are you sure you want to delete ${deletePortalAdmin.firstName} ${deletePortalAdmin.lastName} ?`; + modalRef.result.then((result) => { + if (result === 'Ok') { + this.portalAdminsService.removePortalAdmin(deletePortalAdmin.userId, deletePortalAdmin.loginId).subscribe(_data => { + this.showSpinner = true; + this.getAllPortalAdmins(); + }) + } + }, (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}`; + } + } +}
\ No newline at end of file |