diff --git a/client/src/components/Planner/PlaceFormModal.test.tsx b/client/src/components/Planner/PlaceFormModal.test.tsx index acf47eb97..32ac8a7aa 100644 --- a/client/src/components/Planner/PlaceFormModal.test.tsx +++ b/client/src/components/Planner/PlaceFormModal.test.tsx @@ -1772,6 +1772,16 @@ describe('PlaceFormModal as a road trip service stop', () => { expect(screen.getAllByText('Add as a stop').length).toBeGreaterThan(0); }); + it('FE-PLANNER-PLACEFORM-085: it opens on the kind the corridor was looking for, dwell and all', () => { + // The panel seeds itself to charging on an electric car, and a form opening on a + // fuel pump under a picker that says Charging is the fault this carries the answer to. + render(); + + expect(screen.getByRole('button', { name: 'Charging' })).toHaveAttribute('aria-pressed', 'true'); + expect(screen.getByRole('button', { name: /30 min/ })).toHaveAttribute('aria-pressed', 'true'); + expect(screen.getByRole('button', { name: 'Fuel' })).toHaveAttribute('aria-pressed', 'false'); + }); + it('FE-PLANNER-PLACEFORM-076: picking a kind also picks how long that kind takes', async () => { const onSave = vi.fn().mockResolvedValue({ id: 9 }); render(); diff --git a/client/src/components/Planner/PlaceFormModal.tsx b/client/src/components/Planner/PlaceFormModal.tsx index 901547203..eb0979136 100644 --- a/client/src/components/Planner/PlaceFormModal.tsx +++ b/client/src/components/Planner/PlaceFormModal.tsx @@ -254,10 +254,15 @@ function usePlaceFormModal(props: PlaceFormModalProps) { // path exists to avoid. Read out of the closure rather than watched, because the // mode is fixed for the life of one opening and a rebuilt drive must not reset a // half-filled form. + // What the corridor panel was looking for when the button was pressed, because + // that is the traveller's own answer to what they are adding; only a panel with + // nothing selected falls back to the constant. The dwell follows the kind, the + // same way picking one by hand moves it. + const kind = serviceStop.defaultKind ?? DEFAULT_SERVICE_KIND setForm({ ...DEFAULT_FORM, - stop_type: DEFAULT_SERVICE_KIND, - duration_minutes: STOP_KIND_BY_KEY[DEFAULT_SERVICE_KIND].defaultMinutes, + stop_type: kind, + duration_minutes: STOP_KIND_BY_KEY[kind].defaultMinutes, }) } else { setForm(DEFAULT_FORM) diff --git a/client/src/components/Roadtrip/RoadtripCorridorPanel.test.tsx b/client/src/components/Roadtrip/RoadtripCorridorPanel.test.tsx index fdf90b226..3129b6b45 100644 --- a/client/src/components/Roadtrip/RoadtripCorridorPanel.test.tsx +++ b/client/src/components/Roadtrip/RoadtripCorridorPanel.test.tsx @@ -441,6 +441,35 @@ describe('RoadtripCorridorPanel', () => { // nothing is added until a place has been found and saved in there. fireEvent.click(manual) expect(onAddManual).toHaveBeenCalledTimes(1) + // The kind, never the MouseEvent: the categories above the button are the answer to + // what is being added, and a form that ignored them opened every manual stop on fuel. + expect(onAddManual).toHaveBeenCalledWith('fuel') + }) + + it('FE-ROADTRIP-PANEL-035: the manual add opens on what the panel is looking for', () => { + const open = (categories: string[]): unknown => { + const onAddManual = vi.fn() + const { unmount } = wrap( + , + ) + fireEvent.click(searchRow()[1]) + unmount() + return onAddManual.mock.calls[0][0] + } + + // An electric car seeds the panel to charging, and this is the case the fault was + // reported on: the panel said Charging and the form opened on Fuel. + expect(open(['charging'])).toBe('charging') + expect(open(['restaurant'])).toBe('restaurant') + // Multi-select: the first the panel LISTS wins, rather than a kind nobody switched on. + expect(open(['sights', 'rest_area'])).toBe('rest_area') + // Nothing selected is no answer, and the form falls back on its own. + expect(open([])).toBeNull() }) it('FE-ROADTRIP-PANEL-026: with no drive on the trip there is nowhere to add one by hand', () => { diff --git a/client/src/components/Roadtrip/RoadtripCorridorPanel.tsx b/client/src/components/Roadtrip/RoadtripCorridorPanel.tsx index 505b5f82c..850044776 100644 --- a/client/src/components/Roadtrip/RoadtripCorridorPanel.tsx +++ b/client/src/components/Roadtrip/RoadtripCorridorPanel.tsx @@ -13,9 +13,10 @@ import CustomSelect from '../shared/CustomSelect' import RoadtripCategoryPicker from './RoadtripCategoryPicker' import { serviceColor } from './roadtripModel' import { alongLabel, offRouteLabel } from './corridorSearchModel' -import { CORRIDOR_CATEGORY_BY_KEY } from './stopKinds' +import { CORRIDOR_CATEGORY_BY_KEY, manualStopKindFor } from './stopKinds' import { FS } from './typeScale' import { CORRIDOR_CATEGORY_KEYS, CORRIDOR_SECTION_KM, CORRIDOR_WIDTHS_KM, type RoadtripCorridor } from './useRoadtripCorridor' +import type { RoadtripStopType } from '@trek/shared' import type { CorridorPoi } from './useCorridorPois' import type { RoadtripRoutes } from './useRoadtripRoutes' @@ -38,8 +39,12 @@ interface RoadtripCorridorPanelProps { /** * Opens the place form for a stop the search never found. Given only to somebody who * may add places, which is what keeps the button off a reader's panel. + * + * Carries the kind the panel is looking for, so the form opens on it rather than on a + * constant: the categories above the button are the traveller's own answer to "what am + * I adding", and ignoring them made every manual stop start life as a fuel stop. */ - onAddManual?: () => void + onAddManual?: (kind: RoadtripStopType | null) => void } /** @@ -476,7 +481,9 @@ export default function RoadtripCorridorPanel({ {onAddPoi && onAddManual && corridor.day ? (