Skip to content

Commit

Permalink
[AAE-7010] - Fix nested linked dropdowns are not reset (#7463)
Browse files Browse the repository at this point in the history
* [AAE-7010] - Fix nested linked dropdowns are not reset

* Rebase

* Reset rest in case value is not part of the options

* Update failing unit test due to form field changes
  • Loading branch information
arditdomi committed Jan 24, 2022
1 parent bfe2961 commit e98fd2d
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 25 deletions.
Expand Up @@ -531,18 +531,18 @@ describe('FormFieldModel', () => {
expect(field.value).toBe(false);
});

it('should update form with empty dropdown value', () => {
it('should delete empty dropdown value from the form values', () => {
const form = new FormModel();
const field = new FormFieldModel(form, {
id: 'dropdown-1',
type: FormFieldTypes.DROPDOWN
});

field.value = 'empty';
expect(form.values['dropdown-1']).toEqual({});
expect(form.values['dropdown-1']).toBe(undefined);

field.value = '';
expect(form.values['dropdown-1']).toEqual({});
expect(form.values['dropdown-1']).toBe(undefined);
});

it('should update form with dropdown value', () => {
Expand Down
21 changes: 9 additions & 12 deletions lib/core/form/components/widgets/core/form-field.model.ts
Expand Up @@ -293,17 +293,14 @@ export class FormFieldModel extends FormWidgetModel {
if (json.type === FormFieldTypes.DROPDOWN) {

if (json.options) {
const options = <FormFieldOption[]> json.options || [];
if (options.length > 0) {
if (json.hasEmptyValue) {
const emptyOption = json.options[0];
if (value === '' || value === emptyOption.id || value === emptyOption.name) {
value = emptyOption.id;
}
} else {
if (value?.id && value?.name) {
value = value.id;
}
if (json.hasEmptyValue) {
const emptyOption = json.options[0];
if (value === '' || value === emptyOption.id || value === emptyOption.name) {
value = emptyOption.id;
}
} else {
if (value?.id && value?.name) {
value = value.id;
}
}
}
Expand Down Expand Up @@ -371,7 +368,7 @@ export class FormFieldModel extends FormWidgetModel {

if (typeof this.value === 'string') {
if (this.value === 'empty' || this.value === '') {
this.form.values[this.id] = {};
delete this.form.values[this.id];
break;
}

Expand Down
Expand Up @@ -19,7 +19,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { of, throwError } from 'rxjs';
import { DropdownCloudWidgetComponent } from './dropdown-cloud.widget';
import { FormFieldModel, FormModel, FormService, setupTestBed } from '@alfresco/adf-core';
import { FormFieldModel, FormModel, FormService, setupTestBed, FormFieldEvent } from '@alfresco/adf-core';
import { FormCloudService } from '../../../services/form-cloud.service';
import { ProcessServiceCloudTestingModule } from '../../../../testing/process-service-cloud.testing.module';
import { TranslateModule } from '@ngx-translate/core';
Expand Down Expand Up @@ -428,6 +428,25 @@ describe('DropdownCloudWidgetComponent', () => {
expect(widget.field.options.length).toBe(2);
expect(failedErrorMsgElement3).toBeNull();
});

describe('Rest - On parent value changes (chain)', () => {
it('should fire a form field value changed event when the value gets reset (notify children on the chain to reset)', () => {
spyOn(formCloudService, 'getRestWidgetData').and.returnValue(throwError('Failed to fetch options'));
widget.field.options = mockConditionalEntries[1].options;
widget.field.value = 'MI';
fixture.detectChanges();

const formFieldValueChangedSpy = spyOn(formService.formFieldValueChanged, 'next').and.callThrough();
const formFieldValueChangedEvent = new FormFieldEvent(widget.field.form, widget.field);

parentDropdown.value = 'GR';
widget.selectionChangedForField(parentDropdown);
fixture.detectChanges();

expect(formFieldValueChangedSpy).toHaveBeenCalledWith(formFieldValueChangedEvent);
expect(widget.field.options).toEqual([]);
});
});
});

describe('Manual options', () => {
Expand Down Expand Up @@ -480,6 +499,49 @@ describe('DropdownCloudWidgetComponent', () => {
expect(defaultOption.context.value).toBe('empty');
expect(defaultOption.context.viewValue).toBe('Choose one...');
});

describe('Manual - On parent value changes (chain)', () => {
it('should reset the current value when it not part of the available options', () => {
widget.field.options = mockConditionalEntries[1].options;
widget.field.value = 'non-existent-value';
fixture.detectChanges();

parentDropdown.value = 'GR';
widget.selectionChangedForField(parentDropdown);
fixture.detectChanges();

expect(widget.field.options).toEqual(mockConditionalEntries[0].options);
expect(widget.fieldValue).toEqual('');
});

it('should not reset the current value when it is part of the available options', () => {
widget.field.options = mockConditionalEntries[1].options;
widget.field.value = 'ATH';
fixture.detectChanges();

parentDropdown.value = 'GR';
widget.selectionChangedForField(parentDropdown);
fixture.detectChanges();

expect(widget.field.options).toEqual(mockConditionalEntries[0].options);
expect(widget.fieldValue).toEqual('ATH');
});

it('should fire a form field value changed event when the value gets reset (notify children on the chain to reset)', () => {
widget.field.options = mockConditionalEntries[1].options;
widget.field.value = 'non-existent-value';
fixture.detectChanges();

const formFieldValueChangedSpy = spyOn(formService.formFieldValueChanged, 'next').and.callThrough();
const formFieldValueChangedEvent = new FormFieldEvent(widget.field.form, widget.field);

parentDropdown.value = 'GR';
widget.selectionChangedForField(parentDropdown);
fixture.detectChanges();

expect(formFieldValueChangedSpy).toHaveBeenCalledWith(formFieldValueChangedEvent);
});
});
});

describe('Load selection for linked dropdown (i.e. saved, completed forms)', () => {
Expand Down
Expand Up @@ -104,6 +104,7 @@ export class DropdownCloudWidgetComponent extends WidgetComponent implements OnI
this.field.options = result;
this.updateOptions();
this.field.updateForm();
this.resetInvalidValue();
}, (err) => {
this.resetRestApiOptions();
this.handleError(err);
Expand Down Expand Up @@ -133,18 +134,18 @@ export class DropdownCloudWidgetComponent extends WidgetComponent implements OnI
}

private parentValueChanged(value: string) {
if (this.isValidValue(value)) {
if (value && !this.isDefaultValue(value)) {
this.isValidRestType() ? this.persistFieldOptionsFromRestApi() : this.persistFieldOptionsFromManualList(value);
} else if (this.isDefaultValue(value)) {
this.resetRestApiErrorMessage();
this.addDefaultOption();
this.resetInvalidValue();
} else {
this.field.options = [];
this.resetInvalidValue();
}
}

private isValidValue(value: string): boolean {
return !!value && value !== DropdownCloudWidgetComponent.DEFAULT_OPTION.id;
}

private isDefaultValue(value: string): boolean {
return value === DropdownCloudWidgetComponent.DEFAULT_OPTION.id;
}
Expand All @@ -159,13 +160,37 @@ export class DropdownCloudWidgetComponent extends WidgetComponent implements OnI
rulesEntries.forEach((ruleEntry: RuleEntry) => {
if (ruleEntry.key === value) {
this.field.options = ruleEntry.options;
this.updateOptions();
this.field.updateForm();
this.resetInvalidValue();
}
});
}
}

private resetInvalidValue() {
if (!this.isValidValue()) {
this.resetValue();
}
}

private resetValue() {
this.field.value = '';
this.selectionChangedForField(this.field);
this.updateOptions();
this.field.updateForm();
}

private isValidValue(): boolean {
return this.fieldValue && !this.isDefaultValue(this.fieldValue) && this.isSelectedValueInOptions();
}

private isSelectedValueInOptions(): boolean {
return [...this.field.options].map(option => option.id).includes(this.fieldValue);
}

get fieldValue(): string {
return this.field.value;
}

private hasRuleEntries(): boolean {
return !!this.field.rule.entries.length;
}
Expand Down Expand Up @@ -269,10 +294,9 @@ export class DropdownCloudWidgetComponent extends WidgetComponent implements OnI

resetRestApiOptions() {
this.field.options = [];
this.resetValue();
this.isRestApiFailed = true;
this.restApiHostName = this.getRestUrlHostName();
this.updateOptions();
this.field.updateForm();
}

private getRestUrlHostName(): string {
Expand Down

0 comments on commit e98fd2d

Please sign in to comment.