Skip to content

dashboard: 6 UI/UX fixes (status colors, stat refresh, action transition, mobile, loader)#845

Merged
DorianZheng merged 1 commit into
mainfrom
codex/dashboard-ui-fixes
Jun 25, 2026
Merged

dashboard: 6 UI/UX fixes (status colors, stat refresh, action transition, mobile, loader)#845
DorianZheng merged 1 commit into
mainfrom
codex/dashboard-ui-fixes

Conversation

@law-chain-hot

@law-chain-hot law-chain-hot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Six frontend UI/UX fixes on top of the restyle branch (stacked on #840 / codex/pr829-uiux-mobile, so this PR shows only these fixes). Frontend-only.

  1. Status colorsSTOPPED is now grey (parked) instead of sharing ERROR's red; the two statuses are no longer visually identical (BoxTable + BoxDetails).
  2. Header padding — slightly wider left/right padding.
  3. Stat-count freshness — the Total / Running / Stopped cards now refresh on box events + lifecycle actions. A socket push (box.state.updated etc.) already existed and refreshed the list, but the ['boxesCount'] queries weren't included in the invalidation, so the cards went stale after an action. Now wired in (no polling added).
  4. Action button transition — clicking a row/detail action no longer makes the button vanish; the transitioning state shows a spinner in place.
  5. Mobile stat cards — compact on small screens so the box list gets more vertical room.
  6. Loading screen — terminal/pixel-style boot screen (logo + animated booting console… ellipsis) to match the console aesthetic, replacing the generic skeleton.

Verification: dashboard build + lint + vitest pass; manually exercised on start:mock.

Summary by CodeRabbit

  • New Features

    • Added a visible “Working…” state with a spinner when a box is transitioning.
    • Updated loading screens with a new terminal-style booting experience.
    • Improved status cards with a cleaner mobile layout and synchronized fleet counts.
  • Bug Fixes

    • Box error states now show the correct error color and styling.
    • Status indicators and action buttons now better reflect in-progress box changes.
  • Style

    • Refreshed sidebar spacing and loading/card visuals for a more polished interface.

@law-chain-hot law-chain-hot requested a review from a team as a code owner June 25, 2026 03:22
@coderabbitai

coderabbitai Bot commented Jun 25, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Box status displays now use updated error and dim colors, show a disabled working state during transitions, and the dashboard loading, sidebar, and boxes stat cards have updated layout and refresh behavior.

Changes

Box state UI updates

Layer / File(s) Summary
Status colors and error mapping
apps/dashboard/src/components/BoxTable/index.tsx, apps/dashboard/src/components/boxes/BoxDetails.tsx
STATUS color values and BoxState.ERROR rendering use the updated error and dim colors, and the error reason text in BoxDetails uses STATUS.error.
Transitioning working actions
apps/dashboard/src/components/BoxTable/index.tsx, apps/dashboard/src/components/boxes/BoxDetails.tsx
Both box views detect transitioning boxes and render a disabled “Working…” button with a spinning Loader2 when no normal action applies.

Dashboard shell and stats presentation

Layer / File(s) Summary
Loading screen and sidebar spacing
apps/dashboard/src/components/LoadingFallback.tsx, apps/dashboard/src/components/Sidebar.tsx
The loading fallback renders a terminal-style boot screen with a revised long-loading message, and the sidebar increases horizontal padding on its main controls.
Boxes stats refresh and card layout
apps/dashboard/src/pages/Boxes.tsx
Box updates now also invalidate ['boxesCount'], and the stat-card grid and card structure use a new three-column layout with responsive value rendering.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • boxlite-ai/boxlite#729: Updates isTransitioning handling, which directly affects the new “Working…” transition state in the box action renderers.

Suggested reviewers

  • DorianZheng

Poem

🐇 I hopped through boxes, bright and slow,
While tiny dots and status colors glow.
The dashboard boots with terminal flair,
And working boxes spin with care.
Three stat cards wink; the rabbit grins—
Another tidy dashboard wins!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 14.29% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main dashboard UI fixes, including status colors, stat refresh, transition actions, mobile layout, and loader changes.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/dashboard-ui-fixes

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install failed: dependency version conflict. Check your lock file or package.json.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

…efresh, action transition, mobile stats, terminal loader

- stopped vs error: ERROR gets its own red (STATUS.error); stopped is now grey, no longer identical to error. (BoxTable + BoxDetails)
- header: more L/R padding on the top bar edge cells.
- stat counts refresh on every box change: markAllBoxQueriesAsStale now also invalidates the ['boxesCount'] queries (separate key), so cards stay in sync via the existing socket/action invalidation.
- action button no longer vanishes mid-transition: a disabled spinner placeholder fills the slot during starting/stopping. (table rows + detail strip)
- mobile stat cards collapse to a compact 3-up row (was 3 stacked), reclaiming list space.
- LoadingFallback restyled to a terminal 'booting console' screen to match the console aesthetic.
@law-chain-hot law-chain-hot force-pushed the codex/dashboard-ui-fixes branch from 79a5c68 to 4bc0e4c Compare June 25, 2026 03:26
@law-chain-hot law-chain-hot changed the base branch from codex/pr829-uiux-mobile to main June 25, 2026 03:26

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/dashboard/src/pages/Boxes.tsx (1)

884-911: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Stat value is invisible to screen readers on desktop.

On sm+, the numeric value is rendered only as the visual DotMatrix (the text value at Line 900 is sm:hiddendisplay:none, removed from the a11y tree). Screen-reader users get the label and sub but not the count. Add an sr-only text value (or aria-label) on the desktop block.

♿ Proposed fix
       {/* desktop: dot-matrix value + sub label */}
-      <div className="hidden items-end gap-[10px] sm:flex">
+      <div className="hidden items-end gap-[10px] sm:flex">
+        <span className="sr-only">{value}</span>
         {isNumeric(value) ? (
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/dashboard/src/pages/Boxes.tsx` around lines 884 - 911, The desktop stat
block in Boxes is hiding the numeric value from assistive tech because the
visible DotMatrix is not readable and the mobile text is sm:hidden. Update the
desktop rendering path in the stat card component so the value is exposed to
screen readers, either by adding an sr-only text node or an aria-label on the
container that includes the value. Use the existing DotMatrix and isNumeric
branches as the place to attach the accessible text without changing the visual
layout.
🧹 Nitpick comments (2)
apps/dashboard/src/components/BoxTable/index.tsx (1)

151-155: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Working-state spinner icon differs from BoxDetails.

This transitioning action uses Loader2, while the equivalent disabled “working…” button in apps/dashboard/src/components/boxes/BoxDetails.tsx (Line 365) uses RefreshCw. Both spin, but aligning on a single icon keeps the transition affordance visually consistent across the table and detail views. The logic and disabled handling here are otherwise correct.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/dashboard/src/components/BoxTable/index.tsx` around lines 151 - 155, The
working-state button in BoxTable uses a different spinner icon than the matching
disabled “working…” state in BoxDetails, so align the transition affordance for
consistency. Update the transitioning branch in BoxTable’s render logic to use
the same icon as the BoxDetails working-state button, while keeping the existing
disabled behavior and conditional checks unchanged.
apps/dashboard/src/pages/Boxes.tsx (1)

205-208: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

['boxesCount'] refetch fires on every socket event — risk of request storms.

markAllBoxQueriesAsStale is invoked per box.state.updated event (Line 306) and per action. Because this invalidation uses refetchType: 'active' unconditionally (ignoring shouldRefetchActiveQueries and staleTime), a bulk start/stop of many boxes will emit many socket pushes, each triggering 3 count refetches. Consider debouncing the count invalidation (or gating it behind shouldRefetchActiveQueries) to coalesce bursts.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/dashboard/src/pages/Boxes.tsx` around lines 205 - 208, The boxes count
invalidation in markAllBoxQueriesAsStale is firing on every action and every
box.state.updated socket event, which can cause request storms. Update the
Boxes.tsx queryClient.invalidateQueries call for ['boxesCount'] to avoid
unconditional refetching; either gate it behind
shouldRefetchActiveQueries/staleTime logic or debounce/coalesce repeated calls
so rapid bursts only trigger one count refresh. Keep the fix localized to the
count-query invalidation path used by markAllBoxQueriesAsStale.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/dashboard/src/components/LoadingFallback.tsx`:
- Around line 24-32: The loading status in LoadingFallback is not exposed to
assistive technologies, so add a live region to the status container that wraps
the boot message and indicator. Update the relevant element in LoadingFallback
to include role="status" and aria-live="polite" so screen readers announce the
loading state and any longer-loading updates.

---

Outside diff comments:
In `@apps/dashboard/src/pages/Boxes.tsx`:
- Around line 884-911: The desktop stat block in Boxes is hiding the numeric
value from assistive tech because the visible DotMatrix is not readable and the
mobile text is sm:hidden. Update the desktop rendering path in the stat card
component so the value is exposed to screen readers, either by adding an sr-only
text node or an aria-label on the container that includes the value. Use the
existing DotMatrix and isNumeric branches as the place to attach the accessible
text without changing the visual layout.

---

Nitpick comments:
In `@apps/dashboard/src/components/BoxTable/index.tsx`:
- Around line 151-155: The working-state button in BoxTable uses a different
spinner icon than the matching disabled “working…” state in BoxDetails, so align
the transition affordance for consistency. Update the transitioning branch in
BoxTable’s render logic to use the same icon as the BoxDetails working-state
button, while keeping the existing disabled behavior and conditional checks
unchanged.

In `@apps/dashboard/src/pages/Boxes.tsx`:
- Around line 205-208: The boxes count invalidation in markAllBoxQueriesAsStale
is firing on every action and every box.state.updated socket event, which can
cause request storms. Update the Boxes.tsx queryClient.invalidateQueries call
for ['boxesCount'] to avoid unconditional refetching; either gate it behind
shouldRefetchActiveQueries/staleTime logic or debounce/coalesce repeated calls
so rapid bursts only trigger one count refresh. Keep the fix localized to the
count-query invalidation path used by markAllBoxQueriesAsStale.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 74c923b9-aea0-4700-8aa9-7fc77439f835

📥 Commits

Reviewing files that changed from the base of the PR and between 1885e1d and 4bc0e4c.

📒 Files selected for processing (5)
  • apps/dashboard/src/components/BoxTable/index.tsx
  • apps/dashboard/src/components/LoadingFallback.tsx
  • apps/dashboard/src/components/Sidebar.tsx
  • apps/dashboard/src/components/boxes/BoxDetails.tsx
  • apps/dashboard/src/pages/Boxes.tsx

Comment thread apps/dashboard/src/components/LoadingFallback.tsx
@DorianZheng DorianZheng merged commit 2d6e362 into main Jun 25, 2026
3 checks passed
@DorianZheng DorianZheng deleted the codex/dashboard-ui-fixes branch June 25, 2026 03:44
DorianZheng pushed a commit that referenced this pull request Jun 25, 2026
…pewriter dots (#847)

Follow-up tweaks after testing #845 (which is now merged).
Frontend-only, 4 files.

- **Boxes table (desktop)**: hide the Created + Resource Quota columns
(still shown on the mobile card).
- **Terminal**: remove the paste button — native Cmd/Ctrl+V already
pastes into the terminal — and drop the now-dead
`pasteIntoTerminalIframe` util.
- **LoadingFallback**: bigger terminal boot screen + typewriter ellipsis
(1→2→3 dots, looping).

Verified: dashboard build + targeted eslint clean.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Updated the loading experience with a typewriter-style “booting
console” ellipsis.
* **UI Improvements**
* Simplified the desktop Boxes table by removing less critical columns
to reduce visual clutter.
* **Behavior Changes**
* Terminal pasting now relies on the browser’s native paste shortcut
(Cmd/Ctrl+V) instead of a separate paste action.
* **UI Improvements**
* Adjusted the Dashboard page height calculations to improve
banner/padding alignment across viewports.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
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