Skip to content

feat(ui): table pagination visibility and map date filter node retention - #125

Open
joroses wants to merge 9 commits into
zenitraM:mainfrom
joroses:pr4-ui-map-filters
Open

joroses wants to merge 9 commits into
zenitraM:mainfrom
joroses:pr4-ui-map-filters

Conversation

@joroses

@joroses joroses commented Sep 13, 2026

Copy link
Copy Markdown
Contributor

Summary (PR 4: UI Pagination Visibility & Map Date Filter Retention)

Provides frontend layout and map filtering improvements to ensure table navigation controls remain visible across viewport heights and actively transmitting nodes remain displayed when applying date or age filters.

PR Stack Context:
This is PR 4 of 4 in the traceroute performance & network analysis series:

  1. PR 1 (#122): Storage Layer & Backfill CLI (traceroute_routes & traceroute_hops) — Prerequisite / Merged first
  2. PR 2 (#123): Materialized Traceroute Readers — Switches all views & endpoints to SQL queries
  3. PR 3 (#124): Discard Bogus Near-Zero GPS Coordinates (Null Island) — Sanitizes firmware GPS anomalies
  4. PR 4 (This PR): UI Pagination Visibility & Map Date Filter Retention

Key Changes

  1. Table Pagination Visibility (table_layout_macros.html, traceroute.html):

    • Applies flexbox constraints (min-height: 0, overflow: auto) to .table-content and .table-wrapper.
    • Compacts .table-status-bar so pagination controls are never pushed below the browser viewport on smaller screens or mobile layouts.
  2. Consolidated Node Activity Timestamps (location_service.py):

    • Nodes previously disappeared from the map when applying date or age filters if their last GPS broadcast was outside the window, even if they had routed packets or traceroutes minutes ago.
    • LocationService.get_node_locations() now determines active presence across the latest timestamp among position reports, direct packet links, and traceroute hops while preserving the original GPS fix timestamp.
  3. Map Ghost Links Cleanup (map.html):

    • Ensures stale connection lines are wiped when filter changes result in zero matching RF links.
  4. Exact Time-Window Link Scoping (api_routes.py, map.html):

    • /api/locations accepts start_time/end_time (epoch seconds) or hours/max_age_hours and computes traceroute-hop and direct-packet link aggregates over exactly that window instead of defaulting to a hardcoded 14-day span.

Commits

  • a290230 (Ensure table pagination remains visible in full-screen layouts):
    • Constrains full-screen table containers with flexbox rules and compact status banners so pagination controls are not pushed outside the browser viewport on smaller screens.
  • cd17634 (Keep nodes visible when filtering by date and clean up leftover map lines):
    • Retains active nodes on the map during date/age filtering based on recent traceroutes or direct packets.
    • Cleans up stale connection lines when filter changes match zero RF links.
    • Adds exact server-side time-window scoping for link metrics in /api/locations.

Verification

  • Automated Tests:
    • tests/unit/test_location_service.py: 3 tests verifying timestamp consolidation across traceroute, packet, and position sources pass 100%.
    • tests/unit/test_api_locations_time_window.py: 9 tests verifying exact time window scoping and parameter handling pass 100%.
    • tests/e2e/test_traceroute_filters_e2e.py::test_traceroute_pagination_visibility: Playwright test confirms pagination controls remain within viewport bounds (passes 100%).
  • Code Quality: ruff check src/ tests/ passes cleanly.

roses added 9 commits September 13, 2026 07:44
…ead of being re-read from raw packets every time a page needs them. Two new tables keep track of each route that has ever been seen and the hops between the two endpoints. This prepares for faster queries in PR2
…async restoration

Track user-edited fields in a Set so async applyURLParameters() does not
overwrite user input in form pickers if typing occurs while parameter
resolution is in flight (e.g. following a timezone toggle or page reload).
…hop tables instead of parsing thousands of raw packets on every request. Link analysis between nodes, related node lists, the hop picker, and the main traceroute table now query the database directly with fast filtering and pagination. This removes the old packet caps so busy networks can analyze full multi-day windows without missing data, and updates the table UI to display exact total counts.
…p tables instead of re-decoding raw packets on every page request. The network graph, maps, longest links, route patterns, node statistics, and packet details now query pre-calculated hops and routes, eliminating slow packet loops and repeated database lookups. Also removed obsolete legacy reader code.
…as shorter connected paths. Hop queries now keep the full route structure, and indirect connections and longest-path results are only built from hops that actually link up end to end, so distances, hop counts, and route previews stay correct.
…odes send positions like (0.0001, 0.0002) instead of exactly (0,0), which slipped past the old checks and placed nodes in the middle of the ocean, inflating longest links and paths. Positions near (0,0) or with impossible coordinates are now discarded wherever positions are read; nodes keep showing their last known good position with its original timestamp instead of jumping or disappearing. The capture log now warns when such a position arrives. Note: longest links and paths are still mostly garbage because of other unlikely positions, but this removes the biggest offender.
Constrain full-screen table containers with flexbox rules and compact status
banners so pagination controls are not pushed outside the viewport on
small screens. Add e2e test to verify pagination visibility.
…ines

Nodes on the map used to disappear when using date or age filters because
the system only checked the timestamp of their last GPS broadcast, even if
they were actively routing traceroutes or sending packets minutes ago.

Now, a node is counted as active based on its most recent activity across
traceroutes, direct packets, or position reports, while keeping its known
location on the map. In addition, old connection lines are now always wiped
when filters change, preventing ghost links from lingering on the screen
when no links match the filter.

Link metrics now also honor the selected time window server-side instead of
always aggregating over a hardcoded 14-day/7-day span. /api/locations
accepts start_time/end_time (epoch seconds) or hours/max_age_hours and
computes traceroute-hop and direct-packet aggregates over exactly that
window, so a short selection no longer displays multi-day observation
totals. The map reloads when the age selection or date range changes,
aborting superseded fetches, while fast categorical filters (role, channel,
min contacts) remain client-side. Node position lookups deliberately keep
the wide 14-day window independent of the link window, so an actively
routing node whose last position report is older than the selection stays
visible at its last known good position.
@joroses
joroses marked this pull request as ready for review September 15, 2026 06:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant