From eb9c4821d274756d96dce7bb60c3a7c70f18fbc2 Mon Sep 17 00:00:00 2001 From: "SANDHYA.JS" Date: Wed, 11 Oct 2023 16:29:27 +0530 Subject: [PATCH] Fix Bug 2291: No option to update VIM Account in NG-UI - NG-UI support for VIM Update - Added edit button in VIM Account Action - Patched the value in edit form using vimaccounts get api - schema_type support is not given in patch method - Disabled vim url and type in vim update action Change-Id: I7c90e55fc4223d6c41ce12333ee23536358cab43 Signed-off-by: SANDHYA.JS --- angular.json | 20 +- .../VimAccountsActionComponent.html | 3 + .../VimAccountsActionComponent.ts | 16 +- src/app/vim-accounts/VimAccountsModule.ts | 8 + .../NewVimaccountComponent.html | 13 +- .../new-vimaccount/NewVimaccountComponent.ts | 221 ++++++++++++++++-- src/assets/i18n/de.json | 9 +- src/assets/i18n/en.json | 9 +- src/assets/i18n/es.json | 9 +- src/assets/i18n/pt.json | 9 +- 10 files changed, 288 insertions(+), 29 deletions(-) diff --git a/angular.json b/angular.json index 60abb89..1a6d042 100644 --- a/angular.json +++ b/angular.json @@ -77,8 +77,17 @@ "maximumError": "5mb" } ] + }, + "development": { + "buildOptimizer": false, + "optimization": false, + "vendorChunk": true, + "extractLicenses": false, + "sourceMap": true, + "namedChunks": true } - } + }, + "defaultConfiguration": "production" }, "serve": { "builder": "@angular-devkit/build-angular:dev-server", @@ -88,8 +97,12 @@ "configurations": { "production": { "browserTarget": "osm:build:production" + }, + "development": { + "browserTarget": "osm:build:development" } - } + }, + "defaultConfiguration": "development" }, "extract-i18n": { "builder": "@angular-devkit/build-angular:extract-i18n", @@ -165,6 +178,7 @@ "cli": { "schematicCollections": [ "@angular-eslint/schematics" - ] + ], + "analytics": "bc7a21d3-c008-4362-b213-866be7e71063" } } \ No newline at end of file diff --git a/src/app/utilities/vim-accounts-action/VimAccountsActionComponent.html b/src/app/utilities/vim-accounts-action/VimAccountsActionComponent.html index 51c57b0..1286116 100644 --- a/src/app/utilities/vim-accounts-action/VimAccountsActionComponent.html +++ b/src/app/utilities/vim-accounts-action/VimAccountsActionComponent.html @@ -40,6 +40,9 @@ Author: KUMARAN M (kumaran.m@tataelxsi.co.in), RAJESH S (rajesh.s@tataelxsi.co.i + - @@ -161,7 +165,8 @@ Author: KUMARAN M (kumaran.m@tataelxsi.co.in), RAJESH S (rajesh.s@tataelxsi.co.i diff --git a/src/app/vim-accounts/new-vimaccount/NewVimaccountComponent.ts b/src/app/vim-accounts/new-vimaccount/NewVimaccountComponent.ts index a57b782..724bef2 100644 --- a/src/app/vim-accounts/new-vimaccount/NewVimaccountComponent.ts +++ b/src/app/vim-accounts/new-vimaccount/NewVimaccountComponent.ts @@ -18,11 +18,12 @@ /** * @file Vim Account Component. */ - import { isNullOrUndefined } from 'util'; +import { isNullOrUndefined } from 'util'; import { HttpHeaders } from '@angular/common/http'; import { Component, ElementRef, Injector, OnInit, ViewChild } from '@angular/core'; -import { FormBuilder, FormGroup, Validators } from '@angular/forms'; -import { Router } from '@angular/router'; +import { AbstractControl, FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { ActivatedRoute, Router } from '@angular/router'; +import { NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap'; import { TranslateService } from '@ngx-translate/core'; import { NotifierService } from 'angular-notifier'; import 'codemirror/addon/dialog/dialog'; @@ -41,7 +42,7 @@ import 'codemirror/mode/javascript/javascript'; import 'codemirror/mode/markdown/markdown'; import 'codemirror/mode/yaml/yaml'; import { - APIURLHEADER, ERRORDATA, TYPEAWS, TYPEAZURE, TYPEOPENSTACK, TYPEOPENVIMNEBULA, TYPEOTERS, + APIURLHEADER, CONFIGCONSTANT, ERRORDATA, MODALCLOSERESPONSEDATA, TYPEAWS, TYPEAZURE, TYPEOPENSTACK, TYPEOPENVIMNEBULA, TYPEOTERS, TYPESECTION, TYPEVMWARE, VIM_TYPES } from 'CommonModel'; import { environment } from 'environment'; @@ -49,7 +50,7 @@ import * as jsyaml from 'js-yaml'; import { RestService } from 'RestService'; import { SharedService } from 'SharedService'; import { VimAccountDetails } from 'VimAccountModel'; - +import { WarningComponent } from 'WarningComponent'; /** * Creating component * @Component takes NewVimaccountComponent.html as template url @@ -85,6 +86,9 @@ export class NewVimaccountComponent implements OnInit { /** Give the message for the loading @public */ public message: string = 'PLEASEWAIT'; + /** Set the check value @public */ + public check: boolean = false; + /** Handle the formate Change @public */ public defaults: {} = { 'text/x-yaml': '' @@ -101,7 +105,7 @@ export class NewVimaccountComponent implements OnInit { // eslint-disable-next-line no-invalid-this mode: this.modeDefault, showCursorWhenSelecting: true, - autofocus: true, + autofocus: false, autoRefresh: true, lineNumbers: true, lineWrapping: true, @@ -116,6 +120,9 @@ export class NewVimaccountComponent implements OnInit { /** Data @public */ public data: string = ''; + /** contains vim ID @public */ + public vimID: string; + /** Element ref for fileInput @public */ @ViewChild('fileInput', { static: true }) public fileInput: ElementRef; @@ -125,6 +132,45 @@ export class NewVimaccountComponent implements OnInit { /** Contains all methods related to shared @private */ public sharedService: SharedService; + /** Check key for the Edit form @public */ + public checkFormKeys: string[] = + [ + 'name', + 'vim_type', + 'vim_tenant_name', + 'description', + 'vim_url', + 'schema_type', + 'vim_user', + 'vim_password', + 'locationName', + 'latitude', + 'longitude', + 'config' + ]; + + /** Contains config details in edit @public */ + public config: {}; + + /** Contains latitude value @public */ + public latitude: string; + + /** Contains longitude value @public */ + public longitude: string; + + /** Contains location value @public */ + public locationName: string; + + /** Contains VIMAccount Details @private */ + private details: VimAccountDetails; + + /** Contains config with location @private */ + private configLocation: string; + + /** Check for config length @private */ + // eslint-disable-next-line @typescript-eslint/no-magic-numbers + private configLength: number = 3; + /** Instance of the rest service @private */ private restService: RestService; @@ -143,8 +189,11 @@ export class NewVimaccountComponent implements OnInit { /** Contains tranlsate instance @private */ private translateService: TranslateService; - /** VIM Details @private */ - private vimDetail: VimAccountDetails[]; + /** Holds teh instance of AuthService class of type AuthService @private */ + private activatedRoute: ActivatedRoute; + + /** Instance of the modal service @private */ + private modalService: NgbModal; constructor(injector: Injector) { this.injector = injector; @@ -154,6 +203,8 @@ export class NewVimaccountComponent implements OnInit { this.notifierService = this.injector.get(NotifierService); this.translateService = this.injector.get(TranslateService); this.sharedService = this.injector.get(SharedService); + this.activatedRoute = this.injector.get(ActivatedRoute); + this.modalService = this.injector.get(NgbModal); } /** convenience getter for easy access to form fields */ @@ -163,6 +214,7 @@ export class NewVimaccountComponent implements OnInit { * Lifecyle Hooks the trigger before component is instantiate */ public ngOnInit(): void { + this.vimID = this.activatedRoute.snapshot.paramMap.get('id'); this.vimType = VIM_TYPES; this.headers = new HttpHeaders({ Accept: 'application/json', @@ -170,6 +222,9 @@ export class NewVimaccountComponent implements OnInit { 'Cache-Control': 'no-cache, no-store, must-revalidate, max-age=0' }); this.initializeForm(); + if (!isNullOrUndefined(this.vimID)) { + this.getVIMDetails(this.vimID); + } } /** VIM Initialize Forms @public */ @@ -197,6 +252,52 @@ export class NewVimaccountComponent implements OnInit { }); } + /** Fetching the vim details from get api @protected */ + private getVIMDetails(id: string): void { + this.isLocationLoadingResults = true; + this.restService.getResource(environment.VIMACCOUNTS_URL + '/' + id).subscribe((vimAccountsData: VimAccountDetails) => { + this.details = vimAccountsData; + if (!isNullOrUndefined(this.details.config.location)) { + this.configLocation = this.details.config.location; + if (this.configLocation.indexOf(',') !== -1) { + this.locationName = this.configLocation.split(',')[0]; + this.latitude = this.configLocation.split(',')[1]; + this.longitude = this.configLocation.split(',')[2]; + } + } + delete this.details.config.location; + this.getFormControl('schema_type').disable(); + this.getFormControl('vim_url').disable(); + this.getFormControl('vim_type').disable(); + this.config = { ...this.details.config }; + this.details.vim_password = ''; + this.setEditValue(this.details, this.checkFormKeys); + this.isLocationLoadingResults = false; + }, (error: ERRORDATA) => { + this.restService.handleError(error, 'get'); + this.isLocationLoadingResults = false; + }); + } + + /** Set the value for the Edit Section @public */ + public setEditValue(formValues: VimAccountDetails, checkKey: string[]): void { + Object.keys(formValues).forEach((name: string): void => { + if (checkKey.includes(name)) { + if (name === 'config') { + this.loadConfig(); + this.getFormControl('locationName').patchValue(this.locationName); + this.getFormControl('latitude').patchValue(this.latitude); + this.getFormControl('longitude').patchValue(this.longitude); + } + else { + // eslint-disable-next-line security/detect-object-injection + this.getFormControl(name).setValue(formValues[name], { onlySelf: true }); + this.getFormControl(name).updateValueAndValidity(); + } + } + }); + } + /** On modal submit newVimAccountSubmit will called @public */ public newVimAccountSubmit(): void { this.submitted = true; @@ -231,7 +332,11 @@ export class NewVimaccountComponent implements OnInit { delete this.vimNewAccountForm.value.config[res]; } }); - this.createNewVIM(); + if (!isNullOrUndefined(this.vimID)) { + this.editVIM(); + } else { + this.createNewVIM(); + } } } @@ -245,7 +350,7 @@ export class NewVimaccountComponent implements OnInit { delete this.vimNewAccountForm.value.latitude; delete this.vimNewAccountForm.value.longitude; this.restService.postResource(apiURLHeader, this.vimNewAccountForm.value) - .subscribe((result: {id: string}): void => { + .subscribe((result: { id: string }): void => { this.notifierService.notify('success', this.translateService.instant('PAGE.VIM.CREATEDSUCCESSFULLY')); this.isLocationLoadingResults = false; this.router.navigate(['vim/info/' + result.id]).catch((): void => { @@ -257,6 +362,27 @@ export class NewVimaccountComponent implements OnInit { }); } + /** Create a edit VIM Account @public */ + public editVIM(): void { + const apiURLHeader: APIURLHEADER = { + url: environment.VIMACCOUNTS_URL + '/' + this.vimID, + httpOptions: { headers: this.headers } + }; + delete this.vimNewAccountForm.value.locationName; + delete this.vimNewAccountForm.value.latitude; + delete this.vimNewAccountForm.value.longitude; + this.restService.patchResource(apiURLHeader, this.vimNewAccountForm.value) + .subscribe((result: { id: string }): void => { + this.notifierService.notify('success', this.translateService.instant('PAGE.VIM.UPDATEDSUCCESSFULLY')); + this.isLocationLoadingResults = false; + this.router.navigate(['vim/info/' + this.vimID]).catch((): void => { + // Error Cached; + }); + }, (error: ERRORDATA): void => { + this.restService.handleError(error, 'post'); + this.isLocationLoadingResults = false; + }); + } /** HandleChange function @public */ public handleChange($event: string): void { this.data = $event; @@ -292,9 +418,28 @@ export class NewVimaccountComponent implements OnInit { this.fileInput.nativeElement.value = null; } + /** Check data is empty or not to load config @public */ + public checkData(): void { + if (this.data !== '' && this.data.length > this.configLength) { + // eslint-disable-next-line security/detect-non-literal-fs-filename + const modalRef: NgbModalRef = this.modalService.open(WarningComponent, { backdrop: 'static' }); + modalRef.componentInstance.heading = this.translateService.instant('PAGE.VIMDETAILS.VIMHEADER'); + modalRef.componentInstance.confirmationMessage = this.translateService.instant('PAGE.VIMDETAILS.VIMCONTENT'); + modalRef.componentInstance.submitMessage = this.translateService.instant('PAGE.VIMDETAILS.VIMSUBMIT'); + modalRef.result.then((result: MODALCLOSERESPONSEDATA): void => { + if (result.message === CONFIGCONSTANT.done) { + this.loadSampleConfig(); + } + }).catch((): void => { + // Catch Navigation Error + }); + } else if (this.data.length < this.configLength || this.data === '') { + this.loadSampleConfig(); + } + } + /** Load sample config based on VIM type @public */ public loadSampleConfig(): void { - this.clearConfig(); if (this.selectedVimType === 'openstack') { this.defaults['text/x-yaml'] = jsyaml.dump(TYPEOPENSTACK); this.data = JSON.stringify(TYPEOPENSTACK, null, '\t'); @@ -316,10 +461,58 @@ export class NewVimaccountComponent implements OnInit { } } + /** Load sample config based on VIM type in edit @public */ + public loadConfig(): void { + this.clearConfig(); + if (this.details.vim_type === 'openstack') { + this.defaults['text/x-yaml'] = jsyaml.dump(this.config); + this.data = JSON.stringify(this.config, null, '\t'); + } else if (this.details.vim_type === 'aws') { + this.defaults['text/x-yaml'] = jsyaml.dump(this.config); + this.data = JSON.stringify(this.config, null, '\t'); + } else if (this.details.vim_type === 'vmware') { + this.defaults['text/x-yaml'] = jsyaml.dump(this.config); + this.data = JSON.stringify(this.config, null, '\t'); + } else if (this.details.vim_type === 'openvim' || this.details.vim_type === 'opennebula') { + this.defaults['text/x-yaml'] = jsyaml.dump(this.config); + this.data = JSON.stringify(this.config, null, '\t'); + } else if (this.details.vim_type === 'azure' || this.details.vim_type === 'opennebula') { + this.defaults['text/x-yaml'] = jsyaml.dump(this.config); + this.data = JSON.stringify(this.config, null, '\t'); + } else { + this.defaults['text/x-yaml'] = jsyaml.dump(this.config); + this.data = JSON.stringify(this.config, null, '\t'); + } + } + /** Clear config parameters @public */ public clearConfig(): void { - this.defaults['text/x-yaml'] = ''; - this.data = ''; - this.fileInput.nativeElement.value = null; + this.check = true; + if (this.data !== '' && this.data.length > this.configLength) { + // eslint-disable-next-line security/detect-non-literal-fs-filename + const modalRef: NgbModalRef = this.modalService.open(WarningComponent, { backdrop: 'static' }); + modalRef.componentInstance.heading = this.translateService.instant('PAGE.VIMDETAILS.VIMHEADER'); + modalRef.componentInstance.confirmationMessage = this.translateService.instant('PAGE.VIMDETAILS.CLEARCONTENT'); + modalRef.componentInstance.submitMessage = this.translateService.instant('PAGE.VIMDETAILS.VIMSUBMIT'); + modalRef.result.then((result: MODALCLOSERESPONSEDATA): void => { + if (result.message === CONFIGCONSTANT.done) { + this.defaults['text/x-yaml'] = ''; + this.data = ''; + this.fileInput.nativeElement.value = null; + } + }).catch((): void => { + // Catch Navigation Error + }); + } else { + this.defaults['text/x-yaml'] = ''; + this.data = ''; + this.fileInput.nativeElement.value = null; + } + } + + /** Used to get the AbstractControl of controlName passed @private */ + private getFormControl(controlName: string): AbstractControl { + // eslint-disable-next-line security/detect-object-injection + return this.vimNewAccountForm.controls[controlName]; } } diff --git a/src/assets/i18n/de.json b/src/assets/i18n/de.json index 2bf6386..0bd8553 100644 --- a/src/assets/i18n/de.json +++ b/src/assets/i18n/de.json @@ -250,6 +250,7 @@ }, "VIM": { "CREATEDSUCCESSFULLY": "VIM erfolgreich erstellt", + "UPDATEDSUCCESSFULLY": "VIM wurde erfolgreich aktualisiert", "LOCATIONINFO": "Geben Sie den Namen des Datenorts, den Breiten- und Längengrad ein, der in der Kartenansicht angezeigt werden soll" }, "VIMDETAILS": { @@ -277,7 +278,13 @@ "VIMRESOURCES": "Übersicht über die VIM-Ressourcen", "DOUGHNUT": "Krapfen", "PIE": "Kuchen", - "NODATA": "Keine Daten" + "NODATA": "Keine Daten", + "EDITVIMACCOUNT": "Bearbeiten Sie das VIM-Konto", + "EDITVIM": "VIM bearbeiten", + "VIMHEADER": "Warnung", + "VIMCONTENT": "Diese Aktion umfasst das Laden der Beispielkonfiguration und das Löschen der aktuellen Konfiguration", + "CLEARCONTENT": "Diese Aktion beinhaltet das Löschen der aktuellen Konfiguration", + "VIMSUBMIT": "Fortfahren" }, "WIMACCOUNTS": { "CREATEDSUCCESSFULLY": "WIM erfolgreich erstellt", diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json index 0f8b581..7ea835d 100644 --- a/src/assets/i18n/en.json +++ b/src/assets/i18n/en.json @@ -250,6 +250,7 @@ }, "VIM": { "CREATEDSUCCESSFULLY": "VIM Created Successfully", + "UPDATEDSUCCESSFULLY": "VIM Updated Successfully", "LOCATIONINFO": "Type the Data location name, Latitude & Longitude to show in map view" }, "VIMDETAILS": { @@ -277,7 +278,13 @@ "VIMRESOURCES": "VIM Resources Overview", "DOUGHNUT": "Doughnut", "PIE": "Pie", - "NODATA": "No Data" + "NODATA": "No Data", + "EDITVIMACCOUNT": "Edit VIM Account", + "EDITVIM": "Edit VIM", + "VIMHEADER": "Warning", + "VIMCONTENT": "This action involves loading the sample config & deleting the present config", + "CLEARCONTENT": "This action involves deleting the present config", + "VIMSUBMIT": "Proceed" }, "WIMACCOUNTS": { "CREATEDSUCCESSFULLY": "WIM Created Successfully", diff --git a/src/assets/i18n/es.json b/src/assets/i18n/es.json index f76eef7..7701f03 100644 --- a/src/assets/i18n/es.json +++ b/src/assets/i18n/es.json @@ -250,6 +250,7 @@ }, "VIM": { "CREATEDSUCCESSFULLY": "VIM creada correctamente", + "UPDATEDSUCCESSFULLY": "VIM actualizado con éxito", "LOCATIONINFO": "Escriba el nombre de la ubicación de datos, latitud y longitud para mostrar en la vista de mapa" }, "VIMDETAILS": { @@ -277,7 +278,13 @@ "VIMRESOURCES": "Descripción general de los recursos de VIM", "DOUGHNUT": "Rosquilla", "PIE": "Pastel", - "NODATA": "Sin datos" + "NODATA": "Sin datos", + "EDITVIMACCOUNT": "Editar cuenta VIM", + "EDITVIM": "Editar VIM", + "VIMHEADER": "Advertencia", + "VIMCONTENT": "Esta acción implica cargar la configuración de muestra y eliminar la configuración actual.", + "CLEARCONTENT": "Esta acción implica eliminar la configuración actual.", + "VIMSUBMIT": "Proceder" }, "WIMACCOUNTS": { "CREATEDSUCCESSFULLY": "WIM Creado correctamente", diff --git a/src/assets/i18n/pt.json b/src/assets/i18n/pt.json index 3617fd4..04eea20 100644 --- a/src/assets/i18n/pt.json +++ b/src/assets/i18n/pt.json @@ -250,6 +250,7 @@ }, "VIM": { "CREATEDSUCCESSFULLY": "VIM criado com sucesso", + "UPDATEDSUCCESSFULLY": "VIM atualizado com sucesso", "LOCATIONINFO": "Digite o nome do local de dados, latitude e longitude para mostrar na visualização do mapa" }, "VIMDETAILS": { @@ -277,7 +278,13 @@ "VIMRESOURCES": "Visão geral dos recursos do VIM", "DOUGHNUT": "rosquinha", "PIE": "torta", - "NODATA": "Sem dados" + "NODATA": "Sem dados", + "EDITVIMACCOUNT": "Editar conta VIM", + "EDITVIM": "Editar VIM", + "VIMHEADER": "Aviso", + "VIMCONTENT": "Esta ação envolve carregar a configuração de amostra e excluir a configuração atual", + "CLEARCONTENT": "Esta ação envolve a exclusão da configuração atual", + "VIMSUBMIT": "Continuar" }, "WIMACCOUNTS": { "CREATEDSUCCESSFULLY": "WIM criado com sucesso", -- 2.25.1