|
|
@ -1,7 +1,8 @@ |
|
|
import { UserService } from '@ghostfolio/client/services/user/user.service'; |
|
|
import { UserService } from '@ghostfolio/client/services/user/user.service'; |
|
|
import { |
|
|
import { |
|
|
|
|
|
DEFAULT_COLOR_SCHEME, |
|
|
DEFAULT_PAGE_SIZE, |
|
|
DEFAULT_PAGE_SIZE, |
|
|
ghostfolioScraperApiSymbolPrefix |
|
|
locale |
|
|
} from '@ghostfolio/common/config'; |
|
|
} from '@ghostfolio/common/config'; |
|
|
import { getDateFormatString } from '@ghostfolio/common/helper'; |
|
|
import { getDateFormatString } from '@ghostfolio/common/helper'; |
|
|
import { |
|
|
import { |
|
|
@ -26,9 +27,11 @@ import { |
|
|
ChangeDetectionStrategy, |
|
|
ChangeDetectionStrategy, |
|
|
ChangeDetectorRef, |
|
|
ChangeDetectorRef, |
|
|
Component, |
|
|
Component, |
|
|
|
|
|
computed, |
|
|
DestroyRef, |
|
|
DestroyRef, |
|
|
|
|
|
inject, |
|
|
OnInit, |
|
|
OnInit, |
|
|
ViewChild |
|
|
viewChild |
|
|
} from '@angular/core'; |
|
|
} from '@angular/core'; |
|
|
import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; |
|
|
import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; |
|
|
import { MatButtonModule } from '@angular/material/button'; |
|
|
import { MatButtonModule } from '@angular/material/button'; |
|
|
@ -97,11 +100,8 @@ import { CreateAssetProfileDialogParams } from './create-asset-profile-dialog/in |
|
|
templateUrl: './admin-market-data.html' |
|
|
templateUrl: './admin-market-data.html' |
|
|
}) |
|
|
}) |
|
|
export class GfAdminMarketDataComponent implements AfterViewInit, OnInit { |
|
|
export class GfAdminMarketDataComponent implements AfterViewInit, OnInit { |
|
|
@ViewChild(MatPaginator) paginator: MatPaginator; |
|
|
protected readonly adminMarketDataService = inject(AdminMarketDataService); |
|
|
@ViewChild(MatSort) sort: MatSort; |
|
|
protected readonly allFilters: Filter[] = [ |
|
|
|
|
|
|
|
|
public activeFilters: Filter[] = []; |
|
|
|
|
|
public allFilters: Filter[] = [ |
|
|
|
|
|
...Object.keys(AssetSubClass) |
|
|
...Object.keys(AssetSubClass) |
|
|
.filter((assetSubClass) => { |
|
|
.filter((assetSubClass) => { |
|
|
return assetSubClass !== 'CASH'; |
|
|
return assetSubClass !== 'CASH'; |
|
|
@ -146,37 +146,39 @@ export class GfAdminMarketDataComponent implements AfterViewInit, OnInit { |
|
|
type: 'PRESET_ID' as Filter['type'] |
|
|
type: 'PRESET_ID' as Filter['type'] |
|
|
} |
|
|
} |
|
|
]; |
|
|
]; |
|
|
public benchmarks: Partial<SymbolProfile>[]; |
|
|
protected dataSource = new MatTableDataSource<AdminMarketDataItem>(); |
|
|
public currentDataSource: DataSource; |
|
|
protected defaultDateFormat: string; |
|
|
public currentSymbol: string; |
|
|
protected readonly displayedColumns: string[] = []; |
|
|
public dataSource = new MatTableDataSource<AdminMarketDataItem>(); |
|
|
protected readonly filters$ = new Subject<Filter[]>(); |
|
|
public defaultDateFormat: string; |
|
|
protected isLoading = true; |
|
|
public deviceType: string; |
|
|
protected readonly isUUID = isUUID; |
|
|
public displayedColumns: string[] = []; |
|
|
protected pageSize = DEFAULT_PAGE_SIZE; |
|
|
public filters$ = new Subject<Filter[]>(); |
|
|
protected placeholder = ''; |
|
|
public ghostfolioScraperApiSymbolPrefix = ghostfolioScraperApiSymbolPrefix; |
|
|
protected readonly selection = new SelectionModel<AdminMarketDataItem>(true); |
|
|
public hasPermissionForSubscription: boolean; |
|
|
protected totalItems = 0; |
|
|
public info: InfoItem; |
|
|
protected user: User; |
|
|
public isLoading = true; |
|
|
|
|
|
public isUUID = isUUID; |
|
|
private activeFilters: Filter[] = []; |
|
|
public placeholder = ''; |
|
|
private benchmarks: Partial<SymbolProfile>[]; |
|
|
public pageSize = DEFAULT_PAGE_SIZE; |
|
|
private readonly deviceType = computed( |
|
|
public selection: SelectionModel<Partial<SymbolProfile>>; |
|
|
() => this.deviceDetectorService.deviceInfo().deviceType |
|
|
public totalItems = 0; |
|
|
); |
|
|
public user: User; |
|
|
private readonly hasPermissionForSubscription: boolean; |
|
|
|
|
|
private readonly info: InfoItem; |
|
|
public constructor( |
|
|
private readonly paginator = viewChild.required(MatPaginator); |
|
|
public adminMarketDataService: AdminMarketDataService, |
|
|
private readonly sort = viewChild.required(MatSort); |
|
|
private adminService: AdminService, |
|
|
|
|
|
private changeDetectorRef: ChangeDetectorRef, |
|
|
private readonly adminService = inject(AdminService); |
|
|
private dataService: DataService, |
|
|
private readonly changeDetectorRef = inject(ChangeDetectorRef); |
|
|
private destroyRef: DestroyRef, |
|
|
private readonly dataService = inject(DataService); |
|
|
private deviceDetectorService: DeviceDetectorService, |
|
|
private readonly destroyRef = inject(DestroyRef); |
|
|
private dialog: MatDialog, |
|
|
private readonly deviceDetectorService = inject(DeviceDetectorService); |
|
|
private route: ActivatedRoute, |
|
|
private readonly dialog = inject(MatDialog); |
|
|
private router: Router, |
|
|
private readonly route = inject(ActivatedRoute); |
|
|
private userService: UserService |
|
|
private readonly router = inject(Router); |
|
|
) { |
|
|
private readonly userService = inject(UserService); |
|
|
|
|
|
|
|
|
|
|
|
public constructor() { |
|
|
this.info = this.dataService.fetchInfo(); |
|
|
this.info = this.dataService.fetchInfo(); |
|
|
|
|
|
|
|
|
this.hasPermissionForSubscription = hasPermission( |
|
|
this.hasPermissionForSubscription = hasPermission( |
|
|
@ -255,14 +257,14 @@ export class GfAdminMarketDataComponent implements AfterViewInit, OnInit { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
public ngAfterViewInit() { |
|
|
public ngAfterViewInit() { |
|
|
this.sort.sortChange.subscribe( |
|
|
this.sort().sortChange.subscribe( |
|
|
({ active: sortColumn, direction }: Sort) => { |
|
|
({ active: sortColumn, direction }: Sort) => { |
|
|
this.paginator.pageIndex = 0; |
|
|
this.paginator().pageIndex = 0; |
|
|
|
|
|
|
|
|
this.loadData({ |
|
|
this.loadData({ |
|
|
sortColumn, |
|
|
sortColumn, |
|
|
sortDirection: direction, |
|
|
sortDirection: direction, |
|
|
pageIndex: this.paginator.pageIndex |
|
|
pageIndex: this.paginator().pageIndex |
|
|
}); |
|
|
}); |
|
|
} |
|
|
} |
|
|
); |
|
|
); |
|
|
@ -272,24 +274,24 @@ export class GfAdminMarketDataComponent implements AfterViewInit, OnInit { |
|
|
const { benchmarks } = this.dataService.fetchInfo(); |
|
|
const { benchmarks } = this.dataService.fetchInfo(); |
|
|
|
|
|
|
|
|
this.benchmarks = benchmarks; |
|
|
this.benchmarks = benchmarks; |
|
|
this.deviceType = this.deviceDetectorService.getDeviceInfo().deviceType; |
|
|
|
|
|
|
|
|
|
|
|
this.selection = new SelectionModel(true); |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
public onChangePage(page: PageEvent) { |
|
|
protected onChangePage(page: PageEvent) { |
|
|
this.loadData({ |
|
|
this.loadData({ |
|
|
pageIndex: page.pageIndex, |
|
|
pageIndex: page.pageIndex, |
|
|
sortColumn: this.sort.active, |
|
|
sortColumn: this.sort().active, |
|
|
sortDirection: this.sort.direction |
|
|
sortDirection: this.sort().direction |
|
|
}); |
|
|
}); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
public onDeleteAssetProfile({ dataSource, symbol }: AssetProfileIdentifier) { |
|
|
protected onDeleteAssetProfile({ |
|
|
|
|
|
dataSource, |
|
|
|
|
|
symbol |
|
|
|
|
|
}: AssetProfileIdentifier) { |
|
|
this.adminMarketDataService.deleteAssetProfile({ dataSource, symbol }); |
|
|
this.adminMarketDataService.deleteAssetProfile({ dataSource, symbol }); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
public onDeleteAssetProfiles() { |
|
|
protected onDeleteAssetProfiles() { |
|
|
this.adminMarketDataService.deleteAssetProfiles( |
|
|
this.adminMarketDataService.deleteAssetProfiles( |
|
|
this.selection.selected.map(({ dataSource, symbol }) => { |
|
|
this.selection.selected.map(({ dataSource, symbol }) => { |
|
|
return { dataSource, symbol }; |
|
|
return { dataSource, symbol }; |
|
|
@ -297,7 +299,7 @@ export class GfAdminMarketDataComponent implements AfterViewInit, OnInit { |
|
|
); |
|
|
); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
public onGather7Days() { |
|
|
protected onGather7Days() { |
|
|
this.adminService |
|
|
this.adminService |
|
|
.gather7Days() |
|
|
.gather7Days() |
|
|
.pipe(takeUntilDestroyed(this.destroyRef)) |
|
|
.pipe(takeUntilDestroyed(this.destroyRef)) |
|
|
@ -308,7 +310,7 @@ export class GfAdminMarketDataComponent implements AfterViewInit, OnInit { |
|
|
}); |
|
|
}); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
public onGatherMax() { |
|
|
protected onGatherMax() { |
|
|
this.adminService |
|
|
this.adminService |
|
|
.gatherMax() |
|
|
.gatherMax() |
|
|
.pipe(takeUntilDestroyed(this.destroyRef)) |
|
|
.pipe(takeUntilDestroyed(this.destroyRef)) |
|
|
@ -319,31 +321,14 @@ export class GfAdminMarketDataComponent implements AfterViewInit, OnInit { |
|
|
}); |
|
|
}); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
public onGatherProfileData() { |
|
|
protected onGatherProfileData() { |
|
|
this.adminService |
|
|
this.adminService |
|
|
.gatherProfileData() |
|
|
.gatherProfileData() |
|
|
.pipe(takeUntilDestroyed(this.destroyRef)) |
|
|
.pipe(takeUntilDestroyed(this.destroyRef)) |
|
|
.subscribe(); |
|
|
.subscribe(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
public onGatherProfileDataBySymbol({ |
|
|
protected onOpenAssetProfileDialog({ |
|
|
dataSource, |
|
|
|
|
|
symbol |
|
|
|
|
|
}: AssetProfileIdentifier) { |
|
|
|
|
|
this.adminService |
|
|
|
|
|
.gatherProfileDataBySymbol({ dataSource, symbol }) |
|
|
|
|
|
.pipe(takeUntilDestroyed(this.destroyRef)) |
|
|
|
|
|
.subscribe(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public onGatherSymbol({ dataSource, symbol }: AssetProfileIdentifier) { |
|
|
|
|
|
this.adminService |
|
|
|
|
|
.gatherSymbol({ dataSource, symbol }) |
|
|
|
|
|
.pipe(takeUntilDestroyed(this.destroyRef)) |
|
|
|
|
|
.subscribe(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public onOpenAssetProfileDialog({ |
|
|
|
|
|
dataSource, |
|
|
dataSource, |
|
|
symbol |
|
|
symbol |
|
|
}: AssetProfileIdentifier) { |
|
|
}: AssetProfileIdentifier) { |
|
|
@ -375,8 +360,8 @@ export class GfAdminMarketDataComponent implements AfterViewInit, OnInit { |
|
|
? Number.MAX_SAFE_INTEGER |
|
|
? Number.MAX_SAFE_INTEGER |
|
|
: DEFAULT_PAGE_SIZE; |
|
|
: DEFAULT_PAGE_SIZE; |
|
|
|
|
|
|
|
|
if (pageIndex === 0 && this.paginator) { |
|
|
if (pageIndex === 0 && this.paginator()) { |
|
|
this.paginator.pageIndex = 0; |
|
|
this.paginator().pageIndex = 0; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
this.placeholder = |
|
|
this.placeholder = |
|
|
@ -406,7 +391,7 @@ export class GfAdminMarketDataComponent implements AfterViewInit, OnInit { |
|
|
}; |
|
|
}; |
|
|
}) |
|
|
}) |
|
|
); |
|
|
); |
|
|
this.dataSource.sort = this.sort; |
|
|
this.dataSource.sort = this.sort(); |
|
|
|
|
|
|
|
|
this.isLoading = false; |
|
|
this.isLoading = false; |
|
|
|
|
|
|
|
|
@ -435,12 +420,13 @@ export class GfAdminMarketDataComponent implements AfterViewInit, OnInit { |
|
|
data: { |
|
|
data: { |
|
|
dataSource, |
|
|
dataSource, |
|
|
symbol, |
|
|
symbol, |
|
|
colorScheme: this.user?.settings.colorScheme, |
|
|
colorScheme: |
|
|
deviceType: this.deviceType, |
|
|
this.user?.settings.colorScheme ?? DEFAULT_COLOR_SCHEME, |
|
|
locale: this.user?.settings?.locale |
|
|
deviceType: this.deviceType(), |
|
|
}, |
|
|
locale: this.user?.settings?.locale ?? locale |
|
|
height: this.deviceType === 'mobile' ? '98vh' : '80vh', |
|
|
} satisfies AssetProfileDialogParams, |
|
|
width: this.deviceType === 'mobile' ? '100vw' : '50rem' |
|
|
height: this.deviceType() === 'mobile' ? '98vh' : '80vh', |
|
|
|
|
|
width: this.deviceType() === 'mobile' ? '100vw' : '50rem' |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
dialogRef |
|
|
dialogRef |
|
|
@ -471,10 +457,10 @@ export class GfAdminMarketDataComponent implements AfterViewInit, OnInit { |
|
|
>(GfCreateAssetProfileDialogComponent, { |
|
|
>(GfCreateAssetProfileDialogComponent, { |
|
|
autoFocus: false, |
|
|
autoFocus: false, |
|
|
data: { |
|
|
data: { |
|
|
deviceType: this.deviceType, |
|
|
deviceType: this.deviceType(), |
|
|
locale: this.user?.settings?.locale |
|
|
locale: this.user?.settings?.locale ?? locale |
|
|
}, |
|
|
} satisfies CreateAssetProfileDialogParams, |
|
|
width: this.deviceType === 'mobile' ? '100vw' : '50rem' |
|
|
width: this.deviceType() === 'mobile' ? '100vw' : '50rem' |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
dialogRef |
|
|
dialogRef |
|
|
|