From 302b3e18ec7956439992c9ca37071d04abead5f1 Mon Sep 17 00:00:00 2001 From: Darren Thornton <6361057+dthornton-hyl@users.noreply.github.com> Date: Tue, 3 Feb 2026 02:26:45 -0600 Subject: [PATCH] AAE-40604 Fix for Dropdown required validation message is not present (#11600) --- .../dropdown/dropdown-cloud.widget.html | 44 ++++++++------ .../dropdown/dropdown-cloud.widget.spec.ts | 60 ++++++++++++++++++- .../widgets/dropdown/dropdown-cloud.widget.ts | 3 +- 3 files changed, 84 insertions(+), 23 deletions(-) diff --git a/lib/process-services-cloud/src/lib/form/components/widgets/dropdown/dropdown-cloud.widget.html b/lib/process-services-cloud/src/lib/form/components/widgets/dropdown/dropdown-cloud.widget.html index 828e727acb..ff50652193 100644 --- a/lib/process-services-cloud/src/lib/form/components/widgets/dropdown/dropdown-cloud.widget.html +++ b/lib/process-services-cloud/src/lib/form/components/widgets/dropdown/dropdown-cloud.widget.html @@ -4,11 +4,13 @@ [class.adf-readonly]="field.readOnly" [class.adf-left-label-input-container]="field.leftLabels" > -
- -
+ @if(field.leftLabels) { +
+ +
+ }
@if ( (field.name || this.field?.required) && !field.leftLabels) { @@ -27,7 +29,9 @@ #select (keydown.escape)="select.close()" > - + @if(showInputFilter) { + + } @for(opt of (list$ | async); track opt.id) { @@ -48,19 +52,23 @@
- - - + @if(showRequiredMessage) { + + } + @if(!previewState && isRestApiFailed) { + + } + @if(!previewState && variableOptionsFailed) { + + }
diff --git a/lib/process-services-cloud/src/lib/form/components/widgets/dropdown/dropdown-cloud.widget.spec.ts b/lib/process-services-cloud/src/lib/form/components/widgets/dropdown/dropdown-cloud.widget.spec.ts index 44c05633eb..bfc3d492d9 100644 --- a/lib/process-services-cloud/src/lib/form/components/widgets/dropdown/dropdown-cloud.widget.spec.ts +++ b/lib/process-services-cloud/src/lib/form/components/widgets/dropdown/dropdown-cloud.widget.spec.ts @@ -253,6 +253,24 @@ describe('DropdownCloudWidgetComponent', () => { expect(widget.isRestApiFailed).toBe(true); expect(widget.field.options.length).toEqual(0); expect(errorMessageElement.nativeElement.textContent.trim()).toBe(errorIcon + 'FORM.FIELD.REST_API_FAILED'); + + const errorsMessagesElement = fixture.debugElement.query(By.css('.adf-error-messages-container')); + expect(errorsMessagesElement.nativeElement.classList.contains('adf-error-messages-container-visible')).toBe(true); + }); + + it('should NOT show required message when REST API failed', () => { + widget.field.readOnly = false; + widget.field.required = true; + + widget.ngOnInit(); + widget.dropdownControl.markAsTouched(); + fixture.detectChanges(); + + expect(widget.isRestApiFailed).toBe(true); + const requiredErrorElement = fixture.debugElement.query(By.css('.adf-dropdown-required-message .adf-error-text')); + expect(requiredErrorElement).toBeFalsy(); + const restApiFailedElement = getErrorMessageElement(); + expect(restApiFailedElement).toBeTruthy(); }); it('should NOT show error message when widget is readonly', async () => { @@ -268,6 +286,21 @@ describe('DropdownCloudWidgetComponent', () => { const errorsMessagesElement = fixture.debugElement.query(By.css('.adf-error-messages-container')); expect(errorsMessagesElement.nativeElement.classList.contains('adf-error-messages-container-hidden')).toBe(true); }); + + it('should NOT show REST API failed error message when form is in preview state', () => { + widget.field.readOnly = false; + spyOn(formCloudService, 'getPreviewState').and.returnValue(true); + + widget.ngOnInit(); + fixture.detectChanges(); + + expect(getRestWidgetDataSpy).toHaveBeenCalled(); + expect(widget.isRestApiFailed).toBe(true); + expect(widget.field.options.length).toEqual(0); + + const failedErrorMsgElement = getErrorMessageElement(); + expect(failedErrorMsgElement).toBeNull(); + }); }); it('should preselect dropdown widget value when Json (rest call) passed', async () => { @@ -405,6 +438,9 @@ describe('DropdownCloudWidgetComponent', () => { expect(element.querySelector('.adf-invalid')).toBeTruthy(); + const errorsMessagesElement = fixture.debugElement.query(By.css('.adf-error-messages-container')); + expect(errorsMessagesElement.nativeElement.classList.contains('adf-error-messages-container-visible')).toBe(true); + const requiredErrorElement = fixture.debugElement.query(By.css('.adf-dropdown-required-message .adf-error-text')); expect(requiredErrorElement.nativeElement.innerText).toEqual('FORM.FIELD.REQUIRED'); }); @@ -1158,6 +1194,24 @@ describe('DropdownCloudWidgetComponent', () => { checkDropdownVariableOptionsFailed(); }); + it('should NOT show required message when variable options failed', () => { + widget.field = getVariableDropdownWidget( + 'variables.json-variable', + 'response.wrongPath.players', + 'playerId', + 'playerFullName', + mockProcessVariablesWithJson + ); + widget.field.required = true; + fixture.detectChanges(); + + expect(widget.variableOptionsFailed).toBe(true); + const requiredErrorElement = fixture.debugElement.query(By.css('.adf-dropdown-required-message .adf-error-text')); + expect(requiredErrorElement).toBeFalsy(); + const variableFailedElement = fixture.debugElement.query(By.css('.adf-dropdown-failed-message')); + expect(variableFailedElement).toBeTruthy(); + }); + it('should return empty array and display error when id is incorrect', () => { widget.field = getVariableDropdownWidget( 'variables.json-variable', @@ -1204,7 +1258,7 @@ describe('DropdownCloudWidgetComponent', () => { checkDropdownVariableOptionsFailed(); }); - it('should NOT display errors if form is in the preview state', () => { + it('should NOT display variable options failed error when form is in the preview state', () => { widget.field = getVariableDropdownWidget( 'variables.json-variable', 'response.wrongPath.players', @@ -1215,8 +1269,8 @@ describe('DropdownCloudWidgetComponent', () => { spyOn(formCloudService, 'getPreviewState').and.returnValue(true); fixture.detectChanges(); - const errorsMessagesElement = fixture.debugElement.query(By.css('.adf-error-messages-container')); - expect(errorsMessagesElement.nativeElement.classList.contains('adf-error-messages-container-hidden')).toBe(true); + const failedErrorMsgElement = fixture.debugElement.query(By.css('.adf-dropdown-failed-message')); + expect(failedErrorMsgElement).toBeNull(); }); it('should NOT display errors if field is readonly', () => { diff --git a/lib/process-services-cloud/src/lib/form/components/widgets/dropdown/dropdown-cloud.widget.ts b/lib/process-services-cloud/src/lib/form/components/widgets/dropdown/dropdown-cloud.widget.ts index 3eb04db352..e1d22ce633 100644 --- a/lib/process-services-cloud/src/lib/form/components/widgets/dropdown/dropdown-cloud.widget.ts +++ b/lib/process-services-cloud/src/lib/form/components/widgets/dropdown/dropdown-cloud.widget.ts @@ -29,7 +29,7 @@ import { SelectFilterInputComponent, WidgetComponent } from '@alfresco/adf-core'; -import { AsyncPipe, NgClass, NgIf } from '@angular/common'; +import { AsyncPipe, NgClass } from '@angular/common'; import { Component, DestroyRef, inject, OnInit, ViewEncapsulation } from '@angular/core'; import { FormControl, ReactiveFormsModule, Validators } from '@angular/forms'; import { MatFormFieldModule } from '@angular/material/form-field'; @@ -61,7 +61,6 @@ export const DROPDOWN_CLOUD_WIDGET_SET_VALUE_DEBOUNCE = 100; }, encapsulation: ViewEncapsulation.None, imports: [ - NgIf, NgClass, AsyncPipe, ReactiveFormsModule,