mirror of
https://github.com/maziggy/bambuddy.git
synced 2026-10-22 03:49:18 +02:00
fix(print): keep filament gram usage visible when the name is long (#2669)
In the Print dialog's Filament Mapping, each required filament shows its name and the grams the job needs, e.g. "Bambu PLA Basic (281.2g)". Name and grams shared one fixed-width column with truncate on the whole string, so a long name pushed the "(...g)" off the end and clipped it -- partially on a wide screen, entirely in mobile portrait. The gram usage is the number that matters (does the spool have enough left?), so it shouldn't be the part that gets dropped. Pin the gram usage (shrink-0, whitespace-nowrap) and let only the name truncate, with the full name on hover. Applied to both the Specific-Printer (FilamentMapping) and Any-model (PrinterSelector) panels. Layout only.
This commit is contained in:
@@ -297,4 +297,47 @@ describe('FilamentMapping — FTS routing', () => {
|
||||
expect(swatch).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
it('pins the gram usage so a long name cannot clip it (#2669)', async () => {
|
||||
// Long resolved name + gram usage. The name must be the truncating
|
||||
// element; the "(25g)" must sit in its own non-truncating, shrink-0 span
|
||||
// so it stays visible on narrow/mobile widths.
|
||||
server.use(
|
||||
http.get('/api/v1/printers/:id/status', () => HttpResponse.json(createStatus({}))),
|
||||
http.get('/api/v1/cloud/builtin-filaments', () =>
|
||||
HttpResponse.json([{ filament_id: 'GFA01', name: 'Polymaker PLA Matte' }]),
|
||||
),
|
||||
http.get('/api/v1/cloud/filament-id-map', () => HttpResponse.json({})),
|
||||
http.get('/api/v1/inventory/colors/by-material', () => HttpResponse.json({ color_name: null })),
|
||||
);
|
||||
|
||||
render(
|
||||
<FilamentMapping
|
||||
printerId={1}
|
||||
filamentReqs={{
|
||||
filaments: [
|
||||
{ slot_id: 1, type: 'PLA', color: '#000000', used_grams: 25, used_meters: 8.5, nozzle_id: 1, tray_info_idx: 'GFA01' },
|
||||
],
|
||||
}}
|
||||
manualMappings={{}}
|
||||
onManualMappingChange={() => {}}
|
||||
currencySymbol="$"
|
||||
defaultCostPerKg={0}
|
||||
defaultExpanded
|
||||
/>,
|
||||
);
|
||||
|
||||
const grams = await screen.findByText('(25g)');
|
||||
// The gram usage never truncates and never shrinks away.
|
||||
expect(grams.className).toContain('shrink-0');
|
||||
expect(grams.className).not.toContain('truncate');
|
||||
|
||||
// The name is the element that truncates instead.
|
||||
const name = await screen.findByText('Polymaker PLA Matte');
|
||||
expect(name.className).toContain('truncate');
|
||||
// Name and grams are separate siblings, so the name shrinking can't take
|
||||
// the grams with it.
|
||||
expect(name).not.toBe(grams);
|
||||
expect(grams.parentElement).toBe(name.parentElement);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -243,8 +243,10 @@ export function FilamentMapping({
|
||||
<span title={`Required: ${resolvedName} - ${colorLabel}`}>
|
||||
<Circle className="w-3 h-3" fill={item.color} stroke={item.color} />
|
||||
</span>
|
||||
{/* Required type + grams + nozzle badge */}
|
||||
<span className="text-white truncate flex items-center gap-1">
|
||||
{/* Required type + grams + nozzle badge. Only the name
|
||||
truncates; the gram usage is pinned (shrink-0) so it never
|
||||
clips on narrow/mobile widths (#2669). */}
|
||||
<span className="text-white flex items-center gap-1 min-w-0">
|
||||
{isDualNozzle && item.nozzle_id != null && (
|
||||
<span
|
||||
className="inline-flex items-center justify-center w-3.5 h-3.5 rounded text-[9px] font-bold leading-none bg-bambu-gray/20 text-bambu-gray shrink-0"
|
||||
@@ -253,7 +255,8 @@ export function FilamentMapping({
|
||||
{item.nozzle_id === 1 ? t('printModal.leftNozzle') : t('printModal.rightNozzle')}
|
||||
</span>
|
||||
)}
|
||||
{resolvedName} <span className="text-bambu-gray">({item.used_grams}g)</span>
|
||||
<span className="truncate min-w-0" title={resolvedName}>{resolvedName}</span>
|
||||
<span className="text-bambu-gray shrink-0 whitespace-nowrap">({item.used_grams}g)</span>
|
||||
</span>
|
||||
{/* Arrow */}
|
||||
<span className="text-bambu-gray">→</span>
|
||||
|
||||
@@ -161,8 +161,11 @@ function InlineMappingEditor({
|
||||
<span title={`Required: ${req.type} - ${getColorName(req.color)}`}>
|
||||
<Circle className="w-3 h-3" fill={req.color} stroke={req.color} />
|
||||
</span>
|
||||
<span className="text-white truncate">
|
||||
{req.type} <span className="text-bambu-gray">({req.used_grams}g)</span>
|
||||
{/* Only the name truncates; the gram usage is pinned (shrink-0) so
|
||||
it never clips on narrow/mobile widths (#2669). */}
|
||||
<span className="text-white flex items-center gap-1 min-w-0">
|
||||
<span className="truncate min-w-0" title={req.type}>{req.type}</span>
|
||||
<span className="text-bambu-gray shrink-0 whitespace-nowrap">({req.used_grams}g)</span>
|
||||
</span>
|
||||
<span className="text-bambu-gray">→</span>
|
||||
<select
|
||||
|
||||
Reference in New Issue
Block a user