Fix Schedule UI regressions and complete non-RU/EN locale translations
- Duration now sums segments + transfers (last arrival − first departure) for multi-leg/connecting in Schedule, matching TZ §4.1.14.3 and Angular. - Default day auto-expands per TZ §4.1.14: current-week today, future-week first valid day, last-valid-day fallback when earlier days are out of window. - Aircraft model no longer leaks into collapsed rows; shown only when expanded AND direct, mirroring Angular's operator-logo-and-model [showModel]="expanded && direct". - Week tabs use MONTH-SHORT.* translation table so Russian renders "27 апр. - 3 май." instead of genitive "мая" from Intl. - "Ранее искали" → "Вы искали" across all 9 locales (TZ §4.1.9.5). - Sort-arrow headers compacted (inline-flex nowrap, zero gap) so labels stay on one line next to the chevrons. - robots.txt allows Yandex/Googlebot/* with no Disallow (TZ §4.1.20). - 6 non-RU/EN locales (de/es/fr/it/ja/ko) + zh were missing ~45 strings each; translated from Angular where present, hand-translated otherwise so every locale is down to the two intentional `.undefined` stubs.
This commit is contained in:
@@ -42,9 +42,9 @@ export interface FlightCardProps {
|
||||
onViewDetails?: () => void;
|
||||
/**
|
||||
* Search direction. `arrival` swaps the boarding row to deboarding
|
||||
* (label `Высадка` instead of `Посадка`); `schedule` keeps the
|
||||
* aircraft model visible in the collapsed row per Angular's schedule
|
||||
* results layout.
|
||||
* (label `Высадка` instead of `Посадка`). Aircraft model is only shown
|
||||
* in the expanded body for direct flights (matches Angular's
|
||||
* `[showModel]="expanded && direct"` on operator-logo-and-model).
|
||||
*/
|
||||
direction?: "departure" | "arrival" | "route" | "flight" | "schedule";
|
||||
/**
|
||||
@@ -120,6 +120,28 @@ function formatFlyingTime(value: string, language: string): string {
|
||||
return `${h}h ${m}m`;
|
||||
}
|
||||
|
||||
function formatMinutes(total: number, language: string): string {
|
||||
if (!Number.isFinite(total) || total < 0) return "";
|
||||
const isRu = language.startsWith("ru");
|
||||
const h = Math.floor(total / 60);
|
||||
const m = total % 60;
|
||||
if (isRu) return `${h}ч. ${m}мин.`;
|
||||
return `${h}h ${m}m`;
|
||||
}
|
||||
|
||||
function totalElapsedMinutes(flight: ISimpleFlight): number | null {
|
||||
const legs = flight.routeType === "Direct" ? [flight.leg] : flight.legs;
|
||||
const first = legs[0];
|
||||
const last = legs[legs.length - 1];
|
||||
if (!first || !last) return null;
|
||||
const depUtc = first.departure.times.scheduledDeparture.utc;
|
||||
const arrUtc = last.arrival.times.scheduledArrival.utc;
|
||||
if (!depUtc || !arrUtc) return null;
|
||||
const diffMs = Date.parse(arrUtc) - Date.parse(depUtc);
|
||||
if (!Number.isFinite(diffMs) || diffMs <= 0) return null;
|
||||
return Math.round(diffMs / 60000);
|
||||
}
|
||||
|
||||
/**
|
||||
* A single flight row in search results.
|
||||
*
|
||||
@@ -334,7 +356,7 @@ export const FlightCard: FC<FlightCardProps> = ({
|
||||
>
|
||||
<div className="flight-card__number" data-testid="flight-carrier-number">
|
||||
<div>{flightNumber}</div>
|
||||
{(expanded || direction === "schedule") && aircraftName && (
|
||||
{expanded && flight.routeType === "Direct" && aircraftName && (
|
||||
<div className="flight-card__aircraft">{aircraftName}</div>
|
||||
)}
|
||||
{/* TZ §4.1.13.3 Table 24 C15–C16: route-changed / return-to-airport
|
||||
@@ -393,7 +415,17 @@ export const FlightCard: FC<FlightCardProps> = ({
|
||||
<div className="flight-card__duration" data-testid="flight-duration">
|
||||
<span className="flight-card__duration-icon" aria-hidden="true" />
|
||||
<span className="flight-card__duration-text">
|
||||
{formatFlyingTime(flightDuration, language)}
|
||||
{flight.routeType === "MultiLeg"
|
||||
? (() => {
|
||||
// TZ §4.1.14.3: total duration = segments + pauses.
|
||||
// API's flyingTime is air-time only; use last-arrival minus
|
||||
// first-departure elapsed time so connecting trips match Angular.
|
||||
const mins = totalElapsedMinutes(flight);
|
||||
return mins != null
|
||||
? formatMinutes(mins, language)
|
||||
: formatFlyingTime(flightDuration, language);
|
||||
})()
|
||||
: formatFlyingTime(flightDuration, language)}
|
||||
</span>
|
||||
</div>
|
||||
) : (
|
||||
|
||||
Reference in New Issue
Block a user