Change jobs table in admin control to mat-table (#2444)
* Change jobs table in admin control to mat-table * Update changelog
This commit is contained in:
parent
f47c7313af
commit
d8d4d8f001
@ -11,6 +11,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
- Supported enter key press to submit the form of the create or update access dialog
|
||||
|
||||
### Changed
|
||||
|
||||
- Changed the queue jobs view in the admin control panel to an `@angular/material` data table
|
||||
|
||||
## 2.9.0 - 2023-10-08
|
||||
|
||||
### Added
|
||||
|
@ -6,6 +6,7 @@ import {
|
||||
OnInit
|
||||
} from '@angular/core';
|
||||
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||
import { MatTableDataSource } from '@angular/material/table';
|
||||
import { AdminService } from '@ghostfolio/client/services/admin.service';
|
||||
import { UserService } from '@ghostfolio/client/services/user/user.service';
|
||||
import { QUEUE_JOB_STATUS_LIST } from '@ghostfolio/common/config';
|
||||
@ -24,7 +25,19 @@ import { takeUntil } from 'rxjs/operators';
|
||||
export class AdminJobsComponent implements OnDestroy, OnInit {
|
||||
public defaultDateTimeFormat: string;
|
||||
public filterForm: FormGroup;
|
||||
public jobs: AdminJobs['jobs'] = [];
|
||||
public dataSource: MatTableDataSource<AdminJobs['jobs'][0]> =
|
||||
new MatTableDataSource();
|
||||
public displayedColumns = [
|
||||
'index',
|
||||
'type',
|
||||
'symbol',
|
||||
'dataSource',
|
||||
'attempts',
|
||||
'created',
|
||||
'finished',
|
||||
'status',
|
||||
'actions'
|
||||
];
|
||||
public statusFilterOptions = QUEUE_JOB_STATUS_LIST;
|
||||
public user: User;
|
||||
|
||||
@ -102,7 +115,7 @@ export class AdminJobsComponent implements OnDestroy, OnInit {
|
||||
.fetchJobs({ status: aStatus })
|
||||
.pipe(takeUntil(this.unsubscribeSubject))
|
||||
.subscribe(({ jobs }) => {
|
||||
this.jobs = jobs;
|
||||
this.dataSource = new MatTableDataSource(jobs);
|
||||
|
||||
this.changeDetectorRef.markForCheck();
|
||||
});
|
||||
|
@ -13,18 +13,120 @@
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
</form>
|
||||
<table class="gf-table w-100">
|
||||
<thead>
|
||||
<tr class="mat-header-row">
|
||||
<th class="mat-header-cell px-1 py-2 text-right">#</th>
|
||||
<th class="mat-header-cell px-1 py-2" i18n>Type</th>
|
||||
<th class="mat-header-cell px-1 py-2" i18n>Symbol</th>
|
||||
<th class="mat-header-cell px-1 py-2" i18n>Data Source</th>
|
||||
<th class="mat-header-cell px-1 py-2 text-right" i18n>Attempts</th>
|
||||
<th class="mat-header-cell px-1 py-2" i18n>Created</th>
|
||||
<th class="mat-header-cell px-1 py-2" i18n>Finished</th>
|
||||
<th class="mat-header-cell px-1 py-2" i18n>Status</th>
|
||||
<th class="mat-header-cell px-1 py-2">
|
||||
<table class="gf-table w-100" mat-table [dataSource]="dataSource">
|
||||
<ng-container matColumnDef="index">
|
||||
<th *matHeaderCellDef class="px-1 py-2 text-right" mat-header-cell>
|
||||
#
|
||||
</th>
|
||||
<td *matCellDef="let element" class="px-1 py-2 text-right" mat-cell>
|
||||
{{ element.id }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="type">
|
||||
<th *matHeaderCellDef class="px-1 py-2" mat-header-cell>
|
||||
<ng-container i18n>Type</ng-container>
|
||||
</th>
|
||||
<td *matCellDef="let element" class="px-1 py-2" mat-cell>
|
||||
<span class="align-items-center d-flex">
|
||||
<ion-icon
|
||||
class="mr-1"
|
||||
name="arrow-down-circle-outline"
|
||||
></ion-icon>
|
||||
<ng-container *ngIf="element.name === 'GATHER_ASSET_PROFILE'">
|
||||
<span i18n>Asset Profile</span>
|
||||
</ng-container>
|
||||
<ng-container
|
||||
*ngIf="element.name === 'GATHER_HISTORICAL_MARKET_DATA'"
|
||||
>
|
||||
<span i18n>Historical Market Data</span>
|
||||
</ng-container>
|
||||
</span>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="symbol">
|
||||
<th *matHeaderCellDef class="px-1 py-2" mat-header-cell>
|
||||
<ng-container i18n>Symbol</ng-container>
|
||||
</th>
|
||||
<td *matCellDef="let element" class="px-1 py-2" mat-cell>
|
||||
{{ element.data?.symbol }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="dataSource">
|
||||
<th *matHeaderCellDef class="px-1 py-2" mat-header-cell>
|
||||
<ng-container i18n>Data Source</ng-container>
|
||||
</th>
|
||||
<td *matCellDef="let element" class="px-1 py-2" mat-cell>
|
||||
{{ element.data?.dataSource }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="attempts">
|
||||
<th *matHeaderCellDef class="px-1 py-2 text-right" mat-header-cell>
|
||||
<ng-container i18n>Attempts</ng-container>
|
||||
</th>
|
||||
<td *matCellDef="let element" class="px-1 py-2 text-right" mat-cell>
|
||||
{{ element.attemptsMade }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="created">
|
||||
<th *matHeaderCellDef class="px-1 py-2" mat-header-cell>
|
||||
<ng-container i18n>Created</ng-container>
|
||||
</th>
|
||||
<td *matCellDef="let element" class="px-1 py-2" mat-cell>
|
||||
{{ element.timestamp | date: defaultDateTimeFormat }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="finished">
|
||||
<th *matHeaderCellDef class="px-1 py-2" mat-header-cell>
|
||||
<ng-container i18n>Finished</ng-container>
|
||||
</th>
|
||||
<td *matCellDef="let element" class="px-1 py-2" mat-cell>
|
||||
{{ element.finishedOn | date: defaultDateTimeFormat }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="status">
|
||||
<th *matHeaderCellDef class="px-1 py-2" mat-header-cell>
|
||||
<ng-container i18n>Status</ng-container>
|
||||
</th>
|
||||
<td *matCellDef="let element" class="px-1 py-2" mat-cell>
|
||||
<ion-icon
|
||||
*ngIf="element.state === 'active'"
|
||||
name="play-outline"
|
||||
></ion-icon>
|
||||
<ion-icon
|
||||
*ngIf="element.state === 'completed'"
|
||||
class="text-success"
|
||||
name="checkmark-circle-outline"
|
||||
></ion-icon>
|
||||
<ion-icon
|
||||
*ngIf="element.state === 'delayed'"
|
||||
name="time-outline"
|
||||
[ngClass]="{ 'text-danger': element.stacktrace?.length > 0 }"
|
||||
></ion-icon>
|
||||
<ion-icon
|
||||
*ngIf="element.state === 'failed'"
|
||||
class="text-danger"
|
||||
name="alert-circle-outline"
|
||||
></ion-icon>
|
||||
<ion-icon
|
||||
*ngIf="element.state === 'paused'"
|
||||
name="pause-outline"
|
||||
></ion-icon>
|
||||
<ion-icon
|
||||
*ngIf="element.state === 'waiting'"
|
||||
name="cafe-outline"
|
||||
></ion-icon>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="actions">
|
||||
<th *matHeaderCellDef class="px-1 py-2" mat-header-cell>
|
||||
<button
|
||||
class="mx-1 no-min-width px-2"
|
||||
mat-button
|
||||
@ -39,69 +141,7 @@
|
||||
</button>
|
||||
</mat-menu>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<ng-container *ngFor="let job of jobs">
|
||||
<tr class="mat-row">
|
||||
<td class="mat-cell px-1 py-2 text-right">{{ job.id }}</td>
|
||||
<td class="mat-cell px-1 py-2">
|
||||
<span class="align-items-center d-flex">
|
||||
<ion-icon
|
||||
class="mr-1"
|
||||
name="arrow-down-circle-outline"
|
||||
></ion-icon>
|
||||
<ng-container *ngIf="job.name === 'GATHER_ASSET_PROFILE'">
|
||||
<span i18n>Asset Profile</span>
|
||||
</ng-container>
|
||||
<ng-container
|
||||
*ngIf="job.name === 'GATHER_HISTORICAL_MARKET_DATA'"
|
||||
>
|
||||
<span i18n>Historical Market Data</span>
|
||||
</ng-container>
|
||||
</span>
|
||||
</td>
|
||||
<td class="mat-cell px-1 py-2">{{ job.data?.symbol }}</td>
|
||||
<td class="mat-cell px-1 py-2">{{ job.data?.dataSource }}</td>
|
||||
<td class="mat-cell px-1 py-2 text-right">
|
||||
{{ job.attemptsMade }}
|
||||
</td>
|
||||
<td class="mat-cell px-1 py-2">
|
||||
{{ job.timestamp | date: defaultDateTimeFormat }}
|
||||
</td>
|
||||
<td class="mat-cell px-1 py-2">
|
||||
{{ job.finishedOn | date: defaultDateTimeFormat }}
|
||||
</td>
|
||||
<td class="mat-cell px-1 py-2">
|
||||
<ion-icon
|
||||
*ngIf="job.state === 'active'"
|
||||
name="play-outline"
|
||||
></ion-icon>
|
||||
<ion-icon
|
||||
*ngIf="job.state === 'completed'"
|
||||
class="text-success"
|
||||
name="checkmark-circle-outline"
|
||||
></ion-icon>
|
||||
<ion-icon
|
||||
*ngIf="job.state === 'delayed'"
|
||||
name="time-outline"
|
||||
[ngClass]="{ 'text-danger': job.stacktrace?.length > 0 }"
|
||||
></ion-icon>
|
||||
<ion-icon
|
||||
*ngIf="job.state === 'failed'"
|
||||
class="text-danger"
|
||||
name="alert-circle-outline"
|
||||
></ion-icon>
|
||||
<ion-icon
|
||||
*ngIf="job.state === 'paused'"
|
||||
name="pause-outline"
|
||||
></ion-icon>
|
||||
<ion-icon
|
||||
*ngIf="job.state === 'waiting'"
|
||||
name="cafe-outline"
|
||||
></ion-icon>
|
||||
</td>
|
||||
<td class="mat-cell px-1 py-2">
|
||||
<td *matCellDef="let element" class="px-1 py-2" mat-cell>
|
||||
<button
|
||||
class="mx-1 no-min-width px-2"
|
||||
mat-button
|
||||
@ -111,24 +151,25 @@
|
||||
<ion-icon name="ellipsis-horizontal"></ion-icon>
|
||||
</button>
|
||||
<mat-menu #jobActionsMenu="matMenu" xPosition="before">
|
||||
<button mat-menu-item (click)="onViewData(job.data)">
|
||||
<button mat-menu-item (click)="onViewData(element.data)">
|
||||
<ng-container i18n>View Data</ng-container>
|
||||
</button>
|
||||
<button
|
||||
mat-menu-item
|
||||
[disabled]="job.stacktrace?.length <= 0"
|
||||
(click)="onViewStacktrace(job.stacktrace)"
|
||||
[disabled]="element.stacktrace?.length <= 0"
|
||||
(click)="onViewStacktrace(element.stacktrace)"
|
||||
>
|
||||
<ng-container i18n>View Stacktrace</ng-container>
|
||||
</button>
|
||||
<button mat-menu-item (click)="onDeleteJob(job.id)">
|
||||
<button mat-menu-item (click)="onDeleteJob(element.id)">
|
||||
<ng-container i18n>Delete Job</ng-container>
|
||||
</button>
|
||||
</mat-menu>
|
||||
</td>
|
||||
</tr>
|
||||
</ng-container>
|
||||
</tbody>
|
||||
|
||||
<tr *matHeaderRowDef="displayedColumns" mat-header-row></tr>
|
||||
<tr *matRowDef="let row; columns: displayedColumns" mat-row></tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -4,6 +4,7 @@ import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatMenuModule } from '@angular/material/menu';
|
||||
import { MatSelectModule } from '@angular/material/select';
|
||||
import { MatTableModule } from '@angular/material/table';
|
||||
|
||||
import { AdminJobsComponent } from './admin-jobs.component';
|
||||
|
||||
@ -15,6 +16,7 @@ import { AdminJobsComponent } from './admin-jobs.component';
|
||||
MatButtonModule,
|
||||
MatMenuModule,
|
||||
MatSelectModule,
|
||||
MatTableModule,
|
||||
ReactiveFormsModule
|
||||
],
|
||||
schemas: [CUSTOM_ELEMENTS_SCHEMA]
|
||||
|
Loading…
x
Reference in New Issue
Block a user