Broker System for Supercredit
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

236 行
7.0KB

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