mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-19 13:36:48 +00:00
fix(planner): a leg's time zone sits behind a globe instead of beside the route
A departure or arrival row wrote its zone out ("Europe/Berlin") next to the
phase label, and on the narrow day plan that ate the width the route needed,
so "BER → HAM" ended in an ellipsis. The zone is now a small globe after the
time that names it on hover, the time pill carries only the time, and the
route gets its room back.
This commit is contained in:
@@ -1040,6 +1040,28 @@ describe('DayPlanSidebar', () => {
|
||||
|
||||
// ── Multi-day transport span phases ────────────────────────────────────
|
||||
|
||||
it('FE-PLANNER-DAYPLAN-233: a leg names its time zone behind a globe, not as text beside the route', async () => {
|
||||
const day1 = buildDay({ id: 10, date: '2025-06-01', title: 'Out' })
|
||||
const day2 = buildDay({ id: 11, date: '2025-06-02', title: 'In' })
|
||||
const flight = buildReservation({
|
||||
id: 202, type: 'flight', title: 'Overnight',
|
||||
reservation_time: '2025-06-01T22:00:00',
|
||||
reservation_end_time: '2025-06-02T06:00:00',
|
||||
day_id: 10,
|
||||
end_day_id: 11,
|
||||
metadata: JSON.stringify({ departure_timezone: 'Europe/Berlin', arrival_timezone: 'America/New_York' }),
|
||||
} as any)
|
||||
const { container } = render(<DayPlanSidebar {...makeDefaultProps({ days: [day1, day2], reservations: [flight] })} />)
|
||||
|
||||
// Written out, the zone took the width the route needed.
|
||||
expect(screen.queryByText(/Europe\/Berlin|America\/New_York/)).not.toBeInTheDocument()
|
||||
const globes = container.querySelectorAll('[data-dp="transport-timezone"]')
|
||||
expect([...globes].map(g => g.getAttribute('aria-label'))).toEqual(['Europe/Berlin', 'America/New_York'])
|
||||
|
||||
fireEvent.mouseEnter(globes[0])
|
||||
expect(await screen.findByText('Europe/Berlin')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('FE-PLANNER-DAYPLAN-045: multi-day flight shows departure label on first day', () => {
|
||||
const day1 = buildDay({ id: 10, date: '2025-06-01', title: 'Departure' })
|
||||
const day2 = buildDay({ id: 11, date: '2025-06-02', title: 'Arrival' })
|
||||
|
||||
@@ -7,7 +7,7 @@ declare global { interface Window { __dragData: DragDataPayload | null } }
|
||||
import React, { useState, useEffect, useLayoutEffect, useRef, useMemo, useCallback } from 'react'
|
||||
import { avatarSrc } from '../../utils/avatarSrc'
|
||||
import { safeHttpUrl } from '../../utils/safeUrl'
|
||||
import { ChevronDown, ChevronRight, ChevronUp, Compass, Navigation, RotateCcw, ExternalLink, Pencil, GripVertical, Ticket, Plus, FileText, Trash2, Car, Lock, Hotel, Footprints, Route as RouteIcon, Bookmark, StickyNote, TramFront, Zap, MapPin, Wallet } from 'lucide-react'
|
||||
import { ChevronDown, ChevronRight, ChevronUp, Compass, Navigation, RotateCcw, ExternalLink, Pencil, GripVertical, Ticket, Plus, FileText, Trash2, Car, Lock, Hotel, Footprints, Route as RouteIcon, Bookmark, StickyNote, TramFront, Zap, MapPin, Wallet, Globe } from 'lucide-react'
|
||||
import { type PickedPlace } from './TransitSearchPanel'
|
||||
import { buildTransitLeg, buildTransitNameIndex } from './transitLeg'
|
||||
import { assignmentsApi, reservationsApi, daysApi } from '../../api/client'
|
||||
@@ -2559,15 +2559,24 @@ const DayPlanSidebar = React.memo(function DayPlanSidebar(props: DayPlanSidebarP
|
||||
const timeText = [
|
||||
dispTime ? formatTime(dispTime, locale, timeFormat) : '',
|
||||
spanPhase === 'single' && endTime ? `– ${formatTime(endTime, locale, timeFormat)}` : '',
|
||||
meta.departure_timezone && spanPhase === 'start' ? meta.departure_timezone : '',
|
||||
meta.arrival_timezone && spanPhase === 'end' ? meta.arrival_timezone : '',
|
||||
].filter(Boolean).join(' ')
|
||||
if (!timeText && !spanLabel && !transitMeta && !subtitle) return null
|
||||
// The zone a leg's time is read in. Written out it took the width
|
||||
// the route needs, so it is a globe that names it on hover.
|
||||
const timeZone = (spanPhase === 'start' && meta.departure_timezone) || (spanPhase === 'end' && meta.arrival_timezone) || ''
|
||||
if (!timeText && !timeZone && !spanLabel && !transitMeta && !subtitle) return null
|
||||
return (
|
||||
<div className="mt-0.5 flex min-w-0 items-center gap-1.5">
|
||||
{/* Where in a multi-day span this day falls, said quietly beside its time. */}
|
||||
{spanLabel && <SoftPill caps>{spanLabel}</SoftPill>}
|
||||
{timeText && <TimePill>{timeText}</TimePill>}
|
||||
{timeZone && (
|
||||
<Tooltip label={timeZone} placement="top">
|
||||
<span role="img" aria-label={timeZone} data-dp="transport-timezone"
|
||||
className="grid h-[19px] w-[19px] flex-none place-items-center rounded-full bg-surface-card text-content-faint shadow-sm">
|
||||
<Globe size={10} strokeWidth={2.2} aria-hidden="true" />
|
||||
</span>
|
||||
</Tooltip>
|
||||
)}
|
||||
{transitMeta ? (
|
||||
<span className="flex min-w-0 items-center"><TransitLegChips legs={transitMeta.legs} size="sm" t={t} /></span>
|
||||
) : subtitle && (
|
||||
|
||||
Reference in New Issue
Block a user