diff --git a/CHANGELOG.md b/CHANGELOG.md index 6d9c4284b..513f6266c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/apps/api/src/app/admin/admin.service.ts b/apps/api/src/app/admin/admin.service.ts index 40aaf286e..51b93517f 100644 --- a/apps/api/src/app/admin/admin.service.ts +++ b/apps/api/src/app/admin/admin.service.ts @@ -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, diff --git a/apps/api/src/app/admin/update-asset-profile.dto.ts b/apps/api/src/app/admin/update-asset-profile.dto.ts index a39f8db81..56794606c 100644 --- a/apps/api/src/app/admin/update-asset-profile.dto.ts +++ b/apps/api/src/app/admin/update-asset-profile.dto.ts @@ -14,6 +14,10 @@ export class UpdateAssetProfileDto { @IsOptional() comment?: string; + @IsString() + @IsOptional() + currency?: string; + @IsString() @IsOptional() name?: string; diff --git a/apps/api/src/services/symbol-profile/symbol-profile.service.ts b/apps/api/src/services/symbol-profile/symbol-profile.service.ts index 46a6991cb..37671c4e2 100644 --- a/apps/api/src/services/symbol-profile/symbol-profile.service.ts +++ b/apps/api/src/services/symbol-profile/symbol-profile.service.ts @@ -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 diff --git a/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts b/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts index 03dc717d5..6421e888b 100644 --- a/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts +++ b/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts @@ -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(undefined), assetSubClass: new FormControl(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: (( + (this.assetProfileForm.controls['currency'].value) + ))?.value, + name: this.assetProfileForm.controls['name'].value }; this.adminService diff --git a/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html b/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html index 72d673776..08051a0ef 100644 --- a/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html +++ b/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html @@ -183,6 +183,15 @@ +
+ + Currency + + +
Asset Class diff --git a/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.module.ts b/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.module.ts index 0f9fdaaca..8cbe21ef3 100644 --- a/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.module.ts +++ b/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.module.ts @@ -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, diff --git a/apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.component.ts b/apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.component.ts index 9e153d173..760eb1f03 100644 --- a/apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.component.ts +++ b/apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.component.ts @@ -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'; diff --git a/apps/client/src/app/services/admin.service.ts b/apps/client/src/app/services/admin.service.ts index 2854a2379..9f8fc9d13 100644 --- a/apps/client/src/app/services/admin.service.ts +++ b/apps/client/src/app/services/admin.service.ts @@ -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 diff --git a/libs/common/src/lib/interfaces/index.ts b/libs/common/src/lib/interfaces/index.ts index 7d76c419e..2875cb305 100644 --- a/libs/common/src/lib/interfaces/index.ts +++ b/libs/common/src/lib/interfaces/index.ts @@ -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, diff --git a/libs/ui/src/lib/currency-selector/currency-selector.component.ts b/libs/ui/src/lib/currency-selector/currency-selector.component.ts index f75b684dd..b86ff44da 100644 --- a/libs/ui/src/lib/currency-selector/currency-selector.component.ts +++ b/libs/ui/src/lib/currency-selector/currency-selector.component.ts @@ -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';