Queue UI fixes: disable would-409 controls, hover trace from landing airport, grounded queues draw dotted lines (ISS-077, v0.41.0)
CI / build + unit + e2e (pull_request) Successful in 9m11s
CI / build + unit + e2e (pull_request) Successful in 9m11s
This commit is contained in:
+15
-3
@@ -207,6 +207,11 @@ export default function LeftPane({ state, loading, error, onRefresh, applySnapsh
|
||||
const relocatePlane = relocatable.find((p) => p.id === relocatePlaneId) ?? relocatable[0] ?? null;
|
||||
const relocateDest =
|
||||
airportOptions === null ? null : airportOptions.find((a) => a.icao === relocateDestIcao) ?? airportOptions[0] ?? null;
|
||||
// ISS-077 (v0.41.0): while flying, the Relocate click would POST /queue — block it when the selected
|
||||
// destination is already active or queued (the server rejects that with 409). Grounded planes are unaffected.
|
||||
const relocateBlocked =
|
||||
relocatePlane?.status === 'flying' && relocateDest !== null &&
|
||||
(relocatePlane.destIcao === relocateDest.icao || relocatePlane.queue.includes(relocateDest.icao));
|
||||
|
||||
// ISS-035 (v0.23.0): Refuel-to-full — any GROUNDED plane with fuel below max can be topped up via the
|
||||
// existing refuel endpoint (no body → server defaults to mode 'full'). Moved here from the right-pane
|
||||
@@ -408,6 +413,10 @@ export default function LeftPane({ state, loading, error, onRefresh, applySnapsh
|
||||
)}
|
||||
{cargo.map((pkg) => {
|
||||
const penalty = abandonPenalty(pkg, clockMs);
|
||||
// ISS-077 (v0.41.0): while flying the click would POST /queue — disable it when the
|
||||
// destination is already active or queued (the server rejects that with 409). Grounded
|
||||
// clicks go to /fly, which has no such conflict.
|
||||
const alreadyQueued = p.status === 'flying' && (p.destIcao === pkg.destIcao || p.queue.includes(pkg.destIcao));
|
||||
return (
|
||||
// ISS-025 (v0.22.0): hovering a loaded package draws its full origin→dest trace on the map —
|
||||
// same as job-list rows — and keeps this plane's halo lit via planeId. Leaving the row restores
|
||||
@@ -424,7 +433,8 @@ export default function LeftPane({ state, loading, error, onRefresh, applySnapsh
|
||||
type="button"
|
||||
data-testid={`fly-to-${pkg.id}`}
|
||||
className="pane-btn onboard-fly-btn"
|
||||
disabled={actionsBusy}
|
||||
disabled={actionsBusy || alreadyQueued}
|
||||
title={alreadyQueued ? 'Already in flight queue' : undefined}
|
||||
// ISS-053 (v0.32.0): a flying plane can't start another leg — the click queues it instead,
|
||||
// so "Fly to …" works from any state and the queue needs no dedicated input.
|
||||
onClick={() => void runAction(`/api/planes/${p.id}/${p.status === 'flying' ? 'queue' : 'fly'}`, { destIcao: pkg.destIcao })}
|
||||
@@ -551,7 +561,9 @@ export default function LeftPane({ state, loading, error, onRefresh, applySnapsh
|
||||
onChange={(e) => setRelocateDestIcao(e.target.value || null)}
|
||||
>
|
||||
{airportOptions?.map((a) => (
|
||||
<option key={a.icao} value={a.icao}>
|
||||
// ISS-077 (v0.41.0): a flying plane's active/queued airports can't be re-selected — the
|
||||
// server would reject them with 409; native disabled options, no text change.
|
||||
<option key={a.icao} value={a.icao} disabled={relocatePlane?.status === 'flying' && (relocatePlane.destIcao === a.icao || relocatePlane.queue.includes(a.icao))}>
|
||||
{a.name}
|
||||
</option>
|
||||
))}
|
||||
@@ -560,7 +572,7 @@ export default function LeftPane({ state, loading, error, onRefresh, applySnapsh
|
||||
type="button"
|
||||
data-testid="relocate-go"
|
||||
className="pane-btn"
|
||||
disabled={actionsBusy || relocatePlane === null || relocateDest === null}
|
||||
disabled={actionsBusy || relocatePlane === null || relocateDest === null || relocateBlocked}
|
||||
// ISS-053 (v0.32.0): a flying plane can't start another leg — queue it instead, so the
|
||||
// relocation takes off when the current one lands.
|
||||
onClick={() => {
|
||||
|
||||
Reference in New Issue
Block a user