mirror of
https://github.com/maziggy/bambuddy.git
synced 2026-10-19 07:33:18 +02:00
Size the H2C nozzle rack card to its contents and number its slots
The rack card shared a row with the nozzle, bed and chamber readings but
was set to flex: 2 1 190px -- a 190px floor plus twice their growth share
-- to draw six fixed 28px chips. On anything wider than a compact card it
claimed several hundred pixels and left most of them empty, and the width
came out of the cards that needed it: the combined dual-nozzle reading was
wrapping "220 / 220" onto two lines beside a mostly blank rack. It is now
flex: 0 1 auto, so it takes its content width and gives the remainder
back. Shrink stays enabled so it still gives way on a narrow card instead
of overflowing.
Each slot also carries its physical rack position 1-6 below the chip, so a
nozzle can be named rather than counted along. The numbering is positional
-- an empty slot keeps its number -- so "the nozzle in slot 4" means the
same thing however many of the six are occupied.
The #943 regression test read every span in the slot row, which the new
number spans would have interleaved with the diameters; it now matches the
diameter spans specifically. A second test pins the 1-6 labelling across a
rack with empty positions.
This commit is contained in:
@@ -812,10 +812,34 @@ describe('PrintersPage', () => {
|
||||
const rackLabel = screen.getAllByText('Nozzle Rack')[0];
|
||||
const rackCard = rackLabel.parentElement!;
|
||||
const slotRow = rackCard.querySelectorAll('div.flex')[0];
|
||||
const slotTexts = Array.from(slotRow.querySelectorAll('span')).map(s => s.textContent);
|
||||
// Match the diameter spans specifically — each chip also carries a slot
|
||||
// number span, and a bare `span` sweep would interleave the two.
|
||||
const slotTexts = Array.from(slotRow.querySelectorAll('span[data-rack-diameter]')).map(s => s.textContent);
|
||||
expect(slotTexts).toEqual(['—', '0.2', '0.6', '0.8', '1.0', '1.2']);
|
||||
});
|
||||
|
||||
it('labels every rack position 1..6 regardless of which nozzles are present', async () => {
|
||||
// The numbering is positional, not a count of what is loaded: the empty
|
||||
// position keeps its number so "the nozzle in slot 4" means the same
|
||||
// thing whether or not slots 1..3 are occupied.
|
||||
server.use(
|
||||
http.get('/api/v1/printers/:id/status', () => {
|
||||
return HttpResponse.json(h2cStatus);
|
||||
})
|
||||
);
|
||||
|
||||
render(<PrintersPage />);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getAllByText('Nozzle Rack').length).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
const rackLabel = screen.getAllByText('Nozzle Rack')[0];
|
||||
const slotRow = rackLabel.parentElement!.querySelectorAll('div.flex')[0];
|
||||
const numbers = Array.from(slotRow.querySelectorAll('span:not([data-rack-diameter])')).map(s => s.textContent);
|
||||
expect(numbers).toEqual(['1', '2', '3', '4', '5', '6']);
|
||||
});
|
||||
|
||||
it('hides nozzle rack when only L/R nozzles present (H2D)', async () => {
|
||||
const h2dStatus = {
|
||||
...mockPrinterStatus,
|
||||
|
||||
@@ -555,7 +555,12 @@ function NozzleRackCard({ slots, filamentInfo }: { slots: import('../api/client'
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="text-center px-2.5 py-1.5 bg-bambu-dark rounded-lg flex-[2_1_190px] flex flex-col justify-center">
|
||||
// Sized to its contents rather than growing: the six chips are a fixed
|
||||
// 28px each, so any extra width is dead space taken from the temperature
|
||||
// cards beside it — which are flex-1 with a 0 basis and wrap their values
|
||||
// ("220° / 220°") as soon as they lose it. Shrink stays enabled so the
|
||||
// card still gives way on a narrow printer card instead of overflowing.
|
||||
<div className="text-center px-2.5 py-1.5 bg-bambu-dark rounded-lg flex-[0_1_auto] flex flex-col justify-center">
|
||||
<p className="text-[length:var(--pc-t9,9px)] text-bambu-gray mb-1">{t('printers.nozzleRack')}</p>
|
||||
<div className="flex gap-[3px] justify-center">
|
||||
{rackSlots.map((slot, i) => {
|
||||
@@ -565,18 +570,29 @@ function NozzleRackCard({ slots, filamentInfo }: { slots: import('../api/client'
|
||||
|
||||
return (
|
||||
<NozzleSlotHoverCard key={slot.id >= 0 ? slot.id : `empty-${i}`} slot={slot} index={i} filamentName={slot.filament_id ? filamentInfo?.[slot.filament_id]?.name : undefined}>
|
||||
<div
|
||||
className={`w-7 h-7 rounded flex items-center justify-center cursor-default transition-colors border-b-2 ${
|
||||
isEmpty
|
||||
? 'bg-bambu-dark-tertiary/20 border-bambu-dark-tertiary/20'
|
||||
: 'bg-bambu-dark-tertiary/40 border-bambu-dark-tertiary/40'
|
||||
}`}
|
||||
style={filamentBg ? { backgroundColor: filamentBg } : undefined}
|
||||
>
|
||||
<span className={`text-[length:var(--pc-t10,10px)] font-semibold ${isEmpty ? 'text-bambu-gray/30' : lightBg ? 'text-black/80' : 'text-white'}`}
|
||||
style={filamentBg && !lightBg ? { textShadow: '0 1px 3px rgba(0,0,0,0.9)' } : undefined}
|
||||
<div className="flex flex-col items-center gap-0.5">
|
||||
<div
|
||||
className={`w-7 h-7 rounded flex items-center justify-center cursor-default transition-colors border-b-2 ${
|
||||
isEmpty
|
||||
? 'bg-bambu-dark-tertiary/20 border-bambu-dark-tertiary/20'
|
||||
: 'bg-bambu-dark-tertiary/40 border-bambu-dark-tertiary/40'
|
||||
}`}
|
||||
style={filamentBg ? { backgroundColor: filamentBg } : undefined}
|
||||
>
|
||||
{isEmpty ? '—' : (slot.nozzle_diameter || '?')}
|
||||
<span
|
||||
data-rack-diameter
|
||||
className={`text-[length:var(--pc-t10,10px)] font-semibold ${isEmpty ? 'text-bambu-gray/30' : lightBg ? 'text-black/80' : 'text-white'}`}
|
||||
style={filamentBg && !lightBg ? { textShadow: '0 1px 3px rgba(0,0,0,0.9)' } : undefined}
|
||||
>
|
||||
{isEmpty ? '—' : (slot.nozzle_diameter || '?')}
|
||||
</span>
|
||||
</div>
|
||||
{/* Physical rack position, so "swap the nozzle in slot 4" can be
|
||||
acted on without counting chips. Sits below the chip rather
|
||||
than inside it: the chip is 28px and already carries the
|
||||
diameter over a filament-coloured background. */}
|
||||
<span className="text-[length:var(--pc-t8,8px)] leading-none tabular-nums text-bambu-gray/70">
|
||||
{i + 1}
|
||||
</span>
|
||||
</div>
|
||||
</NozzleSlotHoverCard>
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+2
-2
@@ -26,8 +26,8 @@
|
||||
|
||||
<!-- Splash screens for iOS -->
|
||||
<link rel="apple-touch-startup-image" href="/img/android-chrome-512x512.png" />
|
||||
<script type="module" crossorigin src="/assets/index-D686R9Ft.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-BVhCaZnn.css">
|
||||
<script type="module" crossorigin src="/assets/index-CiO0qpbC.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-B3n6Lnj1.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
|
||||
Reference in New Issue
Block a user