Compare commits

...

3 Commits

Author SHA1 Message Date
Thomas Kaul 5dfbb1ac94
Task/upgrade svgmap to version 2.19.3 (#6729) 4 days ago
Kenrick Tandrian 1dffe79c77
Task/improve type safety in public page component (#6746) 4 days ago
Thomas Kaul c858f41ac6
Task/upgrade prettier to version 3.8.2 (#6733) 4 days ago
  1. 2
      CHANGELOG.md
  2. 87
      apps/client/src/app/pages/public/public-page.component.ts
  3. 4
      apps/client/src/app/pages/public/public-page.html
  4. 16
      package-lock.json
  5. 4
      package.json

2
CHANGELOG.md

@ -14,6 +14,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Sorted the tags of the assistant alphabetically - Sorted the tags of the assistant alphabetically
- Upgraded `angular` from version `21.1.1` to `21.2.7` - Upgraded `angular` from version `21.1.1` to `21.2.7`
- Upgraded `Nx` from version `22.5.3` to `22.6.4` - Upgraded `Nx` from version `22.5.3` to `22.6.4`
- Upgraded `prettier` from version `3.8.1` to `3.8.2`
- Upgraded `svgmap` from version `2.19.2` to `2.19.3`
- Upgraded `yahoo-finance2` from version `3.13.2` to `3.14.0` - Upgraded `yahoo-finance2` from version `3.13.2` to `3.14.0`
### Fixed ### Fixed

87
apps/client/src/app/pages/public/public-page.component.ts

@ -15,11 +15,14 @@ import { GfValueComponent } from '@ghostfolio/ui/value';
import { GfWorldMapChartComponent } from '@ghostfolio/ui/world-map-chart'; import { GfWorldMapChartComponent } from '@ghostfolio/ui/world-map-chart';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { HttpErrorResponse } from '@angular/common/http';
import { import {
ChangeDetectorRef, ChangeDetectorRef,
Component, Component,
computed,
CUSTOM_ELEMENTS_SCHEMA, CUSTOM_ELEMENTS_SCHEMA,
DestroyRef, DestroyRef,
inject,
OnInit OnInit
} from '@angular/core'; } from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
@ -52,48 +55,50 @@ import { catchError } from 'rxjs/operators';
templateUrl: './public-page.html' templateUrl: './public-page.html'
}) })
export class GfPublicPageComponent implements OnInit { export class GfPublicPageComponent implements OnInit {
public continents: { protected continents: {
[code: string]: { name: string; value: number }; [code: string]: { name: string; value: number };
}; };
public countries: { protected countries: {
[code: string]: { name: string; value: number }; [code: string]: { name: string; value: number };
}; };
public defaultAlias = $localize`someone`; protected readonly defaultAlias = $localize`someone`;
public deviceType: string; protected readonly deviceType = computed(
public hasPermissionForSubscription: boolean; () => this.deviceDetectorService.deviceInfo().deviceType
public holdings: PublicPortfolioResponse['holdings'][string][]; );
public info: InfoItem; protected hasPermissionForSubscription: boolean;
public latestActivitiesDataSource: MatTableDataSource< protected holdings: PublicPortfolioResponse['holdings'][string][];
protected info: InfoItem;
protected latestActivitiesDataSource: MatTableDataSource<
PublicPortfolioResponse['latestActivities'][0] PublicPortfolioResponse['latestActivities'][0]
>; >;
public markets: { protected markets: {
[key in Market]: { id: Market; valueInPercentage: number }; [key in Market]: { id: Market; valueInPercentage: number };
}; };
public pageSize = Number.MAX_SAFE_INTEGER; protected readonly pageSize = Number.MAX_SAFE_INTEGER;
public positions: { protected positions: {
[symbol: string]: Pick<PortfolioPosition, 'currency' | 'name'> & { [symbol: string]: Pick<PortfolioPosition, 'currency' | 'name'> & {
value: number; value: number;
}; };
}; };
public publicPortfolioDetails: PublicPortfolioResponse; protected publicPortfolioDetails: PublicPortfolioResponse;
public sectors: { protected sectors: {
[name: string]: { name: string; value: number }; [name: string]: { name: string; value: number };
}; };
public symbols: { protected symbols: {
[name: string]: { name: string; symbol: string; value: number }; [name: string]: { name: string; symbol: string; value: number };
}; };
public UNKNOWN_KEY = UNKNOWN_KEY; protected readonly UNKNOWN_KEY = UNKNOWN_KEY;
private readonly activatedRoute = inject(ActivatedRoute);
private readonly changeDetectorRef = inject(ChangeDetectorRef);
private readonly dataService = inject(DataService);
private readonly destroyRef = inject(DestroyRef);
private readonly deviceDetectorService = inject(DeviceDetectorService);
private readonly router = inject(Router);
private accessId: string; private accessId: string;
public constructor( public constructor() {
private activatedRoute: ActivatedRoute,
private changeDetectorRef: ChangeDetectorRef,
private dataService: DataService,
private destroyRef: DestroyRef,
private deviceService: DeviceDetectorService,
private router: Router
) {
this.activatedRoute.params.subscribe((params) => { this.activatedRoute.params.subscribe((params) => {
this.accessId = params['id']; this.accessId = params['id'];
}); });
@ -107,13 +112,11 @@ export class GfPublicPageComponent implements OnInit {
} }
public ngOnInit() { public ngOnInit() {
this.deviceType = this.deviceService.getDeviceInfo().deviceType;
this.dataService this.dataService
.fetchPublicPortfolio(this.accessId) .fetchPublicPortfolio(this.accessId)
.pipe( .pipe(
takeUntilDestroyed(this.destroyRef), takeUntilDestroyed(this.destroyRef),
catchError((error) => { catchError((error: HttpErrorResponse) => {
if (error.status === StatusCodes.NOT_FOUND) { if (error.status === StatusCodes.NOT_FOUND) {
console.error(error); console.error(error);
this.router.navigate(['/']); this.router.navigate(['/']);
@ -135,7 +138,7 @@ export class GfPublicPageComponent implements OnInit {
}); });
} }
public initializeAnalysisData() { private initializeAnalysisData() {
this.continents = { this.continents = {
[UNKNOWN_KEY]: { [UNKNOWN_KEY]: {
name: UNKNOWN_KEY, name: UNKNOWN_KEY,
@ -185,36 +188,38 @@ export class GfPublicPageComponent implements OnInit {
if (this.continents[continent]?.value) { if (this.continents[continent]?.value) {
this.continents[continent].value += this.continents[continent].value +=
weight * position.valueInBaseCurrency; weight * (position.valueInBaseCurrency ?? 0);
} else { } else {
this.continents[continent] = { this.continents[continent] = {
name: continent, name: continent,
value: value:
weight * weight *
this.publicPortfolioDetails.holdings[symbol] (this.publicPortfolioDetails.holdings[symbol]
.valueInBaseCurrency .valueInBaseCurrency ?? 0)
}; };
} }
if (this.countries[code]?.value) { if (this.countries[code]?.value) {
this.countries[code].value += this.countries[code].value +=
weight * position.valueInBaseCurrency; weight * (position.valueInBaseCurrency ?? 0);
} else { } else {
this.countries[code] = { this.countries[code] = {
name, name,
value: value:
weight * weight *
this.publicPortfolioDetails.holdings[symbol] (this.publicPortfolioDetails.holdings[symbol]
.valueInBaseCurrency .valueInBaseCurrency ?? 0)
}; };
} }
} }
} else { } else {
this.continents[UNKNOWN_KEY].value += this.continents[UNKNOWN_KEY].value +=
this.publicPortfolioDetails.holdings[symbol].valueInBaseCurrency; this.publicPortfolioDetails.holdings[symbol].valueInBaseCurrency ??
0;
this.countries[UNKNOWN_KEY].value += this.countries[UNKNOWN_KEY].value +=
this.publicPortfolioDetails.holdings[symbol].valueInBaseCurrency; this.publicPortfolioDetails.holdings[symbol].valueInBaseCurrency ??
0;
} }
if (position.sectors.length > 0) { if (position.sectors.length > 0) {
@ -222,20 +227,22 @@ export class GfPublicPageComponent implements OnInit {
const { name, weight } = sector; const { name, weight } = sector;
if (this.sectors[name]?.value) { if (this.sectors[name]?.value) {
this.sectors[name].value += weight * position.valueInBaseCurrency; this.sectors[name].value +=
weight * (position.valueInBaseCurrency ?? 0);
} else { } else {
this.sectors[name] = { this.sectors[name] = {
name, name,
value: value:
weight * weight *
this.publicPortfolioDetails.holdings[symbol] (this.publicPortfolioDetails.holdings[symbol]
.valueInBaseCurrency .valueInBaseCurrency ?? 0)
}; };
} }
} }
} else { } else {
this.sectors[UNKNOWN_KEY].value += this.sectors[UNKNOWN_KEY].value +=
this.publicPortfolioDetails.holdings[symbol].valueInBaseCurrency; this.publicPortfolioDetails.holdings[symbol].valueInBaseCurrency ??
0;
} }
} }
@ -244,7 +251,7 @@ export class GfPublicPageComponent implements OnInit {
symbol: prettifySymbol(symbol), symbol: prettifySymbol(symbol),
value: isNumber(position.valueInBaseCurrency) value: isNumber(position.valueInBaseCurrency)
? position.valueInBaseCurrency ? position.valueInBaseCurrency
: position.valueInPercentage : (position.valueInPercentage ?? 0)
}; };
} }
} }

4
apps/client/src/app/pages/public/public-page.html

@ -75,7 +75,7 @@
[data]="symbols" [data]="symbols"
[isInPercentage]="true" [isInPercentage]="true"
[keys]="['symbol']" [keys]="['symbol']"
[showLabels]="deviceType !== 'mobile'" [showLabels]="deviceType() !== 'mobile'"
/> />
<gf-holdings-table <gf-holdings-table
[hasPermissionToOpenDetails]="false" [hasPermissionToOpenDetails]="false"
@ -213,7 +213,7 @@
<mat-card-content> <mat-card-content>
<gf-activities-table <gf-activities-table
[dataSource]="latestActivitiesDataSource" [dataSource]="latestActivitiesDataSource"
[deviceType]="deviceType" [deviceType]="deviceType()"
[hasPermissionToCreateActivity]="false" [hasPermissionToCreateActivity]="false"
[hasPermissionToDeleteActivity]="false" [hasPermissionToDeleteActivity]="false"
[hasPermissionToExportActivities]="false" [hasPermissionToExportActivities]="false"

16
package-lock.json

@ -90,7 +90,7 @@
"reflect-metadata": "0.2.2", "reflect-metadata": "0.2.2",
"rxjs": "7.8.1", "rxjs": "7.8.1",
"stripe": "20.4.1", "stripe": "20.4.1",
"svgmap": "2.19.2", "svgmap": "2.19.3",
"tablemark": "4.1.0", "tablemark": "4.1.0",
"twitter-api-v2": "1.29.0", "twitter-api-v2": "1.29.0",
"yahoo-finance2": "3.14.0", "yahoo-finance2": "3.14.0",
@ -148,7 +148,7 @@
"jest-environment-jsdom": "30.2.0", "jest-environment-jsdom": "30.2.0",
"jest-preset-angular": "16.0.0", "jest-preset-angular": "16.0.0",
"nx": "22.6.4", "nx": "22.6.4",
"prettier": "3.8.1", "prettier": "3.8.2",
"prettier-plugin-organize-attributes": "1.0.0", "prettier-plugin-organize-attributes": "1.0.0",
"prisma": "6.19.3", "prisma": "6.19.3",
"react": "18.2.0", "react": "18.2.0",
@ -33003,9 +33003,9 @@
} }
}, },
"node_modules/prettier": { "node_modules/prettier": {
"version": "3.8.1", "version": "3.8.2",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.1.tgz", "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.2.tgz",
"integrity": "sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==", "integrity": "sha512-8c3mgTe0ASwWAJK+78dpviD+A8EqhndQPUBpNUIPt6+xWlIigCwfN01lWr9MAede4uqXGTEKeQWTvzb3vjia0Q==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"bin": { "bin": {
@ -36428,9 +36428,9 @@
"license": "BSD-2-Clause" "license": "BSD-2-Clause"
}, },
"node_modules/svgmap": { "node_modules/svgmap": {
"version": "2.19.2", "version": "2.19.3",
"resolved": "https://registry.npmjs.org/svgmap/-/svgmap-2.19.2.tgz", "resolved": "https://registry.npmjs.org/svgmap/-/svgmap-2.19.3.tgz",
"integrity": "sha512-mRqRcQiwwSTh9kTOPhjTmd3ywxA9aTfybBHGAoyuGn9CI9PnAQsuZ7H/2/VEIvgJhi1xM5IGBfk8i4/Ke4iTCQ==", "integrity": "sha512-LjKVzKgANVMRiHqFQVz57FqqX7tVm+EskubySCWb5kvizdeDBanscPA/c4tmK/48VCvYxrR1ecBbqStcD6HYfQ==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"svg-pan-zoom": "^3.6.2" "svg-pan-zoom": "^3.6.2"

4
package.json

@ -135,7 +135,7 @@
"reflect-metadata": "0.2.2", "reflect-metadata": "0.2.2",
"rxjs": "7.8.1", "rxjs": "7.8.1",
"stripe": "20.4.1", "stripe": "20.4.1",
"svgmap": "2.19.2", "svgmap": "2.19.3",
"tablemark": "4.1.0", "tablemark": "4.1.0",
"twitter-api-v2": "1.29.0", "twitter-api-v2": "1.29.0",
"yahoo-finance2": "3.14.0", "yahoo-finance2": "3.14.0",
@ -193,7 +193,7 @@
"jest-environment-jsdom": "30.2.0", "jest-environment-jsdom": "30.2.0",
"jest-preset-angular": "16.0.0", "jest-preset-angular": "16.0.0",
"nx": "22.6.4", "nx": "22.6.4",
"prettier": "3.8.1", "prettier": "3.8.2",
"prettier-plugin-organize-attributes": "1.0.0", "prettier-plugin-organize-attributes": "1.0.0",
"prisma": "6.19.3", "prisma": "6.19.3",
"react": "18.2.0", "react": "18.2.0",

Loading…
Cancel
Save