Browse Source

Task/improve data source filter in market data table (#8327)

* Improve data source filter

* Update changelog
pull/7865/merge
Thomas Kaul 4 hours ago
committed by GitHub
parent
commit
67a64074b4
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 1
      CHANGELOG.md
  2. 52
      apps/client/src/app/components/admin-market-data/admin-market-data.component.ts
  3. 1
      libs/ui/src/lib/i18n.ts

1
CHANGELOG.md

@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed
- Improved the data source filter in the historical market data table of the admin control panel to only list the data providers in use
- Restricted the health check endpoint of the AI service (`GET api/v1/health/ai`) to administrators
- Increased the timeout in the health check endpoint of the AI service to 30 seconds
- Deprecated the `api/v1/access` endpoints in favor of the `api/v1/accesses` endpoints

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

@ -11,7 +11,7 @@ import {
import { hasPermission, permissions } from '@ghostfolio/common/permissions';
import { internalRoutes } from '@ghostfolio/common/routes/routes';
import type { SymbolProfile } from '@ghostfolio/prisma/browser';
import { AssetSubClass, DataSource } from '@ghostfolio/prisma/enums';
import { AssetSubClass } from '@ghostfolio/prisma/enums';
import { GfActivitiesFilterComponent } from '@ghostfolio/ui/activities-filter';
import { GfFabComponent } from '@ghostfolio/ui/fab';
import { translate } from '@ghostfolio/ui/i18n';
@ -61,6 +61,7 @@ import {
ellipsisVertical,
trashOutline
} from 'ionicons/icons';
import { isEqual } from 'lodash-es';
import ms from 'ms';
import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader';
import { Subject } from 'rxjs';
@ -95,7 +96,7 @@ import { AdminMarketDataService } from './admin-market-data.service';
export class GfAdminMarketDataComponent implements AfterViewInit, OnInit {
protected readonly adminMarketDataService = inject(AdminMarketDataService);
protected readonly allFilters: Filter[] = [
protected allFilters: Filter[] = [
...Object.keys(AssetSubClass)
.filter((assetSubClass) => {
return assetSubClass !== 'CASH';
@ -107,13 +108,6 @@ export class GfAdminMarketDataComponent implements AfterViewInit, OnInit {
type: 'ASSET_SUB_CLASS' as Filter['type']
};
}),
...Object.keys(DataSource).map((dataSource) => {
return {
id: dataSource.toString(),
label: dataSource,
type: 'DATA_SOURCE' as Filter['type']
};
}),
{
id: 'BENCHMARKS',
label: $localize`Benchmarks`,
@ -202,6 +196,7 @@ export class GfAdminMarketDataComponent implements AfterViewInit, OnInit {
this.adminMarketDataService.refresh$
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe(() => {
this.loadDataSourceFilters();
this.reloadData();
});
@ -214,7 +209,10 @@ export class GfAdminMarketDataComponent implements AfterViewInit, OnInit {
});
this.filters$
.pipe(distinctUntilChanged(), takeUntilDestroyed(this.destroyRef))
.pipe(
distinctUntilChanged<Filter[]>(isEqual),
takeUntilDestroyed(this.destroyRef)
)
.subscribe((filters) => {
this.activeFilters = filters;
@ -250,6 +248,8 @@ export class GfAdminMarketDataComponent implements AfterViewInit, OnInit {
const { benchmarks } = this.dataService.fetchInfo();
this.benchmarks = benchmarks;
this.loadDataSourceFilters();
}
protected onChangePage(page: PageEvent) {
@ -268,6 +268,7 @@ export class GfAdminMarketDataComponent implements AfterViewInit, OnInit {
.deleteAssetProfile({ dataSource, symbol })
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe(() => {
this.loadDataSourceFilters();
this.reloadData();
});
}
@ -281,6 +282,7 @@ export class GfAdminMarketDataComponent implements AfterViewInit, OnInit {
)
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe(() => {
this.loadDataSourceFilters();
this.reloadData();
});
}
@ -382,6 +384,36 @@ export class GfAdminMarketDataComponent implements AfterViewInit, OnInit {
});
}
private loadDataSourceFilters() {
this.adminService
.fetchAdminData()
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe(({ dataProviders }) => {
this.allFilters = [
...this.allFilters.filter(({ type }) => {
return type !== 'DATA_SOURCE';
}),
...dataProviders.flatMap(
({ assetProfileCount, dataSource, name }) => {
if (assetProfileCount === 0 || !dataSource) {
return [];
}
return [
{
id: dataSource,
label: name ?? translate(dataSource),
type: 'DATA_SOURCE' as Filter['type']
}
];
}
)
];
this.changeDetectorRef.markForCheck();
});
}
private notifyDataGatheringHasBeenStarted() {
this.snackBar.open(
'✅ ' + $localize`Data gathering has been started.`,

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

@ -27,6 +27,7 @@ const locales = {
HIGHER_RISK: $localize`Higher Risk`,
IMPORT_ACTIVITY_ERROR_IS_DUPLICATE: $localize`This activity already exists.`,
LOWER_RISK: $localize`Lower Risk`,
MANUAL: $localize`Manual`,
MONTH: $localize`Month`,
MONTHS: $localize`Months`,
OTHER: $localize`Other`,

Loading…
Cancel
Save