From a2cc7af69534a7ef3ccf468ad9f6e873fe7b65bc Mon Sep 17 00:00:00 2001 From: Maurice Date: Fri, 13 Nov 2026 21:21:49 +0100 Subject: [PATCH] fix(bookings): keep 'From mail' out of the card and list head Behind the title stood the review mark, the 'From mail' pill and the two actions, and the title was cut short. Where a booking came from is looked up in its detail dialog, so the pill stays there only. The AirTrail note sat above the mail pill; it is back above AirTrailPill. --- .../Planner/bookings/BookingCard.tsx | 3 +-- .../Planner/bookings/BookingDetailDialog.tsx | 2 +- .../Planner/bookings/BookingsList.tsx | 3 +-- .../Planner/bookings/bookingParts.test.tsx | 13 ++++++--- .../Planner/bookings/bookingParts.tsx | 27 +++++++++---------- 5 files changed, 25 insertions(+), 23 deletions(-) diff --git a/client/src/components/Planner/bookings/BookingCard.tsx b/client/src/components/Planner/bookings/BookingCard.tsx index 81dbe3c6d..fc144fb86 100644 --- a/client/src/components/Planner/bookings/BookingCard.tsx +++ b/client/src/components/Planner/bookings/BookingCard.tsx @@ -15,7 +15,7 @@ import { formatMoney } from '../../../utils/formatters' import { parseMeta, displayTitle, type CostTotal } from './bookingsModel' import type { BookingFacts } from './bookingFacts' import { - AirTrailPill, MailPill, BOX, Block, Field, FileRows, ReviewPill, RoundAction, RouteBox, StatusDot, TravelerChips, TypeChip, WhenFields, + AirTrailPill, BOX, Block, Field, FileRows, ReviewPill, RoundAction, RouteBox, StatusDot, TravelerChips, TypeChip, WhenFields, fs, toneOf, toneTint, } from './bookingParts' import { TransitLegs, transitSummary } from './transitParts' @@ -66,7 +66,6 @@ export default function BookingCard(p: BookingCardProps) { {!!r.needs_review && } - {p.canEdit && } {p.canEdit && } diff --git a/client/src/components/Planner/bookings/BookingDetailDialog.tsx b/client/src/components/Planner/bookings/BookingDetailDialog.tsx index 7c0aaea92..3595dc148 100644 --- a/client/src/components/Planner/bookings/BookingDetailDialog.tsx +++ b/client/src/components/Planner/bookings/BookingDetailDialog.tsx @@ -154,7 +154,7 @@ export default function BookingDetailDialog(p: BookingDetailDialogProps) { )} {!!r.needs_review && void confirmReview() : undefined} />} - + {r.confirmation_number && ( // The copy button rides in the pill's padding (-my-1), so this pill is as tall as its neighbours. diff --git a/client/src/components/Planner/bookings/BookingsList.tsx b/client/src/components/Planner/bookings/BookingsList.tsx index 6a6589ce3..3934bea52 100644 --- a/client/src/components/Planner/bookings/BookingsList.tsx +++ b/client/src/components/Planner/bookings/BookingsList.tsx @@ -7,7 +7,7 @@ import { formatMoney } from '../../../utils/formatters' import { TransitLegChips } from '../transitDisplay' import { displayTitle, parseMeta, type BookingGroup, type CostTotal } from './bookingsModel' import type { BookingFacts } from './bookingFacts' -import { AirTrailPill, CountPill, MailPill, EYEBROW, ReviewPill, RoundAction, StatusDot, TravelerStack, TypeTile, fs } from './bookingParts' +import { AirTrailPill, CountPill, EYEBROW, ReviewPill, RoundAction, StatusDot, TravelerStack, TypeTile, fs } from './bookingParts' export interface BookingsListProps { groups: BookingGroup[] @@ -102,7 +102,6 @@ function Row({ r, p, facts, files, costs, t, locale }: { {displayTitle(r)} {!!r.needs_review && } - {transit ? (
diff --git a/client/src/components/Planner/bookings/bookingParts.test.tsx b/client/src/components/Planner/bookings/bookingParts.test.tsx index 91ad9cef1..01c51bde4 100644 --- a/client/src/components/Planner/bookings/bookingParts.test.tsx +++ b/client/src/components/Planner/bookings/bookingParts.test.tsx @@ -1,11 +1,11 @@ -// FE-PLANNER-BKPARTS-001 to FE-PLANNER-BKPARTS-005 +// FE-PLANNER-BKPARTS-001 to FE-PLANNER-BKPARTS-006 import { fireEvent, render, screen } from '@testing-library/react'; import { describe, expect, it, vi } from 'vitest'; -import { buildTripFile } from '../../../../tests/helpers/factories'; +import { buildReservation, buildTripFile } from '../../../../tests/helpers/factories'; import { downloadFile, openFile } from '../../../utils/fileDownload'; import type { BookingFacts } from './bookingFacts'; -import { FileRows, ReviewPill, WhenFields } from './bookingParts'; +import { FileRows, MailPill, ReviewPill, WhenFields } from './bookingParts'; vi.mock('../../../utils/fileDownload', () => ({ openFile: vi.fn(() => Promise.resolve()), @@ -97,4 +97,11 @@ describe('FileRows', () => { fireEvent.click(screen.getByRole('button')); expect(onConfirm).toHaveBeenCalledOnce(); }); + + it('FE-PLANNER-BKPARTS-006: the mail pill names a booking from a forwarded mail, and nothing else', () => { + const { rerender } = render(); + expect(screen.getByText('From mail')).toBeInTheDocument(); + rerender(); + expect(screen.queryByText('From mail')).toBeNull(); + }); }); diff --git a/client/src/components/Planner/bookings/bookingParts.tsx b/client/src/components/Planner/bookings/bookingParts.tsx index 017d5ee6a..dcc2affb6 100644 --- a/client/src/components/Planner/bookings/bookingParts.tsx +++ b/client/src/components/Planner/bookings/bookingParts.tsx @@ -205,30 +205,27 @@ export function ReviewPill({ pill = false, onConfirm }: { pill?: boolean; onConf } /** - * The AirTrail link of a booking. A multi-leg import is detached from sync by - * design (#1535), which is not the same as a flight removed upstream (#1646). + * Added from a forwarded booking mail (mail-ingest), in the detail dialog's + * head: where a person looks up where a booking came from. The card and the + * list leave it out, their head is the booking itself. */ -/** Added from a forwarded booking mail (mail-ingest): said quietly, so the person knows where it came from. */ -export function MailPill({ r, pill = false }: { r: Reservation; pill?: boolean }) { +export function MailPill({ r }: { r: Reservation }) { const { t } = useTranslation() if (r.external_source !== 'mail') return null return ( - {pill ? ( - - - {t('mailInbox.fromMail')} - - ) : ( - - - {t('mailInbox.fromMail')} - - )} + + + {t('mailInbox.fromMail')} + ) } +/** + * The AirTrail link of a booking. A multi-leg import is detached from sync by + * design (#1535), which is not the same as a flight removed upstream (#1646). + */ export function AirTrailPill({ r, pill = false }: { r: Reservation; pill?: boolean }) { const { t } = useTranslation() if (r.external_source !== 'airtrail') return null