From 21d7a8aec2fb82cf98d103697760cb2eb3074102 Mon Sep 17 00:00:00 2001 From: bbcodrin Date: Wed, 12 Sep 2018 16:21:44 +0300 Subject: [PATCH] autocomplete component added (#3701) --- .../adf/process_services/processListPage.js | 2 +- .../adf/process_services/startProcessPage.js | 4 +- .../process_filters_component.e2e.ts | 2 + .../components/start-process.component.html | 26 +++++------ .../start-process.component.spec.ts | 36 +++++++++------ .../components/start-process.component.ts | 44 +++++++++++++++++-- 6 files changed, 81 insertions(+), 33 deletions(-) diff --git a/e2e/pages/adf/process_services/processListPage.js b/e2e/pages/adf/process_services/processListPage.js index 0365ce5466..bd6fedab95 100644 --- a/e2e/pages/adf/process_services/processListPage.js +++ b/e2e/pages/adf/process_services/processListPage.js @@ -26,7 +26,7 @@ var ProcessListPage = function () { var processListTitle = element(by.css("p[class='adf-empty-content__title']")); var processListSubtitle = element(by.css("p[class='adf-empty-content__subtitle']")); var processDetailsMessage = element(by.css("adf-process-instance-details div[class='ng-star-inserted']")); - var openProcessDropdown = element(by.css('mat-select[aria-label="Select Process"]')); + var openProcessDropdown = element(by.css("input[aria-label='Number']")); var selectProcessDropdown = element.all(by.css('span[class="mat-option-text"]')); var startProcessButton = element(by.css('button[data-automation-id="btn-start"]')); diff --git a/e2e/pages/adf/process_services/startProcessPage.js b/e2e/pages/adf/process_services/startProcessPage.js index 655ce185bd..f2ca9023fe 100644 --- a/e2e/pages/adf/process_services/startProcessPage.js +++ b/e2e/pages/adf/process_services/startProcessPage.js @@ -21,8 +21,8 @@ var StartProcessPage = function () { var defaultProcessName = element(by.css("input[id='processName']")); var processNameInput = element(by.id('processName')); - var selectProcessDropdownArrow = element(by.css("div[class='mat-select-arrow-wrapper'] div")); - var cancelProcessButton = element(by.id('cancle_process')); + var selectProcessDropdownArrow = element(by.css("input[aria-label='Number']")); + var cancelProcessButton = element(by.id('cancel_process')); var formStartProcessButton = element(by.css('button[data-automation-id="adf-form-start process"]')); var startProcessButton = element(by.css("button[data-automation-id='btn-start']")); var noProcess = element(by.id('no-process-message')); diff --git a/e2e/process-services/process_filters_component.e2e.ts b/e2e/process-services/process_filters_component.e2e.ts index 2ce219762a..c570e41fad 100644 --- a/e2e/process-services/process_filters_component.e2e.ts +++ b/e2e/process-services/process_filters_component.e2e.ts @@ -106,6 +106,8 @@ describe('Process Filters Test', () => { startProcessPage.selectFromProcessDropdown(app.process_title); startProcessPage.clickFormStartProcessButton(); + processFiltersPage.clickRunningFilterButton(); + processFiltersPage.checkFilterIsHighlighted(processFilter.running); processFiltersPage.selectFromProcessList(processTitle.running); diff --git a/lib/process-services/process-list/components/start-process.component.html b/lib/process-services/process-list/components/start-process.component.html index 151b745ab9..013ebd04e0 100644 --- a/lib/process-services/process-list/components/start-process.component.html +++ b/lib/process-services/process-list/components/start-process.component.html @@ -9,27 +9,25 @@ -
- - - {{'ADF_PROCESS_LIST.START_PROCESS.FORM.TYPE_PLACEHOLDER' | translate}} - - {{ processDef.name }} - - - -
+ + + + {{'ADF_PROCESS_LIST.START_PROCESS.FORM.TYPE_PLACEHOLDER' | translate}} + + {{ processDef.name }} + + + - - + @@ -37,7 +35,7 @@ - + diff --git a/lib/process-services/process-list/components/start-process.component.spec.ts b/lib/process-services/process-list/components/start-process.component.spec.ts index 02f1c29d72..d65f145738 100644 --- a/lib/process-services/process-list/components/start-process.component.spec.ts +++ b/lib/process-services/process-list/components/start-process.component.spec.ts @@ -143,7 +143,7 @@ describe('StartFormComponent', () => { }); })); - it('should have start button disabled if the process is not seleted', async(() => { + it('should have start button disabled if the process is not selected', async(() => { component.name = 'My new process'; fixture.detectChanges(); fixture.whenStable().then(() => { @@ -154,7 +154,7 @@ describe('StartFormComponent', () => { it('should emit cancel event on cancel Button', async(() => { fixture.detectChanges(); - let cancelButton = fixture.nativeElement.querySelector('#cancle_process'); + let cancelButton = fixture.nativeElement.querySelector('#cancel_process'); let cancelSpy: jasmine.Spy = spyOn(component.cancel, 'emit'); cancelButton.click(); fixture.detectChanges(); @@ -222,8 +222,7 @@ describe('StartFormComponent', () => { component.ngOnChanges({}); fixture.detectChanges(); - let selectElement = fixture.nativeElement.querySelector('mat-select'); - expect(selectElement.children.length).toBe(1); + expect(component.processDefinitions.length).toBe(2); }); it('should display the option def details', () => { @@ -232,7 +231,7 @@ describe('StartFormComponent', () => { component.processDefinitions = testMultipleProcessDefs; fixture.detectChanges(); fixture.whenStable().then(() => { - let selectElement = fixture.nativeElement.querySelector('mat-select > .mat-select-trigger'); + let selectElement = fixture.nativeElement.querySelector('mat-autocomplete'); let optionElement = fixture.nativeElement.querySelectorAll('mat-option'); selectElement.click(); expect(selectElement).not.toBeNull(); @@ -242,7 +241,7 @@ describe('StartFormComponent', () => { }); }); - it('should indicate an error to the user if process defs cannot be loaded', async(() => { + it('should indicate an error to the user if process definitions cannot be loaded', async(() => { getDefinitionsSpy = getDefinitionsSpy.and.returnValue(throwError({})); component.appId = 123; component.ngOnChanges({}); @@ -279,7 +278,7 @@ describe('StartFormComponent', () => { }); })); - it('should select automatically the processDefinition if the app contain oly one', async(() => { + it('should select automatically the processDefinition if the app contain only one', async(() => { getDefinitionsSpy = getDefinitionsSpy.and.returnValue(of(testProcessDefinitions)); component.appId = 123; component.ngOnChanges({}); @@ -289,6 +288,17 @@ describe('StartFormComponent', () => { }); })); + it('should have start button enabled when process is selected', async(() => { + component.selectedProcessDef = testProcessDefRepr; + component.name = 'My process'; + fixture.detectChanges(); + fixture.whenStable().then(() => { + fixture.detectChanges(); + let startBtn = fixture.nativeElement.querySelector('#button-start'); + expect(startBtn.disabled).toBe(false); + }); + })); + describe('dropdown', () => { it('should hide the process dropdown if showSelectProcessDropdown is false', async(() => { @@ -298,12 +308,12 @@ describe('StartFormComponent', () => { component.ngOnChanges({}); fixture.detectChanges(); fixture.whenStable().then(() => { - let selectElement = fixture.nativeElement.querySelector('mat-select > .mat-select-trigger'); + let selectElement = fixture.nativeElement.querySelector('mat-autocomplete'); expect(selectElement).toBeNull(); }); })); - it('should show the process dropdown if showSelectProcessDropdown is false', async(() => { + it('should show the process dropdown if showSelectProcessDropdown is true', async(() => { getDefinitionsSpy = getDefinitionsSpy.and.returnValue(of(testMultipleProcessDefs)); component.appId = 123; component.processDefinitionName = 'My Process 2'; @@ -311,7 +321,7 @@ describe('StartFormComponent', () => { component.ngOnChanges({}); fixture.detectChanges(); fixture.whenStable().then(() => { - let selectElement = fixture.nativeElement.querySelector('mat-select > .mat-select-trigger'); + let selectElement = fixture.nativeElement.querySelector('mat-autocomplete'); expect(selectElement).not.toBeNull(); }); })); @@ -323,7 +333,7 @@ describe('StartFormComponent', () => { component.ngOnChanges({}); fixture.detectChanges(); fixture.whenStable().then(() => { - let selectElement = fixture.nativeElement.querySelector('mat-select > .mat-select-trigger'); + let selectElement = fixture.nativeElement.querySelector('mat-autocomplete'); expect(selectElement).not.toBeNull(); }); })); @@ -351,7 +361,7 @@ describe('StartFormComponent', () => { }); })); - it('should get current processDeff', () => { + it('should get current processDef', () => { component.appId = 456; component.ngOnChanges({ appId: change }); fixture.detectChanges(); @@ -392,7 +402,7 @@ describe('StartFormComponent', () => { }); })); - it('should call service to start process with the variables setted', async(() => { + it('should call service to start process with the variables set up', async(() => { let inputProcessVariable: ProcessInstanceVariable[] = []; let variable: ProcessInstanceVariable = {}; diff --git a/lib/process-services/process-list/components/start-process.component.ts b/lib/process-services/process-list/components/start-process.component.ts index 27f7965b3e..869ccb6030 100644 --- a/lib/process-services/process-list/components/start-process.component.ts +++ b/lib/process-services/process-list/components/start-process.component.ts @@ -15,7 +15,7 @@ * limitations under the License. */ -import { Component, EventEmitter, Input, OnChanges, +import { Component, EventEmitter, Input, AfterViewInit, OnChanges, Output, SimpleChanges, ViewChild, ViewEncapsulation } from '@angular/core'; import { ActivitiContentService, AppConfigService, AppConfigValues, @@ -26,6 +26,9 @@ import { ProcessDefinitionRepresentation } from './../models/process-definition. import { ProcessInstance } from './../models/process-instance.model'; import { ProcessService } from './../services/process.service'; import { AttachFileWidgetComponent, AttachFolderWidgetComponent } from '../../content-widget'; +import { FormControl } from '@angular/forms'; +import { Observable } from 'rxjs'; +import { map, startWith, delay } from 'rxjs/operators'; @Component({ selector: 'adf-start-process', @@ -33,7 +36,7 @@ import { AttachFileWidgetComponent, AttachFolderWidgetComponent } from '../../co styleUrls: ['./start-process.component.scss'], encapsulation: ViewEncapsulation.None }) -export class StartProcessInstanceComponent implements OnChanges { +export class StartProcessInstanceComponent implements AfterViewInit, OnChanges { /** (optional) Limit the list of processes that can be started to those * contained in the specified app. @@ -84,6 +87,9 @@ export class StartProcessInstanceComponent implements OnChanges { errorMessageId: string = ''; + processControl = new FormControl(); + filteredOptions: Observable; + constructor(private activitiProcess: ProcessService, private formRenderingService: FormRenderingService, private activitiContentService: ActivitiContentService, @@ -92,6 +98,17 @@ export class StartProcessInstanceComponent implements OnChanges { this.formRenderingService.setComponentTypeResolver('select-folder', () => AttachFolderWidgetComponent, true); } + ngAfterViewInit() { + setTimeout(() => { + this.filteredOptions = this.processControl.valueChanges + .pipe( + startWith(''), + delay(0), + map(value => this._filter(value)) + ); + }); + } + ngOnChanges(changes: SimpleChanges) { if (changes['values'] && changes['values'].currentValue) { this.moveNodeFromCStoPS(); @@ -100,6 +117,23 @@ export class StartProcessInstanceComponent implements OnChanges { this.loadStartProcess(); } + private _filter(value) { + let filterValue = ''; + if (value && value.name) { + filterValue = value.name.toLowerCase(); + } else if (value) { + filterValue = value.toLowerCase(); + } + let processDefArray = this.processDefinitions.filter(option => option.name.toLowerCase() === filterValue); + this.selectedProcessDef = processDefArray.length ? processDefArray[0] : null; + + return this.processDefinitions.filter(option => option.name.toLowerCase().includes(filterValue)); + } + + displayFn(processDef): string { + return processDef ? processDef.name : ''; + } + public loadStartProcess() { this.resetSelectedProcessDefinition(); this.resetErrorMessage(); @@ -217,6 +251,10 @@ export class StartProcessInstanceComponent implements OnChanges { } hasProcessName(): boolean { - return this.name ? true : false; + return !!this.name; + } + + onItemSelect(item) { + this.selectedProcessDef = item; } }