Feature/eliminate circular dependencies in common library (#896)
* Eliminate circular dependencies * Update changelog
This commit is contained in:
parent
e55b05fe3d
commit
ea3a9d3b79
@ -23,6 +23,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- Upgraded `Nx` from version `13.8.5` to `14.1.4`
|
- Upgraded `Nx` from version `13.8.5` to `14.1.4`
|
||||||
- Upgraded `storybook` from version `6.4.18` to `6.4.22`
|
- Upgraded `storybook` from version `6.4.18` to `6.4.22`
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Eliminated the circular dependencies in the `@ghostfolio/common` library
|
||||||
|
|
||||||
## 1.145.0 - 07.05.2022
|
## 1.145.0 - 07.05.2022
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { EnhancedSymbolProfile } from '@ghostfolio/api/services/interfaces/symbol-profile.interface';
|
import { EnhancedSymbolProfile } from '@ghostfolio/api/services/interfaces/symbol-profile.interface';
|
||||||
|
import { HistoricalDataItem } from '@ghostfolio/common/interfaces';
|
||||||
import { OrderWithAccount } from '@ghostfolio/common/types';
|
import { OrderWithAccount } from '@ghostfolio/common/types';
|
||||||
import { Tag } from '@prisma/client';
|
import { Tag } from '@prisma/client';
|
||||||
|
|
||||||
@ -27,10 +28,3 @@ export interface HistoricalDataContainer {
|
|||||||
isAllTimeLow: boolean;
|
isAllTimeLow: boolean;
|
||||||
items: HistoricalDataItem[];
|
items: HistoricalDataItem[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface HistoricalDataItem {
|
|
||||||
averagePrice?: number;
|
|
||||||
date: string;
|
|
||||||
grossPerformancePercent?: number;
|
|
||||||
value: number;
|
|
||||||
}
|
|
||||||
|
@ -18,7 +18,6 @@ import { FeeRatioInitialInvestment } from '@ghostfolio/api/models/rules/fees/fee
|
|||||||
import { DataProviderService } from '@ghostfolio/api/services/data-provider/data-provider.service';
|
import { DataProviderService } from '@ghostfolio/api/services/data-provider/data-provider.service';
|
||||||
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data.service';
|
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data.service';
|
||||||
import { ImpersonationService } from '@ghostfolio/api/services/impersonation.service';
|
import { ImpersonationService } from '@ghostfolio/api/services/impersonation.service';
|
||||||
import { MarketState } from '@ghostfolio/api/services/interfaces/interfaces';
|
|
||||||
import { EnhancedSymbolProfile } from '@ghostfolio/api/services/interfaces/symbol-profile.interface';
|
import { EnhancedSymbolProfile } from '@ghostfolio/api/services/interfaces/symbol-profile.interface';
|
||||||
import { SymbolProfileService } from '@ghostfolio/api/services/symbol-profile.service';
|
import { SymbolProfileService } from '@ghostfolio/api/services/symbol-profile.service';
|
||||||
import {
|
import {
|
||||||
@ -30,6 +29,7 @@ import { DATE_FORMAT, parseDate } from '@ghostfolio/common/helper';
|
|||||||
import {
|
import {
|
||||||
Accounts,
|
Accounts,
|
||||||
Filter,
|
Filter,
|
||||||
|
HistoricalDataItem,
|
||||||
PortfolioDetails,
|
PortfolioDetails,
|
||||||
PortfolioPerformanceResponse,
|
PortfolioPerformanceResponse,
|
||||||
PortfolioReport,
|
PortfolioReport,
|
||||||
@ -72,7 +72,6 @@ import { isEmpty, sortBy, uniqBy } from 'lodash';
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
HistoricalDataContainer,
|
HistoricalDataContainer,
|
||||||
HistoricalDataItem,
|
|
||||||
PortfolioPositionDetail
|
PortfolioPositionDetail
|
||||||
} from './interfaces/portfolio-position-detail.interface';
|
} from './interfaces/portfolio-position-detail.interface';
|
||||||
import { PortfolioCalculator } from './portfolio-calculator';
|
import { PortfolioCalculator } from './portfolio-calculator';
|
||||||
@ -777,8 +776,7 @@ export class PortfolioService {
|
|||||||
position.grossPerformancePercentage?.toNumber() ?? null,
|
position.grossPerformancePercentage?.toNumber() ?? null,
|
||||||
investment: new Big(position.investment).toNumber(),
|
investment: new Big(position.investment).toNumber(),
|
||||||
marketState:
|
marketState:
|
||||||
dataProviderResponses[position.symbol]?.marketState ??
|
dataProviderResponses[position.symbol]?.marketState ?? 'delayed',
|
||||||
MarketState.delayed,
|
|
||||||
name: symbolProfileMap[position.symbol].name,
|
name: symbolProfileMap[position.symbol].name,
|
||||||
netPerformance: position.netPerformance?.toNumber() ?? null,
|
netPerformance: position.netPerformance?.toNumber() ?? null,
|
||||||
netPerformancePercentage:
|
netPerformancePercentage:
|
||||||
@ -1062,7 +1060,7 @@ export class PortfolioService {
|
|||||||
grossPerformancePercent: 0,
|
grossPerformancePercent: 0,
|
||||||
investment: convertedBalance,
|
investment: convertedBalance,
|
||||||
marketPrice: 0,
|
marketPrice: 0,
|
||||||
marketState: MarketState.open,
|
marketState: 'open',
|
||||||
name: account.currency,
|
name: account.currency,
|
||||||
netPerformance: 0,
|
netPerformance: 0,
|
||||||
netPerformancePercent: 0,
|
netPerformancePercent: 0,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { HistoricalDataItem } from '@ghostfolio/api/app/portfolio/interfaces/portfolio-position-detail.interface';
|
import { HistoricalDataItem } from '@ghostfolio/common/interfaces';
|
||||||
import { DataSource } from '@prisma/client';
|
import { DataSource } from '@prisma/client';
|
||||||
|
|
||||||
export interface SymbolItem {
|
export interface SymbolItem {
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import { HistoricalDataItem } from '@ghostfolio/api/app/portfolio/interfaces/portfolio-position-detail.interface';
|
|
||||||
import { DataProviderService } from '@ghostfolio/api/services/data-provider/data-provider.service';
|
import { DataProviderService } from '@ghostfolio/api/services/data-provider/data-provider.service';
|
||||||
import {
|
import {
|
||||||
IDataGatheringItem,
|
IDataGatheringItem,
|
||||||
@ -6,6 +5,7 @@ import {
|
|||||||
} from '@ghostfolio/api/services/interfaces/interfaces';
|
} from '@ghostfolio/api/services/interfaces/interfaces';
|
||||||
import { MarketDataService } from '@ghostfolio/api/services/market-data.service';
|
import { MarketDataService } from '@ghostfolio/api/services/market-data.service';
|
||||||
import { DATE_FORMAT } from '@ghostfolio/common/helper';
|
import { DATE_FORMAT } from '@ghostfolio/common/helper';
|
||||||
|
import { HistoricalDataItem } from '@ghostfolio/common/interfaces';
|
||||||
import { Injectable, Logger } from '@nestjs/common';
|
import { Injectable, Logger } from '@nestjs/common';
|
||||||
import { DataSource } from '@prisma/client';
|
import { DataSource } from '@prisma/client';
|
||||||
import { format, subDays } from 'date-fns';
|
import { format, subDays } from 'date-fns';
|
||||||
|
@ -1,4 +0,0 @@
|
|||||||
export interface Access {
|
|
||||||
alias?: string;
|
|
||||||
id: string;
|
|
||||||
}
|
|
@ -2,8 +2,7 @@ import { LookupItem } from '@ghostfolio/api/app/symbol/interfaces/lookup-item.in
|
|||||||
import { DataProviderInterface } from '@ghostfolio/api/services/data-provider/interfaces/data-provider.interface';
|
import { DataProviderInterface } from '@ghostfolio/api/services/data-provider/interfaces/data-provider.interface';
|
||||||
import {
|
import {
|
||||||
IDataProviderHistoricalResponse,
|
IDataProviderHistoricalResponse,
|
||||||
IDataProviderResponse,
|
IDataProviderResponse
|
||||||
MarketState
|
|
||||||
} from '@ghostfolio/api/services/interfaces/interfaces';
|
} from '@ghostfolio/api/services/interfaces/interfaces';
|
||||||
import { PrismaService } from '@ghostfolio/api/services/prisma.service';
|
import { PrismaService } from '@ghostfolio/api/services/prisma.service';
|
||||||
import { SymbolProfileService } from '@ghostfolio/api/services/symbol-profile.service';
|
import { SymbolProfileService } from '@ghostfolio/api/services/symbol-profile.service';
|
||||||
@ -133,7 +132,7 @@ export class GhostfolioScraperApiService implements DataProviderInterface {
|
|||||||
marketPrice: marketData.find((marketDataItem) => {
|
marketPrice: marketData.find((marketDataItem) => {
|
||||||
return marketDataItem.symbol === symbolProfile.symbol;
|
return marketDataItem.symbol === symbolProfile.symbol;
|
||||||
}).marketPrice,
|
}).marketPrice,
|
||||||
marketState: MarketState.delayed
|
marketState: 'delayed'
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,8 +3,7 @@ import { ConfigurationService } from '@ghostfolio/api/services/configuration.ser
|
|||||||
import { DataProviderInterface } from '@ghostfolio/api/services/data-provider/interfaces/data-provider.interface';
|
import { DataProviderInterface } from '@ghostfolio/api/services/data-provider/interfaces/data-provider.interface';
|
||||||
import {
|
import {
|
||||||
IDataProviderHistoricalResponse,
|
IDataProviderHistoricalResponse,
|
||||||
IDataProviderResponse,
|
IDataProviderResponse
|
||||||
MarketState
|
|
||||||
} from '@ghostfolio/api/services/interfaces/interfaces';
|
} from '@ghostfolio/api/services/interfaces/interfaces';
|
||||||
import { PrismaService } from '@ghostfolio/api/services/prisma.service';
|
import { PrismaService } from '@ghostfolio/api/services/prisma.service';
|
||||||
import { SymbolProfileService } from '@ghostfolio/api/services/symbol-profile.service';
|
import { SymbolProfileService } from '@ghostfolio/api/services/symbol-profile.service';
|
||||||
@ -114,7 +113,7 @@ export class GoogleSheetsService implements DataProviderInterface {
|
|||||||
return symbolProfile.symbol === symbol;
|
return symbolProfile.symbol === symbol;
|
||||||
})?.currency,
|
})?.currency,
|
||||||
dataSource: this.getName(),
|
dataSource: this.getName(),
|
||||||
marketState: MarketState.delayed
|
marketState: 'delayed'
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,8 +3,7 @@ import { ConfigurationService } from '@ghostfolio/api/services/configuration.ser
|
|||||||
import { DataProviderInterface } from '@ghostfolio/api/services/data-provider/interfaces/data-provider.interface';
|
import { DataProviderInterface } from '@ghostfolio/api/services/data-provider/interfaces/data-provider.interface';
|
||||||
import {
|
import {
|
||||||
IDataProviderHistoricalResponse,
|
IDataProviderHistoricalResponse,
|
||||||
IDataProviderResponse,
|
IDataProviderResponse
|
||||||
MarketState
|
|
||||||
} from '@ghostfolio/api/services/interfaces/interfaces';
|
} from '@ghostfolio/api/services/interfaces/interfaces';
|
||||||
import { PrismaService } from '@ghostfolio/api/services/prisma.service';
|
import { PrismaService } from '@ghostfolio/api/services/prisma.service';
|
||||||
import { ghostfolioFearAndGreedIndexSymbol } from '@ghostfolio/common/config';
|
import { ghostfolioFearAndGreedIndexSymbol } from '@ghostfolio/common/config';
|
||||||
@ -118,7 +117,7 @@ export class RakutenRapidApiService implements DataProviderInterface {
|
|||||||
currency: undefined,
|
currency: undefined,
|
||||||
dataSource: this.getName(),
|
dataSource: this.getName(),
|
||||||
marketPrice: fgi.now.value,
|
marketPrice: fgi.now.value,
|
||||||
marketState: MarketState.open
|
marketState: 'open'
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -3,8 +3,7 @@ import { CryptocurrencyService } from '@ghostfolio/api/services/cryptocurrency/c
|
|||||||
import { DataProviderInterface } from '@ghostfolio/api/services/data-provider/interfaces/data-provider.interface';
|
import { DataProviderInterface } from '@ghostfolio/api/services/data-provider/interfaces/data-provider.interface';
|
||||||
import {
|
import {
|
||||||
IDataProviderHistoricalResponse,
|
IDataProviderHistoricalResponse,
|
||||||
IDataProviderResponse,
|
IDataProviderResponse
|
||||||
MarketState
|
|
||||||
} from '@ghostfolio/api/services/interfaces/interfaces';
|
} from '@ghostfolio/api/services/interfaces/interfaces';
|
||||||
import { baseCurrency } from '@ghostfolio/common/config';
|
import { baseCurrency } from '@ghostfolio/common/config';
|
||||||
import { DATE_FORMAT, isCurrency } from '@ghostfolio/common/helper';
|
import { DATE_FORMAT, isCurrency } from '@ghostfolio/common/helper';
|
||||||
@ -216,8 +215,8 @@ export class YahooFinanceService implements DataProviderInterface {
|
|||||||
marketState:
|
marketState:
|
||||||
quote.marketState === 'REGULAR' ||
|
quote.marketState === 'REGULAR' ||
|
||||||
this.cryptocurrencyService.isCryptocurrency(symbol)
|
this.cryptocurrencyService.isCryptocurrency(symbol)
|
||||||
? MarketState.open
|
? 'open'
|
||||||
: MarketState.closed,
|
: 'closed',
|
||||||
marketPrice: quote.regularMarketPrice || 0
|
marketPrice: quote.regularMarketPrice || 0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,18 +1,11 @@
|
|||||||
|
import { MarketState } from '@ghostfolio/common/types';
|
||||||
import {
|
import {
|
||||||
Account,
|
Account,
|
||||||
AssetClass,
|
|
||||||
AssetSubClass,
|
|
||||||
DataSource,
|
DataSource,
|
||||||
SymbolProfile,
|
SymbolProfile,
|
||||||
Type as TypeOfOrder
|
Type as TypeOfOrder
|
||||||
} from '@prisma/client';
|
} from '@prisma/client';
|
||||||
|
|
||||||
export const MarketState = {
|
|
||||||
closed: 'closed',
|
|
||||||
delayed: 'delayed',
|
|
||||||
open: 'open'
|
|
||||||
};
|
|
||||||
|
|
||||||
export interface IOrder {
|
export interface IOrder {
|
||||||
account: Account;
|
account: Account;
|
||||||
currency: string;
|
currency: string;
|
||||||
@ -44,5 +37,3 @@ export interface IDataGatheringItem {
|
|||||||
date?: Date;
|
date?: Date;
|
||||||
symbol: string;
|
symbol: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type MarketState = typeof MarketState[keyof typeof MarketState];
|
|
||||||
|
@ -1,10 +1,13 @@
|
|||||||
import { ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core';
|
import { ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core';
|
||||||
import { HistoricalDataItem } from '@ghostfolio/api/app/portfolio/interfaces/portfolio-position-detail.interface';
|
|
||||||
import { DataService } from '@ghostfolio/client/services/data.service';
|
import { DataService } from '@ghostfolio/client/services/data.service';
|
||||||
import { UserService } from '@ghostfolio/client/services/user/user.service';
|
import { UserService } from '@ghostfolio/client/services/user/user.service';
|
||||||
import { ghostfolioFearAndGreedIndexSymbol } from '@ghostfolio/common/config';
|
import { ghostfolioFearAndGreedIndexSymbol } from '@ghostfolio/common/config';
|
||||||
import { resetHours } from '@ghostfolio/common/helper';
|
import { resetHours } from '@ghostfolio/common/helper';
|
||||||
import { InfoItem, User } from '@ghostfolio/common/interfaces';
|
import {
|
||||||
|
HistoricalDataItem,
|
||||||
|
InfoItem,
|
||||||
|
User
|
||||||
|
} from '@ghostfolio/common/interfaces';
|
||||||
import { hasPermission, permissions } from '@ghostfolio/common/permissions';
|
import { hasPermission, permissions } from '@ghostfolio/common/permissions';
|
||||||
import { Subject } from 'rxjs';
|
import { Subject } from 'rxjs';
|
||||||
import { takeUntil } from 'rxjs/operators';
|
import { takeUntil } from 'rxjs/operators';
|
||||||
|
@ -5,7 +5,6 @@ import {
|
|||||||
OnChanges,
|
OnChanges,
|
||||||
OnInit
|
OnInit
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
import { MarketState } from '@ghostfolio/api/services/interfaces/interfaces';
|
|
||||||
import { Position } from '@ghostfolio/common/interfaces';
|
import { Position } from '@ghostfolio/common/interfaces';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -42,10 +41,7 @@ export class PositionsComponent implements OnChanges, OnInit {
|
|||||||
this.positionsWithPriority = [];
|
this.positionsWithPriority = [];
|
||||||
|
|
||||||
for (const portfolioPosition of this.positions) {
|
for (const portfolioPosition of this.positions) {
|
||||||
if (
|
if (portfolioPosition.marketState === 'open' || this.range !== '1d') {
|
||||||
portfolioPosition.marketState === MarketState.open ||
|
|
||||||
this.range !== '1d'
|
|
||||||
) {
|
|
||||||
// Only show positions where the market is open in today's view
|
// Only show positions where the market is open in today's view
|
||||||
this.positionsWithPriority.push(portfolioPosition);
|
this.positionsWithPriority.push(portfolioPosition);
|
||||||
} else {
|
} else {
|
||||||
|
@ -0,0 +1,6 @@
|
|||||||
|
export interface HistoricalDataItem {
|
||||||
|
averagePrice?: number;
|
||||||
|
date: string;
|
||||||
|
grossPerformancePercent?: number;
|
||||||
|
value: number;
|
||||||
|
}
|
@ -9,6 +9,7 @@ import {
|
|||||||
import { Coupon } from './coupon.interface';
|
import { Coupon } from './coupon.interface';
|
||||||
import { Export } from './export.interface';
|
import { Export } from './export.interface';
|
||||||
import { Filter } from './filter.interface';
|
import { Filter } from './filter.interface';
|
||||||
|
import { HistoricalDataItem } from './historical-data-item.interface';
|
||||||
import { InfoItem } from './info-item.interface';
|
import { InfoItem } from './info-item.interface';
|
||||||
import { PortfolioChart } from './portfolio-chart.interface';
|
import { PortfolioChart } from './portfolio-chart.interface';
|
||||||
import { PortfolioDetails } from './portfolio-details.interface';
|
import { PortfolioDetails } from './portfolio-details.interface';
|
||||||
@ -40,6 +41,7 @@ export {
|
|||||||
Coupon,
|
Coupon,
|
||||||
Export,
|
Export,
|
||||||
Filter,
|
Filter,
|
||||||
|
HistoricalDataItem,
|
||||||
InfoItem,
|
InfoItem,
|
||||||
PortfolioChart,
|
PortfolioChart,
|
||||||
PortfolioDetails,
|
PortfolioDetails,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { HistoricalDataItem } from '@ghostfolio/api/app/portfolio/interfaces/portfolio-position-detail.interface';
|
import { HistoricalDataItem } from './historical-data-item.interface';
|
||||||
|
|
||||||
export interface PortfolioChart {
|
export interface PortfolioChart {
|
||||||
hasError: boolean;
|
hasError: boolean;
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import { MarketState } from '@ghostfolio/api/services/interfaces/interfaces';
|
|
||||||
import { AssetClass, AssetSubClass, DataSource } from '@prisma/client';
|
import { AssetClass, AssetSubClass, DataSource } from '@prisma/client';
|
||||||
|
|
||||||
import { Market } from '../types';
|
import { Market, MarketState } from '../types';
|
||||||
import { Country } from './country.interface';
|
import { Country } from './country.interface';
|
||||||
import { Sector } from './sector.interface';
|
import { Sector } from './sector.interface';
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { MarketState } from '@ghostfolio/api/services/interfaces/interfaces';
|
|
||||||
import { AssetClass, DataSource } from '@prisma/client';
|
import { AssetClass, DataSource } from '@prisma/client';
|
||||||
|
import { MarketState } from '../types';
|
||||||
|
|
||||||
export interface Position {
|
export interface Position {
|
||||||
assetClass: AssetClass;
|
assetClass: AssetClass;
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
import { Access } from '@ghostfolio/api/app/user/interfaces/access.interface';
|
|
||||||
import { Account, Tag } from '@prisma/client';
|
import { Account, Tag } from '@prisma/client';
|
||||||
|
|
||||||
import { UserSettings } from './user-settings.interface';
|
import { UserSettings } from './user-settings.interface';
|
||||||
|
|
||||||
export interface User {
|
export interface User {
|
||||||
access: Access[];
|
access: {
|
||||||
|
alias?: string;
|
||||||
|
id: string;
|
||||||
|
}[];
|
||||||
accounts: Account[];
|
accounts: Account[];
|
||||||
alias?: string;
|
alias?: string;
|
||||||
id: string;
|
id: string;
|
||||||
|
@ -2,6 +2,7 @@ import type { AccessWithGranteeUser } from './access-with-grantee-user.type';
|
|||||||
import { AccountWithValue } from './account-with-value.type';
|
import { AccountWithValue } from './account-with-value.type';
|
||||||
import type { DateRange } from './date-range.type';
|
import type { DateRange } from './date-range.type';
|
||||||
import type { Granularity } from './granularity.type';
|
import type { Granularity } from './granularity.type';
|
||||||
|
import { MarketState } from './market-state-type';
|
||||||
import { Market } from './market.type';
|
import { Market } from './market.type';
|
||||||
import type { OrderWithAccount } from './order-with-account.type';
|
import type { OrderWithAccount } from './order-with-account.type';
|
||||||
import type { RequestWithUser } from './request-with-user.type';
|
import type { RequestWithUser } from './request-with-user.type';
|
||||||
@ -13,6 +14,7 @@ export type {
|
|||||||
DateRange,
|
DateRange,
|
||||||
Granularity,
|
Granularity,
|
||||||
Market,
|
Market,
|
||||||
|
MarketState,
|
||||||
OrderWithAccount,
|
OrderWithAccount,
|
||||||
RequestWithUser,
|
RequestWithUser,
|
||||||
ToggleOption
|
ToggleOption
|
||||||
|
1
libs/common/src/lib/types/market-state-type.ts
Normal file
1
libs/common/src/lib/types/market-state-type.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export type MarketState = 'closed' | 'delayed' | 'open';
|
@ -1,6 +1,5 @@
|
|||||||
import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
|
import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
|
||||||
import { MarketState } from '@ghostfolio/api/services/interfaces/interfaces';
|
import { DateRange, MarketState } from '@ghostfolio/common/types';
|
||||||
import { DateRange } from '@ghostfolio/common/types';
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'gf-trend-indicator',
|
selector: 'gf-trend-indicator',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user