Browse Source

Merge branch 'main' into refactor/portfolio-filter-component

pull/5618/head
Thomas Kaul 2 weeks ago
committed by GitHub
parent
commit
20da049a1c
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 2
      CHANGELOG.md
  2. 6
      apps/api/src/app/endpoints/data-providers/ghostfolio/ghostfolio.service.ts
  3. 4
      apps/api/src/app/exchange-rate/exchange-rate.controller.ts
  4. 4
      apps/api/src/app/info/info.controller.ts
  5. 4
      apps/api/src/app/portfolio/calculator/portfolio-calculator.ts
  6. 4
      apps/api/src/app/portfolio/interfaces/get-values-params.interface.ts
  7. 4
      apps/api/src/app/symbol/symbol.controller.ts
  8. 10
      apps/api/src/app/symbol/symbol.service.ts
  9. 14
      apps/api/src/services/data-provider/alpha-vantage/alpha-vantage.service.ts
  10. 2
      apps/api/src/services/data-provider/alpha-vantage/interfaces/interfaces.ts
  11. 12
      apps/api/src/services/data-provider/coingecko/coingecko.service.ts
  12. 24
      apps/api/src/services/data-provider/data-provider.service.ts
  13. 14
      apps/api/src/services/data-provider/eod-historical-data/eod-historical-data.service.ts
  14. 14
      apps/api/src/services/data-provider/financial-modeling-prep/financial-modeling-prep.service.ts
  15. 14
      apps/api/src/services/data-provider/ghostfolio/ghostfolio.service.ts
  16. 12
      apps/api/src/services/data-provider/google-sheets/google-sheets.service.ts
  17. 10
      apps/api/src/services/data-provider/interfaces/data-provider.interface.ts
  18. 12
      apps/api/src/services/data-provider/manual/manual.service.ts
  19. 2
      apps/api/src/services/data-provider/rapid-api/interfaces/interfaces.ts
  20. 8
      apps/api/src/services/data-provider/rapid-api/rapid-api.service.ts
  21. 14
      apps/api/src/services/data-provider/yahoo-finance/yahoo-finance.service.ts
  22. 4
      apps/api/src/services/exchange-rate-data/exchange-rate-data.service.ts
  23. 6
      apps/api/src/services/interfaces/interfaces.ts
  24. 4
      apps/api/src/services/market-data/market-data.service.ts
  25. 4
      apps/api/src/services/queues/data-gathering/data-gathering.processor.ts
  26. 12
      apps/api/src/services/queues/data-gathering/data-gathering.service.ts
  27. 2
      apps/api/src/services/queues/portfolio-snapshot/interfaces/portfolio-snapshot-queue-job.interface.ts
  28. 6
      apps/api/src/services/queues/portfolio-snapshot/portfolio-snapshot.processor.ts
  29. 4
      apps/api/src/services/queues/portfolio-snapshot/portfolio-snapshot.service.mock.ts
  30. 4
      apps/api/src/services/queues/portfolio-snapshot/portfolio-snapshot.service.ts
  31. 2
      apps/client/src/app/components/rule/rule-settings-dialog/interfaces/interfaces.ts
  32. 4
      apps/client/src/app/components/rule/rule-settings-dialog/rule-settings-dialog.component.ts
  33. 4
      apps/client/src/app/components/rule/rule.component.ts
  34. 4
      apps/client/src/app/core/notification/alert-dialog/alert-dialog.component.ts
  35. 2
      apps/client/src/app/core/notification/alert-dialog/interfaces/interfaces.ts
  36. 4
      apps/client/src/app/core/notification/confirmation-dialog/confirmation-dialog.component.ts
  37. 2
      apps/client/src/app/core/notification/confirmation-dialog/interfaces/interfaces.ts
  38. 6
      apps/client/src/app/core/notification/interfaces/interfaces.ts
  39. 12
      apps/client/src/app/core/notification/notification.service.ts
  40. 4
      apps/client/src/app/pages/resources/glossary/resources-glossary.component.html
  41. 4
      apps/client/src/app/services/admin.service.ts
  42. 4
      apps/client/src/app/services/data.service.ts
  43. 4
      apps/client/src/main.ts
  44. 2
      libs/common/src/lib/interfaces/index.ts
  45. 4
      libs/common/src/lib/interfaces/responses/dividends-response.interface.ts
  46. 4
      libs/common/src/lib/interfaces/responses/historical-response.interface.ts
  47. 3
      libs/common/src/lib/interfaces/responses/info-response.interface.ts
  48. 4
      libs/common/src/lib/interfaces/responses/quotes-response.interface.ts
  49. 8
      libs/ui/src/lib/assistant/assistant-list-item/assistant-list-item.component.ts
  50. 40
      libs/ui/src/lib/assistant/assistant.component.ts
  51. 26
      libs/ui/src/lib/assistant/interfaces/interfaces.ts

2
CHANGELOG.md

@ -14,7 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed
- Formatted the holdings table in the _Copy AI prompt to clipboard for analysis_ action on the analysis page (experimental)
- Formatted the holdings table in the _Copy portfolio data to clipboard for AI prompt_ action of the analysis page (experimental)
- Formatted the holdings table in the _Copy portfolio data to clipboard for AI prompt_ action on the analysis page (experimental)
- Improved the language localization for German (`de`)
## 2.209.0 - 2025-10-18

6
apps/api/src/app/endpoints/data-providers/ghostfolio/ghostfolio.service.ts

@ -8,7 +8,7 @@ import {
GetQuotesParams,
GetSearchParams
} from '@ghostfolio/api/services/data-provider/interfaces/data-provider.interface';
import { IDataProviderHistoricalResponse } from '@ghostfolio/api/services/interfaces/interfaces';
import { DataProviderHistoricalResponse } from '@ghostfolio/api/services/interfaces/interfaces';
import { PrismaService } from '@ghostfolio/api/services/prisma/prisma.service';
import { PropertyService } from '@ghostfolio/api/services/property/property.service';
import {
@ -114,7 +114,7 @@ export class GhostfolioService {
try {
const promises: Promise<{
[date: string]: IDataProviderHistoricalResponse;
[date: string]: DataProviderHistoricalResponse;
}>[] = [];
for (const dataProviderService of this.getDataProviderServices()) {
@ -156,7 +156,7 @@ export class GhostfolioService {
try {
const promises: Promise<{
[symbol: string]: { [date: string]: IDataProviderHistoricalResponse };
[symbol: string]: { [date: string]: DataProviderHistoricalResponse };
}>[] = [];
for (const dataProviderService of this.getDataProviderServices()) {

4
apps/api/src/app/exchange-rate/exchange-rate.controller.ts

@ -1,5 +1,5 @@
import { HasPermissionGuard } from '@ghostfolio/api/guards/has-permission.guard';
import { IDataProviderHistoricalResponse } from '@ghostfolio/api/services/interfaces/interfaces';
import { DataProviderHistoricalResponse } from '@ghostfolio/api/services/interfaces/interfaces';
import {
Controller,
@ -25,7 +25,7 @@ export class ExchangeRateController {
public async getExchangeRate(
@Param('dateString') dateString: string,
@Param('symbol') symbol: string
): Promise<IDataProviderHistoricalResponse> {
): Promise<DataProviderHistoricalResponse> {
const date = parseISO(dateString);
const exchangeRate = await this.exchangeRateService.getExchangeRate({

4
apps/api/src/app/info/info.controller.ts

@ -1,5 +1,5 @@
import { TransformDataSourceInResponseInterceptor } from '@ghostfolio/api/interceptors/transform-data-source-in-response/transform-data-source-in-response.interceptor';
import { InfoItem } from '@ghostfolio/common/interfaces';
import { InfoResponse } from '@ghostfolio/common/interfaces';
import { Controller, Get, UseInterceptors } from '@nestjs/common';
@ -11,7 +11,7 @@ export class InfoController {
@Get()
@UseInterceptors(TransformDataSourceInResponseInterceptor)
public async getInfo(): Promise<InfoItem> {
public async getInfo(): Promise<InfoResponse> {
return this.infoService.get();
}
}

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

@ -9,7 +9,7 @@ import { getFactor } from '@ghostfolio/api/helper/portfolio.helper';
import { LogPerformance } from '@ghostfolio/api/interceptors/performance-logging/performance-logging.interceptor';
import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service';
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service';
import { IDataGatheringItem } from '@ghostfolio/api/services/interfaces/interfaces';
import { DataGatheringItem } from '@ghostfolio/api/services/interfaces/interfaces';
import { PortfolioSnapshotService } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service';
import { getIntervalFromDateRange } from '@ghostfolio/common/calculation-helper';
import {
@ -193,7 +193,7 @@ export abstract class PortfolioCalculator {
}
const currencies: { [symbol: string]: string } = {};
const dataGatheringItems: IDataGatheringItem[] = [];
const dataGatheringItems: DataGatheringItem[] = [];
let firstIndex = transactionPoints.length;
let firstTransactionPoint: TransactionPoint = null;
let totalInterestWithCurrencyEffect = new Big(0);

4
apps/api/src/app/portfolio/interfaces/get-values-params.interface.ts

@ -1,8 +1,8 @@
import { IDataGatheringItem } from '@ghostfolio/api/services/interfaces/interfaces';
import { DataGatheringItem } from '@ghostfolio/api/services/interfaces/interfaces';
import { DateQuery } from './date-query.interface';
export interface GetValuesParams {
dataGatheringItems: IDataGatheringItem[];
dataGatheringItems: DataGatheringItem[];
dateQuery: DateQuery;
}

4
apps/api/src/app/symbol/symbol.controller.ts

@ -1,7 +1,7 @@
import { HasPermissionGuard } from '@ghostfolio/api/guards/has-permission.guard';
import { TransformDataSourceInRequestInterceptor } from '@ghostfolio/api/interceptors/transform-data-source-in-request/transform-data-source-in-request.interceptor';
import { TransformDataSourceInResponseInterceptor } from '@ghostfolio/api/interceptors/transform-data-source-in-response/transform-data-source-in-response.interceptor';
import { IDataProviderHistoricalResponse } from '@ghostfolio/api/services/interfaces/interfaces';
import { DataProviderHistoricalResponse } from '@ghostfolio/api/services/interfaces/interfaces';
import { LookupResponse } from '@ghostfolio/common/interfaces';
import type { RequestWithUser } from '@ghostfolio/common/types';
@ -97,7 +97,7 @@ export class SymbolController {
@Param('dataSource') dataSource: DataSource,
@Param('dateString') dateString: string,
@Param('symbol') symbol: string
): Promise<IDataProviderHistoricalResponse> {
): Promise<DataProviderHistoricalResponse> {
const date = parseISO(dateString);
if (!isDate(date)) {

10
apps/api/src/app/symbol/symbol.service.ts

@ -1,7 +1,7 @@
import { DataProviderService } from '@ghostfolio/api/services/data-provider/data-provider.service';
import {
IDataGatheringItem,
IDataProviderHistoricalResponse
DataGatheringItem,
DataProviderHistoricalResponse
} from '@ghostfolio/api/services/interfaces/interfaces';
import { MarketDataService } from '@ghostfolio/api/services/market-data/market-data.service';
import { DATE_FORMAT } from '@ghostfolio/common/helper';
@ -27,7 +27,7 @@ export class SymbolService {
dataGatheringItem,
includeHistoricalData
}: {
dataGatheringItem: IDataGatheringItem;
dataGatheringItem: DataGatheringItem;
includeHistoricalData?: number;
}): Promise<SymbolItem> {
const quotes = await this.dataProviderService.getQuotes({
@ -75,10 +75,10 @@ export class SymbolService {
dataSource,
date = new Date(),
symbol
}: IDataGatheringItem): Promise<IDataProviderHistoricalResponse> {
}: DataGatheringItem): Promise<DataProviderHistoricalResponse> {
let historicalData: {
[symbol: string]: {
[date: string]: IDataProviderHistoricalResponse;
[date: string]: DataProviderHistoricalResponse;
};
} = {
[symbol]: {}

14
apps/api/src/services/data-provider/alpha-vantage/alpha-vantage.service.ts

@ -8,8 +8,8 @@ import {
GetSearchParams
} from '@ghostfolio/api/services/data-provider/interfaces/data-provider.interface';
import {
IDataProviderHistoricalResponse,
IDataProviderResponse
DataProviderHistoricalResponse,
DataProviderResponse
} from '@ghostfolio/api/services/interfaces/interfaces';
import { DEFAULT_CURRENCY } from '@ghostfolio/common/config';
import { DATE_FORMAT } from '@ghostfolio/common/helper';
@ -23,7 +23,7 @@ import { DataSource, SymbolProfile } from '@prisma/client';
import * as Alphavantage from 'alphavantage';
import { format, isAfter, isBefore, parse } from 'date-fns';
import { IAlphaVantageHistoricalResponse } from './interfaces/interfaces';
import { AlphaVantageHistoricalResponse } from './interfaces/interfaces';
@Injectable()
export class AlphaVantageService implements DataProviderInterface {
@ -68,11 +68,11 @@ export class AlphaVantageService implements DataProviderInterface {
symbol,
to
}: GetHistoricalParams): Promise<{
[symbol: string]: { [date: string]: IDataProviderHistoricalResponse };
[symbol: string]: { [date: string]: DataProviderHistoricalResponse };
}> {
try {
const historicalData: {
[symbol: string]: IAlphaVantageHistoricalResponse[];
[symbol: string]: AlphaVantageHistoricalResponse[];
} = await this.alphaVantage.crypto.daily(
symbol
.substring(0, symbol.length - DEFAULT_CURRENCY.length)
@ -81,7 +81,7 @@ export class AlphaVantageService implements DataProviderInterface {
);
const response: {
[symbol: string]: { [date: string]: IDataProviderHistoricalResponse };
[symbol: string]: { [date: string]: DataProviderHistoricalResponse };
} = {};
response[symbol] = {};
@ -115,7 +115,7 @@ export class AlphaVantageService implements DataProviderInterface {
}
public async getQuotes({}: GetQuotesParams): Promise<{
[symbol: string]: IDataProviderResponse;
[symbol: string]: DataProviderResponse;
}> {
return {};
}

2
apps/api/src/services/data-provider/alpha-vantage/interfaces/interfaces.ts

@ -1 +1 @@
export interface IAlphaVantageHistoricalResponse {}
export interface AlphaVantageHistoricalResponse {}

12
apps/api/src/services/data-provider/coingecko/coingecko.service.ts

@ -8,8 +8,8 @@ import {
GetSearchParams
} from '@ghostfolio/api/services/data-provider/interfaces/data-provider.interface';
import {
IDataProviderHistoricalResponse,
IDataProviderResponse
DataProviderHistoricalResponse,
DataProviderResponse
} from '@ghostfolio/api/services/interfaces/interfaces';
import { DEFAULT_CURRENCY } from '@ghostfolio/common/config';
import { DATE_FORMAT } from '@ghostfolio/common/helper';
@ -109,7 +109,7 @@ export class CoinGeckoService implements DataProviderInterface {
symbol,
to
}: GetHistoricalParams): Promise<{
[symbol: string]: { [date: string]: IDataProviderHistoricalResponse };
[symbol: string]: { [date: string]: DataProviderHistoricalResponse };
}> {
try {
const { error, prices, status } = await fetch(
@ -133,7 +133,7 @@ export class CoinGeckoService implements DataProviderInterface {
}
const result: {
[symbol: string]: { [date: string]: IDataProviderHistoricalResponse };
[symbol: string]: { [date: string]: DataProviderHistoricalResponse };
} = {
[symbol]: {}
};
@ -166,8 +166,8 @@ export class CoinGeckoService implements DataProviderInterface {
public async getQuotes({
requestTimeout = this.configurationService.get('REQUEST_TIMEOUT'),
symbols
}: GetQuotesParams): Promise<{ [symbol: string]: IDataProviderResponse }> {
const response: { [symbol: string]: IDataProviderResponse } = {};
}: GetQuotesParams): Promise<{ [symbol: string]: DataProviderResponse }> {
const response: { [symbol: string]: DataProviderResponse } = {};
if (symbols.length <= 0) {
return response;

24
apps/api/src/services/data-provider/data-provider.service.ts

@ -2,8 +2,8 @@ import { RedisCacheService } from '@ghostfolio/api/app/redis-cache/redis-cache.s
import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service';
import { DataProviderInterface } from '@ghostfolio/api/services/data-provider/interfaces/data-provider.interface';
import {
IDataProviderHistoricalResponse,
IDataProviderResponse
DataProviderHistoricalResponse,
DataProviderResponse
} from '@ghostfolio/api/services/interfaces/interfaces';
import { MarketDataService } from '@ghostfolio/api/services/market-data/market-data.service';
import { PrismaService } from '@ghostfolio/api/services/prisma/prisma.service';
@ -215,10 +215,10 @@ export class DataProviderService implements OnModuleInit {
from: Date,
to: Date
): Promise<{
[symbol: string]: { [date: string]: IDataProviderHistoricalResponse };
[symbol: string]: { [date: string]: DataProviderHistoricalResponse };
}> {
let response: {
[symbol: string]: { [date: string]: IDataProviderHistoricalResponse };
[symbol: string]: { [date: string]: DataProviderHistoricalResponse };
} = {};
if (isEmpty(aItems) || !isValid(from) || !isValid(to)) {
@ -284,7 +284,7 @@ export class DataProviderService implements OnModuleInit {
from: Date;
to: Date;
}): Promise<{
[symbol: string]: { [date: string]: IDataProviderHistoricalResponse };
[symbol: string]: { [date: string]: DataProviderHistoricalResponse };
}> {
for (const { currency, rootCurrency } of DERIVED_CURRENCIES) {
if (
@ -317,11 +317,11 @@ export class DataProviderService implements OnModuleInit {
);
const result: {
[symbol: string]: { [date: string]: IDataProviderHistoricalResponse };
[symbol: string]: { [date: string]: DataProviderHistoricalResponse };
} = {};
const promises: Promise<{
data: { [date: string]: IDataProviderHistoricalResponse };
data: { [date: string]: DataProviderHistoricalResponse };
symbol: string;
}>[] = [];
for (const { dataSource, symbol } of assetProfileIdentifiers) {
@ -329,7 +329,7 @@ export class DataProviderService implements OnModuleInit {
if (dataProvider.canHandle(symbol)) {
if (symbol === `${DEFAULT_CURRENCY}USX`) {
const data: {
[date: string]: IDataProviderHistoricalResponse;
[date: string]: DataProviderHistoricalResponse;
} = {};
for (const date of eachDayOfInterval({ end: to, start: from })) {
@ -399,10 +399,10 @@ export class DataProviderService implements OnModuleInit {
useCache?: boolean;
user?: UserWithSettings;
}): Promise<{
[symbol: string]: IDataProviderResponse;
[symbol: string]: DataProviderResponse;
}> {
const response: {
[symbol: string]: IDataProviderResponse;
[symbol: string]: DataProviderResponse;
} = {};
const startTimeTotal = performance.now();
@ -716,7 +716,7 @@ export class DataProviderService implements OnModuleInit {
}: {
allData: {
data: {
[date: string]: IDataProviderHistoricalResponse;
[date: string]: DataProviderHistoricalResponse;
};
symbol: string;
}[];
@ -728,7 +728,7 @@ export class DataProviderService implements OnModuleInit {
})?.data;
const data: {
[date: string]: IDataProviderHistoricalResponse;
[date: string]: DataProviderHistoricalResponse;
} = {};
for (const date in rootData) {

14
apps/api/src/services/data-provider/eod-historical-data/eod-historical-data.service.ts

@ -8,8 +8,8 @@ import {
GetSearchParams
} from '@ghostfolio/api/services/data-provider/interfaces/data-provider.interface';
import {
IDataProviderHistoricalResponse,
IDataProviderResponse
DataProviderHistoricalResponse,
DataProviderResponse
} from '@ghostfolio/api/services/interfaces/interfaces';
import { SymbolProfileService } from '@ghostfolio/api/services/symbol-profile/symbol-profile.service';
import {
@ -89,7 +89,7 @@ export class EodHistoricalDataService implements DataProviderInterface {
symbol,
to
}: GetDividendsParams): Promise<{
[date: string]: IDataProviderHistoricalResponse;
[date: string]: DataProviderHistoricalResponse;
}> {
symbol = this.convertToEodSymbol(symbol);
@ -99,7 +99,7 @@ export class EodHistoricalDataService implements DataProviderInterface {
try {
const response: {
[date: string]: IDataProviderHistoricalResponse;
[date: string]: DataProviderHistoricalResponse;
} = {};
const historicalResult = await fetch(
@ -141,7 +141,7 @@ export class EodHistoricalDataService implements DataProviderInterface {
symbol,
to
}: GetHistoricalParams): Promise<{
[symbol: string]: { [date: string]: IDataProviderHistoricalResponse };
[symbol: string]: { [date: string]: DataProviderHistoricalResponse };
}> {
symbol = this.convertToEodSymbol(symbol);
@ -198,8 +198,8 @@ export class EodHistoricalDataService implements DataProviderInterface {
public async getQuotes({
requestTimeout = this.configurationService.get('REQUEST_TIMEOUT'),
symbols
}: GetQuotesParams): Promise<{ [symbol: string]: IDataProviderResponse }> {
const response: { [symbol: string]: IDataProviderResponse } = {};
}: GetQuotesParams): Promise<{ [symbol: string]: DataProviderResponse }> {
const response: { [symbol: string]: DataProviderResponse } = {};
if (symbols.length <= 0) {
return response;

14
apps/api/src/services/data-provider/financial-modeling-prep/financial-modeling-prep.service.ts

@ -9,8 +9,8 @@ import {
GetSearchParams
} from '@ghostfolio/api/services/data-provider/interfaces/data-provider.interface';
import {
IDataProviderHistoricalResponse,
IDataProviderResponse
DataProviderHistoricalResponse,
DataProviderResponse
} from '@ghostfolio/api/services/interfaces/interfaces';
import { PrismaService } from '@ghostfolio/api/services/prisma/prisma.service';
import {
@ -245,7 +245,7 @@ export class FinancialModelingPrepService implements DataProviderInterface {
try {
const response: {
[date: string]: IDataProviderHistoricalResponse;
[date: string]: DataProviderHistoricalResponse;
} = {};
const dividends = await fetch(
@ -289,11 +289,11 @@ export class FinancialModelingPrepService implements DataProviderInterface {
symbol,
to
}: GetHistoricalParams): Promise<{
[symbol: string]: { [date: string]: IDataProviderHistoricalResponse };
[symbol: string]: { [date: string]: DataProviderHistoricalResponse };
}> {
const MAX_YEARS_PER_REQUEST = 5;
const result: {
[symbol: string]: { [date: string]: IDataProviderHistoricalResponse };
[symbol: string]: { [date: string]: DataProviderHistoricalResponse };
} = {
[symbol]: {}
};
@ -353,8 +353,8 @@ export class FinancialModelingPrepService implements DataProviderInterface {
public async getQuotes({
requestTimeout = this.configurationService.get('REQUEST_TIMEOUT'),
symbols
}: GetQuotesParams): Promise<{ [symbol: string]: IDataProviderResponse }> {
const response: { [symbol: string]: IDataProviderResponse } = {};
}: GetQuotesParams): Promise<{ [symbol: string]: DataProviderResponse }> {
const response: { [symbol: string]: DataProviderResponse } = {};
if (symbols.length <= 0) {
return response;

14
apps/api/src/services/data-provider/ghostfolio/ghostfolio.service.ts

@ -9,8 +9,8 @@ import {
GetSearchParams
} from '@ghostfolio/api/services/data-provider/interfaces/data-provider.interface';
import {
IDataProviderHistoricalResponse,
IDataProviderResponse
DataProviderHistoricalResponse,
DataProviderResponse
} from '@ghostfolio/api/services/interfaces/interfaces';
import { PropertyService } from '@ghostfolio/api/services/property/property.service';
import {
@ -111,10 +111,10 @@ export class GhostfolioService implements DataProviderInterface {
symbol,
to
}: GetDividendsParams): Promise<{
[date: string]: IDataProviderHistoricalResponse;
[date: string]: DataProviderHistoricalResponse;
}> {
let dividends: {
[date: string]: IDataProviderHistoricalResponse;
[date: string]: DataProviderHistoricalResponse;
} = {};
try {
@ -164,7 +164,7 @@ export class GhostfolioService implements DataProviderInterface {
symbol,
to
}: GetHistoricalParams): Promise<{
[symbol: string]: { [date: string]: IDataProviderHistoricalResponse };
[symbol: string]: { [date: string]: DataProviderHistoricalResponse };
}> {
try {
const response = await fetch(
@ -228,9 +228,9 @@ export class GhostfolioService implements DataProviderInterface {
requestTimeout = this.configurationService.get('REQUEST_TIMEOUT'),
symbols
}: GetQuotesParams): Promise<{
[symbol: string]: IDataProviderResponse;
[symbol: string]: DataProviderResponse;
}> {
let quotes: { [symbol: string]: IDataProviderResponse } = {};
let quotes: { [symbol: string]: DataProviderResponse } = {};
if (symbols.length <= 0) {
return quotes;

12
apps/api/src/services/data-provider/google-sheets/google-sheets.service.ts

@ -8,8 +8,8 @@ import {
GetSearchParams
} from '@ghostfolio/api/services/data-provider/interfaces/data-provider.interface';
import {
IDataProviderHistoricalResponse,
IDataProviderResponse
DataProviderHistoricalResponse,
DataProviderResponse
} from '@ghostfolio/api/services/interfaces/interfaces';
import { PrismaService } from '@ghostfolio/api/services/prisma/prisma.service';
import { SymbolProfileService } from '@ghostfolio/api/services/symbol-profile/symbol-profile.service';
@ -60,7 +60,7 @@ export class GoogleSheetsService implements DataProviderInterface {
symbol,
to
}: GetHistoricalParams): Promise<{
[symbol: string]: { [date: string]: IDataProviderHistoricalResponse };
[symbol: string]: { [date: string]: DataProviderHistoricalResponse };
}> {
try {
const sheet = await this.getSheet({
@ -71,7 +71,7 @@ export class GoogleSheetsService implements DataProviderInterface {
const rows = await sheet.getRows();
const historicalData: {
[date: string]: IDataProviderHistoricalResponse;
[date: string]: DataProviderHistoricalResponse;
} = {};
rows
@ -104,8 +104,8 @@ export class GoogleSheetsService implements DataProviderInterface {
public async getQuotes({
symbols
}: GetQuotesParams): Promise<{ [symbol: string]: IDataProviderResponse }> {
const response: { [symbol: string]: IDataProviderResponse } = {};
}: GetQuotesParams): Promise<{ [symbol: string]: DataProviderResponse }> {
const response: { [symbol: string]: DataProviderResponse } = {};
if (symbols.length <= 0) {
return response;

10
apps/api/src/services/data-provider/interfaces/data-provider.interface.ts

@ -1,6 +1,6 @@
import {
IDataProviderHistoricalResponse,
IDataProviderResponse
DataProviderHistoricalResponse,
DataProviderResponse
} from '@ghostfolio/api/services/interfaces/interfaces';
import {
DataProviderInfo,
@ -26,7 +26,7 @@ export interface DataProviderInterface {
symbol,
to
}: GetDividendsParams): Promise<{
[date: string]: IDataProviderHistoricalResponse;
[date: string]: DataProviderHistoricalResponse;
}>;
getHistorical({
@ -36,7 +36,7 @@ export interface DataProviderInterface {
symbol,
to
}: GetHistoricalParams): Promise<{
[symbol: string]: { [date: string]: IDataProviderHistoricalResponse };
[symbol: string]: { [date: string]: DataProviderHistoricalResponse };
}>; // TODO: Return only one symbol
getMaxNumberOfSymbolsPerRequest?(): number;
@ -46,7 +46,7 @@ export interface DataProviderInterface {
getQuotes({
requestTimeout,
symbols
}: GetQuotesParams): Promise<{ [symbol: string]: IDataProviderResponse }>;
}: GetQuotesParams): Promise<{ [symbol: string]: DataProviderResponse }>;
getTestSymbol(): string;

12
apps/api/src/services/data-provider/manual/manual.service.ts

@ -8,8 +8,8 @@ import {
GetSearchParams
} from '@ghostfolio/api/services/data-provider/interfaces/data-provider.interface';
import {
IDataProviderHistoricalResponse,
IDataProviderResponse
DataProviderHistoricalResponse,
DataProviderResponse
} from '@ghostfolio/api/services/interfaces/interfaces';
import { PrismaService } from '@ghostfolio/api/services/prisma/prisma.service';
import { SymbolProfileService } from '@ghostfolio/api/services/symbol-profile/symbol-profile.service';
@ -77,7 +77,7 @@ export class ManualService implements DataProviderInterface {
symbol,
to
}: GetHistoricalParams): Promise<{
[symbol: string]: { [date: string]: IDataProviderHistoricalResponse };
[symbol: string]: { [date: string]: DataProviderHistoricalResponse };
}> {
try {
const [symbolProfile] = await this.symbolProfileService.getSymbolProfiles(
@ -88,7 +88,7 @@ export class ManualService implements DataProviderInterface {
if (defaultMarketPrice) {
const historical: {
[symbol: string]: { [date: string]: IDataProviderHistoricalResponse };
[symbol: string]: { [date: string]: DataProviderHistoricalResponse };
} = {
[symbol]: {}
};
@ -132,8 +132,8 @@ export class ManualService implements DataProviderInterface {
public async getQuotes({
symbols
}: GetQuotesParams): Promise<{ [symbol: string]: IDataProviderResponse }> {
const response: { [symbol: string]: IDataProviderResponse } = {};
}: GetQuotesParams): Promise<{ [symbol: string]: DataProviderResponse }> {
const response: { [symbol: string]: DataProviderResponse } = {};
if (symbols.length <= 0) {
return response;

2
apps/api/src/services/data-provider/rapid-api/interfaces/interfaces.ts

@ -1 +1 @@
export interface IRapidApiResponse {}
export interface RapidApiResponse {}

8
apps/api/src/services/data-provider/rapid-api/rapid-api.service.ts

@ -8,8 +8,8 @@ import {
GetSearchParams
} from '@ghostfolio/api/services/data-provider/interfaces/data-provider.interface';
import {
IDataProviderHistoricalResponse,
IDataProviderResponse
DataProviderHistoricalResponse,
DataProviderResponse
} from '@ghostfolio/api/services/interfaces/interfaces';
import {
ghostfolioFearAndGreedIndexSymbol,
@ -59,7 +59,7 @@ export class RapidApiService implements DataProviderInterface {
symbol,
to
}: GetHistoricalParams): Promise<{
[symbol: string]: { [date: string]: IDataProviderHistoricalResponse };
[symbol: string]: { [date: string]: DataProviderHistoricalResponse };
}> {
try {
if (
@ -96,7 +96,7 @@ export class RapidApiService implements DataProviderInterface {
public async getQuotes({
symbols
}: GetQuotesParams): Promise<{ [symbol: string]: IDataProviderResponse }> {
}: GetQuotesParams): Promise<{ [symbol: string]: DataProviderResponse }> {
if (symbols.length <= 0) {
return {};
}

14
apps/api/src/services/data-provider/yahoo-finance/yahoo-finance.service.ts

@ -10,8 +10,8 @@ import {
GetSearchParams
} from '@ghostfolio/api/services/data-provider/interfaces/data-provider.interface';
import {
IDataProviderHistoricalResponse,
IDataProviderResponse
DataProviderHistoricalResponse,
DataProviderResponse
} from '@ghostfolio/api/services/interfaces/interfaces';
import { DEFAULT_CURRENCY } from '@ghostfolio/common/config';
import { DATE_FORMAT } from '@ghostfolio/common/helper';
@ -96,7 +96,7 @@ export class YahooFinanceService implements DataProviderInterface {
)
);
const response: {
[date: string]: IDataProviderHistoricalResponse;
[date: string]: DataProviderHistoricalResponse;
} = {};
for (const historicalItem of historicalResult) {
@ -124,7 +124,7 @@ export class YahooFinanceService implements DataProviderInterface {
symbol,
to
}: GetHistoricalParams): Promise<{
[symbol: string]: { [date: string]: IDataProviderHistoricalResponse };
[symbol: string]: { [date: string]: DataProviderHistoricalResponse };
}> {
if (isSameDay(from, to)) {
to = addDays(to, 1);
@ -145,7 +145,7 @@ export class YahooFinanceService implements DataProviderInterface {
);
const response: {
[symbol: string]: { [date: string]: IDataProviderHistoricalResponse };
[symbol: string]: { [date: string]: DataProviderHistoricalResponse };
} = {};
response[symbol] = {};
@ -183,8 +183,8 @@ export class YahooFinanceService implements DataProviderInterface {
public async getQuotes({
symbols
}: GetQuotesParams): Promise<{ [symbol: string]: IDataProviderResponse }> {
const response: { [symbol: string]: IDataProviderResponse } = {};
}: GetQuotesParams): Promise<{ [symbol: string]: DataProviderResponse }> {
const response: { [symbol: string]: DataProviderResponse } = {};
if (symbols.length <= 0) {
return response;

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

@ -1,6 +1,6 @@
import { LogPerformance } from '@ghostfolio/api/interceptors/performance-logging/performance-logging.interceptor';
import { DataProviderService } from '@ghostfolio/api/services/data-provider/data-provider.service';
import { IDataGatheringItem } from '@ghostfolio/api/services/interfaces/interfaces';
import { DataGatheringItem } from '@ghostfolio/api/services/interfaces/interfaces';
import { MarketDataService } from '@ghostfolio/api/services/market-data/market-data.service';
import { PrismaService } from '@ghostfolio/api/services/prisma/prisma.service';
import { PropertyService } from '@ghostfolio/api/services/property/property.service';
@ -29,7 +29,7 @@ import ms from 'ms';
@Injectable()
export class ExchangeRateDataService {
private currencies: string[] = [];
private currencyPairs: IDataGatheringItem[] = [];
private currencyPairs: DataGatheringItem[] = [];
private exchangeRates: { [currencyPair: string]: number } = {};
public constructor(

6
apps/api/src/services/interfaces/interfaces.ts

@ -6,11 +6,11 @@ import { MarketState } from '@ghostfolio/common/types';
import { DataSource } from '@prisma/client';
export interface IDataProviderHistoricalResponse {
export interface DataProviderHistoricalResponse {
marketPrice: number;
}
export interface IDataProviderResponse {
export interface DataProviderResponse {
currency: string;
dataProviderInfo?: DataProviderInfo;
dataSource: DataSource;
@ -18,6 +18,6 @@ export interface IDataProviderResponse {
marketState: MarketState;
}
export interface IDataGatheringItem extends AssetProfileIdentifier {
export interface DataGatheringItem extends AssetProfileIdentifier {
date?: Date;
}

4
apps/api/src/services/market-data/market-data.service.ts

@ -1,6 +1,6 @@
import { UpdateMarketDataDto } from '@ghostfolio/api/app/admin/update-market-data.dto';
import { DateQuery } from '@ghostfolio/api/app/portfolio/interfaces/date-query.interface';
import { IDataGatheringItem } from '@ghostfolio/api/services/interfaces/interfaces';
import { DataGatheringItem } from '@ghostfolio/api/services/interfaces/interfaces';
import { PrismaService } from '@ghostfolio/api/services/prisma/prisma.service';
import { resetHours } from '@ghostfolio/common/helper';
import { AssetProfileIdentifier } from '@ghostfolio/common/interfaces';
@ -30,7 +30,7 @@ export class MarketDataService {
dataSource,
date = new Date(),
symbol
}: IDataGatheringItem): Promise<MarketData> {
}: DataGatheringItem): Promise<MarketData> {
return await this.prismaService.marketData.findFirst({
where: {
dataSource,

4
apps/api/src/services/queues/data-gathering/data-gathering.processor.ts

@ -1,6 +1,6 @@
import { DataProviderService } from '@ghostfolio/api/services/data-provider/data-provider.service';
import { AssetProfileDelistedError } from '@ghostfolio/api/services/data-provider/errors/asset-profile-delisted.error';
import { IDataGatheringItem } from '@ghostfolio/api/services/interfaces/interfaces';
import { DataGatheringItem } from '@ghostfolio/api/services/interfaces/interfaces';
import { MarketDataService } from '@ghostfolio/api/services/market-data/market-data.service';
import { SymbolProfileService } from '@ghostfolio/api/services/symbol-profile/symbol-profile.service';
import {
@ -99,7 +99,7 @@ export class DataGatheringProcessor {
),
name: GATHER_HISTORICAL_MARKET_DATA_PROCESS_JOB_NAME
})
public async gatherHistoricalMarketData(job: Job<IDataGatheringItem>) {
public async gatherHistoricalMarketData(job: Job<DataGatheringItem>) {
const { dataSource, date, symbol } = job.data;
try {

12
apps/api/src/services/queues/data-gathering/data-gathering.service.ts

@ -1,7 +1,7 @@
import { DataProviderService } from '@ghostfolio/api/services/data-provider/data-provider.service';
import { DataEnhancerInterface } from '@ghostfolio/api/services/data-provider/interfaces/data-enhancer.interface';
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service';
import { IDataGatheringItem } from '@ghostfolio/api/services/interfaces/interfaces';
import { DataGatheringItem } from '@ghostfolio/api/services/interfaces/interfaces';
import { MarketDataService } from '@ghostfolio/api/services/market-data/market-data.service';
import { PrismaService } from '@ghostfolio/api/services/prisma/prisma.service';
import { PropertyService } from '@ghostfolio/api/services/property/property.service';
@ -94,7 +94,7 @@ export class DataGatheringService {
});
}
public async gatherSymbol({ dataSource, date, symbol }: IDataGatheringItem) {
public async gatherSymbol({ dataSource, date, symbol }: DataGatheringItem) {
await this.marketDataService.deleteMany({ dataSource, symbol });
const dataGatheringItems = (await this.getSymbolsMax())
@ -276,7 +276,7 @@ export class DataGatheringService {
dataGatheringItems,
priority
}: {
dataGatheringItems: IDataGatheringItem[];
dataGatheringItems: DataGatheringItem[];
priority: number;
}) {
await this.addJobsToQueue(
@ -348,7 +348,7 @@ export class DataGatheringService {
});
}
private async getCurrencies7D(): Promise<IDataGatheringItem[]> {
private async getCurrencies7D(): Promise<DataGatheringItem[]> {
const assetProfileIdentifiersWithCompleteMarketData =
await this.getAssetProfileIdentifiersWithCompleteMarketData();
@ -376,7 +376,7 @@ export class DataGatheringService {
withUserSubscription = false
}: {
withUserSubscription?: boolean;
}): Promise<IDataGatheringItem[]> {
}): Promise<DataGatheringItem[]> {
const symbolProfiles =
await this.symbolProfileService.getActiveSymbolProfilesByUserSubscription(
{
@ -407,7 +407,7 @@ export class DataGatheringService {
});
}
private async getSymbolsMax(): Promise<IDataGatheringItem[]> {
private async getSymbolsMax(): Promise<DataGatheringItem[]> {
const benchmarkAssetProfileIdMap: { [key: string]: boolean } = {};
(
(await this.propertyService.getByKey<BenchmarkProperty[]>(

2
apps/api/src/services/queues/portfolio-snapshot/interfaces/portfolio-snapshot-queue-job.interface.ts

@ -1,7 +1,7 @@
import { Filter } from '@ghostfolio/common/interfaces';
import { PerformanceCalculationType } from '@ghostfolio/common/types/performance-calculation-type.type';
export interface IPortfolioSnapshotQueueJob {
export interface PortfolioSnapshotQueueJob {
calculationType: PerformanceCalculationType;
filters: Filter[];
userCurrency: string;

6
apps/api/src/services/queues/portfolio-snapshot/portfolio-snapshot.processor.ts

@ -16,7 +16,7 @@ import { Injectable, Logger } from '@nestjs/common';
import { Job } from 'bull';
import { addMilliseconds } from 'date-fns';
import { IPortfolioSnapshotQueueJob } from './interfaces/portfolio-snapshot-queue-job.interface';
import { PortfolioSnapshotQueueJob } from './interfaces/portfolio-snapshot-queue-job.interface';
@Injectable()
@Processor(PORTFOLIO_SNAPSHOT_COMPUTATION_QUEUE)
@ -37,9 +37,7 @@ export class PortfolioSnapshotProcessor {
),
name: PORTFOLIO_SNAPSHOT_PROCESS_JOB_NAME
})
public async calculatePortfolioSnapshot(
job: Job<IPortfolioSnapshotQueueJob>
) {
public async calculatePortfolioSnapshot(job: Job<PortfolioSnapshotQueueJob>) {
try {
const startTime = performance.now();

4
apps/api/src/services/queues/portfolio-snapshot/portfolio-snapshot.service.mock.ts

@ -1,13 +1,13 @@
import { Job, JobOptions } from 'bull';
import { setTimeout } from 'timers/promises';
import { IPortfolioSnapshotQueueJob } from './interfaces/portfolio-snapshot-queue-job.interface';
import { PortfolioSnapshotQueueJob } from './interfaces/portfolio-snapshot-queue-job.interface';
export const PortfolioSnapshotServiceMock = {
addJobToQueue({
opts
}: {
data: IPortfolioSnapshotQueueJob;
data: PortfolioSnapshotQueueJob;
name: string;
opts?: JobOptions;
}): Promise<Job<any>> {

4
apps/api/src/services/queues/portfolio-snapshot/portfolio-snapshot.service.ts

@ -4,7 +4,7 @@ import { InjectQueue } from '@nestjs/bull';
import { Injectable } from '@nestjs/common';
import { JobOptions, Queue } from 'bull';
import { IPortfolioSnapshotQueueJob } from './interfaces/portfolio-snapshot-queue-job.interface';
import { PortfolioSnapshotQueueJob } from './interfaces/portfolio-snapshot-queue-job.interface';
@Injectable()
export class PortfolioSnapshotService {
@ -18,7 +18,7 @@ export class PortfolioSnapshotService {
name,
opts
}: {
data: IPortfolioSnapshotQueueJob;
data: PortfolioSnapshotQueueJob;
name: string;
opts?: JobOptions;
}) {

2
apps/client/src/app/components/rule/rule-settings-dialog/interfaces/interfaces.ts

@ -3,7 +3,7 @@ import {
XRayRulesSettings
} from '@ghostfolio/common/interfaces';
export interface IRuleSettingsDialogParams {
export interface RuleSettingsDialogParams {
categoryName: string;
locale: string;
rule: PortfolioReportRule;

4
apps/client/src/app/components/rule/rule-settings-dialog/rule-settings-dialog.component.ts

@ -12,7 +12,7 @@ import {
} from '@angular/material/dialog';
import { MatSliderModule } from '@angular/material/slider';
import { IRuleSettingsDialogParams } from './interfaces/interfaces';
import { RuleSettingsDialogParams } from './interfaces/interfaces';
@Component({
imports: [
@ -31,7 +31,7 @@ export class GfRuleSettingsDialogComponent {
public settings: XRayRulesSettings['AccountClusterRiskCurrentInvestment'];
public constructor(
@Inject(MAT_DIALOG_DATA) public data: IRuleSettingsDialogParams,
@Inject(MAT_DIALOG_DATA) public data: RuleSettingsDialogParams,
public dialogRef: MatDialogRef<GfRuleSettingsDialogComponent>
) {}
}

4
apps/client/src/app/components/rule/rule.component.ts

@ -31,7 +31,7 @@ import { DeviceDetectorService } from 'ngx-device-detector';
import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader';
import { Subject, takeUntil } from 'rxjs';
import { IRuleSettingsDialogParams } from './rule-settings-dialog/interfaces/interfaces';
import { RuleSettingsDialogParams } from './rule-settings-dialog/interfaces/interfaces';
import { GfRuleSettingsDialogComponent } from './rule-settings-dialog/rule-settings-dialog.component';
@Component({
@ -83,7 +83,7 @@ export class GfRuleComponent implements OnInit {
rule,
categoryName: this.categoryName,
settings: this.settings
} as IRuleSettingsDialogParams,
} as RuleSettingsDialogParams,
width: this.deviceType === 'mobile' ? '100vw' : '50rem'
});

4
apps/client/src/app/core/notification/alert-dialog/alert-dialog.component.ts

@ -2,7 +2,7 @@ import { Component } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { MatDialogModule, MatDialogRef } from '@angular/material/dialog';
import { IAlertDialogParams } from './interfaces/interfaces';
import { AlertDialogParams } from './interfaces/interfaces';
@Component({
imports: [MatButtonModule, MatDialogModule],
@ -17,7 +17,7 @@ export class GfAlertDialogComponent {
public constructor(public dialogRef: MatDialogRef<GfAlertDialogComponent>) {}
public initialize(aParams: IAlertDialogParams) {
public initialize(aParams: AlertDialogParams) {
this.discardLabel = aParams.discardLabel;
this.message = aParams.message;
this.title = aParams.title;

2
apps/client/src/app/core/notification/alert-dialog/interfaces/interfaces.ts

@ -1,4 +1,4 @@
export interface IAlertDialogParams {
export interface AlertDialogParams {
confirmLabel?: string;
discardLabel?: string;
message?: string;

4
apps/client/src/app/core/notification/confirmation-dialog/confirmation-dialog.component.ts

@ -3,7 +3,7 @@ import { MatButtonModule } from '@angular/material/button';
import { MatDialogModule, MatDialogRef } from '@angular/material/dialog';
import { ConfirmationDialogType } from './confirmation-dialog.type';
import { IConfirmDialogParams } from './interfaces/interfaces';
import { ConfirmDialogParams } from './interfaces/interfaces';
@Component({
imports: [MatButtonModule, MatDialogModule],
@ -29,7 +29,7 @@ export class GfConfirmationDialogComponent {
}
}
public initialize(aParams: IConfirmDialogParams) {
public initialize(aParams: ConfirmDialogParams) {
this.confirmLabel = aParams.confirmLabel;
this.confirmType = aParams.confirmType;
this.discardLabel = aParams.discardLabel;

2
apps/client/src/app/core/notification/confirmation-dialog/interfaces/interfaces.ts

@ -1,6 +1,6 @@
import { ConfirmationDialogType } from '../confirmation-dialog.type';
export interface IConfirmDialogParams {
export interface ConfirmDialogParams {
confirmLabel?: string;
confirmType: ConfirmationDialogType;
discardLabel?: string;

6
apps/client/src/app/core/notification/interfaces/interfaces.ts

@ -1,13 +1,13 @@
import { ConfirmationDialogType } from '../confirmation-dialog/confirmation-dialog.type';
export interface IAlertParams {
export interface AlertParams {
discardFn?: () => void;
discardLabel?: string;
message?: string;
title: string;
}
export interface IConfirmParams {
export interface ConfirmParams {
confirmFn: () => void;
confirmLabel?: string;
confirmType?: ConfirmationDialogType;
@ -18,7 +18,7 @@ export interface IConfirmParams {
title: string;
}
export interface IPromptParams {
export interface PromptParams {
confirmFn: (value: string) => void;
confirmLabel?: string;
defaultValue?: string;

12
apps/client/src/app/core/notification/notification.service.ts

@ -8,9 +8,9 @@ import { GfAlertDialogComponent } from './alert-dialog/alert-dialog.component';
import { GfConfirmationDialogComponent } from './confirmation-dialog/confirmation-dialog.component';
import { ConfirmationDialogType } from './confirmation-dialog/confirmation-dialog.type';
import {
IAlertParams,
IConfirmParams,
IPromptParams
AlertParams,
ConfirmParams,
PromptParams
} from './interfaces/interfaces';
import { GfPromptDialogComponent } from './prompt-dialog/prompt-dialog.component';
@ -21,7 +21,7 @@ export class NotificationService {
public constructor(private matDialog: MatDialog) {}
public alert(aParams: IAlertParams) {
public alert(aParams: AlertParams) {
if (!aParams.discardLabel) {
aParams.discardLabel = translate('CLOSE');
}
@ -45,7 +45,7 @@ export class NotificationService {
});
}
public confirm(aParams: IConfirmParams) {
public confirm(aParams: ConfirmParams) {
if (!aParams.confirmLabel) {
aParams.confirmLabel = translate('YES');
}
@ -78,7 +78,7 @@ export class NotificationService {
});
}
public prompt(aParams: IPromptParams) {
public prompt(aParams: PromptParams) {
if (!aParams.confirmLabel) {
aParams.confirmLabel = translate('OK');
}

4
apps/client/src/app/pages/resources/glossary/resources-glossary.component.html

@ -105,8 +105,8 @@
<h3 class="h5 mt-0">Personal Finance Tools</h3>
<div class="mb-1">
Personal finance tools are software applications that help
individuals manage their money, track expenses, set budgets,
monitor investments, and make informed financial decisions.
manage your money, track expenses, set budgets, monitor
investments, and make informed financial decisions.
</div>
<div>
<a [routerLink]="routerLinkResourcesPersonalFinanceTools"

4
apps/client/src/app/services/admin.service.ts

@ -1,7 +1,7 @@
import { UpdateAssetProfileDto } from '@ghostfolio/api/app/admin/update-asset-profile.dto';
import { CreatePlatformDto } from '@ghostfolio/api/app/platform/create-platform.dto';
import { UpdatePlatformDto } from '@ghostfolio/api/app/platform/update-platform.dto';
import { IDataProviderHistoricalResponse } from '@ghostfolio/api/services/interfaces/interfaces';
import { DataProviderHistoricalResponse } from '@ghostfolio/api/services/interfaces/interfaces';
import {
HEADER_KEY_SKIP_INTERCEPTOR,
HEADER_KEY_TOKEN
@ -208,7 +208,7 @@ export class AdminService {
}) {
const url = `/api/v1/symbol/${dataSource}/${symbol}/${dateString}`;
return this.http.get<IDataProviderHistoricalResponse>(url);
return this.http.get<DataProviderHistoricalResponse>(url);
}
public patchAssetProfile(

4
apps/client/src/app/services/data.service.ts

@ -19,7 +19,7 @@ import { DeleteOwnUserDto } from '@ghostfolio/api/app/user/delete-own-user.dto';
import { UserItem } from '@ghostfolio/api/app/user/interfaces/user-item.interface';
import { UpdateOwnAccessTokenDto } from '@ghostfolio/api/app/user/update-own-access-token.dto';
import { UpdateUserSettingDto } from '@ghostfolio/api/app/user/update-user-setting.dto';
import { IDataProviderHistoricalResponse } from '@ghostfolio/api/services/interfaces/interfaces';
import { DataProviderHistoricalResponse } from '@ghostfolio/api/services/interfaces/interfaces';
import { PropertyDto } from '@ghostfolio/api/services/property/property.dto';
import { DATE_FORMAT } from '@ghostfolio/common/helper';
import {
@ -291,7 +291,7 @@ export class DataService {
date: Date;
symbol: string;
}) {
return this.http.get<IDataProviderHistoricalResponse>(
return this.http.get<DataProviderHistoricalResponse>(
`/api/v1/exchange-rate/${symbol}/${format(date, DATE_FORMAT, { in: utc })}`
);
}

4
apps/client/src/main.ts

@ -1,5 +1,5 @@
import { locale } from '@ghostfolio/common/config';
import { InfoItem } from '@ghostfolio/common/interfaces';
import { InfoResponse } from '@ghostfolio/common/interfaces';
import { filterGlobalPermissions } from '@ghostfolio/common/permissions';
import { enableProdMode } from '@angular/core';
@ -11,7 +11,7 @@ import { environment } from './environments/environment';
(async () => {
const response = await fetch('/api/v1/info');
const info: InfoItem = await response.json();
const info: InfoResponse = await response.json();
const utmSource = window.localStorage.getItem('utm_source') as
| 'ios'
| 'trusted-web-activity';

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

@ -50,6 +50,7 @@ import type { DividendsResponse } from './responses/dividends-response.interface
import type { ResponseError } from './responses/errors.interface';
import type { HistoricalResponse } from './responses/historical-response.interface';
import type { ImportResponse } from './responses/import-response.interface';
import type { InfoResponse } from './responses/info-response.interface';
import type { LookupResponse } from './responses/lookup-response.interface';
import type { MarketDataDetailsResponse } from './responses/market-data-details-response.interface';
import type { MarketDataOfMarketsResponse } from './responses/market-data-of-markets-response.interface';
@ -112,6 +113,7 @@ export {
HoldingWithParents,
ImportResponse,
InfoItem,
InfoResponse,
InvestmentItem,
LineChartItem,
LookupItem,

4
libs/common/src/lib/interfaces/responses/dividends-response.interface.ts

@ -1,7 +1,7 @@
import { IDataProviderHistoricalResponse } from '@ghostfolio/api/services/interfaces/interfaces';
import { DataProviderHistoricalResponse } from '@ghostfolio/api/services/interfaces/interfaces';
export interface DividendsResponse {
dividends: {
[date: string]: IDataProviderHistoricalResponse;
[date: string]: DataProviderHistoricalResponse;
};
}

4
libs/common/src/lib/interfaces/responses/historical-response.interface.ts

@ -1,7 +1,7 @@
import { IDataProviderHistoricalResponse } from '@ghostfolio/api/services/interfaces/interfaces';
import { DataProviderHistoricalResponse } from '@ghostfolio/api/services/interfaces/interfaces';
export interface HistoricalResponse {
historicalData: {
[date: string]: IDataProviderHistoricalResponse;
[date: string]: DataProviderHistoricalResponse;
};
}

3
libs/common/src/lib/interfaces/responses/info-response.interface.ts

@ -0,0 +1,3 @@
import { InfoItem } from '../index';
export interface InfoResponse extends InfoItem {}

4
libs/common/src/lib/interfaces/responses/quotes-response.interface.ts

@ -1,5 +1,5 @@
import { IDataProviderResponse } from '@ghostfolio/api/services/interfaces/interfaces';
import { DataProviderResponse } from '@ghostfolio/api/services/interfaces/interfaces';
export interface QuotesResponse {
quotes: { [symbol: string]: IDataProviderResponse };
quotes: { [symbol: string]: DataProviderResponse };
}

8
libs/ui/src/lib/assistant/assistant-list-item/assistant-list-item.component.ts

@ -18,8 +18,8 @@ import { Params, RouterModule } from '@angular/router';
import { SearchMode } from '../enums/search-mode';
import {
IAssetSearchResultItem,
ISearchResultItem
AssetSearchResultItem,
SearchResultItem
} from '../interfaces/interfaces';
@Component({
@ -37,7 +37,7 @@ export class GfAssistantListItemComponent
return this.hasFocus;
}
@Input() item: ISearchResultItem;
@Input() item: SearchResultItem;
@Output() clicked = new EventEmitter<void>();
@ -86,7 +86,7 @@ export class GfAssistantListItemComponent
this.changeDetectorRef.markForCheck();
}
public isAsset(item: ISearchResultItem): item is IAssetSearchResultItem {
public isAsset(item: SearchResultItem): item is AssetSearchResultItem {
return (
(item.mode === SearchMode.ASSET_PROFILE ||
item.mode === SearchMode.HOLDING) &&

40
libs/ui/src/lib/assistant/assistant.component.ts

@ -62,9 +62,9 @@ import {
import { GfAssistantListItemComponent } from './assistant-list-item/assistant-list-item.component';
import { SearchMode } from './enums/search-mode';
import {
IDateRangeOption,
ISearchResultItem,
ISearchResults
DateRangeOption,
SearchResultItem,
SearchResults
} from './interfaces/interfaces';
@Component({
@ -140,7 +140,7 @@ export class GfAssistantComponent implements OnChanges, OnDestroy, OnInit {
public accounts: AccountWithPlatform[] = [];
public assetClasses: Filter[] = [];
public dateRangeFormControl = new FormControl<string>(undefined);
public dateRangeOptions: IDateRangeOption[] = [];
public dateRangeOptions: DateRangeOption[] = [];
public holdings: PortfolioPosition[] = [];
public isLoading = {
accounts: false,
@ -159,7 +159,7 @@ export class GfAssistantComponent implements OnChanges, OnDestroy, OnInit {
}
);
public searchFormControl = new FormControl('');
public searchResults: ISearchResults = {
public searchResults: SearchResults = {
accounts: [],
assetProfiles: [],
holdings: [],
@ -226,7 +226,7 @@ export class GfAssistantComponent implements OnChanges, OnDestroy, OnInit {
assetProfiles: [],
holdings: [],
quickLinks: []
} as ISearchResults;
} as SearchResults;
if (!searchTerm) {
return of(results).pipe(
@ -241,7 +241,7 @@ export class GfAssistantComponent implements OnChanges, OnDestroy, OnInit {
);
}
const accounts$: Observable<Partial<ISearchResults>> =
const accounts$: Observable<Partial<SearchResults>> =
this.searchAccounts(searchTerm).pipe(
map((accounts) => ({
accounts: accounts.slice(
@ -251,7 +251,7 @@ export class GfAssistantComponent implements OnChanges, OnDestroy, OnInit {
})),
catchError((error) => {
console.error('Error fetching accounts for assistant:', error);
return of({ accounts: [] as ISearchResultItem[] });
return of({ accounts: [] as SearchResultItem[] });
}),
tap(() => {
this.isLoading.accounts = false;
@ -259,7 +259,7 @@ export class GfAssistantComponent implements OnChanges, OnDestroy, OnInit {
})
);
const assetProfiles$: Observable<Partial<ISearchResults>> = this
const assetProfiles$: Observable<Partial<SearchResults>> = this
.hasPermissionToAccessAdminControl
? this.searchAssetProfiles(searchTerm).pipe(
map((assetProfiles) => ({
@ -273,21 +273,21 @@ export class GfAssistantComponent implements OnChanges, OnDestroy, OnInit {
'Error fetching asset profiles for assistant:',
error
);
return of({ assetProfiles: [] as ISearchResultItem[] });
return of({ assetProfiles: [] as SearchResultItem[] });
}),
tap(() => {
this.isLoading.assetProfiles = false;
this.changeDetectorRef.markForCheck();
})
)
: of({ assetProfiles: [] as ISearchResultItem[] }).pipe(
: of({ assetProfiles: [] as SearchResultItem[] }).pipe(
tap(() => {
this.isLoading.assetProfiles = false;
this.changeDetectorRef.markForCheck();
})
);
const holdings$: Observable<Partial<ISearchResults>> =
const holdings$: Observable<Partial<SearchResults>> =
this.searchHoldings(searchTerm).pipe(
map((holdings) => ({
holdings: holdings.slice(
@ -297,7 +297,7 @@ export class GfAssistantComponent implements OnChanges, OnDestroy, OnInit {
})),
catchError((error) => {
console.error('Error fetching holdings for assistant:', error);
return of({ holdings: [] as ISearchResultItem[] });
return of({ holdings: [] as SearchResultItem[] });
}),
tap(() => {
this.isLoading.holdings = false;
@ -305,7 +305,7 @@ export class GfAssistantComponent implements OnChanges, OnDestroy, OnInit {
})
);
const quickLinks$: Observable<Partial<ISearchResults>> = of(
const quickLinks$: Observable<Partial<SearchResults>> = of(
this.searchQuickLinks(searchTerm)
).pipe(
map((quickLinks) => ({
@ -322,7 +322,7 @@ export class GfAssistantComponent implements OnChanges, OnDestroy, OnInit {
return merge(accounts$, assetProfiles$, holdings$, quickLinks$).pipe(
scan(
(acc: ISearchResults, curr: Partial<ISearchResults>) => ({
(acc: SearchResults, curr: Partial<SearchResults>) => ({
...acc,
...curr
}),
@ -331,7 +331,7 @@ export class GfAssistantComponent implements OnChanges, OnDestroy, OnInit {
assetProfiles: [],
holdings: [],
quickLinks: []
} as ISearchResults
} as SearchResults
)
);
}),
@ -622,7 +622,7 @@ export class GfAssistantComponent implements OnChanges, OnDestroy, OnInit {
}, this.PRESELECTION_DELAY);
}
private searchAccounts(aSearchTerm: string): Observable<ISearchResultItem[]> {
private searchAccounts(aSearchTerm: string): Observable<SearchResultItem[]> {
return this.dataService
.fetchAccounts({
filters: [
@ -652,7 +652,7 @@ export class GfAssistantComponent implements OnChanges, OnDestroy, OnInit {
private searchAssetProfiles(
aSearchTerm: string
): Observable<ISearchResultItem[]> {
): Observable<SearchResultItem[]> {
return this.adminService
.fetchAdminMarketData({
filters: [
@ -685,7 +685,7 @@ export class GfAssistantComponent implements OnChanges, OnDestroy, OnInit {
);
}
private searchHoldings(aSearchTerm: string): Observable<ISearchResultItem[]> {
private searchHoldings(aSearchTerm: string): Observable<SearchResultItem[]> {
return this.dataService
.fetchPortfolioHoldings({
filters: [
@ -717,7 +717,7 @@ export class GfAssistantComponent implements OnChanges, OnDestroy, OnInit {
);
}
private searchQuickLinks(aSearchTerm: string): ISearchResultItem[] {
private searchQuickLinks(aSearchTerm: string): SearchResultItem[] {
const searchTerm = aSearchTerm.toLowerCase();
const allRoutes = Object.values(internalRoutes)

26
libs/ui/src/lib/assistant/interfaces/interfaces.ts

@ -3,38 +3,38 @@ import { AccountWithValue, DateRange } from '@ghostfolio/common/types';
import { SearchMode } from '../enums/search-mode';
export interface IAccountSearchResultItem
export interface AccountSearchResultItem
extends Pick<AccountWithValue, 'id' | 'name'> {
mode: SearchMode.ACCOUNT;
routerLink: string[];
}
export interface IAssetSearchResultItem extends AssetProfileIdentifier {
export interface AssetSearchResultItem extends AssetProfileIdentifier {
assetSubClassString: string;
currency: string;
mode: SearchMode.ASSET_PROFILE | SearchMode.HOLDING;
name: string;
}
export interface IDateRangeOption {
export interface DateRangeOption {
label: string;
value: DateRange;
}
export interface IQuickLinkSearchResultItem {
export interface QuickLinkSearchResultItem {
mode: SearchMode.QUICK_LINK;
name: string;
routerLink: string[];
}
export type ISearchResultItem =
| IAccountSearchResultItem
| IAssetSearchResultItem
| IQuickLinkSearchResultItem;
export type SearchResultItem =
| AccountSearchResultItem
| AssetSearchResultItem
| QuickLinkSearchResultItem;
export interface ISearchResults {
accounts: ISearchResultItem[];
assetProfiles: ISearchResultItem[];
holdings: ISearchResultItem[];
quickLinks: ISearchResultItem[];
export interface SearchResults {
accounts: SearchResultItem[];
assetProfiles: SearchResultItem[];
holdings: SearchResultItem[];
quickLinks: SearchResultItem[];
}

Loading…
Cancel
Save