Skip to content

Polish dashboard tile styling and header layout#2592

Draft
elizabetdev wants to merge 3 commits into
mainfrom
elizabet/dashboard-tile-visual-polish
Draft

Polish dashboard tile styling and header layout#2592
elizabetdev wants to merge 3 commits into
mainfrom
elizabet/dashboard-tile-visual-polish

Conversation

@elizabetdev

@elizabetdev elizabetdev commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Summary

A visual-polish pass on dashboards to make tiles read as distinct cards and give groups a cleaner, more consistent layout.

Tiles

  • Card styling: tiles use a bg-body (white in light mode) background with a border, sitting on a recessed "sunken" page background so they read as elevated cards.
  • Compact, consistent header: every tile has a slim header strip with a full-bleed separator (titled or not), reducing empty space and preventing actions from overlapping content.
  • Right-aligned kebab menu: tile actions (duplicate, view fullscreen, edit, delete, move-to-group) are consolidated into a menu rendered as a toolbar suffix, so it sits at the far right after each chart's own controls (display switcher, granularity). The alert affordance stays alongside it and is always visible.
  • Alert affordance: uses IconBellPlus when no alert is configured (reads clearly on the light header) and IconBell + a colored status indicator when an alert exists.
  • Non-muted table tiles: dashboard table tiles use the default (white) table variant so they blend into the card instead of showing a muted panel.
  • Modern resize handle: replaced the default corner bracket with a subtle, hover-revealed dotted triangular grip.

Groups

  • Always-visible controls: the drag handle, add-tile, and overflow controls are always visible in the group header (no longer hover-only).
  • Header / body split: group header uses bg-body; the tile area below uses the sunken background with padding around the nested tiles.
  • Removed redundant tab underline: the group's Mantine tab list no longer draws its default ::before underline, since the group border + header/body color split already separate the tab row from the content (the active-tab indicator is preserved).

Theming

  • Renamed --color-bg-muted-subtle--color-bg-sunken (and .bg-muted-subtle.bg-sunken) with explanatory comments, since the token is a recessed backdrop that sits below bg-body cards rather than a "subtler muted".

Tests

  • Updated dashboard E2E specs/page objects so tile edit/duplicate/delete are exercised through the kebab menu.

Test plan

  • Tiles render as bordered bg-body cards on a sunken page background (light + dark).
  • Tile header is compact and consistent for titled and untitled tiles; separator reaches both card edges.
  • Kebab menu sits at the far right after chart controls; alert bell + all actions (edit/duplicate/delete/fullscreen/move) work.
  • Alert icon shows bell + with no alert and a status dot when an alert exists; both visible on light/dark headers.
  • Table tiles no longer show a muted background.
  • Group controls (drag/add/kebab) are always visible; header is bg-body, tile area is sunken with padding; no underline under the group tabs (active-tab indicator still shows).
  • Resize handle grip appears on hover and resizing still works.
  • E2E: make dev-e2e FILE=dashboard

Give dashboard tiles white surface backgrounds with a border on a subtly
muted page background, a modern dotted resize handle, and a compact,
consistent header. Tile actions are consolidated into a right-aligned kebab
menu (alongside the alert bell) that renders after each chart's own controls,
and a full-bleed separator gives every tile a consistent header strip. Table
tiles now use the default (non-muted) table variant so they blend into the
white card. E2E tests and page objects updated for the kebab menu.

Co-authored-by: Cursor <cursoragent@cursor.com>
@vercel

vercel Bot commented Jul 3, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
hyperdx-oss Ready Ready Preview, Comment Jul 3, 2026 4:51pm
hyperdx-storybook Ready Ready Preview, Comment Jul 3, 2026 4:51pm

Request Review

@changeset-bot

changeset-bot Bot commented Jul 3, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 648ea53

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

@greptile-apps

greptile-apps Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

Visual polish pass on dashboard tiles: tiles become white bg-body cards on a bg-sunken recessed background, tile actions are consolidated into a right-aligned kebab menu (with the alert bell alongside), and a new full-bleed card header gives every tile a consistent separator strip.

  • Kebab menu refactor (DBDashboardPage.tsx): individual edit/duplicate/delete/fullscreen ActionIcon buttons are replaced by a single IconDotsVertical Menu; the toolbar is split into toolbarPrefixItems / toolbarSuffixItems so chart-specific controls stay between them. A ChartContainerCardHeaderProvider context (React 19 use()) switches ChartContainer into card-header mode only for the outermost container under a tile, with an automatic context reset to prevent nested containers from inheriting the style.
  • New CSS token + utilities (_tokens.scss, _utilities.scss): --color-bg-sunken added for both HyperDX and Clickstack themes (dark and light variants); .bg-sunken utility class exposed. Resize handle replaced with a radial-gradient dotted-triangle grip revealed on hover.
  • E2E test updates: DashboardPage.ts gains openTileActionsMenu() and all helpers (editTile, duplicateTile, deleteTile, openFullscreenForTile) delegate through it; spec files updated to open the kebab menu before asserting on menu items.

Confidence Score: 5/5

Safe to merge — changes are purely visual/structural with no data-path or auth-path impact.

All logic changes (kebab menu consolidation, context-based card header, new CSS tokens) are self-contained within the dashboard tile rendering path. The React 19 context API usage is valid given the project is on React ^19.2.3. The hovered state is retained for the tile hover-indicator pill, so nothing is orphaned. E2E helpers are correctly wired through openTileActionsMenu. No data mutations, API calls, or auth checks are modified.

ChartContainer.tsx — the full-bleed negative-margin technique couples HEADER_SPACING to Bootstrap's px-2 value; worth a second glance if spacing tokens are ever customised.

Important Files Changed

Filename Overview
packages/app/src/components/charts/ChartContainer.tsx Adds React 19 context (use() + direct provider syntax) to switch between plain and card-style headers; context is reset inside ChartContainer so nested containers stay in plain mode. Full-bleed negative margin is tightly coupled to Bootstrap px-2/Mantine md spacing values.
packages/app/src/DBDashboardPage.tsx Moves individual tile action buttons (edit/duplicate/delete/fullscreen) into a kebab menu; splits toolbar into prefix/suffix to keep the kebab at the far right after chart controls. The hovered state is correctly retained for the hover-indicator pill. Alert bell now uses IconBellPlus when no alert exists.
packages/app/src/components/DashboardContainer.tsx Removes hover-gated opacity from drag handle, add-tile, and group-menu buttons; adds bg-sunken to group content body; removes the explicit header bottom border in favour of background-colour contrast between header and content.
packages/app/tests/e2e/page-objects/DashboardPage.ts Adds openTileActionsMenu helper and wires editTile/duplicateTile/deleteTile/openFullscreenForTile through it; getTileButton type union unchanged and still safe for all callers.
packages/app/styles/app.scss Replaces the old CSS-border resize handle with a radial-gradient dotted triangle grip revealed on hover; adds scoped rule to hide Mantine Tabs default underline inside .dashboard-group-tabs-list.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Tile renders] --> B[ChartContainerCardHeaderProvider\nsets context = true]
    B --> C[renderChartContent]
    C --> D{Chart type?}
    D -->|Time/Table/Number/Pie/Heatmap| E[Chart component\ne.g. DBTimeChart]
    D -->|Search| F[ChartContainer directly\ntoolbarItems = toolbar]
    E --> G[ChartContainer\ncardHeader = true from context]
    F --> G
    G --> H[Resets context to false\nfor nested containers]
    H --> I{showHeader?}
    I -->|title or toolbarItems| J[Card-style header\nfull-bleed separator\nkebab menu on right]
    I -->|neither| K[No header rendered]
    J --> L[Chart content]
    K --> L
    M[Fullscreen modal portal] --> N[renderChartContent\noutside Provider]
    N --> O[ChartContainer\ncardHeader = false default]
    O --> P[Plain inline header\nno separator]
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
    A[Tile renders] --> B[ChartContainerCardHeaderProvider\nsets context = true]
    B --> C[renderChartContent]
    C --> D{Chart type?}
    D -->|Time/Table/Number/Pie/Heatmap| E[Chart component\ne.g. DBTimeChart]
    D -->|Search| F[ChartContainer directly\ntoolbarItems = toolbar]
    E --> G[ChartContainer\ncardHeader = true from context]
    F --> G
    G --> H[Resets context to false\nfor nested containers]
    H --> I{showHeader?}
    I -->|title or toolbarItems| J[Card-style header\nfull-bleed separator\nkebab menu on right]
    I -->|neither| K[No header rendered]
    J --> L[Chart content]
    K --> L
    M[Fullscreen modal portal] --> N[renderChartContent\noutside Provider]
    N --> O[ChartContainer\ncardHeader = false default]
    O --> P[Plain inline header\nno separator]
Loading

Reviews (3): Last reviewed commit: "test(app): update dashboard E2E for keba..." | Re-trigger Greptile

Comment on lines +595 to +601
async openTileActionsMenu(tileIndex: number) {
await this.hoverOverTile(tileIndex);
await this.page
.locator('[data-testid^="tile-actions-button-"]')
.nth(tileIndex)
.click();
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Unnecessary hover step in openTileActionsMenu

The hoverOverTile call is a leftover from when the kebab button was only revealed on hover (visibility: hidden toggled by hovered state). Now that the actions button is always visible in the DOM (the visibility guard was removed from hoverToolbar), the hover step adds latency to every call to editTile, duplicateTile, deleteTile, and openFullscreenForTile without serving any functional purpose.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Fix in Claude Code Fix in Conductor Fix in Cursor Fix in Codex

@github-actions

github-actions Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

E2E Test Results

All tests passed • 225 passed • 3 skipped • 1483s

Status Count
✅ Passed 225
❌ Failed 0
⚠️ Flaky 2
⏭️ Skipped 3

Tests ran across 4 shards in parallel.

View full report →

…oken

- Move tile actions into a right-aligned kebab (after chart controls) and
  slim the tile header height.
- Use IconBellPlus for the "add alert" affordance instead of an overlaid
  "+" badge that was invisible on the light header.
- Group headers: always-visible drag/add/kebab controls, bg-body header with
  a sunken (recessed) tile-area body and padding around nested tiles.
- Remove the redundant Mantine tab-list underline on dashboard group tabs.
- Rename --color-bg-muted-subtle -> --color-bg-sunken (and .bg-sunken) with
  explanatory comments, since it's a recessed backdrop behind bg-body cards.

Co-authored-by: Cursor <cursoragent@cursor.com>
Tile edit/duplicate/delete moved into the actions (kebab) menu, so the
"verify tile interactions" steps now open the menu before asserting those
items are visible, while the alert bell is checked directly in the header.

Co-authored-by: Cursor <cursoragent@cursor.com>
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