From 3f7386d4245f9a05db961440ebf80d97d788f902 Mon Sep 17 00:00:00 2001 From: Sudarshan Kumar Date: Fri, 31 Jan 2020 20:08:08 +0530 Subject: Added portal-FE-os components Removed layout from portal-FE-os and added new components in portal-fe-os Issue-ID: PORTAL-795 Change-Id: I3d7f93fa22a7935f9e73ed96802495019aabc129 Signed-off-by: Sudarshan Kumar --- .../new-user-modal/new-user-modal.component.html | 125 ++++++++ .../new-user-modal/new-user-modal.component.scss | 51 ++++ .../new-user-modal.component.spec.ts | 62 ++++ .../new-user-modal/new-user-modal.component.ts | 322 +++++++++++++++++++++ .../user-details-form.component.html | 118 ++++++++ .../user-details-form.component.scss | 0 .../user-details-form.component.spec.ts | 25 ++ .../user-details-form.component.ts | 51 ++++ 8 files changed, 754 insertions(+) create mode 100644 portal-FE-os/src/app/pages/users/new-user-modal/new-user-modal.component.html create mode 100644 portal-FE-os/src/app/pages/users/new-user-modal/new-user-modal.component.scss create mode 100644 portal-FE-os/src/app/pages/users/new-user-modal/new-user-modal.component.spec.ts create mode 100644 portal-FE-os/src/app/pages/users/new-user-modal/new-user-modal.component.ts create mode 100644 portal-FE-os/src/app/pages/users/user-details-form/user-details-form.component.html create mode 100644 portal-FE-os/src/app/pages/users/user-details-form/user-details-form.component.scss create mode 100644 portal-FE-os/src/app/pages/users/user-details-form/user-details-form.component.spec.ts create mode 100644 portal-FE-os/src/app/pages/users/user-details-form/user-details-form.component.ts (limited to 'portal-FE-os/src/app/pages/users') diff --git a/portal-FE-os/src/app/pages/users/new-user-modal/new-user-modal.component.html b/portal-FE-os/src/app/pages/users/new-user-modal/new-user-modal.component.html new file mode 100644 index 00000000..927b5073 --- /dev/null +++ b/portal-FE-os/src/app/pages/users/new-user-modal/new-user-modal.component.html @@ -0,0 +1,125 @@ + +
+ + +
+ +
+ +
+
+ + + +
diff --git a/portal-FE-os/src/app/pages/users/new-user-modal/new-user-modal.component.scss b/portal-FE-os/src/app/pages/users/new-user-modal/new-user-modal.component.scss new file mode 100644 index 00000000..b919f362 --- /dev/null +++ b/portal-FE-os/src/app/pages/users/new-user-modal/new-user-modal.component.scss @@ -0,0 +1,51 @@ +/*- + * ============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============================================ + * + * + */ +.icon-trash { + cursor: pointer; + font-size: 20px; +} + +.app-item-right-error { + color: red; +} + +::ng-deep .mat-pseudo-checkbox-checked::after { + left: 1px !important; + width: 11px !important; + height: 5px !important; +} \ No newline at end of file diff --git a/portal-FE-os/src/app/pages/users/new-user-modal/new-user-modal.component.spec.ts b/portal-FE-os/src/app/pages/users/new-user-modal/new-user-modal.component.spec.ts new file mode 100644 index 00000000..beb998cf --- /dev/null +++ b/portal-FE-os/src/app/pages/users/new-user-modal/new-user-modal.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 { NewUserModalComponent } from './new-user-modal.component'; + +describe('NewUserModalComponent', () => { + let component: NewUserModalComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ NewUserModalComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(NewUserModalComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/portal-FE-os/src/app/pages/users/new-user-modal/new-user-modal.component.ts b/portal-FE-os/src/app/pages/users/new-user-modal/new-user-modal.component.ts new file mode 100644 index 00000000..76c14f17 --- /dev/null +++ b/portal-FE-os/src/app/pages/users/new-user-modal/new-user-modal.component.ts @@ -0,0 +1,322 @@ +/*- + * ============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, EventEmitter, Output } from '@angular/core'; +import { NgbActiveModal, NgbModal } from '@ng-bootstrap/ng-bootstrap'; +import { ApplicationsService, UsersService } from 'src/app/shared/services'; +import { MatTableDataSource, MatRadioChange } from '@angular/material'; +import { UserAdminApps, UserAccessRoles } from 'src/app/shared/model'; +import { ConfirmationModalComponent } from 'src/app/modals/confirmation-modal/confirmation-modal.component'; +import { InformationModalComponent } from 'src/app/modals/information-modal/information-modal.component'; +import { HttpErrorResponse } from '@angular/common/http'; + +@Component({ + selector: 'app-new-user-modal', + templateUrl: './new-user-modal.component.html', + styleUrls: ['./new-user-modal.component.scss'] +}) +export class NewUserModalComponent implements OnInit { + @Input() dialogState: number; + @Input() userTitle: string; + @Input() disableBack: boolean; + @Input() adminModalData: any; + @Input() userModalData: any; + @Output() passBackNewUserPopup: EventEmitter = new EventEmitter(); + changedSelectedUser: any; + showSpinner: boolean; + isGettingAdminApps: boolean; + adminApps: any; + modelSelectedRoles: any; + appRoles: Array; + numberAppsProcessed: number; + isSystemUserCheck = false; + extRequestValue = false; + searchTitleText = 'Enter First Name, Last Name or Org-ID'; + placeholderText = 'Search'; + ngRepeatDemo = [ + { id: 'userButton', value: 'true', labelValue: 'User' }, + { id: 'systemUserButton', value: 'false', labelValue: 'System' } + ] + selectedvalueradioButtonGroup = { + type: 'true' + } + userRadioSearchButton = this.ngRepeatDemo[0].labelValue; + displayedColumns: string[] = ['applications', 'roles', 'delete']; + userAdminAppsSource = new MatTableDataSource(this.adminApps); + showAppSpinner: boolean; + isError: boolean; + errorMessage: any; + originalSelectedRoles: any; + numberAppsSucceeded: number; + anyChanges: boolean; + orgUserIdValue: string; + constructor(public ngbModal: NgbModal, public activeModal: NgbActiveModal, private applicationsService: ApplicationsService, private usersService: UsersService) { } + + ngOnInit() { + this.appRoles = []; + this.adminApps = []; + this.anyChanges = false; + this.modelSelectedRoles = []; + this.originalSelectedRoles = []; + this.changedSelectedUser = null; + if (this.dialogState === 2) { + this.changedSelectedUser = this.userModalData; + this.orgUserIdValue = this.changedSelectedUser.orgUserId; + this.getUserAppsRoles(); + } + } + + addUserFlag : boolean = false; + + addNewUser(newUserFlag : boolean){ + console.log("New user flag ", newUserFlag); + this.addUserFlag = true; + } + + changeSelectedUser(user: any) { + this.changedSelectedUser = user; + if (this.changedSelectedUser.firstName === undefined || this.changedSelectedUser.lastName === undefined) { + this.userTitle = this.changedSelectedUser; + this.orgUserIdValue = this.changedSelectedUser; + } + else { + this.orgUserIdValue = this.changedSelectedUser.orgUserId; + this.userTitle = `${this.changedSelectedUser.firstName}, ` + ` ${this.changedSelectedUser.lastName} ` + ` (${this.changedSelectedUser.orgUserId})`; + } + } + + searchUserRadioChange($event: MatRadioChange) { + if ($event.value === 'System') { + this.searchTitleText = 'Enter System UserID'; + this.placeholderText = 'xxxxxx@org.com'; + this.isSystemUserCheck = true; + } else { + this.searchTitleText = 'Enter First Name, Last Name or ATTUID'; + this.placeholderText = 'Search'; + this.isSystemUserCheck = false; + } + } + + navigateBack() { + this.anyChanges = false; + this.dialogState = 1; + } + + roleSelectChange(element: any) { // update this.adminApps list when user select roles from dropdown + let existingSelectedRoles = this.modelSelectedRoles; + this.modelSelectedRoles = []; + this.anyChanges = true; + this.adminApps.forEach(_item => { + if (_item.id === element.id) { + _item['isChanged'] = true; + } + let appRoleList = _item.appRoles; + if (appRoleList != undefined) { + appRoleList.forEach(_itemRole => { + if (_itemRole.appId === element.id) { + const index = existingSelectedRoles.indexOf(_itemRole); + if (index != -1) { + _itemRole.isApplied = true; + } else { + _itemRole.isApplied = false; + } + } + if (_itemRole.isApplied) + this.modelSelectedRoles.push(_itemRole); + }); + } + }); + } + + getUserAppsRoles() { + if (this.changedSelectedUser === undefined) { + this.dialogState = 1; + return; + } + this.isGettingAdminApps = true; + this.applicationsService.getAdminApps().subscribe((apps: Array) => { + this.isGettingAdminApps = false; + if (!apps || !apps.length) { + return null; + } + this.adminApps = apps; + this.dialogState = 2; + this.numberAppsProcessed = 0; + this.showSpinner = true; + apps.forEach(app => { + //$log.debug('NewUserModalCtrl::getUserAppsRoles: app: id: ', app.id, 'name: ',app.name); + // Keep track of which app has changed, so we know which apps to update using a BE API + app['isChanged'] = false; + // Each of these specifies a state, which corresponds to a different message and style that gets displayed + app['showSpinner'] = true; + app['isError'] = false; + app['isDeleted'] = false; + app['printNoChanges'] = false; + app['isUpdating'] = false; + app['isErrorUpdating'] = false; + app['isDoneUpdating'] = false; + app['errorMessage'] = ""; + this.usersService.getUserAppRoles(app.id, this.orgUserIdValue, this.extRequestValue, this.isSystemUserCheck).toPromise().then((userAppRolesResult) => { + app['appRoles'] = userAppRolesResult; + app['showSpinner'] = false; + for (var i = 0; i < app['appRoles'].length; i++) { + app['appRoles'][i]['appId'] = app.id; + if (app['appRoles'][i].roleName.indexOf('global_') != -1) { + app['appRoles'][i].roleName = '*' + app['appRoles'][i].roleName; + } + if (app['appRoles'][i].isApplied) + this.modelSelectedRoles.push(app['appRoles'][i]); + } + }).catch((err: HttpErrorResponse) => { + app['isError'] = true; + app['showSpinner'] = false; + if (err.status == 200 || err.message.toLowerCase().includes("rollback")) + app['errorMessage'] = 'Error: ' + 500; + else + app['errorMessage'] = 'Error: ' + err.status; + }).finally(() => { + this.numberAppsProcessed++; + if (this.numberAppsProcessed === this.adminApps.length) { + this.originalSelectedRoles = this.modelSelectedRoles; + this.showSpinner = false; + } + }); + }) + this.userAdminAppsSource = new MatTableDataSource(this.adminApps); + }, (_err) => { + + }) + } + + updateUserAppsRoles() { + this.anyChanges = false; + if (!this.changedSelectedUser || + (this.changedSelectedUser.orgUserId == undefined && !this.isSystemUserCheck) || + !this.adminApps) { + return; + } + this.showSpinner = true; + this.numberAppsProcessed = 0; + this.numberAppsSucceeded = 0; + this.adminApps.forEach(app => { + if (app.isChanged) { + app.isUpdating = true; + for (var i = 0; i < app.appRoles.length; i++) { + if (app.appRoles[i].roleName.indexOf('*global_') != -1) { + app.appRoles[i].roleName = app.appRoles[i].roleName.replace('*', ''); + } + } + var newUserAppRoles = { + orgUserId: this.orgUserIdValue, + appId: app.id, + appRoles: app.appRoles, + appName: app.name, + isSystemUser: this.isSystemUserCheck + }; + this.usersService.updateUserAppRoles(newUserAppRoles).toPromise() + .then((res: any) => { + if (res.status && res.status.toLowerCase() === 'error') { + const modalErrorRef = this.ngbModal.open(ConfirmationModalComponent); + modalErrorRef.componentInstance.message = "Error: " + res.message; + } + app.isUpdating = false; + app.isDoneUpdating = true; + this.numberAppsSucceeded++; + }).catch(err => { + var errorMessage = 'Failed to update the user application roles: ' + err; + if (err.status == 504) { + this.numberAppsSucceeded++; + errorMessage = 'Request is being processed, please check back later!'; + } else { + app.isErrorUpdating = true; + } + const modalErrorRef = this.ngbModal.open(ConfirmationModalComponent); + modalErrorRef.componentInstance.message = errorMessage; + }).finally(() => { + this.numberAppsProcessed++; + if (this.numberAppsProcessed === this.adminApps.length) { + this.showSpinner = false; // hide the spinner + } + if (this.numberAppsSucceeded === this.adminApps.length) { + this.passBackNewUserPopup.emit(); + this.activeModal.close('Close');//close and resolve dialog promise with true (to update the table) + } + }) + } else { + app.noChanges = true; + app.isError = false; //remove the error message; just show the No Changes messages + this.numberAppsProcessed++; + this.numberAppsSucceeded++; + if (this.numberAppsProcessed === this.adminApps.length) { + this.showSpinner = false; // hide the spinner + } + if (this.numberAppsSucceeded === this.adminApps.length) { + this.activeModal.close('Close'); + } + } + }); + } + + deleteApp(app) { + let appMessage = this.changedSelectedUser.firstName + ' ' + this.changedSelectedUser.lastName; + const ngbModalConfirm = this.ngbModal.open(InformationModalComponent); + ngbModalConfirm.componentInstance.title = 'Confirmation'; + ngbModalConfirm.componentInstance.message = 'Are you sure you want to delete ' + appMessage; + ngbModalConfirm.result.then((_res) => { + if (_res === 'Ok') { + this.anyChanges = true; + app.isChanged = true; + app.isDeleted = true; // use this to hide the app in the display + app.appRoles.forEach((role) => { + role.isApplied = false; + }); + // remove app roles if user app delete option is selected + this.modelSelectedRoles.forEach((_role, index) => { + if (_role.appId === app.id) this.modelSelectedRoles.splice(index, 1); + }) + this.roleSelectChange(app); + } + }).catch(err => { + // $log.error('NewUserModalCtrl::deleteApp error: ',err); + const ngbModalError = this.ngbModal.open(InformationModalComponent); + ngbModalError.componentInstance.title = 'Error'; + ngbModalError.componentInstance.message = 'There was a problem deleting the the applications. ' + + 'Please try again later. Error: ' + err.status; + }); + } + +} diff --git a/portal-FE-os/src/app/pages/users/user-details-form/user-details-form.component.html b/portal-FE-os/src/app/pages/users/user-details-form/user-details-form.component.html new file mode 100644 index 00000000..7fc35e44 --- /dev/null +++ b/portal-FE-os/src/app/pages/users/user-details-form/user-details-form.component.html @@ -0,0 +1,118 @@ + + diff --git a/portal-FE-os/src/app/pages/users/user-details-form/user-details-form.component.scss b/portal-FE-os/src/app/pages/users/user-details-form/user-details-form.component.scss new file mode 100644 index 00000000..e69de29b diff --git a/portal-FE-os/src/app/pages/users/user-details-form/user-details-form.component.spec.ts b/portal-FE-os/src/app/pages/users/user-details-form/user-details-form.component.spec.ts new file mode 100644 index 00000000..3262174f --- /dev/null +++ b/portal-FE-os/src/app/pages/users/user-details-form/user-details-form.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { UserDetailsFormComponent } from './user-details-form.component'; + +describe('UserDetailsFormComponent', () => { + let component: UserDetailsFormComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ UserDetailsFormComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(UserDetailsFormComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/portal-FE-os/src/app/pages/users/user-details-form/user-details-form.component.ts b/portal-FE-os/src/app/pages/users/user-details-form/user-details-form.component.ts new file mode 100644 index 00000000..bea0fcdb --- /dev/null +++ b/portal-FE-os/src/app/pages/users/user-details-form/user-details-form.component.ts @@ -0,0 +1,51 @@ +import { Component, OnInit } from '@angular/core'; +import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { MustMatch } from 'src/app/shared/helpers/must-match-validator'; +import { UsersService } from 'src/app/shared/services'; +import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; + +@Component({ + selector: 'app-user-details-form', + templateUrl: './user-details-form.component.html', + styleUrls: ['./user-details-form.component.scss'] +}) +export class UserDetailsFormComponent implements OnInit { + addNewUserForm: FormGroup; + submitted = false; + + constructor(private formBuilder: FormBuilder, + private usersService: UsersService, + public activeModal: NgbActiveModal) { } + + ngOnInit() { + this.addNewUserForm = this.formBuilder.group({ + firstName: ['', Validators.required], + middleInitial: [''], + lastName: ['', Validators.required], + email: ['', [Validators.required, Validators.email]], + loginId: ['', Validators.required], + loginPwd: ['', [Validators.required, Validators.minLength(6)]], + confirmPassword: ['', Validators.required] + }, { + validator: MustMatch('loginPwd', 'confirmPassword') + }); + } + + get formValue() { + return this.addNewUserForm.controls; + } + + addUser() { + this.submitted = true; + if (this.addNewUserForm.invalid) { + console.log("Invalid form!!"); + return; + } + console.log("New user Json : " + JSON.stringify(this.addNewUserForm.value)); + console.log("Get Raw value : " + this.addNewUserForm.getRawValue()); + let newUserFormData = JSON.stringify(this.addNewUserForm.getRawValue()); + this.usersService.addNewUser(newUserFormData); + this.activeModal.close(); + } + +} -- cgit 1.2.3-korg