Feature AMS Info Card (#570)

* AMS Labels addition to PrintersPage

* Added database reinitialization for schema migrations on database restore

* Bug fixes and AMS Label persistence updates

* Update database.py to resolve PR conflicts

* PR Comment Resolution

* Resolve conflicts in database.py for PR#570

* Updates to address PR#570 additional comments

* Optimize visibility handling for popup component

* Improve serial key handling in printers.py

Refactor serial key assignment to handle empty AMS serial gracefully.

* Implement error handling in serial number mapping

Add error handling for serial number mapping.

* Add migration to drop old ams_labels table

---------

Co-authored-by: MartinNYHC <mz@v8w.de>
This commit is contained in:
Thomas Rambach
2026-03-05 08:36:39 +01:00
committed by GitHub
co-authored by MartinNYHC
parent 5ee2ef8dbf
commit 7ba67012f6
20 changed files with 786 additions and 36 deletions
@@ -0,0 +1,47 @@
/**
* FilamentSlotCircle renders a small color circle with the 1-based slot
* number centered inside, matching the style used on AMS cards in PrintersPage.
*
* Props:
* trayColor - 6-char hex color string WITHOUT leading '#' (e.g. "FF0000").
* Pass undefined / empty string when the slot is empty.
* trayType - Filament material string (e.g. "PLA"). Used to decide the
* fallback background when there is no color but a type is known.
* isEmpty - Whether the slot contains no filament.
* slotNumber - 1-based slot number to display inside the circle.
*/
interface FilamentSlotCircleProps {
trayColor?: string | null;
trayType?: string | null;
isEmpty: boolean;
slotNumber: number;
}
function isLightFilamentColor(hex: string): boolean {
if (!hex || hex.length < 6) return false;
const r = parseInt(hex.slice(0, 2), 16);
const g = parseInt(hex.slice(2, 4), 16);
const b = parseInt(hex.slice(4, 6), 16);
return (0.299 * r + 0.587 * g + 0.114 * b) / 255 > 0.6;
}
export function FilamentSlotCircle({ trayColor, trayType, isEmpty, slotNumber }: FilamentSlotCircleProps) {
return (
<div
className="w-3.5 h-3.5 rounded-full mx-auto mb-0.5 border-2 flex items-center justify-center"
style={{
backgroundColor: trayColor ? `#${trayColor}` : (trayType ? '#333' : 'transparent'),
borderColor: isEmpty ? '#666' : 'rgba(255,255,255,0.1)',
borderStyle: isEmpty ? 'dashed' : 'solid',
}}
>
<span
className="text-[6px] font-bold leading-none select-none"
style={{ color: trayColor && isLightFilamentColor(trayColor) ? '#000' : '#fff' }}
>
{slotNumber}
</span>
</div>
);
}