Files
Extrudex/frontend/src/app/components/filament-table/filament-table.component.html
2026-04-26 14:27:08 +00:00

123 lines
4.8 KiB
HTML

<!-- Filament Inventory Table — with low stock indicators -->
<div class="filament-table-container" role="region" aria-label="Filament inventory">
<!-- Low Stock Alert Banner — shown when critical or low stock spools exist -->
@if (criticalCount() > 0) {
<div class="alert-banner critical" role="alert">
<mat-icon aria-hidden="true">error</mat-icon>
<span>{{ criticalCount() }} spool{{ criticalCount() > 1 ? 's' : '' }} critically low (&le;10% remaining)</span>
</div>
} @else if (lowStockCount() > 0) {
<div class="alert-banner low" role="alert">
<mat-icon aria-hidden="true">warning</mat-icon>
<span>{{ lowStockCount() }} spool{{ lowStockCount() > 1 ? 's' : '' }} running low (&le;25% remaining)</span>
</div>
}
<!-- Filament Table -->
<table mat-table
[dataSource]="sortedFilaments()"
matSort
(matSortChange)="sortData($event)"
class="filament-table"
aria-label="Filament inventory table">
<!-- Color Column -->
<ng-container matColumnDef="color">
<th mat-header-cell *matHeaderCellDef mat-sort-header="color">Color</th>
<td mat-cell *matCellDef="let filament">
<span class="color-swatch"
[style.background-color]="filament.colorHex"
[matTooltip]="filament.colorName"
matTooltipPosition="after"
[attr.aria-label]="filament.colorName">
</span>
</td>
</ng-container>
<!-- Material Column -->
<ng-container matColumnDef="material">
<th mat-header-cell *matHeaderCellDef mat-sort-header="material">Material</th>
<td mat-cell *matCellDef="let filament">
<span class="material-name">{{ filament.materialBaseName }}</span>
@if (filament.materialModifierName) {
<span class="material-modifier"> {{ filament.materialModifierName }}</span>
}
</td>
</ng-container>
<!-- Brand Column -->
<ng-container matColumnDef="brand">
<th mat-header-cell *matHeaderCellDef mat-sort-header="brand">Brand</th>
<td mat-cell *matCellDef="let filament">{{ filament.brand }}</td>
</ng-container>
<!-- Serial Column -->
<ng-container matColumnDef="serial">
<th mat-header-cell *matHeaderCellDef mat-sort-header="serial">Serial</th>
<td mat-cell *matCellDef="let filament" class="serial-cell">{{ filament.spoolSerial }}</td>
</ng-container>
<!-- Remaining Weight Column -->
<ng-container matColumnDef="remaining">
<th mat-header-cell *matHeaderCellDef mat-sort-header="remaining">Remaining</th>
<td mat-cell *matCellDef="let filament">
<div class="remaining-cell">
<span class="remaining-text">
{{ formatWeight(filament.weightRemainingGrams) }} / {{ formatWeight(filament.weightTotalGrams) }}
</span>
<mat-progress-bar
mode="determinate"
[value]="getRemainingPercent(filament)"
[ngClass]="classifyStockLevel(filament)"
[matTooltip]="getRemainingPercent(filament).toFixed(0) + '% remaining'"
matTooltipPosition="below">
</mat-progress-bar>
</div>
</td>
</ng-container>
<!-- Stock Level Indicator Column -->
<ng-container matColumnDef="stockLevel">
<th mat-header-cell *matHeaderCellDef mat-sort-header="stockLevel">Stock</th>
<td mat-cell *matCellDef="let filament">
@let level = classifyStockLevel(filament);
<mat-chip-set aria-label="Stock level">
<mat-chip
[ngClass]="level"
[matTooltip]="stockLevelLabel(level) + ' ' + getRemainingPercent(filament).toFixed(0) + '% remaining'"
matTooltipPosition="below">
<mat-icon matChipStart [ngClass]="level">{{ stockLevelIcon(level) }}</mat-icon>
<span>{{ stockLevelLabel(level) }}</span>
</mat-chip>
</mat-chip-set>
</td>
</ng-container>
<!-- Status Column -->
<ng-container matColumnDef="status">
<th mat-header-cell *matHeaderCellDef mat-sort-header="status">Status</th>
<td mat-cell *matCellDef="let filament">
<span class="status-badge"
[class.active]="filament.isActive"
[class.inactive]="!filament.isActive">
{{ filament.isActive ? 'Active' : 'Inactive' }}
</span>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="columns()"></tr>
<tr mat-row *matRowDef="let row; columns: columns();"
[class.row-critical]="classifyStockLevel(row) === 'critical'"
[class.row-low]="classifyStockLevel(row) === 'low'">
</tr>
</table>
<!-- Empty state -->
@if (filaments().length === 0) {
<div class="empty-state" role="status">
<mat-icon aria-hidden="true">inventory_2</mat-icon>
<p>No filament spools found</p>
</div>
}
</div>