fix: keep link hosts whole and drop stale arrival dates on order cards

This commit is contained in:
Linus Rath
2026-10-30 05:24:10 +01:00
parent eb1859dbe3
commit 551d8a79d5
4 changed files with 29 additions and 10 deletions
@@ -218,6 +218,17 @@ describe('StructuredMailCards', () => {
await waitFor(() => expect(writeText).toHaveBeenCalledWith('SO-449120'));
});
it('drops the expected date once the order is delivered', () => {
const shipment = card<Shipment>('order-and-parcel');
shipment.status = 'delivered';
show([shipment]);
const region = screen.getByRole('region', { name: 'region_shipment' });
expect(region).toHaveTextContent('order_status_delivered');
expect(region).not.toHaveTextContent('expected_by');
// Carrier and tracking number stay.
expect(region).toHaveTextContent('00340434161234567890');
});
it('lists three items and says how many more there are', () => {
const shipment: Shipment = {
kind: 'shipment', key: 's', merchant: 'Shop', orderNumber: 'A-1', source: 'json-ld', parcels: [],
@@ -154,9 +154,11 @@ export function TransportCard({ booking, emailId, calendarActions }: BookingCard
/>
) : undefined}
>
{booking.legs.map((leg, i) => (
<Leg key={`${leg.departure.at.date}-${leg.number ?? ""}-${i}`} leg={leg} kind={booking.kind} bookingCancelled={cancelled} />
))}
<div className="flex flex-col gap-2 min-w-0">
{booking.legs.map((leg, i) => (
<Leg key={`${leg.departure.at.date}-${leg.number ?? ""}-${i}`} leg={leg} kind={booking.kind} bookingCancelled={cancelled} />
))}
</div>
<PassengersRow names={booking.passengers} />
</CardShell>
);
@@ -87,7 +87,7 @@ export function CardLink({ link, label, icon: Icon = ExternalLink, emailId }: {
href={link.url}
target="_blank"
rel="noopener noreferrer"
className={ACTION_CLASS}
className={cn(ACTION_CLASS, "flex-wrap gap-y-0")}
data-testid="structured-mail-link"
onClick={async (e) => {
e.preventDefault();
@@ -99,7 +99,8 @@ export function CardLink({ link, label, icon: Icon = ExternalLink, emailId }: {
>
<Icon aria-hidden="true" className="w-3.5 h-3.5 flex-shrink-0" />
<span className="whitespace-nowrap">{label}</span>
<span className="min-w-0 truncate text-muted-foreground/80">· {link.host}</span>
{/* The host is how a reader judges the link: wrapped, never cut off. */}
<span className="max-w-full [overflow-wrap:anywhere] text-muted-foreground/80">· {link.host}</span>
</a>
);
}
@@ -19,6 +19,9 @@ const STATUS_TONE: Record<OrderStatus, string> = {
cancelled: "bg-destructive/15 text-destructive",
};
/** States in which an expected arrival date is out of date. */
const ARRIVED_OR_STOPPED = new Set<OrderStatus>(["delivered", "returned", "cancelled"]);
function OrderStatusPill({ status }: { status: OrderStatus }) {
const t = useTranslations("email_viewer.structured_mail");
const labels: Record<OrderStatus, string> = {
@@ -54,10 +57,12 @@ function ItemImages({ items }: { items: Item[] }) {
);
}
function ParcelRows({ parcel }: { parcel: Parcel }) {
/** Carrier, tracking number and expected date; no date once the order is delivered, returned or cancelled. */
function ParcelRows({ parcel, showExpected }: { parcel: Parcel; showExpected: boolean }) {
const t = useTranslations("email_viewer.structured_mail");
const { opts } = useCardFormat();
if (!parcel.carrier && !parcel.trackingNumber && !parcel.expectedBy) return null;
const expectedBy = showExpected ? parcel.expectedBy : undefined;
if (!parcel.carrier && !parcel.trackingNumber && !expectedBy) return null;
return (
<>
{(parcel.carrier || parcel.trackingNumber) && (
@@ -73,8 +78,8 @@ function ParcelRows({ parcel }: { parcel: Parcel }) {
</span>
</MetaRow>
)}
{parcel.expectedBy && (
<MetaRow icon={Clock}>{t("expected_by", { date: formatMomentDate(parcel.expectedBy, opts) })}</MetaRow>
{expectedBy && (
<MetaRow icon={Clock}>{t("expected_by", { date: formatMomentDate(expectedBy, opts) })}</MetaRow>
)}
</>
);
@@ -144,7 +149,7 @@ export function ShipmentCard({ shipment, emailId, allowRemoteImages }: ShipmentC
.filter(Boolean).join(" · ")}
</div>
)}
{shipment.parcels.map((parcel, i) => <ParcelRows key={parcel.trackingNumber ?? i} parcel={parcel} />)}
{shipment.parcels.map((parcel, i) => <ParcelRows key={parcel.trackingNumber ?? i} parcel={parcel} showExpected={!ARRIVED_OR_STOPPED.has(shipment.status ?? "processing")} />)}
</CardShell>
);
}