Your ROOT_URL in app.ini is https://git.cloudchain.link/ but you are visiting https://dash.bss.nz/open-source-mirrors/ghostfolio/commit/6a802a62a0f478d01f1940b425422fa0313628d5
You should set ROOT_URL correctly, otherwise the web may not work correctly.
16 changed files with
132 additions and
32 deletions
@ -5,6 +5,16 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog ](https://keepachangelog.com/en/1.0.0/ ),
and this project adheres to [Semantic Versioning ](https://semver.org/spec/v2.0.0.html ).
## Unreleased
### Added
- Added the ability to add an index for benchmarks as an asset profile in the admin control panel
### Fixed
- Fixed an issue with the clone functionality of a transaction caused by the symbol search component
## 1.283.5 - 2023-06-25
### Added
@ -36,10 +36,12 @@ export class SymbolController {
@UseGuards ( AuthGuard ( 'jwt' ) )
@UseInterceptors ( TransformDataSourceInResponseInterceptor )
public async lookupSymbol (
@Query ( ) { query = '' }
@Query ( 'includeIndices' ) includeIndices : boolean = false ,
@Query ( 'query' ) query = ''
) : Promise < { items : LookupItem [ ] } > {
try {
return this . symbolService . lookup ( {
includeIndices ,
query : query.toLowerCase ( ) ,
user : this.request.user
} ) ;
@ -81,9 +81,11 @@ export class SymbolService {
}
public async lookup ( {
includeIndices = false ,
query ,
user
} : {
includeIndices? : boolean ;
query : string ;
user : UserWithSettings ;
} ) : Promise < { items : LookupItem [ ] } > {
@ -95,6 +97,7 @@ export class SymbolService {
try {
const { items } = await this . dataProviderService . search ( {
includeIndices ,
query ,
user
} ) ;
@ -114,8 +114,14 @@ export class AlphaVantageService implements DataProviderInterface {
return undefined ;
}
public async search ( aQuery : string ) : Promise < { items : LookupItem [ ] } > {
const result = await this . alphaVantage . data . search ( aQuery ) ;
public async search ( {
includeIndices = false ,
query
} : {
includeIndices? : boolean ;
query : string ;
} ) : Promise < { items : LookupItem [ ] } > {
const result = await this . alphaVantage . data . search ( query ) ;
return {
items : result?.bestMatches?.map ( ( bestMatch ) = > {
@ -164,16 +164,17 @@ export class CoinGeckoService implements DataProviderInterface {
return 'bitcoin' ;
}
public async search ( aQuery : string ) : Promise < { items : LookupItem [ ] } > {
public async search ( {
includeIndices = false ,
query
} : {
includeIndices? : boolean ;
query : string ;
} ) : Promise < { items : LookupItem [ ] } > {
let items : LookupItem [ ] = [ ] ;
try {
const get = bent (
` ${ this . URL } /search?query= ${ aQuery } ` ,
'GET' ,
'json' ,
200
) ;
const get = bent ( ` ${ this . URL } /search?query= ${ query } ` , 'GET' , 'json' , 200 ) ;
const { coins } = await get ( ) ;
items = coins . map ( ( { id : symbol , name } ) = > {
@ -367,9 +367,11 @@ export class DataProviderService {
}
public async search ( {
includeIndices = false ,
query ,
user
} : {
includeIndices? : boolean ;
query : string ;
user : UserWithSettings ;
} ) : Promise < { items : LookupItem [ ] } > {
@ -392,7 +394,12 @@ export class DataProviderService {
}
for ( const dataSource of dataSources ) {
promises . push ( this . getDataProvider ( DataSource [ dataSource ] ) . search ( query ) ) ;
promises . push (
this . getDataProvider ( DataSource [ dataSource ] ) . search ( {
includeIndices ,
query
} )
) ;
}
const searchResults = await Promise . all ( promises ) ;
@ -156,7 +156,7 @@ export class EodHistoricalDataService implements DataProviderInterface {
return ! symbol . endsWith ( '.FOREX' ) ;
} )
. map ( ( symbol ) = > {
return this . search ( symbol ) ;
return this . search ( { query : symbol } ) ;
} )
) ;
@ -219,8 +219,14 @@ export class EodHistoricalDataService implements DataProviderInterface {
return 'AAPL.US' ;
}
public async search ( aQuery : string ) : Promise < { items : LookupItem [ ] } > {
const searchResult = await this . getSearchResult ( aQuery ) ;
public async search ( {
includeIndices = false ,
query
} : {
includeIndices? : boolean ;
query : string ;
} ) : Promise < { items : LookupItem [ ] } > {
const searchResult = await this . getSearchResult ( query ) ;
return {
items : searchResult
@ -143,12 +143,18 @@ export class FinancialModelingPrepService implements DataProviderInterface {
return 'AAPL' ;
}
public async search ( aQuery : string ) : Promise < { items : LookupItem [ ] } > {
public async search ( {
includeIndices = false ,
query
} : {
includeIndices? : boolean ;
query : string ;
} ) : Promise < { items : LookupItem [ ] } > {
let items : LookupItem [ ] = [ ] ;
try {
const get = bent (
` ${ this . URL } /search?query= ${ aQuery } &apikey= ${ this . apiKey } ` ,
` ${ this . URL } /search?query= ${ q uery} &apikey= ${ this . apiKey } ` ,
'GET' ,
'json' ,
200
@ -153,7 +153,13 @@ export class GoogleSheetsService implements DataProviderInterface {
return 'INDEXSP:.INX' ;
}
public async search ( aQuery : string ) : Promise < { items : LookupItem [ ] } > {
public async search ( {
includeIndices = false ,
query
} : {
includeIndices? : boolean ;
query : string ;
} ) : Promise < { items : LookupItem [ ] } > {
const items = await this . prismaService . symbolProfile . findMany ( {
select : {
assetClass : true ,
@ -169,14 +175,14 @@ export class GoogleSheetsService implements DataProviderInterface {
dataSource : this.getName ( ) ,
name : {
mode : 'insensitive' ,
startsWith : aQ uery
startsWith : q uery
}
} ,
{
dataSource : this.getName ( ) ,
symbol : {
mode : 'insensitive' ,
startsWith : aQ uery
startsWith : q uery
}
}
]
@ -42,5 +42,11 @@ export interface DataProviderInterface {
getTestSymbol ( ) : string ;
search ( aQuery : string ) : Promise < { items : LookupItem [ ] } > ;
search ( {
includeIndices ,
query
} : {
includeIndices? : boolean ;
query : string ;
} ) : Promise < { items : LookupItem [ ] } > ;
}
@ -171,7 +171,13 @@ export class ManualService implements DataProviderInterface {
return undefined ;
}
public async search ( aQuery : string ) : Promise < { items : LookupItem [ ] } > {
public async search ( {
includeIndices = false ,
query
} : {
includeIndices? : boolean ;
query : string ;
} ) : Promise < { items : LookupItem [ ] } > {
let items = await this . prismaService . symbolProfile . findMany ( {
select : {
assetClass : true ,
@ -187,14 +193,14 @@ export class ManualService implements DataProviderInterface {
dataSource : this.getName ( ) ,
name : {
mode : 'insensitive' ,
startsWith : aQ uery
startsWith : q uery
}
} ,
{
dataSource : this.getName ( ) ,
symbol : {
mode : 'insensitive' ,
startsWith : aQ uery
startsWith : q uery
}
}
]
@ -117,7 +117,13 @@ export class RapidApiService implements DataProviderInterface {
return undefined ;
}
public async search ( aQuery : string ) : Promise < { items : LookupItem [ ] } > {
public async search ( {
includeIndices = false ,
query
} : {
includeIndices? : boolean ;
query : string ;
} ) : Promise < { items : LookupItem [ ] } > {
return { items : [ ] } ;
}
@ -275,11 +275,23 @@ export class YahooFinanceService implements DataProviderInterface {
return 'AAPL' ;
}
public async search ( aQuery : string ) : Promise < { items : LookupItem [ ] } > {
public async search ( {
includeIndices = false ,
query
} : {
includeIndices? : boolean ;
query : string ;
} ) : Promise < { items : LookupItem [ ] } > {
const items : LookupItem [ ] = [ ] ;
try {
const searchResult = await yahooFinance . search ( aQuery ) ;
const quoteTypes = [ 'EQUITY' , 'ETF' , 'FUTURE' , 'MUTUALFUND' ] ;
if ( includeIndices ) {
quoteTypes . push ( 'INDEX' ) ;
}
const searchResult = await yahooFinance . search ( query ) ;
const quotes = searchResult . quotes
. filter ( ( quote ) = > {
@ -295,7 +307,7 @@ export class YahooFinanceService implements DataProviderInterface {
this . baseCurrency
)
) ) ||
[ 'EQUITY' , 'ETF' , 'FUTURE' , 'MUTUALFUND' ] . includes ( quoteType )
quoteTypes . includes ( quoteType )
) ;
} )
. filter ( ( { quoteType , symbol } ) = > {
@ -8,7 +8,10 @@
< div class = "flex-grow-1 py-3" mat-dialog-content >
< mat-form-field appearance = "outline" class = "w-100" >
< mat-label i18n > Name, symbol or ISIN< / mat-label >
< gf-symbol-autocomplete formControlName = "searchSymbol" / >
< gf-symbol-autocomplete
formControlName="searchSymbol"
[includeIndices]="true"
/>
< / mat-form-field >
< / div >
< div class = "d-flex justify-content-end" mat-dialog-actions >
@ -261,9 +261,21 @@ export class DataService {
} ) ;
}
public fetchSymbols ( aQuery : string ) {
public fetchSymbols ( {
includeIndices = false ,
query
} : {
includeIndices? : boolean ;
query : string ;
} ) {
let params = new HttpParams ( ) . set ( 'query' , query ) ;
if ( includeIndices ) {
params = params . append ( 'includeIndices' , includeIndices ) ;
}
return this . http
. get < { items : LookupItem [ ] } > ( ` /api/v1/symbol/lookup?query= ${ aQuery } ` )
. get < { items : LookupItem [ ] } > ( '/api/v1/symbol/lookup' , { params } )
. pipe (
map ( ( respose ) = > {
return respose . items ;
@ -50,6 +50,7 @@ export class SymbolAutocompleteComponent
extends AbstractMatFormField < LookupItem >
implements OnInit , OnDestroy
{
@Input ( ) private includeIndices = false ;
@Input ( ) public isLoading = false ;
@ViewChild ( MatInput , { static : false } ) private input : MatInput ;
@ -94,7 +95,10 @@ export class SymbolAutocompleteComponent
this . changeDetectorRef . markForCheck ( ) ;
} ) ,
switchMap ( ( query : string ) = > {
return this . dataService . fetchSymbols ( query ) ;
return this . dataService . fetchSymbols ( {
query ,
includeIndices : this.includeIndices
} ) ;
} )
)
. subscribe ( ( filteredLookupItems ) = > {
@ -132,7 +136,11 @@ export class SymbolAutocompleteComponent
public ngDoCheck() {
if ( this . ngControl ) {
this . validateRequired ( ) ;
this . validateSelection ( ) ;
if ( this . control . touched ) {
this . validateSelection ( ) ;
}
this . errorState = this . ngControl . invalid && this . ngControl . touched ;
this . stateChanges . next ( ) ;
}