Add shared helpers and DETAILS i18n keys for flight details panels

This commit is contained in:
2026-04-16 22:23:29 +03:00
parent 81574ae137
commit 6bd17b047f
4 changed files with 196 additions and 0 deletions
@@ -0,0 +1,82 @@
import { describe, it, expect } from "vitest";
import {
shouldShowTransition,
shouldShowAircraft,
SERVICE_ICON_MAP,
MEAL_LINKS,
} from "./shared.js";
import type { IFlightTransitionItem } from "../../types.js";
describe("shouldShowTransition", () => {
const validItem: IFlightTransitionItem = {
start: {} as never,
end: {} as never,
status: "InProgress",
isActual: true,
};
it("returns false for Schedule viewType", () => {
expect(shouldShowTransition(validItem, "Scheduled", "Schedule")).toBe(false);
});
it("returns false when leg is Cancelled", () => {
expect(shouldShowTransition(validItem, "Cancelled", "Onlineboard")).toBe(false);
});
it("returns false when item is undefined", () => {
expect(shouldShowTransition(undefined, "Scheduled", "Onlineboard")).toBe(false);
});
it("returns false when item.status is Scheduled", () => {
const scheduled = { ...validItem, status: "Scheduled" as const };
expect(shouldShowTransition(scheduled, "Scheduled", "Onlineboard")).toBe(false);
});
it("returns true for active transition on Onlineboard", () => {
expect(shouldShowTransition(validItem, "Scheduled", "Onlineboard")).toBe(true);
});
});
describe("shouldShowAircraft", () => {
it("returns true when actual.title exists", () => {
expect(shouldShowAircraft({ aircraft: { actual: { title: "A320" } } })).toBe(true);
});
it("returns true when scheduled.title exists", () => {
expect(shouldShowAircraft({ aircraft: { scheduled: { title: "A320" } } })).toBe(true);
});
it("returns true when configuration exists", () => {
expect(shouldShowAircraft({ aircraft: { configuration: "C12Y138" } })).toBe(true);
});
it("returns false when no aircraft info", () => {
expect(shouldShowAircraft({})).toBe(false);
expect(shouldShowAircraft({ aircraft: {} })).toBe(false);
});
it("returns false when titles are empty strings", () => {
expect(shouldShowAircraft({ aircraft: { actual: { title: "" }, scheduled: { title: "" } } })).toBe(false);
});
});
describe("SERVICE_ICON_MAP", () => {
it("maps all 8 service IDs", () => {
expect(SERVICE_ICON_MAP[1]).toBe("shopping");
expect(SERVICE_ICON_MAP[2]).toBe("space");
expect(SERVICE_ICON_MAP[3]).toBe("taxi");
expect(SERVICE_ICON_MAP[4]).toBe("wifi");
expect(SERVICE_ICON_MAP[5]).toBe("gsm");
expect(SERVICE_ICON_MAP[6]).toBe("entertaintment");
expect(SERVICE_ICON_MAP[7]).toBe("entertaintment");
expect(SERVICE_ICON_MAP[8]).toBe("seat_reservation");
});
});
describe("MEAL_LINKS", () => {
it("has links for Economy, Comfort, Business", () => {
expect(MEAL_LINKS.Economy).toContain("meal-type_0");
expect(MEAL_LINKS.Comfort).toContain("meal-type_1");
expect(MEAL_LINKS.Business).toContain("meal-type_2");
});
});
@@ -0,0 +1,68 @@
import type {
FlightStatus,
IEquipmentFull,
IFlightTransitionItem,
MealType,
} from "../../types.js";
export type DetailsViewType = "Onlineboard" | "Schedule";
/**
* Matches Angular's `showBoardProperty` in flight-details-wrapper.component.ts.
* Transition panels are hidden for Schedule mode, Cancelled flights,
* missing data, or when the transition hasn't started.
*/
export function shouldShowTransition(
item: IFlightTransitionItem | undefined,
legStatus: FlightStatus,
viewType: DetailsViewType,
): boolean {
if (viewType === "Schedule") return false;
if (legStatus === "Cancelled") return false;
if (!item) return false;
if (item.status === "Scheduled") return false;
return true;
}
/**
* Matches Angular's `showAircraft` getter. Shows when actual or scheduled
* title exists, or when configuration string is present.
*/
export function shouldShowAircraft(equipment: Pick<IEquipmentFull, "aircraft">): boolean {
const aircraft = equipment.aircraft;
if (!aircraft) return false;
const title = aircraft.actual?.title || aircraft.scheduled?.title;
if (title) return true;
if (aircraft.configuration) return true;
return false;
}
/**
* Service ID → icon filename mapping.
* From Angular flight-details-services.component.ts.
* IDs 6 and 7 both use the entertaintment icon (typo in original is preserved
* because that's how Angular ships the filename).
*/
export const SERVICE_ICON_MAP: Record<number, string> = {
1: "shopping",
2: "space",
3: "taxi",
4: "wifi",
5: "gsm",
6: "entertaintment",
7: "entertaintment",
8: "seat_reservation",
};
/** Fallback icon for unknown service IDs. */
export const SERVICE_ICON_FALLBACK = "comfort-plus";
/**
* Meal type → aeroflot.ru info page link.
* From Angular flight-details-meal.component.ts.
*/
export const MEAL_LINKS: Record<Exclude<MealType, "Special">, string> = {
Economy: "https://www.aeroflot.ru/ru-ru/information/onboard/dining?0000#meal-type_0",
Comfort: "https://www.aeroflot.ru/ru-ru/information/onboard/dining?0000#meal-type_1",
Business: "https://www.aeroflot.ru/ru-ru/information/onboard/dining?0000#meal-type_2",
};
+23
View File
@@ -37,6 +37,29 @@
"TITLE": "Online Timetable",
"YOU_SEARCH": "You searched"
},
"DETAILS": {
"REGISTRATION": "Check-in",
"BOARDING": "Boarding",
"DEBOARDING": "Deboarding",
"AIRCRAFT": "Aircraft",
"MEAL": "Meal",
"ON_BOARD_SERVICES": "On-board services",
"SCHEDULED": "Scheduled",
"ACTUAL": "Actual",
"MEAL_ECONOMY": "Economy",
"MEAL_COMFORT": "Comfort",
"MEAL_BUSINESS": "Business",
"STATUS_FINISHED": "Finished",
"STATUS_EXPECTED": "Expected",
"STATUS_IN_PROGRESS": "In progress",
"STATUS_SPECIFIED": "Specified",
"STATUS_SCHEDULED": "Scheduled",
"TERMINAL": "Terminal",
"GATE": "Gate",
"BAG_BELT": "Baggage belt",
"CONFIGURATION": "Configuration",
"STATUS": "Status"
},
"BOARDING-STATUSES": {
"Expected": "Expected",
"Finished": "Completed",
+23
View File
@@ -37,6 +37,29 @@
"TITLE": "Онлайн-Табло",
"YOU_SEARCH": "Вы искали"
},
"DETAILS": {
"REGISTRATION": "Регистрация",
"BOARDING": "Посадка",
"DEBOARDING": "Высадка",
"AIRCRAFT": "Воздушное судно",
"MEAL": "Питание",
"ON_BOARD_SERVICES": "Услуги на борту",
"SCHEDULED": "По расписанию",
"ACTUAL": "Фактически",
"MEAL_ECONOMY": "Эконом",
"MEAL_COMFORT": "Комфорт",
"MEAL_BUSINESS": "Бизнес",
"STATUS_FINISHED": "Завершена",
"STATUS_EXPECTED": "Ожидается",
"STATUS_IN_PROGRESS": "В процессе",
"STATUS_SPECIFIED": "Назначена",
"STATUS_SCHEDULED": "По расписанию",
"TERMINAL": "Терминал",
"GATE": "Выход",
"BAG_BELT": "Лента выдачи багажа",
"CONFIGURATION": "Компоновка",
"STATUS": "Статус"
},
"BOARDING-STATUSES": {
"Expected": "Ожидается",
"Finished": "Закончена",