Browse Source

Task/extend personal finance tools (20260705) (#7240)

Extend personal finance tools with categories and platforms
pull/7239/head
Thomas Kaul 1 week ago
committed by GitHub
parent
commit
baf9d8b894
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 32
      apps/client/src/app/pages/resources/personal-finance-tools/product-page.component.ts
  2. 44
      apps/client/src/app/pages/resources/personal-finance-tools/product-page.html
  3. 273
      libs/common/src/lib/personal-finance-tools.ts
  4. 33
      libs/ui/src/lib/i18n.ts

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

@ -29,6 +29,7 @@ export class GfProductPageComponent {
});
protected readonly product1 = computed<Product>(() => ({
categories: ['FINANCIAL_PLANNING', 'NET_WORTH_TRACKING', 'STOCK_TRACKING'],
founded: 2021,
hasFreePlan: true,
hasSelfHostingAbility: true,
@ -49,6 +50,7 @@ export class GfProductPageComponent {
],
name: 'Ghostfolio',
origin: getCountryName({ code: 'CH' }),
platforms: ['ANDROID', 'WEB'],
regions: [$localize`Global`],
slogan: 'Open Source Wealth Management',
useAnonymously: true
@ -89,39 +91,47 @@ export class GfProductPageComponent {
const product1 = this.product1();
const product2 = this.product2();
return Array.from(
new Set(
[
...[product1, product2].flatMap(
({ categories, name, origin, platforms }) => {
return [
product1.name,
product1.origin,
product2.name,
product2.origin,
...[...(categories ?? []), ...(platforms ?? [])].map((key) => {
return translate(key);
}),
name,
origin
];
}
),
$localize`Alternative`,
$localize`App`,
$localize`Budgeting`,
$localize`Community`,
$localize`Family Office`,
`Fintech`,
$localize`Investment`,
$localize`Investor`,
$localize`Open Source`,
`OSS`,
$localize`Personal Finance`,
$localize`Privacy`,
$localize`Portfolio`,
$localize`Privacy`,
$localize`Software`,
$localize`Tool`,
$localize`User Experience`,
$localize`Wealth`,
$localize`Wealth Management`,
`WealthTech`
]
.filter((item): item is string => {
].filter((item): item is string => {
return !!item;
})
.sort((a, b) => {
)
).sort((a, b) => {
return a.localeCompare(b, undefined, { sensitivity: 'base' });
});
});
protected readonly translate = translate;
private readonly dataService = inject(DataService);
private readonly route = inject(ActivatedRoute);
}

44
apps/client/src/app/pages/resources/personal-finance-tools/product-page.html

@ -73,6 +73,27 @@
<td class="mat-mdc-cell px-1 py-2">{{ product1().slogan }}</td>
<td class="mat-mdc-cell px-1 py-2">{{ product2().slogan }}</td>
</tr>
<tr class="mat-mdc-row">
<td class="mat-mdc-cell px-3 py-2 text-right" i18n>Category</td>
<td class="mat-mdc-cell px-1 py-2">
@for (
category of product1().categories;
track category;
let isLast = $last
) {
{{ translate(category) }}{{ isLast ? '' : ', ' }}
}
</td>
<td class="mat-mdc-cell px-1 py-2">
@for (
category of product2().categories;
track category;
let isLast = $last
) {
{{ translate(category) }}{{ isLast ? '' : ', ' }}
}
</td>
</tr>
<tr class="mat-mdc-row">
<td class="mat-mdc-cell px-3 py-2 text-right" i18n>Founded</td>
<td class="mat-mdc-cell px-1 py-2">{{ product1().founded }}</td>
@ -104,6 +125,29 @@
}
</td>
</tr>
<tr class="mat-mdc-row">
<td class="mat-mdc-cell px-3 py-2 text-right" i18n>
Available on
</td>
<td class="mat-mdc-cell px-1 py-2">
@for (
platform of product1().platforms;
track platform;
let isLast = $last
) {
{{ translate(platform) }}{{ isLast ? '' : ', ' }}
}
</td>
<td class="mat-mdc-cell px-1 py-2">
@for (
platform of product2().platforms;
track platform;
let isLast = $last
) {
{{ translate(platform) }}{{ isLast ? '' : ', ' }}
}
</td>
</tr>
<tr class="mat-mdc-row">
<td class="mat-mdc-cell px-3 py-2 text-right" i18n>
Available in

273
libs/common/src/lib/personal-finance-tools.ts

File diff suppressed because it is too large

33
libs/ui/src/lib/i18n.ts

@ -1,4 +1,8 @@
import type { SectorName } from '@ghostfolio/common/types';
import type {
ProductCategory,
ProductPlatform,
SectorName
} from '@ghostfolio/common/types';
import '@angular/localize/init';
@ -94,8 +98,31 @@ const locales = {
Other: $localize`Other`,
'Real Estate': $localize`Real Estate`,
Technology: $localize`Technology`,
Utilities: $localize`Utilities`
} satisfies Record<SectorName, string> & Record<string, string>;
Utilities: $localize`Utilities`,
// Product categories (CRYPTOCURRENCY is defined above under AssetSubClass)
BUDGETING: $localize`Budgeting`,
DIVIDEND_TRACKING: $localize`Dividend Tracking`,
ETF_TRACKING: $localize`ETF Tracking`,
FAMILY_OFFICE: $localize`Family Office`,
FINANCIAL_PLANNING: $localize`Financial Planning`,
INVESTMENT_RESEARCH: $localize`Investment Research`,
NET_WORTH_TRACKING: $localize`Net Worth Tracking`,
STOCK_TRACKING: $localize`Stock Tracking`,
TAX_REPORTING: $localize`Tax Reporting`,
WEALTH_MANAGEMENT: $localize`Wealth Management`,
// Product platforms
ANDROID: $localize`Android`,
IOS: $localize`iOS`,
LINUX: $localize`Linux`,
MACOS: $localize`macOS`,
WEB: $localize`Web`,
WINDOWS: $localize`Windows`
} satisfies Record<ProductCategory, string> &
Record<ProductPlatform, string> &
Record<SectorName, string> &
Record<string, string>;
export function translate(aKey: string): string {
return locales[aKey] ?? aKey;

Loading…
Cancel
Save