mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-07-24 17:32:15 +00:00
[AAE-6572] Search capability for dropdowns (#7387)
This commit is contained in:
@@ -17,10 +17,13 @@
|
|||||||
[compareWith]="compareDropdownValues"
|
[compareWith]="compareDropdownValues"
|
||||||
(ngModelChange)="selectionChangedForField(field)"
|
(ngModelChange)="selectionChangedForField(field)"
|
||||||
[matTooltip]="field.tooltip"
|
[matTooltip]="field.tooltip"
|
||||||
|
panelClass="adf-select-filter"
|
||||||
matTooltipPosition="above"
|
matTooltipPosition="above"
|
||||||
matTooltipShowDelay="1000"
|
matTooltipShowDelay="1000"
|
||||||
[multiple]="field.hasMultipleValues">
|
[multiple]="field.hasMultipleValues">
|
||||||
<mat-option *ngFor="let opt of field.options"
|
<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]="getOptionValue(opt, field.value)"
|
||||||
[id]="opt.id">{{opt.name}}
|
[id]="opt.id">{{opt.name}}
|
||||||
</mat-option>
|
</mat-option>
|
||||||
|
@@ -19,39 +19,35 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|||||||
import { By } from '@angular/platform-browser';
|
import { By } from '@angular/platform-browser';
|
||||||
import { of } from 'rxjs';
|
import { of } from 'rxjs';
|
||||||
import { DropdownCloudWidgetComponent } from './dropdown-cloud.widget';
|
import { DropdownCloudWidgetComponent } from './dropdown-cloud.widget';
|
||||||
import {
|
import { FormFieldModel, FormModel, FormService, setupTestBed } from '@alfresco/adf-core';
|
||||||
FormService,
|
|
||||||
WidgetVisibilityService,
|
|
||||||
FormFieldOption,
|
|
||||||
setupTestBed,
|
|
||||||
FormFieldModel,
|
|
||||||
FormModel
|
|
||||||
} 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';
|
||||||
import { mockConditionalEntries, mockRestDropdownOptions } from '../../../mocks/linked-dropdown.mock';
|
import {
|
||||||
|
fakeOptionList,
|
||||||
|
filterOptionList,
|
||||||
|
mockConditionalEntries,
|
||||||
|
mockRestDropdownOptions
|
||||||
|
} from '../../../mocks/dropdown.mock';
|
||||||
|
import { OverlayContainer } from '@angular/cdk/overlay';
|
||||||
|
|
||||||
describe('DropdownCloudWidgetComponent', () => {
|
describe('DropdownCloudWidgetComponent', () => {
|
||||||
|
|
||||||
let formService: FormService;
|
let formService: FormService;
|
||||||
let widget: DropdownCloudWidgetComponent;
|
let widget: DropdownCloudWidgetComponent;
|
||||||
let visibilityService: WidgetVisibilityService;
|
|
||||||
let formCloudService: FormCloudService;
|
let formCloudService: FormCloudService;
|
||||||
|
let overlayContainer: OverlayContainer;
|
||||||
let fixture: ComponentFixture<DropdownCloudWidgetComponent>;
|
let fixture: ComponentFixture<DropdownCloudWidgetComponent>;
|
||||||
let element: HTMLElement;
|
let element: HTMLElement;
|
||||||
|
|
||||||
function openSelect(_selector?: string) {
|
async function openSelect(_selector?: string) {
|
||||||
const dropdown: any = element.querySelector('.mat-select-trigger');
|
const dropdown: HTMLElement = element.querySelector('.mat-select-trigger');
|
||||||
dropdown.click();
|
dropdown.click();
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
await fixture.whenStable();
|
||||||
|
fixture.detectChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
const fakeOptionList: FormFieldOption[] = [
|
|
||||||
{ id: 'opt_1', name: 'option_1' },
|
|
||||||
{ id: 'opt_2', name: 'option_2' },
|
|
||||||
{ id: 'opt_3', name: 'option_3' }];
|
|
||||||
|
|
||||||
setupTestBed({
|
setupTestBed({
|
||||||
imports: [
|
imports: [
|
||||||
TranslateModule.forRoot(),
|
TranslateModule.forRoot(),
|
||||||
@@ -65,231 +61,202 @@ describe('DropdownCloudWidgetComponent', () => {
|
|||||||
element = fixture.nativeElement;
|
element = fixture.nativeElement;
|
||||||
|
|
||||||
formService = TestBed.inject(FormService);
|
formService = TestBed.inject(FormService);
|
||||||
visibilityService = TestBed.inject(WidgetVisibilityService);
|
|
||||||
formCloudService = TestBed.inject(FormCloudService);
|
formCloudService = TestBed.inject(FormCloudService);
|
||||||
|
overlayContainer = TestBed.inject(OverlayContainer);
|
||||||
widget.field = new FormFieldModel(new FormModel());
|
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => fixture.destroy());
|
afterEach(() => fixture.destroy());
|
||||||
|
|
||||||
it('should require field with restUrl', () => {
|
describe('Simple Dropdown', () => {
|
||||||
spyOn(formService, 'getRestFieldValues').and.stub();
|
|
||||||
|
|
||||||
widget.field = null;
|
beforeEach(() => {
|
||||||
widget.ngOnInit();
|
spyOn(formService, 'getRestFieldValues').and.callFake(() => {
|
||||||
expect(formService.getRestFieldValues).not.toHaveBeenCalled();
|
return of(fakeOptionList);
|
||||||
|
});
|
||||||
|
widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id' }), {
|
||||||
|
id: 'dropdown-id',
|
||||||
|
name: 'date-name',
|
||||||
|
type: 'dropdown',
|
||||||
|
readOnly: false,
|
||||||
|
restUrl: 'fake-rest-url'
|
||||||
|
});
|
||||||
|
widget.field.emptyOption = { id: 'empty', name: 'Choose one...' };
|
||||||
|
widget.field.isVisible = true;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
widget.field = new FormFieldModel(null, { restUrl: null });
|
it('should require field with restUrl', () => {
|
||||||
widget.ngOnInit();
|
widget.field = new FormFieldModel(new FormModel());
|
||||||
expect(formService.getRestFieldValues).not.toHaveBeenCalled();
|
widget.ngOnInit();
|
||||||
|
expect(formService.getRestFieldValues).not.toHaveBeenCalled();
|
||||||
|
|
||||||
|
widget.field = new FormFieldModel(null, { restUrl: null });
|
||||||
|
widget.ngOnInit();
|
||||||
|
expect(formService.getRestFieldValues).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should select the default value when an option is chosen as default', async () => {
|
||||||
|
widget.field.value = 'option_2';
|
||||||
|
widget.ngOnInit();
|
||||||
|
|
||||||
|
fixture.detectChanges();
|
||||||
|
await fixture.whenStable();
|
||||||
|
|
||||||
|
const dropDownElement: any = element.querySelector('#dropdown-id');
|
||||||
|
expect(dropDownElement.attributes['ng-reflect-model'].value).toBe('option_2');
|
||||||
|
expect(dropDownElement.attributes['ng-reflect-model'].textContent).toBe('option_2');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should select the empty value when no default is chosen', async () => {
|
||||||
|
widget.field.value = 'empty';
|
||||||
|
widget.ngOnInit();
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
await openSelect('#dropdown-id');
|
||||||
|
|
||||||
|
const dropDownElement = element.querySelector('#dropdown-id');
|
||||||
|
expect(dropDownElement.attributes['ng-reflect-model'].value).toBe('empty');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should display tooltip when tooltip is set', async () => {
|
||||||
|
widget.field.tooltip = 'dropdown widget';
|
||||||
|
|
||||||
|
widget.ngOnInit();
|
||||||
|
|
||||||
|
fixture.detectChanges();
|
||||||
|
await fixture.whenStable();
|
||||||
|
|
||||||
|
const dropDownElement: any = element.querySelector('#dropdown-id');
|
||||||
|
const tooltip = dropDownElement.getAttribute('ng-reflect-message');
|
||||||
|
|
||||||
|
expect(tooltip).toEqual(widget.field.tooltip);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should load data from restUrl and populate options', async () => {
|
||||||
|
const jsonDataSpy = spyOn(formCloudService, 'getRestWidgetData').and.returnValue(of(fakeOptionList));
|
||||||
|
widget.field.restUrl = 'fake-rest-url';
|
||||||
|
widget.field.optionType = 'rest';
|
||||||
|
widget.field.restIdProperty = 'name';
|
||||||
|
|
||||||
|
widget.ngOnInit();
|
||||||
|
fixture.detectChanges();
|
||||||
|
await fixture.whenStable();
|
||||||
|
|
||||||
|
const dropdown = fixture.debugElement.query(By.css('mat-select'));
|
||||||
|
dropdown.nativeElement.click();
|
||||||
|
fixture.detectChanges();
|
||||||
|
await fixture.whenStable();
|
||||||
|
|
||||||
|
const optOne = fixture.debugElement.query(By.css('[id="opt_1"]'));
|
||||||
|
const optTwo = fixture.debugElement.query(By.css('[id="opt_2"]'));
|
||||||
|
const optThree = fixture.debugElement.query(By.css('[id="opt_3"]'));
|
||||||
|
const allOptions = fixture.debugElement.queryAll(By.css('mat-option'));
|
||||||
|
|
||||||
|
expect(jsonDataSpy).toHaveBeenCalled();
|
||||||
|
expect(allOptions.length).toEqual(3);
|
||||||
|
expect(optOne.nativeElement.innerText).toEqual('option_1');
|
||||||
|
expect(optTwo.nativeElement.innerText).toEqual('option_2');
|
||||||
|
expect(optThree.nativeElement.innerText).toEqual('option_3');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should preselect dropdown widget value when Json (rest call) passed', async () => {
|
||||||
|
widget.field.restUrl = 'fake-rest-url';
|
||||||
|
widget.field.optionType = 'rest';
|
||||||
|
widget.field.value = {
|
||||||
|
id: 'opt1',
|
||||||
|
name: 'default1_value'
|
||||||
|
};
|
||||||
|
|
||||||
|
spyOn(formCloudService, 'getRestWidgetData').and.returnValue(of([
|
||||||
|
{
|
||||||
|
id: 'opt1',
|
||||||
|
name: 'default1_value'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
name: 'default2_value'
|
||||||
|
}
|
||||||
|
]));
|
||||||
|
|
||||||
|
widget.ngOnInit();
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
await openSelect();
|
||||||
|
|
||||||
|
const option = fixture.debugElement.query(By.css('.mat-option-text'));
|
||||||
|
expect(option.nativeElement.innerText).toBe('default1_value');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should preselect dropdown widget value when String (defined value) passed ', async () => {
|
||||||
|
widget.field.restUrl = 'fake-rest-url';
|
||||||
|
widget.field.optionType = 'rest';
|
||||||
|
widget.field.value = 'opt1';
|
||||||
|
|
||||||
|
spyOn(formCloudService, 'getRestWidgetData').and.returnValue(of([
|
||||||
|
{
|
||||||
|
id: 'opt1',
|
||||||
|
name: 'default1_value'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
name: 'default2_value'
|
||||||
|
}
|
||||||
|
]));
|
||||||
|
|
||||||
|
widget.ngOnInit();
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
await openSelect();
|
||||||
|
const options = fixture.debugElement.queryAll(By.css('.mat-option-text'));
|
||||||
|
expect(options[0].nativeElement.innerText).toBe('default1_value');
|
||||||
|
expect(widget.field.form.values['dropdown-id']).toEqual({id: 'opt1', name: 'default1_value'});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('when template is ready', () => {
|
describe('filter', () => {
|
||||||
|
|
||||||
describe('and dropdown is populated', () => {
|
beforeEach(() => {
|
||||||
|
widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id' }), {
|
||||||
beforeEach(() => {
|
id: 'dropdown-id',
|
||||||
spyOn(visibilityService, 'refreshVisibility').and.stub();
|
name: 'option list',
|
||||||
spyOn(formService, 'getRestFieldValues').and.callFake(() => {
|
type: 'dropdown',
|
||||||
return of(fakeOptionList);
|
readOnly: false,
|
||||||
});
|
options: filterOptionList
|
||||||
widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id' }), {
|
|
||||||
id: 'dropdown-id',
|
|
||||||
name: 'date-name',
|
|
||||||
type: 'dropdown',
|
|
||||||
readOnly: 'false',
|
|
||||||
restUrl: 'fake-rest-url'
|
|
||||||
});
|
|
||||||
widget.field.emptyOption = { id: 'empty', name: 'Choose one...' };
|
|
||||||
widget.field.isVisible = true;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
});
|
||||||
|
widget.ngOnInit();
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
it('should select the default value when an option is chosen as default', async () => {
|
it('should show filter if more than 5 options found', async () => {
|
||||||
widget.field.value = 'option_2';
|
await openSelect();
|
||||||
widget.ngOnInit();
|
const filter = fixture.debugElement.query(By.css('.adf-select-filter-input input'));
|
||||||
|
expect(filter.nativeElement).toBeDefined('Filter is not visible');
|
||||||
|
});
|
||||||
|
|
||||||
fixture.detectChanges();
|
it('should be able to filter the options by search', async () => {
|
||||||
await fixture.whenStable();
|
await openSelect();
|
||||||
|
|
||||||
const dropDownElement: any = element.querySelector('#dropdown-id');
|
let options: HTMLElement[] = Array.from(overlayContainer.getContainerElement().querySelectorAll('mat-option'));
|
||||||
expect(dropDownElement.attributes['ng-reflect-model'].value).toBe('option_2');
|
expect(options.length).toBe(6);
|
||||||
expect(dropDownElement.attributes['ng-reflect-model'].textContent).toBe('option_2');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should select the empty value when no default is chosen', async () => {
|
const filter = fixture.debugElement.query(By.css('.adf-select-filter-input input'));
|
||||||
widget.field.value = 'empty';
|
filter.nativeElement.value = '1';
|
||||||
widget.ngOnInit();
|
filter.nativeElement.dispatchEvent(new Event('input'));
|
||||||
fixture.detectChanges();
|
|
||||||
|
|
||||||
openSelect('#dropdown-id');
|
fixture.detectChanges();
|
||||||
|
options = Array.from(overlayContainer.getContainerElement().querySelectorAll('mat-option'));
|
||||||
|
expect(options.length).toBe(1);
|
||||||
|
expect(options[0].innerText).toEqual('option_1');
|
||||||
|
});
|
||||||
|
|
||||||
fixture.detectChanges();
|
it('should be able to select the options if filter present', async () => {
|
||||||
await fixture.whenStable();
|
await openSelect();
|
||||||
|
|
||||||
const dropDownElement = element.querySelector('#dropdown-id');
|
const options: HTMLElement[] = Array.from(overlayContainer.getContainerElement().querySelectorAll('mat-option'));
|
||||||
expect(dropDownElement.attributes['ng-reflect-model'].value).toBe('empty');
|
expect(options.length).toBe(6);
|
||||||
});
|
options[0].click();
|
||||||
|
expect(widget.field.value).toEqual('opt_1');
|
||||||
it('should display tooltip when tooltip is set', async () => {
|
expect(widget.field.form.values['dropdown-id']).toEqual(filterOptionList[0]);
|
||||||
widget.field.tooltip = 'dropdown widget';
|
|
||||||
|
|
||||||
widget.ngOnInit();
|
|
||||||
|
|
||||||
fixture.detectChanges();
|
|
||||||
await fixture.whenStable();
|
|
||||||
|
|
||||||
const dropDownElement: any = element.querySelector('#dropdown-id');
|
|
||||||
const tooltip = dropDownElement.getAttribute('ng-reflect-message');
|
|
||||||
|
|
||||||
expect(tooltip).toEqual(widget.field.tooltip);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should load data from restUrl and populate options', async () => {
|
|
||||||
const jsonDataSpy = spyOn(formCloudService, 'getRestWidgetData').and.returnValue(of(fakeOptionList));
|
|
||||||
widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id' }), {
|
|
||||||
id: 'dropdown-id',
|
|
||||||
name: 'date-name',
|
|
||||||
type: 'dropdown',
|
|
||||||
readOnly: 'false',
|
|
||||||
restUrl: 'fake-rest-url',
|
|
||||||
optionType: 'rest',
|
|
||||||
restIdProperty: 'name'
|
|
||||||
});
|
|
||||||
|
|
||||||
widget.ngOnInit();
|
|
||||||
fixture.detectChanges();
|
|
||||||
await fixture.whenStable();
|
|
||||||
|
|
||||||
const dropdown = fixture.debugElement.query(By.css('mat-select'));
|
|
||||||
dropdown.nativeElement.click();
|
|
||||||
fixture.detectChanges();
|
|
||||||
await fixture.whenStable();
|
|
||||||
|
|
||||||
const optOne = fixture.debugElement.queryAll(By.css('[id="opt_1"]'));
|
|
||||||
const optTwo = fixture.debugElement.queryAll(By.css('[id="opt_2"]'));
|
|
||||||
const optThree = fixture.debugElement.queryAll(By.css('[id="opt_3"]'));
|
|
||||||
const allOptions = fixture.debugElement.queryAll(By.css('mat-option'));
|
|
||||||
|
|
||||||
expect(jsonDataSpy).toHaveBeenCalled();
|
|
||||||
expect(allOptions.length).toEqual(3);
|
|
||||||
expect(optOne.length).toBe(1);
|
|
||||||
expect(optTwo.length).toBe(1);
|
|
||||||
expect(optThree.length).toBe(1);
|
|
||||||
expect(optOne[0].nativeElement.innerText).toEqual('option_1');
|
|
||||||
expect(optTwo[0].nativeElement.innerText).toEqual('option_2');
|
|
||||||
expect(optThree[0].nativeElement.innerText).toEqual('option_3');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should preselect dropdown widget value when Json (rest call) passed', (done) => {
|
|
||||||
widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id' }), {
|
|
||||||
id: 'dropdown-id',
|
|
||||||
name: 'date-name',
|
|
||||||
type: 'dropdown',
|
|
||||||
readOnly: 'false',
|
|
||||||
restUrl: 'fake-rest-url',
|
|
||||||
optionType: 'rest',
|
|
||||||
value: {
|
|
||||||
id: 'opt1',
|
|
||||||
name: 'defaul_value'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
spyOn(formCloudService, 'getRestWidgetData').and.returnValue(of([
|
|
||||||
{
|
|
||||||
id: 'opt1',
|
|
||||||
name: 'default1_value'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 2,
|
|
||||||
name: 'default2_value'
|
|
||||||
}
|
|
||||||
]));
|
|
||||||
|
|
||||||
widget.ngOnInit();
|
|
||||||
fixture.detectChanges();
|
|
||||||
|
|
||||||
openSelect();
|
|
||||||
fixture.detectChanges();
|
|
||||||
|
|
||||||
fixture.whenStable().then(() => {
|
|
||||||
const options = fixture.debugElement.queryAll(By.css('.mat-option-text'));
|
|
||||||
expect(options[0].nativeElement.innerText).toBe('default1_value');
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should preselect dropdown widget value when String (defined value) passed ', (done) => {
|
|
||||||
widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id' }), {
|
|
||||||
id: 'dropdown-id',
|
|
||||||
name: 'date-name',
|
|
||||||
type: 'dropdown',
|
|
||||||
readOnly: 'false',
|
|
||||||
restUrl: 'fake-rest-url',
|
|
||||||
optionType: 'rest',
|
|
||||||
value: 'opt1'
|
|
||||||
});
|
|
||||||
|
|
||||||
spyOn(formCloudService, 'getRestWidgetData').and.returnValue(of([
|
|
||||||
{
|
|
||||||
id: 'opt1',
|
|
||||||
name: 'default1_value'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 2,
|
|
||||||
name: 'default2_value'
|
|
||||||
}
|
|
||||||
]));
|
|
||||||
|
|
||||||
widget.ngOnInit();
|
|
||||||
fixture.detectChanges();
|
|
||||||
|
|
||||||
openSelect();
|
|
||||||
fixture.detectChanges();
|
|
||||||
|
|
||||||
fixture.whenStable().then(() => {
|
|
||||||
const options = fixture.debugElement.queryAll(By.css('.mat-option-text'));
|
|
||||||
expect(options[0].nativeElement.innerText).toBe('default1_value');
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should update the form values when a preselected value is loaded', (done) => {
|
|
||||||
widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id' }), {
|
|
||||||
id: 'dropdown-id',
|
|
||||||
name: 'date-name',
|
|
||||||
type: 'dropdown',
|
|
||||||
readOnly: 'false',
|
|
||||||
restUrl: 'fake-rest-url',
|
|
||||||
optionType: 'rest',
|
|
||||||
value: 'opt1'
|
|
||||||
});
|
|
||||||
|
|
||||||
spyOn(formCloudService, 'getRestWidgetData').and.returnValue(of([
|
|
||||||
{
|
|
||||||
id: 'opt1',
|
|
||||||
name: 'default1_value'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 2,
|
|
||||||
name: 'default2_value'
|
|
||||||
}
|
|
||||||
]));
|
|
||||||
|
|
||||||
widget.ngOnInit();
|
|
||||||
fixture.detectChanges();
|
|
||||||
|
|
||||||
openSelect();
|
|
||||||
fixture.detectChanges();
|
|
||||||
|
|
||||||
fixture.whenStable().then(() => {
|
|
||||||
const options = fixture.debugElement.queryAll(By.css('.mat-option-text'));
|
|
||||||
expect(options[0].nativeElement.innerText).toBe('default1_value');
|
|
||||||
expect(widget.field.form.values['dropdown-id']).toEqual({id: 'opt1', name: 'default1_value'});
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -315,9 +282,7 @@ describe('DropdownCloudWidgetComponent', () => {
|
|||||||
const selectedPlaceHolder = fixture.debugElement.query(By.css('.mat-select-value-text span'));
|
const selectedPlaceHolder = fixture.debugElement.query(By.css('.mat-select-value-text span'));
|
||||||
expect(selectedPlaceHolder.nativeElement.getInnerHTML()).toEqual('option_1, option_2');
|
expect(selectedPlaceHolder.nativeElement.getInnerHTML()).toEqual('option_1, option_2');
|
||||||
|
|
||||||
openSelect('#dropdown-id');
|
await openSelect('#dropdown-id');
|
||||||
await fixture.whenStable();
|
|
||||||
fixture.detectChanges();
|
|
||||||
|
|
||||||
const options = fixture.debugElement.queryAll(By.css('.mat-selected span'));
|
const options = fixture.debugElement.queryAll(By.css('.mat-selected span'));
|
||||||
expect(Array.from(options).map(({ nativeElement }) => nativeElement.getInnerHTML().trim()))
|
expect(Array.from(options).map(({ nativeElement }) => nativeElement.getInnerHTML().trim()))
|
||||||
@@ -334,9 +299,7 @@ describe('DropdownCloudWidgetComponent', () => {
|
|||||||
options: fakeOptionList
|
options: fakeOptionList
|
||||||
});
|
});
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
openSelect('#dropdown-id');
|
await openSelect('#dropdown-id');
|
||||||
await fixture.whenStable();
|
|
||||||
fixture.detectChanges();
|
|
||||||
|
|
||||||
const optionOne = fixture.debugElement.query(By.css('[id="opt_1"]'));
|
const optionOne = fixture.debugElement.query(By.css('[id="opt_1"]'));
|
||||||
const optionTwo = fixture.debugElement.query(By.css('[id="opt_2"]'));
|
const optionTwo = fixture.debugElement.query(By.css('[id="opt_2"]'));
|
||||||
@@ -377,12 +340,9 @@ describe('DropdownCloudWidgetComponent', () => {
|
|||||||
widget.selectionChangedForField(parentDropdown);
|
widget.selectionChangedForField(parentDropdown);
|
||||||
|
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
openSelect('child-dropdown-id');
|
await openSelect('child-dropdown-id');
|
||||||
fixture.detectChanges();
|
|
||||||
await fixture.whenStable();
|
|
||||||
|
|
||||||
const defaultOption: any = fixture.debugElement.query(By.css('[id="empty"]'));
|
const defaultOption: any = fixture.debugElement.query(By.css('[id="empty"]'));
|
||||||
|
|
||||||
expect(widget.field.options).toEqual([{ 'id': 'empty', 'name': 'Choose one...' }]);
|
expect(widget.field.options).toEqual([{ 'id': 'empty', 'name': 'Choose one...' }]);
|
||||||
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...');
|
||||||
@@ -396,9 +356,7 @@ describe('DropdownCloudWidgetComponent', () => {
|
|||||||
widget.selectionChangedForField(parentDropdown);
|
widget.selectionChangedForField(parentDropdown);
|
||||||
|
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
openSelect('child-dropdown-id');
|
await openSelect('child-dropdown-id');
|
||||||
fixture.detectChanges();
|
|
||||||
await fixture.whenStable();
|
|
||||||
|
|
||||||
const optOne: any = fixture.debugElement.query(By.css('[id="LO"]'));
|
const optOne: any = fixture.debugElement.query(By.css('[id="LO"]'));
|
||||||
const optTwo: any = fixture.debugElement.query(By.css('[id="MA"]'));
|
const optTwo: any = fixture.debugElement.query(By.css('[id="MA"]'));
|
||||||
@@ -433,10 +391,7 @@ describe('DropdownCloudWidgetComponent', () => {
|
|||||||
parentDropdown.value = 'GR';
|
parentDropdown.value = 'GR';
|
||||||
widget.selectionChangedForField(parentDropdown);
|
widget.selectionChangedForField(parentDropdown);
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
openSelect('child-dropdown-id');
|
await openSelect('child-dropdown-id');
|
||||||
|
|
||||||
fixture.detectChanges();
|
|
||||||
await fixture.whenStable();
|
|
||||||
|
|
||||||
const optOne: any = fixture.debugElement.query(By.css('[id="empty"]'));
|
const optOne: any = fixture.debugElement.query(By.css('[id="empty"]'));
|
||||||
const optTwo: any = fixture.debugElement.query(By.css('[id="ATH"]'));
|
const optTwo: any = fixture.debugElement.query(By.css('[id="ATH"]'));
|
||||||
@@ -457,13 +412,9 @@ describe('DropdownCloudWidgetComponent', () => {
|
|||||||
widget.selectionChangedForField(parentDropdown);
|
widget.selectionChangedForField(parentDropdown);
|
||||||
|
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
openSelect('child-dropdown-id');
|
await openSelect('child-dropdown-id');
|
||||||
await fixture.whenStable();
|
|
||||||
fixture.detectChanges();
|
|
||||||
await fixture.whenStable();
|
|
||||||
|
|
||||||
const defaultOption: any = fixture.debugElement.query(By.css('[id="empty"]'));
|
const defaultOption: any = fixture.debugElement.query(By.css('[id="empty"]'));
|
||||||
|
|
||||||
expect(widget.field.options).toEqual([{ 'id': 'empty', 'name': 'Choose one...' }]);
|
expect(widget.field.options).toEqual([{ 'id': 'empty', 'name': 'Choose one...' }]);
|
||||||
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...');
|
||||||
|
@@ -15,20 +15,21 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Component, OnInit, ViewEncapsulation, OnDestroy } from '@angular/core';
|
import { Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
|
||||||
import {
|
import {
|
||||||
WidgetComponent,
|
AppConfigService,
|
||||||
FormService,
|
|
||||||
LogService,
|
|
||||||
FormFieldOption,
|
|
||||||
FormFieldEvent,
|
FormFieldEvent,
|
||||||
FormFieldModel,
|
FormFieldModel,
|
||||||
|
FormFieldOption,
|
||||||
FormFieldTypes,
|
FormFieldTypes,
|
||||||
RuleEntry
|
FormService,
|
||||||
|
LogService,
|
||||||
|
RuleEntry,
|
||||||
|
WidgetComponent
|
||||||
} from '@alfresco/adf-core';
|
} from '@alfresco/adf-core';
|
||||||
import { FormCloudService } from '../../../services/form-cloud.service';
|
import { FormCloudService } from '../../../services/form-cloud.service';
|
||||||
import { Subject } from 'rxjs';
|
import { BehaviorSubject, combineLatest, Observable, of, Subject } from 'rxjs';
|
||||||
import { filter, takeUntil } from 'rxjs/operators';
|
import { filter, map, takeUntil } from 'rxjs/operators';
|
||||||
|
|
||||||
/* tslint:disable:component-selector */
|
/* tslint:disable:component-selector */
|
||||||
|
|
||||||
@@ -56,16 +57,22 @@ export class DropdownCloudWidgetComponent extends WidgetComponent implements OnI
|
|||||||
};
|
};
|
||||||
|
|
||||||
typeId = 'DropdownCloudWidgetComponent';
|
typeId = 'DropdownCloudWidgetComponent';
|
||||||
|
HIDE_FILTER_LIMIT = 5;
|
||||||
|
showInputFilter = false;
|
||||||
|
list$: Observable<FormFieldOption[]>;
|
||||||
|
filter$ = new BehaviorSubject<string>('');
|
||||||
|
|
||||||
protected onDestroy$ = new Subject<boolean>();
|
protected onDestroy$ = new Subject<boolean>();
|
||||||
|
|
||||||
constructor(public formService: FormService,
|
constructor(public formService: FormService,
|
||||||
private formCloudService: FormCloudService,
|
private formCloudService: FormCloudService,
|
||||||
private logService: LogService) {
|
private logService: LogService,
|
||||||
|
private appConfig: AppConfigService) {
|
||||||
super(formService);
|
super(formService);
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
if (this.hasRestUrl() && !this.isLinkedWidget()) {
|
if (this.field.restUrl && !this.isLinkedWidget()) {
|
||||||
this.persistFieldOptionsFromRestApi();
|
this.persistFieldOptionsFromRestApi();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,6 +88,7 @@ export class DropdownCloudWidgetComponent extends WidgetComponent implements OnI
|
|||||||
this.parentValueChanged(valueOfParentWidget);
|
this.parentValueChanged(valueOfParentWidget);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
this.updateOptions();
|
||||||
}
|
}
|
||||||
|
|
||||||
private persistFieldOptionsFromRestApi() {
|
private persistFieldOptionsFromRestApi() {
|
||||||
@@ -90,6 +98,7 @@ export class DropdownCloudWidgetComponent extends WidgetComponent implements OnI
|
|||||||
.pipe(takeUntil(this.onDestroy$))
|
.pipe(takeUntil(this.onDestroy$))
|
||||||
.subscribe((result: FormFieldOption[]) => {
|
.subscribe((result: FormFieldOption[]) => {
|
||||||
this.field.options = result;
|
this.field.options = result;
|
||||||
|
this.updateOptions();
|
||||||
this.field.updateForm();
|
this.field.updateForm();
|
||||||
}, (err) => this.handleError(err));
|
}, (err) => this.handleError(err));
|
||||||
}
|
}
|
||||||
@@ -138,26 +147,24 @@ export class DropdownCloudWidgetComponent extends WidgetComponent implements OnI
|
|||||||
|
|
||||||
private persistFieldOptionsFromManualList(value: string) {
|
private persistFieldOptionsFromManualList(value: string) {
|
||||||
if (this.hasRuleEntries()) {
|
if (this.hasRuleEntries()) {
|
||||||
const rulesEntries = this.getRuleEntries();
|
const rulesEntries = this.field.rule.entries;
|
||||||
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.field.updateForm();
|
this.field.updateForm();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private getRuleEntries(): RuleEntry[] {
|
|
||||||
return this.field.rule.entries;
|
|
||||||
}
|
|
||||||
|
|
||||||
private hasRuleEntries(): boolean {
|
private hasRuleEntries(): boolean {
|
||||||
return !!this.getRuleEntries().length;
|
return !!this.field.rule.entries.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
private addDefaultOption() {
|
private addDefaultOption() {
|
||||||
this.field.options = [DropdownCloudWidgetComponent.DEFAULT_OPTION];
|
this.field.options = [DropdownCloudWidgetComponent.DEFAULT_OPTION];
|
||||||
|
this.updateOptions();
|
||||||
}
|
}
|
||||||
|
|
||||||
selectionChangedForField(field: FormFieldModel) {
|
selectionChangedForField(field: FormFieldModel) {
|
||||||
@@ -174,10 +181,6 @@ export class DropdownCloudWidgetComponent extends WidgetComponent implements OnI
|
|||||||
return event.field.type === FormFieldTypes.DROPDOWN;
|
return event.field.type === FormFieldTypes.DROPDOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
private hasRestUrl(): boolean {
|
|
||||||
return !!this.field?.restUrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
isLinkedWidget(): boolean {
|
isLinkedWidget(): boolean {
|
||||||
return !!this.getLinkedWidgetId();
|
return !!this.getLinkedWidgetId();
|
||||||
}
|
}
|
||||||
@@ -200,7 +203,7 @@ export class DropdownCloudWidgetComponent extends WidgetComponent implements OnI
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (typeof opt1 === 'object' && typeof opt2 === 'object') {
|
if (typeof opt1 === 'object' && typeof opt2 === 'object') {
|
||||||
return opt1.id === opt2.id || opt1.name === opt2.name;
|
return opt1.id === opt2.id || opt1.name === opt2.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
return opt1 === opt2;
|
return opt1 === opt2;
|
||||||
@@ -236,4 +239,18 @@ export class DropdownCloudWidgetComponent extends WidgetComponent implements OnI
|
|||||||
this.onDestroy$.next(true);
|
this.onDestroy$.next(true);
|
||||||
this.onDestroy$.complete();
|
this.onDestroy$.complete();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateOptions(): void {
|
||||||
|
this.showInputFilter = this.field.options.length > this.appConfig.get<number>('form.dropDownFilterLimit', this.HIDE_FILTER_LIMIT);
|
||||||
|
this.list$ = combineLatest([of(this.field.options), this.filter$])
|
||||||
|
.pipe(
|
||||||
|
map(([items, search]) => {
|
||||||
|
if (!search) {
|
||||||
|
return items;
|
||||||
|
}
|
||||||
|
return items.filter(({ name }) => name.toLowerCase().includes(search.toLowerCase()));
|
||||||
|
}),
|
||||||
|
takeUntil(this.onDestroy$)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -83,3 +83,18 @@ export const mockRestDropdownOptions: FormFieldOption[] = [
|
|||||||
{ id: 'LO', name: 'LONDON' },
|
{ id: 'LO', name: 'LONDON' },
|
||||||
{ id: 'MA', name: 'MANCHESTER' }
|
{ id: 'MA', name: 'MANCHESTER' }
|
||||||
];
|
];
|
||||||
|
|
||||||
|
export const fakeOptionList: FormFieldOption[] = [
|
||||||
|
{ id: 'opt_1', name: 'option_1' },
|
||||||
|
{ id: 'opt_2', name: 'option_2' },
|
||||||
|
{ id: 'opt_3', name: 'option_3' }
|
||||||
|
];
|
||||||
|
|
||||||
|
export const filterOptionList = [
|
||||||
|
{ id: 'opt_1', name: 'option_1' },
|
||||||
|
{ id: 'opt_2', name: 'option_2' },
|
||||||
|
{ id: 'opt_3', name: 'option_3' },
|
||||||
|
{ id: 'opt_4', name: 'option_4' },
|
||||||
|
{ id: 'opt_5', name: 'option_5' },
|
||||||
|
{ id: 'opt_6', name: 'option_6' }
|
||||||
|
];
|
Reference in New Issue
Block a user