Browse Source

Merge branch 'main' into feature/upgrade-prisma-to-version-5.17.0

pull/3597/head
Thomas Kaul 1 year ago
committed by GitHub
parent
commit
ae371ccdcd
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 3
      CHANGELOG.md
  2. 7
      apps/client/src/app/components/admin-overview/admin-overview.html
  3. 40
      apps/client/src/app/pages/resources/personal-finance-tools/product-page.component.ts
  4. 88
      apps/client/src/app/pages/resources/personal-finance-tools/product-page.html
  5. 2
      libs/common/src/lib/interfaces/product.ts
  6. 14
      libs/common/src/lib/personal-finance-tools.ts
  7. 24
      libs/ui/src/lib/i18n.ts
  8. 29
      libs/ui/src/lib/value/value.component.ts
  9. 70
      package.json
  10. 3059
      yarn.lock

3
CHANGELOG.md

@ -13,6 +13,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed
- Improved the handling of the numerical precision in the value component
- Upgraded `angular` from version `18.0.4` to `18.1.1`
- Upgraded `Nx` from version `19.4.3` to `19.5.1`
- Upgraded `prisma` from version `5.16.1` to `5.17.0`
## 2.97.0 - 2024-07-20

7
apps/client/src/app/components/admin-overview/admin-overview.html

@ -12,11 +12,7 @@
<div class="d-flex my-3">
<div class="w-50" i18n>User Count</div>
<div class="w-50">
<gf-value
[locale]="user?.settings?.locale"
[precision]="0"
[value]="userCount"
/>
<gf-value [locale]="user?.settings?.locale" [value]="userCount" />
</div>
</div>
<div class="d-flex my-3">
@ -24,7 +20,6 @@
<div class="w-50">
<gf-value
[locale]="user?.settings?.locale"
[precision]="0"
[value]="transactionCount"
/>
@if (transactionCount && userCount) {

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

@ -1,6 +1,7 @@
import { DataService } from '@ghostfolio/client/services/data.service';
import { Product } from '@ghostfolio/common/interfaces';
import { personalFinanceTools } from '@ghostfolio/common/personal-finance-tools';
import { translate } from '@ghostfolio/ui/i18n';
import { CommonModule } from '@angular/common';
import { Component, OnInit } from '@angular/core';
@ -26,6 +27,7 @@ export class GfProductPageComponent implements OnInit {
'/' + $localize`resources`,
'personal-finance-tools'
];
public tags: string[];
public constructor(
private dataService: DataService,
@ -56,7 +58,7 @@ export class GfProductPageComponent implements OnInit {
],
name: 'Ghostfolio',
origin: $localize`Switzerland`,
region: $localize`Global`,
regions: [$localize`Global`],
slogan: 'Open Source Wealth Management',
useAnonymously: true
};
@ -64,5 +66,41 @@ export class GfProductPageComponent implements OnInit {
this.product2 = personalFinanceTools.find(({ key }) => {
return key === this.route.snapshot.data['key'];
});
if (this.product2.origin) {
this.product2.origin = translate(this.product2.origin);
}
if (this.product2.regions) {
this.product2.regions = this.product2.regions.map((region) => {
return translate(region);
});
}
this.tags = [
this.product1.name,
this.product2.name,
$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`Software`,
$localize`Tool`,
$localize`User Experience`,
$localize`Wealth`,
$localize`Wealth Management`,
`WealthTech`
].sort((a, b) => {
return a.localeCompare(b, undefined, { sensitivity: 'base' });
});
}
}

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

@ -80,8 +80,24 @@
</tr>
<tr class="mat-mdc-row">
<td class="mat-mdc-cell px-3 py-2 text-right" i18n>Region</td>
<td class="mat-mdc-cell px-1 py-2">{{ product1.region }}</td>
<td class="mat-mdc-cell px-1 py-2">{{ product2.region }}</td>
<td class="mat-mdc-cell px-1 py-2">
@for (
region of product1.regions;
track region;
let isLast = $last
) {
{{ region }}{{ isLast ? '' : ', ' }}
}
</td>
<td class="mat-mdc-cell px-1 py-2">
@for (
region of product2.regions;
track region;
let isLast = $last
) {
{{ region }}{{ isLast ? '' : ', ' }}
}
</td>
</tr>
<tr class="mat-mdc-row">
<td class="mat-mdc-cell px-3 py-2 text-right" i18n>
@ -236,69 +252,11 @@
</section>
<section class="mb-4">
<ul class="list-inline">
<li class="list-inline-item">
<span class="badge badge-light">Alternative</span>
</li>
<li class="list-inline-item">
<span class="badge badge-light">App</span>
</li>
<li class="list-inline-item">
<span class="badge badge-light">Budgeting</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">Family Office</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">{{ product1.name }}</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">Investor</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">Privacy</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">Software</span>
</li>
<li class="list-inline-item">
<span class="badge badge-light">Tool</span>
</li>
<li class="list-inline-item">
<span class="badge badge-light">User Experience</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">WealthTech</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">{{ product2.name }}</span>
</li>
@for (tag of tags; track tag) {
<li class="list-inline-item">
<span class="badge badge-light">{{ tag }}</span>
</li>
}
</ul>
</section>
<nav aria-label="breadcrumb">

2
libs/common/src/lib/interfaces/product.ts

@ -10,7 +10,7 @@ export interface Product {
note?: string;
origin?: string;
pricingPerYear?: string;
region?: string;
regions?: string[];
slogan?: string;
useAnonymously?: boolean;
}

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

@ -277,7 +277,7 @@ export const personalFinanceTools: Product[] = [
name: 'markets.sh',
origin: `Germany`,
pricingPerYear: '€168',
region: `Global`,
regions: [`Global`],
slogan: 'Track your investments'
},
{
@ -289,7 +289,7 @@ export const personalFinanceTools: Product[] = [
note: 'Maybe Finance has discontinued in 2023',
origin: `United States`,
pricingPerYear: '$145',
region: `United States`,
regions: [`United States`],
slogan: 'Your financial future, in your control'
},
{
@ -300,7 +300,7 @@ export const personalFinanceTools: Product[] = [
name: 'Merlin',
origin: `United States`,
pricingPerYear: '$204',
region: 'Canada, United States',
regions: ['Canada', 'United States'],
slogan: 'The smartest way to track your crypto'
},
{
@ -340,7 +340,7 @@ export const personalFinanceTools: Product[] = [
note: 'Originally named as Tresor One',
origin: `Germany`,
pricingPerYear: '€88',
region: 'Austria, Germany, Switzerland',
regions: ['Austria', 'Germany', 'Switzerland'],
slogan: 'Dein Vermögen immer im Blick'
},
{
@ -360,7 +360,7 @@ export const personalFinanceTools: Product[] = [
name: 'PocketSmith',
origin: `New Zealand`,
pricingPerYear: '$120',
region: `Global`,
regions: [`Global`],
slogan: 'Know where your money is going'
},
{
@ -444,7 +444,7 @@ export const personalFinanceTools: Product[] = [
name: 'Sharesight',
origin: `New Zealand`,
pricingPerYear: '$135',
region: `Global`,
regions: [`Global`],
slogan: 'Stock Portfolio Tracker'
},
{
@ -594,7 +594,7 @@ export const personalFinanceTools: Product[] = [
languages: ['Deutsch', 'English', 'Español', 'Français', 'Italiano'],
name: 'yeekatee',
origin: `Switzerland`,
region: `Global`,
regions: [`Global`],
slogan: 'Connect. Share. Invest.'
},
{

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

@ -11,10 +11,10 @@ const locales = {
DATA_IMPORT_AND_EXPORT_TOOLTIP_OSS: $localize`Switch to Ghostfolio Premium easily`,
DATA_IMPORT_AND_EXPORT_TOOLTIP_PREMIUM: $localize`Switch to Ghostfolio Open Source or Ghostfolio Basic easily`,
EMERGENCY_FUND: $localize`Emergency Fund`,
Global: $localize`Global`,
GRANT: $localize`Grant`,
HIGHER_RISK: $localize`Higher Risk`,
IMPORT_ACTIVITY_ERROR_IS_DUPLICATE: $localize`This activity already exists.`,
Japan: $localize`Japan`,
LOWER_RISK: $localize`Lower Risk`,
MONTH: $localize`Month`,
MONTHS: $localize`Months`,
@ -65,6 +65,28 @@ const locales = {
Oceania: $localize`Oceania`,
'South America': $localize`South America`,
// Countries
Australia: $localize`Australia`,
Austria: $localize`Austria`,
Belgium: $localize`Belgium`,
Bulgaria: $localize`Bulgaria`,
Canada: $localize`Canada`,
'Czech Republic': $localize`Czech Republic`,
Finland: $localize`Finland`,
France: $localize`France`,
Germany: $localize`Germany`,
India: $localize`India`,
Italy: $localize`Italy`,
Japan: $localize`Japan`,
Netherlands: $localize`Netherlands`,
'New Zealand': $localize`New Zealand`,
Poland: $localize`Poland`,
Romania: $localize`Romania`,
'South Africa': $localize`South Africa`,
Switzerland: $localize`Switzerland`,
Thailand: $localize`Thailand`,
'United States': $localize`United States`,
// Fear and Greed Index
EXTREME_FEAR: $localize`Extreme Fear`,
EXTREME_GREED: $localize`Extreme Greed`,

29
libs/ui/src/lib/value/value.component.ts

@ -58,8 +58,10 @@ export class GfValueComponent implements OnChanges {
this.formattedValue = this.absoluteValue.toLocaleString(
this.locale,
{
maximumFractionDigits: this.precision,
minimumFractionDigits: this.precision
maximumFractionDigits:
this.precision >= 0 ? this.precision : 2,
minimumFractionDigits:
this.precision >= 0 ? this.precision : 2
}
);
} catch {}
@ -68,8 +70,10 @@ export class GfValueComponent implements OnChanges {
this.formattedValue = (this.absoluteValue * 100).toLocaleString(
this.locale,
{
maximumFractionDigits: this.precision,
minimumFractionDigits: this.precision
maximumFractionDigits:
this.precision >= 0 ? this.precision : 2,
minimumFractionDigits:
this.precision >= 0 ? this.precision : 2
}
);
} catch {}
@ -77,8 +81,8 @@ export class GfValueComponent implements OnChanges {
} else if (this.isCurrency) {
try {
this.formattedValue = this.value?.toLocaleString(this.locale, {
maximumFractionDigits: this.precision,
minimumFractionDigits: this.precision
maximumFractionDigits: this.precision >= 0 ? this.precision : 2,
minimumFractionDigits: this.precision >= 0 ? this.precision : 2
});
} catch {}
} else if (this.isPercent) {
@ -86,11 +90,18 @@ export class GfValueComponent implements OnChanges {
this.formattedValue = (this.value * 100).toLocaleString(
this.locale,
{
maximumFractionDigits: this.precision,
minimumFractionDigits: this.precision
maximumFractionDigits: this.precision >= 0 ? this.precision : 2,
minimumFractionDigits: this.precision >= 0 ? this.precision : 2
}
);
} catch {}
} else if (this.precision >= 0) {
try {
this.formattedValue = this.value?.toLocaleString(this.locale, {
maximumFractionDigits: this.precision,
minimumFractionDigits: this.precision
});
} catch {}
} else {
this.formattedValue = this.value?.toLocaleString(this.locale);
}
@ -129,7 +140,7 @@ export class GfValueComponent implements OnChanges {
this.isNumber = false;
this.isString = false;
this.locale = this.locale || getLocale();
this.precision = this.precision >= 0 ? this.precision : 2;
this.precision = this.precision >= 0 ? this.precision : undefined;
this.useAbsoluteValue = false;
}
}

70
package.json

@ -54,17 +54,17 @@
"workspace-generator": "nx workspace-generator"
},
"dependencies": {
"@angular/animations": "18.0.4",
"@angular/cdk": "18.0.4",
"@angular/common": "18.0.4",
"@angular/compiler": "18.0.4",
"@angular/core": "18.0.4",
"@angular/forms": "18.0.4",
"@angular/material": "18.0.4",
"@angular/platform-browser": "18.0.4",
"@angular/platform-browser-dynamic": "18.0.4",
"@angular/router": "18.0.4",
"@angular/service-worker": "18.0.4",
"@angular/animations": "18.1.1",
"@angular/cdk": "18.1.1",
"@angular/common": "18.1.1",
"@angular/compiler": "18.1.1",
"@angular/core": "18.1.1",
"@angular/forms": "18.1.1",
"@angular/material": "18.1.1",
"@angular/platform-browser": "18.1.1",
"@angular/platform-browser-dynamic": "18.1.1",
"@angular/router": "18.1.1",
"@angular/service-worker": "18.1.1",
"@codewithdan/observable-store": "2.2.15",
"@dfinity/agent": "0.15.7",
"@dfinity/auth-client": "0.15.7",
@ -139,30 +139,30 @@
"zone.js": "0.14.7"
},
"devDependencies": {
"@angular-devkit/build-angular": "18.0.5",
"@angular-devkit/core": "18.0.5",
"@angular-devkit/schematics": "18.0.5",
"@angular-eslint/eslint-plugin": "18.0.1",
"@angular-eslint/eslint-plugin-template": "18.0.1",
"@angular-eslint/template-parser": "18.0.1",
"@angular/cli": "18.0.5",
"@angular/compiler-cli": "18.0.4",
"@angular/language-service": "18.0.4",
"@angular/localize": "18.0.4",
"@angular/pwa": "18.0.5",
"@angular-devkit/build-angular": "18.1.1",
"@angular-devkit/core": "18.1.1",
"@angular-devkit/schematics": "18.1.1",
"@angular-eslint/eslint-plugin": "18.1.0",
"@angular-eslint/eslint-plugin-template": "18.1.0",
"@angular-eslint/template-parser": "18.1.0",
"@angular/cli": "18.1.1",
"@angular/compiler-cli": "18.1.1",
"@angular/language-service": "18.1.1",
"@angular/localize": "18.1.1",
"@angular/pwa": "18.1.1",
"@nestjs/schematics": "10.0.1",
"@nestjs/testing": "10.1.3",
"@nx/angular": "19.4.3",
"@nx/cypress": "19.4.3",
"@nx/eslint-plugin": "19.4.3",
"@nx/jest": "19.4.3",
"@nx/js": "19.4.3",
"@nx/nest": "19.4.3",
"@nx/node": "19.4.3",
"@nx/storybook": "19.4.3",
"@nx/web": "19.4.3",
"@nx/workspace": "19.4.3",
"@schematics/angular": "18.0.3",
"@nx/angular": "19.5.1",
"@nx/cypress": "19.5.1",
"@nx/eslint-plugin": "19.5.1",
"@nx/jest": "19.5.1",
"@nx/js": "19.5.1",
"@nx/nest": "19.5.1",
"@nx/node": "19.5.1",
"@nx/storybook": "19.5.1",
"@nx/web": "19.5.1",
"@nx/workspace": "19.5.1",
"@schematics/angular": "18.1.1",
"@simplewebauthn/types": "9.0.1",
"@storybook/addon-essentials": "7.6.5",
"@storybook/angular": "7.6.5",
@ -190,7 +190,7 @@
"jest": "29.4.3",
"jest-environment-jsdom": "29.4.3",
"jest-preset-angular": "14.1.0",
"nx": "19.4.3",
"nx": "19.5.1",
"prettier": "3.3.3",
"prettier-plugin-organize-attributes": "1.0.0",
"react": "18.2.0",
@ -201,7 +201,7 @@
"ts-jest": "29.1.0",
"ts-node": "10.9.2",
"tslib": "2.6.0",
"typescript": "5.4.4",
"typescript": "5.5.3",
"webpack-bundle-analyzer": "4.10.1"
},
"engines": {

3059
yarn.lock

File diff suppressed because it is too large
Loading…
Cancel
Save