Add sorting functionality to staff playtime table and include roles in UI and database mapping

This commit is contained in:
2025-11-24 01:08:43 +01:00
parent fb01fc7571
commit 2bc5c41435
5 changed files with 48 additions and 9 deletions
@@ -18,21 +18,22 @@
</button>
</div>
<table mat-table [dataSource]="staffPt()" class="mat-elevation-z2 full-width">
<table mat-table [dataSource]="sortedStaffPt()" class="mat-elevation-z2 full-width" matSort (matSortChange)="sort.set($event)"
[matSortActive]="sort().active" [matSortDirection]="sort().direction" [matSortDisableClear]="true">
<ng-container matColumnDef="staff_member">
<th mat-header-cell *matHeaderCellDef>Staff Member</th>
<th mat-header-cell *matHeaderCellDef mat-sort-header="staff_member">Staff Member</th>
<td mat-cell *matCellDef="let row"> {{ row.staff_member }}</td>
</ng-container>
<ng-container matColumnDef="playtime">
<th mat-header-cell *matHeaderCellDef>Playtime</th>
<th mat-header-cell *matHeaderCellDef mat-sort-header="playtime">Playtime</th>
<td mat-cell *matCellDef="let row"
[style.color]="row.playtime < 420 ? 'red' : ''"> {{ minutesToHm(row.playtime) }}
</td>
</ng-container>
<ng-container matColumnDef="role">
<th mat-header-cell *matHeaderCellDef>Rank</th>
<th mat-header-cell *matHeaderCellDef mat-sort-header="role">Rank</th>
<td mat-cell *matCellDef="let row"> {{ row.role }}</td>
</ng-container>
@@ -21,6 +21,23 @@
width: 100%;
}
/* Ensure good contrast in dark/light modes */
.table-theme th.mat-mdc-header-cell,
.table-theme td.mat-mdc-cell,
.table-theme .mat-mdc-header-row,
.table-theme .mat-mdc-row {
color: var(--font-color);
}
/* Apply class to table via HTML's class attribute if needed; here we style all mat tables in this component */
table.mat-mdc-table {
color: var(--font-color);
}
.mat-sort-header-arrow {
color: var(--font-color);
}
.no-data td {
text-align: center;
padding: 16px;
@@ -4,13 +4,15 @@ import {MatTableModule} from '@angular/material/table';
import {MatButtonModule} from '@angular/material/button';
import {MatIconModule} from '@angular/material/icon';
import {MatTooltipModule} from '@angular/material/tooltip';
import {MatSortModule} from '@angular/material/sort';
import {SiteService, StaffPlaytime} from '@api';
import {Sort} from '@angular/material/sort';
import {HeaderComponent} from '@header/header.component';
@Component({
selector: 'app-staff-pt',
standalone: true,
imports: [CommonModule, MatTableModule, MatButtonModule, MatIconModule, MatTooltipModule, HeaderComponent],
imports: [CommonModule, MatTableModule, MatButtonModule, MatIconModule, MatTooltipModule, MatSortModule, HeaderComponent],
templateUrl: './staff-pt.component.html',
styleUrl: './staff-pt.component.scss'
})
@@ -18,13 +20,31 @@ export class StaffPtComponent implements OnInit {
siteService = inject(SiteService);
staffPt = signal<StaffPlaytime[]>([]);
sort = signal<Sort>({active: 'playtime', direction: 'desc'} as Sort);
sortedStaffPt = computed<StaffPlaytime[]>(() => {
const data = [...this.staffPt()];
const {active, direction} = this.sort();
if (!direction || !active) return data;
const dir = direction === 'asc' ? 1 : -1;
return data.sort((a, b) => {
switch (active) {
case 'staff_member':
return a.staff_member.localeCompare(b.staff_member) * dir;
case 'role':
return a.role.localeCompare(b.role) * dir;
case 'playtime':
default:
return ((a.playtime ?? 0) - (b.playtime ?? 0)) * dir;
}
});
});
weekStart = signal<Date>(this.getStartOfWeek(new Date()));
weekEnd = computed(() => this.getEndOfWeek(this.weekStart()));
todayStart = signal<Date>(this.startOfDay(new Date()));
displayedColumns = ['staff_member', 'playtime'];
displayedColumns = ['staff_member', 'playtime', 'role'];
ngOnInit(): void {
this.loadCurrentWeek();