Browse Source

Merge remote-tracking branch 'origin/main' into task/enable-strict-null-checks-in-client

pull/7309/head
KenTandrian 1 day ago
parent
commit
cb5f42a25a
  1. 3
      CHANGELOG.md
  2. 18
      apps/api/src/app/portfolio/calculator/portfolio-calculator.ts
  3. 30
      apps/api/src/app/portfolio/calculator/roai/portfolio-calculator.ts
  4. 8
      apps/api/src/app/portfolio/interfaces/portfolio-order.interface.ts
  5. 8
      apps/client/src/styles.scss
  6. 16
      libs/ui/src/lib/page-tabs/page-tabs.component.html
  7. 5
      libs/ui/src/lib/page-tabs/page-tabs.component.scss
  8. 4
      package-lock.json
  9. 2
      package.json

3
CHANGELOG.md

@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## Unreleased
## 3.25.0 - 2026-07-12
### Changed
@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Fixed
- Fixed the layout of the page tabs component by truncating long labels
- Fixed the display of assets without a currency in the search results of the assistant
- Fixed the display of assets without a currency in the symbol autocomplete component

18
apps/api/src/app/portfolio/calculator/portfolio-calculator.ts

@ -141,9 +141,9 @@ export abstract class PortfolioCalculator {
}
return {
SymbolProfile,
tags,
type,
assetProfile: SymbolProfile,
date: format(date, DATE_FORMAT),
fee: new Big(feeInAssetProfileCurrency),
feeInBaseCurrency: new Big(feeInBaseCurrency),
@ -934,23 +934,23 @@ export abstract class PortfolioCalculator {
let lastTransactionPoint: TransactionPoint = null;
for (const {
assetProfile,
date,
fee,
feeInBaseCurrency,
quantity,
SymbolProfile,
tags,
type,
unitPrice
} of this.activities) {
let currentTransactionPointItem: TransactionPointSymbol;
const assetSubClass = SymbolProfile.assetSubClass;
const currency = SymbolProfile.currency;
const dataSource = SymbolProfile.dataSource;
const assetSubClass = assetProfile.assetSubClass;
const currency = assetProfile.currency;
const dataSource = assetProfile.dataSource;
const factor = getFactor(type);
const skipErrors = !!SymbolProfile.userId; // Skip errors for custom asset profiles
const symbol = SymbolProfile.symbol;
const skipErrors = !!assetProfile.userId; // Skip errors for custom asset profiles
const symbol = assetProfile.symbol;
const oldAccumulatedSymbol = symbols[symbol];
@ -1034,12 +1034,12 @@ export abstract class PortfolioCalculator {
'id'
);
symbols[SymbolProfile.symbol] = currentTransactionPointItem;
symbols[symbol] = currentTransactionPointItem;
const items = lastTransactionPoint?.items ?? [];
const newItems = items.filter(({ symbol }) => {
return symbol !== SymbolProfile.symbol;
return symbol !== assetProfile.symbol;
});
newItems.push(currentTransactionPointItem);

30
apps/api/src/app/portfolio/calculator/roai/portfolio-calculator.ts

@ -192,12 +192,12 @@ export class RoaiPortfolioCalculator extends PortfolioCalculator {
// Clone orders to keep the original values in this.orders
let orders: PortfolioOrderItem[] = cloneDeep(
this.activities.filter(({ SymbolProfile }) => {
return SymbolProfile.symbol === symbol;
this.activities.filter(({ assetProfile }) => {
return assetProfile.symbol === symbol;
})
);
const isCash = orders[0]?.SymbolProfile?.assetSubClass === 'CASH';
const isCash = orders[0]?.assetProfile?.assetSubClass === 'CASH';
if (orders.length <= 0) {
return {
@ -299,32 +299,30 @@ export class RoaiPortfolioCalculator extends PortfolioCalculator {
};
}
const assetProfile: PortfolioOrderItem['assetProfile'] = {
dataSource,
symbol,
assetSubClass: isCash ? 'CASH' : undefined
};
// Add a synthetic order at the start and the end date
orders.push({
assetProfile,
date: startDateString,
fee: new Big(0),
feeInBaseCurrency: new Big(0),
itemType: 'start',
quantity: new Big(0),
SymbolProfile: {
dataSource,
symbol,
assetSubClass: isCash ? 'CASH' : undefined
},
type: 'BUY',
unitPrice: unitPriceAtStartDate
});
orders.push({
assetProfile,
date: endDateString,
fee: new Big(0),
feeInBaseCurrency: new Big(0),
itemType: 'end',
SymbolProfile: {
dataSource,
symbol,
assetSubClass: isCash ? 'CASH' : undefined
},
quantity: new Big(0),
type: 'BUY',
unitPrice: unitPriceAtEndDate
@ -357,15 +355,11 @@ export class RoaiPortfolioCalculator extends PortfolioCalculator {
}
} else {
orders.push({
assetProfile,
date: dateString,
fee: new Big(0),
feeInBaseCurrency: new Big(0),
quantity: new Big(0),
SymbolProfile: {
dataSource,
symbol,
assetSubClass: isCash ? 'CASH' : undefined
},
type: 'BUY',
unitPrice: marketSymbolMap[dateString]?.[symbol] ?? lastUnitPrice,
unitPriceFromMarketData:

8
apps/api/src/app/portfolio/interfaces/portfolio-order.interface.ts

@ -1,13 +1,13 @@
import { Activity } from '@ghostfolio/common/interfaces';
export interface PortfolioOrder extends Pick<Activity, 'tags' | 'type'> {
assetProfile: Pick<
Activity['SymbolProfile'],
'assetSubClass' | 'currency' | 'dataSource' | 'name' | 'symbol' | 'userId'
>;
date: string;
fee: Big;
feeInBaseCurrency: Big;
quantity: Big;
SymbolProfile: Pick<
Activity['SymbolProfile'],
'assetSubClass' | 'currency' | 'dataSource' | 'name' | 'symbol' | 'userId'
>;
unitPrice: Big;
}

8
apps/client/src/styles.scss

@ -376,12 +376,16 @@ ngx-skeleton-loader {
visibility: hidden;
}
.lead {
font-weight: unset;
}
.line-height-1 {
line-height: 1;
}
.lead {
font-weight: unset;
.line-height-normal {
line-height: normal;
}
.mat-mdc-button-base {

16
libs/ui/src/lib/page-tabs/page-tabs.component.html

@ -45,9 +45,15 @@
</nav>
<ng-template #tabContent let-tab>
<ion-icon
[name]="tab.iconName"
[size]="deviceType === 'mobile' ? 'large' : 'small'"
/>
<div class="d-none d-sm-block ml-1" [innerHTML]="tab.label"></div>
<span class="align-items-center d-flex justify-content-start text-left w-100">
<ion-icon
class="flex-shrink-0"
[name]="tab.iconName"
[size]="deviceType === 'mobile' ? 'large' : 'small'"
/>
<span
class="d-none d-sm-block line-height-normal ml-1 overflow-hidden p-0 text-truncate"
[innerHTML]="tab.label"
></span>
</span>
</ng-template>

5
libs/ui/src/lib/page-tabs/page-tabs.component.scss

@ -56,6 +56,11 @@
padding: 2rem 0;
width: 14rem;
.mat-mdc-tab-list,
.mat-mdc-tab-links {
width: 100%;
}
.mat-mdc-tab-links {
flex-direction: column;

4
package-lock.json

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

2
package.json

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

Loading…
Cancel
Save