summaryrefslogtreecommitdiffstats
path: root/portal-FE-os/src/app/pages/users
diff options
context:
space:
mode:
authorSunder Tattavarada <statta@research.att.com>2020-02-04 15:19:19 +0000
committerGerrit Code Review <gerrit@onap.org>2020-02-04 15:19:19 +0000
commit099ece77f49e4a6bc4d9b35ef03a5e0f33bf8384 (patch)
tree43ebcfcc2fb394b729853f4df14a149940c90e36 /portal-FE-os/src/app/pages/users
parent728c55e4233b5f7e449f67dea4c4ca987da701b7 (diff)
parent3f7386d4245f9a05db961440ebf80d97d788f902 (diff)
Merge "Added portal-FE-os components"
Diffstat (limited to 'portal-FE-os/src/app/pages/users')
-rw-r--r--portal-FE-os/src/app/pages/users/new-user-modal/new-user-modal.component.html125
-rw-r--r--portal-FE-os/src/app/pages/users/new-user-modal/new-user-modal.component.scss51
-rw-r--r--portal-FE-os/src/app/pages/users/new-user-modal/new-user-modal.component.spec.ts62
-rw-r--r--portal-FE-os/src/app/pages/users/new-user-modal/new-user-modal.component.ts322
-rw-r--r--portal-FE-os/src/app/pages/users/user-details-form/user-details-form.component.html118
-rw-r--r--portal-FE-os/src/app/pages/users/user-details-form/user-details-form.component.scss0
-rw-r--r--portal-FE-os/src/app/pages/users/user-details-form/user-details-form.component.spec.ts25
-rw-r--r--portal-FE-os/src/app/pages/users/user-details-form/user-details-form.component.ts51
8 files changed, 754 insertions, 0 deletions
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 @@
+<!--
+ ============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">&times;</span>
+ </button>
+ </div>
+ <div class="modal-body" *ngIf="!addUserFlag">
+ <app-search-users [searchTitle]="searchTitleText" [isSystemUser]="isSystemUserCheck" [placeHolder]="placeholderText"
+ (passBackSelectedUser)='changeSelectedUser($event)' (userNotFoundFlag)='addNewUser($event)'></app-search-users>
+ </div>
+ <div *ngIf="addUserFlag">
+ <app-user-details-form></app-user-details-form>
+ </div>
+ <div class="modal-footer" *ngIf="!addUserFlag">
+ <button type="submit" class="btn btn-primary" [disabled]='!changedSelectedUser && !isSystemUserCheck'
+ (click)="getUserAppsRoles()">Next</button> &nbsp;
+ <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">&times;</span>
+ </button>
+ </div>
+ <div class="modal-body adminApps">
+ <!-- User App Roles List -->
+ <span class="ecomp-spinner" *ngIf="adminApps.length === 0"></span>
+ <div class="container adminApps" *ngIf="adminApps.length > 0">
+ Access and roles:
+ <table mat-table [dataSource]="userAdminAppsSource">
+ <!-- Search Result Column-->
+ <ng-container matColumnDef="applications">
+ <th id="rowheader-result" mat-header-cell *matHeaderCellDef> Application
+ <td id="table-data-{{i}}" mat-cell *matCellDef="let element; let i = index;">{{element.name}}
+ </td>
+ </ng-container>
+ <ng-container matColumnDef="roles">
+ <th id="rowheader-result" mat-header-cell *matHeaderCellDef> Roles
+ <td id="rowheader_t1_{{i}}-roles" mat-cell *matCellDef="let element; let i=index;">
+ <mat-form-field
+ [hidden]="element.isError || element.showSpinner || element.noChanges || element.isUpdating || element.isDoneUpdating || element.isErrorUpdating">
+ <mat-select (selectionChange)="roleSelectChange(element)"
+ [(ngModel)]="modelSelectedRoles" multiple>
+ <mat-option *ngFor="let appRole of element.appRoles; let j = index;" [value]="appRole">
+ {{appRole.roleName}}
+ </mat-option>
+ </mat-select>
+ </mat-form-field>
+ <span id="app-item-no-contact" class="app-item-right-error"
+ [hidden]="!element.isError">{{element.errorMessage}}</span>
+ <span id="app-item-contacting" class="app-item-right-contacting" [hidden]="!element.showSpinner">Contacting
+ application... <span class="ecomp-small-spinner" *ngIf="showSpinner"></span></span>
+ <span id="app-item-no-changes" class="app-item-right-contacting" [hidden]="!element.noChanges">No
+ changes</span>
+ <span id="app-item-no-updating" class="app-item-right-contacting" [hidden]="!element.isUpdating">Updating
+ application... <span class="ecomp-small-spinner" *ngIf="showSpinner"></span></span>
+ <span id="app-item-done-updating" class="app-item-right-contacting"
+ [hidden]="!element.isDoneUpdating">Finished updating application</span>
+ <span id="app-item-cannot-update" class="app-item-right-error" [hidden]="!element.isErrorUpdating">Could not
+ update application... </span>
+ </td>
+ </ng-container>
+ <ng-container matColumnDef="delete">
+ <th id="rowheader-result" mat-header-cell *matHeaderCellDef> Delete
+ <td id="table-data-{{i}}" mat-cell *matCellDef="let element; let i = index;">
+ <span class="icon-trash" id="app-item-delete-{{i}}" [hidden]="element.showSpinner || element.isError"
+ (click)="deleteApp(element)">
+ <i class="icon ion-md-trash"></i>
+ </span>
+ </td>
+ </ng-container>
+ <tr mat-header-row *matHeaderRowDef="displayedColumns; sticky: true"></tr>
+ <tr [hidden]="row.isDeleted" 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> &nbsp;
+ <button type="submit" class="btn btn-primary" [disabled]='!anyChanges' (click)="updateUserAppsRoles()">Save</button>
+ &nbsp;
+ <button type="button" class="btn btn-primary" (click)="activeModal.close('Close')">Close</button>
+ </div>
+</div>
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<NewUserModalComponent>;
+
+ 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<any> = new EventEmitter();
+ changedSelectedUser: any;
+ showSpinner: boolean;
+ isGettingAdminApps: boolean;
+ adminApps: any;
+ modelSelectedRoles: any;
+ appRoles: Array<UserAccessRoles>;
+ 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<UserAdminApps>) => {
+ 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 @@
+<div class="modal-body">
+ <form [formGroup]="addNewUserForm">
+ <div class="modal-body">
+ <div class="new-users-details-modal">
+ <div class="new-users-main">
+
+ <!-- First Name -->
+ <div class="new-users-container">
+ <div class="form-group">
+ <div>*First Name</div>
+ <input class="form-control" formControlName="firstName" type="text"
+ [ngClass]="{ 'is-invalid': submitted && formValue.firstName.errors }" />
+ <div *ngIf="submitted && formValue.firstName.errors" class="invalid-feedback">
+ <div *ngIf="formValue.firstName.errors.required">
+ First Name is required
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <!-- Middle Name -->
+ <div class="new-users-container">
+ <div class="form-group">
+ <div>Middle Name</div>
+ <input class="form-control" formControlName="middleInitial" type="text" />
+ </div>
+ </div>
+
+ <!-- Last Name -->
+ <div class="new-users-container">
+ <div class="form-group">
+ <div>*Last Name</div>
+ <input class="form-control" formControlName="lastName" type="text"
+ [ngClass]="{ 'is-invalid': submitted && formValue.lastName.errors }" />
+ <div *ngIf="submitted && formValue.lastName.errors" class="invalid-feedback">
+ <div *ngIf="formValue.lastName.errors.required">
+ Last Name is required
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <!-- Email Address ID -->
+ <div class="new-users-container">
+ <div class="form-group">
+ <div>*Email Address ID</div>
+ <input class="form-control" formControlName="email" type="text"
+ [ngClass]="{ 'is-invalid': submitted && formValue.email.errors }" />
+ <div *ngIf="submitted && formValue.email.errors" class="invalid-feedback">
+ <div *ngIf="formValue.email.errors.required">
+ Email Address is required
+ </div>
+ <div *ngIf="formValue.email.errors.email">
+ Email Address is invalid
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <!-- Login ID -->
+ <div class="new-users-container">
+ <div class="form-group">
+ <div>*Login ID</div>
+ <input class="form-control" formControlName="loginId" type="text"
+ [ngClass]="{ 'is-invalid': submitted && formValue.loginId.errors }" />
+ <div *ngIf="submitted && formValue.loginId.errors" class="invalid-feedback">
+ <div *ngIf="formValue.loginId.errors.required">
+ Login ID is required
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <!-- Login Password -->
+ <div class="new-users-container">
+ <div class="form-group">
+ <div>*Login Password</div>
+ <input class="form-control" formControlName="loginPwd" type="password"
+ [ngClass]="{ 'is-invalid': submitted && formValue.loginPwd.errors }" />
+ <div *ngIf="submitted && formValue.loginPwd.errors" class="invalid-feedback">
+ <div *ngIf="formValue.loginPwd.errors.required">
+ Password is required
+ </div>
+ <div *ngIf="formValue.loginPwd.errors.minlength">
+ Password must be at least 8 characters
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <!-- Confirm Login Password -->
+ <div class="new-users-container">
+ <div class="form-group">
+ <div>*Confirm Password</div>
+ <input class="form-control" formControlName="confirmPassword" type="password"
+ [ngClass]="{ 'is-invalid': submitted && formValue.confirmPassword.errors }"
+ appEqualValidator="password" />
+ <div *ngIf="submitted && formValue.confirmPassword.errors" class="invalid-feedback">
+ <div *ngIf="formValue.confirmPassword.errors.required">
+ Confirm Login password
+ </div>
+ <div *ngIf="formValue.confirmPassword.errors.mustMatch">
+ Password Must Match
+ </div>
+ </div>
+ </div>
+ </div>
+
+
+ </div>
+ </div>
+ </div>
+ </form>
+</div>
+<div class="modal-footer">
+ <button type="submit" class="btn btn-primary" (click)="addUser()" [disabled]="addNewUserForm.invalid">Next</button> &nbsp;
+ <button type="button" class="btn btn-primary" aria-label="Close" (click)="activeModal.dismiss('Cross')">Close</button>
+</div>
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
--- /dev/null
+++ b/portal-FE-os/src/app/pages/users/user-details-form/user-details-form.component.scss
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<UserDetailsFormComponent>;
+
+ 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();
+ }
+
+}