From d2f793b71f8aa0e5713de6347d0e846c4f649e21 Mon Sep 17 00:00:00 2001 From: Krista House Date: Fri, 1 Mar 2024 03:12:39 -0500 Subject: [PATCH] fix(webapp): fix web form controls data submission (#736) Issue: DGW-151 --- .../form/web-client-form.component.html | 1 - .../form/web-client-form.component.scss | 2 +- .../form/web-client-form.component.ts | 101 ++++++++++++------ .../shared/enums/web-client-protocol.enum.ts | 13 +++ 4 files changed, 82 insertions(+), 35 deletions(-) diff --git a/webapp/src/client/app/modules/web-client/form/web-client-form.component.html b/webapp/src/client/app/modules/web-client/form/web-client-form.component.html index e78089d97..e580c1933 100644 --- a/webapp/src/client/app/modules/web-client/form/web-client-form.component.html +++ b/webapp/src/client/app/modules/web-client/form/web-client-form.component.html @@ -19,7 +19,6 @@ appendTo="body" formControlName="protocol" [options]="protocolOptions" - (onChange)="onProtocolChange($event.value)" pTooltip="{{protocolSelectedTooltip}}" required> diff --git a/webapp/src/client/app/modules/web-client/form/web-client-form.component.scss b/webapp/src/client/app/modules/web-client/form/web-client-form.component.scss index fa3068218..59a798906 100644 --- a/webapp/src/client/app/modules/web-client/form/web-client-form.component.scss +++ b/webapp/src/client/app/modules/web-client/form/web-client-form.component.scss @@ -44,7 +44,7 @@ .box { background-color: var(--box-background-color); - width: 377px; + width: 447px; border-radius: 8px; padding: 24px; } diff --git a/webapp/src/client/app/modules/web-client/form/web-client-form.component.ts b/webapp/src/client/app/modules/web-client/form/web-client-form.component.ts index 5f11df116..a5f2ef1c4 100644 --- a/webapp/src/client/app/modules/web-client/form/web-client-form.component.ts +++ b/webapp/src/client/app/modules/web-client/form/web-client-form.component.ts @@ -1,13 +1,13 @@ import {Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges} from '@angular/core'; import {AbstractControl, FormBuilder, FormControl, FormGroup, ValidatorFn, Validators} from "@angular/forms"; import {Message, SelectItem} from "primeng/api"; -import {catchError, switchMap, takeUntil} from "rxjs/operators"; +import {catchError, map, switchMap, takeUntil, tap} from "rxjs/operators"; import {EMPTY, Observable, of} from "rxjs"; import {BaseComponent} from "@shared/bases/base.component"; import {WebSession} from "@shared/models/web-session.model"; import {ComponentStatus} from "@shared/models/component-status.model"; -import {Protocol, WebClientProtocol} from "@shared/enums/web-client-protocol.enum"; +import {Protocol, WebClientProtocol, ProtocolControlMap } from "@shared/enums/web-client-protocol.enum"; import {AuthMode, WebClientAuthMode} from "@shared/enums/web-client-auth-mode.enum"; import {ScreenSize} from "@shared/enums/screen-size.enum"; import {StorageService} from "@shared/services/utils/storage.service"; @@ -105,15 +105,16 @@ export class WebClientFormComponent extends BaseComponent implements OnInit, return this.getCurrentProtocolInputVisibility().showMoreSettingsInputs ?? false; } - onProtocolChange(value: any): void { - this.updateProtocolTooltip(value); - } - onConnectSession(): void { - this.webSessionService.createWebSession(this.connectSessionForm, this.getSelectedProtocol()).pipe( + this.processFormData(this.connectSessionForm).pipe( takeUntil(this.destroyed$), + switchMap((formToSubmit) => this.webSessionService.createWebSession(formToSubmit, this.getSelectedProtocol())), switchMap((webSession) => this.manageScreenSize(webSession)), - switchMap((webSession) => this.manageWebSessionSubject(webSession)) + switchMap((webSession) => this.manageWebSessionSubject(webSession)), + catchError(error => { + console.error('Failed to process web session:', error); + return EMPTY; + }) ).subscribe( (webSession) => { this.addHostnameToStorage(webSession?.data?.hostname); @@ -174,11 +175,31 @@ export class WebClientFormComponent extends BaseComponent implements OnInit, } private updateProtocolTooltip(value: any): void { - const selectedItem: SelectItemWithTooltip = this.protocolOptions - .find(item => item.value === value); + const selectedItem: SelectItemWithTooltip = this.protocolOptions.find(item => item.value === value); + this.protocolSelectedTooltip = selectedItem ? (selectedItem as any).tooltipText : ''; + } - this.protocolSelectedTooltip = selectedItem ? (selectedItem as any).tooltipText : ''; -} + private processFormData(sessionForm: FormGroup): Observable> { + if (this.isSelectedProtocolRdp()) { + return of(new FormGroup(sessionForm.controls)); + } + + const selectedProtocol: Protocol = this.getSelectedProtocol(); + const protocolControlMap: ProtocolControlMap = WebClientProtocol.getProtocolFormControlMap(); + const requiredControls: string[] = protocolControlMap[selectedProtocol]; + + const newFormGroup: FormGroup = new FormGroup({}); + newFormGroup.addControl('protocol', sessionForm.controls['protocol']); + + if (requiredControls) { + requiredControls.forEach(controlName => { + if (sessionForm.controls[controlName]) { + newFormGroup.addControl(controlName, sessionForm.controls[controlName]); + } + }); + } + return of(newFormGroup); + } private manageScreenSize(webSession: WebSession): Observable> { if (!this.isSelectedProtocolRdp()) { @@ -250,7 +271,15 @@ export class WebClientFormComponent extends BaseComponent implements OnInit, } private buildForm(): Observable { - const formControls = { + return this.createFormGroup().pipe( + takeUntil(this.destroyed$), + map((newFormGroup) => this.connectSessionForm = newFormGroup), + switchMap(() => this.updateFormControls()) + ); + } + + private createFormGroup(): Observable> { + const formControls= { protocol: [0, Validators.required], autoComplete: new FormControl('', Validators.required), hostname: [''], @@ -282,15 +311,22 @@ export class WebClientFormComponent extends BaseComponent implements OnInit, }); } - this.connectSessionForm = formGroup; - this.updateFormControls(); - - return of(undefined); + return of(formGroup); } - private updateFormControls(protocol?: Protocol): void { + private updateFormControls(protocol?: Protocol): Observable { protocol = protocol ?? this.getSelectedProtocol(); + this.disableAllFormControls(); + this.enableFormControlsByProtocol(protocol); + + if (protocol === Protocol.VNC) { + this.handleVncFormControls(); + } + return of(undefined); + } + + private disableAllFormControls(): void { const controlsToDisable: string[] = [ 'authMode', 'username', @@ -305,22 +341,18 @@ export class WebClientFormComponent extends BaseComponent implements OnInit, controlsToDisable.forEach(control => { this.connectSessionForm.get(control)?.disable(); }); + } - const protocolControlMap: { [key in Protocol]?: string[] } = { - [Protocol.SSH]: ['username', 'password'], - [Protocol.VNC]: ['authMode', 'username', 'password', 'screenSize'], - [Protocol.ARD]: ['username', 'password', 'screenSize'], - [Protocol.RDP]: ['username', 'password', 'screenSize', 'customWidth', 'customHeight', 'kdcUrl', 'preConnectionBlob'], - }; - + private enableFormControlsByProtocol(protocol: Protocol): void { + const protocolControlMap: ProtocolControlMap = WebClientProtocol.getProtocolFormControlMap(); protocolControlMap[protocol]?.forEach(control => { this.connectSessionForm.get(control)?.enable(); }); + } - if (protocol === Protocol.VNC) { - this.setAuthMode(this.getSelectedAuthMode() ?? AuthMode.VNC_Password); - this.updateFormControlsByAuthMode(); - } + private handleVncFormControls(): void { + this.setAuthMode(this.getSelectedAuthMode() ?? AuthMode.VNC_Password); + this.updateFormControlsByAuthMode(); } private updateFormControlsByAuthMode(authMode?: AuthMode): void { @@ -429,10 +461,13 @@ export class WebClientFormComponent extends BaseComponent implements OnInit, private subscribeToFormProtocol(): void { this.connectSessionForm.get('protocol').valueChanges.pipe( takeUntil(this.destroyed$), - ).subscribe(value => { - this.showMoreSettings = false; - this.updateFormControls(value); - }); + tap(protocol => this.updateProtocolTooltip(protocol)), + switchMap(protocol => this.updateFormControls(protocol)), + catchError(error => { + console.error('Error handling protocol changes:', error); + return EMPTY; + }) + ).subscribe(() => this.showMoreSettings = false); } private subscribeToFormAuthMode(): void { diff --git a/webapp/src/client/app/shared/enums/web-client-protocol.enum.ts b/webapp/src/client/app/shared/enums/web-client-protocol.enum.ts index a352872c5..3e86a3cee 100644 --- a/webapp/src/client/app/shared/enums/web-client-protocol.enum.ts +++ b/webapp/src/client/app/shared/enums/web-client-protocol.enum.ts @@ -16,6 +16,8 @@ enum Tooltips { 'Apple Remote Desktop' = 'ARD' } +export type ProtocolControlMap = { [key in Protocol]?: string[] }; + namespace WebClientProtocol { export function getEnumKey(value: Protocol): string { @@ -39,5 +41,16 @@ namespace WebClientProtocol { return { label, value, tooltipText }; }); } + + export function getProtocolFormControlMap(): ProtocolControlMap { + const protocolControlMap: { [key in Protocol]?: string[] } = { + [Protocol.Telnet]: ['autoComplete', 'hostname'], + [Protocol.SSH]: ['autoComplete', 'hostname', 'username', 'password'], + [Protocol.VNC]: ['autoComplete', 'hostname', 'authMode', 'username', 'password'], + [Protocol.ARD]: ['autoComplete', 'hostname', 'username', 'password'], + [Protocol.RDP]: ['autoComplete', 'hostname', 'username', 'password', 'screenSize', 'customWidth', 'customHeight', 'kdcUrl', 'preConnectionBlob'], + }; + return protocolControlMap; + } } export {WebClientProtocol};