-
Notifications
You must be signed in to change notification settings - Fork 1
feat: add team edit dialog with roles and metrics overview #352
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
* refactor: unify role card styling across all usages * refactor: redesign role dialog with wider two-column layout
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
📝 WalkthroughWalkthroughWidespread UI and component updates: RoleCard no longer accepts a Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant UI as EditTeamDialog (client)
participant API as TRPC
participant Cache as Query Cache
participant DB as Backend
User->>UI: Click "Edit" (open dialog)
UI->>API: fetch team, roles, dashboard charts (lazy)
API-->>UI: return data
UI->>User: render form with data
User->>UI: Submit form (Save)
UI->>Cache: cancel related queries & apply optimistic update
UI->>API: mutate updateTeam
API->>DB: persist update
DB-->>API: success
API-->>UI: mutation success
UI->>Cache: invalidate/refresh related queries
Cache->>UI: refreshed data
UI->>User: close dialog / show success
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
📜 Recent review detailsConfiguration used: defaults Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
🧰 Additional context used📓 Path-based instructions (6)**/*.{ts,tsx}📄 CodeRabbit inference engine (GEMINI.md)
Files:
src/**/*.tsx📄 CodeRabbit inference engine (GEMINI.md)
Files:
src/**/*/*.tsx📄 CodeRabbit inference engine (GEMINI.md)
Files:
**/*.tsx📄 CodeRabbit inference engine (GEMINI.md)
Files:
src/app/**/*.tsx📄 CodeRabbit inference engine (CLAUDE.md)
Files:
**/*.{ts,tsx,js,jsx}📄 CodeRabbit inference engine (CLAUDE.md)
Files:
🧠 Learnings (17)📓 Common learnings📚 Learning: 2025-12-29T12:52:42.935ZApplied to files:
📚 Learning: 2025-12-20T22:12:00.576ZApplied to files:
📚 Learning: 2025-12-20T22:12:00.576ZApplied to files:
📚 Learning: 2025-12-20T22:12:00.576ZApplied to files:
📚 Learning: 2025-12-29T12:52:42.935ZApplied to files:
📚 Learning: 2025-12-29T21:27:04.176ZApplied to files:
📚 Learning: 2025-12-29T21:27:04.176ZApplied to files:
📚 Learning: 2025-12-29T12:52:42.935ZApplied to files:
📚 Learning: 2025-12-29T21:27:04.176ZApplied to files:
📚 Learning: 2025-12-29T21:27:04.176ZApplied to files:
📚 Learning: 2025-12-20T22:12:00.576ZApplied to files:
📚 Learning: 2025-12-29T21:27:04.176ZApplied to files:
📚 Learning: 2025-12-29T12:52:42.935ZApplied to files:
📚 Learning: 2025-12-29T21:27:04.176ZApplied to files:
📚 Learning: 2025-12-29T12:52:42.935ZApplied to files:
📚 Learning: 2025-12-29T21:27:04.176ZApplied to files:
⏰ 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)
🔇 Additional comments (6)
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 |
Code Review - PR #352: Team Edit DialogSummaryThis PR adds a comprehensive edit dialog for teams that allows editing team details, viewing all roles and metrics, with proper optimistic updates and a well-designed UI. Overall implementation quality is strong, but there are a few areas for improvement. ✅ Strengths
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
🤖 Fix all issues with AI agents
In @src/app/teams/_components/edit-team-dialog.tsx:
- Around line 85-93: The useEffect that resets the form when team data loads
includes the `form` object in its dependency array which can cause unnecessary
re-renders or an infinite loop because the `form` reference may change; update
the effect to depend only on stable values (`team` and `open`) and call the
stable method `form.reset` inside the effect (i.e., remove `form` from the
dependency array) so the effect runs only when `team` or `open` change and still
invokes `form.reset` with the team's name and description.
In @src/app/teams/_components/edit-team-metric-card.tsx:
- Around line 57-76: The Tooltip currently wraps MetricSettingsDialog via
TooltipTrigger which can interfere with the dialog's own trigger handling;
instead, wrap only the Button with TooltipTrigger (asChild) and pass that same
Button element into MetricSettingsDialog via its trigger prop (or render
MetricSettingsDialog alongside but not as the TooltipTrigger child), keeping the
onClick stopPropagation and button classes intact so the tooltip and the dialog
triggers operate independently (update references: TooltipTrigger,
MetricSettingsDialog, Button, TooltipContent).
In @src/app/teams/[teamId]/_components/chart-node.tsx:
- Line 61: The fallback container in ChartNode component uses the utility class
string "bg-card h-full w-full rounded-xl border p-6 shadow-md" which applies a
1px border, while the node's interactive handles use "border-2" earlier (line
~43); confirm whether the 1px border was intentional and, if not, change that
class string to use "border-2" for visual consistency (update the JSX element in
src/app/teams/[teamId]/_components/chart-node.tsx that renders the fallback
container to replace "border" with "border-2").
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (13)
src/app/dashboard/[teamId]/_components/dashboard-metric-chart.tsxsrc/app/dashboard/[teamId]/_components/drawer/role-tab-content.tsxsrc/app/member/[id]/_components/member-role-card.tsxsrc/app/teams/[teamId]/_components/canvas-side-panels.tsxsrc/app/teams/[teamId]/_components/chart-node.tsxsrc/app/teams/[teamId]/_components/role-dialog.tsxsrc/app/teams/[teamId]/_components/role-node.tsxsrc/app/teams/_components/delete-team-dialog.tsxsrc/app/teams/_components/edit-team-dialog.tsxsrc/app/teams/_components/edit-team-metric-card.tsxsrc/app/teams/_components/teams-list.tsxsrc/components/form-label-with-tooltip.tsxsrc/components/role/role-card.tsx
💤 Files with no reviewable changes (2)
- src/app/teams/[teamId]/_components/canvas-side-panels.tsx
- src/app/dashboard/[teamId]/_components/drawer/role-tab-content.tsx
🧰 Additional context used
📓 Path-based instructions (7)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (GEMINI.md)
Use TypeScript 5.9 with strict type checking for all frontend and backend code
Files:
src/app/member/[id]/_components/member-role-card.tsxsrc/components/role/role-card.tsxsrc/app/teams/_components/edit-team-metric-card.tsxsrc/app/teams/_components/edit-team-dialog.tsxsrc/app/teams/_components/teams-list.tsxsrc/app/teams/[teamId]/_components/role-node.tsxsrc/app/dashboard/[teamId]/_components/dashboard-metric-chart.tsxsrc/app/teams/_components/delete-team-dialog.tsxsrc/components/form-label-with-tooltip.tsxsrc/app/teams/[teamId]/_components/chart-node.tsxsrc/app/teams/[teamId]/_components/role-dialog.tsx
src/**/*.tsx
📄 CodeRabbit inference engine (GEMINI.md)
Prefer Server Components for initial data fetching; use Client Components ('use client') only for interactivity
Files:
src/app/member/[id]/_components/member-role-card.tsxsrc/components/role/role-card.tsxsrc/app/teams/_components/edit-team-metric-card.tsxsrc/app/teams/_components/edit-team-dialog.tsxsrc/app/teams/_components/teams-list.tsxsrc/app/teams/[teamId]/_components/role-node.tsxsrc/app/dashboard/[teamId]/_components/dashboard-metric-chart.tsxsrc/app/teams/_components/delete-team-dialog.tsxsrc/components/form-label-with-tooltip.tsxsrc/app/teams/[teamId]/_components/chart-node.tsxsrc/app/teams/[teamId]/_components/role-dialog.tsx
src/**/*/*.tsx
📄 CodeRabbit inference engine (GEMINI.md)
Client Components must use
import { api } from '@/trpc/react'for standard HTTP/Hooks wrapper
Files:
src/app/member/[id]/_components/member-role-card.tsxsrc/components/role/role-card.tsxsrc/app/teams/_components/edit-team-metric-card.tsxsrc/app/teams/_components/edit-team-dialog.tsxsrc/app/teams/_components/teams-list.tsxsrc/app/teams/[teamId]/_components/role-node.tsxsrc/app/dashboard/[teamId]/_components/dashboard-metric-chart.tsxsrc/app/teams/_components/delete-team-dialog.tsxsrc/components/form-label-with-tooltip.tsxsrc/app/teams/[teamId]/_components/chart-node.tsxsrc/app/teams/[teamId]/_components/role-dialog.tsx
**/*.tsx
📄 CodeRabbit inference engine (GEMINI.md)
Use Tailwind CSS 4 for styling with shadcn/ui and Radix UI primitive components
Files:
src/app/member/[id]/_components/member-role-card.tsxsrc/components/role/role-card.tsxsrc/app/teams/_components/edit-team-metric-card.tsxsrc/app/teams/_components/edit-team-dialog.tsxsrc/app/teams/_components/teams-list.tsxsrc/app/teams/[teamId]/_components/role-node.tsxsrc/app/dashboard/[teamId]/_components/dashboard-metric-chart.tsxsrc/app/teams/_components/delete-team-dialog.tsxsrc/components/form-label-with-tooltip.tsxsrc/app/teams/[teamId]/_components/chart-node.tsxsrc/app/teams/[teamId]/_components/role-dialog.tsx
src/app/**/*.tsx
📄 CodeRabbit inference engine (CLAUDE.md)
src/app/**/*.tsx: Use the dual tRPC API pattern: direct calls in Server Components (api.team.getById) for 10x faster performance, and React hooks in Client Components (api.team.getById.useQuery)
Use getUserDisplayName(userId, members) utility (client-side sync) from @/lib/helpers/get-user-name for displaying user names in components
Files:
src/app/member/[id]/_components/member-role-card.tsxsrc/app/teams/_components/edit-team-metric-card.tsxsrc/app/teams/_components/edit-team-dialog.tsxsrc/app/teams/_components/teams-list.tsxsrc/app/teams/[teamId]/_components/role-node.tsxsrc/app/dashboard/[teamId]/_components/dashboard-metric-chart.tsxsrc/app/teams/_components/delete-team-dialog.tsxsrc/app/teams/[teamId]/_components/chart-node.tsxsrc/app/teams/[teamId]/_components/role-dialog.tsx
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Use @trivago/prettier-plugin-sort-imports with inline type imports for import organization
Files:
src/app/member/[id]/_components/member-role-card.tsxsrc/components/role/role-card.tsxsrc/app/teams/_components/edit-team-metric-card.tsxsrc/app/teams/_components/edit-team-dialog.tsxsrc/app/teams/_components/teams-list.tsxsrc/app/teams/[teamId]/_components/role-node.tsxsrc/app/dashboard/[teamId]/_components/dashboard-metric-chart.tsxsrc/app/teams/_components/delete-team-dialog.tsxsrc/components/form-label-with-tooltip.tsxsrc/app/teams/[teamId]/_components/chart-node.tsxsrc/app/teams/[teamId]/_components/role-dialog.tsx
src/components/**/*.tsx
📄 CodeRabbit inference engine (GEMINI.md)
Place colocated components in
_components/folders next to their parent componentUse shadcn/ui components from src/components/ui/; add new components via CLI: npx shadcn@latest add [component-name]
Files:
src/components/role/role-card.tsxsrc/components/form-label-with-tooltip.tsx
🧠 Learnings (31)
📓 Common learnings
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T12:52:42.935Z
Learning: Applies to src/app/teams/[teamId]/_components/role-node.tsx,src/app/teams/[teamId]/_components/public-role-node.tsx : These role node components are 75% identical and should be consolidated. Extract shared `RoleNodeTemplate` component with `isEditable` prop to DRY up the code.
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T12:52:42.935Z
Learning: Applies to src/components/dashboard-metric-card.tsx,src/app/dashboard/[teamId]/_components/public-dashboard-metric-card.tsx : Dashboard metric cards are duplicated with public variant. Consolidate into single component with `readOnly` mode prop instead of maintaining separate components.
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-20T22:12:00.576Z
Learning: Applies to src/app/teams/[teamId]/**/*.tsx : React Flow nodes must store minimal data (e.g., just `roleId`); fetch full Role data from TanStack Query cache in the Node component to keep canvas and sidebars in sync
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T21:27:04.176Z
Learning: Applies to src/app/teams/[teamId]/_components/**/*.tsx : Implement cache-first node pattern for role nodes: store only roleId in node data, fetch display data from TanStack Query cache using useRoleData hook
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T21:27:04.176Z
Learning: Applies to src/app/(teams|org)/**/*.tsx : Use shared MembersList component at src/components/member/member-list.tsx for displaying members in canvas sidebar and org page; it includes getMemberDisplayInfo() utility for initials/name logic
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T21:27:04.176Z
Learning: Applies to src/app/metric/_components/**/*.tsx : Use shared MetricDialogBase component from base/ for all metric dialog implementations
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T21:27:04.176Z
Learning: Applies to src/app/teams/[teamId]/**/*.tsx : Use shared React Flow primitives (BaseNode, BaseHandle, ZoomSlider) from src/components/react-flow/ in all canvas implementations
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T21:27:04.176Z
Learning: Applies to src/hooks/**/*.ts : For role-metric cache updates, optimistically update both role cache (role.getByTeamId) and dashboard cache (dashboard.getDashboardCharts) to maintain UI consistency
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-20T22:12:00.576Z
Learning: Applies to src/app/teams/[teamId]/**/*.tsx : Avoid modifying `enrichNodesWithRoleData` flow without understanding the complete canvas serialization logic for saving/loading React Flow nodes to the database
📚 Learning: 2025-12-29T12:52:42.935Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T12:52:42.935Z
Learning: Applies to src/components/dashboard-metric-card.tsx,src/app/dashboard/[teamId]/_components/public-dashboard-metric-card.tsx : Dashboard metric cards are duplicated with public variant. Consolidate into single component with `readOnly` mode prop instead of maintaining separate components.
Applied to files:
src/app/member/[id]/_components/member-role-card.tsxsrc/components/role/role-card.tsxsrc/app/teams/_components/edit-team-metric-card.tsxsrc/app/teams/_components/teams-list.tsxsrc/app/dashboard/[teamId]/_components/dashboard-metric-chart.tsxsrc/app/teams/[teamId]/_components/chart-node.tsx
📚 Learning: 2025-12-29T12:52:42.935Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T12:52:42.935Z
Learning: Applies to src/app/teams/[teamId]/_components/role-node.tsx,src/app/teams/[teamId]/_components/public-role-node.tsx : These role node components are 75% identical and should be consolidated. Extract shared `RoleNodeTemplate` component with `isEditable` prop to DRY up the code.
Applied to files:
src/app/member/[id]/_components/member-role-card.tsxsrc/components/role/role-card.tsxsrc/app/teams/_components/edit-team-metric-card.tsxsrc/app/teams/_components/edit-team-dialog.tsxsrc/app/teams/_components/teams-list.tsxsrc/app/teams/[teamId]/_components/role-node.tsxsrc/app/teams/_components/delete-team-dialog.tsxsrc/app/teams/[teamId]/_components/chart-node.tsxsrc/app/teams/[teamId]/_components/role-dialog.tsx
📚 Learning: 2025-12-29T21:27:04.176Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T21:27:04.176Z
Learning: Applies to src/app/(teams|org)/**/*.tsx : Use shared MembersList component at src/components/member/member-list.tsx for displaying members in canvas sidebar and org page; it includes getMemberDisplayInfo() utility for initials/name logic
Applied to files:
src/app/member/[id]/_components/member-role-card.tsxsrc/components/role/role-card.tsxsrc/app/teams/_components/teams-list.tsxsrc/app/teams/[teamId]/_components/role-dialog.tsx
📚 Learning: 2025-12-29T21:27:04.176Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T21:27:04.176Z
Learning: Applies to src/hooks/**/*.ts : For role-metric cache updates, optimistically update both role cache (role.getByTeamId) and dashboard cache (dashboard.getDashboardCharts) to maintain UI consistency
Applied to files:
src/app/member/[id]/_components/member-role-card.tsxsrc/components/role/role-card.tsxsrc/app/teams/_components/edit-team-metric-card.tsxsrc/app/dashboard/[teamId]/_components/dashboard-metric-chart.tsxsrc/app/teams/[teamId]/_components/role-dialog.tsx
📚 Learning: 2025-12-29T21:27:04.176Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T21:27:04.176Z
Learning: Applies to src/app/teams/[teamId]/_components/**/*.tsx : Implement cache-first node pattern for role nodes: store only roleId in node data, fetch display data from TanStack Query cache using useRoleData hook
Applied to files:
src/app/member/[id]/_components/member-role-card.tsxsrc/components/role/role-card.tsxsrc/app/teams/_components/edit-team-dialog.tsxsrc/app/teams/_components/teams-list.tsxsrc/app/teams/[teamId]/_components/role-node.tsxsrc/app/teams/[teamId]/_components/chart-node.tsxsrc/app/teams/[teamId]/_components/role-dialog.tsx
📚 Learning: 2025-12-29T12:52:42.935Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T12:52:42.935Z
Learning: Applies to src/app/dashboard/[teamId]/**/*.{ts,tsx} : Dashboard cache updates for role-metric assignments must update both `role.getByTeamId` and `dashboard.getDashboardCharts` caches during mutations. Use onMutate for optimistic updates on both caches, then invalidate both on success.
Applied to files:
src/app/member/[id]/_components/member-role-card.tsxsrc/components/role/role-card.tsxsrc/app/teams/_components/edit-team-metric-card.tsxsrc/app/dashboard/[teamId]/_components/dashboard-metric-chart.tsxsrc/app/teams/[teamId]/_components/role-dialog.tsx
📚 Learning: 2025-12-20T22:12:00.576Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-20T22:12:00.576Z
Learning: Applies to src/app/teams/[teamId]/**/*.tsx : React Flow nodes must store minimal data (e.g., just `roleId`); fetch full Role data from TanStack Query cache in the Node component to keep canvas and sidebars in sync
Applied to files:
src/app/member/[id]/_components/member-role-card.tsxsrc/components/role/role-card.tsxsrc/app/teams/_components/edit-team-dialog.tsxsrc/app/teams/_components/teams-list.tsxsrc/app/teams/[teamId]/_components/role-node.tsxsrc/app/teams/_components/delete-team-dialog.tsxsrc/app/teams/[teamId]/_components/chart-node.tsxsrc/app/teams/[teamId]/_components/role-dialog.tsx
📚 Learning: 2025-12-29T21:27:04.176Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T21:27:04.176Z
Learning: Applies to src/server/api/**/*.ts : Use enrichRolesWithUserNames() for flat role arrays and enrichChartRolesWithUserNames() for nested chart roles from src/server/api/utils/organization-members.ts
Applied to files:
src/app/member/[id]/_components/member-role-card.tsxsrc/components/role/role-card.tsx
📚 Learning: 2025-12-29T12:52:42.935Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T12:52:42.935Z
Learning: Applies to src/components/member/member-list.tsx : The MembersList component is consolidated and reused by both canvas sidebar (canvas-side-panels.tsx) and org page (MembersListClient.tsx). Use this component for all member list displays to maintain consistency.
Applied to files:
src/app/member/[id]/_components/member-role-card.tsx
📚 Learning: 2025-12-29T21:27:04.176Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T21:27:04.176Z
Learning: Applies to src/app/(metric|dashboard)/**/*.tsx : Use three-stage metrics transformation: API → DataPoints (DataIngestionTransformer), DataPoints → ChartConfig (ChartTransformer), ChartConfig → UI (DashboardMetricChart)
Applied to files:
src/app/member/[id]/_components/member-role-card.tsxsrc/components/role/role-card.tsxsrc/app/teams/_components/edit-team-metric-card.tsxsrc/app/dashboard/[teamId]/_components/dashboard-metric-chart.tsxsrc/app/teams/[teamId]/_components/chart-node.tsx
📚 Learning: 2025-12-29T21:27:04.176Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T21:27:04.176Z
Learning: Applies to src/app/metric/_components/**/*.tsx : Use shared MetricDialogBase component from base/ for all metric dialog implementations
Applied to files:
src/app/member/[id]/_components/member-role-card.tsxsrc/app/teams/_components/edit-team-metric-card.tsxsrc/app/teams/_components/edit-team-dialog.tsxsrc/app/teams/_components/teams-list.tsxsrc/app/dashboard/[teamId]/_components/dashboard-metric-chart.tsxsrc/app/teams/_components/delete-team-dialog.tsxsrc/app/teams/[teamId]/_components/role-dialog.tsx
📚 Learning: 2025-12-29T21:27:04.176Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T21:27:04.176Z
Learning: Applies to src/app/metric/_components/**/*.tsx : Create metric dialogs with pattern: [Provider]MetricDialog.tsx (dialog wrapper) + [Provider]MetricContent.tsx (form content) in src/app/metric/_components/[provider]/, then register in index.ts
Applied to files:
src/app/member/[id]/_components/member-role-card.tsxsrc/app/teams/_components/edit-team-metric-card.tsxsrc/app/teams/_components/edit-team-dialog.tsxsrc/app/dashboard/[teamId]/_components/dashboard-metric-chart.tsxsrc/app/teams/[teamId]/_components/role-dialog.tsx
📚 Learning: 2025-12-29T12:52:42.935Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T12:52:42.935Z
Learning: Applies to src/app/metric/_components/**/*.tsx : Metric dialog components should follow the pattern: [Provider]MetricDialog.tsx (dialog wrapper) and [Provider]MetricContent.tsx (form content). Register in src/app/metric/_components/index.ts and inherit from shared MetricDialogBase.
Applied to files:
src/app/member/[id]/_components/member-role-card.tsxsrc/app/teams/_components/edit-team-metric-card.tsxsrc/app/teams/_components/edit-team-dialog.tsxsrc/app/dashboard/[teamId]/_components/dashboard-metric-chart.tsxsrc/app/teams/[teamId]/_components/role-dialog.tsx
📚 Learning: 2025-12-29T21:27:04.176Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T21:27:04.176Z
Learning: Applies to src/app/**/*.tsx : Use the dual tRPC API pattern: direct calls in Server Components (api.team.getById) for 10x faster performance, and React hooks in Client Components (api.team.getById.useQuery)
Applied to files:
src/app/member/[id]/_components/member-role-card.tsxsrc/app/teams/[teamId]/_components/role-dialog.tsx
📚 Learning: 2025-12-29T21:27:04.176Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T21:27:04.176Z
Learning: Applies to src/app/teams/[teamId]/**/*.tsx : Use shared React Flow primitives (BaseNode, BaseHandle, ZoomSlider) from src/components/react-flow/ in all canvas implementations
Applied to files:
src/app/member/[id]/_components/member-role-card.tsxsrc/app/teams/_components/edit-team-metric-card.tsxsrc/app/teams/_components/edit-team-dialog.tsxsrc/app/teams/_components/teams-list.tsxsrc/app/teams/[teamId]/_components/role-node.tsxsrc/app/teams/_components/delete-team-dialog.tsxsrc/app/teams/[teamId]/_components/chart-node.tsx
📚 Learning: 2025-12-20T22:12:00.576Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-20T22:12:00.576Z
Learning: Applies to src/app/teams/[teamId]/**/*.tsx : Avoid modifying `enrichNodesWithRoleData` flow without understanding the complete canvas serialization logic for saving/loading React Flow nodes to the database
Applied to files:
src/components/role/role-card.tsxsrc/app/teams/_components/edit-team-dialog.tsxsrc/app/teams/_components/teams-list.tsxsrc/app/teams/[teamId]/_components/role-node.tsxsrc/app/teams/_components/delete-team-dialog.tsxsrc/app/teams/[teamId]/_components/chart-node.tsxsrc/app/teams/[teamId]/_components/role-dialog.tsx
📚 Learning: 2025-12-29T12:52:42.935Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T12:52:42.935Z
Learning: Applies to src/app/teams/[teamId]/**/*.{ts,tsx} : Cache-first node system: Role nodes store only `roleId` in node.data. Display data must be fetched from TanStack Query cache using the `useRoleData()` hook which queries the `role.getByTeamId` procedure.
Applied to files:
src/components/role/role-card.tsxsrc/app/teams/[teamId]/_components/role-node.tsxsrc/app/teams/[teamId]/_components/role-dialog.tsx
📚 Learning: 2025-12-29T12:52:42.935Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T12:52:42.935Z
Learning: Applies to src/app/**/*role*mutation*.{ts,tsx} : For role mutations, use cache pipeline with two operations: (1) onMutate for optimistic update, (2) onSuccess with both setData(updatedRole) using server response AND invalidate() for background refresh. Always use server response data in setData before invalidate to ensure Prisma Accelerate cache consistency.
Applied to files:
src/components/role/role-card.tsx
📚 Learning: 2025-12-29T12:52:42.935Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T12:52:42.935Z
Learning: Applies to src/hooks/use-optimistic-role-update.ts : The `use-optimistic-role-update` hook provides shared logic for all role mutations with proper cache layer handling for TanStack Query and Prisma Accelerate. Use this hook in canvas-specific wrappers to add markDirty side effects.
Applied to files:
src/components/role/role-card.tsx
📚 Learning: 2025-12-20T22:12:00.576Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-20T22:12:00.576Z
Learning: Applies to src/app/teams/[teamId]/**/*.ts : Canvas changes must be debounced (2s) and saved via `editSession` logic to handle concurrent team edits safely
Applied to files:
src/app/teams/_components/edit-team-metric-card.tsxsrc/app/teams/_components/edit-team-dialog.tsxsrc/app/teams/_components/teams-list.tsxsrc/app/teams/_components/delete-team-dialog.tsx
📚 Learning: 2025-12-29T12:52:42.935Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T12:52:42.935Z
Learning: Applies to src/app/metric/_components/**/*.tsx : Metric dialog components have nearly identical wrapper patterns (5 files). Consider implementing a factory pattern or generic wrapper to reduce duplication across provider dialogs.
Applied to files:
src/app/teams/_components/edit-team-metric-card.tsxsrc/app/dashboard/[teamId]/_components/dashboard-metric-chart.tsxsrc/app/teams/[teamId]/_components/role-dialog.tsx
📚 Learning: 2025-12-29T21:27:04.176Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T21:27:04.176Z
Learning: Applies to src/app/teams/[teamId]/**/*.tsx : Use reusable canvas library patterns from src/lib/canvas/ (create-canvas-store.tsx, use-auto-save.ts, save-status.tsx, edge-action-buttons.tsx, floating-edge-utils.ts)
Applied to files:
src/app/teams/_components/edit-team-metric-card.tsxsrc/app/teams/_components/edit-team-dialog.tsxsrc/app/teams/_components/teams-list.tsxsrc/app/teams/[teamId]/_components/role-node.tsxsrc/app/dashboard/[teamId]/_components/dashboard-metric-chart.tsxsrc/app/teams/_components/delete-team-dialog.tsx
📚 Learning: 2025-12-29T12:52:42.935Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T12:52:42.935Z
Learning: Applies to src/app/teams/[teamId]/_components/**/*.{ts,tsx} : When adding new canvas node types: (1) Create node component in teams/[teamId]/_components/, (2) Add type to TeamNode union in types/canvas.ts, (3) Register in nodeTypes in team-canvas.tsx, (4) Update serialization in canvas-serialization.ts.
Applied to files:
src/app/teams/_components/edit-team-dialog.tsxsrc/app/teams/_components/teams-list.tsxsrc/app/teams/[teamId]/_components/role-node.tsxsrc/app/teams/[teamId]/_components/chart-node.tsx
📚 Learning: 2025-12-29T21:27:04.176Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T21:27:04.176Z
Learning: Applies to src/app/teams/[teamId]/_components/**/*.tsx : Auto-save canvas changes with 2-second debounce: markDirty() → debounce → serializeNodes/Edges → tRPC mutation, with beforeunload sendBeacon fallback
Applied to files:
src/app/teams/_components/edit-team-dialog.tsxsrc/app/teams/_components/delete-team-dialog.tsxsrc/app/teams/[teamId]/_components/chart-node.tsx
📚 Learning: 2025-12-29T12:52:42.935Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T12:52:42.935Z
Learning: Applies to src/app/teams/[teamId]/**/*.{ts,tsx} : Canvas auto-save system: Changes trigger markDirty() → Debounce 2s → serializeNodes/Edges → tRPC mutation. Include beforeunload sendBeacon fallback for unsaved changes.
Applied to files:
src/app/teams/_components/edit-team-dialog.tsxsrc/app/teams/[teamId]/_components/role-node.tsxsrc/app/teams/_components/delete-team-dialog.tsxsrc/app/teams/[teamId]/_components/chart-node.tsx
📚 Learning: 2025-12-29T21:27:04.176Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T21:27:04.176Z
Learning: Applies to src/app/teams/[teamId]/**/*.tsx : Use Zustand store with Context pattern for canvas state management as implemented in team-store.tsx; access via useTeamStore for selectors and useTeamStoreApi for callbacks
Applied to files:
src/app/teams/_components/edit-team-dialog.tsxsrc/app/teams/_components/teams-list.tsxsrc/app/teams/_components/delete-team-dialog.tsx
📚 Learning: 2025-12-29T21:27:04.176Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T21:27:04.176Z
Learning: Register new canvas node types in: node component in teams/[teamId]/_components/, TeamNode union in types/canvas.ts, nodeTypes in team-canvas.tsx, and serialization in canvas-serialization.ts
Applied to files:
src/app/teams/[teamId]/_components/role-node.tsx
📚 Learning: 2025-12-29T12:52:42.935Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T12:52:42.935Z
Learning: Applies to src/components/ui/**/*.{ts,tsx} : shadcn/ui components are maintained in src/components/ui/. Add new components using `npx shadcnlatest add [component-name]` CLI.
Applied to files:
src/app/dashboard/[teamId]/_components/dashboard-metric-chart.tsx
📚 Learning: 2025-12-29T12:52:42.935Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T12:52:42.935Z
Learning: Applies to **/*.{ts,tsx} : For client components using tRPC, use the React Query pattern with `import { api } from '@/trpc/react'` and access data via `api.[router].[procedure].useQuery()`. For server components, use direct calls with `import { api } from '@/trpc/server'` and await the result.
Applied to files:
src/app/teams/[teamId]/_components/role-dialog.tsx
📚 Learning: 2025-12-20T22:12:00.576Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-20T22:12:00.576Z
Learning: Applies to src/**/*.tsx : Prefer Server Components for initial data fetching; use Client Components ('use client') only for interactivity
Applied to files:
src/app/teams/[teamId]/_components/role-dialog.tsx
🧬 Code graph analysis (7)
src/app/member/[id]/_components/member-role-card.tsx (1)
src/app/dashboard/[teamId]/_components/dashboard-metric-card.tsx (1)
ReadOnlyMetricCard(125-162)
src/app/teams/_components/edit-team-metric-card.tsx (6)
src/lib/utils.ts (1)
cn(4-6)src/lib/platform-config.ts (1)
getPlatformConfig(94-103)src/components/ui/badge.tsx (1)
Badge(51-51)src/components/ui/tooltip.tsx (3)
Tooltip(62-62)TooltipTrigger(62-62)TooltipContent(62-62)src/app/dashboard/[teamId]/_components/metric-settings-dialog.tsx (1)
MetricSettingsDialog(45-250)src/components/ui/button.tsx (1)
Button(62-62)
src/app/teams/_components/edit-team-dialog.tsx (2)
src/components/role/role-card.tsx (2)
RoleCardData(28-42)RoleCard(329-329)src/app/teams/[teamId]/_components/role-dialog.tsx (1)
RoleDialog(66-607)
src/app/teams/_components/teams-list.tsx (2)
src/app/teams/_components/edit-team-dialog.tsx (1)
EditTeamDialog(57-357)src/app/teams/_components/delete-team-dialog.tsx (1)
DeleteTeamDialog(34-151)
src/app/dashboard/[teamId]/_components/dashboard-metric-chart.tsx (2)
src/components/ui/card.tsx (1)
Card(87-87)src/lib/utils.ts (1)
cn(4-6)
src/app/teams/[teamId]/_components/chart-node.tsx (1)
src/app/dashboard/[teamId]/_components/dashboard-metric-card.tsx (2)
ReadOnlyMetricCard(125-162)DashboardMetricCard(26-123)
src/app/teams/[teamId]/_components/role-dialog.tsx (6)
src/components/ui/dialog.tsx (5)
DialogContent(146-146)DialogHeader(149-149)DialogTitle(152-152)DialogDescription(147-147)DialogFooter(148-148)src/components/form-label-with-tooltip.tsx (1)
FormLabelWithTooltip(20-42)src/lib/role/role-constants.ts (1)
ROLE_FIELD_TOOLTIPS(6-21)src/components/ui/input.tsx (1)
Input(21-21)src/lib/utils.ts (1)
ROLE_COLORS(9-17)src/components/ui/select.tsx (5)
Select(178-178)SelectTrigger(186-186)SelectValue(187-187)SelectContent(179-179)SelectItem(181-181)
⏰ 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: claude-review
🔇 Additional comments (15)
src/app/dashboard/[teamId]/_components/dashboard-metric-chart.tsx (1)
239-239: LGTM! Consistent rounded corners styling.The addition of
rounded-xlaligns with the broader UI refresh across chart and card components in this PR.src/app/teams/_components/delete-team-dialog.tsx (1)
80-80: LGTM! Layout adjustment for header actions.The removal of absolute positioning allows the delete button to work alongside the new edit button in the team card header area, as indicated by the PR changes to teams-list.tsx.
src/app/teams/[teamId]/_components/chart-node.tsx (1)
108-108: Good simplification of container structure.Removing the extra wrapper div and using direct conditional rendering improves code clarity without affecting functionality. The
rounded-xlstyling provides consistent visual presentation.Also applies to: 146-153
src/components/form-label-with-tooltip.tsx (1)
30-30: Excellent UX improvement for required field indicators.Switching from marking optional fields with "(Optional)" text to marking required fields with a red asterisk follows standard web form conventions and reduces visual clutter.
src/app/teams/[teamId]/_components/role-node.tsx (1)
87-87: LGTM! Explicit sizing replaces variant prop.The removal of
variant="canvas"and addition of explicit dimensions viaclassNamealigns with the broader PR refactor that consolidates RoleCard styling. The 160×320px sizing maintains the expected canvas node dimensions.src/app/teams/_components/teams-list.tsx (1)
206-231: Well-structured hover state handling for dual action buttons.The CSS selector pattern using
has-[[data-delete-button]:hover,[data-edit-button]:hover]consistently handles hover interactions for both action buttons, preventing the card's primary hover effect when interacting with either button. The implementation correctly:
- Preserves existing delete button behavior
- Adds edit button with matching interaction patterns
- Maintains accessible link overlay with proper z-indexing
src/components/role/role-card.tsx (1)
262-266: Good conditional rendering for empty purpose.The change to only render the purpose block when
truncatedPurposeis truthy avoids displaying an empty paragraph element, improving the component's layout when no purpose is provided.src/app/member/[id]/_components/member-role-card.tsx (2)
17-83: Clean restructure with header/body/footer pattern.The component redesign effectively separates concerns with:
- Color-styled header with role title
- Body containing purpose and metric info
- Footer for effort points (when present)
- Metric chart section at bottom
The conditional rendering logic correctly handles the three states: chart available, metric assigned but no chart, or no KPI assigned.
62-71: Use explicit effortPoints comparison for consistency with codebase patterns.The condition
{role.effortPoints && ...}will skip rendering wheneffortPointsis0. While the Fibonacci scale documentation suggests minimum meaningful values start at 1, other components in the codebase (e.g.,role-assignment.tsx,member-card.tsx) explicitly checkrole.effortPoints && role.effortPoints > 0. For consistency, either adopt the explicit check or document the intentional behavior.⛔ Skipped due to learnings
Learnt from: CR Repo: drifter089/orgOS PR: 0 File: CLAUDE.md:0-0 Timestamp: 2025-12-29T12:52:42.935Z Learning: Applies to src/app/teams/[teamId]/_components/role-node.tsx,src/app/teams/[teamId]/_components/public-role-node.tsx : These role node components are 75% identical and should be consolidated. Extract shared `RoleNodeTemplate` component with `isEditable` prop to DRY up the code.Learnt from: CR Repo: drifter089/orgOS PR: 0 File: CLAUDE.md:0-0 Timestamp: 2025-12-29T12:52:42.935Z Learning: Applies to src/components/dashboard-metric-card.tsx,src/app/dashboard/[teamId]/_components/public-dashboard-metric-card.tsx : Dashboard metric cards are duplicated with public variant. Consolidate into single component with `readOnly` mode prop instead of maintaining separate components.Learnt from: CR Repo: drifter089/orgOS PR: 0 File: GEMINI.md:0-0 Timestamp: 2025-12-20T22:12:00.576Z Learning: Applies to src/app/teams/[teamId]/**/*.tsx : React Flow nodes must store minimal data (e.g., just `roleId`); fetch full Role data from TanStack Query cache in the Node component to keep canvas and sidebars in syncLearnt from: CR Repo: drifter089/orgOS PR: 0 File: CLAUDE.md:0-0 Timestamp: 2025-12-29T21:27:04.176Z Learning: Applies to src/hooks/**/*.ts : For role-metric cache updates, optimistically update both role cache (role.getByTeamId) and dashboard cache (dashboard.getDashboardCharts) to maintain UI consistencyLearnt from: CR Repo: drifter089/orgOS PR: 0 File: CLAUDE.md:0-0 Timestamp: 2025-12-29T21:27:04.176Z Learning: Applies to src/app/teams/[teamId]/_components/**/*.tsx : Implement cache-first node pattern for role nodes: store only roleId in node data, fetch display data from TanStack Query cache using useRoleData hookLearnt from: CR Repo: drifter089/orgOS PR: 0 File: CLAUDE.md:0-0 Timestamp: 2025-12-29T12:52:42.935Z Learning: Applies to src/app/metric/_components/**/*.tsx : Metric dialog components have nearly identical wrapper patterns (5 files). Consider implementing a factory pattern or generic wrapper to reduce duplication across provider dialogs.Learnt from: CR Repo: drifter089/orgOS PR: 0 File: GEMINI.md:0-0 Timestamp: 2025-12-20T22:12:00.576Z Learning: Applies to src/app/teams/[teamId]/**/*.tsx : Avoid modifying `enrichNodesWithRoleData` flow without understanding the complete canvas serialization logic for saving/loading React Flow nodes to the databaseLearnt from: CR Repo: drifter089/orgOS PR: 0 File: CLAUDE.md:0-0 Timestamp: 2025-12-29T12:52:42.935Z Learning: Applies to src/app/dashboard/[teamId]/**/*.{ts,tsx} : Dashboard cache updates for role-metric assignments must update both `role.getByTeamId` and `dashboard.getDashboardCharts` caches during mutations. Use onMutate for optimistic updates on both caches, then invalidate both on success.Learnt from: CR Repo: drifter089/orgOS PR: 0 File: CLAUDE.md:0-0 Timestamp: 2025-12-29T12:52:42.935Z Learning: Applies to src/lib/metrics/**/*.ts : Goal calculation utility is 271 lines and should be refactored to approximately 50 lines. Simplify logic and extract helper functions.Learnt from: CR Repo: drifter089/orgOS PR: 0 File: CLAUDE.md:0-0 Timestamp: 2025-12-29T21:27:04.176Z Learning: Applies to src/app/(metric|dashboard)/**/*.tsx : Use three-stage metrics transformation: API → DataPoints (DataIngestionTransformer), DataPoints → ChartConfig (ChartTransformer), ChartConfig → UI (DashboardMetricChart)src/app/teams/_components/edit-team-dialog.tsx (2)
95-136: Well-implemented optimistic updates with proper rollback.The mutation correctly:
- Cancels in-flight queries before optimistic update
- Stores previous state for rollback
- Updates both
getAllandgetByIdcaches- Rolls back on error
- Invalidates both caches on settle
This follows the established patterns in the codebase for cache consistency.
345-354: Clean controlled dialog pattern for role editing.The RoleDialog is rendered outside the main Dialog to avoid nested dialog issues, with state managed via
editingRoleId. TheonOpenChangecallback properly clears the editing state when closed.src/app/teams/[teamId]/_components/role-dialog.tsx (4)
70-76: Good controlled/uncontrolled state pattern.The implementation correctly handles both controlled (
openprop provided) and uncontrolled (internal state) modes. The non-null assertion on line 76 is safe becauseisControlledguaranteesonOpenChangeexists when used.
130-147: Efficient memoization for member lookups.The
selectedMemberandselectedMemberStatscomputations are properly memoized with correct dependencies, avoiding unnecessary recalculations during re-renders.
391-481: Enhanced member selection with workload visibility.The member dropdown now shows role count and effort points for each member, helping users make informed assignment decisions. The selected member preview in the trigger provides immediate feedback with the same stats.
242-257: Dynamic header color enhances visual feedback.The header background color updates in real-time as users select different role colors, providing immediate visual feedback that helps users understand how the role will appear on the canvas.
| <div className="flex shrink-0 items-center"> | ||
| <Tooltip> | ||
| <TooltipTrigger asChild> | ||
| <MetricSettingsDialog | ||
| dashboardChart={dashboardChart} | ||
| teamId={teamId} | ||
| trigger={ | ||
| <Button | ||
| variant="outline" | ||
| size="icon" | ||
| className="border-border hover:border-primary/50 h-7 w-7 opacity-0 transition-all duration-200 group-hover:opacity-100 hover:scale-105" | ||
| onClick={(e) => e.stopPropagation()} | ||
| > | ||
| <Settings className="h-3.5 w-3.5" /> | ||
| </Button> | ||
| } | ||
| /> | ||
| </TooltipTrigger> | ||
| <TooltipContent side="top">Metric settings</TooltipContent> | ||
| </Tooltip> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tooltip may not function correctly with this nesting structure.
The TooltipTrigger wraps MetricSettingsDialog rather than directly wrapping the Button. Since MetricSettingsDialog renders a dialog with its own trigger handling, the tooltip may not display properly or could interfere with the dialog's open/close behavior.
Consider restructuring so the tooltip wraps only the button trigger:
Proposed fix
<div className="flex shrink-0 items-center">
- <Tooltip>
- <TooltipTrigger asChild>
- <MetricSettingsDialog
- dashboardChart={dashboardChart}
- teamId={teamId}
- trigger={
+ <MetricSettingsDialog
+ dashboardChart={dashboardChart}
+ teamId={teamId}
+ trigger={
+ <Tooltip>
+ <TooltipTrigger asChild>
<Button
variant="outline"
size="icon"
className="border-border hover:border-primary/50 h-7 w-7 opacity-0 transition-all duration-200 group-hover:opacity-100 hover:scale-105"
onClick={(e) => e.stopPropagation()}
>
<Settings className="h-3.5 w-3.5" />
</Button>
- }
- />
- </TooltipTrigger>
- <TooltipContent side="top">Metric settings</TooltipContent>
- </Tooltip>
+ </TooltipTrigger>
+ <TooltipContent side="top">Metric settings</TooltipContent>
+ </Tooltip>
+ }
+ />
</div>📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| <div className="flex shrink-0 items-center"> | |
| <Tooltip> | |
| <TooltipTrigger asChild> | |
| <MetricSettingsDialog | |
| dashboardChart={dashboardChart} | |
| teamId={teamId} | |
| trigger={ | |
| <Button | |
| variant="outline" | |
| size="icon" | |
| className="border-border hover:border-primary/50 h-7 w-7 opacity-0 transition-all duration-200 group-hover:opacity-100 hover:scale-105" | |
| onClick={(e) => e.stopPropagation()} | |
| > | |
| <Settings className="h-3.5 w-3.5" /> | |
| </Button> | |
| } | |
| /> | |
| </TooltipTrigger> | |
| <TooltipContent side="top">Metric settings</TooltipContent> | |
| </Tooltip> | |
| <div className="flex shrink-0 items-center"> | |
| <MetricSettingsDialog | |
| dashboardChart={dashboardChart} | |
| teamId={teamId} | |
| trigger={ | |
| <Tooltip> | |
| <TooltipTrigger asChild> | |
| <Button | |
| variant="outline" | |
| size="icon" | |
| className="border-border hover:border-primary/50 h-7 w-7 opacity-0 transition-all duration-200 group-hover:opacity-100 hover:scale-105" | |
| onClick={(e) => e.stopPropagation()} | |
| > | |
| <Settings className="h-3.5 w-3.5" /> | |
| </Button> | |
| </TooltipTrigger> | |
| <TooltipContent side="top">Metric settings</TooltipContent> | |
| </Tooltip> | |
| } | |
| /> | |
| </div> |
🤖 Prompt for AI Agents
In @src/app/teams/_components/edit-team-metric-card.tsx around lines 57 - 76,
The Tooltip currently wraps MetricSettingsDialog via TooltipTrigger which can
interfere with the dialog's own trigger handling; instead, wrap only the Button
with TooltipTrigger (asChild) and pass that same Button element into
MetricSettingsDialog via its trigger prop (or render MetricSettingsDialog
alongside but not as the TooltipTrigger child), keeping the onClick
stopPropagation and button classes intact so the tooltip and the dialog triggers
operate independently (update references: TooltipTrigger, MetricSettingsDialog,
Button, TooltipContent).
| <div | ||
| className={cn( | ||
| "bg-card h-full w-full rounded-xl border-2 p-6 shadow-md", | ||
| "bg-card h-full w-full rounded-xl border p-6 shadow-md", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
cat -n src/app/teams/[teamId]/_components/chart-node.tsx | head -80Repository: drifter089/orgOS
Length of output: 3037
🏁 Script executed:
rg -n "border-2" --type=tsx --glob="**/teams/**/*node*.tsx" -C2Repository: drifter089/orgOS
Length of output: 87
🏁 Script executed:
rg -n "border" --type=tsx src/app/teams/[teamId]/_components/chart-node.tsx | head -20Repository: drifter089/orgOS
Length of output: 87
🏁 Script executed:
rg -n "border" src/app/teams/[teamId]/_components/chart-node.tsx | grep -E "border-[0-9]|border['\"]"Repository: drifter089/orgOS
Length of output: 118
🏁 Script executed:
rg -n "border" src/app/dashboard/[teamId]/_components/dashboard-metric-card.tsx | head -30Repository: drifter089/orgOS
Length of output: 42
🏁 Script executed:
rg -rn "border-2" --glob="**/*.tsx" src/app/dashboard src/app/teams | grep -E "card|metric|node" | head -20Repository: drifter089/orgOS
Length of output: 256
🏁 Script executed:
git log --oneline -20 -- src/app/teams/[teamId]/_components/chart-node.tsxRepository: drifter089/orgOS
Length of output: 126
🏁 Script executed:
cat -n src/app/dashboard/[teamId]/_components/dashboard-metric-card.tsx | head -100Repository: drifter089/orgOS
Length of output: 4093
🏁 Script executed:
cat -n src/app/teams/[teamId]/_components/chart-node.tsx | sed -n '50,170p'Repository: drifter089/orgOS
Length of output: 3651
Confirm whether the border width reduction in the fallback state was intentional.
Line 61's fallback container uses border (1px) instead of border-2 (2px). If this was a deliberate simplification for the error state, that's fine. If it was unintended, consider restoring border-2 for visual consistency with the node's interactive handles (line 43).
🤖 Prompt for AI Agents
In @src/app/teams/[teamId]/_components/chart-node.tsx at line 61, The fallback
container in ChartNode component uses the utility class string "bg-card h-full
w-full rounded-xl border p-6 shadow-md" which applies a 1px border, while the
node's interactive handles use "border-2" earlier (line ~43); confirm whether
the 1px border was intentional and, if not, change that class string to use
"border-2" for visual consistency (update the JSX element in
src/app/teams/[teamId]/_components/chart-node.tsx that renders the fallback
container to replace "border" with "border-2").
- Add error and success toast notifications for team updates - Fix useEffect dependency to use stable form.reset reference - Replace tooltip wrapper with title attribute on metric settings button
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
src/app/teams/_components/edit-team-metric-card.tsx (1)
17-71: Consider consolidating metric card variants.The implementation is solid, but this introduces another metric card variant alongside existing dashboard metric cards. Based on learnings, metric cards should be consolidated into a single component with variant/mode props (e.g.,
readOnly,compact) rather than maintaining separate components.As this is a new feature and the duplication is manageable for now, this consolidation can be deferred. However, if you add more metric card variants in the future, consider extracting a shared
MetricCardcomponent that accepts:
variant: "dashboard" | "edit" | "public"showEyeIcon: booleanshowSettingsButton: boolean- Other display options
Based on learnings, this pattern has been identified for dashboard metric cards and would benefit from consolidation.
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
src/app/teams/_components/edit-team-dialog.tsxsrc/app/teams/_components/edit-team-metric-card.tsx
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (GEMINI.md)
Use TypeScript 5.9 with strict type checking for all frontend and backend code
Files:
src/app/teams/_components/edit-team-metric-card.tsxsrc/app/teams/_components/edit-team-dialog.tsx
src/**/*.tsx
📄 CodeRabbit inference engine (GEMINI.md)
Prefer Server Components for initial data fetching; use Client Components ('use client') only for interactivity
Files:
src/app/teams/_components/edit-team-metric-card.tsxsrc/app/teams/_components/edit-team-dialog.tsx
src/**/*/*.tsx
📄 CodeRabbit inference engine (GEMINI.md)
Client Components must use
import { api } from '@/trpc/react'for standard HTTP/Hooks wrapper
Files:
src/app/teams/_components/edit-team-metric-card.tsxsrc/app/teams/_components/edit-team-dialog.tsx
**/*.tsx
📄 CodeRabbit inference engine (GEMINI.md)
Use Tailwind CSS 4 for styling with shadcn/ui and Radix UI primitive components
Files:
src/app/teams/_components/edit-team-metric-card.tsxsrc/app/teams/_components/edit-team-dialog.tsx
src/app/**/*.tsx
📄 CodeRabbit inference engine (CLAUDE.md)
src/app/**/*.tsx: Use the dual tRPC API pattern: direct calls in Server Components (api.team.getById) for 10x faster performance, and React hooks in Client Components (api.team.getById.useQuery)
Use getUserDisplayName(userId, members) utility (client-side sync) from @/lib/helpers/get-user-name for displaying user names in components
Files:
src/app/teams/_components/edit-team-metric-card.tsxsrc/app/teams/_components/edit-team-dialog.tsx
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Use @trivago/prettier-plugin-sort-imports with inline type imports for import organization
Files:
src/app/teams/_components/edit-team-metric-card.tsxsrc/app/teams/_components/edit-team-dialog.tsx
🧠 Learnings (23)
📓 Common learnings
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T12:52:42.935Z
Learning: Applies to src/app/teams/[teamId]/_components/role-node.tsx,src/app/teams/[teamId]/_components/public-role-node.tsx : These role node components are 75% identical and should be consolidated. Extract shared `RoleNodeTemplate` component with `isEditable` prop to DRY up the code.
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T12:52:42.935Z
Learning: Applies to src/components/dashboard-metric-card.tsx,src/app/dashboard/[teamId]/_components/public-dashboard-metric-card.tsx : Dashboard metric cards are duplicated with public variant. Consolidate into single component with `readOnly` mode prop instead of maintaining separate components.
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-20T22:12:00.576Z
Learning: Applies to src/app/teams/[teamId]/**/*.tsx : React Flow nodes must store minimal data (e.g., just `roleId`); fetch full Role data from TanStack Query cache in the Node component to keep canvas and sidebars in sync
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T21:27:04.176Z
Learning: Applies to src/app/teams/[teamId]/_components/**/*.tsx : Implement cache-first node pattern for role nodes: store only roleId in node data, fetch display data from TanStack Query cache using useRoleData hook
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T21:27:04.176Z
Learning: Applies to src/hooks/**/*.ts : For role-metric cache updates, optimistically update both role cache (role.getByTeamId) and dashboard cache (dashboard.getDashboardCharts) to maintain UI consistency
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T21:27:04.176Z
Learning: Applies to src/app/teams/[teamId]/**/*.tsx : Use shared React Flow primitives (BaseNode, BaseHandle, ZoomSlider) from src/components/react-flow/ in all canvas implementations
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-20T22:12:00.576Z
Learning: Applies to src/app/teams/[teamId]/**/*.tsx : Avoid modifying `enrichNodesWithRoleData` flow without understanding the complete canvas serialization logic for saving/loading React Flow nodes to the database
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T21:27:04.176Z
Learning: Applies to src/app/metric/_components/**/*.tsx : Use shared MetricDialogBase component from base/ for all metric dialog implementations
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T21:27:04.176Z
Learning: Applies to src/app/(teams|org)/**/*.tsx : Use shared MembersList component at src/components/member/member-list.tsx for displaying members in canvas sidebar and org page; it includes getMemberDisplayInfo() utility for initials/name logic
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T12:52:42.935Z
Learning: Applies to src/app/dashboard/[teamId]/**/*.{ts,tsx} : Dashboard cache updates for role-metric assignments must update both `role.getByTeamId` and `dashboard.getDashboardCharts` caches during mutations. Use onMutate for optimistic updates on both caches, then invalidate both on success.
📚 Learning: 2025-12-29T12:52:42.935Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T12:52:42.935Z
Learning: Applies to src/components/dashboard-metric-card.tsx,src/app/dashboard/[teamId]/_components/public-dashboard-metric-card.tsx : Dashboard metric cards are duplicated with public variant. Consolidate into single component with `readOnly` mode prop instead of maintaining separate components.
Applied to files:
src/app/teams/_components/edit-team-metric-card.tsx
📚 Learning: 2025-12-29T21:27:04.176Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T21:27:04.176Z
Learning: Applies to src/app/metric/_components/**/*.tsx : Create metric dialogs with pattern: [Provider]MetricDialog.tsx (dialog wrapper) + [Provider]MetricContent.tsx (form content) in src/app/metric/_components/[provider]/, then register in index.ts
Applied to files:
src/app/teams/_components/edit-team-metric-card.tsxsrc/app/teams/_components/edit-team-dialog.tsx
📚 Learning: 2025-12-29T21:27:04.176Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T21:27:04.176Z
Learning: Applies to src/app/metric/_components/**/*.tsx : Use shared MetricDialogBase component from base/ for all metric dialog implementations
Applied to files:
src/app/teams/_components/edit-team-metric-card.tsxsrc/app/teams/_components/edit-team-dialog.tsx
📚 Learning: 2025-12-29T12:52:42.935Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T12:52:42.935Z
Learning: Applies to src/app/metric/_components/**/*.tsx : Metric dialog components should follow the pattern: [Provider]MetricDialog.tsx (dialog wrapper) and [Provider]MetricContent.tsx (form content). Register in src/app/metric/_components/index.ts and inherit from shared MetricDialogBase.
Applied to files:
src/app/teams/_components/edit-team-metric-card.tsx
📚 Learning: 2025-12-29T21:27:04.176Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T21:27:04.176Z
Learning: Applies to src/app/(metric|dashboard)/**/*.tsx : Use three-stage metrics transformation: API → DataPoints (DataIngestionTransformer), DataPoints → ChartConfig (ChartTransformer), ChartConfig → UI (DashboardMetricChart)
Applied to files:
src/app/teams/_components/edit-team-metric-card.tsx
📚 Learning: 2025-12-29T12:52:42.935Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T12:52:42.935Z
Learning: Applies to src/app/dashboard/[teamId]/**/*.{ts,tsx} : Dashboard cache updates for role-metric assignments must update both `role.getByTeamId` and `dashboard.getDashboardCharts` caches during mutations. Use onMutate for optimistic updates on both caches, then invalidate both on success.
Applied to files:
src/app/teams/_components/edit-team-metric-card.tsx
📚 Learning: 2025-12-29T12:52:42.935Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T12:52:42.935Z
Learning: Applies to src/app/metric/_components/**/*.tsx : Metric dialog components have nearly identical wrapper patterns (5 files). Consider implementing a factory pattern or generic wrapper to reduce duplication across provider dialogs.
Applied to files:
src/app/teams/_components/edit-team-metric-card.tsx
📚 Learning: 2025-12-29T12:52:42.935Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T12:52:42.935Z
Learning: Applies to src/app/teams/[teamId]/_components/role-node.tsx,src/app/teams/[teamId]/_components/public-role-node.tsx : These role node components are 75% identical and should be consolidated. Extract shared `RoleNodeTemplate` component with `isEditable` prop to DRY up the code.
Applied to files:
src/app/teams/_components/edit-team-metric-card.tsxsrc/app/teams/_components/edit-team-dialog.tsx
📚 Learning: 2025-12-29T21:27:04.176Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T21:27:04.176Z
Learning: Applies to src/hooks/**/*.ts : For role-metric cache updates, optimistically update both role cache (role.getByTeamId) and dashboard cache (dashboard.getDashboardCharts) to maintain UI consistency
Applied to files:
src/app/teams/_components/edit-team-metric-card.tsx
📚 Learning: 2025-12-20T22:12:00.576Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-20T22:12:00.576Z
Learning: Applies to src/app/teams/[teamId]/**/*.ts : Canvas changes must be debounced (2s) and saved via `editSession` logic to handle concurrent team edits safely
Applied to files:
src/app/teams/_components/edit-team-metric-card.tsxsrc/app/teams/_components/edit-team-dialog.tsx
📚 Learning: 2025-12-29T21:27:04.176Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T21:27:04.176Z
Learning: Applies to src/app/teams/[teamId]/**/*.tsx : Use reusable canvas library patterns from src/lib/canvas/ (create-canvas-store.tsx, use-auto-save.ts, save-status.tsx, edge-action-buttons.tsx, floating-edge-utils.ts)
Applied to files:
src/app/teams/_components/edit-team-metric-card.tsxsrc/app/teams/_components/edit-team-dialog.tsx
📚 Learning: 2025-12-29T21:27:04.176Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T21:27:04.176Z
Learning: Applies to src/app/teams/[teamId]/**/*.tsx : Use shared React Flow primitives (BaseNode, BaseHandle, ZoomSlider) from src/components/react-flow/ in all canvas implementations
Applied to files:
src/app/teams/_components/edit-team-metric-card.tsxsrc/app/teams/_components/edit-team-dialog.tsx
📚 Learning: 2025-12-29T21:27:04.176Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T21:27:04.176Z
Learning: Applies to src/app/teams/[teamId]/_components/**/*.tsx : Auto-save canvas changes with 2-second debounce: markDirty() → debounce → serializeNodes/Edges → tRPC mutation, with beforeunload sendBeacon fallback
Applied to files:
src/app/teams/_components/edit-team-dialog.tsx
📚 Learning: 2025-12-20T22:12:00.576Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-20T22:12:00.576Z
Learning: Applies to src/app/teams/[teamId]/**/*.tsx : React Flow nodes must store minimal data (e.g., just `roleId`); fetch full Role data from TanStack Query cache in the Node component to keep canvas and sidebars in sync
Applied to files:
src/app/teams/_components/edit-team-dialog.tsx
📚 Learning: 2025-12-29T12:52:42.935Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T12:52:42.935Z
Learning: Applies to src/app/teams/[teamId]/_components/**/*.{ts,tsx} : When adding new canvas node types: (1) Create node component in teams/[teamId]/_components/, (2) Add type to TeamNode union in types/canvas.ts, (3) Register in nodeTypes in team-canvas.tsx, (4) Update serialization in canvas-serialization.ts.
Applied to files:
src/app/teams/_components/edit-team-dialog.tsx
📚 Learning: 2025-12-29T12:52:42.935Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T12:52:42.935Z
Learning: Applies to src/app/teams/[teamId]/**/*.{ts,tsx} : Canvas auto-save system: Changes trigger markDirty() → Debounce 2s → serializeNodes/Edges → tRPC mutation. Include beforeunload sendBeacon fallback for unsaved changes.
Applied to files:
src/app/teams/_components/edit-team-dialog.tsx
📚 Learning: 2025-12-20T22:12:00.576Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-20T22:12:00.576Z
Learning: Applies to src/app/teams/[teamId]/**/*.tsx : Avoid modifying `enrichNodesWithRoleData` flow without understanding the complete canvas serialization logic for saving/loading React Flow nodes to the database
Applied to files:
src/app/teams/_components/edit-team-dialog.tsx
📚 Learning: 2025-12-20T22:12:00.576Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-20T22:12:00.576Z
Learning: Applies to src/server/api/routers/**/*.ts : Be careful when modifying team save logic related to `EditSession` model, which handles locking for concurrent team editing
Applied to files:
src/app/teams/_components/edit-team-dialog.tsx
📚 Learning: 2025-12-29T21:27:04.176Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T21:27:04.176Z
Learning: Applies to src/app/teams/[teamId]/**/*.tsx : Use Zustand store with Context pattern for canvas state management as implemented in team-store.tsx; access via useTeamStore for selectors and useTeamStoreApi for callbacks
Applied to files:
src/app/teams/_components/edit-team-dialog.tsx
📚 Learning: 2025-12-29T12:52:42.935Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T12:52:42.935Z
Learning: Applies to src/app/teams/[teamId]/**/*.{ts,tsx} : Use Zustand store with context pattern (TeamStoreContext) for state management. Access store state via `useTeamStore()` selector hook and use `useTeamStoreApi()` in callbacks to avoid stale closures.
Applied to files:
src/app/teams/_components/edit-team-dialog.tsx
📚 Learning: 2025-12-29T21:27:04.176Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T21:27:04.176Z
Learning: Applies to src/app/teams/[teamId]/_components/**/*.tsx : Implement cache-first node pattern for role nodes: store only roleId in node data, fetch display data from TanStack Query cache using useRoleData hook
Applied to files:
src/app/teams/_components/edit-team-dialog.tsx
📚 Learning: 2025-12-29T12:52:42.935Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T12:52:42.935Z
Learning: Applies to src/app/teams/[teamId]/**/*.{ts,tsx} : Cache-first node system: Role nodes store only `roleId` in node.data. Display data must be fetched from TanStack Query cache using the `useRoleData()` hook which queries the `role.getByTeamId` procedure.
Applied to files:
src/app/teams/_components/edit-team-dialog.tsx
🧬 Code graph analysis (1)
src/app/teams/_components/edit-team-metric-card.tsx (5)
src/lib/utils.ts (1)
cn(4-6)src/lib/platform-config.ts (1)
getPlatformConfig(94-103)src/components/ui/badge.tsx (1)
Badge(51-51)src/app/dashboard/[teamId]/_components/metric-settings-dialog.tsx (1)
MetricSettingsDialog(45-250)src/components/ui/button.tsx (1)
Button(62-62)
⏰ 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: claude-review
🔇 Additional comments (4)
src/app/teams/_components/edit-team-dialog.tsx (4)
69-76: Excellent use of lazy loading for performance.The
enabled: openpattern on all three queries ensures data is only fetched when the dialog is opened, avoiding unnecessary network requests. This is a performance best practice for modal/dialog components.
86-96: Proper form reset pattern.Extracting the stable
resetreference and using it in theuseEffectdependencies is correct. This ensures the form resets when the dialog opens with fresh team data, while avoiding unnecessary effect re-runs.
98-145: Well-implemented optimistic updates.The mutation properly:
- Cancels in-flight queries to prevent race conditions
- Updates both
team.getAllandteam.getByIdcaches optimistically- Rolls back changes on error with preserved context
- Provides user feedback via toast notifications
- Invalidates queries on settle to ensure consistency
This follows tRPC and TanStack Query best practices for optimistic UI.
354-363: Controlled RoleDialog integration looks correct.The controlled
openprop pattern withonOpenChangecallback properly manages the editing state. The dialog only renders wheneditingRoleIdis set, and the open state is computed from the presence ofeditingRoleId.
Pull Request Review - PR #352OverviewThis PR adds a team edit dialog with comprehensive role and metric overview functionality. The implementation includes optimistic updates, improved UI components, and better UX. ✅ Strengths1. Excellent Code Organization
2. Optimistic Updates 3. Performance Optimizations
4. Improved UX
5. Accessibility
🔍 Issues and Concerns1. Missing Query Enabled Flag
2. Stale Closure in Callbacks
3. Form Reset Effect Dependency
4. Removed variant Prop
5. Chart Node Border Change 🤔
6. Role Dialog Complexity 📊
7. Missing Error Handling 🛡️
🚀 PerformancePositive:
Improvements:
🔒 SecurityGood:
Verify:
📝 Minor Issues
📊 Test CoverageNo test files visible. Tests would be valuable for:
🎯 RecommendationsHigh Priority:
Medium Priority: Low Priority: ✨ Overall AssessmentSolid PR with good architectural decisions following CLAUDE.md patterns:
Main concerns are minor optimizations and missing error handling. Recommendation: Approve with requested changes 📚 Code Quality: 8/10
Great work! 🎉 |
- Remove useCallback wrapper for onSubmit (mutation is stable) - Add isError states for team, roles, and charts queries - Display error messages when queries fail
Code ReviewThank you for this feature implementation! The edit team dialog is a solid addition that improves team management UX. Here's my detailed feedback: ✅ StrengthsArchitecture & Code Quality
Data Management
UX Improvements
🔍 Issues & Recommendations1. RoleDialog Layout Changes (High Priority)Issue: The RoleDialog has been significantly refactored with a new 2-column grid layout that may affect mobile responsiveness. // Old: Single column, mobile-friendly
<DialogContent className="max-h-[90vh] overflow-y-auto sm:max-w-[31rem]">
// New: 3-column grid
<DialogContent className="gap-0 p-0 sm:max-w-3xl">
<div className="grid grid-cols-1 gap-6 p-6 md:grid-cols-3">Recommendation: Test the RoleDialog on mobile devices (< 768px) to ensure the form fields remain usable. Consider adding responsive breakpoints or reverting to single-column on mobile. 2. Member Stats Query Missing Type SafetyIssue: The const { data: memberStats } = api.organization.getMemberStats.useQuery();Recommendation: Verify this endpoint exists and is properly typed. If this is a new endpoint added in this PR, ensure:
3. RoleCard Component ComplexityIssue: The refactored // Data priority: override > direct > cache > pending
const role = roleDataOverride ?? directRole ?? roleFromCache;Recommendation:
4. Missing Test CoverageIssue: No test files were added for the new Recommendation: Add Playwright E2E tests covering:
Example test structure: test('should open edit team dialog and update team name', async ({ authenticatedPage }) => {
await authenticatedPage.goto('/org');
await authenticatedPage.click('[data-edit-button]');
// ... test implementation
});5. Accessibility ConcernsIssues:
Recommendations:
6. Performance ConsiderationIssue: The Current: const { data: roles } = api.role.getByTeamId.useQuery({ teamId }, { enabled: open });
const { data: dashboardCharts } = api.dashboard.getDashboardCharts.useQuery({ teamId }, { enabled: open });Recommendation: These queries might already be cached from the team page. Verify that TanStack Query's cache is being utilized effectively. Consider adding 7. Styling ConsistencyIssue: Some minor styling inconsistencies:
Recommendation: Establish consistent border radius and width conventions per the project's design system. 8. Chart Node Wrapper RemovedIssue: In chart-node.tsx, a wrapper div with styling was removed: // Removed:
<div className="h-full overflow-hidden rounded-lg">
<ReadOnlyMetricCard ... />
</div>
// New: Direct component
<ReadOnlyMetricCard dashboardChart={dashboardMetric} />Recommendation: Verify that chart metrics still display correctly on the canvas. The overflow and rounded styling might be needed for proper visual containment. 9. Unused Prop RemovalIssue: The - variant="list"Recommendation: Verify that all RoleCard instances still display correctly. If the variant prop is truly unused, remove it from the RoleCard type definition as well to avoid confusion. 🔒 Security✅ No security concerns identified
🎯 Testing ChecklistBefore merging, please verify:
📝 DocumentationConsider updating CLAUDE.md to document:
SummaryThis is a well-implemented feature that follows the codebase conventions. The main concerns are:
The optimistic updates, error handling, and loading states are all implemented correctly. With the testing recommendations addressed, this will be a solid addition to the codebase. Rating: ⭐⭐⭐⭐ (4/5) - Good implementation, needs testing and mobile verification before merge. |
Summary
Adds an edit button to team cards on the /org page that opens a scrollable dialog for editing team details, viewing all roles, and viewing all metrics.
Key Changes
EditTeamDialogcomponent with team name/description formEditTeamMetricCardcomponent (simplified metric card without eye icon)Summary by CodeRabbit
New Features
Improvements
✏️ Tip: You can customize this high-level summary in your review settings.