Compare commits

...

6 Commits

Author SHA1 Message Date
github-actions[bot] 7c59a1b1d8 Update locales 3 days ago
Thomas Kaul 920d078754
Release 3.81.0 (#8085) 3 days ago
Kenrick Tandrian 035462af00
Task/widen input types in holdings and activities tables and enable strictInputTypes (#8083) 3 days ago
Thomas Kaul 2254f7989c
Bugfix/content security policy for Ghostfolio data provider (#8082) 3 days ago
Eren Emre Arik 578684b04e
Task/improve language localization for TR (20261007) (#8079) 3 days ago
Thomas Kaul 817c6775de
Task/refactor average investment of ROAI calculator (#8078) 3 days ago
  1. 4
      CHANGELOG.md
  2. 12
      apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-btcusd-buy-and-sell-partially.spec.ts
  3. 222
      apps/api/src/app/portfolio/calculator/roai/portfolio-calculator.ts
  4. 6
      apps/api/src/app/portfolio/interfaces/average-investment-item.interface.ts
  5. 8
      apps/api/src/app/portfolio/interfaces/weighted-investment.interface.ts
  6. 6
      apps/api/src/helper/security-headers.helper.spec.ts
  7. 1
      apps/api/src/helper/security-headers.helper.ts
  8. 12
      apps/client/src/locales/messages.ca.xlf
  9. 12
      apps/client/src/locales/messages.de.xlf
  10. 12
      apps/client/src/locales/messages.es.xlf
  11. 12
      apps/client/src/locales/messages.fr.xlf
  12. 12
      apps/client/src/locales/messages.it.xlf
  13. 12
      apps/client/src/locales/messages.ja.xlf
  14. 12
      apps/client/src/locales/messages.ko.xlf
  15. 12
      apps/client/src/locales/messages.nl.xlf
  16. 12
      apps/client/src/locales/messages.pl.xlf
  17. 12
      apps/client/src/locales/messages.pt.xlf
  18. 254
      apps/client/src/locales/messages.tr.xlf
  19. 12
      apps/client/src/locales/messages.uk.xlf
  20. 12
      apps/client/src/locales/messages.xlf
  21. 12
      apps/client/src/locales/messages.zh.xlf
  22. 2
      apps/client/tsconfig.json
  23. 30
      libs/ui/src/lib/activities-table/activities-table.component.ts
  24. 1
      libs/ui/src/lib/activities-table/index.ts
  25. 21
      libs/ui/src/lib/activities-table/interfaces/interfaces.ts
  26. 14
      libs/ui/src/lib/holdings-table/holdings-table.component.ts
  27. 1
      libs/ui/src/lib/holdings-table/index.ts
  28. 17
      libs/ui/src/lib/holdings-table/interfaces/interfaces.ts
  29. 4
      package-lock.json
  30. 2
      package.json

4
CHANGELOG.md

@ -5,12 +5,13 @@ 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.81.0 - 2026-10-07
### Changed
- Moved the performance calculation including dividends (total return) from experimental to general availability
- Improved the language localization for German (`de`)
- Improved the language localization for Turkish (`tr`)
### Fixed
@ -18,6 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Fixed the missing mapping for Aland Islands in the country weightings of the _Financial Modeling Prep_ service
- Fixed the net performance percentage of date ranges in the portfolio performance calculation by weighting the average investment by the number of days between the chart dates
- Fixed the start date of calendar year date ranges in the portfolio performance calculation
- Fixed an issue where the Content Security Policy in HTTP security headers blocked the status check of the Ghostfolio data provider when `ENABLE_FEATURE_SECURITY_HEADERS` was enabled (experimental)
## 3.80.2 - 2026-10-06

12
apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-btcusd-buy-and-sell-partially.spec.ts

@ -264,7 +264,7 @@ describe('PortfolioCalculator', () => {
'2017': {
date: '2017-12-31',
netPerformance: 26957.033439,
netPerformanceInPercentage: 44.10965416175681,
netPerformanceInPercentage: 44.10965416175668,
netPerformanceInPercentageWithCurrencyEffect: 43.148434302822835,
netPerformanceWithCurrencyEffect: 27081.23736,
totalInvestmentValueWithCurrencyEffect: 318.54266729999995,
@ -273,8 +273,8 @@ describe('PortfolioCalculator', () => {
max: {
date: '2018-01-01',
netPerformance: 26458.9121202,
netPerformanceInPercentage: 42.43911719562077,
netPerformanceInPercentageWithCurrencyEffect: 41.65910103572173,
netPerformanceInPercentage: 42.439117195620575,
netPerformanceInPercentageWithCurrencyEffect: 41.65910103572163,
netPerformanceWithCurrencyEffect: 26516.2087014,
totalInvestmentValueWithCurrencyEffect: 318.54266729999995,
valueWithCurrencyEffect: 13298.425356
@ -346,7 +346,7 @@ describe('PortfolioCalculator', () => {
// Other weights give another rounding of the floating point numbers
expect(
performanceByDateRange['2017'].netPerformanceInPercentage
).toBeCloseTo(44.10965416175681, 10);
).toBeCloseTo(44.10965416175668, 10);
expect(
performanceByDateRange['2017']
@ -354,13 +354,13 @@ describe('PortfolioCalculator', () => {
).toBeCloseTo(43.148434302822835, 10);
expect(performanceByDateRange.max.netPerformanceInPercentage).toBeCloseTo(
42.43911719562077,
42.439117195620575,
10
);
expect(
performanceByDateRange.max.netPerformanceInPercentageWithCurrencyEffect
).toBeCloseTo(41.65910103572173, 10);
).toBeCloseTo(41.65910103572163, 10);
});
});
});

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

@ -1,8 +1,10 @@
import { PortfolioCalculator } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator';
import { AccumulatedValues } from '@ghostfolio/api/app/portfolio/interfaces/accumulated-values.interface';
import { AverageInvestmentItem } from '@ghostfolio/api/app/portfolio/interfaces/average-investment-item.interface';
import { HoldingPerformance } from '@ghostfolio/api/app/portfolio/interfaces/holding-performance.interface';
import { PortfolioCalculatorActivityItem } from '@ghostfolio/api/app/portfolio/interfaces/portfolio-calculator-activity-item.interface';
import { PortfolioCalculatorHolding } from '@ghostfolio/api/app/portfolio/interfaces/portfolio-calculator-holding.interface';
import { WeightedInvestment } from '@ghostfolio/api/app/portfolio/interfaces/weighted-investment.interface';
import { PerformancePercentages } from '@ghostfolio/api/app/portfolio/types/performance-percentages.type';
import {
getAnnualizedPerformancePercent,
@ -29,6 +31,7 @@ import {
isBefore,
isThisYear
} from 'date-fns';
import { sortedIndex } from 'lodash-es';
export class RoaiPortfolioCalculator extends PortfolioCalculator {
protected calculateOverallPerformance(
@ -209,77 +212,60 @@ export class RoaiPortfolioCalculator extends PortfolioCalculator {
}: {
historicalDataItems: HistoricalDataItem[];
}): { [date: string]: PerformancePercentages } {
let grossPerformanceAtStartDate: number;
let grossPerformanceWithCurrencyEffectAtStartDate: number;
let previousDate: Date;
let sumOfWeightedInvestments = 0;
let sumOfWeightedInvestmentsWithCurrencyEffect = 0;
let totalInvestmentDays = 0;
let totalInvestmentDaysWithCurrencyEffect = 0;
const performancePercentagesByDate: {
[date: string]: PerformancePercentages;
} = {};
for (const [index, historicalDataItem] of historicalDataItems.entries()) {
const date = parseDate(historicalDataItem.date);
// Take the values at the start date from the first day of the date
// range
if (index === 0) {
grossPerformanceAtStartDate =
historicalDataItem.value - historicalDataItem.totalInvestment;
grossPerformanceWithCurrencyEffectAtStartDate =
historicalDataItem.valueWithCurrencyEffect -
historicalDataItem.totalInvestmentValueWithCurrencyEffect;
} else {
// The chart dates are not evenly spaced, and the investment changes on
// a chart date only. Thus the investment of the previous chart date
// applies to each day until this chart date.
const previousHistoricalDataItem = historicalDataItems[index - 1];
if (historicalDataItems.length === 0) {
return performancePercentagesByDate;
}
const daysSincePreviousChartDate = differenceInDays(date, previousDate);
const parsedDates = historicalDataItems.map(({ date }) => {
return parseDate(date);
});
if (previousHistoricalDataItem.totalInvestment > 0) {
sumOfWeightedInvestments +=
(previousHistoricalDataItem.totalInvestment +
grossPerformanceAtStartDate) *
daysSincePreviousChartDate;
const daysUntilNextItem = parsedDates.slice(1).map((nextDate, index) => {
return differenceInDays(nextDate, parsedDates[index]);
});
totalInvestmentDays += daysSincePreviousChartDate;
}
// Take the values at the start date from the first day of the date range
const [firstHistoricalDataItem] = historicalDataItems;
if (
previousHistoricalDataItem.totalInvestmentValueWithCurrencyEffect > 0
) {
sumOfWeightedInvestmentsWithCurrencyEffect +=
(previousHistoricalDataItem.totalInvestmentValueWithCurrencyEffect +
grossPerformanceWithCurrencyEffectAtStartDate) *
daysSincePreviousChartDate;
const weightedInvestments = this.getWeightedInvestments({
grossPerformanceAtStartDate: new Big(firstHistoricalDataItem.value).minus(
firstHistoricalDataItem.totalInvestment
),
items: historicalDataItems.map(({ totalInvestment }, index) => {
return {
daysUntilNextItem: daysUntilNextItem[index],
investment: new Big(totalInvestment)
};
})
});
totalInvestmentDaysWithCurrencyEffect += daysSincePreviousChartDate;
}
const weightedInvestmentsWithCurrencyEffect = this.getWeightedInvestments({
grossPerformanceAtStartDate: new Big(
firstHistoricalDataItem.valueWithCurrencyEffect
).minus(firstHistoricalDataItem.totalInvestmentValueWithCurrencyEffect),
items: historicalDataItems.map(
({ totalInvestmentValueWithCurrencyEffect }, index) => {
return {
daysUntilNextItem: daysUntilNextItem[index],
investment: new Big(totalInvestmentValueWithCurrencyEffect)
};
}
// Add the gross performance at the start date of the range to the
// investment of each day. Thus the range starts with the value of its
// first day, and subsequent buy and sell activities stay included.
const averageInvestmentValue = this.getAverageInvestment({
grossPerformanceAtStartDate,
sumOfWeightedInvestments,
totalInvestmentDays,
investment: historicalDataItem.totalInvestment
)
});
for (const [index, historicalDataItem] of historicalDataItems.entries()) {
const averageInvestmentValue = this.getAverageInvestment(
weightedInvestments[index]
).toNumber();
const averageInvestmentValueWithCurrencyEffect =
this.getAverageInvestment({
grossPerformanceAtStartDate:
grossPerformanceWithCurrencyEffectAtStartDate,
investment: historicalDataItem.totalInvestmentValueWithCurrencyEffect,
sumOfWeightedInvestments: sumOfWeightedInvestmentsWithCurrencyEffect,
totalInvestmentDays: totalInvestmentDaysWithCurrencyEffect
});
this.getAverageInvestment(
weightedInvestmentsWithCurrencyEffect[index]
).toNumber();
performancePercentagesByDate[historicalDataItem.date] = {
dividendInPercentageWithCurrencyEffect:
@ -297,8 +283,6 @@ export class RoaiPortfolioCalculator extends PortfolioCalculator {
averageInvestmentValueWithCurrencyEffect
: 0
};
previousDate = date;
}
return performancePercentagesByDate;
@ -657,46 +641,35 @@ export class RoaiPortfolioCalculator extends PortfolioCalculator {
investmentValuesAccumulatedAtStartDateWithCurrencyEffect
);
let average = new Big(0);
let dayCount = 0;
const averageInvestmentItems: AverageInvestmentItem[] = [];
for (let i = chartDates.length - 1; i >= 0; i -= 1) {
for (
let i = sortedIndex(chartDates, rangeStartDateString);
i < chartDates.length;
i += 1
) {
const date = chartDates[i];
if (date > rangeEndDateString) {
continue;
} else if (date < rangeStartDateString) {
break;
}
const isLastChartDateOfRange =
i === chartDates.length - 1 || chartDates[i + 1] > rangeEndDateString;
// The chart dates are not evenly spaced, and the investment changes
// on a chart date only. Thus the investment of a chart date applies to
// each day until the next chart date. The investment of the last chart
// date of the range counts for this day only.
const investmentDays = isLastChartDateOfRange
? 1
: daysUntilNextChartDate[i];
if (
investmentValuesAccumulatedWithCurrencyEffect[date] instanceof Big &&
investmentValuesAccumulatedWithCurrencyEffect[date].gt(0)
) {
average = average.add(
investmentValuesAccumulatedWithCurrencyEffect[date]
.add(grossPerformanceAtDateRangeStartWithCurrencyEffect)
.mul(investmentDays)
);
dayCount += investmentDays;
}
averageInvestmentItems.push({
daysUntilNextItem: daysUntilNextChartDate[i],
investment:
investmentValuesAccumulatedWithCurrencyEffect[date] ?? new Big(0)
});
}
if (dayCount > 0) {
average = average.div(dayCount);
}
const weightedInvestment = this.getWeightedInvestments({
grossPerformanceAtStartDate:
grossPerformanceAtDateRangeStartWithCurrencyEffect,
items: averageInvestmentItems
}).at(-1);
const average = weightedInvestment
? this.getAverageInvestment(weightedInvestment)
: new Big(0);
netPerformanceWithCurrencyEffectMap[dateRange] =
netPerformanceValuesWithCurrencyEffect[rangeEndDateString]?.minus(
@ -797,23 +770,64 @@ export class RoaiPortfolioCalculator extends PortfolioCalculator {
investment,
sumOfWeightedInvestments,
totalInvestmentDays
}: WeightedInvestment) {
// The investment of the current item counts for this day only
if (investment.gt(0)) {
return sumOfWeightedInvestments
.add(investment.add(grossPerformanceAtStartDate))
.div(totalInvestmentDays + 1);
}
return totalInvestmentDays > 0
? sumOfWeightedInvestments.div(totalInvestmentDays)
: new Big(0);
}
/**
* Returns the sum of the weighted investments and the number of investment
* days before each item of a date range. The chart dates are not evenly
* spaced, and the investment changes on a chart date only. Thus the
* investment of an item applies to each day until the next item.
*
* The gross performance at the start date of the range is added to each
* investment. Thus the range starts with the value of its first day, and
* subsequent buy and sell activities stay included.
*/
private getWeightedInvestments({
grossPerformanceAtStartDate,
items
}: {
grossPerformanceAtStartDate: number;
investment: number;
sumOfWeightedInvestments: number;
totalInvestmentDays: number;
grossPerformanceAtStartDate: Big;
items: AverageInvestmentItem[];
}) {
// The investment of the current chart date counts for this day only
if (investment > 0) {
return (
(sumOfWeightedInvestments +
(investment + grossPerformanceAtStartDate)) /
(totalInvestmentDays + 1)
const weightedInvestments: WeightedInvestment[] = [];
let sumOfWeightedInvestments = new Big(0);
let totalInvestmentDays = 0;
for (const [index, { investment }] of items.entries()) {
if (index > 0) {
const previousItem = items[index - 1];
if (previousItem.investment.gt(0)) {
sumOfWeightedInvestments = sumOfWeightedInvestments.add(
previousItem.investment
.add(grossPerformanceAtStartDate)
.mul(previousItem.daysUntilNextItem)
);
totalInvestmentDays += previousItem.daysUntilNextItem;
}
}
return totalInvestmentDays > 0
? sumOfWeightedInvestments / totalInvestmentDays
: 0;
weightedInvestments.push({
grossPerformanceAtStartDate,
investment,
sumOfWeightedInvestments,
totalInvestmentDays
});
}
return weightedInvestments;
}
}

6
apps/api/src/app/portfolio/interfaces/average-investment-item.interface.ts

@ -0,0 +1,6 @@
import { Big } from 'big.js';
export interface AverageInvestmentItem {
daysUntilNextItem: number;
investment: Big;
}

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

@ -0,0 +1,8 @@
import { Big } from 'big.js';
export interface WeightedInvestment {
grossPerformanceAtStartDate: Big;
investment: Big;
sumOfWeightedInvestments: Big;
totalInvestmentDays: number;
}

6
apps/api/src/helper/security-headers.helper.spec.ts

@ -52,6 +52,12 @@ describe('getHelmetOptions', () => {
);
});
it('should allow connections to ghostfol.io for the status check of the Ghostfolio data provider', () => {
expect(headers.get('content-security-policy')).toContain(
"connect-src 'self' https://ghostfol.io"
);
});
it('should not upgrade insecure requests', () => {
expect(headers.get('content-security-policy')).not.toContain(
'upgrade-insecure-requests'

1
apps/api/src/helper/security-headers.helper.ts

@ -25,6 +25,7 @@ export function getHelmetOptions({
return {
contentSecurityPolicy: {
directives: {
connectSrc: ["'self'", 'https://ghostfol.io'], // Allow connections to ghostfol.io for the status check of the Ghostfolio data provider
scriptSrc: ["'self'", "'unsafe-inline'"], // Allow inline scripts
scriptSrcAttr: ["'self'", "'unsafe-inline'"], // Allow inline event handlers
styleSrc: ["'self'", "'unsafe-inline'"], // Allow inline styles

12
apps/client/src/locales/messages.ca.xlf

@ -695,7 +695,7 @@
<target state="translated">Realment vol suprimir aquest compte?</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/accounts-table/accounts-table.component.ts</context>
<context context-type="linenumber">185</context>
<context context-type="linenumber">191</context>
</context-group>
</trans-unit>
<trans-unit id="8282940047848889809" datatype="html">
@ -1835,7 +1835,7 @@
<target state="translated">Portfolio</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts</context>
<context context-type="linenumber">156</context>
<context context-type="linenumber">162</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/header/header.component.html</context>
@ -1863,7 +1863,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts</context>
<context context-type="linenumber">168</context>
<context context-type="linenumber">174</context>
</context-group>
</trans-unit>
<trans-unit id="7695539617502213949" datatype="html">
@ -4304,7 +4304,7 @@
<target state="new">Do you really want to delete these <x id="count" equiv-text="this.totalItems"/> activities?</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/activities-table/activities-table.component.ts</context>
<context context-type="linenumber">327</context>
<context context-type="linenumber">334</context>
</context-group>
</trans-unit>
<trans-unit id="174909485329693389" datatype="html">
@ -6149,11 +6149,11 @@
<target state="translated">Realment vols suprimir aquesta activitat?</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/activities-table/activities-table.component.ts</context>
<context context-type="linenumber">326</context>
<context context-type="linenumber">333</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/activities-table/activities-table.component.ts</context>
<context context-type="linenumber">337</context>
<context context-type="linenumber">344</context>
</context-group>
</trans-unit>
<trans-unit id="3105754554141014845" datatype="html">

12
apps/client/src/locales/messages.de.xlf

@ -326,7 +326,7 @@
<target state="translated">Möchtest du dieses Konto wirklich löschen?</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/accounts-table/accounts-table.component.ts</context>
<context context-type="linenumber">185</context>
<context context-type="linenumber">191</context>
</context-group>
</trans-unit>
<trans-unit id="8282940047848889809" datatype="html">
@ -2410,7 +2410,7 @@
<target state="translated">Portfolio</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts</context>
<context context-type="linenumber">156</context>
<context context-type="linenumber">162</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/header/header.component.html</context>
@ -2606,11 +2606,11 @@
<target state="translated">Möchtest du diese Aktivität wirklich löschen?</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/activities-table/activities-table.component.ts</context>
<context context-type="linenumber">326</context>
<context context-type="linenumber">333</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/activities-table/activities-table.component.ts</context>
<context context-type="linenumber">337</context>
<context context-type="linenumber">344</context>
</context-group>
</trans-unit>
<trans-unit id="5425547984857378790" datatype="html">
@ -2978,7 +2978,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts</context>
<context context-type="linenumber">168</context>
<context context-type="linenumber">174</context>
</context-group>
</trans-unit>
<trans-unit id="4945362562621747155" datatype="html">
@ -5442,7 +5442,7 @@
<target state="translated">Möchtest du diese <x id="count" equiv-text="this.totalItems"/> Aktivitäten wirklich löschen?</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/activities-table/activities-table.component.ts</context>
<context context-type="linenumber">327</context>
<context context-type="linenumber">334</context>
</context-group>
</trans-unit>
<trans-unit id="174909485329693389" datatype="html">

12
apps/client/src/locales/messages.es.xlf

@ -327,7 +327,7 @@
<target state="translated">¿Seguro que quieres eliminar esta cuenta?</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/accounts-table/accounts-table.component.ts</context>
<context context-type="linenumber">185</context>
<context context-type="linenumber">191</context>
</context-group>
</trans-unit>
<trans-unit id="8282940047848889809" datatype="html">
@ -2395,7 +2395,7 @@
<target state="translated">Cartera</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts</context>
<context context-type="linenumber">156</context>
<context context-type="linenumber">162</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/header/header.component.html</context>
@ -2591,11 +2591,11 @@
<target state="translated">¿Seguro que quieres eliminar esta operación?</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/activities-table/activities-table.component.ts</context>
<context context-type="linenumber">326</context>
<context context-type="linenumber">333</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/activities-table/activities-table.component.ts</context>
<context context-type="linenumber">337</context>
<context context-type="linenumber">344</context>
</context-group>
</trans-unit>
<trans-unit id="5425547984857378790" datatype="html">
@ -2943,7 +2943,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts</context>
<context context-type="linenumber">168</context>
<context context-type="linenumber">174</context>
</context-group>
</trans-unit>
<trans-unit id="7341990227686441824" datatype="html">
@ -5419,7 +5419,7 @@
<target state="translated">¿De verdad quieres eliminar estas <x id="count" equiv-text="this.totalItems"/> actividades?</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/activities-table/activities-table.component.ts</context>
<context context-type="linenumber">327</context>
<context context-type="linenumber">334</context>
</context-group>
</trans-unit>
<trans-unit id="174909485329693389" datatype="html">

12
apps/client/src/locales/messages.fr.xlf

@ -390,7 +390,7 @@
<target state="translated">Voulez-vous vraiment supprimer ce compte ?</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/accounts-table/accounts-table.component.ts</context>
<context context-type="linenumber">185</context>
<context context-type="linenumber">191</context>
</context-group>
</trans-unit>
<trans-unit id="8282940047848889809" datatype="html">
@ -1070,7 +1070,7 @@
<target state="translated">Portefeuille</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts</context>
<context context-type="linenumber">156</context>
<context context-type="linenumber">162</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/header/header.component.html</context>
@ -1098,7 +1098,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts</context>
<context context-type="linenumber">168</context>
<context context-type="linenumber">174</context>
</context-group>
</trans-unit>
<trans-unit id="7695539617502213949" datatype="html">
@ -3174,11 +3174,11 @@
<target state="translated">Voulez-vous vraiment supprimer cette activité ?</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/activities-table/activities-table.component.ts</context>
<context context-type="linenumber">326</context>
<context context-type="linenumber">333</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/activities-table/activities-table.component.ts</context>
<context context-type="linenumber">337</context>
<context context-type="linenumber">344</context>
</context-group>
</trans-unit>
<trans-unit id="5425547984857378790" datatype="html">
@ -5418,7 +5418,7 @@
<target state="new">Do you really want to delete these <x id="count" equiv-text="this.totalItems"/> activities?</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/activities-table/activities-table.component.ts</context>
<context context-type="linenumber">327</context>
<context context-type="linenumber">334</context>
</context-group>
</trans-unit>
<trans-unit id="174909485329693389" datatype="html">

12
apps/client/src/locales/messages.it.xlf

@ -327,7 +327,7 @@
<target state="translated">Vuoi davvero eliminare questo account?</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/accounts-table/accounts-table.component.ts</context>
<context context-type="linenumber">185</context>
<context context-type="linenumber">191</context>
</context-group>
</trans-unit>
<trans-unit id="8282940047848889809" datatype="html">
@ -2395,7 +2395,7 @@
<target state="translated">Portafoglio</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts</context>
<context context-type="linenumber">156</context>
<context context-type="linenumber">162</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/header/header.component.html</context>
@ -2591,11 +2591,11 @@
<target state="translated">Vuoi davvero eliminare questa attività?</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/activities-table/activities-table.component.ts</context>
<context context-type="linenumber">326</context>
<context context-type="linenumber">333</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/activities-table/activities-table.component.ts</context>
<context context-type="linenumber">337</context>
<context context-type="linenumber">344</context>
</context-group>
</trans-unit>
<trans-unit id="5425547984857378790" datatype="html">
@ -2943,7 +2943,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts</context>
<context context-type="linenumber">168</context>
<context context-type="linenumber">174</context>
</context-group>
</trans-unit>
<trans-unit id="7341990227686441824" datatype="html">
@ -5419,7 +5419,7 @@
<target state="new">Do you really want to delete these <x id="count" equiv-text="this.totalItems"/> activities?</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/activities-table/activities-table.component.ts</context>
<context context-type="linenumber">327</context>
<context context-type="linenumber">334</context>
</context-group>
</trans-unit>
<trans-unit id="174909485329693389" datatype="html">

12
apps/client/src/locales/messages.ja.xlf

@ -624,7 +624,7 @@
<target state="translated">このアカウントを削除してもよろしいですか?</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/accounts-table/accounts-table.component.ts</context>
<context context-type="linenumber">185</context>
<context context-type="linenumber">191</context>
</context-group>
</trans-unit>
<trans-unit id="8282940047848889809" datatype="html">
@ -1700,7 +1700,7 @@
<target state="translated">ポートフォリオ</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts</context>
<context context-type="linenumber">156</context>
<context context-type="linenumber">162</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/header/header.component.html</context>
@ -1728,7 +1728,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts</context>
<context context-type="linenumber">168</context>
<context context-type="linenumber">174</context>
</context-group>
</trans-unit>
<trans-unit id="7695539617502213949" datatype="html">
@ -3948,7 +3948,7 @@
<target state="new">Do you really want to delete these <x id="count" equiv-text="this.totalItems"/> activities?</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/activities-table/activities-table.component.ts</context>
<context context-type="linenumber">327</context>
<context context-type="linenumber">334</context>
</context-group>
</trans-unit>
<trans-unit id="174909485329693389" datatype="html">
@ -5725,11 +5725,11 @@
<target state="translated">本当にこのアクティビティを削除したいですか?</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/activities-table/activities-table.component.ts</context>
<context context-type="linenumber">326</context>
<context context-type="linenumber">333</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/activities-table/activities-table.component.ts</context>
<context context-type="linenumber">337</context>
<context context-type="linenumber">344</context>
</context-group>
</trans-unit>
<trans-unit id="3060494754215793943" datatype="html">

12
apps/client/src/locales/messages.ko.xlf

@ -624,7 +624,7 @@
<target state="translated">이 계좌를 정말 삭제하시겠습니까?</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/accounts-table/accounts-table.component.ts</context>
<context context-type="linenumber">185</context>
<context context-type="linenumber">191</context>
</context-group>
</trans-unit>
<trans-unit id="8282940047848889809" datatype="html">
@ -1700,7 +1700,7 @@
<target state="translated">포트폴리오</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts</context>
<context context-type="linenumber">156</context>
<context context-type="linenumber">162</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/header/header.component.html</context>
@ -1728,7 +1728,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts</context>
<context context-type="linenumber">168</context>
<context context-type="linenumber">174</context>
</context-group>
</trans-unit>
<trans-unit id="7695539617502213949" datatype="html">
@ -3948,7 +3948,7 @@
<target state="new">Do you really want to delete these <x id="count" equiv-text="this.totalItems"/> activities?</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/activities-table/activities-table.component.ts</context>
<context context-type="linenumber">327</context>
<context context-type="linenumber">334</context>
</context-group>
</trans-unit>
<trans-unit id="174909485329693389" datatype="html">
@ -5717,11 +5717,11 @@
<target state="translated">정말로 이 거래를 삭제하시겠습니까?</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/activities-table/activities-table.component.ts</context>
<context context-type="linenumber">326</context>
<context context-type="linenumber">333</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/activities-table/activities-table.component.ts</context>
<context context-type="linenumber">337</context>
<context context-type="linenumber">344</context>
</context-group>
</trans-unit>
<trans-unit id="3060494754215793943" datatype="html">

12
apps/client/src/locales/messages.nl.xlf

@ -326,7 +326,7 @@
<target state="translated">Wil je deze rekening echt verwijderen?</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/accounts-table/accounts-table.component.ts</context>
<context context-type="linenumber">185</context>
<context context-type="linenumber">191</context>
</context-group>
</trans-unit>
<trans-unit id="8282940047848889809" datatype="html">
@ -2394,7 +2394,7 @@
<target state="translated">Portefeuille</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts</context>
<context context-type="linenumber">156</context>
<context context-type="linenumber">162</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/header/header.component.html</context>
@ -2590,11 +2590,11 @@
<target state="translated">Wil je deze activiteit echt verwijderen?</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/activities-table/activities-table.component.ts</context>
<context context-type="linenumber">326</context>
<context context-type="linenumber">333</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/activities-table/activities-table.component.ts</context>
<context context-type="linenumber">337</context>
<context context-type="linenumber">344</context>
</context-group>
</trans-unit>
<trans-unit id="5425547984857378790" datatype="html">
@ -2942,7 +2942,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts</context>
<context context-type="linenumber">168</context>
<context context-type="linenumber">174</context>
</context-group>
</trans-unit>
<trans-unit id="7341990227686441824" datatype="html">
@ -5418,7 +5418,7 @@
<target state="new">Do you really want to delete these <x id="count" equiv-text="this.totalItems"/> activities?</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/activities-table/activities-table.component.ts</context>
<context context-type="linenumber">327</context>
<context context-type="linenumber">334</context>
</context-group>
</trans-unit>
<trans-unit id="174909485329693389" datatype="html">

12
apps/client/src/locales/messages.pl.xlf

@ -615,7 +615,7 @@
<target state="translated">Czy na pewno chcesz usunąć to konto?</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/accounts-table/accounts-table.component.ts</context>
<context context-type="linenumber">185</context>
<context context-type="linenumber">191</context>
</context-group>
</trans-unit>
<trans-unit id="8282940047848889809" datatype="html">
@ -1667,7 +1667,7 @@
<target state="translated">Portfel</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts</context>
<context context-type="linenumber">156</context>
<context context-type="linenumber">162</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/header/header.component.html</context>
@ -1695,7 +1695,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts</context>
<context context-type="linenumber">168</context>
<context context-type="linenumber">174</context>
</context-group>
</trans-unit>
<trans-unit id="7695539617502213949" datatype="html">
@ -3915,7 +3915,7 @@
<target state="new">Do you really want to delete these <x id="count" equiv-text="this.totalItems"/> activities?</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/activities-table/activities-table.component.ts</context>
<context context-type="linenumber">327</context>
<context context-type="linenumber">334</context>
</context-group>
</trans-unit>
<trans-unit id="174909485329693389" datatype="html">
@ -5664,11 +5664,11 @@
<target state="translated">Czy na pewno chcesz usunąć tę działalność?</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/activities-table/activities-table.component.ts</context>
<context context-type="linenumber">326</context>
<context context-type="linenumber">333</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/activities-table/activities-table.component.ts</context>
<context context-type="linenumber">337</context>
<context context-type="linenumber">344</context>
</context-group>
</trans-unit>
<trans-unit id="3060494754215793943" datatype="html">

12
apps/client/src/locales/messages.pt.xlf

@ -390,7 +390,7 @@
<target state="translated">Pretende realmente eliminar esta conta?</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/accounts-table/accounts-table.component.ts</context>
<context context-type="linenumber">185</context>
<context context-type="linenumber">191</context>
</context-group>
</trans-unit>
<trans-unit id="8282940047848889809" datatype="html">
@ -902,7 +902,7 @@
<target state="translated">Portefólio</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts</context>
<context context-type="linenumber">156</context>
<context context-type="linenumber">162</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/header/header.component.html</context>
@ -930,7 +930,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts</context>
<context context-type="linenumber">168</context>
<context context-type="linenumber">174</context>
</context-group>
</trans-unit>
<trans-unit id="7695539617502213949" datatype="html">
@ -3042,11 +3042,11 @@
<target state="translated">Deseja realmente eliminar esta atividade?</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/activities-table/activities-table.component.ts</context>
<context context-type="linenumber">326</context>
<context context-type="linenumber">333</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/activities-table/activities-table.component.ts</context>
<context context-type="linenumber">337</context>
<context context-type="linenumber">344</context>
</context-group>
</trans-unit>
<trans-unit id="5425547984857378790" datatype="html">
@ -5418,7 +5418,7 @@
<target state="new">Do you really want to delete these <x id="count" equiv-text="this.totalItems"/> activities?</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/activities-table/activities-table.component.ts</context>
<context context-type="linenumber">327</context>
<context context-type="linenumber">334</context>
</context-group>
</trans-unit>
<trans-unit id="174909485329693389" datatype="html">

254
apps/client/src/locales/messages.tr.xlf

File diff suppressed because it is too large

12
apps/client/src/locales/messages.uk.xlf

@ -719,7 +719,7 @@
<target state="translated">Ви дійсно хочете видалити цей обліковий запис?</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/accounts-table/accounts-table.component.ts</context>
<context context-type="linenumber">185</context>
<context context-type="linenumber">191</context>
</context-group>
</trans-unit>
<trans-unit id="8282940047848889809" datatype="html">
@ -1959,7 +1959,7 @@
<target state="translated">Портфель</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts</context>
<context context-type="linenumber">156</context>
<context context-type="linenumber">162</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/header/header.component.html</context>
@ -1987,7 +1987,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts</context>
<context context-type="linenumber">168</context>
<context context-type="linenumber">174</context>
</context-group>
</trans-unit>
<trans-unit id="7695539617502213949" datatype="html">
@ -4608,7 +4608,7 @@
<target state="new">Do you really want to delete these <x id="count" equiv-text="this.totalItems"/> activities?</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/activities-table/activities-table.component.ts</context>
<context context-type="linenumber">327</context>
<context context-type="linenumber">334</context>
</context-group>
</trans-unit>
<trans-unit id="174909485329693389" datatype="html">
@ -6983,11 +6983,11 @@
<target state="translated">Ви дійсно хочете видалити цю активність?</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/activities-table/activities-table.component.ts</context>
<context context-type="linenumber">326</context>
<context context-type="linenumber">333</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/activities-table/activities-table.component.ts</context>
<context context-type="linenumber">337</context>
<context context-type="linenumber">344</context>
</context-group>
</trans-unit>
<trans-unit id="3105754554141014845" datatype="html">

12
apps/client/src/locales/messages.xlf

@ -590,7 +590,7 @@
<source>Do you really want to delete this account?</source>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/accounts-table/accounts-table.component.ts</context>
<context context-type="linenumber">185</context>
<context context-type="linenumber">191</context>
</context-group>
</trans-unit>
<trans-unit id="8282940047848889809" datatype="html">
@ -1558,7 +1558,7 @@
<source>Portfolio</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts</context>
<context context-type="linenumber">156</context>
<context context-type="linenumber">162</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/header/header.component.html</context>
@ -1585,7 +1585,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts</context>
<context context-type="linenumber">168</context>
<context context-type="linenumber">174</context>
</context-group>
</trans-unit>
<trans-unit id="7695539617502213949" datatype="html">
@ -3608,7 +3608,7 @@
<source>Do you really want to delete these <x id="count" equiv-text="this.totalItems"/> activities?</source>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/activities-table/activities-table.component.ts</context>
<context context-type="linenumber">327</context>
<context context-type="linenumber">334</context>
</context-group>
</trans-unit>
<trans-unit id="174909485329693389" datatype="html">
@ -5203,11 +5203,11 @@
<source>Do you really want to delete this activity?</source>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/activities-table/activities-table.component.ts</context>
<context context-type="linenumber">326</context>
<context context-type="linenumber">333</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/activities-table/activities-table.component.ts</context>
<context context-type="linenumber">337</context>
<context context-type="linenumber">344</context>
</context-group>
</trans-unit>
<trans-unit id="3060494754215793943" datatype="html">

12
apps/client/src/locales/messages.zh.xlf

@ -624,7 +624,7 @@
<target state="translated">您确定要删除此账户吗?</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/accounts-table/accounts-table.component.ts</context>
<context context-type="linenumber">185</context>
<context context-type="linenumber">191</context>
</context-group>
</trans-unit>
<trans-unit id="8282940047848889809" datatype="html">
@ -1676,7 +1676,7 @@
<target state="translated">投资组合</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts</context>
<context context-type="linenumber">156</context>
<context context-type="linenumber">162</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/header/header.component.html</context>
@ -1704,7 +1704,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts</context>
<context context-type="linenumber">168</context>
<context context-type="linenumber">174</context>
</context-group>
</trans-unit>
<trans-unit id="7695539617502213949" datatype="html">
@ -3924,7 +3924,7 @@
<target state="translated">您确定要删除这 <x id="count" equiv-text="this.totalItems"/> 笔活动吗?</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/activities-table/activities-table.component.ts</context>
<context context-type="linenumber">327</context>
<context context-type="linenumber">334</context>
</context-group>
</trans-unit>
<trans-unit id="174909485329693389" datatype="html">
@ -5701,11 +5701,11 @@
<target state="translated">您确实要删除此活动吗?</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/activities-table/activities-table.component.ts</context>
<context context-type="linenumber">326</context>
<context context-type="linenumber">333</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/activities-table/activities-table.component.ts</context>
<context context-type="linenumber">337</context>
<context context-type="linenumber">344</context>
</context-group>
</trans-unit>
<trans-unit id="3060494754215793943" datatype="html">

2
apps/client/tsconfig.json

@ -21,7 +21,7 @@
"strictDomEventTypes": true,
"strictDomLocalRefTypes": true,
"strictInputAccessModifiers": true,
"strictInputTypes": false,
"strictInputTypes": true,
"strictLiteralTypes": true,
"strictNullInputTypes": true,
"strictOutputEventTypes": true,

30
libs/ui/src/lib/activities-table/activities-table.component.ts

@ -71,6 +71,7 @@ import { GfActivityTypeComponent } from '../activity-type/activity-type.componen
import { GfEntityLogoComponent } from '../entity-logo/entity-logo.component';
import { GfNoActivitiesInfoComponent } from '../no-activities-info/no-activities-info.component';
import { GfValueComponent } from '../value/value.component';
import { ActivitiesTableItem } from './interfaces/interfaces';
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
@ -99,7 +100,11 @@ import { GfValueComponent } from '../value/value.component';
styleUrls: ['./activities-table.component.scss'],
templateUrl: './activities-table.component.html'
})
export class GfActivitiesTableComponent implements AfterViewInit, OnInit {
export class GfActivitiesTableComponent<
T extends ActivitiesTableItem = Activity
>
implements AfterViewInit, OnInit
{
@Input() public baseCurrency?: string;
@Input() public deviceType: string;
@Input() public hasActivities: boolean;
@ -127,7 +132,7 @@ export class GfActivitiesTableComponent implements AfterViewInit, OnInit {
@Output() import = new EventEmitter<void>();
@Output() importDividends = new EventEmitter<AssetProfileIdentifier>();
@Output() pageChanged = new EventEmitter<PageEvent>();
@Output() selectedActivities = new EventEmitter<Activity[]>();
@Output() selectedActivities = new EventEmitter<T[]>();
@Output() sortChanged = new EventEmitter<Sort>();
@Output() typesFilterChanged = new EventEmitter<string[]>();
@ -138,12 +143,12 @@ export class GfActivitiesTableComponent implements AfterViewInit, OnInit {
public hasErrors = false;
public isDraftActivity = isDraftActivity;
public isUUID = isUUID;
public selectedRows = new SelectionModel<Activity>(true, []);
public selectedRows = new SelectionModel<T>(true, []);
public typesFilter = new FormControl<string[]>([]);
public readonly activityTypes = input<ActivityType[]>([]);
public readonly dataSource = input.required<
MatTableDataSource<Activity> | undefined
MatTableDataSource<T> | undefined
>();
public readonly showAccountColumn = input(true);
public readonly showCheckbox = input(false);
@ -158,12 +163,14 @@ export class GfActivitiesTableComponent implements AfterViewInit, OnInit {
{ clone: string[]; update: string[] }
>();
for (const { id } of this.dataSource()?.data ?? []) {
routerLinks.set(id, {
clone: clone.routerLink(id),
update: update.routerLink(id)
for (const activity of this.dataSource()?.data ?? []) {
if (activity.id) {
routerLinks.set(activity.id, {
clone: clone.routerLink(activity.id),
update: update.routerLink(activity.id)
});
}
}
return routerLinks;
});
@ -276,7 +283,7 @@ export class GfActivitiesTableComponent implements AfterViewInit, OnInit {
return numSelectedRows === numTotalRows;
}
public canClickActivity(activity: Activity) {
public canClickActivity(activity: T) {
return (
this.hasPermissionToOpenDetails &&
isDraftActivity(activity) === false &&
@ -302,7 +309,7 @@ export class GfActivitiesTableComponent implements AfterViewInit, OnInit {
this.pageChanged.emit(page);
}
public onClickActivity(activity: Activity) {
public onClickActivity(activity: T) {
if (this.showCheckbox()) {
if (!activity.error) {
this.selectedRows.toggle(activity);
@ -355,6 +362,9 @@ export class GfActivitiesTableComponent implements AfterViewInit, OnInit {
.map((activity) => {
return activity.id;
})
.filter((id): id is string => {
return !!id;
})
);
}

1
libs/ui/src/lib/activities-table/index.ts

@ -1 +1,2 @@
export * from './activities-table.component';
export * from './interfaces/interfaces';

21
libs/ui/src/lib/activities-table/interfaces/interfaces.ts

@ -0,0 +1,21 @@
import { Activity, EnhancedAssetProfile } from '@ghostfolio/common/interfaces';
export interface ActivitiesTableItem
extends
Pick<
Activity,
| 'currency'
| 'date'
| 'fee'
| 'quantity'
| 'type'
| 'unitPrice'
| 'value'
| 'valueInBaseCurrency'
>,
Partial<Pick<Activity, 'account' | 'comment' | 'error' | 'id' | 'tags'>> {
assetProfile: Pick<
EnhancedAssetProfile,
'currency' | 'dataSource' | 'name' | 'symbol'
>;
}

14
libs/ui/src/lib/holdings-table/holdings-table.component.ts

@ -6,10 +6,7 @@ import {
getLowercase,
isCashPosition
} from '@ghostfolio/common/helper';
import {
AssetProfileIdentifier,
PortfolioPosition
} from '@ghostfolio/common/interfaces';
import { AssetProfileIdentifier } from '@ghostfolio/common/interfaces';
import {
CUSTOM_ELEMENTS_SCHEMA,
@ -31,6 +28,7 @@ import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader';
import { GfEntityLogoComponent } from '../entity-logo/entity-logo.component';
import { GfValueComponent } from '../value/value.component';
import { HoldingsTableItem } from './interfaces/interfaces';
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
@ -53,7 +51,7 @@ export class GfHoldingsTableComponent {
public readonly hasPermissionToOpenDetails = input(true);
public readonly hasPermissionToShowQuantities = input(true);
public readonly hasPermissionToShowValues = input(true);
public readonly holdings = input.required<PortfolioPosition[] | undefined>();
public readonly holdings = input.required<HoldingsTableItem[] | undefined>();
public readonly locale = input(getLocale(), {
transform: (value?: string) => {
@ -69,7 +67,7 @@ export class GfHoldingsTableComponent {
protected readonly paginator = viewChild.required(MatPaginator);
protected readonly sort = viewChild.required(MatSort);
protected readonly dataSource = new MatTableDataSource<PortfolioPosition>([]);
protected readonly dataSource = new MatTableDataSource<HoldingsTableItem>([]);
protected readonly displayedColumns = computed(() => {
if (this.mode() === 'simple') {
@ -134,13 +132,13 @@ export class GfHoldingsTableComponent {
});
}
protected canShowDetails(holding: PortfolioPosition): boolean {
protected canShowDetails(holding: HoldingsTableItem): boolean {
return this.hasPermissionToOpenDetails() && canOpenHoldingDetail(holding);
}
protected getCountryCodeForCashPosition({
assetProfile
}: PortfolioPosition): string {
}: HoldingsTableItem): string {
return isCashPosition(assetProfile)
? getCountryCodeFromCurrency(assetProfile.currency)
: '';

1
libs/ui/src/lib/holdings-table/index.ts

@ -1 +1,2 @@
export * from './holdings-table.component';
export * from './interfaces/interfaces';

17
libs/ui/src/lib/holdings-table/interfaces/interfaces.ts

@ -0,0 +1,17 @@
import { PortfolioPosition } from '@ghostfolio/common/interfaces';
export interface HoldingsTableItem
extends
Pick<
PortfolioPosition,
| 'allocationInPercentage'
| 'assetProfile'
| 'dateOfFirstActivity'
| 'netPerformancePercentWithCurrencyEffect'
>,
Partial<
Pick<
PortfolioPosition,
'netPerformanceWithCurrencyEffect' | 'quantity' | 'valueInBaseCurrency'
>
> {}

4
package-lock.json

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

2
package.json

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

Loading…
Cancel
Save