|
- import {Component, forwardRef, Input, OnInit, ViewChild} from '@angular/core';
- import {AuthService} from '../service/auth.service';
- import { debounce } from 'ts-debounce';
- import {PeopleModel} from '../models/people.model';
- import {ControlValueAccessor, FormControl, FormGroup, NG_VALUE_ACCESSOR} from '@angular/forms';
- import {MultiColumnComboBoxComponent} from '@progress/kendo-angular-dropdowns';
- import {Observable} from 'rxjs';
- import {PeopleService} from '../service/people.service';
-
- @Component({
- selector: 'app-people-select',
- templateUrl: './people-select.component.html',
- styleUrls: ['./people-select.component.scss'],
- providers: [
- {
- provide: NG_VALUE_ACCESSOR,
- useExisting: forwardRef(() => PeopleSelectComponent),
- multi: true
- }
- ]
- })
- export class PeopleSelectComponent implements OnInit, ControlValueAccessor {
-
- @Input() disabled = false;
- @Input() translateId: true; // always tralsnate user Id, because name is not unique
- @Input() width: number;
- @Input() initSearch: PeopleModel[];
- @Input() formControl: FormControl = new FormControl(); // this is a dummy place holder
- @ViewChild('list', {static: true}) public text: MultiColumnComboBoxComponent;
-
- public searchResult: PeopleModel[] = [];
- public value = ''; // selecting the default and only empty contact element // TODO: remove ngModel
- public total = 0;
-
- private debounceFilter: any ;
-
- // Function to call when the rating changes.
- private onChange = ( nameOrId: string) => {};
- // Function to call when the input is touched (when a star is clicked).
- private onTouched = () => {};
-
-
- constructor(private auth: AuthService, private ps: PeopleService) { }
-
- ngOnInit(): void {
- this.prepareSearchPeople();
- this.initSearchResult();
- }
-
- private initSearchResult(): void {
- this.initSearch.forEach( v => {
- this.searchResult.push(v);
- });
- this.total = this.initSearch.length;
- }
-
- private prepareSearchPeople(): void{
- this.debounceFilter = debounce( (filter: string): void => {
- this.ps.getPeopleList(filter).subscribe(
- resp => {
- this.text.loading = false;
- this.searchResult = resp.List;
- this.total = resp.Count;
- },
- error => { this.text.loading = false; },
- () => { this.text.loading = false; }
- );
- }, 500) ;
- }
-
- getEffectiveField(): string {
- return this.translateId ? 'Id' : 'Display';
- }
-
- filterChange(filter: string): void {
- if ( filter.length > 0 ) {
- this.text.loading = true;
- this.debounceFilter(filter); // conduct search even if filter is empty
- }
- }
-
- public getContactImageUrl(contactId: string): string {
- return this.auth.getUrl('avatar/' + contactId);
- }
-
- // ComboBox emit event on value change
- public valueChange(str: string): void {
- return;
- console.log('value change', str);
- this.onChange(this.value);
- }
-
- // public selectionChange(value: PeopleModel): void {
- // this.onTouched();
- // console.log('selectionChange', value);
- // this.value = this.translateId ? value.Id : value.FullName;
- // this.onChange(this.value);
- // }
-
- // public open(): void {
- // this.onTouched();
- // // console.log('open', this.text);
- // }
- //
- // public close(): void {
- // this.onTouched();
- // // console.log('close', this.text);
- // }
- //
- // public focus(): void {
- // this.onTouched();
- // // console.log('focus', this.text);
- // }
- //
- // public blur(): void {
- // // console.log('blur', this.text);
- // }
-
- // Allows Angular to update the model (name or ID).
- // Update the model and changes needed for the view here.
- writeValue(nameOrId: string): void {
- if ( nameOrId === undefined ){
- console.log('who called me for write', this);
- return;
- }
- const changed = nameOrId !== this.value;
- if (this.needSearch(nameOrId) ){
- this.text.loading = true;
- console.log('searching ... ', nameOrId, this.translateId ? 'by id' : 'by name');
- this.searchUser(nameOrId, this.translateId).subscribe(
- ppl => {
- const person = new PeopleModel(
- ppl.Id,
- ppl.First,
- ppl.Last,
- ppl.Middle,
- ppl.Title,
- ppl.Display,
- ppl.Nick,
- ppl.Enabled
- );
- console.log('got search result ', person);
- this.searchResult.push(person); // make sure it's available for selection, thus proper display
- this.value = this.translateId ? person.Id : person.FullName;
- console.log('before update', this.text.value);
- this.text.value = this.value;
- console.log('after update', this.text.value);
- }, error => { console.error(error); this.text.loading = false; },
- () => {this.text.loading = false; }
- );
- if ( changed ) {
- this.onChange(nameOrId);
- }
- }
- }
-
- needSearch(incoming: string ): boolean {
- if ( incoming === undefined || incoming === '' || incoming === this.value ) {
- return false;
- }
-
- const idx = this.searchResult.findIndex( person => {
- if ( this.translateId) {
- return person.Id === incoming;
- }else{
- return person.FullName.includes(incoming);
- }
- });
-
- return idx === -1; // not found need search
- }
-
- // Search a user either based on partial name or a complete ID
- searchUser(nameOrId: string, translateId: boolean): Observable<PeopleModel>{
- if ( translateId ) {
- return this.ps.getPeopleById(nameOrId);
- // return this.searchPersonById( nameOrId) ;
- }else{
- // return this.ps.searchById(nameOrId);
- // return this.searchPersonByName(nameOrId) ;
- }
- }
-
- // searchPersonByName(name: string): Observable<PeopleModel>{
- // return new Observable ( observer => {
- // const dummy: PeopleModel = new PeopleModel(
- // 'dummy-id',
- // 'FSearch',
- // 'LResult',
- // '',
- // 'Mr.',
- // 'Display Name',
- // 'Nick Name'
- // );
- // setTimeout(() => {
- // observer.next(dummy);
- // observer.complete();
- // }, 1000);
- // });
- // }
- //
- // searchPersonById( id: string): Observable<PeopleModel> {
- // return new Observable ( observer => {
- // const dummy: PeopleModel = new PeopleModel(
- // id,
- // 'FSearch',
- // 'LResult',
- // '',
- // 'Mr.',
- // 'P:' + id,
- // 'Nick Name'
- // );
- // setTimeout(() => {
- // observer.next(dummy);
- // observer.complete();
- // }, 1000);
- // });
- // }
-
- // Allows Angular to register a function to call when the model (rating) changes.
- // Save the function as a property to call later here.
- registerOnChange(fn: (nameOrId: string) => void): void {
- this.onChange = fn;
- }
- // Allows Angular to register a function to call when the input has been touched.
- // Save the function as a property to call later here.
- registerOnTouched(fn: () => void): void {
- this.onTouched = fn;
- }
- // Allows Angular to disable the input.
- setDisabledState(isDisabled: boolean): void {
- this.disabled = isDisabled;
- }
-
- }
|