diff --git a/CHANGELOG.md b/CHANGELOG.md index 6a8d6bb..843729d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ - **Shared action runner hook.** RightPane's local `runAction` (busy gate, inline pane error + shell toast on failure, full post-action snapshot pushed via `applySnapshot`) extracted to new `lib/useGameAction.ts`: `useGameAction(state, applySnapshot, onError) → { runAction, busy, actionError }`, exact semantics kept incl. the non-2xx throw/catch and inline-error auto-clear on the next snapshot. Used in BOTH panes; LeftPane receives `applySnapshot` from the shell (`app/page.tsx`). RightPane keeps `[data-testid="right-error"]`; LeftPane gains a matching `[data-testid="left-action-error"]`. Pure helpers `slotsUsedFor` / `loadEligiblePlanes` stay exported from RightPane (unit tests import them there; LeftPane imports `slotsUsedFor` from it); the Market Relocate row + `/api/airports` fetch stay in RightPane - Tests: e2e — `panes.spec.ts` first test now also asserts the "On board" heading is visible inside `[data-testid="left-pane"]` and absent from the right pane; stale header comments updated in `actions.spec.ts` / `right-pane.spec.ts`. No unit-test changes (baseline 283) - Verified: `tsc --noEmit` clean; unit suite green locally; e2e not run locally by design — CI verifies against an isolated stack +- **On-board cargo rows are two lines (ISS-028).** Each `onboard-package-*` row now stacks a full-width "Fly to " button on its own line above Refuel + Abandon side by side: `components/LeftPane.tsx` moves the fly-to button out of `.contract-main` into the row root and wraps refuel-for + abandon in a new `.onboard-actions` div — all testids, label text, penalty preview and disabled states unchanged. Long destination names in the fly-to label truncate with an ellipsis instead of overflowing: the label's inner span gets `min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap`, full name preserved via a `title` attribute (CSS in `app/globals.css`: `.onboard-block .contract-row` becomes flex-column, new `.onboard-fly-btn` / `.onboard-fly-label` / `.onboard-actions`). No e2e changes — specs locate everything by testid and assert no layout or button order; no version bump (part 2 of v0.20.0) ## v0.19.0 — 2026-09-19 18:05 - **Auto-slow to 1× when all planes have landed (ISS-011).** When the last plane in flight lands, the sim slows down on its own so an idle fleet doesn't sit at 1000×. Server-side and authoritative: `tickOnce` (`lib/sim/engine.ts`) now remembers how many planes `deliverPackages` finalized during a tick, and when ≥1 plane landed this tick AND no plane remains with status `'flying'` AND the sim is not paused, it persists `timeScale = 1` on the same `sim_state` write as the clock — so the UI slider reflects it on the very next snapshot (no API or OpenAPI change: timeScale is still set via the existing `POST /api/sim`, and `clampTimeScale` semantics are untouched since 1 is a valid ladder value) diff --git a/app/globals.css b/app/globals.css index d0a6d0d..25540a3 100644 --- a/app/globals.css +++ b/app/globals.css @@ -384,10 +384,36 @@ body { margin-bottom: 8px; } +/* ISS-028 (v0.20.0 part 2) — on-board cargo rows are two lines: a full-width fly-to button, + then refuel + abandon side by side below it; long destination names truncate with an ellipsis. */ .onboard-block .contract-row { background: transparent; padding: 6px 0 0; border-top: 1px solid rgba(148, 163, 184, 0.2); + display: flex; + flex-direction: column; + gap: 5px; +} + +.onboard-block .contract-row .contract-sub { + margin-top: 0; /* row spacing comes from the container's gap */ +} + +.onboard-fly-btn { + width: 100%; +} + +.onboard-fly-label { + display: block; + min-width: 0; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.onboard-actions { + display: flex; + gap: 6px; } /* v0.17.0 — ISS-008: bottom-right toast stack (action errors + game events) */ diff --git a/components/LeftPane.tsx b/components/LeftPane.tsx index 858089a..23a80d5 100644 --- a/components/LeftPane.tsx +++ b/components/LeftPane.tsx @@ -349,7 +349,18 @@ export default function LeftPane({ state, loading, error, onRefresh, applySnapsh const penalty = abandonPenalty(pkg, clockMs); return (
-
+ +
-