Bugfix/improve symbol lookup (#322)
* Improve symbol lookup * Update changelog
This commit is contained in:
parent
d3be6577c8
commit
6386786ac0
@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
- Filtered out positions without any quantity in the positions table
|
- Filtered out positions without any quantity in the positions table
|
||||||
|
- Improved the symbol lookup: allow saving with valid symbol in create or edit transaction dialog
|
||||||
|
|
||||||
## 1.43.0 - 24.08.2021
|
## 1.43.0 - 24.08.2021
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@ import {
|
|||||||
import { REQUEST } from '@nestjs/core';
|
import { REQUEST } from '@nestjs/core';
|
||||||
import { AuthGuard } from '@nestjs/passport';
|
import { AuthGuard } from '@nestjs/passport';
|
||||||
import { StatusCodes, getReasonPhrase } from 'http-status-codes';
|
import { StatusCodes, getReasonPhrase } from 'http-status-codes';
|
||||||
|
import { isEmpty } from 'lodash';
|
||||||
|
|
||||||
import { LookupItem } from './interfaces/lookup-item.interface';
|
import { LookupItem } from './interfaces/lookup-item.interface';
|
||||||
import { SymbolItem } from './interfaces/symbol-item.interface';
|
import { SymbolItem } from './interfaces/symbol-item.interface';
|
||||||
@ -48,6 +49,15 @@ export class SymbolController {
|
|||||||
@Get(':symbol')
|
@Get(':symbol')
|
||||||
@UseGuards(AuthGuard('jwt'))
|
@UseGuards(AuthGuard('jwt'))
|
||||||
public async getPosition(@Param('symbol') symbol): Promise<SymbolItem> {
|
public async getPosition(@Param('symbol') symbol): Promise<SymbolItem> {
|
||||||
return this.symbolService.get(symbol);
|
const result = await this.symbolService.get(symbol);
|
||||||
|
|
||||||
|
if (!result || isEmpty(result)) {
|
||||||
|
throw new HttpException(
|
||||||
|
getReasonPhrase(StatusCodes.NOT_FOUND),
|
||||||
|
StatusCodes.NOT_FOUND
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,13 +15,17 @@ export class SymbolService {
|
|||||||
|
|
||||||
public async get(aSymbol: string): Promise<SymbolItem> {
|
public async get(aSymbol: string): Promise<SymbolItem> {
|
||||||
const response = await this.dataProviderService.get([aSymbol]);
|
const response = await this.dataProviderService.get([aSymbol]);
|
||||||
const { currency, dataSource, marketPrice } = response[aSymbol];
|
const { currency, dataSource, marketPrice } = response[aSymbol] ?? {};
|
||||||
|
|
||||||
return {
|
if (currency && dataSource && marketPrice) {
|
||||||
dataSource,
|
return {
|
||||||
marketPrice,
|
dataSource,
|
||||||
currency: <Currency>(<unknown>currency)
|
marketPrice,
|
||||||
};
|
currency: <Currency>(<unknown>currency)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async lookup(aQuery: string): Promise<{ items: LookupItem[] }> {
|
public async lookup(aQuery: string): Promise<{ items: LookupItem[] }> {
|
||||||
|
@ -11,8 +11,9 @@ import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
|||||||
import { LookupItem } from '@ghostfolio/api/app/symbol/interfaces/lookup-item.interface';
|
import { LookupItem } from '@ghostfolio/api/app/symbol/interfaces/lookup-item.interface';
|
||||||
import { DataService } from '@ghostfolio/client/services/data.service';
|
import { DataService } from '@ghostfolio/client/services/data.service';
|
||||||
import { Currency } from '@prisma/client';
|
import { Currency } from '@prisma/client';
|
||||||
import { Observable, Subject } from 'rxjs';
|
import { EMPTY, Observable, Subject } from 'rxjs';
|
||||||
import {
|
import {
|
||||||
|
catchError,
|
||||||
debounceTime,
|
debounceTime,
|
||||||
distinctUntilChanged,
|
distinctUntilChanged,
|
||||||
startWith,
|
startWith,
|
||||||
@ -49,7 +50,7 @@ export class CreateOrUpdateTransactionDialog implements OnDestroy {
|
|||||||
@Inject(MAT_DIALOG_DATA) public data: CreateOrUpdateTransactionDialogParams
|
@Inject(MAT_DIALOG_DATA) public data: CreateOrUpdateTransactionDialogParams
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
ngOnInit() {
|
public ngOnInit() {
|
||||||
const { currencies, platforms } = this.dataService.fetchInfo();
|
const { currencies, platforms } = this.dataService.fetchInfo();
|
||||||
|
|
||||||
this.currencies = currencies;
|
this.currencies = currencies;
|
||||||
@ -84,17 +85,45 @@ export class CreateOrUpdateTransactionDialog implements OnDestroy {
|
|||||||
this.data.transaction.unitPrice = this.currentMarketPrice;
|
this.data.transaction.unitPrice = this.currentMarketPrice;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public onBlurSymbol() {
|
||||||
|
const symbol = this.searchSymbolCtrl.value;
|
||||||
|
this.updateSymbol(symbol);
|
||||||
|
}
|
||||||
|
|
||||||
public onCancel(): void {
|
public onCancel(): void {
|
||||||
this.dialogRef.close();
|
this.dialogRef.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
public onUpdateSymbol(event: MatAutocompleteSelectedEvent) {
|
public onUpdateSymbol(event: MatAutocompleteSelectedEvent) {
|
||||||
|
this.updateSymbol(event.option.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ngOnDestroy() {
|
||||||
|
this.unsubscribeSubject.next();
|
||||||
|
this.unsubscribeSubject.complete();
|
||||||
|
}
|
||||||
|
|
||||||
|
private updateSymbol(symbol: string) {
|
||||||
this.isLoading = true;
|
this.isLoading = true;
|
||||||
this.data.transaction.symbol = event.option.value;
|
|
||||||
|
this.data.transaction.symbol = symbol;
|
||||||
|
|
||||||
this.dataService
|
this.dataService
|
||||||
.fetchSymbolItem(this.data.transaction.symbol)
|
.fetchSymbolItem(this.data.transaction.symbol)
|
||||||
.pipe(takeUntil(this.unsubscribeSubject))
|
.pipe(
|
||||||
|
catchError(() => {
|
||||||
|
this.data.transaction.currency = null;
|
||||||
|
this.data.transaction.dataSource = null;
|
||||||
|
this.data.transaction.unitPrice = null;
|
||||||
|
|
||||||
|
this.isLoading = false;
|
||||||
|
|
||||||
|
this.changeDetectorRef.markForCheck();
|
||||||
|
|
||||||
|
return EMPTY;
|
||||||
|
}),
|
||||||
|
takeUntil(this.unsubscribeSubject)
|
||||||
|
)
|
||||||
.subscribe(({ currency, dataSource, marketPrice }) => {
|
.subscribe(({ currency, dataSource, marketPrice }) => {
|
||||||
this.data.transaction.currency = currency;
|
this.data.transaction.currency = currency;
|
||||||
this.data.transaction.dataSource = dataSource;
|
this.data.transaction.dataSource = dataSource;
|
||||||
@ -105,17 +134,4 @@ export class CreateOrUpdateTransactionDialog implements OnDestroy {
|
|||||||
this.changeDetectorRef.markForCheck();
|
this.changeDetectorRef.markForCheck();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public onUpdateSymbolByTyping(value: string) {
|
|
||||||
this.data.transaction.currency = null;
|
|
||||||
this.data.transaction.dataSource = null;
|
|
||||||
this.data.transaction.unitPrice = null;
|
|
||||||
|
|
||||||
this.data.transaction.symbol = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ngOnDestroy() {
|
|
||||||
this.unsubscribeSubject.next();
|
|
||||||
this.unsubscribeSubject.complete();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
required
|
required
|
||||||
[formControl]="searchSymbolCtrl"
|
[formControl]="searchSymbolCtrl"
|
||||||
[matAutocomplete]="auto"
|
[matAutocomplete]="auto"
|
||||||
(change)="onUpdateSymbolByTyping($event.target.value)"
|
(blur)="onBlurSymbol()"
|
||||||
/>
|
/>
|
||||||
<mat-autocomplete
|
<mat-autocomplete
|
||||||
#auto="matAutocomplete"
|
#auto="matAutocomplete"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user