diff options
Diffstat (limited to 'portal-FE-os/src/app')
21 files changed, 973 insertions, 330 deletions
diff --git a/portal-FE-os/src/app/.gitignore b/portal-FE-os/src/app/.gitignore index 75b6ddab..fe6b8ee1 100644 --- a/portal-FE-os/src/app/.gitignore +++ b/portal-FE-os/src/app/.gitignore @@ -1,5 +1,6 @@ /ng-material-module.ts /layout/ +!layout/components/search-users /modals/ /shared/ !shared/interceptors/ diff --git a/portal-FE-os/src/app/app.component.html b/portal-FE-os/src/app/app.component.html index dea5177c..2c914c52 100644 --- a/portal-FE-os/src/app/app.component.html +++ b/portal-FE-os/src/app/app.component.html @@ -35,5 +35,7 @@ --> - +<div class="diaplay-banner" *ngIf="diaplayBanner"> + <span>{{browserCompatibilityMsg}}</span> +</div> <router-outlet></router-outlet> diff --git a/portal-FE-os/src/app/app.component.scss b/portal-FE-os/src/app/app.component.scss index 7a773398..e739496d 100644 --- a/portal-FE-os/src/app/app.component.scss +++ b/portal-FE-os/src/app/app.component.scss @@ -34,4 +34,14 @@ * ============LICENSE_END============================================ * * - */
\ No newline at end of file + */ + + .diaplay-banner{ + margin-top: 14px; + background-color: yellow; + font-weight: bold; + position: fixed; + z-index: 9999; + margin-left: 34em; + height: 24px; +}
\ No newline at end of file diff --git a/portal-FE-os/src/app/app.component.ts b/portal-FE-os/src/app/app.component.ts index dbfb568f..389153bd 100644 --- a/portal-FE-os/src/app/app.component.ts +++ b/portal-FE-os/src/app/app.component.ts @@ -35,13 +35,49 @@ * * */ -import { Component } from '@angular/core'; +import { Component, OnInit } from '@angular/core'; +import { environment } from 'src/environments/environment'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.scss'] }) -export class AppComponent { - -} +export class AppComponent implements OnInit { + diaplayBanner : boolean = false; + api = environment.api; + browserCompatibilityMsg: string; + + ngOnInit() { + this.diaplayBanner = false; + this.browserCompatibilityMsg = this.api.browserCompatibilityMsg; + this.getBrowserName(); + } + + /** + * Identify Browser + */ + getBrowserName() { + const agent = window.navigator.userAgent.toLowerCase(); + switch (true) { + case agent.indexOf('edge') > -1: + return 'edge'; + case agent.indexOf('opr') > -1 && !!(<any>window).opr: + this.diaplayBanner = true; + return 'opera'; + case agent.indexOf('chrome') > -1 && !!(<any>window).chrome: + return 'chrome'; + case agent.indexOf('trident') > -1: + this.diaplayBanner = true; + return 'ie'; + case agent.indexOf('firefox') > -1: + return 'firefox'; + case agent.indexOf('safari') > -1: + this.diaplayBanner = true; + return 'safari'; + default: + this.diaplayBanner = true; + return 'other'; + } + } +}
\ No newline at end of file diff --git a/portal-FE-os/src/app/layout/components/search-users/search-users.component.html b/portal-FE-os/src/app/layout/components/search-users/search-users.component.html new file mode 100644 index 00000000..4c318f9f --- /dev/null +++ b/portal-FE-os/src/app/layout/components/search-users/search-users.component.html @@ -0,0 +1,73 @@ +<!-- + ============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============================================ + + + --> + +<form> + {{searchTitle}} + <div class="form-row"> + <div class="col-md-6 my-1"> + <label for="inputSearch" class="sr-only"></label> + <input id="inputSearch" pattern="[a-zA-Z0-9-'\s]{3,}" [(ngModel)]="searchString" (keyup)="passSystemUserInfo($event.srcElement.value)" maxlength="80" + required="true" name="searchString" #searchInput auto-focus tabindex="0" autocomplete="off" type="text" + class="form-control" value="searchString" placeholder="{{placeHolder}}"> + </div> + + <div class="col-auto my-1"> + <button id="button-search-users" *ngIf="!isSystemUser" [disabled]="!searchInput.validity.valid || isLoading " type="submit" + class="btn btn-primary mb-2" (click)="searchUsers()"> Search + </button> + </div> + </div> +</form> +<span class="ecomp-spinner" *ngIf="isLoading"></span> +<div class="search-user-container" *ngIf="showUserTable && !isSystemUser"> + <table mat-table [dataSource]="dataSourceMap"> + <!-- Search Result Column--> + <ng-container matColumnDef="firstName"> + <th id="rowheader-result" mat-header-cell *matHeaderCellDef> Showing {{searchUsersResults.length}} {{txtResults}} </th> + <td id="table-data-{{i}}" mat-cell *matCellDef="let element; let i = index;"> + {{element.firstName}} {{element.lastName}} <br> {{element.jobTitle}} + </td> + </ng-container> + <tr mat-header-row *matHeaderRowDef="displayedColumns; sticky: true"></tr> + <tr mat-row (click)="setSelectedUser(row)" id="table-row-{{i}}" [ngClass]="{ 'selected': row === selectedUser }" + *matRowDef="let row; columns: displayedColumns; let i = index;"></tr> + </table> +</div> +<div class="search-user-container" *ngIf="noUserFlag"> + <p>{{message}} Or <a href="javascript:void(0);" (click)="addNewUser()"><b>Click Here</b></a> to add <b>New User!</b></p> +</div>
\ No newline at end of file diff --git a/portal-FE-os/src/app/layout/components/search-users/search-users.component.scss b/portal-FE-os/src/app/layout/components/search-users/search-users.component.scss new file mode 100644 index 00000000..95a2a5ec --- /dev/null +++ b/portal-FE-os/src/app/layout/components/search-users/search-users.component.scss @@ -0,0 +1,56 @@ +/*- + * ============LICENSE_START========================================== + * ONAP Portal + * =================================================================== + * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * + * Unless otherwise specified, all software contained herein is licensed + * under the Apache License, Version 2.0 (the "License"); + * you may not use this software except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Unless otherwise specified, all documentation contained herein is licensed + * under the Creative Commons License, Attribution 4.0 Intl. (the "License"); + * you may not use this documentation except in compliance with the License. + * You may obtain a copy of the License at + * + * https://creativecommons.org/licenses/by/4.0/ + * + * Unless required by applicable law or agreed to in writing, documentation + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ============LICENSE_END============================================ + * + * + */ + +@import "../../../pages/pages.component"; + +.mat-row { + cursor: pointer; + background-color: #f2f2f2; +} +.selected { + background-color: #ffffff !important; +} + +.search-user-container { + overflow-y: auto; + height: 250px; +} + +.ecomp-spinner{ + opacity: 10; +} diff --git a/portal-FE-os/src/app/layout/components/search-users/search-users.component.spec.ts b/portal-FE-os/src/app/layout/components/search-users/search-users.component.spec.ts new file mode 100644 index 00000000..9db3e395 --- /dev/null +++ b/portal-FE-os/src/app/layout/components/search-users/search-users.component.spec.ts @@ -0,0 +1,67 @@ +/*- + * ============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 { SearchUsersComponent } from './search-users.component'; +import { NgMaterialModule } from 'src/app/ng-material-module'; +import { FormsModule } from '@angular/forms'; +import { HttpClientTestingModule } from '@angular/common/http/testing'; + +describe('SearchUsersComponent', () => { + let component: SearchUsersComponent; + let fixture: ComponentFixture<SearchUsersComponent>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ SearchUsersComponent ], + imports: [FormsModule,NgMaterialModule,HttpClientTestingModule] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(SearchUsersComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/portal-FE-os/src/app/layout/components/search-users/search-users.component.ts b/portal-FE-os/src/app/layout/components/search-users/search-users.component.ts new file mode 100644 index 00000000..10e4e041 --- /dev/null +++ b/portal-FE-os/src/app/layout/components/search-users/search-users.component.ts @@ -0,0 +1,115 @@ +/*- + * ============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, ViewChild, Output, EventEmitter } from '@angular/core'; +import { UsersService } from 'src/app/shared/services'; +import { MatTableDataSource, MatPaginator, MatSort } from '@angular/material'; +import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; +import { ConfirmationModalComponent } from 'src/app/modals/confirmation-modal/confirmation-modal.component'; +import { PortalAdmin } from 'src/app/shared/model/PortalAdmin'; + +@Component({ + selector: 'app-search-users', + templateUrl: './search-users.component.html', + styleUrls: ['./search-users.component.scss'] +}) +export class SearchUsersComponent implements OnInit { + + constructor(private userService: UsersService, private ngModal: NgbModal) { } + @Input() searchTitle: string; + @Input() placeHolder: string; + @Input() isSystemUser: boolean; + @ViewChild(MatSort) sort: MatSort; + @ViewChild(MatPaginator) paginator: MatPaginator; + @Output() passBackSelectedUser: EventEmitter<any> = new EventEmitter(); + @Output() userNotFoundFlag = new EventEmitter<boolean>(); + searchString: string; + txtResults = 'result'; + searchUsersResults: any; + selected: any; + isLoading: boolean; + showUserTable: boolean; + selectedUser: any; + displayedColumns: string[] = ['firstName']; + dataSourceMap = new MatTableDataSource(this.searchUsersResults); + submitted = false; + message = " No users found with your query. Please change your search and try again."; + + ngOnInit() { + this.searchString = ''; + this.showUserTable = false; + this.isSystemUser = false; + } + + passSystemUserInfo(systemUser: string) { + if (this.isSystemUser) + this.passBackSelectedUser.emit(systemUser); + } + + noUserFlag: boolean = false; + searchUsers() { + if (!this.isSystemUser) { + this.isLoading = true; + this.showUserTable = false; + this.passBackSelectedUser.emit(this.selectedUser = ''); + this.userService.searchUsers(this.searchString).subscribe((_data: PortalAdmin) => { + this.searchUsersResults = _data; + if (this.searchUsersResults == null || this.searchUsersResults.length == 0) { + this.noUserFlag = true; + this.isLoading = false; + } else { + this.noUserFlag = false; + this.showUserTable = true; + this.isLoading = false; + this.dataSourceMap = new MatTableDataSource(this.searchUsersResults); + this.txtResults = (this.searchUsersResults && this.searchUsersResults.length > 1) ? 'results' : 'result'; + } + }); + } + } + + setSelectedUser(user: PortalAdmin) { + this.selectedUser = user; + this.passBackSelectedUser.emit(this.selectedUser); + } + + addNewUser() { + console.log("Emit the value to parent"); + this.userNotFoundFlag.emit(true); + } + +} diff --git a/portal-FE-os/src/app/pages/application-onboarding/application-details-dialog/application-details-dialog.component.html b/portal-FE-os/src/app/pages/application-onboarding/application-details-dialog/application-details-dialog.component.html index bef37b84..f68d8798 100644 --- a/portal-FE-os/src/app/pages/application-onboarding/application-details-dialog/application-details-dialog.component.html +++ b/portal-FE-os/src/app/pages/application-onboarding/application-details-dialog/application-details-dialog.component.html @@ -36,240 +36,308 @@ --> <div class="container"> - <!--Modal Headers--> + <!--Modal Headers--> <div class="modal-header"> <h4 class="modal-title">Application Details</h4> <button type="button" class="close" aria-label="Close" (click)="activeModal.dismiss('Cross')"> <span aria-hidden="true">×</span> </button> </div> - <!--Modal Body goes here--> + <!--Modal Body goes here--> <div class="modal-body"> <div class="application-details-modal"> - <div class="app-properties-main" scroll-top="appDetails.scrollApi"> - <form name="appForm" novalidate autocomplete="off"> - <div id="app-left-container" class="left-container"> - <div class="property-label checkbox-label"> + <div class="app-properties-main" scroll-top="appDetails.scrollApi"> + <form name="appForm" novalidate autocomplete="off"> + <div id="app-left-container" class="left-container"> + <!-- <div class="property-label checkbox-label"> <mat-checkbox name="isRestrictedApp" type="checkbox" [(ngModel)]="applicationObj.restrictedApp" id="checkbox-app-is-restricted" [disabled]="isEditMode" [checked]="applicationObj.restrictedApp"> Hyperlink only application </mat-checkbox> - </div> - - <div class="property required"> - <div class="property-label">Application Name</div> - <input id="input-app-name" type="text" - [(ngModel)]="applicationObj.name" maxlength="100" name="name" - pattern="/^[a-zA-Z0-9_\-\s\&]*$/" required="true" /> - - <div id="error-container-conflict" class="error-container" ng-show="appDetails.conflictMessages.name" - id="conflictMessages-name"> - <small id="app-name-error-conflict" class="err-message" - ng-bind="appDetails.conflictMessages.name"> - </small> - </div> - - <div id="error-container-edit" class="error-container" - *ngIf="(!applicationObj.name || applicationObj.name.length == 0)"> - <small id="app-name-error-required" class="err-message"> - Application name is required - </small> - </div> - </div> - - <div [ngClass]="(applicationObj.isEnabled) ? 'property required' : 'property'"> - <div id="url-property-label" class="property-label">URL</div> - <input id="input-app-url" [(ngModel)]="applicationObj.url" - maxlength="256" name="url" type="url" placeholder="https://" - pattern="/^((?:https?\:\/\/|ftp?\:\/\/)?(w{3}.)?(?:[-a-z0-9]+\.)*[-a-z0-9]+.*)[^-_.]$/i" required /> + </div> --> + + <div class="property required"> + <div class="property-label" style="display: flex;"> + <span style="flex: 9">Application Name</span> + <app-information-tooltip style="flex: 1;" + [textMessage]="'Application Name Information'"> + </app-information-tooltip> + </div> + <input #applicationName id="input-app-name" type="text" [(ngModel)]="applicationObj.appName" + maxlength="100" name="name" pattern="/^[a-zA-Z0-9_\-\s\&]*$/" required="true" /> - <div id="error-container-edit" class="error-container" - *ngIf="(applicationObj.isEnabled && applicationObj.url=='')"> - <small id="app-name-error-required" class="err-message"> - Application URL is required - </small> + <div id="error-container-conflict" class="error-container" + ng-show="appDetails.conflictMessages.name" id="conflictMessages-name"> + <small id="app-name-error-conflict" class="err-message" + ng-bind="appDetails.conflictMessages.name"> + </small> + </div> </div> - </div> - - <div [ngClass]="(applicationObj.isEnabled) ? 'property required' : 'property'" - [hidden] ="applicationObj.restrictedApp"> - <div class="property-label">Rest API URL</div> - <input id="input-app-rest-url" [(ngModel)]="applicationObj.restUrl" - name="restUrl" type="url" placeholder="https://" - pattern="/^((?:https?\:\/\/|ftp?\:\/\/)?(w{3}.)?(?:[-a-z0-9]+\.)*[-a-z0-9]+.*)[^-_.]$/i" maxlength="256" - ng-required="!applicationObj.restrictedApp" /> - - <div id="error-container-edit" class="error-container" - *ngIf="(applicationObj.isEnabled && applicationObj.restUrl=='')"> - <small id="app-name-error-required" class="err-message"> - Rest API URL is required - </small> + + <div id="property-active" class="property-active" style="display: flex; + justify-content: flex-end;margin-right: 16px;"> + <mat-checkbox name="isEnabled" [(ngModel)]="applicationObj.isEnabled" + [checked]="applicationObj.isEnabled" id="checkbox-app-is-enabled">Active + </mat-checkbox> </div> - </div> - - <div [ngClass]="(applicationObj.isEnabled || applicationObj.isCentralAuth) ? 'property required' : 'property'" - [hidden] ="applicationObj.restrictedApp"> - <div id="username-property-label" class="property-label">Username</div> - <input type="text" id="input-username-property" [(ngModel)]="applicationObj.username" name="username" - maxlength="256" ng-required="!appDetails.app.restrictedApp" /> - - <div id="error-container-edit" class="error-container" - *ngIf="((applicationObj.isEnabled || applicationObj.isCentralAuth) && applicationObj.username =='')"> - <small id="app-name-error-required" class="err-message"> - App Username is required - </small> + + <div class="property"> + <div class="property-label" style="display: flex;"> + <mat-label style="flex: 9">Application Type</mat-label> + <app-information-tooltip style="flex: 1;" + [textMessage]="'Application Type Information - Gui, Hyperlink or Non-gui'"> + </app-information-tooltip> + </div> + <mat-select [disabled]="action === 'edit'" [(value)]="applicationObj.applicationType"> + <mat-option *ngFor="let appType of applicationTypeArray" [value]="appType.value"> + {{appType.name}} + </mat-option> + </mat-select> </div> - </div> - - <div [ngClass]="(applicationObj.isEnabled && !applicationObj.isCentralAuth) ? 'property required' : 'property'" - [hidden] ="applicationObj.restrictedApp"> - <div id="pwd-property-label" class="property-label">Password</div> - <input type="password" id="input-mylogins-password" - [(ngModel)]="applicationObj.appPassword" autocomplete="new-password" - name="appPassword" maxlength="256"/> - <div id="error-container-edit" class="error-container" - *ngIf="(applicationObj.isEnabled && !applicationObj.isCentralAuth && applicationObj.appPassword =='')"> - <small id="app-name-error-required" class="err-message"> - Password is required - </small> + <div class="property" *ngIf="applicationObj.applicationType == '1'"> + <div class="property-label" style="display: flex;"> + <mat-label style="flex: 9">Mode of Integration</mat-label> + <app-information-tooltip style="flex: 1;" + [textMessage]="'Mode Of Integration. SDK or Framework'"> + </app-information-tooltip> + </div> + <mat-select [(value)]="applicationObj.modeOfIntegration"> + <mat-option *ngFor="let integrationType of modeOfIntegration" + [value]="integrationType.value"> + {{integrationType.name}} + </mat-option> + </mat-select> </div> - </div> - </div> - - <!-- Right container--> - <div class="right-container"> - <div class="property"> - <div class="property-label">Upload Image</div> - <input type="file" id="input-app-image-upload" - class="input-file-field input-app-image-upload-ht" - accept="image/*" [(ngModel)]="applicationObj.originalImage" - name="appImage" image-upload="applicationObj.originalImage" - image-upload-resize-max-height="300" - image-upload-resize-max-width="360" - image-upload-resize-quality="0.7" - image-upload-api="appDetails.imageApi" - (change)="appImageHandler($event)" /> - - <div id="app-error-image-upload-type" class="error-container" - *ngIf="appImageTypeError" class="ng-hide"> - <div class="error-container"> - <small id="error-app-invalid-image-size" class="err-message">File must be an image</small> + + <div class="property" *ngIf="!(applicationObj.applicationType == '2')"> + <div class="property-label" style="display: flex;"> + <mat-label style="flex: 9">Roles Management Type</mat-label> + <app-information-tooltip style="flex: 1;" [textMessage]="'Roles Management Type'"> + </app-information-tooltip> + </div> + <mat-select [(value)]="applicationObj.rolesInAAF"> + <mat-option *ngFor="let roleRepo of rolesManagementType" [value]="roleRepo.value"> + {{roleRepo.name}} + </mat-option> + </mat-select> </div> - </div> - - <div id="app-error-image-upload" class="error-container" - *ngIf="(applicationObj.originalImage && applicationObj.originalImage.dirty)"> - <div ng-messages="appForm.appImage.$error" - class="error-container"> - <small id="error-app-invalid-image-size" class="err-message" - ng-message="imageSize">Image file must be smaller than - 1MB</small> + + <div *ngIf="!((applicationObj.applicationType=='2') || (!applicationObj.rolesInAAF))" + class="property-active" style="display: flex;"> + <mat-checkbox style="flex: 9" name="appAck" [(ngModel)]="applicationObj.appAck"> + Notify App For AAF Operations + </mat-checkbox> + <app-information-tooltip style="flex: 1;" + [textMessage]="'Notify application for AAF operations'"> + </app-information-tooltip> </div> - </div> - - <div class="property-label preview"> - <span class="left-label">Preview</span> - <span class="remove" (click)="removeImage()">Remove</span> - </div> - <img id="image-app-preview" class="image-preview" - src="{{applicationObj.imageLink || applicationObj.thumbnail || emptyImgForPreview}}" /> - - <br/> - <div id="property-active" class="property-active"> - <mat-checkbox name="isEnabled" [(ngModel)]="applicationObj.isEnabled" - [checked]="applicationObj.isEnabled" - id="checkbox-app-is-enabled">Active - </mat-checkbox> - </div> - - <div id="property-guest-access" class="property-guest-access"> - <mat-checkbox name="isOpen" [(ngModel)]="applicationObj.isOpen" id="checkbox-app-is-open" - [checked]="(applicationObj.isOpen || applicationObj.restrictedApp)" - [disabled]="applicationObj.restrictedApp">Allow guest access</mat-checkbox> - </div> - - <div class="table-control" style="display: inline-flex;" [hidden] ="applicationObj.restrictedApp"> - <div id="property-is-central-auth" class="property" [hidden] ="applicationObj.restrictedApp"> - <mat-checkbox name="isCentralAuth" [(ngModel)]="applicationObj.isCentralAuth" - id="checkbox-app-is-central-auth" [checked]="applicationObj.isCentralAuth"> - Centralized + + <div class="property-active" *ngIf="!(applicationObj.applicationType == '2' + ||(!applicationObj.rolesInAAF))"> + <mat-checkbox name="usesCadi" [(ngModel)]="applicationObj.usesCadi" + [checked]="applicationObj.usesCadi">Is CADI Enabled? </mat-checkbox> </div> - - <div class="centralized-key" aria-haspopup="true" style="padding-left: 150px;"> - <div b2b-flyout-toggler class="notification-div" > - <div id="tooltip" class="icon-primary-flat-info" tabindex="0" - b2b-accessibility-click="13,32" aria-label="notifications" - aria-haspopup="true" - role="button"></div> + + <div class="table-control" style="display: inline-flex;" + *ngIf="!(applicationObj.applicationType == '2' || !applicationObj.rolesInAAF)"> + + <div [ngClass]="(applicationObj.rolesInAAF) ? 'property required' : 'property'" + style="width: 250px;"> + <div id="pwd-property-label" class="property-label">AAF Namespace</div> + <input type="text" id="input-mylogins-auth-namespace" + [(ngModel)]="applicationObj.nameSpace" name="appAuthNameSpace" maxlength="256" + [disabled]="!applicationObj.rolesInAAF" /> </div> - - <!--<div id="notification" align="left"> - <p class="uuid-text" - style="font: normal 12px Omnes-ECOMP-W02, Arial;"> - To convert the non-centralized app to centralized app please - follow below steps. <a href="https://wiki.web.att.com/display/ECops/BulkUpload" target="_blank"> - https://wiki.web.att.com/display/ECops/BulkUpload</a> - </p> + <div class="communitcaion-key" aria-haspopup="true" style="padding-left: 20px;"> + + <div b2b-flyout-toggler class="notification-div"> + <div id="tooltip" class="icon-primary-flat-info" tabindex="0" + b2b-accessibility-click="13,32" aria-label="notifications" aria-haspopup="true" + role="button"></div> + </div> + <!--<div id="notification" align="left"> + <p class="nameSpace-text" style="font: normal 12px Omnes-ECOMP-W02, Arial;">NameSpace should be created in AAF and portal mechid should be admin of the given namespace.</p> </div>--> + </div> + </div> + + <div *ngIf="!(applicationObj.applicationType == '3')" + [ngClass]="(applicationObj.isEnabled) ? 'property required' : 'property'"> + <div class="property-label" style="display: flex;"> + <span style="flex: 9">Landing Page</span> + <app-information-tooltip style="flex: 1;" [textMessage]="'Application URL Information'"> + </app-information-tooltip> + </div> + <input id="input-app-url" [(ngModel)]="applicationObj.landingPage" maxlength="256" + name="url" type="url" placeholder="https://" + pattern="/^((?:https?\:\/\/|ftp?\:\/\/)?(w{3}.)?(?:[-a-z0-9]+\.)*[-a-z0-9]+.*)[^-_.]$/i" + required /> + + <div id="error-container-edit" class="error-container" + *ngIf="(applicationObj.isEnabled && applicationObj.landingPage=='')"> + <small id="app-name-error-required" class="err-message"> + Landing Page URL is required + </small> + </div> + </div> + + <div [ngClass]="(applicationObj.isEnabled) ? 'property required' : 'property'" + *ngIf="!(applicationObj.applicationType == '2' || applicationObj.applicationType == '3')"> + <div class="property-label" style="display: flex;"> + <span style="flex: 9">Rest API URL</span> + <app-information-tooltip style="flex: 1;" [textMessage]="'Rest Api URL Information'"> + </app-information-tooltip> + </div> + <input id="input-app-rest-url" [(ngModel)]="applicationObj.restUrl" name="restUrl" + type="url" placeholder="https://" + pattern="/^((?:https?\:\/\/|ftp?\:\/\/)?(w{3}.)?(?:[-a-z0-9]+\.)*[-a-z0-9]+.*)[^-_.]$/i" + maxlength="256" ng-required="applicationObj.applicationType == '1'" /> + + <div id="error-container-edit" class="error-container" + *ngIf="(applicationObj.isEnabled && applicationObj.restUrl=='')"> + <small id="app-name-error-required" class="err-message"> + Rest API URL is required + </small> + </div> + </div> + + <div [ngClass]="(applicationObj.isEnabled || applicationObj.rolesInAAF) ? 'property required' : 'property'" + *ngIf="!(applicationObj.applicationType == '2')"> + <div id="username-property-label" class="property-label" style="display: flex;"> + <span style="flex: 9">Auth Configured User</span> + <app-information-tooltip style="flex: 1;" + [textMessage]="'Basic Authentication Username Information'"> + </app-information-tooltip> + </div> + <input type="text" id="input-username-property" + [(ngModel)]="applicationObj.appBasicAuthUsername" name="username" maxlength="256" + ng-required="!appDetails.app.restrictedApp" /> + + <div id="error-container-edit" class="error-container" + *ngIf="((applicationObj.isEnabled || applicationObj.rolesInAAF) && applicationObj.appBasicAuthUsername =='')"> + <small id="app-name-error-required" class="err-message"> + App Username is required + </small> + </div> + </div> + + <div [ngClass]="(applicationObj.isEnabled && !applicationObj.rolesInAAF) ? 'property required' : 'property'" + *ngIf="!(applicationObj.applicationType == '2' || (applicationObj.rolesInAAF && applicationObj.usesCadi))"> + <div id="pwd-property-label" class="property-label" style="display: flex;"> + <span style="flex: 9">Basic Auth Password</span> + <app-information-tooltip style="flex: 1;" + [textMessage]="'Basic Authentication Password Information'"> + </app-information-tooltip> + </div> + <input type="password" id="input-mylogins-password" + [(ngModel)]="applicationObj.appBasicAuthPassword" autocomplete="new-password" + name="appPassword" maxlength="256" /> + + <div id="error-container-edit" class="error-container" + *ngIf="(applicationObj.isEnabled && !applicationObj.rolesInAAF && applicationObj.appBasicAuthPassword =='')"> + <small id="app-name-error-required" class="err-message"> + Password is required + </small> + </div> </div> </div> - - <div class="table-control" style="display: inline-flex;" [hidden] ="applicationObj.restrictedApp"> - <div id="property-communication-key" class="property" - [hidden] ="applicationObj.restrictedApp" style="width: 250px;"> - <div id="property-communication-key-label" class="property-label">Application UUID</div> - <input type="text" id="input-UEB-communication-key" - [(ngModel)]="applicationObj.uebKey" name="uebKey" - readonly="readonly" [disabled]="true"/> + + <!-- Right container--> + <div class="right-container"> + + <div class="property" *ngIf="!(applicationObj.applicationType == '3')"> + <div class="property-label" style="display: flex;"> + <span style="flex: 9">Upload + Image</span> + <app-information-tooltip style="flex: 1;" + [textMessage]="'Image file(.png or.jpg or.jpeg with dimension 200X200 pixel) must be smaller than 1MB.'"> + </app-information-tooltip> + </div> + <input #inputAppImageUpload type="file" id="input-app-image-upload" + class="input-file-field input-app-image-upload-ht" accept="image/*" + [(ngModel)]="applicationObj.originalImage" name="appImage" + image-upload="applicationObj.originalImage" image-upload-resize-max-height="300" + image-upload-resize-max-width="360" image-upload-resize-quality="0.7" + image-upload-api="appDetails.imageApi" (change)="appImageHandler($event)" /> + + <div id="app-error-image-upload-type" class="error-container" *ngIf="appImageTypeError" + class="ng-hide"> + <div class="error-container"> + <small id="error-app-invalid-image-size" class="err-message">File must be an + image</small> + </div> + </div> + + <div id="app-error-image-upload" class="error-container" + *ngIf="(applicationObj.originalImage && applicationObj.originalImage.dirty)"> + <div ng-messages="appForm.appImage.$error" class="error-container"> + <small id="error-app-invalid-image-size" class="err-message" + ng-message="imageSize">Image file must be smaller than + 1MB</small> + </div> + </div> + </div> + + + <div class="property" *ngIf="!(applicationObj.applicationType == '3')"> + <div class="property-label preview"> + <span class="left-label">Preview</span> + <span *ngIf="(applicationObj.imageLink && applicationObj.imageLink.indexOf('default_app_image.gif') == -1 + ||applicationObj.thumbnail && applicationObj.thumbnail.indexOf('default_app_image.gif') == -1 + ||emptyImgForPreview && emptyImgForPreview.indexOf('default_app_image.gif') == -1)" + class="remove" (click)="removeImage()">Remove</span> + </div> + <img id="image-app-preview" class="image-preview" + src="{{applicationObj.imageLink || applicationObj.thumbnail || emptyImgForPreview}}" /> + </div> + + <div class="property" *ngIf="!(applicationObj.applicationType == '3')"> + <div id="property-guest-access" class="property-guest-access"> + <mat-checkbox name="isOpen" [(ngModel)]="applicationObj.isOpen" + id="checkbox-app-is-open" + [checked]="(applicationObj.isOpen || applicationObj.applicationType == '2')" + [disabled]="applicationObj.applicationType == '2'">Allow guest access + </mat-checkbox> + </div> </div> - <div class="communitcaion-key" aria-haspopup="true" style="padding-left: 20px;"> - <div b2b-flyout-toggler class="notification-div"> - <div id="tooltip" class="icon-primary-flat-info" tabindex="0" - b2b-accessibility-click="13,32" aria-label="notifications" - aria-haspopup="true" - role="button"></div> + <div class="table-control" style="display: inline-flex;" + *ngIf="!(applicationObj.applicationType == '2')"> + <div id="property-communication-key" class="property" + *ngIf="!(applicationObj.applicationType == '2' || applicationObj.applicationType == '3')" + style="width: 250px;"> + <div id="property-communication-key-label" class="property-label">Application + UUID</div> + <input type="text" id="input-UEB-communication-key" [(ngModel)]="applicationObj.uebKey" + name="uebKey" readonly="readonly" [disabled]="true" /> + </div> + + <div class="communitcaion-key" aria-haspopup="true" style="padding-left: 20px;"> + <div b2b-flyout-toggler class="notification-div"> + <div id="tooltip" class="icon-primary-flat-info" tabindex="0" + b2b-accessibility-click="13,32" aria-label="notifications" aria-haspopup="true" + role="button"></div> + </div> + <!--<div id="notification" align="left"> + <p class="uuid-text" style="font: normal 12px Omnes-ECOMP-W02, Arial;">Application UUID is used as a communication + key between application and portal.Please place this value in + portal.properties</p> + </div>--> + </div> </div> - <!--<div id="notification" align="left"> - <p class="uuid-text" style="font: normal 12px Omnes-ECOMP-W02, Arial;">Application UUID is used as a communication - key between application and portal.Please place this value in - portal.properties</p> - </div>--> - </div> - </div> - - <div class="table-control" style="display: inline-flex;" [hidden] ="applicationObj.restrictedApp"> - - <div [ngClass]="(applicationObj.isCentralAuth) ? 'property required' : 'property'" - [hidden] ="applicationObj.restrictedApp" style="width: 250px;"> - <div id="pwd-property-label" class="property-label" >Name Space</div> - <input type="text" id="input-mylogins-auth-namespace" - [(ngModel)]="applicationObj.nameSpace" name="appAuthNameSpace" - maxlength="256" [disabled]="!applicationObj.isCentralAuth" /> </div> - <div class="communitcaion-key" aria-haspopup="true" style="padding-left: 20px;"> - - <div b2b-flyout-toggler class="notification-div"> - <div id="tooltip" class="icon-primary-flat-info" tabindex="0" - b2b-accessibility-click="13,32" aria-label="notifications" - aria-haspopup="true" - role="button"></div> - </div> - <!--<div id="notification" align="left"> - <p class="nameSpace-text" style="font: normal 12px Omnes-ECOMP-W02, Arial;">NameSpace should be created in AAF and portal mechid should be admin of the given namespace.</p> - </div>--> - </div> - </div> - </div> - </div> - </form> + </form> </div> </div> - </div> - <div class="modal-footer"> - <button type="button" class="btn btn-primary" [disabled]="(!applicationObj.name || applicationObj.name.length == 0)" (click)="saveChanges()">Save</button> - <button type="button" class="btn btn-primary" (click)="activeModal.close('Close')">Cancel</button> + + <div class="modal-footer"> + <button type="button" class="btn btn-primary" + [disabled]="(!applicationObj.appName || applicationObj.appName.length == 0)" + (click)="saveChanges()">Save</button> + <button type="button" class="btn btn-primary" (click)="activeModal.close('Close')">Cancel</button> + </div> + </div> </div>
\ No newline at end of file diff --git a/portal-FE-os/src/app/pages/application-onboarding/application-details-dialog/application-details-dialog.component.scss b/portal-FE-os/src/app/pages/application-onboarding/application-details-dialog/application-details-dialog.component.scss index 0e042a96..1106eb5a 100644 --- a/portal-FE-os/src/app/pages/application-onboarding/application-details-dialog/application-details-dialog.component.scss +++ b/portal-FE-os/src/app/pages/application-onboarding/application-details-dialog/application-details-dialog.component.scss @@ -35,6 +35,10 @@ * * */ + + .application-details-modal{ + min-height: 37vw; + } .application-details-modal .app-properties-mainapp-properties-main{ padding-left: 40px; @@ -58,7 +62,7 @@ .application-details-modal .app-properties-main .property{ position: relative; - margin-bottom: 18px; + margin-bottom: 16px; } .application-details-modal .app-properties-main .checkbox-label{ display: inline-block; @@ -73,7 +77,7 @@ } .application-details-modal .app-properties-main .preview{ width: 220px; - margin-top: 22px; + margin-top: 11px; display: block; } @@ -90,6 +94,17 @@ .application-details-modal .app-properties-main .input-field{ width: 220px; } + +mat-select { + width: 16em; + margin: 0; + font-family: inherit; + font-size: inherit; + line-height: inherit; + border-width: 2px; + border-style: ridge; + border-color: initial; +} .application-details-modal .app-properties-main .input-file-field{ width: 220px; @@ -129,6 +144,10 @@ width: 16em; } +.application-details-modal select { + width: 16em; +} + .application-details-modal input[type="url"] { width: 16em; } @@ -160,4 +179,19 @@ cursor: pointer; color: #007bff; } -
\ No newline at end of file +.application-deatils-radio-group{ + display: flex; + flex-direction: column; +} + +mat-radio-group{ + margin-left: 10%; +} + +.modal-footer{ + width: 100%; +} + +mat-form-field{ + width: 94%; +}
\ No newline at end of file diff --git a/portal-FE-os/src/app/pages/application-onboarding/application-details-dialog/application-details-dialog.component.spec.ts b/portal-FE-os/src/app/pages/application-onboarding/application-details-dialog/application-details-dialog.component.spec.ts index 629e5fa6..d1f352cb 100644 --- a/portal-FE-os/src/app/pages/application-onboarding/application-details-dialog/application-details-dialog.component.spec.ts +++ b/portal-FE-os/src/app/pages/application-onboarding/application-details-dialog/application-details-dialog.component.spec.ts @@ -48,6 +48,9 @@ import { InformationModalComponent } from 'src/app/modals/information-modal/info import { BrowserDynamicTestingModule } from '@angular/platform-browser-dynamic/testing'; import { NgbModalBackdrop } from '@ng-bootstrap/ng-bootstrap/modal/modal-backdrop'; import { ConfirmationModalComponent } from 'src/app/modals/confirmation-modal/confirmation-modal.component'; +import { InformationTooltipComponent } from '../../information-tooltip/information-tooltip.component'; +import { MatTooltipModule } from '@angular/material'; +import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; describe('ApplicationDetailsDialogComponent', () => { @@ -57,9 +60,10 @@ describe('ApplicationDetailsDialogComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [ ApplicationDetailsDialogComponent,InformationModalComponent,ConfirmationModalComponent], - imports: [NgMaterialModule,FormsModule,HttpClientTestingModule,NgbModule.forRoot()], - providers: [NgbActiveModal] + declarations: [ ApplicationDetailsDialogComponent,InformationModalComponent,ConfirmationModalComponent, InformationTooltipComponent], + imports: [NgMaterialModule,FormsModule,HttpClientTestingModule,NgbModule.forRoot(), MatTooltipModule], + providers: [NgbActiveModal], + schemas: [CUSTOM_ELEMENTS_SCHEMA] }).overrideModule(BrowserDynamicTestingModule, { set: { entryComponents: [InformationModalComponent,ConfirmationModalComponent] } }) .compileComponents(); })); @@ -80,20 +84,20 @@ describe('ApplicationDetailsDialogComponent', () => { expect(component.removeImage).toHaveBeenCalledWith(); }); it('saveChanges should return stubbed value', () => { - component.applicationObj.isCentralAuth = true; + component.applicationObj.rolesInAAF = true; component.applicationObj.isEnabled = false; spyOn(component, 'saveChanges').and.callThrough(); component.saveChanges(); expect(component.saveChanges).toHaveBeenCalledWith(); component.applicationObj.isEnabled = true; - component.applicationObj.url = 'www.test.com' + component.applicationObj.landingPage = 'www.test.com' component.applicationObj.restrictedApp =true; //spyOn(component, 'saveChanges').and.callThrough(); component.saveChanges(); expect(component.saveChanges).toHaveBeenCalledWith(); - component.applicationObj.isCentralAuth = false; - component.applicationObj.url = 'test' + component.applicationObj.rolesInAAF = false; + component.applicationObj.landingPage = 'test' component.applicationObj.restrictedApp =false; component.applicationObj.isOpen = true; component.isEditMode =true; @@ -102,7 +106,7 @@ describe('ApplicationDetailsDialogComponent', () => { expect(component.saveChanges).toHaveBeenCalledWith(); }); it('saveChanges Central Auth is disabled', () => { - component.applicationObj.isCentralAuth = false; + component.applicationObj.rolesInAAF = false; component.applicationObj.isEnabled = false; spyOn(component, 'saveChanges').and.callThrough(); component.saveChanges(); @@ -115,11 +119,11 @@ describe('ApplicationDetailsDialogComponent', () => { }); it('saveChanges URL validation changes', () => { - component.applicationObj.isCentralAuth = true; + component.applicationObj.rolesInAAF = true; component.applicationObj.isEnabled = true; - component.applicationObj.name ='test'; - component.applicationObj.url = 'https://www.test.com' - component.applicationObj.username ='test' + component.applicationObj.appName ='test'; + component.applicationObj.landingPage = 'https://www.test.com' + component.applicationObj.appBasicAuthUsername ='test' component.applicationObj.nameSpace ='ONAP' spyOn(component, 'saveChanges').and.callThrough(); component.saveChanges(); diff --git a/portal-FE-os/src/app/pages/application-onboarding/application-details-dialog/application-details-dialog.component.ts b/portal-FE-os/src/app/pages/application-onboarding/application-details-dialog/application-details-dialog.component.ts index 7aad140a..852e9706 100644 --- a/portal-FE-os/src/app/pages/application-onboarding/application-details-dialog/application-details-dialog.component.ts +++ b/portal-FE-os/src/app/pages/application-onboarding/application-details-dialog/application-details-dialog.component.ts @@ -36,7 +36,7 @@ * */ -import { Component, OnInit, Input, Output, EventEmitter, PLATFORM_ID, Inject, Injector} from '@angular/core'; +import { Component, OnInit, Input, Output, EventEmitter, ViewChild, ElementRef, Inject, PLATFORM_ID, Injector } from '@angular/core'; import { NgbActiveModal, NgbModal } from '@ng-bootstrap/ng-bootstrap'; import { IApplications } from 'src/app/shared/model/applications-onboarding/applications'; import { ApplicationsService } from 'src/app/shared/services'; @@ -51,6 +51,7 @@ import { isPlatformBrowser } from '@angular/common'; }) export class ApplicationDetailsDialogComponent implements OnInit { + addEditAction: any; emptyImg = null; emptyImgForPreview:string; conflictMessages = {}; @@ -71,34 +72,76 @@ export class ApplicationDetailsDialogComponent implements OnInit { } @Input() applicationObj: IApplications; + @Input() action: any; @Output() passEntry: EventEmitter<any> = new EventEmitter(); + @ViewChild('applicationName') applicationNameElement: ElementRef; + @ViewChild('inputAppImageUpload') inputAppImageUpload: ElementRef; newAppModel = { 'id': null, - 'name': null, + 'appName': null, 'imageUrl': null, - 'description': null, - 'notes': null, - 'url': null, + 'appDescription': null, + 'appNotes': null, + 'landingPage': null, 'alternateUrl': null, 'restUrl': null, 'isOpen': false, - 'username': null, - 'appPassword': null, + 'appBasicAuthUsername': null, + 'appBasicAuthPassword': null, 'thumbnail': this.emptyImg, 'isEnabled': false, - 'restrictedApp': false, - 'nameSpace':null, - 'isCentralAuth': false, - 'uebTopicName':null, + 'applicationType': null, + 'rolesInAAF': false, + 'nameSpace': null, + 'uebTopicName': null, 'uebKey': null, 'uebSecret': null, - 'imageLink': null + 'imageLink': null, + 'usesCadi': true, + 'modeOfIntegration': null, + 'appAck': false, + 'restrictedApp': false }; + applicationTypeArray: any[] = [ + { name: 'GUI Application', value: "1" }, + { name: 'HyperLink Application', value: "2" }, + { name: 'Non-GUI Application', value: "3" } + + ]; + + rolesManagementType: any[] = [ + { name: 'Roles in Application (Non-Centralized)', value: false }, + { name: 'Roles in AAF (Centralized)', value: true } + ]; + + modeOfIntegration: any[] = [ + { name: 'Portal SDK Based', value: 'sdk' }, + { name: 'Framework Based', value: 'fw' } + ] ngOnInit() { - if(this.applicationObj.id){ + + this.addEditAction = this.action; + + + if (this.action === 'add') { + this.applicationObj.applicationType = "1"; + if (this.applicationObj.applicationType == '1') { + this.applicationObj.modeOfIntegration = this.modeOfIntegration[0].value; + } + this.applicationObj.rolesInAAF = true; + this.applicationObj.usesCadi = true; + this.applicationObj.appAck = false; + console.log("Action : ", this.action); + console.log("Focus : ", this.applicationNameElement.nativeElement); + setTimeout(() => { // this will make the execution after the above boolean has changed + this.applicationNameElement.nativeElement.focus(); + }, 0); + } + + if (this.applicationObj.id) { this.isEditMode = true; }else{ this.isEditMode = false; @@ -158,6 +201,7 @@ export class ApplicationDetailsDialogComponent implements OnInit { this.applicationObj.imageUrl = null; this.applicationObj.imageLink = null; this.emptyImgForPreview = '../../../assets/images/default_app_image.gif'; + this.inputAppImageUpload.nativeElement.value = ""; } }, (resut) => { return; @@ -167,59 +211,91 @@ export class ApplicationDetailsDialogComponent implements OnInit { /** Add/Edit Application Method*/ saveChanges() { //console.log("addNewApplication getting called.."); - if(this.applicationObj.isCentralAuth){ + if (this.applicationObj.rolesInAAF) { + //if valid. + if (this.applicationObj.applicationType == "1") { + console.log("Gui Application valodations"); //if valid. - if(!this.applicationObj.isEnabled){ - if(((this.applicationObj.name == 'undefined' || !this.applicationObj.name)||(this.applicationObj.nameSpace == 'undefined' - || !this.applicationObj.nameSpace) ||(this.applicationObj.username == 'undefined' || !this.applicationObj.username))) { - this.openConfirmationModal('','Please fill in all required fields(*) for centralized application'); + if (!this.applicationObj.isEnabled) { + if (((this.applicationObj.appName == 'undefined' || !this.applicationObj.appName) || (this.applicationObj.nameSpace == 'undefined' + || !this.applicationObj.nameSpace) || (this.applicationObj.appBasicAuthUsername == 'undefined' || !this.applicationObj.appBasicAuthUsername))) { + this.openConfirmationModal('', 'Please fill in all required fields(*) for centralized application'); return; } } - if(this.applicationObj.isEnabled){ - if(((this.applicationObj.name == 'undefined' || !this.applicationObj.name) - ||(this.applicationObj.url == 'undefined'|| !this.applicationObj.url) - ||(this.applicationObj.username == 'undefined' || !this.applicationObj.username)||(this.applicationObj.nameSpace == 'undefined' - || !this.applicationObj.nameSpace))) { + if (this.applicationObj.isEnabled) { + if (((this.applicationObj.appName == 'undefined' || !this.applicationObj.appName) + || (this.applicationObj.landingPage == 'undefined' || !this.applicationObj.landingPage) + || (this.applicationObj.appBasicAuthUsername == 'undefined' || !this.applicationObj.appBasicAuthUsername) || (this.applicationObj.nameSpace == 'undefined' + || !this.applicationObj.nameSpace))) { - this.openConfirmationModal('','Please fill in all required fields(*) for centralized active application'); + this.openConfirmationModal('', 'Please fill in all required fields(*) for centralized active application'); return; } } - }else{ - if(!this.applicationObj.isEnabled) { - if((this.applicationObj.name == 'undefined' || !this.applicationObj.name)){ - this.openConfirmationModal('','Please fill in all required field(*) ApplicationName to Save the applictaion'); - return; - } - }else if(this.applicationObj.isEnabled && !this.applicationObj.restrictedApp){ - if((this.applicationObj.name == 'undefined' || !this.applicationObj.name) - ||(this.applicationObj.url == 'undefined'|| !this.applicationObj.url) - ||(this.applicationObj.username == 'undefined' || !this.applicationObj.username)|| - (this.applicationObj.appPassword== 'undefined' || !this.applicationObj.appPassword)) { - - this.openConfirmationModal('','Please fill in all required fields(*) along with password as the app is not centralized'); - return; + } else if (this.applicationObj.applicationType == "3") { + console.log("Non-Gui Application valodations"); + if (!this.applicationObj.isEnabled) { + if (((this.applicationObj.appName == 'undefined' || !this.applicationObj.appName) || (this.applicationObj.nameSpace == 'undefined' + || !this.applicationObj.nameSpace) || (this.applicationObj.appBasicAuthUsername == 'undefined' || !this.applicationObj.appBasicAuthUsername))) { + this.openConfirmationModal('', 'Please fill in all required fields(*) for centralized application'); + return; } - }else if(this.applicationObj.isEnabled && this.applicationObj.restrictedApp){ - if((this.applicationObj.name == 'undefined' || !this.applicationObj.name) ||(this.applicationObj.url == 'undefined' - || !this.applicationObj.url)){ - this.openConfirmationModal('','Please fill in all required fields(*)'); - return; - } } + + if (this.applicationObj.isEnabled) { + if (((this.applicationObj.appName == 'undefined' || !this.applicationObj.appName) + || (this.applicationObj.appBasicAuthUsername == 'undefined' || !this.applicationObj.appBasicAuthUsername) || (this.applicationObj.nameSpace == 'undefined' + || !this.applicationObj.nameSpace))) { + + this.openConfirmationModal('', 'Please fill in all required fields(*) for centralized active application'); + return; + } + } + } + } else { + console.log("Non-centralized applications validation"); + this.applicationObj.appAck = null; + if (!this.applicationObj.isEnabled) { + if ((this.applicationObj.appName == 'undefined' || !this.applicationObj.appName)) { + this.openConfirmationModal('', 'Please fill in all required field(*) ApplicationName to Save the applictaion'); + return; + } + } else if (this.applicationObj.isEnabled && (this.applicationObj.applicationType == "1")) { + if ((this.applicationObj.appName == 'undefined' || !this.applicationObj.appName) + || (this.applicationObj.landingPage == 'undefined' || !this.applicationObj.landingPage) + || (this.applicationObj.appBasicAuthUsername == 'undefined' || !this.applicationObj.appBasicAuthUsername) || + (this.applicationObj.appBasicAuthPassword == 'undefined' || !this.applicationObj.appBasicAuthPassword)) { + + this.openConfirmationModal('', 'Please fill in all required fields(*) along with password as the app is not centralized'); + return; + } + } else if (this.applicationObj.isEnabled && (this.applicationObj.applicationType == "3")) { + console.log("Non gui validation"); + if ((this.applicationObj.appName == 'undefined' || !this.applicationObj.appName) + || (this.applicationObj.appBasicAuthUsername == 'undefined' || !this.applicationObj.appBasicAuthUsername)) { + this.openConfirmationModal('', 'Please fill in all required fields(*)'); + return; + } + } else if (this.applicationObj.isEnabled && (this.applicationObj.applicationType == "2")) { + if ((this.applicationObj.appName == 'undefined' || !this.applicationObj.appName) || (this.applicationObj.landingPage == 'undefined' + || !this.applicationObj.landingPage)) { + this.openConfirmationModal('', 'Please fill in all required fields(*)'); + return; + } + } } //URL Validation - if(this.applicationObj.isEnabled){ - if(this.applicationObj.url && this.applicationObj.url !='undefined' && this.applicationObj.url != ''){ - let isValidURL = this.isUrlValid(this.applicationObj.url); - if(!isValidURL){ - this.openConfirmationModal('Error','Application URL must be a valid URL.'); + if (this.applicationObj.isEnabled && this.applicationObj.applicationType == "1") { + if (this.applicationObj.landingPage && this.applicationObj.landingPage != 'undefined' && this.applicationObj.landingPage != '') { + let isValidURL = this.isUrlValid(this.applicationObj.landingPage); + if (!isValidURL) { + this.openConfirmationModal('Error', 'Application URL must be a valid URL.'); return; } - }else{ - this.openConfirmationModal('Error','Application URL is required.'); + } else { + this.openConfirmationModal('Error', 'Application URL is required.'); return; } } @@ -227,34 +303,40 @@ export class ApplicationDetailsDialogComponent implements OnInit { this.isSaving = true; // For a restricted app, null out all irrelevant fields - if(this.applicationObj.restrictedApp) { + if (this.applicationObj.applicationType == "2") { + console.log("Hyperlinka pplication validation"); this.newAppModel.restUrl = null; this.newAppModel.isOpen = true; - this.newAppModel.username = null; - this.newAppModel.appPassword = null; + this.newAppModel.appBasicAuthUsername = null; + this.newAppModel.appBasicAuthPassword = null; this.newAppModel.uebTopicName = null; this.newAppModel.uebKey = null; this.newAppModel.uebSecret = null; + this.newAppModel.restrictedApp = true; /**Need to set below fields values based on input provided in the dialog */ - this.newAppModel.restrictedApp = this.applicationObj.restrictedApp; - this.newAppModel.name = this.applicationObj.name; - this.newAppModel.url = this.applicationObj.url; - if(this.applicationObj.isEnabled){ + this.newAppModel.applicationType = this.applicationObj.applicationType; + this.newAppModel.appName = this.applicationObj.appName; + this.newAppModel.landingPage = this.applicationObj.landingPage; + this.newAppModel.usesCadi = this.applicationObj.usesCadi; + if (this.applicationObj.isEnabled) { this.newAppModel.isEnabled = this.applicationObj.isEnabled; }else{ this.newAppModel.isEnabled = false; } + console.log("New Model : ", this.newAppModel); + } else { - }else{ - - /**Need to set below fields values based on input provided in the dialog */ - this.newAppModel.restrictedApp = false; - this.newAppModel.name = this.applicationObj.name; - this.newAppModel.url = this.applicationObj.url; - this.newAppModel.restUrl = this.applicationObj.restUrl; - this.newAppModel.username = this.applicationObj.username; - this.newAppModel.appPassword = this.applicationObj.appPassword; + /**Need to set below fields values based on input provided in the dialog */ + this.newAppModel.applicationType = this.applicationObj.applicationType; + this.newAppModel.appName = this.applicationObj.appName; + this.newAppModel.landingPage = this.applicationObj.landingPage; + this.newAppModel.restUrl = this.applicationObj.restUrl; + this.newAppModel.appBasicAuthUsername = this.applicationObj.appBasicAuthUsername; + this.newAppModel.appBasicAuthPassword = this.applicationObj.appBasicAuthPassword; + this.newAppModel.modeOfIntegration = this.applicationObj.modeOfIntegration; + this.newAppModel.usesCadi = this.applicationObj.usesCadi; + this.newAppModel.appAck = this.applicationObj.appAck; if(this.applicationObj.isEnabled){ this.newAppModel.isEnabled = this.applicationObj.isEnabled; @@ -269,11 +351,12 @@ export class ApplicationDetailsDialogComponent implements OnInit { } //console.log("this.applicationObj.isOpen",this.applicationObj.isOpen); - if(this.applicationObj.isCentralAuth){ - this.newAppModel.isCentralAuth = this.applicationObj.isCentralAuth; - }else{ - this.newAppModel.isCentralAuth = false; - } + if (this.applicationObj.rolesInAAF) { + this.newAppModel.rolesInAAF = this.applicationObj.rolesInAAF; + } else { + this.newAppModel.rolesInAAF = false; + this.newAppModel.usesCadi = false; + } } @@ -283,7 +366,17 @@ export class ApplicationDetailsDialogComponent implements OnInit { this.newAppModel.nameSpace = this.applicationObj.nameSpace; } - if(this.isEditMode){ + if (this.applicationObj.applicationType == "2" || this.applicationObj.applicationType == "3") { + this.applicationObj.modeOfIntegration = null; + } + + if (this.newAppModel.applicationType == "2" || this.newAppModel.applicationType == "3") { + this.newAppModel.modeOfIntegration = null; + } + + if (this.isEditMode) { + console.log("Edit application Object : ", JSON.stringify(this.applicationObj)); + console.log("Mode Of iNtegration : ", this.applicationObj.modeOfIntegration); this.applicationsService.updateOnboardingApp(this.applicationObj) .subscribe( _data => { this.result = _data; diff --git a/portal-FE-os/src/app/pages/application-onboarding/application-onboarding.component.html b/portal-FE-os/src/app/pages/application-onboarding/application-onboarding.component.html index 8a678917..47722471 100644 --- a/portal-FE-os/src/app/pages/application-onboarding/application-onboarding.component.html +++ b/portal-FE-os/src/app/pages/application-onboarding/application-onboarding.component.html @@ -46,17 +46,18 @@ <input matInput type="text" (keyup)="applyFilter($event.target.value)" placeholder="Search in entire table"> </mat-form-field> - <button type="button" style="float: right;" class="btn btn-primary" (click)="openAddApplicationModal('')"> + <button type="button" style="float: right;" class="btn btn-primary" (click)="openAddApplicationModal('', 'add')"> <i class="icon ion-md-person-add"></i> Add App </button> <div class="apps-table"> + <span class="ecomp-spinner" *ngIf="showEcompSpinner"></span> <!-- Applications Table goes here--> <table mat-table [dataSource]="dataSource" matSort> <!-- Thumbnail Column --> <ng-container matColumnDef="thumbnail"> <th id="col1" mat-header-cell *matHeaderCellDef> Thumbnail </th> - <td (click)="openAddApplicationModal(element)" id="rowheader_t1_{{i}}-thumbnail" + <td (click)="openAddApplicationModal(element, 'edit')" id="rowheader_t1_{{i}}-thumbnail" mat-cell *matCellDef="let element; let i = index;"> <div><img class="small-thumbnail" src={{element.imageLink}}></div> </td> @@ -65,64 +66,71 @@ <!-- Application Name Column --> <ng-container matColumnDef="applicationName"> <th id="col2" mat-header-cell *matHeaderCellDef> Application Name </th> - <td (click)="openAddApplicationModal(element)" id="rowheader_t1_{{i}}-applicationName" - mat-cell *matCellDef="let element; let i=index;"> {{element.name}} </td> + <td (click)="openAddApplicationModal(element, 'edit')" id="rowheader_t1_{{i}}-applicationName" + mat-cell *matCellDef="let element; let i=index;"> {{element.appName}} </td> </ng-container> <!-- Active Column --> <ng-container matColumnDef="active"> <th id="col2" mat-header-cell *matHeaderCellDef> Active </th> - <td (click)="openAddApplicationModal(element)" id="rowheader_t1_{{i}}-active" + <td (click)="openAddApplicationModal(element, 'edit')" id="rowheader_t1_{{i}}-active" mat-cell *matCellDef="let element; let i=index;"> {{(element.isEnabled) ? 'yes' : 'no'}} </td> </ng-container> <!-- Integration Type Column --> <ng-container matColumnDef="integrationType"> <th id="col2" mat-header-cell *matHeaderCellDef> Integration Type </th> - <td (click)="openAddApplicationModal(element)" id="rowheader_t1_{{i}}-integrationType" - mat-cell *matCellDef="let element; let i=index;"> {{(element.restrictedApp) ? 'link' : 'standard'}} </td> + <td (click)="openAddApplicationModal(element, 'edit')" id="rowheader_t1_{{i}}-integrationType" + mat-cell *matCellDef="let element; let i=index;"> {{(element.applicationType == 2) ? 'link' : 'standard'}} </td> + </ng-container> + + <!-- Mode Of Integration Type Column --> + <ng-container matColumnDef="modeOfIntegration"> + <th id="col2" mat-header-cell *matHeaderCellDef> Mode Of Integration </th> + <td (click)="openAddApplicationModal(element, 'edit')" id="rowheader_t1_{{i}}-modeOfIntegration" + mat-cell *matCellDef="let element; let i=index;"> {{element.modeOfIntegration}} </td> </ng-container> <!-- Guest Access Column--> <ng-container matColumnDef="guestAccess"> <th id="col2" mat-header-cell *matHeaderCellDef> Guest Access </th> - <td (click)="openAddApplicationModal(element)" id="rowheader_t1_{{i}}-guestAccess" + <td (click)="openAddApplicationModal(element, 'edit')" id="rowheader_t1_{{i}}-guestAccess" mat-cell *matCellDef="let element; let i=index;">{{(element.isOpen) ? 'yes' : 'no'}} </td> </ng-container> <!-- url column --> - <ng-container matColumnDef="url"> - <th id="col2" mat-header-cell *matHeaderCellDef> Url </th> - <td (click)="openAddApplicationModal(element)" id="rowheader_t1_{{i}}-url" - mat-cell *matCellDef="let element; let i=index;">{{element.url}} </td> + <ng-container matColumnDef="landingPage"> + <th id="col2" mat-header-cell *matHeaderCellDef> Landing Page </th> + <td (click)="openAddApplicationModal(element, 'edit')" id="rowheader_t1_{{i}}-url" + mat-cell *matCellDef="let element; let i=index;">{{element.landingPage}} </td> </ng-container> <!-- rest url column --> <ng-container matColumnDef="restURL"> <th id="col2" mat-header-cell *matHeaderCellDef> REST Url </th> - <td (click)="openAddApplicationModal(element)" id="rowheader_t1_{{i}}-restURL" + <td (click)="openAddApplicationModal(element, 'edit')" id="rowheader_t1_{{i}}-restURL" mat-cell *matCellDef="let element; let i=index;">{{element.restUrl}} </td> </ng-container> <!-- communicationKey column --> <ng-container matColumnDef="communicationKey"> <th id="col2" mat-header-cell *matHeaderCellDef> Communication Key </th> - <td (click)="openAddApplicationModal(element)" id="rowheader_t1_{{i}}-communicationKey" + <td (click)="openAddApplicationModal(element, 'edit')" id="rowheader_t1_{{i}}-communicationKey" mat-cell *matCellDef="let element; let i=index;">{{element.uebKey}} </td> </ng-container> <!-- applicationNamespace column --> <ng-container matColumnDef="applicationNamespace"> <th id="col2" mat-header-cell *matHeaderCellDef> Application Namespace </th> - <td (click)="openAddApplicationModal(element)" id="rowheader_t1_{{i}}-applicationNamespace" + <td (click)="openAddApplicationModal(element, 'edit')" id="rowheader_t1_{{i}}-applicationNamespace" mat-cell *matCellDef="let element; let i=index;">{{element.nameSpace}} </td> </ng-container> <!-- centralAuthAccess column --> <ng-container matColumnDef="centralAuthAccess"> <th id="col2" mat-header-cell *matHeaderCellDef> Central Auth Access </th> - <td (click)="openAddApplicationModal(element)" id="rowheader_t1_{{i}}-centralAuthAccess" - mat-cell *matCellDef="let element; let i=index;">{{(element.isCentralAuth) ? 'yes' : 'no'}} </td> + <td (click)="openAddApplicationModal(element, 'edit')" id="rowheader_t1_{{i}}-centralAuthAccess" + mat-cell *matCellDef="let element; let i=index;">{{(element.rolesInAAF) ? 'yes' : 'no'}} </td> </ng-container> <!-- Delete Column --> diff --git a/portal-FE-os/src/app/pages/application-onboarding/application-onboarding.component.ts b/portal-FE-os/src/app/pages/application-onboarding/application-onboarding.component.ts index 8cbf1d28..83cbfa0e 100644 --- a/portal-FE-os/src/app/pages/application-onboarding/application-onboarding.component.ts +++ b/portal-FE-os/src/app/pages/application-onboarding/application-onboarding.component.ts @@ -61,11 +61,12 @@ export class ApplicationOnboardingComponent implements OnInit { emptyImgForPreview: string; isUserSuperAdmin: boolean = false; displayedColumns: string[] = ['thumbnail', 'applicationName','active', - 'integrationType', 'guestAccess', 'url','restURL', + 'integrationType', 'modeOfIntegration', 'guestAccess', 'landingPage','restURL', 'communicationKey', 'applicationNamespace', 'centralAuthAccess']; dataSource = new MatTableDataSource(this.appsList); @ViewChild(MatSort) sort: MatSort; @ViewChild(MatPaginator) paginator: MatPaginator; + showEcompSpinner:boolean = false; constructor(public applicationsService: ApplicationsService, public ngbModal: NgbModal) { } @@ -77,11 +78,13 @@ export class ApplicationOnboardingComponent implements OnInit { getOnboardingApps(){ //console.log("getOnboardingApps called"); + this.showEcompSpinner = true; this.applicationsService.getOnboardingApps() .subscribe(_data => { this.result = _data; if (this.result == null || this.result == 'undefined') { console.log('WidgetOnboardingService::getOnboardingWidgets Failed: Result or result.data is null'); + this.showEcompSpinner = false; }else { this.appsList = _data; for (var i = 0; i < this.appsList.length; i++) { @@ -94,11 +97,14 @@ export class ApplicationOnboardingComponent implements OnInit { } } this.populateTableData(this.appsList); + this.showEcompSpinner = false; } }, error =>{ console.log(error); + this.showEcompSpinner = false; this.openConfirmationModal('Error', error.message); }); + this.showEcompSpinner = false; } applyFilter(filterValue: string) { @@ -112,9 +118,11 @@ export class ApplicationOnboardingComponent implements OnInit { this.dataSource.paginator = this.paginator; }; - openAddApplicationModal(rowData: any) { - const modalRef = this.ngbModal.open(ApplicationDetailsDialogComponent, { size: 'lg' }); + openAddApplicationModal(rowData: any, action:any) { + console.log("Action : ", action); + const modalRef = this.ngbModal.open(ApplicationDetailsDialogComponent, { size: 'lg', backdrop: 'static', keyboard: false }); modalRef.componentInstance.title = 'Application Details'; + modalRef.componentInstance.action = action; //console.log("selectedData in parent",rowData); if(rowData != 'undefined' && rowData){ modalRef.componentInstance.applicationObj = rowData; @@ -134,21 +142,28 @@ export class ApplicationOnboardingComponent implements OnInit { } deleteApplication(application: IApplications){ - let confirmationMsg = 'You are about to delete this App : ' + application.name+ '. Click OK to continue.'; + let confirmationMsg = 'You are about to delete this App : ' + application.appName+ '. Click OK to continue.'; this.openInformationModal("Confirmation",confirmationMsg).result.then((result) => { if (result === 'Ok') { if(!application || application == null){ console.log('ApplicationOnboardingCtrl::deleteApplication: No apllication or ID... cannot delete'); return; } + this.showEcompSpinner = true; this.appsList.splice(this.appsList.indexOf(application), 1); this.applicationsService.deleteOnboardingApp(application.id) .subscribe( data => { this.result = data; this.getOnboardingApps(); + this.showEcompSpinner = false; }, error => { console.log(error); - this.openConfirmationModal('Error', error); + this.showEcompSpinner = false; + if(error && error.status == 405){ + this.openConfirmationModal('', 'Application : ' + application.appName+ ' can not be deleted as it is associsted with one of the Microservices.'); + }else{ + this.openConfirmationModal('Error', error.message); + } }); } }, (resut) => { @@ -162,7 +177,7 @@ export class ApplicationOnboardingComponent implements OnInit { if(res) { this.isUserSuperAdmin = true; this.displayedColumns = ['thumbnail', 'applicationName','active', - 'integrationType', 'guestAccess', 'url','restURL', + 'integrationType', 'modeOfIntegration', 'guestAccess', 'landingPage','restURL', 'communicationKey', 'applicationNamespace', 'centralAuthAccess', 'delete']; } //console.log("isUserSuperAdmin :: ",this.isUserSuperAdmin); diff --git a/portal-FE-os/src/app/pages/information-tooltip/information-tooltip.component.html b/portal-FE-os/src/app/pages/information-tooltip/information-tooltip.component.html new file mode 100644 index 00000000..92f13c8c --- /dev/null +++ b/portal-FE-os/src/app/pages/information-tooltip/information-tooltip.component.html @@ -0,0 +1,3 @@ +<span matTooltip="{{textMessage}}" [matTooltipPosition]="'above'"> + <i class="icon ion-md-help-circle" style="color: #087ac2;"></i> +</span>
\ No newline at end of file diff --git a/portal-FE-os/src/app/pages/information-tooltip/information-tooltip.component.scss b/portal-FE-os/src/app/pages/information-tooltip/information-tooltip.component.scss new file mode 100644 index 00000000..3d72a79e --- /dev/null +++ b/portal-FE-os/src/app/pages/information-tooltip/information-tooltip.component.scss @@ -0,0 +1,13 @@ +.material-icons { + font-size: 17px !important; + cursor: default; +} + +.mat-tooltip { + font-size: 1.5rem !important; + } + + img{ + width: 16px; + } +
\ No newline at end of file diff --git a/portal-FE-os/src/app/pages/information-tooltip/information-tooltip.component.spec.ts b/portal-FE-os/src/app/pages/information-tooltip/information-tooltip.component.spec.ts new file mode 100644 index 00000000..9c8c6214 --- /dev/null +++ b/portal-FE-os/src/app/pages/information-tooltip/information-tooltip.component.spec.ts @@ -0,0 +1,8 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { InformationTooltipComponent } from './information-tooltip.component'; + +describe('InformationTooltipComponent', () => { + + +}); diff --git a/portal-FE-os/src/app/pages/information-tooltip/information-tooltip.component.ts b/portal-FE-os/src/app/pages/information-tooltip/information-tooltip.component.ts new file mode 100644 index 00000000..3c05d074 --- /dev/null +++ b/portal-FE-os/src/app/pages/information-tooltip/information-tooltip.component.ts @@ -0,0 +1,19 @@ +import { Component, OnInit, Input } from '@angular/core'; + +@Component({ + selector: 'app-information-tooltip', + templateUrl: './information-tooltip.component.html', + styleUrls: ['./information-tooltip.component.scss'] +}) +export class InformationTooltipComponent implements OnInit { + + @Input() textMessage : any; + constructor() { } + + message : string; + ngOnInit() { + console.log("Message ", this.textMessage); + this.message = this.textMessage; + } + +} diff --git a/portal-FE-os/src/app/pages/pages.module.ts b/portal-FE-os/src/app/pages/pages.module.ts index 7ccb3f95..b7163da3 100644 --- a/portal-FE-os/src/app/pages/pages.module.ts +++ b/portal-FE-os/src/app/pages/pages.module.ts @@ -35,7 +35,7 @@ * * */ -import { NgModule } from '@angular/core'; +import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; import { CommonModule } from '@angular/common'; import { ReactiveFormsModule, FormsModule } from '@angular/forms'; import { MatIconModule } from '@angular/material/icon'; @@ -96,7 +96,9 @@ import { ApplicationPipesModule } from '../shared/pipes/application-pipes.module import { UsersComponent } from './users/users.component'; import { NewUserModalComponent } from './users/new-user-modal/new-user-modal.component'; import { BulkUserComponent } from './users/bulk-user/bulk-user.component'; +import { InformationTooltipComponent } from './information-tooltip/information-tooltip.component'; import { UserDetailsFormComponent } from './users/user-details-form/user-details-form.component'; +import { MatTooltipModule } from '@angular/material'; @NgModule({ @@ -149,7 +151,8 @@ import { UserDetailsFormComponent } from './users/user-details-form/user-details DashboardWidgetCatalogComponent, FunctionalMenuDialogComponent, GetAccessComponent, - UserDetailsFormComponent + UserDetailsFormComponent, + InformationTooltipComponent ], imports: [ CommonModule, @@ -163,7 +166,8 @@ import { UserDetailsFormComponent } from './users/user-details-form/user-details MatIconModule, MatCheckboxModule, FormsModule, - PluginModule + PluginModule, + MatTooltipModule ], entryComponents: [ SchedulerComponent, @@ -193,7 +197,9 @@ import { UserDetailsFormComponent } from './users/user-details-form/user-details useClass: HeaderInterceptor, multi: true, }], - + schemas: [ + CUSTOM_ELEMENTS_SCHEMA + ] }) export class PagesModule { 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 index 7fc35e44..bd9d69b6 100644 --- 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 @@ -113,6 +113,6 @@ </form> </div> <div class="modal-footer"> - <button type="submit" class="btn btn-primary" (click)="addUser()" [disabled]="addNewUserForm.invalid">Next</button> + <button type="submit" class="btn btn-primary" (click)="addUser()">Next</button> <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.ts b/portal-FE-os/src/app/pages/users/user-details-form/user-details-form.component.ts index bea0fcdb..33d2b331 100644 --- 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 @@ -2,7 +2,8 @@ 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'; +import { NgbActiveModal, NgbModal } from '@ng-bootstrap/ng-bootstrap'; +import { ConfirmationModalComponent } from 'src/app/modals/confirmation-modal/confirmation-modal.component'; @Component({ selector: 'app-user-details-form', @@ -13,9 +14,10 @@ export class UserDetailsFormComponent implements OnInit { addNewUserForm: FormGroup; submitted = false; - constructor(private formBuilder: FormBuilder, + constructor(private formBuilder: FormBuilder, private usersService: UsersService, - public activeModal: NgbActiveModal) { } + public activeModal: NgbActiveModal, + public ngbModal: NgbModal) { } ngOnInit() { this.addNewUserForm = this.formBuilder.group({ @@ -24,7 +26,7 @@ export class UserDetailsFormComponent implements OnInit { lastName: ['', Validators.required], email: ['', [Validators.required, Validators.email]], loginId: ['', Validators.required], - loginPwd: ['', [Validators.required, Validators.minLength(6)]], + loginPwd: ['', Validators.required], confirmPassword: ['', Validators.required] }, { validator: MustMatch('loginPwd', 'confirmPassword') @@ -44,7 +46,17 @@ export class UserDetailsFormComponent implements OnInit { 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.usersService.addNewUser(newUserFormData).subscribe(result => { + console.log("Result : ", result); + const modalSuccess = this.ngbModal.open(ConfirmationModalComponent); + modalSuccess.componentInstance.title = "Success"; + modalSuccess.componentInstance.message = 'User added Successfully!'; + }, error => { + console.log("Error : ", error); + const modalErrorRef = this.ngbModal.open(ConfirmationModalComponent); + modalErrorRef.componentInstance.title = "Error"; + modalErrorRef.componentInstance.message = 'Something went wrong. Error Message: ' + error.message; + }) this.activeModal.close(); } |