Commit Graph

415 Commits

Author SHA1 Message Date
gnezim 83a9edb44e §4.1.24: assertion tests for all 6 sub-subsection clusters
Adds 48 new rule-tagged tests across 7 test files covering:
- §4.1.24.1/.2: filter disabled states (R13/R14/R16), swap button (R11),
  no-collapse (R8), hint text (R19), IATA tooltip label (R24)
- §4.1.24.3: arc style (R25), rendering mode (R21/R27/R28/R29),
  domestic/intl/connecting filters (R32-R35), zoom tiers (R23)
- §4.1.24.4: click sequence first/second/third (R36/R37/R39/R41)
- §4.1.24.5: API endpoint contract, bit-string parsing (R44/R45)
- §4.1.24.6: CTA URL format, new-tab intent, date-omit (R46/R47/R48)

Total: 175 tests, all passing.
2026-04-22 02:09:06 +03:00
gnezim 41d229a197 §4.1.24.6 R48: omit date segment in SB URL when Дата рейса not set
TZ §4.1.24.6: "Если Дата рейса не известна, то переход в SB должен
выполнятся без даты." buildBuyTicketUrl now accepts date as
string | undefined; when undefined the route triple is {dep}.{arr}
instead of {dep}.{YYYYMMDD}.{arr}. FlightsMapStartPage passes
filterState.date directly (possibly undefined) instead of defaulting
to today.
2026-04-22 02:08:56 +03:00
gnezim 0bb6bf2032 §4.1.24.3 R24: map marker tooltip label = IATA code, not city name
TZ §4.1.24.3 line 3098: "всплывающая подсказка с кодом аэропорта".
The marker `label` now uses `city.code` (IATA city code) instead of the
human-readable city name. On hover, Leaflet's tooltip shows the code.
2026-04-22 02:08:49 +03:00
gnezim f5dfa14eab §4.1.24.1/.2: filter label hidden on mobile; date locked until departure set
- Hide `.flights-map-filter-header` on mobile via `@include screen.mobile`
  so the "Найдите свой маршрут" label is absent on phone (R7).
- Disable the PrimeReact Calendar and DayQuickPick when `Город вылета` is
  empty; date picker must not be selectable without a departure city (R16).
- Add `disabled?` prop to DayQuickPick so callers can block the quick-day
  buttons on mobile (R16 mobile quick-day parity).
2026-04-22 02:08:43 +03:00
gnezim 5286049420 Audit OpenGraph + canonical + hreflang per TZ 4.1.19/20 (assertion tests)
All three feature seo builders already emitted the full OG set (title,
description, url, image, type, locale, site_name), canonical with no
query params, and hreflang for all 9 locales + x-default. No builder
gaps found. Added explicit §4.1.19/20 requirement-ID test cases to each
seo.test.ts so the contractual coverage is machine-verifiable.
2026-04-22 01:48:00 +03:00
gnezim 944015d658 Add JSON-LD microdata builders per TZ 4.1.19 + CLAUDE.md #6
WebSite JSON-LD now emitted on Online Board and Schedule start pages
via buildWebsiteJsonLd in the shared jsonLdBuilders module. Flight Map
already had WebPage JSON-LD; Online Board/Schedule search and details
pages already rendered Flight/ItemList JSON-LD directly in components.
2026-04-22 01:45:32 +03:00
gnezim 67504aa4d6 Fix P5 Task 13 typecheck errors (exactOptionalPropertyTypes, union narrowing, unused props) 2026-04-22 01:07:25 +03:00
gnezim 896dea9297 Audit details page structure + mini-list + day tabs per TZ 4.1.15.1-3 + 4.1.16.1-3
- FlightsMiniListItem: SVO/VKO airport names rendered as role=link spans that
  open external sites in a new tab (R19, R20) — avoids <a> nesting inside Link
- ScheduleDetailsPage: wire FlightsMiniList into contentLeft and DayTabs into
  stickyContent (schedule window [-1, +330]) per §4.1.16.1 R2/R3 and §4.1.16.3 R22
- Add navigation handler for schedule day-tab clicks (simple date URL swap;
  full §4.1.16.3.1 re-search algorithm is deferred)
- Tests: 72 tests across four files covering R12/R13/R16/R17/R22 (mini-list),
  R23/R27/R28 (day-tabs), R3/R5/R6/R7 (page structure), R2/R4/R22 (schedule)
2026-04-22 00:59:59 +03:00
gnezim 0485a3b0ac Lock in execution-days algorithm per TZ 4.1.16.8 (assertion tests)
Add targeted assertions covering every rendering rule in §4.1.16.8:
- DaysOfWeekStrip: Mon/Wed/Fri, weekend-only, single-day patterns;
  explicit bit-index contract (0=Mon … 6=Sun)
- weekDateRange: Mon–Sun ISO week, 6-day span invariant, leading-zero
  dd.MM.yyyy format, Sat input resolves to same week as Mon
- FlightSchedule: daysOfWeek.flight (not .current) drives active days;
  accordion collapses on click; week note anchored to dep-local date
2026-04-22 00:47:27 +03:00
gnezim c0c2d7d748 Audit intermediate landing + transfer per TZ 4.1.15.6 + 4.1.16.7
Three concrete gaps fixed:

1. TransferBar (Online-Board §4.1.15.6): duration now uses actual/estimated
   UTC times when viewType=Onlineboard instead of always scheduled UTC.
   Adds isIntermediateLanding prop (default true) so the label can switch
   between "Промежуточная посадка" and "Пересадка" based on flight-number
   identity rather than being hardcoded. StationChange now always rendered
   (not only when separated) so city/airport/terminal are always shown.

2. ScheduleFlightBody (§4.1.16.7): transferDuration previously computed
   ground time from .local strings ("HH:MM:SS" without timezone), making
   new Date() result timezone-dependent and often NaN. Switched to .utc
   (ISO 8601 with Z suffix) for a correct, deterministic diff.

Tests: 53 pass (8 TransferBar + 32+3 ScheduleFlightBody + 10 computeTransferTime).
New test cases: isIntermediateLanding=false label, StationChange always-on,
--separated class, UTC-based 90-min duration, label distinction per TZ.
2026-04-22 00:44:07 +03:00
gnezim c49a2a8525 Audit connecting flight details per TZ §4.1.16.6
Three fixes:
- Transfer box: use IATA cityCode (not display text) for city-level
  station change detection (TZ §4.1.16.6 rule 12), catching cases where
  city codes differ even if airport codes are the same.
- Transfer box: add terminal-change case — same airport but different
  arrival/departure terminals now renders both codes separated by →
  (TZ §4.1.16.6 rule 14).
- ScheduleDetailsPage title: show all connecting flight numbers in the
  page <h1> and title string (TZ §4.1.16.6 Table 60 header rule 1+5).

Also fixes a pre-existing flaky test in ScheduleFlightBody: todayUtc()
now always returns UTC noon of today to avoid day-boundary races.
2026-04-22 00:39:23 +03:00
gnezim 7fcb844b82 Audit multi-segment flight details per TZ 4.1.15.5 + 4.1.16.5
Gap found and fixed: Timeline route bar (Маршрут section) was rendering
departure/arrival times without day-change badges. TZ §4.1.15.5 rows 3
and 9 require +X/-X indicators whenever a leg crosses midnight.

Added TimeCell component to Timeline that emits the badge when
dayChange != 0, with priority to actual times when canChange=true
(Online Board) and fallback to scheduled (Schedule). Added 9 new
assertion tests covering: no badge when 0, +1/+2/-1 on arrival, badge
on departure, actual-takes-priority, and multi-badge (3 badges when 3
of 4 time cells carry non-zero day offsets).

All other multi-segment rules (routeChanged/returnToAirport from any
leg, codesharing in header, StationChange detection, TransferBar,
per-leg LegRoute with its own arrival day-change badge, ScheduleFlightBody
per-leg TimeGroup) were verified as already implemented. Per-segment
collapse/expand accordion (rows 7 of §4.1.15.5) deferred to Task 13.
2026-04-22 00:32:06 +03:00
gnezim 21b6c90d0f Audit direct flight details per TZ §4.1.15.4/.10/.11
Gaps found and closed:
- Departure gate (§4.1.15.4): rendered in boarding accordion row body,
  sourced from leg.departure.gate (Angular parity: flight-details-boarding L21)
- Departure transfer type / dispatch (§4.1.15.4): rendered in boarding row body
  from leg.departure.dispatch (Angular parity: flight-details-boarding L17)
- Aircraft tail number (§4.1.15.4): rendered in AircraftPanel from
  aircraft.registration field; AIRPLANE.TAIL-NUMBER added to all 9 locales
- BoardingPanel accepts optional departure prop for gate/dispatch display;
  legacy hidden panel keeps existing testids without duplication
- §4.1.15.10 meals + §4.1.15.11 services already implemented (assertion tests
  already cover icon rendering, links, fallback icon)

Tests added: 4 in BoardingPanel, 2 in AircraftPanel, 3 in FlightDetailsAccordion
2026-04-22 00:26:39 +03:00
gnezim 1740af682c Render previous-flight chip as link per TZ §4.1.15.9
Angular rule: show the previous-flight identifier as a clickable link
opening the prior flight's details in a new browser tab, gated on the
flight's scheduled departure being > today − 2 days old. Outside that
window it falls back to plain text to avoid stale cross-links.

Threads locale + departureDateLocal from OnlineBoardDetailsPage through
FlightLegs → FlightDetailsAccordion → AircraftPanel. URL is built with
the existing buildFlightUrlParams helper using previousFlight.localDate,
matching Angular's dateToSearchBy = new Date(prevFlight.localDate).
2026-04-22 00:17:43 +03:00
gnezim e33c8c4b24 Audit timeline status display per TZ 4.1.15.8
Two gaps: Delayed fell into center--progress (blue) instead of
orange; Sent was excluded from the isInFlight branch despite the
Angular FlightStatusLegacy.inFlight contract. Fixed both and added
8 per-status assertions covering all 8 FlightStatus enum values.
2026-04-22 00:09:49 +03:00
gnezim 877cd87162 Add timeline time-calculation algorithm per TZ §4.1.15.7
Creates timelineTime.ts with computeTimelineCalc (R94–R97: total/elapsed/
remaining minutes + aircraft position %) and formatTimelineDuration (R98:
omit zero leading units — «45мин.» not «0ч. 45мин.»).

Wires into OnlineBoardDetailsPage: arrival time now uses actual > estimated
> scheduled priority (R94), and В пути / До прилета labels use the new
formatter. 24 unit tests cover all branches.
2026-04-22 00:06:21 +03:00
gnezim 63fc6060f2 Verify day-change algorithm per TZ 4.1.17 (per-time-type badges, query-date baseline)
R4 gap fixed: TimeGroup now accepts scheduledDayChange + actualDayChange props
separately so each time type renders its own independent badge. FlightCard
updated to pass them independently (scheduled vs actual/estimated); expanded
row time block also now shows per-type badges.

R5 tooltip fixed: dayChangeBadgeTooltip() uses string-based date extraction
(no TZ reprojection via new Date()) — avoids viewer-TZ shift for SSR and
cross-TZ correctness. Returns "День" for ±1, DD.MM.YYYY for ±2+.

New shared helper dayChange.ts exports computeDayChange(), dayChangeBadgeTooltip(),
formatDayChangeBadge(). 27 unit tests cover +0/+1/+2/-1/-2, null, malformed
input, month/year boundaries, and per-time-type independence (R4).

R1–R3, R6 confirmed correct (API supplies dayChange per ITimesSet; badge
adjacent to time; hidden when 0). R8 (mobile tooltip suppression) deferred.
2026-04-22 00:01:30 +03:00
gnezim 5d31f4389e Add operator icon mapping helper per TZ §4.1.22
Extracts the 35-carrier logo path table from OperatorLogo into a shared
pure module (src/shared/operatorIcon.ts) so the mapping can be tested and
reused independently. Adds the 7-range SU flight-number fallback that the
TZ requires when OperatingBy is null — SU5000-5399 shows Pobeda (DP),
SU5400-5799 shows Aurora (HZ), SU6000-6999 shows Rossiya (FV), and the
3000-4999 / 5800-5999 bands explicitly render no logo.

63 table-driven tests lock in every range boundary and carrier entry.
FlightCard and ScheduleFlightBody both apply the range resolution before
falling back to the flight's own carrier code.
2026-04-21 23:54:00 +03:00
gnezim 4290c819bb Audit Schedule expanded rows per TZ 4.1.14.4 (multi-segment + connecting)
Gate Buy button to the TZ §4.1.14.4.4 window: visible only when departure
UTC is > 2 hours ahead AND < 330 days ahead; first leg governs for multi/
connecting. Gate Status button (§4.1.14.4.5) to same-day departure only,
based on UTC calendar date. Add separate Details button (§4.1.14.4.6) that
is always visible when an onStatus handler is provided. Add SCSS for the
new details-btn outline style. Add 25-test ScheduleFlightBody.test.tsx
covering structure, transfer-box labels, buy gate, and status gate.
2026-04-21 23:18:16 +03:00
gnezim 6f67c06786 Audit Schedule week-tabs + collapsed row per TZ 4.1.14.1 + 4.1.14.3
WeekTabs (§4.1.14.1):
- Fix active range: derive weeks from scheduleWindowBounds() [-1,+330 days]
  instead of hardcoded WEEKS_AFTER=30 (≈210 days, less than required 330).
- Fix auto-scroll: sync page via useEffect when selectedMonday prop changes
  so navigating to a different week always reveals its tab.
- Add fill-to-7: pad last page with disabled placeholder tabs when the
  final active week does not end a complete group of 7; disable next arrow.

Collapsed row (§4.1.14.3): already implemented — add lock-in tests for
Tables 36–40 (direct / multi-leg / connecting) covering flight number,
operator logos (round for multi-leg per commit 3ae59da), dep/arr times,
day-change chips, duration column, expand chevron, and DayGroupedFlightList
day-grouping + column headers.
2026-04-21 23:11:32 +03:00
gnezim 8b0d559df9 Implement Online-Board flight-list default sort per TZ §4.1.13.2
Departure/route/flight-number modes sort by scheduled departure time;
arrival mode sorts by scheduled arrival time (last leg for MultiLeg).
Day ordering (yesterday < today < tomorrow) emerges from absolute ISO
timestamps — no bespoke bucketing needed. Flights missing a timestamp
are pushed to the end. 18 unit tests lock the contract in.
2026-04-21 22:48:39 +03:00
gnezim 439624244d Audit DayTabs behavior per TZ 4.1.13.1 (7-day window, paging, padding, active range)
- Fix daysAfter: 7→14 in OnlineBoardSearchPage (TZ active range is today-1 to today+14)
- Add inactive padding tabs on the last page when it has fewer than 7 slots; right-arrow stays disabled on last page regardless (TZ §4.1.13.1)
- Add aria-current="date" to active DayTabButton for accessible highlight (TZ requires visual highlight + screen-reader signal)
- Add auto-scroll via scrollIntoView when selectedDate changes externally (URL-driven day navigation)
- Convert DayTabButton to forwardRef to support the activeBtnRef scroll anchor
- 9 new TZ-labelled tests locking in all the above behaviors
2026-04-21 22:45:08 +03:00
gnezim 38a512004f Add scroll-to-current-time + auto-expand-nearest on Online-Board today's tab per TZ 4.1.13
- New findNearestFlightIndex helper (scrollToCurrentTime.ts) with 5 unit tests
- FlightList: lock scroll-to-nearest behind a ref so live SignalR updates
  don't yank the viewport back to the auto-selected flight after the user
  has manually scrolled elsewhere
- OnlineBoardSearchPage integration tests: verify today/future/past tab
  selection logic via findClosestFlightId (the id-based variant already
  wired to FlightList.initialCurrentFlightId)
2026-04-21 22:39:33 +03:00
gnezim a5c64a2270 Search execution, cancellation, and error handling per TZ §4.1.10/11/12
- AbortController wired through ApiClient → api functions → hooks so a
  new search immediately aborts the previous in-flight request (§4.1.12)
- cancel() exposed from useOnlineBoard / useScheduleSearch; Escape key
  triggers it while the loader is showing (§4.1.12)
- «Отменить поиск» button rendered during loading; hides when idle (§4.1.12)
- data-searching attribute on search pages disables filter/tabs/breadcrumbs
  via pointer-events:none CSS while a search is running (§4.1.10/11)
- Submit buttons disabled for 30 s after each search (hardcoded, per TZ
  §4.1.10/11: «не должно выноситься в конфигурационный файл»)
- Per-status error messages: BOARD.ERROR-TIMEOUT / ERROR-4XX / ERROR-5XX
  replace the generic LOAD-FAILED-MESSAGE (§4.1.10.1/11.1)
- Error messages added to all 9 locales
- 8 new tests: 3 for AbortController wiring, 5 for error banners + cancel
  button visibility
2026-04-21 22:08:11 +03:00
gnezim c509131649 Tighten filter validation per TZ 4.1.9.3 + 4.1.9.4 2026-04-21 21:50:46 +03:00
gnezim 66518a6f0c Enforce 1h minimum gap on time-range slider per TZ 4.1.9 Tables 12/14 2026-04-21 21:36:07 +03:00
gnezim 83951d4292 Add clear-button (X) to filter fields per TZ 4.1.9 Tables 11/12/14
- OB flight-number: X was always visible; now conditionally rendered only
  when the field has a value (hides when empty)
- OB flight-date and route-date: add X button next to calendar icon,
  clears date state and hides itself when empty
- Schedule outbound and return date-range calendars: same inline X pattern
- CSS: .calendar-input-wrapper + .calendar-clear-btn added to both SCSS
  files (absolute-positioned left of the calendar icon)
- CityAutocomplete: already correct (CSS show/hide via has-value class)
- 21 new tests across OnlineBoardFilter, ScheduleFilter, CityAutocomplete
  (aria-label, visibility toggling, click-to-clear); all 640 pass
2026-04-21 20:05:53 +03:00
gnezim 8f4d5fcaa2 Add Current-Week label substitution to Schedule date-range picker per TZ 4.1.9 Table 14 2026-04-21 19:59:27 +03:00
gnezim 04a3d9cd7c Add Today/Tomorrow label substitution to Online-Board date picker per TZ 4.1.9 Tables 11+12 2026-04-21 19:55:36 +03:00
gnezim b27ee2ae8b Verify start-page info-section content per TZ Table 8 + Table 9
Add assertion tests confirming both OnlineBoardStartPage and ScheduleStartPage
render the required info-section headings and content blocks per TZ specifications.

OnlineBoardStartPage (TZ Table 8):
- Heading: 'Что такое Онлайн-табло и что я могу в нем увидеть?'
- 4 info blocks: Актуальная информация, Информация об услугах, Купить билет, Расписание

ScheduleStartPage (TZ Table 9):
- First heading: 'Как пользоваться расписанием?' + 4 info blocks
- Second heading: 'Возможности расписания' + 2 capabilities blocks
- Blocks 5-6 (Купить билет, Расписание) now rendered under capabilities heading

Tests added:
- OnlineBoardStartPage: 6 new assertions (4.1.6-R-info-heading through 4.1.6-R-popular)
- ScheduleStartPage: 8 new assertions (4.1.7-R-info-heading-1 through 4.1.7-R-popular)
2026-04-21 19:25:45 +03:00
gnezim fbb84fc0da Align Flight-Map first-entry toggle defaults with TZ 4.1.1-R14/R21 2026-04-21 19:22:16 +03:00
gnezim 4b6cb5bc40 Audit popular-requests Top-4 click-prefill against TZ §4.1.5 (6 kinds)
Board kinds (Arrival, Departure, Route, FlightNumber): buildOnlineBoardPrefillState
now emits date=today in every case; OnlineBoardStartPage wires it through to
OnlineBoardFilter via initialDate.

Schedule one-way (Route/Schedule): click handler now includes dateFrom/dateTo
= current ISO week (Mon-Sun) in the transient prefill written to sessionStorage.

Schedule round-trip (RouteWithBack/Schedule): additionally includes
returnDateFrom/returnDateTo = next ISO week.

SchedulePrefillState extended with the four new optional date fields;
yyyymmddToDate helper added to ScheduleStartPage; currentWeekBounds /
nextWeekBounds helpers implement the TZ week-boundary logic.

Nine new §4.1.5-labeled tests (4 unit + 5 integration) added; existing
prefill-state tests updated to expect the new date fields. All 55 tests pass.
2026-04-21 19:19:38 +03:00
gnezim c3c1f830b9 Wire first-entry geolocation into Schedule start page (TZ 4.1.1-R8) 2026-04-21 19:11:57 +03:00
gnezim b023cb922a Wire first-entry geolocation + mobile time default into Online-Board start page (TZ 4.1.1) 2026-04-21 19:09:34 +03:00
gnezim 9aed10c281 Add useIsMobileViewport hook + Online-Board mobile time defaults per TZ 4.1.1-R4/R5 2026-04-21 19:03:54 +03:00
gnezim bc0b10bd8e Migrate flights-map to shared useGeoCityDefault hook 2026-04-21 19:01:07 +03:00
gnezim a6454dc07f Fix exactOptionalPropertyTypes errors in cross-section store hydration initializers 2026-04-21 18:04:36 +03:00
gnezim 47fee9d7b5 Wire cross-section filter hydration into Board/Schedule/Map per TZ 4.1.8 Table 10 2026-04-21 18:03:27 +03:00
gnezim 2fe5364187 Verify TZ Table 7 Карта полетов breadcrumb = [Главная] only 2026-04-21 17:53:16 +03:00
gnezim 266a6f910c Fix ScheduleDetailsPage happy-path breadcrumb + add missing breadcrumb tests
The final (success) return branch was passing a hardcoded 1-item breadcrumb
array instead of the computed `breadcrumbs` variable, so the leaf crumb built
from ?request= was silently dropped for loaded flights. Loading/error/empty
branches were already correct. Adds 3 unit tests to lock the wiring.
2026-04-21 17:50:57 +03:00
gnezim 5728861c5c Schedule search → details links emit ?request= + details page shows leaf breadcrumb (TZ §4.1.2 row 11, §4.1.4 rows 11-13) 2026-04-21 17:45:36 +03:00
gnezim 1821f7f78e Add TZ Table 7 mode-specific leaf breadcrumb + clickable back-to-search link on Online-Board details
Per TZ §4.1.4 Table 7 rows 6–8, the details page now builds a 3-item
breadcrumb trail [Home, Онлайн-Табло, <leaf>] where <leaf> is mode-aware:
- flight: "Номер рейса: SU-1234" (hyphen per TZ)
- departure: "Вылет: {station}"
- arrival: "Прилет: {station}"
- route: "Маршрут: {dep}-{arr}"

The leaf crumb is a clickable link back to the source search page with
time-range preserved in the URL. Share-link entries (no ?request=) get
only [Home, Онлайн-Табло] with no leaf.

Breadcrumbs component updated to allow last-item links (was suppressed),
since TZ explicitly requires the leaf to be navigatable.

CONFLICT (deferred to Task 16): TZ row 6 says departure/arrival leaf
should show both dep+arr cities; parentRequest only carries one station,
so only that station is shown. Departure/arrival search returns flights
to many arrival cities — "both cities" makes no sense at search-mode level.
2026-04-21 17:35:49 +03:00
gnezim bcaf3ab503 Verify Flight-Map title 'Карта полетов' per TZ Table 6 rows 1-3 2026-04-21 17:27:18 +03:00
gnezim df4ac19f7d Branch schedule details title by direct vs connecting per TZ Table 6 rows 11-13 2026-04-21 17:24:16 +03:00
gnezim f03562e4cd Align Online-Board page titles with TZ Table 6 (сегодня/завтра/ДД.ММ.ГГГГ date display)
- Add formatDateForTitle helper: returns today/tomorrow labels or dd.MM.yyyy
- Switch all search page title builders to use formatDateForTitle; descriptions keep dd.MM.yyyy
- FLIGHT-DETAILS title now uses routeCities (no date) per TZ rows 6-8; adds TITLE-NO-ROUTE fallback for SSR when cities not yet loaded
- buildFlightDetailsSeoFromId accepts optional cityNames param
- Update ru/en i18n TITLE strings to TZ Table 6 format; add TITLE-NO-ROUTE to all 9 locales
- Tests: 32 cases covering today/tomorrow/arbitrary-date branches and routeCities logic
2026-04-21 17:18:59 +03:00
gnezim 4f840486b8 Consolidate scattered +330/+6mo date-window literals into shared dateWindow module 2026-04-21 17:09:17 +03:00
gnezim 8b22f0601f Use shared detailsRequestParam codec for mini-list parent-request (route + flight kinds) 2026-04-21 16:37:32 +03:00
gnezim 7577e703c2 Close SharePanel on Escape + mark as role=dialog with aria-label (a11y + PrimeNG parity) 2026-04-21 08:32:21 +03:00
gnezim 36db7d3f2e Add aria-label to OnlineBoard search forms (flight-number + route) for a11y 2026-04-21 08:30:25 +03:00
gnezim 3d815fa9e3 Add aria-label to Schedule search forms (a11y discoverable forms) 2026-04-20 23:08:55 +03:00