Replace the inline 'Invalid parameters' fallbacks and the framework's
default '404' text with the existing Aeroflot 404 screen. Unknown
locale, malformed flight/route/station params, and unmatched URLs
(including bad paths like onlineboard//route/...) now all land on the
same ErrorPage component.
Angular's schedule renders 7 day pills ("20 пн … 26 вс") spanning the
active week, not weekly date ranges. Match that: tabs now render the
seven days of selectedMonday's week with day-num + weekday-abbr stack.
Prev/next arrows shift by full weeks. Day clicks scroll to the
matching day group in DayGroupedFlightList for the schedule UX.
Schedule list day accordion stays collapsed by default but auto-
opens the day matching today's date when it's in the visible week
window — mirrors Angular's p-accordion default-active behaviour
where today's flights are visible without a click. The user can
still collapse it; we never re-open after that for the same date.
Visual-diff URLs were hardcoded to a past date with the wrong React
URL format (Angular path-style /AAQ/16042026 instead of React's
single-segment /AAQ-20260420-00002400). Switch to dynamic
yyyyMMdd of today for onlineboard pages and Mon→Sun of the current
week for schedule. Schedule-route diff dropped from ~91% to ~28%
on desktop after these two fixes.
ANGULAR_BASE / ANGULAR_PATH_PREFIX / REACT_BASE / MOCK_ANGULAR /
MOCK_REACT env vars let the script target the live test env
(https://flights.test.aeroflot.ru/ru-ru) without code changes.
Used to rerun the Visual Parity Report against the live Angular
backend instead of a local ng serve.
Match Angular's p-accordion default-collapsed state on the schedule
results page. State now tracks expanded days (default empty)
instead of collapsed days (default empty), so the initial render
shows day headers only and the user clicks to reveal flights.
Schedule details page used to show only a one-line FlightCard and
stop. Reuse ScheduleFlightBody so each flight in the chain renders
the same per-leg layout the schedule results page uses (route
summary, leg cards, transit pill, share/Купить/Детали рейса
actions). Add a `Вернуться к Расписанию` back link to the header.
While here, fix the SEO title key — buildScheduleDetailsSeo was
calling SEO.SCHEDULE.DETAILS.TITLE with `flights={...}`, but the
i18n bundle only defines SEO.SCHEDULE.FLIGHT-DETAILS.TITLE with
`flightNumber={...}`. The unresolved key was leaking into the
document title as "SEO.SCHEDULE.DETAILS.TITLE".
Round-trip schedules used to render outbound and inbound lists
stacked. Mirror Angular's schedule-direction-switch: keep both
fetches running, but render only the active direction's list and add
a button group to the sticky header that swaps which one is shown.
WeekTabs track the active direction's week independently, and tab
navigation updates whichever direction is currently active.
Each schedule + onlineboard search now records itself into the
existing useSearchHistory localStorage hook, with a structured
params payload (departure/arrival/dates/flightNumber). The
SearchHistory sidebar renders the rich Angular layout: clock or
plane icon, optional sub-title (e.g. "Расписание рейсов, в одну
сторону"), city pair, and date range, with inbound dates appended
for round-trip searches.
Schedule flight cards now expand into the rich Angular layout instead
of the online-board time/transition rows. Mirrors connecting-flight-
body / multi-flight-body: horizontal timeline summary, per-leg card
with section number + flight number + operator + aircraft + dep/arr
times + leg duration + stations, transfer-inline-extended pill
between legs (Пересадка, ground time, transit city), and the actions
row (share, Купить, Детали рейса).
Wired via a renderExpandedBody render prop on FlightCard/FlightList so
ui/flights doesn't need to know about schedule-specific bodies.
Replace OnlineBoardFilter on schedule pages with a dedicated
ScheduleFilter that matches Angular's schedule-filter:
- Город вылета / Город прилета with swap arrows
- 'Показать расписание на' date range picker
- 'Время вылета' time slider
- 'Только прямые рейсы' checkbox (sets connections=0)
- 'Показать обратные рейсы' checkbox
- 'Показать расписание' submit button (blue, full-width)
The OnlineBoardFilter accordion (Номер рейса + Маршрут tabs) is no
longer rendered on schedule pages — Angular only ships flight-number
search on the online-board side.
Add sort arrows on ВЫЛЕТ / ВРЕМЯ В ПУТИ / ПРИЛЕТ headers — clicking
toggles ascending/descending order; clicking again clears the sort.
Day groups (Понедельник 20 апреля, etc.) are now collapsible via the
header chevron — matches Angular's p-accordion structure where each
day is an accordionTab. Default state expanded.
- Connecting (multi-leg via transit) flights are now folded into a
synthetic MultiLeg shape with combined flight numbers (SU 6188,
SU 6233) and per-leg airline logos, matching Angular's
schedule-list-flight-header.
- Schedule grid now uses Angular's 8-column layout
(80/120/100/240/100/100/240/16). The middle status icon is
replaced by a duration column with the blue clock icon and
'3ч. 48мин.' / '4h 19m' formatting.
- Multi-leg airline logos use the round badge variant (separate
round.png assets) so two carriers fit side-by-side without overlap.
- Action buttons removed from collapsed rows — Angular only shows
flight-actions in the expanded body. Added chevron column for
every schedule card and made schedule cards expandable by default.
- Removed 'Туда: MOW → KUF' subhead from outbound section, matching
Angular's bare flight list under the column header.
Angular's FlightsMapFilterComponent only sets departure when
UserLocationService.location emits an actual position — there's no
fallback to Moscow. Removing the React fallback aligns the empty
initial state (no splines drawn before user input).
Angular's getCityOrAirport walks airport→city when the input code is
an airport (SVO → Москва), only falling back to the airport name when
no parent city is dictionarised. React was returning the raw airport
name (Шереметьево) on the popular requests panel.
Match Angular's flight-actions layout — schedule rows now show the
orange Buy and outlined Status рейса buttons inline at the right edge
of the row instead of inside the expanded panel.
Companion markdown to the comparison-report/visual/report.html with
the same coverage matrix and per-page findings. Useful for git-based
review without serving the HTML.
Also adds AGENTS.md (subagent role definitions for future sessions)
and the modernjs-v3-upgrade plan stub from the earlier scoping.
The mobile day-select dropdown was rendering as an empty <select>
on detail pages where the calendar API hasn't shipped any usable
days for that view. The empty box took layout space and looked
broken. Match Angular: don't render the picker when there's
nothing to pick.
ScheduleStartPage now starts dateFrom/dateTo as null so the input
shows the `ДД.ММ.ГГГГ - ДД.ММ.ГГГГ` placeholder Angular ships
instead of pre-filling with the current week. The submit handler
defaults to current-week range when the user submits without
picking dates, preserving the legacy "find this week" UX.
Same pattern as the onlineboard date fix.