Route operatingBy.carrier lookups through operatingCarrier()

Several components still read `flight.operatingBy.carrier` directly.
The API actually returns `{scheduled, actual}` — I kept `.carrier` on
IOperatingBy as a deprecated alias during the refactor, so nothing
fails typechecking, but at runtime the lookup is always undefined,
which silently disabled the Registration, Flight-status and
Operated-by UIs (the Reg button did nothing on click, the status
visibility check always returned false).

Swap the affected sites — RegistrationButton, FlightStatusButton, the
canRegister / canViewFlightStatus visibility helpers, and the
'Operated by' block in OnlineBoardDetailsPage — to use the
operatingCarrier() helper that reads actual/scheduled/legacy in turn.
This commit is contained in:
2026-04-18 10:04:22 +03:00
parent 0633e6de39
commit 25986dfca2
5 changed files with 23 additions and 16 deletions
@@ -1,6 +1,6 @@
import type { FC } from "react";
import { useTranslation } from "@/i18n/provider.js";
import type { ISimpleFlight } from "../../types.js";
import { operatingCarrier, type ISimpleFlight } from "../../types.js";
import { AIRLINES } from "./airlines.js";
import { buildOnlineBoardUrl } from "../../url.js";
import "./actions.scss";
@@ -15,7 +15,7 @@ export const FlightStatusButton: FC<FlightStatusButtonProps> = ({ flight, locale
const { t } = useTranslation();
const handleClick = () => {
const carrier = flight.operatingBy.carrier;
const carrier = operatingCarrier(flight.operatingBy);
if (!carrier) return;
const config = AIRLINES[carrier];
if (!config) return;
@@ -1,6 +1,6 @@
import type { FC } from "react";
import { useTranslation } from "@/i18n/provider.js";
import type { ISimpleFlight } from "../../types.js";
import { operatingCarrier, type ISimpleFlight } from "../../types.js";
import { AIRLINES } from "./airlines.js";
import "./actions.scss";
@@ -12,7 +12,10 @@ export const RegistrationButton: FC<RegistrationButtonProps> = ({ flight }) => {
const { t } = useTranslation();
const handleClick = () => {
const carrier = flight.operatingBy.carrier;
// IOperatingBy is `{scheduled, actual}` on real API payloads. The old
// `.carrier` shape survives as a deprecated alias; read through the
// helper so both work.
const carrier = operatingCarrier(flight.operatingBy);
if (!carrier) return;
const config = AIRLINES[carrier];
if (!config?.registrationUrl) return;
@@ -1,5 +1,5 @@
import { parseISO, subHours, isAfter, isSameDay } from "date-fns";
import type { ISimpleFlight } from "../../../types.js";
import { operatingCarrier, type ISimpleFlight } from "../../../types.js";
/**
* Flight Status button is visible when:
@@ -13,7 +13,7 @@ export function canViewFlightStatus(
availableFromHours: number,
airlinesWithStatus: Set<string>,
): boolean {
const carrier = flight.operatingBy.carrier;
const carrier = operatingCarrier(flight.operatingBy);
if (!carrier || !airlinesWithStatus.has(carrier)) return false;
const leg = flight.routeType === "Direct" ? flight.leg : flight.legs[0];
@@ -1,4 +1,4 @@
import type { ISimpleFlight } from "../../../types.js";
import { operatingCarrier, type ISimpleFlight } from "../../../types.js";
import type { AirlineConfig } from "../airlines.js";
/**
@@ -10,7 +10,7 @@ export function canRegister(
flight: ISimpleFlight,
airlineConfig: Record<string, AirlineConfig>,
): boolean {
const carrier = flight.operatingBy.carrier;
const carrier = operatingCarrier(flight.operatingBy);
if (!carrier) return false;
const config = airlineConfig[carrier];
if (!config?.registrationUrl) return false;
@@ -31,6 +31,7 @@ import { FlightSchedule } from "./FlightSchedule/index.js";
import { FullRouteTimeline } from "./FullRouteTimeline/index.js";
import { TransferBar } from "./TransferBar/index.js";
import type { IParsedFlightId, IFlightLeg } from "../types.js";
import { operatingCarrier } from "../types.js";
import {
formatLocalTime,
formatUtcOffset,
@@ -361,14 +362,17 @@ export const OnlineBoardDetailsPage: FC<OnlineBoardDetailsPageProps> = ({
<FlightCard flight={displayFlight} />
{/* Operating carrier */}
{displayFlight.operatingBy.carrier && (
<div className="flight-details__operating" data-testid="operating-carrier">
{t("BOARD.OPERATED-BY")}: {displayFlight.operatingBy.carrier}
{displayFlight.operatingBy.flightNumber
? ` ${displayFlight.operatingBy.flightNumber}`
: ""}
</div>
)}
{(() => {
const opCarrier = operatingCarrier(displayFlight.operatingBy);
const opNumber = displayFlight.operatingBy.flightNumber;
if (!opCarrier) return null;
return (
<div className="flight-details__operating" data-testid="operating-carrier">
{t("BOARD.OPERATED-BY")}: {opCarrier}
{opNumber ? ` ${opNumber}` : ""}
</div>
);
})()}
{/* Detailed leg information */}
<FlightLegs legs={legs} viewType="Onlineboard" />