Compare commits

...

22 Commits

Author SHA1 Message Date
da827a08f5 Release 1.221.0 (#1541) 2022-12-26 17:09:51 +01:00
d545e4877c Feature/improve activities import by preview step (#1540)
* Improve activities import

* Update changelog
2022-12-26 17:07:51 +01:00
1918dee9c5 Format code 2022-12-26 16:50:50 +01:00
a08610b603 Feature/improve activities import (#1531) 2022-12-26 16:26:51 +01:00
c22733db56 Feature/resolve blog post titles (#1539)
* Resolve blog post titles

* Update changelog
2022-12-26 16:23:21 +01:00
ee4866eb7d Feature/add blog post the importance of tracking your personal finances (#1537)
* Add blog post: The importance of tracking your personal finances

* Update changelog
2022-12-26 12:23:43 +01:00
327b1fa0d7 Feature/refresh cryptocurrencies list 20221225 (#1536)
* Update cryptocurrencies.json

* Update changelog
2022-12-25 18:17:35 +01:00
b155666d21 Feature/improve label based on type in create or edit activity dialog (#1535)
* Improve label

* Update changelog
2022-12-25 12:41:48 +01:00
c5ee3237ed Refactoring (#1533) 2022-12-25 12:40:29 +01:00
16118d635c Bugfix/fix date conversion of two digit year (#1529)
* Fix date conversion of two digit year

* Update changelog
2022-12-25 12:38:40 +01:00
49ce4803ce Feature/add support to manage tags in create or edit activity dialog (#1532)
* Add support to manage tags

* Update changelog
2022-12-25 12:23:52 +01:00
0b65d05013 Feature/remove rakuten from data source type (#1534)
* Remove RAKUTEN

* Update changelog
2022-12-25 12:20:09 +01:00
8793284e75 Feature/add tags to admin control panel (#1530)
* Add tags

* Update changelog
2022-12-24 12:28:17 +01:00
1c5e4050a8 Release 1.220.0 (#1528) 2022-12-23 11:08:22 +01:00
4f187e1a9f Feature/increase fear and greed index to 365 days (#1519)
* Increase fear and greed index to 365 days

* Update changelog
2022-12-23 11:06:52 +01:00
b56111ae85 Feature/add dry run to import api endpoint (#1526)
* Add dry run to import API endpoint

* Update changelog
2022-12-23 10:51:49 +01:00
61dfc1f819 Feature/upgrade prettier to version 2.8.1 (#1523)
* Upgrade prettier to version 2.8.1

* Update changelog
2022-12-23 10:50:57 +01:00
6137f228a8 Upgrade @types/lodash to version 4.14.191 (#1527) 2022-12-23 10:50:38 +01:00
5293de14cd Bugfix/fix rounding of y axis ticks in benchmark comparator (#1521)
* Fix rounding

* Update changelog
2022-12-22 12:27:34 +01:00
7340a674b5 Feature/upgrade color to version 4.2.3 (#1524)
* Upgrade color to version 4.2.3

* Update changelog
2022-12-21 19:40:29 +01:00
42cb3e2c73 Harmonize style of symbol (#1520) 2022-12-20 13:29:57 +01:00
e8a4a53c9f Feature/support position detail dialog in top performers of analysis page (#1522)
* Add support for position detail dialog

* Update changelog
2022-12-19 09:36:34 +01:00
50 changed files with 1955 additions and 661 deletions

View File

@ -5,6 +5,43 @@ 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.221.0 - 2022-12-26
### Added
- Added support to manage the tags in the create or edit activity dialog
- Added the tags to the admin control panel
- Added a blog post: _The importance of tracking your personal finances_
- Resolved the title of the blog post
### Changed
- Improved the activities import by a preview step
- Improved the labels based on the type in the create or edit activity dialog
- Refreshed the cryptocurrencies list
- Removed the data source type `RAKUTEN`
### Fixed
- Fixed the date conversion for years with only two digits
## 1.220.0 - 2022-12-23
### Added
- Added the position detail dialog to the _Top 3_ and _Bottom 3_ performers of the analysis page
- Added the `dryRun` option to the import activities endpoint
### Changed
- Increased the historical data chart of the _Fear & Greed Index_ (market mood) to 365 days
- Upgraded `color` from version `4.0.1` to `4.2.3`
- Upgraded `prettier` from version `2.7.1` to `2.8.1`
### Fixed
- Fixed the rounding of the y-axis ticks in the benchmark comparator
## 1.219.0 - 2022-12-17
### Added

View File

@ -3,8 +3,10 @@ import * as path from 'path';
import { ConfigurationService } from '@ghostfolio/api/services/configuration.service';
import { DEFAULT_LANGUAGE_CODE } from '@ghostfolio/common/config';
import { DATE_FORMAT } from '@ghostfolio/common/helper';
import { Injectable, NestMiddleware } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { format } from 'date-fns';
import { NextFunction, Request, Response } from 'express';
@Injectable()
@ -51,14 +53,26 @@ export class FrontendMiddleware implements NestMiddleware {
}
public use(request: Request, response: Response, next: NextFunction) {
const currentDate = format(new Date(), DATE_FORMAT);
let featureGraphicPath = 'assets/cover.png';
let title = 'Ghostfolio Open Source Wealth Management Software';
if (request.path.startsWith('/en/blog/2022/08/500-stars-on-github')) {
featureGraphicPath = 'assets/images/blog/500-stars-on-github.jpg';
title = `500 Stars - ${title}`;
} else if (request.path.startsWith('/en/blog/2022/10/hacktoberfest-2022')) {
featureGraphicPath = 'assets/images/blog/hacktoberfest-2022.png';
title = `Hacktoberfest 2022 - ${title}`;
} else if (request.path.startsWith('/en/blog/2022/11/black-friday-2022')) {
featureGraphicPath = 'assets/images/blog/black-friday-2022.jpg';
title = `Black Friday 2022 - ${title}`;
} else if (
request.path.startsWith(
'/en/blog/2022/12/the-importance-of-tracking-your-personal-finances'
)
) {
featureGraphicPath = 'assets/images/blog/20221226.jpg';
title = `The importance of tracking your personal finances - ${title}`;
}
if (
@ -71,7 +85,9 @@ export class FrontendMiddleware implements NestMiddleware {
} else if (request.path === '/de' || request.path.startsWith('/de/')) {
response.send(
this.interpolate(this.indexHtmlDe, {
currentDate,
featureGraphicPath,
title,
languageCode: 'de',
path: request.path,
rootUrl: this.configurationService.get('ROOT_URL')
@ -80,7 +96,9 @@ export class FrontendMiddleware implements NestMiddleware {
} else if (request.path === '/es' || request.path.startsWith('/es/')) {
response.send(
this.interpolate(this.indexHtmlEs, {
currentDate,
featureGraphicPath,
title,
languageCode: 'es',
path: request.path,
rootUrl: this.configurationService.get('ROOT_URL')
@ -89,7 +107,9 @@ export class FrontendMiddleware implements NestMiddleware {
} else if (request.path === '/it' || request.path.startsWith('/it/')) {
response.send(
this.interpolate(this.indexHtmlIt, {
currentDate,
featureGraphicPath,
title,
languageCode: 'it',
path: request.path,
rootUrl: this.configurationService.get('ROOT_URL')
@ -98,7 +118,9 @@ export class FrontendMiddleware implements NestMiddleware {
} else if (request.path === '/nl' || request.path.startsWith('/nl/')) {
response.send(
this.interpolate(this.indexHtmlNl, {
currentDate,
featureGraphicPath,
title,
languageCode: 'nl',
path: request.path,
rootUrl: this.configurationService.get('ROOT_URL')
@ -107,7 +129,9 @@ export class FrontendMiddleware implements NestMiddleware {
} else {
response.send(
this.interpolate(this.indexHtmlEn, {
currentDate,
featureGraphicPath,
title,
languageCode: DEFAULT_LANGUAGE_CODE,
path: request.path,
rootUrl: this.configurationService.get('ROOT_URL')

View File

@ -1,4 +1,5 @@
import { ConfigurationService } from '@ghostfolio/api/services/configuration.service';
import { ImportResponse } from '@ghostfolio/common/interfaces';
import type { RequestWithUser } from '@ghostfolio/common/types';
import {
Body,
@ -7,6 +8,7 @@ import {
Inject,
Logger,
Post,
Query,
UseGuards
} from '@nestjs/common';
import { REQUEST } from '@nestjs/core';
@ -26,7 +28,10 @@ export class ImportController {
@Post()
@UseGuards(AuthGuard('jwt'))
public async import(@Body() importData: ImportDataDto): Promise<void> {
public async import(
@Body() importData: ImportDataDto,
@Query('dryRun') isDryRun?: boolean
): Promise<ImportResponse> {
if (!this.configurationService.get('ENABLE_FEATURE_IMPORT')) {
throw new HttpException(
getReasonPhrase(StatusCodes.FORBIDDEN),
@ -45,12 +50,18 @@ export class ImportController {
maxActivitiesToImport = Number.MAX_SAFE_INTEGER;
}
const userCurrency = this.request.user.Settings.settings.baseCurrency;
try {
return await this.importService.import({
const activities = await this.importService.import({
maxActivitiesToImport,
activities: importData.activities,
isDryRun,
userCurrency,
activitiesDto: importData.activities,
userId: this.request.user.id
});
return { activities };
} catch (error) {
Logger.error(error, ImportController);

View File

@ -5,6 +5,7 @@ import { RedisCacheModule } from '@ghostfolio/api/app/redis-cache/redis-cache.mo
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 { Module } from '@nestjs/common';
@ -19,6 +20,7 @@ import { ImportService } from './import.service';
ConfigurationModule,
DataGatheringModule,
DataProviderModule,
ExchangeRateDataModule,
OrderModule,
PrismaModule,
RedisCacheModule

View File

@ -1,30 +1,38 @@
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 { ConfigurationService } from '@ghostfolio/api/services/configuration.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 { Injectable } from '@nestjs/common';
import { isSameDay, parseISO } from 'date-fns';
import Big from 'big.js';
import { endOfToday, isAfter, isSameDay, parseISO } from 'date-fns';
import { v4 as uuidv4 } from 'uuid';
@Injectable()
export class ImportService {
public constructor(
private readonly accountService: AccountService,
private readonly configurationService: ConfigurationService,
private readonly dataProviderService: DataProviderService,
private readonly exchangeRateDataService: ExchangeRateDataService,
private readonly orderService: OrderService
) {}
public async import({
activities,
activitiesDto,
isDryRun = false,
maxActivitiesToImport,
userCurrency,
userId
}: {
activities: Partial<CreateOrderDto>[];
activitiesDto: Partial<CreateOrderDto>[];
isDryRun?: boolean;
maxActivitiesToImport: number;
userCurrency: string;
userId: string;
}): Promise<void> {
for (const activity of activities) {
}): Promise<Activity[]> {
for (const activity of activitiesDto) {
if (!activity.dataSource) {
if (activity.type === 'ITEM') {
activity.dataSource = 'MANUAL';
@ -35,7 +43,7 @@ export class ImportService {
}
await this.validateActivities({
activities,
activitiesDto,
maxActivitiesToImport,
userId
});
@ -46,57 +54,121 @@ export class ImportService {
}
);
const activities: Activity[] = [];
for (const {
accountId,
comment,
currency,
dataSource,
date,
date: dateString,
fee,
quantity,
symbol,
type,
unitPrice
} of activities) {
await this.orderService.createOrder({
comment,
fee,
quantity,
type,
unitPrice,
userId,
accountId: accountIds.includes(accountId) ? accountId : undefined,
date: parseISO(<string>(<unknown>date)),
SymbolProfile: {
connectOrCreate: {
create: {
currency,
dataSource,
symbol
},
where: {
dataSource_symbol: {
} of activitiesDto) {
const date = parseISO(<string>(<unknown>dateString));
const validatedAccountId = accountIds.includes(accountId)
? accountId
: undefined;
let order: OrderWithAccount;
if (isDryRun) {
order = {
comment,
date,
fee,
quantity,
type,
unitPrice,
userId,
accountId: validatedAccountId,
accountUserId: undefined,
createdAt: new Date(),
id: uuidv4(),
isDraft: isAfter(date, endOfToday()),
SymbolProfile: {
currency,
dataSource,
symbol,
assetClass: null,
assetSubClass: null,
comment: null,
countries: null,
createdAt: undefined,
id: undefined,
name: null,
scraperConfiguration: null,
sectors: null,
symbolMapping: null,
updatedAt: undefined,
url: null
},
symbolProfileId: undefined,
updatedAt: new Date()
};
} else {
order = await this.orderService.createOrder({
comment,
date,
fee,
quantity,
type,
unitPrice,
userId,
accountId: validatedAccountId,
SymbolProfile: {
connectOrCreate: {
create: {
currency,
dataSource,
symbol
},
where: {
dataSource_symbol: {
dataSource,
symbol
}
}
}
}
},
User: { connect: { id: userId } }
},
User: { connect: { id: userId } }
});
}
const value = new Big(quantity).mul(unitPrice).toNumber();
activities.push({
...order,
value,
feeInBaseCurrency: this.exchangeRateDataService.toCurrency(
fee,
currency,
userCurrency
),
valueInBaseCurrency: this.exchangeRateDataService.toCurrency(
value,
currency,
userCurrency
)
});
}
return activities;
}
private async validateActivities({
activities,
activitiesDto,
maxActivitiesToImport,
userId
}: {
activities: Partial<CreateOrderDto>[];
activitiesDto: Partial<CreateOrderDto>[];
maxActivitiesToImport: number;
userId: string;
}) {
if (activities?.length > maxActivitiesToImport) {
if (activitiesDto?.length > maxActivitiesToImport) {
throw new Error(`Too many activities (${maxActivitiesToImport} at most)`);
}
@ -109,7 +181,7 @@ export class ImportService {
for (const [
index,
{ currency, dataSource, date, fee, quantity, symbol, type, unitPrice }
] of activities.entries()) {
] of activitiesDto.entries()) {
const duplicateActivity = existingActivities.find((activity) => {
return (
activity.SymbolProfile.currency === currency &&

View File

@ -362,6 +362,12 @@ export class OrderService {
delete data.symbol;
delete data.tags;
// Remove existing tags
await this.prismaService.order.update({
data: { tags: { set: [] } },
where
});
return this.prismaService.order.update({
data: {
...data,

File diff suppressed because it is too large Load Diff

View File

@ -5,20 +5,18 @@ import {
IDataProviderHistoricalResponse,
IDataProviderResponse
} from '@ghostfolio/api/services/interfaces/interfaces';
import { PrismaService } from '@ghostfolio/api/services/prisma.service';
import { ghostfolioFearAndGreedIndexSymbol } from '@ghostfolio/common/config';
import { DATE_FORMAT, getToday, getYesterday } from '@ghostfolio/common/helper';
import { DATE_FORMAT, getYesterday } from '@ghostfolio/common/helper';
import { Granularity } from '@ghostfolio/common/types';
import { Injectable, Logger } from '@nestjs/common';
import { DataSource, SymbolProfile } from '@prisma/client';
import bent from 'bent';
import { format, subMonths, subWeeks, subYears } from 'date-fns';
import { format } from 'date-fns';
@Injectable()
export class RapidApiService implements DataProviderInterface {
public constructor(
private readonly configurationService: ConfigurationService,
private readonly prismaService: PrismaService
private readonly configurationService: ConfigurationService
) {}
public canHandle(symbol: string) {
@ -47,41 +45,6 @@ export class RapidApiService implements DataProviderInterface {
if (symbol === ghostfolioFearAndGreedIndexSymbol) {
const fgi = await this.getFearAndGreedIndex();
try {
// Rebuild historical data
// TODO: can be removed after all data from the last year has been gathered
// (introduced on 27.03.2021)
await this.prismaService.marketData.create({
data: {
symbol,
dataSource: this.getName(),
date: subWeeks(getToday(), 1),
marketPrice: fgi.oneWeekAgo.value
}
});
await this.prismaService.marketData.create({
data: {
symbol,
dataSource: this.getName(),
date: subMonths(getToday(), 1),
marketPrice: fgi.oneMonthAgo.value
}
});
await this.prismaService.marketData.create({
data: {
symbol,
dataSource: this.getName(),
date: subYears(getToday(), 1),
marketPrice: fgi.oneYearAgo.value
}
});
///////////////////////////////////////////////////////////////////////////
} catch {}
return {
[ghostfolioFearAndGreedIndexSymbol]: {
[format(getYesterday(), DATE_FORMAT)]: {

View File

@ -2,7 +2,7 @@ import { Platform } from '@angular/cdk/platform';
import { Inject, forwardRef } from '@angular/core';
import { MAT_DATE_LOCALE, NativeDateAdapter } from '@angular/material/core';
import { getDateFormatString } from '@ghostfolio/common/helper';
import { format, parse } from 'date-fns';
import { addYears, format, getYear, parse } from 'date-fns';
export class CustomDateAdapter extends NativeDateAdapter {
public constructor(
@ -31,6 +31,16 @@ export class CustomDateAdapter extends NativeDateAdapter {
* Parses a date from a provided value
*/
public parse(aValue: string): Date {
return parse(aValue, getDateFormatString(this.locale), new Date());
let date = parse(aValue, getDateFormatString(this.locale), new Date());
if (getYear(date) < 1900) {
if (getYear(date) > Number(format(new Date(), 'yy')) + 1) {
date = addYears(date, 1900);
} else {
date = addYears(date, 2000);
}
}
return date;
}
}

View File

@ -109,6 +109,13 @@ const routes: Routes = [
'./pages/blog/2022/11/black-friday-2022/black-friday-2022-page.module'
).then((m) => m.BlackFriday2022PageModule)
},
{
path: 'blog/2022/12/the-importance-of-tracking-your-personal-finances',
loadChildren: () =>
import(
'./pages/blog/2022/12/the-importance-of-tracking-your-personal-finances/the-importance-of-tracking-your-personal-finances-page.module'
).then((m) => m.TheImportanceOfTrackingYourPersonalFinancesPageModule)
},
{
path: 'demo',
loadChildren: () =>

View File

@ -72,16 +72,32 @@
</div>
</div>
</div>
<div class="align-items-start d-flex my-3">
<div
*ngIf="info?.benchmarks?.length > 0"
class="align-items-start d-flex my-3"
>
<div class="w-50" i18n>Benchmarks</div>
<div class="w-50">
<table>
<tr *ngFor="let benchmark of info?.benchmarks">
<tr *ngFor="let benchmark of info.benchmarks">
<td class="pl-1">{{ benchmark.symbol }}</td>
</tr>
</table>
</div>
</div>
<div
*ngIf="info?.tags?.length > 0"
class="align-items-start d-flex my-3"
>
<div class="w-50" i18n>Tags</div>
<div class="w-50">
<table>
<tr *ngFor="let tag of info.tags">
<td class="pl-1">{{ tag.name }}</td>
</tr>
</table>
</div>
</div>
<div class="d-flex my-3">
<div class="w-50" i18n>User Signup</div>
<div class="w-50">

View File

@ -187,7 +187,7 @@ export class BenchmarkComparatorComponent implements OnChanges, OnDestroy {
position: 'right',
ticks: {
callback: (value: number) => {
return `${value} %`;
return `${value.toFixed(2)} %`;
},
display: true,
mirror: true,

View File

@ -27,7 +27,7 @@ export class HomeMarketComponent implements OnDestroy, OnInit {
public historicalDataItems: HistoricalDataItem[];
public info: InfoItem;
public isLoading = true;
public readonly numberOfDays = 180;
public readonly numberOfDays = 365;
public user: User;
private unsubscribeSubject = new Subject<void>();

View File

@ -3,12 +3,12 @@
<a
class="d-flex p-3 w-100"
[ngClass]="{ 'cursor-default': isLoading }"
[routerLink]="[]"
[queryParams]="{
dataSource: position?.dataSource,
positionDetailDialog: true,
symbol: position?.symbol
}"
[routerLink]="[]"
>
<div class="d-flex mr-2">
<gf-trend-indicator
@ -39,7 +39,7 @@
<div *ngIf="!isLoading" class="flex-grow-1 text-truncate">
<div class="h6 m-0 text-truncate">{{ position?.name }}</div>
<div class="d-flex">
<span>{{ position?.symbol | gfSymbol }}</span>
<small class="text-muted">{{ position?.symbol | gfSymbol }}</small>
</div>
<div class="d-flex mt-1">
<gf-value

View File

@ -0,0 +1,20 @@
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { AuthGuard } from '@ghostfolio/client/core/auth.guard';
import { TheImportanceOfTrackingYourPersonalFinancesPageComponent } from './the-importance-of-tracking-your-personal-finances-page.component';
const routes: Routes = [
{
canActivate: [AuthGuard],
component: TheImportanceOfTrackingYourPersonalFinancesPageComponent,
path: '',
title: 'The importance of tracking your personal finances'
}
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class TheImportanceOfTrackingYourPersonalFinancesRoutingModule {}

View File

@ -0,0 +1,9 @@
import { Component } from '@angular/core';
@Component({
host: { class: 'page' },
selector: 'gf-the-importance-of-tracking-your-personal-finances-page',
styleUrls: ['./the-importance-of-tracking-your-personal-finances-page.scss'],
templateUrl: './the-importance-of-tracking-your-personal-finances-page.html'
})
export class TheImportanceOfTrackingYourPersonalFinancesPageComponent {}

View File

@ -0,0 +1,168 @@
<div class="blog container">
<div class="row">
<div class="col-md-8 offset-md-2">
<article>
<div class="mb-4 text-center">
<h1 class="mb-1">
The importance of tracking your personal finances
</h1>
<div class="mb-3 text-muted"><small>2022-12-26</small></div>
<img
alt="The importance of tracking your personal finances Teaser"
class="rounded w-100"
src="../assets/images/blog/20221226.jpg"
title="The importance of tracking your personal finances"
/>
</div>
<section class="mb-4">
<p>
Once again, the end of the year is peak season for making
resolutions, whether in the area of personal fitness, relationships
or career. For sustainable changes, its important to track your
progress and celebrate even small successes. Not surprisingly, these
same principles apply to personal finances as well.
</p>
<p>
Tracking your assets is an important part of achieving your
financial goals. By regularly reviewing and monitoring your assets,
you can get a clear picture of your financial situation and identify
areas where action is required to reach your financial ambitions.
</p>
</section>
<section class="mb-4">
<h2 class="h4">Understanding your net worth</h2>
<p>
One of the main benefits of monitoring wealth is that it helps you
understand the value of your assets. By keeping track of your
assets, you can see how much money you have invested, where it is
invested, and how well it is performing. This allows you to see how
your assets are performing over time, and you can adjust your
strategy if necessary.
</p>
</section>
<section class="mb-4">
<h2 class="h4">Identifying opportunities</h2>
<p>
Tracking your wealth can also help you identify financial
opportunities for growth and improvement. By reviewing your assets
regularly, you may be able to identify new investment opportunities
or strategies that can help you grow your wealth and reach your
financial objectives faster.
</p>
</section>
<section class="mb-4">
<h2 class="h4">Managing the risk and making informed decisions</h2>
<p>
Monitoring your assets not only helps you understand the value of
your assets and identify potential for growth, but also helps you
manage your risk. By understanding the different types of your
assets and their performance, you can make informed decisions about
how to allocate your assets to minimize risk and maximize the
potential return on investment.
</p>
</section>
<section class="mb-4">
<h2 class="h4">Tracking personal finances with Ghostfolio</h2>
<p>
In summary, monitoring your assets is an important aspect of
achieving your financial goals. It helps you understand the value of
your assets, identify growth opportunities and manage your risk. By
regularly reviewing and monitoring your assets, you can make
informed decisions about your financial strategy and work toward
your financial success.
</p>
<p>
Instead of manually recording your assets and net worth in a
spreadsheet, you can use
<a href="https://ghostfol.io">Ghostfolio</a>, a web-based software
to manage your personal finances.
</p>
</section>
<section class="mb-4 py-3">
<h2 class="h4 mb-0 text-center">
Would you like to <strong>refine</strong> your
<strong>personal investment strategy</strong>?
</h2>
<p class="lead mb-2 text-center">
Ghostfolio empowers you to keep track of your wealth.
</p>
<div class="text-center">
<a color="primary" href="https://ghostfol.io" mat-flat-button>
Get Started
</a>
</div>
</section>
<section class="mb-4">
<ul class="list-inline">
<li class="list-inline-item">
<span class="badge badge-light">App</span>
</li>
<li class="list-inline-item">
<span class="badge badge-light">Assets</span>
</li>
<li class="list-inline-item">
<span class="badge badge-light">Decision</span>
</li>
<li class="list-inline-item">
<span class="badge badge-light">Finance</span>
</li>
<li class="list-inline-item">
<span class="badge badge-light">Fintech</span>
</li>
<li class="list-inline-item">
<span class="badge badge-light">Ghostfolio</span>
</li>
<li class="list-inline-item">
<span class="badge badge-light">Goal</span>
</li>
<li class="list-inline-item">
<span class="badge badge-light">Investment</span>
</li>
<li class="list-inline-item">
<span class="badge badge-light">Management</span>
</li>
<li class="list-inline-item">
<span class="badge badge-light">Monitoring</span>
</li>
<li class="list-inline-item">
<span class="badge badge-light">Net Worth</span>
</li>
<li class="list-inline-item">
<span class="badge badge-light">Opportunity</span>
</li>
<li class="list-inline-item">
<span class="badge badge-light">Performance</span>
</li>
<li class="list-inline-item">
<span class="badge badge-light">Personal Finance</span>
</li>
<li class="list-inline-item">
<span class="badge badge-light">Portfolio Tracker</span>
</li>
<li class="list-inline-item">
<span class="badge badge-light">Progress</span>
</li>
<li class="list-inline-item">
<span class="badge badge-light">Risk</span>
</li>
<li class="list-inline-item">
<span class="badge badge-light">Software</span>
</li>
<li class="list-inline-item">
<span class="badge badge-light">Spreadsheet</span>
</li>
<li class="list-inline-item">
<span class="badge badge-light">Strategy</span>
</li>
<li class="list-inline-item">
<span class="badge badge-light">Success</span>
</li>
<li class="list-inline-item">
<span class="badge badge-light">Wealth</span>
</li>
</ul>
</section>
</article>
</div>
</div>
</div>

View File

@ -0,0 +1,19 @@
import { CommonModule } from '@angular/common';
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { RouterModule } from '@angular/router';
import { TheImportanceOfTrackingYourPersonalFinancesRoutingModule } from './the-importance-of-tracking-your-personal-finances-page-routing.module';
import { TheImportanceOfTrackingYourPersonalFinancesPageComponent } from './the-importance-of-tracking-your-personal-finances-page.component';
@NgModule({
declarations: [TheImportanceOfTrackingYourPersonalFinancesPageComponent],
imports: [
CommonModule,
MatButtonModule,
RouterModule,
TheImportanceOfTrackingYourPersonalFinancesRoutingModule
],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
export class TheImportanceOfTrackingYourPersonalFinancesPageModule {}

View File

@ -2,15 +2,41 @@
<div class="mb-5 row">
<div class="col">
<h3 class="mb-3 text-center" i18n>Blog</h3>
<mat-card class="mb-3">
<mat-card-content>
<div class="container p-0">
<div class="flex-nowrap no-gutters row">
<a
class="d-flex overflow-hidden w-100"
href="../en/blog/2022/12/the-importance-of-tracking-your-personal-finances"
>
<div class="flex-grow-1 overflow-hidden">
<div class="h6 m-0 text-truncate">
The importance of tracking your personal finances
</div>
<div class="d-flex text-muted">2022-12-26</div>
</div>
<div class="align-items-center d-flex">
<ion-icon
class="chevron text-muted"
name="chevron-forward-outline"
size="small"
></ion-icon>
</div>
</a>
</div>
</div>
</mat-card-content>
</mat-card>
<mat-card *ngIf="hasPermissionForSubscription" class="mb-3">
<mat-card-content>
<div class="container p-0">
<div class="flex-nowrap no-gutters row">
<a
class="d-flex w-100"
class="d-flex overflow-hidden w-100"
href="../en/blog/2022/11/black-friday-2022"
>
<div class="flex-grow-1">
<div class="flex-grow-1 overflow-hidden">
<div class="h6 m-0 text-truncate">Black Friday 2022</div>
<div class="d-flex text-muted">2022-11-13</div>
</div>
@ -31,10 +57,10 @@
<div class="container p-0">
<div class="flex-nowrap no-gutters row">
<a
class="d-flex w-100"
class="d-flex overflow-hidden w-100"
href="../en/blog/2022/10/hacktoberfest-2022"
>
<div class="flex-grow-1">
<div class="flex-grow-1 overflow-hidden">
<div class="h6 m-0 text-truncate">Hacktoberfest 2022</div>
<div class="d-flex text-muted">2022-10-01</div>
</div>
@ -55,10 +81,10 @@
<div class="container p-0">
<div class="flex-nowrap no-gutters row">
<a
class="d-flex w-100"
class="d-flex overflow-hidden w-100"
href="../en/blog/2022/08/500-stars-on-github"
>
<div class="flex-grow-1">
<div class="flex-grow-1 overflow-hidden">
<div class="h6 m-0 text-truncate">500 Stars on GitHub</div>
<div class="d-flex text-muted">2022-08-18</div>
</div>
@ -79,10 +105,10 @@
<div class="container p-0">
<div class="flex-nowrap no-gutters row">
<a
class="d-flex w-100"
class="d-flex overflow-hidden w-100"
href="../en/blog/2022/07/ghostfolio-meets-internet-identity"
>
<div class="flex-grow-1">
<div class="flex-grow-1 overflow-hidden">
<div class="h6 m-0 text-truncate">
Ghostfolio meets Internet Identity
</div>
@ -105,10 +131,10 @@
<div class="container p-0">
<div class="flex-nowrap no-gutters row">
<a
class="d-flex w-100"
class="d-flex overflow-hidden w-100"
href="../en/blog/2022/07/how-do-i-get-my-finances-in-order"
>
<div class="flex-grow-1">
<div class="flex-grow-1 overflow-hidden">
<div class="h6 m-0 text-truncate">
How do I get my finances in order?
</div>
@ -131,10 +157,10 @@
<div class="container p-0">
<div class="flex-nowrap no-gutters row">
<a
class="d-flex w-100"
class="d-flex overflow-hidden w-100"
href="../en/blog/2022/01/ghostfolio-first-months-in-open-source"
>
<div class="flex-grow-1">
<div class="flex-grow-1 overflow-hidden">
<div class="h6 m-0 text-truncate">
First months in Open Source
</div>
@ -157,10 +183,10 @@
<div class="container p-0">
<div class="flex-nowrap no-gutters row">
<a
class="d-flex w-100"
class="d-flex overflow-hidden w-100"
href="../en/blog/2021/07/hello-ghostfolio"
>
<div class="flex-grow-1">
<div class="flex-grow-1 overflow-hidden">
<div class="h6 m-0 text-truncate">Hello Ghostfolio</div>
<div class="d-flex text-muted">2021-07-31</div>
</div>
@ -181,10 +207,10 @@
<div class="container p-0">
<div class="flex-nowrap no-gutters row">
<a
class="d-flex w-100"
class="d-flex overflow-hidden w-100"
href="../de/blog/2021/07/hallo-ghostfolio"
>
<div class="flex-grow-1">
<div class="flex-grow-1 overflow-hidden">
<div class="h6 m-0 text-truncate">Hallo Ghostfolio</div>
<div class="d-flex text-muted">2021-07-31</div>
</div>

View File

@ -1,7 +1,9 @@
import { COMMA, ENTER } from '@angular/cdk/keycodes';
import {
ChangeDetectionStrategy,
ChangeDetectorRef,
Component,
ElementRef,
Inject,
OnDestroy,
ViewChild
@ -15,7 +17,7 @@ import { UpdateOrderDto } from '@ghostfolio/api/app/order/update-order.dto';
import { LookupItem } from '@ghostfolio/api/app/symbol/interfaces/lookup-item.interface';
import { DataService } from '@ghostfolio/client/services/data.service';
import { translate } from '@ghostfolio/ui/i18n';
import { AssetClass, AssetSubClass, Type } from '@prisma/client';
import { AssetClass, AssetSubClass, Tag, Type } from '@prisma/client';
import { isUUID } from 'class-validator';
import { isString } from 'lodash';
import { EMPTY, Observable, Subject, lastValueFrom } from 'rxjs';
@ -23,6 +25,7 @@ import {
catchError,
debounceTime,
distinctUntilChanged,
map,
startWith,
switchMap,
takeUntil
@ -38,7 +41,8 @@ import { CreateOrUpdateActivityDialogParams } from './interfaces/interfaces';
templateUrl: 'create-or-update-activity-dialog.html'
})
export class CreateOrUpdateActivityDialog implements OnDestroy {
@ViewChild('autocomplete') autocomplete;
@ViewChild('symbolAutocomplete') symbolAutocomplete;
@ViewChild('tagInput') tagInput: ElementRef<HTMLInputElement>;
public activityForm: FormGroup;
public assetClasses = Object.keys(AssetClass).map((assetClass) => {
@ -51,8 +55,11 @@ export class CreateOrUpdateActivityDialog implements OnDestroy {
public currentMarketPrice = null;
public filteredLookupItems: LookupItem[];
public filteredLookupItemsObservable: Observable<LookupItem[]>;
public filteredTagsObservable: Observable<Tag[]>;
public isLoading = false;
public platforms: { id: string; name: string }[];
public separatorKeysCodes: number[] = [ENTER, COMMA];
public tags: Tag[] = [];
public total = 0;
public Validators = Validators;
@ -72,10 +79,11 @@ export class CreateOrUpdateActivityDialog implements OnDestroy {
this.locale = this.data.user?.settings?.locale;
this.dateAdapter.setLocale(this.locale);
const { currencies, platforms } = this.dataService.fetchInfo();
const { currencies, platforms, tags } = this.dataService.fetchInfo();
this.currencies = currencies;
this.platforms = platforms;
this.tags = tags;
this.activityForm = this.formBuilder.group({
accountId: [this.data.activity?.accountId, Validators.required],
@ -185,6 +193,15 @@ export class CreateOrUpdateActivityDialog implements OnDestroy {
})
);
this.filteredTagsObservable = this.activityForm.controls[
'tags'
].valueChanges.pipe(
startWith(this.activityForm.controls['tags'].value),
map((aTags: Tag[] | null) => {
return aTags ? this.filterTags(aTags) : this.tags.slice();
})
);
this.activityForm.controls['type'].valueChanges
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe((type: Type) => {
@ -264,6 +281,16 @@ export class CreateOrUpdateActivityDialog implements OnDestroy {
return aLookupItem?.symbol ?? '';
}
public onAddTag(event: MatAutocompleteSelectedEvent) {
this.activityForm.controls['tags'].setValue([
...(this.activityForm.controls['tags'].value ?? []),
this.tags.find(({ id }) => {
return id === event.option.value;
})
]);
this.tagInput.nativeElement.value = '';
}
public onBlurSymbol() {
const currentLookupItem = this.filteredLookupItems.find((lookupItem) => {
return (
@ -283,10 +310,18 @@ export class CreateOrUpdateActivityDialog implements OnDestroy {
this.changeDetectorRef.markForCheck();
}
public onCancel(): void {
public onCancel() {
this.dialogRef.close();
}
public onRemoveTag(aTag: Tag) {
this.activityForm.controls['tags'].setValue(
this.activityForm.controls['tags'].value.filter(({ id }) => {
return id !== aTag.id;
})
);
}
public onSubmit() {
const activity: CreateOrderDto | UpdateOrderDto = {
accountId: this.activityForm.controls['accountId'].value,
@ -327,6 +362,16 @@ export class CreateOrUpdateActivityDialog implements OnDestroy {
this.unsubscribeSubject.complete();
}
private filterTags(aTags: Tag[]) {
const tagIds = aTags.map((tag) => {
return tag.id;
});
return this.tags.filter((tag) => {
return !tagIds.includes(tag.id);
});
}
private updateSymbol(symbol: string) {
this.isLoading = true;

View File

@ -11,10 +11,10 @@
<mat-form-field appearance="outline" class="w-100">
<mat-label i18n>Type</mat-label>
<mat-select formControlName="type">
<mat-option i18n value="BUY">BUY</mat-option>
<mat-option i18n value="DIVIDEND">DIVIDEND</mat-option>
<mat-option i18n value="ITEM">ITEM</mat-option>
<mat-option i18n value="SELL">SELL</mat-option>
<mat-option i18n value="BUY">Buy</mat-option>
<mat-option i18n value="DIVIDEND">Dividend</mat-option>
<mat-option i18n value="ITEM">Item</mat-option>
<mat-option i18n value="SELL">Sell</mat-option>
</mat-select>
</mat-form-field>
</div>
@ -41,11 +41,11 @@
autocorrect="off"
formControlName="searchSymbol"
matInput
[matAutocomplete]="autocomplete"
[matAutocomplete]="symbolAutocomplete"
(blur)="onBlurSymbol()"
/>
<mat-autocomplete
#autocomplete="matAutocomplete"
#symbolAutocomplete="matAutocomplete"
[displayWith]="displayFn"
(optionSelected)="onUpdateSymbol($event)"
>
@ -109,7 +109,15 @@
</div>
<div>
<mat-form-field appearance="outline" class="w-100">
<mat-label i18n>Unit Price</mat-label>
<mat-label
><ng-container [ngSwitch]="activityForm.controls['type']?.value">
<ng-container *ngSwitchCase="'DIVIDEND'" i18n
>Dividend</ng-container
>
<ng-container *ngSwitchCase="'ITEM'" i18n>Value</ng-container>
<ng-container *ngSwitchDefault i18n>Unit Price</ng-container>
</ng-container>
</mat-label>
<input formControlName="unitPrice" matInput type="number" />
<span class="ml-2" matSuffix
>{{ activityForm.controls['currency'].value }}</span
@ -194,16 +202,38 @@
</mat-select>
</mat-form-field>
</div>
<div
[ngClass]="{ 'd-none': activityForm.controls['tags']?.value?.length <= 0 }"
>
<div [ngClass]="{ 'd-none': tags?.length <= 0 }">
<mat-form-field appearance="outline" class="w-100">
<mat-label i18n>Tags</mat-label>
<mat-chip-list>
<mat-chip *ngFor="let tag of activityForm.controls['tags']?.value">
<mat-chip-list #tagsChipList>
<mat-chip
*ngFor="let tag of activityForm.controls['tags']?.value"
matChipRemove
[removable]="true"
(removed)="onRemoveTag(tag)"
>
{{ tag.name }}
<ion-icon class="ml-2" matPrefix name="close-outline"></ion-icon>
</mat-chip>
<input
#tagInput
name="close-outline"
[matAutocomplete]="autocompleteTags"
[matChipInputFor]="tagsChipList"
[matChipInputSeparatorKeyCodes]="separatorKeysCodes"
/>
</mat-chip-list>
<mat-autocomplete
#autocompleteTags="matAutocomplete"
(optionSelected)="onAddTag($event)"
>
<mat-option
*ngFor="let tag of filteredTagsObservable | async"
[value]="tag.id"
>
{{ tag.name }}
</mat-option>
</mat-autocomplete>
</mat-form-field>
</div>
</div>

View File

@ -20,6 +20,11 @@
}
}
.mat-chip {
cursor: pointer;
min-height: 1.5rem !important;
}
.mat-form-field-appearance-outline {
::ng-deep {
.mat-form-field-suffix {

View File

@ -7,6 +7,7 @@ import {
} from '@angular/core';
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 { ImportActivitiesService } from '@ghostfolio/client/services/import-activities.service';
import { isArray } from 'lodash';
import { Subject } from 'rxjs';
@ -20,8 +21,11 @@ import { ImportActivitiesDialogParams } from './interfaces/interfaces';
templateUrl: 'import-activities-dialog.html'
})
export class ImportActivitiesDialog implements OnDestroy {
public activities: Activity[] = [];
public details: any[] = [];
public errorMessages: string[] = [];
public isFileSelected = false;
public selectedActivities: Activity[] = [];
private unsubscribeSubject = new Subject<void>();
@ -39,13 +43,47 @@ export class ImportActivitiesDialog implements OnDestroy {
this.dialogRef.close();
}
public onImport() {
public async onImportActivities() {
try {
this.snackBar.open('⏳ ' + $localize`Importing data...`);
await this.importActivitiesService.importSelectedActivities(
this.selectedActivities
);
this.snackBar.open(
'✅ ' + $localize`Import has been completed`,
undefined,
{
duration: 3000
}
);
} catch (error) {
this.snackBar.open(
$localize`Oops! Something went wrong.` +
' ' +
$localize`Please try again later.`,
$localize`Okay`,
{ duration: 3000 }
);
} finally {
this.dialogRef.close();
}
}
public onReset() {
this.details = [];
this.errorMessages = [];
this.isFileSelected = false;
}
public onSelectFile() {
const input = document.createElement('input');
input.accept = 'application/JSON, .csv';
input.type = 'file';
input.onchange = (event) => {
this.snackBar.open('⏳ ' + $localize`Importing data...`);
this.snackBar.open('⏳ ' + $localize`Validating data...`);
// Getting the file reference
const file = (event.target as HTMLInputElement).files[0];
@ -80,11 +118,10 @@ export class ImportActivitiesDialog implements OnDestroy {
}
try {
await this.importActivitiesService.importJson({
content: content.activities
this.activities = await this.importActivitiesService.importJson({
content: content.activities,
isDryRun: true
});
this.handleImportSuccess();
} catch (error) {
console.error(error);
this.handleImportError({ error, activities: content.activities });
@ -93,12 +130,11 @@ export class ImportActivitiesDialog implements OnDestroy {
return;
} else if (file.name.endsWith('.csv')) {
try {
await this.importActivitiesService.importCsv({
this.activities = await this.importActivitiesService.importCsv({
fileContent,
isDryRun: true,
userAccounts: this.data.user.accounts
});
this.handleImportSuccess();
} catch (error) {
console.error(error);
this.handleImportError({
@ -119,6 +155,10 @@ export class ImportActivitiesDialog implements OnDestroy {
activities: [],
error: { error: { message: ['Unexpected format'] } }
});
} finally {
this.isFileSelected = true;
this.snackBar.dismiss();
this.changeDetectorRef.markForCheck();
}
};
};
@ -126,9 +166,8 @@ export class ImportActivitiesDialog implements OnDestroy {
input.click();
}
public onReset() {
this.details = [];
this.errorMessages = [];
public updateSelection(data: Activity[]) {
this.selectedActivities = data;
}
public ngOnDestroy() {
@ -143,8 +182,6 @@ export class ImportActivitiesDialog implements OnDestroy {
activities: any[];
error: any;
}) {
this.snackBar.dismiss();
this.errorMessages = error?.error?.message;
for (const message of this.errorMessages) {
@ -161,16 +198,4 @@ export class ImportActivitiesDialog implements OnDestroy {
this.changeDetectorRef.markForCheck();
}
private handleImportSuccess() {
this.snackBar.open(
'✅ ' + $localize`Import has been completed`,
undefined,
{
duration: 3000
}
);
this.dialogRef.close();
}
}

View File

@ -6,13 +6,13 @@
></gf-dialog-header>
<div class="flex-grow-1" mat-dialog-content>
<ng-container *ngIf="errorMessages.length === 0">
<ng-container *ngIf="!isFileSelected">
<div class="d-flex justify-content-center flex-column">
<button
class="py-3"
color="primary"
mat-stroked-button
(click)="onImport()"
(click)="onSelectFile()"
>
<ion-icon class="mr-2" name="cloud-upload-outline"></ion-icon>
<span i18n>Choose File</span>
@ -33,37 +33,68 @@
</p>
</div>
</ng-container>
<ng-container *ngIf="errorMessages.length > 0">
<mat-accordion displayMode="flat">
<mat-expansion-panel
*ngFor="let message of errorMessages; let i = index"
[disabled]="!details[i]"
>
<mat-expansion-panel-header class="pl-1">
<mat-panel-title>
<div class="d-flex">
<div class="align-items-center d-flex mr-2">
<ion-icon name="warning-outline"></ion-icon>
<ng-container *ngIf="isFileSelected">
<ng-container *ngIf="errorMessages.length === 0; else errorMessage">
<gf-activities-table
[activities]="activities"
[baseCurrency]="data?.user?.settings?.baseCurrency"
[deviceType]="data?.deviceType"
[hasPermissionToCreateActivity]="false"
[hasPermissionToExportActivities]="false"
[hasPermissionToFilter]="false"
[hasPermissionToImportActivities]="false"
[hasPermissionToOpenDetails]="false"
[locale]="data?.user?.settings?.locale"
[showActions]="false"
[showCheckbox]="true"
[showSymbolColumn]="false"
(selectedActivities)="updateSelection($event)"
></gf-activities-table>
</ng-container>
<ng-template #errorMessage>
<mat-accordion displayMode="flat">
<mat-expansion-panel
*ngFor="let message of errorMessages; let i = index"
[disabled]="!details[i]"
>
<mat-expansion-panel-header class="pl-1">
<mat-panel-title>
<div class="d-flex">
<div class="align-items-center d-flex mr-2">
<ion-icon name="warning-outline"></ion-icon>
</div>
<div>{{ message }}</div>
</div>
<div>{{ message }}</div>
</div>
</mat-panel-title>
</mat-expansion-panel-header>
<pre
*ngIf="details[i]"
class="m-0"
><code>{{ details[i] | json }}</code></pre>
</mat-expansion-panel>
</mat-accordion>
<div class="mt-2">
<button mat-button (click)="onReset()">
<ion-icon class="mr-2" name="arrow-back-outline"></ion-icon>
<span i18n>Back</span>
</button>
</div>
</mat-panel-title>
</mat-expansion-panel-header>
<pre
*ngIf="details[i]"
class="m-0"
><code>{{ details[i] | json }}</code></pre>
</mat-expansion-panel>
</mat-accordion>
<div class="mt-2">
<button mat-button (click)="onReset()">
<ion-icon class="mr-2" name="arrow-back-outline"></ion-icon>
<span i18n>Back</span>
</button>
</div>
</ng-template>
</ng-container>
</div>
<div *ngIf="isFileSelected" class="justify-content-end" mat-dialog-actions>
<button i18n mat-button (click)="onCancel()">Cancel</button>
<button
color="primary"
mat-flat-button
[disabled]="!selectedActivities?.length"
(click)="onImportActivities()"
>
<ng-container i18n>Import</ng-container>
</button>
</div>
<gf-dialog-footer
mat-dialog-actions
[deviceType]="data.deviceType"

View File

@ -5,6 +5,7 @@ import { MatDialogModule } from '@angular/material/dialog';
import { MatExpansionModule } from '@angular/material/expansion';
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';
import { ImportActivitiesDialog } from './import-activities-dialog.component';
@ -12,6 +13,7 @@ import { ImportActivitiesDialog } from './import-activities-dialog.component';
declarations: [ImportActivitiesDialog],
imports: [
CommonModule,
GfActivitiesTableModule,
GfDialogFooterModule,
GfDialogHeaderModule,
MatButtonModule,

View File

@ -22,7 +22,7 @@ import { Market, ToggleOption } from '@ghostfolio/common/types';
import { translate } from '@ghostfolio/ui/i18n';
import { Account, AssetClass, DataSource } from '@prisma/client';
import { DeviceDetectorService } from 'ngx-device-detector';
import { Subject, Subscription } from 'rxjs';
import { Subject } from 'rxjs';
import { distinctUntilChanged, switchMap, takeUntil } from 'rxjs/operators';
@Component({
@ -71,7 +71,6 @@ export class AllocationsPageComponent implements OnDestroy, OnInit {
| 'value'
>;
};
public routeQueryParams: Subscription;
public sectors: {
[name: string]: { name: string; value: number };
};
@ -98,7 +97,7 @@ export class AllocationsPageComponent implements OnDestroy, OnInit {
private router: Router,
private userService: UserService
) {
this.routeQueryParams = route.queryParams
route.queryParams
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe((params) => {
if (params['accountId'] && params['accountDetailDialog']) {

View File

@ -1,4 +1,8 @@
import { ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { ActivatedRoute, Router } from '@angular/router';
import { PositionDetailDialogParams } from '@ghostfolio/client/components/position/position-detail-dialog/interfaces/interfaces';
import { PositionDetailDialog } from '@ghostfolio/client/components/position/position-detail-dialog/position-detail-dialog.component';
import { ToggleComponent } from '@ghostfolio/client/components/toggle/toggle.component';
import { DataService } from '@ghostfolio/client/services/data.service';
import { ImpersonationStorageService } from '@ghostfolio/client/services/impersonation-storage.service';
@ -9,8 +13,9 @@ import {
User
} from '@ghostfolio/common/interfaces';
import { InvestmentItem } from '@ghostfolio/common/interfaces/investment-item.interface';
import { hasPermission, permissions } from '@ghostfolio/common/permissions';
import { DateRange, GroupBy, ToggleOption } from '@ghostfolio/common/types';
import { SymbolProfile } from '@prisma/client';
import { DataSource, SymbolProfile } from '@prisma/client';
import { differenceInDays } from 'date-fns';
import { sortBy } from 'lodash';
import { DeviceDetectorService } from 'ngx-device-detector';
@ -54,12 +59,30 @@ export class AnalysisPageComponent implements OnDestroy, OnInit {
public constructor(
private changeDetectorRef: ChangeDetectorRef,
private dataService: DataService,
private dialog: MatDialog,
private deviceService: DeviceDetectorService,
private impersonationStorageService: ImpersonationStorageService,
private route: ActivatedRoute,
private router: Router,
private userService: UserService
) {
const { benchmarks } = this.dataService.fetchInfo();
this.benchmarks = benchmarks;
route.queryParams
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe((params) => {
if (
params['dataSource'] &&
params['positionDetailDialog'] &&
params['symbol']
) {
this.openPositionDialog({
dataSource: params['dataSource'],
symbol: params['symbol']
});
}
});
}
public ngOnInit() {
@ -128,6 +151,47 @@ export class AnalysisPageComponent implements OnDestroy, OnInit {
this.unsubscribeSubject.complete();
}
private openPositionDialog({
dataSource,
symbol
}: {
dataSource: DataSource;
symbol: string;
}) {
this.userService
.get()
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe((user) => {
this.user = user;
const dialogRef = this.dialog.open(PositionDetailDialog, {
autoFocus: false,
data: <PositionDetailDialogParams>{
dataSource,
symbol,
baseCurrency: this.user?.settings?.baseCurrency,
colorScheme: this.user?.settings?.colorScheme,
deviceType: this.deviceType,
hasImpersonationId: this.hasImpersonationId,
hasPermissionToReportDataGlitch: hasPermission(
this.user?.permissions,
permissions.reportDataGlitch
),
locale: this.user?.settings?.locale
},
height: this.deviceType === 'mobile' ? '97.5vh' : '80vh',
width: this.deviceType === 'mobile' ? '100vw' : '50rem'
});
dialogRef
.afterClosed()
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe(() => {
this.router.navigate(['.'], { relativeTo: this.route });
});
});
}
private update() {
this.isLoadingBenchmarkComparator = true;
this.isLoadingInvestmentChart = true;

View File

@ -35,20 +35,30 @@
>
</mat-card-header>
<mat-card-content>
<div *ngFor="let position of top3; let i = index" class="d-flex py-1">
<div class="flex-grow-1 mr-2 text-truncate">
{{ i + 1 }}. {{ position.name }}
</div>
<div class="d-flex justify-content-end">
<gf-value
class="justify-content-end"
position="end"
[colorizeSign]="true"
[isPercent]="true"
[locale]="user?.settings?.locale"
[value]="position.netPerformancePercentage"
></gf-value>
</div>
<div *ngFor="let position of top3; let i = index" class="py-1">
<a
class="d-flex"
[queryParams]="{
dataSource: position.dataSource,
positionDetailDialog: true,
symbol: position.symbol
}"
[routerLink]="[]"
>
<div class="flex-grow-1 mr-2 text-truncate">
{{ i + 1 }}. {{ position.name }}
</div>
<div class="d-flex justify-content-end">
<gf-value
class="justify-content-end"
position="end"
[colorizeSign]="true"
[isPercent]="true"
[locale]="user?.settings?.locale"
[value]="position.netPerformancePercentage"
></gf-value>
</div>
</a>
</div>
<div>
<ngx-skeleton-loader
@ -71,23 +81,30 @@
>
</mat-card-header>
<mat-card-content>
<div
*ngFor="let position of bottom3; let i = index"
class="d-flex py-1"
>
<div class="flex-grow-1 mr-2 text-truncate">
{{ i + 1 }}. {{ position.name }}
</div>
<div class="d-flex justify-content-end">
<gf-value
class="justify-content-end"
position="end"
[colorizeSign]="true"
[isPercent]="true"
[locale]="user?.settings?.locale"
[value]="position.netPerformancePercentage"
></gf-value>
</div>
<div *ngFor="let position of bottom3; let i = index" class="py-1">
<a
class="d-flex"
[queryParams]="{
dataSource: position.dataSource,
positionDetailDialog: true,
symbol: position.symbol
}"
[routerLink]="[]"
>
<div class="flex-grow-1 mr-2 text-truncate">
{{ i + 1 }}. {{ position.name }}
</div>
<div class="d-flex justify-content-end">
<gf-value
class="justify-content-end"
position="end"
[colorizeSign]="true"
[isPercent]="true"
[locale]="user?.settings?.locale"
[value]="position.netPerformancePercentage"
></gf-value>
</div>
</a>
</div>
<div>
<ngx-skeleton-loader

View File

@ -16,7 +16,7 @@ import { hasPermission, permissions } from '@ghostfolio/common/permissions';
import { translate } from '@ghostfolio/ui/i18n';
import { AssetClass, DataSource } from '@prisma/client';
import { DeviceDetectorService } from 'ngx-device-detector';
import { Subject, Subscription } from 'rxjs';
import { Subject } from 'rxjs';
import { distinctUntilChanged, switchMap, takeUntil } from 'rxjs/operators';
@Component({
@ -36,7 +36,6 @@ export class HoldingsPageComponent implements OnDestroy, OnInit {
public placeholder = '';
public portfolioDetails: PortfolioDetails;
public positionsArray: PortfolioPosition[];
public routeQueryParams: Subscription;
public user: User;
private unsubscribeSubject = new Subject<void>();
@ -51,7 +50,7 @@ export class HoldingsPageComponent implements OnDestroy, OnInit {
private router: Router,
private userService: UserService
) {
this.routeQueryParams = route.queryParams
route.queryParams
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe((params) => {
if (

View File

@ -1,8 +1,8 @@
import { CommonModule } from '@angular/common';
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { GfHoldingsTableModule } from '@ghostfolio/ui/holdings-table/holdings-table.module';
import { GfActivitiesFilterModule } from '@ghostfolio/ui/activities-filter/activities-filter.module';
import { GfHoldingsTableModule } from '@ghostfolio/ui/holdings-table/holdings-table.module';
import { HoldingsPageRoutingModule } from './holdings-page-routing.module';
import { HoldingsPageComponent } from './holdings-page.component';

View File

@ -2,8 +2,8 @@ import { CommonModule } from '@angular/common';
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { MatCardModule } from '@angular/material/card';
import { GfHoldingsTableModule } from '@ghostfolio/ui/holdings-table/holdings-table.module';
import { GfWorldMapChartModule } from '@ghostfolio/client/components/world-map-chart/world-map-chart.module';
import { GfHoldingsTableModule } from '@ghostfolio/ui/holdings-table/holdings-table.module';
import { GfPortfolioProportionChartModule } from '@ghostfolio/ui/portfolio-proportion-chart/portfolio-proportion-chart.module';
import { GfValueModule } from '@ghostfolio/ui/value';

View File

@ -1,6 +1,7 @@
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { CreateOrderDto } from '@ghostfolio/api/app/order/create-order.dto';
import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface';
import { Account, DataSource, Type } from '@prisma/client';
import { isMatch, parse, parseISO } from 'date-fns';
import { isFinite } from 'lodash';
@ -26,11 +27,13 @@ export class ImportActivitiesService {
public async importCsv({
fileContent,
isDryRun = false,
userAccounts
}: {
fileContent: string;
isDryRun?: boolean;
userAccounts: Account[];
}) {
}): Promise<Activity[]> {
const content = csvToJson(fileContent, {
dynamicTyping: true,
header: true,
@ -52,14 +55,23 @@ export class ImportActivitiesService {
});
}
await this.importJson({ content: activities });
return await this.importJson({ isDryRun, content: activities });
}
public importJson({ content }: { content: CreateOrderDto[] }): Promise<void> {
public importJson({
content,
isDryRun = false
}: {
content: CreateOrderDto[];
isDryRun?: boolean;
}): Promise<Activity[]> {
return new Promise((resolve, reject) => {
this.postImport({
activities: content
})
this.postImport(
{
activities: content
},
isDryRun
)
.pipe(
catchError((error) => {
reject(error);
@ -67,13 +79,42 @@ export class ImportActivitiesService {
})
)
.subscribe({
next: () => {
resolve();
next: (data) => {
resolve(data.activities);
}
});
});
}
public importSelectedActivities(
selectedActivities: Activity[]
): Promise<Activity[]> {
const importData: CreateOrderDto[] = [];
for (const activity of selectedActivities) {
importData.push(this.convertToCreateOrderDto(activity));
}
return this.importJson({ content: importData });
}
private convertToCreateOrderDto({
date,
fee,
quantity,
SymbolProfile,
type,
unitPrice
}: Activity): CreateOrderDto {
return {
fee,
quantity,
type,
unitPrice,
currency: SymbolProfile.currency,
date: date.toString(),
symbol: SymbolProfile.symbol
};
}
private lowercaseKeys(aObject: any) {
return Object.keys(aObject).reduce((acc, key) => {
acc[key.toLowerCase()] = aObject[key];
@ -301,7 +342,13 @@ export class ImportActivitiesService {
};
}
private postImport(aImportData: { activities: CreateOrderDto[] }) {
return this.http.post<void>('/api/v1/import', aImportData);
private postImport(
aImportData: { activities: CreateOrderDto[] },
aIsDryRun = false
) {
return this.http.post<{ activities: Activity[] }>(
`/api/v1/import?dryRun=${aIsDryRun}`,
aImportData
);
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 195 KiB

View File

@ -6,78 +6,82 @@
http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">
<url>
<loc>https://ghostfol.io</loc>
<lastmod>2022-11-10T00:00:00+00:00</lastmod>
<lastmod>2022-12-26T00:00:00+00:00</lastmod>
</url>
<url>
<loc>https://ghostfol.io/de/blog/2021/07/hallo-ghostfolio</loc>
<lastmod>2022-11-10T00:00:00+00:00</lastmod>
<lastmod>2022-12-26T00:00:00+00:00</lastmod>
</url>
<url>
<loc>https://ghostfol.io/en/about</loc>
<lastmod>2022-11-10T00:00:00+00:00</lastmod>
<lastmod>2022-12-26T00:00:00+00:00</lastmod>
</url>
<url>
<loc>https://ghostfol.io/en/about/changelog</loc>
<lastmod>2022-11-10T00:00:00+00:00</lastmod>
<lastmod>2022-12-26T00:00:00+00:00</lastmod>
</url>
<url>
<loc>https://ghostfol.io/en/blog</loc>
<lastmod>2022-11-10T00:00:00+00:00</lastmod>
<lastmod>2022-12-26T00:00:00+00:00</lastmod>
</url>
<url>
<loc>https://ghostfol.io/en/blog/2021/07/hello-ghostfolio</loc>
<lastmod>2022-11-10T00:00:00+00:00</lastmod>
<lastmod>2022-12-26T00:00:00+00:00</lastmod>
</url>
<url>
<loc>https://ghostfol.io/en/blog/2022/01/ghostfolio-first-months-in-open-source</loc>
<lastmod>2022-11-10T00:00:00+00:00</lastmod>
<lastmod>2022-12-26T00:00:00+00:00</lastmod>
</url>
<url>
<loc>https://ghostfol.io/en/blog/2022/07/ghostfolio-meets-internet-identity</loc>
<lastmod>2022-11-10T00:00:00+00:00</lastmod>
<lastmod>2022-12-26T00: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-11-10T00:00:00+00:00</lastmod>
<lastmod>2022-12-26T00:00:00+00:00</lastmod>
</url>
<url>
<loc>https://ghostfol.io/en/blog/2022/08/500-stars-on-github</loc>
<lastmod>2022-11-10T00:00:00+00:00</lastmod>
<lastmod>2022-12-26T00:00:00+00:00</lastmod>
</url>
<url>
<loc>https://ghostfol.io/en/blog/2022/10/hacktoberfest-2022</loc>
<lastmod>2022-11-10T00:00:00+00:00</lastmod>
<lastmod>2022-12-26T00:00:00+00:00</lastmod>
</url>
<url>
<loc>https://ghostfol.io/en/blog/2022/11/black-friday-2022</loc>
<lastmod>2022-11-10T00:00:00+00:00</lastmod>
<lastmod>2022-12-26T00: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>
</url>
<url>
<loc>https://ghostfol.io/en/demo</loc>
<lastmod>2022-11-10T00:00:00+00:00</lastmod>
<lastmod>2022-12-26T00:00:00+00:00</lastmod>
</url>
<url>
<loc>https://ghostfol.io/en/faq</loc>
<lastmod>2022-11-10T00:00:00+00:00</lastmod>
<lastmod>2022-12-26T00:00:00+00:00</lastmod>
</url>
<url>
<loc>https://ghostfol.io/en/features</loc>
<lastmod>2022-11-10T00:00:00+00:00</lastmod>
<lastmod>2022-12-26T00:00:00+00:00</lastmod>
</url>
<url>
<loc>https://ghostfol.io/en/markets</loc>
<lastmod>2022-11-10T00:00:00+00:00</lastmod>
<lastmod>2022-12-26T00:00:00+00:00</lastmod>
</url>
<url>
<loc>https://ghostfol.io/en/pricing</loc>
<lastmod>2022-11-10T00:00:00+00:00</lastmod>
<lastmod>2022-12-26T00:00:00+00:00</lastmod>
</url>
<url>
<loc>https://ghostfol.io/en/register</loc>
<lastmod>2022-11-10T00:00:00+00:00</lastmod>
<lastmod>2022-12-26T00:00:00+00:00</lastmod>
</url>
<url>
<loc>https://ghostfol.io/en/resources</loc>
<lastmod>2022-11-10T00:00:00+00:00</lastmod>
<lastmod>2022-12-26T00:00:00+00:00</lastmod>
</url>
</urlset>

View File

@ -1,7 +1,7 @@
<!DOCTYPE html>
<html class="h-100 position-relative" lang="${languageCode}">
<head>
<title>Ghostfolio Open Source Wealth Management Software</title>
<title>${title}</title>
<base href="/" />
<meta charset="utf-8" />
<meta content="yes" name="apple-mobile-web-app-capable" />
@ -20,28 +20,19 @@
name="twitter:description"
/>
<meta content="${rootUrl}/${featureGraphicPath}" name="twitter:image" />
<meta
content="Ghostfolio Open Source Wealth Management Software"
name="twitter:title"
/>
<meta content="${title}" name="twitter:title" />
<meta
content="initial-scale=1, viewport-fit=cover, width=device-width"
name="viewport"
/>
<meta content="#FFFFFF" name="theme-color" />
<meta content="" property="og:description" />
<meta
content="Ghostfolio Open Source Wealth Management Software"
property="og:title"
/>
<meta content="${title}" property="og:title" />
<meta content="website" property="og:type" />
<meta content="${rootUrl}${path}" property="og:url" />
<meta content="${rootUrl}/${featureGraphicPath}" property="og:image" />
<meta content="2022-10-16T00:00:00+00:00" property="og:updated_time" />
<meta
content="Ghostfolio Open Source Wealth Management Software"
property="og:site_name"
/>
<meta content="${currentDate}T00:00:00+00:00" property="og:updated_time" />
<meta content="${title}" property="og:site_name" />
<link
href="../assets/apple-touch-icon.png"

View File

@ -156,6 +156,10 @@
<context context-type="sourcefile">apps/client/src/app/components/accounts-table/accounts-table.component.html</context>
<context context-type="linenumber">182</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>
<context context-type="linenumber">117,118</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/activities-table/activities-table.component.html</context>
<context context-type="linenumber">235</context>
@ -374,7 +378,7 @@
</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>
<context context-type="linenumber">218,222</context>
<context context-type="linenumber">226,230</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.html</context>
@ -402,7 +406,7 @@
</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>
<context context-type="linenumber">225,230</context>
<context context-type="linenumber">233,238</context>
</context-group>
</trans-unit>
<trans-unit id="86c6e9437398addbc04b6570de19b2cb4afe6084" datatype="html">
@ -558,7 +562,7 @@
<target state="translated">Systemmeldung</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-overview/admin-overview.html</context>
<context context-type="linenumber">106</context>
<context context-type="linenumber">122</context>
</context-group>
</trans-unit>
<trans-unit id="657028d5fc9c3da8f2d667b6b15cd0df8b9a3729" datatype="html">
@ -566,7 +570,7 @@
<target state="translated">Systemmeldung setzen</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-overview/admin-overview.html</context>
<context context-type="linenumber">128</context>
<context context-type="linenumber">144</context>
</context-group>
</trans-unit>
<trans-unit id="7fd64c34428887e4cd56d05534b89c100b8544ad" datatype="html">
@ -574,7 +578,7 @@
<target state="translated">Lese-Modus</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-overview/admin-overview.html</context>
<context context-type="linenumber">96</context>
<context context-type="linenumber">112</context>
</context-group>
</trans-unit>
<trans-unit id="e698b03c34b459b1b006d7f0473a49b9fcf5dfc1" datatype="html">
@ -582,7 +586,7 @@
<target state="translated">Gutscheincodes</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-overview/admin-overview.html</context>
<context context-type="linenumber">136</context>
<context context-type="linenumber">152</context>
</context-group>
</trans-unit>
<trans-unit id="f6755cff4957d5c3c89bafce5651f1b6fa2b1fd9" datatype="html">
@ -590,7 +594,7 @@
<target state="translated">Hinzufügen</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-overview/admin-overview.html</context>
<context context-type="linenumber">171</context>
<context context-type="linenumber">187</context>
</context-group>
</trans-unit>
<trans-unit id="e799e6b926557f0098f41888cdf8df868eff3d47" datatype="html">
@ -598,7 +602,7 @@
<target state="translated">Verwaltung</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-overview/admin-overview.html</context>
<context context-type="linenumber">178</context>
<context context-type="linenumber">194</context>
</context-group>
</trans-unit>
<trans-unit id="c7ac907e52a7ce2ac70b1786eb5f403ce306ce1f" datatype="html">
@ -606,7 +610,7 @@
<target state="translated">Cache leeren</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-overview/admin-overview.html</context>
<context context-type="linenumber">182</context>
<context context-type="linenumber">198</context>
</context-group>
</trans-unit>
<trans-unit id="2817099043823177227" datatype="html">
@ -944,6 +948,10 @@
<context context-type="sourcefile">apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html</context>
<context context-type="linenumber">12</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>
<context context-type="linenumber">14,15</context>
</context-group>
</trans-unit>
<trans-unit id="fe708b572beec788b18edd1b5852d63c07dfaead" datatype="html">
<source>Sell</source>
@ -952,6 +960,10 @@
<context context-type="sourcefile">apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html</context>
<context context-type="linenumber">23</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>
<context context-type="linenumber">17,21</context>
</context-group>
</trans-unit>
<trans-unit id="9bbc9e4cebf91162be7d3e324ca5984d576e462c" datatype="html">
<source>Investment</source>
@ -1068,6 +1080,14 @@
<context context-type="sourcefile">apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html</context>
<context context-type="linenumber">214</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>
<context context-type="linenumber">15,17</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>
<context context-type="linenumber">115,117</context>
</context-group>
</trans-unit>
<trans-unit id="6785405835169448749" datatype="html">
<source>Please enter the amount of your emergency fund:</source>
@ -1108,13 +1128,17 @@
<trans-unit id="cafc87479686947e2590b9f588a88040aeaf660b" datatype="html">
<source>Tags</source>
<target state="translated">Tags</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-overview/admin-overview.html</context>
<context context-type="linenumber">92</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>
<context context-type="linenumber">234</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>
<context context-type="linenumber">201,203</context>
<context context-type="linenumber">209,211</context>
</context-group>
</trans-unit>
<trans-unit id="43d544c2e88959f6c59cc4db419528fb0776bd6c" datatype="html">
@ -1738,7 +1762,7 @@
<target state="translated">Zeitstrahl der Investitionen</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.html</context>
<context context-type="linenumber">143</context>
<context context-type="linenumber">160</context>
</context-group>
</trans-unit>
<trans-unit id="6ae1c94f6bad274424f97e9bc8766242c1577447" datatype="html">
@ -1754,7 +1778,7 @@
<target state="translated">Verlierer</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.html</context>
<context context-type="linenumber">70</context>
<context context-type="linenumber">80</context>
</context-group>
</trans-unit>
<trans-unit id="5857197365507636437" datatype="html">
@ -1825,38 +1849,14 @@
<context context-type="linenumber">8,11</context>
</context-group>
</trans-unit>
<trans-unit id="ed4df708b0da9af32f3ba7174729749f6c36f29a" datatype="html">
<source>BUY</source>
<target state="translated">Kauf</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">14,15</context>
</context-group>
</trans-unit>
<trans-unit id="2389486e186b91e335cd9278cfe3af185b2ce0c2" datatype="html">
<source>DIVIDEND</source>
<target state="translated">Dividende</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">15,17</context>
</context-group>
</trans-unit>
<trans-unit id="19288e8ab62dd8d905d5f6dac7a0c244062ab4f5" datatype="html">
<source>ITEM</source>
<target state="translated">Wertsache</target>
<trans-unit id="9bca420227979312de74f0a932a003437410b1ab" datatype="html">
<source>Item</source>
<target state="new">Wertsache</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>
</context-group>
</trans-unit>
<trans-unit id="e14e3acc1ebdb5839aa65787f4ce52558659a9cc" datatype="html">
<source>SELL</source>
<target state="translated">Verkauf</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">17,21</context>
</context-group>
</trans-unit>
<trans-unit id="5ab4d451ff9ce6d18d53360c51e7cd6e91c69555" datatype="html">
<source>Name, symbol or ISIN</source>
<target state="translated">Name, Symbol oder ISIN</target>
@ -1886,7 +1886,7 @@
<target state="translated">Stückpreis</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">112,113</context>
<context context-type="linenumber">118,121</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/activities-table/activities-table.component.html</context>
@ -1898,11 +1898,11 @@
<target state="translated">Gebühr</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">131,132</context>
<context context-type="linenumber">139,140</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>
<context context-type="linenumber">148,149</context>
<context context-type="linenumber">156,157</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/activities-table/activities-table.component.html</context>
@ -1918,7 +1918,7 @@
</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>
<context context-type="linenumber">157,160</context>
<context context-type="linenumber">165,168</context>
</context-group>
</trans-unit>
<trans-unit id="584c9433705e9bfdd2e7a9f0192690f453d36196" datatype="html">
@ -1938,7 +1938,7 @@
</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>
<context context-type="linenumber">171,173</context>
<context context-type="linenumber">179,181</context>
</context-group>
</trans-unit>
<trans-unit id="2309808536212982229" datatype="html">
@ -2322,7 +2322,7 @@
</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>
<context context-type="linenumber">186,188</context>
<context context-type="linenumber">194,196</context>
</context-group>
</trans-unit>
<trans-unit id="936788a5ab949fe0d70098ba051ac7a44999ff08" datatype="html">
@ -2422,7 +2422,7 @@
<target state="translated">Monatlich</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">44</context>
<context context-type="linenumber">49</context>
</context-group>
</trans-unit>
<trans-unit id="5213771062241898526" datatype="html">
@ -2430,11 +2430,11 @@
<target state="translated">Einlage</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">38</context>
<context context-type="linenumber">43</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">48</context>
<context context-type="linenumber">53</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/fire-calculator/fire-calculator.component.ts</context>
@ -2502,11 +2502,11 @@
<target state="translated">Filtern nach Konto oder Tag...</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/allocations/allocations-page.component.ts</context>
<context context-type="linenumber">137</context>
<context context-type="linenumber">136</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/holdings/holdings-page.component.ts</context>
<context context-type="linenumber">88</context>
<context context-type="linenumber">87</context>
</context-group>
</trans-unit>
<trans-unit id="303469635941752458" datatype="html">
@ -2550,7 +2550,7 @@
<target state="translated">Benchmarks</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-overview/admin-overview.html</context>
<context context-type="linenumber">76</context>
<context context-type="linenumber">79</context>
</context-group>
</trans-unit>
<trans-unit id="44fcf77e86dc038202ebad6b46d1d833d60d781b" datatype="html">
@ -2654,7 +2654,7 @@
<target state="translated">Portfolio Wertentwicklung</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.html</context>
<context context-type="linenumber">113</context>
<context context-type="linenumber">130</context>
</context-group>
</trans-unit>
<trans-unit id="8192718423057883427" datatype="html">
@ -2942,7 +2942,7 @@
<target state="translated">Zeitstrahl der Dividenden</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.html</context>
<context context-type="linenumber">180</context>
<context context-type="linenumber">197</context>
</context-group>
</trans-unit>
<trans-unit id="7765499580020598783" datatype="html">
@ -2950,7 +2950,7 @@
<target state="translated">Dividenden</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">34</context>
<context context-type="linenumber">39</context>
</context-group>
</trans-unit>
<trans-unit id="7608037008789240367" datatype="html">
@ -2966,7 +2966,7 @@
<target state="translated">Benutzer Registrierung</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-overview/admin-overview.html</context>
<context context-type="linenumber">86</context>
<context context-type="linenumber">102</context>
</context-group>
</trans-unit>
</body>

View File

@ -157,6 +157,10 @@
<context context-type="sourcefile">apps/client/src/app/components/accounts-table/accounts-table.component.html</context>
<context context-type="linenumber">182</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>
<context context-type="linenumber">117,118</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/activities-table/activities-table.component.html</context>
<context context-type="linenumber">235</context>
@ -375,7 +379,7 @@
</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>
<context context-type="linenumber">218,222</context>
<context context-type="linenumber">226,230</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.html</context>
@ -403,7 +407,7 @@
</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>
<context context-type="linenumber">225,230</context>
<context context-type="linenumber">233,238</context>
</context-group>
</trans-unit>
<trans-unit id="86c6e9437398addbc04b6570de19b2cb4afe6084" datatype="html">
@ -559,7 +563,7 @@
<target state="translated">Mensaje del sistema</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-overview/admin-overview.html</context>
<context context-type="linenumber">106</context>
<context context-type="linenumber">122</context>
</context-group>
</trans-unit>
<trans-unit id="657028d5fc9c3da8f2d667b6b15cd0df8b9a3729" datatype="html">
@ -567,7 +571,7 @@
<target state="translated">Establecer mensaje</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-overview/admin-overview.html</context>
<context context-type="linenumber">128</context>
<context context-type="linenumber">144</context>
</context-group>
</trans-unit>
<trans-unit id="7fd64c34428887e4cd56d05534b89c100b8544ad" datatype="html">
@ -575,7 +579,7 @@
<target state="translated">Modo de solo lectura</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-overview/admin-overview.html</context>
<context context-type="linenumber">96</context>
<context context-type="linenumber">112</context>
</context-group>
</trans-unit>
<trans-unit id="e698b03c34b459b1b006d7f0473a49b9fcf5dfc1" datatype="html">
@ -583,7 +587,7 @@
<target state="translated">Cupones</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-overview/admin-overview.html</context>
<context context-type="linenumber">136</context>
<context context-type="linenumber">152</context>
</context-group>
</trans-unit>
<trans-unit id="f6755cff4957d5c3c89bafce5651f1b6fa2b1fd9" datatype="html">
@ -591,7 +595,7 @@
<target state="translated">Añadir</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-overview/admin-overview.html</context>
<context context-type="linenumber">171</context>
<context context-type="linenumber">187</context>
</context-group>
</trans-unit>
<trans-unit id="e799e6b926557f0098f41888cdf8df868eff3d47" datatype="html">
@ -599,7 +603,7 @@
<target state="translated">Tareas domésticas</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-overview/admin-overview.html</context>
<context context-type="linenumber">178</context>
<context context-type="linenumber">194</context>
</context-group>
</trans-unit>
<trans-unit id="c7ac907e52a7ce2ac70b1786eb5f403ce306ce1f" datatype="html">
@ -607,7 +611,7 @@
<target state="translated">Limpiar caché</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-overview/admin-overview.html</context>
<context context-type="linenumber">182</context>
<context context-type="linenumber">198</context>
</context-group>
</trans-unit>
<trans-unit id="2817099043823177227" datatype="html">
@ -945,6 +949,10 @@
<context context-type="sourcefile">apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html</context>
<context context-type="linenumber">12</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>
<context context-type="linenumber">14,15</context>
</context-group>
</trans-unit>
<trans-unit id="fe708b572beec788b18edd1b5852d63c07dfaead" datatype="html">
<source>Sell</source>
@ -953,6 +961,10 @@
<context context-type="sourcefile">apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html</context>
<context context-type="linenumber">23</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>
<context context-type="linenumber">17,21</context>
</context-group>
</trans-unit>
<trans-unit id="9bbc9e4cebf91162be7d3e324ca5984d576e462c" datatype="html">
<source>Investment</source>
@ -1069,6 +1081,14 @@
<context context-type="sourcefile">apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html</context>
<context context-type="linenumber">214</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>
<context context-type="linenumber">15,17</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>
<context context-type="linenumber">115,117</context>
</context-group>
</trans-unit>
<trans-unit id="6785405835169448749" datatype="html">
<source>Please enter the amount of your emergency fund:</source>
@ -1109,13 +1129,17 @@
<trans-unit id="cafc87479686947e2590b9f588a88040aeaf660b" datatype="html">
<source>Tags</source>
<target state="translated">Etiquetas</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-overview/admin-overview.html</context>
<context context-type="linenumber">92</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>
<context context-type="linenumber">234</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>
<context context-type="linenumber">201,203</context>
<context context-type="linenumber">209,211</context>
</context-group>
</trans-unit>
<trans-unit id="43d544c2e88959f6c59cc4db419528fb0776bd6c" datatype="html">
@ -1739,7 +1763,7 @@
<target state="translated">Cronología de la inversión</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.html</context>
<context context-type="linenumber">143</context>
<context context-type="linenumber">160</context>
</context-group>
</trans-unit>
<trans-unit id="6ae1c94f6bad274424f97e9bc8766242c1577447" datatype="html">
@ -1755,7 +1779,7 @@
<target state="translated">Lo peor</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.html</context>
<context context-type="linenumber">70</context>
<context context-type="linenumber">80</context>
</context-group>
</trans-unit>
<trans-unit id="5857197365507636437" datatype="html">
@ -1826,38 +1850,14 @@
<context context-type="linenumber">8,11</context>
</context-group>
</trans-unit>
<trans-unit id="ed4df708b0da9af32f3ba7174729749f6c36f29a" datatype="html">
<source>BUY</source>
<target state="translated">COMPRA</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">14,15</context>
</context-group>
</trans-unit>
<trans-unit id="2389486e186b91e335cd9278cfe3af185b2ce0c2" datatype="html">
<source>DIVIDEND</source>
<target state="translated">DIVIDENDO</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">15,17</context>
</context-group>
</trans-unit>
<trans-unit id="19288e8ab62dd8d905d5f6dac7a0c244062ab4f5" datatype="html">
<source>ITEM</source>
<target state="translated">ARTÍCULO</target>
<trans-unit id="9bca420227979312de74f0a932a003437410b1ab" datatype="html">
<source>Item</source>
<target state="new">ARTÍCULO</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>
</context-group>
</trans-unit>
<trans-unit id="e14e3acc1ebdb5839aa65787f4ce52558659a9cc" datatype="html">
<source>SELL</source>
<target state="translated">VENTA</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">17,21</context>
</context-group>
</trans-unit>
<trans-unit id="5ab4d451ff9ce6d18d53360c51e7cd6e91c69555" datatype="html">
<source>Name, symbol or ISIN</source>
<target state="translated">Nombre, símbolo o ISIN</target>
@ -1887,7 +1887,7 @@
<target state="translated">Precio unitario</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">112,113</context>
<context context-type="linenumber">118,121</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/activities-table/activities-table.component.html</context>
@ -1899,11 +1899,11 @@
<target state="translated">Comisión</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">131,132</context>
<context context-type="linenumber">139,140</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>
<context context-type="linenumber">148,149</context>
<context context-type="linenumber">156,157</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/activities-table/activities-table.component.html</context>
@ -1919,7 +1919,7 @@
</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>
<context context-type="linenumber">157,160</context>
<context context-type="linenumber">165,168</context>
</context-group>
</trans-unit>
<trans-unit id="584c9433705e9bfdd2e7a9f0192690f453d36196" datatype="html">
@ -1939,7 +1939,7 @@
</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>
<context context-type="linenumber">171,173</context>
<context context-type="linenumber">179,181</context>
</context-group>
</trans-unit>
<trans-unit id="2309808536212982229" datatype="html">
@ -2303,7 +2303,7 @@
</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>
<context context-type="linenumber">186,188</context>
<context context-type="linenumber">194,196</context>
</context-group>
</trans-unit>
<trans-unit id="3c5ec7bc638db6f37c402e4afab2084f8763e268" datatype="html">
@ -2431,11 +2431,11 @@
<target state="translated">Depósito</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">38</context>
<context context-type="linenumber">43</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">48</context>
<context context-type="linenumber">53</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/fire-calculator/fire-calculator.component.ts</context>
@ -2455,7 +2455,7 @@
<target state="translated">Mensual</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">44</context>
<context context-type="linenumber">49</context>
</context-group>
</trans-unit>
<trans-unit id="8511b16abcf065252b350d64e337ba2447db3ffb" datatype="html">
@ -2495,11 +2495,11 @@
<target state="translated">Filtrar por cuenta o etiqueta...</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/allocations/allocations-page.component.ts</context>
<context context-type="linenumber">137</context>
<context context-type="linenumber">136</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/holdings/holdings-page.component.ts</context>
<context context-type="linenumber">88</context>
<context context-type="linenumber">87</context>
</context-group>
</trans-unit>
<trans-unit id="4550487415324294802" datatype="html">
@ -2559,7 +2559,7 @@
<target state="translated">Benchmark</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-overview/admin-overview.html</context>
<context context-type="linenumber">76</context>
<context context-type="linenumber">79</context>
</context-group>
</trans-unit>
<trans-unit id="44fcf77e86dc038202ebad6b46d1d833d60d781b" datatype="html">
@ -2655,7 +2655,7 @@
<target state="translated">Evolución cartera</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.html</context>
<context context-type="linenumber">113</context>
<context context-type="linenumber">130</context>
</context-group>
</trans-unit>
<trans-unit id="8192718423057883427" datatype="html">
@ -2943,7 +2943,7 @@
<target state="new">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">34</context>
<context context-type="linenumber">39</context>
</context-group>
</trans-unit>
<trans-unit id="6410cffb96159fcff46d91effc26df0e240bc0e3" datatype="html">
@ -2951,7 +2951,7 @@
<target state="new">Dividend Timeline</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.html</context>
<context context-type="linenumber">180</context>
<context context-type="linenumber">197</context>
</context-group>
</trans-unit>
<trans-unit id="7608037008789240367" datatype="html">
@ -2967,7 +2967,7 @@
<target state="new">User Signup</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-overview/admin-overview.html</context>
<context context-type="linenumber">86</context>
<context context-type="linenumber">102</context>
</context-group>
</trans-unit>
</body>

View File

@ -157,6 +157,10 @@
<context context-type="sourcefile">apps/client/src/app/components/accounts-table/accounts-table.component.html</context>
<context context-type="linenumber">182</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>
<context context-type="linenumber">117,118</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/activities-table/activities-table.component.html</context>
<context context-type="linenumber">235</context>
@ -375,7 +379,7 @@
</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>
<context context-type="linenumber">218,222</context>
<context context-type="linenumber">226,230</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.html</context>
@ -403,7 +407,7 @@
</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>
<context context-type="linenumber">225,230</context>
<context context-type="linenumber">233,238</context>
</context-group>
</trans-unit>
<trans-unit id="86c6e9437398addbc04b6570de19b2cb4afe6084" datatype="html">
@ -559,7 +563,7 @@
<target state="translated">Messaggio di sistema</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-overview/admin-overview.html</context>
<context context-type="linenumber">106</context>
<context context-type="linenumber">122</context>
</context-group>
</trans-unit>
<trans-unit id="657028d5fc9c3da8f2d667b6b15cd0df8b9a3729" datatype="html">
@ -567,7 +571,7 @@
<target state="translated">Imposta messaggio</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-overview/admin-overview.html</context>
<context context-type="linenumber">128</context>
<context context-type="linenumber">144</context>
</context-group>
</trans-unit>
<trans-unit id="7fd64c34428887e4cd56d05534b89c100b8544ad" datatype="html">
@ -575,7 +579,7 @@
<target state="translated">Modalità di sola lettura</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-overview/admin-overview.html</context>
<context context-type="linenumber">96</context>
<context context-type="linenumber">112</context>
</context-group>
</trans-unit>
<trans-unit id="e698b03c34b459b1b006d7f0473a49b9fcf5dfc1" datatype="html">
@ -583,7 +587,7 @@
<target state="translated">Buoni sconto</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-overview/admin-overview.html</context>
<context context-type="linenumber">136</context>
<context context-type="linenumber">152</context>
</context-group>
</trans-unit>
<trans-unit id="f6755cff4957d5c3c89bafce5651f1b6fa2b1fd9" datatype="html">
@ -591,7 +595,7 @@
<target state="translated">Aggiungi</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-overview/admin-overview.html</context>
<context context-type="linenumber">171</context>
<context context-type="linenumber">187</context>
</context-group>
</trans-unit>
<trans-unit id="e799e6b926557f0098f41888cdf8df868eff3d47" datatype="html">
@ -599,7 +603,7 @@
<target state="translated">Bilancio domestico</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-overview/admin-overview.html</context>
<context context-type="linenumber">178</context>
<context context-type="linenumber">194</context>
</context-group>
</trans-unit>
<trans-unit id="c7ac907e52a7ce2ac70b1786eb5f403ce306ce1f" datatype="html">
@ -607,7 +611,7 @@
<target state="translated">Svuota la cache</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-overview/admin-overview.html</context>
<context context-type="linenumber">182</context>
<context context-type="linenumber">198</context>
</context-group>
</trans-unit>
<trans-unit id="2817099043823177227" datatype="html">
@ -945,6 +949,10 @@
<context context-type="sourcefile">apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html</context>
<context context-type="linenumber">12</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>
<context context-type="linenumber">14,15</context>
</context-group>
</trans-unit>
<trans-unit id="fe708b572beec788b18edd1b5852d63c07dfaead" datatype="html">
<source>Sell</source>
@ -953,6 +961,10 @@
<context context-type="sourcefile">apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html</context>
<context context-type="linenumber">23</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>
<context context-type="linenumber">17,21</context>
</context-group>
</trans-unit>
<trans-unit id="9bbc9e4cebf91162be7d3e324ca5984d576e462c" datatype="html">
<source>Investment</source>
@ -1069,6 +1081,14 @@
<context context-type="sourcefile">apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html</context>
<context context-type="linenumber">214</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>
<context context-type="linenumber">15,17</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>
<context context-type="linenumber">115,117</context>
</context-group>
</trans-unit>
<trans-unit id="6785405835169448749" datatype="html">
<source>Please enter the amount of your emergency fund:</source>
@ -1109,13 +1129,17 @@
<trans-unit id="cafc87479686947e2590b9f588a88040aeaf660b" datatype="html">
<source>Tags</source>
<target state="translated">Tag</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-overview/admin-overview.html</context>
<context context-type="linenumber">92</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>
<context context-type="linenumber">234</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>
<context context-type="linenumber">201,203</context>
<context context-type="linenumber">209,211</context>
</context-group>
</trans-unit>
<trans-unit id="43d544c2e88959f6c59cc4db419528fb0776bd6c" datatype="html">
@ -1739,7 +1763,7 @@
<target state="translated">Cronologia degli investimenti</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.html</context>
<context context-type="linenumber">143</context>
<context context-type="linenumber">160</context>
</context-group>
</trans-unit>
<trans-unit id="6ae1c94f6bad274424f97e9bc8766242c1577447" datatype="html">
@ -1755,7 +1779,7 @@
<target state="translated">In basso</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.html</context>
<context context-type="linenumber">70</context>
<context context-type="linenumber">80</context>
</context-group>
</trans-unit>
<trans-unit id="5857197365507636437" datatype="html">
@ -1826,38 +1850,14 @@
<context context-type="linenumber">8,11</context>
</context-group>
</trans-unit>
<trans-unit id="ed4df708b0da9af32f3ba7174729749f6c36f29a" datatype="html">
<source>BUY</source>
<target state="translated">ACQUISTO</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">14,15</context>
</context-group>
</trans-unit>
<trans-unit id="2389486e186b91e335cd9278cfe3af185b2ce0c2" datatype="html">
<source>DIVIDEND</source>
<target state="translated">DIVIDENDO</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">15,17</context>
</context-group>
</trans-unit>
<trans-unit id="19288e8ab62dd8d905d5f6dac7a0c244062ab4f5" datatype="html">
<source>ITEM</source>
<target state="translated">ARTICOLO</target>
<trans-unit id="9bca420227979312de74f0a932a003437410b1ab" datatype="html">
<source>Item</source>
<target state="new">ARTICOLO</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>
</context-group>
</trans-unit>
<trans-unit id="e14e3acc1ebdb5839aa65787f4ce52558659a9cc" datatype="html">
<source>SELL</source>
<target state="translated">VENDITA</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">17,21</context>
</context-group>
</trans-unit>
<trans-unit id="5ab4d451ff9ce6d18d53360c51e7cd6e91c69555" datatype="html">
<source>Name, symbol or ISIN</source>
<target state="translated">Nome, simbolo o ISIN</target>
@ -1887,7 +1887,7 @@
<target state="translated">Prezzo unitario</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">112,113</context>
<context context-type="linenumber">118,121</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/activities-table/activities-table.component.html</context>
@ -1899,11 +1899,11 @@
<target state="translated">Commissione</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">131,132</context>
<context context-type="linenumber">139,140</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>
<context context-type="linenumber">148,149</context>
<context context-type="linenumber">156,157</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/activities-table/activities-table.component.html</context>
@ -1919,7 +1919,7 @@
</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>
<context context-type="linenumber">157,160</context>
<context context-type="linenumber">165,168</context>
</context-group>
</trans-unit>
<trans-unit id="584c9433705e9bfdd2e7a9f0192690f453d36196" datatype="html">
@ -1939,7 +1939,7 @@
</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>
<context context-type="linenumber">171,173</context>
<context context-type="linenumber">179,181</context>
</context-group>
</trans-unit>
<trans-unit id="2309808536212982229" datatype="html">
@ -2303,7 +2303,7 @@
</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>
<context context-type="linenumber">186,188</context>
<context context-type="linenumber">194,196</context>
</context-group>
</trans-unit>
<trans-unit id="3c5ec7bc638db6f37c402e4afab2084f8763e268" datatype="html">
@ -2431,11 +2431,11 @@
<target state="translated">Deposito</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">38</context>
<context context-type="linenumber">43</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">48</context>
<context context-type="linenumber">53</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/fire-calculator/fire-calculator.component.ts</context>
@ -2455,7 +2455,7 @@
<target state="translated">Mensile</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">44</context>
<context context-type="linenumber">49</context>
</context-group>
</trans-unit>
<trans-unit id="8511b16abcf065252b350d64e337ba2447db3ffb" datatype="html">
@ -2495,11 +2495,11 @@
<target state="translated">Filtra per account o tag...</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/allocations/allocations-page.component.ts</context>
<context context-type="linenumber">137</context>
<context context-type="linenumber">136</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/holdings/holdings-page.component.ts</context>
<context context-type="linenumber">88</context>
<context context-type="linenumber">87</context>
</context-group>
</trans-unit>
<trans-unit id="4550487415324294802" datatype="html">
@ -2559,7 +2559,7 @@
<target state="translated">Benchmark</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-overview/admin-overview.html</context>
<context context-type="linenumber">76</context>
<context context-type="linenumber">79</context>
</context-group>
</trans-unit>
<trans-unit id="44fcf77e86dc038202ebad6b46d1d833d60d781b" datatype="html">
@ -2655,7 +2655,7 @@
<target state="new">Portfolio Evolution</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.html</context>
<context context-type="linenumber">113</context>
<context context-type="linenumber">130</context>
</context-group>
</trans-unit>
<trans-unit id="8192718423057883427" datatype="html">
@ -2943,7 +2943,7 @@
<target state="new">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">34</context>
<context context-type="linenumber">39</context>
</context-group>
</trans-unit>
<trans-unit id="6410cffb96159fcff46d91effc26df0e240bc0e3" datatype="html">
@ -2951,7 +2951,7 @@
<target state="new">Dividend Timeline</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.html</context>
<context context-type="linenumber">180</context>
<context context-type="linenumber">197</context>
</context-group>
</trans-unit>
<trans-unit id="7608037008789240367" datatype="html">
@ -2967,7 +2967,7 @@
<target state="new">User Signup</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-overview/admin-overview.html</context>
<context context-type="linenumber">86</context>
<context context-type="linenumber">102</context>
</context-group>
</trans-unit>
</body>

View File

@ -156,6 +156,10 @@
<context context-type="sourcefile">apps/client/src/app/components/accounts-table/accounts-table.component.html</context>
<context context-type="linenumber">182</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>
<context context-type="linenumber">117,118</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/activities-table/activities-table.component.html</context>
<context context-type="linenumber">235</context>
@ -374,7 +378,7 @@
</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>
<context context-type="linenumber">218,222</context>
<context context-type="linenumber">226,230</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.html</context>
@ -402,7 +406,7 @@
</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>
<context context-type="linenumber">225,230</context>
<context context-type="linenumber">233,238</context>
</context-group>
</trans-unit>
<trans-unit id="86c6e9437398addbc04b6570de19b2cb4afe6084" datatype="html">
@ -558,7 +562,7 @@
<target state="translated">Systeembericht</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-overview/admin-overview.html</context>
<context context-type="linenumber">106</context>
<context context-type="linenumber">122</context>
</context-group>
</trans-unit>
<trans-unit id="657028d5fc9c3da8f2d667b6b15cd0df8b9a3729" datatype="html">
@ -566,7 +570,7 @@
<target state="translated">Bericht instellen</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-overview/admin-overview.html</context>
<context context-type="linenumber">128</context>
<context context-type="linenumber">144</context>
</context-group>
</trans-unit>
<trans-unit id="7fd64c34428887e4cd56d05534b89c100b8544ad" datatype="html">
@ -574,7 +578,7 @@
<target state="translated">Alleen lezen</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-overview/admin-overview.html</context>
<context context-type="linenumber">96</context>
<context context-type="linenumber">112</context>
</context-group>
</trans-unit>
<trans-unit id="e698b03c34b459b1b006d7f0473a49b9fcf5dfc1" datatype="html">
@ -582,7 +586,7 @@
<target state="translated">Coupons</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-overview/admin-overview.html</context>
<context context-type="linenumber">136</context>
<context context-type="linenumber">152</context>
</context-group>
</trans-unit>
<trans-unit id="f6755cff4957d5c3c89bafce5651f1b6fa2b1fd9" datatype="html">
@ -590,7 +594,7 @@
<target state="translated">Toevoegen</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-overview/admin-overview.html</context>
<context context-type="linenumber">171</context>
<context context-type="linenumber">187</context>
</context-group>
</trans-unit>
<trans-unit id="e799e6b926557f0098f41888cdf8df868eff3d47" datatype="html">
@ -598,7 +602,7 @@
<target state="translated">Huishouding</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-overview/admin-overview.html</context>
<context context-type="linenumber">178</context>
<context context-type="linenumber">194</context>
</context-group>
</trans-unit>
<trans-unit id="c7ac907e52a7ce2ac70b1786eb5f403ce306ce1f" datatype="html">
@ -606,7 +610,7 @@
<target state="translated">Cache legen</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-overview/admin-overview.html</context>
<context context-type="linenumber">182</context>
<context context-type="linenumber">198</context>
</context-group>
</trans-unit>
<trans-unit id="2817099043823177227" datatype="html">
@ -944,6 +948,10 @@
<context context-type="sourcefile">apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html</context>
<context context-type="linenumber">12</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>
<context context-type="linenumber">14,15</context>
</context-group>
</trans-unit>
<trans-unit id="fe708b572beec788b18edd1b5852d63c07dfaead" datatype="html">
<source>Sell</source>
@ -952,6 +960,10 @@
<context context-type="sourcefile">apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html</context>
<context context-type="linenumber">23</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>
<context context-type="linenumber">17,21</context>
</context-group>
</trans-unit>
<trans-unit id="9bbc9e4cebf91162be7d3e324ca5984d576e462c" datatype="html">
<source>Investment</source>
@ -1068,6 +1080,14 @@
<context context-type="sourcefile">apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html</context>
<context context-type="linenumber">214</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>
<context context-type="linenumber">15,17</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>
<context context-type="linenumber">115,117</context>
</context-group>
</trans-unit>
<trans-unit id="6785405835169448749" datatype="html">
<source>Please enter the amount of your emergency fund:</source>
@ -1108,13 +1128,17 @@
<trans-unit id="cafc87479686947e2590b9f588a88040aeaf660b" datatype="html">
<source>Tags</source>
<target state="translated">Tags</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-overview/admin-overview.html</context>
<context context-type="linenumber">92</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>
<context context-type="linenumber">234</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>
<context context-type="linenumber">201,203</context>
<context context-type="linenumber">209,211</context>
</context-group>
</trans-unit>
<trans-unit id="43d544c2e88959f6c59cc4db419528fb0776bd6c" datatype="html">
@ -1738,7 +1762,7 @@
<target state="translated">Tijdlijn investeringen</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.html</context>
<context context-type="linenumber">143</context>
<context context-type="linenumber">160</context>
</context-group>
</trans-unit>
<trans-unit id="6ae1c94f6bad274424f97e9bc8766242c1577447" datatype="html">
@ -1754,7 +1778,7 @@
<target state="translated">Onder</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.html</context>
<context context-type="linenumber">70</context>
<context context-type="linenumber">80</context>
</context-group>
</trans-unit>
<trans-unit id="5857197365507636437" datatype="html">
@ -1825,38 +1849,14 @@
<context context-type="linenumber">8,11</context>
</context-group>
</trans-unit>
<trans-unit id="ed4df708b0da9af32f3ba7174729749f6c36f29a" datatype="html">
<source>BUY</source>
<target state="translated">KOPEN</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">14,15</context>
</context-group>
</trans-unit>
<trans-unit id="2389486e186b91e335cd9278cfe3af185b2ce0c2" datatype="html">
<source>DIVIDEND</source>
<target state="translated">DIVIDEND</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">15,17</context>
</context-group>
</trans-unit>
<trans-unit id="19288e8ab62dd8d905d5f6dac7a0c244062ab4f5" datatype="html">
<source>ITEM</source>
<target state="translated">ITEM</target>
<trans-unit id="9bca420227979312de74f0a932a003437410b1ab" datatype="html">
<source>Item</source>
<target state="new">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>
</context-group>
</trans-unit>
<trans-unit id="e14e3acc1ebdb5839aa65787f4ce52558659a9cc" datatype="html">
<source>SELL</source>
<target state="translated">VERKOPEN</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">17,21</context>
</context-group>
</trans-unit>
<trans-unit id="5ab4d451ff9ce6d18d53360c51e7cd6e91c69555" datatype="html">
<source>Name, symbol or ISIN</source>
<target state="translated">Naam, symbool of ISIN</target>
@ -1886,7 +1886,7 @@
<target state="translated">Prijs per eenheid</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">112,113</context>
<context context-type="linenumber">118,121</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/activities-table/activities-table.component.html</context>
@ -1898,11 +1898,11 @@
<target state="translated">Transactiekosten</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">131,132</context>
<context context-type="linenumber">139,140</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>
<context context-type="linenumber">148,149</context>
<context context-type="linenumber">156,157</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/activities-table/activities-table.component.html</context>
@ -1918,7 +1918,7 @@
</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>
<context context-type="linenumber">157,160</context>
<context context-type="linenumber">165,168</context>
</context-group>
</trans-unit>
<trans-unit id="584c9433705e9bfdd2e7a9f0192690f453d36196" datatype="html">
@ -1938,7 +1938,7 @@
</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>
<context context-type="linenumber">171,173</context>
<context context-type="linenumber">179,181</context>
</context-group>
</trans-unit>
<trans-unit id="2309808536212982229" datatype="html">
@ -2302,7 +2302,7 @@
</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>
<context context-type="linenumber">186,188</context>
<context context-type="linenumber">194,196</context>
</context-group>
</trans-unit>
<trans-unit id="3c5ec7bc638db6f37c402e4afab2084f8763e268" datatype="html">
@ -2430,11 +2430,11 @@
<target state="translated">Storting</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">38</context>
<context context-type="linenumber">43</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">48</context>
<context context-type="linenumber">53</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/fire-calculator/fire-calculator.component.ts</context>
@ -2454,7 +2454,7 @@
<target state="translated">Maandelijks</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">44</context>
<context context-type="linenumber">49</context>
</context-group>
</trans-unit>
<trans-unit id="8511b16abcf065252b350d64e337ba2447db3ffb" datatype="html">
@ -2494,11 +2494,11 @@
<target state="translated">Filter op account of tag...</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/allocations/allocations-page.component.ts</context>
<context context-type="linenumber">137</context>
<context context-type="linenumber">136</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/holdings/holdings-page.component.ts</context>
<context context-type="linenumber">88</context>
<context context-type="linenumber">87</context>
</context-group>
</trans-unit>
<trans-unit id="4550487415324294802" datatype="html">
@ -2558,7 +2558,7 @@
<target state="translated">Benchmarks</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-overview/admin-overview.html</context>
<context context-type="linenumber">76</context>
<context context-type="linenumber">79</context>
</context-group>
</trans-unit>
<trans-unit id="44fcf77e86dc038202ebad6b46d1d833d60d781b" datatype="html">
@ -2654,7 +2654,7 @@
<target state="new">Portfolio Evolution</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.html</context>
<context context-type="linenumber">113</context>
<context context-type="linenumber">130</context>
</context-group>
</trans-unit>
<trans-unit id="8192718423057883427" datatype="html">
@ -2942,7 +2942,7 @@
<target state="new">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">34</context>
<context context-type="linenumber">39</context>
</context-group>
</trans-unit>
<trans-unit id="6410cffb96159fcff46d91effc26df0e240bc0e3" datatype="html">
@ -2950,7 +2950,7 @@
<target state="new">Dividend Timeline</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.html</context>
<context context-type="linenumber">180</context>
<context context-type="linenumber">197</context>
</context-group>
</trans-unit>
<trans-unit id="7608037008789240367" datatype="html">
@ -2966,7 +2966,7 @@
<target state="new">User Signup</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-overview/admin-overview.html</context>
<context context-type="linenumber">86</context>
<context context-type="linenumber">102</context>
</context-group>
</trans-unit>
</body>

View File

@ -146,6 +146,10 @@
<context context-type="sourcefile">apps/client/src/app/components/accounts-table/accounts-table.component.html</context>
<context context-type="linenumber">182</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>
<context context-type="linenumber">117,118</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/activities-table/activities-table.component.html</context>
<context context-type="linenumber">235</context>
@ -345,7 +349,7 @@
</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>
<context context-type="linenumber">218,222</context>
<context context-type="linenumber">226,230</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.html</context>
@ -372,7 +376,7 @@
</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>
<context context-type="linenumber">225,230</context>
<context context-type="linenumber">233,238</context>
</context-group>
</trans-unit>
<trans-unit id="86c6e9437398addbc04b6570de19b2cb4afe6084" datatype="html">
@ -511,49 +515,49 @@
<source>System Message</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-overview/admin-overview.html</context>
<context context-type="linenumber">106</context>
<context context-type="linenumber">122</context>
</context-group>
</trans-unit>
<trans-unit id="657028d5fc9c3da8f2d667b6b15cd0df8b9a3729" datatype="html">
<source>Set Message</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-overview/admin-overview.html</context>
<context context-type="linenumber">128</context>
<context context-type="linenumber">144</context>
</context-group>
</trans-unit>
<trans-unit id="7fd64c34428887e4cd56d05534b89c100b8544ad" datatype="html">
<source>Read-only Mode</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-overview/admin-overview.html</context>
<context context-type="linenumber">96</context>
<context context-type="linenumber">112</context>
</context-group>
</trans-unit>
<trans-unit id="e698b03c34b459b1b006d7f0473a49b9fcf5dfc1" datatype="html">
<source>Coupons</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-overview/admin-overview.html</context>
<context context-type="linenumber">136</context>
<context context-type="linenumber">152</context>
</context-group>
</trans-unit>
<trans-unit id="f6755cff4957d5c3c89bafce5651f1b6fa2b1fd9" datatype="html">
<source>Add</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-overview/admin-overview.html</context>
<context context-type="linenumber">171</context>
<context context-type="linenumber">187</context>
</context-group>
</trans-unit>
<trans-unit id="e799e6b926557f0098f41888cdf8df868eff3d47" datatype="html">
<source>Housekeeping</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-overview/admin-overview.html</context>
<context context-type="linenumber">178</context>
<context context-type="linenumber">194</context>
</context-group>
</trans-unit>
<trans-unit id="c7ac907e52a7ce2ac70b1786eb5f403ce306ce1f" datatype="html">
<source>Flush Cache</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-overview/admin-overview.html</context>
<context context-type="linenumber">182</context>
<context context-type="linenumber">198</context>
</context-group>
</trans-unit>
<trans-unit id="2817099043823177227" datatype="html">
@ -859,6 +863,10 @@
<context context-type="sourcefile">apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html</context>
<context context-type="linenumber">12</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>
<context context-type="linenumber">14,15</context>
</context-group>
</trans-unit>
<trans-unit id="fe708b572beec788b18edd1b5852d63c07dfaead" datatype="html">
<source>Sell</source>
@ -866,6 +874,10 @@
<context context-type="sourcefile">apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html</context>
<context context-type="linenumber">23</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>
<context context-type="linenumber">17,21</context>
</context-group>
</trans-unit>
<trans-unit id="9bbc9e4cebf91162be7d3e324ca5984d576e462c" datatype="html">
<source>Investment</source>
@ -968,6 +980,14 @@
<context context-type="sourcefile">apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html</context>
<context context-type="linenumber">214</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>
<context context-type="linenumber">15,17</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>
<context context-type="linenumber">115,117</context>
</context-group>
</trans-unit>
<trans-unit id="6785405835169448749" datatype="html">
<source>Please enter the amount of your emergency fund:</source>
@ -1004,13 +1024,17 @@
</trans-unit>
<trans-unit id="cafc87479686947e2590b9f588a88040aeaf660b" datatype="html">
<source>Tags</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-overview/admin-overview.html</context>
<context context-type="linenumber">92</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>
<context context-type="linenumber">234</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>
<context context-type="linenumber">201,203</context>
<context context-type="linenumber">209,211</context>
</context-group>
</trans-unit>
<trans-unit id="43d544c2e88959f6c59cc4db419528fb0776bd6c" datatype="html">
@ -1563,7 +1587,7 @@
<source>Investment Timeline</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.html</context>
<context context-type="linenumber">143</context>
<context context-type="linenumber">160</context>
</context-group>
</trans-unit>
<trans-unit id="6ae1c94f6bad274424f97e9bc8766242c1577447" datatype="html">
@ -1577,7 +1601,7 @@
<source>Bottom</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.html</context>
<context context-type="linenumber">70</context>
<context context-type="linenumber">80</context>
</context-group>
</trans-unit>
<trans-unit id="5857197365507636437" datatype="html">
@ -1640,34 +1664,13 @@
<context context-type="linenumber">8,11</context>
</context-group>
</trans-unit>
<trans-unit id="ed4df708b0da9af32f3ba7174729749f6c36f29a" datatype="html">
<source>BUY</source>
<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">14,15</context>
</context-group>
</trans-unit>
<trans-unit id="2389486e186b91e335cd9278cfe3af185b2ce0c2" datatype="html">
<source>DIVIDEND</source>
<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">15,17</context>
</context-group>
</trans-unit>
<trans-unit id="19288e8ab62dd8d905d5f6dac7a0c244062ab4f5" datatype="html">
<source>ITEM</source>
<trans-unit id="9bca420227979312de74f0a932a003437410b1ab" datatype="html">
<source>Item</source>
<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>
</context-group>
</trans-unit>
<trans-unit id="e14e3acc1ebdb5839aa65787f4ce52558659a9cc" datatype="html">
<source>SELL</source>
<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">17,21</context>
</context-group>
</trans-unit>
<trans-unit id="5ab4d451ff9ce6d18d53360c51e7cd6e91c69555" datatype="html">
<source>Name, symbol or ISIN</source>
<context-group purpose="location">
@ -1694,7 +1697,7 @@
<source>Unit Price</source>
<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">112,113</context>
<context context-type="linenumber">118,121</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/activities-table/activities-table.component.html</context>
@ -1705,11 +1708,11 @@
<source>Fee</source>
<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">131,132</context>
<context context-type="linenumber">139,140</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>
<context context-type="linenumber">148,149</context>
<context context-type="linenumber">156,157</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/activities-table/activities-table.component.html</context>
@ -1724,7 +1727,7 @@
</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>
<context context-type="linenumber">157,160</context>
<context context-type="linenumber">165,168</context>
</context-group>
</trans-unit>
<trans-unit id="584c9433705e9bfdd2e7a9f0192690f453d36196" datatype="html">
@ -1743,7 +1746,7 @@
</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>
<context context-type="linenumber">171,173</context>
<context context-type="linenumber">179,181</context>
</context-group>
</trans-unit>
<trans-unit id="2309808536212982229" datatype="html">
@ -2065,7 +2068,7 @@
</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>
<context context-type="linenumber">186,188</context>
<context context-type="linenumber">194,196</context>
</context-group>
</trans-unit>
<trans-unit id="3c5ec7bc638db6f37c402e4afab2084f8763e268" datatype="html">
@ -2179,11 +2182,11 @@
<source>Deposit</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">38</context>
<context context-type="linenumber">43</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">48</context>
<context context-type="linenumber">53</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/fire-calculator/fire-calculator.component.ts</context>
@ -2201,7 +2204,7 @@
<source>Monthly</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">44</context>
<context context-type="linenumber">49</context>
</context-group>
</trans-unit>
<trans-unit id="8511b16abcf065252b350d64e337ba2447db3ffb" datatype="html">
@ -2236,11 +2239,11 @@
<source>Filter by account or tag...</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/allocations/allocations-page.component.ts</context>
<context context-type="linenumber">137</context>
<context context-type="linenumber">136</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/holdings/holdings-page.component.ts</context>
<context context-type="linenumber">88</context>
<context context-type="linenumber">87</context>
</context-group>
</trans-unit>
<trans-unit id="4550487415324294802" datatype="html">
@ -2293,7 +2296,7 @@
<source>Benchmarks</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-overview/admin-overview.html</context>
<context context-type="linenumber">76</context>
<context context-type="linenumber">79</context>
</context-group>
</trans-unit>
<trans-unit id="44fcf77e86dc038202ebad6b46d1d833d60d781b" datatype="html">
@ -2377,7 +2380,7 @@
<source>Portfolio Evolution</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.html</context>
<context context-type="linenumber">113</context>
<context context-type="linenumber">130</context>
</context-group>
</trans-unit>
<trans-unit id="8192718423057883427" datatype="html">
@ -2631,7 +2634,7 @@
<source>Dividend Timeline</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.html</context>
<context context-type="linenumber">180</context>
<context context-type="linenumber">197</context>
</context-group>
</trans-unit>
<trans-unit id="7608037008789240367" datatype="html">
@ -2645,14 +2648,14 @@
<source>Dividend</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">34</context>
<context context-type="linenumber">39</context>
</context-group>
</trans-unit>
<trans-unit id="62f17fd50522539fd4c85854828db9d2e1c5330f" datatype="html">
<source>User Signup</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-overview/admin-overview.html</context>
<context context-type="linenumber">86</context>
<context context-type="linenumber">102</context>
</context-group>
</trans-unit>
</body>

View File

@ -32,6 +32,7 @@ import { PortfolioSummary } from './portfolio-summary.interface';
import { Position } from './position.interface';
import { BenchmarkResponse } from './responses/benchmark-response.interface';
import { ResponseError } from './responses/errors.interface';
import { ImportResponse } from './responses/import-response.interface';
import { OAuthResponse } from './responses/oauth-response.interface';
import { PortfolioPerformanceResponse } from './responses/portfolio-performance-response.interface';
import { ScraperConfiguration } from './scraper-configuration.interface';
@ -58,6 +59,7 @@ export {
Filter,
FilterGroup,
HistoricalDataItem,
ImportResponse,
InfoItem,
LineChartItem,
OAuthResponse,

View File

@ -0,0 +1,5 @@
import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface';
export interface ImportResponse {
activities: Activity[];
}

View File

@ -15,6 +15,28 @@
matSortDirection="desc"
[dataSource]="dataSource"
>
<ng-container matColumnDef="select">
<th *matHeaderCellDef class="px-1" mat-header-cell>
<mat-checkbox
class="mt-2"
color="primary"
[checked]="selectedRows.hasValue() && areAllRowsSelected()"
[indeterminate]="selectedRows.hasValue() && !areAllRowsSelected()"
(change)="$event ? toggleAllRows() : null"
></mat-checkbox>
</th>
<td *matCellDef="let element" class="px-1" mat-cell>
<mat-checkbox
class="mt-2"
color="primary"
[checked]="selectedRows.isSelected(element)"
(change)="$event ? selectedRows.toggle(element) : null"
(click)="$event.stopPropagation()"
></mat-checkbox>
</td>
<td *matFooterCellDef class="px-1" mat-footer-cell></td>
</ng-container>
<ng-container matColumnDef="count">
<th
*matHeaderCellDef
@ -45,7 +67,7 @@
</th>
<td *matCellDef="let element" class="px-1" mat-cell>
<div class="d-flex">
{{ element.date | date: defaultDateFormat }}
{{ element.date | date : defaultDateFormat }}
</div>
</td>
<td *matFooterCellDef class="px-1" i18n mat-footer-cell>Total</td>
@ -432,15 +454,7 @@
'cursor-pointer':
hasPermissionToOpenDetails && !row.isDraft && row.type !== 'ITEM'
}"
(click)="
hasPermissionToOpenDetails &&
!row.isDraft &&
row.type !== 'ITEM' &&
onOpenPositionDialog({
dataSource: row.SymbolProfile.dataSource,
symbol: row.SymbolProfile.symbol
})
"
(click)="onClickActivity(row)"
></tr>
<tr
*matFooterRowDef="displayedColumns"

View File

@ -1,3 +1,4 @@
import { SelectionModel } from '@angular/cdk/collections';
import {
ChangeDetectionStrategy,
Component,
@ -41,6 +42,7 @@ export class ActivitiesTableComponent implements OnChanges, OnDestroy {
@Input() locale: string;
@Input() pageSize = DEFAULT_PAGE_SIZE;
@Input() showActions: boolean;
@Input() showCheckbox = false;
@Input() showNameColumn = true;
@Output() activityDeleted = new EventEmitter<string>();
@ -49,6 +51,7 @@ export class ActivitiesTableComponent implements OnChanges, OnDestroy {
@Output() export = new EventEmitter<string[]>();
@Output() exportDrafts = new EventEmitter<string[]>();
@Output() import = new EventEmitter<void>();
@Output() selectedActivities = new EventEmitter<Activity[]>();
@ViewChild(MatPaginator) paginator: MatPaginator;
@ViewChild(MatSort) sort: MatSort;
@ -67,6 +70,7 @@ export class ActivitiesTableComponent implements OnChanges, OnDestroy {
public placeholder = '';
public routeQueryParams: Subscription;
public searchKeywords: string[] = [];
public selectedRows = new SelectionModel<Activity>(true, []);
public totalFees: number;
public totalValue: number;
@ -81,8 +85,15 @@ export class ActivitiesTableComponent implements OnChanges, OnDestroy {
});
}
public areAllRowsSelected() {
const numSelectedRows = this.selectedRows.selected.length;
const numTotalRows = this.dataSource.data.length;
return numSelectedRows === numTotalRows;
}
public ngOnChanges() {
this.displayedColumns = [
'select',
'count',
'date',
'type',
@ -98,6 +109,16 @@ export class ActivitiesTableComponent implements OnChanges, OnDestroy {
'actions'
];
if (this.showCheckbox) {
this.displayedColumns = this.displayedColumns.filter((column) => {
return column !== 'count';
});
} else {
this.displayedColumns = this.displayedColumns.filter((column) => {
return column !== 'select';
});
}
if (!this.showNameColumn) {
this.displayedColumns = this.displayedColumns.filter((column) => {
return column !== 'nameWithSymbol';
@ -133,6 +154,17 @@ export class ActivitiesTableComponent implements OnChanges, OnDestroy {
}
}
ngOnInit() {
if (this.showCheckbox) {
this.toggleAllRows();
this.selectedRows.changed
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe((selectedRows) => {
this.selectedActivities.emit(selectedRows.source.selected);
});
}
}
public onChangePage(page: PageEvent) {
this.pageIndex = page.pageIndex;
@ -140,6 +172,21 @@ export class ActivitiesTableComponent implements OnChanges, OnDestroy {
this.totalValue = this.getTotalValue();
}
public onClickActivity(activity: Activity) {
if (this.showCheckbox) {
this.selectedRows.toggle(activity);
} else if (
this.hasPermissionToOpenDetails &&
!activity.isDraft &&
activity.type !== 'ITEM'
) {
this.onOpenPositionDialog({
dataSource: activity.SymbolProfile.dataSource,
symbol: activity.SymbolProfile.symbol
});
}
}
public onCloneActivity(aActivity: OrderWithAccount) {
this.activityToClone.emit(aActivity);
}
@ -200,6 +247,14 @@ export class ActivitiesTableComponent implements OnChanges, OnDestroy {
this.activityToUpdate.emit(aActivity);
}
public toggleAllRows() {
this.areAllRowsSelected()
? this.selectedRows.clear()
: this.dataSource.data.forEach((row) => this.selectedRows.select(row));
this.selectedActivities.emit(this.selectedRows.selected);
}
public ngOnDestroy() {
this.unsubscribeSubject.next();
this.unsubscribeSubject.complete();
@ -237,9 +292,9 @@ export class ActivitiesTableComponent implements OnChanges, OnDestroy {
type: 'TAG'
};
fieldValueMap[format(activity.date, 'yyyy')] = {
id: format(activity.date, 'yyyy'),
label: format(activity.date, 'yyyy'),
fieldValueMap[format(new Date(activity.date), 'yyyy')] = {
id: format(new Date(activity.date), 'yyyy'),
label: format(new Date(activity.date), 'yyyy'),
type: 'TAG'
};

View File

@ -1,6 +1,7 @@
import { CommonModule } from '@angular/common';
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { MatCheckboxModule } from '@angular/material/checkbox';
import { MatMenuModule } from '@angular/material/menu';
import { MatPaginatorModule } from '@angular/material/paginator';
import { MatSortModule } from '@angular/material/sort';
@ -26,6 +27,7 @@ import { ActivitiesTableComponent } from './activities-table.component';
GfSymbolModule,
GfValueModule,
MatButtonModule,
MatCheckboxModule,
MatMenuModule,
MatPaginatorModule,
MatSortModule,

View File

@ -1,6 +1,6 @@
{
"name": "ghostfolio",
"version": "1.219.0",
"version": "1.221.0",
"homepage": "https://ghostfol.io",
"license": "AGPL-3.0",
"scripts": {
@ -101,7 +101,7 @@
"cheerio": "1.0.0-rc.12",
"class-transformer": "0.3.2",
"class-validator": "0.13.1",
"color": "4.0.1",
"color": "4.2.3",
"countries-list": "2.6.1",
"countup.js": "2.0.7",
"date-fns": "2.29.3",
@ -160,10 +160,10 @@
"@types/big.js": "6.1.6",
"@types/bull": "3.15.9",
"@types/cache-manager": "3.4.2",
"@types/color": "3.0.2",
"@types/color": "3.0.3",
"@types/google-spreadsheet": "3.1.5",
"@types/jest": "28.1.8",
"@types/lodash": "4.14.174",
"@types/lodash": "4.14.191",
"@types/node": "18.7.1",
"@types/papaparse": "5.2.6",
"@types/passport-google-oauth20": "2.0.11",
@ -182,7 +182,7 @@
"jest-environment-jsdom": "28.1.1",
"jest-preset-angular": "12.2.2",
"nx": "15.0.13",
"prettier": "2.7.1",
"prettier": "2.8.1",
"prettier-plugin-organize-attributes": "0.0.5",
"replace-in-file": "6.3.5",
"rimraf": "3.0.2",

View File

@ -0,0 +1,9 @@
-- AlterEnum
BEGIN;
CREATE TYPE "DataSource_new" AS ENUM ('ALPHA_VANTAGE', 'EOD_HISTORICAL_DATA', 'GHOSTFOLIO', 'GOOGLE_SHEETS', 'MANUAL', 'RAPID_API', 'YAHOO');
ALTER TABLE "MarketData" ALTER COLUMN "dataSource" TYPE "DataSource_new" USING ("dataSource"::text::"DataSource_new");
ALTER TABLE "SymbolProfile" ALTER COLUMN "dataSource" TYPE "DataSource_new" USING ("dataSource"::text::"DataSource_new");
ALTER TYPE "DataSource" RENAME TO "DataSource_old";
ALTER TYPE "DataSource_new" RENAME TO "DataSource";
DROP TYPE "DataSource_old";
COMMIT;

View File

@ -207,7 +207,6 @@ enum DataSource {
GHOSTFOLIO
GOOGLE_SHEETS
MANUAL
RAKUTEN
RAPID_API
YAHOO
}

View File

@ -4749,10 +4749,10 @@
resolved "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz"
integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==
"@types/color@3.0.2":
version "3.0.2"
resolved "https://registry.npmjs.org/@types/color/-/color-3.0.2.tgz"
integrity sha512-INiJl6sfNn8iyC5paxVzqiVUEj2boIlFki02uRTAkKwAj++7aAF+ZfEv/XrIeBa0XI/fTZuDHW8rEEcEVnON+Q==
"@types/color@3.0.3":
version "3.0.3"
resolved "https://registry.yarnpkg.com/@types/color/-/color-3.0.3.tgz#e6d8d72b7aaef4bb9fe80847c26c7c786191016d"
integrity sha512-X//qzJ3d3Zj82J9sC/C18ZY5f43utPbAJ6PhYt/M7uG6etcF6MRpKdN880KBy43B0BMzSfeT96MzrsNjFI3GbA==
dependencies:
"@types/color-convert" "*"
@ -4920,10 +4920,10 @@
dependencies:
"@types/node" "*"
"@types/lodash@4.14.174":
version "4.14.174"
resolved "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.174.tgz"
integrity sha512-KMBLT6+g9qrGXpDt7ohjWPUD34WA/jasrtjTEHStF0NPdEwJ1N9SZ+4GaMVDeuk/y0+X5j9xFm6mNiXS7UoaLQ==
"@types/lodash@4.14.191":
version "4.14.191"
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.191.tgz#09511e7f7cba275acd8b419ddac8da9a6a79e2fa"
integrity sha512-BdZ5BCCvho3EIXw6wUCXHe7rS53AIDPLE+JzwgT+OsJk53oBfbSmZZ7CX4VaRoN78N+TJpFi9QPlfIVNmJYWxQ==
"@types/lodash@^4.14.167":
version "4.14.182"
@ -7688,9 +7688,9 @@ color-name@^1.0.0, color-name@~1.1.4:
resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz"
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
color-string@^1.6.0:
color-string@^1.9.0:
version "1.9.1"
resolved "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz"
resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.9.1.tgz#4467f9146f036f855b764dfb5bf8582bf342c7a4"
integrity sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==
dependencies:
color-name "^1.0.0"
@ -7701,13 +7701,13 @@ color-support@^1.1.2, color-support@^1.1.3:
resolved "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz"
integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==
color@4.0.1:
version "4.0.1"
resolved "https://registry.npmjs.org/color/-/color-4.0.1.tgz"
integrity sha512-rpZjOKN5O7naJxkH2Rx1sZzzBgaiWECc6BYXjeCE6kF0kcASJYbUq02u7JqIHwCb/j3NhV+QhRL2683aICeGZA==
color@4.2.3:
version "4.2.3"
resolved "https://registry.yarnpkg.com/color/-/color-4.2.3.tgz#d781ecb5e57224ee43ea9627560107c0e0c6463a"
integrity sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==
dependencies:
color-convert "^2.0.1"
color-string "^1.6.0"
color-string "^1.9.0"
colord@^2.9.1:
version "2.9.2"
@ -16399,10 +16399,10 @@ prettier-plugin-organize-attributes@0.0.5:
resolved "https://registry.npmjs.org/prettier-plugin-organize-attributes/-/prettier-plugin-organize-attributes-0.0.5.tgz"
integrity sha512-dSts16q8wd+oq8Zwk5mwmYXo1aN3B+ZkEJqx/ar5fedNHdOvx7S4XDMH/pNK7rmBW0bPXkp/kJX5gAANsWzh3A==
prettier@2.7.1:
version "2.7.1"
resolved "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz"
integrity sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==
prettier@2.8.1:
version "2.8.1"
resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.1.tgz#4e1fd11c34e2421bc1da9aea9bd8127cd0a35efc"
integrity sha512-lqGoSJBQNJidqCHE80vqZJHWHRFoNYsSpP9AjFhlhi9ODCJA541svILes/+/1GM3VaL/abZi7cpFzOpdR9UPKg==
"prettier@>=2.2.1 <=2.3.0":
version "2.3.0"