From cb0b072b1e1b310f4902f297cfe8ffa7db359377 Mon Sep 17 00:00:00 2001 From: Wiktor Danielewski <63188869+wiktord2000@users.noreply.github.com> Date: Tue, 6 Aug 2024 15:38:21 +0200 Subject: [PATCH] AAE-24007 Display radio buttons and dropdown options depending on optionType (#9975) * AAE-24007 Update form-field.moel * AAE-24007 Update dropdown-cloud.widget * AAE-24007 Update radio-buttons-cloud.widget * AAE-24007 Dropdown aligment (undefined value should be reserved for empty option) * AAE-24007 Minor update * AAE-24007 Update tests * AAE-24007 Update * AAE-24007 Update * AAE-24007 Update * AAE-24007 Fix units * AAE-24007 Fix * AAE-24007 Align standard dropdown and radio --- .../widgets/core/form-field.model.spec.ts | 254 ++++++++++-------- .../widgets/core/form-field.model.ts | 23 +- .../dropdown/dropdown-cloud.widget.spec.ts | 14 +- .../widgets/dropdown/dropdown-cloud.widget.ts | 17 +- .../radio-buttons-cloud.widget.spec.ts | 18 ++ .../radio-buttons-cloud.widget.ts | 18 +- .../widgets/dropdown/dropdown.widget.spec.ts | 16 +- .../form/widgets/dropdown/dropdown.widget.ts | 14 +- .../radio-buttons.widget.spec.ts | 17 +- .../radio-buttons/radio-buttons.widget.ts | 18 +- 10 files changed, 267 insertions(+), 142 deletions(-) diff --git a/lib/core/src/lib/form/components/widgets/core/form-field.model.spec.ts b/lib/core/src/lib/form/components/widgets/core/form-field.model.spec.ts index 044facefa4..8b6eaa6ba3 100644 --- a/lib/core/src/lib/form/components/widgets/core/form-field.model.spec.ts +++ b/lib/core/src/lib/form/components/widgets/core/form-field.model.spec.ts @@ -112,6 +112,31 @@ describe('FormFieldModel', () => { expect(field.readOnly).toBeTruthy(); }); + describe('option type property', () => { + const staticOptions = [ + { id: 'op1', name: 'Option 1' }, + { id: 'op2', name: 'Option 2' } + ]; + + it('should assign static options array to options in case of manual type', () => { + const field = new FormFieldModel(new FormModel(), { + optionType: 'manual', + options: staticOptions + }); + + expect(field.options).toEqual(staticOptions); + }); + + it('should assign empty array to options in case of rest type', () => { + const field = new FormFieldModel(new FormModel(), { + optionType: 'rest', + options: staticOptions + }); + + expect(field.options).toEqual([]); + }); + }); + describe('dropdown field model instantiation', () => { it('should add value (selected option) to field options if NOT present', () => { const field = new FormFieldModel(new FormModel(), { @@ -137,7 +162,6 @@ describe('FormFieldModel', () => { }); expect(field.options).toEqual(selectedOptions); - expect(field.value).toEqual(selectedOptions); }); it('should assign "empty" option as value if value is null and "empty" option is present in options', () => { @@ -532,7 +556,7 @@ describe('FormFieldModel', () => { expect(field.value).toBeFalsy(); }); - it('should return the label of selected dropdown value ', () => { + it('should return the label of selected dropdown value', () => { const field = new FormFieldModel(new FormModel(), { type: FormFieldTypes.DROPDOWN, options: [ @@ -702,15 +726,19 @@ describe('FormFieldModel', () => { id: 'rest-radio', type: FormFieldTypes.RADIO_BUTTONS, optionType: 'rest', - options: [ - { id: 'restOpt1', name: 'Rest Option 1' }, - { id: 'restOpt2', name: 'Rest Option 2' } - ] + restUrl: 'fake-url', + options: [] }); + + field.options = [ + { id: 'restOpt1', name: 'Rest Option 1' }, + { id: 'restOpt2', name: 'Rest Option 2' } + ]; }); it('should update form with selected option and options from which we chose', () => { field.value = 'restOpt2'; + field.updateForm(); expect(form.values['rest-radio']).toEqual({ id: 'restOpt2', @@ -722,6 +750,7 @@ describe('FormFieldModel', () => { describe('should update form with selected option properties set to null and options from which we chose', () => { it('when value does NOT match any option', () => { field.value = 'not_exist'; + field.updateForm(); expect(form.values['rest-radio']).toEqual({ id: null, @@ -732,6 +761,7 @@ describe('FormFieldModel', () => { it('when radio button value is null', () => { field.value = null; + field.updateForm(); expect(form.values['rest-radio']).toEqual({ id: null, @@ -863,115 +893,123 @@ describe('FormFieldModel', () => { expect(form.values['header_field']).not.toBeDefined(); }); - it('dropdown field type should appear into form values', () => { - const form = new FormModel(); - const field = new FormFieldModel(form, { - fieldType: 'HeaderFieldtype', - id: 'dropdown_field', - name: 'header', - type: FormFieldTypes.DROPDOWN, - value: 'opt1', - required: false, - readOnly: true, - options: [ - { id: 'opt1', name: 'Option 1' }, - { id: 'opt2', name: 'Option 2' } - ] + describe('dropdown field', () => { + const getFieldConfig = (optionType, options, value) => + new FormFieldModel(new FormModel(), { + id: 'dropdown_field', + name: 'dropdown', + type: FormFieldTypes.DROPDOWN, + optionType, + options, + value, + required: false, + restUrl: 'fake-url', + restIdProperty: 'fake-id-property', + restLabelProperty: 'fake-label-property', + restResponsePath: 'fake-response-path' + }); + + const staticOptions = [ + { id: 'opt1', name: 'Option 1' }, + { id: 'opt2', name: 'Option 2' } + ]; + + it('should assign rest properties properly', () => { + const field = getFieldConfig('rest', [], 'delayed-rest-option-id'); + + field.updateForm(); + + expect(field.value).toEqual('delayed-rest-option-id'); + expect(field.form.values['dropdown_field']).toEqual(null); + expect(field.restUrl).toEqual('fake-url'); + expect(field.restIdProperty).toEqual('fake-id-property'); + expect(field.restLabelProperty).toEqual('fake-label-property'); + expect(field.restResponsePath).toEqual('fake-response-path'); + }); + + it('should NOT consider the static list of options in case of rest type', () => { + const field = getFieldConfig('rest', staticOptions, 'delayed-rest-option-id'); + + field.updateForm(); + + expect(field.value).toEqual('delayed-rest-option-id'); + expect(field.form.values['dropdown_field']).toEqual(null); + expect(field.options).toEqual([]); + }); + + it('should consider the static list of options in case of manual type', () => { + const field = getFieldConfig('manual', staticOptions, ''); + + field.updateForm(); + + expect(field.value).toEqual(''); + expect(field.form.values['dropdown_field']).toEqual(null); + expect(field.options).toEqual(staticOptions); + }); + + it('should selected option appear in form values', () => { + const field = getFieldConfig('manual', staticOptions, 'opt2'); + + field.updateForm(); + + expect(field.value).toEqual('opt2'); + expect(field.form.values['dropdown_field']).toEqual({ id: 'opt2', name: 'Option 2' }); }); - field.updateForm(); - expect(form.values['dropdown_field'].name).toEqual('Option 1'); }); - it('dropdown field type should be formatted on rest properties', () => { - const form = new FormModel(); - const field = new FormFieldModel(form, { - fieldType: 'HeaderFieldtype', - id: 'dropdown_field', - name: 'header', - type: FormFieldTypes.DROPDOWN, - value: 'opt1', - required: false, - readOnly: true, - restUrl: 'fake-url-just-to-show', - optionType: 'rest', - restIdProperty: 'fake-id-property', - restLabelProperty: 'fake-label-property', - options: [ - { id: 'opt1', name: 'Option 1' }, - { id: 'opt2', name: 'Option 2' } - ] - }); - field.updateForm(); - expect(form.values['dropdown_field'].id).toEqual('opt1'); - expect(form.values['dropdown_field'].name).toEqual('Option 1'); - }); + describe('radio buttons field', () => { + const getFieldConfig = (optionType, options, value) => + new FormFieldModel(new FormModel(), { + id: 'radio_field', + name: 'radio', + type: FormFieldTypes.RADIO_BUTTONS, + optionType, + options, + value, + required: false, + restUrl: 'fake-url', + restIdProperty: 'fake-id-property', + restLabelProperty: 'fake-label-property', + restResponsePath: 'fake-response-path' + }); - it('dropdown field type should be formatted on id and name properties if rest properties are not set', () => { - const form = new FormModel(); - const field = new FormFieldModel(form, { - fieldType: 'HeaderFieldtype', - id: 'dropdown_field', - name: 'header', - type: FormFieldTypes.DROPDOWN, - value: 'opt1', - required: false, - readOnly: true, - restUrl: 'fake-url-just-to-show', - optionType: 'rest', - options: [ - { id: 'opt1', name: 'Option 1' }, - { id: 'opt2', name: 'Option 2' } - ] - }); - field.updateForm(); - expect(form.values['dropdown_field']['id']).toEqual('opt1'); - expect(form.values['dropdown_field']['name']).toEqual('Option 1'); - }); + const staticOptions = [ + { id: 'opt1', name: 'Option 1' }, + { id: 'opt2', name: 'Option 2' } + ]; - it('radio button field rest type should appear with its configured label and id into the rest values', () => { - const form = new FormModel(); - const field = new FormFieldModel(form, { - fieldType: 'HeaderFieldtype', - id: 'radio_bananan_field', - name: 'banana', - type: FormFieldTypes.RADIO_BUTTONS, - value: 'opt1', - required: false, - readOnly: true, - restUrl: '', - restIdProperty: 'banana', - restLabelProperty: 'banLabel', - optionType: 'rest', - options: [ - { id: 'opt1', name: 'Option 1' }, - { id: 'opt2', name: 'Option 2' } - ] - }); - field.updateForm(); - expect(form.values['radio_bananan_field'].id).toEqual('opt1'); - expect(form.values['radio_bananan_field'].name).toEqual('Option 1'); - }); + it('should assign rest properties properly', () => { + const field = getFieldConfig('rest', [], 'delayed-rest-option-id'); - it('radio button field rest type should appear with id / name properties when rest properties are not configured', () => { - const form = new FormModel(); - const field = new FormFieldModel(form, { - fieldType: 'HeaderFieldtype', - id: 'radio_bananan_field', - name: 'banana', - type: FormFieldTypes.RADIO_BUTTONS, - value: 'opt1', - required: false, - readOnly: true, - restUrl: '', - optionType: 'rest', - options: [ - { id: 'opt1', name: 'Option 1' }, - { id: 'opt2', name: 'Option 2' } - ] + field.updateForm(); + + expect(field.value).toEqual('delayed-rest-option-id'); + expect(field.form.values['radio_field']).toEqual({ id: null, name: null, options: [] }); + expect(field.restUrl).toEqual('fake-url'); + expect(field.restIdProperty).toEqual('fake-id-property'); + expect(field.restLabelProperty).toEqual('fake-label-property'); + expect(field.restResponsePath).toEqual('fake-response-path'); + }); + + it('should NOT consider the static list of options in case of rest type', () => { + const field = getFieldConfig('rest', staticOptions, 'delayed-rest-option-id'); + + field.updateForm(); + + expect(field.value).toEqual('delayed-rest-option-id'); + expect(field.form.values['radio_field']).toEqual({ id: null, name: null, options: [] }); + expect(field.options).toEqual([]); + }); + + it('should consider the static list of options in case of manual type', () => { + const field = getFieldConfig('manual', staticOptions, 'opt1'); + + field.updateForm(); + + expect(field.value).toEqual('opt1'); + expect(field.form.values['radio_field']).toEqual({ id: 'opt1', name: 'Option 1' }); + expect(field.options).toEqual(staticOptions); }); - field.updateForm(); - expect(form.values['radio_bananan_field']['id']).toEqual('opt1'); - expect(form.values['radio_bananan_field']['name']).toEqual('Option 1'); }); it('should parse and resolve people null value as null', () => { diff --git a/lib/core/src/lib/form/components/widgets/core/form-field.model.ts b/lib/core/src/lib/form/components/widgets/core/form-field.model.ts index e32b3e93bd..5d0ab7865a 100644 --- a/lib/core/src/lib/form/components/widgets/core/form-field.model.ts +++ b/lib/core/src/lib/form/components/widgets/core/form-field.model.ts @@ -31,6 +31,10 @@ import { DataColumn } from '../../../../datatable/data/data-column.model'; import { DateFnsUtils } from '../../../../common'; import { isValid as isValidDate } from 'date-fns'; +export type FieldOptionType = 'rest' | 'manual' | 'variable'; +export type FieldSelectionType = 'single' | 'multiple'; +export type FieldAlignmentType = 'vertical' | 'horizontal'; + // Maps to FormFieldRepresentation export class FormFieldModel extends FormWidgetModel { private _value: string; @@ -71,7 +75,7 @@ export class FormFieldModel extends FormWidgetModel { restLabelProperty: string; hasEmptyValue: boolean; className: string; - optionType: 'rest' | 'manual' | 'variable'; + optionType: FieldOptionType; params: FormFieldMetadata = {}; hyperlinkUrl: string; displayText: string; @@ -80,8 +84,8 @@ export class FormFieldModel extends FormWidgetModel { enableFractions: boolean = false; currency: string = null; dateDisplayFormat: string = this.defaultDateFormat; - selectionType: 'single' | 'multiple' = null; - alignmentType: 'vertical' | 'horizontal' = null; + selectionType: FieldSelectionType; + alignmentType: FieldAlignmentType; rule?: FormFieldRule; selectLoggedUser: boolean; groupsRestriction: string[]; @@ -193,7 +197,7 @@ export class FormFieldModel extends FormWidgetModel { this.maxDateRangeValue = json.maxDateRangeValue; this.dynamicDateRangeSelection = json.dynamicDateRangeSelection; this.regexPattern = json.regexPattern; - this.options = this.parseValidOptions(json.options); + this.options = this.parseOptions(json.options, json.optionType); this.emptyOption = this.getEmptyOption(this.options); this.hasEmptyValue = json?.hasEmptyValue ?? !!this.emptyOption; this.className = json.className; @@ -422,10 +426,9 @@ export class FormFieldModel extends FormWidgetModel { break; } - const entry: FormFieldOption[] = this.options.filter((opt) => opt.id === this.value); - if (entry.length > 0) { - this.form.values[this.id] = entry[0]; - } + const matchingOption: FormFieldOption = this.options.find((opt) => opt.id === this.value); + + this.form.values[this.id] = matchingOption || null; } break; } @@ -567,6 +570,10 @@ export class FormFieldModel extends FormWidgetModel { return Array.isArray(options) ? options.filter((option) => this.isValidOption(option)) : []; } + private parseOptions(options: any, optionType: FieldOptionType): FormFieldOption[] { + return optionType === 'rest' ? [] : this.parseValidOptions(options); + } + private isValidOption(option: any): boolean { return typeof option === 'object' && !Array.isArray(option) && option?.id && option?.name; } 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 c8809b5a60..f0b6dbba82 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 @@ -75,15 +75,21 @@ describe('DropdownCloudWidgetComponent', () => { fixture.detectChanges(); }); - it('should require field with restUrl', () => { - spyOn(formCloudService, 'getRestWidgetData'); - widget.field = new FormFieldModel(new FormModel()); + it('should call rest api only when url is present and field type is rest', () => { + const getFieldConfig = (optionType: string, restUrl: string) => new FormFieldModel(new FormModel(), { optionType, restUrl }); + spyOn(formCloudService, 'getRestWidgetData').and.returnValue(of(fakeOptionList)); + + widget.field = getFieldConfig('manual', 'fake-rest-url'); widget.ngOnInit(); expect(formCloudService.getRestWidgetData).not.toHaveBeenCalled(); - widget.field = new FormFieldModel(null, { restUrl: null }); + widget.field = getFieldConfig('rest', null); widget.ngOnInit(); expect(formCloudService.getRestWidgetData).not.toHaveBeenCalled(); + + widget.field = getFieldConfig('rest', 'fake-rest-url'); + widget.ngOnInit(); + expect(formCloudService.getRestWidgetData).toHaveBeenCalled(); }); it('should select the default value when an option is chosen as default', 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 ad027d2716..2a1b147b71 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 @@ -86,7 +86,8 @@ export class DropdownCloudWidgetComponent extends WidgetComponent implements OnI switch (true) { case this.isReadOnlyForm(): break; - case this.hasRestUrl() && !this.isLinkedWidget(): + + case this.isValidRestConfig() && !this.isLinkedWidget(): this.persistFieldOptionsFromRestApi(); break; @@ -192,8 +193,12 @@ export class DropdownCloudWidgetComponent extends WidgetComponent implements OnI return this.field?.optionType === 'variable'; } + private isRestOptionType(): boolean { + return this.field?.optionType === 'rest'; + } + private persistFieldOptionsFromRestApi() { - if (this.isValidRestType()) { + if (this.isValidRestConfig()) { this.resetRestApiErrorMessage(); const bodyParam = this.buildBodyParam(); this.formCloudService @@ -248,7 +253,7 @@ export class DropdownCloudWidgetComponent extends WidgetComponent implements OnI private parentValueChanged(value: string) { if (value && !this.isNoneValueSelected(value)) { - this.isValidRestType() ? this.persistFieldOptionsFromRestApi() : this.persistFieldOptionsFromManualList(value); + this.isValidRestConfig() ? this.persistFieldOptionsFromRestApi() : this.persistFieldOptionsFromManualList(value); } else if (this.isNoneValueSelected(value)) { this.resetRestApiErrorMessage(); this.resetOptions(); @@ -378,8 +383,8 @@ export class DropdownCloudWidgetComponent extends WidgetComponent implements OnI return optionValue; } - private isValidRestType(): boolean { - return this.field.optionType === 'rest' && this.hasRestUrl(); + private isValidRestConfig(): boolean { + return this.isRestOptionType() && this.hasRestUrl(); } private setPreviewState(): void { @@ -401,7 +406,7 @@ export class DropdownCloudWidgetComponent extends WidgetComponent implements OnI } private hasRestUrl(): boolean { - return !!this.field.restUrl; + return !!this.field?.restUrl; } isReadOnlyType(): boolean { 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 01afd7a1f3..5db542518d 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 @@ -65,6 +65,7 @@ describe('RadioButtonsCloudWidgetComponent', () => { widget.field = new FormFieldModel(form, { id: fieldId, + optionType: 'rest', restUrl: '' }); const field = widget.field; @@ -74,6 +75,23 @@ describe('RadioButtonsCloudWidgetComponent', () => { expect(field.updateForm).toHaveBeenCalled(); }); + it('should call rest api only when url is present and field type is rest', () => { + const getFieldConfig = (optionType: string, restUrl: string) => new FormFieldModel(new FormModel(), { optionType, restUrl }); + spyOn(formCloudService, 'getRestWidgetData').and.returnValue(of([])); + + widget.field = getFieldConfig('manual', 'fake-rest-url'); + widget.ngOnInit(); + expect(formCloudService.getRestWidgetData).not.toHaveBeenCalled(); + + widget.field = getFieldConfig('rest', null); + widget.ngOnInit(); + expect(formCloudService.getRestWidgetData).not.toHaveBeenCalled(); + + widget.field = getFieldConfig('rest', 'fake-rest-url'); + widget.ngOnInit(); + expect(formCloudService.getRestWidgetData).toHaveBeenCalled(); + }); + it('should update the field value when an option is selected', () => { spyOn(widget, 'onFieldChanged').and.stub(); widget.onOptionClick('fake-opt'); 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 6aba1c50cb..5fcb8d07c9 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 @@ -52,7 +52,7 @@ export class RadioButtonsCloudWidgetComponent extends WidgetComponent implements } ngOnInit() { - if (this.field?.restUrl && !this.field?.form?.readOnly) { + if (this.isValidRestConfig() && !this.isReadOnlyForm()) { this.getValuesFromRestApi(); } } @@ -103,4 +103,20 @@ export class RadioButtonsCloudWidgetComponent extends WidgetComponent implements hasError(): ErrorMessageModel { return this.restApiError || this.field.validationSummary; } + + private isRestType(): boolean { + return this.field?.optionType === 'rest'; + } + + private isReadOnlyForm(): boolean { + return !!this.field?.form?.readOnly; + } + + private hasRestUrl(): boolean { + return !!this.field?.restUrl; + } + + private isValidRestConfig(): boolean { + return this.isRestType() && this.hasRestUrl(); + } } 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 e7ae7ee817..e1d1209432 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 @@ -82,7 +82,7 @@ describe('DropdownWidgetComponent', () => { beforeEach(() => { getRestFieldValuesSpy = spyOn(taskFormService, 'getRestFieldValues').and.returnValue(of([])); - widget.field = new FormFieldModel(new FormModel({ taskId }), { id: fieldId, restUrl: '' }); + widget.field = new FormFieldModel(new FormModel({ taskId }), { id: fieldId, restUrl: '', optionType: 'rest' }); }); it('should request options from service when form is NOT readonly', () => { @@ -110,7 +110,7 @@ describe('DropdownWidgetComponent', () => { expect(element.querySelector('.adf-dropdown-required-message')).toBeNull(); }); - it('should preserve empty option when loading fields', () => { + it('should NOT preserve empty option when loading fields', () => { const restFieldValue: FormFieldOption = { id: '1', name: 'Option1' } as FormFieldOption; spyOn(taskFormService, 'getRestFieldValues').and.callFake( () => @@ -125,15 +125,15 @@ describe('DropdownWidgetComponent', () => { widget.field = new FormFieldModel(form, { id: '', restUrl: '/some/url/address', + optionType: 'rest', hasEmptyValue: true, options: [emptyOption] }); widget.ngOnInit(); expect(taskFormService.getRestFieldValues).toHaveBeenCalled(); - expect(widget.field.options.length).toBe(2); - expect(widget.field.options[0]).toBe(emptyOption); - expect(widget.field.options[1]).toBe(restFieldValue); + expect(widget.field.options.length).toBe(1); + expect(widget.field.options[0]).toEqual(restFieldValue); }); describe('when is required', () => { @@ -187,7 +187,8 @@ describe('DropdownWidgetComponent', () => { name: 'date-name', type: 'dropdown', readOnly: 'false', - restUrl: 'fake-rest-url' + restUrl: 'fake-rest-url', + optionType: 'rest' }); widget.field.emptyOption = { id: 'empty', name: 'Choose one...' }; widget.field.isVisible = true; @@ -237,7 +238,8 @@ describe('DropdownWidgetComponent', () => { name: 'date-name', type: 'dropdown', readOnly: 'false', - restUrl: 'fake-rest-url' + restUrl: 'fake-rest-url', + optionType: 'rest' }); widget.field.emptyOption = { id: 'empty', name: 'Choose one...' }; widget.field.isVisible = true; 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 b3886ee4a4..3f99fe6c8d 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 && !this.isReadOnlyForm()) { + if (this.isValidRestConfig() && !this.isReadOnlyForm()) { if (this.field.form.taskId) { this.getValuesByTaskId(); } else { @@ -107,7 +107,19 @@ export class DropdownWidgetComponent extends WidgetComponent implements OnInit { return this.field.readOnly; } + private isRestType(): boolean { + return this.field?.optionType === 'rest'; + } + private isReadOnlyForm(): boolean { return !!this.field?.form?.readOnly; } + + private hasRestUrl(): boolean { + return !!this.field?.restUrl; + } + + private isValidRestConfig(): boolean { + return this.isRestType() && this.hasRestUrl(); + } } diff --git a/lib/process-services/src/lib/form/widgets/radio-buttons/radio-buttons.widget.spec.ts b/lib/process-services/src/lib/form/widgets/radio-buttons/radio-buttons.widget.spec.ts index b7028f62dc..fe2a791f3f 100644 --- a/lib/process-services/src/lib/form/widgets/radio-buttons/radio-buttons.widget.spec.ts +++ b/lib/process-services/src/lib/form/widgets/radio-buttons/radio-buttons.widget.spec.ts @@ -74,7 +74,7 @@ describe('RadioButtonsWidgetComponent', () => { formService = new FormService(); widget = new RadioButtonsWidgetComponent(formService, taskFormService, processDefinitionService); - widget.field = new FormFieldModel(new FormModel(), { restUrl: '' }); + widget.field = new FormFieldModel(new FormModel(), { restUrl: '', optionType: 'rest' }); }); it('should request field values from service', () => { @@ -87,7 +87,8 @@ describe('RadioButtonsWidgetComponent', () => { widget.field = new FormFieldModel(form, { id: fieldId, - restUrl: '' + restUrl: '', + optionType: 'rest' }); spyOn(taskFormService, 'getRestFieldValues').and.returnValue( @@ -110,7 +111,8 @@ describe('RadioButtonsWidgetComponent', () => { widget.field = new FormFieldModel(form, { id: fieldId, - restUrl: '' + restUrl: '', + optionType: 'rest' }); const field = widget.field; spyOn(field, 'updateForm').and.stub(); @@ -135,7 +137,8 @@ describe('RadioButtonsWidgetComponent', () => { widget.field = new FormFieldModel(form, { id: fieldId, - restUrl: '' + restUrl: '', + optionType: 'rest' }); spyOn(taskFormService, 'getRestFieldValues').and.returnValue( new Observable((observer) => { @@ -364,7 +367,8 @@ describe('RadioButtonsWidgetComponent', () => { id: 'radio-id', name: 'radio-name', type: FormFieldTypes.RADIO_BUTTONS, - restUrl: 'rest-url' + restUrl: 'rest-url', + optionType: 'rest' }); radioButtonWidget.field.isVisible = true; const fakeContainer = new ContainerModel(radioButtonWidget.field); @@ -427,7 +431,8 @@ describe('RadioButtonsWidgetComponent', () => { id: 'radio-id', name: 'radio-name', type: FormFieldTypes.RADIO_BUTTONS, - restUrl: 'rest-url' + restUrl: 'rest-url', + optionType: 'rest' }); spyOn(processDefinitionService, 'getRestFieldValuesByProcessId').and.returnValue(of(restOption)); radioButtonWidget.field.isVisible = true; diff --git a/lib/process-services/src/lib/form/widgets/radio-buttons/radio-buttons.widget.ts b/lib/process-services/src/lib/form/widgets/radio-buttons/radio-buttons.widget.ts index 2a01397840..f3a1ccb3d7 100644 --- a/lib/process-services/src/lib/form/widgets/radio-buttons/radio-buttons.widget.ts +++ b/lib/process-services/src/lib/form/widgets/radio-buttons/radio-buttons.widget.ts @@ -55,7 +55,7 @@ export class RadioButtonsWidgetComponent extends WidgetComponent implements OnIn } ngOnInit() { - if (this.field?.restUrl && !this.field?.form?.readOnly) { + if (this.isValidRestConfig() && !this.isReadOnlyForm()) { if (this.field.form.taskId) { this.getOptionsByTaskId(); } else { @@ -84,4 +84,20 @@ export class RadioButtonsWidgetComponent extends WidgetComponent implements OnIn this.field.value = optionSelected; this.fieldChanged.emit(this.field); } + + private isRestType(): boolean { + return this.field?.optionType === 'rest'; + } + + private isReadOnlyForm(): boolean { + return !!this.field?.form?.readOnly; + } + + private hasRestUrl(): boolean { + return !!this.field?.restUrl; + } + + private isValidRestConfig(): boolean { + return this.isRestType() && this.hasRestUrl(); + } }