diff --git a/CHANGELOG.md b/CHANGELOG.md index e64c5d30d..40c7e843e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,8 +9,61 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- Added support for notes in the activities import +- Added the application version to the endpoint `GET api/v1/admin` - Introduced a carousel component for the testimonial section on the landing page +### Fixed + +- Fixed the style of the active features page in the navigation on desktop + +## 2.8.0 - 2023-10-03 + +### Added + +- Supported enter key press to submit the form of the create or update account dialog +- Added the application version to the admin control panel +- Added pagination parameters (`skip`, `take`) to the endpoint `GET api/v1/order` + +### Changed + +- Harmonized the settings icon of the user account page +- Improved the usability to set an asset profile as a benchmark +- Reload platforms after making a change in the admin control panel +- Reload tags after making a change in the admin control panel + +### Fixed + +- Fixed the sidebar navigation on the user account page + +## 2.7.0 - 2023-09-30 + +### Added + +- Added a new static portfolio analysis rule: Emergency fund setup +- Added tabs to the user account page + +### Changed + +- Set up the _Inter_ font family +- Upgraded `yahoo-finance2` from version `2.7.0` to `2.8.0` + +### Fixed + +- Fixed a link on the features page + +## 2.6.0 - 2023-09-26 + +### Added + +- Added the management of tags in the admin control panel +- Added a blog post: _Hacktoberfest 2023_ + +### Changed + +- Upgraded `prettier` from version `3.0.2` to `3.0.3` +- Upgraded `yahoo-finance2` from version `2.5.0` to `2.7.0` + ## 2.5.0 - 2023-09-23 ### Added diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index b73831d98..a950e5672 100644 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -18,6 +18,12 @@ ### Prisma +#### Access database via GUI + +Run `yarn database:gui` + +https://www.prisma.io/studio + #### Synchronize schema with database for prototyping Run `yarn database:push` diff --git a/apps/api/src/app/account/create-account.dto.ts b/apps/api/src/app/account/create-account.dto.ts index eb24d959a..fff982ecf 100644 --- a/apps/api/src/app/account/create-account.dto.ts +++ b/apps/api/src/app/account/create-account.dto.ts @@ -12,7 +12,7 @@ import { isString } from 'lodash'; export class CreateAccountDto { @IsOptional() @IsString() - accountType: AccountType; + accountType?: AccountType; @IsNumber() balance: number; diff --git a/apps/api/src/app/account/update-account.dto.ts b/apps/api/src/app/account/update-account.dto.ts index a91914482..7ab829454 100644 --- a/apps/api/src/app/account/update-account.dto.ts +++ b/apps/api/src/app/account/update-account.dto.ts @@ -12,7 +12,7 @@ import { isString } from 'lodash'; export class UpdateAccountDto { @IsOptional() @IsString() - accountType: AccountType; + accountType?: AccountType; @IsNumber() balance: number; diff --git a/apps/api/src/app/admin/admin.service.ts b/apps/api/src/app/admin/admin.service.ts index a45fbe634..dd9e3f9ce 100644 --- a/apps/api/src/app/admin/admin.service.ts +++ b/apps/api/src/app/admin/admin.service.ts @@ -1,4 +1,5 @@ import { SubscriptionService } from '@ghostfolio/api/app/subscription/subscription.service'; +import { environment } from '@ghostfolio/api/environments/environment'; import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service'; import { DataProviderService } from '@ghostfolio/api/services/data-provider/data-provider.service'; import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; @@ -97,7 +98,8 @@ export class AdminService { settings: await this.propertyService.get(), transactionCount: await this.prismaService.order.count(), userCount: await this.prismaService.user.count(), - users: await this.getUsersWithAnalytics() + users: await this.getUsersWithAnalytics(), + version: environment.version }; } diff --git a/apps/api/src/app/app.module.ts b/apps/api/src/app/app.module.ts index a521e7fa9..03c6a4aaa 100644 --- a/apps/api/src/app/app.module.ts +++ b/apps/api/src/app/app.module.ts @@ -39,6 +39,7 @@ import { RedisCacheModule } from './redis-cache/redis-cache.module'; import { SitemapModule } from './sitemap/sitemap.module'; import { SubscriptionModule } from './subscription/subscription.module'; import { SymbolModule } from './symbol/symbol.module'; +import { TagModule } from './tag/tag.module'; import { UserModule } from './user/user.module'; @Module({ @@ -101,6 +102,7 @@ import { UserModule } from './user/user.module'; SitemapModule, SubscriptionModule, SymbolModule, + TagModule, TwitterBotModule, UserModule ], diff --git a/apps/api/src/app/benchmark/benchmark.controller.ts b/apps/api/src/app/benchmark/benchmark.controller.ts index d59a231ff..2230ff42b 100644 --- a/apps/api/src/app/benchmark/benchmark.controller.ts +++ b/apps/api/src/app/benchmark/benchmark.controller.ts @@ -10,6 +10,7 @@ import type { RequestWithUser } from '@ghostfolio/common/types'; import { Body, Controller, + Delete, Get, HttpException, Inject, @@ -32,35 +33,49 @@ export class BenchmarkController { @Inject(REQUEST) private readonly request: RequestWithUser ) {} - @Get() - @UseInterceptors(TransformDataSourceInRequestInterceptor) - @UseInterceptors(TransformDataSourceInResponseInterceptor) - public async getBenchmark(): Promise { - return { - benchmarks: await this.benchmarkService.getBenchmarks() - }; - } - - @Get(':dataSource/:symbol/:startDateString') + @Post() @UseGuards(AuthGuard('jwt')) - @UseInterceptors(TransformDataSourceInRequestInterceptor) - public async getBenchmarkMarketDataBySymbol( - @Param('dataSource') dataSource: DataSource, - @Param('startDateString') startDateString: string, - @Param('symbol') symbol: string - ): Promise { - const startDate = new Date(startDateString); + public async addBenchmark(@Body() { dataSource, symbol }: UniqueAsset) { + if ( + !hasPermission( + this.request.user.permissions, + permissions.accessAdminControl + ) + ) { + throw new HttpException( + getReasonPhrase(StatusCodes.FORBIDDEN), + StatusCodes.FORBIDDEN + ); + } - return this.benchmarkService.getMarketDataBySymbol({ - dataSource, - startDate, - symbol - }); + try { + const benchmark = await this.benchmarkService.addBenchmark({ + dataSource, + symbol + }); + + if (!benchmark) { + throw new HttpException( + getReasonPhrase(StatusCodes.NOT_FOUND), + StatusCodes.NOT_FOUND + ); + } + + return benchmark; + } catch { + throw new HttpException( + getReasonPhrase(StatusCodes.INTERNAL_SERVER_ERROR), + StatusCodes.INTERNAL_SERVER_ERROR + ); + } } - @Post() + @Delete(':dataSource/:symbol') @UseGuards(AuthGuard('jwt')) - public async addBenchmark(@Body() { dataSource, symbol }: UniqueAsset) { + public async deleteBenchmark( + @Param('dataSource') dataSource: DataSource, + @Param('symbol') symbol: string + ) { if ( !hasPermission( this.request.user.permissions, @@ -74,7 +89,7 @@ export class BenchmarkController { } try { - const benchmark = await this.benchmarkService.addBenchmark({ + const benchmark = await this.benchmarkService.deleteBenchmark({ dataSource, symbol }); @@ -94,4 +109,30 @@ export class BenchmarkController { ); } } + + @Get() + @UseInterceptors(TransformDataSourceInRequestInterceptor) + @UseInterceptors(TransformDataSourceInResponseInterceptor) + public async getBenchmark(): Promise { + return { + benchmarks: await this.benchmarkService.getBenchmarks() + }; + } + + @Get(':dataSource/:symbol/:startDateString') + @UseGuards(AuthGuard('jwt')) + @UseInterceptors(TransformDataSourceInRequestInterceptor) + public async getBenchmarkMarketDataBySymbol( + @Param('dataSource') dataSource: DataSource, + @Param('startDateString') startDateString: string, + @Param('symbol') symbol: string + ): Promise { + const startDate = new Date(startDateString); + + return this.benchmarkService.getMarketDataBySymbol({ + dataSource, + startDate, + symbol + }); + } } diff --git a/apps/api/src/app/benchmark/benchmark.service.ts b/apps/api/src/app/benchmark/benchmark.service.ts index 785c2801a..7fe1911a4 100644 --- a/apps/api/src/app/benchmark/benchmark.service.ts +++ b/apps/api/src/app/benchmark/benchmark.service.ts @@ -245,6 +245,43 @@ export class BenchmarkService { }; } + public async deleteBenchmark({ + dataSource, + symbol + }: UniqueAsset): Promise> { + const assetProfile = await this.prismaService.symbolProfile.findFirst({ + where: { + dataSource, + symbol + } + }); + + if (!assetProfile) { + return null; + } + + let benchmarks = + ((await this.propertyService.getByKey( + PROPERTY_BENCHMARKS + )) as BenchmarkProperty[]) ?? []; + + benchmarks = benchmarks.filter(({ symbolProfileId }) => { + return symbolProfileId !== assetProfile.id; + }); + + await this.propertyService.put({ + key: PROPERTY_BENCHMARKS, + value: JSON.stringify(benchmarks) + }); + + return { + dataSource, + symbol, + id: assetProfile.id, + name: assetProfile.name + }; + } + private getMarketCondition(aPerformanceInPercent: number) { return aPerformanceInPercent <= -0.2 ? 'BEAR_MARKET' : 'NEUTRAL_MARKET'; } diff --git a/apps/api/src/app/order/order.controller.ts b/apps/api/src/app/order/order.controller.ts index be6a6bead..8c8e3e27a 100644 --- a/apps/api/src/app/order/order.controller.ts +++ b/apps/api/src/app/order/order.controller.ts @@ -89,7 +89,9 @@ export class OrderController { @Headers(HEADER_KEY_IMPERSONATION.toLowerCase()) impersonationId, @Query('accounts') filterByAccounts?: string, @Query('assetClasses') filterByAssetClasses?: string, - @Query('tags') filterByTags?: string + @Query('skip') skip?: number, + @Query('tags') filterByTags?: string, + @Query('take') take?: number ): Promise { const filters = this.apiService.buildFiltersFromQueryParams({ filterByAccounts, @@ -105,6 +107,8 @@ export class OrderController { filters, userCurrency, includeDrafts: true, + skip: isNaN(skip) ? undefined : skip, + take: isNaN(take) ? undefined : take, userId: impersonationUserId || this.request.user.id, withExcludedAccounts: true }); diff --git a/apps/api/src/app/order/order.service.ts b/apps/api/src/app/order/order.service.ts index f518e0bb3..10515018c 100644 --- a/apps/api/src/app/order/order.service.ts +++ b/apps/api/src/app/order/order.service.ts @@ -230,6 +230,8 @@ export class OrderService { public async getOrders({ filters, includeDrafts = false, + skip, + take = Number.MAX_SAFE_INTEGER, types, userCurrency, userId, @@ -237,6 +239,8 @@ export class OrderService { }: { filters?: Filter[]; includeDrafts?: boolean; + skip?: number; + take?: number; types?: TypeOfOrder[]; userCurrency: string; userId: string; @@ -315,6 +319,8 @@ export class OrderService { return ( await this.orders({ + skip, + take, where, include: { // eslint-disable-next-line @typescript-eslint/naming-convention diff --git a/apps/api/src/app/portfolio/portfolio.service.ts b/apps/api/src/app/portfolio/portfolio.service.ts index 228ab18f6..b9d6cef1b 100644 --- a/apps/api/src/app/portfolio/portfolio.service.ts +++ b/apps/api/src/app/portfolio/portfolio.service.ts @@ -10,6 +10,7 @@ import { AccountClusterRiskCurrentInvestment } from '@ghostfolio/api/models/rule import { AccountClusterRiskSingleAccount } from '@ghostfolio/api/models/rules/account-cluster-risk/single-account'; import { CurrencyClusterRiskBaseCurrencyCurrentInvestment } from '@ghostfolio/api/models/rules/currency-cluster-risk/base-currency-current-investment'; import { CurrencyClusterRiskCurrentInvestment } from '@ghostfolio/api/models/rules/currency-cluster-risk/current-investment'; +import { EmergencyFundSetup } from '@ghostfolio/api/models/rules/emergency-fund/emergency-fund-setup'; import { FeeRatioInitialInvestment } from '@ghostfolio/api/models/rules/fees/fee-ratio-initial-investment'; import { DataProviderService } from '@ghostfolio/api/services/data-provider/data-provider.service'; import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; @@ -50,13 +51,13 @@ import { Inject, Injectable } from '@nestjs/common'; import { REQUEST } from '@nestjs/core'; import { Account, + Type as ActivityType, AssetClass, DataSource, Order, Platform, Prisma, - Tag, - Type as ActivityType + Tag } from '@prisma/client'; import Big from 'big.js'; import { @@ -1214,12 +1215,6 @@ export class PortfolioService { userId }); - if (isEmpty(orders)) { - return { - rules: {} - }; - } - const portfolioCalculator = new PortfolioCalculator({ currency: userCurrency, currentRateService: this.currentRateService, @@ -1228,7 +1223,9 @@ export class PortfolioService { portfolioCalculator.setTransactionPoints(transactionPoints); - const portfolioStart = parseDate(transactionPoints[0].date); + const portfolioStart = parseDate( + transactionPoints[0]?.date ?? format(new Date(), DATE_FORMAT) + ); const currentPositions = await portfolioCalculator.getCurrentPositions(portfolioStart); @@ -1249,33 +1246,48 @@ export class PortfolioService { userId }); + const userSettings = this.request.user.Settings.settings; + return { rules: { - accountClusterRisk: await this.rulesService.evaluate( - [ - new AccountClusterRiskCurrentInvestment( - this.exchangeRateDataService, - accounts + accountClusterRisk: isEmpty(orders) + ? undefined + : await this.rulesService.evaluate( + [ + new AccountClusterRiskCurrentInvestment( + this.exchangeRateDataService, + accounts + ), + new AccountClusterRiskSingleAccount( + this.exchangeRateDataService, + accounts + ) + ], + userSettings ), - new AccountClusterRiskSingleAccount( - this.exchangeRateDataService, - accounts - ) - ], - this.request.user.Settings.settings - ), - currencyClusterRisk: await this.rulesService.evaluate( - [ - new CurrencyClusterRiskBaseCurrencyCurrentInvestment( - this.exchangeRateDataService, - positions + currencyClusterRisk: isEmpty(orders) + ? undefined + : await this.rulesService.evaluate( + [ + new CurrencyClusterRiskBaseCurrencyCurrentInvestment( + this.exchangeRateDataService, + positions + ), + new CurrencyClusterRiskCurrentInvestment( + this.exchangeRateDataService, + positions + ) + ], + userSettings ), - new CurrencyClusterRiskCurrentInvestment( + emergencyFund: await this.rulesService.evaluate( + [ + new EmergencyFundSetup( this.exchangeRateDataService, - positions + userSettings.emergencyFund ) ], - this.request.user.Settings.settings + userSettings ), fees: await this.rulesService.evaluate( [ @@ -1285,7 +1297,7 @@ export class PortfolioService { this.getFees({ userCurrency, activities: orders }).toNumber() ) ], - this.request.user.Settings.settings + userSettings ) } }; diff --git a/apps/api/src/app/tag/create-tag.dto.ts b/apps/api/src/app/tag/create-tag.dto.ts new file mode 100644 index 000000000..650a0ce12 --- /dev/null +++ b/apps/api/src/app/tag/create-tag.dto.ts @@ -0,0 +1,6 @@ +import { IsString } from 'class-validator'; + +export class CreateTagDto { + @IsString() + name: string; +} diff --git a/apps/api/src/app/tag/tag.controller.ts b/apps/api/src/app/tag/tag.controller.ts new file mode 100644 index 000000000..950719201 --- /dev/null +++ b/apps/api/src/app/tag/tag.controller.ts @@ -0,0 +1,104 @@ +import { hasPermission, permissions } from '@ghostfolio/common/permissions'; +import type { RequestWithUser } from '@ghostfolio/common/types'; +import { + Body, + Controller, + Delete, + Get, + HttpException, + Inject, + Param, + Post, + Put, + UseGuards +} from '@nestjs/common'; +import { REQUEST } from '@nestjs/core'; +import { AuthGuard } from '@nestjs/passport'; +import { Tag } from '@prisma/client'; +import { StatusCodes, getReasonPhrase } from 'http-status-codes'; + +import { CreateTagDto } from './create-tag.dto'; +import { TagService } from './tag.service'; +import { UpdateTagDto } from './update-tag.dto'; + +@Controller('tag') +export class TagController { + public constructor( + @Inject(REQUEST) private readonly request: RequestWithUser, + private readonly tagService: TagService + ) {} + + @Get() + @UseGuards(AuthGuard('jwt')) + public async getTags() { + return this.tagService.getTagsWithActivityCount(); + } + + @Post() + @UseGuards(AuthGuard('jwt')) + public async createTag(@Body() data: CreateTagDto): Promise { + if (!hasPermission(this.request.user.permissions, permissions.createTag)) { + throw new HttpException( + getReasonPhrase(StatusCodes.FORBIDDEN), + StatusCodes.FORBIDDEN + ); + } + + return this.tagService.createTag(data); + } + + @Put(':id') + @UseGuards(AuthGuard('jwt')) + public async updateTag(@Param('id') id: string, @Body() data: UpdateTagDto) { + if (!hasPermission(this.request.user.permissions, permissions.updateTag)) { + throw new HttpException( + getReasonPhrase(StatusCodes.FORBIDDEN), + StatusCodes.FORBIDDEN + ); + } + + const originalTag = await this.tagService.getTag({ + id + }); + + if (!originalTag) { + throw new HttpException( + getReasonPhrase(StatusCodes.FORBIDDEN), + StatusCodes.FORBIDDEN + ); + } + + return this.tagService.updateTag({ + data: { + ...data + }, + where: { + id + } + }); + } + + @Delete(':id') + @UseGuards(AuthGuard('jwt')) + public async deleteTag(@Param('id') id: string) { + if (!hasPermission(this.request.user.permissions, permissions.deleteTag)) { + throw new HttpException( + getReasonPhrase(StatusCodes.FORBIDDEN), + StatusCodes.FORBIDDEN + ); + } + + const originalTag = await this.tagService.getTag({ + id + }); + + if (!originalTag) { + throw new HttpException( + getReasonPhrase(StatusCodes.FORBIDDEN), + StatusCodes.FORBIDDEN + ); + } + + return this.tagService.deleteTag({ id }); + } +} diff --git a/apps/api/src/app/tag/tag.module.ts b/apps/api/src/app/tag/tag.module.ts new file mode 100644 index 000000000..810105c51 --- /dev/null +++ b/apps/api/src/app/tag/tag.module.ts @@ -0,0 +1,13 @@ +import { PrismaModule } from '@ghostfolio/api/services/prisma/prisma.module'; +import { Module } from '@nestjs/common'; + +import { TagController } from './tag.controller'; +import { TagService } from './tag.service'; + +@Module({ + controllers: [TagController], + exports: [TagService], + imports: [PrismaModule], + providers: [TagService] +}) +export class TagModule {} diff --git a/apps/api/src/app/tag/tag.service.ts b/apps/api/src/app/tag/tag.service.ts new file mode 100644 index 000000000..9da7cc475 --- /dev/null +++ b/apps/api/src/app/tag/tag.service.ts @@ -0,0 +1,79 @@ +import { PrismaService } from '@ghostfolio/api/services/prisma/prisma.service'; +import { Injectable } from '@nestjs/common'; +import { Prisma, Tag } from '@prisma/client'; + +@Injectable() +export class TagService { + public constructor(private readonly prismaService: PrismaService) {} + + public async createTag(data: Prisma.TagCreateInput) { + return this.prismaService.tag.create({ + data + }); + } + + public async deleteTag(where: Prisma.TagWhereUniqueInput): Promise { + return this.prismaService.tag.delete({ where }); + } + + public async getTag( + tagWhereUniqueInput: Prisma.TagWhereUniqueInput + ): Promise { + return this.prismaService.tag.findUnique({ + where: tagWhereUniqueInput + }); + } + + public async getTags({ + cursor, + orderBy, + skip, + take, + where + }: { + cursor?: Prisma.TagWhereUniqueInput; + orderBy?: Prisma.TagOrderByWithRelationInput; + skip?: number; + take?: number; + where?: Prisma.TagWhereInput; + } = {}) { + return this.prismaService.tag.findMany({ + cursor, + orderBy, + skip, + take, + where + }); + } + + public async getTagsWithActivityCount() { + const tagsWithOrderCount = await this.prismaService.tag.findMany({ + include: { + _count: { + select: { orders: true } + } + } + }); + + return tagsWithOrderCount.map(({ _count, id, name }) => { + return { + id, + name, + activityCount: _count.orders + }; + }); + } + + public async updateTag({ + data, + where + }: { + data: Prisma.TagUpdateInput; + where: Prisma.TagWhereUniqueInput; + }): Promise { + return this.prismaService.tag.update({ + data, + where + }); + } +} diff --git a/apps/api/src/app/tag/update-tag.dto.ts b/apps/api/src/app/tag/update-tag.dto.ts new file mode 100644 index 000000000..b26ffde11 --- /dev/null +++ b/apps/api/src/app/tag/update-tag.dto.ts @@ -0,0 +1,9 @@ +import { IsString } from 'class-validator'; + +export class UpdateTagDto { + @IsString() + id: string; + + @IsString() + name: string; +} diff --git a/apps/api/src/assets/sitemap.xml b/apps/api/src/assets/sitemap.xml index 52b2154e0..2a3650752 100644 --- a/apps/api/src/assets/sitemap.xml +++ b/apps/api/src/assets/sitemap.xml @@ -78,6 +78,10 @@ https://ghostfol.io/de/ressourcen/personal-finance-tools/open-source-alternative-zu-exirio ${currentDate}T00:00:00+00:00 + + https://ghostfol.io/de/ressourcen/personal-finance-tools/open-source-alternative-zu-finary + ${currentDate}T00:00:00+00:00 + https://ghostfol.io/de/ressourcen/personal-finance-tools/open-source-alternative-zu-folishare ${currentDate}T00:00:00+00:00 @@ -146,6 +150,10 @@ https://ghostfol.io/de/ressourcen/personal-finance-tools/open-source-alternative-zu-snowball-analytics ${currentDate}T00:00:00+00:00 + + https://ghostfol.io/de/ressourcen/personal-finance-tools/open-source-alternative-zu-stockle + ${currentDate}T00:00:00+00:00 + https://ghostfol.io/de/ressourcen/personal-finance-tools/open-source-alternative-zu-stockmarketeye ${currentDate}T00:00:00+00:00 @@ -262,6 +270,10 @@ https://ghostfol.io/en/blog/2023/09/ghostfolio-2 ${currentDate}T00:00:00+00:00 + + https://ghostfol.io/en/blog/2023/09/hacktoberfest-2023 + ${currentDate}T00:00:00+00:00 + https://ghostfol.io/en/faq ${currentDate}T00:00:00+00:00 @@ -320,6 +332,10 @@ https://ghostfol.io/en/resources/personal-finance-tools/open-source-alternative-to-exirio ${currentDate}T00:00:00+00:00 + + https://ghostfol.io/en/resources/personal-finance-tools/open-source-alternative-to-finary + ${currentDate}T00:00:00+00:00 + https://ghostfol.io/en/resources/personal-finance-tools/open-source-alternative-to-folishare ${currentDate}T00:00:00+00:00 @@ -388,6 +404,10 @@ https://ghostfol.io/en/resources/personal-finance-tools/open-source-alternative-to-snowball-analytics ${currentDate}T00:00:00+00:00 + + https://ghostfol.io/en/resources/personal-finance-tools/open-source-alternative-to-stockle + ${currentDate}T00:00:00+00:00 + https://ghostfol.io/en/resources/personal-finance-tools/open-source-alternative-to-stockmarketeye ${currentDate}T00:00:00+00:00 @@ -594,6 +614,10 @@ https://ghostfol.io/it/risorse/personal-finance-tools/alternativa-open-source-a-exirio ${currentDate}T00:00:00+00:00 + + https://ghostfol.io/it/risorse/personal-finance-tools/alternativa-open-source-a-finary + ${currentDate}T00:00:00+00:00 + https://ghostfol.io/it/risorse/personal-finance-tools/alternativa-open-source-a-folishare ${currentDate}T00:00:00+00:00 @@ -662,6 +686,10 @@ https://ghostfol.io/it/risorse/personal-finance-tools/alternativa-open-source-a-snowball-analytics ${currentDate}T00:00:00+00:00 + + https://ghostfol.io/it/risorse/personal-finance-tools/alternativa-open-source-a-stockle + ${currentDate}T00:00:00+00:00 + https://ghostfol.io/it/risorse/personal-finance-tools/alternativa-open-source-a-stockmarketeye ${currentDate}T00:00:00+00:00 @@ -714,6 +742,10 @@ https://ghostfol.io/nl/bronnen/personal-finance-tools/open-source-alternatief-voor-exirio ${currentDate}T00:00:00+00:00 + + https://ghostfol.io/nl/bronnen/personal-finance-tools/open-source-alternatief-voor-finary + ${currentDate}T00:00:00+00:00 + https://ghostfol.io/nl/bronnen/personal-finance-tools/open-source-alternatief-voor-folishare ${currentDate}T00:00:00+00:00 @@ -782,6 +814,10 @@ https://ghostfol.io/nl/bronnen/personal-finance-tools/open-source-alternatief-voor-snowball-analytics ${currentDate}T00:00:00+00:00 + + https://ghostfol.io/nl/bronnen/personal-finance-tools/open-source-alternatief-voor-stockle + ${currentDate}T00:00:00+00:00 + https://ghostfol.io/nl/bronnen/personal-finance-tools/open-source-alternatief-voor-stockmarketeye ${currentDate}T00:00:00+00:00 diff --git a/apps/api/src/helper/object.helper.ts b/apps/api/src/helper/object.helper.ts index 50a4f2b12..2f0399fb8 100644 --- a/apps/api/src/helper/object.helper.ts +++ b/apps/api/src/helper/object.helper.ts @@ -3,7 +3,7 @@ import { cloneDeep, isArray, isObject } from 'lodash'; export function hasNotDefinedValuesInObject(aObject: Object): boolean { for (const key in aObject) { - if (aObject[key] === null || aObject[key] === null) { + if (aObject[key] === null || aObject[key] === undefined) { return true; } else if (isObject(aObject[key])) { return hasNotDefinedValuesInObject(aObject[key]); diff --git a/apps/api/src/middlewares/html-template.middleware.ts b/apps/api/src/middlewares/html-template.middleware.ts index 2b7d24cb6..9d44bdbe0 100644 --- a/apps/api/src/middlewares/html-template.middleware.ts +++ b/apps/api/src/middlewares/html-template.middleware.ts @@ -80,6 +80,10 @@ const locales = { '/en/blog/2023/09/ghostfolio-2': { featureGraphicPath: 'assets/images/blog/ghostfolio-2.jpg', title: `Announcing Ghostfolio 2.0 - ${titleShort}` + }, + '/en/blog/2023/09/hacktoberfest-2023': { + featureGraphicPath: 'assets/images/blog/hacktoberfest-2023.png', + title: `Hacktoberfest 2023 - ${titleShort}` } }; diff --git a/apps/api/src/models/rules/account-cluster-risk/current-investment.ts b/apps/api/src/models/rules/account-cluster-risk/current-investment.ts index d0cdbb58c..23d3307de 100644 --- a/apps/api/src/models/rules/account-cluster-risk/current-investment.ts +++ b/apps/api/src/models/rules/account-cluster-risk/current-investment.ts @@ -1,4 +1,5 @@ import { RuleSettings } from '@ghostfolio/api/models/interfaces/rule-settings.interface'; +import { Rule } from '@ghostfolio/api/models/rule'; import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; import { PortfolioDetails, @@ -6,16 +7,18 @@ import { UserSettings } from '@ghostfolio/common/interfaces'; -import { Rule } from '../../rule'; - export class AccountClusterRiskCurrentInvestment extends Rule { + private accounts: PortfolioDetails['accounts']; + public constructor( protected exchangeRateDataService: ExchangeRateDataService, - private accounts: PortfolioDetails['accounts'] + accounts: PortfolioDetails['accounts'] ) { super(exchangeRateDataService, { name: 'Investment' }); + + this.accounts = accounts; } public evaluate(ruleSettings: Settings) { diff --git a/apps/api/src/models/rules/account-cluster-risk/single-account.ts b/apps/api/src/models/rules/account-cluster-risk/single-account.ts index 3be323d7c..b5028228a 100644 --- a/apps/api/src/models/rules/account-cluster-risk/single-account.ts +++ b/apps/api/src/models/rules/account-cluster-risk/single-account.ts @@ -1,17 +1,20 @@ import { RuleSettings } from '@ghostfolio/api/models/interfaces/rule-settings.interface'; +import { Rule } from '@ghostfolio/api/models/rule'; import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; import { PortfolioDetails, UserSettings } from '@ghostfolio/common/interfaces'; -import { Rule } from '../../rule'; - export class AccountClusterRiskSingleAccount extends Rule { + private accounts: PortfolioDetails['accounts']; + public constructor( protected exchangeRateDataService: ExchangeRateDataService, - private accounts: PortfolioDetails['accounts'] + accounts: PortfolioDetails['accounts'] ) { super(exchangeRateDataService, { name: 'Single Account' }); + + this.accounts = accounts; } public evaluate() { diff --git a/apps/api/src/models/rules/currency-cluster-risk/base-currency-current-investment.ts b/apps/api/src/models/rules/currency-cluster-risk/base-currency-current-investment.ts index 2facb8803..a23a208c3 100644 --- a/apps/api/src/models/rules/currency-cluster-risk/base-currency-current-investment.ts +++ b/apps/api/src/models/rules/currency-cluster-risk/base-currency-current-investment.ts @@ -1,17 +1,20 @@ import { RuleSettings } from '@ghostfolio/api/models/interfaces/rule-settings.interface'; +import { Rule } from '@ghostfolio/api/models/rule'; import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; import { TimelinePosition, UserSettings } from '@ghostfolio/common/interfaces'; -import { Rule } from '../../rule'; - export class CurrencyClusterRiskBaseCurrencyCurrentInvestment extends Rule { + private positions: TimelinePosition[]; + public constructor( protected exchangeRateDataService: ExchangeRateDataService, - private positions: TimelinePosition[] + positions: TimelinePosition[] ) { super(exchangeRateDataService, { name: 'Investment: Base Currency' }); + + this.positions = positions; } public evaluate(ruleSettings: Settings) { diff --git a/apps/api/src/models/rules/currency-cluster-risk/current-investment.ts b/apps/api/src/models/rules/currency-cluster-risk/current-investment.ts index 2d69865f5..bd6e060ef 100644 --- a/apps/api/src/models/rules/currency-cluster-risk/current-investment.ts +++ b/apps/api/src/models/rules/currency-cluster-risk/current-investment.ts @@ -1,17 +1,20 @@ import { RuleSettings } from '@ghostfolio/api/models/interfaces/rule-settings.interface'; +import { Rule } from '@ghostfolio/api/models/rule'; import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; import { TimelinePosition, UserSettings } from '@ghostfolio/common/interfaces'; -import { Rule } from '../../rule'; - export class CurrencyClusterRiskCurrentInvestment extends Rule { + private positions: TimelinePosition[]; + public constructor( protected exchangeRateDataService: ExchangeRateDataService, - private positions: TimelinePosition[] + positions: TimelinePosition[] ) { super(exchangeRateDataService, { name: 'Investment' }); + + this.positions = positions; } public evaluate(ruleSettings: Settings) { diff --git a/apps/api/src/models/rules/emergency-fund/emergency-fund-setup.ts b/apps/api/src/models/rules/emergency-fund/emergency-fund-setup.ts new file mode 100644 index 000000000..b6248ab51 --- /dev/null +++ b/apps/api/src/models/rules/emergency-fund/emergency-fund-setup.ts @@ -0,0 +1,46 @@ +import { RuleSettings } from '@ghostfolio/api/models/interfaces/rule-settings.interface'; +import { Rule } from '@ghostfolio/api/models/rule'; +import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; +import { UserSettings } from '@ghostfolio/common/interfaces'; + +export class EmergencyFundSetup extends Rule { + private emergencyFund: number; + + public constructor( + protected exchangeRateDataService: ExchangeRateDataService, + emergencyFund: number + ) { + super(exchangeRateDataService, { + name: 'Emergency Fund: Set up' + }); + + this.emergencyFund = emergencyFund; + } + + public evaluate(ruleSettings: Settings) { + if (this.emergencyFund > ruleSettings.threshold) { + return { + evaluation: 'An emergency fund has been set up', + value: true + }; + } + + return { + evaluation: 'No emergency fund has been set up', + value: false + }; + } + + public getSettings(aUserSettings: UserSettings): Settings { + return { + baseCurrency: aUserSettings.baseCurrency, + isActive: true, + threshold: 0 + }; + } +} + +interface Settings extends RuleSettings { + baseCurrency: string; + threshold: number; +} diff --git a/apps/api/src/models/rules/fees/fee-ratio-initial-investment.ts b/apps/api/src/models/rules/fees/fee-ratio-initial-investment.ts index dfe375c43..0ba70d23c 100644 --- a/apps/api/src/models/rules/fees/fee-ratio-initial-investment.ts +++ b/apps/api/src/models/rules/fees/fee-ratio-initial-investment.ts @@ -1,22 +1,29 @@ import { RuleSettings } from '@ghostfolio/api/models/interfaces/rule-settings.interface'; +import { Rule } from '@ghostfolio/api/models/rule'; import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; import { UserSettings } from '@ghostfolio/common/interfaces'; -import { Rule } from '../../rule'; - export class FeeRatioInitialInvestment extends Rule { + private fees: number; + private totalInvestment: number; + public constructor( protected exchangeRateDataService: ExchangeRateDataService, - private totalInvestment: number, - private fees: number + totalInvestment: number, + fees: number ) { super(exchangeRateDataService, { - name: 'Investment' + name: 'Fee Ratio' }); + + this.fees = fees; + this.totalInvestment = totalInvestment; } public evaluate(ruleSettings: Settings) { - const feeRatio = this.fees / this.totalInvestment; + const feeRatio = this.totalInvestment + ? this.fees / this.totalInvestment + : 0; if (feeRatio > ruleSettings.threshold) { return { diff --git a/apps/client/project.json b/apps/client/project.json index 03cbde62d..2e36f7144 100644 --- a/apps/client/project.json +++ b/apps/client/project.json @@ -21,6 +21,7 @@ "tsConfig": "apps/client/tsconfig.app.json", "assets": [], "styles": [ + "apps/client/src/assets/fonts/inter.css", "apps/client/src/styles/theme.scss", "apps/client/src/styles.scss" ], @@ -103,40 +104,40 @@ "options": { "commands": [ { - "command": "mkdir -p dist/apps/client" + "command": "shx mkdir -p dist/apps/client" }, { - "command": "cp -r apps/client/src/assets dist/apps/client" + "command": "shx cp -r apps/client/src/assets dist/apps/client" }, { - "command": "cp -r apps/client/src/assets/.well-known dist/apps/client" + "command": "shx cp -r apps/client/src/assets/.well-known dist/apps/client" }, { - "command": "cp apps/client/src/assets/favicon.ico dist/apps/client" + "command": "shx cp apps/client/src/assets/favicon.ico dist/apps/client" }, { - "command": "cp apps/client/src/assets/index.html dist/apps/client" + "command": "shx cp apps/client/src/assets/index.html dist/apps/client" }, { - "command": "cp apps/client/src/assets/robots.txt dist/apps/client" + "command": "shx cp apps/client/src/assets/robots.txt dist/apps/client" }, { - "command": "cp apps/client/src/assets/site.webmanifest dist/apps/client" + "command": "shx cp apps/client/src/assets/site.webmanifest dist/apps/client" }, { - "command": "cp node_modules/ionicons/dist/index.js dist/apps/client" + "command": "shx cp node_modules/ionicons/dist/index.js dist/apps/client" }, { - "command": "cp node_modules/ionicons/dist/ionicons.js dist/apps/client" + "command": "shx cp node_modules/ionicons/dist/ionicons.js dist/apps/client" }, { - "command": "cp -r node_modules/ionicons/dist/ionicons dist/apps/client/ionicons" + "command": "shx cp -r node_modules/ionicons/dist/ionicons dist/apps/client/ionicons" }, { - "command": "cp CHANGELOG.md dist/apps/client/assets" + "command": "shx cp CHANGELOG.md dist/apps/client/assets" }, { - "command": "cp LICENSE dist/apps/client/assets" + "command": "shx cp LICENSE dist/apps/client/assets" } ] } diff --git a/apps/client/src/app/app.component.ts b/apps/client/src/app/app.component.ts index f260f4bbd..d1d9529ce 100644 --- a/apps/client/src/app/app.component.ts +++ b/apps/client/src/app/app.component.ts @@ -112,6 +112,7 @@ export class AppComponent implements OnDestroy, OnInit { this.hasTabs = (this.currentRoute === this.routerLinkAbout[0].slice(1) || + this.currentRoute === 'account' || this.currentRoute === 'admin' || this.currentRoute === 'home' || this.currentRoute === 'portfolio' || diff --git a/apps/client/src/app/app.module.ts b/apps/client/src/app/app.module.ts index a5f0d755c..608ba0100 100644 --- a/apps/client/src/app/app.module.ts +++ b/apps/client/src/app/app.module.ts @@ -1,6 +1,6 @@ import { Platform } from '@angular/cdk/platform'; import { HttpClientModule } from '@angular/common/http'; -import { NgModule } from '@angular/core'; +import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; import { MatAutocompleteModule } from '@angular/material/autocomplete'; import { MatChipsModule } from '@angular/material/chips'; import { @@ -35,6 +35,7 @@ export function NgxStripeFactory(): string { } @NgModule({ + bootstrap: [AppComponent], declarations: [AppComponent], imports: [ AppRoutingModule, @@ -72,6 +73,6 @@ export function NgxStripeFactory(): string { useFactory: NgxStripeFactory } ], - bootstrap: [AppComponent] + schemas: [CUSTOM_ELEMENTS_SCHEMA] }) export class AppModule {} diff --git a/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts b/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts index be1892e91..792025e9b 100644 --- a/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts +++ b/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts @@ -13,7 +13,6 @@ import { AdminService } from '@ghostfolio/client/services/admin.service'; import { DataService } from '@ghostfolio/client/services/data.service'; import { AdminMarketDataDetails, - ScraperConfiguration, UniqueAsset } from '@ghostfolio/common/interfaces'; import { translate } from '@ghostfolio/ui/i18n'; @@ -146,9 +145,11 @@ export class AssetProfileDialog implements OnDestroy, OnInit { .postBenchmark({ dataSource, symbol }) .pipe(takeUntil(this.unsubscribeSubject)) .subscribe(() => { - setTimeout(() => { - window.location.reload(); - }, 300); + this.dataService.updateInfo(); + + this.isBenchmark = true; + + this.changeDetectorRef.markForCheck(); }); } @@ -185,6 +186,19 @@ export class AssetProfileDialog implements OnDestroy, OnInit { }); } + public onUnsetBenchmark({ dataSource, symbol }: UniqueAsset) { + this.dataService + .deleteBenchmark({ dataSource, symbol }) + .pipe(takeUntil(this.unsubscribeSubject)) + .subscribe(() => { + this.dataService.updateInfo(); + + this.isBenchmark = false; + + this.changeDetectorRef.markForCheck(); + }); + } + public ngOnDestroy() { this.unsubscribeSubject.next(); this.unsubscribeSubject.complete(); diff --git a/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html b/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html index be99df7cb..6682d004d 100644 --- a/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html +++ b/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html @@ -37,13 +37,6 @@ > Gather Profile Data - @@ -151,6 +144,17 @@ +
+
+ Benchmark +
+
Symbol Mapping diff --git a/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.module.ts b/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.module.ts index 8672342b0..1911f5a47 100644 --- a/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.module.ts +++ b/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.module.ts @@ -3,6 +3,7 @@ import { CommonModule } from '@angular/common'; import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { MatButtonModule } from '@angular/material/button'; +import { MatCheckboxModule } from '@angular/material/checkbox'; import { MatDialogModule } from '@angular/material/dialog'; import { MatInputModule } from '@angular/material/input'; import { MatMenuModule } from '@angular/material/menu'; @@ -21,6 +22,7 @@ import { AssetProfileDialog } from './asset-profile-dialog.component'; GfPortfolioProportionChartModule, GfValueModule, MatButtonModule, + MatCheckboxModule, MatDialogModule, MatInputModule, MatMenuModule, diff --git a/apps/client/src/app/components/admin-overview/admin-overview.component.ts b/apps/client/src/app/components/admin-overview/admin-overview.component.ts index 2053c4298..2ca3f0724 100644 --- a/apps/client/src/app/components/admin-overview/admin-overview.component.ts +++ b/apps/client/src/app/components/admin-overview/admin-overview.component.ts @@ -1,5 +1,6 @@ import { ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core'; import { MatCheckboxChange } from '@angular/material/checkbox'; +import { environment } from '@ghostfolio/client/../environments/environment'; import { AdminService } from '@ghostfolio/client/services/admin.service'; import { CacheService } from '@ghostfolio/client/services/cache.service'; import { DataService } from '@ghostfolio/client/services/data.service'; @@ -42,6 +43,7 @@ export class AdminOverviewComponent implements OnDestroy, OnInit { public transactionCount: number; public userCount: number; public user: User; + public version = environment.version; private unsubscribeSubject = new Subject(); diff --git a/apps/client/src/app/components/admin-overview/admin-overview.html b/apps/client/src/app/components/admin-overview/admin-overview.html index f72c88050..e54f8f27b 100644 --- a/apps/client/src/app/components/admin-overview/admin-overview.html +++ b/apps/client/src/app/components/admin-overview/admin-overview.html @@ -3,12 +3,16 @@
+
+
Version
+
{{ version }}
+
User Count
@@ -17,8 +21,8 @@
Activity Count
@@ -72,19 +76,6 @@
-
-
Tags
-
- - - - -
{{ tag.name }}
-
-
User Signup
diff --git a/apps/client/src/app/components/admin-platform/admin-platform.component.ts b/apps/client/src/app/components/admin-platform/admin-platform.component.ts index f8f1f4b58..ffc5810b3 100644 --- a/apps/client/src/app/components/admin-platform/admin-platform.component.ts +++ b/apps/client/src/app/components/admin-platform/admin-platform.component.ts @@ -13,13 +13,14 @@ import { ActivatedRoute, Router } from '@angular/router'; import { CreatePlatformDto } from '@ghostfolio/api/app/platform/create-platform.dto'; import { UpdatePlatformDto } from '@ghostfolio/api/app/platform/update-platform.dto'; import { AdminService } from '@ghostfolio/client/services/admin.service'; +import { DataService } from '@ghostfolio/client/services/data.service'; import { UserService } from '@ghostfolio/client/services/user/user.service'; import { Platform } from '@prisma/client'; import { get } from 'lodash'; import { DeviceDetectorService } from 'ngx-device-detector'; import { Subject, takeUntil } from 'rxjs'; -import { CreateOrUpdatePlatformDialog } from './create-or-update-platform-dialog/create-or-update-account-platform.component'; +import { CreateOrUpdatePlatformDialog } from './create-or-update-platform-dialog/create-or-update-platform-dialog.component'; @Component({ changeDetection: ChangeDetectionStrategy.OnPush, @@ -40,6 +41,7 @@ export class AdminPlatformComponent implements OnInit, OnDestroy { public constructor( private adminService: AdminService, private changeDetectorRef: ChangeDetectorRef, + private dataService: DataService, private deviceService: DeviceDetectorService, private dialog: MatDialog, private route: ActivatedRoute, @@ -119,6 +121,8 @@ export class AdminPlatformComponent implements OnInit, OnDestroy { this.dataSource.sort = this.sort; this.dataSource.sortingDataAccessor = get; + this.dataService.updateInfo(); + this.changeDetectorRef.markForCheck(); }); } diff --git a/apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-account-platform.component.ts b/apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.component.ts similarity index 100% rename from apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-account-platform.component.ts rename to apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.component.ts diff --git a/apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.module.ts b/apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.module.ts index cbc74b9cf..bf576480a 100644 --- a/apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.module.ts +++ b/apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.module.ts @@ -6,7 +6,7 @@ import { MatDialogModule } from '@angular/material/dialog'; import { MatFormFieldModule } from '@angular/material/form-field'; import { MatInputModule } from '@angular/material/input'; -import { CreateOrUpdatePlatformDialog } from './create-or-update-account-platform.component'; +import { CreateOrUpdatePlatformDialog } from './create-or-update-platform-dialog.component'; @NgModule({ declarations: [CreateOrUpdatePlatformDialog], diff --git a/apps/client/src/app/components/admin-settings/admin-settings.component.html b/apps/client/src/app/components/admin-settings/admin-settings.component.html index 6f23a4056..4c4a6df1e 100644 --- a/apps/client/src/app/components/admin-settings/admin-settings.component.html +++ b/apps/client/src/app/components/admin-settings/admin-settings.component.html @@ -2,14 +2,13 @@

Platforms

- +
-
diff --git a/apps/client/src/app/components/admin-settings/admin-settings.module.ts b/apps/client/src/app/components/admin-settings/admin-settings.module.ts index aaa16651f..e778c113d 100644 --- a/apps/client/src/app/components/admin-settings/admin-settings.module.ts +++ b/apps/client/src/app/components/admin-settings/admin-settings.module.ts @@ -2,12 +2,18 @@ import { CommonModule } from '@angular/common'; import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; import { RouterModule } from '@angular/router'; import { GfAdminPlatformModule } from '@ghostfolio/client/components/admin-platform/admin-platform.module'; +import { GfAdminTagModule } from '@ghostfolio/client/components/admin-tag/admin-tag.module'; import { AdminSettingsComponent } from './admin-settings.component'; @NgModule({ declarations: [AdminSettingsComponent], - imports: [CommonModule, GfAdminPlatformModule, RouterModule], + imports: [ + CommonModule, + GfAdminPlatformModule, + GfAdminTagModule, + RouterModule + ], schemas: [CUSTOM_ELEMENTS_SCHEMA] }) export class GfAdminSettingsModule {} diff --git a/apps/client/src/app/components/admin-tag/admin-tag.component.html b/apps/client/src/app/components/admin-tag/admin-tag.component.html new file mode 100644 index 000000000..d21523321 --- /dev/null +++ b/apps/client/src/app/components/admin-tag/admin-tag.component.html @@ -0,0 +1,85 @@ +
+
+
+ + + + + + + + + + + + + + + + + + + +
+ Name + + {{ element.name }} + + Activities + + {{ element.activityCount }} + + + + + + +
+
+
+
diff --git a/apps/client/src/app/components/admin-tag/admin-tag.component.scss b/apps/client/src/app/components/admin-tag/admin-tag.component.scss new file mode 100644 index 000000000..b5b58f67e --- /dev/null +++ b/apps/client/src/app/components/admin-tag/admin-tag.component.scss @@ -0,0 +1,5 @@ +@import 'apps/client/src/styles/ghostfolio-style'; + +:host { + display: block; +} diff --git a/apps/client/src/app/components/admin-tag/admin-tag.component.ts b/apps/client/src/app/components/admin-tag/admin-tag.component.ts new file mode 100644 index 000000000..e0dce2477 --- /dev/null +++ b/apps/client/src/app/components/admin-tag/admin-tag.component.ts @@ -0,0 +1,204 @@ +import { + ChangeDetectionStrategy, + ChangeDetectorRef, + Component, + OnDestroy, + OnInit, + ViewChild +} from '@angular/core'; +import { MatDialog } from '@angular/material/dialog'; +import { MatSort } from '@angular/material/sort'; +import { MatTableDataSource } from '@angular/material/table'; +import { ActivatedRoute, Router } from '@angular/router'; +import { CreateTagDto } from '@ghostfolio/api/app/tag/create-tag.dto'; +import { UpdateTagDto } from '@ghostfolio/api/app/tag/update-tag.dto'; +import { AdminService } from '@ghostfolio/client/services/admin.service'; +import { DataService } from '@ghostfolio/client/services/data.service'; +import { UserService } from '@ghostfolio/client/services/user/user.service'; +import { Tag } from '@prisma/client'; +import { get } from 'lodash'; +import { DeviceDetectorService } from 'ngx-device-detector'; +import { Subject, takeUntil } from 'rxjs'; + +import { CreateOrUpdateTagDialog } from './create-or-update-tag-dialog/create-or-update-tag-dialog.component'; + +@Component({ + changeDetection: ChangeDetectionStrategy.OnPush, + selector: 'gf-admin-tag', + styleUrls: ['./admin-tag.component.scss'], + templateUrl: './admin-tag.component.html' +}) +export class AdminTagComponent implements OnInit, OnDestroy { + @ViewChild(MatSort) sort: MatSort; + + public dataSource: MatTableDataSource = new MatTableDataSource(); + public deviceType: string; + public displayedColumns = ['name', 'activities', 'actions']; + public tags: Tag[]; + + private unsubscribeSubject = new Subject(); + + public constructor( + private adminService: AdminService, + private changeDetectorRef: ChangeDetectorRef, + private dataService: DataService, + private deviceService: DeviceDetectorService, + private dialog: MatDialog, + private route: ActivatedRoute, + private router: Router, + private userService: UserService + ) { + this.route.queryParams + .pipe(takeUntil(this.unsubscribeSubject)) + .subscribe((params) => { + if (params['createTagDialog']) { + this.openCreateTagDialog(); + } else if (params['editTagDialog']) { + if (this.tags) { + const tag = this.tags.find(({ id }) => { + return id === params['tagId']; + }); + + this.openUpdateTagDialog(tag); + } else { + this.router.navigate(['.'], { relativeTo: this.route }); + } + } + }); + } + + public ngOnInit() { + this.deviceType = this.deviceService.getDeviceInfo().deviceType; + + this.fetchTags(); + } + + public onDeleteTag(aId: string) { + const confirmation = confirm( + $localize`Do you really want to delete this tag?` + ); + + if (confirmation) { + this.deleteTag(aId); + } + } + + public onUpdateTag({ id }: Tag) { + this.router.navigate([], { + queryParams: { editTagDialog: true, tagId: id } + }); + } + + public ngOnDestroy() { + this.unsubscribeSubject.next(); + this.unsubscribeSubject.complete(); + } + + private deleteTag(aId: string) { + this.adminService + .deleteTag(aId) + .pipe(takeUntil(this.unsubscribeSubject)) + .subscribe({ + next: () => { + this.userService + .get(true) + .pipe(takeUntil(this.unsubscribeSubject)) + .subscribe(); + + this.fetchTags(); + } + }); + } + + private fetchTags() { + this.adminService + .fetchTags() + .pipe(takeUntil(this.unsubscribeSubject)) + .subscribe((tags) => { + this.tags = tags; + + this.dataSource = new MatTableDataSource(this.tags); + this.dataSource.sort = this.sort; + this.dataSource.sortingDataAccessor = get; + + this.dataService.updateInfo(); + + this.changeDetectorRef.markForCheck(); + }); + } + + private openCreateTagDialog() { + const dialogRef = this.dialog.open(CreateOrUpdateTagDialog, { + data: { + tag: { + name: null + } + }, + height: this.deviceType === 'mobile' ? '97.5vh' : '80vh', + width: this.deviceType === 'mobile' ? '100vw' : '50rem' + }); + + dialogRef + .afterClosed() + .pipe(takeUntil(this.unsubscribeSubject)) + .subscribe((data) => { + const tag: CreateTagDto = data?.tag; + + if (tag) { + this.adminService + .postTag(tag) + .pipe(takeUntil(this.unsubscribeSubject)) + .subscribe({ + next: () => { + this.userService + .get(true) + .pipe(takeUntil(this.unsubscribeSubject)) + .subscribe(); + + this.fetchTags(); + } + }); + } + + this.router.navigate(['.'], { relativeTo: this.route }); + }); + } + + private openUpdateTagDialog({ id, name }) { + const dialogRef = this.dialog.open(CreateOrUpdateTagDialog, { + data: { + tag: { + id, + name + } + }, + height: this.deviceType === 'mobile' ? '97.5vh' : '80vh', + width: this.deviceType === 'mobile' ? '100vw' : '50rem' + }); + + dialogRef + .afterClosed() + .pipe(takeUntil(this.unsubscribeSubject)) + .subscribe((data) => { + const tag: UpdateTagDto = data?.tag; + + if (tag) { + this.adminService + .putTag(tag) + .pipe(takeUntil(this.unsubscribeSubject)) + .subscribe({ + next: () => { + this.userService + .get(true) + .pipe(takeUntil(this.unsubscribeSubject)) + .subscribe(); + + this.fetchTags(); + } + }); + } + + this.router.navigate(['.'], { relativeTo: this.route }); + }); + } +} diff --git a/apps/client/src/app/components/admin-tag/admin-tag.module.ts b/apps/client/src/app/components/admin-tag/admin-tag.module.ts new file mode 100644 index 000000000..aec5ac5a6 --- /dev/null +++ b/apps/client/src/app/components/admin-tag/admin-tag.module.ts @@ -0,0 +1,26 @@ +import { CommonModule } from '@angular/common'; +import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; +import { MatButtonModule } from '@angular/material/button'; +import { MatMenuModule } from '@angular/material/menu'; +import { MatSortModule } from '@angular/material/sort'; +import { MatTableModule } from '@angular/material/table'; +import { RouterModule } from '@angular/router'; + +import { AdminTagComponent } from './admin-tag.component'; +import { GfCreateOrUpdateTagDialogModule } from './create-or-update-tag-dialog/create-or-update-tag-dialog.module'; + +@NgModule({ + declarations: [AdminTagComponent], + exports: [AdminTagComponent], + imports: [ + CommonModule, + GfCreateOrUpdateTagDialogModule, + MatButtonModule, + MatMenuModule, + MatSortModule, + MatTableModule, + RouterModule + ], + schemas: [CUSTOM_ELEMENTS_SCHEMA] +}) +export class GfAdminTagModule {} diff --git a/apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.component.ts b/apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.component.ts new file mode 100644 index 000000000..aaa5a0221 --- /dev/null +++ b/apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.component.ts @@ -0,0 +1,30 @@ +import { ChangeDetectionStrategy, Component, Inject } from '@angular/core'; +import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; +import { Subject } from 'rxjs'; + +import { CreateOrUpdateTagDialogParams } from './interfaces/interfaces'; + +@Component({ + changeDetection: ChangeDetectionStrategy.OnPush, + host: { class: 'h-100' }, + selector: 'gf-create-or-update-tag-dialog', + styleUrls: ['./create-or-update-tag-dialog.scss'], + templateUrl: 'create-or-update-tag-dialog.html' +}) +export class CreateOrUpdateTagDialog { + private unsubscribeSubject = new Subject(); + + public constructor( + @Inject(MAT_DIALOG_DATA) public data: CreateOrUpdateTagDialogParams, + public dialogRef: MatDialogRef + ) {} + + public onCancel() { + this.dialogRef.close(); + } + + public ngOnDestroy() { + this.unsubscribeSubject.next(); + this.unsubscribeSubject.complete(); + } +} diff --git a/apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html b/apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html new file mode 100644 index 000000000..c2e8f4ee1 --- /dev/null +++ b/apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html @@ -0,0 +1,23 @@ +
+

Update tag

+

Add tag

+
+
+ + Name + + +
+
+
+ + +
+
diff --git a/apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.module.ts b/apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.module.ts new file mode 100644 index 000000000..d8b12edc2 --- /dev/null +++ b/apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.module.ts @@ -0,0 +1,23 @@ +import { CommonModule } from '@angular/common'; +import { NgModule } from '@angular/core'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { MatButtonModule } from '@angular/material/button'; +import { MatDialogModule } from '@angular/material/dialog'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatInputModule } from '@angular/material/input'; + +import { CreateOrUpdateTagDialog } from './create-or-update-tag-dialog.component'; + +@NgModule({ + declarations: [CreateOrUpdateTagDialog], + imports: [ + CommonModule, + FormsModule, + MatButtonModule, + MatDialogModule, + MatFormFieldModule, + MatInputModule, + ReactiveFormsModule + ] +}) +export class GfCreateOrUpdateTagDialogModule {} diff --git a/apps/client/src/app/pages/user-account/create-or-update-access-dialog/create-or-update-access-dialog.scss b/apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.scss similarity index 100% rename from apps/client/src/app/pages/user-account/create-or-update-access-dialog/create-or-update-access-dialog.scss rename to apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.scss diff --git a/apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/interfaces/interfaces.ts b/apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/interfaces/interfaces.ts new file mode 100644 index 000000000..bd7214786 --- /dev/null +++ b/apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/interfaces/interfaces.ts @@ -0,0 +1,5 @@ +import { Tag } from '@prisma/client'; + +export interface CreateOrUpdateTagDialogParams { + tag: Tag; +} diff --git a/apps/client/src/app/components/header/header.component.html b/apps/client/src/app/components/header/header.component.html index 2c56cb742..a2c69245c 100644 --- a/apps/client/src/app/components/header/header.component.html +++ b/apps/client/src/app/components/header/header.component.html @@ -272,7 +272,7 @@ mat-flat-button [ngClass]="{ 'font-weight-bold': currentRoute === routeFeatures, - 'text-decoration-underline': currentRoute === routeFeatuers + 'text-decoration-underline': currentRoute === routeFeatures }" [routerLink]="routerLinkFeatures" >Features
Sectors
@@ -225,11 +225,11 @@
Countries
diff --git a/apps/client/src/app/pages/user-account/create-or-update-access-dialog/create-or-update-access-dialog.component.ts b/apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.component.ts similarity index 100% rename from apps/client/src/app/pages/user-account/create-or-update-access-dialog/create-or-update-access-dialog.component.ts rename to apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.component.ts diff --git a/apps/client/src/app/pages/user-account/create-or-update-access-dialog/create-or-update-access-dialog.html b/apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html similarity index 100% rename from apps/client/src/app/pages/user-account/create-or-update-access-dialog/create-or-update-access-dialog.html rename to apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html diff --git a/apps/client/src/app/pages/user-account/create-or-update-access-dialog/create-or-update-access-dialog.module.ts b/apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.module.ts similarity index 100% rename from apps/client/src/app/pages/user-account/create-or-update-access-dialog/create-or-update-access-dialog.module.ts rename to apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.module.ts diff --git a/apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.scss b/apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.scss new file mode 100644 index 000000000..b63df0134 --- /dev/null +++ b/apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.scss @@ -0,0 +1,7 @@ +:host { + display: block; + + .mat-mdc-dialog-content { + max-height: unset; + } +} diff --git a/apps/client/src/app/pages/user-account/create-or-update-access-dialog/interfaces/interfaces.ts b/apps/client/src/app/components/user-account-access/create-or-update-access-dialog/interfaces/interfaces.ts similarity index 100% rename from apps/client/src/app/pages/user-account/create-or-update-access-dialog/interfaces/interfaces.ts rename to apps/client/src/app/components/user-account-access/create-or-update-access-dialog/interfaces/interfaces.ts diff --git a/apps/client/src/app/components/user-account-access/user-account-access.component.ts b/apps/client/src/app/components/user-account-access/user-account-access.component.ts new file mode 100644 index 000000000..1bd1d85d6 --- /dev/null +++ b/apps/client/src/app/components/user-account-access/user-account-access.component.ts @@ -0,0 +1,146 @@ +import { + ChangeDetectionStrategy, + ChangeDetectorRef, + Component, + OnDestroy, + OnInit +} from '@angular/core'; +import { MatDialog } from '@angular/material/dialog'; +import { ActivatedRoute, Router } from '@angular/router'; +import { CreateAccessDto } from '@ghostfolio/api/app/access/create-access.dto'; +import { DataService } from '@ghostfolio/client/services/data.service'; +import { UserService } from '@ghostfolio/client/services/user/user.service'; +import { Access, User } from '@ghostfolio/common/interfaces'; +import { hasPermission, permissions } from '@ghostfolio/common/permissions'; +import { DeviceDetectorService } from 'ngx-device-detector'; +import { Subject } from 'rxjs'; +import { takeUntil } from 'rxjs/operators'; + +import { CreateOrUpdateAccessDialog } from './create-or-update-access-dialog/create-or-update-access-dialog.component'; + +@Component({ + changeDetection: ChangeDetectionStrategy.OnPush, + selector: 'gf-user-account-access', + styleUrls: ['./user-account-access.scss'], + templateUrl: './user-account-access.html' +}) +export class UserAccountAccessComponent implements OnDestroy, OnInit { + public accesses: Access[]; + public deviceType: string; + public hasPermissionToCreateAccess: boolean; + public hasPermissionToDeleteAccess: boolean; + public user: User; + + private unsubscribeSubject = new Subject(); + + public constructor( + private changeDetectorRef: ChangeDetectorRef, + private dataService: DataService, + private deviceService: DeviceDetectorService, + private dialog: MatDialog, + private route: ActivatedRoute, + private router: Router, + private userService: UserService + ) { + const { globalPermissions } = this.dataService.fetchInfo(); + + this.hasPermissionToDeleteAccess = hasPermission( + globalPermissions, + permissions.deleteAccess + ); + + this.userService.stateChanged + .pipe(takeUntil(this.unsubscribeSubject)) + .subscribe((state) => { + if (state?.user) { + this.user = state.user; + + this.hasPermissionToCreateAccess = hasPermission( + this.user.permissions, + permissions.createAccess + ); + + this.hasPermissionToDeleteAccess = hasPermission( + this.user.permissions, + permissions.deleteAccess + ); + + this.changeDetectorRef.markForCheck(); + } + }); + + this.route.queryParams + .pipe(takeUntil(this.unsubscribeSubject)) + .subscribe((params) => { + if (params['createDialog']) { + this.openCreateAccessDialog(); + } + }); + } + + public ngOnInit() { + this.deviceType = this.deviceService.getDeviceInfo().deviceType; + + this.update(); + } + + public onDeleteAccess(aId: string) { + this.dataService + .deleteAccess(aId) + .pipe(takeUntil(this.unsubscribeSubject)) + .subscribe({ + next: () => { + this.update(); + } + }); + } + + public ngOnDestroy() { + this.unsubscribeSubject.next(); + this.unsubscribeSubject.complete(); + } + + private openCreateAccessDialog(): void { + const dialogRef = this.dialog.open(CreateOrUpdateAccessDialog, { + data: { + access: { + alias: '', + type: 'PUBLIC' + } + }, + height: this.deviceType === 'mobile' ? '97.5vh' : '80vh', + width: this.deviceType === 'mobile' ? '100vw' : '50rem' + }); + + dialogRef + .afterClosed() + .pipe(takeUntil(this.unsubscribeSubject)) + .subscribe((data: any) => { + const access: CreateAccessDto = data?.access; + + if (access) { + this.dataService + .postAccess({ alias: access.alias }) + .pipe(takeUntil(this.unsubscribeSubject)) + .subscribe({ + next: () => { + this.update(); + } + }); + } + + this.router.navigate(['.'], { relativeTo: this.route }); + }); + } + + private update() { + this.dataService + .fetchAccesses() + .pipe(takeUntil(this.unsubscribeSubject)) + .subscribe((accesses) => { + this.accesses = accesses; + + this.changeDetectorRef.markForCheck(); + }); + } +} diff --git a/apps/client/src/app/components/user-account-access/user-account-access.html b/apps/client/src/app/components/user-account-access/user-account-access.html new file mode 100644 index 000000000..c3aa485cd --- /dev/null +++ b/apps/client/src/app/components/user-account-access/user-account-access.html @@ -0,0 +1,17 @@ +
+

+ Granted Access + +

+ +
diff --git a/apps/client/src/app/components/user-account-access/user-account-access.module.ts b/apps/client/src/app/components/user-account-access/user-account-access.module.ts new file mode 100644 index 000000000..76495db63 --- /dev/null +++ b/apps/client/src/app/components/user-account-access/user-account-access.module.ts @@ -0,0 +1,23 @@ +import { CommonModule } from '@angular/common'; +import { NgModule } from '@angular/core'; +import { MatDialogModule } from '@angular/material/dialog'; +import { RouterModule } from '@angular/router'; +import { GfPortfolioAccessTableModule } from '@ghostfolio/client/components/access-table/access-table.module'; +import { GfPremiumIndicatorModule } from '@ghostfolio/ui/premium-indicator'; + +import { GfCreateOrUpdateAccessDialogModule } from './create-or-update-access-dialog/create-or-update-access-dialog.module'; +import { UserAccountAccessComponent } from './user-account-access.component'; + +@NgModule({ + declarations: [UserAccountAccessComponent], + exports: [UserAccountAccessComponent], + imports: [ + CommonModule, + GfCreateOrUpdateAccessDialogModule, + GfPortfolioAccessTableModule, + GfPremiumIndicatorModule, + MatDialogModule, + RouterModule + ] +}) +export class GfUserAccountAccessModule {} diff --git a/apps/client/src/app/components/user-account-access/user-account-access.scss b/apps/client/src/app/components/user-account-access/user-account-access.scss new file mode 100644 index 000000000..695f786f2 --- /dev/null +++ b/apps/client/src/app/components/user-account-access/user-account-access.scss @@ -0,0 +1,12 @@ +:host { + color: rgb(var(--dark-primary-text)); + display: block; + + gf-access-table { + overflow-x: auto; + } +} + +:host-context(.is-dark-theme) { + color: rgb(var(--light-primary-text)); +} diff --git a/apps/client/src/app/components/user-account-membership/user-account-membership.component.ts b/apps/client/src/app/components/user-account-membership/user-account-membership.component.ts new file mode 100644 index 000000000..13d7495a9 --- /dev/null +++ b/apps/client/src/app/components/user-account-membership/user-account-membership.component.ts @@ -0,0 +1,160 @@ +import { + ChangeDetectionStrategy, + ChangeDetectorRef, + Component, + OnDestroy, + OnInit +} from '@angular/core'; +import { + MatSnackBar, + MatSnackBarRef, + TextOnlySnackBar +} from '@angular/material/snack-bar'; +import { DataService } from '@ghostfolio/client/services/data.service'; +import { UserService } from '@ghostfolio/client/services/user/user.service'; +import { getDateFormatString } from '@ghostfolio/common/helper'; +import { User } from '@ghostfolio/common/interfaces'; +import { hasPermission, permissions } from '@ghostfolio/common/permissions'; +import { StripeService } from 'ngx-stripe'; +import { EMPTY, Subject } from 'rxjs'; +import { catchError, switchMap, takeUntil } from 'rxjs/operators'; + +@Component({ + changeDetection: ChangeDetectionStrategy.OnPush, + selector: 'gf-user-account-membership', + styleUrls: ['./user-account-membership.scss'], + templateUrl: './user-account-membership.html' +}) +export class UserAccountMembershipComponent implements OnDestroy, OnInit { + public baseCurrency: string; + public coupon: number; + public couponId: string; + public defaultDateFormat: string; + public hasPermissionForSubscription: boolean; + public hasPermissionToUpdateUserSettings: boolean; + public price: number; + public priceId: string; + public routerLinkPricing = ['/' + $localize`pricing`]; + public snackBarRef: MatSnackBarRef; + public trySubscriptionMail = + 'mailto:hi@ghostfol.io?Subject=Ghostfolio Premium Trial&body=Hello%0D%0DI am interested in Ghostfolio Premium. Can you please send me a coupon code to try it for some time?%0D%0DKind regards'; + public user: User; + + private unsubscribeSubject = new Subject(); + + public constructor( + private changeDetectorRef: ChangeDetectorRef, + private dataService: DataService, + private snackBar: MatSnackBar, + private stripeService: StripeService, + private userService: UserService + ) { + const { baseCurrency, globalPermissions, subscriptions } = + this.dataService.fetchInfo(); + + this.baseCurrency = baseCurrency; + + this.hasPermissionForSubscription = hasPermission( + globalPermissions, + permissions.enableSubscription + ); + + this.userService.stateChanged + .pipe(takeUntil(this.unsubscribeSubject)) + .subscribe((state) => { + if (state?.user) { + this.user = state.user; + + this.defaultDateFormat = getDateFormatString( + this.user.settings.locale + ); + + this.hasPermissionToUpdateUserSettings = hasPermission( + this.user.permissions, + permissions.updateUserSettings + ); + + this.coupon = subscriptions?.[this.user.subscription.offer]?.coupon; + this.couponId = + subscriptions?.[this.user.subscription.offer]?.couponId; + this.price = subscriptions?.[this.user.subscription.offer]?.price; + this.priceId = subscriptions?.[this.user.subscription.offer]?.priceId; + + this.changeDetectorRef.markForCheck(); + } + }); + } + + public ngOnInit() {} + + public onCheckout() { + this.dataService + .createCheckoutSession({ couponId: this.couponId, priceId: this.priceId }) + .pipe( + switchMap(({ sessionId }: { sessionId: string }) => { + return this.stripeService.redirectToCheckout({ sessionId }); + }), + catchError((error) => { + alert(error.message); + throw error; + }) + ) + .subscribe((result) => { + if (result.error) { + alert(result.error.message); + } + }); + } + + public onRedeemCoupon() { + let couponCode = prompt($localize`Please enter your coupon code:`); + couponCode = couponCode?.trim(); + + if (couponCode) { + this.dataService + .redeemCoupon(couponCode) + .pipe( + takeUntil(this.unsubscribeSubject), + catchError(() => { + this.snackBar.open( + '😞 ' + $localize`Could not redeem coupon code`, + undefined, + { + duration: 3000 + } + ); + + return EMPTY; + }) + ) + .subscribe(() => { + this.snackBarRef = this.snackBar.open( + '✅ ' + $localize`Coupon code has been redeemed`, + $localize`Reload`, + { + duration: 3000 + } + ); + + this.snackBarRef + .afterDismissed() + .pipe(takeUntil(this.unsubscribeSubject)) + .subscribe(() => { + window.location.reload(); + }); + + this.snackBarRef + .onAction() + .pipe(takeUntil(this.unsubscribeSubject)) + .subscribe(() => { + window.location.reload(); + }); + }); + } + } + + public ngOnDestroy() { + this.unsubscribeSubject.next(); + this.unsubscribeSubject.complete(); + } +} diff --git a/apps/client/src/app/components/user-account-membership/user-account-membership.html b/apps/client/src/app/components/user-account-membership/user-account-membership.html new file mode 100644 index 000000000..1681e3e16 --- /dev/null +++ b/apps/client/src/app/components/user-account-membership/user-account-membership.html @@ -0,0 +1,69 @@ +
+

Membership

+
+
+
+
+ +
+ Valid until {{ + user?.subscription?.expiresAt | date: defaultDateFormat }} +
+
+ + +
+ {{ baseCurrency }} {{ price }} {{ baseCurrency }} {{ price - coupon + }} + {{ baseCurrency }} {{ price }} per year +
+
+ Try Premium + + Redeem Coupon +
+
+
+
+
+
diff --git a/apps/client/src/app/components/user-account-membership/user-account-membership.module.ts b/apps/client/src/app/components/user-account-membership/user-account-membership.module.ts new file mode 100644 index 000000000..bef027c62 --- /dev/null +++ b/apps/client/src/app/components/user-account-membership/user-account-membership.module.ts @@ -0,0 +1,23 @@ +import { CommonModule } from '@angular/common'; +import { NgModule } from '@angular/core'; +import { MatButtonModule } from '@angular/material/button'; +import { MatCardModule } from '@angular/material/card'; +import { RouterModule } from '@angular/router'; +import { GfPremiumIndicatorModule } from '@ghostfolio/ui/premium-indicator'; +import { GfValueModule } from '@ghostfolio/ui/value'; + +import { UserAccountMembershipComponent } from './user-account-membership.component'; + +@NgModule({ + declarations: [UserAccountMembershipComponent], + exports: [UserAccountMembershipComponent], + imports: [ + CommonModule, + GfPremiumIndicatorModule, + GfValueModule, + MatButtonModule, + MatCardModule, + RouterModule + ] +}) +export class GfUserAccountMembershipModule {} diff --git a/apps/client/src/app/components/user-account-membership/user-account-membership.scss b/apps/client/src/app/components/user-account-membership/user-account-membership.scss new file mode 100644 index 000000000..39eb6792e --- /dev/null +++ b/apps/client/src/app/components/user-account-membership/user-account-membership.scss @@ -0,0 +1,8 @@ +:host { + color: rgb(var(--dark-primary-text)); + display: block; +} + +:host-context(.is-dark-theme) { + color: rgb(var(--light-primary-text)); +} diff --git a/apps/client/src/app/components/user-account-settings/user-account-settings.component.ts b/apps/client/src/app/components/user-account-settings/user-account-settings.component.ts new file mode 100644 index 000000000..a52812ed3 --- /dev/null +++ b/apps/client/src/app/components/user-account-settings/user-account-settings.component.ts @@ -0,0 +1,258 @@ +import { + ChangeDetectionStrategy, + ChangeDetectorRef, + Component, + OnDestroy, + OnInit, + ViewChild +} from '@angular/core'; +import { MatCheckbox, MatCheckboxChange } from '@angular/material/checkbox'; +import { DataService } from '@ghostfolio/client/services/data.service'; +import { + STAY_SIGNED_IN, + SettingsStorageService +} from '@ghostfolio/client/services/settings-storage.service'; +import { UserService } from '@ghostfolio/client/services/user/user.service'; +import { WebAuthnService } from '@ghostfolio/client/services/web-authn.service'; +import { downloadAsFile } from '@ghostfolio/common/helper'; +import { User } from '@ghostfolio/common/interfaces'; +import { hasPermission, permissions } from '@ghostfolio/common/permissions'; +import { format, parseISO } from 'date-fns'; +import { uniq } from 'lodash'; +import { EMPTY, Subject } from 'rxjs'; +import { catchError, takeUntil } from 'rxjs/operators'; + +@Component({ + changeDetection: ChangeDetectionStrategy.OnPush, + selector: 'gf-user-account-settings', + styleUrls: ['./user-account-settings.scss'], + templateUrl: './user-account-settings.html' +}) +export class UserAccountSettingsComponent implements OnDestroy, OnInit { + @ViewChild('toggleSignInWithFingerprintEnabledElement') + signInWithFingerprintElement: MatCheckbox; + + public appearancePlaceholder = $localize`Auto`; + public baseCurrency: string; + public currencies: string[] = []; + public hasPermissionToUpdateViewMode: boolean; + public hasPermissionToUpdateUserSettings: boolean; + public language = document.documentElement.lang; + public locales = [ + 'de', + 'de-CH', + 'en-GB', + 'en-US', + 'es', + 'fr', + 'it', + 'nl', + 'pt', + 'tr' + ]; + public user: User; + + private unsubscribeSubject = new Subject(); + + public constructor( + private changeDetectorRef: ChangeDetectorRef, + private dataService: DataService, + private settingsStorageService: SettingsStorageService, + private userService: UserService, + public webAuthnService: WebAuthnService + ) { + const { baseCurrency, currencies } = this.dataService.fetchInfo(); + + this.baseCurrency = baseCurrency; + this.currencies = currencies; + + this.userService.stateChanged + .pipe(takeUntil(this.unsubscribeSubject)) + .subscribe((state) => { + if (state?.user) { + this.user = state.user; + + this.hasPermissionToUpdateUserSettings = hasPermission( + this.user.permissions, + permissions.updateUserSettings + ); + + this.hasPermissionToUpdateViewMode = hasPermission( + this.user.permissions, + permissions.updateViewMode + ); + + this.locales.push(this.user.settings.locale); + this.locales = uniq(this.locales.sort()); + + this.changeDetectorRef.markForCheck(); + } + }); + } + + public ngOnInit() { + this.update(); + } + + public onChangeUserSetting(aKey: string, aValue: string) { + this.dataService + .putUserSetting({ [aKey]: aValue }) + .pipe(takeUntil(this.unsubscribeSubject)) + .subscribe(() => { + this.userService.remove(); + + this.userService + .get() + .pipe(takeUntil(this.unsubscribeSubject)) + .subscribe((user) => { + this.user = user; + + this.changeDetectorRef.markForCheck(); + + if (aKey === 'language') { + if (aValue) { + window.location.href = `../${aValue}/account`; + } else { + window.location.href = `../`; + } + } + }); + }); + } + + public onExperimentalFeaturesChange(aEvent: MatCheckboxChange) { + this.dataService + .putUserSetting({ isExperimentalFeatures: aEvent.checked }) + .pipe(takeUntil(this.unsubscribeSubject)) + .subscribe(() => { + this.userService.remove(); + + this.userService + .get() + .pipe(takeUntil(this.unsubscribeSubject)) + .subscribe((user) => { + this.user = user; + + this.changeDetectorRef.markForCheck(); + }); + }); + } + + public onExport() { + this.dataService + .fetchExport() + .pipe(takeUntil(this.unsubscribeSubject)) + .subscribe((data) => { + for (const activity of data.activities) { + delete activity.id; + } + + downloadAsFile({ + content: data, + fileName: `ghostfolio-export-${format( + parseISO(data.meta.date), + 'yyyyMMddHHmm' + )}.json`, + format: 'json' + }); + }); + } + + public onRestrictedViewChange(aEvent: MatCheckboxChange) { + this.dataService + .putUserSetting({ isRestrictedView: aEvent.checked }) + .pipe(takeUntil(this.unsubscribeSubject)) + .subscribe(() => { + this.userService.remove(); + + this.userService + .get() + .pipe(takeUntil(this.unsubscribeSubject)) + .subscribe((user) => { + this.user = user; + + this.changeDetectorRef.markForCheck(); + }); + }); + } + + public onSignInWithFingerprintChange(aEvent: MatCheckboxChange) { + if (aEvent.checked) { + this.registerDevice(); + } else { + const confirmation = confirm( + $localize`Do you really want to remove this sign in method?` + ); + + if (confirmation) { + this.deregisterDevice(); + } else { + this.update(); + } + } + } + + public onViewModeChange(aEvent: MatCheckboxChange) { + this.dataService + .putUserSetting({ viewMode: aEvent.checked === true ? 'ZEN' : 'DEFAULT' }) + .pipe(takeUntil(this.unsubscribeSubject)) + .subscribe(() => { + this.userService.remove(); + + this.userService + .get() + .pipe(takeUntil(this.unsubscribeSubject)) + .subscribe((user) => { + this.user = user; + + this.changeDetectorRef.markForCheck(); + }); + }); + } + + public ngOnDestroy() { + this.unsubscribeSubject.next(); + this.unsubscribeSubject.complete(); + } + + private deregisterDevice() { + this.webAuthnService + .deregister() + .pipe( + takeUntil(this.unsubscribeSubject), + catchError(() => { + this.update(); + + return EMPTY; + }) + ) + .subscribe(() => { + this.update(); + }); + } + + private registerDevice() { + this.webAuthnService + .register() + .pipe( + takeUntil(this.unsubscribeSubject), + catchError(() => { + this.update(); + + return EMPTY; + }) + ) + .subscribe(() => { + this.settingsStorageService.removeSetting(STAY_SIGNED_IN); + + this.update(); + }); + } + + private update() { + if (this.signInWithFingerprintElement) { + this.signInWithFingerprintElement.checked = + this.webAuthnService.isEnabled() ?? false; + } + } +} diff --git a/apps/client/src/app/components/user-account-settings/user-account-settings.html b/apps/client/src/app/components/user-account-settings/user-account-settings.html new file mode 100644 index 000000000..12f3da458 --- /dev/null +++ b/apps/client/src/app/components/user-account-settings/user-account-settings.html @@ -0,0 +1,197 @@ +
+

Settings

+
+
+
+
+
Presenter View
+
+ Protection for sensitive information like absolute performances and + quantity values +
+
+
+ +
+
+
+
+
+
+ Base Currency +
+
+ + + {{ currency }} + + +
+
+
+
+
Language
+
+
+ + + + Deutsch + English + Español (Community) + Français (Community) + Italiano (Community) + Nederlands (Community) + Português (Community) + Türkçe (Community) + + +
+
+
+
+
Locale
+
+ Date and number format +
+
+
+ + + + {{ locale }} + + +
+
+
+
+ Appearance +
+
+ + + Auto + Light + Dark + + +
+
+
+
+
+
+
Zen Mode
+
+ Distraction-free experience for turbulent times +
+
+
+ +
+
+
+
+
Biometric Authentication
+
Sign in with fingerprint
+
+
+ +
+
+
+
+
Experimental Features
+
+ Sneak peek at upcoming functionality +
+
+
+ +
+
+
+
User ID
+
{{ user?.id }}
+
+
+
+
+ +
+
+
+
+
diff --git a/apps/client/src/app/components/user-account-settings/user-account-settings.module.ts b/apps/client/src/app/components/user-account-settings/user-account-settings.module.ts new file mode 100644 index 000000000..24e57ff20 --- /dev/null +++ b/apps/client/src/app/components/user-account-settings/user-account-settings.module.ts @@ -0,0 +1,30 @@ +import { CommonModule } from '@angular/common'; +import { NgModule } from '@angular/core'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { MatButtonModule } from '@angular/material/button'; +import { MatCardModule } from '@angular/material/card'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatSelectModule } from '@angular/material/select'; +import { RouterModule } from '@angular/router'; +import { GfValueModule } from '@ghostfolio/ui/value'; + +import { UserAccountSettingsComponent } from './user-account-settings.component'; + +@NgModule({ + declarations: [UserAccountSettingsComponent], + exports: [UserAccountSettingsComponent], + imports: [ + CommonModule, + FormsModule, + GfValueModule, + MatButtonModule, + MatCardModule, + MatCheckboxModule, + MatFormFieldModule, + MatSelectModule, + ReactiveFormsModule, + RouterModule + ] +}) +export class GfUserAccountSettingsModule {} diff --git a/apps/client/src/app/components/user-account-settings/user-account-settings.scss b/apps/client/src/app/components/user-account-settings/user-account-settings.scss new file mode 100644 index 000000000..1bcd1c65a --- /dev/null +++ b/apps/client/src/app/components/user-account-settings/user-account-settings.scss @@ -0,0 +1,13 @@ +:host { + color: rgb(var(--dark-primary-text)); + display: block; + + .hint-text { + font-size: 90%; + line-height: 1.2; + } +} + +:host-context(.is-dark-theme) { + color: rgb(var(--light-primary-text)); +} diff --git a/apps/client/src/app/directives/file-drop/file-drop.directive.ts b/apps/client/src/app/directives/file-drop/file-drop.directive.ts index 65f3ed23a..129f6f251 100644 --- a/apps/client/src/app/directives/file-drop/file-drop.directive.ts +++ b/apps/client/src/app/directives/file-drop/file-drop.directive.ts @@ -1,4 +1,4 @@ -import { Directive, HostListener, Output, EventEmitter } from '@angular/core'; +import { Directive, EventEmitter, HostListener, Output } from '@angular/core'; @Directive({ selector: '[gfFileDrop]' diff --git a/apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.component.ts b/apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.component.ts index f0178f2f5..3babc14bc 100644 --- a/apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.component.ts +++ b/apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.component.ts @@ -4,7 +4,10 @@ import { Inject, OnDestroy } from '@angular/core'; +import { FormBuilder, FormGroup, Validators } from '@angular/forms'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; +import { CreateAccountDto } from '@ghostfolio/api/app/account/create-account.dto'; +import { UpdateAccountDto } from '@ghostfolio/api/app/account/update-account.dto'; import { DataService } from '@ghostfolio/client/services/data.service'; import { Subject } from 'rxjs'; @@ -18,15 +21,17 @@ import { CreateOrUpdateAccountDialogParams } from './interfaces/interfaces'; templateUrl: 'create-or-update-account-dialog.html' }) export class CreateOrUpdateAccountDialog implements OnDestroy { + public accountForm: FormGroup; public currencies: string[] = []; public platforms: { id: string; name: string }[]; private unsubscribeSubject = new Subject(); public constructor( + @Inject(MAT_DIALOG_DATA) public data: CreateOrUpdateAccountDialogParams, private dataService: DataService, public dialogRef: MatDialogRef, - @Inject(MAT_DIALOG_DATA) public data: CreateOrUpdateAccountDialogParams + private formBuilder: FormBuilder ) {} ngOnInit() { @@ -34,12 +39,42 @@ export class CreateOrUpdateAccountDialog implements OnDestroy { this.currencies = currencies; this.platforms = platforms; + + this.accountForm = this.formBuilder.group({ + accountId: [{ disabled: true, value: this.data.account.id }], + balance: [this.data.account.balance, Validators.required], + comment: [this.data.account.comment], + currency: [this.data.account.currency, Validators.required], + isExcluded: [this.data.account.isExcluded], + name: [this.data.account.name, Validators.required], + platformId: [this.data.account.platformId] + }); } public onCancel() { this.dialogRef.close(); } + public onSubmit() { + const account: CreateAccountDto | UpdateAccountDto = { + balance: this.accountForm.controls['balance'].value, + comment: this.accountForm.controls['comment'].value, + currency: this.accountForm.controls['currency'].value, + id: this.accountForm.controls['accountId'].value, + isExcluded: this.accountForm.controls['isExcluded'].value, + name: this.accountForm.controls['name'].value, + platformId: this.accountForm.controls['platformId'].value + }; + + if (this.data.account.id) { + (account as UpdateAccountDto).id = this.data.account.id; + } else { + delete (account as CreateAccountDto).id; + } + + this.dialogRef.close({ account }); + } + public ngOnDestroy() { this.unsubscribeSubject.next(); this.unsubscribeSubject.complete(); diff --git a/apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html b/apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html index 7b6f399a0..2d068dde1 100644 --- a/apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html +++ b/apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -1,17 +1,26 @@ -
+

Update account

Add account

Name - +
Currency - + {{ currency }} @@ -22,11 +31,10 @@ Cash Balance {{ data.account.currency }} @@ -34,7 +42,7 @@
Platform - + {{ platform.name }}
- Exclude from Analysis
Account ID - +
- + diff --git a/apps/client/src/app/pages/blog/2023/09/hacktoberfest-2023/hacktoberfest-2023-page.component.ts b/apps/client/src/app/pages/blog/2023/09/hacktoberfest-2023/hacktoberfest-2023-page.component.ts new file mode 100644 index 000000000..614c681e8 --- /dev/null +++ b/apps/client/src/app/pages/blog/2023/09/hacktoberfest-2023/hacktoberfest-2023-page.component.ts @@ -0,0 +1,14 @@ +import { Component } from '@angular/core'; +import { MatButtonModule } from '@angular/material/button'; +import { RouterModule } from '@angular/router'; + +@Component({ + host: { class: 'page' }, + imports: [MatButtonModule, RouterModule], + selector: 'gf-hacktoberfest-2023-page', + standalone: true, + templateUrl: './hacktoberfest-2023-page.html' +}) +export class Hacktoberfest2023PageComponent { + public routerLinkAbout = ['/' + $localize`about`]; +} diff --git a/apps/client/src/app/pages/blog/2023/09/hacktoberfest-2023/hacktoberfest-2023-page.html b/apps/client/src/app/pages/blog/2023/09/hacktoberfest-2023/hacktoberfest-2023-page.html new file mode 100644 index 000000000..9f062f6a0 --- /dev/null +++ b/apps/client/src/app/pages/blog/2023/09/hacktoberfest-2023/hacktoberfest-2023-page.html @@ -0,0 +1,194 @@ +
+
+
+
+
+

Hacktoberfest 2023

+
2023-09-26
+ Hacktoberfest 2023 with Ghostfolio Teaser +
+
+

+ At Ghostfolio, we are very + excited to participate in + Hacktoberfest for the second + time, looking forward to connecting with new and enthusiastic + open-source contributors. Hacktoberfest is a month-long celebration + of open-source projects, their maintainers, and the entire community + of contributors. Each October, open source maintainers from all over + the world give extra attention to new contributors while guiding + them through their first pull requests on + GitHub. This + year the event celebrates its 10th anniversary. +

+
+
+

About Ghostfolio

+

+ Ghostfolio is a modern web + application for managing personal finances. The software aggregates + your assets and empowers informed decision-making to help you + balance your portfolio or plan for future investments. +

+

+ Ghostfolio is written in + TypeScript and + organized as an Nx workspace, utilizing + the latest framework releases. The backend is based on + NestJS in combination with + PostgreSQL as a database + together with Prisma and + Redis for caching. The frontend is + built with Angular. +

+

+ The software is used daily by a thriving global community. With over + 2’600 stars on GitHub and + 300’000+ pulls on Docker Hub, + Ghostfolio has gained widespread recognition for its user-friendly + experience and simplicity. +

+
+
+

How to contribute?

+

+ Each contribution can make a meaningful impact. Whether it involves + implementing new features, resolving bugs, refactoring code, + enhancing documentation, adding unit tests, or translating content + into another language, you can actively shape our project. +

+

+ Are you not yet familiar with our code base? That is not a problem. + We have applied the label hacktoberfest to a few + issues + that are well suited for newcomers. +

+

+ The official Hacktoberfest website provides some valuable + resources for beginners + to start contributing in open source. +

+
+
+

Get support

+

+ If you have further questions or ideas, please join our + Slack + community or get in touch on X + @ghostfolio_. +

+

+ We look forward to hearing from you.
+ Thomas from Ghostfolio +

+
+
+
    +
  • + Angular +
  • +
  • + Community +
  • +
  • + Docker +
  • +
  • + Finance +
  • +
  • + Fintech +
  • +
  • + Ghostfolio +
  • +
  • + GitHub +
  • +
  • + Hacktoberfest +
  • +
  • + Investment +
  • +
  • + NestJS +
  • +
  • + Nx +
  • +
  • + October +
  • +
  • + Open Source +
  • +
  • + OSS +
  • +
  • + Personal Finance +
  • +
  • + Portfolio +
  • +
  • + Portfolio Tracker +
  • +
  • + Prisma +
  • +
  • + Software +
  • +
  • + TypeScript +
  • +
  • + UX +
  • +
  • + Wealth +
  • +
  • + Wealth Management +
  • +
  • + Web3 +
  • +
  • + Web 3.0 +
  • +
+
+ +
+
+
+
diff --git a/apps/client/src/app/pages/blog/blog-page-routing.module.ts b/apps/client/src/app/pages/blog/blog-page-routing.module.ts index 6041e3d89..290fb3a4a 100644 --- a/apps/client/src/app/pages/blog/blog-page-routing.module.ts +++ b/apps/client/src/app/pages/blog/blog-page-routing.module.ts @@ -154,6 +154,15 @@ const routes: Routes = [ (c) => c.Ghostfolio2PageComponent ), title: 'Ghostfolio 2.0' + }, + { + canActivate: [AuthGuard], + path: '2023/09/hacktoberfest-2023', + loadComponent: () => + import( + './2023/09/hacktoberfest-2023/hacktoberfest-2023-page.component' + ).then((c) => c.Hacktoberfest2023PageComponent), + title: 'Hacktoberfest 2023' } ]; diff --git a/apps/client/src/app/pages/blog/blog-page.html b/apps/client/src/app/pages/blog/blog-page.html index 259bfac7c..827c277b3 100644 --- a/apps/client/src/app/pages/blog/blog-page.html +++ b/apps/client/src/app/pages/blog/blog-page.html @@ -8,6 +8,30 @@ finance + + + + +
diff --git a/apps/client/src/app/pages/features/features-page.component.ts b/apps/client/src/app/pages/features/features-page.component.ts index 07ae360fb..3ec35c91d 100644 --- a/apps/client/src/app/pages/features/features-page.component.ts +++ b/apps/client/src/app/pages/features/features-page.component.ts @@ -15,6 +15,7 @@ export class FeaturesPageComponent implements OnDestroy { public hasPermissionForSubscription: boolean; public info: InfoItem; public routerLinkRegister = ['/' + $localize`register`]; + public routerLinkResources = ['/' + $localize`resources`]; public user: User; private unsubscribeSubject = new Subject(); diff --git a/apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html b/apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html index 06cadad8e..eab62642a 100644 --- a/apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html +++ b/apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html @@ -8,7 +8,7 @@

X-ray

- Ghostfolio X-ray uses static analysis to identify potential issues and - risks in your portfolio. + Ghostfolio X-ray uses static analysis to identify potential issues + and risks in your portfolio. It will be highly configurable in the future: activate / deactivate rules and customize the thresholds to match your personal investment @@ -106,7 +108,20 @@

- Currency Cluster RisksEmergency Fund +

+ +
+
+

+ Currency Cluster Risks

- Account Cluster RisksAccount Cluster Risks

- FeesFees
diff --git a/apps/client/src/app/pages/resources/personal-finance-tools/products.ts b/apps/client/src/app/pages/resources/personal-finance-tools/products.ts index 8387e7891..15850f324 100644 --- a/apps/client/src/app/pages/resources/personal-finance-tools/products.ts +++ b/apps/client/src/app/pages/resources/personal-finance-tools/products.ts @@ -6,6 +6,7 @@ import { CopilotMoneyPageComponent } from './products/copilot-money-page.compone import { DeltaPageComponent } from './products/delta-page.component'; import { DivvyDiaryPageComponent } from './products/divvydiary-page.component'; import { ExirioPageComponent } from './products/exirio-page.component'; +import { FinaryPageComponent } from './products/finary-page.component'; import { FolisharePageComponent } from './products/folishare-page.component'; import { GetquinPageComponent } from './products/getquin-page.component'; import { GoSpatzPageComponent } from './products/gospatz-page.component'; @@ -23,6 +24,7 @@ import { SeekingAlphaPageComponent } from './products/seeking-alpha-page.compone import { SharesightPageComponent } from './products/sharesight-page.component'; import { SimplePortfolioPageComponent } from './products/simple-portfolio-page.component'; import { SnowballAnalyticsPageComponent } from './products/snowball-analytics-page.component'; +import { StocklePageComponent } from './products/stockle-page.component'; import { StockMarketEyePageComponent } from './products/stockmarketeye-page.component'; import { SumioPageComponent } from './products/sumio-page.component'; import { UtlunaPageComponent } from './products/utluna-page.component'; @@ -115,6 +117,15 @@ export const products: Product[] = [ pricingPerYear: '$100', slogan: 'All your wealth, in one place.' }, + { + component: FinaryPageComponent, + founded: 2020, + key: 'finary', + languages: ['Deutsch', 'English', 'Français'], + name: 'Finary', + origin: $localize`United States`, + slogan: 'Real-Time Portfolio Tracker & Stock Tracker' + }, { component: FolisharePageComponent, hasFreePlan: true, @@ -304,6 +315,13 @@ export const products: Product[] = [ pricingPerYear: '$80', slogan: 'Simple and powerful portfolio tracker' }, + { + component: StocklePageComponent, + key: 'stockle', + name: 'Stockle', + origin: $localize`Finland`, + slogan: 'Supercharge your investments tracking experience' + }, { component: StockMarketEyePageComponent, founded: 2008, diff --git a/apps/client/src/app/pages/resources/personal-finance-tools/products/finary-page.component.ts b/apps/client/src/app/pages/resources/personal-finance-tools/products/finary-page.component.ts new file mode 100644 index 000000000..6b2d25827 --- /dev/null +++ b/apps/client/src/app/pages/resources/personal-finance-tools/products/finary-page.component.ts @@ -0,0 +1,31 @@ +import { CommonModule } from '@angular/common'; +import { Component } from '@angular/core'; +import { MatButtonModule } from '@angular/material/button'; +import { RouterModule } from '@angular/router'; + +import { products } from '../products'; + +@Component({ + host: { class: 'page' }, + imports: [CommonModule, MatButtonModule, RouterModule], + selector: 'gf-finary-page', + standalone: true, + styleUrls: ['../product-page-template.scss'], + templateUrl: '../product-page-template.html' +}) +export class FinaryPageComponent { + public product1 = products.find(({ key }) => { + return key === 'ghostfolio'; + }); + + public product2 = products.find(({ key }) => { + return key === 'finary'; + }); + + public routerLinkAbout = ['/' + $localize`about`]; + public routerLinkFeatures = ['/' + $localize`features`]; + public routerLinkResourcesPersonalFinanceTools = [ + '/' + $localize`resources`, + 'personal-finance-tools' + ]; +} diff --git a/apps/client/src/app/pages/resources/personal-finance-tools/products/stockle-page.component.ts b/apps/client/src/app/pages/resources/personal-finance-tools/products/stockle-page.component.ts new file mode 100644 index 000000000..eb1b41a9c --- /dev/null +++ b/apps/client/src/app/pages/resources/personal-finance-tools/products/stockle-page.component.ts @@ -0,0 +1,31 @@ +import { CommonModule } from '@angular/common'; +import { Component } from '@angular/core'; +import { MatButtonModule } from '@angular/material/button'; +import { RouterModule } from '@angular/router'; + +import { products } from '../products'; + +@Component({ + host: { class: 'page' }, + imports: [CommonModule, MatButtonModule, RouterModule], + selector: 'gf-stockle-page', + standalone: true, + styleUrls: ['../product-page-template.scss'], + templateUrl: '../product-page-template.html' +}) +export class StocklePageComponent { + public product1 = products.find(({ key }) => { + return key === 'ghostfolio'; + }); + + public product2 = products.find(({ key }) => { + return key === 'stockle'; + }); + + public routerLinkAbout = ['/' + $localize`about`]; + public routerLinkFeatures = ['/' + $localize`features`]; + public routerLinkResourcesPersonalFinanceTools = [ + '/' + $localize`resources`, + 'personal-finance-tools' + ]; +} diff --git a/apps/client/src/app/pages/user-account/user-account-page-routing.module.ts b/apps/client/src/app/pages/user-account/user-account-page-routing.module.ts index f52591d21..568095009 100644 --- a/apps/client/src/app/pages/user-account/user-account-page-routing.module.ts +++ b/apps/client/src/app/pages/user-account/user-account-page-routing.module.ts @@ -1,5 +1,8 @@ import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; +import { UserAccountAccessComponent } from '@ghostfolio/client/components/user-account-access/user-account-access.component'; +import { UserAccountMembershipComponent } from '@ghostfolio/client/components/user-account-membership/user-account-membership.component'; +import { UserAccountSettingsComponent } from '@ghostfolio/client/components/user-account-settings/user-account-settings.component'; import { AuthGuard } from '@ghostfolio/client/core/auth.guard'; import { UserAccountPageComponent } from './user-account-page.component'; @@ -7,6 +10,23 @@ import { UserAccountPageComponent } from './user-account-page.component'; const routes: Routes = [ { canActivate: [AuthGuard], + children: [ + { + path: '', + component: UserAccountSettingsComponent, + title: $localize`Settings` + }, + { + path: 'membership', + component: UserAccountMembershipComponent, + title: $localize`Membership` + }, + { + path: 'access', + component: UserAccountAccessComponent, + title: $localize`Access` + } + ], component: UserAccountPageComponent, path: '', title: $localize`My Ghostfolio` diff --git a/apps/client/src/app/pages/user-account/user-account-page.component.ts b/apps/client/src/app/pages/user-account/user-account-page.component.ts index c02c8bdf1..80c4a8f72 100644 --- a/apps/client/src/app/pages/user-account/user-account-page.component.ts +++ b/apps/client/src/app/pages/user-account/user-account-page.component.ts @@ -1,448 +1,63 @@ -import { - ChangeDetectorRef, - Component, - OnDestroy, - OnInit, - ViewChild -} from '@angular/core'; -import { MatCheckbox, MatCheckboxChange } from '@angular/material/checkbox'; -import { MatDialog } from '@angular/material/dialog'; -import { - MatSnackBar, - MatSnackBarRef, - TextOnlySnackBar -} from '@angular/material/snack-bar'; -import { ActivatedRoute, Router } from '@angular/router'; -import { CreateAccessDto } from '@ghostfolio/api/app/access/create-access.dto'; -import { DataService } from '@ghostfolio/client/services/data.service'; -import { - STAY_SIGNED_IN, - SettingsStorageService -} from '@ghostfolio/client/services/settings-storage.service'; +import { ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core'; import { UserService } from '@ghostfolio/client/services/user/user.service'; -import { WebAuthnService } from '@ghostfolio/client/services/web-authn.service'; -import { downloadAsFile, getDateFormatString } from '@ghostfolio/common/helper'; -import { Access, User } from '@ghostfolio/common/interfaces'; -import { hasPermission, permissions } from '@ghostfolio/common/permissions'; -import { format, parseISO } from 'date-fns'; -import { uniq } from 'lodash'; +import { TabConfiguration, User } from '@ghostfolio/common/interfaces'; import { DeviceDetectorService } from 'ngx-device-detector'; -import { StripeService } from 'ngx-stripe'; -import { EMPTY, Subject } from 'rxjs'; -import { catchError, switchMap, takeUntil } from 'rxjs/operators'; - -import { CreateOrUpdateAccessDialog } from './create-or-update-access-dialog/create-or-update-access-dialog.component'; +import { Subject, takeUntil } from 'rxjs'; @Component({ - host: { class: 'page' }, + host: { class: 'page has-tabs' }, selector: 'gf-user-account-page', styleUrls: ['./user-account-page.scss'], templateUrl: './user-account-page.html' }) export class UserAccountPageComponent implements OnDestroy, OnInit { - @ViewChild('toggleSignInWithFingerprintEnabledElement') - signInWithFingerprintElement: MatCheckbox; - - public accesses: Access[]; - public appearancePlaceholder = $localize`Auto`; - public baseCurrency: string; - public coupon: number; - public couponId: string; - public currencies: string[] = []; - public defaultDateFormat: string; public deviceType: string; - public hasPermissionForSubscription: boolean; - public hasPermissionToCreateAccess: boolean; - public hasPermissionToDeleteAccess: boolean; - public hasPermissionToUpdateViewMode: boolean; - public hasPermissionToUpdateUserSettings: boolean; - public language = document.documentElement.lang; - public locales = [ - 'de', - 'de-CH', - 'en-GB', - 'en-US', - 'es', - 'fr', - 'it', - 'nl', - 'pt', - 'tr' - ]; - public price: number; - public priceId: string; - public snackBarRef: MatSnackBarRef; - public trySubscriptionMail = - 'mailto:hi@ghostfol.io?Subject=Ghostfolio Premium Trial&body=Hello%0D%0DI am interested in Ghostfolio Premium. Can you please send me a coupon code to try it for some time?%0D%0DKind regards'; + public tabs: TabConfiguration[] = []; public user: User; private unsubscribeSubject = new Subject(); public constructor( private changeDetectorRef: ChangeDetectorRef, - private dataService: DataService, private deviceService: DeviceDetectorService, - private dialog: MatDialog, - private snackBar: MatSnackBar, - private route: ActivatedRoute, - private router: Router, - private settingsStorageService: SettingsStorageService, - private stripeService: StripeService, - private userService: UserService, - public webAuthnService: WebAuthnService + private userService: UserService ) { - const { baseCurrency, currencies, globalPermissions, subscriptions } = - this.dataService.fetchInfo(); - - this.baseCurrency = baseCurrency; - this.currencies = currencies; - - this.hasPermissionForSubscription = hasPermission( - globalPermissions, - permissions.enableSubscription - ); - - this.hasPermissionToDeleteAccess = hasPermission( - globalPermissions, - permissions.deleteAccess - ); - this.userService.stateChanged .pipe(takeUntil(this.unsubscribeSubject)) .subscribe((state) => { if (state?.user) { this.user = state.user; - this.defaultDateFormat = getDateFormatString( - this.user.settings.locale - ); - - this.hasPermissionToCreateAccess = hasPermission( - this.user.permissions, - permissions.createAccess - ); - - this.hasPermissionToDeleteAccess = hasPermission( - this.user.permissions, - permissions.deleteAccess - ); - - this.hasPermissionToUpdateUserSettings = hasPermission( - this.user.permissions, - permissions.updateUserSettings - ); - - this.hasPermissionToUpdateViewMode = hasPermission( - this.user.permissions, - permissions.updateViewMode - ); - - this.locales.push(this.user.settings.locale); - this.locales = uniq(this.locales.sort()); - - this.coupon = subscriptions?.[this.user.subscription.offer]?.coupon; - this.couponId = - subscriptions?.[this.user.subscription.offer]?.couponId; - this.price = subscriptions?.[this.user.subscription.offer]?.price; - this.priceId = subscriptions?.[this.user.subscription.offer]?.priceId; + this.tabs = [ + { + iconName: 'settings-outline', + label: $localize`Settings`, + path: ['/account'] + }, + { + iconName: 'diamond-outline', + label: $localize`Membership`, + path: ['/account/membership'], + showCondition: !!this.user?.subscription + }, + { + iconName: 'share-social-outline', + label: $localize`Access`, + path: ['/account', 'access'] + } + ]; this.changeDetectorRef.markForCheck(); } }); - - this.route.queryParams - .pipe(takeUntil(this.unsubscribeSubject)) - .subscribe((params) => { - if (params['createDialog']) { - this.openCreateAccessDialog(); - } - }); } public ngOnInit() { this.deviceType = this.deviceService.getDeviceInfo().deviceType; - - this.update(); - } - - public onChangeUserSetting(aKey: string, aValue: string) { - this.dataService - .putUserSetting({ [aKey]: aValue }) - .pipe(takeUntil(this.unsubscribeSubject)) - .subscribe(() => { - this.userService.remove(); - - this.userService - .get() - .pipe(takeUntil(this.unsubscribeSubject)) - .subscribe((user) => { - this.user = user; - - this.changeDetectorRef.markForCheck(); - - if (aKey === 'language') { - if (aValue) { - window.location.href = `../${aValue}/account`; - } else { - window.location.href = `../`; - } - } - }); - }); - } - - public onCheckout() { - this.dataService - .createCheckoutSession({ couponId: this.couponId, priceId: this.priceId }) - .pipe( - switchMap(({ sessionId }: { sessionId: string }) => { - return this.stripeService.redirectToCheckout({ sessionId }); - }), - catchError((error) => { - alert(error.message); - throw error; - }) - ) - .subscribe((result) => { - if (result.error) { - alert(result.error.message); - } - }); - } - - public onDeleteAccess(aId: string) { - this.dataService - .deleteAccess(aId) - .pipe(takeUntil(this.unsubscribeSubject)) - .subscribe({ - next: () => { - this.update(); - } - }); - } - - public onExperimentalFeaturesChange(aEvent: MatCheckboxChange) { - this.dataService - .putUserSetting({ isExperimentalFeatures: aEvent.checked }) - .pipe(takeUntil(this.unsubscribeSubject)) - .subscribe(() => { - this.userService.remove(); - - this.userService - .get() - .pipe(takeUntil(this.unsubscribeSubject)) - .subscribe((user) => { - this.user = user; - - this.changeDetectorRef.markForCheck(); - }); - }); - } - - public onExport() { - this.dataService - .fetchExport() - .pipe(takeUntil(this.unsubscribeSubject)) - .subscribe((data) => { - for (const activity of data.activities) { - delete activity.id; - } - - downloadAsFile({ - content: data, - fileName: `ghostfolio-export-${format( - parseISO(data.meta.date), - 'yyyyMMddHHmm' - )}.json`, - format: 'json' - }); - }); - } - - public onRedeemCoupon() { - let couponCode = prompt($localize`Please enter your coupon code:`); - couponCode = couponCode?.trim(); - - if (couponCode) { - this.dataService - .redeemCoupon(couponCode) - .pipe( - takeUntil(this.unsubscribeSubject), - catchError(() => { - this.snackBar.open( - '😞 ' + $localize`Could not redeem coupon code`, - undefined, - { - duration: 3000 - } - ); - - return EMPTY; - }) - ) - .subscribe(() => { - this.snackBarRef = this.snackBar.open( - '✅ ' + $localize`Coupon code has been redeemed`, - $localize`Reload`, - { - duration: 3000 - } - ); - - this.snackBarRef - .afterDismissed() - .pipe(takeUntil(this.unsubscribeSubject)) - .subscribe(() => { - window.location.reload(); - }); - - this.snackBarRef - .onAction() - .pipe(takeUntil(this.unsubscribeSubject)) - .subscribe(() => { - window.location.reload(); - }); - }); - } - } - - public onRestrictedViewChange(aEvent: MatCheckboxChange) { - this.dataService - .putUserSetting({ isRestrictedView: aEvent.checked }) - .pipe(takeUntil(this.unsubscribeSubject)) - .subscribe(() => { - this.userService.remove(); - - this.userService - .get() - .pipe(takeUntil(this.unsubscribeSubject)) - .subscribe((user) => { - this.user = user; - - this.changeDetectorRef.markForCheck(); - }); - }); - } - - public onSignInWithFingerprintChange(aEvent: MatCheckboxChange) { - if (aEvent.checked) { - this.registerDevice(); - } else { - const confirmation = confirm( - $localize`Do you really want to remove this sign in method?` - ); - - if (confirmation) { - this.deregisterDevice(); - } else { - this.update(); - } - } - } - - public onViewModeChange(aEvent: MatCheckboxChange) { - this.dataService - .putUserSetting({ viewMode: aEvent.checked === true ? 'ZEN' : 'DEFAULT' }) - .pipe(takeUntil(this.unsubscribeSubject)) - .subscribe(() => { - this.userService.remove(); - - this.userService - .get() - .pipe(takeUntil(this.unsubscribeSubject)) - .subscribe((user) => { - this.user = user; - - this.changeDetectorRef.markForCheck(); - }); - }); } public ngOnDestroy() { this.unsubscribeSubject.next(); this.unsubscribeSubject.complete(); } - - private openCreateAccessDialog(): void { - const dialogRef = this.dialog.open(CreateOrUpdateAccessDialog, { - data: { - access: { - alias: '', - type: 'PUBLIC' - } - }, - height: this.deviceType === 'mobile' ? '97.5vh' : '80vh', - width: this.deviceType === 'mobile' ? '100vw' : '50rem' - }); - - dialogRef - .afterClosed() - .pipe(takeUntil(this.unsubscribeSubject)) - .subscribe((data: any) => { - const access: CreateAccessDto = data?.access; - - if (access) { - this.dataService - .postAccess({ alias: access.alias }) - .pipe(takeUntil(this.unsubscribeSubject)) - .subscribe({ - next: () => { - this.update(); - } - }); - } - - this.router.navigate(['.'], { relativeTo: this.route }); - }); - } - - private deregisterDevice() { - this.webAuthnService - .deregister() - .pipe( - takeUntil(this.unsubscribeSubject), - catchError(() => { - this.update(); - - return EMPTY; - }) - ) - .subscribe(() => { - this.update(); - }); - } - - private registerDevice() { - this.webAuthnService - .register() - .pipe( - takeUntil(this.unsubscribeSubject), - catchError(() => { - this.update(); - - return EMPTY; - }) - ) - .subscribe(() => { - this.settingsStorageService.removeSetting(STAY_SIGNED_IN); - - this.update(); - }); - } - - private update() { - this.dataService - .fetchAccesses() - .pipe(takeUntil(this.unsubscribeSubject)) - .subscribe((response) => { - this.accesses = response; - - if (this.signInWithFingerprintElement) { - this.signInWithFingerprintElement.checked = - this.webAuthnService.isEnabled() ?? false; - } - - this.changeDetectorRef.markForCheck(); - }); - } } diff --git a/apps/client/src/app/pages/user-account/user-account-page.html b/apps/client/src/app/pages/user-account/user-account-page.html index debd190c1..d3fbca534 100644 --- a/apps/client/src/app/pages/user-account/user-account-page.html +++ b/apps/client/src/app/pages/user-account/user-account-page.html @@ -1,309 +1,29 @@ -
-
-
-

Account

-
-
-
-
- - -
-
Membership
-
- -
- Valid until {{ - user?.subscription?.expiresAt | date: defaultDateFormat }} -
-
- - -
- {{ baseCurrency }} {{ price }} {{ baseCurrency }} {{ price - coupon - }} - {{ baseCurrency }} {{ price }} per year -
-
- Try Premium - - Redeem Coupon -
-
-
-
-
-
Presenter View
-
- Protection for sensitive information like absolute performances - and quantity values -
-
-
- -
-
-
- -
-
- Base Currency -
-
- - - {{ currency }} - - -
-
-
-
-
Language
-
-
- - - - Deutsch - English - Español (Community) - Français (Community) - Italiano (Community) - Nederlands (Community) - Português (Community) - Türkçe (Community) - - -
-
-
-
-
Locale
-
- Date and number format -
-
-
- - - - {{ locale }} - - -
-
-
-
- Appearance -
-
- - - Auto - Light - Dark - - -
-
- -
-
-
-
Zen Mode
-
- Distraction-free experience for turbulent times -
-
-
- -
-
-
-
-
Biometric Authentication
-
- Sign in with fingerprint -
-
-
- -
-
-
-
-
Experimental Features
-
- Sneak peek at upcoming functionality -
-
-
- -
-
-
-
User ID
-
{{ user?.id }}
-
-
-
-
- -
-
-
-
-
-
-
-
-

- Granted Access - -

- -
-
-
+ + + + + diff --git a/apps/client/src/app/pages/user-account/user-account-page.module.ts b/apps/client/src/app/pages/user-account/user-account-page.module.ts index 240441ada..5ec767170 100644 --- a/apps/client/src/app/pages/user-account/user-account-page.module.ts +++ b/apps/client/src/app/pages/user-account/user-account-page.module.ts @@ -1,18 +1,10 @@ import { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { FormsModule, ReactiveFormsModule } from '@angular/forms'; -import { MatButtonModule } from '@angular/material/button'; -import { MatCardModule } from '@angular/material/card'; -import { MatCheckboxModule } from '@angular/material/checkbox'; -import { MatDialogModule } from '@angular/material/dialog'; -import { MatFormFieldModule } from '@angular/material/form-field'; -import { MatSelectModule } from '@angular/material/select'; -import { RouterModule } from '@angular/router'; -import { GfPortfolioAccessTableModule } from '@ghostfolio/client/components/access-table/access-table.module'; -import { GfPremiumIndicatorModule } from '@ghostfolio/ui/premium-indicator'; -import { GfValueModule } from '@ghostfolio/ui/value'; +import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; +import { MatTabsModule } from '@angular/material/tabs'; +import { GfUserAccountAccessModule } from '@ghostfolio/client/components/user-account-access/user-account-access.module'; +import { GfUserAccountMembershipModule } from '@ghostfolio/client/components/user-account-membership/user-account-membership.module'; +import { GfUserAccountSettingsModule } from '@ghostfolio/client/components/user-account-settings/user-account-settings.module'; -import { GfCreateOrUpdateAccessDialogModule } from './create-or-update-access-dialog/create-or-update-access-dialog.module'; import { UserAccountPageRoutingModule } from './user-account-page-routing.module'; import { UserAccountPageComponent } from './user-account-page.component'; @@ -20,20 +12,12 @@ import { UserAccountPageComponent } from './user-account-page.component'; declarations: [UserAccountPageComponent], imports: [ CommonModule, - FormsModule, - GfCreateOrUpdateAccessDialogModule, - GfPortfolioAccessTableModule, - GfPremiumIndicatorModule, - GfValueModule, - MatButtonModule, - MatCardModule, - MatCheckboxModule, - MatDialogModule, - MatFormFieldModule, - MatSelectModule, - ReactiveFormsModule, - RouterModule, + GfUserAccountAccessModule, + GfUserAccountMembershipModule, + GfUserAccountSettingsModule, + MatTabsModule, UserAccountPageRoutingModule - ] + ], + schemas: [CUSTOM_ELEMENTS_SCHEMA] }) export class UserAccountPageModule {} diff --git a/apps/client/src/app/pages/user-account/user-account-page.scss b/apps/client/src/app/pages/user-account/user-account-page.scss index 6dddf0e35..6a0b74854 100644 --- a/apps/client/src/app/pages/user-account/user-account-page.scss +++ b/apps/client/src/app/pages/user-account/user-account-page.scss @@ -1,15 +1,7 @@ +@import 'apps/client/src/styles/ghostfolio-style'; + :host { color: rgb(var(--dark-primary-text)); - display: block; - - gf-access-table { - overflow-x: auto; - } - - .hint-text { - font-size: 90%; - line-height: 1.2; - } } :host-context(.is-dark-theme) { diff --git a/apps/client/src/app/services/admin.service.ts b/apps/client/src/app/services/admin.service.ts index 3f72ff01d..e62641db7 100644 --- a/apps/client/src/app/services/admin.service.ts +++ b/apps/client/src/app/services/admin.service.ts @@ -4,6 +4,8 @@ import { UpdateAssetProfileDto } from '@ghostfolio/api/app/admin/update-asset-pr import { UpdateMarketDataDto } from '@ghostfolio/api/app/admin/update-market-data.dto'; import { CreatePlatformDto } from '@ghostfolio/api/app/platform/create-platform.dto'; import { UpdatePlatformDto } from '@ghostfolio/api/app/platform/update-platform.dto'; +import { CreateTagDto } from '@ghostfolio/api/app/tag/create-tag.dto'; +import { UpdateTagDto } from '@ghostfolio/api/app/tag/update-tag.dto'; import { IDataProviderHistoricalResponse } from '@ghostfolio/api/services/interfaces/interfaces'; import { DATE_FORMAT } from '@ghostfolio/common/helper'; import { @@ -15,7 +17,7 @@ import { Filter, UniqueAsset } from '@ghostfolio/common/interfaces'; -import { DataSource, MarketData, Platform, Prisma } from '@prisma/client'; +import { DataSource, MarketData, Platform, Prisma, Tag } from '@prisma/client'; import { JobStatus } from 'bull'; import { format, parseISO } from 'date-fns'; import { Observable, map } from 'rxjs'; @@ -64,6 +66,10 @@ export class AdminService { ); } + public deleteTag(aId: string) { + return this.http.delete(`/api/v1/tag/${aId}`); + } + public fetchAdminData() { return this.http.get('/api/v1/admin'); } @@ -139,6 +145,10 @@ export class AdminService { return this.http.get('/api/v1/platform'); } + public fetchTags() { + return this.http.get('/api/v1/tag'); + } + public gather7Days() { return this.http.post('/api/v1/admin/gather', {}); } @@ -208,6 +218,10 @@ export class AdminService { return this.http.post(`/api/v1/platform`, aPlatform); } + public postTag(aTag: CreateTagDto) { + return this.http.post(`/api/v1/tag`, aTag); + } + public putMarketData({ dataSource, date, @@ -233,4 +247,8 @@ export class AdminService { aPlatform ); } + + public putTag(aTag: UpdateTagDto) { + return this.http.put(`/api/v1/tag/${aTag.id}`, aTag); + } } diff --git a/apps/client/src/app/services/data.service.ts b/apps/client/src/app/services/data.service.ts index 82b4acca0..62845eda1 100644 --- a/apps/client/src/app/services/data.service.ts +++ b/apps/client/src/app/services/data.service.ts @@ -36,7 +36,6 @@ import { } from '@ghostfolio/common/interfaces'; import { filterGlobalPermissions } from '@ghostfolio/common/permissions'; import { AccountWithValue, DateRange, GroupBy } from '@ghostfolio/common/types'; -import { translate } from '@ghostfolio/ui/i18n'; import { DataSource, Order as OrderModel } from '@prisma/client'; import { format, parseISO } from 'date-fns'; import { cloneDeep, groupBy, isNumber } from 'lodash'; @@ -204,6 +203,10 @@ export class DataService { return this.http.delete(`/api/v1/order/`); } + public deleteBenchmark({ dataSource, symbol }: UniqueAsset) { + return this.http.delete(`/api/v1/benchmark/${dataSource}/${symbol}`); + } + public deleteOrder(aId: string) { return this.http.delete(`/api/v1/order/${aId}`); } @@ -496,4 +499,19 @@ export class DataService { couponCode }); } + + public updateInfo() { + this.http.get('/api/v1/info').subscribe((info) => { + const utmSource = <'ios' | 'trusted-web-activity'>( + window.localStorage.getItem('utm_source') + ); + + info.globalPermissions = filterGlobalPermissions( + info.globalPermissions, + utmSource + ); + + (window as any).info = info; + }); + } } diff --git a/apps/client/src/app/services/import-activities.service.ts b/apps/client/src/app/services/import-activities.service.ts index 808081bea..0a58e3cdd 100644 --- a/apps/client/src/app/services/import-activities.service.ts +++ b/apps/client/src/app/services/import-activities.service.ts @@ -15,6 +15,7 @@ import { catchError } from 'rxjs/operators'; }) export class ImportActivitiesService { private static ACCOUNT_KEYS = ['account', 'accountid']; + private static COMMENT_KEYS = ['comment', 'note']; private static CURRENCY_KEYS = ['ccy', 'currency', 'currencyprimary']; private static DATA_SOURCE_KEYS = ['datasource']; private static DATE_KEYS = ['date', 'tradedate']; @@ -52,6 +53,7 @@ export class ImportActivitiesService { for (const [index, item] of content.entries()) { activities.push({ accountId: this.parseAccount({ item, userAccounts }), + comment: this.parseComment({ item }), currency: this.parseCurrency({ content, index, item }), dataSource: this.parseDataSource({ item }), date: this.parseDate({ content, index, item }), @@ -122,6 +124,7 @@ export class ImportActivitiesService { private convertToCreateOrderDto({ accountId, + comment, date, fee, quantity, @@ -132,6 +135,7 @@ export class ImportActivitiesService { }: Activity): CreateOrderDto { return { accountId, + comment, fee, quantity, type, @@ -174,6 +178,18 @@ export class ImportActivitiesService { return undefined; } + private parseComment({ item }: { item: any }) { + item = this.lowercaseKeys(item); + + for (const key of ImportActivitiesService.COMMENT_KEYS) { + if (item[key]) { + return item[key]; + } + } + + return undefined; + } + private parseCurrency({ content, index, diff --git a/apps/client/src/assets/fonts/Inter-Black.woff b/apps/client/src/assets/fonts/Inter-Black.woff new file mode 100644 index 000000000..a18593a09 Binary files /dev/null and b/apps/client/src/assets/fonts/Inter-Black.woff differ diff --git a/apps/client/src/assets/fonts/Inter-Black.woff2 b/apps/client/src/assets/fonts/Inter-Black.woff2 new file mode 100644 index 000000000..68f64c9ed Binary files /dev/null and b/apps/client/src/assets/fonts/Inter-Black.woff2 differ diff --git a/apps/client/src/assets/fonts/Inter-BlackItalic.woff b/apps/client/src/assets/fonts/Inter-BlackItalic.woff new file mode 100644 index 000000000..b6b01943d Binary files /dev/null and b/apps/client/src/assets/fonts/Inter-BlackItalic.woff differ diff --git a/apps/client/src/assets/fonts/Inter-BlackItalic.woff2 b/apps/client/src/assets/fonts/Inter-BlackItalic.woff2 new file mode 100644 index 000000000..1c9c7ca8b Binary files /dev/null and b/apps/client/src/assets/fonts/Inter-BlackItalic.woff2 differ diff --git a/apps/client/src/assets/fonts/Inter-Bold.woff b/apps/client/src/assets/fonts/Inter-Bold.woff new file mode 100644 index 000000000..eaf3d4bfd Binary files /dev/null and b/apps/client/src/assets/fonts/Inter-Bold.woff differ diff --git a/apps/client/src/assets/fonts/Inter-Bold.woff2 b/apps/client/src/assets/fonts/Inter-Bold.woff2 new file mode 100644 index 000000000..2846f29cc Binary files /dev/null and b/apps/client/src/assets/fonts/Inter-Bold.woff2 differ diff --git a/apps/client/src/assets/fonts/Inter-BoldItalic.woff b/apps/client/src/assets/fonts/Inter-BoldItalic.woff new file mode 100644 index 000000000..327507616 Binary files /dev/null and b/apps/client/src/assets/fonts/Inter-BoldItalic.woff differ diff --git a/apps/client/src/assets/fonts/Inter-BoldItalic.woff2 b/apps/client/src/assets/fonts/Inter-BoldItalic.woff2 new file mode 100644 index 000000000..0b1fe8e12 Binary files /dev/null and b/apps/client/src/assets/fonts/Inter-BoldItalic.woff2 differ diff --git a/apps/client/src/assets/fonts/Inter-ExtraBold.woff b/apps/client/src/assets/fonts/Inter-ExtraBold.woff new file mode 100644 index 000000000..c2c17edea Binary files /dev/null and b/apps/client/src/assets/fonts/Inter-ExtraBold.woff differ diff --git a/apps/client/src/assets/fonts/Inter-ExtraBold.woff2 b/apps/client/src/assets/fonts/Inter-ExtraBold.woff2 new file mode 100644 index 000000000..c24c2bdc2 Binary files /dev/null and b/apps/client/src/assets/fonts/Inter-ExtraBold.woff2 differ diff --git a/apps/client/src/assets/fonts/Inter-ExtraBoldItalic.woff b/apps/client/src/assets/fonts/Inter-ExtraBoldItalic.woff new file mode 100644 index 000000000..c42f70526 Binary files /dev/null and b/apps/client/src/assets/fonts/Inter-ExtraBoldItalic.woff differ diff --git a/apps/client/src/assets/fonts/Inter-ExtraBoldItalic.woff2 b/apps/client/src/assets/fonts/Inter-ExtraBoldItalic.woff2 new file mode 100644 index 000000000..4a81dc798 Binary files /dev/null and b/apps/client/src/assets/fonts/Inter-ExtraBoldItalic.woff2 differ diff --git a/apps/client/src/assets/fonts/Inter-ExtraLight.woff b/apps/client/src/assets/fonts/Inter-ExtraLight.woff new file mode 100644 index 000000000..d0de5f397 Binary files /dev/null and b/apps/client/src/assets/fonts/Inter-ExtraLight.woff differ diff --git a/apps/client/src/assets/fonts/Inter-ExtraLight.woff2 b/apps/client/src/assets/fonts/Inter-ExtraLight.woff2 new file mode 100644 index 000000000..f2ea706fa Binary files /dev/null and b/apps/client/src/assets/fonts/Inter-ExtraLight.woff2 differ diff --git a/apps/client/src/assets/fonts/Inter-ExtraLightItalic.woff b/apps/client/src/assets/fonts/Inter-ExtraLightItalic.woff new file mode 100644 index 000000000..81f1a28ef Binary files /dev/null and b/apps/client/src/assets/fonts/Inter-ExtraLightItalic.woff differ diff --git a/apps/client/src/assets/fonts/Inter-ExtraLightItalic.woff2 b/apps/client/src/assets/fonts/Inter-ExtraLightItalic.woff2 new file mode 100644 index 000000000..9af717ba9 Binary files /dev/null and b/apps/client/src/assets/fonts/Inter-ExtraLightItalic.woff2 differ diff --git a/apps/client/src/assets/fonts/Inter-Italic.woff b/apps/client/src/assets/fonts/Inter-Italic.woff new file mode 100644 index 000000000..a806b3820 Binary files /dev/null and b/apps/client/src/assets/fonts/Inter-Italic.woff differ diff --git a/apps/client/src/assets/fonts/Inter-Italic.woff2 b/apps/client/src/assets/fonts/Inter-Italic.woff2 new file mode 100644 index 000000000..a619fc548 Binary files /dev/null and b/apps/client/src/assets/fonts/Inter-Italic.woff2 differ diff --git a/apps/client/src/assets/fonts/Inter-Light.woff b/apps/client/src/assets/fonts/Inter-Light.woff new file mode 100644 index 000000000..c496464d0 Binary files /dev/null and b/apps/client/src/assets/fonts/Inter-Light.woff differ diff --git a/apps/client/src/assets/fonts/Inter-Light.woff2 b/apps/client/src/assets/fonts/Inter-Light.woff2 new file mode 100644 index 000000000..bc4be6658 Binary files /dev/null and b/apps/client/src/assets/fonts/Inter-Light.woff2 differ diff --git a/apps/client/src/assets/fonts/Inter-LightItalic.woff b/apps/client/src/assets/fonts/Inter-LightItalic.woff new file mode 100644 index 000000000..f84a9de35 Binary files /dev/null and b/apps/client/src/assets/fonts/Inter-LightItalic.woff differ diff --git a/apps/client/src/assets/fonts/Inter-LightItalic.woff2 b/apps/client/src/assets/fonts/Inter-LightItalic.woff2 new file mode 100644 index 000000000..842b2dfcb Binary files /dev/null and b/apps/client/src/assets/fonts/Inter-LightItalic.woff2 differ diff --git a/apps/client/src/assets/fonts/Inter-Medium.woff b/apps/client/src/assets/fonts/Inter-Medium.woff new file mode 100644 index 000000000..d546843f2 Binary files /dev/null and b/apps/client/src/assets/fonts/Inter-Medium.woff differ diff --git a/apps/client/src/assets/fonts/Inter-Medium.woff2 b/apps/client/src/assets/fonts/Inter-Medium.woff2 new file mode 100644 index 000000000..f92498a2e Binary files /dev/null and b/apps/client/src/assets/fonts/Inter-Medium.woff2 differ diff --git a/apps/client/src/assets/fonts/Inter-MediumItalic.woff b/apps/client/src/assets/fonts/Inter-MediumItalic.woff new file mode 100644 index 000000000..459a65688 Binary files /dev/null and b/apps/client/src/assets/fonts/Inter-MediumItalic.woff differ diff --git a/apps/client/src/assets/fonts/Inter-MediumItalic.woff2 b/apps/client/src/assets/fonts/Inter-MediumItalic.woff2 new file mode 100644 index 000000000..0e3019f4a Binary files /dev/null and b/apps/client/src/assets/fonts/Inter-MediumItalic.woff2 differ diff --git a/apps/client/src/assets/fonts/Inter-Regular.woff b/apps/client/src/assets/fonts/Inter-Regular.woff new file mode 100644 index 000000000..62d3a6187 Binary files /dev/null and b/apps/client/src/assets/fonts/Inter-Regular.woff differ diff --git a/apps/client/src/assets/fonts/Inter-Regular.woff2 b/apps/client/src/assets/fonts/Inter-Regular.woff2 new file mode 100644 index 000000000..6c2b6893d Binary files /dev/null and b/apps/client/src/assets/fonts/Inter-Regular.woff2 differ diff --git a/apps/client/src/assets/fonts/Inter-SemiBold.woff b/apps/client/src/assets/fonts/Inter-SemiBold.woff new file mode 100644 index 000000000..a815f43a9 Binary files /dev/null and b/apps/client/src/assets/fonts/Inter-SemiBold.woff differ diff --git a/apps/client/src/assets/fonts/Inter-SemiBold.woff2 b/apps/client/src/assets/fonts/Inter-SemiBold.woff2 new file mode 100644 index 000000000..611e90c95 Binary files /dev/null and b/apps/client/src/assets/fonts/Inter-SemiBold.woff2 differ diff --git a/apps/client/src/assets/fonts/Inter-SemiBoldItalic.woff b/apps/client/src/assets/fonts/Inter-SemiBoldItalic.woff new file mode 100644 index 000000000..909e43a97 Binary files /dev/null and b/apps/client/src/assets/fonts/Inter-SemiBoldItalic.woff differ diff --git a/apps/client/src/assets/fonts/Inter-SemiBoldItalic.woff2 b/apps/client/src/assets/fonts/Inter-SemiBoldItalic.woff2 new file mode 100644 index 000000000..545685bd2 Binary files /dev/null and b/apps/client/src/assets/fonts/Inter-SemiBoldItalic.woff2 differ diff --git a/apps/client/src/assets/fonts/Inter-Thin.woff b/apps/client/src/assets/fonts/Inter-Thin.woff new file mode 100644 index 000000000..62bc58cd1 Binary files /dev/null and b/apps/client/src/assets/fonts/Inter-Thin.woff differ diff --git a/apps/client/src/assets/fonts/Inter-Thin.woff2 b/apps/client/src/assets/fonts/Inter-Thin.woff2 new file mode 100644 index 000000000..abbc3a5c9 Binary files /dev/null and b/apps/client/src/assets/fonts/Inter-Thin.woff2 differ diff --git a/apps/client/src/assets/fonts/Inter-ThinItalic.woff b/apps/client/src/assets/fonts/Inter-ThinItalic.woff new file mode 100644 index 000000000..700a7f069 Binary files /dev/null and b/apps/client/src/assets/fonts/Inter-ThinItalic.woff differ diff --git a/apps/client/src/assets/fonts/Inter-ThinItalic.woff2 b/apps/client/src/assets/fonts/Inter-ThinItalic.woff2 new file mode 100644 index 000000000..ab0b2002a Binary files /dev/null and b/apps/client/src/assets/fonts/Inter-ThinItalic.woff2 differ diff --git a/apps/client/src/assets/fonts/Inter-italic.var.woff2 b/apps/client/src/assets/fonts/Inter-italic.var.woff2 new file mode 100644 index 000000000..b826d5af8 Binary files /dev/null and b/apps/client/src/assets/fonts/Inter-italic.var.woff2 differ diff --git a/apps/client/src/assets/fonts/Inter-roman.var.woff2 b/apps/client/src/assets/fonts/Inter-roman.var.woff2 new file mode 100644 index 000000000..6a256a068 Binary files /dev/null and b/apps/client/src/assets/fonts/Inter-roman.var.woff2 differ diff --git a/apps/client/src/assets/fonts/Inter.var.woff2 b/apps/client/src/assets/fonts/Inter.var.woff2 new file mode 100644 index 000000000..365eedc50 Binary files /dev/null and b/apps/client/src/assets/fonts/Inter.var.woff2 differ diff --git a/apps/client/src/assets/fonts/inter.css b/apps/client/src/assets/fonts/inter.css new file mode 100644 index 000000000..71afda98a --- /dev/null +++ b/apps/client/src/assets/fonts/inter.css @@ -0,0 +1,226 @@ +@font-face { + font-family: 'Inter'; + font-style: normal; + font-weight: 100; + font-display: swap; + src: + url('Inter-Thin.woff2?v=3.19') format('woff2'), + url('Inter-Thin.woff?v=3.19') format('woff'); +} + +@font-face { + font-family: 'Inter'; + font-style: italic; + font-weight: 100; + font-display: swap; + src: + url('Inter-ThinItalic.woff2?v=3.19') format('woff2'), + url('Inter-ThinItalic.woff?v=3.19') format('woff'); +} + +@font-face { + font-family: 'Inter'; + font-style: normal; + font-weight: 200; + font-display: swap; + src: + url('Inter-ExtraLight.woff2?v=3.19') format('woff2'), + url('Inter-ExtraLight.woff?v=3.19') format('woff'); +} + +@font-face { + font-family: 'Inter'; + font-style: italic; + font-weight: 200; + font-display: swap; + src: + url('Inter-ExtraLightItalic.woff2?v=3.19') format('woff2'), + url('Inter-ExtraLightItalic.woff?v=3.19') format('woff'); +} + +@font-face { + font-family: 'Inter'; + font-style: normal; + font-weight: 300; + font-display: swap; + src: + url('Inter-Light.woff2?v=3.19') format('woff2'), + url('Inter-Light.woff?v=3.19') format('woff'); +} + +@font-face { + font-family: 'Inter'; + font-style: italic; + font-weight: 300; + font-display: swap; + src: + url('Inter-LightItalic.woff2?v=3.19') format('woff2'), + url('Inter-LightItalic.woff?v=3.19') format('woff'); +} + +@font-face { + font-family: 'Inter'; + font-style: normal; + font-weight: 400; + font-display: swap; + src: + url('Inter-Regular.woff2?v=3.19') format('woff2'), + url('Inter-Regular.woff?v=3.19') format('woff'); +} + +@font-face { + font-family: 'Inter'; + font-style: italic; + font-weight: 400; + font-display: swap; + src: + url('Inter-Italic.woff2?v=3.19') format('woff2'), + url('Inter-Italic.woff?v=3.19') format('woff'); +} + +@font-face { + font-family: 'Inter'; + font-style: normal; + font-weight: 500; + font-display: swap; + src: + url('Inter-Medium.woff2?v=3.19') format('woff2'), + url('Inter-Medium.woff?v=3.19') format('woff'); +} + +@font-face { + font-family: 'Inter'; + font-style: italic; + font-weight: 500; + font-display: swap; + src: + url('Inter-MediumItalic.woff2?v=3.19') format('woff2'), + url('Inter-MediumItalic.woff?v=3.19') format('woff'); +} + +@font-face { + font-family: 'Inter'; + font-style: normal; + font-weight: 600; + font-display: swap; + src: + url('Inter-SemiBold.woff2?v=3.19') format('woff2'), + url('Inter-SemiBold.woff?v=3.19') format('woff'); +} + +@font-face { + font-family: 'Inter'; + font-style: italic; + font-weight: 600; + font-display: swap; + src: + url('Inter-SemiBoldItalic.woff2?v=3.19') format('woff2'), + url('Inter-SemiBoldItalic.woff?v=3.19') format('woff'); +} + +@font-face { + font-family: 'Inter'; + font-style: normal; + font-weight: 700; + font-display: swap; + src: + url('Inter-Bold.woff2?v=3.19') format('woff2'), + url('Inter-Bold.woff?v=3.19') format('woff'); +} + +@font-face { + font-family: 'Inter'; + font-style: italic; + font-weight: 700; + font-display: swap; + src: + url('Inter-BoldItalic.woff2?v=3.19') format('woff2'), + url('Inter-BoldItalic.woff?v=3.19') format('woff'); +} + +@font-face { + font-family: 'Inter'; + font-style: normal; + font-weight: 800; + font-display: swap; + src: + url('Inter-ExtraBold.woff2?v=3.19') format('woff2'), + url('Inter-ExtraBold.woff?v=3.19') format('woff'); +} + +@font-face { + font-family: 'Inter'; + font-style: italic; + font-weight: 800; + font-display: swap; + src: + url('Inter-ExtraBoldItalic.woff2?v=3.19') format('woff2'), + url('Inter-ExtraBoldItalic.woff?v=3.19') format('woff'); +} + +@font-face { + font-family: 'Inter'; + font-style: normal; + font-weight: 900; + font-display: swap; + src: + url('Inter-Black.woff2?v=3.19') format('woff2'), + url('Inter-Black.woff?v=3.19') format('woff'); +} + +@font-face { + font-family: 'Inter'; + font-style: italic; + font-weight: 900; + font-display: swap; + src: + url('Inter-BlackItalic.woff2?v=3.19') format('woff2'), + url('Inter-BlackItalic.woff?v=3.19') format('woff'); +} + +/* ------------------------------------------------------- +Variable font. +Usage: + + html { font-family: 'Inter', sans-serif; } + @supports (font-variation-settings: normal) { + html { font-family: 'Inter var', sans-serif; } + } +*/ +@font-face { + font-family: 'Inter var'; + font-weight: 100 900; + font-display: swap; + font-style: normal; + font-named-instance: 'Regular'; + src: url('Inter-roman.var.woff2?v=3.19') format('woff2'); +} +@font-face { + font-family: 'Inter var'; + font-weight: 100 900; + font-display: swap; + font-style: italic; + font-named-instance: 'Italic'; + src: url('Inter-italic.var.woff2?v=3.19') format('woff2'); +} + +/* -------------------------------------------------------------------------- +[EXPERIMENTAL] Multi-axis, single variable font. + +Slant axis is not yet widely supported (as of February 2019) and thus this +multi-axis single variable font is opt-in rather than the default. + +When using this, you will probably need to set font-variation-settings +explicitly, e.g. + + * { font-variation-settings: "slnt" 0deg } + .italic { font-variation-settings: "slnt" 10deg } + +*/ +@font-face { + font-family: 'Inter var experimental'; + font-weight: 100 900; + font-display: swap; + font-style: oblique 0deg 10deg; + src: url('Inter.var.woff2?v=3.19') format('woff2'); +} diff --git a/apps/client/src/assets/images/blog/hacktoberfest-2023.png b/apps/client/src/assets/images/blog/hacktoberfest-2023.png new file mode 100644 index 000000000..c9d0a3eac Binary files /dev/null and b/apps/client/src/assets/images/blog/hacktoberfest-2023.png differ diff --git a/apps/client/src/assets/oss-friends.json b/apps/client/src/assets/oss-friends.json index cceb8a836..d7d8e1506 100644 --- a/apps/client/src/assets/oss-friends.json +++ b/apps/client/src/assets/oss-friends.json @@ -1,11 +1,6 @@ { - "createdAt": "2023-09-18T13:16:22.059Z", + "createdAt": "2023-10-05T00:00:00.000Z", "data": [ - { - "name": "Appsmith", - "description": "Build build custom software on top of your data.", - "href": "https://www.appsmith.com" - }, { "name": "BoxyHQ", "description": "BoxyHQ’s suite of APIs for security and privacy helps engineering teams build and ship compliant cloud applications faster.", @@ -66,11 +61,6 @@ "description": "Mockoon is the easiest and quickest way to design and run mock REST APIs.", "href": "https://mockoon.com" }, - { - "name": "Novu", - "description": "The open-source notification infrastructure for developers. Simple components and APIs for managing all communication channels in one place.", - "href": "https://novu.co" - }, { "name": "OpenBB", "description": "Democratizing investment research through an open source financial ecosystem. The OpenBB Terminal allows everyone to perform investment research, from everywhere.", @@ -81,6 +71,11 @@ "description": "Open-source monitoring platform with beautiful status pages", "href": "https://www.openstatus.dev" }, + { + "name": "Papermark", + "description": "Open-Source Docsend Alternative to securely share documents with real-time analytics.", + "href": "https://www.papermark.io/" + }, { "name": "Requestly", "description": "Makes frontend development cycle 10x faster with API Client, Mock Server, Intercept & Modify HTTP Requests and Session Replays.", diff --git a/apps/client/src/locales/messages.de.xlf b/apps/client/src/locales/messages.de.xlf index 43da453a1..4ca6c031e 100644 --- a/apps/client/src/locales/messages.de.xlf +++ b/apps/client/src/locales/messages.de.xlf @@ -22,7 +22,7 @@ Das Ausfallrisiko beim Börsenhandel kann erheblich sein. Es ist nicht ratsam, Geld zu investieren, welches du kurzfristig benötigst. apps/client/src/app/app.component.html - 172,173 + 174,175 @@ -100,6 +100,10 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html 88 + + apps/client/src/app/components/admin-tag/admin-tag.component.html + 44 + apps/client/src/app/components/admin-users/admin-users.html 23 @@ -128,6 +132,14 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html 7 + + apps/client/src/app/components/admin-tag/admin-tag.component.html + 30 + + + apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html + 7 + apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html 7 @@ -138,7 +150,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 208 + 171 libs/ui/src/lib/holdings-table/holdings-table.component.html @@ -198,11 +210,11 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 350 + 313 libs/ui/src/lib/activities-table/activities-table.component.html - 385 + 348 libs/ui/src/lib/holdings-table/holdings-table.component.html @@ -220,9 +232,13 @@ apps/client/src/app/components/admin-platform/admin-platform.component.html 90 + + apps/client/src/app/components/admin-tag/admin-tag.component.html + 70 + libs/ui/src/lib/activities-table/activities-table.component.html - 527 + 490 @@ -240,9 +256,13 @@ apps/client/src/app/components/admin-platform/admin-platform.component.html 94 + + apps/client/src/app/components/admin-tag/admin-tag.component.html + 74 + libs/ui/src/lib/activities-table/activities-table.component.html - 543 + 506 @@ -420,6 +440,10 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html 19 + + apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html + 13 + apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html 79 @@ -456,6 +480,10 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html 26 + + apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html + 20 + apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html 86 @@ -606,7 +634,7 @@ Systemmeldung apps/client/src/app/components/admin-overview/admin-overview.html - 109 + 96 @@ -614,7 +642,7 @@ Systemmeldung setzen apps/client/src/app/components/admin-overview/admin-overview.html - 131 + 118 @@ -622,7 +650,7 @@ Lese-Modus apps/client/src/app/components/admin-overview/admin-overview.html - 99 + 86 @@ -630,7 +658,7 @@ Gutscheincodes apps/client/src/app/components/admin-overview/admin-overview.html - 139 + 126 @@ -638,7 +666,7 @@ Hinzufügen apps/client/src/app/components/admin-overview/admin-overview.html - 183 + 170 @@ -646,7 +674,7 @@ Verwaltung apps/client/src/app/components/admin-overview/admin-overview.html - 190 + 177 @@ -654,7 +682,7 @@ Cache leeren apps/client/src/app/components/admin-overview/admin-overview.html - 194 + 181 @@ -908,6 +936,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 179 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 179 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 179 + About @@ -1238,6 +1274,10 @@ apps/client/src/app/pages/features/features-page.html 89 + + apps/client/src/app/pages/portfolio/fire/fire-page.html + 150 + Buying Power @@ -1327,8 +1367,8 @@ Tags Tags - apps/client/src/app/components/admin-overview/admin-overview.html - 79 + apps/client/src/app/components/admin-settings/admin-settings.component.html + 10 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -1554,6 +1594,10 @@ apps/client/src/app/pages/blog/2023/09/ghostfolio-2/ghostfolio-2-page.html 273 + + apps/client/src/app/pages/blog/2023/09/hacktoberfest-2023/hacktoberfest-2023-page.html + 181 + apps/client/src/app/pages/blog/blog-page.html 5 @@ -1656,7 +1700,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 416 + 379 @@ -1840,7 +1884,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 238 + 201 @@ -2212,7 +2256,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 259 + 222 @@ -2228,7 +2272,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 288 + 251 @@ -2244,7 +2288,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 317 + 280 @@ -2440,7 +2484,7 @@ Geplant libs/ui/src/lib/activities-table/activities-table.component.html - 218 + 181 @@ -2460,7 +2504,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 500 + 463 @@ -2472,7 +2516,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 510 + 473 @@ -2480,7 +2524,7 @@ Kopieren libs/ui/src/lib/activities-table/activities-table.component.html - 531 + 494 @@ -2488,7 +2532,7 @@ Geplante Aktivität als ICS exportieren libs/ui/src/lib/activities-table/activities-table.component.html - 539 + 502 @@ -3284,7 +3328,7 @@ Benutzer Registrierung apps/client/src/app/components/admin-overview/admin-overview.html - 89 + 76 @@ -3698,6 +3742,10 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html 148 + + apps/client/src/app/pages/portfolio/fire/fire-page.html + 137 + Portfolio Allocations @@ -3880,7 +3928,7 @@ Möchtest du wirklich alle Aktivitäten löschen? apps/client/src/app/pages/portfolio/activities/activities-page.component.ts - 142 + 140 @@ -3901,7 +3949,7 @@ Update platform - Plattform aktualisieren + Plattform bearbeiten apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html 2 @@ -4068,7 +4116,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 481 + 444 @@ -4080,7 +4128,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 490 + 453 @@ -4438,6 +4486,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 63 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 63 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 63 + Origin @@ -4542,6 +4598,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 68 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 68 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 68 + Region @@ -4646,6 +4710,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 73 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 73 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 73 + Available in @@ -4750,6 +4822,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 78,80 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 78,80 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 78,80 + ✅ Yes @@ -4854,6 +4934,18 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 100 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 100 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 100 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 107 + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 107 @@ -4954,6 +5046,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 107 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 107 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 121 + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 121 @@ -5054,6 +5154,18 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 121 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 121 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 132 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 132 + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 132 @@ -5254,6 +5366,22 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 146 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 146 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 146 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 153 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 153 + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 153 @@ -5454,6 +5582,22 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 165 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 165 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 165 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 172 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 172 + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 172 @@ -5658,6 +5802,18 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 102 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 102 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 102 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 125 + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 125 @@ -5758,6 +5914,18 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 125 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 125 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 136 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 136 + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 136 @@ -5958,6 +6126,22 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 148 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 148 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 148 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 155 @@ -6158,6 +6342,22 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 167 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 167 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 167 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 174 @@ -6362,6 +6562,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 109,110 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109,110 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109,110 + Self-Hosting @@ -6466,6 +6674,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 114,116 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 114,116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 114,116 + Use anonymously @@ -6570,6 +6786,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 141,143 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141,143 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141,143 + Free Plan @@ -6674,6 +6898,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 160,162 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 160,162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 160,162 + Notes @@ -6778,6 +7010,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 191 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + Effortlessly track, analyze, and visualize your wealth with Ghostfolio. @@ -6882,6 +7122,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 215,218 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 215,218 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 215,218 + Personal Finance Tools @@ -6986,6 +7234,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 287 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 287 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 287 + Guides @@ -7718,6 +7974,10 @@ apps/client/src/app/pages/resources/personal-finance-tools/products/altoo-page.component.ts 26 + + apps/client/src/app/pages/resources/personal-finance-tools/products/capmon-page.component.ts + 26 + apps/client/src/app/pages/resources/personal-finance-tools/products/copilot-money-page.component.ts 26 @@ -7802,6 +8062,10 @@ apps/client/src/app/pages/resources/personal-finance-tools/products/snowball-analytics-page.component.ts 26 + + apps/client/src/app/pages/resources/personal-finance-tools/products/stockmarketeye-page.component.ts + 26 + apps/client/src/app/pages/resources/personal-finance-tools/products/sumio-page.component.ts 26 @@ -7878,6 +8142,10 @@ apps/client/src/app/pages/blog/2023/09/ghostfolio-2/ghostfolio-2-page.component.ts 14 + + apps/client/src/app/pages/blog/2023/09/hacktoberfest-2023/hacktoberfest-2023-page.component.ts + 13 + apps/client/src/app/pages/landing/landing-page.component.ts 25 @@ -7890,6 +8158,10 @@ apps/client/src/app/pages/resources/personal-finance-tools/products/altoo-page.component.ts 25 + + apps/client/src/app/pages/resources/personal-finance-tools/products/capmon-page.component.ts + 25 + apps/client/src/app/pages/resources/personal-finance-tools/products/copilot-money-page.component.ts 25 @@ -7974,6 +8246,10 @@ apps/client/src/app/pages/resources/personal-finance-tools/products/snowball-analytics-page.component.ts 25 + + apps/client/src/app/pages/resources/personal-finance-tools/products/stockmarketeye-page.component.ts + 25 + apps/client/src/app/pages/resources/personal-finance-tools/products/sumio-page.component.ts 25 @@ -8190,6 +8466,10 @@ apps/client/src/app/pages/resources/personal-finance-tools/products/altoo-page.component.ts 28 + + apps/client/src/app/pages/resources/personal-finance-tools/products/capmon-page.component.ts + 28 + apps/client/src/app/pages/resources/personal-finance-tools/products/copilot-money-page.component.ts 28 @@ -8274,6 +8554,10 @@ apps/client/src/app/pages/resources/personal-finance-tools/products/snowball-analytics-page.component.ts 28 + + apps/client/src/app/pages/resources/personal-finance-tools/products/stockmarketeye-page.component.ts + 28 + apps/client/src/app/pages/resources/personal-finance-tools/products/sumio-page.component.ts 28 @@ -8426,6 +8710,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 8 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + Are you looking for an open source alternative to ? Ghostfolio is a powerful portfolio management tool that provides individuals with a comprehensive platform to track, analyze, and optimize their investments. Whether you are an experienced investor or just starting out, Ghostfolio offers an intuitive user interface and a wide range of functionalities to help you make informed decisions and take control of your financial future. @@ -8530,6 +8822,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 13,25 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13,25 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13,25 + Ghostfolio is an open source software (OSS), providing a cost-effective alternative to making it particularly suitable for individuals on a tight budget, such as those pursuing Financial Independence, Retire Early (FIRE). By leveraging the collective efforts of a community of developers and personal finance enthusiasts, Ghostfolio continuously enhances its capabilities, security, and user experience. @@ -8634,6 +8934,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 26,36 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 26,36 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 26,36 + Let’s dive deeper into the detailed comparison table below to gain a thorough understanding of how Ghostfolio positions itself relative to . We will explore various aspects such as features, data privacy, pricing, and more, allowing you to make a well-informed choice for your personal requirements. @@ -8738,6 +9046,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 37,43 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 37,43 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 37,43 + Starting from / year @@ -8842,6 +9158,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 180,182 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 180,182 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 180,182 + Starting from / year @@ -8946,6 +9270,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 185,186 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 185,186 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 185,186 + open-source-alternative-to @@ -9062,6 +9394,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 199,208 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 199,208 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 199,208 + Ready to take your investments to the next level? @@ -9166,6 +9506,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 211,214 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 211,214 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 211,214 + Get Started @@ -9270,29 +9618,37 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 220,222 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 220,222 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 220,222 + Switzerland Schweiz apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 47 + 49 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 60 + 61 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 337 + 333 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 349 + 344 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 350 + 345 @@ -9300,7 +9656,7 @@ Weltweit apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 49 + 51 apps/client/src/app/pages/resources/personal-finance-tools/products.ts @@ -9308,7 +9664,7 @@ apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 292 + 283 @@ -9316,31 +9672,31 @@ Vereinigte Staaten von Amerika apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 71 + 80 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 108 + 114 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 167 + 168 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 194 + 193 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 196 + 195 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 266 + 259 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 278 + 270 @@ -9348,7 +9704,7 @@ Belgien apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 84 + 92 @@ -9356,19 +9712,23 @@ Deutschland apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 96 + 69 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 133 + 103 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 144 + 137 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 155 + 147 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 157 apps/client/src/app/pages/resources/personal-finance-tools/products.ts @@ -9376,7 +9736,7 @@ apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 218 + 215 @@ -9384,7 +9744,7 @@ Österreich apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 120 + 125 @@ -9392,7 +9752,7 @@ Italien apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 230 + 226 @@ -9400,7 +9760,7 @@ Niederlande apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 241 + 236 @@ -9408,7 +9768,7 @@ Thailand apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 254 + 248 @@ -9416,7 +9776,7 @@ Neuseeland apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 290 + 281 @@ -9424,11 +9784,11 @@ Tschechische Republik apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 302 + 292 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 325 + 322 @@ -9539,6 +9899,74 @@ 45 + + Add Tag + Tag hinzufügen + + apps/client/src/app/components/admin-tag/admin-tag.component.html + 11,13 + + + + Do you really want to delete this tag? + Möchtest du diesen Tag wirklich löschen? + + apps/client/src/app/components/admin-tag/admin-tag.component.ts + 76 + + + + Update tag + Tag bearbeiten + + apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html + 2 + + + + Add tag + Tag hinzufügen + + apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html + 3 + + + + France + Frankreich + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 303 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 312 + + + + Ghostfolio X-ray uses static analysis to identify potential issues and risks in your portfolio. + Ghostfolio X-ray nutzt statische Analysen, um potenzielle Probleme und Risiken in deinem Portfolio zu identifizieren. + + apps/client/src/app/pages/portfolio/fire/fire-page.html + 100,101 + + + + Currency Cluster Risks + Währungsklumpenrisiken + + apps/client/src/app/pages/portfolio/fire/fire-page.html + 111 + + + + Account Cluster Risks + Kontoklumpenrisiken + + apps/client/src/app/pages/portfolio/fire/fire-page.html + 124 + + diff --git a/apps/client/src/locales/messages.es.xlf b/apps/client/src/locales/messages.es.xlf index 3a615d0bd..bbb2d41a5 100644 --- a/apps/client/src/locales/messages.es.xlf +++ b/apps/client/src/locales/messages.es.xlf @@ -23,7 +23,7 @@ El riesgo de pérdida en trading puede ser importante. No es aconsejable invertir dinero que puedas necesitar a corto plazo. apps/client/src/app/app.component.html - 172,173 + 174,175 @@ -101,6 +101,10 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html 88 + + apps/client/src/app/components/admin-tag/admin-tag.component.html + 44 + apps/client/src/app/components/admin-users/admin-users.html 23 @@ -129,6 +133,14 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html 7 + + apps/client/src/app/components/admin-tag/admin-tag.component.html + 30 + + + apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html + 7 + apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html 7 @@ -139,7 +151,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 208 + 171 libs/ui/src/lib/holdings-table/holdings-table.component.html @@ -199,11 +211,11 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 350 + 313 libs/ui/src/lib/activities-table/activities-table.component.html - 385 + 348 libs/ui/src/lib/holdings-table/holdings-table.component.html @@ -221,9 +233,13 @@ apps/client/src/app/components/admin-platform/admin-platform.component.html 90 + + apps/client/src/app/components/admin-tag/admin-tag.component.html + 70 + libs/ui/src/lib/activities-table/activities-table.component.html - 527 + 490 @@ -241,9 +257,13 @@ apps/client/src/app/components/admin-platform/admin-platform.component.html 94 + + apps/client/src/app/components/admin-tag/admin-tag.component.html + 74 + libs/ui/src/lib/activities-table/activities-table.component.html - 543 + 506 @@ -421,6 +441,10 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html 19 + + apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html + 13 + apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html 79 @@ -457,6 +481,10 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html 26 + + apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html + 20 + apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html 86 @@ -607,7 +635,7 @@ Mensaje del sistema apps/client/src/app/components/admin-overview/admin-overview.html - 109 + 96 @@ -615,7 +643,7 @@ Establecer mensaje apps/client/src/app/components/admin-overview/admin-overview.html - 131 + 118 @@ -623,7 +651,7 @@ Modo de solo lectura apps/client/src/app/components/admin-overview/admin-overview.html - 99 + 86 @@ -631,7 +659,7 @@ Cupones apps/client/src/app/components/admin-overview/admin-overview.html - 139 + 126 @@ -639,7 +667,7 @@ Añadir apps/client/src/app/components/admin-overview/admin-overview.html - 183 + 170 @@ -647,7 +675,7 @@ Tareas domésticas apps/client/src/app/components/admin-overview/admin-overview.html - 190 + 177 @@ -655,7 +683,7 @@ Limpiar caché apps/client/src/app/components/admin-overview/admin-overview.html - 194 + 181 @@ -909,6 +937,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 179 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 179 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 179 + About @@ -1236,6 +1272,10 @@ apps/client/src/app/pages/features/features-page.html 89 + + apps/client/src/app/pages/portfolio/fire/fire-page.html + 150 + Buying Power @@ -1325,8 +1365,8 @@ Tags Etiquetas - apps/client/src/app/components/admin-overview/admin-overview.html - 79 + apps/client/src/app/components/admin-settings/admin-settings.component.html + 10 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -1552,6 +1592,10 @@ apps/client/src/app/pages/blog/2023/09/ghostfolio-2/ghostfolio-2-page.html 273 + + apps/client/src/app/pages/blog/2023/09/hacktoberfest-2023/hacktoberfest-2023-page.html + 181 + apps/client/src/app/pages/blog/blog-page.html 5 @@ -1654,7 +1698,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 416 + 379 @@ -1838,7 +1882,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 238 + 201 @@ -2210,7 +2254,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 259 + 222 @@ -2226,7 +2270,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 288 + 251 @@ -2242,7 +2286,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 317 + 280 @@ -2438,7 +2482,7 @@ Borrador libs/ui/src/lib/activities-table/activities-table.component.html - 218 + 181 @@ -2458,7 +2502,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 500 + 463 @@ -2470,7 +2514,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 510 + 473 @@ -2478,7 +2522,7 @@ Clonar libs/ui/src/lib/activities-table/activities-table.component.html - 531 + 494 @@ -2486,7 +2530,7 @@ Exportar borrador como ICS libs/ui/src/lib/activities-table/activities-table.component.html - 539 + 502 @@ -3282,7 +3326,7 @@ User Signup apps/client/src/app/components/admin-overview/admin-overview.html - 89 + 76 @@ -3696,6 +3740,10 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html 148 + + apps/client/src/app/pages/portfolio/fire/fire-page.html + 137 + Portfolio Allocations @@ -3878,7 +3926,7 @@ Do you really want to delete all your activities? apps/client/src/app/pages/portfolio/activities/activities-page.component.ts - 142 + 140 @@ -4066,7 +4114,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 481 + 444 @@ -4078,7 +4126,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 490 + 453 @@ -4436,6 +4484,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 63 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 63 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 63 + Origin @@ -4540,6 +4596,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 68 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 68 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 68 + Region @@ -4644,6 +4708,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 73 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 73 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 73 + Available in @@ -4748,6 +4820,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 78,80 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 78,80 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 78,80 + ✅ Yes @@ -4852,6 +4932,18 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 100 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 100 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 100 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 107 + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 107 @@ -4952,6 +5044,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 107 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 107 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 121 + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 121 @@ -5052,6 +5152,18 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 121 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 121 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 132 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 132 + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 132 @@ -5252,6 +5364,22 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 146 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 146 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 146 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 153 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 153 + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 153 @@ -5452,6 +5580,22 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 165 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 165 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 165 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 172 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 172 + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 172 @@ -5656,6 +5800,18 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 102 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 102 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 102 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 125 + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 125 @@ -5756,6 +5912,18 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 125 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 125 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 136 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 136 + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 136 @@ -5956,6 +6124,22 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 148 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 148 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 148 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 155 @@ -6156,6 +6340,22 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 167 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 167 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 167 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 174 @@ -6360,6 +6560,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 109,110 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109,110 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109,110 + Self-Hosting @@ -6464,6 +6672,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 114,116 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 114,116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 114,116 + Use anonymously @@ -6568,6 +6784,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 141,143 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141,143 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141,143 + Free Plan @@ -6672,6 +6896,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 160,162 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 160,162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 160,162 + Notes @@ -6776,6 +7008,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 191 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + Effortlessly track, analyze, and visualize your wealth with Ghostfolio. @@ -6880,6 +7120,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 215,218 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 215,218 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 215,218 + Personal Finance Tools @@ -6984,6 +7232,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 287 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 287 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 287 + Guides @@ -7716,6 +7972,10 @@ apps/client/src/app/pages/resources/personal-finance-tools/products/altoo-page.component.ts 26 + + apps/client/src/app/pages/resources/personal-finance-tools/products/capmon-page.component.ts + 26 + apps/client/src/app/pages/resources/personal-finance-tools/products/copilot-money-page.component.ts 26 @@ -7800,6 +8060,10 @@ apps/client/src/app/pages/resources/personal-finance-tools/products/snowball-analytics-page.component.ts 26 + + apps/client/src/app/pages/resources/personal-finance-tools/products/stockmarketeye-page.component.ts + 26 + apps/client/src/app/pages/resources/personal-finance-tools/products/sumio-page.component.ts 26 @@ -7876,6 +8140,10 @@ apps/client/src/app/pages/blog/2023/09/ghostfolio-2/ghostfolio-2-page.component.ts 14 + + apps/client/src/app/pages/blog/2023/09/hacktoberfest-2023/hacktoberfest-2023-page.component.ts + 13 + apps/client/src/app/pages/landing/landing-page.component.ts 25 @@ -7888,6 +8156,10 @@ apps/client/src/app/pages/resources/personal-finance-tools/products/altoo-page.component.ts 25 + + apps/client/src/app/pages/resources/personal-finance-tools/products/capmon-page.component.ts + 25 + apps/client/src/app/pages/resources/personal-finance-tools/products/copilot-money-page.component.ts 25 @@ -7972,6 +8244,10 @@ apps/client/src/app/pages/resources/personal-finance-tools/products/snowball-analytics-page.component.ts 25 + + apps/client/src/app/pages/resources/personal-finance-tools/products/stockmarketeye-page.component.ts + 25 + apps/client/src/app/pages/resources/personal-finance-tools/products/sumio-page.component.ts 25 @@ -8188,6 +8464,10 @@ apps/client/src/app/pages/resources/personal-finance-tools/products/altoo-page.component.ts 28 + + apps/client/src/app/pages/resources/personal-finance-tools/products/capmon-page.component.ts + 28 + apps/client/src/app/pages/resources/personal-finance-tools/products/copilot-money-page.component.ts 28 @@ -8272,6 +8552,10 @@ apps/client/src/app/pages/resources/personal-finance-tools/products/snowball-analytics-page.component.ts 28 + + apps/client/src/app/pages/resources/personal-finance-tools/products/stockmarketeye-page.component.ts + 28 + apps/client/src/app/pages/resources/personal-finance-tools/products/sumio-page.component.ts 28 @@ -8424,6 +8708,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 8 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + Are you looking for an open source alternative to ? Ghostfolio is a powerful portfolio management tool that provides individuals with a comprehensive platform to track, analyze, and optimize their investments. Whether you are an experienced investor or just starting out, Ghostfolio offers an intuitive user interface and a wide range of functionalities to help you make informed decisions and take control of your financial future. @@ -8528,6 +8820,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 13,25 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13,25 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13,25 + Ghostfolio is an open source software (OSS), providing a cost-effective alternative to making it particularly suitable for individuals on a tight budget, such as those pursuing Financial Independence, Retire Early (FIRE). By leveraging the collective efforts of a community of developers and personal finance enthusiasts, Ghostfolio continuously enhances its capabilities, security, and user experience. @@ -8632,6 +8932,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 26,36 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 26,36 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 26,36 + Let’s dive deeper into the detailed comparison table below to gain a thorough understanding of how Ghostfolio positions itself relative to . We will explore various aspects such as features, data privacy, pricing, and more, allowing you to make a well-informed choice for your personal requirements. @@ -8736,6 +9044,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 37,43 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 37,43 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 37,43 + Starting from / year @@ -8840,6 +9156,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 180,182 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 180,182 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 180,182 + Starting from / year @@ -8944,6 +9268,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 185,186 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 185,186 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 185,186 + open-source-alternative-to @@ -9060,6 +9392,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 199,208 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 199,208 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 199,208 + Ready to take your investments to the next level? @@ -9164,6 +9504,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 211,214 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 211,214 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 211,214 + Get Started @@ -9268,29 +9616,37 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 220,222 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 220,222 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 220,222 + Switzerland Switzerland apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 47 + 49 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 60 + 61 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 337 + 333 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 349 + 344 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 350 + 345 @@ -9298,7 +9654,7 @@ Global apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 49 + 51 apps/client/src/app/pages/resources/personal-finance-tools/products.ts @@ -9306,7 +9662,7 @@ apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 292 + 283 @@ -9314,31 +9670,31 @@ United States apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 71 + 80 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 108 + 114 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 167 + 168 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 194 + 193 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 196 + 195 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 266 + 259 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 278 + 270 @@ -9346,7 +9702,7 @@ Belgium apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 84 + 92 @@ -9354,19 +9710,23 @@ Germany apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 96 + 69 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 133 + 103 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 144 + 137 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 155 + 147 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 157 apps/client/src/app/pages/resources/personal-finance-tools/products.ts @@ -9374,7 +9734,7 @@ apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 218 + 215 @@ -9382,7 +9742,7 @@ Austria apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 120 + 125 @@ -9390,7 +9750,7 @@ Italy apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 230 + 226 @@ -9398,7 +9758,7 @@ Netherlands apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 241 + 236 @@ -9406,7 +9766,7 @@ Thailand apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 254 + 248 @@ -9414,7 +9774,7 @@ New Zealand apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 290 + 281 @@ -9422,11 +9782,11 @@ Czech Republic apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 302 + 292 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 325 + 322 @@ -9537,6 +9897,74 @@ 45 + + Add Tag + Add Tag + + apps/client/src/app/components/admin-tag/admin-tag.component.html + 11,13 + + + + Do you really want to delete this tag? + Do you really want to delete this tag? + + apps/client/src/app/components/admin-tag/admin-tag.component.ts + 76 + + + + Update tag + Update tag + + apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html + 2 + + + + Add tag + Add tag + + apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html + 3 + + + + France + France + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 303 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 312 + + + + Ghostfolio X-ray uses static analysis to identify potential issues and risks in your portfolio. + Ghostfolio X-ray uses static analysis to identify potential issues and risks in your portfolio. + + apps/client/src/app/pages/portfolio/fire/fire-page.html + 100,101 + + + + Currency Cluster Risks + Currency Cluster Risks + + apps/client/src/app/pages/portfolio/fire/fire-page.html + 111 + + + + Account Cluster Risks + Account Cluster Risks + + apps/client/src/app/pages/portfolio/fire/fire-page.html + 124 + + diff --git a/apps/client/src/locales/messages.fr.xlf b/apps/client/src/locales/messages.fr.xlf index 1ade12a0d..bdba67fad 100644 --- a/apps/client/src/locales/messages.fr.xlf +++ b/apps/client/src/locales/messages.fr.xlf @@ -6,7 +6,7 @@ Le risque de perte en investissant peut être important. Il est déconseillé d'investir de l'argent dont vous pourriez avoir besoin à court terme. apps/client/src/app/app.component.html - 172,173 + 174,175 @@ -112,6 +112,10 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html 88 + + apps/client/src/app/components/admin-tag/admin-tag.component.html + 44 + apps/client/src/app/components/admin-users/admin-users.html 23 @@ -140,6 +144,14 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html 7 + + apps/client/src/app/components/admin-tag/admin-tag.component.html + 30 + + + apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html + 7 + apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html 7 @@ -150,7 +162,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 208 + 171 libs/ui/src/lib/holdings-table/holdings-table.component.html @@ -190,7 +202,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 238 + 201 @@ -250,11 +262,11 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 350 + 313 libs/ui/src/lib/activities-table/activities-table.component.html - 385 + 348 libs/ui/src/lib/holdings-table/holdings-table.component.html @@ -272,9 +284,13 @@ apps/client/src/app/components/admin-platform/admin-platform.component.html 90 + + apps/client/src/app/components/admin-tag/admin-tag.component.html + 70 + libs/ui/src/lib/activities-table/activities-table.component.html - 527 + 490 @@ -292,9 +308,13 @@ apps/client/src/app/components/admin-platform/admin-platform.component.html 94 + + apps/client/src/app/components/admin-tag/admin-tag.component.html + 74 + libs/ui/src/lib/activities-table/activities-table.component.html - 543 + 506 @@ -472,6 +492,10 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html 19 + + apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html + 13 + apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html 79 @@ -508,6 +532,10 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html 26 + + apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html + 20 + apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html 86 @@ -817,8 +845,8 @@ Tags Étiquettes - apps/client/src/app/components/admin-overview/admin-overview.html - 79 + apps/client/src/app/components/admin-settings/admin-settings.component.html + 10 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -834,7 +862,7 @@ Inscription de Nouveaux Utilisateurs apps/client/src/app/components/admin-overview/admin-overview.html - 89 + 76 @@ -842,7 +870,7 @@ Mode Lecture Seule apps/client/src/app/components/admin-overview/admin-overview.html - 99 + 86 @@ -850,7 +878,7 @@ Message Système apps/client/src/app/components/admin-overview/admin-overview.html - 109 + 96 @@ -858,7 +886,7 @@ Définir Message apps/client/src/app/components/admin-overview/admin-overview.html - 131 + 118 @@ -866,7 +894,7 @@ Codes promotionnels apps/client/src/app/components/admin-overview/admin-overview.html - 139 + 126 @@ -874,7 +902,7 @@ Ajouter apps/client/src/app/components/admin-overview/admin-overview.html - 183 + 170 @@ -882,7 +910,7 @@ Maintenance apps/client/src/app/components/admin-overview/admin-overview.html - 190 + 177 @@ -890,7 +918,7 @@ Vider le Cache apps/client/src/app/components/admin-overview/admin-overview.html - 194 + 181 @@ -1188,6 +1216,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 179 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 179 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 179 + About @@ -1567,6 +1603,10 @@ apps/client/src/app/pages/features/features-page.html 89 + + apps/client/src/app/pages/portfolio/fire/fire-page.html + 150 + Buying Power @@ -1677,7 +1717,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 259 + 222 @@ -1925,7 +1965,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 416 + 379 @@ -2303,6 +2343,10 @@ apps/client/src/app/pages/blog/2023/09/ghostfolio-2/ghostfolio-2-page.html 273 + + apps/client/src/app/pages/blog/2023/09/hacktoberfest-2023/hacktoberfest-2023-page.html + 181 + apps/client/src/app/pages/blog/blog-page.html 5 @@ -2449,7 +2493,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 288 + 251 @@ -2465,7 +2509,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 317 + 280 @@ -2985,7 +3029,7 @@ Brouillon libs/ui/src/lib/activities-table/activities-table.component.html - 218 + 181 @@ -3005,7 +3049,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 500 + 463 @@ -3017,7 +3061,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 510 + 473 @@ -3025,7 +3069,7 @@ Dupliquer libs/ui/src/lib/activities-table/activities-table.component.html - 531 + 494 @@ -3033,7 +3077,7 @@ Exporter Brouillon sous ICS libs/ui/src/lib/activities-table/activities-table.component.html - 539 + 502 @@ -3695,6 +3739,10 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html 148 + + apps/client/src/app/pages/portfolio/fire/fire-page.html + 137 + Portfolio Allocations @@ -3877,7 +3925,7 @@ Voulez-vous vraiment supprimer toutes vos activités ? apps/client/src/app/pages/portfolio/activities/activities-page.component.ts - 142 + 140 @@ -4065,7 +4113,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 481 + 444 @@ -4077,7 +4125,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 490 + 453 @@ -4435,6 +4483,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 63 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 63 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 63 + Origin @@ -4539,6 +4595,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 68 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 68 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 68 + Region @@ -4643,6 +4707,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 73 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 73 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 73 + Available in @@ -4747,6 +4819,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 78,80 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 78,80 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 78,80 + ✅ Yes @@ -4851,6 +4931,18 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 100 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 100 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 100 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 107 + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 107 @@ -4951,6 +5043,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 107 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 107 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 121 + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 121 @@ -5051,6 +5151,18 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 121 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 121 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 132 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 132 + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 132 @@ -5251,6 +5363,22 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 146 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 146 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 146 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 153 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 153 + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 153 @@ -5451,6 +5579,22 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 165 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 165 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 165 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 172 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 172 + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 172 @@ -5655,6 +5799,18 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 102 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 102 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 102 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 125 + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 125 @@ -5755,6 +5911,18 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 125 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 125 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 136 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 136 + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 136 @@ -5955,6 +6123,22 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 148 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 148 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 148 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 155 @@ -6155,6 +6339,22 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 167 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 167 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 167 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 174 @@ -6359,6 +6559,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 109,110 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109,110 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109,110 + Self-Hosting @@ -6463,6 +6671,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 114,116 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 114,116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 114,116 + Use anonymously @@ -6567,6 +6783,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 141,143 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141,143 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141,143 + Free Plan @@ -6671,6 +6895,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 160,162 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 160,162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 160,162 + Notes @@ -6775,6 +7007,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 191 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + Effortlessly track, analyze, and visualize your wealth with Ghostfolio. @@ -6879,6 +7119,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 215,218 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 215,218 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 215,218 + Personal Finance Tools @@ -6983,6 +7231,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 287 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 287 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 287 + Guides @@ -7715,6 +7971,10 @@ apps/client/src/app/pages/resources/personal-finance-tools/products/altoo-page.component.ts 26 + + apps/client/src/app/pages/resources/personal-finance-tools/products/capmon-page.component.ts + 26 + apps/client/src/app/pages/resources/personal-finance-tools/products/copilot-money-page.component.ts 26 @@ -7799,6 +8059,10 @@ apps/client/src/app/pages/resources/personal-finance-tools/products/snowball-analytics-page.component.ts 26 + + apps/client/src/app/pages/resources/personal-finance-tools/products/stockmarketeye-page.component.ts + 26 + apps/client/src/app/pages/resources/personal-finance-tools/products/sumio-page.component.ts 26 @@ -7875,6 +8139,10 @@ apps/client/src/app/pages/blog/2023/09/ghostfolio-2/ghostfolio-2-page.component.ts 14 + + apps/client/src/app/pages/blog/2023/09/hacktoberfest-2023/hacktoberfest-2023-page.component.ts + 13 + apps/client/src/app/pages/landing/landing-page.component.ts 25 @@ -7887,6 +8155,10 @@ apps/client/src/app/pages/resources/personal-finance-tools/products/altoo-page.component.ts 25 + + apps/client/src/app/pages/resources/personal-finance-tools/products/capmon-page.component.ts + 25 + apps/client/src/app/pages/resources/personal-finance-tools/products/copilot-money-page.component.ts 25 @@ -7971,6 +8243,10 @@ apps/client/src/app/pages/resources/personal-finance-tools/products/snowball-analytics-page.component.ts 25 + + apps/client/src/app/pages/resources/personal-finance-tools/products/stockmarketeye-page.component.ts + 25 + apps/client/src/app/pages/resources/personal-finance-tools/products/sumio-page.component.ts 25 @@ -8187,6 +8463,10 @@ apps/client/src/app/pages/resources/personal-finance-tools/products/altoo-page.component.ts 28 + + apps/client/src/app/pages/resources/personal-finance-tools/products/capmon-page.component.ts + 28 + apps/client/src/app/pages/resources/personal-finance-tools/products/copilot-money-page.component.ts 28 @@ -8271,6 +8551,10 @@ apps/client/src/app/pages/resources/personal-finance-tools/products/snowball-analytics-page.component.ts 28 + + apps/client/src/app/pages/resources/personal-finance-tools/products/stockmarketeye-page.component.ts + 28 + apps/client/src/app/pages/resources/personal-finance-tools/products/sumio-page.component.ts 28 @@ -8423,6 +8707,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 8 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + Are you looking for an open source alternative to ? Ghostfolio is a powerful portfolio management tool that provides individuals with a comprehensive platform to track, analyze, and optimize their investments. Whether you are an experienced investor or just starting out, Ghostfolio offers an intuitive user interface and a wide range of functionalities to help you make informed decisions and take control of your financial future. @@ -8527,6 +8819,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 13,25 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13,25 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13,25 + Ghostfolio is an open source software (OSS), providing a cost-effective alternative to making it particularly suitable for individuals on a tight budget, such as those pursuing Financial Independence, Retire Early (FIRE). By leveraging the collective efforts of a community of developers and personal finance enthusiasts, Ghostfolio continuously enhances its capabilities, security, and user experience. @@ -8631,6 +8931,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 26,36 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 26,36 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 26,36 + Let’s dive deeper into the detailed comparison table below to gain a thorough understanding of how Ghostfolio positions itself relative to . We will explore various aspects such as features, data privacy, pricing, and more, allowing you to make a well-informed choice for your personal requirements. @@ -8735,6 +9043,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 37,43 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 37,43 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 37,43 + Starting from / year @@ -8839,6 +9155,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 180,182 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 180,182 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 180,182 + Starting from / year @@ -8943,6 +9267,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 185,186 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 185,186 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 185,186 + open-source-alternative-to @@ -9059,6 +9391,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 199,208 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 199,208 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 199,208 + Ready to take your investments to the next level? @@ -9163,6 +9503,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 211,214 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 211,214 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 211,214 + Get Started @@ -9267,29 +9615,37 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 220,222 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 220,222 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 220,222 + Switzerland Switzerland apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 47 + 49 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 60 + 61 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 337 + 333 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 349 + 344 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 350 + 345 @@ -9297,7 +9653,7 @@ Global apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 49 + 51 apps/client/src/app/pages/resources/personal-finance-tools/products.ts @@ -9305,7 +9661,7 @@ apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 292 + 283 @@ -9313,31 +9669,31 @@ United States apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 71 + 80 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 108 + 114 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 167 + 168 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 194 + 193 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 196 + 195 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 266 + 259 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 278 + 270 @@ -9345,7 +9701,7 @@ Belgium apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 84 + 92 @@ -9353,19 +9709,23 @@ Germany apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 96 + 69 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 133 + 103 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 144 + 137 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 155 + 147 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 157 apps/client/src/app/pages/resources/personal-finance-tools/products.ts @@ -9373,7 +9733,7 @@ apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 218 + 215 @@ -9381,7 +9741,7 @@ Austria apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 120 + 125 @@ -9389,7 +9749,7 @@ Italy apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 230 + 226 @@ -9397,7 +9757,7 @@ Netherlands apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 241 + 236 @@ -9405,7 +9765,7 @@ Thailand apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 254 + 248 @@ -9413,7 +9773,7 @@ New Zealand apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 290 + 281 @@ -9421,11 +9781,11 @@ Czech Republic apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 302 + 292 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 325 + 322 @@ -9536,6 +9896,74 @@ 45 + + Add Tag + Add Tag + + apps/client/src/app/components/admin-tag/admin-tag.component.html + 11,13 + + + + Do you really want to delete this tag? + Do you really want to delete this tag? + + apps/client/src/app/components/admin-tag/admin-tag.component.ts + 76 + + + + Update tag + Update tag + + apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html + 2 + + + + Add tag + Add tag + + apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html + 3 + + + + France + France + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 303 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 312 + + + + Ghostfolio X-ray uses static analysis to identify potential issues and risks in your portfolio. + Ghostfolio X-ray uses static analysis to identify potential issues and risks in your portfolio. + + apps/client/src/app/pages/portfolio/fire/fire-page.html + 100,101 + + + + Currency Cluster Risks + Currency Cluster Risks + + apps/client/src/app/pages/portfolio/fire/fire-page.html + 111 + + + + Account Cluster Risks + Account Cluster Risks + + apps/client/src/app/pages/portfolio/fire/fire-page.html + 124 + + diff --git a/apps/client/src/locales/messages.it.xlf b/apps/client/src/locales/messages.it.xlf index 2740564e6..ae8834f0c 100644 --- a/apps/client/src/locales/messages.it.xlf +++ b/apps/client/src/locales/messages.it.xlf @@ -23,7 +23,7 @@ Il rischio di perdita nel trading può essere notevole. Non è consigliabile investire denaro di cui potresti avere bisogno a breve termine. apps/client/src/app/app.component.html - 172,173 + 174,175 @@ -101,6 +101,10 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html 88 + + apps/client/src/app/components/admin-tag/admin-tag.component.html + 44 + apps/client/src/app/components/admin-users/admin-users.html 23 @@ -129,6 +133,14 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html 7 + + apps/client/src/app/components/admin-tag/admin-tag.component.html + 30 + + + apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html + 7 + apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html 7 @@ -139,7 +151,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 208 + 171 libs/ui/src/lib/holdings-table/holdings-table.component.html @@ -199,11 +211,11 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 350 + 313 libs/ui/src/lib/activities-table/activities-table.component.html - 385 + 348 libs/ui/src/lib/holdings-table/holdings-table.component.html @@ -221,9 +233,13 @@ apps/client/src/app/components/admin-platform/admin-platform.component.html 90 + + apps/client/src/app/components/admin-tag/admin-tag.component.html + 70 + libs/ui/src/lib/activities-table/activities-table.component.html - 527 + 490 @@ -241,9 +257,13 @@ apps/client/src/app/components/admin-platform/admin-platform.component.html 94 + + apps/client/src/app/components/admin-tag/admin-tag.component.html + 74 + libs/ui/src/lib/activities-table/activities-table.component.html - 543 + 506 @@ -421,6 +441,10 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html 19 + + apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html + 13 + apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html 79 @@ -457,6 +481,10 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html 26 + + apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html + 20 + apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html 86 @@ -607,7 +635,7 @@ Messaggio di sistema apps/client/src/app/components/admin-overview/admin-overview.html - 109 + 96 @@ -615,7 +643,7 @@ Imposta messaggio apps/client/src/app/components/admin-overview/admin-overview.html - 131 + 118 @@ -623,7 +651,7 @@ Modalità di sola lettura apps/client/src/app/components/admin-overview/admin-overview.html - 99 + 86 @@ -631,7 +659,7 @@ Buoni sconto apps/client/src/app/components/admin-overview/admin-overview.html - 139 + 126 @@ -639,7 +667,7 @@ Aggiungi apps/client/src/app/components/admin-overview/admin-overview.html - 183 + 170 @@ -647,7 +675,7 @@ Bilancio domestico apps/client/src/app/components/admin-overview/admin-overview.html - 190 + 177 @@ -655,7 +683,7 @@ Svuota la cache apps/client/src/app/components/admin-overview/admin-overview.html - 194 + 181 @@ -909,6 +937,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 179 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 179 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 179 + About @@ -1236,6 +1272,10 @@ apps/client/src/app/pages/features/features-page.html 89 + + apps/client/src/app/pages/portfolio/fire/fire-page.html + 150 + Buying Power @@ -1325,8 +1365,8 @@ Tags Tag - apps/client/src/app/components/admin-overview/admin-overview.html - 79 + apps/client/src/app/components/admin-settings/admin-settings.component.html + 10 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -1552,6 +1592,10 @@ apps/client/src/app/pages/blog/2023/09/ghostfolio-2/ghostfolio-2-page.html 273 + + apps/client/src/app/pages/blog/2023/09/hacktoberfest-2023/hacktoberfest-2023-page.html + 181 + apps/client/src/app/pages/blog/blog-page.html 5 @@ -1654,7 +1698,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 416 + 379 @@ -1838,7 +1882,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 238 + 201 @@ -2210,7 +2254,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 259 + 222 @@ -2226,7 +2270,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 288 + 251 @@ -2242,7 +2286,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 317 + 280 @@ -2438,7 +2482,7 @@ Bozza libs/ui/src/lib/activities-table/activities-table.component.html - 218 + 181 @@ -2458,7 +2502,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 500 + 463 @@ -2470,7 +2514,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 510 + 473 @@ -2478,7 +2522,7 @@ Clona libs/ui/src/lib/activities-table/activities-table.component.html - 531 + 494 @@ -2486,7 +2530,7 @@ Esporta la bozza come ICS libs/ui/src/lib/activities-table/activities-table.component.html - 539 + 502 @@ -3282,7 +3326,7 @@ Registrazione utente apps/client/src/app/components/admin-overview/admin-overview.html - 89 + 76 @@ -3696,6 +3740,10 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html 148 + + apps/client/src/app/pages/portfolio/fire/fire-page.html + 137 + Portfolio Allocations @@ -3878,7 +3926,7 @@ Vuoi davvero eliminare tutte le tue attività? apps/client/src/app/pages/portfolio/activities/activities-page.component.ts - 142 + 140 @@ -4066,7 +4114,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 481 + 444 @@ -4078,7 +4126,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 490 + 453 @@ -4436,6 +4484,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 63 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 63 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 63 + Origin @@ -4540,6 +4596,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 68 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 68 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 68 + Region @@ -4644,6 +4708,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 73 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 73 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 73 + Available in @@ -4748,6 +4820,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 78,80 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 78,80 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 78,80 + ✅ Yes @@ -4852,6 +4932,18 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 100 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 100 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 100 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 107 + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 107 @@ -4952,6 +5044,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 107 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 107 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 121 + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 121 @@ -5052,6 +5152,18 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 121 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 121 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 132 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 132 + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 132 @@ -5252,6 +5364,22 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 146 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 146 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 146 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 153 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 153 + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 153 @@ -5452,6 +5580,22 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 165 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 165 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 165 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 172 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 172 + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 172 @@ -5656,6 +5800,18 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 102 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 102 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 102 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 125 + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 125 @@ -5756,6 +5912,18 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 125 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 125 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 136 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 136 + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 136 @@ -5956,6 +6124,22 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 148 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 148 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 148 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 155 @@ -6156,6 +6340,22 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 167 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 167 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 167 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 174 @@ -6360,6 +6560,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 109,110 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109,110 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109,110 + Self-Hosting @@ -6464,6 +6672,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 114,116 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 114,116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 114,116 + Use anonymously @@ -6568,6 +6784,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 141,143 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141,143 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141,143 + Free Plan @@ -6672,6 +6896,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 160,162 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 160,162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 160,162 + Notes @@ -6776,6 +7008,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 191 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + Effortlessly track, analyze, and visualize your wealth with Ghostfolio. @@ -6880,6 +7120,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 215,218 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 215,218 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 215,218 + Personal Finance Tools @@ -6984,6 +7232,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 287 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 287 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 287 + Guides @@ -7716,6 +7972,10 @@ apps/client/src/app/pages/resources/personal-finance-tools/products/altoo-page.component.ts 26 + + apps/client/src/app/pages/resources/personal-finance-tools/products/capmon-page.component.ts + 26 + apps/client/src/app/pages/resources/personal-finance-tools/products/copilot-money-page.component.ts 26 @@ -7800,6 +8060,10 @@ apps/client/src/app/pages/resources/personal-finance-tools/products/snowball-analytics-page.component.ts 26 + + apps/client/src/app/pages/resources/personal-finance-tools/products/stockmarketeye-page.component.ts + 26 + apps/client/src/app/pages/resources/personal-finance-tools/products/sumio-page.component.ts 26 @@ -7876,6 +8140,10 @@ apps/client/src/app/pages/blog/2023/09/ghostfolio-2/ghostfolio-2-page.component.ts 14 + + apps/client/src/app/pages/blog/2023/09/hacktoberfest-2023/hacktoberfest-2023-page.component.ts + 13 + apps/client/src/app/pages/landing/landing-page.component.ts 25 @@ -7888,6 +8156,10 @@ apps/client/src/app/pages/resources/personal-finance-tools/products/altoo-page.component.ts 25 + + apps/client/src/app/pages/resources/personal-finance-tools/products/capmon-page.component.ts + 25 + apps/client/src/app/pages/resources/personal-finance-tools/products/copilot-money-page.component.ts 25 @@ -7972,6 +8244,10 @@ apps/client/src/app/pages/resources/personal-finance-tools/products/snowball-analytics-page.component.ts 25 + + apps/client/src/app/pages/resources/personal-finance-tools/products/stockmarketeye-page.component.ts + 25 + apps/client/src/app/pages/resources/personal-finance-tools/products/sumio-page.component.ts 25 @@ -8188,6 +8464,10 @@ apps/client/src/app/pages/resources/personal-finance-tools/products/altoo-page.component.ts 28 + + apps/client/src/app/pages/resources/personal-finance-tools/products/capmon-page.component.ts + 28 + apps/client/src/app/pages/resources/personal-finance-tools/products/copilot-money-page.component.ts 28 @@ -8272,6 +8552,10 @@ apps/client/src/app/pages/resources/personal-finance-tools/products/snowball-analytics-page.component.ts 28 + + apps/client/src/app/pages/resources/personal-finance-tools/products/stockmarketeye-page.component.ts + 28 + apps/client/src/app/pages/resources/personal-finance-tools/products/sumio-page.component.ts 28 @@ -8424,6 +8708,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 8 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + Are you looking for an open source alternative to ? Ghostfolio is a powerful portfolio management tool that provides individuals with a comprehensive platform to track, analyze, and optimize their investments. Whether you are an experienced investor or just starting out, Ghostfolio offers an intuitive user interface and a wide range of functionalities to help you make informed decisions and take control of your financial future. @@ -8528,6 +8820,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 13,25 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13,25 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13,25 + Ghostfolio is an open source software (OSS), providing a cost-effective alternative to making it particularly suitable for individuals on a tight budget, such as those pursuing Financial Independence, Retire Early (FIRE). By leveraging the collective efforts of a community of developers and personal finance enthusiasts, Ghostfolio continuously enhances its capabilities, security, and user experience. @@ -8632,6 +8932,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 26,36 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 26,36 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 26,36 + Let’s dive deeper into the detailed comparison table below to gain a thorough understanding of how Ghostfolio positions itself relative to . We will explore various aspects such as features, data privacy, pricing, and more, allowing you to make a well-informed choice for your personal requirements. @@ -8736,6 +9044,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 37,43 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 37,43 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 37,43 + Starting from / year @@ -8840,6 +9156,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 180,182 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 180,182 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 180,182 + Starting from / year @@ -8944,6 +9268,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 185,186 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 185,186 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 185,186 + open-source-alternative-to @@ -9060,6 +9392,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 199,208 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 199,208 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 199,208 + Ready to take your investments to the next level? @@ -9164,6 +9504,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 211,214 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 211,214 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 211,214 + Get Started @@ -9268,29 +9616,37 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 220,222 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 220,222 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 220,222 + Switzerland Svizzera apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 47 + 49 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 60 + 61 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 337 + 333 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 349 + 344 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 350 + 345 @@ -9298,7 +9654,7 @@ Globale apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 49 + 51 apps/client/src/app/pages/resources/personal-finance-tools/products.ts @@ -9306,7 +9662,7 @@ apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 292 + 283 @@ -9314,31 +9670,31 @@ Stati Uniti apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 71 + 80 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 108 + 114 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 167 + 168 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 194 + 193 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 196 + 195 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 266 + 259 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 278 + 270 @@ -9346,7 +9702,7 @@ Belgio apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 84 + 92 @@ -9354,19 +9710,23 @@ Germania apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 96 + 69 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 133 + 103 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 144 + 137 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 155 + 147 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 157 apps/client/src/app/pages/resources/personal-finance-tools/products.ts @@ -9374,7 +9734,7 @@ apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 218 + 215 @@ -9382,7 +9742,7 @@ Austria apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 120 + 125 @@ -9390,7 +9750,7 @@ Italia apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 230 + 226 @@ -9398,7 +9758,7 @@ Paesi Bassi apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 241 + 236 @@ -9406,7 +9766,7 @@ Thailandia apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 254 + 248 @@ -9414,7 +9774,7 @@ Nuova Zelanda apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 290 + 281 @@ -9422,11 +9782,11 @@ Repubblica Ceca apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 302 + 292 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 325 + 322 @@ -9537,6 +9897,74 @@ 45 + + Add Tag + Add Tag + + apps/client/src/app/components/admin-tag/admin-tag.component.html + 11,13 + + + + Do you really want to delete this tag? + Do you really want to delete this tag? + + apps/client/src/app/components/admin-tag/admin-tag.component.ts + 76 + + + + Update tag + Update tag + + apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html + 2 + + + + Add tag + Add tag + + apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html + 3 + + + + France + France + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 303 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 312 + + + + Ghostfolio X-ray uses static analysis to identify potential issues and risks in your portfolio. + Ghostfolio X-ray uses static analysis to identify potential issues and risks in your portfolio. + + apps/client/src/app/pages/portfolio/fire/fire-page.html + 100,101 + + + + Currency Cluster Risks + Currency Cluster Risks + + apps/client/src/app/pages/portfolio/fire/fire-page.html + 111 + + + + Account Cluster Risks + Account Cluster Risks + + apps/client/src/app/pages/portfolio/fire/fire-page.html + 124 + + diff --git a/apps/client/src/locales/messages.nl.xlf b/apps/client/src/locales/messages.nl.xlf index a146eb5b9..f69216f63 100644 --- a/apps/client/src/locales/messages.nl.xlf +++ b/apps/client/src/locales/messages.nl.xlf @@ -22,7 +22,7 @@ Het risico op verlies bij handelen kan aanzienlijk zijn. Het is niet aan te raden om geld te investeren dat je misschien op korte termijn nodig heeft. apps/client/src/app/app.component.html - 172,173 + 174,175 @@ -100,6 +100,10 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html 88 + + apps/client/src/app/components/admin-tag/admin-tag.component.html + 44 + apps/client/src/app/components/admin-users/admin-users.html 23 @@ -128,6 +132,14 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html 7 + + apps/client/src/app/components/admin-tag/admin-tag.component.html + 30 + + + apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html + 7 + apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html 7 @@ -138,7 +150,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 208 + 171 libs/ui/src/lib/holdings-table/holdings-table.component.html @@ -198,11 +210,11 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 350 + 313 libs/ui/src/lib/activities-table/activities-table.component.html - 385 + 348 libs/ui/src/lib/holdings-table/holdings-table.component.html @@ -220,9 +232,13 @@ apps/client/src/app/components/admin-platform/admin-platform.component.html 90 + + apps/client/src/app/components/admin-tag/admin-tag.component.html + 70 + libs/ui/src/lib/activities-table/activities-table.component.html - 527 + 490 @@ -240,9 +256,13 @@ apps/client/src/app/components/admin-platform/admin-platform.component.html 94 + + apps/client/src/app/components/admin-tag/admin-tag.component.html + 74 + libs/ui/src/lib/activities-table/activities-table.component.html - 543 + 506 @@ -420,6 +440,10 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html 19 + + apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html + 13 + apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html 79 @@ -456,6 +480,10 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html 26 + + apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html + 20 + apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html 86 @@ -606,7 +634,7 @@ Systeembericht apps/client/src/app/components/admin-overview/admin-overview.html - 109 + 96 @@ -614,7 +642,7 @@ Bericht instellen apps/client/src/app/components/admin-overview/admin-overview.html - 131 + 118 @@ -622,7 +650,7 @@ Alleen lezen apps/client/src/app/components/admin-overview/admin-overview.html - 99 + 86 @@ -630,7 +658,7 @@ Coupons apps/client/src/app/components/admin-overview/admin-overview.html - 139 + 126 @@ -638,7 +666,7 @@ Toevoegen apps/client/src/app/components/admin-overview/admin-overview.html - 183 + 170 @@ -646,7 +674,7 @@ Huishouding apps/client/src/app/components/admin-overview/admin-overview.html - 190 + 177 @@ -654,7 +682,7 @@ Cache legen apps/client/src/app/components/admin-overview/admin-overview.html - 194 + 181 @@ -908,6 +936,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 179 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 179 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 179 + About @@ -1235,6 +1271,10 @@ apps/client/src/app/pages/features/features-page.html 89 + + apps/client/src/app/pages/portfolio/fire/fire-page.html + 150 + Buying Power @@ -1324,8 +1364,8 @@ Tags Tags - apps/client/src/app/components/admin-overview/admin-overview.html - 79 + apps/client/src/app/components/admin-settings/admin-settings.component.html + 10 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -1551,6 +1591,10 @@ apps/client/src/app/pages/blog/2023/09/ghostfolio-2/ghostfolio-2-page.html 273 + + apps/client/src/app/pages/blog/2023/09/hacktoberfest-2023/hacktoberfest-2023-page.html + 181 + apps/client/src/app/pages/blog/blog-page.html 5 @@ -1653,7 +1697,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 416 + 379 @@ -1837,7 +1881,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 238 + 201 @@ -2209,7 +2253,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 259 + 222 @@ -2225,7 +2269,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 288 + 251 @@ -2241,7 +2285,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 317 + 280 @@ -2437,7 +2481,7 @@ Concept libs/ui/src/lib/activities-table/activities-table.component.html - 218 + 181 @@ -2457,7 +2501,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 500 + 463 @@ -2469,7 +2513,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 510 + 473 @@ -2477,7 +2521,7 @@ Kloon libs/ui/src/lib/activities-table/activities-table.component.html - 531 + 494 @@ -2485,7 +2529,7 @@ Concept exporteren als ICS libs/ui/src/lib/activities-table/activities-table.component.html - 539 + 502 @@ -3281,7 +3325,7 @@ Account aanmaken apps/client/src/app/components/admin-overview/admin-overview.html - 89 + 76 @@ -3695,6 +3739,10 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html 148 + + apps/client/src/app/pages/portfolio/fire/fire-page.html + 137 + Portfolio Allocations @@ -3877,7 +3925,7 @@ Wil je echt al je activiteiten verwijderen? apps/client/src/app/pages/portfolio/activities/activities-page.component.ts - 142 + 140 @@ -4065,7 +4113,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 481 + 444 @@ -4077,7 +4125,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 490 + 453 @@ -4435,6 +4483,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 63 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 63 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 63 + Origin @@ -4539,6 +4595,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 68 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 68 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 68 + Region @@ -4643,6 +4707,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 73 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 73 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 73 + Available in @@ -4747,6 +4819,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 78,80 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 78,80 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 78,80 + ✅ Yes @@ -4851,6 +4931,18 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 100 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 100 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 100 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 107 + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 107 @@ -4951,6 +5043,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 107 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 107 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 121 + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 121 @@ -5051,6 +5151,18 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 121 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 121 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 132 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 132 + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 132 @@ -5251,6 +5363,22 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 146 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 146 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 146 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 153 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 153 + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 153 @@ -5451,6 +5579,22 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 165 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 165 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 165 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 172 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 172 + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 172 @@ -5655,6 +5799,18 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 102 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 102 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 102 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 125 + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 125 @@ -5755,6 +5911,18 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 125 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 125 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 136 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 136 + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 136 @@ -5955,6 +6123,22 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 148 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 148 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 148 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 155 @@ -6155,6 +6339,22 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 167 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 167 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 167 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 174 @@ -6359,6 +6559,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 109,110 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109,110 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109,110 + Self-Hosting @@ -6463,6 +6671,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 114,116 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 114,116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 114,116 + Use anonymously @@ -6567,6 +6783,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 141,143 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141,143 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141,143 + Free Plan @@ -6671,6 +6895,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 160,162 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 160,162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 160,162 + Notes @@ -6775,6 +7007,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 191 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + Effortlessly track, analyze, and visualize your wealth with Ghostfolio. @@ -6879,6 +7119,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 215,218 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 215,218 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 215,218 + Personal Finance Tools @@ -6983,6 +7231,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 287 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 287 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 287 + Guides @@ -7715,6 +7971,10 @@ apps/client/src/app/pages/resources/personal-finance-tools/products/altoo-page.component.ts 26 + + apps/client/src/app/pages/resources/personal-finance-tools/products/capmon-page.component.ts + 26 + apps/client/src/app/pages/resources/personal-finance-tools/products/copilot-money-page.component.ts 26 @@ -7799,6 +8059,10 @@ apps/client/src/app/pages/resources/personal-finance-tools/products/snowball-analytics-page.component.ts 26 + + apps/client/src/app/pages/resources/personal-finance-tools/products/stockmarketeye-page.component.ts + 26 + apps/client/src/app/pages/resources/personal-finance-tools/products/sumio-page.component.ts 26 @@ -7875,6 +8139,10 @@ apps/client/src/app/pages/blog/2023/09/ghostfolio-2/ghostfolio-2-page.component.ts 14 + + apps/client/src/app/pages/blog/2023/09/hacktoberfest-2023/hacktoberfest-2023-page.component.ts + 13 + apps/client/src/app/pages/landing/landing-page.component.ts 25 @@ -7887,6 +8155,10 @@ apps/client/src/app/pages/resources/personal-finance-tools/products/altoo-page.component.ts 25 + + apps/client/src/app/pages/resources/personal-finance-tools/products/capmon-page.component.ts + 25 + apps/client/src/app/pages/resources/personal-finance-tools/products/copilot-money-page.component.ts 25 @@ -7971,6 +8243,10 @@ apps/client/src/app/pages/resources/personal-finance-tools/products/snowball-analytics-page.component.ts 25 + + apps/client/src/app/pages/resources/personal-finance-tools/products/stockmarketeye-page.component.ts + 25 + apps/client/src/app/pages/resources/personal-finance-tools/products/sumio-page.component.ts 25 @@ -8187,6 +8463,10 @@ apps/client/src/app/pages/resources/personal-finance-tools/products/altoo-page.component.ts 28 + + apps/client/src/app/pages/resources/personal-finance-tools/products/capmon-page.component.ts + 28 + apps/client/src/app/pages/resources/personal-finance-tools/products/copilot-money-page.component.ts 28 @@ -8271,6 +8551,10 @@ apps/client/src/app/pages/resources/personal-finance-tools/products/snowball-analytics-page.component.ts 28 + + apps/client/src/app/pages/resources/personal-finance-tools/products/stockmarketeye-page.component.ts + 28 + apps/client/src/app/pages/resources/personal-finance-tools/products/sumio-page.component.ts 28 @@ -8423,6 +8707,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 8 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + Are you looking for an open source alternative to ? Ghostfolio is a powerful portfolio management tool that provides individuals with a comprehensive platform to track, analyze, and optimize their investments. Whether you are an experienced investor or just starting out, Ghostfolio offers an intuitive user interface and a wide range of functionalities to help you make informed decisions and take control of your financial future. @@ -8527,6 +8819,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 13,25 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13,25 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13,25 + Ghostfolio is an open source software (OSS), providing a cost-effective alternative to making it particularly suitable for individuals on a tight budget, such as those pursuing Financial Independence, Retire Early (FIRE). By leveraging the collective efforts of a community of developers and personal finance enthusiasts, Ghostfolio continuously enhances its capabilities, security, and user experience. @@ -8631,6 +8931,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 26,36 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 26,36 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 26,36 + Let’s dive deeper into the detailed comparison table below to gain a thorough understanding of how Ghostfolio positions itself relative to . We will explore various aspects such as features, data privacy, pricing, and more, allowing you to make a well-informed choice for your personal requirements. @@ -8735,6 +9043,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 37,43 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 37,43 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 37,43 + Starting from / year @@ -8839,6 +9155,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 180,182 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 180,182 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 180,182 + Starting from / year @@ -8943,6 +9267,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 185,186 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 185,186 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 185,186 + open-source-alternative-to @@ -9059,6 +9391,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 199,208 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 199,208 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 199,208 + Ready to take your investments to the next level? @@ -9163,6 +9503,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 211,214 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 211,214 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 211,214 + Get Started @@ -9267,29 +9615,37 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 220,222 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 220,222 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 220,222 + Switzerland Zwitserland apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 47 + 49 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 60 + 61 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 337 + 333 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 349 + 344 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 350 + 345 @@ -9297,7 +9653,7 @@ Wereldwijd apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 49 + 51 apps/client/src/app/pages/resources/personal-finance-tools/products.ts @@ -9305,7 +9661,7 @@ apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 292 + 283 @@ -9313,31 +9669,31 @@ Verenigde Staten apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 71 + 80 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 108 + 114 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 167 + 168 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 194 + 193 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 196 + 195 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 266 + 259 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 278 + 270 @@ -9345,7 +9701,7 @@ België apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 84 + 92 @@ -9353,19 +9709,23 @@ Duitsland apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 96 + 69 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 133 + 103 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 144 + 137 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 155 + 147 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 157 apps/client/src/app/pages/resources/personal-finance-tools/products.ts @@ -9373,7 +9733,7 @@ apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 218 + 215 @@ -9381,7 +9741,7 @@ Oostenrijk apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 120 + 125 @@ -9389,7 +9749,7 @@ Italië apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 230 + 226 @@ -9397,7 +9757,7 @@ Nederland apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 241 + 236 @@ -9405,7 +9765,7 @@ Thailand apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 254 + 248 @@ -9413,7 +9773,7 @@ Nieuw-Zeeland apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 290 + 281 @@ -9421,11 +9781,11 @@ Tsjechië apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 302 + 292 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 325 + 322 @@ -9536,6 +9896,74 @@ 45 + + Add Tag + Add Tag + + apps/client/src/app/components/admin-tag/admin-tag.component.html + 11,13 + + + + Do you really want to delete this tag? + Do you really want to delete this tag? + + apps/client/src/app/components/admin-tag/admin-tag.component.ts + 76 + + + + Update tag + Update tag + + apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html + 2 + + + + Add tag + Add tag + + apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html + 3 + + + + France + France + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 303 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 312 + + + + Ghostfolio X-ray uses static analysis to identify potential issues and risks in your portfolio. + Ghostfolio X-ray uses static analysis to identify potential issues and risks in your portfolio. + + apps/client/src/app/pages/portfolio/fire/fire-page.html + 100,101 + + + + Currency Cluster Risks + Currency Cluster Risks + + apps/client/src/app/pages/portfolio/fire/fire-page.html + 111 + + + + Account Cluster Risks + Account Cluster Risks + + apps/client/src/app/pages/portfolio/fire/fire-page.html + 124 + + diff --git a/apps/client/src/locales/messages.pt.xlf b/apps/client/src/locales/messages.pt.xlf index a9abda1af..19a8df179 100644 --- a/apps/client/src/locales/messages.pt.xlf +++ b/apps/client/src/locales/messages.pt.xlf @@ -6,7 +6,7 @@ O risco de perda em investimentos pode ser substancial. Não é aconselhável investir dinheiro que possa vir a precisar a curto prazo. apps/client/src/app/app.component.html - 172,173 + 174,175 @@ -112,6 +112,10 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html 88 + + apps/client/src/app/components/admin-tag/admin-tag.component.html + 44 + apps/client/src/app/components/admin-users/admin-users.html 23 @@ -140,6 +144,14 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html 7 + + apps/client/src/app/components/admin-tag/admin-tag.component.html + 30 + + + apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html + 7 + apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html 7 @@ -150,7 +162,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 208 + 171 libs/ui/src/lib/holdings-table/holdings-table.component.html @@ -190,7 +202,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 238 + 201 @@ -250,11 +262,11 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 350 + 313 libs/ui/src/lib/activities-table/activities-table.component.html - 385 + 348 libs/ui/src/lib/holdings-table/holdings-table.component.html @@ -272,9 +284,13 @@ apps/client/src/app/components/admin-platform/admin-platform.component.html 90 + + apps/client/src/app/components/admin-tag/admin-tag.component.html + 70 + libs/ui/src/lib/activities-table/activities-table.component.html - 527 + 490 @@ -292,9 +308,13 @@ apps/client/src/app/components/admin-platform/admin-platform.component.html 94 + + apps/client/src/app/components/admin-tag/admin-tag.component.html + 74 + libs/ui/src/lib/activities-table/activities-table.component.html - 543 + 506 @@ -472,6 +492,10 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html 19 + + apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html + 13 + apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html 79 @@ -508,6 +532,10 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html 26 + + apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html + 20 + apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html 86 @@ -722,7 +750,7 @@ Mensagem de Sistema apps/client/src/app/components/admin-overview/admin-overview.html - 109 + 96 @@ -730,7 +758,7 @@ Definir Mensagem apps/client/src/app/components/admin-overview/admin-overview.html - 131 + 118 @@ -738,7 +766,7 @@ Modo Somente Leitura apps/client/src/app/components/admin-overview/admin-overview.html - 99 + 86 @@ -746,7 +774,7 @@ Cupões apps/client/src/app/components/admin-overview/admin-overview.html - 139 + 126 @@ -754,7 +782,7 @@ Adicionar apps/client/src/app/components/admin-overview/admin-overview.html - 183 + 170 @@ -762,7 +790,7 @@ Manutenção apps/client/src/app/components/admin-overview/admin-overview.html - 190 + 177 @@ -770,7 +798,7 @@ Limpar Cache apps/client/src/app/components/admin-overview/admin-overview.html - 194 + 181 @@ -1068,6 +1096,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 179 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 179 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 179 + About @@ -1463,6 +1499,10 @@ apps/client/src/app/pages/features/features-page.html 89 + + apps/client/src/app/pages/portfolio/fire/fire-page.html + 150 + Buying Power @@ -1573,7 +1613,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 259 + 222 @@ -1652,8 +1692,8 @@ Tags Marcadores - apps/client/src/app/components/admin-overview/admin-overview.html - 79 + apps/client/src/app/components/admin-settings/admin-settings.component.html + 10 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -1909,7 +1949,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 416 + 379 @@ -2227,6 +2267,10 @@ apps/client/src/app/pages/blog/2023/09/ghostfolio-2/ghostfolio-2-page.html 273 + + apps/client/src/app/pages/blog/2023/09/hacktoberfest-2023/hacktoberfest-2023-page.html + 181 + apps/client/src/app/pages/blog/blog-page.html 5 @@ -2369,7 +2413,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 288 + 251 @@ -2385,7 +2429,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 317 + 280 @@ -2869,7 +2913,7 @@ Rascunho libs/ui/src/lib/activities-table/activities-table.component.html - 218 + 181 @@ -2889,7 +2933,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 500 + 463 @@ -2901,7 +2945,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 510 + 473 @@ -2909,7 +2953,7 @@ Clonar libs/ui/src/lib/activities-table/activities-table.component.html - 531 + 494 @@ -2917,7 +2961,7 @@ Exportar Rascunho como ICS libs/ui/src/lib/activities-table/activities-table.component.html - 539 + 502 @@ -3241,7 +3285,7 @@ Registo do Utilizador apps/client/src/app/components/admin-overview/admin-overview.html - 89 + 76 @@ -3695,6 +3739,10 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html 148 + + apps/client/src/app/pages/portfolio/fire/fire-page.html + 137 + Portfolio Allocations @@ -3877,7 +3925,7 @@ Deseja mesmo eliminar todas as suas atividades? apps/client/src/app/pages/portfolio/activities/activities-page.component.ts - 142 + 140 @@ -4065,7 +4113,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 481 + 444 @@ -4077,7 +4125,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 490 + 453 @@ -4435,6 +4483,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 63 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 63 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 63 + Origin @@ -4539,6 +4595,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 68 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 68 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 68 + Region @@ -4643,6 +4707,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 73 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 73 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 73 + Available in @@ -4747,6 +4819,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 78,80 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 78,80 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 78,80 + ✅ Yes @@ -4851,6 +4931,18 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 100 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 100 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 100 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 107 + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 107 @@ -4951,6 +5043,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 107 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 107 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 121 + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 121 @@ -5051,6 +5151,18 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 121 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 121 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 132 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 132 + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 132 @@ -5251,6 +5363,22 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 146 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 146 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 146 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 153 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 153 + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 153 @@ -5451,6 +5579,22 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 165 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 165 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 165 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 172 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 172 + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 172 @@ -5655,6 +5799,18 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 102 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 102 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 102 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 125 + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 125 @@ -5755,6 +5911,18 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 125 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 125 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 136 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 136 + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 136 @@ -5955,6 +6123,22 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 148 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 148 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 148 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 155 @@ -6155,6 +6339,22 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 167 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 167 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 167 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 174 @@ -6359,6 +6559,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 109,110 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109,110 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109,110 + Self-Hosting @@ -6463,6 +6671,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 114,116 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 114,116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 114,116 + Use anonymously @@ -6567,6 +6783,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 141,143 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141,143 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141,143 + Free Plan @@ -6671,6 +6895,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 160,162 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 160,162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 160,162 + Notes @@ -6775,6 +7007,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 191 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + Effortlessly track, analyze, and visualize your wealth with Ghostfolio. @@ -6879,6 +7119,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 215,218 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 215,218 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 215,218 + Personal Finance Tools @@ -6983,6 +7231,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 287 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 287 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 287 + Guides @@ -7715,6 +7971,10 @@ apps/client/src/app/pages/resources/personal-finance-tools/products/altoo-page.component.ts 26 + + apps/client/src/app/pages/resources/personal-finance-tools/products/capmon-page.component.ts + 26 + apps/client/src/app/pages/resources/personal-finance-tools/products/copilot-money-page.component.ts 26 @@ -7799,6 +8059,10 @@ apps/client/src/app/pages/resources/personal-finance-tools/products/snowball-analytics-page.component.ts 26 + + apps/client/src/app/pages/resources/personal-finance-tools/products/stockmarketeye-page.component.ts + 26 + apps/client/src/app/pages/resources/personal-finance-tools/products/sumio-page.component.ts 26 @@ -7875,6 +8139,10 @@ apps/client/src/app/pages/blog/2023/09/ghostfolio-2/ghostfolio-2-page.component.ts 14 + + apps/client/src/app/pages/blog/2023/09/hacktoberfest-2023/hacktoberfest-2023-page.component.ts + 13 + apps/client/src/app/pages/landing/landing-page.component.ts 25 @@ -7887,6 +8155,10 @@ apps/client/src/app/pages/resources/personal-finance-tools/products/altoo-page.component.ts 25 + + apps/client/src/app/pages/resources/personal-finance-tools/products/capmon-page.component.ts + 25 + apps/client/src/app/pages/resources/personal-finance-tools/products/copilot-money-page.component.ts 25 @@ -7971,6 +8243,10 @@ apps/client/src/app/pages/resources/personal-finance-tools/products/snowball-analytics-page.component.ts 25 + + apps/client/src/app/pages/resources/personal-finance-tools/products/stockmarketeye-page.component.ts + 25 + apps/client/src/app/pages/resources/personal-finance-tools/products/sumio-page.component.ts 25 @@ -8187,6 +8463,10 @@ apps/client/src/app/pages/resources/personal-finance-tools/products/altoo-page.component.ts 28 + + apps/client/src/app/pages/resources/personal-finance-tools/products/capmon-page.component.ts + 28 + apps/client/src/app/pages/resources/personal-finance-tools/products/copilot-money-page.component.ts 28 @@ -8271,6 +8551,10 @@ apps/client/src/app/pages/resources/personal-finance-tools/products/snowball-analytics-page.component.ts 28 + + apps/client/src/app/pages/resources/personal-finance-tools/products/stockmarketeye-page.component.ts + 28 + apps/client/src/app/pages/resources/personal-finance-tools/products/sumio-page.component.ts 28 @@ -8423,6 +8707,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 8 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + Are you looking for an open source alternative to ? Ghostfolio is a powerful portfolio management tool that provides individuals with a comprehensive platform to track, analyze, and optimize their investments. Whether you are an experienced investor or just starting out, Ghostfolio offers an intuitive user interface and a wide range of functionalities to help you make informed decisions and take control of your financial future. @@ -8527,6 +8819,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 13,25 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13,25 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13,25 + Ghostfolio is an open source software (OSS), providing a cost-effective alternative to making it particularly suitable for individuals on a tight budget, such as those pursuing Financial Independence, Retire Early (FIRE). By leveraging the collective efforts of a community of developers and personal finance enthusiasts, Ghostfolio continuously enhances its capabilities, security, and user experience. @@ -8631,6 +8931,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 26,36 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 26,36 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 26,36 + Let’s dive deeper into the detailed comparison table below to gain a thorough understanding of how Ghostfolio positions itself relative to . We will explore various aspects such as features, data privacy, pricing, and more, allowing you to make a well-informed choice for your personal requirements. @@ -8735,6 +9043,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 37,43 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 37,43 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 37,43 + Starting from / year @@ -8839,6 +9155,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 180,182 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 180,182 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 180,182 + Starting from / year @@ -8943,6 +9267,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 185,186 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 185,186 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 185,186 + open-source-alternative-to @@ -9059,6 +9391,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 199,208 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 199,208 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 199,208 + Ready to take your investments to the next level? @@ -9163,6 +9503,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 211,214 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 211,214 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 211,214 + Get Started @@ -9267,29 +9615,37 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 220,222 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 220,222 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 220,222 + Switzerland Switzerland apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 47 + 49 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 60 + 61 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 337 + 333 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 349 + 344 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 350 + 345 @@ -9297,7 +9653,7 @@ Global apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 49 + 51 apps/client/src/app/pages/resources/personal-finance-tools/products.ts @@ -9305,7 +9661,7 @@ apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 292 + 283 @@ -9313,31 +9669,31 @@ United States apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 71 + 80 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 108 + 114 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 167 + 168 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 194 + 193 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 196 + 195 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 266 + 259 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 278 + 270 @@ -9345,7 +9701,7 @@ Belgium apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 84 + 92 @@ -9353,19 +9709,23 @@ Germany apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 96 + 69 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 133 + 103 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 144 + 137 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 155 + 147 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 157 apps/client/src/app/pages/resources/personal-finance-tools/products.ts @@ -9373,7 +9733,7 @@ apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 218 + 215 @@ -9381,7 +9741,7 @@ Austria apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 120 + 125 @@ -9389,7 +9749,7 @@ Italy apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 230 + 226 @@ -9397,7 +9757,7 @@ Netherlands apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 241 + 236 @@ -9405,7 +9765,7 @@ Thailand apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 254 + 248 @@ -9413,7 +9773,7 @@ New Zealand apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 290 + 281 @@ -9421,11 +9781,11 @@ Czech Republic apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 302 + 292 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 325 + 322 @@ -9536,6 +9896,74 @@ 45 + + Add Tag + Add Tag + + apps/client/src/app/components/admin-tag/admin-tag.component.html + 11,13 + + + + Do you really want to delete this tag? + Do you really want to delete this tag? + + apps/client/src/app/components/admin-tag/admin-tag.component.ts + 76 + + + + Update tag + Update tag + + apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html + 2 + + + + Add tag + Add tag + + apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html + 3 + + + + France + France + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 303 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 312 + + + + Ghostfolio X-ray uses static analysis to identify potential issues and risks in your portfolio. + Ghostfolio X-ray uses static analysis to identify potential issues and risks in your portfolio. + + apps/client/src/app/pages/portfolio/fire/fire-page.html + 100,101 + + + + Currency Cluster Risks + Currency Cluster Risks + + apps/client/src/app/pages/portfolio/fire/fire-page.html + 111 + + + + Account Cluster Risks + Account Cluster Risks + + apps/client/src/app/pages/portfolio/fire/fire-page.html + 124 + + diff --git a/apps/client/src/locales/messages.tr.xlf b/apps/client/src/locales/messages.tr.xlf index 493726879..61cdc0972 100644 --- a/apps/client/src/locales/messages.tr.xlf +++ b/apps/client/src/locales/messages.tr.xlf @@ -64,6 +64,10 @@ apps/client/src/app/pages/blog/2023/09/ghostfolio-2/ghostfolio-2-page.component.ts 14 + + apps/client/src/app/pages/blog/2023/09/hacktoberfest-2023/hacktoberfest-2023-page.component.ts + 13 + apps/client/src/app/pages/landing/landing-page.component.ts 25 @@ -76,6 +80,10 @@ apps/client/src/app/pages/resources/personal-finance-tools/products/altoo-page.component.ts 25 + + apps/client/src/app/pages/resources/personal-finance-tools/products/capmon-page.component.ts + 25 + apps/client/src/app/pages/resources/personal-finance-tools/products/copilot-money-page.component.ts 25 @@ -160,6 +168,10 @@ apps/client/src/app/pages/resources/personal-finance-tools/products/snowball-analytics-page.component.ts 25 + + apps/client/src/app/pages/resources/personal-finance-tools/products/stockmarketeye-page.component.ts + 25 + apps/client/src/app/pages/resources/personal-finance-tools/products/sumio-page.component.ts 25 @@ -244,6 +256,10 @@ apps/client/src/app/pages/resources/personal-finance-tools/products/altoo-page.component.ts 26 + + apps/client/src/app/pages/resources/personal-finance-tools/products/capmon-page.component.ts + 26 + apps/client/src/app/pages/resources/personal-finance-tools/products/copilot-money-page.component.ts 26 @@ -328,6 +344,10 @@ apps/client/src/app/pages/resources/personal-finance-tools/products/snowball-analytics-page.component.ts 26 + + apps/client/src/app/pages/resources/personal-finance-tools/products/stockmarketeye-page.component.ts + 26 + apps/client/src/app/pages/resources/personal-finance-tools/products/sumio-page.component.ts 26 @@ -544,6 +564,10 @@ apps/client/src/app/pages/resources/personal-finance-tools/products/altoo-page.component.ts 28 + + apps/client/src/app/pages/resources/personal-finance-tools/products/capmon-page.component.ts + 28 + apps/client/src/app/pages/resources/personal-finance-tools/products/copilot-money-page.component.ts 28 @@ -628,6 +652,10 @@ apps/client/src/app/pages/resources/personal-finance-tools/products/snowball-analytics-page.component.ts 28 + + apps/client/src/app/pages/resources/personal-finance-tools/products/stockmarketeye-page.component.ts + 28 + apps/client/src/app/pages/resources/personal-finance-tools/products/sumio-page.component.ts 28 @@ -780,6 +808,10 @@ apps/client/src/app/pages/blog/2023/09/ghostfolio-2/ghostfolio-2-page.html 273 + + apps/client/src/app/pages/blog/2023/09/hacktoberfest-2023/hacktoberfest-2023-page.html + 181 + apps/client/src/app/pages/blog/blog-page.html 5 @@ -952,6 +984,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 179 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 179 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 179 + Privacy Policy @@ -1006,7 +1046,7 @@ Alım satımda kayıp riski büyük boyutta olabilir. Kısa vadede ihtiyaç duyabileceğiniz parayla yatırım yapmak tavsiye edilmez. apps/client/src/app/app.component.html - 172,173 + 174,175 @@ -1136,6 +1176,10 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html 88 + + apps/client/src/app/components/admin-tag/admin-tag.component.html + 44 + apps/client/src/app/components/admin-users/admin-users.html 23 @@ -1164,6 +1208,14 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html 7 + + apps/client/src/app/components/admin-tag/admin-tag.component.html + 30 + + + apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html + 7 + apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html 7 @@ -1174,7 +1226,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 208 + 171 libs/ui/src/lib/holdings-table/holdings-table.component.html @@ -1214,7 +1266,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 238 + 201 @@ -1258,11 +1310,11 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 350 + 313 libs/ui/src/lib/activities-table/activities-table.component.html - 385 + 348 libs/ui/src/lib/holdings-table/holdings-table.component.html @@ -1280,9 +1332,13 @@ apps/client/src/app/components/admin-platform/admin-platform.component.html 90 + + apps/client/src/app/components/admin-tag/admin-tag.component.html + 70 + libs/ui/src/lib/activities-table/activities-table.component.html - 527 + 490 @@ -1300,9 +1356,13 @@ apps/client/src/app/components/admin-platform/admin-platform.component.html 94 + + apps/client/src/app/components/admin-tag/admin-tag.component.html + 74 + libs/ui/src/lib/activities-table/activities-table.component.html - 543 + 506 @@ -1480,6 +1540,10 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html 19 + + apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html + 13 + apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html 79 @@ -1516,6 +1580,10 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html 26 + + apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html + 20 + apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html 86 @@ -1893,8 +1961,8 @@ Tags Etiketler - apps/client/src/app/components/admin-overview/admin-overview.html - 79 + apps/client/src/app/components/admin-settings/admin-settings.component.html + 10 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -1910,7 +1978,7 @@ Kullanıcı Kaydı apps/client/src/app/components/admin-overview/admin-overview.html - 89 + 76 @@ -1918,7 +1986,7 @@ Salt okunur mod apps/client/src/app/components/admin-overview/admin-overview.html - 99 + 86 @@ -1926,7 +1994,7 @@ Sistem Mesajı apps/client/src/app/components/admin-overview/admin-overview.html - 109 + 96 @@ -1934,7 +2002,7 @@ Mesaj Belirle apps/client/src/app/components/admin-overview/admin-overview.html - 131 + 118 @@ -1942,7 +2010,7 @@ Kupon apps/client/src/app/components/admin-overview/admin-overview.html - 139 + 126 @@ -1950,7 +2018,7 @@ Ekle apps/client/src/app/components/admin-overview/admin-overview.html - 183 + 170 @@ -1958,7 +2026,7 @@ Genel Ayarlar apps/client/src/app/components/admin-overview/admin-overview.html - 190 + 177 @@ -1966,7 +2034,7 @@ Önbelleği temizle apps/client/src/app/components/admin-overview/admin-overview.html - 194 + 181 @@ -2611,6 +2679,10 @@ apps/client/src/app/pages/features/features-page.html 89 + + apps/client/src/app/pages/portfolio/fire/fire-page.html + 150 + Cash @@ -2749,7 +2821,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 259 + 222 @@ -2763,6 +2835,10 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html 148 + + apps/client/src/app/pages/portfolio/fire/fire-page.html + 137 + First Buy Date @@ -3833,7 +3909,7 @@ Do you really want to delete all your activities? apps/client/src/app/pages/portfolio/activities/activities-page.component.ts - 142 + 140 @@ -3885,7 +3961,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 416 + 379 @@ -3909,7 +3985,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 288 + 251 @@ -3933,7 +4009,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 317 + 280 @@ -4871,6 +4947,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 8 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + Are you looking for an open source alternative to ? Ghostfolio is a powerful portfolio management tool that provides individuals with a comprehensive platform to track, analyze, and optimize their investments. Whether you are an experienced investor or just starting out, Ghostfolio offers an intuitive user interface and a wide range of functionalities to help you make informed decisions and take control of your financial future. @@ -4975,6 +5059,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 13,25 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13,25 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13,25 + Ghostfolio is an open source software (OSS), providing a cost-effective alternative to making it particularly suitable for individuals on a tight budget, such as those pursuing Financial Independence, Retire Early (FIRE). By leveraging the collective efforts of a community of developers and personal finance enthusiasts, Ghostfolio continuously enhances its capabilities, security, and user experience. @@ -5079,6 +5171,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 26,36 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 26,36 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 26,36 + Let’s dive deeper into the detailed comparison table below to gain a thorough understanding of how Ghostfolio positions itself relative to . We will explore various aspects such as features, data privacy, pricing, and more, allowing you to make a well-informed choice for your personal requirements. @@ -5183,6 +5283,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 37,43 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 37,43 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 37,43 + Founded @@ -5287,6 +5395,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 63 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 63 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 63 + Origin @@ -5391,6 +5507,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 68 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 68 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 68 + Region @@ -5495,6 +5619,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 73 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 73 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 73 + Available in @@ -5599,6 +5731,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 78,80 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 78,80 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 78,80 + ✅ Yes @@ -5703,6 +5843,18 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 100 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 100 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 100 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 107 + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 107 @@ -5803,6 +5955,18 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 107 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 107 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 121 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 121 + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 121 @@ -6003,6 +6167,22 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 132 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 132 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 132 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 146 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 146 + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 146 @@ -6203,6 +6383,18 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 153 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 153 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 153 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 165 + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 165 @@ -6303,6 +6495,18 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 165 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 165 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 172 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 172 + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 172 @@ -6507,6 +6711,22 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 102 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 102 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 102 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 125 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 125 + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 125 @@ -6707,6 +6927,22 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 136 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 136 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 136 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 148 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 148 + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 148 @@ -6907,6 +7143,18 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 155 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 167 + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 167 @@ -7007,6 +7255,18 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 167 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 167 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 174 @@ -7211,6 +7471,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 109,110 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109,110 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109,110 + Self-Hosting @@ -7315,6 +7583,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 114,116 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 114,116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 114,116 + Use anonymously @@ -7419,6 +7695,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 141,143 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141,143 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141,143 + Free Plan @@ -7523,6 +7807,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 160,162 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 160,162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 160,162 + Starting from / year @@ -7627,6 +7919,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 180,182 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 180,182 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 180,182 + Starting from / year @@ -7731,6 +8031,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 185,186 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 185,186 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 185,186 + Notes @@ -7835,6 +8143,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 191 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + Please note that the information provided is based on our independent research and analysis. This website is not affiliated with or any other product mentioned in the comparison. As the landscape of personal finance tools evolves, it is essential to verify any specific details or changes directly from the respective product page. Data needs a refresh? Help us maintain accurate data on GitHub. @@ -7939,6 +8255,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 199,208 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 199,208 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 199,208 + Ready to take your investments to the next level? @@ -8043,6 +8367,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 211,214 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 211,214 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 211,214 + Effortlessly track, analyze, and visualize your wealth with Ghostfolio. @@ -8147,6 +8479,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 215,218 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 215,218 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 215,218 + Get Started @@ -8251,6 +8591,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 220,222 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 220,222 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 220,222 + Personal Finance Tools @@ -8355,29 +8703,37 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 287 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 287 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 287 + Switzerland Switzerland apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 47 + 49 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 60 + 61 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 337 + 333 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 349 + 344 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 350 + 345 @@ -8385,7 +8741,7 @@ Global apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 49 + 51 apps/client/src/app/pages/resources/personal-finance-tools/products.ts @@ -8393,7 +8749,7 @@ apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 292 + 283 @@ -8401,31 +8757,31 @@ United States apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 71 + 80 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 108 + 114 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 167 + 168 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 194 + 193 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 196 + 195 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 266 + 259 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 278 + 270 @@ -8433,7 +8789,7 @@ Belgium apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 84 + 92 @@ -8441,19 +8797,23 @@ Germany apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 96 + 69 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 133 + 103 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 144 + 137 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 155 + 147 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 157 apps/client/src/app/pages/resources/personal-finance-tools/products.ts @@ -8461,7 +8821,7 @@ apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 218 + 215 @@ -8469,7 +8829,7 @@ Austria apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 120 + 125 @@ -8477,7 +8837,7 @@ Italy apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 230 + 226 @@ -8485,7 +8845,7 @@ Netherlands apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 241 + 236 @@ -8493,7 +8853,7 @@ Thailand apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 254 + 248 @@ -8501,7 +8861,7 @@ New Zealand apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 290 + 281 @@ -8509,11 +8869,11 @@ Czech Republic apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 302 + 292 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 325 + 322 @@ -8849,7 +9209,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 481 + 444 @@ -8861,7 +9221,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 490 + 453 @@ -8873,7 +9233,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 500 + 463 @@ -8885,7 +9245,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 510 + 473 @@ -8901,7 +9261,7 @@ Draft libs/ui/src/lib/activities-table/activities-table.component.html - 218 + 181 @@ -8909,7 +9269,7 @@ Clone libs/ui/src/lib/activities-table/activities-table.component.html - 531 + 494 @@ -8917,7 +9277,7 @@ Export Draft as ICS libs/ui/src/lib/activities-table/activities-table.component.html - 539 + 502 @@ -9536,6 +9896,74 @@ 32 + + Add Tag + Add Tag + + apps/client/src/app/components/admin-tag/admin-tag.component.html + 11,13 + + + + Do you really want to delete this tag? + Do you really want to delete this tag? + + apps/client/src/app/components/admin-tag/admin-tag.component.ts + 76 + + + + Update tag + Update tag + + apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html + 2 + + + + Add tag + Add tag + + apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html + 3 + + + + France + France + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 303 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 312 + + + + Ghostfolio X-ray uses static analysis to identify potential issues and risks in your portfolio. + Ghostfolio X-ray uses static analysis to identify potential issues and risks in your portfolio. + + apps/client/src/app/pages/portfolio/fire/fire-page.html + 100,101 + + + + Currency Cluster Risks + Currency Cluster Risks + + apps/client/src/app/pages/portfolio/fire/fire-page.html + 111 + + + + Account Cluster Risks + Account Cluster Risks + + apps/client/src/app/pages/portfolio/fire/fire-page.html + 124 + + diff --git a/apps/client/src/locales/messages.xlf b/apps/client/src/locales/messages.xlf index 5521bee63..956a2ad85 100644 --- a/apps/client/src/locales/messages.xlf +++ b/apps/client/src/locales/messages.xlf @@ -64,6 +64,10 @@ apps/client/src/app/pages/blog/2023/09/ghostfolio-2/ghostfolio-2-page.component.ts 14 + + apps/client/src/app/pages/blog/2023/09/hacktoberfest-2023/hacktoberfest-2023-page.component.ts + 13 + apps/client/src/app/pages/landing/landing-page.component.ts 25 @@ -76,6 +80,10 @@ apps/client/src/app/pages/resources/personal-finance-tools/products/altoo-page.component.ts 25 + + apps/client/src/app/pages/resources/personal-finance-tools/products/capmon-page.component.ts + 25 + apps/client/src/app/pages/resources/personal-finance-tools/products/copilot-money-page.component.ts 25 @@ -160,6 +168,10 @@ apps/client/src/app/pages/resources/personal-finance-tools/products/snowball-analytics-page.component.ts 25 + + apps/client/src/app/pages/resources/personal-finance-tools/products/stockmarketeye-page.component.ts + 25 + apps/client/src/app/pages/resources/personal-finance-tools/products/sumio-page.component.ts 25 @@ -242,6 +254,10 @@ apps/client/src/app/pages/resources/personal-finance-tools/products/altoo-page.component.ts 26 + + apps/client/src/app/pages/resources/personal-finance-tools/products/capmon-page.component.ts + 26 + apps/client/src/app/pages/resources/personal-finance-tools/products/copilot-money-page.component.ts 26 @@ -326,6 +342,10 @@ apps/client/src/app/pages/resources/personal-finance-tools/products/snowball-analytics-page.component.ts 26 + + apps/client/src/app/pages/resources/personal-finance-tools/products/stockmarketeye-page.component.ts + 26 + apps/client/src/app/pages/resources/personal-finance-tools/products/sumio-page.component.ts 26 @@ -536,6 +556,10 @@ apps/client/src/app/pages/resources/personal-finance-tools/products/altoo-page.component.ts 28 + + apps/client/src/app/pages/resources/personal-finance-tools/products/capmon-page.component.ts + 28 + apps/client/src/app/pages/resources/personal-finance-tools/products/copilot-money-page.component.ts 28 @@ -620,6 +644,10 @@ apps/client/src/app/pages/resources/personal-finance-tools/products/snowball-analytics-page.component.ts 28 + + apps/client/src/app/pages/resources/personal-finance-tools/products/stockmarketeye-page.component.ts + 28 + apps/client/src/app/pages/resources/personal-finance-tools/products/sumio-page.component.ts 28 @@ -767,6 +795,10 @@ apps/client/src/app/pages/blog/2023/09/ghostfolio-2/ghostfolio-2-page.html 273 + + apps/client/src/app/pages/blog/2023/09/hacktoberfest-2023/hacktoberfest-2023-page.html + 181 + apps/client/src/app/pages/blog/blog-page.html 5 @@ -934,6 +966,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 179 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 179 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 179 + Privacy Policy @@ -985,7 +1025,7 @@ The risk of loss in trading can be substantial. It is not advisable to invest money you may need in the short term. apps/client/src/app/app.component.html - 172,173 + 174,175 @@ -1105,6 +1145,10 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html 88 + + apps/client/src/app/components/admin-tag/admin-tag.component.html + 44 + apps/client/src/app/components/admin-users/admin-users.html 23 @@ -1132,6 +1176,14 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html 7 + + apps/client/src/app/components/admin-tag/admin-tag.component.html + 30 + + + apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html + 7 + apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html 7 @@ -1142,7 +1194,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 208 + 171 libs/ui/src/lib/holdings-table/holdings-table.component.html @@ -1180,7 +1232,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 238 + 201 @@ -1223,11 +1275,11 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 350 + 313 libs/ui/src/lib/activities-table/activities-table.component.html - 385 + 348 libs/ui/src/lib/holdings-table/holdings-table.component.html @@ -1244,9 +1296,13 @@ apps/client/src/app/components/admin-platform/admin-platform.component.html 90 + + apps/client/src/app/components/admin-tag/admin-tag.component.html + 70 + libs/ui/src/lib/activities-table/activities-table.component.html - 527 + 490 @@ -1263,9 +1319,13 @@ apps/client/src/app/components/admin-platform/admin-platform.component.html 94 + + apps/client/src/app/components/admin-tag/admin-tag.component.html + 74 + libs/ui/src/lib/activities-table/activities-table.component.html - 543 + 506 @@ -1426,6 +1486,10 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html 19 + + apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html + 13 + apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html 79 @@ -1461,6 +1525,10 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html 26 + + apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html + 20 + apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html 86 @@ -1801,8 +1869,8 @@ Tags - apps/client/src/app/components/admin-overview/admin-overview.html - 79 + apps/client/src/app/components/admin-settings/admin-settings.component.html + 10 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -1817,56 +1885,56 @@ User Signup apps/client/src/app/components/admin-overview/admin-overview.html - 89 + 76 Read-only Mode apps/client/src/app/components/admin-overview/admin-overview.html - 99 + 86 System Message apps/client/src/app/components/admin-overview/admin-overview.html - 109 + 96 Set Message apps/client/src/app/components/admin-overview/admin-overview.html - 131 + 118 Coupons apps/client/src/app/components/admin-overview/admin-overview.html - 139 + 126 Add apps/client/src/app/components/admin-overview/admin-overview.html - 183 + 170 Housekeeping apps/client/src/app/components/admin-overview/admin-overview.html - 190 + 177 Flush Cache apps/client/src/app/components/admin-overview/admin-overview.html - 194 + 181 @@ -2444,6 +2512,10 @@ apps/client/src/app/pages/features/features-page.html 89 + + apps/client/src/app/pages/portfolio/fire/fire-page.html + 150 + Cash @@ -2568,7 +2640,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 259 + 222 @@ -2581,6 +2653,10 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html 148 + + apps/client/src/app/pages/portfolio/fire/fire-page.html + 137 + First Buy Date @@ -3571,7 +3647,7 @@ Do you really want to delete all your activities? apps/client/src/app/pages/portfolio/activities/activities-page.component.ts - 142 + 140 @@ -3618,7 +3694,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 416 + 379 @@ -3640,7 +3716,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 288 + 251 @@ -3662,7 +3738,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 317 + 280 @@ -4520,6 +4596,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 8 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + Are you looking for an open source alternative to ? Ghostfolio is a powerful portfolio management tool that provides individuals with a comprehensive platform to track, analyze, and optimize their investments. Whether you are an experienced investor or just starting out, Ghostfolio offers an intuitive user interface and a wide range of functionalities to help you make informed decisions and take control of your financial future. @@ -4623,6 +4707,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 13,25 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13,25 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13,25 + Ghostfolio is an open source software (OSS), providing a cost-effective alternative to making it particularly suitable for individuals on a tight budget, such as those pursuing Financial Independence, Retire Early (FIRE). By leveraging the collective efforts of a community of developers and personal finance enthusiasts, Ghostfolio continuously enhances its capabilities, security, and user experience. @@ -4726,6 +4818,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 26,36 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 26,36 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 26,36 + Let’s dive deeper into the detailed comparison table below to gain a thorough understanding of how Ghostfolio positions itself relative to . We will explore various aspects such as features, data privacy, pricing, and more, allowing you to make a well-informed choice for your personal requirements. @@ -4829,6 +4929,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 37,43 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 37,43 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 37,43 + Founded @@ -4932,6 +5040,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 63 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 63 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 63 + Origin @@ -5035,6 +5151,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 68 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 68 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 68 + Region @@ -5138,6 +5262,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 73 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 73 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 73 + Available in @@ -5241,6 +5373,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 78,80 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 78,80 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 78,80 + ✅ Yes @@ -5344,6 +5484,18 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 100 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 100 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 100 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 107 + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 107 @@ -5444,6 +5596,18 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 107 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 107 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 121 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 121 + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 121 @@ -5644,6 +5808,22 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 132 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 132 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 132 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 146 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 146 + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 146 @@ -5844,6 +6024,18 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 153 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 153 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 153 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 165 + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 165 @@ -5944,6 +6136,18 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 165 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 165 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 172 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 172 + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 172 @@ -6147,6 +6351,22 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 102 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 102 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 102 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 125 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 125 + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 125 @@ -6347,6 +6567,22 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 136 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 136 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 136 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 148 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 148 + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 148 @@ -6547,6 +6783,18 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 155 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 167 + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 167 @@ -6647,6 +6895,18 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 167 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 167 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 174 @@ -6850,6 +7110,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 109,110 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109,110 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109,110 + Self-Hosting @@ -6953,6 +7221,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 114,116 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 114,116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 114,116 + Use anonymously @@ -7056,6 +7332,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 141,143 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141,143 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141,143 + Free Plan @@ -7159,6 +7443,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 160,162 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 160,162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 160,162 + Starting from / year @@ -7262,6 +7554,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 180,182 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 180,182 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 180,182 + Starting from / year @@ -7365,6 +7665,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 185,186 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 185,186 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 185,186 + Notes @@ -7468,6 +7776,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 191 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + Please note that the information provided is based on our independent research and analysis. This website is not affiliated with or any other product mentioned in the comparison. As the landscape of personal finance tools evolves, it is essential to verify any specific details or changes directly from the respective product page. Data needs a refresh? Help us maintain accurate data on GitHub. @@ -7571,6 +7887,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 199,208 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 199,208 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 199,208 + Ready to take your investments to the next level? @@ -7674,6 +7998,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 211,214 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 211,214 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 211,214 + Effortlessly track, analyze, and visualize your wealth with Ghostfolio. @@ -7777,6 +8109,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 215,218 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 215,218 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 215,218 + Get Started @@ -7880,6 +8220,14 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 220,222 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 220,222 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 220,222 + Personal Finance Tools @@ -7983,35 +8331,43 @@ apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 287 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 287 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 287 + Switzerland apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 47 + 49 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 60 + 61 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 337 + 333 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 349 + 344 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 350 + 345 Global apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 49 + 51 apps/client/src/app/pages/resources/personal-finance-tools/products.ts @@ -8019,64 +8375,68 @@ apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 292 + 283 United States apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 71 + 80 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 108 + 114 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 167 + 168 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 194 + 193 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 196 + 195 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 266 + 259 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 278 + 270 Belgium apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 84 + 92 Germany apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 96 + 69 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 133 + 103 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 144 + 137 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 155 + 147 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 157 apps/client/src/app/pages/resources/personal-finance-tools/products.ts @@ -8084,53 +8444,53 @@ apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 218 + 215 Austria apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 120 + 125 Italy apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 230 + 226 Netherlands apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 241 + 236 Thailand apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 254 + 248 New Zealand apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 290 + 281 Czech Republic apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 302 + 292 apps/client/src/app/pages/resources/personal-finance-tools/products.ts - 325 + 322 @@ -8414,7 +8774,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 481 + 444 @@ -8425,7 +8785,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 490 + 453 @@ -8436,7 +8796,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 500 + 463 @@ -8447,7 +8807,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 510 + 473 @@ -8461,21 +8821,21 @@ Draft libs/ui/src/lib/activities-table/activities-table.component.html - 218 + 181 Clone libs/ui/src/lib/activities-table/activities-table.component.html - 531 + 494 Export Draft as ICS libs/ui/src/lib/activities-table/activities-table.component.html - 539 + 502 @@ -8987,6 +9347,66 @@ 280 + + Add tag + + apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html + 3 + + + + Do you really want to delete this tag? + + apps/client/src/app/components/admin-tag/admin-tag.component.ts + 76 + + + + France + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 303 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 312 + + + + Update tag + + apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html + 2 + + + + Add Tag + + apps/client/src/app/components/admin-tag/admin-tag.component.html + 11,13 + + + + Ghostfolio X-ray uses static analysis to identify potential issues and risks in your portfolio. + + apps/client/src/app/pages/portfolio/fire/fire-page.html + 100,101 + + + + Currency Cluster Risks + + apps/client/src/app/pages/portfolio/fire/fire-page.html + 111 + + + + Account Cluster Risks + + apps/client/src/app/pages/portfolio/fire/fire-page.html + 124 + + diff --git a/apps/client/src/styles.scss b/apps/client/src/styles.scss index 5920df530..c5f8ffd0b 100644 --- a/apps/client/src/styles.scss +++ b/apps/client/src/styles.scss @@ -5,7 +5,7 @@ :root { --dark-background: rgb(25, 25, 25); - --font-family-sans-serif: Roboto, 'Helvetica Neue', sans-serif; + --font-family-sans-serif: 'Inter', Roboto, 'Helvetica Neue', sans-serif; --light-background: rgb(255, 255, 255); --dark-primary-text: 0, 0, 0, 0.87; diff --git a/libs/common/src/lib/interfaces/admin-data.interface.ts b/libs/common/src/lib/interfaces/admin-data.interface.ts index b66676346..68e1cbca4 100644 --- a/libs/common/src/lib/interfaces/admin-data.interface.ts +++ b/libs/common/src/lib/interfaces/admin-data.interface.ts @@ -12,4 +12,5 @@ export interface AdminData { lastActivity: Date; transactionCount: number; }[]; + version: string; } diff --git a/libs/common/src/lib/permissions.ts b/libs/common/src/lib/permissions.ts index 30bd627bc..0c2e8578e 100644 --- a/libs/common/src/lib/permissions.ts +++ b/libs/common/src/lib/permissions.ts @@ -7,12 +7,14 @@ export const permissions = { createAccount: 'createAccount', createOrder: 'createOrder', createPlatform: 'createPlatform', + createTag: 'createTag', createUserAccount: 'createUserAccount', deleteAccess: 'deleteAccess', deleteAccount: 'deleteAcccount', deleteAuthDevice: 'deleteAuthDevice', deleteOrder: 'deleteOrder', deletePlatform: 'deletePlatform', + deleteTag: 'deleteTag', deleteUser: 'deleteUser', enableFearAndGreedIndex: 'enableFearAndGreedIndex', enableImport: 'enableImport', @@ -29,6 +31,7 @@ export const permissions = { updateAuthDevice: 'updateAuthDevice', updateOrder: 'updateOrder', updatePlatform: 'updatePlatform', + updateTag: 'updateTag', updateUserSettings: 'updateUserSettings', updateViewMode: 'updateViewMode' }; @@ -42,16 +45,19 @@ export function getPermissions(aRole: Role): string[] { permissions.createAccount, permissions.createOrder, permissions.createPlatform, + permissions.createTag, permissions.deleteAccess, permissions.deleteAccount, permissions.deleteAuthDevice, permissions.deleteOrder, permissions.deletePlatform, + permissions.deleteTag, permissions.deleteUser, permissions.updateAccount, permissions.updateAuthDevice, permissions.updateOrder, permissions.updatePlatform, + permissions.updateTag, permissions.updateUserSettings, permissions.updateViewMode ]; diff --git a/package.json b/package.json index 48d83f597..2e2f81186 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ghostfolio", - "version": "2.5.0", + "version": "2.8.0", "homepage": "https://ghostfol.io", "license": "AGPL-3.0", "repository": "https://github.com/ghostfolio/ghostfolio", @@ -129,7 +129,7 @@ "svgmap": "2.6.0", "twitter-api-v2": "1.14.2", "uuid": "9.0.0", - "yahoo-finance2": "2.5.0", + "yahoo-finance2": "2.8.0", "zone.js": "0.13.1" }, "devDependencies": { @@ -189,11 +189,12 @@ "jest-preset-angular": "13.1.1", "nx": "16.7.4", "nx-cloud": "16.3.0", - "prettier": "3.0.2", + "prettier": "3.0.3", "prettier-plugin-organize-attributes": "1.0.0", "react": "18.2.0", "react-dom": "18.2.0", "replace-in-file": "7.0.1", + "shx": "0.3.4", "storybook": "7.0.9", "ts-jest": "29.1.0", "ts-node": "10.9.1", diff --git a/test/import/ok.csv b/test/import/ok.csv index 732ab4699..9f1f1c768 100644 --- a/test/import/ok.csv +++ b/test/import/ok.csv @@ -1,5 +1,5 @@ -Date,Code,Currency,Price,Quantity,Action,Fee -16-09-2021,MSFT,USD,298.580,5,buy,19.00 +Date,Code,Currency,Price,Quantity,Action,Fee,Note +16-09-2021,MSFT,USD,298.580,5,buy,19.00,My first order 🤓 17/11/2021,MSFT,USD,0.62,5,dividend,0.00 01.01.2022,Penthouse Apartment,USD,500000.0,1,item,0.00 20500606,MSFT,USD,0.00,0,buy,0.00 diff --git a/yarn.lock b/yarn.lock index ab4cd5f9d..69f995b5d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -14264,7 +14264,7 @@ minimatch@^9.0.0, minimatch@^9.0.1: dependencies: brace-expansion "^2.0.1" -minimist@^1.2.0, minimist@^1.2.5, minimist@^1.2.6: +minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.5, minimist@^1.2.6: version "1.2.8" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== @@ -15881,10 +15881,10 @@ prettier-plugin-organize-attributes@1.0.0: resolved "https://registry.yarnpkg.com/prettier-plugin-organize-attributes/-/prettier-plugin-organize-attributes-1.0.0.tgz#037870ee3111b3c1d6371f677b64888de353cc63" integrity sha512-+NmameaLxbCcylEXsKPmawtzla5EE6ECqvGkpfQz4KM847fXDifB1gFnPQEpoADAq6IXg+cMI8Z0ISJEXa6fhg== -prettier@3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.0.2.tgz#78fcecd6d870551aa5547437cdae39d4701dca5b" - integrity sha512-o2YR9qtniXvwEZlOKbveKfDQVyqxbEIWn48Z8m3ZJjBjcCmUy3xZGIv+7AkaeuaTr6yPXJjwv07ZWlsWbEy1rQ== +prettier@3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.0.3.tgz#432a51f7ba422d1469096c0fdc28e235db8f9643" + integrity sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg== prettier@^2.8.0: version "2.8.8" @@ -16984,6 +16984,14 @@ shelljs@^0.8.5: interpret "^1.0.0" rechoir "^0.6.2" +shx@0.3.4: + version "0.3.4" + resolved "https://registry.yarnpkg.com/shx/-/shx-0.3.4.tgz#74289230b4b663979167f94e1935901406e40f02" + integrity sha512-N6A9MLVqjxZYcVn8hLmtneQWIJtp8IKzMP4eMnx+nqkvXoqinUPCbUFLp2UcWTEIUONhlk0ewxr/jaVGlc+J+g== + dependencies: + minimist "^1.2.3" + shelljs "^0.8.5" + side-channel@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" @@ -17889,6 +17897,13 @@ toidentifier@1.0.1: resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== +tough-cookie-file-store@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/tough-cookie-file-store/-/tough-cookie-file-store-2.0.3.tgz#788f7a6fe5cd8f61a1afb71b2f0b964ebf914b80" + integrity sha512-sMpZVcmFf6EYFHFFl+SYH4W1/OnXBYMGDsv2IlbQ2caHyFElW/UR/gpj/KYU1JwmP4dE9xqwv2+vWcmlXHojSw== + dependencies: + tough-cookie "^4.0.0" + tough-cookie@^4.0.0, tough-cookie@^4.1.2: version "4.1.3" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.1.3.tgz#97b9adb0728b42280aa3d814b6b999b2ff0318bf" @@ -19035,16 +19050,17 @@ y18n@^5.0.5: resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== -yahoo-finance2@2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/yahoo-finance2/-/yahoo-finance2-2.5.0.tgz#847834b33d24dc8ce96357401aba7dae1bcfda9f" - integrity sha512-YTniHzTx17lrs7tUonFZMWvY0dF4UJSrPkrTNMqNrb+la7Nde/5KY7mQFf+8VdXhngPup2V9ex27M2WK3ADtbw== +yahoo-finance2@2.8.0: + version "2.8.0" + resolved "https://registry.yarnpkg.com/yahoo-finance2/-/yahoo-finance2-2.8.0.tgz#c1c1d139d6d16ff3e105af6269e6c869724ac16d" + integrity sha512-8KupoZQEBb+nynDXcOinYdrQ0anPjrX1wQQ8ehVOGZUGMW73fR2YznxumRlVyqSw9J9clS7eS8UhjcOUecmKUA== dependencies: "@types/tough-cookie" "^4.0.2" ajv "8.10.0" ajv-formats "2.1.1" node-fetch "^2.6.1" tough-cookie "^4.1.2" + tough-cookie-file-store "^2.0.3" yallist@^3.0.2: version "3.1.1"