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. 72
      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

72
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>(() => ({ protected readonly product1 = computed<Product>(() => ({
categories: ['FINANCIAL_PLANNING', 'NET_WORTH_TRACKING', 'STOCK_TRACKING'],
founded: 2021, founded: 2021,
hasFreePlan: true, hasFreePlan: true,
hasSelfHostingAbility: true, hasSelfHostingAbility: true,
@ -49,6 +50,7 @@ export class GfProductPageComponent {
], ],
name: 'Ghostfolio', name: 'Ghostfolio',
origin: getCountryName({ code: 'CH' }), origin: getCountryName({ code: 'CH' }),
platforms: ['ANDROID', 'WEB'],
regions: [$localize`Global`], regions: [$localize`Global`],
slogan: 'Open Source Wealth Management', slogan: 'Open Source Wealth Management',
useAnonymously: true useAnonymously: true
@ -89,39 +91,47 @@ export class GfProductPageComponent {
const product1 = this.product1(); const product1 = this.product1();
const product2 = this.product2(); const product2 = this.product2();
return [ return Array.from(
product1.name, new Set(
product1.origin, [
product2.name, ...[product1, product2].flatMap(
product2.origin, ({ categories, name, origin, platforms }) => {
$localize`Alternative`, return [
$localize`App`, ...[...(categories ?? []), ...(platforms ?? [])].map((key) => {
$localize`Budgeting`, return translate(key);
$localize`Community`, }),
$localize`Family Office`, name,
`Fintech`, origin
$localize`Investment`, ];
$localize`Investor`, }
$localize`Open Source`, ),
`OSS`, $localize`Alternative`,
$localize`Personal Finance`, $localize`App`,
$localize`Privacy`, $localize`Community`,
$localize`Portfolio`, `Fintech`,
$localize`Software`, $localize`Investment`,
$localize`Tool`, $localize`Investor`,
$localize`User Experience`, $localize`Open Source`,
$localize`Wealth`, `OSS`,
$localize`Wealth Management`, $localize`Personal Finance`,
`WealthTech` $localize`Portfolio`,
] $localize`Privacy`,
.filter((item): item is string => { $localize`Software`,
return !!item; $localize`Tool`,
}) $localize`User Experience`,
.sort((a, b) => { $localize`Wealth`,
return a.localeCompare(b, undefined, { sensitivity: 'base' }); `WealthTech`
}); ].filter((item): item is string => {
return !!item;
})
)
).sort((a, b) => {
return a.localeCompare(b, undefined, { sensitivity: 'base' });
});
}); });
protected readonly translate = translate;
private readonly dataService = inject(DataService); private readonly dataService = inject(DataService);
private readonly route = inject(ActivatedRoute); 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">{{ product1().slogan }}</td>
<td class="mat-mdc-cell px-1 py-2">{{ product2().slogan }}</td> <td class="mat-mdc-cell px-1 py-2">{{ product2().slogan }}</td>
</tr> </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"> <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-3 py-2 text-right" i18n>Founded</td>
<td class="mat-mdc-cell px-1 py-2">{{ product1().founded }}</td> <td class="mat-mdc-cell px-1 py-2">{{ product1().founded }}</td>
@ -104,6 +125,29 @@
} }
</td> </td>
</tr> </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"> <tr class="mat-mdc-row">
<td class="mat-mdc-cell px-3 py-2 text-right" i18n> <td class="mat-mdc-cell px-3 py-2 text-right" i18n>
Available in 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'; import '@angular/localize/init';
@ -94,8 +98,31 @@ const locales = {
Other: $localize`Other`, Other: $localize`Other`,
'Real Estate': $localize`Real Estate`, 'Real Estate': $localize`Real Estate`,
Technology: $localize`Technology`, Technology: $localize`Technology`,
Utilities: $localize`Utilities` Utilities: $localize`Utilities`,
} satisfies Record<SectorName, string> & Record<string, string>;
// 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 { export function translate(aKey: string): string {
return locales[aKey] ?? aKey; return locales[aKey] ?? aKey;

Loading…
Cancel
Save