diff options
Diffstat (limited to 'portal-FE-common/src/app/pages/user-notification-admin')
8 files changed, 1676 insertions, 0 deletions
diff --git a/portal-FE-common/src/app/pages/user-notification-admin/new-notification-modal/new-notification-modal.component.html b/portal-FE-common/src/app/pages/user-notification-admin/new-notification-modal/new-notification-modal.component.html new file mode 100644 index 00000000..b4325dbd --- /dev/null +++ b/portal-FE-common/src/app/pages/user-notification-admin/new-notification-modal/new-notification-modal.component.html @@ -0,0 +1,168 @@ +<!-- + ============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"> + <!--Modal Headers--> + <div class="modal-header"> + <h4 class="modal-title">Add a New Notification</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" [ngClass]="{'disable-div': (isEditMode)}"> + <div class="user-notification-details-contents"> + <!-- Left Side container--> + <div class="left-container"> + <div id="add-user-notif-broadcast" class="add-widget-field"> + <div class="user-notif-label" style="padding-bottom: 7px">Broadcast to All Categories</div> + <mat-radio-group [(ngModel)]="notification.isForAllRoles" #radioGroup="matRadioGroup" aria-label="Select an option"> + <span style="padding-left: 12px;"><mat-radio-button value="Y">Yes</mat-radio-button></span><br/> + <span style="padding-left: 12px;"><mat-radio-button value="N">No</mat-radio-button></span> + </mat-radio-group> + <div style="padding-bottom: 12px;"></div> + + <div class="categories-selection" [ngClass]="{'disable-category-selection': (!notification.isForAllRoles ||notification.isForAllRoles=='Y')}"> + <div [ngClass]="{'required': (notification.isForAllRoles=='N')}" style="padding-bottom: 7px"> + Categories + </div> + <mat-radio-group [(ngModel)]="notification.isFunctionalMenu" #radioGroup="matRadioGroup" aria-label="Select an option"> + <span style="padding-left: 12px;"><mat-radio-button (click)="getFunctionalMenu()" value="Y">Functional Menu</mat-radio-button></span><br/> + <span style="padding-left: 12px;"><mat-radio-button (click)="getAppRoleIds()" value="N">Application Roles</mat-radio-button></span> + </mat-radio-group> + <br/> + <div id="user-notif-tree-div" class="tree-div" > + <!-- Mat Tree code will goes here..--> + <mat-tree [dataSource]="dataSource" [treeControl]="treeControl"> + <mat-tree-node *matTreeNodeDef="let node" matTreeNodeToggle matTreeNodePadding> + <button mat-icon-button disabled></button> + <mat-checkbox class="checklist-leaf-node" + [checked]="checklistSelection.isSelected(node)" + (change)="checklistSelection.toggle(node);">{{node.item}}</mat-checkbox> + </mat-tree-node> + + <mat-tree-node *matTreeNodeDef="let node; when: hasNoContent" matTreeNodePadding> + <button mat-icon-button disabled></button> + </mat-tree-node> + + <mat-tree-node *matTreeNodeDef="let node; when: hasChild" matTreeNodePadding> + <button mat-icon-button matTreeNodeToggle + [attr.aria-label]="'toggle ' + node.filename"> + <mat-icon class="mat-icon-rtl-mirror"> + {{treeControl.isExpanded(node) ? 'expand_more' : 'chevron_right'}} + </mat-icon> + </button> + <mat-checkbox + [indeterminate]="descendantsPartiallySelected(node)" + (change)="todoItemSelectionToggle(node)">{{node.item}} + </mat-checkbox> + </mat-tree-node> + </mat-tree> + </div> + </div> + </div> + </div> + + <!-- Right Side container--> + <div id="app-conatiner-right" class="right-container"> + <div id="add-user-notif-priority" class="add-widget-field"> + <div id="user-notification-priority-label" class="user-notif-label">Priority</div> + <mat-radio-group [(ngModel)]="notification.priority" #radioGroup="matRadioGroup" aria-label="Select an option"> + <span><mat-radio-button value="1">Normal</mat-radio-button></span><br/> + <span><mat-radio-button value="2">Important</mat-radio-button></span> + </mat-radio-group> + </div> + <div id="add-user-notif-startdate" class="add-widget-field" style="padding-bottom: 12px; width: 301px !important;"> + <div id="user-notification-startdate-label" class="user-notif-label"> + <div class="user-notif-label"> + <span runat="server" ID="required" class="notifcation-label-required">*</span>Start Date (Local Time) + </div> + <mat-form-field> + <input [(ngModel)]="notification.startTime" name="startTime" matInput [matDatepicker]="startdate" + placeholder="MM/dd/yyyy"> + <mat-datepicker-toggle matSuffix [for]="startdate"></mat-datepicker-toggle> + <mat-datepicker #startdate></mat-datepicker> + </mat-form-field> + <div class="user-notif-label"> + <span runat="server" ID="required" class="notifcation-label-required">*</span>End Date (Local Time) + </div> + <mat-form-field> + <input [(ngModel)]="notification.endTime" name="endTime" matInput [matDatepicker]="enddate" + placeholder="MM/dd/yyyy"> + <mat-datepicker-toggle matSuffix [for]="enddate"></mat-datepicker-toggle> + <mat-datepicker #enddate></mat-datepicker> + </mat-form-field> + </div> + </div> + + <div id="add-user-notif-title" class="add-widget-field" style="padding-bottom: 12px;"> + <div id="user-notification-title-label" class="user-notif-label"> + <span runat="server" ID="required" class="notifcation-label-required" visible="false"> *</span> Title + </div> + <textarea id="add-notification-input-title" + [(ngModel)]="notification.msgHeader" name="content" class="add-notification-input-title-ht"> + </textarea> + <div id="user-title-required"> + <small *ngIf="notification.msgHeader ==''" class="mandatory-categories">Title is Required</small> + </div> + </div> + + <div id="add-user-notif-message" class="add-widget-field" + style="padding-bottom: 12px;"> + <div id="user-notif-message-label" class="user-notif-label"> + <span runat="server" ID="required" class="notifcation-label-required" + visible="false"> *</span> Message + </div> + <textarea id="user-notif-input-message" class="add-notification-input-title-ht" + [(ngModel)]="notification.msgDescription" name="content"> + </textarea> + <div id="user-notif-message-required"> + <small *ngIf="notification.msgDescription ==''" class="mandatory-categories">Message is Required</small> + </div> + </div> + </div> + </div> + </div> + + <!--Modal Footer goes Here--> + <div class="modal-footer"> + <button type="button" [hidden]="isEditMode" class="btn btn-primary" (click)="addUserNotification('')">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/user-notification-admin/new-notification-modal/new-notification-modal.component.scss b/portal-FE-common/src/app/pages/user-notification-admin/new-notification-modal/new-notification-modal.component.scss new file mode 100644 index 00000000..0389b7da --- /dev/null +++ b/portal-FE-common/src/app/pages/user-notification-admin/new-notification-modal/new-notification-modal.component.scss @@ -0,0 +1,116 @@ +/*- + * ============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 .modal-body .user-notification-details-contents { + padding-left: 0; + padding-top: 16px; + padding-bottom: 16px; + height: 630px; + //overflow-y: auto; + margin-left: 10px; + padding-right: 100px; + margin-bottom: 5px; + color: #5a5a5a; + font-family: Omnes-ECOMP-W02,Arial; + font-size: 14px; + font-weight: 700; +} + +.container .modal-body .user-notification-details-contents .left-container { + display: inline-block; + width: 48%; +} + +.container .modal-body .user-notification-details-contents .right-container { + display: inline-block; + width: 39%; + float: right; +} +.mat-radio-button ~ .mat-radio-button { + margin-left: 16px; +} + +.add-widget-field { + width: 250px; + display: inline-table; + margin: 10px; +} + +.container .modal-body .user-notification-details-contents .right-container .add-notification-input-title-ht{ + width: 284px; + height: 76px; +} + +::ng-deep .modal-dialog { + max-width: 800px; + width: 800px; +} + + +::ng-deep .mat-form-field { + width: 279px; +} + +.tree-div { + height: 308px; + width: 320px; + overflow: auto; +} + +.disable-category-selection{ + opacity: 0.6; + pointer-events: none; +} + +.disable-div{ + opacity: 0.6; + pointer-events: none; +} + +.required::before { + color: #cf2a2a; + margin-right: 2px; + content: "* "; + position: absolute; + top: 141px; + left: 27px; +} + +.notifcation-label-required{ + color: #cf2a2a; +}
\ No newline at end of file diff --git a/portal-FE-common/src/app/pages/user-notification-admin/new-notification-modal/new-notification-modal.component.spec.ts b/portal-FE-common/src/app/pages/user-notification-admin/new-notification-modal/new-notification-modal.component.spec.ts new file mode 100644 index 00000000..142a0ba0 --- /dev/null +++ b/portal-FE-common/src/app/pages/user-notification-admin/new-notification-modal/new-notification-modal.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 { NewNotificationModalComponent } from './new-notification-modal.component'; + +describe('NewNotificationModalComponent', () => { + let component: NewNotificationModalComponent; + let fixture: ComponentFixture<NewNotificationModalComponent>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ NewNotificationModalComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(NewNotificationModalComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/portal-FE-common/src/app/pages/user-notification-admin/new-notification-modal/new-notification-modal.component.ts b/portal-FE-common/src/app/pages/user-notification-admin/new-notification-modal/new-notification-modal.component.ts new file mode 100644 index 00000000..44ad18f5 --- /dev/null +++ b/portal-FE-common/src/app/pages/user-notification-admin/new-notification-modal/new-notification-modal.component.ts @@ -0,0 +1,943 @@ +/*- + * ============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, Injectable} from '@angular/core'; +import { NgbActiveModal, NgbModal } from '@ng-bootstrap/ng-bootstrap'; +import { NotificationService, FunctionalMenuService } from 'src/app/shared/services'; +import { SelectionModel } from '@angular/cdk/collections'; +import { FlatTreeControl } from '@angular/cdk/tree'; +import { MatTreeFlatDataSource, MatTreeFlattener } from '@angular/material/tree'; +import { BehaviorSubject } from 'rxjs'; +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-notification-modal', + templateUrl: './new-notification-modal.component.html', + styleUrls: ['./new-notification-modal.component.scss'] +}) +export class NewNotificationModalComponent implements OnInit { + + notification = { + 'notificationId': null, + 'isOnlineUsersOnly': null, + 'isForAllRoles': null, + 'priority': null, + 'isActive': null, + 'startTime': null, + 'endTime': null, + 'msgHeader': null, + 'msgDescription': null, + 'roleIds': null, + 'isFunctionalMenu': null, + 'treeTitle': null, + 'anyTreeItemSelected': false, + 'notifObj':null, + 'roleObj': { + notificationRoleIds: null + }, + 'notificationRoleIds': null + }; + + /** + * The Json object for to-do list data. + */ + MAT_TREE_DATA = {}; + notificationId = null; + selectedCat = null; + selectedEcompFunc = null; + YN_index_mapping = { + "Y": 0, + "N": 1 + } + + onlineAllUsersOptions = [{ + "index": 0, + "value": "Y", + "title": "Online Users Only" + }, + { + "index": 1, + "value": "N", + "title": "Online & Offline Users" + } + ]; + + isForAllRoles = [{ + "index": 0, + "value": "Y", + "title": "Yes" + }, + { + "index": 1, + "value": "N", + "title": "No" + } + ]; + + priorityOptions = [{ + "index": 0, + "value": "1", + "title": "Normal" + }, + { + "index": 1, + "value": "2", + "title": "Important" + } + ]; + + isActiveOptions = [{ + "index": 0, + "value": "Y", + "title": "Yes" + }, + { + "index": 1, + "value": "N", + "title": "No" + } + ]; + + @Input() selectedNotification: any; + @Output() passEntry: EventEmitter<any> = new EventEmitter(); + result: any; + isEditMode: any; + functionalMenuRes = {}; + treedata = []; + checkBoxObj: any; + + dataChange = new BehaviorSubject<TodoItemNode[]>([]); + get data(): TodoItemNode[] { return this.dataChange.value; } + + constructor(public ngbModal: NgbModal, + public activeModal: NgbActiveModal, + private notificationService: NotificationService, + public functionalMenuService: FunctionalMenuService) { } + + ngOnInit() { + this.notification.isFunctionalMenu='Y'; + console.log("selectedNotification ::::",this.selectedNotification); + if(this.selectedNotification && this.selectedNotification.msgSource !=''){ + + this.isEditMode = true; + this.notification = Object.assign({}, this.selectedNotification); + if(this.selectedNotification && this.selectedNotification.priority ==1 ){ + this.notification.priority = this.priorityOptions[0].value; + }else{ + this.notification.priority = this.priorityOptions[1].value; + } + if(this.selectedNotification && this.selectedNotification.startTime){ + this.notification.startTime = new Date(this.selectedNotification.startTime); + } + if(this.selectedNotification && this.selectedNotification.endTime ){ + this.notification.endTime = new Date(this.selectedNotification.endTime); + } + this.notification.isFunctionalMenu='Y'; + }else{ + this.isEditMode = false; + this.notification.isActive = this.isActiveOptions[0]; + this.notification.isOnlineUsersOnly = this.onlineAllUsersOptions[1]; + this.notification.isForAllRoles = this.isForAllRoles[0].value; + this.notification.priority = this.priorityOptions[0].value; + this.notification.isFunctionalMenu = "Y"; + this.notification.msgHeader = ''; + this.notification.msgDescription = ''; + this.notification.treeTitle = "Functional Menu"; + this.notification.notifObj = { + isCategoriesFunctionalMenu: true + } + } + this.getFunctionalMenu(); + this.treeFlattener = new MatTreeFlattener(this.transformer, this.getLevel, this.isExpandable, this.getChildren); + this.treeControl = new FlatTreeControl<TodoItemFlatNode>(this.getLevel, this.isExpandable); + this.dataSource = new MatTreeFlatDataSource(this.treeControl, this.treeFlattener); + const data = this.buildFileTree(this.MAT_TREE_DATA, 0); + this.dataChange.next(data); + this.dataChange.subscribe(data => { + this.dataSource.data = data; + }); + } + + addUserNotification(){ + let notificationRoleIds = [] + let endDate = new Date(this.notification.endTime); + let selectedTreeNode: Array<TodoItemFlatNode> = this.checklistSelection.selected; + selectedTreeNode.forEach(element => { + if(element && element.roleIds && element.roleIds.length >0){ + element.roleIds.forEach(id =>{ + if(id && id !='undefined'){ + notificationRoleIds.push(id); + } + }); + } + }); + console.log("notificationRoleIds >>>>>>>>",notificationRoleIds); + if(notificationRoleIds && notificationRoleIds.length >0){ + notificationRoleIds.sort(); + } + + let newUserNotification = { + 'notificationId': (this.notification && this.notification.notificationId ? this.notification.notificationId: null), + 'isForOnlineUsers': (this.notification && this.notification.isOnlineUsersOnly ? this.notification.isOnlineUsersOnly.value : null), + 'isForAllRoles': this.notification.isForAllRoles, + 'priority': this.notification.priority, + 'activeYn': (this.notification && this.notification.isActive ? this.notification.isActive.value :'Y'), + 'startTime': new Date(this.notification.startTime), + 'endTime': new Date(this.notification.endTime), + 'msgHeader': this.notification.msgHeader, + 'msgDescription': this.notification.msgDescription, + 'roleIds': notificationRoleIds, + 'createdDate': new Date() + }; + + if((newUserNotification.isForAllRoles) && (newUserNotification.priority) && (newUserNotification.activeYn) + && (newUserNotification.startTime) && (newUserNotification.endTime) + && (newUserNotification.msgHeader != '') && (newUserNotification.msgDescription != '')){ + + console.log("newUserNotification >>> ",newUserNotification); + // POST ajax call here; + if (this.isEditMode) { + this.notificationService.updateAdminNotification(newUserNotification) + .subscribe(_data => { + this.result = _data; + if(this.result && this.result.status ==='ERROR'){ + this.openConfirmationModal('Error', this.result.response); + }else{ + this.passEntry.emit(this.result); + this.ngbModal.dismissAll(); + } + }, error =>{ + console.log(error); + this.openConfirmationModal('Error', error); + return; + }); + }else{ + this.notificationService.addAdminNotification(newUserNotification) + .subscribe(_data => { + this.result = _data; + if(this.result && this.result.status ==='ERROR'){ + this.openConfirmationModal('Error', this.result.response); + return; + }else{ + this.passEntry.emit(this.result); + this.ngbModal.dismissAll(); + } + }, error =>{ + console.log(error); + this.openConfirmationModal('Error', error); + return; + }); + } + }else{ + this.openConfirmationModal("","Please fill in all required(*) fields."); + return; + } + } + + getFunctionalMenu(){ + let menu_role_dict = {}; + /**First Rest Call */ + this.functionalMenuService.getFunctionalMenuRole() + .subscribe(role_res => { + this.result = role_res; + if (this.result == null || this.result == 'undefined') { + console.log('FunctionalMenuService::getFunctionalMenu Failed: Result or result.data is null'); + }else { + //console.log('First Rest Call Data ::',this.result); + for (var i in role_res) { + // if first time appear in menu_role_dict + if (!(role_res[i].menuId in menu_role_dict)) { + menu_role_dict[role_res[i].menuId] = [role_res[i].roleId]; + } else { + menu_role_dict[role_res[i].menuId].push(role_res[i].roleId); + } + } + + /** 2nd Rest Call */ + this.functionalMenuService.getManagedFunctionalMenuForNotificationTree() + .subscribe(res => { + this.result = res; + //console.log("2nd REST CALL RESPONSE :: ",this.result); + var exclude_list = ['Favorites']; + let actualData = []; + //Adding children and label attribute to all objects in res + for (let i = 0; i < this.result.length; i++) { + res[i].child = []; + res[i].name = res[i].text; + res[i].id = res[i].text; + res[i].displayCheckbox = true; + let checkBoxObj = { + isAnyRoleSelected: false + }; + res[i].roleId = menu_role_dict[res[i].menuId]; + res[i].onSelect = function() { + this.notification.anyTreeItemSelected = this.checkTreeSelect(); + }; + + let intersectionObj: any; + intersectionObj = res[i].roleId & this.notification.notificationRoleIds; + if (res[i].roleId && res[i].roleId.length == intersectionObj.length) { + res[i].isSelected = true; + res[i].selected = true; + res[i].indeterminate = false; + } else { + /*default*/ + res[i].isSelected = false; + res[i].selected = false; + res[i].indeterminate = false; + } + } + + // Adding actual child items to children array in res + // objects + let parentChildDict = {}; + let parentChildRoleIdDict = {}; + for (let i = 0; i < this.result.length; i++) { + let parentId = this.result[i].menuId; + parentChildDict[parentId] = []; + parentChildRoleIdDict[parentId] = []; + for (let j = 0; j < this.result.length; j++) { + let childId = res[j].parentMenuId; + if (parentId === childId) { + res[i].child.push(res[j]); + parentChildDict[parentId].push(res[j].menuId); + //if res[j].roleId is defined + if (res[j].roleId) { + for (let k in res[j].roleId) { + parentChildRoleIdDict[parentId].push(res[j].roleId[k]); + } + + } + } + } + } + + //check if grand children exist + for (var key in parentChildDict) { + var child = parentChildDict[key]; + var isGrandParent = false; + if (child.length > 0) { + for (var i in child) { + if (parentChildDict[child[i]].length > 0) { + isGrandParent = true; + break; + } + } + } + if (isGrandParent) { + for (var i in child) { + // if the child has children + if (parentChildDict[child[i]].length > 0) { + for (var j in parentChildRoleIdDict[child[i]]) { + if (parentChildRoleIdDict[key].indexOf(parentChildRoleIdDict[child[i]][j]) === -1) { + parentChildRoleIdDict[key].push(parentChildRoleIdDict[child[i]][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 child in order based on the column + for (let i = 0; i < this.result.length; i++) { + res[i].child.sort(function(a, b) { + return a.column - b.column; + }); + } + + //Forming actual parent items + for (let i = 0; i < this.result.length; i++) { + let pmid = res[i].parentMenuId; + if (pmid === null) { + actualData.push(res[i]); + } + } + var treedata = actualData[0].child; + + this.treedata = []; + + /*Remove favorite from the list */ + for (var i in treedata) { + if (!(treedata[i].name.indexOf(exclude_list) > -1)) { + this.treedata.push(treedata[i]) + } + } + //setting b2b tree parameter + this.settingTreeParam(); + this.populateTreeDataSourceByFunctionalMenu(this.treedata); + + }, error =>{ + console.log(error); + }); + } + }, error =>{ + console.log(error); + }); + } + + settingTreeParam() { + /**************first level****************/ + for (var fi = 0; fi < this.treedata.length; fi++) { + var fLevel = this.treedata[fi]; + var sLevel = this.treedata[fi].child; + var sLevelSelectedCount = 0; + var sLevelChildNumber = 0 + if (fLevel.child.length == 0 && fLevel.roleId == null) { + delete fLevel.child; + } else if (sLevel) { + /**************Second level****************/ + var sLevelDelArray = []; + for (var si = 0; si < sLevel.length; si++) { + var deletThisSLev = false; + if (sLevel[si].child.length == 0 && sLevel[si].roleId == null) { + sLevel[si].displayCheckbox = false; + sLevelDelArray.push(sLevel[si].name); + sLevel[si].name = ''; + sLevel[si].active = false; + delete sLevel[si].child; + } else if (sLevel[si].child.length == 0) { + delete sLevel[si].child; + } else { + /**************Third level****************/ + var tLevel = sLevel[si].child; + var tLevelSelectedCount = 0; + var tLevelChildNumber = 0; + if (tLevel) { + var tLevelDelArray = []; + var tLevelLen = tLevel.length; + var tLevelRoleIdUndefined = 0; + for (var ti = 0; ti < tLevel.length; ti++) { + delete tLevel[ti].child; + if (tLevel[ti].roleId == null) { + tLevel[ti].displayCheckbox = false; + tLevelDelArray.push(tLevel[ti].name); + tLevel[ti].name = ''; + tLevel[ti].active = false; + tLevelRoleIdUndefined++ + } else { + if (tLevel[ti].isSelected) + tLevelSelectedCount++; + + if (tLevel[ti].displayCheckbox) + tLevelChildNumber++; + } + } + if (tLevelRoleIdUndefined == tLevelLen) + deletThisSLev = true; + if (tLevelSelectedCount == tLevelChildNumber) { + sLevel[si].isSelected = true; + sLevel[si].indeterminate = false; + sLevel[si].active = true; + } else if (tLevelSelectedCount > 0) { + sLevel[si].indeterminate = true; + sLevel[si].active = true; + } + + /*Cleanup unused third level items*/ + for (var i = 0; i < tLevelDelArray.length; i++) { + var name = tLevelDelArray[i]; + for (var ti = 0; ti < tLevel.length; ti++) { + if (name == tLevel[ti].text) { + tLevel.splice(ti, 1); + break; + } + } + } + } + } + if (deletThisSLev) { //remove the whole second level item if all it's child has no roleId + sLevel[si].displayCheckbox = false; + sLevelDelArray.push(sLevel[si].name); + sLevel[si].name = ''; + sLevel[si].active = false; + } else { + if (sLevel[si].isSelected) + sLevelSelectedCount++; + if (sLevel[si].displayCheckbox) + sLevelChildNumber++; + } + } + if (sLevelSelectedCount == sLevelChildNumber && sLevelChildNumber != 0) { + fLevel.isSelected = true; + fLevel.indeterminate = false; + fLevel.active = true; + } else if (sLevelSelectedCount > 0) { + fLevel.indeterminate = true; + fLevel.active = true; + } else { + //fLevel.active=false; + fLevel.indeterminate = false; + } + /*Cleanup unused second level items*/ + for (var i = 0; i < sLevelDelArray.length; i++) { + var name = sLevelDelArray[i]; + for (var si = 0; si < sLevel.length; si++) { + if (name == sLevel[si].text) { + sLevel.splice(si, 1); + break; + } + } + } + } + } +} + + +checkTreeSelect() { + if (this.treedata) { + for (var fi = 0; fi < this.treedata.length; fi++) { + var fLevel = this.treedata[fi]; + if (fLevel.isSelected) { + return true; + } + var sLevel = fLevel.child; + if (sLevel) { + for (var si = 0; si < sLevel.length; si++) { + if (sLevel[si].isSelected) { + return true; + } + var tLevel = sLevel[si].child; + if (tLevel) { + for (var ti = 0; ti < tLevel.length; ti++) { + if (tLevel[ti].isSelected) { + return true; + } + } + } + } + } + } + } + return false; + } + + getAppRoleIds() { + this.notification.notifObj = { + isCategoriesFunctionalMenu: false + }; + this.notificationService.getAppRoleIds() + .subscribe(_data => { + this.result = _data; + let actualData = []; + var app_id_name_list = {}; + this.checkBoxObj = { + isAnyRoleSelected: false + }; + for (let i = 0; i < this.result.length; i++) { + if (!(this.result[i].appId in app_id_name_list)) { + app_id_name_list[this.result[i].appId] = this.result[i].appName; + } + this.result[i].child = []; + this.result[i].name = this.result[i].roleName; + this.result[i].displayCheckbox = true; + this.result[i].id = this.result[i].roleId; + this.result[i].menuId = this.result[i].roleId; + this.result[i].parentMenuId = this.result[i].appId; + this.result[i].can_check = true; + this.result[i].roleId = [this.result[i].roleId]; + this.result[i].onSelect = function() { + this.notification.anyTreeItemSelected = this.checkTreeSelect(); + }; + /*assigning selected value*/ + let intersectionObj: any; + intersectionObj = this.result[i].roleId & this.notification.notificationRoleIds; + if (this.result[i].roleId && this.result[i].roleId.length == intersectionObj.length) { + this.result[i].isSelected = true; + this.result[i].selected = true; + this.result[i].indeterminate = false; + } else { + /*default*/ + this.result[i].isSelected = false; + this.result[i].selected = false; + this.result[i].indeterminate = false; + } + } + + for (var app_id in app_id_name_list) { + + let new_res = { + 'child': null, + 'name': null, + 'id': null, + 'displayCheckbox': null, + 'menuId': null, + 'parentMenuId': '', + 'appId': '', + 'can_check': null, + 'msgDescription': null, + 'roleIds': null, + 'roleId': null, + 'onSelect': null, + }; + + new_res.child = []; + new_res.name = app_id_name_list[app_id]; + new_res.id = app_id; + new_res.displayCheckbox = true; + new_res.menuId = app_id; + new_res.parentMenuId = null; + new_res.appId = null; + new_res.can_check = true; + new_res.roleId = null; + new_res.onSelect = function() { + this.notification.anyTreeItemSelected = this.checkTreeSelect(); + }; + this.result.push(new_res); + } + + let parentChildRoleIdDict = {}; + //Adding actual child items to child array in res objects + for (let i = 0; i < this.result.length; i++) { + let parentId = this.result[i].menuId; + parentChildRoleIdDict[parentId] = []; + for (let j = 0; j < this.result.length; j++) { + let childId = this.result[j].parentMenuId; + if (parentId == childId) { + this.result[i].child.push(this.result[j]); + if (this.result[j].roleId) { + for (let k in this.result[j].roleId) { + parentChildRoleIdDict[parentId].push(this.result[j].roleId[k]); + } + } + } + } + } + + //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; + //setting correct parameters for b2b tree + this.settingTreeParam(); + this.makeFinalTreeDataByProcessingAppRoleIds(this.treedata); + + }, error =>{ + console.log(error); + }); + } + + makeFinalTreeDataByProcessingAppRoleIds(treeData_approleids){ + let datamap: any = new Map(); + let data = treeData_approleids; + + if(data && data.length > 0){ + data.forEach(element => { + let iskeyPresent: boolean = false; + try{ + if(datamap.get(element.id)){ + iskeyPresent = true; + } + }catch(e){// + } + if(iskeyPresent){ + let temp = datamap.get(element.id); + temp.push(element); + datamap.set(element.id,temp) + }else{ + datamap.set(element.id,element); + } + }); + } + + if(datamap && datamap.size > 0){ + let treeNode = {}; + datamap.forEach((value, key) => { + if(value.child){ + let keyname = ""; + let childArray = []; + for(let item of value.child){ + keyname = item.appName+"~"+'undefined'; + let childItem = item.roleName+"~"+item.roleId; + childArray.push(childItem); + } + treeNode[keyname] = childArray; + } + }); + console.log("makeFinalTreeDataByProcessingAppRoleIds >>",treeNode); + + this.treeFlattener = new MatTreeFlattener(this.transformer, this.getLevel, this.isExpandable, this.getChildren); + this.treeControl = new FlatTreeControl<TodoItemFlatNode>(this.getLevel, this.isExpandable); + this.dataSource = new MatTreeFlatDataSource(this.treeControl, this.treeFlattener); + const data = this.buildFileTree(treeNode, 0); + this.dataChange.next(data); + this.dataChange.subscribe(data => { + this.dataSource.data = data; + }); + } + } + + + /** + * Prepare Tree datasoure using functional Menu Data. + * @param functionMenuData + */ + populateTreeDataSourceByFunctionalMenu(functionMenuData: any){ + console.log("populateTreeDataSourceByFunctionalMenu :: ",functionMenuData); + if(functionMenuData){ + let treeNode = {}; + functionMenuData.forEach(element => { + let name = element.text+"~"+element.roleId; + treeNode[name] = { }; + + if(element.child && element.child.length >0){ + let childArray = []; + element.child.forEach(element => { + let childItem = element.text+"~"+element.roleId; + childArray.push(childItem); + }); + treeNode[name] = childArray; + } + + }); + console.log("treeNode>>",treeNode); + + this.treeFlattener = new MatTreeFlattener(this.transformer, this.getLevel, this.isExpandable, this.getChildren); + this.treeControl = new FlatTreeControl<TodoItemFlatNode>(this.getLevel, this.isExpandable); + this.dataSource = new MatTreeFlatDataSource(this.treeControl, this.treeFlattener); + const data = this.buildFileTree(treeNode, 0); + this.dataChange.next(data); + this.dataChange.subscribe(data => { + this.dataSource.data = data; + }); + } + } + + 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; + } + + + /*************************************** mat-tree code start here ******************************/ + + /** Map from flat node to nested node. This helps us finding the nested node to be modified */ + flatNodeMap = new Map<TodoItemFlatNode, TodoItemNode>(); + /** Map from nested node to flattened node. This helps us to keep the same object for selection */ + nestedNodeMap = new Map<TodoItemNode, TodoItemFlatNode>(); + /** A selected parent node to be inserted */ + selectedParent: TodoItemFlatNode | null = null; + /** The new item's name */ + newItemName = ''; + treeControl: FlatTreeControl<TodoItemFlatNode>; + treeFlattener: MatTreeFlattener<TodoItemNode, TodoItemFlatNode>; + dataSource: MatTreeFlatDataSource<TodoItemNode, TodoItemFlatNode>; + /** The selection for checklist */ + checklistSelection = new SelectionModel<TodoItemFlatNode>(true /* multiple */); + getLevel = (node: TodoItemFlatNode) => node.level; + isExpandable = (node: TodoItemFlatNode) => node.expandable; + getChildren = (node: TodoItemNode): TodoItemNode[] => node.children; + hasChild = (_: number, _nodeData: TodoItemFlatNode) => _nodeData.expandable; + hasNoContent = (_: number, _nodeData: TodoItemFlatNode) => _nodeData.item === ''; + + /** + * Transformer to convert nested node to flat node. Record the nodes in maps for later use. + */ + transformer = (node: TodoItemNode, level: number) => { + const existingNode = this.nestedNodeMap.get(node); + const flatNode = existingNode && existingNode.item === node.item + ? existingNode + : new TodoItemFlatNode(); + flatNode.item = node.item; + flatNode.level = level; + flatNode.expandable = !!node.children; + flatNode.roleIds = node.roleIds; + this.flatNodeMap.set(flatNode, node); + this.nestedNodeMap.set(node, flatNode); + return flatNode; + } + + /** Whether all the descendants of the node are selected. */ + descendantsAllSelected(node: TodoItemFlatNode): boolean { + const descendants = this.treeControl.getDescendants(node); + const descAllSelected = descendants.every(child => + this.checklistSelection.isSelected(child) + ); + return descAllSelected; + } + + /** Whether part of the descendants are selected */ + descendantsPartiallySelected(node: TodoItemFlatNode): boolean { + const descendants = this.treeControl.getDescendants(node); + const result = descendants.some(child => this.checklistSelection.isSelected(child)); + return result && !this.descendantsAllSelected(node); + } + + /** Toggle the to-do item selection. Select/deselect all the descendants node */ + todoItemSelectionToggle(node: TodoItemFlatNode): void { + this.checklistSelection.toggle(node); + const descendants = this.treeControl.getDescendants(node); + this.checklistSelection.isSelected(node) + ? this.checklistSelection.select(...descendants) + : this.checklistSelection.deselect(...descendants); + + // Force update for the parent + descendants.every(child => + this.checklistSelection.isSelected(child) + ); + this.checkAllParentsSelection(node); + } + + /** Toggle a leaf to-do item selection. Check all the parents to see if they changed */ + todoLeafItemSelectionToggle(node: TodoItemFlatNode): void { + this.checklistSelection.toggle(node); + this.checkAllParentsSelection(node); + } + + /* Checks all the parents when a leaf node is selected/unselected */ + checkAllParentsSelection(node: TodoItemFlatNode): void { + let parent: TodoItemFlatNode | null = this.getParentNode(node); + while (parent) { + this.checkRootNodeSelection(parent); + parent = this.getParentNode(parent); + } + } + + /** Check root node checked state and change it accordingly */ + checkRootNodeSelection(node: TodoItemFlatNode): void { + const nodeSelected = this.checklistSelection.isSelected(node); + const descendants = this.treeControl.getDescendants(node); + const descAllSelected = descendants.every(child => + this.checklistSelection.isSelected(child) + ); + if (nodeSelected && !descAllSelected) { + this.checklistSelection.deselect(node); + } else if (!nodeSelected && descAllSelected) { + this.checklistSelection.select(node); + } + } + + /* Get the parent node of a node */ + getParentNode(node: TodoItemFlatNode): TodoItemFlatNode | null { + const currentLevel = this.getLevel(node); + + if (currentLevel < 1) { + return null; + } + + const startIndex = this.treeControl.dataNodes.indexOf(node) - 1; + + for (let i = startIndex; i >= 0; i--) { + const currentNode = this.treeControl.dataNodes[i]; + + if (this.getLevel(currentNode) < currentLevel) { + return currentNode; + } + } + return null; + } + + + /** + * Build the file structure tree. The `value` is the Json object, or a sub-tree of a Json object. + * The return value is the list of `TodoItemNode`. + */ + buildFileTree(obj: {[key: string]: any}, level: number): TodoItemNode[] { + return Object.keys(obj).reduce<TodoItemNode[]>((accumulator, key) => { + const value = obj[key]; + const node = new TodoItemNode(); + node.item = key; + + if(key.indexOf("~") !== -1){ + let nodeDetails = key.split("~"); + node.item = nodeDetails[0]; + if(nodeDetails[1]){ + node.roleIds = nodeDetails[1].split(","); + }else{ + node.roleIds = []; + } + } + + if (value != null) { + if (typeof value === 'object') { + node.children = this.buildFileTree(value, level + 1); + } else { + node.item = value; + if(value.indexOf("~") !== -1){ + let nodeDetails = value.split("~"); + node.item = nodeDetails[0]; + if(nodeDetails[1]){ + node.roleIds = nodeDetails[1].split(","); + }else{ + node.roleIds = []; + } + } + } + } + + return accumulator.concat(node); + }, []); + } + /*************************************** mat-tree code end here ******************************/ +} + +/** + * Node for to-do item + */ +export class TodoItemNode { + children: TodoItemNode[]; + item: string; + roleIds: string[]; +} + +/** Flat to-do item node with expandable and level information */ +export class TodoItemFlatNode { + item: string; + level: number; + expandable: boolean; + roleIds: string[]; +}
\ No newline at end of file diff --git a/portal-FE-common/src/app/pages/user-notification-admin/user-notification-admin.component.html b/portal-FE-common/src/app/pages/user-notification-admin/user-notification-admin.component.html new file mode 100644 index 00000000..b9e63d4a --- /dev/null +++ b/portal-FE-common/src/app/pages/user-notification-admin/user-notification-admin.component.html @@ -0,0 +1,137 @@ +<!-- + ============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"> + <!-- Heading --> + <div class="onap-main-view-title"> + <h1 class="heading-page">User Notifications</h1> + </div> + + + <!--Filter Search Box --> + <mat-form-field> + <input matInput type="text" (keyup)="applyFilter($event.target.value)" placeholder="Search in entire table"> + </mat-form-field> + + <!--Add Notifications--> + <button type="button" class="btn btn-primary" (click)="openAddNewNotificationModal('')"> + <i class="icon ion-md-person-add"></i> Add Notification + </button> + + <!-- Recent Notification History table --> + <table mat-table [dataSource]="notificationsDataSource" matSort> + <!-- Message Source Column --> + <ng-container matColumnDef="messageSource"> + <th id="col1" mat-header-cell *matHeaderCellDef> Message Source </th> + <td (click)="openAddNewNotificationModal(element)" + id="rowheader_t1_{{i}}-messageSource" mat-cell *matCellDef="let element; let i = index;"> {{element.msgSource}} + </td> + </ng-container> + + <!-- Message Column --> + <ng-container matColumnDef="message"> + <th id="col2" mat-header-cell *matHeaderCellDef> Message </th> + <td (click)="openAddNewNotificationModal(element)" + id="rowheader_t1_{{i}}-message" mat-cell *matCellDef="let element; let i=index;"> {{element.msgDescription}} + </td> + </ng-container> + + <!-- Start Date (Local Time) Column --> + <ng-container matColumnDef="startDateLocalTime"> + <th id="col3" mat-header-cell *matHeaderCellDef> Start Date (Local Time) </th> + <td (click)="openAddNewNotificationModal(element)" + id="rowheader_t1_{{i}}-startDateLocalTime" mat-cell *matCellDef="let element; let i=index;"> {{element.startTime | date:'dd/MM/yyyy'}} + </td> + </ng-container> + + <!-- End Date (Local Time) Column --> + <ng-container matColumnDef="endDateLocalTime"> + <th id="col4" mat-header-cell *matHeaderCellDef> End Date (Local Time) </th> + <td (click)="openAddNewNotificationModal(element)" + id="rowheader_t1_{{i}}-endDateLocalTime" mat-cell *matCellDef="let element; let i=index;">{{element.endTime | date:'dd/MM/yyyy'}} + </td> + </ng-container> + + <!-- Priority Column --> + <ng-container matColumnDef="priority"> + <th id="col4" mat-header-cell *matHeaderCellDef> Priority </th> + <td (click)="openAddNewNotificationModal(element)" + id="rowheader_t1_{{i}}-priority" mat-cell *matCellDef="let element; let i=index;"> {{element.priority}} + </td> + </ng-container> + + <!-- Created By Column --> + <ng-container matColumnDef="createdBy"> + <th id="col4" mat-header-cell *matHeaderCellDef> Created By </th> + <td (click)="openAddNewNotificationModal(element)" + id="rowheader_t1_{{i}}-createdBy" mat-cell *matCellDef="let element; let i=index;"> {{element.loginId}} + </td> + </ng-container> + + <!-- Created Time Column --> + <ng-container matColumnDef="createdTime"> + <th id="col4" mat-header-cell *matHeaderCellDef> Created Time </th> + <td (click)="openAddNewNotificationModal(element)" + id="rowheader_t1_{{i}}-createdTime" mat-cell *matCellDef="let element; let i=index;"> {{element.createdDate}} + </td> + </ng-container> + + <!-- All Users (Roles)? Column --> + <ng-container matColumnDef="allUsersRoles"> + <th id="col4" mat-header-cell *matHeaderCellDef> All Users (Roles)? </th> + <td (click)="openAddNewNotificationModal(element)" + id="rowheader_t1_{{i}}-allUsersRoles" mat-cell *matCellDef="let element; let i=index;"> {{element.isForAllRoles}} + </td> + </ng-container> + + <!-- view/Delete Column --> + <ng-container matColumnDef="viewOrDelete"> + <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)="removeUserNotification(element)"> + <i class="icon ion-md-trash"></i> + </span> + </td> + </ng-container> + + <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr> + <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr> + </table> + <mat-paginator [pageSizeOptions]="[10, 20]" showFirstLastButtons></mat-paginator> + + </div>
\ No newline at end of file diff --git a/portal-FE-common/src/app/pages/user-notification-admin/user-notification-admin.component.scss b/portal-FE-common/src/app/pages/user-notification-admin/user-notification-admin.component.scss new file mode 100644 index 00000000..7a773398 --- /dev/null +++ b/portal-FE-common/src/app/pages/user-notification-admin/user-notification-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/user-notification-admin/user-notification-admin.component.spec.ts b/portal-FE-common/src/app/pages/user-notification-admin/user-notification-admin.component.spec.ts new file mode 100644 index 00000000..82b4e129 --- /dev/null +++ b/portal-FE-common/src/app/pages/user-notification-admin/user-notification-admin.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 { UserNotificationAdminComponent } from './user-notification-admin.component'; + +describe('UserNotificationAdminComponent', () => { + let component: UserNotificationAdminComponent; + let fixture: ComponentFixture<UserNotificationAdminComponent>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ UserNotificationAdminComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(UserNotificationAdminComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/portal-FE-common/src/app/pages/user-notification-admin/user-notification-admin.component.ts b/portal-FE-common/src/app/pages/user-notification-admin/user-notification-admin.component.ts new file mode 100644 index 00000000..bf4a39f7 --- /dev/null +++ b/portal-FE-common/src/app/pages/user-notification-admin/user-notification-admin.component.ts @@ -0,0 +1,149 @@ +/*- + * ============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 { NgbModal } from '@ng-bootstrap/ng-bootstrap'; +import { MatTableDataSource } from '@angular/material'; +import { MatSort, MatPaginator } from '@angular/material'; +import { NotificationService } from '../../shared/services/index'; +import { NewNotificationModalComponent } from './new-notification-modal/new-notification-modal.component'; +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-user-notification-admin', + templateUrl: './user-notification-admin.component.html', + styleUrls: ['./user-notification-admin.component.scss'] +}) +export class UserNotificationAdminComponent implements OnInit { + + isEditMode: any; + result: any; + tableAdminNotifItems: any = []; + displayedColumns: string[] = ['messageSource', 'message', 'startDateLocalTime','endDateLocalTime', 'priority', 'createdBy', 'createdTime', 'allUsersRoles', 'viewOrDelete']; + notificationsDataSource = new MatTableDataSource(this.tableAdminNotifItems); + @ViewChild(MatSort) sort: MatSort; + @ViewChild(MatPaginator) paginator: MatPaginator; + + constructor(public notificationService: NotificationService, public ngbModal: NgbModal) { } + + ngOnInit() { + this.getAdminNotifications(); + } + + getAdminNotifications(){ + this.notificationService.getAdminNotification() + .subscribe(_data => { + this.result = _data; + if (this.result == null || this.result == 'undefined') { + console.log('NotificationService::getAdminNotifications Failed:::: Result or result.data is null'); + }else { + this.tableAdminNotifItems = this.result; + this.populateTableData(this.tableAdminNotifItems); + } + }, error =>{ + console.log(error); + this.openConfirmationModal('Error', error); + return; + }); + } + + removeUserNotification(selectedAdminNotification: any){ + let confirmationMsg = 'You are about to delete this Notification : ' + selectedAdminNotification.msgHeader+ '. Click OK to continue.'; + this.openInformationModal("Confirmation",confirmationMsg).result.then((result) => { + if (result === 'Ok') { + selectedAdminNotification.activeYn = 'N'; + this.notificationService.updateAdminNotification(selectedAdminNotification) + .subscribe(_data => { + this.result = _data; + this.tableAdminNotifItems = []; + this.getAdminNotifications(); + }, error =>{ + console.log(error); + this.openConfirmationModal('Error', error); + return; + }); + } + }, (resut) => { + this.openConfirmationModal('Error', resut); + return; + }) + } + + + openAddNewNotificationModal(rowData: any){ + const modalRef = this.ngbModal.open(NewNotificationModalComponent, { windowClass: 'add-notification-modal'}); + modalRef.componentInstance.title = 'Add a New Notification'; + if(rowData != 'undefined' && rowData){ + modalRef.componentInstance.selectedNotification = rowData; + this.isEditMode = true; + }else{ + modalRef.componentInstance.notification = {}; + this.isEditMode = false; + } + modalRef.componentInstance.passEntry.subscribe((receivedEntry: any) => { + if(receivedEntry){ + this.tableAdminNotifItems = []; + this.getAdminNotifications(); + } + }); + } + + populateTableData(notificationHistory: Array<Object>){ + this.notificationsDataSource = new MatTableDataSource(notificationHistory); + this.notificationsDataSource.sort = this.sort; + this.notificationsDataSource.paginator = this.paginator; + } + + applyFilter(filterValue: string) { + this.notificationsDataSource.filter = filterValue.trim().toLowerCase(); + } + + 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; + } +} |