From 016572e99ce64bfcca6011333a33963512de5e72 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sat, 10 Oct 2026 20:21:43 +0200 Subject: [PATCH 1/2] Task/hide currency in portfolio performance on mobile (#8114) * Hide currency on mobile * Update changelog --- CHANGELOG.md | 1 + .../home-overview/home-overview.component.ts | 10 ++++++---- .../portfolio-performance.component.ts | 2 +- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 919032a762..5216b1726a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- Simplified the portfolio performance on the overview tab of the home page by hiding the currency on mobile - Extended the access to share the portfolio with the Model Context Protocol (MCP) to support the _View_ and the _View and manage_ permissions (experimental) - Improved the performance of getting the historical market data by selecting only the required columns diff --git a/apps/client/src/app/components/home-overview/home-overview.component.ts b/apps/client/src/app/components/home-overview/home-overview.component.ts index 3cecc5e5de..c7b880efce 100644 --- a/apps/client/src/app/components/home-overview/home-overview.component.ts +++ b/apps/client/src/app/components/home-overview/home-overview.component.ts @@ -106,11 +106,13 @@ export class GfHomeOverviewComponent implements OnInit { }); protected readonly unit = computed(() => { - const user = this.user(); + if (!this.showDetails()) { + return '%'; + } - return this.showDetails() - ? (user?.settings?.baseCurrency ?? DEFAULT_CURRENCY) - : '%'; + return this.deviceType() === 'mobile' + ? undefined + : (this.user()?.settings?.baseCurrency ?? DEFAULT_CURRENCY); }); private readonly dataService = inject(DataService); diff --git a/apps/client/src/app/components/portfolio-performance/portfolio-performance.component.ts b/apps/client/src/app/components/portfolio-performance/portfolio-performance.component.ts index aade357b78..04929e03a6 100644 --- a/apps/client/src/app/components/portfolio-performance/portfolio-performance.component.ts +++ b/apps/client/src/app/components/portfolio-performance/portfolio-performance.component.ts @@ -44,7 +44,7 @@ export class GfPortfolioPerformanceComponent { } }); public readonly showDetails = input(false); - public readonly unit = input.required(); + public readonly unit = input.required(); private readonly value = viewChild.required>('value'); From 6a1cbccc4391eec81a3e4481e128e6bab3a24c2e Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sat, 10 Oct 2026 20:33:47 +0200 Subject: [PATCH 2/2] Bugfix/AI prompt in impersonation mode (#8115) * Fix AI prompt in impersonation mode * Update changelog --- CHANGELOG.md | 4 ++++ .../api/src/app/endpoints/ai/ai.controller.ts | 19 ++++++++++++------- apps/api/src/app/endpoints/ai/ai.module.ts | 2 ++ 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5216b1726a..a5aea753b4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Extended the access to share the portfolio with the Model Context Protocol (MCP) to support the _View_ and the _View and manage_ permissions (experimental) - Improved the performance of getting the historical market data by selecting only the required columns +### Fixed + +- Fixed the _Copy AI prompt to clipboard_ actions on the analysis page in impersonation mode to be based on the impersonated user (experimental) + ## 3.83.0 - 2026-10-10 ### Added diff --git a/apps/api/src/app/endpoints/ai/ai.controller.ts b/apps/api/src/app/endpoints/ai/ai.controller.ts index 9691e211de..3c7f6661d7 100644 --- a/apps/api/src/app/endpoints/ai/ai.controller.ts +++ b/apps/api/src/app/endpoints/ai/ai.controller.ts @@ -1,11 +1,17 @@ import { HasPermission } from '@ghostfolio/api/decorators/has-permission.decorator'; +import { Impersonation } from '@ghostfolio/api/decorators/impersonation.decorator'; +import { RequiresScope } from '@ghostfolio/api/decorators/requires-scope.decorator'; import { FilterDto } from '@ghostfolio/api/dtos/filter.dto'; -import { HasPermissionGuard } from '@ghostfolio/api/guards/has-permission.guard'; import { TransformDataSourceInRequestInterceptor } from '@ghostfolio/api/interceptors/transform-data-source-in-request/transform-data-source-in-request.interceptor'; import { ApiService } from '@ghostfolio/api/services/api/api.service'; import { AiPromptResponse } from '@ghostfolio/common/interfaces'; import { permissions } from '@ghostfolio/common/permissions'; -import type { AiPromptMode, RequestWithUser } from '@ghostfolio/common/types'; +import { scopes } from '@ghostfolio/common/scopes'; +import type { + AiPromptMode, + ImpersonationContext, + RequestWithUser +} from '@ghostfolio/common/types'; import { Controller, @@ -13,11 +19,9 @@ import { Inject, Param, Query, - UseGuards, UseInterceptors } from '@nestjs/common'; import { REQUEST } from '@nestjs/core'; -import { AuthGuard } from '@nestjs/passport'; import { AiService } from './ai.service'; @@ -31,9 +35,10 @@ export class AiController { @Get('prompt/:mode') @HasPermission(permissions.readAiPrompt) - @UseGuards(AuthGuard('jwt'), HasPermissionGuard) + @RequiresScope(scopes.portfolioRead) @UseInterceptors(TransformDataSourceInRequestInterceptor) public async getPrompt( + @Impersonation() { userId, userSettings }: ImpersonationContext, @Param('mode') mode: AiPromptMode, @Query() { accounts, assetClasses, dataSource, symbol, tags }: FilterDto @@ -49,9 +54,9 @@ export class AiController { const prompt = await this.aiService.getPrompt({ filters, mode, + userId, languageCode: this.request.user.settings.settings.language, - userCurrency: this.request.user.settings.settings.baseCurrency, - userId: this.request.user.id + userCurrency: userSettings.baseCurrency }); return { prompt }; diff --git a/apps/api/src/app/endpoints/ai/ai.module.ts b/apps/api/src/app/endpoints/ai/ai.module.ts index f46ed1df88..756f6914fd 100644 --- a/apps/api/src/app/endpoints/ai/ai.module.ts +++ b/apps/api/src/app/endpoints/ai/ai.module.ts @@ -1,6 +1,7 @@ import { TransformDataSourceInRequestModule } from '@ghostfolio/api/interceptors/transform-data-source-in-request/transform-data-source-in-request.module'; import { ApiModule } from '@ghostfolio/api/services/api/api.module'; import { ConfigurationModule } from '@ghostfolio/api/services/configuration/configuration.module'; +import { ImpersonationModule } from '@ghostfolio/api/services/impersonation/impersonation.module'; import { PortfolioTableModule } from '@ghostfolio/api/services/portfolio-table/portfolio-table.module'; import { PropertyModule } from '@ghostfolio/api/services/property/property.module'; @@ -15,6 +16,7 @@ import { AiService } from './ai.service'; imports: [ ApiModule, ConfigurationModule, + ImpersonationModule, PortfolioTableModule, PropertyModule, TransformDataSourceInRequestModule