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 a38c6f0383..27fe1892fb 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
@@ -30,7 +30,7 @@
{{field.value}}
-
+
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 170e36a45a..c8809b5a60 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
@@ -37,6 +37,7 @@ import { HarnessLoader } from '@angular/cdk/testing';
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
import { MatSelectHarness } from '@angular/material/select/testing';
import { MatFormFieldHarness } from '@angular/material/form-field/testing';
+import { DebugElement } from '@angular/core';
describe('DropdownCloudWidgetComponent', () => {
let formService: FormService;
@@ -118,35 +119,79 @@ describe('DropdownCloudWidgetComponent', () => {
expect(await allOptions[2].getText()).toEqual('option_3');
});
- it('should NOT load data from restUrl when field is readonly', () => {
+ it('should NOT load data from restUrl when form is readonly', () => {
spyOn(formCloudService, 'getRestWidgetData');
- widget.field.readOnly = true;
+ widget.field.readOnly = false;
widget.field.restUrl = 'https://fake-rest-url';
widget.field.optionType = 'rest';
- widget.field.restIdProperty = 'name';
+ widget.field.form.readOnly = true;
widget.ngOnInit();
expect(formCloudService.getRestWidgetData).not.toHaveBeenCalled();
});
- it('should show error message if the restUrl failed to fetch options', async () => {
- const jsonDataSpy = spyOn(formCloudService, 'getRestWidgetData').and.returnValue(throwError('Failed to fetch options'));
+ describe('should load data from restUrl when form is NOT readonly', () => {
+ beforeEach(() => {
+ spyOn(formCloudService, 'getRestWidgetData').and.returnValue(of([]));
+
+ widget.field.restUrl = 'https://fake-rest-url';
+ widget.field.optionType = 'rest';
+ widget.field.restIdProperty = 'name';
+ widget.field.form.readOnly = false;
+ });
+
+ it('when widget is NOT readonly', () => {
+ widget.field.readOnly = false;
+ widget.ngOnInit();
+
+ expect(formCloudService.getRestWidgetData).toHaveBeenCalled();
+ });
+
+ it('when widget is readonly', () => {
+ widget.field.readOnly = true;
+ widget.ngOnInit();
+
+ expect(formCloudService.getRestWidgetData).toHaveBeenCalled();
+ });
+ });
+
+ describe('when failed on loading options from restUrl', () => {
+ let getRestWidgetDataSpy: jasmine.Spy;
+ const getErrorMessageElement = (): DebugElement => fixture.debugElement.query(By.css('.adf-dropdown-failed-message'));
const errorIcon: string = 'error_outline';
- widget.field.restUrl = 'https://fake-rest-url';
- widget.field.optionType = 'rest';
- widget.field.restIdProperty = 'name';
- widget.ngOnInit();
+ beforeEach(() => {
+ getRestWidgetDataSpy = spyOn(formCloudService, 'getRestWidgetData').and.returnValue(throwError('Failed to fetch options'));
+ widget.field.restUrl = 'https://fake-rest-url';
+ widget.field.optionType = 'rest';
+ });
- const dropdown = await loader.getHarness(MatSelectHarness.with({ selector: '.adf-select' }));
- await dropdown.open();
+ it('should show error message when widget is NOT readonly', () => {
+ widget.field.readOnly = false;
- const failedErrorMsgElement = fixture.debugElement.query(By.css('.adf-dropdown-failed-message'));
- expect(jsonDataSpy).toHaveBeenCalled();
- expect(widget.isRestApiFailed).toBe(true);
- expect(widget.field.options.length).toEqual(0);
- expect(failedErrorMsgElement.nativeElement.textContent.trim()).toBe(errorIcon + 'FORM.FIELD.REST_API_FAILED');
+ widget.ngOnInit();
+ fixture.detectChanges();
+
+ const errorMessageElement = getErrorMessageElement();
+ expect(getRestWidgetDataSpy).toHaveBeenCalled();
+ expect(widget.isRestApiFailed).toBe(true);
+ expect(widget.field.options.length).toEqual(0);
+ expect(errorMessageElement.nativeElement.textContent.trim()).toBe(errorIcon + 'FORM.FIELD.REST_API_FAILED');
+ });
+
+ it('should NOT show error message when widget is readonly', async () => {
+ widget.field.readOnly = true;
+
+ widget.ngOnInit();
+ fixture.detectChanges();
+
+ const errorMessageElement = getErrorMessageElement();
+ expect(getRestWidgetDataSpy).toHaveBeenCalled();
+ expect(widget.isRestApiFailed).toBe(true);
+ expect(widget.field.options.length).toEqual(0);
+ expect(errorMessageElement).toBe(null);
+ });
});
it('should preselect dropdown widget value when Json (rest call) passed', async () => {
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 3b852b85ad..ad027d2716 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
@@ -84,7 +84,7 @@ export class DropdownCloudWidgetComponent extends WidgetComponent implements OnI
private checkFieldOptionsSource(): void {
switch (true) {
- case this.isReadOnly():
+ case this.isReadOnlyForm():
break;
case this.hasRestUrl() && !this.isLinkedWidget():
this.persistFieldOptionsFromRestApi();
@@ -392,7 +392,11 @@ export class DropdownCloudWidgetComponent extends WidgetComponent implements OnI
}
}
- private isReadOnly(): boolean {
+ private isReadOnlyForm(): boolean {
+ return !!this.field?.form?.readOnly;
+ }
+
+ get isReadOnlyField(): boolean {
return this.field.readOnly;
}
@@ -410,7 +414,7 @@ export class DropdownCloudWidgetComponent extends WidgetComponent implements OnI
}
updateOptions(): void {
- if (this.isReadOnly()) {
+ if (this.isReadOnlyForm()) {
this.list$ = of(this.field.options);
}
diff --git a/lib/process-services/src/lib/form/widgets/dropdown/dropdown.widget.html b/lib/process-services/src/lib/form/widgets/dropdown/dropdown.widget.html
index c77a1db3e9..42d22640f0 100644
--- a/lib/process-services/src/lib/form/widgets/dropdown/dropdown.widget.html
+++ b/lib/process-services/src/lib/form/widgets/dropdown/dropdown.widget.html
@@ -15,7 +15,9 @@
{{field.value}}
-
-
+
+
+
diff --git a/lib/process-services/src/lib/form/widgets/dropdown/dropdown.widget.spec.ts b/lib/process-services/src/lib/form/widgets/dropdown/dropdown.widget.spec.ts
index 08047fa2cf..e7ae7ee817 100644
--- a/lib/process-services/src/lib/form/widgets/dropdown/dropdown.widget.spec.ts
+++ b/lib/process-services/src/lib/form/widgets/dropdown/dropdown.widget.spec.ts
@@ -17,7 +17,15 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { Observable, of } from 'rxjs';
-import { WidgetVisibilityService, FormFieldOption, FormFieldModel, FormModel, FormFieldTypes, CoreTestingModule } from '@alfresco/adf-core';
+import {
+ WidgetVisibilityService,
+ FormFieldOption,
+ FormFieldModel,
+ FormModel,
+ FormFieldTypes,
+ CoreTestingModule,
+ ErrorMessageModel
+} from '@alfresco/adf-core';
import { DropdownWidgetComponent } from './dropdown.widget';
import { TaskFormService } from '../../services/task-form.service';
import { ProcessDefinitionService } from '../../services/process-definition.service';
@@ -66,27 +74,40 @@ describe('DropdownWidgetComponent', () => {
expect(taskFormService.getRestFieldValues).not.toHaveBeenCalled();
});
- it('should request field values from service', () => {
+ describe('requesting field options', () => {
+ let getRestFieldValuesSpy: jasmine.Spy;
const taskId = '
';
const fieldId = '';
- const form = new FormModel({
- taskId
+ beforeEach(() => {
+ getRestFieldValuesSpy = spyOn(taskFormService, 'getRestFieldValues').and.returnValue(of([]));
+
+ widget.field = new FormFieldModel(new FormModel({ taskId }), { id: fieldId, restUrl: '' });
});
- widget.field = new FormFieldModel(form, {
- id: fieldId,
- restUrl: ''
+ it('should request options from service when form is NOT readonly', () => {
+ widget.field.form.readOnly = false;
+ widget.ngOnInit();
+
+ expect(getRestFieldValuesSpy).toHaveBeenCalledWith(taskId, fieldId);
});
- spyOn(taskFormService, 'getRestFieldValues').and.returnValue(
- new Observable((observer) => {
- observer.next(null);
- observer.complete();
- })
- );
+ it('should NOT request options from service when form is readonly', () => {
+ widget.field.form.readOnly = true;
+ widget.ngOnInit();
+
+ expect(getRestFieldValuesSpy).not.toHaveBeenCalled();
+ });
+ });
+
+ it('should NOT display any error when widget is readonly', () => {
+ widget.field = new FormFieldModel(new FormModel({}, undefined, false), { readOnly: true });
+ widget.field.validationSummary = { message: 'Some error occurred' } as ErrorMessageModel;
+
widget.ngOnInit();
- expect(taskFormService.getRestFieldValues).toHaveBeenCalledWith(taskId, fieldId);
+ fixture.detectChanges();
+
+ expect(element.querySelector('.adf-dropdown-required-message')).toBeNull();
});
it('should preserve empty option when loading fields', () => {
diff --git a/lib/process-services/src/lib/form/widgets/dropdown/dropdown.widget.ts b/lib/process-services/src/lib/form/widgets/dropdown/dropdown.widget.ts
index 47d578dbbb..b3886ee4a4 100644
--- a/lib/process-services/src/lib/form/widgets/dropdown/dropdown.widget.ts
+++ b/lib/process-services/src/lib/form/widgets/dropdown/dropdown.widget.ts
@@ -52,7 +52,7 @@ export class DropdownWidgetComponent extends WidgetComponent implements OnInit {
}
ngOnInit() {
- if (this.field?.restUrl) {
+ if (this.field?.restUrl && !this.isReadOnlyForm()) {
if (this.field.form.taskId) {
this.getValuesByTaskId();
} else {
@@ -102,4 +102,12 @@ export class DropdownWidgetComponent extends WidgetComponent implements OnInit {
showRequiredMessage(): boolean {
return (this.isInvalidFieldRequired() || this.field.value === 'empty') && this.isTouched();
}
+
+ get isReadOnlyField(): boolean {
+ return this.field.readOnly;
+ }
+
+ private isReadOnlyForm(): boolean {
+ return !!this.field?.form?.readOnly;
+ }
}