From 68a9a7f6f9b34ec71a2e645610d6fa530fd5e30b Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sat, 15 Jul 2023 17:54:16 +0200 Subject: [PATCH 1/7] Feature/add queries to market data table in admin control (#2153) * Add queries * ETF_WITHOUT_COUNTRIES * ETF_WITHOUT_SECTORS * Update changelog --- CHANGELOG.md | 1 + apps/api/src/app/admin/admin.controller.ts | 7 +- apps/api/src/app/admin/admin.service.ts | 96 ++++++++++++------- .../admin-market-data.component.ts | 33 +++++-- apps/client/src/app/services/admin.service.ts | 4 +- apps/client/src/app/services/data.service.ts | 5 + .../src/lib/interfaces/filter.interface.ts | 8 +- libs/common/src/lib/types/index.ts | 2 + .../src/lib/types/market-data-query.type.ts | 1 + libs/ui/src/lib/i18n.ts | 1 + 10 files changed, 113 insertions(+), 45 deletions(-) create mode 100644 libs/common/src/lib/types/market-data-query.type.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 646b2805e..074737a6c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Added hints to the activity types in the create or edit activity dialog +- Added queries to the historical market data table of the admin control panel ### Changed diff --git a/apps/api/src/app/admin/admin.controller.ts b/apps/api/src/app/admin/admin.controller.ts index 75b2b2bb9..6077c19f8 100644 --- a/apps/api/src/app/admin/admin.controller.ts +++ b/apps/api/src/app/admin/admin.controller.ts @@ -15,7 +15,10 @@ import { Filter } from '@ghostfolio/common/interfaces'; import { hasPermission, permissions } from '@ghostfolio/common/permissions'; -import type { RequestWithUser } from '@ghostfolio/common/types'; +import type { + MarketDataQuery, + RequestWithUser +} from '@ghostfolio/common/types'; import { Body, Controller, @@ -249,6 +252,7 @@ export class AdminController { @UseGuards(AuthGuard('jwt')) public async getMarketData( @Query('assetSubClasses') filterByAssetSubClasses?: string, + @Query('queryId') queryId?: MarketDataQuery, @Query('skip') skip?: number, @Query('sortColumn') sortColumn?: string, @Query('sortDirection') sortDirection?: Prisma.SortOrder, @@ -279,6 +283,7 @@ export class AdminController { return this.adminService.getMarketData({ filters, + queryId, sortColumn, sortDirection, skip: isNaN(skip) ? undefined : skip, diff --git a/apps/api/src/app/admin/admin.service.ts b/apps/api/src/app/admin/admin.service.ts index 4dce77982..003f930b2 100644 --- a/apps/api/src/app/admin/admin.service.ts +++ b/apps/api/src/app/admin/admin.service.ts @@ -17,6 +17,7 @@ import { Filter, UniqueAsset } from '@ghostfolio/common/interfaces'; +import { MarketDataQuery } from '@ghostfolio/common/types'; import { BadRequestException, Injectable } from '@nestjs/common'; import { AssetSubClass, Prisma, Property, SymbolProfile } from '@prisma/client'; import { differenceInDays } from 'date-fns'; @@ -103,12 +104,14 @@ export class AdminService { public async getMarketData({ filters, + queryId, sortColumn, sortDirection, skip, - take = DEFAULT_PAGE_SIZE + take = Number.MAX_SAFE_INTEGER }: { filters?: Filter[]; + queryId?: MarketDataQuery; skip?: number; sortColumn?: string; sortDirection?: Prisma.SortOrder; @@ -118,6 +121,13 @@ export class AdminService { [{ symbol: 'asc' }]; const where: Prisma.SymbolProfileWhereInput = {}; + if ( + queryId === 'ETF_WITHOUT_COUNTRIES' || + queryId === 'ETF_WITHOUT_SECTORS' + ) { + filters = [{ id: 'ETF', type: 'ASSET_SUB_CLASS' }]; + } + const { ASSET_SUB_CLASS: filtersByAssetSubClass } = groupBy( filters, (filter) => { @@ -146,7 +156,7 @@ export class AdminService { } } - const [assetProfiles, count] = await Promise.all([ + let [assetProfiles, count] = await Promise.all([ this.prismaService.symbolProfile.findMany({ orderBy, skip, @@ -174,44 +184,60 @@ export class AdminService { this.prismaService.symbolProfile.count({ where }) ]); - return { - count, - marketData: assetProfiles.map( - ({ - _count, + let marketData = assetProfiles.map( + ({ + _count, + assetClass, + assetSubClass, + comment, + countries, + dataSource, + Order, + sectors, + symbol + }) => { + const countriesCount = countries ? Object.keys(countries).length : 0; + const marketDataItemCount = + marketDataItems.find((marketDataItem) => { + return ( + marketDataItem.dataSource === dataSource && + marketDataItem.symbol === symbol + ); + })?._count ?? 0; + const sectorsCount = sectors ? Object.keys(sectors).length : 0; + + return { assetClass, assetSubClass, comment, - countries, + countriesCount, dataSource, - Order, - sectors, - symbol - }) => { - const countriesCount = countries ? Object.keys(countries).length : 0; - const marketDataItemCount = - marketDataItems.find((marketDataItem) => { - return ( - marketDataItem.dataSource === dataSource && - marketDataItem.symbol === symbol - ); - })?._count ?? 0; - const sectorsCount = sectors ? Object.keys(sectors).length : 0; + symbol, + marketDataItemCount, + sectorsCount, + activitiesCount: _count.Order, + date: Order?.[0]?.date + }; + } + ); - return { - assetClass, - assetSubClass, - comment, - countriesCount, - dataSource, - symbol, - marketDataItemCount, - sectorsCount, - activitiesCount: _count.Order, - date: Order?.[0]?.date - }; - } - ) + if (queryId) { + if (queryId === 'ETF_WITHOUT_COUNTRIES') { + marketData = marketData.filter(({ countriesCount }) => { + return countriesCount === 0; + }); + } else if (queryId === 'ETF_WITHOUT_SECTORS') { + marketData = marketData.filter(({ sectorsCount }) => { + return sectorsCount === 0; + }); + } + + count = marketData.length; + } + + return { + count, + marketData }; } diff --git a/apps/client/src/app/components/admin-market-data/admin-market-data.component.ts b/apps/client/src/app/components/admin-market-data/admin-market-data.component.ts index 37c7a666a..716b5ff3d 100644 --- a/apps/client/src/app/components/admin-market-data/admin-market-data.component.ts +++ b/apps/client/src/app/components/admin-market-data/admin-market-data.component.ts @@ -51,13 +51,26 @@ export class AdminMarketDataComponent AssetSubClass.PRECIOUS_METAL, AssetSubClass.PRIVATE_EQUITY, AssetSubClass.STOCK - ].map((assetSubClass) => { - return { - id: assetSubClass, - label: translate(assetSubClass), - type: 'ASSET_SUB_CLASS' - }; - }); + ] + .map((assetSubClass) => { + return { + id: assetSubClass.toString(), + label: translate(assetSubClass), + type: 'ASSET_SUB_CLASS' + }; + }) + .concat([ + { + id: 'ETF_WITHOUT_COUNTRIES', + label: $localize`ETFs without Countries`, + type: 'QUERY_ID' + }, + { + id: 'ETF_WITHOUT_SECTORS', + label: $localize`ETFs without Sectors`, + type: 'QUERY_ID' + } + ]); public currentDataSource: DataSource; public currentSymbol: string; public dataSource: MatTableDataSource = @@ -237,6 +250,12 @@ export class AdminMarketDataComponent ) { this.isLoading = true; + this.pageSize = + this.activeFilters.length === 1 && + this.activeFilters[0].type === 'QUERY_ID' + ? undefined + : DEFAULT_PAGE_SIZE; + if (pageIndex === 0 && this.paginator) { this.paginator.pageIndex = 0; } diff --git a/apps/client/src/app/services/admin.service.ts b/apps/client/src/app/services/admin.service.ts index d1967aaf4..3f72ff01d 100644 --- a/apps/client/src/app/services/admin.service.ts +++ b/apps/client/src/app/services/admin.service.ts @@ -95,7 +95,9 @@ export class AdminService { params = params.append('sortDirection', sortDirection); } - params = params.append('take', take); + if (take) { + params = params.append('take', take); + } return this.http.get('/api/v1/admin/market-data', { params diff --git a/apps/client/src/app/services/data.service.ts b/apps/client/src/app/services/data.service.ts index f2e5169db..99416ae57 100644 --- a/apps/client/src/app/services/data.service.ts +++ b/apps/client/src/app/services/data.service.ts @@ -57,6 +57,7 @@ export class DataService { ACCOUNT: filtersByAccount, ASSET_CLASS: filtersByAssetClass, ASSET_SUB_CLASS: filtersByAssetSubClass, + QUERY_ID: filtersByQueryId, TAG: filtersByTag } = groupBy(filters, (filter) => { return filter.type; @@ -95,6 +96,10 @@ export class DataService { ); } + if (filtersByQueryId) { + params = params.append('queryId', filtersByQueryId[0].id); + } + if (filtersByTag) { params = params.append( 'tags', diff --git a/libs/common/src/lib/interfaces/filter.interface.ts b/libs/common/src/lib/interfaces/filter.interface.ts index 6695de883..f6c83a230 100644 --- a/libs/common/src/lib/interfaces/filter.interface.ts +++ b/libs/common/src/lib/interfaces/filter.interface.ts @@ -1,5 +1,11 @@ export interface Filter { id: string; label?: string; - type: 'ACCOUNT' | 'ASSET_CLASS' | 'ASSET_SUB_CLASS' | 'SYMBOL' | 'TAG'; + type: + | 'ACCOUNT' + | 'ASSET_CLASS' + | 'ASSET_SUB_CLASS' + | 'QUERY_ID' + | 'SYMBOL' + | 'TAG'; } diff --git a/libs/common/src/lib/types/index.ts b/libs/common/src/lib/types/index.ts index dc6f154dc..79566bcfd 100644 --- a/libs/common/src/lib/types/index.ts +++ b/libs/common/src/lib/types/index.ts @@ -5,6 +5,7 @@ import type { ColorScheme } from './color-scheme.type'; import type { DateRange } from './date-range.type'; import type { Granularity } from './granularity.type'; import type { GroupBy } from './group-by.type'; +import type { MarketDataQuery } from './market-data-query.type'; import type { MarketState } from './market-state.type'; import type { Market } from './market.type'; import type { OrderWithAccount } from './order-with-account.type'; @@ -23,6 +24,7 @@ export type { Granularity, GroupBy, Market, + MarketDataQuery, MarketState, OrderWithAccount, RequestWithUser, diff --git a/libs/common/src/lib/types/market-data-query.type.ts b/libs/common/src/lib/types/market-data-query.type.ts new file mode 100644 index 000000000..fa14af61c --- /dev/null +++ b/libs/common/src/lib/types/market-data-query.type.ts @@ -0,0 +1 @@ +export type MarketDataQuery = 'ETF_WITHOUT_COUNTRIES' | 'ETF_WITHOUT_SECTORS'; diff --git a/libs/ui/src/lib/i18n.ts b/libs/ui/src/lib/i18n.ts index 38d92e5f1..cd8794979 100644 --- a/libs/ui/src/lib/i18n.ts +++ b/libs/ui/src/lib/i18n.ts @@ -16,6 +16,7 @@ const locales = { MONTH: $localize`Month`, MONTHS: $localize`Months`, OTHER: $localize`Other`, + QUERY_ID: $localize`Query`, RETIREMENT_PROVISION: $localize`Retirement Provision`, SATELLITE: $localize`Satellite`, SECURITIES: $localize`Securities`, From 4857b2e620233a28719279a8f3fd31cfd201c791 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sat, 15 Jul 2023 19:50:11 +0200 Subject: [PATCH 2/7] Update locales (#2154) --- apps/client/src/locales/messages.de.xlf | 86 +++++++++++++++--------- apps/client/src/locales/messages.es.xlf | 86 +++++++++++++++--------- apps/client/src/locales/messages.fr.xlf | 86 +++++++++++++++--------- apps/client/src/locales/messages.it.xlf | 86 +++++++++++++++--------- apps/client/src/locales/messages.nl.xlf | 88 ++++++++++++++++--------- apps/client/src/locales/messages.pt.xlf | 86 +++++++++++++++--------- apps/client/src/locales/messages.xlf | 83 ++++++++++++++--------- 7 files changed, 383 insertions(+), 218 deletions(-) diff --git a/apps/client/src/locales/messages.de.xlf b/apps/client/src/locales/messages.de.xlf index 3e6aa805e..a74016261 100644 --- a/apps/client/src/locales/messages.de.xlf +++ b/apps/client/src/locales/messages.de.xlf @@ -2142,7 +2142,7 @@ Verkauf libs/ui/src/lib/i18n.ts - 32 + 33 @@ -2766,7 +2766,7 @@ Filtern nach... apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 245 + 264 @@ -2946,7 +2946,7 @@ Symbol libs/ui/src/lib/i18n.ts - 22 + 23 @@ -2954,7 +2954,7 @@ Tag libs/ui/src/lib/i18n.ts - 23 + 24 @@ -2962,7 +2962,7 @@ Bargeld libs/ui/src/lib/i18n.ts - 35 + 36 @@ -2970,7 +2970,7 @@ Rohstoff libs/ui/src/lib/i18n.ts - 36 + 37 @@ -2978,7 +2978,7 @@ Beteiligungskapital libs/ui/src/lib/i18n.ts - 37 + 38 @@ -2986,7 +2986,7 @@ Feste Einkünfte libs/ui/src/lib/i18n.ts - 38 + 39 @@ -2994,7 +2994,7 @@ Immobilien libs/ui/src/lib/i18n.ts - 39 + 40 @@ -3002,7 +3002,7 @@ Anleihe libs/ui/src/lib/i18n.ts - 42 + 43 @@ -3010,7 +3010,7 @@ Kryptowährung libs/ui/src/lib/i18n.ts - 43 + 44 @@ -3018,7 +3018,7 @@ ETF libs/ui/src/lib/i18n.ts - 44 + 45 @@ -3026,7 +3026,7 @@ Investmentfonds libs/ui/src/lib/i18n.ts - 45 + 46 @@ -3034,7 +3034,7 @@ Edelmetall libs/ui/src/lib/i18n.ts - 46 + 47 @@ -3042,7 +3042,7 @@ Privates Beteiligungskapital libs/ui/src/lib/i18n.ts - 47 + 48 @@ -3050,7 +3050,7 @@ Aktie libs/ui/src/lib/i18n.ts - 48 + 49 @@ -3090,7 +3090,7 @@ Nordamerika libs/ui/src/lib/i18n.ts - 54 + 55 @@ -3098,7 +3098,7 @@ Afrika libs/ui/src/lib/i18n.ts - 51 + 52 @@ -3106,7 +3106,7 @@ Asien libs/ui/src/lib/i18n.ts - 52 + 53 @@ -3114,7 +3114,7 @@ Europa libs/ui/src/lib/i18n.ts - 53 + 54 @@ -3122,7 +3122,7 @@ Ozeanien libs/ui/src/lib/i18n.ts - 55 + 56 @@ -3130,7 +3130,7 @@ Südamerika libs/ui/src/lib/i18n.ts - 56 + 57 @@ -3234,7 +3234,7 @@ libs/ui/src/lib/i18n.ts - 29 + 30 @@ -3278,7 +3278,7 @@ Wertschriften libs/ui/src/lib/i18n.ts - 21 + 22 @@ -3406,7 +3406,7 @@ Altersvorsorge libs/ui/src/lib/i18n.ts - 19 + 20 @@ -3414,7 +3414,7 @@ Satellit libs/ui/src/lib/i18n.ts - 20 + 21 @@ -4102,7 +4102,7 @@ Jahre libs/ui/src/lib/i18n.ts - 25 + 26 @@ -4118,7 +4118,7 @@ Jahr libs/ui/src/lib/i18n.ts - 24 + 25 @@ -4274,7 +4274,7 @@ Verbindlichkeit libs/ui/src/lib/i18n.ts - 31 + 32 @@ -6906,7 +6906,7 @@ Kauf libs/ui/src/lib/i18n.ts - 28 + 29 @@ -6914,7 +6914,31 @@ Wertsache libs/ui/src/lib/i18n.ts - 30 + 31 + + + + ETFs without Countries + ETFs ohne Länder + + apps/client/src/app/components/admin-market-data/admin-market-data.component.ts + 65 + + + + ETFs without Sectors + ETFs ohne Sektoren + + apps/client/src/app/components/admin-market-data/admin-market-data.component.ts + 70 + + + + Query + Suchanfrage + + libs/ui/src/lib/i18n.ts + 19 diff --git a/apps/client/src/locales/messages.es.xlf b/apps/client/src/locales/messages.es.xlf index 463e465d9..25a0a9a07 100644 --- a/apps/client/src/locales/messages.es.xlf +++ b/apps/client/src/locales/messages.es.xlf @@ -2143,7 +2143,7 @@ Venta libs/ui/src/lib/i18n.ts - 32 + 33 @@ -2783,7 +2783,7 @@ Filtrar por... apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 245 + 264 @@ -2947,7 +2947,7 @@ Símbolo libs/ui/src/lib/i18n.ts - 22 + 23 @@ -2955,7 +2955,7 @@ Etiqueta libs/ui/src/lib/i18n.ts - 23 + 24 @@ -2963,7 +2963,7 @@ Efectivo libs/ui/src/lib/i18n.ts - 35 + 36 @@ -2971,7 +2971,7 @@ Bien libs/ui/src/lib/i18n.ts - 36 + 37 @@ -2979,7 +2979,7 @@ Capital libs/ui/src/lib/i18n.ts - 37 + 38 @@ -2987,7 +2987,7 @@ Renta fija libs/ui/src/lib/i18n.ts - 38 + 39 @@ -2995,7 +2995,7 @@ Propiedad inmobiliaria libs/ui/src/lib/i18n.ts - 39 + 40 @@ -3003,7 +3003,7 @@ Bono libs/ui/src/lib/i18n.ts - 42 + 43 @@ -3011,7 +3011,7 @@ Criptomoneda libs/ui/src/lib/i18n.ts - 43 + 44 @@ -3019,7 +3019,7 @@ ETF libs/ui/src/lib/i18n.ts - 44 + 45 @@ -3027,7 +3027,7 @@ Fondo de inversión libs/ui/src/lib/i18n.ts - 45 + 46 @@ -3035,7 +3035,7 @@ Metal precioso libs/ui/src/lib/i18n.ts - 46 + 47 @@ -3043,7 +3043,7 @@ Capital riesgo libs/ui/src/lib/i18n.ts - 47 + 48 @@ -3051,7 +3051,7 @@ Acción libs/ui/src/lib/i18n.ts - 48 + 49 @@ -3091,7 +3091,7 @@ América del Norte libs/ui/src/lib/i18n.ts - 54 + 55 @@ -3099,7 +3099,7 @@ África libs/ui/src/lib/i18n.ts - 51 + 52 @@ -3107,7 +3107,7 @@ Asia libs/ui/src/lib/i18n.ts - 52 + 53 @@ -3115,7 +3115,7 @@ Europa libs/ui/src/lib/i18n.ts - 53 + 54 @@ -3123,7 +3123,7 @@ Oceanía libs/ui/src/lib/i18n.ts - 55 + 56 @@ -3131,7 +3131,7 @@ América del Sur libs/ui/src/lib/i18n.ts - 56 + 57 @@ -3227,7 +3227,7 @@ libs/ui/src/lib/i18n.ts - 29 + 30 @@ -3279,7 +3279,7 @@ Securities libs/ui/src/lib/i18n.ts - 21 + 22 @@ -3407,7 +3407,7 @@ Retirement Provision libs/ui/src/lib/i18n.ts - 19 + 20 @@ -3415,7 +3415,7 @@ Satellite libs/ui/src/lib/i18n.ts - 20 + 21 @@ -4103,7 +4103,7 @@ Years libs/ui/src/lib/i18n.ts - 25 + 26 @@ -4119,7 +4119,7 @@ Year libs/ui/src/lib/i18n.ts - 24 + 25 @@ -4275,7 +4275,7 @@ Liability libs/ui/src/lib/i18n.ts - 31 + 32 @@ -6907,7 +6907,7 @@ Buy libs/ui/src/lib/i18n.ts - 28 + 29 @@ -6915,7 +6915,31 @@ Valuable libs/ui/src/lib/i18n.ts - 30 + 31 + + + + ETFs without Countries + ETFs without Countries + + apps/client/src/app/components/admin-market-data/admin-market-data.component.ts + 65 + + + + ETFs without Sectors + ETFs without Sectors + + apps/client/src/app/components/admin-market-data/admin-market-data.component.ts + 70 + + + + Query + Query + + libs/ui/src/lib/i18n.ts + 19 diff --git a/apps/client/src/locales/messages.fr.xlf b/apps/client/src/locales/messages.fr.xlf index 4c8f00f47..de37f9afc 100644 --- a/apps/client/src/locales/messages.fr.xlf +++ b/apps/client/src/locales/messages.fr.xlf @@ -522,7 +522,7 @@ Filtrer par... apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 245 + 264 @@ -2390,7 +2390,7 @@ Vente libs/ui/src/lib/i18n.ts - 32 + 33 @@ -2670,7 +2670,7 @@ libs/ui/src/lib/i18n.ts - 29 + 30 @@ -3146,7 +3146,7 @@ Titres libs/ui/src/lib/i18n.ts - 21 + 22 @@ -3154,7 +3154,7 @@ Symbole libs/ui/src/lib/i18n.ts - 22 + 23 @@ -3162,7 +3162,7 @@ Étiquette libs/ui/src/lib/i18n.ts - 23 + 24 @@ -3170,7 +3170,7 @@ Cash libs/ui/src/lib/i18n.ts - 35 + 36 @@ -3178,7 +3178,7 @@ Marchandise libs/ui/src/lib/i18n.ts - 36 + 37 @@ -3186,7 +3186,7 @@ Capital libs/ui/src/lib/i18n.ts - 37 + 38 @@ -3194,7 +3194,7 @@ Revenu Fixe libs/ui/src/lib/i18n.ts - 38 + 39 @@ -3202,7 +3202,7 @@ Immobilier libs/ui/src/lib/i18n.ts - 39 + 40 @@ -3210,7 +3210,7 @@ Obligation libs/ui/src/lib/i18n.ts - 42 + 43 @@ -3218,7 +3218,7 @@ Cryptomonnaie libs/ui/src/lib/i18n.ts - 43 + 44 @@ -3226,7 +3226,7 @@ ETF libs/ui/src/lib/i18n.ts - 44 + 45 @@ -3234,7 +3234,7 @@ SICAV libs/ui/src/lib/i18n.ts - 45 + 46 @@ -3242,7 +3242,7 @@ Métal Précieux libs/ui/src/lib/i18n.ts - 46 + 47 @@ -3250,7 +3250,7 @@ Capital Propre libs/ui/src/lib/i18n.ts - 47 + 48 @@ -3258,7 +3258,7 @@ Action libs/ui/src/lib/i18n.ts - 48 + 49 @@ -3266,7 +3266,7 @@ Afrique libs/ui/src/lib/i18n.ts - 51 + 52 @@ -3274,7 +3274,7 @@ Asie libs/ui/src/lib/i18n.ts - 52 + 53 @@ -3282,7 +3282,7 @@ Europe libs/ui/src/lib/i18n.ts - 53 + 54 @@ -3290,7 +3290,7 @@ Amérique du Nord libs/ui/src/lib/i18n.ts - 54 + 55 @@ -3298,7 +3298,7 @@ Océanie libs/ui/src/lib/i18n.ts - 55 + 56 @@ -3306,7 +3306,7 @@ Amérique du Sud libs/ui/src/lib/i18n.ts - 56 + 57 @@ -3406,7 +3406,7 @@ Réserve pour retraite libs/ui/src/lib/i18n.ts - 19 + 20 @@ -3414,7 +3414,7 @@ Satellite libs/ui/src/lib/i18n.ts - 20 + 21 @@ -4102,7 +4102,7 @@ Années libs/ui/src/lib/i18n.ts - 25 + 26 @@ -4118,7 +4118,7 @@ Année libs/ui/src/lib/i18n.ts - 24 + 25 @@ -4274,7 +4274,7 @@ Dette libs/ui/src/lib/i18n.ts - 31 + 32 @@ -6906,7 +6906,7 @@ Buy libs/ui/src/lib/i18n.ts - 28 + 29 @@ -6914,7 +6914,31 @@ Valuable libs/ui/src/lib/i18n.ts - 30 + 31 + + + + ETFs without Countries + ETFs without Countries + + apps/client/src/app/components/admin-market-data/admin-market-data.component.ts + 65 + + + + ETFs without Sectors + ETFs without Sectors + + apps/client/src/app/components/admin-market-data/admin-market-data.component.ts + 70 + + + + Query + Query + + libs/ui/src/lib/i18n.ts + 19 diff --git a/apps/client/src/locales/messages.it.xlf b/apps/client/src/locales/messages.it.xlf index afc24559a..e09f17795 100644 --- a/apps/client/src/locales/messages.it.xlf +++ b/apps/client/src/locales/messages.it.xlf @@ -2143,7 +2143,7 @@ Vendi libs/ui/src/lib/i18n.ts - 32 + 33 @@ -2783,7 +2783,7 @@ Filtra per... apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 245 + 264 @@ -2947,7 +2947,7 @@ Symbol libs/ui/src/lib/i18n.ts - 22 + 23 @@ -2955,7 +2955,7 @@ Tag libs/ui/src/lib/i18n.ts - 23 + 24 @@ -2963,7 +2963,7 @@ Cash libs/ui/src/lib/i18n.ts - 35 + 36 @@ -2971,7 +2971,7 @@ Commodity libs/ui/src/lib/i18n.ts - 36 + 37 @@ -2979,7 +2979,7 @@ Equity libs/ui/src/lib/i18n.ts - 37 + 38 @@ -2987,7 +2987,7 @@ Fixed Income libs/ui/src/lib/i18n.ts - 38 + 39 @@ -2995,7 +2995,7 @@ Real Estate libs/ui/src/lib/i18n.ts - 39 + 40 @@ -3003,7 +3003,7 @@ Bond libs/ui/src/lib/i18n.ts - 42 + 43 @@ -3011,7 +3011,7 @@ Cryptocurrency libs/ui/src/lib/i18n.ts - 43 + 44 @@ -3019,7 +3019,7 @@ ETF libs/ui/src/lib/i18n.ts - 44 + 45 @@ -3027,7 +3027,7 @@ Mutual Fund libs/ui/src/lib/i18n.ts - 45 + 46 @@ -3035,7 +3035,7 @@ Precious Metal libs/ui/src/lib/i18n.ts - 46 + 47 @@ -3043,7 +3043,7 @@ Private Equity libs/ui/src/lib/i18n.ts - 47 + 48 @@ -3051,7 +3051,7 @@ Stock libs/ui/src/lib/i18n.ts - 48 + 49 @@ -3091,7 +3091,7 @@ North America libs/ui/src/lib/i18n.ts - 54 + 55 @@ -3099,7 +3099,7 @@ Africa libs/ui/src/lib/i18n.ts - 51 + 52 @@ -3107,7 +3107,7 @@ Asia libs/ui/src/lib/i18n.ts - 52 + 53 @@ -3115,7 +3115,7 @@ Europe libs/ui/src/lib/i18n.ts - 53 + 54 @@ -3123,7 +3123,7 @@ Oceania libs/ui/src/lib/i18n.ts - 55 + 56 @@ -3131,7 +3131,7 @@ South America libs/ui/src/lib/i18n.ts - 56 + 57 @@ -3227,7 +3227,7 @@ libs/ui/src/lib/i18n.ts - 29 + 30 @@ -3279,7 +3279,7 @@ Securities libs/ui/src/lib/i18n.ts - 21 + 22 @@ -3407,7 +3407,7 @@ Retirement Provision libs/ui/src/lib/i18n.ts - 19 + 20 @@ -3415,7 +3415,7 @@ Satellite libs/ui/src/lib/i18n.ts - 20 + 21 @@ -4103,7 +4103,7 @@ Years libs/ui/src/lib/i18n.ts - 25 + 26 @@ -4119,7 +4119,7 @@ Year libs/ui/src/lib/i18n.ts - 24 + 25 @@ -4275,7 +4275,7 @@ Liability libs/ui/src/lib/i18n.ts - 31 + 32 @@ -6907,7 +6907,7 @@ Buy libs/ui/src/lib/i18n.ts - 28 + 29 @@ -6915,7 +6915,31 @@ Valuable libs/ui/src/lib/i18n.ts - 30 + 31 + + + + ETFs without Countries + ETFs without Countries + + apps/client/src/app/components/admin-market-data/admin-market-data.component.ts + 65 + + + + ETFs without Sectors + ETFs without Sectors + + apps/client/src/app/components/admin-market-data/admin-market-data.component.ts + 70 + + + + Query + Query + + libs/ui/src/lib/i18n.ts + 19 diff --git a/apps/client/src/locales/messages.nl.xlf b/apps/client/src/locales/messages.nl.xlf index ba67b886e..df6abc18b 100644 --- a/apps/client/src/locales/messages.nl.xlf +++ b/apps/client/src/locales/messages.nl.xlf @@ -2139,10 +2139,10 @@ Sell - Verkopen + Verkopen libs/ui/src/lib/i18n.ts - 32 + 33 @@ -2782,7 +2782,7 @@ Filter op... apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 245 + 264 @@ -2946,7 +2946,7 @@ Symbool libs/ui/src/lib/i18n.ts - 22 + 23 @@ -2954,7 +2954,7 @@ Label libs/ui/src/lib/i18n.ts - 23 + 24 @@ -2962,7 +2962,7 @@ Contant geld libs/ui/src/lib/i18n.ts - 35 + 36 @@ -2970,7 +2970,7 @@ Commodity libs/ui/src/lib/i18n.ts - 36 + 37 @@ -2978,7 +2978,7 @@ Equity libs/ui/src/lib/i18n.ts - 37 + 38 @@ -2986,7 +2986,7 @@ Vast inkomen libs/ui/src/lib/i18n.ts - 38 + 39 @@ -2994,7 +2994,7 @@ Vastgoed libs/ui/src/lib/i18n.ts - 39 + 40 @@ -3002,7 +3002,7 @@ Obligatie libs/ui/src/lib/i18n.ts - 42 + 43 @@ -3010,7 +3010,7 @@ Cryptovaluta libs/ui/src/lib/i18n.ts - 43 + 44 @@ -3018,7 +3018,7 @@ ETF libs/ui/src/lib/i18n.ts - 44 + 45 @@ -3026,7 +3026,7 @@ Beleggingsfonds libs/ui/src/lib/i18n.ts - 45 + 46 @@ -3034,7 +3034,7 @@ Edel metaal libs/ui/src/lib/i18n.ts - 46 + 47 @@ -3042,7 +3042,7 @@ Private equity libs/ui/src/lib/i18n.ts - 47 + 48 @@ -3050,7 +3050,7 @@ Aandeel libs/ui/src/lib/i18n.ts - 48 + 49 @@ -3090,7 +3090,7 @@ Noord Amerika libs/ui/src/lib/i18n.ts - 54 + 55 @@ -3098,7 +3098,7 @@ Afrika libs/ui/src/lib/i18n.ts - 51 + 52 @@ -3106,7 +3106,7 @@ Azië libs/ui/src/lib/i18n.ts - 52 + 53 @@ -3114,7 +3114,7 @@ Europa libs/ui/src/lib/i18n.ts - 53 + 54 @@ -3122,7 +3122,7 @@ Oceanië libs/ui/src/lib/i18n.ts - 55 + 56 @@ -3130,7 +3130,7 @@ Zuid Amerika libs/ui/src/lib/i18n.ts - 56 + 57 @@ -3226,7 +3226,7 @@ libs/ui/src/lib/i18n.ts - 29 + 30 @@ -3278,7 +3278,7 @@ Effecten libs/ui/src/lib/i18n.ts - 21 + 22 @@ -3406,7 +3406,7 @@ Retirement Provision libs/ui/src/lib/i18n.ts - 19 + 20 @@ -3414,7 +3414,7 @@ Satellite libs/ui/src/lib/i18n.ts - 20 + 21 @@ -4102,7 +4102,7 @@ Years libs/ui/src/lib/i18n.ts - 25 + 26 @@ -4118,7 +4118,7 @@ Year libs/ui/src/lib/i18n.ts - 24 + 25 @@ -4274,7 +4274,7 @@ Liability libs/ui/src/lib/i18n.ts - 31 + 32 @@ -6906,7 +6906,7 @@ Buy libs/ui/src/lib/i18n.ts - 28 + 29 @@ -6914,7 +6914,31 @@ Valuable libs/ui/src/lib/i18n.ts - 30 + 31 + + + + ETFs without Countries + ETFs without Countries + + apps/client/src/app/components/admin-market-data/admin-market-data.component.ts + 65 + + + + ETFs without Sectors + ETFs without Sectors + + apps/client/src/app/components/admin-market-data/admin-market-data.component.ts + 70 + + + + Query + Query + + libs/ui/src/lib/i18n.ts + 19 diff --git a/apps/client/src/locales/messages.pt.xlf b/apps/client/src/locales/messages.pt.xlf index 5e489a759..9755caac8 100644 --- a/apps/client/src/locales/messages.pt.xlf +++ b/apps/client/src/locales/messages.pt.xlf @@ -522,7 +522,7 @@ Filtrar por... apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 245 + 264 @@ -2314,7 +2314,7 @@ Venda libs/ui/src/lib/i18n.ts - 32 + 33 @@ -3010,7 +3010,7 @@ Símbolo libs/ui/src/lib/i18n.ts - 22 + 23 @@ -3018,7 +3018,7 @@ Marcador libs/ui/src/lib/i18n.ts - 23 + 24 @@ -3026,7 +3026,7 @@ Dinheiro libs/ui/src/lib/i18n.ts - 35 + 36 @@ -3034,7 +3034,7 @@ Matéria-prima libs/ui/src/lib/i18n.ts - 36 + 37 @@ -3042,7 +3042,7 @@ Ações libs/ui/src/lib/i18n.ts - 37 + 38 @@ -3050,7 +3050,7 @@ Rendimento Fixo libs/ui/src/lib/i18n.ts - 38 + 39 @@ -3058,7 +3058,7 @@ Imobiliário libs/ui/src/lib/i18n.ts - 39 + 40 @@ -3066,7 +3066,7 @@ Obrigação libs/ui/src/lib/i18n.ts - 42 + 43 @@ -3074,7 +3074,7 @@ Criptomoedas libs/ui/src/lib/i18n.ts - 43 + 44 @@ -3082,7 +3082,7 @@ ETF libs/ui/src/lib/i18n.ts - 44 + 45 @@ -3090,7 +3090,7 @@ Fundo de Investimento libs/ui/src/lib/i18n.ts - 45 + 46 @@ -3098,7 +3098,7 @@ Metal Precioso libs/ui/src/lib/i18n.ts - 46 + 47 @@ -3106,7 +3106,7 @@ Private Equity libs/ui/src/lib/i18n.ts - 47 + 48 @@ -3114,7 +3114,7 @@ Ação libs/ui/src/lib/i18n.ts - 48 + 49 @@ -3122,7 +3122,7 @@ África libs/ui/src/lib/i18n.ts - 51 + 52 @@ -3130,7 +3130,7 @@ Ásia libs/ui/src/lib/i18n.ts - 52 + 53 @@ -3138,7 +3138,7 @@ Europa libs/ui/src/lib/i18n.ts - 53 + 54 @@ -3146,7 +3146,7 @@ América do Norte libs/ui/src/lib/i18n.ts - 54 + 55 @@ -3154,7 +3154,7 @@ Oceânia libs/ui/src/lib/i18n.ts - 55 + 56 @@ -3162,7 +3162,7 @@ América do Sul libs/ui/src/lib/i18n.ts - 56 + 57 @@ -3302,7 +3302,7 @@ libs/ui/src/lib/i18n.ts - 29 + 30 @@ -3326,7 +3326,7 @@ Títulos libs/ui/src/lib/i18n.ts - 21 + 22 @@ -3406,7 +3406,7 @@ Provisão de Reforma libs/ui/src/lib/i18n.ts - 19 + 20 @@ -3414,7 +3414,7 @@ Satélite libs/ui/src/lib/i18n.ts - 20 + 21 @@ -4102,7 +4102,7 @@ Anos libs/ui/src/lib/i18n.ts - 25 + 26 @@ -4118,7 +4118,7 @@ Ano libs/ui/src/lib/i18n.ts - 24 + 25 @@ -4274,7 +4274,7 @@ Liability libs/ui/src/lib/i18n.ts - 31 + 32 @@ -6906,7 +6906,7 @@ Buy libs/ui/src/lib/i18n.ts - 28 + 29 @@ -6914,7 +6914,31 @@ Valuable libs/ui/src/lib/i18n.ts - 30 + 31 + + + + ETFs without Countries + ETFs without Countries + + apps/client/src/app/components/admin-market-data/admin-market-data.component.ts + 65 + + + + ETFs without Sectors + ETFs without Sectors + + apps/client/src/app/components/admin-market-data/admin-market-data.component.ts + 70 + + + + Query + Query + + libs/ui/src/lib/i18n.ts + 19 diff --git a/apps/client/src/locales/messages.xlf b/apps/client/src/locales/messages.xlf index 6a7c942ba..717a9c62a 100644 --- a/apps/client/src/locales/messages.xlf +++ b/apps/client/src/locales/messages.xlf @@ -1959,7 +1959,7 @@ Sell libs/ui/src/lib/i18n.ts - 32 + 33 @@ -2535,7 +2535,7 @@ Filter by... apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 245 + 264 @@ -2665,35 +2665,35 @@ Precious Metal libs/ui/src/lib/i18n.ts - 46 + 47 Tag libs/ui/src/lib/i18n.ts - 23 + 24 Equity libs/ui/src/lib/i18n.ts - 37 + 38 Real Estate libs/ui/src/lib/i18n.ts - 39 + 40 Cryptocurrency libs/ui/src/lib/i18n.ts - 43 + 44 @@ -2707,14 +2707,14 @@ Stock libs/ui/src/lib/i18n.ts - 48 + 49 Private Equity libs/ui/src/lib/i18n.ts - 47 + 48 @@ -2728,49 +2728,49 @@ Mutual Fund libs/ui/src/lib/i18n.ts - 45 + 46 Cash libs/ui/src/lib/i18n.ts - 35 + 36 Symbol libs/ui/src/lib/i18n.ts - 22 + 23 Commodity libs/ui/src/lib/i18n.ts - 36 + 37 Bond libs/ui/src/lib/i18n.ts - 42 + 43 ETF libs/ui/src/lib/i18n.ts - 44 + 45 Fixed Income libs/ui/src/lib/i18n.ts - 38 + 39 @@ -2806,42 +2806,42 @@ North America libs/ui/src/lib/i18n.ts - 54 + 55 Africa libs/ui/src/lib/i18n.ts - 51 + 52 Oceania libs/ui/src/lib/i18n.ts - 55 + 56 Asia libs/ui/src/lib/i18n.ts - 52 + 53 South America libs/ui/src/lib/i18n.ts - 56 + 57 Europe libs/ui/src/lib/i18n.ts - 53 + 54 @@ -2943,7 +2943,7 @@ libs/ui/src/lib/i18n.ts - 29 + 30 @@ -2957,7 +2957,7 @@ Securities libs/ui/src/lib/i18n.ts - 21 + 22 @@ -3082,14 +3082,14 @@ Satellite libs/ui/src/lib/i18n.ts - 20 + 21 Retirement Provision libs/ui/src/lib/i18n.ts - 19 + 20 @@ -3705,7 +3705,7 @@ Years libs/ui/src/lib/i18n.ts - 25 + 26 @@ -3719,7 +3719,7 @@ Year libs/ui/src/lib/i18n.ts - 24 + 25 @@ -3857,7 +3857,7 @@ Liability libs/ui/src/lib/i18n.ts - 31 + 32 @@ -6455,14 +6455,14 @@ Buy libs/ui/src/lib/i18n.ts - 28 + 29 Valuable libs/ui/src/lib/i18n.ts - 30 + 31 @@ -6483,6 +6483,27 @@ 39 + + ETFs without Countries + + apps/client/src/app/components/admin-market-data/admin-market-data.component.ts + 65 + + + + ETFs without Sectors + + apps/client/src/app/components/admin-market-data/admin-market-data.component.ts + 70 + + + + Query + + libs/ui/src/lib/i18n.ts + 19 + + \ No newline at end of file From 2bf4f1237a42a7b8d510ce2ea4830f8ded45488c Mon Sep 17 00:00:00 2001 From: bptrgx <47859535+bptrgx@users.noreply.github.com> Date: Sat, 15 Jul 2023 22:09:12 +0200 Subject: [PATCH 3/7] Feature/Improve login dialog (#2124) * Improve login dialog * Update changelog --------- Co-authored-by: Thomas <4159106+dtslvr@users.noreply.github.com> --- CHANGELOG.md | 1 + ...ogin-with-access-token-dialog.component.ts | 8 +++++ .../login-with-access-token-dialog.html | 30 +++++++++++++------ 3 files changed, 30 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 074737a6c..e3d3ea887 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- Improved the usability of the login dialog - Disabled the caching in the health check endpoints for data providers - Improved the content of the Frequently Asked Questions (FAQ) page - Upgraded `prisma` from version `4.15.0` to `4.16.2` diff --git a/apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.component.ts b/apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.component.ts index 85af8aaee..b3236b2be 100644 --- a/apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.component.ts +++ b/apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.component.ts @@ -16,6 +16,8 @@ import { TokenStorageService } from '@ghostfolio/client/services/token-storage.s templateUrl: 'login-with-access-token-dialog.html' }) export class LoginWithAccessTokenDialog { + public isAccessTokenHidden = true; + public constructor( @Inject(MAT_DIALOG_DATA) public data: any, public dialogRef: MatDialogRef, @@ -38,6 +40,12 @@ export class LoginWithAccessTokenDialog { this.dialogRef.close(); } + public onLoginWithAccessToken() { + if (this.data.accessToken) { + this.dialogRef.close(this.data); + } + } + public async onLoginWithInternetIdentity() { try { const { authToken } = await this.internetIdentityService.login(); diff --git a/apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html b/apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html index 5dfc84a02..080ad4428 100644 --- a/apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html +++ b/apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html @@ -6,15 +6,27 @@
- - Security Token - - +
+ + Security Token + + + +
or
From 6728e04ff73db707e71e89119c03f31bca2c3973 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sat, 15 Jul 2023 22:17:07 +0200 Subject: [PATCH 4/7] Improve http response interceptor (#2157) Do not show snack bar for login endpoint --- apps/client/src/app/core/http-response.interceptor.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/client/src/app/core/http-response.interceptor.ts b/apps/client/src/app/core/http-response.interceptor.ts index 84390b44c..b9f60eb65 100644 --- a/apps/client/src/app/core/http-response.interceptor.ts +++ b/apps/client/src/app/core/http-response.interceptor.ts @@ -62,7 +62,7 @@ export class HttpResponseInterceptor implements HttpInterceptor { undefined, { duration: 6000 } ); - } else { + } else if (!error.url.endsWith('auth/anonymous')) { this.snackBarRef = this.snackBar.open( $localize`This feature requires a subscription.`, this.hasPermissionForSubscription From 85336061772e9c064163832e3864c5aeb73c3939 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sun, 16 Jul 2023 08:01:31 +0200 Subject: [PATCH 5/7] Release 1.290.0 (#2158) --- CHANGELOG.md | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e3d3ea887..a02baea1b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## Unreleased +## 1.290.0 - 2023-07-16 ### Added diff --git a/package.json b/package.json index 45293b758..13ca27fcc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ghostfolio", - "version": "1.289.0", + "version": "1.290.0", "homepage": "https://ghostfol.io", "license": "AGPL-3.0", "scripts": { From 9c0f46b5876f11fcaeb5310297bb650e556133a6 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Tue, 18 Jul 2023 21:28:44 +0200 Subject: [PATCH 6/7] Add markets.sh (#2161) --- .../personal-finance-tools/products.ts | 15 ++++++++++++ .../products/markets.sh-page.component.ts | 24 +++++++++++++++++++ apps/client/src/assets/sitemap.xml | 4 ++++ 3 files changed, 43 insertions(+) create mode 100644 apps/client/src/app/pages/resources/personal-finance-tools/products/markets.sh-page.component.ts 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 2dc29ee1e..74d8829e7 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 @@ -10,6 +10,7 @@ import { GetquinPageComponent } from './products/getquin-page.component'; import { GoSpatzPageComponent } from './products/gospatz-page.component'; import { JustEtfPageComponent } from './products/justetf-page.component'; import { KuberaPageComponent } from './products/kubera-page.component'; +import { MarketsShPageComponent } from './products/markets.sh-page.component'; import { MaybeFinancePageComponent } from './products/maybe-finance-page.component'; import { MonsePageComponent } from './products/monse-page.component'; import { ParqetPageComponent } from './products/parqet-page.component'; @@ -167,6 +168,20 @@ export const products: Product[] = [ pricingPerYear: '$150', slogan: 'The Time Machine for your Net Worth' }, + { + component: MarketsShPageComponent, + founded: 2022, + hasFreePlan: true, + hasSelfHostingAbility: false, + isOpenSource: false, + key: 'markets.sh', + languages: ['English'], + name: 'markets.sh', + origin: 'Germany', + pricingPerYear: '€168', + region: 'Global', + slogan: 'Track your investments' + }, { component: MaybeFinancePageComponent, founded: 2021, diff --git a/apps/client/src/app/pages/resources/personal-finance-tools/products/markets.sh-page.component.ts b/apps/client/src/app/pages/resources/personal-finance-tools/products/markets.sh-page.component.ts new file mode 100644 index 000000000..aa5cb6066 --- /dev/null +++ b/apps/client/src/app/pages/resources/personal-finance-tools/products/markets.sh-page.component.ts @@ -0,0 +1,24 @@ +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-markets-sh-page', + standalone: true, + styleUrls: ['../product-page-template.scss'], + templateUrl: '../product-page-template.html' +}) +export class MarketsShPageComponent { + public product1 = products.find(({ key }) => { + return key === 'ghostfolio'; + }); + + public product2 = products.find(({ key }) => { + return key === 'markets.sh'; + }); +} diff --git a/apps/client/src/assets/sitemap.xml b/apps/client/src/assets/sitemap.xml index 6e976a755..cfc44a814 100644 --- a/apps/client/src/assets/sitemap.xml +++ b/apps/client/src/assets/sitemap.xml @@ -208,6 +208,10 @@ https://ghostfol.io/en/resources/personal-finance-tools/open-source-alternative-to-kubera 2023-07-10T00:00:00+00:00 + + https://ghostfol.io/en/resources/personal-finance-tools/open-source-alternative-to-markets.sh + 2023-07-10T00:00:00+00:00 + https://ghostfol.io/en/resources/personal-finance-tools/open-source-alternative-to-maybe-finance 2023-07-10T00:00:00+00:00 From 455a2d2e92c3072b89bfad98fa8e8e5df06c5a71 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Tue, 18 Jul 2023 21:29:08 +0200 Subject: [PATCH 7/7] Refactor value to valueInBaseCurrency (#2160) --- .../src/app/portfolio/portfolio.controller.ts | 7 +-- .../src/app/portfolio/portfolio.service.ts | 12 +++-- .../allocations/allocations-page.component.ts | 42 +++++++++------- .../app/pages/public/public-page.component.ts | 48 ++++++++++++------- apps/client/src/app/services/data.service.ts | 6 +-- .../portfolio-position.interface.ts | 2 +- .../portfolio-public-details.interface.ts | 2 +- 7 files changed, 72 insertions(+), 47 deletions(-) diff --git a/apps/api/src/app/portfolio/portfolio.controller.ts b/apps/api/src/app/portfolio/portfolio.controller.ts index 06f841e12..0d9afea51 100644 --- a/apps/api/src/app/portfolio/portfolio.controller.ts +++ b/apps/api/src/app/portfolio/portfolio.controller.ts @@ -134,7 +134,7 @@ export class PortfolioController { portfolioPosition.netPerformance = null; portfolioPosition.quantity = null; portfolioPosition.valueInPercentage = - portfolioPosition.value / totalValue; + portfolioPosition.valueInBaseCurrency / totalValue; } for (const [name, { valueInBaseCurrency }] of Object.entries(accounts)) { @@ -445,7 +445,8 @@ export class PortfolioController { for (const [symbol, portfolioPosition] of Object.entries(holdings)) { portfolioPublicDetails.holdings[symbol] = { - allocationInPercentage: portfolioPosition.value / totalValue, + allocationInPercentage: + portfolioPosition.valueInBaseCurrency / totalValue, countries: hasDetails ? portfolioPosition.countries : [], currency: hasDetails ? portfolioPosition.currency : undefined, dataSource: portfolioPosition.dataSource, @@ -456,7 +457,7 @@ export class PortfolioController { sectors: hasDetails ? portfolioPosition.sectors : [], symbol: portfolioPosition.symbol, url: portfolioPosition.url, - valueInPercentage: portfolioPosition.value / totalValue + valueInPercentage: portfolioPosition.valueInBaseCurrency / totalValue }; } diff --git a/apps/api/src/app/portfolio/portfolio.service.ts b/apps/api/src/app/portfolio/portfolio.service.ts index 7d13728d2..4bc1c7b15 100644 --- a/apps/api/src/app/portfolio/portfolio.service.ts +++ b/apps/api/src/app/portfolio/portfolio.service.ts @@ -585,7 +585,7 @@ export class PortfolioService { symbol: item.symbol, transactionCount: item.transactionCount, url: symbolProfile.url, - value: value.toNumber() + valueInBaseCurrency: value.toNumber() }; } @@ -645,7 +645,7 @@ export class PortfolioService { holdings[userCurrency] = { ...emergencyFundCashPositions[userCurrency], investment: emergencyFundInCash, - value: emergencyFundInCash + valueInBaseCurrency: emergencyFundInCash }; } @@ -1278,7 +1278,7 @@ export class PortfolioService { if (cashPositions[account.currency]) { cashPositions[account.currency].investment += convertedBalance; - cashPositions[account.currency].value += convertedBalance; + cashPositions[account.currency].valueInBaseCurrency += convertedBalance; } else { cashPositions[account.currency] = this.getInitialCashPosition({ balance: convertedBalance, @@ -1290,7 +1290,9 @@ export class PortfolioService { for (const symbol of Object.keys(cashPositions)) { // Calculate allocations for each currency cashPositions[symbol].allocationInPercentage = value.gt(0) - ? new Big(cashPositions[symbol].value).div(value).toNumber() + ? new Big(cashPositions[symbol].valueInBaseCurrency) + .div(value) + .toNumber() : 0; } @@ -1475,7 +1477,7 @@ export class PortfolioService { sectors: [], symbol: currency, transactionCount: 0, - value: balance + valueInBaseCurrency: balance }; } diff --git a/apps/client/src/app/pages/portfolio/allocations/allocations-page.component.ts b/apps/client/src/app/pages/portfolio/allocations/allocations-page.component.ts index 43f33b70e..6d2ada8b0 100644 --- a/apps/client/src/app/pages/portfolio/allocations/allocations-page.component.ts +++ b/apps/client/src/app/pages/portfolio/allocations/allocations-page.component.ts @@ -70,7 +70,7 @@ export class AllocationsPageComponent implements OnDestroy, OnInit { | 'currency' | 'exchange' | 'name' - | 'value' + | 'valueInBaseCurrency' > & { etfProvider: string }; }; public sectors: { @@ -292,11 +292,11 @@ export class AllocationsPageComponent implements OnDestroy, OnInit { if (this.hasImpersonationId) { value = position.allocationInPercentage; } else { - value = position.value; + value = position.valueInBaseCurrency; } this.positions[symbol] = { - value, + valueInBaseCurrency: value, assetClass: position.assetClass, assetSubClass: position.assetSubClass, currency: position.currency, @@ -323,39 +323,45 @@ export class AllocationsPageComponent implements OnDestroy, OnInit { } this.markets.developedMarkets.value += - position.markets.developedMarkets * position.value; + position.markets.developedMarkets * position.valueInBaseCurrency; this.markets.emergingMarkets.value += - position.markets.emergingMarkets * position.value; + position.markets.emergingMarkets * position.valueInBaseCurrency; this.markets.otherMarkets.value += - position.markets.otherMarkets * position.value; + position.markets.otherMarkets * position.valueInBaseCurrency; for (const country of position.countries) { const { code, continent, name, weight } = country; if (this.continents[continent]?.value) { - this.continents[continent].value += weight * position.value; + this.continents[continent].value += + weight * position.valueInBaseCurrency; } else { this.continents[continent] = { name: continent, - value: weight * this.portfolioDetails.holdings[symbol].value + value: + weight * + this.portfolioDetails.holdings[symbol].valueInBaseCurrency }; } if (this.countries[code]?.value) { - this.countries[code].value += weight * position.value; + this.countries[code].value += + weight * position.valueInBaseCurrency; } else { this.countries[code] = { name, - value: weight * this.portfolioDetails.holdings[symbol].value + value: + weight * + this.portfolioDetails.holdings[symbol].valueInBaseCurrency }; } } } else { this.continents[UNKNOWN_KEY].value += - this.portfolioDetails.holdings[symbol].value; + this.portfolioDetails.holdings[symbol].valueInBaseCurrency; this.countries[UNKNOWN_KEY].value += - this.portfolioDetails.holdings[symbol].value; + this.portfolioDetails.holdings[symbol].valueInBaseCurrency; } if (position.sectors.length > 0) { @@ -363,17 +369,19 @@ export class AllocationsPageComponent implements OnDestroy, OnInit { const { name, weight } = sector; if (this.sectors[name]?.value) { - this.sectors[name].value += weight * position.value; + this.sectors[name].value += weight * position.valueInBaseCurrency; } else { this.sectors[name] = { name, - value: weight * this.portfolioDetails.holdings[symbol].value + value: + weight * + this.portfolioDetails.holdings[symbol].valueInBaseCurrency }; } } } else { this.sectors[UNKNOWN_KEY].value += - this.portfolioDetails.holdings[symbol].value; + this.portfolioDetails.holdings[symbol].valueInBaseCurrency; } } @@ -381,8 +389,8 @@ export class AllocationsPageComponent implements OnDestroy, OnInit { dataSource: position.dataSource, name: position.name, symbol: prettifySymbol(symbol), - value: isNumber(position.value) - ? position.value + value: isNumber(position.valueInBaseCurrency) + ? position.valueInBaseCurrency : position.valueInPercentage }; } diff --git a/apps/client/src/app/pages/public/public-page.component.ts b/apps/client/src/app/pages/public/public-page.component.ts index f25c69dae..54ff0cf15 100644 --- a/apps/client/src/app/pages/public/public-page.component.ts +++ b/apps/client/src/app/pages/public/public-page.component.ts @@ -33,11 +33,18 @@ export class PublicPageComponent implements OnInit { }; public portfolioPublicDetails: PortfolioPublicDetails; public positions: { - [symbol: string]: Pick; + [symbol: string]: Pick< + PortfolioPosition, + 'currency' | 'name' | 'valueInBaseCurrency' + >; }; public positionsArray: Pick< PortfolioPosition, - 'currency' | 'name' | 'netPerformancePercent' | 'symbol' | 'value' + | 'currency' + | 'name' + | 'netPerformancePercent' + | 'symbol' + | 'valueInBaseCurrency' >[]; public sectors: { [name: string]: { name: string; value: number }; @@ -135,7 +142,7 @@ export class PublicPageComponent implements OnInit { const value = position.allocationInPercentage; this.positions[symbol] = { - value, + valueInBaseCurrency: value, currency: position.currency, name: position.name }; @@ -143,39 +150,44 @@ export class PublicPageComponent implements OnInit { if (position.countries.length > 0) { this.markets.developedMarkets.value += - position.markets.developedMarkets * position.value; + position.markets.developedMarkets * position.valueInBaseCurrency; this.markets.emergingMarkets.value += - position.markets.emergingMarkets * position.value; + position.markets.emergingMarkets * position.valueInBaseCurrency; this.markets.otherMarkets.value += - position.markets.otherMarkets * position.value; + position.markets.otherMarkets * position.valueInBaseCurrency; for (const country of position.countries) { const { code, continent, name, weight } = country; if (this.continents[continent]?.value) { - this.continents[continent].value += weight * position.value; + this.continents[continent].value += + weight * position.valueInBaseCurrency; } else { this.continents[continent] = { name: continent, - value: weight * this.portfolioPublicDetails.holdings[symbol].value + value: + weight * + this.portfolioPublicDetails.holdings[symbol].valueInBaseCurrency }; } if (this.countries[code]?.value) { - this.countries[code].value += weight * position.value; + this.countries[code].value += weight * position.valueInBaseCurrency; } else { this.countries[code] = { name, - value: weight * this.portfolioPublicDetails.holdings[symbol].value + value: + weight * + this.portfolioPublicDetails.holdings[symbol].valueInBaseCurrency }; } } } else { this.continents[UNKNOWN_KEY].value += - this.portfolioPublicDetails.holdings[symbol].value; + this.portfolioPublicDetails.holdings[symbol].valueInBaseCurrency; this.countries[UNKNOWN_KEY].value += - this.portfolioPublicDetails.holdings[symbol].value; + this.portfolioPublicDetails.holdings[symbol].valueInBaseCurrency; } if (position.sectors.length > 0) { @@ -183,24 +195,26 @@ export class PublicPageComponent implements OnInit { const { name, weight } = sector; if (this.sectors[name]?.value) { - this.sectors[name].value += weight * position.value; + this.sectors[name].value += weight * position.valueInBaseCurrency; } else { this.sectors[name] = { name, - value: weight * this.portfolioPublicDetails.holdings[symbol].value + value: + weight * + this.portfolioPublicDetails.holdings[symbol].valueInBaseCurrency }; } } } else { this.sectors[UNKNOWN_KEY].value += - this.portfolioPublicDetails.holdings[symbol].value; + this.portfolioPublicDetails.holdings[symbol].valueInBaseCurrency; } this.symbols[prettifySymbol(symbol)] = { name: position.name, symbol: prettifySymbol(symbol), - value: isNumber(position.value) - ? position.value + value: isNumber(position.valueInBaseCurrency) + ? position.valueInBaseCurrency : position.valueInPercentage }; } diff --git a/apps/client/src/app/services/data.service.ts b/apps/client/src/app/services/data.service.ts index 99416ae57..c29529590 100644 --- a/apps/client/src/app/services/data.service.ts +++ b/apps/client/src/app/services/data.service.ts @@ -415,10 +415,10 @@ export class DataService { map((response) => { if (response.holdings) { for (const symbol of Object.keys(response.holdings)) { - response.holdings[symbol].value = isNumber( - response.holdings[symbol].value + response.holdings[symbol].valueInBaseCurrency = isNumber( + response.holdings[symbol].valueInBaseCurrency ) - ? response.holdings[symbol].value + ? response.holdings[symbol].valueInBaseCurrency : response.holdings[symbol].valueInPercentage; } } diff --git a/libs/common/src/lib/interfaces/portfolio-position.interface.ts b/libs/common/src/lib/interfaces/portfolio-position.interface.ts index 2b7c6c486..81ac0b7ad 100644 --- a/libs/common/src/lib/interfaces/portfolio-position.interface.ts +++ b/libs/common/src/lib/interfaces/portfolio-position.interface.ts @@ -30,6 +30,6 @@ export interface PortfolioPosition { symbol: string; type?: string; url?: string; - value?: number; + valueInBaseCurrency?: number; valueInPercentage?: number; } diff --git a/libs/common/src/lib/interfaces/portfolio-public-details.interface.ts b/libs/common/src/lib/interfaces/portfolio-public-details.interface.ts index 7abc7f78f..fb56ed94d 100644 --- a/libs/common/src/lib/interfaces/portfolio-public-details.interface.ts +++ b/libs/common/src/lib/interfaces/portfolio-public-details.interface.ts @@ -17,7 +17,7 @@ export interface PortfolioPublicDetails { | 'sectors' | 'symbol' | 'url' - | 'value' + | 'valueInBaseCurrency' | 'valueInPercentage' >; };