Feature/extend historical data view in admin control (#646)
* Extend market data view * Update changelog
This commit is contained in:
parent
585f99e4df
commit
9c086edffe
@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
|
- Extended the historical data view in the admin control panel
|
||||||
- Upgraded _Stripe_ dependencies
|
- Upgraded _Stripe_ dependencies
|
||||||
- Upgraded `prisma` from version `3.7.0` to `3.8.1`
|
- Upgraded `prisma` from version `3.7.0` to `3.8.1`
|
||||||
|
|
||||||
|
@ -9,7 +9,8 @@ import { PROPERTY_CURRENCIES, baseCurrency } from '@ghostfolio/common/config';
|
|||||||
import {
|
import {
|
||||||
AdminData,
|
AdminData,
|
||||||
AdminMarketData,
|
AdminMarketData,
|
||||||
AdminMarketDataDetails
|
AdminMarketDataDetails,
|
||||||
|
AdminMarketDataItem
|
||||||
} from '@ghostfolio/common/interfaces';
|
} from '@ghostfolio/common/interfaces';
|
||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
import { Property } from '@prisma/client';
|
import { Property } from '@prisma/client';
|
||||||
@ -56,12 +57,67 @@ export class AdminService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async getMarketData(): Promise<AdminMarketData> {
|
public async getMarketData(): Promise<AdminMarketData> {
|
||||||
return {
|
const marketData = await this.prismaService.marketData.groupBy({
|
||||||
marketData: await (
|
_count: true,
|
||||||
await this.dataGatheringService.getSymbolsMax()
|
by: ['dataSource', 'symbol']
|
||||||
).map((symbol) => {
|
});
|
||||||
return symbol;
|
|
||||||
|
const currencyPairsToGather: AdminMarketDataItem[] =
|
||||||
|
this.exchangeRateDataService
|
||||||
|
.getCurrencyPairs()
|
||||||
|
.map(({ dataSource, symbol }) => {
|
||||||
|
const marketDataItemCount =
|
||||||
|
marketData.find((marketDataItem) => {
|
||||||
|
return (
|
||||||
|
marketDataItem.dataSource === dataSource &&
|
||||||
|
marketDataItem.symbol === symbol
|
||||||
|
);
|
||||||
|
})?._count ?? 0;
|
||||||
|
|
||||||
|
return {
|
||||||
|
dataSource,
|
||||||
|
marketDataItemCount,
|
||||||
|
symbol
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
const symbolProfilesToGather: AdminMarketDataItem[] = (
|
||||||
|
await this.prismaService.symbolProfile.findMany({
|
||||||
|
orderBy: [{ symbol: 'asc' }],
|
||||||
|
select: {
|
||||||
|
_count: {
|
||||||
|
select: { Order: true }
|
||||||
|
},
|
||||||
|
dataSource: true,
|
||||||
|
Order: {
|
||||||
|
orderBy: [{ date: 'asc' }],
|
||||||
|
select: { date: true },
|
||||||
|
take: 1
|
||||||
|
},
|
||||||
|
scraperConfiguration: true,
|
||||||
|
symbol: true
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
).map((symbolProfile) => {
|
||||||
|
const marketDataItemCount =
|
||||||
|
marketData.find((marketDataItem) => {
|
||||||
|
return (
|
||||||
|
marketDataItem.dataSource === symbolProfile.dataSource &&
|
||||||
|
marketDataItem.symbol === symbolProfile.symbol
|
||||||
|
);
|
||||||
|
})?._count ?? 0;
|
||||||
|
|
||||||
|
return {
|
||||||
|
marketDataItemCount,
|
||||||
|
activityCount: symbolProfile._count.Order,
|
||||||
|
dataSource: symbolProfile.dataSource,
|
||||||
|
date: symbolProfile.Order?.[0]?.date,
|
||||||
|
symbol: symbolProfile.symbol
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
marketData: [...currencyPairsToGather, ...symbolProfilesToGather]
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,7 +6,9 @@
|
|||||||
<tr class="mat-header-row">
|
<tr class="mat-header-row">
|
||||||
<th class="mat-header-cell px-1 py-2" i18n>Symbol</th>
|
<th class="mat-header-cell px-1 py-2" i18n>Symbol</th>
|
||||||
<th class="mat-header-cell px-1 py-2" i18n>Data Source</th>
|
<th class="mat-header-cell px-1 py-2" i18n>Data Source</th>
|
||||||
<th class="mat-header-cell px-1 py-2" i18n>First Transaction</th>
|
<th class="mat-header-cell px-1 py-2" i18n>First Activity</th>
|
||||||
|
<th class="mat-header-cell px-1 py-2" i18n>Activity Count</th>
|
||||||
|
<th class="mat-header-cell px-1 py-2" i18n>Historical Data</th>
|
||||||
<th class="mat-header-cell px-1 py-2"></th>
|
<th class="mat-header-cell px-1 py-2"></th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
@ -21,6 +23,8 @@
|
|||||||
<td class="mat-cell px-1 py-2">
|
<td class="mat-cell px-1 py-2">
|
||||||
{{ (item.date | date: defaultDateFormat) ?? '' }}
|
{{ (item.date | date: defaultDateFormat) ?? '' }}
|
||||||
</td>
|
</td>
|
||||||
|
<td class="mat-cell px-1 py-2">{{ item.activityCount }}</td>
|
||||||
|
<td class="mat-cell px-1 py-2">{{ item.marketDataItemCount }}</td>
|
||||||
<td class="mat-cell px-1 py-2">
|
<td class="mat-cell px-1 py-2">
|
||||||
<button
|
<button
|
||||||
class="mx-1 no-min-width px-2"
|
class="mx-1 no-min-width px-2"
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
[showYAxis]="false"
|
[showYAxis]="false"
|
||||||
></gf-line-chart>
|
></gf-line-chart>
|
||||||
<div
|
<div
|
||||||
*ngIf="hasPermissionToCreateOrder&& historicalDataItems?.length === 0"
|
*ngIf="hasPermissionToCreateOrder && historicalDataItems?.length === 0"
|
||||||
class="align-items-center d-flex h-100 justify-content-center w-100"
|
class="align-items-center d-flex h-100 justify-content-center w-100"
|
||||||
>
|
>
|
||||||
<div class="d-flex justify-content-center">
|
<div class="d-flex justify-content-center">
|
||||||
|
@ -1,7 +1,12 @@
|
|||||||
|
import { DataSource } from '@prisma/client';
|
||||||
|
|
||||||
export interface AdminMarketData {
|
export interface AdminMarketData {
|
||||||
marketData: AdminMarketDataItem[];
|
marketData: AdminMarketDataItem[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AdminMarketDataItem {
|
export interface AdminMarketDataItem {
|
||||||
|
dataSource: DataSource;
|
||||||
|
date?: Date;
|
||||||
|
marketDataItemCount?: number;
|
||||||
symbol: string;
|
symbol: string;
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,10 @@ import { Access } from './access.interface';
|
|||||||
import { Accounts } from './accounts.interface';
|
import { Accounts } from './accounts.interface';
|
||||||
import { AdminData } from './admin-data.interface';
|
import { AdminData } from './admin-data.interface';
|
||||||
import { AdminMarketDataDetails } from './admin-market-data-details.interface';
|
import { AdminMarketDataDetails } from './admin-market-data-details.interface';
|
||||||
import { AdminMarketData } from './admin-market-data.interface';
|
import {
|
||||||
|
AdminMarketData,
|
||||||
|
AdminMarketDataItem
|
||||||
|
} from './admin-market-data.interface';
|
||||||
import { Coupon } from './coupon.interface';
|
import { Coupon } from './coupon.interface';
|
||||||
import { Export } from './export.interface';
|
import { Export } from './export.interface';
|
||||||
import { InfoItem } from './info-item.interface';
|
import { InfoItem } from './info-item.interface';
|
||||||
@ -29,6 +32,7 @@ export {
|
|||||||
AdminData,
|
AdminData,
|
||||||
AdminMarketData,
|
AdminMarketData,
|
||||||
AdminMarketDataDetails,
|
AdminMarketDataDetails,
|
||||||
|
AdminMarketDataItem,
|
||||||
Coupon,
|
Coupon,
|
||||||
Export,
|
Export,
|
||||||
InfoItem,
|
InfoItem,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user