diff --git a/lib/core/form/components/widgets/people/people.widget.html b/lib/core/form/components/widgets/people/people.widget.html index 9bf4e0c740..00791451cb 100644 --- a/lib/core/form/components/widgets/people/people.widget.html +++ b/lib/core/form/components/widgets/people/people.widget.html @@ -9,13 +9,13 @@ class="adf-input" type="text" [id]="field.id" + [formControl] ="searchTerm" [value]="getDisplayName(field.value)" - (keyup)="onKeyUp($event)" [disabled]="field.readOnly" placeholder="{{field.placeholder}}" [matAutocomplete]="auto"> - - + +
diff --git a/lib/core/form/components/widgets/people/people.widget.scss b/lib/core/form/components/widgets/people/people.widget.scss index 39303988dd..445645d810 100644 --- a/lib/core/form/components/widgets/people/people.widget.scss +++ b/lib/core/form/components/widgets/people/people.widget.scss @@ -9,22 +9,23 @@ width: 100%; } + &-people-widget-row { + display: flex; + align-items: center; + } + &-people-widget-pic { background: mat-color($primary); - display: inline-block; + display: flex; + justify-content: center; + align-items: center; width: 40px; height: 40px; border-radius: 100px; color: mat-color($foreground, text); - text-align: center; font-weight: bolder; font-size: 18px; text-transform: uppercase; - vertical-align: middle; - } - - &-people-widget-row { - padding-bottom: 10px; } &-people-widget-image { diff --git a/lib/core/form/components/widgets/people/people.widget.spec.ts b/lib/core/form/components/widgets/people/people.widget.spec.ts index a0e064e1f2..fc8523cd67 100644 --- a/lib/core/form/components/widgets/people/people.widget.spec.ts +++ b/lib/core/form/components/widgets/people/people.widget.spec.ts @@ -112,115 +112,6 @@ describe('PeopleWidgetComponent', () => { expect(widget.groupId).toBe(''); }); - it('should fetch users by search term', () => { - let users: any = [{ - id: 'people-id', - firstName: 'John', - lastName: 'Doe' - }, { - id: 'people-id2', - firstName: 'John', - lastName: 'Ping' - }]; - - spyOn(formService, 'getWorkflowUsers').and.returnValue( - Observable.create(observer => { - observer.next(users); - observer.complete(); - }) - ); - fixture.detectChanges(); - - let keyboardEvent = new KeyboardEvent('keypress'); - let input = widget.input; - input.nativeElement.value = 'John'; - widget.onKeyUp(keyboardEvent); - - expect(formService.getWorkflowUsers).toHaveBeenCalledWith('John', widget.groupId); - expect(widget.users).toBe(users); - }); - - it('should fetch users by search term and group id', () => { - let users: any = [{ - id: 'people-id', - firstName: 'John', - lastName: 'Doe' - }, { - id: 'people-id2', - firstName: 'John', - lastName: 'Ping' - }]; - - spyOn(formService, 'getWorkflowUsers').and.returnValue( - Observable.create(observer => { - observer.next(users); - observer.complete(); - }) - ); - fixture.detectChanges(); - - let keyboardEvent = new KeyboardEvent('keypress'); - let input = widget.input; - input.nativeElement.value = 'John'; - widget.groupId = '1001'; - widget.onKeyUp(keyboardEvent); - - expect(formService.getWorkflowUsers).toHaveBeenCalledWith('John', widget.groupId); - expect(widget.users).toBe(users); - }); - - it('should fetch users and show no popup', () => { - spyOn(formService, 'getWorkflowUsers').and.returnValue( - Observable.create(observer => { - observer.next(null); - observer.complete(); - }) - ); - fixture.detectChanges(); - - let keyboardEvent = new KeyboardEvent('keypress'); - let input = widget.input; - input.nativeElement.value = 'user1'; - widget.onKeyUp(keyboardEvent); - - expect(formService.getWorkflowUsers).toHaveBeenCalledWith('user1', widget.groupId); - expect(widget.users).toEqual([]); - }); - - it('should require search term to fetch users', () => { - spyOn(formService, 'getWorkflowUsers').and.stub(); - - let keyboardEvent = new KeyboardEvent('keypress'); - let input = widget.input; - input.nativeElement.value = null; - widget.onKeyUp(keyboardEvent); - - expect(formService.getWorkflowUsers).not.toHaveBeenCalled(); - }); - - it('should not fetch users due to constraint violation', () => { - spyOn(formService, 'getWorkflowUsers').and.stub(); - - let keyboardEvent = new KeyboardEvent('keypress'); - (element.querySelector('input') as HTMLInputElement).value = '123'; - widget.minTermLength = 4; - widget.onKeyUp(keyboardEvent); - - expect(formService.getWorkflowUsers).not.toHaveBeenCalled(); - }); - - it('should reset users when the input field is blank string', () => { - let fakeUser = new UserProcessModel({ id: '1', email: 'ffff@fff' }); - widget.users.push(fakeUser); - fixture.detectChanges(); - - let keyboardEvent = new KeyboardEvent('keypress'); - (element.querySelector('input') as HTMLInputElement).value = ''; - widget.onKeyUp(keyboardEvent); - - expect(widget.users).toEqual([]); - }); - describe('when template is ready', () => { let fakeUserResult = [ diff --git a/lib/core/form/components/widgets/people/people.widget.ts b/lib/core/form/components/widgets/people/people.widget.ts index c29943cada..3449453ef3 100644 --- a/lib/core/form/components/widgets/people/people.widget.ts +++ b/lib/core/form/components/widgets/people/people.widget.ts @@ -19,11 +19,20 @@ import { PeopleProcessService } from '../../../../services/people-process.service'; import { UserProcessModel } from '../../../../models'; -import { ENTER, ESCAPE } from '@angular/cdk/keycodes'; import { Component, ElementRef, OnInit, ViewChild, ViewEncapsulation } from '@angular/core'; import { FormService } from '../../../services/form.service'; import { GroupModel } from '../core/group.model'; import { baseHost, WidgetComponent } from './../widget.component'; +import { FormControl } from '@angular/forms'; +import { Observable } from 'rxjs/Observable'; +import { + catchError, + distinctUntilChanged, + map, + switchMap, + tap +} from 'rxjs/operators'; +import 'rxjs/add/observable/empty'; @Component({ selector: 'people-widget', @@ -37,10 +46,45 @@ export class PeopleWidgetComponent extends WidgetComponent implements OnInit { @ViewChild('inputValue') input: ElementRef; - minTermLength: number = 1; - oldValue: string; - users: UserProcessModel[] = []; groupId: string; + value: any; + + searchTerm = new FormControl(); + errorMsg = ''; + searchTerms$: Observable = this.searchTerm.valueChanges; + + users$ = this.searchTerms$.pipe( + tap(() => { + this.errorMsg = ''; + }), + distinctUntilChanged(), + switchMap((searchTerm) => { + let userResponse = Observable.empty(); + + if (typeof searchTerm === 'string') { + userResponse = this.formService.getWorkflowUsers(searchTerm, this.groupId) + .pipe( + catchError(err => { + this.errorMsg = err.message; + return userResponse; + }) + ); + } + + return userResponse; + }), + map((list: UserProcessModel[]) => { + let value = (this.input.nativeElement as HTMLInputElement).value; + + if (value) { + this.checkUserAndValidateForm(list, value); + } else { + this.field.value = null; + } + + return list; + }) + ); constructor(public formService: FormService, public peopleProcessService: PeopleProcessService) { super(formService); @@ -56,34 +100,12 @@ export class PeopleWidgetComponent extends WidgetComponent implements OnInit { } } - onKeyUp(event: KeyboardEvent) { - let value = (this.input.nativeElement as HTMLInputElement).value; - if (value && value.length >= this.minTermLength && this.oldValue !== value) { - if (event.keyCode !== ESCAPE && event.keyCode !== ENTER) { - if (value.length >= this.minTermLength) { - this.oldValue = value; - this.searchUsers(value); - } - } - } else { - this.validateValue(value); - } - } - - searchUsers(userName: string) { - this.formService.getWorkflowUsers(userName, this.groupId) - .subscribe((result: UserProcessModel[]) => { - this.users = result || []; - this.validateValue(userName); - }); - } - - validateValue(userName: string) { - if (this.isValidUser(userName)) { + checkUserAndValidateForm(list, value) { + const isValidUser = this.isValidUser(list, value); + if (isValidUser) { this.field.validationSummary.message = ''; - } else if (!userName) { - this.field.value = null; - this.users = []; + this.field.validate(); + this.field.form.validateForm(); } else { this.field.validationSummary.message = 'FORM.FIELD.VALIDATOR.INVALID_VALUE'; this.field.markAsInvalid(); @@ -91,17 +113,10 @@ export class PeopleWidgetComponent extends WidgetComponent implements OnInit { } } - isValidUser(value: string): boolean { - let isValid = false; - if (value) { - let resultUser: UserProcessModel = this.users.find((user) => this.getDisplayName(user).toLocaleLowerCase() === value.toLocaleLowerCase()); - - if (resultUser) { - isValid = true; - } - } - - return isValid; + isValidUser(users: UserProcessModel[], name: string) { + return users.find((user) => { + return this.getDisplayName(user).toLocaleLowerCase() === name.toLocaleLowerCase(); + }); } getDisplayName(model: UserProcessModel) { @@ -114,7 +129,7 @@ export class PeopleWidgetComponent extends WidgetComponent implements OnInit { onItemSelect(item: UserProcessModel) { if (item) { - this.field.value = item; + this.field.value = `${item.firstName || ''} ${item.lastName || ''}`; } } }