CUB-41: Add low stock indicators to filament UI
This commit is contained in:
100
frontend/src/app/models/filament.model.ts
Normal file
100
frontend/src/app/models/filament.model.ts
Normal file
@@ -0,0 +1,100 @@
|
||||
/**
|
||||
* Filament model matching the Extrudex backend FilamentResponse DTO.
|
||||
* Used for displaying spool inventory in the filament table UI.
|
||||
*/
|
||||
export interface Filament {
|
||||
/** Unique identifier for the filament spool. */
|
||||
id: string;
|
||||
|
||||
/** Foreign key to the base material. */
|
||||
materialBaseId: string;
|
||||
|
||||
/** Name of the base material (e.g., "PLA", "PETG"). */
|
||||
materialBaseName: string;
|
||||
|
||||
/** Foreign key to the material finish. */
|
||||
materialFinishId: string;
|
||||
|
||||
/** Name of the material finish (e.g., "Basic", "Matte"). */
|
||||
materialFinishName: string;
|
||||
|
||||
/** Foreign key to the optional material modifier. */
|
||||
materialModifierId: string | null;
|
||||
|
||||
/** Name of the material modifier (e.g., "Carbon Fiber"). Null if none. */
|
||||
materialModifierName: string | null;
|
||||
|
||||
/** Brand name (e.g., "Bambu Lab", "Polymaker"). */
|
||||
brand: string;
|
||||
|
||||
/** Human-readable color name (e.g., "Fire Engine Red"). */
|
||||
colorName: string;
|
||||
|
||||
/** Hex color code (e.g., "#FF0000"). */
|
||||
colorHex: string;
|
||||
|
||||
/** Total spool weight in grams when full. */
|
||||
weightTotalGrams: number;
|
||||
|
||||
/** Current remaining weight in grams. */
|
||||
weightRemainingGrams: number;
|
||||
|
||||
/** Filament diameter in millimeters. Typically 1.75mm. */
|
||||
filamentDiameterMm: number;
|
||||
|
||||
/** Manufacturer-assigned serial number. */
|
||||
spoolSerial: string;
|
||||
|
||||
/** Purchase price per spool. Null if not tracked. */
|
||||
purchasePrice: number | null;
|
||||
|
||||
/** Date the spool was purchased or received. */
|
||||
purchaseDate: string | null;
|
||||
|
||||
/** Whether the spool is currently active and available. */
|
||||
isActive: boolean;
|
||||
|
||||
/** Timestamp when this record was created (UTC). */
|
||||
createdAt: string;
|
||||
|
||||
/** Timestamp when this record was last updated (UTC). */
|
||||
updatedAt: string;
|
||||
|
||||
/** URL to the QR code image for this spool. */
|
||||
qrCodeUrl: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stock level classification for low stock indicators.
|
||||
* - critical: ≤ 10% remaining
|
||||
* - low: ≤ 25% remaining
|
||||
* - moderate: ≤ 50% remaining
|
||||
* - healthy: > 50% remaining
|
||||
*/
|
||||
export type StockLevel = 'critical' | 'low' | 'moderate' | 'healthy';
|
||||
|
||||
/**
|
||||
* Compute the remaining weight percentage for a filament spool.
|
||||
* Returns a value from 0 to 100.
|
||||
*/
|
||||
export function getRemainingPercent(filament: Filament): number {
|
||||
if (filament.weightTotalGrams <= 0) return 0;
|
||||
const pct = (filament.weightRemainingGrams / filament.weightTotalGrams) * 100;
|
||||
return Math.min(Math.max(pct, 0), 100);
|
||||
}
|
||||
|
||||
/**
|
||||
* Classify the stock level based on remaining percentage.
|
||||
* Thresholds:
|
||||
* critical — ≤ 10% (nearly empty, red alert)
|
||||
* low — ≤ 25% (getting low, amber warning)
|
||||
* moderate — ≤ 50% (half or less, yellow info)
|
||||
* healthy — > 50% (plenty left, green OK)
|
||||
*/
|
||||
export function classifyStockLevel(filament: Filament): StockLevel {
|
||||
const pct = getRemainingPercent(filament);
|
||||
if (pct <= 10) return 'critical';
|
||||
if (pct <= 25) return 'low';
|
||||
if (pct <= 50) return 'moderate';
|
||||
return 'healthy';
|
||||
}
|
||||
Reference in New Issue
Block a user