|
|
@ -1,4 +1,5 @@ |
|
|
|
import { |
|
|
|
AfterViewInit, |
|
|
|
ChangeDetectionStrategy, |
|
|
|
ChangeDetectorRef, |
|
|
|
Component, |
|
|
@ -7,17 +8,16 @@ import { |
|
|
|
ViewChild |
|
|
|
} from '@angular/core'; |
|
|
|
import { MatDialog } from '@angular/material/dialog'; |
|
|
|
import { MatSort } from '@angular/material/sort'; |
|
|
|
import { MatSort, Sort } from '@angular/material/sort'; |
|
|
|
import { MatTableDataSource } from '@angular/material/table'; |
|
|
|
import { ActivatedRoute, Router } from '@angular/router'; |
|
|
|
import { AdminService } from '@ghostfolio/client/services/admin.service'; |
|
|
|
import { DataService } from '@ghostfolio/client/services/data.service'; |
|
|
|
import { UserService } from '@ghostfolio/client/services/user/user.service'; |
|
|
|
import { getDateFormatString } from '@ghostfolio/common/helper'; |
|
|
|
import { Filter, UniqueAsset, User } from '@ghostfolio/common/interfaces'; |
|
|
|
import { AdminMarketDataItem } from '@ghostfolio/common/interfaces/admin-market-data.interface'; |
|
|
|
import { translate } from '@ghostfolio/ui/i18n'; |
|
|
|
import { AssetSubClass, DataSource } from '@prisma/client'; |
|
|
|
import { AssetSubClass, DataSource, Prisma } from '@prisma/client'; |
|
|
|
import { DeviceDetectorService } from 'ngx-device-detector'; |
|
|
|
import { Subject } from 'rxjs'; |
|
|
|
import { distinctUntilChanged, switchMap, takeUntil } from 'rxjs/operators'; |
|
|
@ -26,6 +26,8 @@ import { AssetProfileDialog } from './asset-profile-dialog/asset-profile-dialog. |
|
|
|
import { AssetProfileDialogParams } from './asset-profile-dialog/interfaces/interfaces'; |
|
|
|
import { CreateAssetProfileDialog } from './create-asset-profile-dialog/create-asset-profile-dialog.component'; |
|
|
|
import { CreateAssetProfileDialogParams } from './create-asset-profile-dialog/interfaces/interfaces'; |
|
|
|
import { DEFAULT_PAGE_SIZE } from '@ghostfolio/common/config'; |
|
|
|
import { MatPaginator, PageEvent } from '@angular/material/paginator'; |
|
|
|
|
|
|
|
@Component({ |
|
|
|
changeDetection: ChangeDetectionStrategy.OnPush, |
|
|
@ -33,7 +35,10 @@ import { CreateAssetProfileDialogParams } from './create-asset-profile-dialog/in |
|
|
|
styleUrls: ['./admin-market-data.scss'], |
|
|
|
templateUrl: './admin-market-data.html' |
|
|
|
}) |
|
|
|
export class AdminMarketDataComponent implements OnDestroy, OnInit { |
|
|
|
export class AdminMarketDataComponent |
|
|
|
implements AfterViewInit, OnDestroy, OnInit |
|
|
|
{ |
|
|
|
@ViewChild(MatPaginator) paginator: MatPaginator; |
|
|
|
@ViewChild(MatSort) sort: MatSort; |
|
|
|
|
|
|
|
public activeFilters: Filter[] = []; |
|
|
@ -75,6 +80,8 @@ export class AdminMarketDataComponent implements OnDestroy, OnInit { |
|
|
|
public filters$ = new Subject<Filter[]>(); |
|
|
|
public isLoading = false; |
|
|
|
public placeholder = ''; |
|
|
|
public pageSize = DEFAULT_PAGE_SIZE; |
|
|
|
public totalItems = 0; |
|
|
|
public user: User; |
|
|
|
|
|
|
|
private unsubscribeSubject = new Subject<void>(); |
|
|
@ -82,7 +89,6 @@ export class AdminMarketDataComponent implements OnDestroy, OnInit { |
|
|
|
public constructor( |
|
|
|
private adminService: AdminService, |
|
|
|
private changeDetectorRef: ChangeDetectorRef, |
|
|
|
private dataService: DataService, |
|
|
|
private deviceService: DeviceDetectorService, |
|
|
|
private dialog: MatDialog, |
|
|
|
private route: ActivatedRoute, |
|
|
@ -117,34 +123,40 @@ export class AdminMarketDataComponent implements OnDestroy, OnInit { |
|
|
|
); |
|
|
|
} |
|
|
|
}); |
|
|
|
|
|
|
|
this.filters$ |
|
|
|
.pipe(distinctUntilChanged(), takeUntil(this.unsubscribeSubject)) |
|
|
|
.subscribe((filters) => { |
|
|
|
this.activeFilters = filters; |
|
|
|
|
|
|
|
this.loadData(); |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
public ngOnInit() { |
|
|
|
this.deviceType = this.deviceService.getDeviceInfo().deviceType; |
|
|
|
public ngAfterViewInit() { |
|
|
|
this.sort.sortChange.subscribe( |
|
|
|
({ active: sortColumn, direction }: Sort) => { |
|
|
|
this.paginator.pageIndex = 0; |
|
|
|
|
|
|
|
this.filters$ |
|
|
|
.pipe( |
|
|
|
distinctUntilChanged(), |
|
|
|
switchMap((filters) => { |
|
|
|
this.isLoading = true; |
|
|
|
this.activeFilters = filters; |
|
|
|
this.placeholder = |
|
|
|
this.activeFilters.length <= 0 ? $localize`Filter by...` : ''; |
|
|
|
|
|
|
|
return this.dataService.fetchAdminMarketData({ |
|
|
|
filters: this.activeFilters |
|
|
|
}); |
|
|
|
}), |
|
|
|
takeUntil(this.unsubscribeSubject) |
|
|
|
) |
|
|
|
.subscribe(({ marketData }) => { |
|
|
|
this.dataSource = new MatTableDataSource(marketData); |
|
|
|
this.dataSource.sort = this.sort; |
|
|
|
this.loadData({ |
|
|
|
sortColumn, |
|
|
|
sortDirection: <Prisma.SortOrder>direction, |
|
|
|
pageIndex: this.paginator.pageIndex |
|
|
|
}); |
|
|
|
} |
|
|
|
); |
|
|
|
} |
|
|
|
|
|
|
|
this.isLoading = false; |
|
|
|
public ngOnInit() { |
|
|
|
this.deviceType = this.deviceService.getDeviceInfo().deviceType; |
|
|
|
} |
|
|
|
|
|
|
|
this.changeDetectorRef.markForCheck(); |
|
|
|
}); |
|
|
|
public onChangePage(page: PageEvent) { |
|
|
|
this.loadData({ |
|
|
|
pageIndex: page.pageIndex, |
|
|
|
sortColumn: this.sort.active, |
|
|
|
sortDirection: <Prisma.SortOrder>this.sort.direction |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
public onDeleteProfileData({ dataSource, symbol }: UniqueAsset) { |
|
|
@ -212,6 +224,47 @@ export class AdminMarketDataComponent implements OnDestroy, OnInit { |
|
|
|
this.unsubscribeSubject.complete(); |
|
|
|
} |
|
|
|
|
|
|
|
private loadData( |
|
|
|
{ |
|
|
|
pageIndex, |
|
|
|
sortColumn, |
|
|
|
sortDirection |
|
|
|
}: { |
|
|
|
pageIndex: number; |
|
|
|
sortColumn?: string; |
|
|
|
sortDirection?: Prisma.SortOrder; |
|
|
|
} = { pageIndex: 0 } |
|
|
|
) { |
|
|
|
this.isLoading = true; |
|
|
|
|
|
|
|
if (pageIndex === 0 && this.paginator) { |
|
|
|
this.paginator.pageIndex = 0; |
|
|
|
} |
|
|
|
|
|
|
|
this.placeholder = |
|
|
|
this.activeFilters.length <= 0 ? $localize`Filter by...` : ''; |
|
|
|
|
|
|
|
this.adminService |
|
|
|
.fetchAdminMarketData({ |
|
|
|
sortColumn, |
|
|
|
sortDirection, |
|
|
|
filters: this.activeFilters, |
|
|
|
skip: pageIndex * this.pageSize, |
|
|
|
take: this.pageSize |
|
|
|
}) |
|
|
|
.pipe(takeUntil(this.unsubscribeSubject)) |
|
|
|
.subscribe(({ count, marketData }) => { |
|
|
|
this.totalItems = count; |
|
|
|
|
|
|
|
this.dataSource = new MatTableDataSource(marketData); |
|
|
|
this.dataSource.sort = this.sort; |
|
|
|
|
|
|
|
this.isLoading = false; |
|
|
|
|
|
|
|
this.changeDetectorRef.markForCheck(); |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
private openAssetProfileDialog({ |
|
|
|
dataSource, |
|
|
|
symbol |
|
|
@ -274,8 +327,9 @@ export class AdminMarketDataComponent implements OnDestroy, OnInit { |
|
|
|
this.isLoading = true; |
|
|
|
this.changeDetectorRef.markForCheck(); |
|
|
|
|
|
|
|
return this.dataService.fetchAdminMarketData({ |
|
|
|
filters: this.activeFilters |
|
|
|
return this.adminService.fetchAdminMarketData({ |
|
|
|
filters: this.activeFilters, |
|
|
|
take: this.pageSize |
|
|
|
}); |
|
|
|
}), |
|
|
|
takeUntil(this.unsubscribeSubject) |
|
|
|