mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-10-08 14:51:32 +00:00
AAE-22947 Update dropdown-cloud.widget
This commit is contained in:
@@ -7,8 +7,8 @@
|
||||
</div>
|
||||
<div>
|
||||
<mat-form-field>
|
||||
<mat-label *ngIf="getDefaultOption(list$ | async) as defaultOption">
|
||||
{{ defaultOption.name }}
|
||||
<mat-label *ngIf="getEmptyValueOption(list$ | async) as emptyValueOption">
|
||||
{{ emptyValueOption.name }}
|
||||
</mat-label>
|
||||
<mat-select class="adf-select"
|
||||
[id]="field.id"
|
||||
@@ -26,7 +26,7 @@
|
||||
<adf-select-filter-input *ngIf="showInputFilter" (change)="filter$.next($event)"></adf-select-filter-input>
|
||||
|
||||
<mat-option *ngFor="let opt of list$ | async"
|
||||
[value]="getOptionValue(opt, field.value)"
|
||||
[value]="opt"
|
||||
[id]="opt.id">{{opt.name}}
|
||||
</mat-option>
|
||||
<mat-option id="readonlyOption" *ngIf="isReadOnlyType()" [value]="field.value">{{field.value}}</mat-option>
|
||||
|
@@ -179,10 +179,10 @@ describe('DropdownCloudWidgetComponent', () => {
|
||||
expect(await (await dropdown.getOptions())[0].getText()).toEqual('default1_value');
|
||||
});
|
||||
|
||||
it('should preselect dropdown widget value when String (defined value) passed ', async () => {
|
||||
it('should preselect dropdown widget value when value matches one of the fetched options', async () => {
|
||||
widget.field.restUrl = 'https://fake-rest-url';
|
||||
widget.field.optionType = 'rest';
|
||||
widget.field.value = 'opt1';
|
||||
widget.field.value = { id: 'opt1', name: 'default1_value' };
|
||||
|
||||
spyOn(formCloudService, 'getRestWidgetData').and.returnValue(
|
||||
of([
|
||||
@@ -245,7 +245,7 @@ describe('DropdownCloudWidgetComponent', () => {
|
||||
await dropdown.clickOptions({ selector: '[id="opt_1"]' });
|
||||
|
||||
expect(await dropdown.getValueText()).toEqual('option_1');
|
||||
expect(widget.fieldValue).toEqual('opt_1');
|
||||
expect(widget.fieldValue).toEqual({ id: 'opt_1', name: 'option_1' });
|
||||
|
||||
await dropdown.open();
|
||||
await dropdown.clickOptions({ selector: '[id="empty"]' });
|
||||
@@ -254,8 +254,8 @@ describe('DropdownCloudWidgetComponent', () => {
|
||||
const dropdownLabel = await formField.getLabel();
|
||||
|
||||
expect(dropdownLabel).toEqual('This is a mock none option');
|
||||
expect(widget.fieldValue).toEqual(undefined);
|
||||
expect(await dropdown.getValueText()).toEqual('');
|
||||
expect(widget.fieldValue).toEqual({ id: 'empty', name: 'This is a mock none option' });
|
||||
expect(await dropdown.getValueText()).toEqual('This is a mock none option');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -344,6 +344,22 @@ describe('DropdownCloudWidgetComponent', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('should NOT display a required error when dropdown is readonly', async () => {
|
||||
widget.field.readOnly = true;
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
expect(element.querySelector('.adf-invalid')).toBeFalsy();
|
||||
|
||||
const dropdownSelect = element.querySelector('.adf-select');
|
||||
dropdownSelect.dispatchEvent(new Event('blur'));
|
||||
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
expect(element.querySelector('.adf-invalid')).toBeFalsy();
|
||||
});
|
||||
|
||||
describe('filter', () => {
|
||||
beforeEach(() => {
|
||||
widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id', readOnly: false }), {
|
||||
@@ -432,7 +448,7 @@ describe('DropdownCloudWidgetComponent', () => {
|
||||
});
|
||||
|
||||
it('should show preselected option for rest options', async () => {
|
||||
widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id', readOnly: 'false' }), {
|
||||
widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id', readOnly: false }), {
|
||||
id: 'dropdown-id',
|
||||
name: 'date-name',
|
||||
type: 'dropdown',
|
||||
@@ -471,7 +487,7 @@ describe('DropdownCloudWidgetComponent', () => {
|
||||
});
|
||||
|
||||
it('should support multiple options for rest options', async () => {
|
||||
widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id', readOnly: 'false' }), {
|
||||
widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id', readOnly: false }), {
|
||||
id: 'dropdown-id',
|
||||
name: 'date-name',
|
||||
type: 'dropdown',
|
||||
|
@@ -31,7 +31,7 @@ import { BehaviorSubject, combineLatest, Observable, of, Subject } from 'rxjs';
|
||||
import { filter, map, takeUntil } from 'rxjs/operators';
|
||||
import { TaskVariableCloud } from '../../../models/task-variable-cloud.model';
|
||||
|
||||
export const DEFAULT_OPTION = {
|
||||
export const DEFAULT_OPTION: FormFieldOption = {
|
||||
id: 'empty',
|
||||
name: 'Choose one...'
|
||||
};
|
||||
@@ -218,16 +218,18 @@ export class DropdownCloudWidgetComponent extends WidgetComponent implements OnI
|
||||
private buildBodyParam(): any {
|
||||
const bodyParam = Object.assign({});
|
||||
if (this.isLinkedWidget()) {
|
||||
const parentWidgetValue = this.getParentWidgetValue();
|
||||
const parentWidgetSelectedOption = this.getParentWidgetSelectedOption();
|
||||
const parentWidgetSelectedOptionId = this.field.isEmptyValueOption(parentWidgetSelectedOption) ? null : parentWidgetSelectedOption.id;
|
||||
|
||||
const parentWidgetId = this.getLinkedWidgetId();
|
||||
bodyParam[parentWidgetId] = parentWidgetValue;
|
||||
bodyParam[parentWidgetId] = parentWidgetSelectedOptionId;
|
||||
}
|
||||
return bodyParam;
|
||||
}
|
||||
|
||||
private loadFieldOptionsForLinkedWidget() {
|
||||
const parentWidgetValue = this.getParentWidgetValue();
|
||||
this.parentValueChanged(parentWidgetValue);
|
||||
const parentWidgetSelectedOption = this.getParentWidgetSelectedOption();
|
||||
this.parentValueChanged(parentWidgetSelectedOption);
|
||||
|
||||
this.formService.formFieldValueChanged
|
||||
.pipe(
|
||||
@@ -240,16 +242,16 @@ export class DropdownCloudWidgetComponent extends WidgetComponent implements OnI
|
||||
});
|
||||
}
|
||||
|
||||
private getParentWidgetValue(): string {
|
||||
private getParentWidgetSelectedOption(): FormFieldOption {
|
||||
const parentWidgetId = this.getLinkedWidgetId();
|
||||
const parentWidget = this.getFormFieldById(parentWidgetId);
|
||||
return parentWidget?.value;
|
||||
}
|
||||
|
||||
private parentValueChanged(value: string) {
|
||||
if (value && !this.isNoneValueSelected(value)) {
|
||||
private parentValueChanged(value: FormFieldOption) {
|
||||
if (value && !this.isEmptyValueOption(value)) {
|
||||
this.isValidRestType() ? this.persistFieldOptionsFromRestApi() : this.persistFieldOptionsFromManualList(value);
|
||||
} else if (this.isNoneValueSelected(value)) {
|
||||
} else if (this.isEmptyValueOption(value)) {
|
||||
this.resetRestApiErrorMessage();
|
||||
this.resetOptions();
|
||||
this.resetInvalidValue();
|
||||
@@ -259,19 +261,23 @@ export class DropdownCloudWidgetComponent extends WidgetComponent implements OnI
|
||||
}
|
||||
}
|
||||
|
||||
private isNoneValueSelected(value: string): boolean {
|
||||
return value === undefined;
|
||||
private isEmptyValueOptionSelected(): boolean {
|
||||
return this.isEmptyValueOption(this.field.value);
|
||||
}
|
||||
|
||||
private isEmptyValueOption(value: FormFieldOption): boolean {
|
||||
return this.field.isEmptyValueOption(value);
|
||||
}
|
||||
|
||||
private getFormFieldById(fieldId): FormFieldModel {
|
||||
return this.field.form.getFormFields().filter((field: FormFieldModel) => field.id === fieldId)[0];
|
||||
}
|
||||
|
||||
private persistFieldOptionsFromManualList(value: string) {
|
||||
private persistFieldOptionsFromManualList(option: FormFieldOption) {
|
||||
if (this.hasRuleEntries()) {
|
||||
const rulesEntries = this.field.rule.entries;
|
||||
rulesEntries.forEach((ruleEntry: RuleEntry) => {
|
||||
if (ruleEntry.key === value) {
|
||||
if (ruleEntry.key === option.id) {
|
||||
this.field.options = ruleEntry.options;
|
||||
this.resetInvalidValue();
|
||||
this.field.updateForm();
|
||||
@@ -287,7 +293,7 @@ export class DropdownCloudWidgetComponent extends WidgetComponent implements OnI
|
||||
}
|
||||
|
||||
private resetValue() {
|
||||
this.field.value = '';
|
||||
this.field.value = null;
|
||||
this.selectionChangedForField(this.field);
|
||||
this.updateOptions();
|
||||
this.field.updateForm();
|
||||
@@ -298,16 +304,15 @@ export class DropdownCloudWidgetComponent extends WidgetComponent implements OnI
|
||||
}
|
||||
|
||||
private isSelectedValueInOptions(): boolean {
|
||||
if (Array.isArray(this.fieldValue)) {
|
||||
const optionIdList = [...this.field.options].map((option) => option.id);
|
||||
const fieldValueIds = this.fieldValue.map((valueOption) => valueOption.id);
|
||||
return fieldValueIds.every((valueOptionId) => optionIdList.includes(valueOptionId));
|
||||
} else {
|
||||
return [...this.field.options].map((option) => option.id).includes(this.fieldValue);
|
||||
}
|
||||
const selectedOptions: FormFieldOption[] = Array.isArray(this.fieldValue) ? this.fieldValue : [this.fieldValue];
|
||||
|
||||
return selectedOptions.every((selectedOption) => {
|
||||
const isIncludedInOptions = this.field.options.some((option) => option.id === selectedOption.id);
|
||||
return isIncludedInOptions;
|
||||
});
|
||||
}
|
||||
|
||||
get fieldValue(): string {
|
||||
get fieldValue(): FormFieldOption {
|
||||
return this.field.value;
|
||||
}
|
||||
|
||||
@@ -342,40 +347,12 @@ export class DropdownCloudWidgetComponent extends WidgetComponent implements OnI
|
||||
return this.field?.rule?.ruleOn;
|
||||
}
|
||||
|
||||
compareDropdownValues(opt1: FormFieldOption | string, opt2: FormFieldOption | string): boolean {
|
||||
compareDropdownValues(opt1: FormFieldOption, opt2: FormFieldOption): boolean {
|
||||
if (!opt1 || !opt2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (typeof opt1 === 'string' && typeof opt2 === 'object') {
|
||||
return opt1 === opt2.id || opt1 === opt2.name;
|
||||
}
|
||||
|
||||
if (typeof opt1 === 'object' && typeof opt2 === 'string') {
|
||||
return opt1.id === opt2 || opt1.name === opt2;
|
||||
}
|
||||
|
||||
if (typeof opt1 === 'object' && typeof opt2 === 'object') {
|
||||
return opt1.id === opt2.id || opt1.name === opt2.name;
|
||||
}
|
||||
|
||||
return opt1 === opt2;
|
||||
}
|
||||
|
||||
getOptionValue(option: FormFieldOption, fieldValue: string): string | FormFieldOption {
|
||||
if (this.field.hasMultipleValues) {
|
||||
return option;
|
||||
}
|
||||
|
||||
let optionValue: string = '';
|
||||
if (option.id === DEFAULT_OPTION.id) {
|
||||
optionValue = undefined;
|
||||
} else if (option.name !== fieldValue) {
|
||||
optionValue = option.id;
|
||||
} else {
|
||||
optionValue = option.name;
|
||||
}
|
||||
return optionValue;
|
||||
return opt1.id === opt2.id && opt1.name === opt2.name;
|
||||
}
|
||||
|
||||
private isValidRestType(): boolean {
|
||||
@@ -404,11 +381,6 @@ export class DropdownCloudWidgetComponent extends WidgetComponent implements OnI
|
||||
return this.field.type === 'readonly';
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.onDestroy$.next(true);
|
||||
this.onDestroy$.complete();
|
||||
}
|
||||
|
||||
updateOptions(): void {
|
||||
if (this.isReadOnly()) {
|
||||
this.list$ = of(this.field.options);
|
||||
@@ -448,14 +420,22 @@ export class DropdownCloudWidgetComponent extends WidgetComponent implements OnI
|
||||
|
||||
showRequiredMessage(): boolean {
|
||||
return (
|
||||
(this.isInvalidFieldRequired() || (this.isNoneValueSelected(this.field.value) && this.isRequired())) &&
|
||||
(this.isInvalidFieldRequired() || (this.isEmptyValueOptionSelected() && this.isRequired())) &&
|
||||
this.isTouched() &&
|
||||
!this.isRestApiFailed &&
|
||||
!this.variableOptionsFailed
|
||||
);
|
||||
}
|
||||
|
||||
getDefaultOption(options: FormFieldOption[]): FormFieldOption {
|
||||
return options.find((option: FormFieldOption) => option.id === DEFAULT_OPTION.id);
|
||||
getEmptyValueOption(options: FormFieldOption[]): null | FormFieldOption {
|
||||
if (!this.field.hasEmptyValue) {
|
||||
return null;
|
||||
}
|
||||
return options.find((option: FormFieldOption) => this.field.isEmptyValueOption(option));
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.onDestroy$.next(true);
|
||||
this.onDestroy$.complete();
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user