Broker System for Supercredit
No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.

237 líneas
7.1KB

  1. import {Component, forwardRef, Input, OnInit, ViewChild} from '@angular/core';
  2. import {AuthService} from '../../service/auth.service';
  3. import { debounce } from 'ts-debounce';
  4. import {PeopleModel} from '../../models/people.model';
  5. import {ControlValueAccessor, FormControl, FormGroup, NG_VALUE_ACCESSOR} from '@angular/forms';
  6. import {MultiColumnComboBoxComponent} from '@progress/kendo-angular-dropdowns';
  7. import {Observable, of} from 'rxjs';
  8. import {PercentPipe} from '@angular/common';
  9. import {map} from 'rxjs/operators';
  10. import {PeopleService} from '../../service/people.service';
  11. @Component({
  12. selector: 'app-people-select',
  13. templateUrl: './people-select.component.html',
  14. styleUrls: ['./people-select.component.scss'],
  15. providers: [
  16. {
  17. provide: NG_VALUE_ACCESSOR,
  18. useExisting: forwardRef(() => PeopleSelectComponent),
  19. multi: true
  20. }
  21. ]
  22. })
  23. export class PeopleSelectComponent implements OnInit, ControlValueAccessor {
  24. @Input() disabled = false;
  25. @Input() translateId: true; // always tralsnate user Id, because name is not unique
  26. @Input() width: number;
  27. @Input() initSearch: PeopleModel[];
  28. @Input() formControl: FormControl = new FormControl(); // this is a dummy place holder
  29. @ViewChild('list', {static: true}) public text: MultiColumnComboBoxComponent;
  30. public searchResult: PeopleModel[] = [];
  31. public value = ''; // selecting the default and only empty contact element // TODO: remove ngModel
  32. public total = 0;
  33. private debounceFilter: any ;
  34. // Function to call when the rating changes.
  35. private onChange = ( nameOrId: string) => {};
  36. // Function to call when the input is touched (when a star is clicked).
  37. private onTouched = () => {};
  38. constructor(private auth: AuthService, private ps: PeopleService) { }
  39. ngOnInit(): void {
  40. this.prepareSearchPeople();
  41. this.initSearchResult();
  42. }
  43. private initSearchResult(): void {
  44. this.initSearch.forEach( v => {
  45. this.searchResult.push(v);
  46. });
  47. this.total = this.initSearch.length;
  48. }
  49. private prepareSearchPeople(): void{
  50. this.debounceFilter = debounce( (filter: string): void => {
  51. this.auth.getPeopleList(filter).subscribe(
  52. resp => {
  53. this.text.loading = false;
  54. this.searchResult = resp.List;
  55. this.total = resp.Count;
  56. },
  57. error => { this.text.loading = false; },
  58. () => { this.text.loading = false; }
  59. );
  60. }, 500) ;
  61. }
  62. getEffectiveField(): string {
  63. return this.translateId ? 'Id' : 'Display';
  64. }
  65. filterChange(filter: string): void {
  66. if ( filter.length > 0 ) {
  67. this.text.loading = true;
  68. this.debounceFilter(filter); // conduct search even if filter is empty
  69. }
  70. }
  71. public getContactImageUrl(contactId: string): string {
  72. return this.auth.getUrl('avatar/' + contactId);
  73. }
  74. // ComboBox emit event on value change
  75. public valueChange(str: string): void {
  76. return;
  77. console.log('value change', str);
  78. this.onChange(this.value);
  79. }
  80. // public selectionChange(value: PeopleModel): void {
  81. // this.onTouched();
  82. // console.log('selectionChange', value);
  83. // this.value = this.translateId ? value.Id : value.FullName;
  84. // this.onChange(this.value);
  85. // }
  86. // public open(): void {
  87. // this.onTouched();
  88. // // console.log('open', this.text);
  89. // }
  90. //
  91. // public close(): void {
  92. // this.onTouched();
  93. // // console.log('close', this.text);
  94. // }
  95. //
  96. // public focus(): void {
  97. // this.onTouched();
  98. // // console.log('focus', this.text);
  99. // }
  100. //
  101. // public blur(): void {
  102. // // console.log('blur', this.text);
  103. // }
  104. // Allows Angular to update the model (name or ID).
  105. // Update the model and changes needed for the view here.
  106. writeValue(nameOrId: string): void {
  107. if ( nameOrId === undefined ){
  108. console.log('who called me for write', this);
  109. return;
  110. }
  111. const changed = nameOrId !== this.value;
  112. if (this.needSearch(nameOrId) ){
  113. this.text.loading = true;
  114. console.log('searching ... ', nameOrId, this.translateId ? 'by id' : 'by name');
  115. this.searchUser(nameOrId, this.translateId).subscribe(
  116. ppl => {
  117. const person = new PeopleModel(
  118. ppl.Id,
  119. ppl.First,
  120. ppl.Last,
  121. ppl.Middle,
  122. ppl.Title,
  123. ppl.Display,
  124. ppl.Nick
  125. );
  126. console.log('got search result ', person);
  127. this.searchResult.push(person); // make sure it's available for selection, thus proper display
  128. this.value = this.translateId ? person.Id : person.FullName;
  129. console.log('before update', this.text.value);
  130. this.text.value = this.value;
  131. console.log('after update', this.text.value);
  132. }, error => { console.error(error); this.text.loading = false; },
  133. () => {this.text.loading = false; }
  134. );
  135. if ( changed ) {
  136. this.onChange(nameOrId);
  137. }
  138. }
  139. }
  140. needSearch(incoming: string ): boolean {
  141. if ( incoming === undefined || incoming === '' || incoming === this.value ) {
  142. return false;
  143. }
  144. const idx = this.searchResult.findIndex( person => {
  145. if ( this.translateId) {
  146. return person.Id === incoming;
  147. }else{
  148. return person.FullName.includes(incoming);
  149. }
  150. });
  151. return idx === -1; // not found need search
  152. }
  153. // Search a user either based on partial name or a complete ID
  154. searchUser(nameOrId: string, translateId: boolean): Observable<PeopleModel>{
  155. if ( translateId ) {
  156. return this.ps.searchById(nameOrId);
  157. // return this.searchPersonById( nameOrId) ;
  158. }else{
  159. // return this.ps.searchById(nameOrId);
  160. // return this.searchPersonByName(nameOrId) ;
  161. }
  162. }
  163. // searchPersonByName(name: string): Observable<PeopleModel>{
  164. // return new Observable ( observer => {
  165. // const dummy: PeopleModel = new PeopleModel(
  166. // 'dummy-id',
  167. // 'FSearch',
  168. // 'LResult',
  169. // '',
  170. // 'Mr.',
  171. // 'Display Name',
  172. // 'Nick Name'
  173. // );
  174. // setTimeout(() => {
  175. // observer.next(dummy);
  176. // observer.complete();
  177. // }, 1000);
  178. // });
  179. // }
  180. //
  181. // searchPersonById( id: string): Observable<PeopleModel> {
  182. // return new Observable ( observer => {
  183. // const dummy: PeopleModel = new PeopleModel(
  184. // id,
  185. // 'FSearch',
  186. // 'LResult',
  187. // '',
  188. // 'Mr.',
  189. // 'P:' + id,
  190. // 'Nick Name'
  191. // );
  192. // setTimeout(() => {
  193. // observer.next(dummy);
  194. // observer.complete();
  195. // }, 1000);
  196. // });
  197. // }
  198. // Allows Angular to register a function to call when the model (rating) changes.
  199. // Save the function as a property to call later here.
  200. registerOnChange(fn: (nameOrId: string) => void): void {
  201. this.onChange = fn;
  202. }
  203. // Allows Angular to register a function to call when the input has been touched.
  204. // Save the function as a property to call later here.
  205. registerOnTouched(fn: () => void): void {
  206. this.onTouched = fn;
  207. }
  208. // Allows Angular to disable the input.
  209. setDisabledState(isDisabled: boolean): void {
  210. this.disabled = isDisabled;
  211. }
  212. }