Feature/support filtering by asset class on the allocations page (#926)
* Support filtering by asset class * Update changelog
This commit is contained in:
parent
4a123c38f2
commit
5cb6e5dec6
@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
### Added
|
||||
|
||||
- Added groups to the activities filter component
|
||||
- Added support for filtering by asset class on the allocations page
|
||||
|
||||
## 1.148.0 - 14.05.2022
|
||||
|
||||
|
@ -4,6 +4,7 @@ import { Filter } from '@ghostfolio/common/interfaces';
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { Account, Order, Platform, Prisma } from '@prisma/client';
|
||||
import Big from 'big.js';
|
||||
import { groupBy } from 'lodash';
|
||||
|
||||
import { CashDetails } from './interfaces/cash-details.interface';
|
||||
|
||||
@ -116,15 +117,19 @@ export class AccountService {
|
||||
|
||||
const where: Prisma.AccountWhereInput = { userId };
|
||||
|
||||
if (filters?.length > 0) {
|
||||
const {
|
||||
ACCOUNT: filtersByAccount,
|
||||
ASSET_CLASS: filtersByAssetClass,
|
||||
TAG: filtersByTag
|
||||
} = groupBy(filters, (filter) => {
|
||||
return filter.type;
|
||||
});
|
||||
|
||||
if (filtersByAccount?.length > 0) {
|
||||
where.id = {
|
||||
in: filters
|
||||
.filter(({ type }) => {
|
||||
return type === 'ACCOUNT';
|
||||
})
|
||||
.map(({ id }) => {
|
||||
return id;
|
||||
})
|
||||
in: filtersByAccount.map(({ id }) => {
|
||||
return id;
|
||||
})
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -188,12 +188,13 @@ export class OrderService {
|
||||
}): Promise<Activity[]> {
|
||||
const where: Prisma.OrderWhereInput = { userId };
|
||||
|
||||
const { ACCOUNT: filtersByAccount, TAG: filtersByTag } = groupBy(
|
||||
filters,
|
||||
(filter) => {
|
||||
return filter.type;
|
||||
}
|
||||
);
|
||||
const {
|
||||
ACCOUNT: filtersByAccount,
|
||||
ASSET_CLASS: filtersByAssetClass,
|
||||
TAG: filtersByTag
|
||||
} = groupBy(filters, (filter) => {
|
||||
return filter.type;
|
||||
});
|
||||
|
||||
if (filtersByAccount?.length > 0) {
|
||||
where.accountId = {
|
||||
@ -207,6 +208,34 @@ export class OrderService {
|
||||
where.isDraft = false;
|
||||
}
|
||||
|
||||
if (filtersByAssetClass?.length > 0) {
|
||||
where.SymbolProfile = {
|
||||
OR: [
|
||||
{
|
||||
AND: [
|
||||
{
|
||||
OR: filtersByAssetClass.map(({ id }) => {
|
||||
return { assetClass: AssetClass[id] };
|
||||
})
|
||||
},
|
||||
{
|
||||
SymbolProfileOverrides: {
|
||||
is: null
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
SymbolProfileOverrides: {
|
||||
OR: filtersByAssetClass.map(({ id }) => {
|
||||
return { assetClass: AssetClass[id] };
|
||||
})
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
|
||||
if (filtersByTag?.length > 0) {
|
||||
where.tags = {
|
||||
some: {
|
||||
|
@ -107,12 +107,14 @@ export class PortfolioController {
|
||||
public async getDetails(
|
||||
@Headers('impersonation-id') impersonationId: string,
|
||||
@Query('accounts') filterByAccounts?: string,
|
||||
@Query('assetClasses') filterByAssetClasses?: string,
|
||||
@Query('range') range?: DateRange,
|
||||
@Query('tags') filterByTags?: string
|
||||
): Promise<PortfolioDetails & { hasError: boolean }> {
|
||||
let hasError = false;
|
||||
|
||||
const accountIds = filterByAccounts?.split(',') ?? [];
|
||||
const assetClasses = filterByAssetClasses?.split(',') ?? [];
|
||||
const tagIds = filterByTags?.split(',') ?? [];
|
||||
|
||||
const filters: Filter[] = [
|
||||
@ -122,6 +124,12 @@ export class PortfolioController {
|
||||
type: 'ACCOUNT'
|
||||
};
|
||||
}),
|
||||
...assetClasses.map((assetClass) => {
|
||||
return <Filter>{
|
||||
id: assetClass,
|
||||
type: 'ASSET_CLASS'
|
||||
};
|
||||
}),
|
||||
...tagIds.map((tagId) => {
|
||||
return <Filter>{
|
||||
id: tagId,
|
||||
|
@ -441,7 +441,12 @@ export class PortfolioService {
|
||||
};
|
||||
}
|
||||
|
||||
if (aFilters?.length === 0) {
|
||||
if (
|
||||
aFilters?.length === 0 ||
|
||||
(aFilters?.length === 1 &&
|
||||
aFilters[0].type === 'ASSET_CLASS' &&
|
||||
aFilters[0].id === 'CASH')
|
||||
) {
|
||||
const cashPositions = await this.getCashPositions({
|
||||
cashDetails,
|
||||
emergencyFund,
|
||||
|
@ -172,6 +172,15 @@ export class AllocationsPageComponent implements OnDestroy, OnInit {
|
||||
};
|
||||
});
|
||||
|
||||
const assetClassFilters: Filter[] = [];
|
||||
for (const assetClass of Object.keys(AssetClass)) {
|
||||
assetClassFilters.push({
|
||||
id: assetClass,
|
||||
label: assetClass,
|
||||
type: 'ASSET_CLASS'
|
||||
});
|
||||
}
|
||||
|
||||
const tagFilters: Filter[] = this.user.tags.map(({ id, name }) => {
|
||||
return {
|
||||
id,
|
||||
@ -180,7 +189,11 @@ export class AllocationsPageComponent implements OnDestroy, OnInit {
|
||||
};
|
||||
});
|
||||
|
||||
this.allFilters = [...accountFilters, ...tagFilters];
|
||||
this.allFilters = [
|
||||
...accountFilters,
|
||||
...assetClassFilters,
|
||||
...tagFilters
|
||||
];
|
||||
|
||||
this.changeDetectorRef.markForCheck();
|
||||
}
|
||||
|
@ -187,12 +187,13 @@ export class DataService {
|
||||
let params = new HttpParams();
|
||||
|
||||
if (filters?.length > 0) {
|
||||
const { ACCOUNT: filtersByAccount, TAG: filtersByTag } = groupBy(
|
||||
filters,
|
||||
(filter) => {
|
||||
return filter.type;
|
||||
}
|
||||
);
|
||||
const {
|
||||
ACCOUNT: filtersByAccount,
|
||||
ASSET_CLASS: filtersByAssetClass,
|
||||
TAG: filtersByTag
|
||||
} = groupBy(filters, (filter) => {
|
||||
return filter.type;
|
||||
});
|
||||
|
||||
if (filtersByAccount) {
|
||||
params = params.append(
|
||||
@ -205,6 +206,17 @@ export class DataService {
|
||||
);
|
||||
}
|
||||
|
||||
if (filtersByAssetClass) {
|
||||
params = params.append(
|
||||
'assetClasses',
|
||||
filtersByAssetClass
|
||||
.map(({ id }) => {
|
||||
return id;
|
||||
})
|
||||
.join(',')
|
||||
);
|
||||
}
|
||||
|
||||
if (filtersByTag) {
|
||||
params = params.append(
|
||||
'tags',
|
||||
|
@ -1,5 +1,5 @@
|
||||
export interface Filter {
|
||||
id: string;
|
||||
label?: string;
|
||||
type: 'ACCOUNT' | 'SYMBOL' | 'TAG';
|
||||
type: 'ACCOUNT' | 'ASSET_CLASS' | 'SYMBOL' | 'TAG';
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user