|
@ -8,6 +8,7 @@ import { |
|
|
} from '@angular/core'; |
|
|
} from '@angular/core'; |
|
|
import { FormBuilder, FormControl, Validators } from '@angular/forms'; |
|
|
import { FormBuilder, FormControl, Validators } from '@angular/forms'; |
|
|
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; |
|
|
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; |
|
|
|
|
|
import { MatSnackBar } from '@angular/material/snack-bar'; |
|
|
import { UpdateAssetProfileDto } from '@ghostfolio/api/app/admin/update-asset-profile.dto'; |
|
|
import { UpdateAssetProfileDto } from '@ghostfolio/api/app/admin/update-asset-profile.dto'; |
|
|
import { AdminService } from '@ghostfolio/client/services/admin.service'; |
|
|
import { AdminService } from '@ghostfolio/client/services/admin.service'; |
|
|
import { DataService } from '@ghostfolio/client/services/data.service'; |
|
|
import { DataService } from '@ghostfolio/client/services/data.service'; |
|
@ -52,14 +53,16 @@ export class AssetProfileDialog implements OnDestroy, OnInit { |
|
|
comment: '', |
|
|
comment: '', |
|
|
name: ['', Validators.required], |
|
|
name: ['', Validators.required], |
|
|
scraperConfiguration: '', |
|
|
scraperConfiguration: '', |
|
|
symbolMapping: '' |
|
|
symbolMapping: '', |
|
|
|
|
|
historicalData: this.formBuilder.group({ |
|
|
|
|
|
csvString: '' |
|
|
|
|
|
}) |
|
|
}); |
|
|
}); |
|
|
public assetProfileSubClass: string; |
|
|
public assetProfileSubClass: string; |
|
|
public benchmarks: Partial<SymbolProfile>[]; |
|
|
public benchmarks: Partial<SymbolProfile>[]; |
|
|
public countries: { |
|
|
public countries: { |
|
|
[code: string]: { name: string; value: number }; |
|
|
[code: string]: { name: string; value: number }; |
|
|
}; |
|
|
}; |
|
|
public historicalDataAsCsvString: string; |
|
|
|
|
|
public isBenchmark = false; |
|
|
public isBenchmark = false; |
|
|
public marketDataDetails: MarketData[] = []; |
|
|
public marketDataDetails: MarketData[] = []; |
|
|
public sectors: { |
|
|
public sectors: { |
|
@ -78,7 +81,8 @@ export class AssetProfileDialog implements OnDestroy, OnInit { |
|
|
@Inject(MAT_DIALOG_DATA) public data: AssetProfileDialogParams, |
|
|
@Inject(MAT_DIALOG_DATA) public data: AssetProfileDialogParams, |
|
|
private dataService: DataService, |
|
|
private dataService: DataService, |
|
|
public dialogRef: MatDialogRef<AssetProfileDialog>, |
|
|
public dialogRef: MatDialogRef<AssetProfileDialog>, |
|
|
private formBuilder: FormBuilder |
|
|
private formBuilder: FormBuilder, |
|
|
|
|
|
private snackBar: MatSnackBar |
|
|
) {} |
|
|
) {} |
|
|
|
|
|
|
|
|
public ngOnInit(): void { |
|
|
public ngOnInit(): void { |
|
@ -88,9 +92,6 @@ export class AssetProfileDialog implements OnDestroy, OnInit { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
public initialize() { |
|
|
public initialize() { |
|
|
this.historicalDataAsCsvString = |
|
|
|
|
|
AssetProfileDialog.HISTORICAL_DATA_TEMPLATE; |
|
|
|
|
|
|
|
|
|
|
|
this.adminService |
|
|
this.adminService |
|
|
.fetchAdminMarketDataBySymbol({ |
|
|
.fetchAdminMarketDataBySymbol({ |
|
|
dataSource: this.data.dataSource, |
|
|
dataSource: this.data.dataSource, |
|
@ -135,7 +136,10 @@ export class AssetProfileDialog implements OnDestroy, OnInit { |
|
|
scraperConfiguration: JSON.stringify( |
|
|
scraperConfiguration: JSON.stringify( |
|
|
this.assetProfile?.scraperConfiguration ?? {} |
|
|
this.assetProfile?.scraperConfiguration ?? {} |
|
|
), |
|
|
), |
|
|
symbolMapping: JSON.stringify(this.assetProfile?.symbolMapping ?? {}) |
|
|
symbolMapping: JSON.stringify(this.assetProfile?.symbolMapping ?? {}), |
|
|
|
|
|
historicalData: { |
|
|
|
|
|
csvString: AssetProfileDialog.HISTORICAL_DATA_TEMPLATE |
|
|
|
|
|
} |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
this.assetProfileForm.markAsPristine(); |
|
|
this.assetProfileForm.markAsPristine(); |
|
@ -163,26 +167,34 @@ export class AssetProfileDialog implements OnDestroy, OnInit { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
public onImportHistoricalData() { |
|
|
public onImportHistoricalData() { |
|
|
const marketData = csvToJson(this.historicalDataAsCsvString, { |
|
|
try { |
|
|
dynamicTyping: true, |
|
|
const marketData = csvToJson( |
|
|
header: true, |
|
|
this.assetProfileForm.controls['historicalData'].controls['csvString'] |
|
|
skipEmptyLines: true |
|
|
.value, |
|
|
}).data; |
|
|
{ |
|
|
|
|
|
dynamicTyping: true, |
|
|
this.adminService |
|
|
header: true, |
|
|
.postMarketData({ |
|
|
skipEmptyLines: true |
|
|
dataSource: this.data.dataSource, |
|
|
} |
|
|
marketData: { |
|
|
).data; |
|
|
marketData: marketData.map(({ date, marketPrice }) => { |
|
|
|
|
|
return { marketPrice, date: parseDate(date).toISOString() }; |
|
|
this.adminService |
|
|
}) |
|
|
.postMarketData({ |
|
|
}, |
|
|
dataSource: this.data.dataSource, |
|
|
symbol: this.data.symbol |
|
|
marketData: { |
|
|
}) |
|
|
marketData: marketData.map(({ date, marketPrice }) => { |
|
|
.pipe(takeUntil(this.unsubscribeSubject)) |
|
|
return { marketPrice, date: parseDate(date).toISOString() }; |
|
|
.subscribe(() => { |
|
|
}) |
|
|
this.initialize(); |
|
|
}, |
|
|
}); |
|
|
symbol: this.data.symbol |
|
|
|
|
|
}) |
|
|
|
|
|
.pipe(takeUntil(this.unsubscribeSubject)) |
|
|
|
|
|
.subscribe(() => { |
|
|
|
|
|
this.initialize(); |
|
|
|
|
|
}); |
|
|
|
|
|
} catch (err) { |
|
|
|
|
|
this.snackBar.open('Unable to parse data', undefined, { duration: 3000 }); |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
public onMarketDataChanged(withRefresh: boolean = false) { |
|
|
public onMarketDataChanged(withRefresh: boolean = false) { |
|
|