Compare commits

...

10 Commits

Author SHA1 Message Date
38474f54b0 Release 1.225.0 (#1580) 2023-01-07 18:26:38 +01:00
18d25fb6c2 Feature/extend faq page (#1577)
* Extend FAQ page

* Update changelog
2023-01-07 18:21:09 +01:00
a850e8ca22 Import dividend (#1560)
* Import dividend

* Update changelog
2023-01-07 18:20:02 +01:00
b5f565c054 Simplify data source transformation (#1578) 2023-01-07 17:06:42 +01:00
aa6d0a4533 Update dates (#1575) 2023-01-07 08:48:06 +01:00
25e9028a41 Release 1.224.0 (#1573) 2023-01-04 20:15:29 +01:00
925d38703e Feature/add group by year option on analysis page (#1568)
* Add group by year option
2023-01-04 20:13:13 +01:00
158bb00b8a Add missing dutch translations (#1572)
* Add missing dutch translations

* Update changelog
2023-01-03 21:12:01 +01:00
b17111e6f1 Feature/setup fr (#1571)
* Setup fr

* Update changelog
2023-01-02 21:19:19 +01:00
c4765e31cd Feature/setup pt (#1439)
* Setup pt

* Update changelog
2023-01-02 20:52:48 +01:00
67 changed files with 4636 additions and 686 deletions

View File

@ -5,6 +5,29 @@ 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).
## 1.225.0 - 2023-01-07
### Added
- Added support for importing dividends from a data provider
### Changed
- Extended the Frequently Asked Questions (FAQ) page
## 1.224.0 - 2023-01-04
### Added
- Added support for the dividend timeline grouped by year
- Added support for the investment timeline grouped by year
- Set up the language localization for Français (`fr`)
- Set up the language localization for Português (`pt`)
### Changed
- Improved the language localization for Dutch (`nl`)
## 1.223.0 - 2023-01-01
### Added

View File

@ -48,7 +48,7 @@ Ghostfolio is for you if you are...
- 🧘 into minimalism
- 🧺 caring about diversifying your financial resources
- 🆓 interested in financial independence
- 🙅 saying no to spreadsheets in 2022
- 🙅 saying no to spreadsheets in 2023
- 😎 still reading this list
## Features
@ -282,6 +282,6 @@ If you like to support this project, get **[Ghostfolio Premium](https://ghostfol
## License
© 2022 [Ghostfolio](https://ghostfol.io)
© 2023 [Ghostfolio](https://ghostfol.io)
Licensed under the [AGPLv3 License](https://www.gnu.org/licenses/agpl-3.0.html).

View File

@ -14,8 +14,10 @@ export class FrontendMiddleware implements NestMiddleware {
public indexHtmlDe = '';
public indexHtmlEn = '';
public indexHtmlEs = '';
public indexHtmlFr = '';
public indexHtmlIt = '';
public indexHtmlNl = '';
public indexHtmlPt = '';
public isProduction: boolean;
public constructor(
@ -41,6 +43,10 @@ export class FrontendMiddleware implements NestMiddleware {
this.getPathOfIndexHtmlFile('es'),
'utf8'
);
this.indexHtmlFr = fs.readFileSync(
this.getPathOfIndexHtmlFile('fr'),
'utf8'
);
this.indexHtmlIt = fs.readFileSync(
this.getPathOfIndexHtmlFile('it'),
'utf8'
@ -49,6 +55,10 @@ export class FrontendMiddleware implements NestMiddleware {
this.getPathOfIndexHtmlFile('nl'),
'utf8'
);
this.indexHtmlPt = fs.readFileSync(
this.getPathOfIndexHtmlFile('pt'),
'utf8'
);
} catch {}
}
@ -104,6 +114,15 @@ export class FrontendMiddleware implements NestMiddleware {
rootUrl: this.configurationService.get('ROOT_URL')
})
);
} else if (request.path === '/fr' || request.path.startsWith('/fr/')) {
response.send(
this.interpolate(this.indexHtmlFr, {
featureGraphicPath,
languageCode: 'fr',
path: request.path,
rootUrl: this.configurationService.get('ROOT_URL')
})
);
} else if (request.path === '/it' || request.path.startsWith('/it/')) {
response.send(
this.interpolate(this.indexHtmlIt, {
@ -126,6 +145,15 @@ export class FrontendMiddleware implements NestMiddleware {
rootUrl: this.configurationService.get('ROOT_URL')
})
);
} else if (request.path === '/pt' || request.path.startsWith('/pt/')) {
response.send(
this.interpolate(this.indexHtmlPt, {
featureGraphicPath,
languageCode: 'pt',
path: request.path,
rootUrl: this.configurationService.get('ROOT_URL')
})
);
} else {
response.send(
this.interpolate(this.indexHtmlEn, {

View File

@ -1,19 +1,26 @@
import { TransformDataSourceInRequestInterceptor } from '@ghostfolio/api/interceptors/transform-data-source-in-request.interceptor';
import { TransformDataSourceInResponseInterceptor } from '@ghostfolio/api/interceptors/transform-data-source-in-response.interceptor';
import { ConfigurationService } from '@ghostfolio/api/services/configuration.service';
import { ImportResponse } from '@ghostfolio/common/interfaces';
import type { RequestWithUser } from '@ghostfolio/common/types';
import {
Body,
Controller,
Get,
HttpException,
Inject,
Logger,
Param,
Post,
Query,
UseGuards
UseGuards,
UseInterceptors
} from '@nestjs/common';
import { REQUEST } from '@nestjs/core';
import { AuthGuard } from '@nestjs/passport';
import { DataSource } from '@prisma/client';
import { StatusCodes, getReasonPhrase } from 'http-status-codes';
import { isEmpty } from 'lodash';
import { ImportDataDto } from './import-data.dto';
import { ImportService } from './import.service';
@ -74,4 +81,23 @@ export class ImportController {
);
}
}
@Get('dividends/:dataSource/:symbol')
@UseGuards(AuthGuard('jwt'))
@UseInterceptors(TransformDataSourceInRequestInterceptor)
@UseInterceptors(TransformDataSourceInResponseInterceptor)
public async gatherDividends(
@Param('dataSource') dataSource: DataSource,
@Param('symbol') symbol: string
): Promise<ImportResponse> {
const userCurrency = this.request.user.Settings.settings.baseCurrency;
const activities = await this.importService.getDividends({
dataSource,
symbol,
userCurrency
});
return { activities };
}
}

View File

@ -1,12 +1,14 @@
import { AccountModule } from '@ghostfolio/api/app/account/account.module';
import { CacheModule } from '@ghostfolio/api/app/cache/cache.module';
import { OrderModule } from '@ghostfolio/api/app/order/order.module';
import { PortfolioModule } from '@ghostfolio/api/app/portfolio/portfolio.module';
import { RedisCacheModule } from '@ghostfolio/api/app/redis-cache/redis-cache.module';
import { ConfigurationModule } from '@ghostfolio/api/services/configuration.module';
import { DataGatheringModule } from '@ghostfolio/api/services/data-gathering.module';
import { DataProviderModule } from '@ghostfolio/api/services/data-provider/data-provider.module';
import { ExchangeRateDataModule } from '@ghostfolio/api/services/exchange-rate-data.module';
import { PrismaModule } from '@ghostfolio/api/services/prisma.module';
import { SymbolProfileModule } from '@ghostfolio/api/services/symbol-profile.module';
import { Module } from '@nestjs/common';
import { ImportController } from './import.controller';
@ -22,8 +24,10 @@ import { ImportService } from './import.service';
DataProviderModule,
ExchangeRateDataModule,
OrderModule,
PortfolioModule,
PrismaModule,
RedisCacheModule
RedisCacheModule,
SymbolProfileModule
],
providers: [ImportService]
})

View File

@ -2,9 +2,16 @@ import { AccountService } from '@ghostfolio/api/app/account/account.service';
import { CreateOrderDto } from '@ghostfolio/api/app/order/create-order.dto';
import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface';
import { OrderService } from '@ghostfolio/api/app/order/order.service';
import { PortfolioService } from '@ghostfolio/api/app/portfolio/portfolio.service';
import { DataProviderService } from '@ghostfolio/api/services/data-provider/data-provider.service';
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data.service';
import { OrderWithAccount } from '@ghostfolio/common/types';
import { SymbolProfileService } from '@ghostfolio/api/services/symbol-profile.service';
import { parseDate } from '@ghostfolio/common/helper';
import { UniqueAsset } from '@ghostfolio/common/interfaces';
import {
AccountWithPlatform,
OrderWithAccount
} from '@ghostfolio/common/types';
import { Injectable } from '@nestjs/common';
import { SymbolProfile } from '@prisma/client';
import Big from 'big.js';
@ -17,9 +24,81 @@ export class ImportService {
private readonly accountService: AccountService,
private readonly dataProviderService: DataProviderService,
private readonly exchangeRateDataService: ExchangeRateDataService,
private readonly orderService: OrderService
private readonly orderService: OrderService,
private readonly portfolioService: PortfolioService,
private readonly symbolProfileService: SymbolProfileService
) {}
public async getDividends({
dataSource,
symbol,
userCurrency
}: UniqueAsset & { userCurrency: string }): Promise<Activity[]> {
try {
const { firstBuyDate, historicalData, orders } =
await this.portfolioService.getPosition(dataSource, undefined, symbol);
const [[assetProfile], dividends] = await Promise.all([
this.symbolProfileService.getSymbolProfiles([
{
dataSource,
symbol
}
]),
await this.dataProviderService.getDividends({
dataSource,
symbol,
from: parseDate(firstBuyDate),
granularity: 'day',
to: new Date()
})
]);
const accounts = orders.map((order) => {
return order.Account;
});
const Account = this.isUniqueAccount(accounts) ? accounts[0] : undefined;
return Object.entries(dividends).map(([dateString, { marketPrice }]) => {
const quantity =
historicalData.find((historicalDataItem) => {
return historicalDataItem.date === dateString;
})?.quantity ?? 0;
const value = new Big(quantity).mul(marketPrice).toNumber();
return {
Account,
quantity,
value,
accountId: Account?.id,
accountUserId: undefined,
comment: undefined,
createdAt: undefined,
date: parseDate(dateString),
fee: 0,
feeInBaseCurrency: 0,
id: assetProfile.id,
isDraft: false,
SymbolProfile: <SymbolProfile>(<unknown>assetProfile),
symbolProfileId: assetProfile.id,
type: 'DIVIDEND',
unitPrice: marketPrice,
updatedAt: undefined,
userId: Account?.userId,
valueInBaseCurrency: this.exchangeRateDataService.toCurrency(
value,
assetProfile.currency,
userCurrency
)
};
});
} catch {
return [];
}
}
public async import({
activitiesDto,
isDryRun = false,
@ -161,6 +240,16 @@ export class ImportService {
return activities;
}
private isUniqueAccount(accounts: AccountWithPlatform[]) {
const uniqueAccountIds = new Set<string>();
for (const account of accounts) {
uniqueAccountIds.add(account.id);
}
return uniqueAccountIds.size === 1;
}
private async validateActivities({
activitiesDto,
maxActivitiesToImport,

View File

@ -64,7 +64,8 @@ describe('PortfolioCalculator', () => {
const investments = portfolioCalculator.getInvestments();
const investmentsByMonth = portfolioCalculator.getInvestmentsByMonth();
const investmentsByMonth =
portfolioCalculator.getInvestmentsByGroup('month');
spy.mockRestore();

View File

@ -53,7 +53,8 @@ describe('PortfolioCalculator', () => {
const investments = portfolioCalculator.getInvestments();
const investmentsByMonth = portfolioCalculator.getInvestmentsByMonth();
const investmentsByMonth =
portfolioCalculator.getInvestmentsByGroup('month');
spy.mockRestore();

View File

@ -64,7 +64,8 @@ describe('PortfolioCalculator', () => {
const investments = portfolioCalculator.getInvestments();
const investmentsByMonth = portfolioCalculator.getInvestmentsByMonth();
const investmentsByMonth =
portfolioCalculator.getInvestmentsByGroup('month');
spy.mockRestore();

View File

@ -41,7 +41,8 @@ describe('PortfolioCalculator', () => {
const investments = portfolioCalculator.getInvestments();
const investmentsByMonth = portfolioCalculator.getInvestmentsByMonth();
const investmentsByMonth =
portfolioCalculator.getInvestmentsByGroup('month');
spy.mockRestore();

View File

@ -64,7 +64,8 @@ describe('PortfolioCalculator', () => {
const investments = portfolioCalculator.getInvestments();
const investmentsByMonth = portfolioCalculator.getInvestmentsByMonth();
const investmentsByMonth =
portfolioCalculator.getInvestmentsByGroup('month');
spy.mockRestore();

View File

@ -68,7 +68,8 @@ describe('PortfolioCalculator', () => {
const investments = portfolioCalculator.getInvestments();
const investmentsByMonth = portfolioCalculator.getInvestmentsByMonth();
const investmentsByMonth =
portfolioCalculator.getInvestmentsByGroup('month');
spy.mockRestore();

View File

@ -2,6 +2,7 @@ import { TimelineInfoInterface } from '@ghostfolio/api/app/portfolio/interfaces/
import { IDataGatheringItem } from '@ghostfolio/api/services/interfaces/interfaces';
import { DATE_FORMAT, parseDate, resetHours } from '@ghostfolio/common/helper';
import { ResponseError, TimelinePosition } from '@ghostfolio/common/interfaces';
import { GroupBy } from '@ghostfolio/common/types';
import { Logger } from '@nestjs/common';
import { Type as TypeOfOrder } from '@prisma/client';
import Big from 'big.js';
@ -478,46 +479,60 @@ export class PortfolioCalculator {
});
}
public getInvestmentsByMonth(): { date: string; investment: Big }[] {
public getInvestmentsByGroup(
groupBy: GroupBy
): { date: string; investment: Big }[] {
if (this.orders.length === 0) {
return [];
}
const investments = [];
let currentDate: Date;
let investmentByMonth = new Big(0);
let investmentByGroup = new Big(0);
for (const [index, order] of this.orders.entries()) {
if (
isSameMonth(parseDate(order.date), currentDate) &&
isSameYear(parseDate(order.date), currentDate)
isSameYear(parseDate(order.date), currentDate) &&
(groupBy === 'year' || isSameMonth(parseDate(order.date), currentDate))
) {
// Same month: Add up investments
// Same group: Add up investments
investmentByMonth = investmentByMonth.plus(
investmentByGroup = investmentByGroup.plus(
order.quantity.mul(order.unitPrice).mul(this.getFactor(order.type))
);
} else {
// New month: Store previous month and reset
// New group: Store previous group and reset
if (currentDate) {
investments.push({
date: format(set(currentDate, { date: 1 }), DATE_FORMAT),
investment: investmentByMonth
date: format(
set(currentDate, {
date: 1,
month: groupBy === 'year' ? 0 : currentDate.getMonth()
}),
DATE_FORMAT
),
investment: investmentByGroup
});
}
currentDate = parseDate(order.date);
investmentByMonth = order.quantity
investmentByGroup = order.quantity
.mul(order.unitPrice)
.mul(this.getFactor(order.type));
}
if (index === this.orders.length - 1) {
// Store current month (latest order)
// Store current group (latest order)
investments.push({
date: format(set(currentDate, { date: 1 }), DATE_FORMAT),
investment: investmentByMonth
date: format(
set(currentDate, {
date: 1,
month: groupBy === 'year' ? 0 : currentDate.getMonth()
}),
DATE_FORMAT
),
investment: investmentByGroup
});
}
}

View File

@ -235,8 +235,8 @@ export class PortfolioService {
};
});
if (groupBy === 'month') {
dividends = this.getDividendsByMonth(dividends);
if (groupBy) {
dividends = this.getDividendsByGroup({ dividends, groupBy });
}
const startDate = this.getStartDate(
@ -282,26 +282,31 @@ export class PortfolioService {
let investments: InvestmentItem[];
if (groupBy === 'month') {
investments = portfolioCalculator.getInvestmentsByMonth().map((item) => {
return {
date: item.date,
investment: item.investment.toNumber()
};
});
if (groupBy) {
investments = portfolioCalculator
.getInvestmentsByGroup(groupBy)
.map((item) => {
return {
date: item.date,
investment: item.investment.toNumber()
};
});
// Add investment of current month
const dateOfCurrentMonth = format(
set(new Date(), { date: 1 }),
// Add investment of current group
const dateOfCurrentGroup = format(
set(new Date(), {
date: 1,
month: groupBy === 'year' ? 0 : new Date().getMonth()
}),
DATE_FORMAT
);
const investmentOfCurrentMonth = investments.filter(({ date }) => {
return date === dateOfCurrentMonth;
const investmentOfCurrentGroup = investments.filter(({ date }) => {
return date === dateOfCurrentGroup;
});
if (investmentOfCurrentMonth.length <= 0) {
if (investmentOfCurrentGroup.length <= 0) {
investments.push({
date: dateOfCurrentMonth,
date: dateOfCurrentGroup,
investment: 0
});
}
@ -655,8 +660,9 @@ export class PortfolioService {
}
const positionCurrency = orders[0].SymbolProfile.currency;
const [SymbolProfile] =
await this.symbolProfileService.getSymbolProfilesBySymbols([aSymbol]);
const [SymbolProfile] = await this.symbolProfileService.getSymbolProfiles([
{ dataSource: aDataSource, symbol: aSymbol }
]);
const portfolioOrders: PortfolioOrder[] = orders
.filter((order) => {
@ -740,6 +746,7 @@ export class PortfolioService {
historicalDataArray.push({
averagePrice: orders[0].unitPrice,
date: firstBuyDate,
quantity: orders[0].quantity,
value: orders[0].unitPrice
});
}
@ -756,6 +763,7 @@ export class PortfolioService {
j++;
}
let currentAveragePrice = 0;
let currentQuantity = 0;
const currentSymbol = transactionPoints[j].items.find(
(item) => item.symbol === aSymbol
);
@ -763,11 +771,13 @@ export class PortfolioService {
currentAveragePrice = currentSymbol.quantity.eq(0)
? 0
: currentSymbol.investment.div(currentSymbol.quantity).toNumber();
currentQuantity = currentSymbol.quantity.toNumber();
}
historicalDataArray.push({
date,
averagePrice: currentAveragePrice,
quantity: currentQuantity,
value: marketPrice
});
@ -1264,47 +1274,66 @@ export class PortfolioService {
);
}
private getDividendsByMonth(aDividends: InvestmentItem[]): InvestmentItem[] {
if (aDividends.length === 0) {
private getDividendsByGroup({
dividends,
groupBy
}: {
dividends: InvestmentItem[];
groupBy: GroupBy;
}): InvestmentItem[] {
if (dividends.length === 0) {
return [];
}
const dividends = [];
const dividendsByGroup: InvestmentItem[] = [];
let currentDate: Date;
let investmentByMonth = new Big(0);
let investmentByGroup = new Big(0);
for (const [index, dividend] of aDividends.entries()) {
for (const [index, dividend] of dividends.entries()) {
if (
isSameMonth(parseDate(dividend.date), currentDate) &&
isSameYear(parseDate(dividend.date), currentDate)
isSameYear(parseDate(dividend.date), currentDate) &&
(groupBy === 'year' ||
isSameMonth(parseDate(dividend.date), currentDate))
) {
// Same month: Add up divididends
// Same group: Add up dividends
investmentByMonth = investmentByMonth.plus(dividend.investment);
investmentByGroup = investmentByGroup.plus(dividend.investment);
} else {
// New month: Store previous month and reset
// New group: Store previous group and reset
if (currentDate) {
dividends.push({
date: format(set(currentDate, { date: 1 }), DATE_FORMAT),
investment: investmentByMonth
dividendsByGroup.push({
date: format(
set(currentDate, {
date: 1,
month: groupBy === 'year' ? 0 : currentDate.getMonth()
}),
DATE_FORMAT
),
investment: investmentByGroup.toNumber()
});
}
currentDate = parseDate(dividend.date);
investmentByMonth = new Big(dividend.investment);
investmentByGroup = new Big(dividend.investment);
}
if (index === aDividends.length - 1) {
if (index === dividends.length - 1) {
// Store current month (latest order)
dividends.push({
date: format(set(currentDate, { date: 1 }), DATE_FORMAT),
investment: investmentByMonth
dividendsByGroup.push({
date: format(
set(currentDate, {
date: 1,
month: groupBy === 'year' ? 0 : currentDate.getMonth()
}),
DATE_FORMAT
),
investment: investmentByGroup.toNumber()
});
}
}
return dividends;
return dividendsByGroup;
}
private getFees({

View File

@ -27,3 +27,40 @@ export function nullifyValuesInObjects<T>(aObjects: T[], keys: string[]): T[] {
return nullifyValuesInObject(object, keys);
});
}
export function redactAttributes({
object,
options
}: {
object: any;
options: { attribute: string; valueMap: { [key: string]: any } }[];
}): any {
if (!object || !options || !options.length) {
return object;
}
const redactedObject = cloneDeep(object);
for (const option of options) {
if (redactedObject.hasOwnProperty(option.attribute)) {
redactedObject[option.attribute] =
option.valueMap[redactedObject[option.attribute]] ??
option.valueMap['*'] ??
redactedObject[option.attribute];
} else {
// If the attribute is not present on the current object,
// check if it exists on any nested objects
for (const property in redactedObject) {
if (typeof redactedObject[property] === 'object') {
// Recursively call the function on the nested object
redactedObject[property] = redactAttributes({
options,
object: redactedObject[property]
});
}
}
}
}
return redactedObject;
}

View File

@ -1,3 +1,4 @@
import { redactAttributes } from '@ghostfolio/api/helper/object.helper';
import { encodeDataSource } from '@ghostfolio/common/helper';
import {
CallHandler,
@ -5,7 +6,7 @@ import {
Injectable,
NestInterceptor
} from '@nestjs/common';
import { isArray } from 'lodash';
import { DataSource } from '@prisma/client';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
@ -28,63 +29,23 @@ export class TransformDataSourceInResponseInterceptor<T>
if (
this.configurationService.get('ENABLE_FEATURE_SUBSCRIPTION') === true
) {
if (data.activities) {
data.activities.map((activity) => {
activity.SymbolProfile.dataSource = encodeDataSource(
activity.SymbolProfile.dataSource
);
return activity;
});
}
if (isArray(data.benchmarks)) {
data.benchmarks.map((benchmark) => {
benchmark.dataSource = encodeDataSource(benchmark.dataSource);
return benchmark;
});
}
if (data.dataSource) {
data.dataSource = encodeDataSource(data.dataSource);
}
if (data.errors) {
for (const error of data.errors) {
if (error.dataSource) {
error.dataSource = encodeDataSource(error.dataSource);
data = redactAttributes({
options: [
{
attribute: 'dataSource',
valueMap: Object.keys(DataSource).reduce(
(valueMap, dataSource) => {
valueMap[dataSource] = encodeDataSource(
DataSource[dataSource]
);
return valueMap;
},
{}
)
}
}
}
if (data.holdings) {
for (const symbol of Object.keys(data.holdings)) {
if (data.holdings[symbol].dataSource) {
data.holdings[symbol].dataSource = encodeDataSource(
data.holdings[symbol].dataSource
);
}
}
}
if (data.items) {
data.items.map((item) => {
item.dataSource = encodeDataSource(item.dataSource);
return item;
});
}
if (data.positions) {
data.positions.map((position) => {
position.dataSource = encodeDataSource(position.dataSource);
return position;
});
}
if (data.SymbolProfile) {
data.SymbolProfile.dataSource = encodeDataSource(
data.SymbolProfile.dataSource
);
}
],
object: data
});
}
return data;

View File

@ -37,6 +37,20 @@ export class AlphaVantageService implements DataProviderInterface {
};
}
public async getDividends({
from,
granularity = 'day',
symbol,
to
}: {
from: Date;
granularity: Granularity;
symbol: string;
to: Date;
}) {
return {};
}
public async getHistorical(
aSymbol: string,
aGranularity: Granularity = 'day',

View File

@ -59,6 +59,10 @@ import { DataProviderService } from './data-provider.service';
]
}
],
exports: [DataProviderService, GhostfolioScraperApiService]
exports: [
DataProviderService,
GhostfolioScraperApiService,
YahooFinanceService
]
})
export class DataProviderModule {}

View File

@ -23,6 +23,27 @@ export class DataProviderService {
private readonly prismaService: PrismaService
) {}
public async getDividends({
dataSource,
from,
granularity = 'day',
symbol,
to
}: {
dataSource: DataSource;
from: Date;
granularity: Granularity;
symbol: string;
to: Date;
}) {
return this.getDataProvider(DataSource[dataSource]).getDividends({
from,
granularity,
symbol,
to
});
}
public async getHistorical(
aItems: IDataGatheringItem[],
aGranularity: Granularity = 'month',

View File

@ -37,6 +37,20 @@ export class EodHistoricalDataService implements DataProviderInterface {
};
}
public async getDividends({
from,
granularity = 'day',
symbol,
to
}: {
from: Date;
granularity: Granularity;
symbol: string;
to: Date;
}) {
return {};
}
public async getHistorical(
aSymbol: string,
aGranularity: Granularity = 'day',

View File

@ -37,6 +37,20 @@ export class GhostfolioScraperApiService implements DataProviderInterface {
};
}
public async getDividends({
from,
granularity = 'day',
symbol,
to
}: {
from: Date;
granularity: Granularity;
symbol: string;
to: Date;
}) {
return {};
}
public async getHistorical(
aSymbol: string,
aGranularity: Granularity = 'day',

View File

@ -34,6 +34,20 @@ export class GoogleSheetsService implements DataProviderInterface {
};
}
public async getDividends({
from,
granularity = 'day',
symbol,
to
}: {
from: Date;
granularity: Granularity;
symbol: string;
to: Date;
}) {
return {};
}
public async getHistorical(
aSymbol: string,
aGranularity: Granularity = 'day',

View File

@ -11,6 +11,18 @@ export interface DataProviderInterface {
getAssetProfile(aSymbol: string): Promise<Partial<SymbolProfile>>;
getDividends({
from,
granularity,
symbol,
to
}: {
from: Date;
granularity: Granularity;
symbol: string;
to: Date;
}): Promise<{ [date: string]: IDataProviderHistoricalResponse }>;
getHistorical(
aSymbol: string,
aGranularity: Granularity,

View File

@ -29,6 +29,20 @@ export class ManualService implements DataProviderInterface {
};
}
public async getDividends({
from,
granularity = 'day',
symbol,
to
}: {
from: Date;
granularity: Granularity;
symbol: string;
to: Date;
}) {
return {};
}
public async getHistorical(
aSymbol: string,
aGranularity: Granularity = 'day',

View File

@ -31,6 +31,20 @@ export class RapidApiService implements DataProviderInterface {
};
}
public async getDividends({
from,
granularity = 'day',
symbol,
to
}: {
from: Date;
granularity: Granularity;
symbol: string;
to: Date;
}) {
return {};
}
public async getHistorical(
aSymbol: string,
aGranularity: Granularity = 'day',

View File

@ -160,6 +160,59 @@ export class YahooFinanceService implements DataProviderInterface {
return response;
}
public async getDividends({
from,
granularity = 'day',
symbol,
to
}: {
from: Date;
granularity: Granularity;
symbol: string;
to: Date;
}) {
if (isSameDay(from, to)) {
to = addDays(to, 1);
}
try {
const historicalResult = await yahooFinance.historical(
this.convertToYahooFinanceSymbol(symbol),
{
events: 'dividends',
interval: granularity === 'month' ? '1mo' : '1d',
period1: format(from, DATE_FORMAT),
period2: format(to, DATE_FORMAT)
}
);
const response: {
[date: string]: IDataProviderHistoricalResponse;
} = {};
for (const historicalItem of historicalResult) {
response[format(historicalItem.date, DATE_FORMAT)] = {
marketPrice: this.getConvertedValue({
symbol,
value: historicalItem.dividends
})
};
}
return response;
} catch (error) {
Logger.error(
`Could not get dividends for ${symbol} (${this.getName()}) from ${format(
from,
DATE_FORMAT
)} to ${format(to, DATE_FORMAT)}: [${error.name}] ${error.message}`,
'YahooFinanceService'
);
return {};
}
}
public async getHistorical(
aSymbol: string,
aGranularity: Granularity = 'day',
@ -172,11 +225,9 @@ export class YahooFinanceService implements DataProviderInterface {
to = addDays(to, 1);
}
const yahooFinanceSymbol = this.convertToYahooFinanceSymbol(aSymbol);
try {
const historicalResult = await yahooFinance.historical(
yahooFinanceSymbol,
this.convertToYahooFinanceSymbol(aSymbol),
{
interval: '1d',
period1: format(from, DATE_FORMAT),
@ -188,27 +239,14 @@ export class YahooFinanceService implements DataProviderInterface {
[symbol: string]: { [date: string]: IDataProviderHistoricalResponse };
} = {};
// Convert symbol back
const symbol = this.convertFromYahooFinanceSymbol(yahooFinanceSymbol);
response[symbol] = {};
response[aSymbol] = {};
for (const historicalItem of historicalResult) {
let marketPrice = historicalItem.close;
if (symbol === `${this.baseCurrency}GBp`) {
// Convert GPB to GBp (pence)
marketPrice = new Big(marketPrice).mul(100).toNumber();
} else if (symbol === `${this.baseCurrency}ILA`) {
// Convert ILS to ILA
marketPrice = new Big(marketPrice).mul(100).toNumber();
} else if (symbol === `${this.baseCurrency}ZAc`) {
// Convert ZAR to ZAc (cents)
marketPrice = new Big(marketPrice).mul(100).toNumber();
}
response[symbol][format(historicalItem.date, DATE_FORMAT)] = {
marketPrice,
response[aSymbol][format(historicalItem.date, DATE_FORMAT)] = {
marketPrice: this.getConvertedValue({
symbol: aSymbol,
value: historicalItem.close
}),
performance: historicalItem.open - historicalItem.close
};
}
@ -423,6 +461,27 @@ export class YahooFinanceService implements DataProviderInterface {
return name || shortName || symbol;
}
private getConvertedValue({
symbol,
value
}: {
symbol: string;
value: number;
}) {
if (symbol === `${this.baseCurrency}GBp`) {
// Convert GPB to GBp (pence)
return new Big(value).mul(100).toNumber();
} else if (symbol === `${this.baseCurrency}ILA`) {
// Convert ILS to ILA
return new Big(value).mul(100).toNumber();
} else if (symbol === `${this.baseCurrency}ZAc`) {
// Convert ZAR to ZAc (cents)
return new Big(value).mul(100).toNumber();
}
return value;
}
private parseAssetClass(aPrice: Price): {
assetClass: AssetClass;
assetSubClass: AssetSubClass;

View File

@ -89,6 +89,10 @@
"baseHref": "/es/",
"localize": ["es"]
},
"development-fr": {
"baseHref": "/fr/",
"localize": ["fr"]
},
"development-it": {
"baseHref": "/it/",
"localize": ["it"]
@ -97,6 +101,10 @@
"baseHref": "/nl/",
"localize": ["nl"]
},
"development-pt": {
"baseHref": "/pt/",
"localize": ["pt"]
},
"production": {
"fileReplacements": [
{
@ -144,12 +152,18 @@
"development-es": {
"browserTarget": "client:build:development-es"
},
"development-fr": {
"browserTarget": "client:build:development-fr"
},
"development-it": {
"browserTarget": "client:build:development-it"
},
"development-nl": {
"browserTarget": "client:build:development-nl"
},
"development-pt": {
"browserTarget": "client:build:development-pt"
},
"production": {
"browserTarget": "client:build:production"
}
@ -164,8 +178,10 @@
"targetFiles": [
"messages.de.xlf",
"messages.es.xlf",
"messages.fr.xlf",
"messages.it.xlf",
"messages.nl.xlf"
"messages.nl.xlf",
"messages.pt.xlf"
]
}
},
@ -194,6 +210,10 @@
"baseHref": "/es/",
"translation": "apps/client/src/locales/messages.es.xlf"
},
"fr": {
"baseHref": "/fr/",
"translation": "apps/client/src/locales/messages.fr.xlf"
},
"it": {
"baseHref": "/it/",
"translation": "apps/client/src/locales/messages.it.xlf"
@ -201,6 +221,10 @@
"nl": {
"baseHref": "/nl/",
"translation": "apps/client/src/locales/messages.nl.xlf"
},
"pt": {
"baseHref": "/pt/",
"translation": "apps/client/src/locales/messages.pt.xlf"
}
},
"sourceLocale": "en"

View File

@ -198,6 +198,15 @@ export class InvestmentChartComponent implements OnChanges, OnDestroy {
this.chart.options.scales.x.min = this.daysInMarket
? subDays(new Date(), this.daysInMarket).toISOString()
: undefined;
if (
this.savingsRate &&
this.chart.options.plugins.annotation.annotations.savingsRate
) {
this.chart.options.plugins.annotation.annotations.savingsRate.value =
this.savingsRate;
}
this.chart.update();
} else {
this.chart = new Chart(this.chartCanvas.nativeElement, {

View File

@ -55,7 +55,17 @@ export class AccountPageComponent implements OnDestroy, OnInit {
public hasPermissionToUpdateViewMode: boolean;
public hasPermissionToUpdateUserSettings: boolean;
public language = document.documentElement.lang;
public locales = ['de', 'de-CH', 'en-GB', 'en-US', 'es', 'it', 'nl'];
public locales = [
'de',
'de-CH',
'en-GB',
'en-US',
'es',
'fr',
'it',
'nl',
'pt'
];
public price: number;
public priceId: string;
public snackBarRef: MatSnackBarRef<TextOnlySnackBar>;

View File

@ -135,6 +135,10 @@
>Español (<ng-container i18n>Community</ng-container
>)</mat-option
>
<!--<mat-option value="fr"
>Français (<ng-container i18n>Community</ng-container
>)</mat-option
>-->
<mat-option value="it"
>Italiano (<ng-container i18n>Community</ng-container
>)</mat-option
@ -143,6 +147,10 @@
>Nederlands (<ng-container i18n>Community</ng-container
>)</mat-option
>
<!--<mat-option value="pt"
>Português (<ng-container i18n>Community</ng-container
>)</mat-option
>-->
</mat-select>
</mat-form-field>
</div>

View File

@ -125,7 +125,7 @@
feedback, bug reports, feature requests and of course contributions!
</p>
<p>
You can reach me by email at
You can reach me by e-mail at
<a href="mailto:hi@ghostfol.io">hi@ghostfol.io</a> or on Twitter
<a href="https://twitter.com/ghostfolio_">@ghostfolio_</a>.
</p>

View File

@ -99,7 +99,7 @@
>
of users. In the future, I would like to involve more contributors
to further extend the functionality of Ghostfolio (e.g. with new
reports). Get in touch with me by email at
reports). Get in touch with me by e-mail at
<a href="mailto:hi@ghostfol.io">hi@ghostfol.io</a> or on Twitter
<a href="https://twitter.com/ghostfolio_">@ghostfolio_</a> if you
are interested, Im happy to discuss ideas.

View File

@ -64,15 +64,15 @@
<p>
When you authenticate with <i>Internet Identity</i>, the service
only gets a dedicated pseudonym rather than sensitive user data like
the email address or phone number. This preserves your anonymity and
prevents you being tracked on the Internet.
the e-mail address or phone number. This preserves your anonymity
and prevents you being tracked on the Internet.
</p>
</section>
<section class="mb-4">
<h2 class="h4">The key benefits in a nutshell</h2>
<ul>
<li>
Authenticate yourself securely without the need of an email
Authenticate yourself securely without the need of an e-mail
address, username, or a password: all you need is your device to
log in.
</li>
@ -89,7 +89,7 @@
<section class="mb-4">
<p>
If you would like to provide feedback or get involved in further
development of Ghostfolio, please get in touch by email via
development of Ghostfolio, please get in touch by e-mail via
<a href="mailto:hi@ghostfol.io">hi@ghostfol.io</a> or on Twitter
<a href="https://twitter.com/ghostfolio_">@ghostfolio_</a>.
</p>

View File

@ -62,7 +62,7 @@
new and better Internet based on decentralized blockchains to give
power back to the users. <i>Internet Identity</i> created by the
<a href="https://dfinity.org">Dfinity Foundation</a> enables you to
sign in securely and anonymously to Ghostfolio without an email
sign in securely and anonymously to Ghostfolio without an e-mail
address, username, or a password. All you need is your device with
built-in biometric authentication.
</p>
@ -90,7 +90,7 @@
onboard more contributors who are actively involved in software
engineering to realize the full potential of open source software.
If you are a web developer and interested in personal finance,
please get in touch by email via
please get in touch by e-mail via
<a href="mailto:hi@ghostfol.io">hi@ghostfol.io</a> or on Twitter
<a href="https://twitter.com/ghostfolio_">@ghostfolio_</a>. We are
happy to discuss ideas.

View File

@ -83,7 +83,7 @@
<a href="https://ghostfolio.slack.com">Slack community</a> or get in
touch on Twitter
<a href="https://twitter.com/ghostfolio_">@ghostfolio_</a> or by
email via <a href="mailto:hi@ghostfol.io">hi@ghostfol.io</a>.
e-mail via <a href="mailto:hi@ghostfol.io">hi@ghostfol.io</a>.
</p>
<p>
We look forward to hearing from you.<br />

View File

@ -48,7 +48,7 @@
<a href="../en/blog/2022/07/ghostfolio-meets-internet-identity"
>Internet Identity</a
>) enable you to sign in securely and anonymously to Ghostfolio. There
is no need for an email address, phone number, or a username.
is no need for an e-mail address, phone number, or a username.
</mat-card-content>
</mat-card>
<mat-card class="mb-3">
@ -57,10 +57,11 @@
>This project is driven by the efforts of contributors from around the
world. The
<a href="https://github.com/ghostfolio/ghostfolio">source code</a> is
fully available as open source software (OSS). Our
fully available as open source software (OSS). Thanks to our generous
<a [routerLink]="['/pricing']">Ghostfolio Premium</a> users and
<a href="https://www.buymeacoffee.com/ghostfolio">sponsors</a> allow
us to run a free, limited plan for new investors.</mat-card-content
<a href="https://www.buymeacoffee.com/ghostfolio">sponsors</a> we have
the ability to run a free, limited plan for new
investors.</mat-card-content
>
</mat-card>
<mat-card class="mb-3">
@ -77,7 +78,8 @@
><a [routerLink]="['/pricing']">Ghostfolio Premium</a> is a fully
managed Ghostfolio cloud offering for ambitious investors. The revenue
is used to cover the hosting infrastructure. It is the Open Source
code base with some extras like the market overview.</mat-card-content
code base with some extras like the
<a [routerLink]="['/markets']">markets overview</a>.</mat-card-content
>
</mat-card>
<mat-card class="mb-3">
@ -85,24 +87,45 @@
<mat-card-content
>Yes, you can try
<a [routerLink]="['/pricing']">Ghostfolio Premium</a> by signing up
for Ghostfolio and applying for a trial (see “My Ghostfolio”). Its
for Ghostfolio and applying for a trial (see “My Ghostfolio”). It is
easy, free and there is no commitment. You can stop using it at any
time.</mat-card-content
>
</mat-card>
<mat-card class="mb-3">
<mat-card-title
>How can I get a student discount for Ghostfolio
Premium?</mat-card-title
>
<mat-card-content
>Request your student discount
<a href="mailto:hi@ghostfol.io?Subject=Student Discount">here</a> with
your university e-mail address.</mat-card-content
>
</mat-card>
<mat-card class="mb-3">
<mat-card-title>Which devices are supported?</mat-card-title>
<mat-card-content
>Ghostfolio works in every modern web browser on smartphones, tablets
and desktop computers (where you have even more analysis options and
statistics). For Android users, there is a dedicated Ghostfolio app
available in the
and desktop computers. For <i>Android</i> users, there is a dedicated
Ghostfolio app available in the
<a
href="https://play.google.com/store/apps/details?id=ch.dotsilver.ghostfolio.twa"
>Google Play Store</a
>.</mat-card-content
>
</mat-card>
<mat-card class="mb-3">
<mat-card-title
>I cannot find my broker in the list of platforms. What can I
do?</mat-card-title
>
<mat-card-content>
Please send an e-mail with the web address of your broker to
<a href="mailto:hi@ghostfol.io">hi@ghostfol.io</a> and we are happy to
add it.
</mat-card-content>
</mat-card>
<mat-card class="mb-3">
<mat-card-title
>Ghostfolio sounds cool, how can I get involved?</mat-card-title
@ -117,7 +140,7 @@
>, a star on
<a href="https://github.com/ghostfolio/ghostfolio">GitHub</a>,
feedback, bug reports, feature requests and of course contributions!
You can reach us by email at
You can reach us by e-mail at
<a href="mailto:hi@ghostfol.io">hi@ghostfol.io</a> or on Twitter
<a href="https://twitter.com/ghostfolio_">@ghostfolio_</a
>.</mat-card-content

View File

@ -197,8 +197,12 @@
<div class="flex-grow-1">
<h4>Multi-Language</h4>
<p class="m-0">
Use Ghostfolio in multiple languages: English, Dutch, German,
Italian and Spanish are currently supported.
Use Ghostfolio in multiple languages: English,
Dutch<ng-container *ngIf="false">, Français</ng-container>,
German, Italian<ng-container *ngIf="false"
>, Portuguese</ng-container
>
and Spanish are currently supported.
</p>
</div>
</mat-card>

View File

@ -11,7 +11,7 @@ import { IcsService } from '@ghostfolio/client/services/ics/ics.service';
import { ImpersonationStorageService } from '@ghostfolio/client/services/impersonation-storage.service';
import { UserService } from '@ghostfolio/client/services/user/user.service';
import { downloadAsFile } from '@ghostfolio/common/helper';
import { User } from '@ghostfolio/common/interfaces';
import { UniqueAsset, User } from '@ghostfolio/common/interfaces';
import { hasPermission, permissions } from '@ghostfolio/common/permissions';
import { DataSource, Order as OrderModel } from '@prisma/client';
import { format, parseISO } from 'date-fns';
@ -198,6 +198,24 @@ export class ActivitiesPageComponent implements OnDestroy, OnInit {
});
}
public onImportDividends() {
const dialogRef = this.dialog.open(ImportActivitiesDialog, {
data: <ImportActivitiesDialogParams>{
activityTypes: ['DIVIDEND'],
deviceType: this.deviceType,
user: this.user
},
width: this.deviceType === 'mobile' ? '100vw' : '50rem'
});
dialogRef
.afterClosed()
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe(() => {
this.fetchActivities();
});
}
public onUpdateActivity(aActivity: OrderModel) {
this.router.navigate([], {
queryParams: { activityId: aActivity.id, editDialog: true }

View File

@ -17,6 +17,7 @@
(export)="onExport($event)"
(exportDrafts)="onExportDrafts($event)"
(import)="onImport()"
(importDividends)="onImportDividends()"
></gf-activities-table>
</div>
</div>

View File

@ -5,12 +5,16 @@ import {
Inject,
OnDestroy
} from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { MatSnackBar } from '@angular/material/snack-bar';
import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface';
import { DataService } from '@ghostfolio/client/services/data.service';
import { ImportActivitiesService } from '@ghostfolio/client/services/import-activities.service';
import { isArray } from 'lodash';
import { Subject } from 'rxjs';
import { Position } from '@ghostfolio/common/interfaces';
import { AssetClass } from '@prisma/client';
import { isArray, sortBy } from 'lodash';
import { Subject, takeUntil } from 'rxjs';
import { ImportActivitiesDialogParams } from './interfaces/interfaces';
@ -24,20 +28,55 @@ export class ImportActivitiesDialog implements OnDestroy {
public activities: Activity[] = [];
public details: any[] = [];
public errorMessages: string[] = [];
public holdings: Position[] = [];
public isFileSelected = false;
public mode: 'DIVIDEND';
public selectedActivities: Activity[] = [];
public uniqueAssetForm: FormGroup;
private unsubscribeSubject = new Subject<void>();
public constructor(
private changeDetectorRef: ChangeDetectorRef,
@Inject(MAT_DIALOG_DATA) public data: ImportActivitiesDialogParams,
private dataService: DataService,
private formBuilder: FormBuilder,
public dialogRef: MatDialogRef<ImportActivitiesDialog>,
private importActivitiesService: ImportActivitiesService,
private snackBar: MatSnackBar
) {}
public ngOnInit() {}
public ngOnInit() {
this.uniqueAssetForm = this.formBuilder.group({
uniqueAsset: [undefined, Validators.required]
});
if (
this.data?.activityTypes?.length === 1 &&
this.data?.activityTypes?.[0] === 'DIVIDEND'
) {
this.mode = 'DIVIDEND';
this.dataService
.fetchPositions({
filters: [
{
id: AssetClass.EQUITY,
type: 'ASSET_CLASS'
}
],
range: 'max'
})
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe(({ positions }) => {
this.holdings = sortBy(positions, ({ name }) => {
return name.toLowerCase();
});
this.changeDetectorRef.markForCheck();
});
}
}
public onCancel(): void {
this.dialogRef.close();
@ -71,6 +110,24 @@ export class ImportActivitiesDialog implements OnDestroy {
}
}
public onLoadDividends() {
const { dataSource, symbol } =
this.uniqueAssetForm.controls['uniqueAsset'].value;
this.dataService
.fetchDividendsImport({
dataSource,
symbol
})
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe(({ activities }) => {
this.activities = activities;
this.isFileSelected = true;
this.changeDetectorRef.markForCheck();
});
}
public onReset() {
this.details = [];
this.errorMessages = [];
@ -95,8 +152,6 @@ export class ImportActivitiesDialog implements OnDestroy {
reader.onload = async (readerEvent) => {
const fileContent = readerEvent.target.result as string;
console.log(fileContent);
try {
if (file.name.endsWith('.json')) {
const content = JSON.parse(fileContent);

View File

@ -7,31 +7,59 @@
<div class="flex-grow-1" mat-dialog-content>
<ng-container *ngIf="!isFileSelected">
<div class="d-flex justify-content-center flex-column">
<button
class="py-3"
color="primary"
mat-stroked-button
(click)="onSelectFile()"
>
<ion-icon class="mr-2" name="cloud-upload-outline"></ion-icon>
<span i18n>Choose File</span>
</button>
<p class="mb-0 mt-4 text-center">
<span class="mr-1" i18n>The following file formats are supported:</span>
<a
href="https://github.com/ghostfolio/ghostfolio/blob/main/test/import/ok.csv"
target="_blank"
>CSV</a
<ng-container *ngIf="mode === 'DIVIDEND'; else selectFile">
<form [formGroup]="uniqueAssetForm" (ngSubmit)="onLoadDividends()">
<mat-form-field appearance="outline" class="w-100">
<mat-label i18n>Holding</mat-label>
<mat-select formControlName="uniqueAsset">
<mat-option
*ngFor="let holding of holdings"
[value]="{dataSource: holding.dataSource, symbol: holding.symbol}"
>{{ holding.name }}</mat-option
>
</mat-select>
</mat-form-field>
<div class="d-flex justify-content-center flex-column">
<button
color="primary"
mat-flat-button
type="submit"
[disabled]="!uniqueAssetForm.valid"
>
<span i18n>Load Dividends</span>
</button>
</div>
</form>
</ng-container>
<ng-template #selectFile>
<div class="d-flex justify-content-center flex-column">
<button
class="py-3"
color="primary"
mat-stroked-button
(click)="onSelectFile()"
>
<span class="mx-1" i18n>or</span>
<a
href="https://github.com/ghostfolio/ghostfolio/blob/main/test/import/ok.json"
target="_blank"
>JSON</a
>
</p>
</div>
<ion-icon class="mr-2" name="cloud-upload-outline"></ion-icon>
<span i18n>Choose File</span>
</button>
<p class="mb-0 mt-4 text-center">
<span class="mr-1" i18n
>The following file formats are supported:</span
>
<a
href="https://github.com/ghostfolio/ghostfolio/blob/main/test/import/ok.csv"
target="_blank"
>CSV</a
>
<span class="mx-1" i18n>or</span>
<a
href="https://github.com/ghostfolio/ghostfolio/blob/main/test/import/ok.json"
target="_blank"
>JSON</a
>
</p>
</div>
</ng-template>
</ng-container>
<ng-container *ngIf="isFileSelected">
<ng-container *ngIf="errorMessages.length === 0; else errorMessage">
@ -47,6 +75,7 @@
[locale]="data?.user?.settings?.locale"
[showActions]="false"
[showCheckbox]="true"
[showFooter]="false"
[showSymbolColumn]="false"
(selectedActivities)="updateSelection($event)"
></gf-activities-table>

View File

@ -1,8 +1,11 @@
import { CommonModule } from '@angular/common';
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { MatButtonModule } from '@angular/material/button';
import { MatDialogModule } from '@angular/material/dialog';
import { MatExpansionModule } from '@angular/material/expansion';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatSelectModule } from '@angular/material/select';
import { GfDialogFooterModule } from '@ghostfolio/client/components/dialog-footer/dialog-footer.module';
import { GfDialogHeaderModule } from '@ghostfolio/client/components/dialog-header/dialog-header.module';
import { GfActivitiesTableModule } from '@ghostfolio/ui/activities-table/activities-table.module';
@ -13,12 +16,16 @@ import { ImportActivitiesDialog } from './import-activities-dialog.component';
declarations: [ImportActivitiesDialog],
imports: [
CommonModule,
FormsModule,
GfActivitiesTableModule,
GfDialogFooterModule,
GfDialogHeaderModule,
MatButtonModule,
MatDialogModule,
MatExpansionModule
MatExpansionModule,
MatFormFieldModule,
MatSelectModule,
ReactiveFormsModule
],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
})

View File

@ -1,6 +1,8 @@
import { User } from '@ghostfolio/common/interfaces';
import { Type } from '@prisma/client';
export interface ImportActivitiesDialogParams {
activityTypes: Type[];
deviceType: string;
user: User;
}

View File

@ -39,19 +39,20 @@ export class AnalysisPageComponent implements OnDestroy, OnInit {
public dateRangeOptions = ToggleComponent.DEFAULT_DATE_RANGE_OPTIONS;
public daysInMarket: number;
public deviceType: string;
public dividendsByMonth: InvestmentItem[];
public dividendsByGroup: InvestmentItem[];
public dividendTimelineDataLabel = $localize`Dividend`;
public filters$ = new Subject<Filter[]>();
public firstOrderDate: Date;
public hasImpersonationId: boolean;
public investments: InvestmentItem[];
public investmentTimelineDataLabel = $localize`Deposit`;
public investmentsByMonth: InvestmentItem[];
public investmentsByGroup: InvestmentItem[];
public isLoadingBenchmarkComparator: boolean;
public isLoadingInvestmentChart: boolean;
public mode: GroupBy = 'month';
public modeOptions: ToggleOption[] = [
{ label: $localize`Monthly`, value: 'month' }
{ label: $localize`Monthly`, value: 'month' },
{ label: $localize`Yearly`, value: 'year' }
];
public performanceDataItems: HistoricalDataItem[];
public performanceDataItemsInPercentage: HistoricalDataItem[];
@ -91,6 +92,17 @@ export class AnalysisPageComponent implements OnDestroy, OnInit {
});
}
get savingsRate() {
const savingsRatePerMonth =
this.hasImpersonationId || this.user.settings.isRestrictedView
? undefined
: this.user?.settings?.savingsRate;
return this.mode === 'year'
? savingsRatePerMonth * 12
: savingsRatePerMonth;
}
public ngOnInit() {
this.deviceType = this.deviceService.getDeviceInfo().deviceType;
@ -201,6 +213,7 @@ export class AnalysisPageComponent implements OnDestroy, OnInit {
public onChangeGroupBy(aMode: GroupBy) {
this.mode = aMode;
this.fetchDividendsAndInvestments();
}
public ngOnDestroy() {
@ -208,6 +221,34 @@ export class AnalysisPageComponent implements OnDestroy, OnInit {
this.unsubscribeSubject.complete();
}
private fetchDividendsAndInvestments() {
this.dataService
.fetchDividends({
filters: this.activeFilters,
groupBy: this.mode,
range: this.user?.settings?.dateRange
})
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe(({ dividends }) => {
this.dividendsByGroup = dividends;
this.changeDetectorRef.markForCheck();
});
this.dataService
.fetchInvestments({
filters: this.activeFilters,
groupBy: this.mode,
range: this.user?.settings?.dateRange
})
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe(({ investments }) => {
this.investmentsByGroup = investments;
this.changeDetectorRef.markForCheck();
});
}
private openPositionDialog({
dataSource,
symbol
@ -291,32 +332,6 @@ export class AnalysisPageComponent implements OnDestroy, OnInit {
this.changeDetectorRef.markForCheck();
});
this.dataService
.fetchDividends({
filters: this.activeFilters,
groupBy: 'month',
range: this.user?.settings?.dateRange
})
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe(({ dividends }) => {
this.dividendsByMonth = dividends;
this.changeDetectorRef.markForCheck();
});
this.dataService
.fetchInvestments({
filters: this.activeFilters,
groupBy: 'month',
range: this.user?.settings?.dateRange
})
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe(({ investments }) => {
this.investmentsByMonth = investments;
this.changeDetectorRef.markForCheck();
});
this.dataService
.fetchPositions({
filters: this.activeFilters,
@ -340,6 +355,7 @@ export class AnalysisPageComponent implements OnDestroy, OnInit {
this.changeDetectorRef.markForCheck();
});
this.fetchDividendsAndInvestments();
this.changeDetectorRef.markForCheck();
}

View File

@ -180,15 +180,15 @@
<div class="chart-container">
<gf-investment-chart
class="h-100"
groupBy="month"
[benchmarkDataItems]="investmentsByMonth"
[benchmarkDataItems]="investmentsByGroup"
[benchmarkDataLabel]="investmentTimelineDataLabel"
[currency]="user?.settings?.baseCurrency"
[daysInMarket]="daysInMarket"
[groupBy]="mode"
[isInPercent]="hasImpersonationId || user.settings.isRestrictedView"
[locale]="user?.settings?.locale"
[range]="user?.settings?.dateRange"
[savingsRate]="(hasImpersonationId || user.settings.isRestrictedView) ? undefined : user?.settings?.savingsRate"
[savingsRate]="savingsRate"
></gf-investment-chart>
</div>
</div>
@ -217,11 +217,11 @@
<div class="chart-container">
<gf-investment-chart
class="h-100"
groupBy="month"
[benchmarkDataItems]="dividendsByMonth"
[benchmarkDataItems]="dividendsByGroup"
[benchmarkDataLabel]="dividendTimelineDataLabel"
[currency]="user?.settings?.baseCurrency"
[daysInMarket]="daysInMarket"
[groupBy]="mode"
[isInPercent]="hasImpersonationId || user.settings.isRestrictedView"
[locale]="user?.settings?.locale"
[range]="user?.settings?.dateRange"

View File

@ -18,7 +18,7 @@
to use our referral link and get a Ghostfolio Premium membership for
one year. Looking for a student discount? Request it
<a href="mailto:hi@ghostfol.io?Subject=Student Discount">here</a> with
your university email address.
your university e-mail address.
</p>
<p>
If you prefer to run Ghostfolio on your own infrastructure, please

View File

@ -24,6 +24,7 @@ import {
BenchmarkResponse,
Export,
Filter,
ImportResponse,
InfoItem,
OAuthResponse,
PortfolioDetails,
@ -119,6 +120,12 @@ export class DataService {
});
}
public fetchDividendsImport({ dataSource, symbol }: UniqueAsset) {
return this.http.get<ImportResponse>(
`/api/v1/import/dividends/${dataSource}/${symbol}`
);
}
public fetchExchangeRateForDate({
date,
symbol

View File

@ -90,13 +90,16 @@ export class ImportActivitiesService {
selectedActivities: Activity[]
): Promise<Activity[]> {
const importData: CreateOrderDto[] = [];
for (const activity of selectedActivities) {
importData.push(this.convertToCreateOrderDto(activity));
}
return this.importJson({ content: importData });
}
private convertToCreateOrderDto({
accountId,
date,
fee,
quantity,
@ -105,6 +108,7 @@ export class ImportActivitiesService {
unitPrice
}: Activity): CreateOrderDto {
return {
accountId,
fee,
quantity,
type,

View File

@ -6,82 +6,82 @@
http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">
<url>
<loc>https://ghostfol.io</loc>
<lastmod>2022-12-26T00:00:00+00:00</lastmod>
<lastmod>2023-01-05T00:00:00+00:00</lastmod>
</url>
<url>
<loc>https://ghostfol.io/de/blog/2021/07/hallo-ghostfolio</loc>
<lastmod>2022-12-26T00:00:00+00:00</lastmod>
<lastmod>2023-01-05T00:00:00+00:00</lastmod>
</url>
<url>
<loc>https://ghostfol.io/en/about</loc>
<lastmod>2022-12-26T00:00:00+00:00</lastmod>
<lastmod>2023-01-05T00:00:00+00:00</lastmod>
</url>
<url>
<loc>https://ghostfol.io/en/about/changelog</loc>
<lastmod>2022-12-26T00:00:00+00:00</lastmod>
<lastmod>2023-01-05T00:00:00+00:00</lastmod>
</url>
<url>
<loc>https://ghostfol.io/en/blog</loc>
<lastmod>2022-12-26T00:00:00+00:00</lastmod>
<lastmod>2023-01-05T00:00:00+00:00</lastmod>
</url>
<url>
<loc>https://ghostfol.io/en/blog/2021/07/hello-ghostfolio</loc>
<lastmod>2022-12-26T00:00:00+00:00</lastmod>
<lastmod>2023-01-05T00:00:00+00:00</lastmod>
</url>
<url>
<loc>https://ghostfol.io/en/blog/2022/01/ghostfolio-first-months-in-open-source</loc>
<lastmod>2022-12-26T00:00:00+00:00</lastmod>
<lastmod>2023-01-05T00:00:00+00:00</lastmod>
</url>
<url>
<loc>https://ghostfol.io/en/blog/2022/07/ghostfolio-meets-internet-identity</loc>
<lastmod>2022-12-26T00:00:00+00:00</lastmod>
<lastmod>2023-01-05T00:00:00+00:00</lastmod>
</url>
<url>
<loc>https://ghostfol.io/en/blog/2022/07/how-do-i-get-my-finances-in-order</loc>
<lastmod>2022-12-26T00:00:00+00:00</lastmod>
<lastmod>2023-01-05T00:00:00+00:00</lastmod>
</url>
<url>
<loc>https://ghostfol.io/en/blog/2022/08/500-stars-on-github</loc>
<lastmod>2022-12-26T00:00:00+00:00</lastmod>
<lastmod>2023-01-05T00:00:00+00:00</lastmod>
</url>
<url>
<loc>https://ghostfol.io/en/blog/2022/10/hacktoberfest-2022</loc>
<lastmod>2022-12-26T00:00:00+00:00</lastmod>
<lastmod>2023-01-05T00:00:00+00:00</lastmod>
</url>
<url>
<loc>https://ghostfol.io/en/blog/2022/11/black-friday-2022</loc>
<lastmod>2022-12-26T00:00:00+00:00</lastmod>
<lastmod>2023-01-05T00:00:00+00:00</lastmod>
</url>
<url>
<loc>https://ghostfol.io/en/blog/2022/12/the-importance-of-tracking-your-personal-finances</loc>
<lastmod>2022-12-26T00:00:00+00:00</lastmod>
<lastmod>2023-01-05T00:00:00+00:00</lastmod>
</url>
<url>
<loc>https://ghostfol.io/en/demo</loc>
<lastmod>2022-12-26T00:00:00+00:00</lastmod>
<lastmod>2023-01-05T00:00:00+00:00</lastmod>
</url>
<url>
<loc>https://ghostfol.io/en/faq</loc>
<lastmod>2022-12-26T00:00:00+00:00</lastmod>
<lastmod>2023-01-05T00:00:00+00:00</lastmod>
</url>
<url>
<loc>https://ghostfol.io/en/features</loc>
<lastmod>2022-12-26T00:00:00+00:00</lastmod>
<lastmod>2023-01-05T00:00:00+00:00</lastmod>
</url>
<url>
<loc>https://ghostfol.io/en/markets</loc>
<lastmod>2022-12-26T00:00:00+00:00</lastmod>
<lastmod>2023-01-05T00:00:00+00:00</lastmod>
</url>
<url>
<loc>https://ghostfol.io/en/pricing</loc>
<lastmod>2022-12-26T00:00:00+00:00</lastmod>
<lastmod>2023-01-05T00:00:00+00:00</lastmod>
</url>
<url>
<loc>https://ghostfol.io/en/register</loc>
<lastmod>2022-12-26T00:00:00+00:00</lastmod>
<lastmod>2023-01-05T00:00:00+00:00</lastmod>
</url>
<url>
<loc>https://ghostfol.io/en/resources</loc>
<lastmod>2022-12-26T00:00:00+00:00</lastmod>
<lastmod>2023-01-05T00:00:00+00:00</lastmod>
</url>
</urlset>

View File

@ -94,7 +94,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
<context context-type="linenumber">70</context>
<context context-type="linenumber">81</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-users/admin-users.html</context>
@ -232,6 +232,10 @@
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">24</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
<context context-type="linenumber">57</context>
</context-group>
</trans-unit>
<trans-unit id="1b6bc6d5daaa6ec75d201690bb6f782f30bf98a0" datatype="html">
<source>Data Source</source>
@ -362,11 +366,11 @@
<target state="translated">Abbrechen</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data-detail/market-data-detail-dialog/market-data-detail-dialog.html</context>
<context context-type="linenumber">45</context>
<context context-type="linenumber">46</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
<context context-type="linenumber">166</context>
<context context-type="linenumber">173</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/create-or-update-access-dialog/create-or-update-access-dialog.html</context>
@ -394,11 +398,11 @@
<target state="translated">Speichern</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data-detail/market-data-detail-dialog/market-data-detail-dialog.html</context>
<context context-type="linenumber">47</context>
<context context-type="linenumber">48</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
<context context-type="linenumber">173</context>
<context context-type="linenumber">180</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/create-or-update-access-dialog/create-or-update-access-dialog.html</context>
@ -422,7 +426,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
<context context-type="linenumber">61</context>
<context context-type="linenumber">72</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/holdings-table/holdings-table.component.html</context>
@ -1106,7 +1110,7 @@
<target state="translated">Sektoren</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
<context context-type="linenumber">118</context>
<context context-type="linenumber">125</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html</context>
@ -1122,7 +1126,7 @@
<target state="translated">Länder</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
<context context-type="linenumber">128</context>
<context context-type="linenumber">135</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html</context>
@ -1330,7 +1334,7 @@
<target state="translated">Bitte gebe deinen Gutscheincode ein:</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.component.ts</context>
<context context-type="linenumber">226</context>
<context context-type="linenumber">236</context>
</context-group>
</trans-unit>
<trans-unit id="4420880039966769543" datatype="html">
@ -1338,7 +1342,7 @@
<target state="translated">Gutscheincode konnte nicht eingelöst werden</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.component.ts</context>
<context context-type="linenumber">236</context>
<context context-type="linenumber">246</context>
</context-group>
</trans-unit>
<trans-unit id="4819099731531004979" datatype="html">
@ -1346,7 +1350,7 @@
<target state="translated">Gutscheincode wurde eingelöst</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.component.ts</context>
<context context-type="linenumber">248</context>
<context context-type="linenumber">258</context>
</context-group>
</trans-unit>
<trans-unit id="7967484035994732534" datatype="html">
@ -1354,7 +1358,7 @@
<target state="translated">Neu laden</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.component.ts</context>
<context context-type="linenumber">249</context>
<context context-type="linenumber">259</context>
</context-group>
</trans-unit>
<trans-unit id="7963559562180316948" datatype="html">
@ -1362,7 +1366,7 @@
<target state="translated">Möchtest du diese Anmeldemethode wirklich löschen?</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.component.ts</context>
<context context-type="linenumber">295</context>
<context context-type="linenumber">305</context>
</context-group>
</trans-unit>
<trans-unit id="29881a45dafbe5aa05cd9d0441a4c0c2fb06df92" datatype="html">
@ -1450,7 +1454,7 @@
<target state="translated">Lokalität</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.html</context>
<context context-type="linenumber">152</context>
<context context-type="linenumber">160</context>
</context-group>
</trans-unit>
<trans-unit id="4402006eb2c97591dd8c87a5bd8f721fe9e4dc00" datatype="html">
@ -1458,7 +1462,7 @@
<target state="translated">Datums- und Zahlenformat</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.html</context>
<context context-type="linenumber">154</context>
<context context-type="linenumber">162</context>
</context-group>
</trans-unit>
<trans-unit id="b5dc65493e3e15fbe15b7d9c17f7626321d82e76" datatype="html">
@ -1466,7 +1470,7 @@
<target state="translated">Zen Modus</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.html</context>
<context context-type="linenumber">206</context>
<context context-type="linenumber">214</context>
</context-group>
</trans-unit>
<trans-unit id="9ae348ee3a7319c2fc4794fa8bc425999d355f8f" datatype="html">
@ -1474,7 +1478,7 @@
<target state="translated">Einloggen mit Fingerabdruck</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.html</context>
<context context-type="linenumber">218</context>
<context context-type="linenumber">226</context>
</context-group>
</trans-unit>
<trans-unit id="83c4d4d764d2e2725ab8e919ec16ac400e1f290a" datatype="html">
@ -1482,7 +1486,7 @@
<target state="translated">Benutzer ID</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.html</context>
<context context-type="linenumber">245</context>
<context context-type="linenumber">253</context>
</context-group>
</trans-unit>
<trans-unit id="9021c579c084e68d9db06a569d76f024111c6c54" datatype="html">
@ -1490,7 +1494,7 @@
<target state="translated">Zugangsberechtigung</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.html</context>
<context context-type="linenumber">254</context>
<context context-type="linenumber">262</context>
</context-group>
</trans-unit>
<trans-unit id="5e41f1b4c46ad9e0a9bc83fa36445483aa5cc324" datatype="html">
@ -1556,6 +1560,10 @@
<context context-type="sourcefile">apps/client/src/app/components/accounts-table/accounts-table.component.html</context>
<context context-type="linenumber">48</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
<context context-type="linenumber">62</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html</context>
<context context-type="linenumber">22</context>
@ -1926,7 +1934,7 @@
<target state="translated">Kommentar</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
<context context-type="linenumber">153</context>
<context context-type="linenumber">160</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html</context>
@ -1942,7 +1950,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
<context context-type="linenumber">79</context>
<context context-type="linenumber">86</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html</context>
@ -2330,7 +2338,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
<context context-type="linenumber">88</context>
<context context-type="linenumber">95</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html</context>
@ -2346,7 +2354,7 @@
<target state="translated">Sektor</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
<context context-type="linenumber">103</context>
<context context-type="linenumber">110</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html</context>
@ -2358,7 +2366,7 @@
<target state="translated">Land</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
<context context-type="linenumber">112</context>
<context context-type="linenumber">119</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html</context>
@ -2562,7 +2570,7 @@
<target state="translated">Experimentelle Funktionen</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.html</context>
<context context-type="linenumber">233</context>
<context context-type="linenumber">241</context>
</context-group>
</trans-unit>
<trans-unit id="1b25c6e22f822e07a3e4d5aae4edc5b41fe083c2" datatype="html">
@ -2634,7 +2642,7 @@
<target state="translated">Aussehen</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.html</context>
<context context-type="linenumber">180</context>
<context context-type="linenumber">188</context>
</context-group>
</trans-unit>
<trans-unit id="5fb13fb4a8447e59cdf05dc196ade39c02a6f8aa" datatype="html">
@ -2642,7 +2650,7 @@
<target state="translated">Automatisch</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.html</context>
<context context-type="linenumber">195</context>
<context context-type="linenumber">203</context>
</context-group>
</trans-unit>
<trans-unit id="693d14f486a25e86bc515dfcfc4462d5201217ef" datatype="html">
@ -2650,7 +2658,7 @@
<target state="translated">Hell</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.html</context>
<context context-type="linenumber">196</context>
<context context-type="linenumber">204</context>
</context-group>
</trans-unit>
<trans-unit id="adb4562d2dbd3584370e44496969d58c511ecb63" datatype="html">
@ -2658,7 +2666,7 @@
<target state="translated">Dunkel</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.html</context>
<context context-type="linenumber">197</context>
<context context-type="linenumber">205</context>
</context-group>
</trans-unit>
<trans-unit id="112783260724635106" datatype="html">
@ -2926,11 +2934,11 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.html</context>
<context context-type="linenumber">139</context>
<context context-type="linenumber">143</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.html</context>
<context context-type="linenumber">143</context>
<context context-type="linenumber">147</context>
</context-group>
</trans-unit>
<trans-unit id="064d88bead9e71bd849ecaefd8b38cca8f195a88" datatype="html">
@ -2954,7 +2962,7 @@
<target state="translated">Symbol Zuordnung</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
<context context-type="linenumber">142</context>
<context context-type="linenumber">149</context>
</context-group>
</trans-unit>
<trans-unit id="6410cffb96159fcff46d91effc26df0e240bc0e3" datatype="html">

View File

@ -95,7 +95,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
<context context-type="linenumber">70</context>
<context context-type="linenumber">81</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-users/admin-users.html</context>
@ -233,6 +233,10 @@
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">24</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
<context context-type="linenumber">57</context>
</context-group>
</trans-unit>
<trans-unit id="1b6bc6d5daaa6ec75d201690bb6f782f30bf98a0" datatype="html">
<source>Data Source</source>
@ -363,11 +367,11 @@
<target state="translated">Cancela</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data-detail/market-data-detail-dialog/market-data-detail-dialog.html</context>
<context context-type="linenumber">45</context>
<context context-type="linenumber">46</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
<context context-type="linenumber">166</context>
<context context-type="linenumber">173</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/create-or-update-access-dialog/create-or-update-access-dialog.html</context>
@ -395,11 +399,11 @@
<target state="translated">Guarda</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data-detail/market-data-detail-dialog/market-data-detail-dialog.html</context>
<context context-type="linenumber">47</context>
<context context-type="linenumber">48</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
<context context-type="linenumber">173</context>
<context context-type="linenumber">180</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/create-or-update-access-dialog/create-or-update-access-dialog.html</context>
@ -423,7 +427,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
<context context-type="linenumber">61</context>
<context context-type="linenumber">72</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/holdings-table/holdings-table.component.html</context>
@ -1107,7 +1111,7 @@
<target state="translated">Sectores</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
<context context-type="linenumber">118</context>
<context context-type="linenumber">125</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html</context>
@ -1123,7 +1127,7 @@
<target state="translated">Países</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
<context context-type="linenumber">128</context>
<context context-type="linenumber">135</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html</context>
@ -1331,7 +1335,7 @@
<target state="translated">Por favor, ingresa tu código de cupón:</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.component.ts</context>
<context context-type="linenumber">226</context>
<context context-type="linenumber">236</context>
</context-group>
</trans-unit>
<trans-unit id="4420880039966769543" datatype="html">
@ -1339,7 +1343,7 @@
<target state="translated">No se puede canjear este código de cupón</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.component.ts</context>
<context context-type="linenumber">236</context>
<context context-type="linenumber">246</context>
</context-group>
</trans-unit>
<trans-unit id="4819099731531004979" datatype="html">
@ -1347,7 +1351,7 @@
<target state="translated">El codigo de cupón ha sido canjeado</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.component.ts</context>
<context context-type="linenumber">248</context>
<context context-type="linenumber">258</context>
</context-group>
</trans-unit>
<trans-unit id="7967484035994732534" datatype="html">
@ -1355,7 +1359,7 @@
<target state="translated">Refrescar</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.component.ts</context>
<context context-type="linenumber">249</context>
<context context-type="linenumber">259</context>
</context-group>
</trans-unit>
<trans-unit id="7963559562180316948" datatype="html">
@ -1363,7 +1367,7 @@
<target state="translated">¿Estás seguro de eliminar este método de acceso?</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.component.ts</context>
<context context-type="linenumber">295</context>
<context context-type="linenumber">305</context>
</context-group>
</trans-unit>
<trans-unit id="29881a45dafbe5aa05cd9d0441a4c0c2fb06df92" datatype="html">
@ -1451,7 +1455,7 @@
<target state="translated">Ubicación</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.html</context>
<context context-type="linenumber">152</context>
<context context-type="linenumber">160</context>
</context-group>
</trans-unit>
<trans-unit id="4402006eb2c97591dd8c87a5bd8f721fe9e4dc00" datatype="html">
@ -1459,7 +1463,7 @@
<target state="translated">Formato de fecha y número</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.html</context>
<context context-type="linenumber">154</context>
<context context-type="linenumber">162</context>
</context-group>
</trans-unit>
<trans-unit id="b5dc65493e3e15fbe15b7d9c17f7626321d82e76" datatype="html">
@ -1467,7 +1471,7 @@
<target state="translated">Modo Zen</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.html</context>
<context context-type="linenumber">206</context>
<context context-type="linenumber">214</context>
</context-group>
</trans-unit>
<trans-unit id="9ae348ee3a7319c2fc4794fa8bc425999d355f8f" datatype="html">
@ -1475,7 +1479,7 @@
<target state="translated">Accede con huella digital</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.html</context>
<context context-type="linenumber">218</context>
<context context-type="linenumber">226</context>
</context-group>
</trans-unit>
<trans-unit id="83c4d4d764d2e2725ab8e919ec16ac400e1f290a" datatype="html">
@ -1483,7 +1487,7 @@
<target state="translated">ID usuario</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.html</context>
<context context-type="linenumber">245</context>
<context context-type="linenumber">253</context>
</context-group>
</trans-unit>
<trans-unit id="9021c579c084e68d9db06a569d76f024111c6c54" datatype="html">
@ -1491,7 +1495,7 @@
<target state="translated">Acceso concedido</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.html</context>
<context context-type="linenumber">254</context>
<context context-type="linenumber">262</context>
</context-group>
</trans-unit>
<trans-unit id="5e41f1b4c46ad9e0a9bc83fa36445483aa5cc324" datatype="html">
@ -1557,6 +1561,10 @@
<context context-type="sourcefile">apps/client/src/app/components/accounts-table/accounts-table.component.html</context>
<context context-type="linenumber">48</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
<context context-type="linenumber">62</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html</context>
<context context-type="linenumber">22</context>
@ -1927,7 +1935,7 @@
<target state="translated">Nota</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
<context context-type="linenumber">153</context>
<context context-type="linenumber">160</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html</context>
@ -1943,7 +1951,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
<context context-type="linenumber">79</context>
<context context-type="linenumber">86</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html</context>
@ -2311,7 +2319,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
<context context-type="linenumber">88</context>
<context context-type="linenumber">95</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html</context>
@ -2367,7 +2375,7 @@
<target state="translated">Sector</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
<context context-type="linenumber">103</context>
<context context-type="linenumber">110</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html</context>
@ -2379,7 +2387,7 @@
<target state="translated">País</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
<context context-type="linenumber">112</context>
<context context-type="linenumber">119</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html</context>
@ -2563,7 +2571,7 @@
<target state="translated">Funcionalidades experimentales</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.html</context>
<context context-type="linenumber">233</context>
<context context-type="linenumber">241</context>
</context-group>
</trans-unit>
<trans-unit id="1931353503905413384" datatype="html">
@ -2635,7 +2643,7 @@
<target state="translated">Apariencia</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.html</context>
<context context-type="linenumber">180</context>
<context context-type="linenumber">188</context>
</context-group>
</trans-unit>
<trans-unit id="5fb13fb4a8447e59cdf05dc196ade39c02a6f8aa" datatype="html">
@ -2643,7 +2651,7 @@
<target state="translated">Automático</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.html</context>
<context context-type="linenumber">195</context>
<context context-type="linenumber">203</context>
</context-group>
</trans-unit>
<trans-unit id="693d14f486a25e86bc515dfcfc4462d5201217ef" datatype="html">
@ -2651,7 +2659,7 @@
<target state="translated">Claro</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.html</context>
<context context-type="linenumber">196</context>
<context context-type="linenumber">204</context>
</context-group>
</trans-unit>
<trans-unit id="adb4562d2dbd3584370e44496969d58c511ecb63" datatype="html">
@ -2659,7 +2667,7 @@
<target state="translated">Oscuro</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.html</context>
<context context-type="linenumber">197</context>
<context context-type="linenumber">205</context>
</context-group>
</trans-unit>
<trans-unit id="112783260724635106" datatype="html">
@ -2927,11 +2935,11 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.html</context>
<context context-type="linenumber">139</context>
<context context-type="linenumber">143</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.html</context>
<context context-type="linenumber">143</context>
<context context-type="linenumber">147</context>
</context-group>
</trans-unit>
<trans-unit id="064d88bead9e71bd849ecaefd8b38cca8f195a88" datatype="html">
@ -2955,7 +2963,7 @@
<target state="translated">Mapeo de símbolos</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
<context context-type="linenumber">142</context>
<context context-type="linenumber">149</context>
</context-group>
</trans-unit>
<trans-unit id="7765499580020598783" datatype="html">

File diff suppressed because it is too large Load Diff

View File

@ -95,7 +95,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
<context context-type="linenumber">70</context>
<context context-type="linenumber">81</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-users/admin-users.html</context>
@ -233,6 +233,10 @@
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">24</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
<context context-type="linenumber">57</context>
</context-group>
</trans-unit>
<trans-unit id="1b6bc6d5daaa6ec75d201690bb6f782f30bf98a0" datatype="html">
<source>Data Source</source>
@ -363,11 +367,11 @@
<target state="translated">Annulla</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data-detail/market-data-detail-dialog/market-data-detail-dialog.html</context>
<context context-type="linenumber">45</context>
<context context-type="linenumber">46</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
<context context-type="linenumber">166</context>
<context context-type="linenumber">173</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/create-or-update-access-dialog/create-or-update-access-dialog.html</context>
@ -395,11 +399,11 @@
<target state="translated">Salva</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data-detail/market-data-detail-dialog/market-data-detail-dialog.html</context>
<context context-type="linenumber">47</context>
<context context-type="linenumber">48</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
<context context-type="linenumber">173</context>
<context context-type="linenumber">180</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/create-or-update-access-dialog/create-or-update-access-dialog.html</context>
@ -423,7 +427,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
<context context-type="linenumber">61</context>
<context context-type="linenumber">72</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/holdings-table/holdings-table.component.html</context>
@ -1107,7 +1111,7 @@
<target state="translated">Settori</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
<context context-type="linenumber">118</context>
<context context-type="linenumber">125</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html</context>
@ -1123,7 +1127,7 @@
<target state="translated">Paesi</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
<context context-type="linenumber">128</context>
<context context-type="linenumber">135</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html</context>
@ -1331,7 +1335,7 @@
<target state="translated">Inserisci il tuo codice del buono:</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.component.ts</context>
<context context-type="linenumber">226</context>
<context context-type="linenumber">236</context>
</context-group>
</trans-unit>
<trans-unit id="4420880039966769543" datatype="html">
@ -1339,7 +1343,7 @@
<target state="translated">Impossibile riscattare il codice del buono</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.component.ts</context>
<context context-type="linenumber">236</context>
<context context-type="linenumber">246</context>
</context-group>
</trans-unit>
<trans-unit id="4819099731531004979" datatype="html">
@ -1347,7 +1351,7 @@
<target state="translated">Il codice del buono è stato riscattato</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.component.ts</context>
<context context-type="linenumber">248</context>
<context context-type="linenumber">258</context>
</context-group>
</trans-unit>
<trans-unit id="7967484035994732534" datatype="html">
@ -1355,7 +1359,7 @@
<target state="translated">Ricarica</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.component.ts</context>
<context context-type="linenumber">249</context>
<context context-type="linenumber">259</context>
</context-group>
</trans-unit>
<trans-unit id="7963559562180316948" datatype="html">
@ -1363,7 +1367,7 @@
<target state="translated">Vuoi davvero rimuovere questo metodo di accesso?</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.component.ts</context>
<context context-type="linenumber">295</context>
<context context-type="linenumber">305</context>
</context-group>
</trans-unit>
<trans-unit id="29881a45dafbe5aa05cd9d0441a4c0c2fb06df92" datatype="html">
@ -1451,7 +1455,7 @@
<target state="translated">Locale</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.html</context>
<context context-type="linenumber">152</context>
<context context-type="linenumber">160</context>
</context-group>
</trans-unit>
<trans-unit id="4402006eb2c97591dd8c87a5bd8f721fe9e4dc00" datatype="html">
@ -1459,7 +1463,7 @@
<target state="translated">Formato data e numero</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.html</context>
<context context-type="linenumber">154</context>
<context context-type="linenumber">162</context>
</context-group>
</trans-unit>
<trans-unit id="b5dc65493e3e15fbe15b7d9c17f7626321d82e76" datatype="html">
@ -1467,7 +1471,7 @@
<target state="translated">Modalità Zen</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.html</context>
<context context-type="linenumber">206</context>
<context context-type="linenumber">214</context>
</context-group>
</trans-unit>
<trans-unit id="9ae348ee3a7319c2fc4794fa8bc425999d355f8f" datatype="html">
@ -1475,7 +1479,7 @@
<target state="translated">Accesso con impronta digitale</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.html</context>
<context context-type="linenumber">218</context>
<context context-type="linenumber">226</context>
</context-group>
</trans-unit>
<trans-unit id="83c4d4d764d2e2725ab8e919ec16ac400e1f290a" datatype="html">
@ -1483,7 +1487,7 @@
<target state="translated">ID utente</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.html</context>
<context context-type="linenumber">245</context>
<context context-type="linenumber">253</context>
</context-group>
</trans-unit>
<trans-unit id="9021c579c084e68d9db06a569d76f024111c6c54" datatype="html">
@ -1491,7 +1495,7 @@
<target state="translated">Accesso concesso</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.html</context>
<context context-type="linenumber">254</context>
<context context-type="linenumber">262</context>
</context-group>
</trans-unit>
<trans-unit id="5e41f1b4c46ad9e0a9bc83fa36445483aa5cc324" datatype="html">
@ -1557,6 +1561,10 @@
<context context-type="sourcefile">apps/client/src/app/components/accounts-table/accounts-table.component.html</context>
<context context-type="linenumber">48</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
<context context-type="linenumber">62</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html</context>
<context context-type="linenumber">22</context>
@ -1927,7 +1935,7 @@
<target state="translated">Nota</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
<context context-type="linenumber">153</context>
<context context-type="linenumber">160</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html</context>
@ -1943,7 +1951,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
<context context-type="linenumber">79</context>
<context context-type="linenumber">86</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html</context>
@ -2311,7 +2319,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
<context context-type="linenumber">88</context>
<context context-type="linenumber">95</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html</context>
@ -2367,7 +2375,7 @@
<target state="translated">Settore</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
<context context-type="linenumber">103</context>
<context context-type="linenumber">110</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html</context>
@ -2379,7 +2387,7 @@
<target state="translated">Paese</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
<context context-type="linenumber">112</context>
<context context-type="linenumber">119</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html</context>
@ -2563,7 +2571,7 @@
<target state="translated">Funzionalità sperimentali</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.html</context>
<context context-type="linenumber">233</context>
<context context-type="linenumber">241</context>
</context-group>
</trans-unit>
<trans-unit id="1931353503905413384" datatype="html">
@ -2635,7 +2643,7 @@
<target state="new">Appearance</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.html</context>
<context context-type="linenumber">180</context>
<context context-type="linenumber">188</context>
</context-group>
</trans-unit>
<trans-unit id="5fb13fb4a8447e59cdf05dc196ade39c02a6f8aa" datatype="html">
@ -2643,7 +2651,7 @@
<target state="new">Auto</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.html</context>
<context context-type="linenumber">195</context>
<context context-type="linenumber">203</context>
</context-group>
</trans-unit>
<trans-unit id="693d14f486a25e86bc515dfcfc4462d5201217ef" datatype="html">
@ -2651,7 +2659,7 @@
<target state="new">Light</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.html</context>
<context context-type="linenumber">196</context>
<context context-type="linenumber">204</context>
</context-group>
</trans-unit>
<trans-unit id="adb4562d2dbd3584370e44496969d58c511ecb63" datatype="html">
@ -2659,7 +2667,7 @@
<target state="new">Dark</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.html</context>
<context context-type="linenumber">197</context>
<context context-type="linenumber">205</context>
</context-group>
</trans-unit>
<trans-unit id="112783260724635106" datatype="html">
@ -2927,11 +2935,11 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.html</context>
<context context-type="linenumber">139</context>
<context context-type="linenumber">143</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.html</context>
<context context-type="linenumber">143</context>
<context context-type="linenumber">147</context>
</context-group>
</trans-unit>
<trans-unit id="064d88bead9e71bd849ecaefd8b38cca8f195a88" datatype="html">
@ -2955,7 +2963,7 @@
<target state="new">Symbol Mapping</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
<context context-type="linenumber">142</context>
<context context-type="linenumber">149</context>
</context-group>
</trans-unit>
<trans-unit id="7765499580020598783" datatype="html">

View File

@ -94,7 +94,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
<context context-type="linenumber">70</context>
<context context-type="linenumber">81</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-users/admin-users.html</context>
@ -207,7 +207,7 @@
</trans-unit>
<trans-unit id="8280212421112607879" datatype="html">
<source>Do you really want to delete this account?</source>
<target state="translated">Wilt u deze account echt verwijderen?</target>
<target state="translated">Wilt u dit account echt verwijderen?</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/accounts-table/accounts-table.component.ts</context>
<context context-type="linenumber">81</context>
@ -232,6 +232,10 @@
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">24</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
<context context-type="linenumber">57</context>
</context-group>
</trans-unit>
<trans-unit id="1b6bc6d5daaa6ec75d201690bb6f782f30bf98a0" datatype="html">
<source>Data Source</source>
@ -362,11 +366,11 @@
<target state="translated">Annuleren</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data-detail/market-data-detail-dialog/market-data-detail-dialog.html</context>
<context context-type="linenumber">45</context>
<context context-type="linenumber">46</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
<context context-type="linenumber">166</context>
<context context-type="linenumber">173</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/create-or-update-access-dialog/create-or-update-access-dialog.html</context>
@ -394,11 +398,11 @@
<target state="translated">Opslaan</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data-detail/market-data-detail-dialog/market-data-detail-dialog.html</context>
<context context-type="linenumber">47</context>
<context context-type="linenumber">48</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
<context context-type="linenumber">173</context>
<context context-type="linenumber">180</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/create-or-update-access-dialog/create-or-update-access-dialog.html</context>
@ -422,7 +426,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
<context context-type="linenumber">61</context>
<context context-type="linenumber">72</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/holdings-table/holdings-table.component.html</context>
@ -1106,7 +1110,7 @@
<target state="translated">Sectoren</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
<context context-type="linenumber">118</context>
<context context-type="linenumber">125</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html</context>
@ -1122,7 +1126,7 @@
<target state="translated">Landen</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
<context context-type="linenumber">128</context>
<context context-type="linenumber">135</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html</context>
@ -1330,7 +1334,7 @@
<target state="translated">Voer uw couponcode in:</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.component.ts</context>
<context context-type="linenumber">226</context>
<context context-type="linenumber">236</context>
</context-group>
</trans-unit>
<trans-unit id="4420880039966769543" datatype="html">
@ -1338,7 +1342,7 @@
<target state="translated">Kon kortingscode niet inwisselen</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.component.ts</context>
<context context-type="linenumber">236</context>
<context context-type="linenumber">246</context>
</context-group>
</trans-unit>
<trans-unit id="4819099731531004979" datatype="html">
@ -1346,7 +1350,7 @@
<target state="translated">Couponcode is ingewisseld</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.component.ts</context>
<context context-type="linenumber">248</context>
<context context-type="linenumber">258</context>
</context-group>
</trans-unit>
<trans-unit id="7967484035994732534" datatype="html">
@ -1354,7 +1358,7 @@
<target state="translated">Herladen</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.component.ts</context>
<context context-type="linenumber">249</context>
<context context-type="linenumber">259</context>
</context-group>
</trans-unit>
<trans-unit id="7963559562180316948" datatype="html">
@ -1362,7 +1366,7 @@
<target state="translated">Wilt u deze aanmeldingsmethode echt verwijderen?</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.component.ts</context>
<context context-type="linenumber">295</context>
<context context-type="linenumber">305</context>
</context-group>
</trans-unit>
<trans-unit id="29881a45dafbe5aa05cd9d0441a4c0c2fb06df92" datatype="html">
@ -1450,7 +1454,7 @@
<target state="translated">Locale</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.html</context>
<context context-type="linenumber">152</context>
<context context-type="linenumber">160</context>
</context-group>
</trans-unit>
<trans-unit id="4402006eb2c97591dd8c87a5bd8f721fe9e4dc00" datatype="html">
@ -1458,7 +1462,7 @@
<target state="translated">Formaat datum en getal</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.html</context>
<context context-type="linenumber">154</context>
<context context-type="linenumber">162</context>
</context-group>
</trans-unit>
<trans-unit id="b5dc65493e3e15fbe15b7d9c17f7626321d82e76" datatype="html">
@ -1466,7 +1470,7 @@
<target state="translated">Zen-modus</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.html</context>
<context context-type="linenumber">206</context>
<context context-type="linenumber">214</context>
</context-group>
</trans-unit>
<trans-unit id="9ae348ee3a7319c2fc4794fa8bc425999d355f8f" datatype="html">
@ -1474,7 +1478,7 @@
<target state="translated">Aanmelden met vingerafdruk</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.html</context>
<context context-type="linenumber">218</context>
<context context-type="linenumber">226</context>
</context-group>
</trans-unit>
<trans-unit id="83c4d4d764d2e2725ab8e919ec16ac400e1f290a" datatype="html">
@ -1482,7 +1486,7 @@
<target state="translated">Gebruikers-ID</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.html</context>
<context context-type="linenumber">245</context>
<context context-type="linenumber">253</context>
</context-group>
</trans-unit>
<trans-unit id="9021c579c084e68d9db06a569d76f024111c6c54" datatype="html">
@ -1490,7 +1494,7 @@
<target state="translated">Verleende toegang</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.html</context>
<context context-type="linenumber">254</context>
<context context-type="linenumber">262</context>
</context-group>
</trans-unit>
<trans-unit id="5e41f1b4c46ad9e0a9bc83fa36445483aa5cc324" datatype="html">
@ -1556,6 +1560,10 @@
<context context-type="sourcefile">apps/client/src/app/components/accounts-table/accounts-table.component.html</context>
<context context-type="linenumber">48</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
<context context-type="linenumber">62</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html</context>
<context context-type="linenumber">22</context>
@ -1863,7 +1871,7 @@
</trans-unit>
<trans-unit id="9bca420227979312de74f0a932a003437410b1ab" datatype="html">
<source>Item</source>
<target state="new">ITEM</target>
<target state="translated">Item</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html</context>
<context context-type="linenumber">16,18</context>
@ -1926,7 +1934,7 @@
<target state="translated">Opmerking</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
<context context-type="linenumber">153</context>
<context context-type="linenumber">160</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html</context>
@ -1942,7 +1950,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
<context context-type="linenumber">79</context>
<context context-type="linenumber">86</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html</context>
@ -2310,7 +2318,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
<context context-type="linenumber">88</context>
<context context-type="linenumber">95</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html</context>
@ -2366,7 +2374,7 @@
<target state="translated">Sector</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
<context context-type="linenumber">103</context>
<context context-type="linenumber">110</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html</context>
@ -2378,7 +2386,7 @@
<target state="translated">Land</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
<context context-type="linenumber">112</context>
<context context-type="linenumber">119</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html</context>
@ -2562,7 +2570,7 @@
<target state="translated">Experimentele functies</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.html</context>
<context context-type="linenumber">233</context>
<context context-type="linenumber">241</context>
</context-group>
</trans-unit>
<trans-unit id="1931353503905413384" datatype="html">
@ -2599,7 +2607,7 @@
</trans-unit>
<trans-unit id="ac598d664f86ba5783915d65f2664a7f38a9d23a" datatype="html">
<source>Account Type</source>
<target state="new">Account Type</target>
<target state="translated">Accounttype</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/account-detail-dialog/account-detail-dialog.html</context>
<context context-type="linenumber">25</context>
@ -2607,7 +2615,7 @@
</trans-unit>
<trans-unit id="98fc3013bfcbf452b9f37bbfcdb77b9b882866e3" datatype="html">
<source>Excluded from Analysis</source>
<target state="new">Excluded from Analysis</target>
<target state="translated">Uitgesloten van analyse</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html</context>
<context context-type="linenumber">173</context>
@ -2615,7 +2623,7 @@
</trans-unit>
<trans-unit id="458363f8e413759aa9e3235a53fd0f64cc916395" datatype="html">
<source> If you retire today, you would be able to withdraw <x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span class=&quot;font-weight-bold&quot; &gt;"/><x id="START_TAG_GF_VALUE" ctype="x-gf_value" equiv-text="&lt;gf-value class=&quot;d-inline-block&quot; [currency]=&quot;user?.settings?.baseCurrency&quot; [locale]=&quot;user?.settings?.locale&quot; [value]=&quot;withdrawalRatePerYear?.toNumber()&quot; &gt;"/><x id="CLOSE_TAG_GF_VALUE" ctype="x-gf_value" equiv-text="&lt;/gf-value&gt;"/> per year<x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span &gt;"/> or <x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span class=&quot;font-weight-bold&quot; &gt;"/><x id="START_TAG_GF_VALUE_1" ctype="x-gf_value_1" equiv-text="&lt;gf-value class=&quot;d-inline-block&quot; [currency]=&quot;user?.settings?.baseCurrency&quot; [locale]=&quot;user?.settings?.locale&quot; [value]=&quot;withdrawalRatePerMonth?.toNumber()&quot; &gt;"/><x id="CLOSE_TAG_GF_VALUE" ctype="x-gf_value" equiv-text="&lt;/gf-value&gt;"/> per month<x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span &gt;"/>, based on your total assets of <x id="START_TAG_GF_VALUE_2" ctype="x-gf_value_2" equiv-text="&lt;gf-value class=&quot;d-inline-block&quot; [currency]=&quot;user?.settings?.baseCurrency&quot; [locale]=&quot;user?.settings?.locale&quot; [value]=&quot;fireWealth?.toNumber()&quot; &gt;"/><x id="CLOSE_TAG_GF_VALUE" ctype="x-gf_value" equiv-text="&lt;/gf-value&gt;"/> and a withdrawal rate of 4%. </source>
<target state="new"> If you retire today, you would be able to withdraw <x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span class=&quot;font-weight-bold&quot; &gt;"/><x id="START_TAG_GF_VALUE" ctype="x-gf_value" equiv-text="&lt;gf-value class=&quot;d-inline-block&quot; [currency]=&quot;user?.settings?.baseCurrency&quot; [locale]=&quot;user?.settings?.locale&quot; [value]=&quot;withdrawalRatePerYear?.toNumber()&quot; &gt;"/><x id="CLOSE_TAG_GF_VALUE" ctype="x-gf_value" equiv-text="&lt;/gf-value&gt;"/> per year<x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span &gt;"/> or <x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span class=&quot;font-weight-bold&quot; &gt;"/><x id="START_TAG_GF_VALUE_1" ctype="x-gf_value_1" equiv-text="&lt;gf-value class=&quot;d-inline-block&quot; [currency]=&quot;user?.settings?.baseCurrency&quot; [locale]=&quot;user?.settings?.locale&quot; [value]=&quot;withdrawalRatePerMonth?.toNumber()&quot; &gt;"/><x id="CLOSE_TAG_GF_VALUE" ctype="x-gf_value" equiv-text="&lt;/gf-value&gt;"/> per month<x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span &gt;"/>, based on your total assets of <x id="START_TAG_GF_VALUE_2" ctype="x-gf_value_2" equiv-text="&lt;gf-value class=&quot;d-inline-block&quot; [currency]=&quot;user?.settings?.baseCurrency&quot; [locale]=&quot;user?.settings?.locale&quot; [value]=&quot;fireWealth?.toNumber()&quot; &gt;"/><x id="CLOSE_TAG_GF_VALUE" ctype="x-gf_value" equiv-text="&lt;/gf-value&gt;"/> and a withdrawal rate of 4%. </target>
<target state="translated"> Mocht u vandaag met pension gaan, kunt u <x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span class=&quot;font-weight-bold&quot; &gt;"/><x id="START_TAG_GF_VALUE" ctype="x-gf_value" equiv-text="&lt;gf-value class=&quot;d-inline-block&quot; [currency]=&quot;user?.settings?.baseCurrency&quot; [locale]=&quot;user?.settings?.locale&quot; [value]=&quot;withdrawalRatePerYear?.toNumber()&quot; &gt;"/><x id="CLOSE_TAG_GF_VALUE" ctype="x-gf_value" equiv-text="&lt;/gf-value&gt;"/> per jaar<x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span &gt;"/> of <x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span class=&quot;font-weight-bold&quot; &gt;"/><x id="START_TAG_GF_VALUE_1" ctype="x-gf_value_1" equiv-text="&lt;gf-value class=&quot;d-inline-block&quot; [currency]=&quot;user?.settings?.baseCurrency&quot; [locale]=&quot;user?.settings?.locale&quot; [value]=&quot;withdrawalRatePerMonth?.toNumber()&quot; &gt;"/><x id="CLOSE_TAG_GF_VALUE" ctype="x-gf_value" equiv-text="&lt;/gf-value&gt;"/> per maand<x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span &gt;"/> opnemen, gebaseerd op al uw activa <x id="START_TAG_GF_VALUE_2" ctype="x-gf_value_2" equiv-text="&lt;gf-value class=&quot;d-inline-block&quot; [currency]=&quot;user?.settings?.baseCurrency&quot; [locale]=&quot;user?.settings?.locale&quot; [value]=&quot;fireWealth?.toNumber()&quot; &gt;"/><x id="CLOSE_TAG_GF_VALUE" ctype="x-gf_value" equiv-text="&lt;/gf-value&gt;"/> en een opnamepercentage van 4%. </target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/fire/fire-page.html</context>
<context context-type="linenumber">51,79</context>
@ -2623,7 +2631,7 @@
</trans-unit>
<trans-unit id="616064537937996961" datatype="html">
<source>Auto</source>
<target state="new">Auto</target>
<target state="translated">Auto</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.component.ts</context>
<context context-type="linenumber">45</context>
@ -2631,39 +2639,39 @@
</trans-unit>
<trans-unit id="bbe41ac2ea4a6c00ea941a41b33105048f8e9f13" datatype="html">
<source>Appearance</source>
<target state="new">Appearance</target>
<target state="translated">Weergave</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.html</context>
<context context-type="linenumber">180</context>
<context context-type="linenumber">188</context>
</context-group>
</trans-unit>
<trans-unit id="5fb13fb4a8447e59cdf05dc196ade39c02a6f8aa" datatype="html">
<source>Auto</source>
<target state="new">Auto</target>
<target state="translated">Automatisch</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.html</context>
<context context-type="linenumber">195</context>
<context context-type="linenumber">203</context>
</context-group>
</trans-unit>
<trans-unit id="693d14f486a25e86bc515dfcfc4462d5201217ef" datatype="html">
<source>Light</source>
<target state="new">Light</target>
<target state="translated">Licht</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.html</context>
<context context-type="linenumber">196</context>
<context context-type="linenumber">204</context>
</context-group>
</trans-unit>
<trans-unit id="adb4562d2dbd3584370e44496969d58c511ecb63" datatype="html">
<source>Dark</source>
<target state="new">Dark</target>
<target state="translated">Donker</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.html</context>
<context context-type="linenumber">197</context>
<context context-type="linenumber">205</context>
</context-group>
</trans-unit>
<trans-unit id="112783260724635106" datatype="html">
<source>Total Amount</source>
<target state="new">Total Amount</target>
<target state="translated">Totaalbedrag</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/investment-chart/investment-chart.component.ts</context>
<context context-type="linenumber">178</context>
@ -2671,7 +2679,7 @@
</trans-unit>
<trans-unit id="f1a355a1af2e818050a3af693ac8b521fa7edc5f" datatype="html">
<source>Portfolio Evolution</source>
<target state="new">Portfolio Evolution</target>
<target state="translated">Ontwikkeling van portefeuille</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.html</context>
<context context-type="linenumber">136</context>
@ -2687,7 +2695,7 @@
</trans-unit>
<trans-unit id="4086606389696938932" datatype="html">
<source>Account</source>
<target state="new">Account</target>
<target state="translated">Account</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">4</context>
@ -2695,7 +2703,7 @@
</trans-unit>
<trans-unit id="4574987680940794089" datatype="html">
<source>Asset Class</source>
<target state="new">Asset Class</target>
<target state="translated">Activaklasse</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">5</context>
@ -2703,7 +2711,7 @@
</trans-unit>
<trans-unit id="8106025670158480144" datatype="html">
<source>Symbol</source>
<target state="new">Symbol</target>
<target state="translated">Symbool</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">10</context>
@ -2711,7 +2719,7 @@
</trans-unit>
<trans-unit id="1825829511397926879" datatype="html">
<source>Tag</source>
<target state="new">Tag</target>
<target state="translated">Label</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">11</context>
@ -2719,7 +2727,7 @@
</trans-unit>
<trans-unit id="787798817533231355" datatype="html">
<source>Cash</source>
<target state="new">Cash</target>
<target state="translated">Contant geld</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">14</context>
@ -2727,7 +2735,7 @@
</trans-unit>
<trans-unit id="8431989971855844965" datatype="html">
<source>Commodity</source>
<target state="new">Commodity</target>
<target state="translated">Commodity</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">15</context>
@ -2735,7 +2743,7 @@
</trans-unit>
<trans-unit id="1983771552391474467" datatype="html">
<source>Equity</source>
<target state="new">Equity</target>
<target state="translated">Equity</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">16</context>
@ -2743,7 +2751,7 @@
</trans-unit>
<trans-unit id="6124744839836623630" datatype="html">
<source>Fixed Income</source>
<target state="new">Fixed Income</target>
<target state="translated">Vast inkomen</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">17</context>
@ -2751,7 +2759,7 @@
</trans-unit>
<trans-unit id="8432027249343784512" datatype="html">
<source>Real Estate</source>
<target state="new">Real Estate</target>
<target state="translated">Vastgoed</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">18</context>
@ -2759,7 +2767,7 @@
</trans-unit>
<trans-unit id="8977365084844053365" datatype="html">
<source>Bond</source>
<target state="new">Bond</target>
<target state="translated">Obligatie</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">21</context>
@ -2767,7 +2775,7 @@
</trans-unit>
<trans-unit id="2893204435511484886" datatype="html">
<source>Cryptocurrency</source>
<target state="new">Cryptocurrency</target>
<target state="translated">Cryptovaluta</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">22</context>
@ -2775,7 +2783,7 @@
</trans-unit>
<trans-unit id="9071695492820527473" datatype="html">
<source>ETF</source>
<target state="new">ETF</target>
<target state="translated">ETF</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">23</context>
@ -2783,7 +2791,7 @@
</trans-unit>
<trans-unit id="5734784563242233466" datatype="html">
<source>Mutual Fund</source>
<target state="new">Mutual Fund</target>
<target state="translated">Beleggingsfonds</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">24</context>
@ -2791,7 +2799,7 @@
</trans-unit>
<trans-unit id="1270654249046226808" datatype="html">
<source>Precious Metal</source>
<target state="new">Precious Metal</target>
<target state="translated">Edel metaal</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">25</context>
@ -2799,7 +2807,7 @@
</trans-unit>
<trans-unit id="1346519036036997811" datatype="html">
<source>Private Equity</source>
<target state="new">Private Equity</target>
<target state="translated">Private equity</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">26</context>
@ -2807,7 +2815,7 @@
</trans-unit>
<trans-unit id="4613338085351943838" datatype="html">
<source>Stock</source>
<target state="new">Stock</target>
<target state="translated">Aandeel</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">27</context>
@ -2815,7 +2823,7 @@
</trans-unit>
<trans-unit id="6268646680388419543" datatype="html">
<source>Emergency Fund</source>
<target state="new">Emergency Fund</target>
<target state="translated">Noodfonds</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">7</context>
@ -2823,7 +2831,7 @@
</trans-unit>
<trans-unit id="8693603235657020323" datatype="html">
<source>Other</source>
<target state="new">Other</target>
<target state="translated">Anders</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">8</context>
@ -2835,7 +2843,7 @@
</trans-unit>
<trans-unit id="4893616715766810081" datatype="html">
<source>No data available</source>
<target state="new">No data available</target>
<target state="translated">Geen gegevens beschikbaar</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts</context>
<context context-type="linenumber">371</context>
@ -2847,7 +2855,7 @@
</trans-unit>
<trans-unit id="1228771048078164312" datatype="html">
<source>North America</source>
<target state="new">North America</target>
<target state="translated">Noord Amerika</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">33</context>
@ -2855,7 +2863,7 @@
</trans-unit>
<trans-unit id="1413778527796351850" datatype="html">
<source>Africa</source>
<target state="new">Africa</target>
<target state="translated">Afrika</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">30</context>
@ -2863,7 +2871,7 @@
</trans-unit>
<trans-unit id="3345512471687795386" datatype="html">
<source>Asia</source>
<target state="new">Asia</target>
<target state="translated">Azië</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">31</context>
@ -2871,7 +2879,7 @@
</trans-unit>
<trans-unit id="8350109327144196614" datatype="html">
<source>Europe</source>
<target state="new">Europe</target>
<target state="translated">Europa</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">32</context>
@ -2879,7 +2887,7 @@
</trans-unit>
<trans-unit id="3228811828827738441" datatype="html">
<source>Oceania</source>
<target state="new">Oceania</target>
<target state="translated">Oceanië</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">34</context>
@ -2887,7 +2895,7 @@
</trans-unit>
<trans-unit id="5957846001261659229" datatype="html">
<source>South America</source>
<target state="new">South America</target>
<target state="translated">Zuid Amerika</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">35</context>
@ -2895,7 +2903,7 @@
</trans-unit>
<trans-unit id="73f8489a3ae4d805787b8350d3d91e03e830115b" datatype="html">
<source>Choose File</source>
<target state="new">Choose File</target>
<target state="translated">Kies bestand</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html</context>
<context context-type="linenumber">18,21</context>
@ -2903,7 +2911,7 @@
</trans-unit>
<trans-unit id="6f9fd3da06dc9000eef0d4dcbb37747b303048e9" datatype="html">
<source>The following file formats are supported:</source>
<target state="new">The following file formats are supported:</target>
<target state="translated">The volgende bestandsformaten worden ondersteund:</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html</context>
<context context-type="linenumber">21,23</context>
@ -2911,7 +2919,7 @@
</trans-unit>
<trans-unit id="cda31dbd724cf5f4fa7a4274d9120651490c8a8c" datatype="html">
<source>Back</source>
<target state="new">Back</target>
<target state="translated">Terug</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html</context>
<context context-type="linenumber">79,83</context>
@ -2919,23 +2927,23 @@
</trans-unit>
<trans-unit id="ec2d3a89b366d1ca80be056e9e71f0165ae75c7b" datatype="html">
<source>Community</source>
<target state="new">Community</target>
<target state="translated">Gemeenschap</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.html</context>
<context context-type="linenumber">135</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.html</context>
<context context-type="linenumber">139</context>
<context context-type="linenumber">143</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.html</context>
<context context-type="linenumber">143</context>
<context context-type="linenumber">147</context>
</context-group>
</trans-unit>
<trans-unit id="064d88bead9e71bd849ecaefd8b38cca8f195a88" datatype="html">
<source>Activities Count</source>
<target state="new">Activities Count</target>
<target state="translated">Aantal activiteiten</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">69</context>
@ -2943,7 +2951,7 @@
</trans-unit>
<trans-unit id="c8d1785038d461ec66b5799db21864182b35900a" datatype="html">
<source>Refresh</source>
<target state="new">Refresh</target>
<target state="translated">Vernieuwen</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
<context context-type="linenumber">22</context>
@ -2951,15 +2959,15 @@
</trans-unit>
<trans-unit id="638bbddabc5883a7a4087f45592944ce6558409c" datatype="html">
<source>Symbol Mapping</source>
<target state="new">Symbol Mapping</target>
<target state="translated">Symbool toewijzen</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
<context context-type="linenumber">142</context>
<context context-type="linenumber">149</context>
</context-group>
</trans-unit>
<trans-unit id="7765499580020598783" datatype="html">
<source>Dividend</source>
<target state="new">Dividend</target>
<target state="translated">Dividend</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">43</context>
@ -2967,7 +2975,7 @@
</trans-unit>
<trans-unit id="6410cffb96159fcff46d91effc26df0e240bc0e3" datatype="html">
<source>Dividend Timeline</source>
<target state="new">Dividend Timeline</target>
<target state="translated">Dividend tijdlijn</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.html</context>
<context context-type="linenumber">203</context>
@ -2983,7 +2991,7 @@
</trans-unit>
<trans-unit id="62f17fd50522539fd4c85854828db9d2e1c5330f" datatype="html">
<source>User Signup</source>
<target state="new">User Signup</target>
<target state="translated">Account aanmaken</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-overview/admin-overview.html</context>
<context context-type="linenumber">102</context>
@ -2991,7 +2999,7 @@
</trans-unit>
<trans-unit id="8763985977445247551" datatype="html">
<source>Validating data...</source>
<target state="new">Validating data...</target>
<target state="translated">Gegevens valideren...</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts</context>
<context context-type="linenumber">86</context>
@ -2999,7 +3007,7 @@
</trans-unit>
<trans-unit id="a059709f71aa4c0ac219e160e78a738682ca6a36" datatype="html">
<source>Import</source>
<target state="new">Import</target>
<target state="translated">Importeren</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html</context>
<context context-type="linenumber">94,99</context>
@ -3007,7 +3015,7 @@
</trans-unit>
<trans-unit id="1803867056160333091" datatype="html">
<source>Securities</source>
<target state="new">Securities</target>
<target state="translated">Effecten</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">9</context>
@ -3015,7 +3023,7 @@
</trans-unit>
<trans-unit id="3229595422546554334" datatype="html">
<source>Jobs</source>
<target state="new">Jobs</target>
<target state="translated">Taken</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/admin/admin-page-routing.module.ts</context>
<context context-type="linenumber">16</context>
@ -3023,7 +3031,7 @@
</trans-unit>
<trans-unit id="4798457301875181136" datatype="html">
<source>Market Data</source>
<target state="new">Market Data</target>
<target state="translated">Marktgegevens</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/admin/admin-page-routing.module.ts</context>
<context context-type="linenumber">20</context>
@ -3031,7 +3039,7 @@
</trans-unit>
<trans-unit id="4555457172864212828" datatype="html">
<source>Users</source>
<target state="new">Users</target>
<target state="translated">Gebruikers</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/admin/admin-page-routing.module.ts</context>
<context context-type="linenumber">27</context>
@ -3039,7 +3047,7 @@
</trans-unit>
<trans-unit id="4739818603756173797" datatype="html">
<source>Summary</source>
<target state="new">Summary</target>
<target state="translated">Samenvatting</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/home/home-page-routing.module.ts</context>
<context context-type="linenumber">28</context>

File diff suppressed because it is too large Load Diff

View File

@ -87,7 +87,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
<context context-type="linenumber">70</context>
<context context-type="linenumber">81</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-users/admin-users.html</context>
@ -217,6 +217,10 @@
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">24</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
<context context-type="linenumber">57</context>
</context-group>
</trans-unit>
<trans-unit id="1b6bc6d5daaa6ec75d201690bb6f782f30bf98a0" datatype="html">
<source>Data Source</source>
@ -333,11 +337,11 @@
<source>Cancel</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data-detail/market-data-detail-dialog/market-data-detail-dialog.html</context>
<context context-type="linenumber">45</context>
<context context-type="linenumber">46</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
<context context-type="linenumber">166</context>
<context context-type="linenumber">173</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/create-or-update-access-dialog/create-or-update-access-dialog.html</context>
@ -364,11 +368,11 @@
<source>Save</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data-detail/market-data-detail-dialog/market-data-detail-dialog.html</context>
<context context-type="linenumber">47</context>
<context context-type="linenumber">48</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
<context context-type="linenumber">173</context>
<context context-type="linenumber">180</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/create-or-update-access-dialog/create-or-update-access-dialog.html</context>
@ -391,7 +395,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
<context context-type="linenumber">61</context>
<context context-type="linenumber">72</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/holdings-table/holdings-table.component.html</context>
@ -1004,7 +1008,7 @@
<source>Sectors</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
<context context-type="linenumber">118</context>
<context context-type="linenumber">125</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html</context>
@ -1019,7 +1023,7 @@
<source>Countries</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
<context context-type="linenumber">128</context>
<context context-type="linenumber">135</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html</context>
@ -1205,35 +1209,35 @@
<source>Please enter your coupon code:</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.component.ts</context>
<context context-type="linenumber">226</context>
<context context-type="linenumber">236</context>
</context-group>
</trans-unit>
<trans-unit id="4420880039966769543" datatype="html">
<source>Could not redeem coupon code</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.component.ts</context>
<context context-type="linenumber">236</context>
<context context-type="linenumber">246</context>
</context-group>
</trans-unit>
<trans-unit id="4819099731531004979" datatype="html">
<source>Coupon code has been redeemed</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.component.ts</context>
<context context-type="linenumber">248</context>
<context context-type="linenumber">258</context>
</context-group>
</trans-unit>
<trans-unit id="7967484035994732534" datatype="html">
<source>Reload</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.component.ts</context>
<context context-type="linenumber">249</context>
<context context-type="linenumber">259</context>
</context-group>
</trans-unit>
<trans-unit id="7963559562180316948" datatype="html">
<source>Do you really want to remove this sign in method?</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.component.ts</context>
<context context-type="linenumber">295</context>
<context context-type="linenumber">305</context>
</context-group>
</trans-unit>
<trans-unit id="29881a45dafbe5aa05cd9d0441a4c0c2fb06df92" datatype="html">
@ -1311,42 +1315,42 @@
<source>Locale</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.html</context>
<context context-type="linenumber">152</context>
<context context-type="linenumber">160</context>
</context-group>
</trans-unit>
<trans-unit id="4402006eb2c97591dd8c87a5bd8f721fe9e4dc00" datatype="html">
<source>Date and number format</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.html</context>
<context context-type="linenumber">154</context>
<context context-type="linenumber">162</context>
</context-group>
</trans-unit>
<trans-unit id="b5dc65493e3e15fbe15b7d9c17f7626321d82e76" datatype="html">
<source>Zen Mode</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.html</context>
<context context-type="linenumber">206</context>
<context context-type="linenumber">214</context>
</context-group>
</trans-unit>
<trans-unit id="9ae348ee3a7319c2fc4794fa8bc425999d355f8f" datatype="html">
<source>Sign in with fingerprint</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.html</context>
<context context-type="linenumber">218</context>
<context context-type="linenumber">226</context>
</context-group>
</trans-unit>
<trans-unit id="83c4d4d764d2e2725ab8e919ec16ac400e1f290a" datatype="html">
<source>User ID</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.html</context>
<context context-type="linenumber">245</context>
<context context-type="linenumber">253</context>
</context-group>
</trans-unit>
<trans-unit id="9021c579c084e68d9db06a569d76f024111c6c54" datatype="html">
<source>Granted Access</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.html</context>
<context context-type="linenumber">254</context>
<context context-type="linenumber">262</context>
</context-group>
</trans-unit>
<trans-unit id="5e41f1b4c46ad9e0a9bc83fa36445483aa5cc324" datatype="html">
@ -1404,6 +1408,10 @@
<context context-type="sourcefile">apps/client/src/app/components/accounts-table/accounts-table.component.html</context>
<context context-type="linenumber">48</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
<context context-type="linenumber">62</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html</context>
<context context-type="linenumber">22</context>
@ -1735,7 +1743,7 @@
<source>Note</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
<context context-type="linenumber">153</context>
<context context-type="linenumber">160</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html</context>
@ -1750,7 +1758,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
<context context-type="linenumber">79</context>
<context context-type="linenumber">86</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html</context>
@ -2076,7 +2084,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
<context context-type="linenumber">88</context>
<context context-type="linenumber">95</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html</context>
@ -2127,7 +2135,7 @@
<source>Sector</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
<context context-type="linenumber">103</context>
<context context-type="linenumber">110</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html</context>
@ -2138,7 +2146,7 @@
<source>Country</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
<context context-type="linenumber">112</context>
<context context-type="linenumber">119</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html</context>
@ -2302,7 +2310,7 @@
<source>Experimental Features</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.html</context>
<context context-type="linenumber">233</context>
<context context-type="linenumber">241</context>
</context-group>
</trans-unit>
<trans-unit id="1931353503905413384" datatype="html">
@ -2358,7 +2366,7 @@
<source>Auto</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.html</context>
<context context-type="linenumber">195</context>
<context context-type="linenumber">203</context>
</context-group>
</trans-unit>
<trans-unit id="616064537937996961" datatype="html">
@ -2372,21 +2380,21 @@
<source>Light</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.html</context>
<context context-type="linenumber">196</context>
<context context-type="linenumber">204</context>
</context-group>
</trans-unit>
<trans-unit id="adb4562d2dbd3584370e44496969d58c511ecb63" datatype="html">
<source>Dark</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.html</context>
<context context-type="linenumber">197</context>
<context context-type="linenumber">205</context>
</context-group>
</trans-unit>
<trans-unit id="bbe41ac2ea4a6c00ea941a41b33105048f8e9f13" datatype="html">
<source>Appearance</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.html</context>
<context context-type="linenumber">180</context>
<context context-type="linenumber">188</context>
</context-group>
</trans-unit>
<trans-unit id="112783260724635106" datatype="html">
@ -2622,11 +2630,11 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.html</context>
<context context-type="linenumber">139</context>
<context context-type="linenumber">143</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.html</context>
<context context-type="linenumber">143</context>
<context context-type="linenumber">147</context>
</context-group>
</trans-unit>
<trans-unit id="064d88bead9e71bd849ecaefd8b38cca8f195a88" datatype="html">
@ -2640,7 +2648,7 @@
<source>Symbol Mapping</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
<context context-type="linenumber">142</context>
<context context-type="linenumber">149</context>
</context-group>
</trans-unit>
<trans-unit id="c8d1785038d461ec66b5799db21864182b35900a" datatype="html">

View File

@ -1,7 +1,7 @@
import * as currencies from '@dinero.js/currencies';
import { DataSource } from '@prisma/client';
import { getDate, getMonth, getYear, parse, subDays } from 'date-fns';
import { de, es, it, nl } from 'date-fns/locale';
import { de, es, fr, it, nl, pt } from 'date-fns/locale';
import { ghostfolioScraperApiSymbolPrefix, locale } from './config';
import { Benchmark } from './interfaces';
@ -79,10 +79,14 @@ export function getDateFnsLocale(aLanguageCode: string) {
return de;
} else if (aLanguageCode === 'es') {
return es;
} else if (aLanguageCode === 'fr') {
return fr;
} else if (aLanguageCode === 'it') {
return it;
} else if (aLanguageCode === 'nl') {
return nl;
} else if (aLanguageCode === 'pt') {
return pt;
}
return undefined;

View File

@ -8,7 +8,7 @@ export interface EnhancedSymbolProfile {
activitiesCount: number;
assetClass: AssetClass;
assetSubClass: AssetSubClass;
comment?: string;
comment: string | null;
countries: Country[];
createdAt: Date;
currency: string | null;

View File

@ -4,6 +4,7 @@ export interface HistoricalDataItem {
grossPerformancePercent?: number;
netPerformance?: number;
netPerformanceInPercentage?: number;
quantity?: number;
totalInvestment?: number;
value?: number;
}

View File

@ -10,5 +10,6 @@ export interface UserSettings {
isRestrictedView?: boolean;
language?: string;
locale?: string;
savingsRate?: number;
viewMode?: ViewMode;
}

View File

@ -0,0 +1,3 @@
import { Account, Platform } from '@prisma/client';
export type AccountWithPlatform = Account & { Platform?: Platform };

View File

@ -1 +1 @@
export type GroupBy = 'month';
export type GroupBy = 'month' | 'year';

View File

@ -1,4 +1,5 @@
import type { AccessWithGranteeUser } from './access-with-grantee-user.type';
import { AccountWithPlatform } from './account-with-platform.type';
import { AccountWithValue } from './account-with-value.type';
import type { ColorScheme } from './color-scheme';
import type { DateRange } from './date-range.type';
@ -13,6 +14,7 @@ import type { ViewMode } from './view-mode.type';
export type {
AccessWithGranteeUser,
AccountWithPlatform,
AccountWithValue,
ColorScheme,
DateRange,

View File

@ -1,6 +1,6 @@
import { Account, Order, Platform, SymbolProfile, Tag } from '@prisma/client';
import { Order, SymbolProfile, Tag } from '@prisma/client';
type AccountWithPlatform = Account & { Platform?: Platform };
import { AccountWithPlatform } from './account-with-platform.type';
export type OrderWithAccount = Order & {
Account?: AccountWithPlatform;

View File

@ -117,7 +117,7 @@
<td *matCellDef="let element" class="px-1" mat-cell>
<div class="d-flex align-items-center">
<div>
<span class="text-truncate">{{ element.SymbolProfile.name }}</span>
<span class="text-truncate">{{ element.SymbolProfile?.name }}</span>
<span
*ngIf="element.isDraft"
class="badge badge-secondary ml-1"
@ -126,9 +126,9 @@
>
</div>
</div>
<div *ngIf="!isUUID(element.SymbolProfile.symbol)">
<div *ngIf="!isUUID(element.SymbolProfile?.symbol)">
<small class="text-muted">{{
element.SymbolProfile.symbol | gfSymbol
element.SymbolProfile?.symbol | gfSymbol
}}</small>
</div>
</td>
@ -149,7 +149,7 @@
class="d-none d-lg-table-cell px-1"
mat-cell
>
{{ element.SymbolProfile.currency }}
{{ element.SymbolProfile?.currency }}
</td>
<td *matFooterCellDef class="d-none d-lg-table-cell px-1" mat-footer-cell>
{{ baseCurrency }}
@ -388,6 +388,14 @@
<ion-icon class="mr-2" name="cloud-upload-outline"></ion-icon>
<span i18n>Import Activities</span>
</button>
<button
*ngIf="hasPermissionToImportActivities"
mat-menu-item
(click)="onImportDividends()"
>
<ion-icon class="mr-2" name="color-wand-outline"></ion-icon>
<span i18n>Import Dividends</span>
</button>
<button
*ngIf="hasPermissionToExportActivities"
class="align-items-center d-flex"
@ -459,7 +467,10 @@
<tr
*matFooterRowDef="displayedColumns"
mat-footer-row
[ngClass]="{ 'd-none': isLoading || dataSource.data.length === 0 }"
[ngClass]="{
'd-none':
isLoading || dataSource.data.length === 0 || showFooter === false
}"
></tr>
</table>
</div>

View File

@ -41,8 +41,9 @@ export class ActivitiesTableComponent implements OnChanges, OnDestroy {
@Input() hasPermissionToOpenDetails = true;
@Input() locale: string;
@Input() pageSize = DEFAULT_PAGE_SIZE;
@Input() showActions: boolean;
@Input() showActions = true;
@Input() showCheckbox = false;
@Input() showFooter = true;
@Input() showNameColumn = true;
@Output() activityDeleted = new EventEmitter<string>();
@ -51,6 +52,7 @@ export class ActivitiesTableComponent implements OnChanges, OnDestroy {
@Output() export = new EventEmitter<string[]>();
@Output() exportDrafts = new EventEmitter<string[]>();
@Output() import = new EventEmitter<void>();
@Output() importDividends = new EventEmitter<UniqueAsset>();
@Output() selectedActivities = new EventEmitter<Activity[]>();
@ViewChild(MatPaginator) paginator: MatPaginator;
@ -233,6 +235,10 @@ export class ActivitiesTableComponent implements OnChanges, OnDestroy {
this.import.emit();
}
public onImportDividends() {
this.importDividends.emit();
}
public onOpenComment(aComment: string) {
alert(aComment);
}
@ -272,13 +278,18 @@ export class ActivitiesTableComponent implements OnChanges, OnDestroy {
};
}
fieldValueMap[activity.SymbolProfile.currency] = {
id: activity.SymbolProfile.currency,
label: activity.SymbolProfile.currency,
type: 'TAG'
};
if (activity.SymbolProfile?.currency) {
fieldValueMap[activity.SymbolProfile.currency] = {
id: activity.SymbolProfile.currency,
label: activity.SymbolProfile.currency,
type: 'TAG'
};
}
if (!isUUID(activity.SymbolProfile.symbol)) {
if (
activity.SymbolProfile?.symbol &&
!isUUID(activity.SymbolProfile.symbol)
) {
fieldValueMap[activity.SymbolProfile.symbol] = {
id: activity.SymbolProfile.symbol,
label: activity.SymbolProfile.symbol,

View File

@ -1,6 +1,6 @@
{
"name": "ghostfolio",
"version": "1.223.0",
"version": "1.225.0",
"homepage": "https://ghostfol.io",
"license": "AGPL-3.0",
"scripts": {