add relations to stop page #115
Labels
No labels
Compat/Breaking
Kind/Bug
Kind/Documentation
Kind/Enhancement
Kind/Feature
Kind/Security
Kind/Testing
Priority
Critical
Priority
High
Priority
Low
Priority
Medium
Reviewed
Confirmed
Reviewed
Duplicate
Reviewed
Invalid
Reviewed
Won't Fix
Status
Abandoned
Status
Blocked
Status
Need More Info
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
gtfs.zone/coloring-book#115
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
The stop page currently shows which routes and agencies serve a stop but doesn't link to any timetables. This feature adds a "Timetables" section to the stop page — one row per unique
(route_id, service_id)pair — using the samerenderServiceReferencecard rows the route page uses. No direction button is shown; clicking a row navigates to the timetable. The two redundantstop_timesqueries that exist today are collapsed into one shared pass. The meaningless "Transit Network" heading is removed.Relevant Context
src/modules/stop-view-controller.ts— the entire stop page.renderStopViewcallsgetAgenciesServingStopandgetRoutesServingStopindependently, each doing a fullstop_times+tripsscan.renderTransitNetworkrenders the "Transit Network" heading + agency-grouped route cards.src/utils/entity-references.ts— containsrenderServiceReference(used by route page) andrenderRouteReference(used by service page).ServiceReferenceOptsacceptsroute_id,tripCount,calendarDates. Whenroute_idis set, the row getsdata-route-idand navigates to timetable.SERVICE_REF_ROWCSS class keys the existing click handler.src/modules/page-content-renderer.tsline ~711 — theSERVICE_REF_ROWclick handler: if bothdata-route-idanddata-service-idare present, callsonTimetableClick(route_id, service_id). This handler already runs for the entire container, so stop-page service rows get timetable navigation for free without any new handler code.src/modules/page-content-renderer.tsline ~183 — constructsStopViewDependencies. Currently does NOT passonTimetableClick, even thoughContentRendererDependenciesalready has it.{ type: 'timetable', route_id: string, service_id: string, direction_id?: string }. Navigation withoutdirection_idis valid — the timetable page shows all directions.src/utils/entity-display.ts—getServiceDisplay(record)returns{ primary: service_id }.formatDaysOfWeekandformatDateRangeare used inrenderServiceReferenceto show human-readable service context.stop_times.stop_id → trips.trip_id → (route_id, service_id). Deduplicate by${route_id}||${service_id}.Phase 1 — Consolidate data fetching in
StopViewControllergetAgenciesServingStopandgetRoutesServingStopboth independently querystop_timesandtrips. This phase merges them.stop-view-controller.ts:fetchStopRelations(stop_id: string): Promise<StopRelations>method:stop_timesfiltered bystop_idonce → collect uniquetrip_ids.trips(full table) once → filter to thosetrip_ids → collect uniqueroute_ids and unique(route_id, service_id)pairs (deduplicate with aSetkeyed on${route_id}||${service_id}; ignoredirection_id).routesonce → filter to relevantroute_ids → collectagency_ids.agencyonce → filter to relevantagency_ids.{ agencies, routes, timetableKeys }.renderStopView, replace the twoPromise.all([getAgenciesServingStop, getRoutesServingStop])calls with a singlefetchStopRelationscall.getAgenciesServingStopandgetRoutesServingStopmethods.Gotcha:
queryRows('trips')with no filter is the existing pattern — keep it. Virtual table copy-on-read means results are safe to mutate.Phase 2 — Add timetable section and wire navigation
StopViewDependencies, addonTimetableClick: (route_id: string, service_id: string) => void. Nodirection_idparameter (matching the "no direction button" requirement).page-content-renderer.tsat theStopViewControllerconstructor call (~line 183), addonTimetableClick: (route_id, service_id) => dependencies.onTimetableClick(route_id, service_id)to the dependencies object.stop-view-controller.ts, addrenderTimetablesSectionas a private method mirroringServiceViewController.renderTimetablesSection:timetableKeys: TimetableKey[],routes: Routes[], andcalendarByServiceId: Map<string, Record<string, unknown>>.renderServiceReference(calendarOrFallback, { route_id, tripCount: undefined }). OmittripCountunless it's easily available from the Phase 1 data (it's not without an extra scan — leave it out for now).<div class="space-y-4"><h2>Timetables</h2><div class="card ..."><div class="card-body p-4"><div class="space-y-2">…rows…</div></div></div></div>.renderStopView, fetch calendar data for the relevantservice_ids:queryRows('calendar')filtered (or post-filtered) to the service_ids intimetableKeys. BuildcalendarByServiceId: Map<string, Record<string, unknown>>from this. Also fetchedcalendar_datesfor exception-only services.renderTimetablesSectionfromrenderStopViewand include its output in the returned HTML, after the stop properties and in place ofrenderTransitNetwork.renderServiceReferenceandSERVICE_REF_ROWfromentity-references.tsinstop-view-controller.ts.renderTransitNetwork,renderRouteCard, and the "Transit Network" heading entirely. Also remove the now-unusedonAgencyClick,onRouteClick, agency buttons, and route-card-mini event listeners fromaddEventListeners.Navigation works via existing
SERVICE_REF_ROWdelegation inpage-content-renderer.ts(~line 711) — no new click handler needed inStopViewController.calendar_dateswas also fetched so exception-only services show a date range.Gotcha:
renderServiceReferenceusesSERVICE_REF_ROWwhich is already handled by thepage-content-rendererevent listener at line 711. No new click handler is needed inStopViewController.addEventListenersfor the timetable rows — the existing delegation covers it. Only the delete button needs its own handler.Gotcha: After removing
onAgencyClickandonRouteClickfromStopViewDependencies, remove them from the dependency object inpage-content-renderer.tsconstructor to avoid a TypeScript error (or keep them if they're still used elsewhere on the stop page for some reason).Gotcha:
calendarDates(exceptions) is an optional param torenderServiceReference— fetch calendar_dates rows as well if you want the date range to show for exception-only services. Can do in Phase 2 or defer.Original Issue