mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-23 07:26:30 +00:00
feat(planner): reach a hotel's booking from the plan, not only its place
A booked stay's pill in the day head gets a second target that opens the booking; the name still opens the place. The place panel of a hotel, on the desktop and on the phone, lists the stay booked for it next to the bookings pinned to the stop. (#2363)
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { describe, it, expect } from 'vitest'
|
||||
import { parseTimeToMinutes, getSpanPhase, hidesOnMiddleDay, getTransportRouteEndpoints, getDisplayTimeForDay, getTransportForDay, getAssignmentReservations, getMergedItems, rideSeatKey, stayStartingOn, storedRideSlot, timedSlot } from './dayMerge'
|
||||
import { parseTimeToMinutes, getSpanPhase, hidesOnMiddleDay, getTransportRouteEndpoints, getDisplayTimeForDay, getTransportForDay, getAssignmentReservations, getPlaceBookings, getMergedItems, rideSeatKey, stayStartingOn, storedRideSlot, timedSlot } from './dayMerge'
|
||||
|
||||
describe('parseTimeToMinutes', () => {
|
||||
it('parses HH:MM string', () => {
|
||||
@@ -199,6 +199,28 @@ describe('getTransportForDay', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('getPlaceBookings (#2363)', () => {
|
||||
const reservations = [
|
||||
{ id: 1, assignment_id: 42, reservation_time: '2025-06-01T10:00:00' },
|
||||
{ id: 2, assignment_id: null, reservation_time: '2025-06-01T15:00:00', accommodation_place_id: 9 },
|
||||
{ id: 3, assignment_id: 42, reservation_time: '2025-06-01T09:00:00', accommodation_place_id: 9 },
|
||||
{ id: 4, assignment_id: null, reservation_time: null, accommodation_place_id: 8 },
|
||||
]
|
||||
|
||||
it('adds the stay booked for a hotel after the bookings pinned to the stop, each once', () => {
|
||||
expect(getPlaceBookings(reservations, 42, 9).map(r => r.id)).toEqual([3, 1, 2])
|
||||
})
|
||||
|
||||
it('finds the stay even when no stop is open, as from the pill in the day head', () => {
|
||||
expect(getPlaceBookings(reservations, null, 9).map(r => r.id)).toEqual([2, 3])
|
||||
})
|
||||
|
||||
it('without a place it is the pinned list alone', () => {
|
||||
expect(getPlaceBookings(reservations, 42, null).map(r => r.id)).toEqual([3, 1])
|
||||
expect(getPlaceBookings(reservations, null, 7)).toEqual([])
|
||||
})
|
||||
})
|
||||
|
||||
describe('getAssignmentReservations', () => {
|
||||
it('returns every booking pinned to the assignment, not just the first (#2201)', () => {
|
||||
const reservations = [
|
||||
|
||||
@@ -267,6 +267,25 @@ export function getAssignmentReservations<T extends {
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* The bookings that belong to a place: the ones pinned to the open stop, and the
|
||||
* stay booked for it when the place is a hotel (#2363). Without the second, a
|
||||
* hotel opened from its pill in the day head showed the place but no route to its
|
||||
* booking. Pinned ones keep their order and come first.
|
||||
*/
|
||||
export function getPlaceBookings<T extends {
|
||||
id: number
|
||||
assignment_id?: number | null
|
||||
reservation_time?: string | null
|
||||
accommodation_place_id?: number | null
|
||||
}>(reservations: T[], assignmentId: number | null | undefined, placeId: number | null | undefined): T[] {
|
||||
const pinned = getAssignmentReservations(reservations, assignmentId)
|
||||
if (placeId == null) return pinned
|
||||
const pinnedIds = new Set(pinned.map(r => r.id))
|
||||
const stays = reservations.filter(r => r.accommodation_place_id === placeId && !pinnedIds.has(r.id))
|
||||
return [...pinned, ...stays]
|
||||
}
|
||||
|
||||
/**
|
||||
* Order items chronologically: anything with a time (a place's place_time, a
|
||||
* transport/leg display time, a timed note) sorts by that time. An item WITHOUT a
|
||||
|
||||
Reference in New Issue
Block a user