-
Notifications
You must be signed in to change notification settings - Fork 3
Add Projects Grid to Users page #1708
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
base: develop
Are you sure you want to change the base?
Conversation
📝 WalkthroughWalkthroughThis update introduces a tabbed interface to the user detail view, separating profile and project information into distinct tabs. New React components and a GraphQL query are added to support dynamic user profile and project displays, including live local time and paginated project lists. Type policies are updated for Apollo cache handling. Changes
Possibly related PRs
📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (7)
✅ Files skipped from review due to trivial changes (1)
🚧 Files skipped from review as they are similar to previous changes (3)
🧰 Additional context used🧠 Learnings (2)📓 Common learnings
src/scenes/Users/Detail/UserDetail.tsx (3)
🪛 Biome (1.9.4)src/scenes/Users/Detail/UserDetail.tsx[error] 8-8: Do not shadow the global "Error" property. Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global. (lint/suspicious/noShadowRestrictedNames) 🔇 Additional comments (4)
✨ Finishing Touches
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
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: 2
🧹 Nitpick comments (3)
src/scenes/Users/Detail/Tabs/Projects/UserProjectPanel/UserProjectList.graphql (1)
15-17
: Remove redundant fragment wrapperThe
userProjectDataGridRow
fragment only spreadsprojectDataGridRow
without adding any fields. This adds unnecessary indirection.- ...userProjectDataGridRow + ...projectDataGridRowThen remove the redundant fragment definition:
-fragment userProjectDataGridRow on Project { - ...projectDataGridRow -}src/scenes/Users/Detail/Tabs/Profile/UserDetailProfile.tsx (2)
81-89
: Consider adding accessibility attributes to the time display.The LocalTime component correctly handles timezone formatting, but could benefit from accessibility improvements for screen readers.
- return <>{formatted}</>; + return <span title={`Local time in ${timezone}`}>{formatted}</span>;
99-127
: Consider simplifying the loading state logic.The DisplayProperty wrapper has complex loading logic that could be streamlined. The skeleton structure with two Typography components may not perfectly match the actual content structure.
const DisplayProperty = (props: DisplaySimplePropertyProps) => !props.value && !props.loading ? null : ( <DisplaySimpleProperty variant="body1" {...{ component: 'div' }} {...props} loading={ - props.loading ? ( - <> - <Typography variant="body2"> - <Skeleton width="10%" /> - </Typography> - <Typography variant="body1"> - <Skeleton width="40%" /> - </Typography> - </> - ) : null + props.loading ? <Skeleton width="60%" /> : null } LabelProps={{ color: 'textSecondary', variant: 'body2', ...props.LabelProps, }} ValueProps={{ color: 'textPrimary', ...props.ValueProps, }} /> );
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
src/api/schema/typePolicies/typePolicies.base.ts
(1 hunks)src/scenes/Users/Detail/Tabs/Profile/UserDetailProfile.tsx
(1 hunks)src/scenes/Users/Detail/Tabs/Projects/UserDetailProjects.tsx
(1 hunks)src/scenes/Users/Detail/Tabs/Projects/UserProjectPanel/UserProjectList.graphql
(1 hunks)src/scenes/Users/Detail/Tabs/Projects/UserProjectPanel/UserProjectsPanel.tsx
(1 hunks)src/scenes/Users/Detail/UserDetail.tsx
(3 hunks)
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: CarsonF
PR: SeedCompany/cord-field#1604
File: src/scenes/Root/Notifications/Notifications.tsx:35-51
Timestamp: 2024-10-21T15:15:09.113Z
Learning: In the `Notifications` component (`src/scenes/Root/Notifications/Notifications.tsx`), Apollo Client automatically updates the notification's unread status in the cache when the mutation returns the updated notification, so manually updating the cache in the `update` function is unnecessary.
src/scenes/Users/Detail/UserDetail.tsx (2)
Learnt from: CarsonF
PR: SeedCompany/cord-field#1604
File: src/components/Feature.tsx:12-19
Timestamp: 2024-10-21T15:17:35.618Z
Learning: In `src/components/Feature.tsx`, the `Feature` component uses `useFeatureFlagPayload` and the `match` prop to determine feature availability, which differs from the `useFeatureEnabled` hook.
Learnt from: CarsonF
PR: SeedCompany/cord-field#1696
File: src/scenes/FieldZones/CreateFieldZone/CreateFieldZone.tsx:0-0
Timestamp: 2025-06-20T17:50:15.534Z
Learning: In this codebase, GraphQL documents (like CreateFieldZoneDocument, CreateFieldRegionDocument, etc.) are already properly typed, and Apollo hooks (useMutation, useQuery, etc.) automatically infer the correct types from these typed documents. Therefore, explicit generic type parameters on Apollo hooks are unnecessary and should not be suggested.
src/scenes/Users/Detail/Tabs/Profile/UserDetailProfile.tsx (1)
Learnt from: CarsonF
PR: SeedCompany/cord-field#1604
File: src/components/Feature.tsx:12-19
Timestamp: 2024-10-21T15:17:35.618Z
Learning: In `src/components/Feature.tsx`, the `Feature` component uses `useFeatureFlagPayload` and the `match` prop to determine feature availability, which differs from the `useFeatureEnabled` hook.
🧬 Code Graph Analysis (3)
src/scenes/Users/Detail/Tabs/Projects/UserDetailProjects.tsx (2)
src/components/Tabs/TabPanelContent.tsx (1)
TabPanelContent
(6-22)src/scenes/Users/Detail/Tabs/Projects/UserProjectPanel/UserProjectsPanel.tsx (1)
UserProjectsPanel
(23-61)
src/scenes/Users/Detail/UserDetail.tsx (8)
src/hooks/useQueryParams.ts (3)
makeQueryHandler
(183-247)withDefault
(92-104)EnumParam
(69-85)src/components/Comments/CommentsContext.tsx (1)
useComments
(65-71)src/components/Dialog/useDialog.tsx (1)
useDialog
(4-33)src/components/Error/Error.tsx (1)
Error
(57-116)src/components/Tabs/TabsContainer.tsx (1)
TabsContainer
(4-16)src/scenes/Users/Detail/Tabs/Profile/UserDetailProfile.tsx (1)
UserDetailProfile
(18-79)src/scenes/Users/Detail/Tabs/Projects/UserDetailProjects.tsx (1)
UserDetailProjects
(4-10)src/scenes/Users/Edit/EditUser.tsx (1)
EditUser
(13-57)
src/scenes/Users/Detail/Tabs/Profile/UserDetailProfile.tsx (3)
src/common/displayEnums.ts (1)
labelsFrom
(16-19)src/components/PartnerListItemCard/PartnerListItemCard.tsx (1)
PartnerListItemCard
(37-85)src/components/DisplaySimpleProperty/DisplaySimpleProperty.tsx (2)
DisplaySimplePropertyProps
(4-12)DisplaySimpleProperty
(14-50)
🪛 Biome (1.9.4)
src/scenes/Users/Detail/UserDetail.tsx
[error] 11-11: Do not shadow the global "Error" property.
Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.
(lint/suspicious/noShadowRestrictedNames)
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: run
🔇 Additional comments (6)
src/api/schema/typePolicies/typePolicies.base.ts (1)
88-92
: LGTM!The type policy addition follows the existing pattern used for
Partner.projects
and correctly configures Apollo cache to avoid page merging for infinite scroll functionality.src/scenes/Users/Detail/Tabs/Projects/UserDetailProjects.tsx (1)
1-11
: LGTM!Clean wrapper component that properly uses
TabPanelContent
for consistent tab panel styling.src/scenes/Users/Detail/UserDetail.tsx (1)
124-124
: Verify EditUser rendering logic changeThe
EditUser
component now renders outside the error check, meaning it will render even when there's an error (if user data exists from cache). Is this intentional?If this change is unintentional, consider moving it back inside the error check:
- {user ? <EditUser user={user} {...editUserState} /> : null} + {user ? <EditUser user={user} {...editUserState} /> : null} </> )}src/scenes/Users/Detail/Tabs/Profile/UserDetailProfile.tsx (3)
18-79
: Well-structured component with good separation of concerns.The main component structure is clean and follows React best practices. The use of optional chaining for undefined user data is appropriate, and the conditional rendering for the partners section is correctly implemented.
91-97
: Time update interval is reasonable but consider performance implications.The 1-second update interval is appropriate for a time display. The
useInterval
hook from ahooks should handle cleanup properly when the component unmounts.
42-42
: labelsFrom handles empty/undefined values correctlyThe
labelsFrom
utility insrc/common/displayEnums.ts
defaultsvalues
to an empty array (values ?? []
) and returns an empty string when there are no roles, solabelsFrom(RoleLabels)(user?.roles.value)
will gracefully display nothing for undefined or empty role lists. No changes are needed.
const { userId = '' } = useParams(); | ||
|
||
const [dataGridProps] = useDataGridSource({ | ||
query: UserProjectListDocument, | ||
variables: { userId }, | ||
listAt: 'user.projects', | ||
initialInput: { | ||
sort: 'name', | ||
}, | ||
}); |
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.
Handle missing userId gracefully
Defaulting userId
to an empty string could cause the GraphQL query to fail or return unexpected results. Consider adding explicit error handling for this case.
export const UserProjectsPanel = () => {
- const { userId = '' } = useParams();
+ const { userId } = useParams();
+
+ if (!userId) {
+ return (
+ <Typography color="error" sx={{ p: 2 }}>
+ User ID is required
+ </Typography>
+ );
+ }
const [dataGridProps] = useDataGridSource({
query: UserProjectListDocument,
variables: { userId },
🤖 Prompt for AI Agents
In src/scenes/Users/Detail/Tabs/Projects/UserProjectPanel/UserProjectsPanel.tsx
around lines 24 to 33, the userId is defaulted to an empty string which may
cause the GraphQL query to fail or behave unexpectedly. Instead of defaulting,
add explicit error handling to check if userId is missing or undefined before
running the query. If userId is not present, handle this case gracefully by
either showing an error message or skipping the query execution to prevent
invalid requests.
src/scenes/Users/Detail/Tabs/Projects/UserProjectPanel/UserProjectsPanel.tsx
Show resolved
Hide resolved
8ccdc83
to
f697c21
Compare
Adds a Projects table prefiltered by
userId
to the User detail and also creates a new tab list whereProfile
is separated out fromProjects
.