Skip to content

Add diagnostics_agg topic support with tab UI, filters, and export#1

Merged
Tiryoh merged 4 commits intomainfrom
feature/diagnostics-support
Feb 28, 2026
Merged

Add diagnostics_agg topic support with tab UI, filters, and export#1
Tiryoh merged 4 commits intomainfrom
feature/diagnostics-support

Conversation

@Tiryoh
Copy link
Copy Markdown
Owner

@Tiryoh Tiryoh commented Feb 27, 2026

Summary

  • Add support for parsing and displaying /diagnostics and /diagnostics_agg topics (diagnostic_msgs/DiagnosticArray)
    from rosbag files
  • Show rosout / diagnostics tab switcher only when diagnostics topics exist in the bag
  • Record and display only state-change entries (when level or message changes for a given name)
  • Expand rows on click to reveal key-value pairs
  • Add filters for diagnostics tab (level, name, keywords/regex, OR/AND mode)
  • Export (CSV/JSON/TXT) independently per tab
  • Add configurable preview row limit (100/500/1000) for both tabs

Test plan

  • Tabs appear when bag contains diagnostics_agg topics
  • No tabs shown when bag has no diagnostics topics (same look as before)
  • Only state changes are recorded in diagnostics view
  • Row click expands/collapses key-value pairs
  • Diagnostics filters (level, name, keywords) work correctly
  • Rosout and diagnostics export independently
  • Preview row limit switcher works on both tabs

🤖 Generated with Claude Code

- Parse /diagnostics and /diagnostics_agg topics (diagnostic_msgs/DiagnosticArray)
- Display diagnostics as state changes (only when level or message changes)
- Add tab switching between rosout and diagnostics views
- Add diagnostics filters (level, name, keywords/regex, OR/AND mode)
- Add diagnostics export (CSV/JSON/TXT) separate from rosout
- Add configurable preview limit (100/500/1000 rows) for both tabs
- Row click expands to show key-value pairs
- Update title and description to reflect diagnostics support

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds first-class support for ROS diagnostics topics (/diagnostics, /diagnostics_agg) alongside rosout, including a tabbed UI, filtering, expandable key/value details, and per-tab export.

Changes:

  • Extend rosbag parsing to detect/load diagnostic_msgs/DiagnosticArray and record only per-name state changes.
  • Add diagnostics tab UI (shown only when diagnostics topics exist) with level/name/keyword-or-regex filters and expandable rows.
  • Add per-tab export (CSV/JSON/TXT) and configurable preview row limit for both tables.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.

File Description
src/types.ts Introduces diagnostics entry type and level name/color mappings for UI.
src/rosbagUtils.ts Loads diagnostics messages from bag files and adds diagnostics export functions.
src/App.tsx Adds diagnostics tab UI, filters, row expansion, preview limit, and per-tab export wiring.
index.html Updates page title to reflect diagnostics support.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/App.tsx
Comment thread src/App.tsx
Comment thread src/rosbagUtils.ts Outdated
Comment thread src/rosbagUtils.ts Outdated
Tiryoh and others added 3 commits February 28, 2026 16:23
- Reset expandedDiagRows on Clear Filters to prevent stale expansion state
- Add key to Fragment in diagnostics table map to fix React key warning
- Update error message to reflect actual topic detection logic
- Remove duplicate DIAGNOSTIC_LEVEL_NAMES, import from types.ts instead

Co-Authored-By: Claude Opus 4.6 <[email protected]>
@Tiryoh Tiryoh merged commit f31a634 into main Feb 28, 2026
1 check passed
@Tiryoh Tiryoh deleted the feature/diagnostics-support branch February 28, 2026 17:29
Tiryoh added a commit that referenced this pull request Apr 15, 2026
Long path-like values in diagnostic details (e.g.
`/auto_stop/slow_down_mid/brake_trigger`) were rendered outside the
grid item's box and visually overlapped the next key:value pair, a bug
that has existed since diagnostics support was first introduced in #1.

Add `min-w-0` + `shrink-0` + `break-all` so long values wrap within
their column, and add an e2e test that injects a realistic long value
into the DOM and asserts `scrollWidth <= clientWidth` on each grid
item, which is the exact invariant the fix preserves.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Tiryoh added a commit that referenced this pull request Apr 16, 2026
* Add UTF-8 BOM to CSV exports and add export output tests

CSV exports lacked UTF-8 BOM, causing LibreOffice to misdetect encoding
as Shift-JIS for Japanese text. Also adds comprehensive unit tests for
all CSV/JSON/TXT export functions and E2E tests verifying downloaded
file content including BOM presence.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

* Fix diagnostics detail value overflow and add overlap regression test

Long path-like values in diagnostic details (e.g.
`/auto_stop/slow_down_mid/brake_trigger`) were rendered outside the
grid item's box and visually overlapped the next key:value pair, a bug
that has existed since diagnostics support was first introduced in #1.

Add `min-w-0` + `shrink-0` + `break-all` so long values wrap within
their column, and add an e2e test that injects a realistic long value
into the DOM and asserts `scrollWidth <= clientWidth` on each grid
item, which is the exact invariant the fix preserves.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

* Address Copilot PR feedback: CR in CSV quoting and explicit BOM stripping

- `escapeCSV` now also quotes values containing `\r`, so fields with
  Windows CRLF (plausible in ROS log messages) produce RFC 4180-valid
  output. Add unit tests for both lone `\r` and `\r\n`.
- Export-content E2E tests now use a `stripBomAndSplitLines` helper that
  explicitly removes a leading `\uFEFF` and splits on `/\r?\n/`, rather
  than relying on `String.prototype.trim()` to incidentally drop the BOM
  (which also strips meaningful whitespace).

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

* Expand diagnostics fixture to cover 1/3/4-value and long-value cases

The test_sample.bag diagnostics previously had mostly 2-value entries,
which didn't exercise the real-world shape of diagnostic messages or
the overflow condition the recent UI fix targets.

- @0.0 /sensor/lidar OK: 2 → 4 values (full lg:grid-cols-4 row)
- @2.0 /sensor/lidar ERROR: 2 → 3 values, with one realistic long
  path-like value (`last_heartbeat_source`) that reproduces the
  grid-cell overflow case
- @3.0 /sensor/lidar STALE: 1 value (unchanged; kept as single-value case)
- WARN entries at @1.0 /sensor/camera and @3.0 /motor/left left
  untouched — they are pinned byte-for-byte by the parquet export test

Regenerated test_sample.bag via the existing ros:noetic-ros-base Docker
recipe in the script's docstring. All 104 e2e tests still pass.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

* Sync mcap fixture diag_data with bag fixture

The mcap generator had a comment saying "Same data as
generate_test_bag.py for consistency" but the diag_data was stale
after the previous commit expanded the bag fixture to cover 1/3/4-value
and long-value cases.

Apply the same diag_data changes and regenerate test_sample.mcap,
test_sample.mcap.zstd, and test_sample_truncated.mcap via the existing
Dockerfile.mcap recipe. All 104 e2e tests pass.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

* Use full-width row for long diagnostic key-value pairs

Long values like `/rover/sensors/lidar_front_driver/heartbeat_monitor_node`
were being crammed into a narrow grid column with `break-all`, splitting
the path at every character boundary and making it very hard to read.

Now key-value pairs whose combined length exceeds 40 characters get
`col-span-full`, so they take an entire grid row and the value stays
readable without forced character-level breaks. Also switch from
`break-all` to `break-words` — only breaks when the value actually
overflows, producing more natural wrap points.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

* Address Copilot feedback: update stale comments and strengthen CSV level assertion

- Update e2e test comments to reflect current implementation
  (`break-words` + `col-span-full`, not `break-all`; fixture now
  includes long values)
- Strengthen `exportDiagnosticsToCSV` level-name test to assert on the
  Level column (index 3) specifically via `split(',')[3]` instead of
  `toContain()` on the full line, which could match 'OK' in the
  message field ('OK running')
- Update PR description to match the current approach

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <[email protected]>
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.

2 participants