fix(ui): redo dashboard page design#1547
Conversation
|
Important Review skippedAuto incremental reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the 📝 WalkthroughWalkthroughThis PR redesigns dashboard and queue UI components, introduces a multi-state animation system for toast notifications, refactors metric presentation from icon-driven to text-based layouts, and refines button depth styling. Changes maintain existing public API signatures while significantly altering visual presentation and component structure across the dashboard interface. Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
ui/src/components/ui/simple-toast.tsx (1)
161-167: Context undefined check is ineffective.The check
context === undefinedwill never be true becauseToastContexthas a default value (line 127-129). When used outsideToastProvider, it returns the default object with a no-opshowToast, silently failing instead of throwing.To properly detect missing provider, use
nullas the default or a separate sentinel:🔎 Proposed fix
-export const ToastContext = React.createContext<ToastContextType>({ - showToast: () => {}, -}); +export const ToastContext = React.createContext<ToastContextType | null>(null); export const useSimpleToast = () => { const context = React.useContext(ToastContext); - if (context === undefined) { + if (context === null) { throw new Error('useSimpleToast must be used within a ToastProvider'); } return context; };Also update
ToastProviderto cast the value:<ToastContext.Provider value={{ showToast }}>
🧹 Nitpick comments (6)
ui/src/components/ui/simple-toast.tsx (2)
64-79: Add accessibility attributes for screen readers.The toast lacks ARIA attributes for accessibility. Per coding guidelines, interactive components should have appropriate ARIA labels. Toast notifications should announce to screen readers.
🔎 Proposed fix
<div + role="status" + aria-live="polite" + aria-label={message} className={` pointer-events-auto flex flex-col items-center justify-center gap-3
138-140: Duration default mismatch.
showToastdefaults to 1500ms (line 138) whileSimpleToastdefaults to 1800ms (line 13). SinceToastProvideralways passes a duration, the 1800ms default is never used. Align these for clarity.🔎 Proposed fix
- const showToast = (message: string, duration = 1500) => { + const showToast = (message: string, duration = 1800) => { setToast({ message, duration, id: Date.now() }); };ui/src/features/queues/components/QueueCard.tsx (1)
197-231: Table structure is clean and accessible.The table uses proper semantic markup (
<thead>,<tbody>,<th>,<td>) with consistent styling. Thetabular-numsclass on numeric columns ensures proper alignment. Consider addingscope="col"to<th>elements for improved screen reader support.🔎 Optional: Add scope attribute for accessibility
-<th className="text-left py-1 px-2 font-medium text-muted-foreground"> +<th scope="col" className="text-left py-1 px-2 font-medium text-muted-foreground"> DAG </th>Apply similarly to other
<th>elements.ui/src/pages/index.tsx (2)
368-385: Date input timezone logic is duplicated.The timezone offset calculation for
startOf('day')andendOf('day')appears both here and in the "Today" button handler (lines 388-396). Consider extracting this into a helper function for consistency and maintainability.🔎 Extract timezone-aware date helpers
// Add near getDefaultDateRange const getStartOfDay = React.useCallback((date: dayjs.Dayjs) => { return config.tzOffsetInSec !== undefined ? date.utcOffset(config.tzOffsetInSec / 60).startOf('day') : date.startOf('day'); }, [config.tzOffsetInSec]); const getEndOfDay = React.useCallback((date: dayjs.Dayjs) => { return config.tzOffsetInSec !== undefined ? date.utcOffset(config.tzOffsetInSec / 60).endOf('day') : date.endOf('day'); }, [config.tzOffsetInSec]); // Then use in handlers: const startOfDay = getStartOfDay(date); const endOfDay = getEndOfDay(date);
356-366: SelectTrigger height should use compact sizing.Per coding guidelines, select boxes should be
h-7or smaller. The currenth-9is slightly larger than recommended. Consider reducing for consistency with the compact design system.🔎 Reduce select trigger height
-<SelectTrigger className="h-9 w-[140px]"> +<SelectTrigger className="h-7 w-[140px]">Also consider adjusting the Input height on line 384:
-className="h-9 w-[150px]" +className="h-7 w-[150px]"Based on coding guidelines: "Use small heights for form elements: select boxes h-7 or smaller".
ui/src/features/dashboard/components/MiniResourceChart.tsx (1)
15-27: Remove unusedcolorprop from interface.The
colorprop is declared but not destructured or used in the component. Since colors are hardcoded from CSS variables (hsl(var(--foreground) / ...)), this prop can be removed.🔎 Remove unused color prop
interface MiniResourceChartProps { title: string; data: MetricPoint[] | undefined; - color?: string; unit?: string; isLoading?: boolean; error?: string; }
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (11)
ui/src/components/ui/simple-toast.tsxui/src/features/dags/components/dag-details/DAGDetailsContent.tsxui/src/features/dags/components/dag-editor/DAGSpec.tsxui/src/features/dags/components/dag-editor/SchemaDocSidebar/SchemaDocSidebar.tsxui/src/features/dashboard/components/MiniResourceChart.tsxui/src/features/dashboard/components/WorkersSummary.tsxui/src/features/queues/components/QueueCard.tsxui/src/features/queues/components/QueueMetrics.tsxui/src/pages/dags/dag/index.tsxui/src/pages/index.tsxui/src/styles/global.css
🧰 Additional context used
📓 Path-based instructions (2)
ui/**/*.{ts,tsx,jsx,js}
📄 CodeRabbit inference engine (ui/CLAUDE.md)
ui/**/*.{ts,tsx,jsx,js}: Use developer-centric UI design with high information density, minimal whitespace, compact components, and no unnecessary decorations
Support both light and dark modes for all UI components using Tailwind CSS class pairs likedark:bg-slate-700
NEVER use full-page loading overlays or LoadingIndicator components that hide content - show stale data while fetching updates instead
Use compact modal design with small headers, minimal padding (p-2 or p-3), tight spacing, and support keyboard navigation (arrows, enter, escape)
Use small heights for form elements: select boxes h-7 or smaller, buttons h-7 or h-8, inputs with compact padding (py-0.5 or py-1)
Minimize row heights in tables and lists while maintaining readability, merge related columns, and always handle long text withwhitespace-normal break-words
Use consistent metadata styling withbg-slate-200 dark:bg-slate-700backgrounds and maintain text hierarchy with primary/secondary/muted text colors
Use flexbox-first layouts withmin-h-0andoverflow-hiddento prevent layout breaks, account for fixed elements when setting heights
Maintain keyboard navigation support in all interactive components with appropriate focus indicators and ARIA labels
Files:
ui/src/features/dags/components/dag-details/DAGDetailsContent.tsxui/src/features/dags/components/dag-editor/DAGSpec.tsxui/src/features/dashboard/components/MiniResourceChart.tsxui/src/features/dags/components/dag-editor/SchemaDocSidebar/SchemaDocSidebar.tsxui/src/features/queues/components/QueueMetrics.tsxui/src/components/ui/simple-toast.tsxui/src/pages/dags/dag/index.tsxui/src/features/queues/components/QueueCard.tsxui/src/pages/index.tsxui/src/features/dashboard/components/WorkersSummary.tsx
ui/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
ui/**/*.{ts,tsx}: The React + TypeScript frontend resides inui/, with production bundles copied tointernal/service/frontend/assetsbymake ui
UI code follows ESLint + Prettier (2-space indent) and Tailwind utilities; name React components in PascalCase (JobList.tsx) and hooks withuse*(useJobs.ts)
Files:
ui/src/features/dags/components/dag-details/DAGDetailsContent.tsxui/src/features/dags/components/dag-editor/DAGSpec.tsxui/src/features/dashboard/components/MiniResourceChart.tsxui/src/features/dags/components/dag-editor/SchemaDocSidebar/SchemaDocSidebar.tsxui/src/features/queues/components/QueueMetrics.tsxui/src/components/ui/simple-toast.tsxui/src/pages/dags/dag/index.tsxui/src/features/queues/components/QueueCard.tsxui/src/pages/index.tsxui/src/features/dashboard/components/WorkersSummary.tsx
🧠 Learnings (6)
📚 Learning: 2025-12-04T10:34:01.045Z
Learnt from: CR
Repo: dagu-org/dagu PR: 0
File: ui/CLAUDE.md:0-0
Timestamp: 2025-12-04T10:34:01.045Z
Learning: Applies to ui/**/*.{ts,tsx,jsx,js} : Minimize row heights in tables and lists while maintaining readability, merge related columns, and always handle long text with `whitespace-normal break-words`
Applied to files:
ui/src/features/dags/components/dag-details/DAGDetailsContent.tsxui/src/features/dags/components/dag-editor/DAGSpec.tsxui/src/features/dashboard/components/MiniResourceChart.tsxui/src/features/queues/components/QueueMetrics.tsxui/src/pages/dags/dag/index.tsxui/src/pages/index.tsxui/src/features/dashboard/components/WorkersSummary.tsx
📚 Learning: 2025-12-04T10:34:01.045Z
Learnt from: CR
Repo: dagu-org/dagu PR: 0
File: ui/CLAUDE.md:0-0
Timestamp: 2025-12-04T10:34:01.045Z
Learning: Applies to ui/**/*.{ts,tsx,jsx,js} : Use flexbox-first layouts with `min-h-0` and `overflow-hidden` to prevent layout breaks, account for fixed elements when setting heights
Applied to files:
ui/src/features/dags/components/dag-details/DAGDetailsContent.tsxui/src/features/dags/components/dag-editor/DAGSpec.tsxui/src/pages/dags/dag/index.tsx
📚 Learning: 2025-12-04T10:34:01.045Z
Learnt from: CR
Repo: dagu-org/dagu PR: 0
File: ui/CLAUDE.md:0-0
Timestamp: 2025-12-04T10:34:01.045Z
Learning: Applies to ui/**/*.{ts,tsx,jsx,js} : Use developer-centric UI design with high information density, minimal whitespace, compact components, and no unnecessary decorations
Applied to files:
ui/src/features/dags/components/dag-details/DAGDetailsContent.tsxui/src/features/dags/components/dag-editor/DAGSpec.tsxui/src/features/dashboard/components/MiniResourceChart.tsxui/src/features/queues/components/QueueMetrics.tsxui/src/styles/global.cssui/src/pages/dags/dag/index.tsxui/src/pages/index.tsxui/src/features/dashboard/components/WorkersSummary.tsx
📚 Learning: 2025-12-04T10:34:01.045Z
Learnt from: CR
Repo: dagu-org/dagu PR: 0
File: ui/CLAUDE.md:0-0
Timestamp: 2025-12-04T10:34:01.045Z
Learning: Applies to ui/**/*.{ts,tsx,jsx,js} : Use small heights for form elements: select boxes h-7 or smaller, buttons h-7 or h-8, inputs with compact padding (py-0.5 or py-1)
Applied to files:
ui/src/features/dags/components/dag-editor/DAGSpec.tsxui/src/styles/global.css
📚 Learning: 2025-12-04T10:34:01.045Z
Learnt from: CR
Repo: dagu-org/dagu PR: 0
File: ui/CLAUDE.md:0-0
Timestamp: 2025-12-04T10:34:01.045Z
Learning: Applies to ui/**/*.{ts,tsx,jsx,js} : Use consistent metadata styling with `bg-slate-200 dark:bg-slate-700` backgrounds and maintain text hierarchy with primary/secondary/muted text colors
Applied to files:
ui/src/features/dashboard/components/MiniResourceChart.tsxui/src/features/dags/components/dag-editor/SchemaDocSidebar/SchemaDocSidebar.tsxui/src/features/queues/components/QueueMetrics.tsxui/src/styles/global.cssui/src/pages/dags/dag/index.tsxui/src/features/dashboard/components/WorkersSummary.tsx
📚 Learning: 2025-12-04T10:34:17.062Z
Learnt from: CR
Repo: dagu-org/dagu PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-04T10:34:17.062Z
Learning: Applies to ui/**/*.{ts,tsx} : UI code follows ESLint + Prettier (2-space indent) and Tailwind utilities; name React components in PascalCase (`JobList.tsx`) and hooks with `use*` (`useJobs.ts`)
Applied to files:
ui/src/pages/index.tsxui/src/features/dashboard/components/WorkersSummary.tsx
🧬 Code graph analysis (1)
ui/src/pages/index.tsx (1)
api/v2/api.gen.go (3)
Status(950-950)SchedulerInstance(895-907)CoordinatorInstance(235-250)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Build
🔇 Additional comments (15)
ui/src/components/ui/simple-toast.tsx (1)
52-61: LGTM!The animation state mapping is clean and covers all cases. TypeScript's exhaustive checking ensures safety.
ui/src/features/dags/components/dag-details/DAGDetailsContent.tsx (1)
99-99: LGTM! Height constraint removal aligns with flexible layout pattern.Removing
h-fullallows the container to size flexibly within its parent, consistent with the PR's coordinated refactor toward responsive, flexbox-driven layouts across DAG components.Based on learnings, this follows the flexbox-first layout guideline with
min-h-0andoverflow-hiddenpatterns to prevent layout breaks.ui/src/features/dags/components/dag-editor/DAGSpec.tsx (1)
393-393: LGTM! Proper flexbox pattern with min-h-0.Replacing
h-full min-h-[500px]withmin-h-0is a correct flexbox pattern that overrides the implicitmin-height: autoon flex items, allowing proper shrinking and overflow handling within the flex container.Based on learnings, this follows the flexbox-first layout guideline to prevent layout breaks.
ui/src/pages/dags/dag/index.tsx (1)
209-209: LGTM! Consistent with flexible layout refactor.Removing
h-fullaligns with the coordinated changes across DAG components to adopt flexible, responsive layouts rather than fixed height constraints.ui/src/features/dags/components/dag-editor/SchemaDocSidebar/SchemaDocSidebar.tsx (1)
66-97: LGTM! Polished error state with clear UX.The redesigned error UI provides better visual hierarchy and user guidance with a centered layout, descriptive icon, two-tier messaging, and an accessible retry action. The design properly reassures users that "the editor still works normally" while offering a clear recovery path.
Based on learnings, this follows consistent metadata styling with semantic color tokens and maintains compact component design.
ui/src/features/queues/components/QueueMetrics.tsx (1)
18-49: LGTM! Simplified metrics display with better information density.The redesign from card-based to inline metrics significantly reduces visual complexity while maintaining clear readability. The use of
tabular-nums, responsive gaps, and inline loading states aligns well with the developer-centric, high-information-density guidelines.The conditional styling on line 38 for
totalQueuedis a nice UX touch that draws attention when items are waiting.Based on learnings, this follows the guideline for developer-centric UI design with high information density, minimal whitespace, and compact components.
ui/src/features/dashboard/components/WorkersSummary.tsx (2)
58-75: Clean, compact metrics presentation.The text-based metrics layout with baseline alignment and
tabular-numsprovides excellent readability and aligns well with the developer-centric, high information density guidelines. The consistent use of semantic color tokens (text-foreground,text-muted-foreground) ensures theme compatibility.
143-152: Simplified utilization bar is appropriate.The reduced bar height (
h-1) and staticbg-foreground/40color simplify the visual while maintaining functionality. The fixed-width container (w-8) withtabular-numsensures consistent alignment across rows.ui/src/styles/global.css (2)
652-659: Focus outline change looks good, but verify contrast.The focus outline changed from
rgb(var(--ring))torgba(var(--primary), 0.5). While this provides visual consistency with the primary color theme, ensure the 50% opacity provides sufficient contrast against various background colors for accessibility compliance (WCAG 2.1 focus indicator guidelines).
481-514: 3D button styling refinements are well-structured.The reduced border depths (4px→3px) and added inset shadows create a more refined tactile appearance. The consistent transition timing (
0.1s ease) ensures smooth interactions across all states.ui/src/features/queues/components/QueueCard.tsx (2)
87-95: Date format change removes timezone indicator.The format changed from including
[GMT]Zto just'MMM D, HH:mm:ss'whentzOffsetis set. This is cleaner but users may lose context about which timezone the time represents. Consider adding a subtle timezone indicator elsewhere in the UI if this information is important for users operating across timezones.
146-149: Compact type badge styling is appropriate.The
text-[10px]size withbg-mutedbackground creates a subtle, unobtrusive badge that doesn't compete with the queue name. This aligns with the high information density guideline.ui/src/features/dashboard/components/MiniResourceChart.tsx (1)
28-30: CSS variable usage for colors is well-implemented.Using
hsl(var(--foreground) / 0.5)ensures the chart adapts to both light and dark themes automatically. The monochrome approach aligns with the simplified dashboard aesthetic.ui/src/pages/index.tsx (2)
408-434: Stats row layout is well-implemented.The inline metrics with
tabular-numsand responsive gap sizing (gap-x-4 sm:gap-x-6) provide a clean, scannable summary. The conditional styling for failures (hasFailures ? 'text-foreground' : 'text-muted-foreground/50') appropriately draws attention when needed. Good use offlex-wrapfor narrow viewports.
436-455: Layout structure with flex sizing is correct.Using
flex-[2]for the timeline andflex-1for workers with explicitmin-h-*constraints ensures stable proportions. Theoverflow-hiddenon containers prevents layout breaks. This aligns with the coding guideline for flexbox-first layouts withmin-h-0.
Summary by CodeRabbit
New Features
Style
Refactor
✏️ Tip: You can customize this high-level summary in your review settings.