diff --git a/lib/process-services-cloud/src/lib/form/components/widgets/radio-buttons/radio-buttons-cloud.widget.html b/lib/process-services-cloud/src/lib/form/components/widgets/radio-buttons/radio-buttons-cloud.widget.html index 63877833a7..4342d734a0 100644 --- a/lib/process-services-cloud/src/lib/form/components/widgets/radio-buttons/radio-buttons-cloud.widget.html +++ b/lib/process-services-cloud/src/lib/form/components/widgets/radio-buttons/radio-buttons-cloud.widget.html @@ -18,5 +18,5 @@ - + diff --git a/lib/process-services-cloud/src/lib/form/components/widgets/radio-buttons/radio-buttons-cloud.widget.scss b/lib/process-services-cloud/src/lib/form/components/widgets/radio-buttons/radio-buttons-cloud.widget.scss index c56a304ee3..5779428960 100644 --- a/lib/process-services-cloud/src/lib/form/components/widgets/radio-buttons/radio-buttons-cloud.widget.scss +++ b/lib/process-services-cloud/src/lib/form/components/widgets/radio-buttons/radio-buttons-cloud.widget.scss @@ -28,4 +28,8 @@ &-radio-button { margin: 5px; } + + &-radio-group-error-message .adf-error-container { + margin-top: 5px; + } } diff --git a/lib/process-services-cloud/src/lib/form/components/widgets/radio-buttons/radio-buttons-cloud.widget.spec.ts b/lib/process-services-cloud/src/lib/form/components/widgets/radio-buttons/radio-buttons-cloud.widget.spec.ts index 21a3c79479..fc1d6d4ee8 100644 --- a/lib/process-services-cloud/src/lib/form/components/widgets/radio-buttons/radio-buttons-cloud.widget.spec.ts +++ b/lib/process-services-cloud/src/lib/form/components/widgets/radio-buttons/radio-buttons-cloud.widget.spec.ts @@ -21,7 +21,7 @@ import { FormFieldModel, FormFieldOption, FormFieldTypes, FormModel, setupTestBe import { FormCloudService } from '../../../services/form-cloud.service'; import { RadioButtonsCloudWidgetComponent } from './radio-buttons-cloud.widget'; import { ProcessServiceCloudTestingModule } from '../../../../testing/process-service-cloud.testing.module'; -import { of } from 'rxjs'; +import { of, throwError } from 'rxjs'; describe('RadioButtonsCloudWidgetComponent', () => { let fixture: ComponentFixture; @@ -48,7 +48,6 @@ describe('RadioButtonsCloudWidgetComponent', () => { beforeEach(() => { formCloudService = TestBed.inject(FormCloudService); - spyOn(formCloudService, 'getRestWidgetData').and.returnValue(of(restOption)); fixture = TestBed.createComponent(RadioButtonsCloudWidgetComponent); widget = fixture.componentInstance; element = fixture.nativeElement; @@ -56,6 +55,7 @@ describe('RadioButtonsCloudWidgetComponent', () => { }); it('should update form on values fetched', () => { + spyOn(formCloudService, 'getRestWidgetData').and.returnValue(of(restOption)); const taskId = ''; const fieldId = ''; @@ -70,7 +70,7 @@ describe('RadioButtonsCloudWidgetComponent', () => { const field = widget.field; spyOn(field, 'updateForm').and.stub(); - widget.ngOnInit(); + fixture.detectChanges(); expect(field.updateForm).toHaveBeenCalled(); }); @@ -155,6 +155,7 @@ describe('RadioButtonsCloudWidgetComponent', () => { }); it('should be able to set a Radio Button widget when rest option enabled', () => { + spyOn(formCloudService, 'getRestWidgetData').and.returnValue(of(restOption)); widget.field = new FormFieldModel(new FormModel({}), { id: 'radio-id', name: 'radio-name-label', @@ -172,4 +173,22 @@ describe('RadioButtonsCloudWidgetComponent', () => { expect(selectedOption.innerText).toBe('opt-name-1'); expect(widget.field.isValid).toBe(true); }); + + it('should show error message if the restUrl failed to fetch options', () => { + spyOn(formCloudService, 'getRestWidgetData').and.returnValue(throwError('Failed to fetch options')); + widget.field.restUrl = 'https://fake-rest-url'; + widget.field.optionType = 'rest'; + widget.field.restIdProperty = 'name'; + fixture.detectChanges(); + + const radioButtons = element.querySelector('mat-radio-group'); + radioButtons.click(); + fixture.detectChanges(); + + const errorMessage = element.querySelector('.adf-radio-group-error-message .adf-error-text'); + const errorIcon = element.querySelector('.adf-radio-group-error-message .adf-error-icon'); + + expect(errorIcon.textContent).toBe('error_outline'); + expect(errorMessage.textContent).toBe('FORM.FIELD.REST_API_FAILED'); + }); }); diff --git a/lib/process-services-cloud/src/lib/form/components/widgets/radio-buttons/radio-buttons-cloud.widget.ts b/lib/process-services-cloud/src/lib/form/components/widgets/radio-buttons/radio-buttons-cloud.widget.ts index d49e104e13..7d5093bd5b 100644 --- a/lib/process-services-cloud/src/lib/form/components/widgets/radio-buttons/radio-buttons-cloud.widget.ts +++ b/lib/process-services-cloud/src/lib/form/components/widgets/radio-buttons/radio-buttons-cloud.widget.ts @@ -18,10 +18,11 @@ /* eslint-disable @angular-eslint/component-selector */ import { Component, OnInit, ViewEncapsulation } from '@angular/core'; -import { WidgetComponent, FormService, LogService, FormFieldOption } from '@alfresco/adf-core'; +import { WidgetComponent, FormService, LogService, FormFieldOption, ErrorMessageModel } from '@alfresco/adf-core'; import { FormCloudService } from '../../../services/form-cloud.service'; import { Subject } from 'rxjs'; import { takeUntil } from 'rxjs/operators'; +import { TranslateService } from '@ngx-translate/core'; @Component({ selector: 'radio-buttons-cloud-widget', @@ -43,11 +44,14 @@ import { takeUntil } from 'rxjs/operators'; export class RadioButtonsCloudWidgetComponent extends WidgetComponent implements OnInit { typeId = 'RadioButtonsCloudWidgetComponent'; + restApiError: ErrorMessageModel; + protected onDestroy$ = new Subject(); constructor(public formService: FormService, private formCloudService: FormCloudService, - private logService: LogService) { + private logService: LogService, + private translateService: TranslateService) { super(formService); } @@ -63,7 +67,10 @@ export class RadioButtonsCloudWidgetComponent extends WidgetComponent implements .subscribe((result: FormFieldOption[]) => { this.field.options = result; this.field.updateForm(); - }, (err) => this.handleError(err)); + }, (err) => { + this.resetRestApiOptions(); + this.handleError(err); + }); } onOptionClick(optionSelected: any) { @@ -72,6 +79,7 @@ export class RadioButtonsCloudWidgetComponent extends WidgetComponent implements } handleError(error: any) { + this.restApiError = new ErrorMessageModel({ message: this.translateService.instant('FORM.FIELD.REST_API_FAILED', { hostname: this.getRestUrlHostName() }) }); this.logService.error(error); } @@ -87,4 +95,16 @@ export class RadioButtonsCloudWidgetComponent extends WidgetComponent implements } return this.field.value === option.id; } + + resetRestApiOptions() { + this.field.options = []; + } + + getRestUrlHostName(): string { + return new URL(this.field?.restUrl).hostname ?? this.field?.restUrl; + } + + hasError(): ErrorMessageModel { + return this.restApiError || this.field.validationSummary; + } }