Browse Source

Merge branch 'main' into feature/generate-security-token-for-user

pull/4458/head
Thomas Kaul 1 month ago
committed by GitHub
parent
commit
e32fd3d789
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 4
      CHANGELOG.md
  2. 4
      DEVELOPMENT.md
  3. 2
      README.md
  4. 2
      apps/api/src/app/app.module.ts
  5. 46
      apps/api/src/app/endpoints/assets/assets.controller.ts
  6. 11
      apps/api/src/app/endpoints/assets/assets.module.ts
  7. 3
      apps/api/src/app/export/export.controller.ts
  8. 96
      apps/api/src/app/export/export.service.ts
  9. 4
      apps/api/src/app/portfolio/calculator/portfolio-calculator.ts
  10. 20
      apps/api/src/app/portfolio/portfolio.service.ts
  11. 8
      apps/api/src/app/sitemap/sitemap.controller.ts
  12. 4
      apps/api/src/assets/site.webmanifest
  13. 4
      apps/api/src/assets/sitemap.xml
  14. 3
      apps/api/src/environments/environment.prod.ts
  15. 3
      apps/api/src/environments/environment.ts
  16. 10
      apps/api/src/main.ts
  17. 3
      apps/api/src/middlewares/html-template.middleware.ts
  18. 14
      apps/api/src/services/configuration/configuration.service.ts
  19. 4
      apps/api/src/services/exchange-rate-data/exchange-rate-data.service.ts
  20. 8
      apps/client/ngsw-config.json
  21. 3
      apps/client/project.json
  22. 5
      apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.component.ts
  23. 3
      apps/client/src/app/components/user-account-settings/user-account-settings.component.ts
  24. 5
      apps/client/src/index.html
  25. 14
      apps/client/src/locales/messages.ca.xlf
  26. 14
      apps/client/src/locales/messages.de.xlf
  27. 14
      apps/client/src/locales/messages.es.xlf
  28. 14
      apps/client/src/locales/messages.fr.xlf
  29. 14
      apps/client/src/locales/messages.it.xlf
  30. 14
      apps/client/src/locales/messages.nl.xlf
  31. 14
      apps/client/src/locales/messages.pl.xlf
  32. 14
      apps/client/src/locales/messages.pt.xlf
  33. 14
      apps/client/src/locales/messages.tr.xlf
  34. 14
      apps/client/src/locales/messages.uk.xlf
  35. 14
      apps/client/src/locales/messages.xlf
  36. 14
      apps/client/src/locales/messages.zh.xlf
  37. 3
      libs/common/src/lib/config.ts
  38. 2
      libs/ui/src/lib/fire-calculator/fire-calculator.component.stories.ts

4
CHANGELOG.md

@ -11,10 +11,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Added support for filtering in the _Copy AI prompt to clipboard_ actions on the analysis page (experimental) - Added support for filtering in the _Copy AI prompt to clipboard_ actions on the analysis page (experimental)
- Added support for generating a new _Security Token_ via the users table of the admin control panel - Added support for generating a new _Security Token_ via the users table of the admin control panel
- Added an endpoint to localize the `site.webmanifest`
- Added the _Storybook_ path to the `sitemap.xml` file
### Changed ### Changed
- Improved the export functionality by applying filters on accounts and tags
- Improved the symbol validation in the _Yahoo Finance_ service (get asset profiles) - Improved the symbol validation in the _Yahoo Finance_ service (get asset profiles)
- Refactored `lodash.uniq` with `Array.from(new Set(...))`
- Refreshed the cryptocurrencies list - Refreshed the cryptocurrencies list
### Fixed ### Fixed

4
DEVELOPMENT.md

@ -60,6 +60,10 @@ Remove permission in `UserService` using `without()`
Use `@if (user?.settings?.isExperimentalFeatures) {}` in HTML template Use `@if (user?.settings?.isExperimentalFeatures) {}` in HTML template
## Component Library (_Storybook_)
https://ghostfol.io/development/storybook
## Git ## Git
### Rebase ### Rebase

2
README.md

@ -47,7 +47,7 @@ Ghostfolio is for you if you are...
- ✅ Create, update and delete transactions - ✅ Create, update and delete transactions
- ✅ Multi account management - ✅ Multi account management
- ✅ Portfolio performance: Time-weighted rate of return (TWR) for `Today`, `WTD`, `MTD`, `YTD`, `1Y`, `5Y`, `Max` - ✅ Portfolio performance: Return on Average Investment (ROAI) for `Today`, `WTD`, `MTD`, `YTD`, `1Y`, `5Y`, `Max`
- ✅ Various charts - ✅ Various charts
- ✅ Static analysis to identify potential risks in your portfolio - ✅ Static analysis to identify potential risks in your portfolio
- ✅ Import and export transactions - ✅ Import and export transactions

2
apps/api/src/app/app.module.ts

@ -32,6 +32,7 @@ import { AuthModule } from './auth/auth.module';
import { CacheModule } from './cache/cache.module'; import { CacheModule } from './cache/cache.module';
import { AiModule } from './endpoints/ai/ai.module'; import { AiModule } from './endpoints/ai/ai.module';
import { ApiKeysModule } from './endpoints/api-keys/api-keys.module'; import { ApiKeysModule } from './endpoints/api-keys/api-keys.module';
import { AssetsModule } from './endpoints/assets/assets.module';
import { BenchmarksModule } from './endpoints/benchmarks/benchmarks.module'; import { BenchmarksModule } from './endpoints/benchmarks/benchmarks.module';
import { GhostfolioModule } from './endpoints/data-providers/ghostfolio/ghostfolio.module'; import { GhostfolioModule } from './endpoints/data-providers/ghostfolio/ghostfolio.module';
import { MarketDataModule } from './endpoints/market-data/market-data.module'; import { MarketDataModule } from './endpoints/market-data/market-data.module';
@ -61,6 +62,7 @@ import { UserModule } from './user/user.module';
AiModule, AiModule,
ApiKeysModule, ApiKeysModule,
AssetModule, AssetModule,
AssetsModule,
AuthDeviceModule, AuthDeviceModule,
AuthModule, AuthModule,
BenchmarksModule, BenchmarksModule,

46
apps/api/src/app/endpoints/assets/assets.controller.ts

@ -0,0 +1,46 @@
import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service';
import { interpolate } from '@ghostfolio/common/helper';
import {
Controller,
Get,
Param,
Res,
Version,
VERSION_NEUTRAL
} from '@nestjs/common';
import { Response } from 'express';
import { readFileSync } from 'fs';
import { join } from 'path';
@Controller('assets')
export class AssetsController {
private webManifest = '';
public constructor(
public readonly configurationService: ConfigurationService
) {
try {
this.webManifest = readFileSync(
join(__dirname, 'assets', 'site.webmanifest'),
'utf8'
);
} catch {}
}
@Get('/:languageCode/site.webmanifest')
@Version(VERSION_NEUTRAL)
public getWebManifest(
@Param('languageCode') languageCode: string,
@Res() response: Response
): void {
const rootUrl = this.configurationService.get('ROOT_URL');
const webManifest = interpolate(this.webManifest, {
languageCode,
rootUrl
});
response.setHeader('Content-Type', 'application/json');
response.send(webManifest);
}
}

11
apps/api/src/app/endpoints/assets/assets.module.ts

@ -0,0 +1,11 @@
import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service';
import { Module } from '@nestjs/common';
import { AssetsController } from './assets.controller';
@Module({
controllers: [AssetsController],
providers: [ConfigurationService]
})
export class AssetsModule {}

3
apps/api/src/app/export/export.controller.ts

@ -21,10 +21,11 @@ export class ExportController {
@UseGuards(AuthGuard('jwt'), HasPermissionGuard) @UseGuards(AuthGuard('jwt'), HasPermissionGuard)
public async export( public async export(
@Query('accounts') filterByAccounts?: string, @Query('accounts') filterByAccounts?: string,
@Query('activityIds') activityIds?: string[], @Query('activityIds') filterByActivityIds?: string,
@Query('assetClasses') filterByAssetClasses?: string, @Query('assetClasses') filterByAssetClasses?: string,
@Query('tags') filterByTags?: string @Query('tags') filterByTags?: string
): Promise<Export> { ): Promise<Export> {
const activityIds = filterByActivityIds?.split(',') ?? [];
const filters = this.apiService.buildFiltersFromQueryParams({ const filters = this.apiService.buildFiltersFromQueryParams({
filterByAccounts, filterByAccounts,
filterByAssetClasses, filterByAssetClasses,

96
apps/api/src/app/export/export.service.ts

@ -28,6 +28,22 @@ export class ExportService {
}): Promise<Export> { }): Promise<Export> {
const platformsMap: { [platformId: string]: Platform } = {}; const platformsMap: { [platformId: string]: Platform } = {};
let { activities } = await this.orderService.getOrders({
filters,
userCurrency,
userId,
includeDrafts: true,
sortColumn: 'date',
sortDirection: 'asc',
withExcludedAccounts: true
});
if (activityIds?.length > 0) {
activities = activities.filter(({ id }) => {
return activityIds.includes(id);
});
}
const accounts = ( const accounts = (
await this.accountService.accounts({ await this.accountService.accounts({
include: { include: {
@ -39,57 +55,55 @@ export class ExportService {
}, },
where: { userId } where: { userId }
}) })
).map( )
({ .filter(({ id }) => {
balance, return activities.length > 0
balances, ? activities.some(({ accountId }) => {
comment, return accountId === id;
currency, })
id, : true;
isExcluded, })
name, .map(
Platform: platform, ({
platformId
}) => {
if (platformId) {
platformsMap[platformId] = platform;
}
return {
balance, balance,
balances: balances.map(({ date, value }) => { balances,
return { date: date.toISOString(), value };
}),
comment, comment,
currency, currency,
id, id,
isExcluded, isExcluded,
name, name,
Platform: platform,
platformId platformId
}; }) => {
} if (platformId) {
); platformsMap[platformId] = platform;
}
let { activities } = await this.orderService.getOrders({
filters,
userCurrency,
userId,
includeDrafts: true,
sortColumn: 'date',
sortDirection: 'asc',
withExcludedAccounts: true
});
if (activityIds) { return {
activities = activities.filter((activity) => { balance,
return activityIds.includes(activity.id); balances: balances.map(({ date, value }) => {
}); return { date: date.toISOString(), value };
} }),
comment,
currency,
id,
isExcluded,
name,
platformId
};
}
);
const tags = (await this.tagService.getTagsForUser(userId)) const tags = (await this.tagService.getTagsForUser(userId))
.filter(({ isUsed }) => { .filter(
return isUsed; ({ id, isUsed }) =>
}) isUsed &&
activities.some((activity) => {
return activity.tags.some(({ id: tagId }) => {
return tagId === id;
});
})
)
.map(({ id, name }) => { .map(({ id, name }) => {
return { return {
id, id,

4
apps/api/src/app/portfolio/calculator/portfolio-calculator.ts

@ -49,7 +49,7 @@ import {
min, min,
subDays subDays
} from 'date-fns'; } from 'date-fns';
import { isNumber, sortBy, sum, uniq, uniqBy } from 'lodash'; import { isNumber, sortBy, sum, uniqBy } from 'lodash';
export abstract class PortfolioCalculator { export abstract class PortfolioCalculator {
protected static readonly ENABLE_LOGGING = false; protected static readonly ENABLE_LOGGING = false;
@ -222,7 +222,7 @@ export abstract class PortfolioCalculator {
const exchangeRatesByCurrency = const exchangeRatesByCurrency =
await this.exchangeRateDataService.getExchangeRatesByCurrency({ await this.exchangeRateDataService.getExchangeRatesByCurrency({
currencies: uniq(Object.values(currencies)), currencies: Array.from(new Set(Object.values(currencies))),
endDate: endOfDay(this.endDate), endDate: endOfDay(this.endDate),
startDate: this.startDate, startDate: this.startDate,
targetCurrency: this.currency targetCurrency: this.currency

20
apps/api/src/app/portfolio/portfolio.service.ts

@ -82,7 +82,7 @@ import {
parseISO, parseISO,
set set
} from 'date-fns'; } from 'date-fns';
import { isEmpty, uniq } from 'lodash'; import { isEmpty } from 'lodash';
import { PortfolioCalculator } from './calculator/portfolio-calculator'; import { PortfolioCalculator } from './calculator/portfolio-calculator';
import { import {
@ -2032,14 +2032,16 @@ export class PortfolioService {
where: { id: filters[0].id } where: { id: filters[0].id }
}); });
} else { } else {
const accountIds = uniq( const accountIds = Array.from(
activities new Set(
.filter(({ accountId }) => { activities
return accountId; .filter(({ accountId }) => {
}) return accountId;
.map(({ accountId }) => { })
return accountId; .map(({ accountId }) => {
}) return accountId;
})
)
); );
currentAccounts = await this.accountService.accounts({ currentAccounts = await this.accountService.accounts({

8
apps/api/src/app/sitemap/sitemap.controller.ts

@ -9,8 +9,8 @@ import { personalFinanceTools } from '@ghostfolio/common/personal-finance-tools'
import { Controller, Get, Res, VERSION_NEUTRAL, Version } from '@nestjs/common'; import { Controller, Get, Res, VERSION_NEUTRAL, Version } from '@nestjs/common';
import { format } from 'date-fns'; import { format } from 'date-fns';
import { Response } from 'express'; import { Response } from 'express';
import * as fs from 'fs'; import { readFileSync } from 'fs';
import * as path from 'path'; import { join } from 'path';
@Controller('sitemap.xml') @Controller('sitemap.xml')
export class SitemapController { export class SitemapController {
@ -20,8 +20,8 @@ export class SitemapController {
private readonly configurationService: ConfigurationService private readonly configurationService: ConfigurationService
) { ) {
try { try {
this.sitemapXml = fs.readFileSync( this.sitemapXml = readFileSync(
path.join(__dirname, 'assets', 'sitemap.xml'), join(__dirname, 'assets', 'sitemap.xml'),
'utf8' 'utf8'
); );
} catch {} } catch {}

4
apps/client/src/assets/site.webmanifest → apps/api/src/assets/site.webmanifest

@ -25,7 +25,7 @@
"name": "Ghostfolio", "name": "Ghostfolio",
"orientation": "portrait", "orientation": "portrait",
"short_name": "Ghostfolio", "short_name": "Ghostfolio",
"start_url": "/en/", "start_url": "/${languageCode}/",
"theme_color": "#FFFFFF", "theme_color": "#FFFFFF",
"url": "https://ghostfol.io" "url": "${rootUrl}"
} }

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

@ -92,6 +92,10 @@
<loc>https://ghostfol.io/de/ueber-uns/oss-friends</loc> <loc>https://ghostfol.io/de/ueber-uns/oss-friends</loc>
<lastmod>${currentDate}T00:00:00+00:00</lastmod> <lastmod>${currentDate}T00:00:00+00:00</lastmod>
</url> </url>
<url>
<loc>https://ghostfol.io/development/storybook</loc>
<lastmod>${currentDate}T00:00:00+00:00</lastmod>
</url>
<url> <url>
<loc>https://ghostfol.io/en</loc> <loc>https://ghostfol.io/en</loc>
<lastmod>${currentDate}T00:00:00+00:00</lastmod> <lastmod>${currentDate}T00:00:00+00:00</lastmod>

3
apps/api/src/environments/environment.prod.ts

@ -1,4 +1,7 @@
import { DEFAULT_HOST, DEFAULT_PORT } from '@ghostfolio/common/config';
export const environment = { export const environment = {
production: true, production: true,
rootUrl: `http://${DEFAULT_HOST}:${DEFAULT_PORT}`,
version: `${require('../../../../package.json').version}` version: `${require('../../../../package.json').version}`
}; };

3
apps/api/src/environments/environment.ts

@ -1,4 +1,7 @@
import { DEFAULT_HOST } from '@ghostfolio/common/config';
export const environment = { export const environment = {
production: false, production: false,
rootUrl: `https://${DEFAULT_HOST}:4200`,
version: 'dev' version: 'dev'
}; };

10
apps/api/src/main.ts

@ -1,4 +1,8 @@
import { STORYBOOK_PATH } from '@ghostfolio/common/config'; import {
DEFAULT_HOST,
DEFAULT_PORT,
STORYBOOK_PATH
} from '@ghostfolio/common/config';
import { import {
Logger, Logger,
@ -75,8 +79,8 @@ async function bootstrap() {
app.use(HtmlTemplateMiddleware); app.use(HtmlTemplateMiddleware);
const HOST = configService.get<string>('HOST') || '0.0.0.0'; const HOST = configService.get<string>('HOST') || DEFAULT_HOST;
const PORT = configService.get<number>('PORT') || 3333; const PORT = configService.get<number>('PORT') || DEFAULT_PORT;
await app.listen(PORT, HOST, () => { await app.listen(PORT, HOST, () => {
logLogo(); logLogo();

3
apps/api/src/middlewares/html-template.middleware.ts

@ -2,7 +2,6 @@ import { environment } from '@ghostfolio/api/environments/environment';
import { I18nService } from '@ghostfolio/api/services/i18n/i18n.service'; import { I18nService } from '@ghostfolio/api/services/i18n/i18n.service';
import { import {
DEFAULT_LANGUAGE_CODE, DEFAULT_LANGUAGE_CODE,
DEFAULT_ROOT_URL,
STORYBOOK_PATH, STORYBOOK_PATH,
SUPPORTED_LANGUAGE_CODES SUPPORTED_LANGUAGE_CODES
} from '@ghostfolio/common/config'; } from '@ghostfolio/common/config';
@ -126,7 +125,7 @@ export const HtmlTemplateMiddleware = async (
} }
const currentDate = format(new Date(), DATE_FORMAT); const currentDate = format(new Date(), DATE_FORMAT);
const rootUrl = process.env.ROOT_URL || DEFAULT_ROOT_URL; const rootUrl = process.env.ROOT_URL || environment.rootUrl;
if ( if (
path.startsWith('/api/') || path.startsWith('/api/') ||

14
apps/api/src/services/configuration/configuration.service.ts

@ -1,11 +1,13 @@
import { environment } from '@ghostfolio/api/environments/environment';
import { Environment } from '@ghostfolio/api/services/interfaces/environment.interface'; import { Environment } from '@ghostfolio/api/services/interfaces/environment.interface';
import { import {
CACHE_TTL_NO_CACHE, CACHE_TTL_NO_CACHE,
DEFAULT_HOST,
DEFAULT_PORT,
DEFAULT_PROCESSOR_GATHER_ASSET_PROFILE_CONCURRENCY, DEFAULT_PROCESSOR_GATHER_ASSET_PROFILE_CONCURRENCY,
DEFAULT_PROCESSOR_GATHER_HISTORICAL_MARKET_DATA_CONCURRENCY, DEFAULT_PROCESSOR_GATHER_HISTORICAL_MARKET_DATA_CONCURRENCY,
DEFAULT_PROCESSOR_PORTFOLIO_SNAPSHOT_COMPUTATION_CONCURRENCY, DEFAULT_PROCESSOR_PORTFOLIO_SNAPSHOT_COMPUTATION_CONCURRENCY,
DEFAULT_PROCESSOR_PORTFOLIO_SNAPSHOT_COMPUTATION_TIMEOUT, DEFAULT_PROCESSOR_PORTFOLIO_SNAPSHOT_COMPUTATION_TIMEOUT
DEFAULT_ROOT_URL
} from '@ghostfolio/common/config'; } from '@ghostfolio/common/config';
import { Injectable } from '@nestjs/common'; import { Injectable } from '@nestjs/common';
@ -49,11 +51,11 @@ export class ConfigurationService {
GOOGLE_SHEETS_ACCOUNT: str({ default: '' }), GOOGLE_SHEETS_ACCOUNT: str({ default: '' }),
GOOGLE_SHEETS_ID: str({ default: '' }), GOOGLE_SHEETS_ID: str({ default: '' }),
GOOGLE_SHEETS_PRIVATE_KEY: str({ default: '' }), GOOGLE_SHEETS_PRIVATE_KEY: str({ default: '' }),
HOST: host({ default: '0.0.0.0' }), HOST: host({ default: DEFAULT_HOST }),
JWT_SECRET_KEY: str({}), JWT_SECRET_KEY: str({}),
MAX_ACTIVITIES_TO_IMPORT: num({ default: Number.MAX_SAFE_INTEGER }), MAX_ACTIVITIES_TO_IMPORT: num({ default: Number.MAX_SAFE_INTEGER }),
MAX_CHART_ITEMS: num({ default: 365 }), MAX_CHART_ITEMS: num({ default: 365 }),
PORT: port({ default: 3333 }), PORT: port({ default: DEFAULT_PORT }),
PROCESSOR_GATHER_ASSET_PROFILE_CONCURRENCY: num({ PROCESSOR_GATHER_ASSET_PROFILE_CONCURRENCY: num({
default: DEFAULT_PROCESSOR_GATHER_ASSET_PROFILE_CONCURRENCY default: DEFAULT_PROCESSOR_GATHER_ASSET_PROFILE_CONCURRENCY
}), }),
@ -71,7 +73,9 @@ export class ConfigurationService {
REDIS_PASSWORD: str({ default: '' }), REDIS_PASSWORD: str({ default: '' }),
REDIS_PORT: port({ default: 6379 }), REDIS_PORT: port({ default: 6379 }),
REQUEST_TIMEOUT: num({ default: ms('3 seconds') }), REQUEST_TIMEOUT: num({ default: ms('3 seconds') }),
ROOT_URL: url({ default: DEFAULT_ROOT_URL }), ROOT_URL: url({
default: environment.rootUrl
}),
STRIPE_PUBLIC_KEY: str({ default: '' }), STRIPE_PUBLIC_KEY: str({ default: '' }),
STRIPE_SECRET_KEY: str({ default: '' }), STRIPE_SECRET_KEY: str({ default: '' }),
TWITTER_ACCESS_TOKEN: str({ default: 'dummyAccessToken' }), TWITTER_ACCESS_TOKEN: str({ default: 'dummyAccessToken' }),

4
apps/api/src/services/exchange-rate-data/exchange-rate-data.service.ts

@ -23,7 +23,7 @@ import {
isToday, isToday,
subDays subDays
} from 'date-fns'; } from 'date-fns';
import { isNumber, uniq } from 'lodash'; import { isNumber } from 'lodash';
import ms from 'ms'; import ms from 'ms';
@Injectable() @Injectable()
@ -515,7 +515,7 @@ export class ExchangeRateDataService {
} }
} }
return uniq(currencies).filter(Boolean).sort(); return Array.from(new Set(currencies)).filter(Boolean).sort();
} }
private prepareCurrencyPairs(aCurrencies: string[]) { private prepareCurrencyPairs(aCurrencies: string[]) {

8
apps/client/ngsw-config.json

@ -6,13 +6,7 @@
"name": "app", "name": "app",
"installMode": "prefetch", "installMode": "prefetch",
"resources": { "resources": {
"files": [ "files": ["/favicon.ico", "/index.html", "/*.css", "/*.js"]
"/favicon.ico",
"/index.html",
"/assets/site.webmanifest",
"/*.css",
"/*.js"
]
} }
}, },
{ {

3
apps/client/project.json

@ -146,9 +146,6 @@
{ {
"command": "shx cp apps/client/src/assets/robots.txt dist/apps/client" "command": "shx cp apps/client/src/assets/robots.txt dist/apps/client"
}, },
{
"command": "shx cp apps/client/src/assets/site.webmanifest dist/apps/client"
},
{ {
"command": "shx cp node_modules/ionicons/dist/index.js dist/apps/client" "command": "shx cp node_modules/ionicons/dist/index.js dist/apps/client"
}, },

5
apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.component.ts

@ -20,7 +20,6 @@ import {
} from '@angular/forms'; } from '@angular/forms';
import { MatDialogRef } from '@angular/material/dialog'; import { MatDialogRef } from '@angular/material/dialog';
import { isISO4217CurrencyCode } from 'class-validator'; import { isISO4217CurrencyCode } from 'class-validator';
import { uniq } from 'lodash';
import { Subject, takeUntil } from 'rxjs'; import { Subject, takeUntil } from 'rxjs';
import { CreateAssetProfileDialogMode } from './interfaces/interfaces'; import { CreateAssetProfileDialogMode } from './interfaces/interfaces';
@ -87,7 +86,9 @@ export class CreateAssetProfileDialog implements OnInit, OnDestroy {
this.createAssetProfileForm.get('addCurrency').value as string this.createAssetProfileForm.get('addCurrency').value as string
).toUpperCase(); ).toUpperCase();
const currencies = uniq([...this.customCurrencies, currency]).sort(); const currencies = Array.from(
new Set([...this.customCurrencies, currency])
).sort();
this.dataService this.dataService
.putAdminSetting(PROPERTY_CURRENCIES, { .putAdminSetting(PROPERTY_CURRENCIES, {

3
apps/client/src/app/components/user-account-settings/user-account-settings.component.ts

@ -24,7 +24,6 @@ import { FormBuilder, Validators } from '@angular/forms';
import { MatSlideToggleChange } from '@angular/material/slide-toggle'; import { MatSlideToggleChange } from '@angular/material/slide-toggle';
import { MatSnackBar } from '@angular/material/snack-bar'; import { MatSnackBar } from '@angular/material/snack-bar';
import { format, parseISO } from 'date-fns'; import { format, parseISO } from 'date-fns';
import { uniq } from 'lodash';
import ms from 'ms'; import ms from 'ms';
import { EMPTY, Subject, throwError } from 'rxjs'; import { EMPTY, Subject, throwError } from 'rxjs';
import { catchError, takeUntil } from 'rxjs/operators'; import { catchError, takeUntil } from 'rxjs/operators';
@ -108,7 +107,7 @@ export class UserAccountSettingsComponent implements OnDestroy, OnInit {
); );
this.locales.push(this.user.settings.locale); this.locales.push(this.user.settings.locale);
this.locales = uniq(this.locales.sort()); this.locales = Array.from(new Set(this.locales)).sort();
this.changeDetectorRef.markForCheck(); this.changeDetectorRef.markForCheck();
} }

5
apps/client/src/index.html

@ -45,7 +45,10 @@
sizes="16x16" sizes="16x16"
type="image/png" type="image/png"
/> />
<link href="../assets/site.webmanifest" rel="manifest" /> <link
href="../api/assets/${languageCode}/site.webmanifest"
rel="manifest"
/>
</head> </head>
<body> <body>
<gf-root></gf-root> <gf-root></gf-root>

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

@ -2475,7 +2475,7 @@
</context-group> </context-group>
<context-group purpose="location"> <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="sourcefile">apps/client/src/app/components/user-account-settings/user-account-settings.component.ts</context>
<context context-type="linenumber">160</context> <context context-type="linenumber">159</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="024cdb2814b0cb3f4ced148f1a0b9854447cb214" datatype="html"> <trans-unit id="024cdb2814b0cb3f4ced148f1a0b9854447cb214" datatype="html">
@ -3343,7 +3343,7 @@
<target state="new">Auto</target> <target state="new">Auto</target>
<context-group purpose="location"> <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="sourcefile">apps/client/src/app/components/user-account-settings/user-account-settings.component.ts</context>
<context context-type="linenumber">40</context> <context context-type="linenumber">39</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="4941836956820527118" datatype="html"> <trans-unit id="4941836956820527118" datatype="html">
@ -3351,7 +3351,7 @@
<target state="new">Do you really want to close your Ghostfolio account?</target> <target state="new">Do you really want to close your Ghostfolio account?</target>
<context-group purpose="location"> <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="sourcefile">apps/client/src/app/components/user-account-settings/user-account-settings.component.ts</context>
<context context-type="linenumber">175</context> <context context-type="linenumber">174</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="7963559562180316948" datatype="html"> <trans-unit id="7963559562180316948" datatype="html">
@ -3359,7 +3359,7 @@
<target state="new">Do you really want to remove this sign in method?</target> <target state="new">Do you really want to remove this sign in method?</target>
<context-group purpose="location"> <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="sourcefile">apps/client/src/app/components/user-account-settings/user-account-settings.component.ts</context>
<context context-type="linenumber">249</context> <context context-type="linenumber">248</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="5724720497710437101" datatype="html"> <trans-unit id="5724720497710437101" datatype="html">
@ -3367,7 +3367,7 @@
<target state="new">Oops! There was an error setting up biometric authentication.</target> <target state="new">Oops! There was an error setting up biometric authentication.</target>
<context-group purpose="location"> <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="sourcefile">apps/client/src/app/components/user-account-settings/user-account-settings.component.ts</context>
<context context-type="linenumber">303</context> <context context-type="linenumber">302</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="121cc5391cd2a5115bc2b3160379ee5b36cd7716" datatype="html"> <trans-unit id="121cc5391cd2a5115bc2b3160379ee5b36cd7716" datatype="html">
@ -7589,7 +7589,7 @@
<target state="new">AI prompt has been copied to the clipboard</target> <target state="new">AI prompt has been copied to the clipboard</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context> <context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">170</context> <context context-type="linenumber">173</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="1616747898909934803" datatype="html"> <trans-unit id="1616747898909934803" datatype="html">
@ -7685,7 +7685,7 @@
<target state="new">Open Duck.ai</target> <target state="new">Open Duck.ai</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context> <context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">171</context> <context context-type="linenumber">174</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="70a67e04629f6d412db0a12d51820b480788d795" datatype="html"> <trans-unit id="70a67e04629f6d412db0a12d51820b480788d795" datatype="html">

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

@ -1022,7 +1022,7 @@
</context-group> </context-group>
<context-group purpose="location"> <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="sourcefile">apps/client/src/app/components/user-account-settings/user-account-settings.component.ts</context>
<context context-type="linenumber">160</context> <context context-type="linenumber">159</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="ec8b93e2ecc776c8dc2e43a791b6974612a90148" datatype="html"> <trans-unit id="ec8b93e2ecc776c8dc2e43a791b6974612a90148" datatype="html">
@ -1662,7 +1662,7 @@
<target state="translated">Möchtest du diese Anmeldemethode wirklich löschen?</target> <target state="translated">Möchtest du diese Anmeldemethode wirklich löschen?</target>
<context-group purpose="location"> <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="sourcefile">apps/client/src/app/components/user-account-settings/user-account-settings.component.ts</context>
<context context-type="linenumber">249</context> <context context-type="linenumber">248</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="29881a45dafbe5aa05cd9d0441a4c0c2fb06df92" datatype="html"> <trans-unit id="29881a45dafbe5aa05cd9d0441a4c0c2fb06df92" datatype="html">
@ -2906,7 +2906,7 @@
<target state="translated">Automatisch</target> <target state="translated">Automatisch</target>
<context-group purpose="location"> <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="sourcefile">apps/client/src/app/components/user-account-settings/user-account-settings.component.ts</context>
<context context-type="linenumber">40</context> <context context-type="linenumber">39</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="bbe41ac2ea4a6c00ea941a41b33105048f8e9f13" datatype="html"> <trans-unit id="bbe41ac2ea4a6c00ea941a41b33105048f8e9f13" datatype="html">
@ -6603,7 +6603,7 @@
<target state="translated">Möchtest du dieses Ghostfolio Konto wirklich schliessen?</target> <target state="translated">Möchtest du dieses Ghostfolio Konto wirklich schliessen?</target>
<context-group purpose="location"> <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="sourcefile">apps/client/src/app/components/user-account-settings/user-account-settings.component.ts</context>
<context context-type="linenumber">175</context> <context context-type="linenumber">174</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="85614ebfd89fe16873dfcf593a05f18b7468daac" datatype="html"> <trans-unit id="85614ebfd89fe16873dfcf593a05f18b7468daac" datatype="html">
@ -6651,7 +6651,7 @@
<target state="translated">Ups! Beim Einrichten der biometrischen Authentifizierung ist ein Fehler aufgetreten.</target> <target state="translated">Ups! Beim Einrichten der biometrischen Authentifizierung ist ein Fehler aufgetreten.</target>
<context-group purpose="location"> <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="sourcefile">apps/client/src/app/components/user-account-settings/user-account-settings.component.ts</context>
<context context-type="linenumber">303</context> <context context-type="linenumber">302</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="f0c5f6f270e70cbe063b5368fcf48f9afc1abd9b" datatype="html"> <trans-unit id="f0c5f6f270e70cbe063b5368fcf48f9afc1abd9b" datatype="html">
@ -7589,7 +7589,7 @@
<target state="translated">KI-Anweisung wurde in die Zwischenablage kopiert</target> <target state="translated">KI-Anweisung wurde in die Zwischenablage kopiert</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context> <context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">170</context> <context context-type="linenumber">173</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="1616747898909934803" datatype="html"> <trans-unit id="1616747898909934803" datatype="html">
@ -7685,7 +7685,7 @@
<target state="translated">Öffne Duck.ai</target> <target state="translated">Öffne Duck.ai</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context> <context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">171</context> <context context-type="linenumber">174</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="70a67e04629f6d412db0a12d51820b480788d795" datatype="html"> <trans-unit id="70a67e04629f6d412db0a12d51820b480788d795" datatype="html">

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

@ -1023,7 +1023,7 @@
</context-group> </context-group>
<context-group purpose="location"> <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="sourcefile">apps/client/src/app/components/user-account-settings/user-account-settings.component.ts</context>
<context context-type="linenumber">160</context> <context context-type="linenumber">159</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="ec8b93e2ecc776c8dc2e43a791b6974612a90148" datatype="html"> <trans-unit id="ec8b93e2ecc776c8dc2e43a791b6974612a90148" datatype="html">
@ -1663,7 +1663,7 @@
<target state="translated">¿Estás seguro de eliminar este método de acceso?</target> <target state="translated">¿Estás seguro de eliminar este método de acceso?</target>
<context-group purpose="location"> <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="sourcefile">apps/client/src/app/components/user-account-settings/user-account-settings.component.ts</context>
<context context-type="linenumber">249</context> <context context-type="linenumber">248</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="29881a45dafbe5aa05cd9d0441a4c0c2fb06df92" datatype="html"> <trans-unit id="29881a45dafbe5aa05cd9d0441a4c0c2fb06df92" datatype="html">
@ -2907,7 +2907,7 @@
<target state="translated">Automático</target> <target state="translated">Automático</target>
<context-group purpose="location"> <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="sourcefile">apps/client/src/app/components/user-account-settings/user-account-settings.component.ts</context>
<context context-type="linenumber">40</context> <context context-type="linenumber">39</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="bbe41ac2ea4a6c00ea941a41b33105048f8e9f13" datatype="html"> <trans-unit id="bbe41ac2ea4a6c00ea941a41b33105048f8e9f13" datatype="html">
@ -6604,7 +6604,7 @@
<target state="translated">¿Estás seguro de querer borrar tu cuenta de Ghostfolio?</target> <target state="translated">¿Estás seguro de querer borrar tu cuenta de Ghostfolio?</target>
<context-group purpose="location"> <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="sourcefile">apps/client/src/app/components/user-account-settings/user-account-settings.component.ts</context>
<context context-type="linenumber">175</context> <context context-type="linenumber">174</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="85614ebfd89fe16873dfcf593a05f18b7468daac" datatype="html"> <trans-unit id="85614ebfd89fe16873dfcf593a05f18b7468daac" datatype="html">
@ -6652,7 +6652,7 @@
<target state="new">Oops! There was an error setting up biometric authentication.</target> <target state="new">Oops! There was an error setting up biometric authentication.</target>
<context-group purpose="location"> <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="sourcefile">apps/client/src/app/components/user-account-settings/user-account-settings.component.ts</context>
<context context-type="linenumber">303</context> <context context-type="linenumber">302</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="f0c5f6f270e70cbe063b5368fcf48f9afc1abd9b" datatype="html"> <trans-unit id="f0c5f6f270e70cbe063b5368fcf48f9afc1abd9b" datatype="html">
@ -7590,7 +7590,7 @@
<target state="new">AI prompt has been copied to the clipboard</target> <target state="new">AI prompt has been copied to the clipboard</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context> <context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">170</context> <context context-type="linenumber">173</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="1616747898909934803" datatype="html"> <trans-unit id="1616747898909934803" datatype="html">
@ -7686,7 +7686,7 @@
<target state="new">Open Duck.ai</target> <target state="new">Open Duck.ai</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context> <context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">171</context> <context context-type="linenumber">174</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="70a67e04629f6d412db0a12d51820b480788d795" datatype="html"> <trans-unit id="70a67e04629f6d412db0a12d51820b480788d795" datatype="html">

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

@ -1334,7 +1334,7 @@
</context-group> </context-group>
<context-group purpose="location"> <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="sourcefile">apps/client/src/app/components/user-account-settings/user-account-settings.component.ts</context>
<context context-type="linenumber">160</context> <context context-type="linenumber">159</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="ec8b93e2ecc776c8dc2e43a791b6974612a90148" datatype="html"> <trans-unit id="ec8b93e2ecc776c8dc2e43a791b6974612a90148" datatype="html">
@ -1878,7 +1878,7 @@
<target state="translated">Auto</target> <target state="translated">Auto</target>
<context-group purpose="location"> <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="sourcefile">apps/client/src/app/components/user-account-settings/user-account-settings.component.ts</context>
<context context-type="linenumber">40</context> <context context-type="linenumber">39</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="1257540657265073416" datatype="html"> <trans-unit id="1257540657265073416" datatype="html">
@ -1918,7 +1918,7 @@
<target state="translated">Voulez-vous vraiment supprimer cette méthode de connexion ?</target> <target state="translated">Voulez-vous vraiment supprimer cette méthode de connexion ?</target>
<context-group purpose="location"> <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="sourcefile">apps/client/src/app/components/user-account-settings/user-account-settings.component.ts</context>
<context context-type="linenumber">249</context> <context context-type="linenumber">248</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="29881a45dafbe5aa05cd9d0441a4c0c2fb06df92" datatype="html"> <trans-unit id="29881a45dafbe5aa05cd9d0441a4c0c2fb06df92" datatype="html">
@ -6603,7 +6603,7 @@
<target state="translated">Confirmer la suppresion de votre compte Ghostfolio ?</target> <target state="translated">Confirmer la suppresion de votre compte Ghostfolio ?</target>
<context-group purpose="location"> <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="sourcefile">apps/client/src/app/components/user-account-settings/user-account-settings.component.ts</context>
<context context-type="linenumber">175</context> <context context-type="linenumber">174</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="85614ebfd89fe16873dfcf593a05f18b7468daac" datatype="html"> <trans-unit id="85614ebfd89fe16873dfcf593a05f18b7468daac" datatype="html">
@ -6651,7 +6651,7 @@
<target state="translated">Oops! Une erreur s&apos;est produite lors de la configuration de l&apos;authentification biométrique.</target> <target state="translated">Oops! Une erreur s&apos;est produite lors de la configuration de l&apos;authentification biométrique.</target>
<context-group purpose="location"> <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="sourcefile">apps/client/src/app/components/user-account-settings/user-account-settings.component.ts</context>
<context context-type="linenumber">303</context> <context context-type="linenumber">302</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="f0c5f6f270e70cbe063b5368fcf48f9afc1abd9b" datatype="html"> <trans-unit id="f0c5f6f270e70cbe063b5368fcf48f9afc1abd9b" datatype="html">
@ -7589,7 +7589,7 @@
<target state="new">AI prompt has been copied to the clipboard</target> <target state="new">AI prompt has been copied to the clipboard</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context> <context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">170</context> <context context-type="linenumber">173</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="1616747898909934803" datatype="html"> <trans-unit id="1616747898909934803" datatype="html">
@ -7685,7 +7685,7 @@
<target state="new">Open Duck.ai</target> <target state="new">Open Duck.ai</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context> <context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">171</context> <context context-type="linenumber">174</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="70a67e04629f6d412db0a12d51820b480788d795" datatype="html"> <trans-unit id="70a67e04629f6d412db0a12d51820b480788d795" datatype="html">

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

@ -1023,7 +1023,7 @@
</context-group> </context-group>
<context-group purpose="location"> <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="sourcefile">apps/client/src/app/components/user-account-settings/user-account-settings.component.ts</context>
<context context-type="linenumber">160</context> <context context-type="linenumber">159</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="ec8b93e2ecc776c8dc2e43a791b6974612a90148" datatype="html"> <trans-unit id="ec8b93e2ecc776c8dc2e43a791b6974612a90148" datatype="html">
@ -1663,7 +1663,7 @@
<target state="translated">Vuoi davvero rimuovere questo metodo di accesso?</target> <target state="translated">Vuoi davvero rimuovere questo metodo di accesso?</target>
<context-group purpose="location"> <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="sourcefile">apps/client/src/app/components/user-account-settings/user-account-settings.component.ts</context>
<context context-type="linenumber">249</context> <context context-type="linenumber">248</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="29881a45dafbe5aa05cd9d0441a4c0c2fb06df92" datatype="html"> <trans-unit id="29881a45dafbe5aa05cd9d0441a4c0c2fb06df92" datatype="html">
@ -2907,7 +2907,7 @@
<target state="translated">Auto</target> <target state="translated">Auto</target>
<context-group purpose="location"> <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="sourcefile">apps/client/src/app/components/user-account-settings/user-account-settings.component.ts</context>
<context context-type="linenumber">40</context> <context context-type="linenumber">39</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="bbe41ac2ea4a6c00ea941a41b33105048f8e9f13" datatype="html"> <trans-unit id="bbe41ac2ea4a6c00ea941a41b33105048f8e9f13" datatype="html">
@ -6604,7 +6604,7 @@
<target state="translated">Confermi di voler chiudere il tuo account Ghostfolio?</target> <target state="translated">Confermi di voler chiudere il tuo account Ghostfolio?</target>
<context-group purpose="location"> <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="sourcefile">apps/client/src/app/components/user-account-settings/user-account-settings.component.ts</context>
<context context-type="linenumber">175</context> <context context-type="linenumber">174</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="85614ebfd89fe16873dfcf593a05f18b7468daac" datatype="html"> <trans-unit id="85614ebfd89fe16873dfcf593a05f18b7468daac" datatype="html">
@ -6652,7 +6652,7 @@
<target state="translated">Ops! C&apos;è stato un errore impostando l&apos;autenticazione biometrica.</target> <target state="translated">Ops! C&apos;è stato un errore impostando l&apos;autenticazione biometrica.</target>
<context-group purpose="location"> <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="sourcefile">apps/client/src/app/components/user-account-settings/user-account-settings.component.ts</context>
<context context-type="linenumber">303</context> <context context-type="linenumber">302</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="f0c5f6f270e70cbe063b5368fcf48f9afc1abd9b" datatype="html"> <trans-unit id="f0c5f6f270e70cbe063b5368fcf48f9afc1abd9b" datatype="html">
@ -7590,7 +7590,7 @@
<target state="new">AI prompt has been copied to the clipboard</target> <target state="new">AI prompt has been copied to the clipboard</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context> <context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">170</context> <context context-type="linenumber">173</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="1616747898909934803" datatype="html"> <trans-unit id="1616747898909934803" datatype="html">
@ -7686,7 +7686,7 @@
<target state="new">Open Duck.ai</target> <target state="new">Open Duck.ai</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context> <context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">171</context> <context context-type="linenumber">174</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="70a67e04629f6d412db0a12d51820b480788d795" datatype="html"> <trans-unit id="70a67e04629f6d412db0a12d51820b480788d795" datatype="html">

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

@ -1022,7 +1022,7 @@
</context-group> </context-group>
<context-group purpose="location"> <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="sourcefile">apps/client/src/app/components/user-account-settings/user-account-settings.component.ts</context>
<context context-type="linenumber">160</context> <context context-type="linenumber">159</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="ec8b93e2ecc776c8dc2e43a791b6974612a90148" datatype="html"> <trans-unit id="ec8b93e2ecc776c8dc2e43a791b6974612a90148" datatype="html">
@ -1662,7 +1662,7 @@
<target state="translated">Wil je deze aanmeldingsmethode echt verwijderen?</target> <target state="translated">Wil je deze aanmeldingsmethode echt verwijderen?</target>
<context-group purpose="location"> <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="sourcefile">apps/client/src/app/components/user-account-settings/user-account-settings.component.ts</context>
<context context-type="linenumber">249</context> <context context-type="linenumber">248</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="29881a45dafbe5aa05cd9d0441a4c0c2fb06df92" datatype="html"> <trans-unit id="29881a45dafbe5aa05cd9d0441a4c0c2fb06df92" datatype="html">
@ -2906,7 +2906,7 @@
<target state="translated">Automatisch</target> <target state="translated">Automatisch</target>
<context-group purpose="location"> <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="sourcefile">apps/client/src/app/components/user-account-settings/user-account-settings.component.ts</context>
<context context-type="linenumber">40</context> <context context-type="linenumber">39</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="bbe41ac2ea4a6c00ea941a41b33105048f8e9f13" datatype="html"> <trans-unit id="bbe41ac2ea4a6c00ea941a41b33105048f8e9f13" datatype="html">
@ -6603,7 +6603,7 @@
<target state="new">Do you really want to close your Ghostfolio account?</target> <target state="new">Do you really want to close your Ghostfolio account?</target>
<context-group purpose="location"> <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="sourcefile">apps/client/src/app/components/user-account-settings/user-account-settings.component.ts</context>
<context context-type="linenumber">175</context> <context context-type="linenumber">174</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="85614ebfd89fe16873dfcf593a05f18b7468daac" datatype="html"> <trans-unit id="85614ebfd89fe16873dfcf593a05f18b7468daac" datatype="html">
@ -6651,7 +6651,7 @@
<target state="new">Oops! There was an error setting up biometric authentication.</target> <target state="new">Oops! There was an error setting up biometric authentication.</target>
<context-group purpose="location"> <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="sourcefile">apps/client/src/app/components/user-account-settings/user-account-settings.component.ts</context>
<context context-type="linenumber">303</context> <context context-type="linenumber">302</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="f0c5f6f270e70cbe063b5368fcf48f9afc1abd9b" datatype="html"> <trans-unit id="f0c5f6f270e70cbe063b5368fcf48f9afc1abd9b" datatype="html">
@ -7589,7 +7589,7 @@
<target state="new">AI prompt has been copied to the clipboard</target> <target state="new">AI prompt has been copied to the clipboard</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context> <context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">170</context> <context context-type="linenumber">173</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="1616747898909934803" datatype="html"> <trans-unit id="1616747898909934803" datatype="html">
@ -7685,7 +7685,7 @@
<target state="new">Open Duck.ai</target> <target state="new">Open Duck.ai</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context> <context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">171</context> <context context-type="linenumber">174</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="70a67e04629f6d412db0a12d51820b480788d795" datatype="html"> <trans-unit id="70a67e04629f6d412db0a12d51820b480788d795" datatype="html">

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

@ -2287,7 +2287,7 @@
</context-group> </context-group>
<context-group purpose="location"> <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="sourcefile">apps/client/src/app/components/user-account-settings/user-account-settings.component.ts</context>
<context context-type="linenumber">160</context> <context context-type="linenumber">159</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="ec8b93e2ecc776c8dc2e43a791b6974612a90148" datatype="html"> <trans-unit id="ec8b93e2ecc776c8dc2e43a791b6974612a90148" datatype="html">
@ -3075,7 +3075,7 @@
<target state="translated">Auto</target> <target state="translated">Auto</target>
<context-group purpose="location"> <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="sourcefile">apps/client/src/app/components/user-account-settings/user-account-settings.component.ts</context>
<context context-type="linenumber">40</context> <context context-type="linenumber">39</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="7963559562180316948" datatype="html"> <trans-unit id="7963559562180316948" datatype="html">
@ -3083,7 +3083,7 @@
<target state="translated">Czy na pewno chcesz usunąć tą metode logowania?</target> <target state="translated">Czy na pewno chcesz usunąć tą metode logowania?</target>
<context-group purpose="location"> <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="sourcefile">apps/client/src/app/components/user-account-settings/user-account-settings.component.ts</context>
<context context-type="linenumber">249</context> <context context-type="linenumber">248</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="121cc5391cd2a5115bc2b3160379ee5b36cd7716" datatype="html"> <trans-unit id="121cc5391cd2a5115bc2b3160379ee5b36cd7716" datatype="html">
@ -6603,7 +6603,7 @@
<target state="translated">Czy na pewno chcesz zamknąć swoje konto Ghostfolio?</target> <target state="translated">Czy na pewno chcesz zamknąć swoje konto Ghostfolio?</target>
<context-group purpose="location"> <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="sourcefile">apps/client/src/app/components/user-account-settings/user-account-settings.component.ts</context>
<context context-type="linenumber">175</context> <context context-type="linenumber">174</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="85614ebfd89fe16873dfcf593a05f18b7468daac" datatype="html"> <trans-unit id="85614ebfd89fe16873dfcf593a05f18b7468daac" datatype="html">
@ -6651,7 +6651,7 @@
<target state="translated">Ups! Wystąpił błąd podczas konfigurowania uwierzytelniania biometrycznego.</target> <target state="translated">Ups! Wystąpił błąd podczas konfigurowania uwierzytelniania biometrycznego.</target>
<context-group purpose="location"> <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="sourcefile">apps/client/src/app/components/user-account-settings/user-account-settings.component.ts</context>
<context context-type="linenumber">303</context> <context context-type="linenumber">302</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="f0c5f6f270e70cbe063b5368fcf48f9afc1abd9b" datatype="html"> <trans-unit id="f0c5f6f270e70cbe063b5368fcf48f9afc1abd9b" datatype="html">
@ -7589,7 +7589,7 @@
<target state="new">AI prompt has been copied to the clipboard</target> <target state="new">AI prompt has been copied to the clipboard</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context> <context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">170</context> <context context-type="linenumber">173</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="1616747898909934803" datatype="html"> <trans-unit id="1616747898909934803" datatype="html">
@ -7685,7 +7685,7 @@
<target state="new">Open Duck.ai</target> <target state="new">Open Duck.ai</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context> <context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">171</context> <context context-type="linenumber">174</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="70a67e04629f6d412db0a12d51820b480788d795" datatype="html"> <trans-unit id="70a67e04629f6d412db0a12d51820b480788d795" datatype="html">

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

@ -1206,7 +1206,7 @@
</context-group> </context-group>
<context-group purpose="location"> <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="sourcefile">apps/client/src/app/components/user-account-settings/user-account-settings.component.ts</context>
<context context-type="linenumber">160</context> <context context-type="linenumber">159</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="ec8b93e2ecc776c8dc2e43a791b6974612a90148" datatype="html"> <trans-unit id="ec8b93e2ecc776c8dc2e43a791b6974612a90148" datatype="html">
@ -1862,7 +1862,7 @@
<target state="translated">Auto</target> <target state="translated">Auto</target>
<context-group purpose="location"> <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="sourcefile">apps/client/src/app/components/user-account-settings/user-account-settings.component.ts</context>
<context context-type="linenumber">40</context> <context context-type="linenumber">39</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="1257540657265073416" datatype="html"> <trans-unit id="1257540657265073416" datatype="html">
@ -1902,7 +1902,7 @@
<target state="translated">Deseja realmente remover este método de início de sessão?</target> <target state="translated">Deseja realmente remover este método de início de sessão?</target>
<context-group purpose="location"> <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="sourcefile">apps/client/src/app/components/user-account-settings/user-account-settings.component.ts</context>
<context context-type="linenumber">249</context> <context context-type="linenumber">248</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="29881a45dafbe5aa05cd9d0441a4c0c2fb06df92" datatype="html"> <trans-unit id="29881a45dafbe5aa05cd9d0441a4c0c2fb06df92" datatype="html">
@ -6603,7 +6603,7 @@
<target state="new">Do you really want to close your Ghostfolio account?</target> <target state="new">Do you really want to close your Ghostfolio account?</target>
<context-group purpose="location"> <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="sourcefile">apps/client/src/app/components/user-account-settings/user-account-settings.component.ts</context>
<context context-type="linenumber">175</context> <context context-type="linenumber">174</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="85614ebfd89fe16873dfcf593a05f18b7468daac" datatype="html"> <trans-unit id="85614ebfd89fe16873dfcf593a05f18b7468daac" datatype="html">
@ -6651,7 +6651,7 @@
<target state="new">Oops! There was an error setting up biometric authentication.</target> <target state="new">Oops! There was an error setting up biometric authentication.</target>
<context-group purpose="location"> <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="sourcefile">apps/client/src/app/components/user-account-settings/user-account-settings.component.ts</context>
<context context-type="linenumber">303</context> <context context-type="linenumber">302</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="f0c5f6f270e70cbe063b5368fcf48f9afc1abd9b" datatype="html"> <trans-unit id="f0c5f6f270e70cbe063b5368fcf48f9afc1abd9b" datatype="html">
@ -7589,7 +7589,7 @@
<target state="new">AI prompt has been copied to the clipboard</target> <target state="new">AI prompt has been copied to the clipboard</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context> <context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">170</context> <context context-type="linenumber">173</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="1616747898909934803" datatype="html"> <trans-unit id="1616747898909934803" datatype="html">
@ -7685,7 +7685,7 @@
<target state="new">Open Duck.ai</target> <target state="new">Open Duck.ai</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context> <context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">171</context> <context context-type="linenumber">174</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="70a67e04629f6d412db0a12d51820b480788d795" datatype="html"> <trans-unit id="70a67e04629f6d412db0a12d51820b480788d795" datatype="html">

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

@ -2135,7 +2135,7 @@
</context-group> </context-group>
<context-group purpose="location"> <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="sourcefile">apps/client/src/app/components/user-account-settings/user-account-settings.component.ts</context>
<context context-type="linenumber">160</context> <context context-type="linenumber">159</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="ec8b93e2ecc776c8dc2e43a791b6974612a90148" datatype="html"> <trans-unit id="ec8b93e2ecc776c8dc2e43a791b6974612a90148" datatype="html">
@ -4895,7 +4895,7 @@
<target state="translated">Otomatik</target> <target state="translated">Otomatik</target>
<context-group purpose="location"> <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="sourcefile">apps/client/src/app/components/user-account-settings/user-account-settings.component.ts</context>
<context context-type="linenumber">40</context> <context context-type="linenumber">39</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="1257540657265073416" datatype="html"> <trans-unit id="1257540657265073416" datatype="html">
@ -4935,7 +4935,7 @@
<target state="translated">Bu giriş yöntemini kaldırmayı gerçekten istiyor musunuz?</target> <target state="translated">Bu giriş yöntemini kaldırmayı gerçekten istiyor musunuz?</target>
<context-group purpose="location"> <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="sourcefile">apps/client/src/app/components/user-account-settings/user-account-settings.component.ts</context>
<context context-type="linenumber">249</context> <context context-type="linenumber">248</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="3c33a66194384cf8c14e25170416767efa56fd98" datatype="html"> <trans-unit id="3c33a66194384cf8c14e25170416767efa56fd98" datatype="html">
@ -6603,7 +6603,7 @@
<target state="new">Do you really want to close your Ghostfolio account?</target> <target state="new">Do you really want to close your Ghostfolio account?</target>
<context-group purpose="location"> <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="sourcefile">apps/client/src/app/components/user-account-settings/user-account-settings.component.ts</context>
<context context-type="linenumber">175</context> <context context-type="linenumber">174</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="85614ebfd89fe16873dfcf593a05f18b7468daac" datatype="html"> <trans-unit id="85614ebfd89fe16873dfcf593a05f18b7468daac" datatype="html">
@ -6651,7 +6651,7 @@
<target state="new">Oops! There was an error setting up biometric authentication.</target> <target state="new">Oops! There was an error setting up biometric authentication.</target>
<context-group purpose="location"> <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="sourcefile">apps/client/src/app/components/user-account-settings/user-account-settings.component.ts</context>
<context context-type="linenumber">303</context> <context context-type="linenumber">302</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="f0c5f6f270e70cbe063b5368fcf48f9afc1abd9b" datatype="html"> <trans-unit id="f0c5f6f270e70cbe063b5368fcf48f9afc1abd9b" datatype="html">
@ -7589,7 +7589,7 @@
<target state="new">AI prompt has been copied to the clipboard</target> <target state="new">AI prompt has been copied to the clipboard</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context> <context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">170</context> <context context-type="linenumber">173</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="1616747898909934803" datatype="html"> <trans-unit id="1616747898909934803" datatype="html">
@ -7685,7 +7685,7 @@
<target state="new">Open Duck.ai</target> <target state="new">Open Duck.ai</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context> <context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">171</context> <context context-type="linenumber">174</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="70a67e04629f6d412db0a12d51820b480788d795" datatype="html"> <trans-unit id="70a67e04629f6d412db0a12d51820b480788d795" datatype="html">

14
apps/client/src/locales/messages.uk.xlf

@ -2595,7 +2595,7 @@
</context-group> </context-group>
<context-group purpose="location"> <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="sourcefile">apps/client/src/app/components/user-account-settings/user-account-settings.component.ts</context>
<context context-type="linenumber">160</context> <context context-type="linenumber">159</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="76897e07c5670ce3b7710cc10c5e1c08b5f6a83a" datatype="html"> <trans-unit id="76897e07c5670ce3b7710cc10c5e1c08b5f6a83a" datatype="html">
@ -3591,7 +3591,7 @@
<target state="translated">Автоматичний</target> <target state="translated">Автоматичний</target>
<context-group purpose="location"> <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="sourcefile">apps/client/src/app/components/user-account-settings/user-account-settings.component.ts</context>
<context context-type="linenumber">40</context> <context context-type="linenumber">39</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="4941836956820527118" datatype="html"> <trans-unit id="4941836956820527118" datatype="html">
@ -3599,7 +3599,7 @@
<target state="translated">Ви дійсно хочете закрити ваш обліковий запис Ghostfolio?</target> <target state="translated">Ви дійсно хочете закрити ваш обліковий запис Ghostfolio?</target>
<context-group purpose="location"> <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="sourcefile">apps/client/src/app/components/user-account-settings/user-account-settings.component.ts</context>
<context context-type="linenumber">175</context> <context context-type="linenumber">174</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="7963559562180316948" datatype="html"> <trans-unit id="7963559562180316948" datatype="html">
@ -3607,7 +3607,7 @@
<target state="translated">Ви дійсно хочете вилучити цей спосіб входу?</target> <target state="translated">Ви дійсно хочете вилучити цей спосіб входу?</target>
<context-group purpose="location"> <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="sourcefile">apps/client/src/app/components/user-account-settings/user-account-settings.component.ts</context>
<context context-type="linenumber">249</context> <context context-type="linenumber">248</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="5724720497710437101" datatype="html"> <trans-unit id="5724720497710437101" datatype="html">
@ -3615,7 +3615,7 @@
<target state="translated">Упс! Виникла помилка під час налаштування біометричної автентифікації.</target> <target state="translated">Упс! Виникла помилка під час налаштування біометричної автентифікації.</target>
<context-group purpose="location"> <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="sourcefile">apps/client/src/app/components/user-account-settings/user-account-settings.component.ts</context>
<context context-type="linenumber">303</context> <context context-type="linenumber">302</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="121cc5391cd2a5115bc2b3160379ee5b36cd7716" datatype="html"> <trans-unit id="121cc5391cd2a5115bc2b3160379ee5b36cd7716" datatype="html">
@ -7597,7 +7597,7 @@
<target state="translated">Запит AI скопійовано в буфер обміну</target> <target state="translated">Запит AI скопійовано в буфер обміну</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context> <context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">170</context> <context context-type="linenumber">173</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="4499ce8c46ad55564b23a42ed752e72984c0248f" datatype="html"> <trans-unit id="4499ce8c46ad55564b23a42ed752e72984c0248f" datatype="html">
@ -7685,7 +7685,7 @@
<target state="new">Open Duck.ai</target> <target state="new">Open Duck.ai</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context> <context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">171</context> <context context-type="linenumber">174</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="70a67e04629f6d412db0a12d51820b480788d795" datatype="html"> <trans-unit id="70a67e04629f6d412db0a12d51820b480788d795" datatype="html">

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

@ -2152,7 +2152,7 @@
</context-group> </context-group>
<context-group purpose="location"> <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="sourcefile">apps/client/src/app/components/user-account-settings/user-account-settings.component.ts</context>
<context context-type="linenumber">160</context> <context context-type="linenumber">159</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="ec8b93e2ecc776c8dc2e43a791b6974612a90148" datatype="html"> <trans-unit id="ec8b93e2ecc776c8dc2e43a791b6974612a90148" datatype="html">
@ -2864,14 +2864,14 @@
<source>Auto</source> <source>Auto</source>
<context-group purpose="location"> <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="sourcefile">apps/client/src/app/components/user-account-settings/user-account-settings.component.ts</context>
<context context-type="linenumber">40</context> <context context-type="linenumber">39</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="7963559562180316948" datatype="html"> <trans-unit id="7963559562180316948" datatype="html">
<source>Do you really want to remove this sign in method?</source> <source>Do you really want to remove this sign in method?</source>
<context-group purpose="location"> <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="sourcefile">apps/client/src/app/components/user-account-settings/user-account-settings.component.ts</context>
<context context-type="linenumber">249</context> <context context-type="linenumber">248</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="121cc5391cd2a5115bc2b3160379ee5b36cd7716" datatype="html"> <trans-unit id="121cc5391cd2a5115bc2b3160379ee5b36cd7716" datatype="html">
@ -6009,7 +6009,7 @@
<source>Do you really want to close your Ghostfolio account?</source> <source>Do you really want to close your Ghostfolio account?</source>
<context-group purpose="location"> <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="sourcefile">apps/client/src/app/components/user-account-settings/user-account-settings.component.ts</context>
<context context-type="linenumber">175</context> <context context-type="linenumber">174</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="85614ebfd89fe16873dfcf593a05f18b7468daac" datatype="html"> <trans-unit id="85614ebfd89fe16873dfcf593a05f18b7468daac" datatype="html">
@ -6044,7 +6044,7 @@
<source>Oops! There was an error setting up biometric authentication.</source> <source>Oops! There was an error setting up biometric authentication.</source>
<context-group purpose="location"> <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="sourcefile">apps/client/src/app/components/user-account-settings/user-account-settings.component.ts</context>
<context context-type="linenumber">303</context> <context context-type="linenumber">302</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="f0c5f6f270e70cbe063b5368fcf48f9afc1abd9b" datatype="html"> <trans-unit id="f0c5f6f270e70cbe063b5368fcf48f9afc1abd9b" datatype="html">
@ -6867,7 +6867,7 @@
<source>AI prompt has been copied to the clipboard</source> <source>AI prompt has been copied to the clipboard</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context> <context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">170</context> <context context-type="linenumber">173</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="1616747898909934803" datatype="html"> <trans-unit id="1616747898909934803" datatype="html">
@ -6951,7 +6951,7 @@
<source>Open Duck.ai</source> <source>Open Duck.ai</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context> <context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">171</context> <context context-type="linenumber">174</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="70a67e04629f6d412db0a12d51820b480788d795" datatype="html"> <trans-unit id="70a67e04629f6d412db0a12d51820b480788d795" datatype="html">

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

@ -2296,7 +2296,7 @@
</context-group> </context-group>
<context-group purpose="location"> <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="sourcefile">apps/client/src/app/components/user-account-settings/user-account-settings.component.ts</context>
<context context-type="linenumber">160</context> <context context-type="linenumber">159</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="ec8b93e2ecc776c8dc2e43a791b6974612a90148" datatype="html"> <trans-unit id="ec8b93e2ecc776c8dc2e43a791b6974612a90148" datatype="html">
@ -3084,7 +3084,7 @@
<target state="translated">自动</target> <target state="translated">自动</target>
<context-group purpose="location"> <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="sourcefile">apps/client/src/app/components/user-account-settings/user-account-settings.component.ts</context>
<context context-type="linenumber">40</context> <context context-type="linenumber">39</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="7963559562180316948" datatype="html"> <trans-unit id="7963559562180316948" datatype="html">
@ -3092,7 +3092,7 @@
<target state="translated">您确实要删除此登录方法吗?</target> <target state="translated">您确实要删除此登录方法吗?</target>
<context-group purpose="location"> <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="sourcefile">apps/client/src/app/components/user-account-settings/user-account-settings.component.ts</context>
<context context-type="linenumber">249</context> <context context-type="linenumber">248</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="121cc5391cd2a5115bc2b3160379ee5b36cd7716" datatype="html"> <trans-unit id="121cc5391cd2a5115bc2b3160379ee5b36cd7716" datatype="html">
@ -6604,7 +6604,7 @@
<target state="new">Do you really want to close your Ghostfolio account?</target> <target state="new">Do you really want to close your Ghostfolio account?</target>
<context-group purpose="location"> <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="sourcefile">apps/client/src/app/components/user-account-settings/user-account-settings.component.ts</context>
<context context-type="linenumber">175</context> <context context-type="linenumber">174</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="85614ebfd89fe16873dfcf593a05f18b7468daac" datatype="html"> <trans-unit id="85614ebfd89fe16873dfcf593a05f18b7468daac" datatype="html">
@ -6652,7 +6652,7 @@
<target state="new">Oops! There was an error setting up biometric authentication.</target> <target state="new">Oops! There was an error setting up biometric authentication.</target>
<context-group purpose="location"> <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="sourcefile">apps/client/src/app/components/user-account-settings/user-account-settings.component.ts</context>
<context context-type="linenumber">303</context> <context context-type="linenumber">302</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="f0c5f6f270e70cbe063b5368fcf48f9afc1abd9b" datatype="html"> <trans-unit id="f0c5f6f270e70cbe063b5368fcf48f9afc1abd9b" datatype="html">
@ -7590,7 +7590,7 @@
<target state="new">AI prompt has been copied to the clipboard</target> <target state="new">AI prompt has been copied to the clipboard</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context> <context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">170</context> <context context-type="linenumber">173</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="1616747898909934803" datatype="html"> <trans-unit id="1616747898909934803" datatype="html">
@ -7686,7 +7686,7 @@
<target state="new">Open Duck.ai</target> <target state="new">Open Duck.ai</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context> <context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">171</context> <context context-type="linenumber">174</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="70a67e04629f6d412db0a12d51820b480788d795" datatype="html"> <trans-unit id="70a67e04629f6d412db0a12d51820b480788d795" datatype="html">

3
libs/common/src/lib/config.ts

@ -48,13 +48,14 @@ export const PORTFOLIO_SNAPSHOT_COMPUTATION_QUEUE_PRIORITY_LOW =
export const DEFAULT_CURRENCY = 'USD'; export const DEFAULT_CURRENCY = 'USD';
export const DEFAULT_DATE_FORMAT_MONTH_YEAR = 'MMM yyyy'; export const DEFAULT_DATE_FORMAT_MONTH_YEAR = 'MMM yyyy';
export const DEFAULT_HOST = '0.0.0.0';
export const DEFAULT_LANGUAGE_CODE = 'en'; export const DEFAULT_LANGUAGE_CODE = 'en';
export const DEFAULT_PAGE_SIZE = 50; export const DEFAULT_PAGE_SIZE = 50;
export const DEFAULT_PORT = 3333;
export const DEFAULT_PROCESSOR_GATHER_ASSET_PROFILE_CONCURRENCY = 1; export const DEFAULT_PROCESSOR_GATHER_ASSET_PROFILE_CONCURRENCY = 1;
export const DEFAULT_PROCESSOR_GATHER_HISTORICAL_MARKET_DATA_CONCURRENCY = 1; export const DEFAULT_PROCESSOR_GATHER_HISTORICAL_MARKET_DATA_CONCURRENCY = 1;
export const DEFAULT_PROCESSOR_PORTFOLIO_SNAPSHOT_COMPUTATION_CONCURRENCY = 1; export const DEFAULT_PROCESSOR_PORTFOLIO_SNAPSHOT_COMPUTATION_CONCURRENCY = 1;
export const DEFAULT_PROCESSOR_PORTFOLIO_SNAPSHOT_COMPUTATION_TIMEOUT = 30000; export const DEFAULT_PROCESSOR_PORTFOLIO_SNAPSHOT_COMPUTATION_TIMEOUT = 30000;
export const DEFAULT_ROOT_URL = 'https://localhost:4200';
// USX is handled separately // USX is handled separately
export const DERIVED_CURRENCIES = [ export const DERIVED_CURRENCIES = [

2
libs/ui/src/lib/fire-calculator/fire-calculator.component.stories.ts

@ -45,7 +45,7 @@ type Story = StoryObj<GfFireCalculatorComponent>;
export const Simple: Story = { export const Simple: Story = {
args: { args: {
currency: 'USD', currency: 'USD',
fireWealth: 0, fireWealth: 50000,
locale: locale locale: locale
} }
}; };

Loading…
Cancel
Save