|
@ -36,11 +36,12 @@ import { |
|
|
import { MatInput, MatInputModule } from '@angular/material/input'; |
|
|
import { MatInput, MatInputModule } from '@angular/material/input'; |
|
|
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; |
|
|
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; |
|
|
import { isString } from 'lodash'; |
|
|
import { isString } from 'lodash'; |
|
|
import { Subject, tap } from 'rxjs'; |
|
|
import { combineLatest, Subject, tap } from 'rxjs'; |
|
|
import { |
|
|
import { |
|
|
debounceTime, |
|
|
debounceTime, |
|
|
distinctUntilChanged, |
|
|
distinctUntilChanged, |
|
|
filter, |
|
|
filter, |
|
|
|
|
|
startWith, |
|
|
switchMap, |
|
|
switchMap, |
|
|
takeUntil |
|
|
takeUntil |
|
|
} from 'rxjs/operators'; |
|
|
} from 'rxjs/operators'; |
|
@ -79,7 +80,8 @@ export class GfSymbolAutocompleteComponent |
|
|
implements OnChanges, OnDestroy, OnInit |
|
|
implements OnChanges, OnDestroy, OnInit |
|
|
{ |
|
|
{ |
|
|
@Input() public defaultLookupItems: LookupItem[] = []; |
|
|
@Input() public defaultLookupItems: LookupItem[] = []; |
|
|
@Input() public isLoading = false; |
|
|
@Input() public isLoadingLocal = false; |
|
|
|
|
|
@Input() public isLoadingRemote = false; |
|
|
|
|
|
|
|
|
@ViewChild('symbolAutocomplete') public symbolAutocomplete: MatAutocomplete; |
|
|
@ViewChild('symbolAutocomplete') public symbolAutocomplete: MatAutocomplete; |
|
|
|
|
|
|
|
@ -88,8 +90,8 @@ export class GfSymbolAutocompleteComponent |
|
|
@ViewChild(MatInput) private input: MatInput; |
|
|
@ViewChild(MatInput) private input: MatInput; |
|
|
|
|
|
|
|
|
public control = new FormControl(); |
|
|
public control = new FormControl(); |
|
|
public lookupItems: (LookupItem & { assetSubClassString: string })[] = []; |
|
|
public filteredLookupItems: (LookupItem & { assetSubClassString: string })[] = |
|
|
|
|
|
[]; |
|
|
private unsubscribeSubject = new Subject<void>(); |
|
|
private unsubscribeSubject = new Subject<void>(); |
|
|
|
|
|
|
|
|
public constructor( |
|
|
public constructor( |
|
@ -129,29 +131,53 @@ export class GfSymbolAutocompleteComponent |
|
|
return isString(query); |
|
|
return isString(query); |
|
|
}), |
|
|
}), |
|
|
tap(() => { |
|
|
tap(() => { |
|
|
this.isLoading = true; |
|
|
this.isLoadingRemote = true; |
|
|
|
|
|
this.isLoadingLocal = true; |
|
|
|
|
|
|
|
|
this.changeDetectorRef.markForCheck(); |
|
|
this.changeDetectorRef.markForCheck(); |
|
|
}), |
|
|
}), |
|
|
debounceTime(400), |
|
|
debounceTime(400), |
|
|
distinctUntilChanged(), |
|
|
distinctUntilChanged(), |
|
|
takeUntil(this.unsubscribeSubject), |
|
|
takeUntil(this.unsubscribeSubject), |
|
|
switchMap((query: string) => { |
|
|
switchMap((query: string) => |
|
|
return this.dataService.fetchSymbols({ |
|
|
combineLatest([ |
|
|
query, |
|
|
this.dataService |
|
|
includeIndices: this.includeIndices |
|
|
.fetchPortfolioLookup({ |
|
|
}); |
|
|
query |
|
|
}) |
|
|
}) |
|
|
|
|
|
.pipe(startWith(undefined)), |
|
|
|
|
|
this.dataService |
|
|
|
|
|
.fetchSymbols({ |
|
|
|
|
|
query, |
|
|
|
|
|
includeIndices: this.includeIndices |
|
|
|
|
|
}) |
|
|
|
|
|
.pipe(startWith(undefined)) |
|
|
|
|
|
]) |
|
|
|
|
|
) |
|
|
) |
|
|
) |
|
|
.subscribe((filteredLookupItems) => { |
|
|
.subscribe((filteredLookupItems) => { |
|
|
this.lookupItems = filteredLookupItems.map((lookupItem) => { |
|
|
const [localItems, remoteItems]: [LookupItem[], LookupItem[]] = |
|
|
|
|
|
filteredLookupItems; |
|
|
|
|
|
const uniqueItems = [ |
|
|
|
|
|
...new Map( |
|
|
|
|
|
(localItems ?? []) |
|
|
|
|
|
.concat(remoteItems ?? []) |
|
|
|
|
|
.map((item) => [item.symbol, item]) |
|
|
|
|
|
).values() |
|
|
|
|
|
]; |
|
|
|
|
|
this.filteredLookupItems = uniqueItems.map((lookupItem) => { |
|
|
return { |
|
|
return { |
|
|
...lookupItem, |
|
|
...lookupItem, |
|
|
assetSubClassString: translate(lookupItem.assetSubClass) |
|
|
assetSubClassString: translate(lookupItem.assetSubClass) |
|
|
}; |
|
|
}; |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
this.isLoading = false; |
|
|
if (localItems !== undefined) { |
|
|
|
|
|
this.isLoadingLocal = false; |
|
|
|
|
|
} |
|
|
|
|
|
if (remoteItems !== undefined) { |
|
|
|
|
|
this.isLoadingRemote = false; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
this.changeDetectorRef.markForCheck(); |
|
|
this.changeDetectorRef.markForCheck(); |
|
|
}); |
|
|
}); |
|
@ -176,7 +202,7 @@ export class GfSymbolAutocompleteComponent |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
public isValueInOptions(value: string) { |
|
|
public isValueInOptions(value: string) { |
|
|
return this.lookupItems.some((item) => { |
|
|
return this.filteredLookupItems.some((item) => { |
|
|
return item.symbol === value; |
|
|
return item.symbol === value; |
|
|
}); |
|
|
}); |
|
|
} |
|
|
} |
|
@ -209,7 +235,7 @@ export class GfSymbolAutocompleteComponent |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
private showDefaultOptions() { |
|
|
private showDefaultOptions() { |
|
|
this.lookupItems = this.defaultLookupItems.map((lookupItem) => { |
|
|
this.filteredLookupItems = this.defaultLookupItems.map((lookupItem) => { |
|
|
return { |
|
|
return { |
|
|
...lookupItem, |
|
|
...lookupItem, |
|
|
assetSubClassString: translate(lookupItem.assetSubClass) |
|
|
assetSubClassString: translate(lookupItem.assetSubClass) |
|
|