Feature/add support to edit currency of asset profile with data source manual (#2789)
* Add support to edit currency * Update changelog
This commit is contained in:
parent
01b6c14bcc
commit
e465f1b791
@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
## Unreleased
|
||||
|
||||
### Added
|
||||
|
||||
- Added support to edit the currency of asset profiles with `MANUAL` data source in the asset profile details dialog of the admin control panel
|
||||
|
||||
### Changed
|
||||
|
||||
- Changed the performance calculation to a time-weighted approach
|
||||
|
@ -321,6 +321,7 @@ export class AdminService {
|
||||
assetClass,
|
||||
assetSubClass,
|
||||
comment,
|
||||
currency,
|
||||
dataSource,
|
||||
name,
|
||||
scraperConfiguration,
|
||||
@ -331,6 +332,7 @@ export class AdminService {
|
||||
assetClass,
|
||||
assetSubClass,
|
||||
comment,
|
||||
currency,
|
||||
dataSource,
|
||||
name,
|
||||
scraperConfiguration,
|
||||
|
@ -14,6 +14,10 @@ export class UpdateAssetProfileDto {
|
||||
@IsOptional()
|
||||
comment?: string;
|
||||
|
||||
@IsString()
|
||||
@IsOptional()
|
||||
currency?: string;
|
||||
|
||||
@IsString()
|
||||
@IsOptional()
|
||||
name?: string;
|
||||
|
@ -89,6 +89,7 @@ export class SymbolProfileService {
|
||||
assetClass,
|
||||
assetSubClass,
|
||||
comment,
|
||||
currency,
|
||||
dataSource,
|
||||
name,
|
||||
scraperConfiguration,
|
||||
@ -100,6 +101,7 @@ export class SymbolProfileService {
|
||||
assetClass,
|
||||
assetSubClass,
|
||||
comment,
|
||||
currency,
|
||||
name,
|
||||
scraperConfiguration,
|
||||
symbolMapping
|
||||
|
@ -15,6 +15,7 @@ import { DataService } from '@ghostfolio/client/services/data.service';
|
||||
import { DATE_FORMAT, parseDate } from '@ghostfolio/common/helper';
|
||||
import {
|
||||
AdminMarketDataDetails,
|
||||
Currency,
|
||||
UniqueAsset
|
||||
} from '@ghostfolio/common/interfaces';
|
||||
import { translate } from '@ghostfolio/ui/i18n';
|
||||
@ -51,6 +52,7 @@ export class AssetProfileDialog implements OnDestroy, OnInit {
|
||||
assetClass: new FormControl<AssetClass>(undefined),
|
||||
assetSubClass: new FormControl<AssetSubClass>(undefined),
|
||||
comment: '',
|
||||
currency: '',
|
||||
historicalData: this.formBuilder.group({
|
||||
csvString: ''
|
||||
}),
|
||||
@ -63,6 +65,7 @@ export class AssetProfileDialog implements OnDestroy, OnInit {
|
||||
public countries: {
|
||||
[code: string]: { name: string; value: number };
|
||||
};
|
||||
public currencies: Currency[] = [];
|
||||
public isBenchmark = false;
|
||||
public marketDataDetails: MarketData[] = [];
|
||||
public sectors: {
|
||||
@ -86,7 +89,13 @@ export class AssetProfileDialog implements OnDestroy, OnInit {
|
||||
) {}
|
||||
|
||||
public ngOnInit(): void {
|
||||
this.benchmarks = this.dataService.fetchInfo().benchmarks;
|
||||
const { benchmarks, currencies } = this.dataService.fetchInfo();
|
||||
|
||||
this.benchmarks = benchmarks;
|
||||
this.currencies = currencies.map((currency) => ({
|
||||
label: currency,
|
||||
value: currency
|
||||
}));
|
||||
|
||||
this.initialize();
|
||||
}
|
||||
@ -132,6 +141,7 @@ export class AssetProfileDialog implements OnDestroy, OnInit {
|
||||
assetClass: this.assetProfile.assetClass ?? null,
|
||||
assetSubClass: this.assetProfile.assetSubClass ?? null,
|
||||
comment: this.assetProfile?.comment ?? '',
|
||||
currency: this.assetProfile?.currency,
|
||||
historicalData: {
|
||||
csvString: AssetProfileDialog.HISTORICAL_DATA_TEMPLATE
|
||||
},
|
||||
@ -245,12 +255,15 @@ export class AssetProfileDialog implements OnDestroy, OnInit {
|
||||
} catch {}
|
||||
|
||||
const assetProfileData: UpdateAssetProfileDto = {
|
||||
scraperConfiguration,
|
||||
symbolMapping,
|
||||
assetClass: this.assetProfileForm.controls['assetClass'].value,
|
||||
assetSubClass: this.assetProfileForm.controls['assetSubClass'].value,
|
||||
comment: this.assetProfileForm.controls['comment'].value ?? null,
|
||||
name: this.assetProfileForm.controls['name'].value,
|
||||
scraperConfiguration,
|
||||
symbolMapping
|
||||
currency: (<Currency>(
|
||||
(<unknown>this.assetProfileForm.controls['currency'].value)
|
||||
))?.value,
|
||||
name: this.assetProfileForm.controls['name'].value
|
||||
};
|
||||
|
||||
this.adminService
|
||||
|
@ -183,6 +183,15 @@
|
||||
<input formControlName="name" matInput type="text" />
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div *ngIf="assetProfile?.dataSource === 'MANUAL'" class="mt-3">
|
||||
<mat-form-field appearance="outline" class="w-100 without-hint">
|
||||
<mat-label i18n>Currency</mat-label>
|
||||
<gf-currency-selector
|
||||
formControlName="currency"
|
||||
[currencies]="currencies"
|
||||
/>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div *ngIf="assetProfile?.dataSource === 'MANUAL'" class="mt-3">
|
||||
<mat-form-field appearance="outline" class="w-100 without-hint">
|
||||
<mat-label i18n>Asset Class</mat-label>
|
||||
|
@ -10,6 +10,7 @@ import { MatMenuModule } from '@angular/material/menu';
|
||||
import { MatSelectModule } from '@angular/material/select';
|
||||
import { MatSnackBarModule } from '@angular/material/snack-bar';
|
||||
import { GfAdminMarketDataDetailModule } from '@ghostfolio/client/components/admin-market-data-detail/admin-market-data-detail.module';
|
||||
import { GfCurrencySelectorModule } from '@ghostfolio/ui/currency-selector/currency-selector.module';
|
||||
import { GfPortfolioProportionChartModule } from '@ghostfolio/ui/portfolio-proportion-chart/portfolio-proportion-chart.module';
|
||||
import { GfValueModule } from '@ghostfolio/ui/value';
|
||||
|
||||
@ -21,6 +22,7 @@ import { AssetProfileDialog } from './asset-profile-dialog.component';
|
||||
CommonModule,
|
||||
FormsModule,
|
||||
GfAdminMarketDataDetailModule,
|
||||
GfCurrencySelectorModule,
|
||||
GfPortfolioProportionChartModule,
|
||||
GfValueModule,
|
||||
MatButtonModule,
|
||||
|
@ -15,7 +15,7 @@ import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
||||
import { CreateAccountDto } from '@ghostfolio/api/app/account/create-account.dto';
|
||||
import { UpdateAccountDto } from '@ghostfolio/api/app/account/update-account.dto';
|
||||
import { DataService } from '@ghostfolio/client/services/data.service';
|
||||
import { Currency } from '@ghostfolio/common/interfaces/currency.interface';
|
||||
import { Currency } from '@ghostfolio/common/interfaces';
|
||||
import { Platform } from '@prisma/client';
|
||||
import { Observable, Subject } from 'rxjs';
|
||||
import { map, startWith } from 'rxjs/operators';
|
||||
|
@ -206,6 +206,7 @@ export class AdminService {
|
||||
assetClass,
|
||||
assetSubClass,
|
||||
comment,
|
||||
currency,
|
||||
dataSource,
|
||||
name,
|
||||
scraperConfiguration,
|
||||
@ -218,6 +219,7 @@ export class AdminService {
|
||||
assetClass,
|
||||
assetSubClass,
|
||||
comment,
|
||||
currency,
|
||||
name,
|
||||
scraperConfiguration,
|
||||
symbolMapping
|
||||
|
@ -11,6 +11,7 @@ import type { BenchmarkMarketDataDetails } from './benchmark-market-data-details
|
||||
import type { BenchmarkProperty } from './benchmark-property.interface';
|
||||
import type { Benchmark } from './benchmark.interface';
|
||||
import type { Coupon } from './coupon.interface';
|
||||
import type { Currency } from './currency.interface';
|
||||
import type { DataProviderInfo } from './data-provider-info.interface';
|
||||
import type { EnhancedSymbolProfile } from './enhanced-symbol-profile.interface';
|
||||
import type { Export } from './export.interface';
|
||||
@ -42,8 +43,8 @@ import type { PortfolioPerformanceResponse } from './responses/portfolio-perform
|
||||
import type { ScraperConfiguration } from './scraper-configuration.interface';
|
||||
import type { Statistics } from './statistics.interface';
|
||||
import type { Subscription } from './subscription.interface';
|
||||
import { SystemMessage } from './system-message.interface';
|
||||
import { TabConfiguration } from './tab-configuration.interface';
|
||||
import type { SystemMessage } from './system-message.interface';
|
||||
import type { TabConfiguration } from './tab-configuration.interface';
|
||||
import type { TimelinePosition } from './timeline-position.interface';
|
||||
import type { UniqueAsset } from './unique-asset.interface';
|
||||
import type { UserSettings } from './user-settings.interface';
|
||||
@ -63,6 +64,7 @@ export {
|
||||
BenchmarkProperty,
|
||||
BenchmarkResponse,
|
||||
Coupon,
|
||||
Currency,
|
||||
DataProviderInfo,
|
||||
EnhancedSymbolProfile,
|
||||
Export,
|
||||
|
@ -16,7 +16,7 @@ import {
|
||||
} from '@angular/material/autocomplete';
|
||||
import { MatFormFieldControl } from '@angular/material/form-field';
|
||||
import { MatInput } from '@angular/material/input';
|
||||
import { Currency } from '@ghostfolio/common/interfaces/currency.interface';
|
||||
import { Currency } from '@ghostfolio/common/interfaces';
|
||||
import { AbstractMatFormField } from '@ghostfolio/ui/shared/abstract-mat-form-field';
|
||||
import { Subject } from 'rxjs';
|
||||
import { map, startWith, takeUntil } from 'rxjs/operators';
|
||||
|
Loading…
x
Reference in New Issue
Block a user