diff --git a/apps/api/src/app/endpoints/public/public.controller.ts b/apps/api/src/app/endpoints/public/public.controller.ts index 4faa8222d..633e6418a 100644 --- a/apps/api/src/app/endpoints/public/public.controller.ts +++ b/apps/api/src/app/endpoints/public/public.controller.ts @@ -94,17 +94,6 @@ export class PublicController { }) ]); - const baseCurrency = - user.settings?.settings.baseCurrency ?? DEFAULT_CURRENCY; - const filteredHoldings = Object.fromEntries( - Object.entries(holdings).filter(([, holding]) => { - const isCash = - holding.assetProfile.assetSubClass === AssetSubClass.CASH; - const isBaseCurrency = holding.assetProfile.symbol === baseCurrency; - return !(isCash && isBaseCurrency); - }) - ); - const { activities } = await this.activitiesService.getActivities({ filters: portfolioFilters.length > 0 ? portfolioFilters : undefined, sortColumn: 'date', @@ -175,23 +164,19 @@ export class PublicController { }; const totalValue = getSum( - Object.values(filteredHoldings).map( - ({ assetProfile, marketPrice, quantity }) => { - return new Big( - this.exchangeRateDataService.toCurrency( - quantity * marketPrice, - assetProfile.currency, - this.request.user?.settings?.settings.baseCurrency ?? - DEFAULT_CURRENCY - ) - ); - } - ) + Object.values(holdings).map(({ assetProfile, marketPrice, quantity }) => { + return new Big( + this.exchangeRateDataService.toCurrency( + quantity * marketPrice, + assetProfile.currency, + this.request.user?.settings?.settings.baseCurrency ?? + DEFAULT_CURRENCY + ) + ); + }) ).toNumber(); - for (const [symbol, portfolioPosition] of Object.entries( - filteredHoldings - )) { + for (const [symbol, portfolioPosition] of Object.entries(holdings)) { publicPortfolioResponse.holdings[symbol] = { allocationInPercentage: portfolioPosition.valueInBaseCurrency / totalValue, diff --git a/apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.component.ts b/apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.component.ts index 88c343e74..3db40781e 100644 --- a/apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.component.ts +++ b/apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.component.ts @@ -3,6 +3,7 @@ import { CreateAccessDto, UpdateAccessDto } from '@ghostfolio/common/dtos'; import { Filter, PortfolioPosition } from '@ghostfolio/common/interfaces'; import { AccountWithPlatform } from '@ghostfolio/common/types'; import { validateObjectForForm } from '@ghostfolio/common/utils'; +import { translate } from '@ghostfolio/ui/i18n'; import { NotificationService } from '@ghostfolio/ui/notifications'; import { GfPortfolioFilterFormComponent, @@ -37,7 +38,7 @@ import { import { MatFormFieldModule } from '@angular/material/form-field'; import { MatInputModule } from '@angular/material/input'; import { MatSelectModule } from '@angular/material/select'; -import { AccessPermission } from '@prisma/client'; +import { AccessPermission, AssetClass } from '@prisma/client'; import { StatusCodes } from 'http-status-codes'; import { EMPTY, catchError } from 'rxjs'; @@ -110,6 +111,18 @@ export class GfCreateOrUpdateAccessDialogComponent implements OnInit { ] }); + this.assetClasses = Object.keys(AssetClass) + .map((assetClass) => { + return { + id: assetClass, + label: translate(assetClass), + type: 'ASSET_CLASS' as const + }; + }) + .sort((a, b) => { + return a.label.localeCompare(b.label); + }); + this.userService .get() .pipe(takeUntilDestroyed(this.destroyRef)) @@ -117,13 +130,21 @@ export class GfCreateOrUpdateAccessDialogComponent implements OnInit { this.accounts = accounts; this.hasExperimentalFeatures = settings.isExperimentalFeatures ?? false; - this.tags = tags - .filter(({ isUsed }) => isUsed) - .map(({ id, name }) => ({ - id, - label: name, - type: 'TAG' as const - })); + this.tags = + tags + ?.filter(({ isUsed }) => { + return isUsed; + }) + ?.map(({ id, name }) => { + return { + id, + label: translate(name), + type: 'TAG' as const + }; + }) + ?.sort((a, b) => { + return a.label.localeCompare(b.label); + }) ?? []; this.updateFiltersFormControl(this.data.access?.settings?.filters); @@ -216,26 +237,24 @@ export class GfCreateOrUpdateAccessDialogComponent implements OnInit { private loadHoldings() { this.dataService - .fetchPortfolioDetails({}) + .fetchPortfolioHoldings() .pipe(takeUntilDestroyed(this.destroyRef)) - .subscribe((response) => { - if (response.holdings) { - this.holdings = Object.values(response.holdings); - - const assetClassesSet = new Set(); - Object.values(response.holdings).forEach((holding) => { - if (holding.assetProfile.assetClass) { - assetClassesSet.add(holding.assetProfile.assetClass); - } + .subscribe(({ holdings }) => { + this.holdings = holdings + .filter(({ assetProfile }) => { + return ( + assetProfile.assetSubClass && + !['CASH'].includes(assetProfile.assetSubClass) + ); + }) + .sort((a, b) => { + return (a.assetProfile.name ?? '').localeCompare( + b.assetProfile.name ?? '' + ); }); - this.assetClasses = Array.from(assetClassesSet).map((ac) => ({ - id: ac, - label: ac, - type: 'ASSET_CLASS' as const - })); - this.updateFiltersFormControl(this.data.access?.settings?.filters); - } + this.updateFiltersFormControl(this.data.access?.settings?.filters); + this.changeDetectorRef.markForCheck(); }); }