Browse Source

Merge branch 'main' into feature/extend-public-api-with-portfolio-performance-metrics-endpoint

pull/3762/head
Thomas Kaul 11 months ago
committed by GitHub
parent
commit
046b100d93
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 16
      CHANGELOG.md
  2. 40
      apps/api/src/assets/sitemap.xml
  3. 30
      apps/api/src/services/data-provider/eod-historical-data/eod-historical-data.service.ts
  4. 2
      apps/client/src/app/app.component.html
  5. 28
      apps/client/src/app/app.component.ts
  6. 13
      apps/client/src/app/components/access-table/access-table.component.html
  7. 14
      apps/client/src/app/components/access-table/access-table.component.ts
  8. 2
      apps/client/src/app/components/access-table/access-table.module.ts
  9. 2
      apps/client/src/app/components/accounts-table/accounts-table.component.ts
  10. 22
      apps/client/src/app/components/header/header.component.ts
  11. 2
      apps/client/src/app/components/subscription-interstitial-dialog/subscription-interstitial-dialog.component.ts
  12. 2
      apps/client/src/app/components/user-account-membership/user-account-membership.component.ts
  13. 4
      apps/client/src/app/pages/about/overview/about-overview-page.component.ts
  14. 33
      apps/client/src/app/pages/accounts/accounts-page.component.ts
  15. 4
      apps/client/src/app/pages/blog/2021/07/hallo-ghostfolio/hallo-ghostfolio-page.component.ts
  16. 4
      apps/client/src/app/pages/blog/2021/07/hello-ghostfolio/hello-ghostfolio-page.component.ts
  17. 2
      apps/client/src/app/pages/blog/2022/01/first-months-in-open-source/first-months-in-open-source-page.component.ts
  18. 2
      apps/client/src/app/pages/blog/2022/07/how-do-i-get-my-finances-in-order/how-do-i-get-my-finances-in-order-page.component.ts
  19. 4
      apps/client/src/app/pages/blog/2022/08/500-stars-on-github/500-stars-on-github-page.component.ts
  20. 4
      apps/client/src/app/pages/blog/2022/11/black-friday-2022/black-friday-2022-page.component.ts
  21. 4
      apps/client/src/app/pages/blog/2023/03/1000-stars-on-github/1000-stars-on-github-page.component.ts
  22. 4
      apps/client/src/app/pages/blog/2023/05/unlock-your-financial-potential-with-ghostfolio/unlock-your-financial-potential-with-ghostfolio-page.component.ts
  23. 2
      apps/client/src/app/pages/blog/2023/07/exploring-the-path-to-fire/exploring-the-path-to-fire-page.component.ts
  24. 5
      apps/client/src/app/pages/blog/2023/08/ghostfolio-joins-oss-friends/ghostfolio-joins-oss-friends-page.component.ts
  25. 11
      apps/client/src/app/pages/blog/2023/09/ghostfolio-2/ghostfolio-2-page.component.ts
  26. 2
      apps/client/src/app/pages/blog/2023/09/hacktoberfest-2023/hacktoberfest-2023-page.component.ts
  27. 4
      apps/client/src/app/pages/blog/2023/11/black-week-2023/black-week-2023-page.component.ts
  28. 4
      apps/client/src/app/pages/blog/2023/11/hacktoberfest-2023-debriefing/hacktoberfest-2023-debriefing-page.component.ts
  29. 14
      apps/client/src/app/pages/blog/2024/09/hacktoberfest-2024/hacktoberfest-2024-page.component.ts
  30. 200
      apps/client/src/app/pages/blog/2024/09/hacktoberfest-2024/hacktoberfest-2024-page.html
  31. 9
      apps/client/src/app/pages/blog/blog-page-routing.module.ts
  32. 24
      apps/client/src/app/pages/blog/blog-page.html
  33. 2
      apps/client/src/app/pages/faq/overview/faq-overview-page.component.ts
  34. 6
      apps/client/src/app/pages/faq/saas/saas-page.component.ts
  35. 4
      apps/client/src/app/pages/features/features-page.component.ts
  36. 4
      apps/client/src/app/pages/landing/landing-page.component.ts
  37. 4
      apps/client/src/app/pages/pricing/pricing-page.component.ts
  38. 2
      apps/client/src/app/pages/resources/personal-finance-tools/personal-finance-tools-page.component.ts
  39. 6
      apps/client/src/app/pages/resources/personal-finance-tools/product-page.component.ts
  40. 4
      apps/client/src/app/pages/resources/resources-page.component.ts
  41. BIN
      apps/client/src/assets/images/blog/hacktoberfest-2024.png
  42. 329
      apps/client/src/locales/messages.ca.xlf
  43. 329
      apps/client/src/locales/messages.de.xlf
  44. 329
      apps/client/src/locales/messages.es.xlf
  45. 385
      apps/client/src/locales/messages.fr.xlf
  46. 353
      apps/client/src/locales/messages.it.xlf
  47. 329
      apps/client/src/locales/messages.nl.xlf
  48. 447
      apps/client/src/locales/messages.pl.xlf
  49. 329
      apps/client/src/locales/messages.pt.xlf
  50. 329
      apps/client/src/locales/messages.tr.xlf
  51. 316
      apps/client/src/locales/messages.xlf
  52. 329
      apps/client/src/locales/messages.zh.xlf
  53. 2
      libs/ui/src/lib/membership-card/membership-card.component.ts
  54. 2
      package.json

16
CHANGELOG.md

@ -9,8 +9,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- Added support for bonds in the import dividends dialog
- Extended the _Public API_ with a new endpoint that provides portfolio performance metrics (experimental)
- Added a blog post: _Hacktoberfest 2024_
### Changed
- Improved the loading indicator of the accounts table
- Improved the language localization for German (`de`)
- Improved the language localization for Polish (`pl`)
## 2.108.0 - 2024-09-17
### Added
- Added support for bonds in the import dividends dialog
- Added a _Copy link to clipboard_ action to the access table to share the portfolio
- Added the current market price column to the historical market data table of the admin control
- Introduced filters (`dataSource` and `symbol`) in the accounts endpoint
@ -18,6 +31,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Improved the usability of the toggle component
- Switched to the accounts endpoint in the holding detail dialog
- Added a fallback in the get quotes functionality of the _EOD Historical Data_ service
## 2.107.1 - 2024-09-12

40
apps/api/src/assets/sitemap.xml

@ -172,6 +172,10 @@
<loc>https://ghostfol.io/en/blog/2023/11/hacktoberfest-2023-debriefing</loc>
<lastmod>${currentDate}T00:00:00+00:00</lastmod>
</url>
<url>
<loc>https://ghostfol.io/en/blog/2024/09/hacktoberfest-2024</loc>
<lastmod>${currentDate}T00:00:00+00:00</lastmod>
</url>
<url>
<loc>https://ghostfol.io/en/faq</loc>
<lastmod>${currentDate}T00:00:00+00:00</lastmod>
@ -446,12 +450,46 @@
<loc>https://ghostfol.io/nl/veelgestelde-vragen</loc>
<lastmod>${currentDate}T00:00:00+00:00</lastmod>
</url>
<!--
<url>
<loc>https://ghostfol.io/pl</loc>
<lastmod>${currentDate}T00:00:00+00:00</lastmod>
</url>
<url>
<loc>https://ghostfol.io/pl/blog</loc>
<lastmod>${currentDate}T00:00:00+00:00</lastmod>
</url>
<url>
<loc>https://ghostfol.io/pl/cennik</loc>
<lastmod>${currentDate}T00:00:00+00:00</lastmod>
</url>
<!--
<url>
<loc>https://ghostfol.io/pl/faq</loc>
<lastmod>${currentDate}T00:00:00+00:00</lastmod>
</url>
-->
<url>
<loc>https://ghostfol.io/pl/funkcje</loc>
<lastmod>${currentDate}T00:00:00+00:00</lastmod>
</url>
<url>
<loc>https://ghostfol.io/pl/o-ghostfolio</loc>
<lastmod>${currentDate}T00:00:00+00:00</lastmod>
</url>
<!--
<url>
<loc>https://ghostfol.io/pl/open</loc>
<lastmod>${currentDate}T00:00:00+00:00</lastmod>
</url>
-->
<url>
<loc>https://ghostfol.io/pl/rynki</loc>
<lastmod>${currentDate}T00:00:00+00:00</lastmod>
</url>
<url>
<loc>https://ghostfol.io/pl/zarejestruj</loc>
<lastmod>${currentDate}T00:00:00+00:00</lastmod>
</url>
<url>
<loc>https://ghostfol.io/pt</loc>
<lastmod>${currentDate}T00:00:00+00:00</lastmod>

30
apps/api/src/services/data-provider/eod-historical-data/eod-historical-data.service.ts

@ -18,6 +18,7 @@ import {
} from '@ghostfolio/common/config';
import { DATE_FORMAT, isCurrency } from '@ghostfolio/common/helper';
import { DataProviderInfo } from '@ghostfolio/common/interfaces';
import { MarketState } from '@ghostfolio/common/types';
import { Injectable, Logger } from '@nestjs/common';
import {
@ -229,7 +230,12 @@ export class EodHistoricalDataService implements DataProviderInterface {
}
).json<any>();
const quotes =
const quotes: {
close: number;
code: string;
previousClose: number;
timestamp: number;
}[] =
eodHistoricalDataSymbols.length === 1
? [realTimeResponse]
: realTimeResponse;
@ -243,7 +249,7 @@ export class EodHistoricalDataService implements DataProviderInterface {
})
);
for (const { close, code, timestamp } of quotes) {
for (const { close, code, previousClose, timestamp } of quotes) {
let currency: string;
if (this.isForex(code)) {
@ -267,15 +273,21 @@ export class EodHistoricalDataService implements DataProviderInterface {
}
}
if (isNumber(close)) {
if (isNumber(close) || isNumber(previousClose)) {
const marketPrice: number = isNumber(close) ? close : previousClose;
let marketState: MarketState = 'closed';
if (this.isForex(code) || isToday(new Date(timestamp * 1000))) {
marketState = 'open';
} else if (!isNumber(close)) {
marketState = 'delayed';
}
response[this.convertFromEodSymbol(code)] = {
currency,
dataSource: this.getName(),
marketPrice: close,
marketState:
this.isForex(code) || isToday(new Date(timestamp * 1000))
? 'open'
: 'closed'
marketPrice,
marketState,
dataSource: this.getName()
};
} else {
Logger.error(

2
apps/client/src/app/app.component.html

@ -168,11 +168,9 @@
<li>
<a href="../nl" title="Ghostfolio in Nederlands">Nederlands</a>
</li>
<!--
<li>
<a href="../pl" title="Ghostfolio in Polski">Polski</a>
</li>
-->
<li>
<a href="../pt" title="Ghostfolio in Português">Português</a>
</li>

28
apps/client/src/app/app.component.ts

@ -57,19 +57,25 @@ export class AppComponent implements OnDestroy, OnInit {
public hasTabs = false;
public info: InfoItem;
public pageTitle: string;
public routerLinkAbout = ['/' + $localize`about`];
public routerLinkAboutChangelog = ['/' + $localize`about`, 'changelog'];
public routerLinkAboutLicense = ['/' + $localize`about`, $localize`license`];
public routerLinkAbout = ['/' + $localize`:snake-case:about`];
public routerLinkAboutChangelog = [
'/' + $localize`:snake-case:about`,
'changelog'
];
public routerLinkAboutLicense = [
'/' + $localize`:snake-case:about`,
$localize`:snake-case:license`
];
public routerLinkAboutPrivacyPolicy = [
'/' + $localize`about`,
$localize`privacy-policy`
'/' + $localize`:snake-case:about`,
$localize`:snake-case:privacy-policy`
];
public routerLinkFaq = ['/' + $localize`faq`];
public routerLinkFeatures = ['/' + $localize`features`];
public routerLinkMarkets = ['/' + $localize`markets`];
public routerLinkPricing = ['/' + $localize`pricing`];
public routerLinkRegister = ['/' + $localize`register`];
public routerLinkResources = ['/' + $localize`resources`];
public routerLinkFaq = ['/' + $localize`:snake-case:faq`];
public routerLinkFeatures = ['/' + $localize`:snake-case:features`];
public routerLinkMarkets = ['/' + $localize`:snake-case:markets`];
public routerLinkPricing = ['/' + $localize`:snake-case:pricing`];
public routerLinkRegister = ['/' + $localize`:snake-case:register`];
public routerLinkResources = ['/' + $localize`:snake-case:resources`];
public showFooter = false;
public user: User;

13
apps/client/src/app/components/access-table/access-table.component.html

@ -35,11 +35,9 @@
@if (element.type === 'PUBLIC') {
<div class="align-items-center d-flex">
<ion-icon class="mr-1" name="link-outline" />
<a
href="{{ baseUrl }}/{{ defaultLanguageCode }}/p/{{ element.id }}"
target="_blank"
>{{ baseUrl }}/{{ defaultLanguageCode }}/p/{{ element.id }}</a
>
<a target="_blank" [href]="getPublicUrl(element.id)">{{
getPublicUrl(element.id)
}}</a>
</div>
@if (user?.settings?.isExperimentalFeatures) {
<div>
@ -67,6 +65,11 @@
<ion-icon name="ellipsis-horizontal" />
</button>
<mat-menu #transactionMenu="matMenu" xPosition="before">
@if (element.type === 'PUBLIC') {
<button mat-menu-item (click)="onCopyToClipboard(element.id)">
<ng-container i18n>Copy link to clipboard</ng-container>
</button>
}
<button mat-menu-item (click)="onDeleteAccess(element.id)">
<ng-container i18n>Revoke</ng-container>
</button>

14
apps/client/src/app/components/access-table/access-table.component.ts

@ -3,6 +3,7 @@ import { NotificationService } from '@ghostfolio/client/core/notification/notifi
import { DEFAULT_LANGUAGE_CODE } from '@ghostfolio/common/config';
import { Access, User } from '@ghostfolio/common/interfaces';
import { Clipboard } from '@angular/cdk/clipboard';
import {
ChangeDetectionStrategy,
Component,
@ -32,7 +33,10 @@ export class AccessTableComponent implements OnChanges, OnInit {
public defaultLanguageCode = DEFAULT_LANGUAGE_CODE;
public displayedColumns = [];
public constructor(private notificationService: NotificationService) {}
public constructor(
private clipboard: Clipboard,
private notificationService: NotificationService
) {}
public ngOnInit() {}
@ -48,6 +52,14 @@ export class AccessTableComponent implements OnChanges, OnInit {
}
}
public getPublicUrl(aId: string): string {
return `${this.baseUrl}/${this.defaultLanguageCode}/p/${aId}`;
}
public onCopyToClipboard(aId: string): void {
this.clipboard.copy(this.getPublicUrl(aId));
}
public onDeleteAccess(aId: string) {
this.notificationService.confirm({
confirmFn: () => {

2
apps/client/src/app/components/access-table/access-table.module.ts

@ -1,3 +1,4 @@
import { ClipboardModule } from '@angular/cdk/clipboard';
import { CommonModule } from '@angular/common';
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
@ -11,6 +12,7 @@ import { AccessTableComponent } from './access-table.component';
declarations: [AccessTableComponent],
exports: [AccessTableComponent],
imports: [
ClipboardModule,
CommonModule,
MatButtonModule,
MatMenuModule,

2
apps/client/src/app/components/accounts-table/accounts-table.component.ts

@ -92,11 +92,11 @@ export class AccountsTableComponent implements OnChanges, OnDestroy, OnInit {
this.isLoading = true;
if (this.accounts) {
this.dataSource = new MatTableDataSource(this.accounts);
this.dataSource.sort = this.sort;
this.dataSource.sortingDataAccessor = get;
if (this.accounts) {
this.isLoading = false;
}
}

22
apps/client/src/app/components/header/header.component.ts

@ -75,17 +75,17 @@ export class HeaderComponent implements OnChanges {
public hasPermissionToCreateUser: boolean;
public impersonationId: string;
public isMenuOpen: boolean;
public routeAbout = $localize`about`;
public routeFeatures = $localize`features`;
public routeMarkets = $localize`markets`;
public routePricing = $localize`pricing`;
public routeResources = $localize`resources`;
public routerLinkAbout = ['/' + $localize`about`];
public routerLinkFeatures = ['/' + $localize`features`];
public routerLinkMarkets = ['/' + $localize`markets`];
public routerLinkPricing = ['/' + $localize`pricing`];
public routerLinkRegister = ['/' + $localize`register`];
public routerLinkResources = ['/' + $localize`resources`];
public routeAbout = $localize`:snake-case:about`;
public routeFeatures = $localize`:snake-case:features`;
public routeMarkets = $localize`:snake-case:markets`;
public routePricing = $localize`:snake-case:pricing`;
public routeResources = $localize`:snake-case:resources`;
public routerLinkAbout = ['/' + $localize`:snake-case:about`];
public routerLinkFeatures = ['/' + $localize`:snake-case:features`];
public routerLinkMarkets = ['/' + $localize`:snake-case:markets`];
public routerLinkPricing = ['/' + $localize`:snake-case:pricing`];
public routerLinkRegister = ['/' + $localize`:snake-case:register`];
public routerLinkResources = ['/' + $localize`:snake-case:resources`];
private unsubscribeSubject = new Subject<void>();

2
apps/client/src/app/components/subscription-interstitial-dialog/subscription-interstitial-dialog.component.ts

@ -11,7 +11,7 @@ import { SubscriptionInterstitialDialogParams } from './interfaces/interfaces';
templateUrl: 'subscription-interstitial-dialog.html'
})
export class SubscriptionInterstitialDialog {
public routerLinkPricing = ['/' + $localize`pricing`];
public routerLinkPricing = ['/' + $localize`:snake-case:pricing`];
public constructor(
@Inject(MAT_DIALOG_DATA) public data: SubscriptionInterstitialDialogParams,

2
apps/client/src/app/components/user-account-membership/user-account-membership.component.ts

@ -36,7 +36,7 @@ export class UserAccountMembershipComponent implements OnDestroy, OnInit {
public hasPermissionToUpdateUserSettings: boolean;
public price: number;
public priceId: string;
public routerLinkPricing = ['/' + $localize`pricing`];
public routerLinkPricing = ['/' + $localize`:snake-case:pricing`];
public snackBarRef: MatSnackBarRef<TextOnlySnackBar>;
public trySubscriptionMail =
'mailto:hi@ghostfol.io?Subject=Ghostfolio Premium Trial&body=Hello%0D%0DI am interested in Ghostfolio Premium. Can you please send me a coupon code to try it for some time?%0D%0DKind regards';

4
apps/client/src/app/pages/about/overview/about-overview-page.component.ts

@ -16,8 +16,8 @@ export class AboutOverviewPageComponent implements OnDestroy, OnInit {
public hasPermissionForStatistics: boolean;
public hasPermissionForSubscription: boolean;
public isLoggedIn: boolean;
public routerLinkFaq = ['/' + $localize`faq`];
public routerLinkFeatures = ['/' + $localize`features`];
public routerLinkFaq = ['/' + $localize`:snake-case:faq`];
public routerLinkFeatures = ['/' + $localize`:snake-case:features`];
public user: User;
private unsubscribeSubject = new Subject<void>();

33
apps/client/src/app/pages/accounts/accounts-page.component.ts

@ -136,18 +136,18 @@ export class AccountsPageComponent implements OnDestroy, OnInit {
}
public onDeleteAccount(aId: string) {
this.reset();
this.dataService
.deleteAccount(aId)
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe({
next: () => {
.subscribe(() => {
this.userService
.get(true)
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe();
this.fetchAccounts();
}
});
}
@ -193,19 +193,21 @@ export class AccountsPageComponent implements OnDestroy, OnInit {
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe((account: UpdateAccountDto | null) => {
if (account) {
this.reset();
this.dataService
.putAccount(account)
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe({
next: () => {
.subscribe(() => {
this.userService
.get(true)
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe();
this.fetchAccounts();
}
});
this.changeDetectorRef.markForCheck();
}
this.router.navigate(['.'], { relativeTo: this.route });
@ -264,19 +266,21 @@ export class AccountsPageComponent implements OnDestroy, OnInit {
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe((account: CreateAccountDto | null) => {
if (account) {
this.reset();
this.dataService
.postAccount(account)
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe({
next: () => {
.subscribe(() => {
this.userService
.get(true)
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe();
this.fetchAccounts();
}
});
this.changeDetectorRef.markForCheck();
}
this.router.navigate(['.'], { relativeTo: this.route });
@ -296,6 +300,8 @@ export class AccountsPageComponent implements OnDestroy, OnInit {
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe((data: any) => {
if (data) {
this.reset();
const { accountIdFrom, accountIdTo, balance }: TransferBalanceDto =
data?.account;
@ -318,9 +324,18 @@ export class AccountsPageComponent implements OnDestroy, OnInit {
.subscribe(() => {
this.fetchAccounts();
});
this.changeDetectorRef.markForCheck();
}
this.router.navigate(['.'], { relativeTo: this.route });
});
}
private reset() {
this.accounts = undefined;
this.totalBalanceInBaseCurrency = 0;
this.totalValueInBaseCurrency = 0;
this.transactionCount = 0;
}
}

4
apps/client/src/app/pages/blog/2021/07/hallo-ghostfolio/hallo-ghostfolio-page.component.ts

@ -10,6 +10,6 @@ import { RouterModule } from '@angular/router';
templateUrl: './hallo-ghostfolio-page.html'
})
export class HalloGhostfolioPageComponent {
public routerLinkPricing = ['/' + $localize`pricing`];
public routerLinkResources = ['/' + $localize`resources`];
public routerLinkPricing = ['/' + $localize`:snake-case:pricing`];
public routerLinkResources = ['/' + $localize`:snake-case:resources`];
}

4
apps/client/src/app/pages/blog/2021/07/hello-ghostfolio/hello-ghostfolio-page.component.ts

@ -10,6 +10,6 @@ import { RouterModule } from '@angular/router';
templateUrl: './hello-ghostfolio-page.html'
})
export class HelloGhostfolioPageComponent {
public routerLinkPricing = ['/' + $localize`pricing`];
public routerLinkResources = ['/' + $localize`resources`];
public routerLinkPricing = ['/' + $localize`:snake-case:pricing`];
public routerLinkResources = ['/' + $localize`:snake-case:resources`];
}

2
apps/client/src/app/pages/blog/2022/01/first-months-in-open-source/first-months-in-open-source-page.component.ts

@ -10,5 +10,5 @@ import { RouterModule } from '@angular/router';
templateUrl: './first-months-in-open-source-page.html'
})
export class FirstMonthsInOpenSourcePageComponent {
public routerLinkPricing = ['/' + $localize`pricing`];
public routerLinkPricing = ['/' + $localize`:snake-case:pricing`];
}

2
apps/client/src/app/pages/blog/2022/07/how-do-i-get-my-finances-in-order/how-do-i-get-my-finances-in-order-page.component.ts

@ -10,5 +10,5 @@ import { RouterModule } from '@angular/router';
templateUrl: './how-do-i-get-my-finances-in-order-page.html'
})
export class HowDoIGetMyFinancesInOrderPageComponent {
public routerLinkResources = ['/' + $localize`resources`];
public routerLinkResources = ['/' + $localize`:snake-case:resources`];
}

4
apps/client/src/app/pages/blog/2022/08/500-stars-on-github/500-stars-on-github-page.component.ts

@ -10,6 +10,6 @@ import { RouterModule } from '@angular/router';
templateUrl: './500-stars-on-github-page.html'
})
export class FiveHundredStarsOnGitHubPageComponent {
public routerLinkMarkets = ['/' + $localize`markets`];
public routerLinkPricing = ['/' + $localize`pricing`];
public routerLinkMarkets = ['/' + $localize`:snake-case:markets`];
public routerLinkPricing = ['/' + $localize`:snake-case:pricing`];
}

4
apps/client/src/app/pages/blog/2022/11/black-friday-2022/black-friday-2022-page.component.ts

@ -12,6 +12,6 @@ import { RouterModule } from '@angular/router';
templateUrl: './black-friday-2022-page.html'
})
export class BlackFriday2022PageComponent {
public routerLinkFeatures = ['/' + $localize`features`];
public routerLinkPricing = ['/' + $localize`pricing`];
public routerLinkFeatures = ['/' + $localize`:snake-case:features`];
public routerLinkPricing = ['/' + $localize`:snake-case:pricing`];
}

4
apps/client/src/app/pages/blog/2023/03/1000-stars-on-github/1000-stars-on-github-page.component.ts

@ -10,6 +10,6 @@ import { RouterModule } from '@angular/router';
templateUrl: './1000-stars-on-github-page.html'
})
export class ThousandStarsOnGitHubPageComponent {
public routerLinkFeatures = ['/' + $localize`features`];
public routerLinkPricing = ['/' + $localize`pricing`];
public routerLinkFeatures = ['/' + $localize`:snake-case:features`];
public routerLinkPricing = ['/' + $localize`:snake-case:pricing`];
}

4
apps/client/src/app/pages/blog/2023/05/unlock-your-financial-potential-with-ghostfolio/unlock-your-financial-potential-with-ghostfolio-page.component.ts

@ -10,6 +10,6 @@ import { RouterModule } from '@angular/router';
templateUrl: './unlock-your-financial-potential-with-ghostfolio-page.html'
})
export class UnlockYourFinancialPotentialWithGhostfolioPageComponent {
public routerLinkFeatures = ['/' + $localize`features`];
public routerLinkResources = ['/' + $localize`resources`];
public routerLinkFeatures = ['/' + $localize`:snake-case:features`];
public routerLinkResources = ['/' + $localize`:snake-case:resources`];
}

2
apps/client/src/app/pages/blog/2023/07/exploring-the-path-to-fire/exploring-the-path-to-fire-page.component.ts

@ -10,5 +10,5 @@ import { RouterModule } from '@angular/router';
templateUrl: './exploring-the-path-to-fire-page.html'
})
export class ExploringThePathToFirePageComponent {
public routerLinkFeatures = ['/' + $localize`features`];
public routerLinkFeatures = ['/' + $localize`:snake-case:features`];
}

5
apps/client/src/app/pages/blog/2023/08/ghostfolio-joins-oss-friends/ghostfolio-joins-oss-friends-page.component.ts

@ -10,5 +10,8 @@ import { RouterModule } from '@angular/router';
templateUrl: './ghostfolio-joins-oss-friends-page.html'
})
export class GhostfolioJoinsOssFriendsPageComponent {
public routerLinkAboutOssFriends = ['/' + $localize`about`, 'oss-friends'];
public routerLinkAboutOssFriends = [
'/' + $localize`:snake-case:about`,
'oss-friends'
];
}

11
apps/client/src/app/pages/blog/2023/09/ghostfolio-2/ghostfolio-2-page.component.ts

@ -10,8 +10,11 @@ import { RouterModule } from '@angular/router';
templateUrl: './ghostfolio-2-page.html'
})
export class Ghostfolio2PageComponent {
public routerLinkAbout = ['/' + $localize`about`];
public routerLinkAboutChangelog = ['/' + $localize`about`, 'changelog'];
public routerLinkFeatures = ['/' + $localize`features`];
public routerLinkMarkets = ['/' + $localize`markets`];
public routerLinkAbout = ['/' + $localize`:snake-case:about`];
public routerLinkAboutChangelog = [
'/' + $localize`:snake-case:about`,
'changelog'
];
public routerLinkFeatures = ['/' + $localize`:snake-case:features`];
public routerLinkMarkets = ['/' + $localize`:snake-case:markets`];
}

2
apps/client/src/app/pages/blog/2023/09/hacktoberfest-2023/hacktoberfest-2023-page.component.ts

@ -10,5 +10,5 @@ import { RouterModule } from '@angular/router';
templateUrl: './hacktoberfest-2023-page.html'
})
export class Hacktoberfest2023PageComponent {
public routerLinkAbout = ['/' + $localize`about`];
public routerLinkAbout = ['/' + $localize`:snake-case:about`];
}

4
apps/client/src/app/pages/blog/2023/11/black-week-2023/black-week-2023-page.component.ts

@ -12,6 +12,6 @@ import { RouterModule } from '@angular/router';
templateUrl: './black-week-2023-page.html'
})
export class BlackWeek2023PageComponent {
public routerLinkFeatures = ['/' + $localize`features`];
public routerLinkPricing = ['/' + $localize`pricing`];
public routerLinkFeatures = ['/' + $localize`:snake-case:features`];
public routerLinkPricing = ['/' + $localize`:snake-case:pricing`];
}

4
apps/client/src/app/pages/blog/2023/11/hacktoberfest-2023-debriefing/hacktoberfest-2023-debriefing-page.component.ts

@ -10,6 +10,6 @@ import { RouterModule } from '@angular/router';
templateUrl: './hacktoberfest-2023-debriefing-page.html'
})
export class Hacktoberfest2023DebriefingPageComponent {
public routerLinkAbout = ['/' + $localize`about`];
public routerLinkFeatures = ['/' + $localize`features`];
public routerLinkAbout = ['/' + $localize`:snake-case:about`];
public routerLinkFeatures = ['/' + $localize`:snake-case:features`];
}

14
apps/client/src/app/pages/blog/2024/09/hacktoberfest-2024/hacktoberfest-2024-page.component.ts

@ -0,0 +1,14 @@
import { Component } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { RouterModule } from '@angular/router';
@Component({
host: { class: 'page' },
imports: [MatButtonModule, RouterModule],
selector: 'gf-hacktoberfest-2024-page',
standalone: true,
templateUrl: './hacktoberfest-2024-page.html'
})
export class Hacktoberfest2024PageComponent {
public routerLinkAbout = ['/' + $localize`:snake-case:about`];
}

200
apps/client/src/app/pages/blog/2024/09/hacktoberfest-2024/hacktoberfest-2024-page.html

@ -0,0 +1,200 @@
<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">Hacktoberfest 2024</h1>
<div class="mb-3 text-muted"><small>2024-09-21</small></div>
<img
alt="Hacktoberfest 2024 with Ghostfolio Teaser"
class="rounded w-100"
src="../assets/images/blog/hacktoberfest-2024.png"
title="Hacktoberfest 2024 with Ghostfolio"
/>
</div>
<section class="mb-4">
<p>
At Ghostfolio, <a [routerLink]="routerLinkAbout">we</a> are very
excited to join
<a href="https://hacktoberfest.com">Hacktoberfest</a> for the
<a href="../en/blog/2023/11/hacktoberfest-2023-debriefing"
>third time</a
>
and look forward to connecting with new, enthusiastic open-source
contributors. Hacktoberfest is a a month-long celebration of all
things open-source: projects, their maintainers, and the entire
community of contributors. Every October, open source maintainers
around the globe dedicate extra time to support new contributors
while guiding them through their first pull requests on
<a href="https://github.com/ghostfolio/ghostfolio">GitHub</a>.
</p>
</section>
<section class="mb-4">
<h2 class="h4">Introducing Ghostfolio: Personal Finance Dashboard</h2>
<p>
<a href="https://ghostfol.io">Ghostfolio</a> is a modern web
application for managing personal finances. It aggregates your
assets and helps you make informed decisions to balance your
portfolio or plan future investments.
</p>
<p>
The software is fully written in
<a href="https://www.typescriptlang.org">TypeScript</a> and
organized as an <a href="https://nx.dev">Nx</a> workspace, utilizing
the latest framework releases. The backend is based on
<a href="https://nestjs.com">NestJS</a> in combination with
<a href="https://www.postgresql.org">PostgreSQL</a> as a database
together with <a href="https://www.prisma.io">Prisma</a> and
<a href="https://redis.io">Redis</a> for caching. The frontend is
built with <a href="https://angular.dev">Angular</a>.
</p>
<p>
The OSS project counting more than 100 contributors is used daily by
its growing global community. With over
<a [routerLink]="['/open']">4’000 stars on GitHub</a> and
<a [routerLink]="['/open']">800’000+ pulls on Docker Hub</a>,
Ghostfolio has gained widespread recognition for its user-friendly
experience and simplicity.
</p>
</section>
<section class="mb-4">
<h2 class="h4">How you can make an impact</h2>
<p>
Every contribution can make a difference. Whether it involves
implementing new features, resolving bugs, refactoring code,
enhancing documentation, adding unit tests, or translating content
into another language, you can actively shape our project.
</p>
<p>
Not familiar with our codebase yet? No problem! We have labeled a
few
<a
href="https://github.com/ghostfolio/ghostfolio/issues?q=is%3Aissue+is%3Aopen+label%3Ahacktoberfest"
>issues</a
>
with <code>hacktoberfest</code> that are well suited for newcomers.
</p>
<p>
The official Hacktoberfest website provides some valuable
<a
href="https://hacktoberfest.com/participation/#beginner-resources"
>resources for beginners</a
>
to start contributing in open source.
</p>
</section>
<section class="mb-4">
<h2 class="h4">Connect with us</h2>
<p>
If you have further questions or ideas, please join our
<a
href="https://join.slack.com/t/ghostfolio/shared_invite/zt-vsaan64h-F_I0fEo5M0P88lP9ibCxFg"
>Slack</a
>
community or get in touch on X
<a href="https://x.com/ghostfolio_">&#64;ghostfolio_</a>.
</p>
<p>
We look forward to collaborating.<br />
Thomas from Ghostfolio
</p>
</section>
<section class="mb-4">
<ul class="list-inline">
<li class="list-inline-item">
<span class="badge badge-light">Angular</span>
</li>
<li class="list-inline-item">
<span class="badge badge-light">Community</span>
</li>
<li class="list-inline-item">
<span class="badge badge-light">Docker</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">GitHub</span>
</li>
<li class="list-inline-item">
<span class="badge badge-light">Hacktoberfest</span>
</li>
<li class="list-inline-item">
<span class="badge badge-light">Hacktoberfest 2024</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">NestJS</span>
</li>
<li class="list-inline-item">
<span class="badge badge-light">Nx</span>
</li>
<li class="list-inline-item">
<span class="badge badge-light">October</span>
</li>
<li class="list-inline-item">
<span class="badge badge-light">Open Source</span>
</li>
<li class="list-inline-item">
<span class="badge badge-light">OSS</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</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">Prisma</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">TypeScript</span>
</li>
<li class="list-inline-item">
<span class="badge badge-light">UX</span>
</li>
<li class="list-inline-item">
<span class="badge badge-light">Wealth</span>
</li>
<li class="list-inline-item">
<span class="badge badge-light">Wealth Management</span>
</li>
<li class="list-inline-item">
<span class="badge badge-light">Web3</span>
</li>
<li class="list-inline-item">
<span class="badge badge-light">Web 3.0</span>
</li>
</ul>
</section>
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item">
<a i18n [routerLink]="['/blog']">Blog</a>
</li>
<li
aria-current="page"
class="active breadcrumb-item text-truncate"
>
Hacktoberfest 2024
</li>
</ol>
</nav>
</article>
</div>
</div>
</div>

9
apps/client/src/app/pages/blog/blog-page-routing.module.ts

@ -182,6 +182,15 @@ const routes: Routes = [
(c) => c.BlackWeek2023PageComponent
),
title: 'Black Week 2023'
},
{
canActivate: [AuthGuard],
path: '2024/09/hacktoberfest-2024',
loadComponent: () =>
import(
'./2024/09/hacktoberfest-2024/hacktoberfest-2024-page.component'
).then((c) => c.Hacktoberfest2024PageComponent),
title: 'Hacktoberfest 2024'
}
];

24
apps/client/src/app/pages/blog/blog-page.html

@ -8,6 +8,30 @@
finance</small
>
</h1>
<mat-card appearance="outlined" class="mb-3">
<mat-card-content class="p-0">
<div class="container p-0">
<div class="flex-nowrap no-gutters row">
<a
class="d-flex overflow-hidden p-3 w-100"
href="../en/blog/2024/09/hacktoberfest-2024"
>
<div class="flex-grow-1 overflow-hidden">
<div class="h6 m-0 text-truncate">Hacktoberfest 2024</div>
<div class="d-flex text-muted">2024-09-21</div>
</div>
<div class="align-items-center d-flex">
<ion-icon
class="chevron text-muted"
name="chevron-forward-outline"
size="small"
/>
</div>
</a>
</div>
</div>
</mat-card-content>
</mat-card>
@if (hasPermissionForSubscription) {
<mat-card appearance="outlined" class="mb-3">
<mat-card-content class="p-0">

2
apps/client/src/app/pages/faq/overview/faq-overview-page.component.ts

@ -11,7 +11,7 @@ import { Subject, takeUntil } from 'rxjs';
templateUrl: './faq-overview-page.html'
})
export class FaqOverviewPageComponent implements OnDestroy {
public routerLinkFeatures = ['/' + $localize`features`];
public routerLinkFeatures = ['/' + $localize`:snake-case:features`];
public user: User;
private unsubscribeSubject = new Subject<void>();

6
apps/client/src/app/pages/faq/saas/saas-page.component.ts

@ -11,9 +11,9 @@ import { Subject, takeUntil } from 'rxjs';
templateUrl: './saas-page.html'
})
export class SaasPageComponent implements OnDestroy {
public routerLinkMarkets = ['/' + $localize`markets`];
public routerLinkPricing = ['/' + $localize`pricing`];
public routerLinkRegister = ['/' + $localize`register`];
public routerLinkMarkets = ['/' + $localize`:snake-case:markets`];
public routerLinkPricing = ['/' + $localize`:snake-case:pricing`];
public routerLinkRegister = ['/' + $localize`:snake-case:register`];
public user: User;
private unsubscribeSubject = new Subject<void>();

4
apps/client/src/app/pages/features/features-page.component.ts

@ -26,8 +26,8 @@ import { Subject, takeUntil } from 'rxjs';
export class GfFeaturesPageComponent implements OnDestroy {
public hasPermissionForSubscription: boolean;
public info: InfoItem;
public routerLinkRegister = ['/' + $localize`register`];
public routerLinkResources = ['/' + $localize`resources`];
public routerLinkRegister = ['/' + $localize`:snake-case:register`];
public routerLinkResources = ['/' + $localize`:snake-case:resources`];
public user: User;
private unsubscribeSubject = new Subject<void>();

4
apps/client/src/app/pages/landing/landing-page.component.ts

@ -23,8 +23,8 @@ export class LandingPageComponent implements OnDestroy, OnInit {
public hasPermissionForStatistics: boolean;
public hasPermissionForSubscription: boolean;
public hasPermissionToCreateUser: boolean;
public routerLinkAbout = ['/' + $localize`about`];
public routerLinkRegister = ['/' + $localize`register`];
public routerLinkAbout = ['/' + $localize`:snake-case:about`];
public routerLinkRegister = ['/' + $localize`:snake-case:register`];
public statistics: Statistics;
public testimonials = [
{

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

@ -33,8 +33,8 @@ export class PricingPageComponent implements OnDestroy, OnInit {
public isLoggedIn: boolean;
public price: number;
public priceId: string;
public routerLinkFeatures = ['/' + $localize`features`];
public routerLinkRegister = ['/' + $localize`register`];
public routerLinkFeatures = ['/' + $localize`:snake-case:features`];
public routerLinkRegister = ['/' + $localize`:snake-case:register`];
public user: User;
private unsubscribeSubject = new Subject<void>();

2
apps/client/src/app/pages/resources/personal-finance-tools/personal-finance-tools-page.component.ts

@ -15,7 +15,7 @@ export class PersonalFinanceToolsPageComponent implements OnDestroy {
public personalFinanceTools = personalFinanceTools.sort((a, b) => {
return a.name.localeCompare(b.name, undefined, { sensitivity: 'base' });
});
public routerLinkAbout = ['/' + $localize`about`];
public routerLinkAbout = ['/' + $localize`:snake-case:about`];
private unsubscribeSubject = new Subject<void>();

6
apps/client/src/app/pages/resources/personal-finance-tools/product-page.component.ts

@ -21,10 +21,10 @@ export class GfProductPageComponent implements OnInit {
public price: number;
public product1: Product;
public product2: Product;
public routerLinkAbout = ['/' + $localize`about`];
public routerLinkFeatures = ['/' + $localize`features`];
public routerLinkAbout = ['/' + $localize`:snake-case:about`];
public routerLinkFeatures = ['/' + $localize`:snake-case:features`];
public routerLinkResourcesPersonalFinanceTools = [
'/' + $localize`resources`,
'/' + $localize`:snake-case:resources`,
'personal-finance-tools'
];
public tags: string[];

4
apps/client/src/app/pages/resources/resources-page.component.ts

@ -14,9 +14,9 @@ import { Subject } from 'rxjs';
export class ResourcesPageComponent implements OnInit {
public hasPermissionForSubscription: boolean;
public info: InfoItem;
public routerLinkFaq = ['/' + $localize`faq`];
public routerLinkFaq = ['/' + $localize`:snake-case:faq`];
public routerLinkResourcesPersonalFinanceTools = [
'/' + $localize`resources`,
'/' + $localize`:snake-case:resources`,
'personal-finance-tools'
];

BIN
apps/client/src/assets/images/blog/hacktoberfest-2024.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

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

File diff suppressed because it is too large

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

File diff suppressed because it is too large

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

File diff suppressed because it is too large

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

File diff suppressed because it is too large

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

File diff suppressed because it is too large

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

File diff suppressed because it is too large

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

File diff suppressed because it is too large

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

File diff suppressed because it is too large

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

File diff suppressed because it is too large

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

@ -4,21 +4,22 @@
<body>
<trans-unit id="8379314117913380516" datatype="html">
<source>about</source>
<note priority="1" from="description">snake-case</note>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/app.component.ts</context>
<context context-type="linenumber">60</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/app.component.ts</context>
<context context-type="linenumber">61</context>
<context context-type="linenumber">62</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/app.component.ts</context>
<context context-type="linenumber">62</context>
<context context-type="linenumber">66</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/app.component.ts</context>
<context context-type="linenumber">64</context>
<context context-type="linenumber">70</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/header/header.component.ts</context>
@ -54,7 +55,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/blog/2023/08/ghostfolio-joins-oss-friends/ghostfolio-joins-oss-friends-page.component.ts</context>
<context context-type="linenumber">13</context>
<context context-type="linenumber">14</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/blog/2023/09/ghostfolio-2/ghostfolio-2-page.component.ts</context>
@ -62,7 +63,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/blog/2023/09/ghostfolio-2/ghostfolio-2-page.component.ts</context>
<context context-type="linenumber">14</context>
<context context-type="linenumber">15</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/blog/2023/09/hacktoberfest-2023/hacktoberfest-2023-page.component.ts</context>
@ -87,9 +88,10 @@
</trans-unit>
<trans-unit id="4656883433287439415" datatype="html">
<source>faq</source>
<note priority="1" from="description">snake-case</note>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/app.component.ts</context>
<context context-type="linenumber">67</context>
<context context-type="linenumber">73</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/core/paths.ts</context>
@ -118,9 +120,10 @@
</trans-unit>
<trans-unit id="6703761340382395781" datatype="html">
<source>features</source>
<note priority="1" from="description">snake-case</note>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/app.component.ts</context>
<context context-type="linenumber">68</context>
<context context-type="linenumber">74</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/header/header.component.ts</context>
@ -156,7 +159,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/blog/2023/09/ghostfolio-2/ghostfolio-2-page.component.ts</context>
<context context-type="linenumber">15</context>
<context context-type="linenumber">18</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/blog/2023/11/black-week-2023/black-week-2023-page.component.ts</context>
@ -181,9 +184,10 @@
</trans-unit>
<trans-unit id="6099902667884446960" datatype="html">
<source>license</source>
<note priority="1" from="description">snake-case</note>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/app.component.ts</context>
<context context-type="linenumber">62</context>
<context context-type="linenumber">67</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/core/paths.ts</context>
@ -196,9 +200,10 @@
</trans-unit>
<trans-unit id="8566970793924820888" datatype="html">
<source>markets</source>
<note priority="1" from="description">snake-case</note>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/app.component.ts</context>
<context context-type="linenumber">69</context>
<context context-type="linenumber">75</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/header/header.component.ts</context>
@ -218,7 +223,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/blog/2023/09/ghostfolio-2/ghostfolio-2-page.component.ts</context>
<context context-type="linenumber">16</context>
<context context-type="linenumber">19</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/faq/saas/saas-page.component.ts</context>
@ -227,9 +232,10 @@
</trans-unit>
<trans-unit id="9167640275204796639" datatype="html">
<source>pricing</source>
<note priority="1" from="description">snake-case</note>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/app.component.ts</context>
<context context-type="linenumber">70</context>
<context context-type="linenumber">76</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/header/header.component.ts</context>
@ -294,9 +300,10 @@
</trans-unit>
<trans-unit id="6948811958230386934" datatype="html">
<source>privacy-policy</source>
<note priority="1" from="description">snake-case</note>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/app.component.ts</context>
<context context-type="linenumber">65</context>
<context context-type="linenumber">71</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/core/paths.ts</context>
@ -309,9 +316,10 @@
</trans-unit>
<trans-unit id="5915338689523424386" datatype="html">
<source>register</source>
<note priority="1" from="description">snake-case</note>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/app.component.ts</context>
<context context-type="linenumber">71</context>
<context context-type="linenumber">77</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/header/header.component.ts</context>
@ -344,9 +352,10 @@
</trans-unit>
<trans-unit id="4002166200801232073" datatype="html">
<source>resources</source>
<note priority="1" from="description">snake-case</note>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/app.component.ts</context>
<context context-type="linenumber">72</context>
<context context-type="linenumber">78</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/header/header.component.ts</context>
@ -695,7 +704,7 @@
<source>The risk of loss in trading can be substantial. It is not advisable to invest money you may need in the short term.</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/app.component.html</context>
<context context-type="linenumber">199</context>
<context context-type="linenumber">197</context>
</context-group>
</trans-unit>
<trans-unit id="fbaaeb297e70b9a800acf841b9d26c19d60651ef" datatype="html">
@ -746,21 +755,21 @@
<source>Revoke</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/access-table/access-table.component.html</context>
<context context-type="linenumber">62</context>
<context context-type="linenumber">65</context>
</context-group>
</trans-unit>
<trans-unit id="8264698726451826067" datatype="html">
<source>Do you really want to revoke this granted access?</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/access-table/access-table.component.ts</context>
<context context-type="linenumber">56</context>
<context context-type="linenumber">68</context>
</context-group>
</trans-unit>
<trans-unit id="237bd6e6d07f448b7884f05f56a20e30df8622c4" datatype="html">
<source>Cash Balance</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/account-detail-dialog/account-detail-dialog.html</context>
<context context-type="linenumber">45</context>
<context context-type="linenumber">47</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/accounts-table/accounts-table.component.html</context>
@ -775,18 +784,18 @@
<source>Equity</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/account-detail-dialog/account-detail-dialog.html</context>
<context context-type="linenumber">56</context>
<context context-type="linenumber">58</context>
</context-group>
</trans-unit>
<trans-unit id="dd3b6c367381ddfa8f317b8e9b31c55368c65136" datatype="html">
<source>Activities</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/account-detail-dialog/account-detail-dialog.html</context>
<context context-type="linenumber">61</context>
<context context-type="linenumber">63</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/account-detail-dialog/account-detail-dialog.html</context>
<context context-type="linenumber">90</context>
<context context-type="linenumber">92</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/accounts-table/accounts-table.component.html</context>
@ -806,11 +815,11 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html</context>
<context context-type="linenumber">225</context>
<context context-type="linenumber">209</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html</context>
<context context-type="linenumber">335</context>
<context context-type="linenumber">319</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/activities/activities-page.html</context>
@ -821,7 +830,7 @@
<source>Platform</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/account-detail-dialog/account-detail-dialog.html</context>
<context context-type="linenumber">65</context>
<context context-type="linenumber">67</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/accounts-table/accounts-table.component.html</context>
@ -836,7 +845,7 @@
<source>Cash Balances</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/account-detail-dialog/account-detail-dialog.html</context>
<context context-type="linenumber">122</context>
<context context-type="linenumber">124</context>
</context-group>
</trans-unit>
<trans-unit id="4b00337456de4a757f7abc8224d8b391f5d0634a" datatype="html">
@ -1006,7 +1015,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">215</context>
<context context-type="linenumber">230</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-overview/admin-overview.html</context>
@ -1033,7 +1042,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">236</context>
<context context-type="linenumber">251</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
@ -1089,7 +1098,7 @@
<source>Symbol</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-jobs/admin-jobs.html</context>
<context context-type="linenumber">44</context>
<context context-type="linenumber">46</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
@ -1105,14 +1114,14 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html</context>
<context context-type="linenumber">305</context>
<context context-type="linenumber">289</context>
</context-group>
</trans-unit>
<trans-unit id="1b6bc6d5daaa6ec75d201690bb6f782f30bf98a0" datatype="html">
<source>Data Source</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-jobs/admin-jobs.html</context>
<context context-type="linenumber">53</context>
<context context-type="linenumber">55</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
@ -1131,56 +1140,56 @@
<source>Attempts</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-jobs/admin-jobs.html</context>
<context context-type="linenumber">81</context>
<context context-type="linenumber">83</context>
</context-group>
</trans-unit>
<trans-unit id="1b051734b0ee9021991c91b3ed4e81c244322462" datatype="html">
<source>Created</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-jobs/admin-jobs.html</context>
<context context-type="linenumber">90</context>
<context context-type="linenumber">92</context>
</context-group>
</trans-unit>
<trans-unit id="edcc19a49c950289ffe5d38be4843cdf194e5622" datatype="html">
<source>Finished</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-jobs/admin-jobs.html</context>
<context context-type="linenumber">99</context>
<context context-type="linenumber">101</context>
</context-group>
</trans-unit>
<trans-unit id="81b97b8ea996ad1e4f9fca8415021850214884b1" datatype="html">
<source>Status</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-jobs/admin-jobs.html</context>
<context context-type="linenumber">108</context>
<context context-type="linenumber">110</context>
</context-group>
</trans-unit>
<trans-unit id="056853138da25939da59abfb432ed2316fe50934" datatype="html">
<source>Delete Jobs</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-jobs/admin-jobs.html</context>
<context context-type="linenumber">149</context>
<context context-type="linenumber">151</context>
</context-group>
</trans-unit>
<trans-unit id="30afc50625f30e4ac97acc23fd7e77031a341a8f" datatype="html">
<source>View Data</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-jobs/admin-jobs.html</context>
<context context-type="linenumber">164</context>
<context context-type="linenumber">166</context>
</context-group>
</trans-unit>
<trans-unit id="94e6ec0f0d021b88dfa4ef191447315fc1898f00" datatype="html">
<source>View Stacktrace</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-jobs/admin-jobs.html</context>
<context context-type="linenumber">171</context>
<context context-type="linenumber">173</context>
</context-group>
</trans-unit>
<trans-unit id="de50f7bcb18ed16c00012741202155acb5c61acf" datatype="html">
<source>Delete Job</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-jobs/admin-jobs.html</context>
<context context-type="linenumber">177</context>
<context context-type="linenumber">179</context>
</context-group>
</trans-unit>
<trans-unit id="bfb6a28329c452254e363723ef9718b5178dfd1d" datatype="html">
@ -1215,9 +1224,13 @@
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data-detail/market-data-detail-dialog/market-data-detail-dialog.html</context>
<context context-type="linenumber">26</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">104</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html</context>
<context context-type="linenumber">114</context>
<context context-type="linenumber">98</context>
</context-group>
</trans-unit>
<trans-unit id="d7b35c384aecd25a516200d6921836374613dfe7" datatype="html">
@ -1285,6 +1298,10 @@
<context context-type="sourcefile">apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html</context>
<context context-type="linenumber">32</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/rule/rule-settings-dialog/rule-settings-dialog.html</context>
<context context-type="linenumber">21</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html</context>
<context context-type="linenumber">65</context>
@ -1330,7 +1347,7 @@
<source>Filter by...</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">328</context>
<context context-type="linenumber">329</context>
</context-group>
</trans-unit>
<trans-unit id="584c9433705e9bfdd2e7a9f0192690f453d36196" datatype="html">
@ -1349,7 +1366,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html</context>
<context context-type="linenumber">232</context>
<context context-type="linenumber">216</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>
@ -1372,7 +1389,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html</context>
<context context-type="linenumber">241</context>
<context context-type="linenumber">225</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>
@ -1383,7 +1400,7 @@
<source>First Activity</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">104</context>
<context context-type="linenumber">119</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
@ -1391,7 +1408,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html</context>
<context context-type="linenumber">213</context>
<context context-type="linenumber">197</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/holdings-table/holdings-table.component.html</context>
@ -1402,14 +1419,14 @@
<source>Activities Count</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">113</context>
<context context-type="linenumber">128</context>
</context-group>
</trans-unit>
<trans-unit id="5eebcc824c2d34b17abba8c9ef718c5ce118a5c8" datatype="html">
<source>Historical Data</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">122</context>
<context context-type="linenumber">137</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
@ -1420,35 +1437,35 @@
<source>Sectors Count</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">131</context>
<context context-type="linenumber">146</context>
</context-group>
</trans-unit>
<trans-unit id="aad5320acd7453f912bc8714e72c2fa71e8ab18e" datatype="html">
<source>Countries Count</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">140</context>
<context context-type="linenumber">155</context>
</context-group>
</trans-unit>
<trans-unit id="5067ede95804e0e0e2b078747848367a7373cc9b" datatype="html">
<source>Gather Recent Data</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">177</context>
<context context-type="linenumber">192</context>
</context-group>
</trans-unit>
<trans-unit id="27e27f3f7338baefacfd5668bad03ece9c5955df" datatype="html">
<source>Gather All Data</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">180</context>
<context context-type="linenumber">195</context>
</context-group>
</trans-unit>
<trans-unit id="cc65b67b46b69cf06ff1f16a909e61612c9d57b8" datatype="html">
<source>Gather Profile Data</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">183</context>
<context context-type="linenumber">198</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
@ -1499,7 +1516,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html</context>
<context context-type="linenumber">258</context>
<context context-type="linenumber">242</context>
</context-group>
</trans-unit>
<trans-unit id="a43f25a9ac40e8e2441ff0be7a36b8e5d15534df" datatype="html">
@ -1514,7 +1531,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html</context>
<context context-type="linenumber">268</context>
<context context-type="linenumber">252</context>
</context-group>
</trans-unit>
<trans-unit id="fc61416d48adb7af122b8697e806077eb251fb57" datatype="html">
@ -1529,7 +1546,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html</context>
<context context-type="linenumber">274</context>
<context context-type="linenumber">258</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/public/public-page.html</context>
@ -1548,7 +1565,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html</context>
<context context-type="linenumber">286</context>
<context context-type="linenumber">270</context>
</context-group>
</trans-unit>
<trans-unit id="0b05507801c7eca260d8978c36621e826f07aaaa" datatype="html">
@ -1812,7 +1829,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html</context>
<context context-type="linenumber">368</context>
<context context-type="linenumber">352</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/accounts/accounts-page.html</context>
@ -1859,11 +1876,11 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html</context>
<context context-type="linenumber">393</context>
<context context-type="linenumber">377</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html</context>
<context context-type="linenumber">430</context>
<context context-type="linenumber">414</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>
@ -1906,7 +1923,7 @@
<source>Do you really want to delete this user?</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-users/admin-users.component.ts</context>
<context context-type="linenumber">125</context>
<context context-type="linenumber">126</context>
</context-group>
</trans-unit>
<trans-unit id="a3db2898b85fed425f03294b839a98cef247a2dc" datatype="html">
@ -1957,10 +1974,6 @@
<context context-type="sourcefile">apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.html</context>
<context context-type="linenumber">6</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html</context>
<context context-type="linenumber">91</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/holdings-table/holdings-table.component.html</context>
<context context-type="linenumber">142</context>
@ -2100,18 +2113,18 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/header/header.component.ts</context>
<context context-type="linenumber">231</context>
<context context-type="linenumber">227</context>
</context-group>
</trans-unit>
<trans-unit id="9066319854608270526" datatype="html">
<source>Oops! Incorrect Security Token.</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/header/header.component.ts</context>
<context context-type="linenumber">246</context>
<context context-type="linenumber">242</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/user-account-settings/user-account-settings.component.ts</context>
<context context-type="linenumber">159</context>
<context context-type="linenumber">157</context>
</context-group>
</trans-unit>
<trans-unit id="ec8b93e2ecc776c8dc2e43a791b6974612a90148" datatype="html">
@ -2333,7 +2346,7 @@
<source>Investment</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html</context>
<context context-type="linenumber">168</context>
<context context-type="linenumber">152</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html</context>
@ -2347,22 +2360,15 @@
<context context-type="linenumber">70</context>
</context-group>
</trans-unit>
<trans-unit id="a1cfd95460b49b8cfa6c34f0c673715044bcde14" datatype="html">
<source>Gross Performance</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html</context>
<context context-type="linenumber">85</context>
</context-group>
</trans-unit>
<trans-unit id="c20172223f84462032664d717d739297e5a9e2fe" datatype="html">
<source>Fees</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html</context>
<context context-type="linenumber">203</context>
<context context-type="linenumber">187</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html</context>
<context context-type="linenumber">108</context>
<context context-type="linenumber">84</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/fire/fire-page.html</context>
@ -2373,35 +2379,35 @@
<source>Absolute Net Performance</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html</context>
<context context-type="linenumber">126</context>
<context context-type="linenumber">102</context>
</context-group>
</trans-unit>
<trans-unit id="26de2fb4d52a11f78e22587a48690cba0fc6fa58" datatype="html">
<source>Net Performance</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html</context>
<context context-type="linenumber">141</context>
<context context-type="linenumber">117</context>
</context-group>
</trans-unit>
<trans-unit id="f159ffb7a09c8c1fe7913ef063462db50ddcd878" datatype="html">
<source>Total Assets</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html</context>
<context context-type="linenumber">167</context>
<context context-type="linenumber">143</context>
</context-group>
</trans-unit>
<trans-unit id="59d87bdb983dda90c1e86d086430552ec05c7a4d" datatype="html">
<source>Valuables</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html</context>
<context context-type="linenumber">180</context>
<context context-type="linenumber">156</context>
</context-group>
</trans-unit>
<trans-unit id="2201b2004bc4997a66f6f8ea2511a4e1311f3de1" datatype="html">
<source>Emergency Fund</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html</context>
<context context-type="linenumber">192</context>
<context context-type="linenumber">168</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/features/features-page.html</context>
@ -2416,35 +2422,35 @@
<source>Cash</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html</context>
<context context-type="linenumber">226</context>
<context context-type="linenumber">202</context>
</context-group>
</trans-unit>
<trans-unit id="ee8f8008bae6ce3a49840c4e1d39b4af23d4c263" datatype="html">
<source>Assets</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html</context>
<context context-type="linenumber">239</context>
<context context-type="linenumber">215</context>
</context-group>
</trans-unit>
<trans-unit id="8cce9d03787606e0052d19c2ae7e7fa5ff785e94" datatype="html">
<source>Buying Power</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html</context>
<context context-type="linenumber">252</context>
<context context-type="linenumber">228</context>
</context-group>
</trans-unit>
<trans-unit id="98fc3013bfcbf452b9f37bbfcdb77b9b882866e3" datatype="html">
<source>Excluded from Analysis</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html</context>
<context context-type="linenumber">264</context>
<context context-type="linenumber">240</context>
</context-group>
</trans-unit>
<trans-unit id="0b1e2c97e139808a34bd77b7da3504ece6c570cb" datatype="html">
<source>Liabilities</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html</context>
<context context-type="linenumber">279</context>
<context context-type="linenumber">255</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/features/features-page.html</context>
@ -2455,32 +2461,32 @@
<source>Net Worth</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html</context>
<context context-type="linenumber">297</context>
<context context-type="linenumber">273</context>
</context-group>
</trans-unit>
<trans-unit id="e702514cebbfb335331b6d6156ffeacb8c3b14e4" datatype="html">
<source> Annualized Performance </source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html</context>
<context context-type="linenumber">309</context>
<context context-type="linenumber">285</context>
</context-group>
</trans-unit>
<trans-unit id="fe788dd32538034a1afe978e956f3d2403e2df83" datatype="html">
<source>Interest</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html</context>
<context context-type="linenumber">331</context>
<context context-type="linenumber">307</context>
</context-group>
</trans-unit>
<trans-unit id="d3aa83bd247983dd056a62f56ffb25269bd98d47" datatype="html">
<source>Dividend</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html</context>
<context context-type="linenumber">181</context>
<context context-type="linenumber">165</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html</context>
<context context-type="linenumber">343</context>
<context context-type="linenumber">319</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/features/features-page.html</context>
@ -2504,10 +2510,6 @@
</trans-unit>
<trans-unit id="024cdb2814b0cb3f4ced148f1a0b9854447cb214" datatype="html">
<source>Change</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html</context>
<context context-type="linenumber">65</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/holdings-table/holdings-table.component.html</context>
<context context-type="linenumber">119</context>
@ -2517,28 +2519,28 @@
<source>Average Unit Price</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html</context>
<context context-type="linenumber">103</context>
<context context-type="linenumber">87</context>
</context-group>
</trans-unit>
<trans-unit id="b1c1c6a43da1ad3e41b7a6e3aa5dcc24226cf580" datatype="html">
<source>Minimum Price</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html</context>
<context context-type="linenumber">130</context>
<context context-type="linenumber">114</context>
</context-group>
</trans-unit>
<trans-unit id="6dd84054c52e1edf631f37accb054de0c4071069" datatype="html">
<source>Maximum Price</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html</context>
<context context-type="linenumber">146</context>
<context context-type="linenumber">130</context>
</context-group>
</trans-unit>
<trans-unit id="ca30c1aa79fb5ab487fbd2caa4ca01f2f6691d70" datatype="html">
<source>Quantity</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html</context>
<context context-type="linenumber">156</context>
<context context-type="linenumber">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>
@ -2553,7 +2555,7 @@
<source>Report Data Glitch</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html</context>
<context context-type="linenumber">448</context>
<context context-type="linenumber">433</context>
</context-group>
</trans-unit>
<trans-unit id="280c5b1f5b5b748fbbb37bf7a12c37f41539c1ff" datatype="html">
@ -2734,7 +2736,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/assistant/assistant.component.ts</context>
<context context-type="linenumber">250</context>
<context context-type="linenumber">251</context>
</context-group>
</trans-unit>
<trans-unit id="3667949571823271511" datatype="html">
@ -2745,7 +2747,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/assistant/assistant.component.ts</context>
<context context-type="linenumber">253</context>
<context context-type="linenumber">254</context>
</context-group>
</trans-unit>
<trans-unit id="5e41f1b4c46ad9e0a9bc83fa36445483aa5cc324" datatype="html">
@ -2833,7 +2835,7 @@
<source>Do you really want to remove this sign in method?</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/user-account-settings/user-account-settings.component.ts</context>
<context context-type="linenumber">252</context>
<context context-type="linenumber">246</context>
</context-group>
</trans-unit>
<trans-unit id="121cc5391cd2a5115bc2b3160379ee5b36cd7716" datatype="html">
@ -2996,7 +2998,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts</context>
<context context-type="linenumber">138</context>
<context context-type="linenumber">142</context>
</context-group>
</trans-unit>
<trans-unit id="7224997887539831269" datatype="html">
@ -3007,7 +3009,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts</context>
<context context-type="linenumber">136</context>
<context context-type="linenumber">140</context>
</context-group>
</trans-unit>
<trans-unit id="1579692722565712588" datatype="html">
@ -3018,7 +3020,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts</context>
<context context-type="linenumber">139</context>
<context context-type="linenumber">143</context>
</context-group>
</trans-unit>
<trans-unit id="1726363342938046830" datatype="html">
@ -3803,7 +3805,7 @@
<source>Do you really want to delete these activities?</source>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/activities-table/activities-table.component.ts</context>
<context context-type="linenumber">225</context>
<context context-type="linenumber">223</context>
</context-group>
</trans-unit>
<trans-unit id="72ba3bcdd8350cb8bf462e217a28ec7f7a48bb44" datatype="html">
@ -3939,21 +3941,21 @@
<source>Importing data...</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts</context>
<context context-type="linenumber">120</context>
<context context-type="linenumber">124</context>
</context-group>
</trans-unit>
<trans-unit id="7500216440144530775" datatype="html">
<source>Import has been completed</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts</context>
<context context-type="linenumber">128</context>
<context context-type="linenumber">132</context>
</context-group>
</trans-unit>
<trans-unit id="8763985977445247551" datatype="html">
<source>Validating data...</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts</context>
<context context-type="linenumber">234</context>
<context context-type="linenumber">238</context>
</context-group>
</trans-unit>
<trans-unit id="4de7b521c9a386fa682d6c995b30f6bc2d6c14b8" datatype="html">
@ -4329,7 +4331,7 @@
<source>Holdings</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/account-detail-dialog/account-detail-dialog.html</context>
<context context-type="linenumber">77</context>
<context context-type="linenumber">79</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/home-holdings/home-holdings.html</context>
@ -5045,7 +5047,7 @@
<source>Do you really want to delete this activity?</source>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/activities-table/activities-table.component.ts</context>
<context context-type="linenumber">235</context>
<context context-type="linenumber">233</context>
</context-group>
</trans-unit>
<trans-unit id="4149127798893455354" datatype="html">
@ -5789,7 +5791,7 @@
<source>years</source>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/assistant/assistant.component.ts</context>
<context context-type="linenumber">250</context>
<context context-type="linenumber">251</context>
</context-group>
</trans-unit>
<trans-unit id="73864299814955e733ade6e3e7204548b7b9adae" datatype="html">
@ -5892,21 +5894,21 @@
<source>Activity</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html</context>
<context context-type="linenumber">223</context>
<context context-type="linenumber">207</context>
</context-group>
</trans-unit>
<trans-unit id="00ab08d0337ad99d0fabd37b521f8908a33f8550" datatype="html">
<source>Dividend Yield</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html</context>
<context context-type="linenumber">191</context>
<context context-type="linenumber">175</context>
</context-group>
</trans-unit>
<trans-unit id="c356d831858fd8fed753c149088c800e36b36d84" datatype="html">
<source>Execute Job</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-jobs/admin-jobs.html</context>
<context context-type="linenumber">174</context>
<context context-type="linenumber">176</context>
</context-group>
</trans-unit>
<trans-unit id="8236987838684066590" datatype="html">
@ -5920,7 +5922,7 @@
<source>Priority</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-jobs/admin-jobs.html</context>
<context context-type="linenumber">62</context>
<context context-type="linenumber">64</context>
</context-group>
</trans-unit>
<trans-unit id="67933701892581429" datatype="html">
@ -5930,20 +5932,6 @@
<context context-type="linenumber">47</context>
</context-group>
</trans-unit>
<trans-unit id="220d94c89713386f9003dfa237262d17a2cb1c0d" datatype="html">
<source>Change with currency effect</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html</context>
<context context-type="linenumber">53</context>
</context-group>
</trans-unit>
<trans-unit id="f6b690ad88cca4208035a1be392f327d9a2405ac" datatype="html">
<source>Performance with currency effect</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html</context>
<context context-type="linenumber">81</context>
</context-group>
</trans-unit>
<trans-unit id="8903954975609359428" datatype="html">
<source>Buy and sell</source>
<context-group purpose="location">
@ -5983,7 +5971,7 @@
<source>Do you really want to close your Ghostfolio account?</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/user-account-settings/user-account-settings.component.ts</context>
<context context-type="linenumber">174</context>
<context context-type="linenumber">172</context>
</context-group>
</trans-unit>
<trans-unit id="85614ebfd89fe16873dfcf593a05f18b7468daac" datatype="html">
@ -6018,7 +6006,7 @@
<source>Oops! There was an error setting up biometric authentication.</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/user-account-settings/user-account-settings.component.ts</context>
<context context-type="linenumber">308</context>
<context context-type="linenumber">300</context>
</context-group>
</trans-unit>
<trans-unit id="f0c5f6f270e70cbe063b5368fcf48f9afc1abd9b" datatype="html">
@ -6039,7 +6027,7 @@
<source>Delete Profiles</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">190</context>
<context context-type="linenumber">205</context>
</context-group>
</trans-unit>
<trans-unit id="8127349194179456616" datatype="html">
@ -6340,16 +6328,72 @@
<source>Activate</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/rule/rule.component.html</context>
<context context-type="linenumber">69</context>
<context context-type="linenumber">74</context>
</context-group>
</trans-unit>
<trans-unit id="c95505b5a74151a0c235b19b9c41db7983205ba7" datatype="html">
<source>Deactivate</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/rule/rule.component.html</context>
<context context-type="linenumber">72</context>
</context-group>
</trans-unit>
<trans-unit id="012b48ee5281a77c66760b2007c3ccd7e34aa340" datatype="html">
<source>Threshold Max</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/rule/rule-settings-dialog/rule-settings-dialog.html</context>
<context context-type="linenumber">9</context>
</context-group>
</trans-unit>
<trans-unit id="072d4d4ec83a5a97345a1c13b90c213b47326d09" datatype="html">
<source>Customize</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/rule/rule.component.html</context>
<context context-type="linenumber">67</context>
</context-group>
</trans-unit>
<trans-unit id="306e3758e5303c780f0984c003e6283d49796f79" datatype="html">
<source>Portfolio Snapshot</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-jobs/admin-jobs.html</context>
<context context-type="linenumber">39</context>
</context-group>
</trans-unit>
<trans-unit id="5502bf2eace842803c7b3f5ce5f600e102d3424a" datatype="html">
<source>Threshold Min</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/rule/rule-settings-dialog/rule-settings-dialog.html</context>
<context context-type="linenumber">5</context>
</context-group>
</trans-unit>
<trans-unit id="65ff514a2e167229e1a34b3712f2cf2908576d0f" datatype="html">
<source><x id="START_BLOCK_IF" equiv-text="Currency !== SymbolProfile?.currency ) {"/> Performance with currency effect <x id="CLOSE_BLOCK_IF" equiv-text="}"/><x id="START_BLOCK_ELSE" equiv-text="@else {"/> Performance <x id="CLOSE_BLOCK_ELSE" equiv-text="}"/></source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html</context>
<context context-type="linenumber">69</context>
</context-group>
</trans-unit>
<trans-unit id="665692df9ab12bc228c1276f7d04e97902ff9afc" datatype="html">
<source>Copy link to clipboard</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/access-table/access-table.component.html</context>
<context context-type="linenumber">61</context>
</context-group>
</trans-unit>
<trans-unit id="76897e07c5670ce3b7710cc10c5e1c08b5f6a83a" datatype="html">
<source><x id="START_BLOCK_IF" equiv-text="Currency !== SymbolProfile?.currency ) {"/> Change with currency effect <x id="CLOSE_BLOCK_IF" equiv-text="}"/><x id="START_BLOCK_ELSE" equiv-text="@else {"/> Change <x id="CLOSE_BLOCK_ELSE" equiv-text="}"/></source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html</context>
<context context-type="linenumber">50</context>
</context-group>
</trans-unit>
<trans-unit id="f4e529ae5ffd73001d1ff4bbdeeb0a72e342e5c8" datatype="html">
<source>Close</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/rule/rule-settings-dialog/rule-settings-dialog.html</context>
<context context-type="linenumber">15</context>
</context-group>
</trans-unit>
</body>
</file>
</xliff>

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

File diff suppressed because it is too large

2
libs/ui/src/lib/membership-card/membership-card.component.ts

@ -22,5 +22,5 @@ export class GfMembershipCardComponent {
@Input() public expiresAt: string;
@Input() public name: string;
public routerLinkPricing = ['/' + $localize`pricing`];
public routerLinkPricing = ['/' + $localize`:snake-case:pricing`];
}

2
package.json

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

Loading…
Cancel
Save