Skip to content

Migrate Kubernetes dashboard to PageLayout#2347

Merged
kodiakhq[bot] merged 6 commits into
mainfrom
page-migrate-kubernetes
May 28, 2026
Merged

Migrate Kubernetes dashboard to PageLayout#2347
kodiakhq[bot] merged 6 commits into
mainfrom
page-migrate-kubernetes

Conversation

@elizabetdev
Copy link
Copy Markdown
Contributor

Summary

  • Wraps the Kubernetes dashboard in PageLayout with breadcrumbs and controls in the sticky header (log + metric sources, time range, refresh).
  • Preserves the browser tab title (Kubernetes Dashboard – {brandName}) that was added in feat: Minor dashboard improvements #2302.

Recreated from #2285 now that the base PageLayout/PageHeader work has landed on main. The cherry-pick conflicted with #2302 (which added the <Head> tab title); resolution keeps the new tab title inside the PageLayout content.

Test plan

  • Kubernetes dashboard loads; tabs and charts work
  • Breadcrumbs and filters behave as before
  • Browser tab title still reads "Kubernetes Dashboard – "

Made with Cursor

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 27, 2026

🦋 Changeset detected

Latest commit: 0f145fe

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 3 packages
Name Type
@hyperdx/app Patch
@hyperdx/api Patch
@hyperdx/otel-collector Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel
Copy link
Copy Markdown

vercel Bot commented May 27, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
hyperdx-oss Ready Ready Preview, Comment May 28, 2026 4:47pm
hyperdx-storybook Error Error May 28, 2026 4:47pm

Request Review

@github-actions github-actions Bot added the review/tier-3 Standard — full human review required label May 27, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 27, 2026

🔵 Tier 2 — Low Risk

Small, isolated change with no API route or data model modifications.

Why this tier:

  • Standard feature/fix — introduces new logic or modifies core functionality

Review process: AI review + quick human skim (target: 5–15 min). Reviewer validates AI assessment and checks for domain-specific concerns.
SLA: Resolve within 4 business hours.

Stats
  • Production files changed: 3
  • Production lines changed: 214 (+ 19 in test files, excluded from tier calculation)
  • Branch: page-migrate-kubernetes
  • Author: elizabetdev

To override this classification, remove the review/tier-2 label and apply a different review/tier-* label. Manual overrides are preserved on subsequent pushes.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 27, 2026

Deep Review

This is a small, contained UI refactor: KubernetesDashboardPage swaps a bare <Box> for the shared <PageLayout> with breadcrumbs / leading / actions slots, drops the duplicate <Text size="xl">Kubernetes Dashboard</Text> heading, preserves the <Head> tab title inside the new content fragment, and updates the e2e smoke test to assert on data-testid="kubernetes-dashboard-page" (forwarded by PageLayout to its root <div>). The remaining changes are JSDoc-only edits to PageHeader / PageLayout documenting two composition forms (structured slots vs. custom children / header escape hatch). Hooks order, side-panel portals, next/head hoisting, and the /dashboards/list route were all spot-checked and remain correct.

🟡 P2 -- recommended

  • packages/app/tests/e2e/features/kubernetes.spec.ts:13 -- Swapping k8sPage.title (getByText('Kubernetes Dashboard')) for k8sPage.pageContainer (getByTestId('kubernetes-dashboard-page')) weakens the smoke test: PageLayout renders that wrapper <div> unconditionally before any K8s content paints, so the assertion passes even if dashboardBody throws or <Head> is silently dropped.
    • Fix: Add a second assertion against content that requires the page to render successfully, e.g. await expect(k8sPage.page.getByText('Dashboards')).toBeVisible() for the breadcrumb or await expect(k8sPage.page).toHaveTitle(/Kubernetes Dashboard/) to also guard the preserved tab title.
    • testing, adversarial
🔵 P3 nitpicks (2)
  • packages/app/src/components/PageLayout.tsx:17 -- The new JSDoc cites AlertsPage, DashboardsListPage, and SavedSearchesListPage as title-only PageLayout examples, but at HEAD those pages render <PageHeader title="..."/> directly without any <PageLayout> wrapper, so a reader following the doc will copy the wrong pattern or stop trusting the citation list.

    • Fix: Replace those three names in PageLayout.tsx with pages that actually wrap in PageLayout (the DBServiceMapPage and KubernetesDashboardPage examples already cited cover the structured-slot story), or rephrase them as bare-PageHeader examples.
    • correctness, maintainability, adversarial
  • packages/app/src/components/PageLayout.tsx:29 -- PageLayoutProps Picks 'children' from PageHeaderProps, so <PageLayout>body</PageLayout> silently routes the body into the internal <PageHeader> rather than the content slot; this PR added composition-form JSDoc to both files but did not call out that footgun.

    • Fix: Add a short note on the children key (or the type block) clarifying that JSX children are forwarded into the internal PageHeader and that page bodies must use the content prop.

Reviewers (6): correctness, testing, maintainability, project-standards, kieran-typescript, adversarial.

Testing gaps:

  • No assertion that the <Head> block still resolves the tab title to Kubernetes Dashboard – {brandName} after the migration moved it deeper into the tree.
  • No coverage of the new Dashboards / Kubernetes breadcrumb (rendered text or anchor navigation to /dashboards/list).

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 27, 2026

E2E Test Results

All tests passed • 191 passed • 3 skipped • 1287s

Status Count
✅ Passed 191
❌ Failed 0
⚠️ Flaky 4
⏭️ Skipped 3

Tests ran across 4 shards in parallel.

View full report →

Sticky header includes breadcrumbs, log/metric sources, and time controls
without a duplicate page title.

Co-authored-by: Cursor <cursoragent@cursor.com>
The PageLayout migration intentionally dropped the visible
`<Text size="xl">Kubernetes Dashboard</Text>` heading — the
`Dashboards / Kubernetes` breadcrumb is the new identifier
(see `PageHeader` docs: "omit `title` when the toolbar has
inputs"). The remaining occurrence of "Kubernetes Dashboard"
lives inside `<Head><title>`, which `page.getByText` cannot match.

That left the `should load kubernetes dashboard` smoke test
asserting on an empty locator. Update the page object to follow
the existing convention — every other page object exposes
`pageContainer = page.getByTestId('<page>-page')` (see
`SavedSearchesListPage`, `DashboardsListPage`, `TeamPage`,
`ClickHouseDashboardPage`, etc.) — and assert on that testid,
which `<PageLayout>` already renders on the page root.

Also drop the now-unused `dashboardTitle` field and `title`
getter so the page object's surface matches its actual locators.
…ageHeader composition forms

Two follow-up cleanups on the PageLayout migration:

P2 — Extract `dashboardBody`.

The ~380-line inline `content={<>...</>}` fragment in
`KubernetesDashboardPage` added three indentation levels to the
already-deeply-nested tab / chart JSX, forcing the
`convertV1ChartConfigToV2({...})` config objects to wrap further than
necessary. The author already extracted `headerLeading`, `headerActions`,
and `pageBreadcrumbs` into local consts; the body deserved the same
treatment. The render now reads as a small `return (<PageLayout ...
content={dashboardBody} />)` with all four header / body fragments
declared above. Prettier reformatted the body to the new indentation;
the diff looks larger than the semantic change.

P3 — Document the two valid composition forms.

`PageLayout` accepts both structured slots (`title` / `leading` /
`actions` / `breadcrumbs`, used by `KubernetesDashboardPage`) and a
custom `header` prop (used by `SessionsPage` for its full-width
source / search / time / Run row, which doesn't split cleanly into
leading + actions). Both are valid, but with only two consumers so
far it's worth picking a canonical form before more pages migrate.

Strengthened the JSDoc on `PageLayoutProps`, `PageHeaderProps`,
`children`, and `header` to:

- spell out the two forms in order of preference (structured slots
  first, custom `header` / `children` as the escape hatch),
- cite the concrete pages that exemplify each form,
- explain the criterion for reaching for the escape hatch (the
  toolbar can't be expressed as leading + actions, e.g. a single
  full-width Group with a search input that grows to 50% width).

No code-level changes to `SessionsPage` — its layout genuinely doesn't
fit the structured slots, so forcing a refactor would be worse than
the documented escape hatch.
@github-actions github-actions Bot added review/tier-2 Low risk — AI review + quick human skim and removed review/tier-3 Standard — full human review required labels May 28, 2026
Main now contains two additional structured-slot users:
- AlertsPage / DashboardsListPage / SavedSearchesListPage (#2345) now
  use `<PageHeader title="..." />` instead of the children form.
- DBServiceMapPage (#2346) uses `<PageLayout leading actions />`.

Update PageLayout / PageHeader JSDoc to cite the three concrete slot
shapes (title-only, leading+actions, breadcrumbs+leading+actions) with
the now-canonical examples, so future page migrations have an obvious
reference for which form to pick.
@kodiakhq kodiakhq Bot merged commit 41d6760 into main May 28, 2026
18 of 19 checks passed
@kodiakhq kodiakhq Bot deleted the page-migrate-kubernetes branch May 28, 2026 16:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

automerge review/tier-2 Low risk — AI review + quick human skim

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants