diff --git a/CHANGELOG.md b/CHANGELOG.md
index 370df2834..e2ec6836f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,6 +11,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Upgraded `ionicons` from version `7.3.0` to `7.4.0`
+### Fixed
+
+- Fixed the position detail dialog open functionality when searching for a holding in the assistant
+
## 2.79.0 - 2024-05-04
### Changed
diff --git a/README.md b/README.md
index b48fa48db..eaf641544 100644
--- a/README.md
+++ b/README.md
@@ -142,7 +142,7 @@ docker compose --env-file ./.env -f docker/docker-compose.build.yml up -d
### Home Server Systems (Community)
-Ghostfolio is available for various home server systems, including [CasaOS](https://github.com/bigbeartechworld/big-bear-casaos), Home Assistant, [Runtipi](https://www.runtipi.io/docs/apps-available), [TrueCharts](https://truecharts.org/charts/stable/ghostfolio), [Umbrel](https://apps.umbrel.com/app/ghostfolio), and [Unraid](https://unraid.net/community/apps?q=ghostfolio).
+Ghostfolio is available for various home server systems, including [CasaOS](https://github.com/bigbeartechworld/big-bear-casaos), [Home Assistant](https://github.com/lildude/ha-addon-ghostfolio), [Runtipi](https://www.runtipi.io/docs/apps-available), [TrueCharts](https://truecharts.org/charts/stable/ghostfolio), [Umbrel](https://apps.umbrel.com/app/ghostfolio), and [Unraid](https://unraid.net/community/apps?q=ghostfolio).
## Development
diff --git a/apps/api/src/events/portfolio-changed.listener.ts b/apps/api/src/events/portfolio-changed.listener.ts
index 4a6e3d386..fcf47ce6c 100644
--- a/apps/api/src/events/portfolio-changed.listener.ts
+++ b/apps/api/src/events/portfolio-changed.listener.ts
@@ -12,7 +12,7 @@ export class PortfolioChangedListener {
@OnEvent(PortfolioChangedEvent.getName())
handlePortfolioChangedEvent(event: PortfolioChangedEvent) {
Logger.log(
- `Portfolio of user with id ${event.getUserId()} has changed`,
+ `Portfolio of user '${event.getUserId()}' has changed`,
'PortfolioChangedListener'
);
diff --git a/apps/client/src/app/pages/faq/self-hosting/self-hosting-page.html b/apps/client/src/app/pages/faq/self-hosting/self-hosting-page.html
index da6690d58..4445495fd 100644
--- a/apps/client/src/app/pages/faq/self-hosting/self-hosting-page.html
+++ b/apps/client/src/app/pages/faq/self-hosting/self-hosting-page.html
@@ -30,8 +30,10 @@
systems, including
CasaOS, Home Assistant,
- Runtipi,
+ >,
+ Home Assistant, Runtipi,
TrueCharts, Umbrel, and
diff --git a/apps/client/src/app/pages/home/home-page.component.ts b/apps/client/src/app/pages/home/home-page.component.ts
index 3a6a0cb26..8f8386473 100644
--- a/apps/client/src/app/pages/home/home-page.component.ts
+++ b/apps/client/src/app/pages/home/home-page.component.ts
@@ -1,7 +1,14 @@
+import { PositionDetailDialogParams } from '@ghostfolio/client/components/position-detail-dialog/interfaces/interfaces';
+import { PositionDetailDialog } from '@ghostfolio/client/components/position-detail-dialog/position-detail-dialog.component';
+import { ImpersonationStorageService } from '@ghostfolio/client/services/impersonation-storage.service';
import { UserService } from '@ghostfolio/client/services/user/user.service';
import { TabConfiguration, User } from '@ghostfolio/common/interfaces';
+import { hasPermission, permissions } from '@ghostfolio/common/permissions';
import { ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core';
+import { MatDialog } from '@angular/material/dialog';
+import { ActivatedRoute, Router } from '@angular/router';
+import { DataSource } from '@prisma/client';
import { DeviceDetectorService } from 'ngx-device-detector';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
@@ -14,6 +21,7 @@ import { takeUntil } from 'rxjs/operators';
})
export class HomePageComponent implements OnDestroy, OnInit {
public deviceType: string;
+ public hasImpersonationId: boolean;
public tabs: TabConfiguration[] = [];
public user: User;
@@ -22,8 +30,27 @@ export class HomePageComponent implements OnDestroy, OnInit {
public constructor(
private changeDetectorRef: ChangeDetectorRef,
private deviceService: DeviceDetectorService,
+ private dialog: MatDialog,
+ private impersonationStorageService: ImpersonationStorageService,
+ private route: ActivatedRoute,
+ private router: Router,
private userService: UserService
) {
+ this.route.queryParams
+ .pipe(takeUntil(this.unsubscribeSubject))
+ .subscribe((params) => {
+ if (
+ params['dataSource'] &&
+ params['positionDetailDialog'] &&
+ params['symbol']
+ ) {
+ this.openPositionDialog({
+ dataSource: params['dataSource'],
+ symbol: params['symbol']
+ });
+ }
+ });
+
this.userService.stateChanged
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe((state) => {
@@ -59,10 +86,58 @@ export class HomePageComponent implements OnDestroy, OnInit {
public ngOnInit() {
this.deviceType = this.deviceService.getDeviceInfo().deviceType;
+
+ this.impersonationStorageService
+ .onChangeHasImpersonation()
+ .pipe(takeUntil(this.unsubscribeSubject))
+ .subscribe((impersonationId) => {
+ this.hasImpersonationId = !!impersonationId;
+ });
}
public ngOnDestroy() {
this.unsubscribeSubject.next();
this.unsubscribeSubject.complete();
}
+
+ private openPositionDialog({
+ dataSource,
+ symbol
+ }: {
+ dataSource: DataSource;
+ symbol: string;
+ }) {
+ this.userService
+ .get()
+ .pipe(takeUntil(this.unsubscribeSubject))
+ .subscribe((user) => {
+ this.user = user;
+
+ const dialogRef = this.dialog.open(PositionDetailDialog, {
+ autoFocus: false,
+ data: {
+ dataSource,
+ symbol,
+ baseCurrency: this.user?.settings?.baseCurrency,
+ colorScheme: this.user?.settings?.colorScheme,
+ deviceType: this.deviceType,
+ hasImpersonationId: this.hasImpersonationId,
+ hasPermissionToReportDataGlitch: hasPermission(
+ this.user?.permissions,
+ permissions.reportDataGlitch
+ ),
+ locale: this.user?.settings?.locale
+ },
+ height: this.deviceType === 'mobile' ? '97.5vh' : '80vh',
+ width: this.deviceType === 'mobile' ? '100vw' : '50rem'
+ });
+
+ dialogRef
+ .afterClosed()
+ .pipe(takeUntil(this.unsubscribeSubject))
+ .subscribe(() => {
+ this.router.navigate(['.'], { relativeTo: this.route });
+ });
+ });
+ }
}