feat: v0.15.0 — ISS-002 hovering a plane or package in the side panels highlights it on the map
CI / build + unit + e2e (pull_request) Failing after 6m8s
CI / build + unit + e2e (pull_request) Failing after 6m8s
This commit is contained in:
@@ -5,6 +5,7 @@ import type { PackageState, PlaneState, StateSnapshot } from '@/lib/game/state';
|
||||
import { PLANE_TYPES } from '@/lib/game/catalog';
|
||||
import { abandonPenalty } from '@/lib/game/penalty';
|
||||
import { formatCash, formatDeadlineRelative } from '@/lib/format';
|
||||
import type { HoverTarget } from './hoverTypes';
|
||||
|
||||
interface RightPaneProps {
|
||||
state: StateSnapshot | null;
|
||||
@@ -12,6 +13,9 @@ interface RightPaneProps {
|
||||
// Push the full snapshot returned by an action endpoint into the shared shell state (v0.10.0),
|
||||
// so the pane updates on click without waiting for the next poll tick.
|
||||
applySnapshot: (snapshot: StateSnapshot) => void;
|
||||
// ISS-002 (v0.15.0): report row hovers to the shell so the map can highlight the plane or
|
||||
// the package's endpoint airports.
|
||||
onHover: (target: HoverTarget | null) => void;
|
||||
}
|
||||
|
||||
const planeName = (p: PlaneState): string => PLANE_TYPES[p.model]?.name ?? p.model;
|
||||
@@ -100,7 +104,7 @@ function LoadControls({
|
||||
);
|
||||
}
|
||||
|
||||
export default function RightPane({ state, loading, applySnapshot }: RightPaneProps) {
|
||||
export default function RightPane({ state, loading, applySnapshot, onHover }: RightPaneProps) {
|
||||
const [busy, setBusy] = useState(false);
|
||||
// Inline error from a failed action — auto-clears on the next successful poll (the shell's
|
||||
// snapshot prop changes every tick) or the next successful action.
|
||||
@@ -192,7 +196,14 @@ export default function RightPane({ state, loading, applySnapshot }: RightPanePr
|
||||
{open.map((pkg) => {
|
||||
const eligible = loadEligiblePlanes(state, pkg);
|
||||
return (
|
||||
<li key={pkg.id} data-testid={`open-package-${pkg.id}`} className="contract-row">
|
||||
// ISS-002: hovering an open package highlights its two endpoint airports on the map.
|
||||
<li
|
||||
key={pkg.id}
|
||||
data-testid={`open-package-${pkg.id}`}
|
||||
className="contract-row"
|
||||
onMouseEnter={() => onHover({ kind: 'package', originIcao: pkg.originIcao, destIcao: pkg.destIcao })}
|
||||
onMouseLeave={() => onHover(null)}
|
||||
>
|
||||
<div className="contract-main">
|
||||
<span className="contract-route">{pkg.originName} → {pkg.destName}</span>
|
||||
{eligible.length > 0 ? (
|
||||
@@ -232,7 +243,16 @@ export default function RightPane({ state, loading, applySnapshot }: RightPanePr
|
||||
(pkg) => pkg.planeId === plane.id && (pkg.status === 'loaded' || pkg.status === 'expired'),
|
||||
);
|
||||
return (
|
||||
<div key={plane.id} data-testid={`onboard-${plane.id}`} className="onboard-block">
|
||||
// ISS-002: hovering the on-board block (including its cargo rows) highlights the plane.
|
||||
// Handlers live only on the outer div — React's enter/leave don't fire when moving to a
|
||||
// child, so this covers the whole block without flicker between sub-elements.
|
||||
<div
|
||||
key={plane.id}
|
||||
data-testid={`onboard-${plane.id}`}
|
||||
className="onboard-block"
|
||||
onMouseEnter={() => onHover({ kind: 'plane', id: plane.id })}
|
||||
onMouseLeave={() => onHover(null)}
|
||||
>
|
||||
<div className="contract-main">
|
||||
<span className="plane-model">{planeName(plane)}</span>
|
||||
{plane.status === 'flying' ? (
|
||||
|
||||
Reference in New Issue
Block a user