Skip to content

fix(drawer): populate Recent Events and bias toward K8s events (#547)#556

Merged
nadaverell merged 2 commits intomainfrom
fix/547-recent-events
Apr 28, 2026
Merged

fix(drawer): populate Recent Events and bias toward K8s events (#547)#556
nadaverell merged 2 commits intomainfrom
fix/547-recent-events

Conversation

@nadaverell
Copy link
Copy Markdown
Contributor

@nadaverell nadaverell commented Apr 28, 2026

Closes #547.

The Recent Events section in the resource detail drawer was always empty. Three independent bugs combined to cause this — and once they were fixed, K8s events were being drowned out by informer status flips on flapping pods.

What was broken

  1. Kind format mismatch + missing include_managed in useResourceEvents. The hook sent the URL kind ("pods") to a backend that filters by K8s Kind ("Pod"), and didn't pass include_managed=true so Pod/Event/ReplicaSet entries (which IsManaged() flags as managed) got dropped by the default preset.
  2. pluralToKind("pods") returned "PodMetrics" because initNavigationMap let the metrics.k8s.io API resource (also named pods) overwrite the canonical Pod mapping. Fixed to make builtin mappings first-wins. This was a broader bug likely affecting other kind-based lookups in the app too.
  3. The package's WorkloadView never passed an events prop to ResourceRendererDispatch in either drawer or expanded mode — so even with a working query, the data never reached EventsSection. Added resourceFocusedK8sEvents / resourceFocusedUpdates props through the chain.

UX improvement

K8s events and resource updates are now fetched in two separate queries with separate limits (500 vs 50). A flapping resource's high-frequency informer diffs can't starve out the user-meaningful K8s events.

EventsSection shows K8s events by default with a "Show N changes" toggle (with hover tooltip explaining the distinction: changes = field-level diffs to spec/status; K8s events = messages emitted by kubelet/controllers). The drawer for a CrashLooping pod now opens with a clean list of Pulling, Failed, BackOff, Killing, etc. — not 25 lines of ErrImagePull↔ImagePullBackOff flips.

Backend: /api/changes now accepts a sources= query param. The filter already existed in pkg/timeline.QueryOptions — just wasn't exposed.

Also removes web/src/components/shared/ResourceRendererDispatch.tsx, a wrapper nothing imported.


Note

Medium Risk
Touches both backend timeline querying (/api/changes) and frontend event-fetch/rendering logic; behavior changes are scoped but could affect event visibility and API consumers if the new sources filter is misused.

Overview
Fixes the resource drawer’s Recent Events so it reliably populates and defaults to user-meaningful K8s events.

Backend /api/changes now accepts a sources= query param (validated against informer, k8s_event, historical) to filter timeline results by origin.

Frontend splits resource-focused fetching into two queries (k8s_event with a high limit vs informer/historical with a low limit), passes both streams (and per-stream errors) through WorkloadViewResourceRendererDispatch, and updates EventsSection to show K8s events by default with a toggle to include high-volume “changes.”

Also hardens navigation kind mapping so builtin plural→kind mappings are first-wins (avoiding collisions like pods vs PodMetrics), and removes an unused web wrapper ResourceRendererDispatch component.

Reviewed by Cursor Bugbot for commit 5c3484d. Bugbot is set up for automated code reviews on this repo. Configure here.

#547)

The Recent Events section in the resource detail drawer was always empty.
Three independent bugs combined to cause this; once they were fixed, a
fourth UX issue was addressed: K8s events were being drowned out by
high-frequency informer status flips on flapping resources.

Root causes fixed:

1. useResourceEvents queried /api/changes with kind="pods" (URL form), but
   the timeline store keys events by K8s Kind ("Pod") and did not pass
   include_managed=true, so the default preset's IsManaged() filter dropped
   Pod/Event/ReplicaSet entries entirely.
2. pluralToKind("pods") was returning "PodMetrics" because initNavigationMap
   let the metrics.k8s.io API resource (also named "pods") overwrite the
   canonical Pod mapping. Fixed to be first-wins for builtins. This was a
   broader bug that likely affected other kind-based lookups too.
3. The package's WorkloadView never plumbed the events array into
   ResourceRendererDispatch (in either drawer or expanded mode), so even a
   correct query never reached EventsSection. Added resourceFocusedK8sEvents
   and resourceFocusedUpdates props through the chain.

UX improvements on top:

- K8s events and informer/historical updates are now fetched in two separate
  React Query calls with separate limits (500 vs 50). On a flapping pod the
  k8s_event stream cannot be starved out by an unbounded update stream.
- EventsSection shows K8s events by default with a "Show N changes" toggle
  to fold in resource updates, with a tooltip explaining the distinction.
  Default is K8s-only because for most users those are the actionable
  signals (Pulling, Failed, BackOff, Killing, etc.).
- Backend /api/changes now accepts a sources= query param (already supported
  internally by the timeline store, just wasn't exposed).

Also removes web/src/components/shared/ResourceRendererDispatch.tsx, a
wrapper that nothing imported.
@nadaverell nadaverell requested a review from hisco as a code owner April 28, 2026 12:01
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit a268420. Configure here.

Comment thread internal/server/server.go
- useResourceEvents now returns k8sError/updatesError; EventsSection
  renders them inline so a partial query failure doesn't render as
  "no events" (same silent-failure class as the original #547 bug).
- /api/changes rejects invalid sources= values with 400 instead of
  silently returning [] (typos like "k8sevent" looked like empty).
- ResourceRendererDispatch: events?: any[] -> TimelineEvent[]; same
  for updates. No reason for any[] now that TimelineEvent is in scope.
- Add initNavigationMap regression test for the metrics.k8s.io/Pod
  collision — easy to "clean up" the first-wins guard without realizing.
- Trim a few JSDoc/inline comments that narrated WHAT or referenced
  the calling site.
@nadaverell nadaverell merged commit 88bd1e9 into main Apr 28, 2026
7 checks passed
@nadaverell nadaverell deleted the fix/547-recent-events branch April 28, 2026 12:43
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.

Show events associated with an object in the preview/details panel

1 participant