Browse Source

Add filter by data source

pull/5385/head
Thomas Kaul 21 hours ago
parent
commit
89c69267f9
  1. 2
      apps/api/src/app/admin/admin.controller.ts
  2. 16
      apps/api/src/app/admin/admin.service.ts
  3. 69
      apps/client/src/app/components/admin-market-data/admin-market-data.component.ts
  4. 1
      libs/ui/src/lib/i18n.ts

2
apps/api/src/app/admin/admin.controller.ts

@ -197,6 +197,7 @@ export class AdminController {
@UseGuards(AuthGuard('jwt'), HasPermissionGuard)
public async getMarketData(
@Query('assetSubClasses') filterByAssetSubClasses?: string,
@Query('dataSource') filterByDataSource?: string,
@Query('presetId') presetId?: MarketDataPreset,
@Query('query') filterBySearchQuery?: string,
@Query('skip') skip?: number,
@ -206,6 +207,7 @@ export class AdminController {
): Promise<AdminMarketData> {
const filters = this.apiService.buildFiltersFromQueryParams({
filterByAssetSubClasses,
filterByDataSource,
filterBySearchQuery
});

16
apps/api/src/app/admin/admin.service.ts

@ -214,12 +214,12 @@ export class AdminService {
return type === 'SEARCH_QUERY';
})?.id;
const { ASSET_SUB_CLASS: filtersByAssetSubClass } = groupBy(
filters,
({ type }) => {
return type;
}
);
const {
ASSET_SUB_CLASS: filtersByAssetSubClass,
DATA_SOURCE: filtersByDataSource
} = groupBy(filters, ({ type }) => {
return type;
});
const marketDataItems = await this.prismaService.marketData.groupBy({
_count: true,
@ -230,6 +230,10 @@ export class AdminService {
where.assetSubClass = AssetSubClass[filtersByAssetSubClass[0].id];
}
if (filtersByDataSource) {
where.dataSource = DataSource[filtersByDataSource[0].id];
}
if (searchQuery) {
where.OR = [
{ id: { mode: 'insensitive', startsWith: searchQuery } },

69
apps/client/src/app/components/admin-market-data/admin-market-data.component.ts

@ -103,39 +103,46 @@ export class GfAdminMarketDataComponent
@ViewChild(MatSort) sort: MatSort;
public activeFilters: Filter[] = [];
public allFilters: Filter[] = Object.keys(AssetSubClass)
.filter((assetSubClass) => {
return assetSubClass !== 'CASH';
})
.map((assetSubClass) => {
public allFilters: Filter[] = [
...Object.keys(AssetSubClass)
.filter((assetSubClass) => {
return assetSubClass !== 'CASH';
})
.map((assetSubClass) => {
return {
id: assetSubClass.toString(),
label: translate(assetSubClass),
type: 'ASSET_SUB_CLASS' as Filter['type']
};
}),
...Object.keys(DataSource).map((dataSource) => {
return {
id: assetSubClass.toString(),
label: translate(assetSubClass),
type: 'ASSET_SUB_CLASS' as Filter['type']
id: dataSource.toString(),
label: dataSource,
type: 'DATA_SOURCE' as Filter['type']
};
})
.concat([
{
id: 'BENCHMARKS',
label: $localize`Benchmarks`,
type: 'PRESET_ID' as Filter['type']
},
{
id: 'CURRENCIES',
label: $localize`Currencies`,
type: 'PRESET_ID' as Filter['type']
},
{
id: 'ETF_WITHOUT_COUNTRIES',
label: $localize`ETFs without Countries`,
type: 'PRESET_ID' as Filter['type']
},
{
id: 'ETF_WITHOUT_SECTORS',
label: $localize`ETFs without Sectors`,
type: 'PRESET_ID' as Filter['type']
}
]);
}),
{
id: 'BENCHMARKS',
label: $localize`Benchmarks`,
type: 'PRESET_ID' as Filter['type']
},
{
id: 'CURRENCIES',
label: $localize`Currencies`,
type: 'PRESET_ID' as Filter['type']
},
{
id: 'ETF_WITHOUT_COUNTRIES',
label: $localize`ETFs without Countries`,
type: 'PRESET_ID' as Filter['type']
},
{
id: 'ETF_WITHOUT_SECTORS',
label: $localize`ETFs without Sectors`,
type: 'PRESET_ID' as Filter['type']
}
];
public benchmarks: Partial<SymbolProfile>[];
public currentDataSource: DataSource;
public currentSymbol: string;

1
libs/ui/src/lib/i18n.ts

@ -12,6 +12,7 @@ const locales = {
DATA_IMPORT_AND_EXPORT_TOOLTIP_BASIC: $localize`Switch to Ghostfolio Premium or Ghostfolio Open Source easily`,
DATA_IMPORT_AND_EXPORT_TOOLTIP_OSS: $localize`Switch to Ghostfolio Premium easily`,
DATA_IMPORT_AND_EXPORT_TOOLTIP_PREMIUM: $localize`Switch to Ghostfolio Open Source or Ghostfolio Basic easily`,
DATA_SOURCE: $localize`Data Source`,
EMERGENCY_FUND: $localize`Emergency Fund`,
EXCLUDE_FROM_ANALYSIS: $localize`Exclude from Analysis`,
Global: $localize`Global`,

Loading…
Cancel
Save