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
This commit is contained in:
Wiktor Danielewski 2024-08-06 15:38:21 +02:00 committed by GitHub
parent 3406341859
commit cb0b072b1e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 267 additions and 142 deletions

View File

@ -112,6 +112,31 @@ describe('FormFieldModel', () => {
expect(field.readOnly).toBeTruthy(); 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', () => { describe('dropdown field model instantiation', () => {
it('should add value (selected option) to field options if NOT present', () => { it('should add value (selected option) to field options if NOT present', () => {
const field = new FormFieldModel(new FormModel(), { const field = new FormFieldModel(new FormModel(), {
@ -137,7 +162,6 @@ describe('FormFieldModel', () => {
}); });
expect(field.options).toEqual(selectedOptions); 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', () => { 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(); 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(), { const field = new FormFieldModel(new FormModel(), {
type: FormFieldTypes.DROPDOWN, type: FormFieldTypes.DROPDOWN,
options: [ options: [
@ -702,15 +726,19 @@ describe('FormFieldModel', () => {
id: 'rest-radio', id: 'rest-radio',
type: FormFieldTypes.RADIO_BUTTONS, type: FormFieldTypes.RADIO_BUTTONS,
optionType: 'rest', optionType: 'rest',
options: [ restUrl: 'fake-url',
{ id: 'restOpt1', name: 'Rest Option 1' }, options: []
{ id: 'restOpt2', name: 'Rest Option 2' }
]
}); });
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', () => { it('should update form with selected option and options from which we chose', () => {
field.value = 'restOpt2'; field.value = 'restOpt2';
field.updateForm();
expect(form.values['rest-radio']).toEqual({ expect(form.values['rest-radio']).toEqual({
id: 'restOpt2', 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', () => { 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', () => { it('when value does NOT match any option', () => {
field.value = 'not_exist'; field.value = 'not_exist';
field.updateForm();
expect(form.values['rest-radio']).toEqual({ expect(form.values['rest-radio']).toEqual({
id: null, id: null,
@ -732,6 +761,7 @@ describe('FormFieldModel', () => {
it('when radio button value is null', () => { it('when radio button value is null', () => {
field.value = null; field.value = null;
field.updateForm();
expect(form.values['rest-radio']).toEqual({ expect(form.values['rest-radio']).toEqual({
id: null, id: null,
@ -863,115 +893,123 @@ describe('FormFieldModel', () => {
expect(form.values['header_field']).not.toBeDefined(); expect(form.values['header_field']).not.toBeDefined();
}); });
it('dropdown field type should appear into form values', () => { describe('dropdown field', () => {
const form = new FormModel(); const getFieldConfig = (optionType, options, value) =>
const field = new FormFieldModel(form, { new FormFieldModel(new FormModel(), {
fieldType: 'HeaderFieldtype', id: 'dropdown_field',
id: 'dropdown_field', name: 'dropdown',
name: 'header', type: FormFieldTypes.DROPDOWN,
type: FormFieldTypes.DROPDOWN, optionType,
value: 'opt1', options,
required: false, value,
readOnly: true, required: false,
options: [ restUrl: 'fake-url',
{ id: 'opt1', name: 'Option 1' }, restIdProperty: 'fake-id-property',
{ id: 'opt2', name: 'Option 2' } 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', () => { describe('radio buttons field', () => {
const form = new FormModel(); const getFieldConfig = (optionType, options, value) =>
const field = new FormFieldModel(form, { new FormFieldModel(new FormModel(), {
fieldType: 'HeaderFieldtype', id: 'radio_field',
id: 'dropdown_field', name: 'radio',
name: 'header', type: FormFieldTypes.RADIO_BUTTONS,
type: FormFieldTypes.DROPDOWN, optionType,
value: 'opt1', options,
required: false, value,
readOnly: true, required: false,
restUrl: 'fake-url-just-to-show', restUrl: 'fake-url',
optionType: 'rest', restIdProperty: 'fake-id-property',
restIdProperty: 'fake-id-property', restLabelProperty: 'fake-label-property',
restLabelProperty: 'fake-label-property', restResponsePath: 'fake-response-path'
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');
});
it('dropdown field type should be formatted on id and name properties if rest properties are not set', () => { const staticOptions = [
const form = new FormModel(); { id: 'opt1', name: 'Option 1' },
const field = new FormFieldModel(form, { { id: 'opt2', name: 'Option 2' }
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');
});
it('radio button field rest type should appear with its configured label and id into the rest values', () => { it('should assign rest properties properly', () => {
const form = new FormModel(); const field = getFieldConfig('rest', [], 'delayed-rest-option-id');
const field = new FormFieldModel(form, {
fieldType: 'HeaderFieldtype',
id: 'radio_bananan_field',
name: 'banana',
type: FormFieldTypes.RADIO_BUTTONS,
value: 'opt1',
required: false,
readOnly: true,
restUrl: '<whatever-url-you-like-we-do-not-mind>',
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('radio button field rest type should appear with id / name properties when rest properties are not configured', () => { field.updateForm();
const form = new FormModel();
const field = new FormFieldModel(form, { expect(field.value).toEqual('delayed-rest-option-id');
fieldType: 'HeaderFieldtype', expect(field.form.values['radio_field']).toEqual({ id: null, name: null, options: [] });
id: 'radio_bananan_field', expect(field.restUrl).toEqual('fake-url');
name: 'banana', expect(field.restIdProperty).toEqual('fake-id-property');
type: FormFieldTypes.RADIO_BUTTONS, expect(field.restLabelProperty).toEqual('fake-label-property');
value: 'opt1', expect(field.restResponsePath).toEqual('fake-response-path');
required: false, });
readOnly: true,
restUrl: '<whatever-url-you-like-we-do-not-mind>', it('should NOT consider the static list of options in case of rest type', () => {
optionType: 'rest', const field = getFieldConfig('rest', staticOptions, 'delayed-rest-option-id');
options: [
{ id: 'opt1', name: 'Option 1' }, field.updateForm();
{ id: 'opt2', name: 'Option 2' }
] 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', () => { it('should parse and resolve people null value as null', () => {

View File

@ -31,6 +31,10 @@ import { DataColumn } from '../../../../datatable/data/data-column.model';
import { DateFnsUtils } from '../../../../common'; import { DateFnsUtils } from '../../../../common';
import { isValid as isValidDate } from 'date-fns'; 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 // Maps to FormFieldRepresentation
export class FormFieldModel extends FormWidgetModel { export class FormFieldModel extends FormWidgetModel {
private _value: string; private _value: string;
@ -71,7 +75,7 @@ export class FormFieldModel extends FormWidgetModel {
restLabelProperty: string; restLabelProperty: string;
hasEmptyValue: boolean; hasEmptyValue: boolean;
className: string; className: string;
optionType: 'rest' | 'manual' | 'variable'; optionType: FieldOptionType;
params: FormFieldMetadata = {}; params: FormFieldMetadata = {};
hyperlinkUrl: string; hyperlinkUrl: string;
displayText: string; displayText: string;
@ -80,8 +84,8 @@ export class FormFieldModel extends FormWidgetModel {
enableFractions: boolean = false; enableFractions: boolean = false;
currency: string = null; currency: string = null;
dateDisplayFormat: string = this.defaultDateFormat; dateDisplayFormat: string = this.defaultDateFormat;
selectionType: 'single' | 'multiple' = null; selectionType: FieldSelectionType;
alignmentType: 'vertical' | 'horizontal' = null; alignmentType: FieldAlignmentType;
rule?: FormFieldRule; rule?: FormFieldRule;
selectLoggedUser: boolean; selectLoggedUser: boolean;
groupsRestriction: string[]; groupsRestriction: string[];
@ -193,7 +197,7 @@ export class FormFieldModel extends FormWidgetModel {
this.maxDateRangeValue = json.maxDateRangeValue; this.maxDateRangeValue = json.maxDateRangeValue;
this.dynamicDateRangeSelection = json.dynamicDateRangeSelection; this.dynamicDateRangeSelection = json.dynamicDateRangeSelection;
this.regexPattern = json.regexPattern; 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.emptyOption = this.getEmptyOption(this.options);
this.hasEmptyValue = json?.hasEmptyValue ?? !!this.emptyOption; this.hasEmptyValue = json?.hasEmptyValue ?? !!this.emptyOption;
this.className = json.className; this.className = json.className;
@ -422,10 +426,9 @@ export class FormFieldModel extends FormWidgetModel {
break; break;
} }
const entry: FormFieldOption[] = this.options.filter((opt) => opt.id === this.value); const matchingOption: FormFieldOption = this.options.find((opt) => opt.id === this.value);
if (entry.length > 0) {
this.form.values[this.id] = entry[0]; this.form.values[this.id] = matchingOption || null;
}
} }
break; break;
} }
@ -567,6 +570,10 @@ export class FormFieldModel extends FormWidgetModel {
return Array.isArray(options) ? options.filter((option) => this.isValidOption(option)) : []; 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 { private isValidOption(option: any): boolean {
return typeof option === 'object' && !Array.isArray(option) && option?.id && option?.name; return typeof option === 'object' && !Array.isArray(option) && option?.id && option?.name;
} }

View File

@ -75,15 +75,21 @@ describe('DropdownCloudWidgetComponent', () => {
fixture.detectChanges(); fixture.detectChanges();
}); });
it('should require field with restUrl', () => { it('should call rest api only when url is present and field type is rest', () => {
spyOn(formCloudService, 'getRestWidgetData'); const getFieldConfig = (optionType: string, restUrl: string) => new FormFieldModel(new FormModel(), { optionType, restUrl });
widget.field = new FormFieldModel(new FormModel()); spyOn(formCloudService, 'getRestWidgetData').and.returnValue(of(fakeOptionList));
widget.field = getFieldConfig('manual', 'fake-rest-url');
widget.ngOnInit(); widget.ngOnInit();
expect(formCloudService.getRestWidgetData).not.toHaveBeenCalled(); expect(formCloudService.getRestWidgetData).not.toHaveBeenCalled();
widget.field = new FormFieldModel(null, { restUrl: null }); widget.field = getFieldConfig('rest', null);
widget.ngOnInit(); widget.ngOnInit();
expect(formCloudService.getRestWidgetData).not.toHaveBeenCalled(); 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 () => { it('should select the default value when an option is chosen as default', async () => {

View File

@ -86,7 +86,8 @@ export class DropdownCloudWidgetComponent extends WidgetComponent implements OnI
switch (true) { switch (true) {
case this.isReadOnlyForm(): case this.isReadOnlyForm():
break; break;
case this.hasRestUrl() && !this.isLinkedWidget():
case this.isValidRestConfig() && !this.isLinkedWidget():
this.persistFieldOptionsFromRestApi(); this.persistFieldOptionsFromRestApi();
break; break;
@ -192,8 +193,12 @@ export class DropdownCloudWidgetComponent extends WidgetComponent implements OnI
return this.field?.optionType === 'variable'; return this.field?.optionType === 'variable';
} }
private isRestOptionType(): boolean {
return this.field?.optionType === 'rest';
}
private persistFieldOptionsFromRestApi() { private persistFieldOptionsFromRestApi() {
if (this.isValidRestType()) { if (this.isValidRestConfig()) {
this.resetRestApiErrorMessage(); this.resetRestApiErrorMessage();
const bodyParam = this.buildBodyParam(); const bodyParam = this.buildBodyParam();
this.formCloudService this.formCloudService
@ -248,7 +253,7 @@ export class DropdownCloudWidgetComponent extends WidgetComponent implements OnI
private parentValueChanged(value: string) { private parentValueChanged(value: string) {
if (value && !this.isNoneValueSelected(value)) { if (value && !this.isNoneValueSelected(value)) {
this.isValidRestType() ? this.persistFieldOptionsFromRestApi() : this.persistFieldOptionsFromManualList(value); this.isValidRestConfig() ? this.persistFieldOptionsFromRestApi() : this.persistFieldOptionsFromManualList(value);
} else if (this.isNoneValueSelected(value)) { } else if (this.isNoneValueSelected(value)) {
this.resetRestApiErrorMessage(); this.resetRestApiErrorMessage();
this.resetOptions(); this.resetOptions();
@ -378,8 +383,8 @@ export class DropdownCloudWidgetComponent extends WidgetComponent implements OnI
return optionValue; return optionValue;
} }
private isValidRestType(): boolean { private isValidRestConfig(): boolean {
return this.field.optionType === 'rest' && this.hasRestUrl(); return this.isRestOptionType() && this.hasRestUrl();
} }
private setPreviewState(): void { private setPreviewState(): void {
@ -401,7 +406,7 @@ export class DropdownCloudWidgetComponent extends WidgetComponent implements OnI
} }
private hasRestUrl(): boolean { private hasRestUrl(): boolean {
return !!this.field.restUrl; return !!this.field?.restUrl;
} }
isReadOnlyType(): boolean { isReadOnlyType(): boolean {

View File

@ -65,6 +65,7 @@ describe('RadioButtonsCloudWidgetComponent', () => {
widget.field = new FormFieldModel(form, { widget.field = new FormFieldModel(form, {
id: fieldId, id: fieldId,
optionType: 'rest',
restUrl: '<url>' restUrl: '<url>'
}); });
const field = widget.field; const field = widget.field;
@ -74,6 +75,23 @@ describe('RadioButtonsCloudWidgetComponent', () => {
expect(field.updateForm).toHaveBeenCalled(); 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', () => { it('should update the field value when an option is selected', () => {
spyOn(widget, 'onFieldChanged').and.stub(); spyOn(widget, 'onFieldChanged').and.stub();
widget.onOptionClick('fake-opt'); widget.onOptionClick('fake-opt');

View File

@ -52,7 +52,7 @@ export class RadioButtonsCloudWidgetComponent extends WidgetComponent implements
} }
ngOnInit() { ngOnInit() {
if (this.field?.restUrl && !this.field?.form?.readOnly) { if (this.isValidRestConfig() && !this.isReadOnlyForm()) {
this.getValuesFromRestApi(); this.getValuesFromRestApi();
} }
} }
@ -103,4 +103,20 @@ export class RadioButtonsCloudWidgetComponent extends WidgetComponent implements
hasError(): ErrorMessageModel { hasError(): ErrorMessageModel {
return this.restApiError || this.field.validationSummary; 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();
}
} }

View File

@ -82,7 +82,7 @@ describe('DropdownWidgetComponent', () => {
beforeEach(() => { beforeEach(() => {
getRestFieldValuesSpy = spyOn(taskFormService, 'getRestFieldValues').and.returnValue(of([])); getRestFieldValuesSpy = spyOn(taskFormService, 'getRestFieldValues').and.returnValue(of([]));
widget.field = new FormFieldModel(new FormModel({ taskId }), { id: fieldId, restUrl: '<url>' }); widget.field = new FormFieldModel(new FormModel({ taskId }), { id: fieldId, restUrl: '<url>', optionType: 'rest' });
}); });
it('should request options from service when form is NOT readonly', () => { 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(); 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; const restFieldValue: FormFieldOption = { id: '1', name: 'Option1' } as FormFieldOption;
spyOn(taskFormService, 'getRestFieldValues').and.callFake( spyOn(taskFormService, 'getRestFieldValues').and.callFake(
() => () =>
@ -125,15 +125,15 @@ describe('DropdownWidgetComponent', () => {
widget.field = new FormFieldModel(form, { widget.field = new FormFieldModel(form, {
id: '<id>', id: '<id>',
restUrl: '/some/url/address', restUrl: '/some/url/address',
optionType: 'rest',
hasEmptyValue: true, hasEmptyValue: true,
options: [emptyOption] options: [emptyOption]
}); });
widget.ngOnInit(); widget.ngOnInit();
expect(taskFormService.getRestFieldValues).toHaveBeenCalled(); expect(taskFormService.getRestFieldValues).toHaveBeenCalled();
expect(widget.field.options.length).toBe(2); expect(widget.field.options.length).toBe(1);
expect(widget.field.options[0]).toBe(emptyOption); expect(widget.field.options[0]).toEqual(restFieldValue);
expect(widget.field.options[1]).toBe(restFieldValue);
}); });
describe('when is required', () => { describe('when is required', () => {
@ -187,7 +187,8 @@ describe('DropdownWidgetComponent', () => {
name: 'date-name', name: 'date-name',
type: 'dropdown', type: 'dropdown',
readOnly: 'false', readOnly: 'false',
restUrl: 'fake-rest-url' restUrl: 'fake-rest-url',
optionType: 'rest'
}); });
widget.field.emptyOption = { id: 'empty', name: 'Choose one...' }; widget.field.emptyOption = { id: 'empty', name: 'Choose one...' };
widget.field.isVisible = true; widget.field.isVisible = true;
@ -237,7 +238,8 @@ describe('DropdownWidgetComponent', () => {
name: 'date-name', name: 'date-name',
type: 'dropdown', type: 'dropdown',
readOnly: 'false', readOnly: 'false',
restUrl: 'fake-rest-url' restUrl: 'fake-rest-url',
optionType: 'rest'
}); });
widget.field.emptyOption = { id: 'empty', name: 'Choose one...' }; widget.field.emptyOption = { id: 'empty', name: 'Choose one...' };
widget.field.isVisible = true; widget.field.isVisible = true;

View File

@ -52,7 +52,7 @@ export class DropdownWidgetComponent extends WidgetComponent implements OnInit {
} }
ngOnInit() { ngOnInit() {
if (this.field?.restUrl && !this.isReadOnlyForm()) { if (this.isValidRestConfig() && !this.isReadOnlyForm()) {
if (this.field.form.taskId) { if (this.field.form.taskId) {
this.getValuesByTaskId(); this.getValuesByTaskId();
} else { } else {
@ -107,7 +107,19 @@ export class DropdownWidgetComponent extends WidgetComponent implements OnInit {
return this.field.readOnly; return this.field.readOnly;
} }
private isRestType(): boolean {
return this.field?.optionType === 'rest';
}
private isReadOnlyForm(): boolean { private isReadOnlyForm(): boolean {
return !!this.field?.form?.readOnly; return !!this.field?.form?.readOnly;
} }
private hasRestUrl(): boolean {
return !!this.field?.restUrl;
}
private isValidRestConfig(): boolean {
return this.isRestType() && this.hasRestUrl();
}
} }

View File

@ -74,7 +74,7 @@ describe('RadioButtonsWidgetComponent', () => {
formService = new FormService(); formService = new FormService();
widget = new RadioButtonsWidgetComponent(formService, taskFormService, processDefinitionService); widget = new RadioButtonsWidgetComponent(formService, taskFormService, processDefinitionService);
widget.field = new FormFieldModel(new FormModel(), { restUrl: '<url>' }); widget.field = new FormFieldModel(new FormModel(), { restUrl: '<url>', optionType: 'rest' });
}); });
it('should request field values from service', () => { it('should request field values from service', () => {
@ -87,7 +87,8 @@ describe('RadioButtonsWidgetComponent', () => {
widget.field = new FormFieldModel(form, { widget.field = new FormFieldModel(form, {
id: fieldId, id: fieldId,
restUrl: '<url>' restUrl: '<url>',
optionType: 'rest'
}); });
spyOn(taskFormService, 'getRestFieldValues').and.returnValue( spyOn(taskFormService, 'getRestFieldValues').and.returnValue(
@ -110,7 +111,8 @@ describe('RadioButtonsWidgetComponent', () => {
widget.field = new FormFieldModel(form, { widget.field = new FormFieldModel(form, {
id: fieldId, id: fieldId,
restUrl: '<url>' restUrl: '<url>',
optionType: 'rest'
}); });
const field = widget.field; const field = widget.field;
spyOn(field, 'updateForm').and.stub(); spyOn(field, 'updateForm').and.stub();
@ -135,7 +137,8 @@ describe('RadioButtonsWidgetComponent', () => {
widget.field = new FormFieldModel(form, { widget.field = new FormFieldModel(form, {
id: fieldId, id: fieldId,
restUrl: '<url>' restUrl: '<url>',
optionType: 'rest'
}); });
spyOn(taskFormService, 'getRestFieldValues').and.returnValue( spyOn(taskFormService, 'getRestFieldValues').and.returnValue(
new Observable((observer) => { new Observable((observer) => {
@ -364,7 +367,8 @@ describe('RadioButtonsWidgetComponent', () => {
id: 'radio-id', id: 'radio-id',
name: 'radio-name', name: 'radio-name',
type: FormFieldTypes.RADIO_BUTTONS, type: FormFieldTypes.RADIO_BUTTONS,
restUrl: 'rest-url' restUrl: 'rest-url',
optionType: 'rest'
}); });
radioButtonWidget.field.isVisible = true; radioButtonWidget.field.isVisible = true;
const fakeContainer = new ContainerModel(radioButtonWidget.field); const fakeContainer = new ContainerModel(radioButtonWidget.field);
@ -427,7 +431,8 @@ describe('RadioButtonsWidgetComponent', () => {
id: 'radio-id', id: 'radio-id',
name: 'radio-name', name: 'radio-name',
type: FormFieldTypes.RADIO_BUTTONS, type: FormFieldTypes.RADIO_BUTTONS,
restUrl: 'rest-url' restUrl: 'rest-url',
optionType: 'rest'
}); });
spyOn(processDefinitionService, 'getRestFieldValuesByProcessId').and.returnValue(of(restOption)); spyOn(processDefinitionService, 'getRestFieldValuesByProcessId').and.returnValue(of(restOption));
radioButtonWidget.field.isVisible = true; radioButtonWidget.field.isVisible = true;

View File

@ -55,7 +55,7 @@ export class RadioButtonsWidgetComponent extends WidgetComponent implements OnIn
} }
ngOnInit() { ngOnInit() {
if (this.field?.restUrl && !this.field?.form?.readOnly) { if (this.isValidRestConfig() && !this.isReadOnlyForm()) {
if (this.field.form.taskId) { if (this.field.form.taskId) {
this.getOptionsByTaskId(); this.getOptionsByTaskId();
} else { } else {
@ -84,4 +84,20 @@ export class RadioButtonsWidgetComponent extends WidgetComponent implements OnIn
this.field.value = optionSelected; this.field.value = optionSelected;
this.fieldChanged.emit(this.field); 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();
}
} }