mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-07-24 17:32:15 +00:00
[AAE-7010] - Fix nested linked dropdowns are not reset (#7463)
* [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
This commit is contained in:
@@ -531,7 +531,7 @@ describe('FormFieldModel', () => {
|
|||||||
expect(field.value).toBe(false);
|
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 form = new FormModel();
|
||||||
const field = new FormFieldModel(form, {
|
const field = new FormFieldModel(form, {
|
||||||
id: 'dropdown-1',
|
id: 'dropdown-1',
|
||||||
@@ -539,10 +539,10 @@ describe('FormFieldModel', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
field.value = 'empty';
|
field.value = 'empty';
|
||||||
expect(form.values['dropdown-1']).toEqual({});
|
expect(form.values['dropdown-1']).toBe(undefined);
|
||||||
|
|
||||||
field.value = '';
|
field.value = '';
|
||||||
expect(form.values['dropdown-1']).toEqual({});
|
expect(form.values['dropdown-1']).toBe(undefined);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should update form with dropdown value', () => {
|
it('should update form with dropdown value', () => {
|
||||||
|
@@ -293,17 +293,14 @@ export class FormFieldModel extends FormWidgetModel {
|
|||||||
if (json.type === FormFieldTypes.DROPDOWN) {
|
if (json.type === FormFieldTypes.DROPDOWN) {
|
||||||
|
|
||||||
if (json.options) {
|
if (json.options) {
|
||||||
const options = <FormFieldOption[]> json.options || [];
|
if (json.hasEmptyValue) {
|
||||||
if (options.length > 0) {
|
const emptyOption = json.options[0];
|
||||||
if (json.hasEmptyValue) {
|
if (value === '' || value === emptyOption.id || value === emptyOption.name) {
|
||||||
const emptyOption = json.options[0];
|
value = emptyOption.id;
|
||||||
if (value === '' || value === emptyOption.id || value === emptyOption.name) {
|
}
|
||||||
value = emptyOption.id;
|
} else {
|
||||||
}
|
if (value?.id && value?.name) {
|
||||||
} else {
|
value = value.id;
|
||||||
if (value?.id && value?.name) {
|
|
||||||
value = value.id;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -371,7 +368,7 @@ export class FormFieldModel extends FormWidgetModel {
|
|||||||
|
|
||||||
if (typeof this.value === 'string') {
|
if (typeof this.value === 'string') {
|
||||||
if (this.value === 'empty' || this.value === '') {
|
if (this.value === 'empty' || this.value === '') {
|
||||||
this.form.values[this.id] = {};
|
delete this.form.values[this.id];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -19,7 +19,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|||||||
import { By } from '@angular/platform-browser';
|
import { By } from '@angular/platform-browser';
|
||||||
import { of, throwError } from 'rxjs';
|
import { of, throwError } from 'rxjs';
|
||||||
import { DropdownCloudWidgetComponent } from './dropdown-cloud.widget';
|
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 { FormCloudService } from '../../../services/form-cloud.service';
|
||||||
import { ProcessServiceCloudTestingModule } from '../../../../testing/process-service-cloud.testing.module';
|
import { ProcessServiceCloudTestingModule } from '../../../../testing/process-service-cloud.testing.module';
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
@@ -428,6 +428,25 @@ describe('DropdownCloudWidgetComponent', () => {
|
|||||||
expect(widget.field.options.length).toBe(2);
|
expect(widget.field.options.length).toBe(2);
|
||||||
expect(failedErrorMsgElement3).toBeNull();
|
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', () => {
|
describe('Manual options', () => {
|
||||||
@@ -480,6 +499,49 @@ describe('DropdownCloudWidgetComponent', () => {
|
|||||||
expect(defaultOption.context.value).toBe('empty');
|
expect(defaultOption.context.value).toBe('empty');
|
||||||
expect(defaultOption.context.viewValue).toBe('Choose one...');
|
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)', () => {
|
describe('Load selection for linked dropdown (i.e. saved, completed forms)', () => {
|
||||||
|
@@ -104,6 +104,7 @@ export class DropdownCloudWidgetComponent extends WidgetComponent implements OnI
|
|||||||
this.field.options = result;
|
this.field.options = result;
|
||||||
this.updateOptions();
|
this.updateOptions();
|
||||||
this.field.updateForm();
|
this.field.updateForm();
|
||||||
|
this.resetInvalidValue();
|
||||||
}, (err) => {
|
}, (err) => {
|
||||||
this.resetRestApiOptions();
|
this.resetRestApiOptions();
|
||||||
this.handleError(err);
|
this.handleError(err);
|
||||||
@@ -133,18 +134,18 @@ export class DropdownCloudWidgetComponent extends WidgetComponent implements OnI
|
|||||||
}
|
}
|
||||||
|
|
||||||
private parentValueChanged(value: string) {
|
private parentValueChanged(value: string) {
|
||||||
if (this.isValidValue(value)) {
|
if (value && !this.isDefaultValue(value)) {
|
||||||
this.isValidRestType() ? this.persistFieldOptionsFromRestApi() : this.persistFieldOptionsFromManualList(value);
|
this.isValidRestType() ? this.persistFieldOptionsFromRestApi() : this.persistFieldOptionsFromManualList(value);
|
||||||
} else if (this.isDefaultValue(value)) {
|
} else if (this.isDefaultValue(value)) {
|
||||||
this.resetRestApiErrorMessage();
|
this.resetRestApiErrorMessage();
|
||||||
this.addDefaultOption();
|
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 {
|
private isDefaultValue(value: string): boolean {
|
||||||
return value === DropdownCloudWidgetComponent.DEFAULT_OPTION.id;
|
return value === DropdownCloudWidgetComponent.DEFAULT_OPTION.id;
|
||||||
}
|
}
|
||||||
@@ -159,13 +160,37 @@ export class DropdownCloudWidgetComponent extends WidgetComponent implements OnI
|
|||||||
rulesEntries.forEach((ruleEntry: RuleEntry) => {
|
rulesEntries.forEach((ruleEntry: RuleEntry) => {
|
||||||
if (ruleEntry.key === value) {
|
if (ruleEntry.key === value) {
|
||||||
this.field.options = ruleEntry.options;
|
this.field.options = ruleEntry.options;
|
||||||
this.updateOptions();
|
this.resetInvalidValue();
|
||||||
this.field.updateForm();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 {
|
private hasRuleEntries(): boolean {
|
||||||
return !!this.field.rule.entries.length;
|
return !!this.field.rule.entries.length;
|
||||||
}
|
}
|
||||||
@@ -269,10 +294,9 @@ export class DropdownCloudWidgetComponent extends WidgetComponent implements OnI
|
|||||||
|
|
||||||
resetRestApiOptions() {
|
resetRestApiOptions() {
|
||||||
this.field.options = [];
|
this.field.options = [];
|
||||||
|
this.resetValue();
|
||||||
this.isRestApiFailed = true;
|
this.isRestApiFailed = true;
|
||||||
this.restApiHostName = this.getRestUrlHostName();
|
this.restApiHostName = this.getRestUrlHostName();
|
||||||
this.updateOptions();
|
|
||||||
this.field.updateForm();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private getRestUrlHostName(): string {
|
private getRestUrlHostName(): string {
|
||||||
|
Reference in New Issue
Block a user