Browse Source

Merge branch 'main' into task/improve-sorting-to-be-case-insensitive-in-platform-and-tag-management-of-admin-control-panel

pull/7061/head
Thomas Kaul 4 weeks ago
committed by GitHub
parent
commit
1eafbccece
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 12
      CHANGELOG.md
  2. 12
      apps/api/src/app/portfolio/portfolio.service.ts
  3. 14
      apps/api/src/app/user/user.service.ts
  4. 1
      apps/api/src/interceptors/transform-data-source-in-response/transform-data-source-in-response.interceptor.ts
  5. 4
      apps/client/src/app/components/admin-users/admin-users.html
  6. 14
      apps/client/src/app/pages/pricing/pricing-page.component.ts
  7. 10
      apps/client/src/app/pages/pricing/pricing-page.html
  8. 1
      libs/common/src/lib/config.ts
  9. 2
      libs/common/src/lib/interfaces/index.ts
  10. 3
      libs/common/src/lib/interfaces/referral-partner.interface.ts
  11. 16
      libs/common/src/lib/interfaces/responses/portfolio-holding-response.interface.ts
  12. 2
      libs/common/src/lib/interfaces/user.interface.ts
  13. 4
      package-lock.json
  14. 2
      package.json

12
CHANGELOG.md

@ -9,12 +9,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed
- Improved the sorting to be case-insensitive in the platform management of the admin control panel
- Improved the sorting to be case-insensitive in the tag management of the admin control panel
## 3.12.0 - 2026-06-17
### Changed
- Improved the styling of the checkboxes to consistently use the primary color in their states
- Improved the account name display in the accounts table
- Improved the name display in the activities table
- Improved the last activity display in the users table of the admin control panel
- Improved the registration display in the users table of the admin control panel
- Improved the user id display in the users table of the admin control panel
- Improved the sorting to be case-insensitive in the platform management of the admin control panel
- Improved the sorting to be case-insensitive in the tag management of the admin control panel
- Deprecated `SymbolProfile` in favor of `assetProfile` in the endpoint `GET api/v1/portfolio/holding/:dataSource/:symbol`
- Improved the language localization for German (`de`)
- Upgraded `svgmap` from version `2.19.3` to `2.21.0`

12
apps/api/src/app/portfolio/portfolio.service.ts

@ -957,6 +957,18 @@ export class PortfolioService {
marketPriceMin,
SymbolProfile,
tags,
assetProfile: {
assetClass: SymbolProfile.assetClass,
assetSubClass: SymbolProfile.assetSubClass,
countries: SymbolProfile.countries,
currency: SymbolProfile.currency,
dataSource: SymbolProfile.dataSource,
isin: SymbolProfile.isin,
name: SymbolProfile.name,
sectors: SymbolProfile.sectors,
symbol: SymbolProfile.symbol,
userId: SymbolProfile.userId
},
averagePrice: averagePrice.toNumber(),
dataProviderInfo: portfolioCalculator.getDataProviderInfos()?.[0],
dividendInBaseCurrency: dividendInBaseCurrency.toNumber(),

14
apps/api/src/app/user/user.service.ts

@ -29,6 +29,7 @@ import {
DEFAULT_DATE_RANGE,
DEFAULT_LANGUAGE_CODE,
PROPERTY_IS_READ_ONLY_MODE,
PROPERTY_REFERRAL_PARTNERS,
PROPERTY_SYSTEM_MESSAGE,
TAG_ID_EXCLUDE_FROM_ANALYSIS,
locale as defaultLocale
@ -36,6 +37,7 @@ import {
import { SubscriptionType } from '@ghostfolio/common/enums';
import {
User as IUser,
ReferralPartner,
SystemMessage,
UserSettings
} from '@ghostfolio/common/interfaces';
@ -153,6 +155,17 @@ export class UserService {
(impersonationUserSettings?.settings as UserSettings)?.baseCurrency ??
(settings.settings as UserSettings)?.baseCurrency;
let referralPartners: ReferralPartner[];
if (
this.configurationService.get('ENABLE_FEATURE_SUBSCRIPTION') &&
subscription.type === SubscriptionType.Basic
) {
referralPartners = await this.propertyService.getByKey<ReferralPartner[]>(
PROPERTY_REFERRAL_PARTNERS
);
}
let systemMessage: SystemMessage;
const systemMessageProperty =
@ -179,6 +192,7 @@ export class UserService {
activitiesCount,
id,
permissions,
referralPartners,
subscription,
systemMessage,
tags,

1
apps/api/src/interceptors/transform-data-source-in-response/transform-data-source-in-response.interceptor.ts

@ -64,6 +64,7 @@ export class TransformDataSourceInResponseInterceptor<
paths: [
'activities[*].dataSource',
'activities[*].SymbolProfile.dataSource',
'assetProfile.dataSource',
'benchmarks[*].dataSource',
'errors[*].dataSource',
'fearAndGreedIndex.CRYPTOCURRENCIES.dataSource',

4
apps/client/src/app/components/admin-users/admin-users.html

@ -77,7 +77,7 @@
</th>
<td
*matCellDef="let element"
class="mat-mdc-cell px-1 py-2"
class="mat-mdc-cell px-1 py-2 text-nowrap"
mat-cell
>
{{ formatDistanceToNow(element.createdAt) }}
@ -183,7 +183,7 @@
</th>
<td
*matCellDef="let element"
class="mat-mdc-cell px-1 py-2"
class="mat-mdc-cell px-1 py-2 text-nowrap"
mat-cell
>
{{ formatDistanceToNow(element.lastActivity) }}

14
apps/client/src/app/pages/pricing/pricing-page.component.ts

@ -68,20 +68,6 @@ export class GfPricingPageComponent implements OnInit {
'PROFESSIONAL_DATA_PROVIDER_TOOLTIP_PREMIUM'
);
protected readonly referralBrokers = [
'Alpian',
'DEGIRO',
'finpension',
'frankly',
'Interactive Brokers',
'Mintos',
'Monefit SmartSaver',
'Revolut',
'Swissquote',
'VIAC',
'Zak'
] as const;
protected readonly routerLinkFeatures = publicRoutes.features.routerLink;
protected readonly routerLinkRegister = publicRoutes.register.routerLink;
protected user: User;

10
apps/client/src/app/pages/pricing/pricing-page.html

@ -305,23 +305,23 @@
</div>
</div>
</div>
@if (user?.subscription?.type === 'Basic') {
@if (user?.referralPartners?.length) {
<div class="row">
<div class="col mt-3">
<p>
<ng-container i18n>If you plan to open an account at</ng-container>
<ng-container>&nbsp;</ng-container>
@for (
broker of referralBrokers;
track broker;
partner of user.referralPartners;
track partner.name;
let i = $index;
let last = $last
) {
<i>{{ broker }}</i>
<i>{{ partner.name }}</i>
@if (last) {
<span>, </span>
} @else {
@if (i === referralBrokers.length - 2) {
@if (i === user.referralPartners.length - 2) {
<ng-container>&nbsp;</ng-container>
<ng-container i18n>or</ng-container>
<ng-container>&nbsp;</ng-container>

1
libs/common/src/lib/config.ts

@ -253,6 +253,7 @@ export const PROPERTY_IS_READ_ONLY_MODE = 'IS_READ_ONLY_MODE';
export const PROPERTY_IS_USER_SIGNUP_ENABLED = 'IS_USER_SIGNUP_ENABLED';
export const PROPERTY_OPENROUTER_MODEL = 'OPENROUTER_MODEL';
export const PROPERTY_OPENROUTER_MODEL_WEB_FETCH = 'OPENROUTER_MODEL_WEB_FETCH';
export const PROPERTY_REFERRAL_PARTNERS = 'REFERRAL_PARTNERS';
export const PROPERTY_SLACK_COMMUNITY_USERS = 'SLACK_COMMUNITY_USERS';
export const PROPERTY_STRIPE_CONFIG = 'STRIPE_CONFIG';
export const PROPERTY_SYSTEM_MESSAGE = 'SYSTEM_MESSAGE';

2
libs/common/src/lib/interfaces/index.ts

@ -38,6 +38,7 @@ import type { PortfolioPosition } from './portfolio-position.interface';
import type { PortfolioReportRule } from './portfolio-report-rule.interface';
import type { PortfolioSummary } from './portfolio-summary.interface';
import type { Product } from './product';
import type { ReferralPartner } from './referral-partner.interface';
import type { AccessTokenResponse } from './responses/access-token-response.interface';
import type { AccountBalancesResponse } from './responses/account-balances-response.interface';
import type { AccountResponse } from './responses/account-response.interface';
@ -181,6 +182,7 @@ export {
PublicKeyCredentialRequestOptionsJSON,
PublicPortfolioResponse,
QuotesResponse,
ReferralPartner,
ResponseError,
RuleSettings,
ScraperConfiguration,

3
libs/common/src/lib/interfaces/referral-partner.interface.ts

@ -0,0 +1,3 @@
export interface ReferralPartner {
name: string;
}

16
libs/common/src/lib/interfaces/responses/portfolio-holding-response.interface.ts

@ -9,6 +9,19 @@ import { Tag } from '@prisma/client';
export interface PortfolioHoldingResponse {
activitiesCount: number;
assetProfile: Pick<
EnhancedSymbolProfile,
| 'assetClass'
| 'assetSubClass'
| 'countries'
| 'currency'
| 'dataSource'
| 'isin'
| 'name'
| 'sectors'
| 'symbol'
| 'userId'
>;
averagePrice: number;
dataProviderInfo: DataProviderInfo;
dateOfFirstActivity: string;
@ -31,7 +44,10 @@ export interface PortfolioHoldingResponse {
netPerformanceWithCurrencyEffect: number;
performances: Benchmark['performances'];
quantity: number;
/* @deprecated */
SymbolProfile: EnhancedSymbolProfile;
tags: Tag[];
value: number;
}

2
libs/common/src/lib/interfaces/user.interface.ts

@ -3,6 +3,7 @@ import { AccountWithPlatform } from '@ghostfolio/common/types';
import { Access, Tag } from '@prisma/client';
import { ReferralPartner } from './referral-partner.interface';
import { SubscriptionOffer } from './subscription-offer.interface';
import { SystemMessage } from './system-message.interface';
import { UserSettings } from './user-settings.interface';
@ -15,6 +16,7 @@ export interface User {
dateOfFirstActivity: Date;
id: string;
permissions: string[];
referralPartners?: ReferralPartner[];
settings: UserSettings;
systemMessage?: SystemMessage;
subscription: {

4
package-lock.json

@ -1,12 +1,12 @@
{
"name": "ghostfolio",
"version": "3.11.0",
"version": "3.12.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "ghostfolio",
"version": "3.11.0",
"version": "3.12.0",
"hasInstallScript": true,
"license": "AGPL-3.0",
"dependencies": {

2
package.json

@ -1,6 +1,6 @@
{
"name": "ghostfolio",
"version": "3.11.0",
"version": "3.12.0",
"homepage": "https://ghostfol.io",
"license": "AGPL-3.0",
"repository": "https://github.com/ghostfolio/ghostfolio",

Loading…
Cancel
Save