Skip to content

Conversation

@drifter089
Copy link
Owner

@drifter089 drifter089 commented Dec 20, 2025

Redesigned the dashboard metric drawer to provide a better user experience.

  • Increased drawer size to 96vh and removed max-width constraints for a full-screen feel.
  • Added a prominent 'Hero Chart' section (450px height) for better visibility.
  • Integrated chart controls (Bar/Line, Cadence) into the header.
  • Structured settings into a 3-column grid (Configuration, Goals, Data Pipeline).
  • Fixed scrolling issues by implementing native overflow handling within a flex layout.

Summary by CodeRabbit

Release Notes

  • Improvements
    • Redesigned dashboard metric card and drawer layouts with a new card-based grid structure
    • Added Quick Actions, Chart Controls (bar/line toggle and cadence), AI customization options, and Data Pipeline health visibility
    • Enhanced metric management with better-organized configuration, goals, and data pipeline sections
    • Improved delete action with confirmation

✏️ Tip: You can customize this high-level summary in your review settings.

@vercel
Copy link

vercel bot commented Dec 20, 2025

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

Project Deployment Review Updated (UTC)
org-os Ready Ready Preview, Comment Dec 20, 2025 10:02pm

@linear
Copy link

linear bot commented Dec 20, 2025

@coderabbitai
Copy link

coderabbitai bot commented Dec 20, 2025

Walkthrough

The pull request restructures two dashboard metric UI components. The metric card's drawer layout transitions from responsive max-height/width constraints to a fixed 96vh flex column. The metric drawer undergoes extensive UI reorganization, replacing a scroll-area-based multi-column layout with a modular card-based grid featuring prominent chart area, configuration panels, and data pipeline health sections.

Changes

Cohort / File(s) Summary
Drawer Layout Optimization
src/app/dashboard/[teamId]/_components/dashboard-metric-card.tsx
Changed DrawerContent classes from responsive max-height/width to flex column with 96vh height. Updated inner wrapper from fixed-width centering div to flexible min-height container expanding to fill available space.
Drawer Content Restructuring
src/app/dashboard/[teamId]/_components/dashboard-metric-drawer.tsx
Rewrote UI from scroll-area multi-column layout to modular card-based grid with hero chart area and side panel. Restructured into three main columns: Chart Configuration, Goals & Alignment, and Data Pipeline. Introduced Quick Actions, Chart Controls, AI customization prompt, data pipeline health area, and Danger Zone delete section. Replaced collapsible/scroll-area sections with inline panels. Updated imports and state/event wiring (e.g., _isUpdating, _onClose aliasing).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • dashboard-metric-drawer.tsx requires careful review due to extensive structural changes spanning the entire component layout, multiple new sections, state/event wiring updates, and import modifications.
  • Verify state management and event handler bindings align between old and new section layouts (e.g., isProcessing, isRegeneratingPipeline references).
  • Ensure new Grid/Panel components integrate correctly with existing styling and responsive behavior.

Possibly related PRs

Poem

🐰 The drawer takes shape with newfound grace,
Three columns dance in their rightful place—
Charts and configs, a pipeline's song,
The dashboard metrics now belong,
In modular panels, strong and bright! ✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main change: a redesign of the metric drawer UI with emphasis on a larger chart and improved layout structure.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch akshat/ryo-95-drawer-updated-for-dashbaord-cards

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 and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (5)
src/app/dashboard/[teamId]/_components/dashboard-metric-drawer.tsx (5)

111-111: Unused prop: _isUpdating is never referenced.

The isUpdating prop is aliased to _isUpdating and never used in the component. Either remove it from the props interface or use it (e.g., to disable the save button or show a loading state).

🔎 If the prop is intentionally unused, remove it from the interface
 interface DashboardMetricDrawerProps {
   // ...
-  isUpdating: boolean;
   // ...
 }
 
 export function DashboardMetricDrawer({
   // ...
-  isUpdating: _isUpdating,
   // ...
 }: DashboardMetricDrawerProps) {

120-120: Misleading underscore prefix on _onClose.

The underscore prefix conventionally indicates an unused variable, but _onClose is actually used in handleDelete (line 162). Rename it to onClose for clarity.

🔎 Proposed fix
-  onClose: _onClose,
+  onClose,
 }: DashboardMetricDrawerProps) {

And update line 162:

   const handleDelete = () => {
     onDelete();
-    _onClose();
+    onClose();
   };

454-466: Inconsistent disabled logic between regenerate buttons.

The "Apply Customization" button (line 458) is disabled only when isProcessing, but the Quick Actions "Regenerate" button (line 400) also checks !hasChartChanges. Consider aligning the behavior—if there are no changes to apply, this button should probably also be disabled or provide visual feedback.

🔎 Proposed fix for consistent behavior
                     <Button
                       size="sm"
                       className="w-full"
                       onClick={handleApplyChanges}
-                      disabled={isProcessing}
+                      disabled={isProcessing || !hasChartChanges}
                     >

491-529: Section heading renders without content when teamId is null.

The "Goals & Alignment" heading (lines 493-496) is always rendered, but the content (lines 497-528) is conditional on teamId. This results in an empty section with just a heading when no team context exists.

🔎 Proposed fix: wrap entire section conditionally
-            {/* Col 2: Business Goals */}
-            <div className="space-y-4">
-              <h4 className="flex items-center gap-2 font-semibold">
-                <Target className="h-4 w-4" />
-                Goals & Alignment
-              </h4>
-              {teamId && (
-                <div className="space-y-4">
+            {/* Col 2: Business Goals */}
+            {teamId && (
+              <div className="space-y-4">
+                <h4 className="flex items-center gap-2 font-semibold">
+                  <Target className="h-4 w-4" />
+                  Goals & Alignment
+                </h4>
+                <div className="space-y-4">
                   {/* ... cards ... */}
                 </div>
-              )}
-            </div>
+              </div>
+            )}

556-570: "Rebuild Transformers" should be disabled during any processing.

The button is only disabled when isRegeneratingPipeline (line 560), but it should likely also be disabled when isProcessing to prevent conflicting operations.

🔎 Proposed fix
                       <Button
                         variant="secondary"
                         size="sm"
                         onClick={onRegeneratePipeline}
-                        disabled={isRegeneratingPipeline}
+                        disabled={isProcessing || isRegeneratingPipeline}
                         className="h-8 w-full text-xs"
                       >
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1707487 and 69b8dd6.

📒 Files selected for processing (2)
  • src/app/dashboard/[teamId]/_components/dashboard-metric-card.tsx (1 hunks)
  • src/app/dashboard/[teamId]/_components/dashboard-metric-drawer.tsx (6 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Use the tRPC dual API pattern: for server components, directly call tRPC server API (10x faster); for client components, use React hooks with TanStack Query
Use inline type imports with @trivago/prettier-plugin-sort-imports for consistent import ordering

Files:

  • src/app/dashboard/[teamId]/_components/dashboard-metric-card.tsx
  • src/app/dashboard/[teamId]/_components/dashboard-metric-drawer.tsx
src/app/dashboard/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Three-stage metrics transformation pipeline: Stage 1 (API → DataPoints via DataIngestionTransformer), Stage 2 (DataPoints → ChartConfig via ChartTransformer), Stage 3 (ChartConfig → UI via DashboardMetricChart with Recharts)

Files:

  • src/app/dashboard/[teamId]/_components/dashboard-metric-card.tsx
  • src/app/dashboard/[teamId]/_components/dashboard-metric-drawer.tsx
src/app/dashboard/**/*.tsx

📄 CodeRabbit inference engine (CLAUDE.md)

Consolidate dashboard metric card duplication: add readOnly mode to dashboard-metric-card.tsx instead of maintaining separate public-dashboard-metric-card.tsx component

Files:

  • src/app/dashboard/[teamId]/_components/dashboard-metric-card.tsx
  • src/app/dashboard/[teamId]/_components/dashboard-metric-drawer.tsx
🧠 Learnings (8)
📓 Common learnings
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-20T16:32:46.818Z
Learning: Applies to src/app/dashboard/**/*.tsx : Consolidate dashboard metric card duplication: add readOnly mode to dashboard-metric-card.tsx instead of maintaining separate public-dashboard-metric-card.tsx component
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-20T16:32:46.818Z
Learning: Applies to src/app/dashboard/**/*.{ts,tsx} : Three-stage metrics transformation pipeline: Stage 1 (API → DataPoints via DataIngestionTransformer), Stage 2 (DataPoints → ChartConfig via ChartTransformer), Stage 3 (ChartConfig → UI via DashboardMetricChart with Recharts)
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-20T16:32:46.818Z
Learning: Applies to src/app/metric/_components/**/*.tsx : Use MetricDialogBase from base/ for shared metric dialog functionality to reduce duplication across provider-specific dialogs
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-20T16:32:46.818Z
Learning: Applies to src/app/metric/_components/**/*.tsx : Consider factory pattern for metric dialogs to reduce the 5 nearly identical wrapper components (currently duplicated across providers)
📚 Learning: 2025-12-20T16:32:46.818Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-20T16:32:46.818Z
Learning: Applies to src/app/dashboard/**/*.tsx : Consolidate dashboard metric card duplication: add readOnly mode to dashboard-metric-card.tsx instead of maintaining separate public-dashboard-metric-card.tsx component

Applied to files:

  • src/app/dashboard/[teamId]/_components/dashboard-metric-card.tsx
  • src/app/dashboard/[teamId]/_components/dashboard-metric-drawer.tsx
📚 Learning: 2025-12-20T16:32:46.818Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-20T16:32:46.818Z
Learning: Applies to src/app/dashboard/**/*.{ts,tsx} : Three-stage metrics transformation pipeline: Stage 1 (API → DataPoints via DataIngestionTransformer), Stage 2 (DataPoints → ChartConfig via ChartTransformer), Stage 3 (ChartConfig → UI via DashboardMetricChart with Recharts)

Applied to files:

  • src/app/dashboard/[teamId]/_components/dashboard-metric-card.tsx
  • src/app/dashboard/[teamId]/_components/dashboard-metric-drawer.tsx
📚 Learning: 2025-12-20T16:32:46.818Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-20T16:32:46.818Z
Learning: Applies to src/app/metric/_components/**/*.tsx : Use MetricDialogBase from base/ for shared metric dialog functionality to reduce duplication across provider-specific dialogs

Applied to files:

  • src/app/dashboard/[teamId]/_components/dashboard-metric-card.tsx
  • src/app/dashboard/[teamId]/_components/dashboard-metric-drawer.tsx
📚 Learning: 2025-12-20T16:32:46.818Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-20T16:32:46.818Z
Learning: Applies to src/app/metric/_components/**/*.tsx : Consider factory pattern for metric dialogs to reduce the 5 nearly identical wrapper components (currently duplicated across providers)

Applied to files:

  • src/app/dashboard/[teamId]/_components/dashboard-metric-card.tsx
  • src/app/dashboard/[teamId]/_components/dashboard-metric-drawer.tsx
📚 Learning: 2025-12-20T16:32:46.818Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-20T16:32:46.818Z
Learning: Applies to src/app/metric/_components/**/*.tsx : Metric dialogs should follow the pattern: [Provider]MetricDialog.tsx (dialog wrapper) + [Provider]MetricContent.tsx (form content) and be registered in src/app/metric/_components/index.ts

Applied to files:

  • src/app/dashboard/[teamId]/_components/dashboard-metric-card.tsx
  • src/app/dashboard/[teamId]/_components/dashboard-metric-drawer.tsx
📚 Learning: 2025-12-20T16:32:46.818Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-20T16:32:46.818Z
Learning: Applies to src/app/teams/[teamId]/**/*.tsx : Consolidate role node duplication: extract shared RoleNodeTemplate from role-node.tsx and public-role-node.tsx with isEditable prop instead of maintaining separate components

Applied to files:

  • src/app/dashboard/[teamId]/_components/dashboard-metric-card.tsx
  • src/app/dashboard/[teamId]/_components/dashboard-metric-drawer.tsx
📚 Learning: 2025-12-20T16:32:46.818Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-20T16:32:46.818Z
Learning: Applies to **/*canvas*.{ts,tsx} : Use React Flow primitives (BaseNode, BaseHandle, ZoomSlider) from src/components/react-flow/ for consistent canvas styling

Applied to files:

  • src/app/dashboard/[teamId]/_components/dashboard-metric-drawer.tsx
🧬 Code graph analysis (2)
src/app/dashboard/[teamId]/_components/dashboard-metric-card.tsx (1)
src/components/ui/drawer.tsx (1)
  • DrawerContent (131-131)
src/app/dashboard/[teamId]/_components/dashboard-metric-drawer.tsx (4)
src/lib/utils.ts (1)
  • cn (4-6)
src/lib/helpers/format-value.ts (1)
  • formatValue (6-17)
src/components/metric/goal-editor.tsx (1)
  • GoalEditor (86-398)
src/components/metric/role-assignment.tsx (1)
  • RoleAssignment (39-236)
⏰ 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: test
🔇 Additional comments (2)
src/app/dashboard/[teamId]/_components/dashboard-metric-drawer.tsx (1)

178-301: Well-structured redesign with clear visual hierarchy.

The new modular card-based grid layout with a prominent hero chart section (450px), organized 3-column configuration grid, and consistent spacing improves the UX significantly. The separation of concerns (Chart Configuration, Goals & Alignment, Data Pipeline) is intuitive.

Also applies to: 411-599

src/app/dashboard/[teamId]/_components/dashboard-metric-card.tsx (1)

406-441: LGTM! Proper flex layout for the redesigned drawer.

The min-h-0 on the inner wrapper is essential for proper overflow behavior within flex containers, and the fixed 96vh height provides a consistent full-screen drawer experience. The layout correctly enables the inner DashboardMetricDrawer to handle its own scrolling.

Comment on lines +197 to +216
<DrawerDescription className="flex items-center gap-3">
{lastFetchedAt && (
<span className="flex items-center gap-1.5 text-xs">
<Clock className="h-3.5 w-3.5" />
Updated{" "}
{formatDistanceToNow(new Date(lastFetchedAt), {
addSuffix: true,
})}
</span>
)}
<span className="text-border">|</span>
<span className="text-xs">
Polls {pollFrequency.toLowerCase()}
</span>
{lastError && (
<Badge variant="destructive" className="h-5 px-1.5 text-[10px]">
Error
</Badge>
)}
</DrawerDescription>
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Separator displays even when lastFetchedAt is missing.

The | separator (line 207) is always rendered regardless of whether lastFetchedAt exists, which will result in a leading separator when there's no timestamp.

🔎 Proposed fix: make the separator conditional
             <DrawerDescription className="flex items-center gap-3">
               {lastFetchedAt && (
-                <span className="flex items-center gap-1.5 text-xs">
-                  <Clock className="h-3.5 w-3.5" />
-                  Updated{" "}
-                  {formatDistanceToNow(new Date(lastFetchedAt), {
-                    addSuffix: true,
-                  })}
-                </span>
+                <>
+                  <span className="flex items-center gap-1.5 text-xs">
+                    <Clock className="h-3.5 w-3.5" />
+                    Updated{" "}
+                    {formatDistanceToNow(new Date(lastFetchedAt), {
+                      addSuffix: true,
+                    })}
+                  </span>
+                  <span className="text-border">|</span>
+                </>
               )}
-              <span className="text-border">|</span>
               <span className="text-xs">
                 Polls {pollFrequency.toLowerCase()}
               </span>
🤖 Prompt for AI Agents
In src/app/dashboard/[teamId]/_components/dashboard-metric-drawer.tsx around
lines 197 to 216, the vertical separator "|" is always rendered causing a
leading separator when lastFetchedAt is absent; update the JSX so the separator
is rendered only when lastFetchedAt exists (i.e., conditionally render the <span
className="text-border">|</span> together with the timestamp block), ensuring
spacing remains correct and other elements (poll frequency, error badge) render
as before.

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