Skip to content

Conversation

rdonigian
Copy link
Contributor

@rdonigian rdonigian commented Jul 18, 2025

@rdonigian rdonigian force-pushed the region-zone-project-grid branch from 6c4a85a to 8d1e71a Compare July 21, 2025 14:31
@rdonigian rdonigian marked this pull request as ready for review July 28, 2025 12:58
@rdonigian rdonigian requested a review from CarsonF as a code owner July 28, 2025 12:58
Copy link
Contributor

coderabbitai bot commented Jul 28, 2025

📝 Walkthrough

Walkthrough

This change introduces tabbed detail views for FieldRegion and FieldZone entities, separating profile and projects information. It adds new data grid columns and GraphQL fields for displaying field region associations on engagements and projects. Type policies are updated for FieldRegion and FieldZone, and new fragments and queries are introduced to support the new UI structure and data requirements.

Changes

Cohort / File(s) Change Summary
Type Policy Updates
src/api/schema/typePolicies/typePolicies.base.ts
Added type policies for FieldRegion and FieldZone with projects field; removed engagements field policy from Query.
Engagement Data Grid Enhancements
src/components/EngagementDataGrid/EngagementColumns.tsx, src/components/EngagementDataGrid/engagementDataGridRow.graphql
Added "Field Region" column to engagement grid and extended GraphQL fragment to fetch field region data.
Project Data Grid Enhancements
src/components/ProjectDataGrid/ProjectColumns.tsx, src/components/ProjectDataGrid/projectDataGridRow.graphql
Added "Field Region" column to project grid and extended GraphQL fragment to fetch field region data.
FieldRegion Detail Refactor
src/scenes/FieldRegions/Detail/FieldRegionDetail.tsx
Refactored detail view to use tabbed interface (Profile, Projects); removed edit dialog and related UI.
FieldRegion Profile Tab
src/scenes/FieldRegions/Detail/Tabs/Profile/FieldRegionProfile.graphql, src/scenes/FieldRegions/Detail/Tabs/Profile/FieldRegionProfile.tsx
Added GraphQL fragment and new React component for displaying and editing field region profile information.
FieldRegion Projects Tab
src/scenes/FieldRegions/Detail/Tabs/Projects/FieldRegionProjects.graphql, src/scenes/FieldRegions/Detail/Tabs/Projects/FieldRegionProjects.tsx
Added GraphQL query/fragment and new React component for listing projects associated with a field region.
FieldZone Detail Refactor
src/scenes/FieldZones/Detail/FieldZoneDetail.tsx
Refactored detail view to use tabbed interface (Profile, Projects); removed editing and simplified UI.
FieldZone Profile Tab
src/scenes/FieldZones/Detail/Tabs/Profile/FieldZoneProfile.graphql, src/scenes/FieldZones/Detail/Tabs/Profile/FieldZoneProfile.tsx
Added GraphQL fragment and new React component for displaying and editing field zone profile information.
FieldZone Projects Tab
src/scenes/FieldZones/Detail/Tabs/Projects/FieldZoneProjects.graphql, src/scenes/FieldZones/Detail/Tabs/Projects/FieldZoneProjects.tsx
Added GraphQL query/fragment and new React component for listing projects associated with a field zone.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • SeedCompany/cord-field#1696: Introduces initial creation pages and detail components for FieldRegion and FieldZone, including editing dialogs. Related as both PRs work on FieldRegion and FieldZone detail and editing components, but this PR focuses on tabbed detail views and project lists.

Note

⚡️ Unit Test Generation is now available in beta!

Learn more here, or try it out under "Finishing Touches" below.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch region-zone-project-grid

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need 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)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@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: 0

♻️ Duplicate comments (1)
src/scenes/FieldZones/Detail/Tabs/Profile/FieldZoneProfile.tsx (1)

70-98: Extract shared DisplayProperty component.

This is identical to the DisplayProperty in FieldRegionProfile.tsx. Consider extracting to a shared location to reduce duplication.

🧹 Nitpick comments (3)
src/components/ProjectDataGrid/ProjectColumns.tsx (1)

47-61: LGTM! Well-implemented column with minor suggestion.

The Field Region column follows the established patterns with proper valueGetter, renderCell, and Link integration. The implementation correctly handles the nested GraphQL structure.

Consider adding a safety check in the renderCell to handle cases where fieldRegion.value might be null:

renderCell: ({ row: project }) => {
  const { fieldRegion } = project;
+ if (!fieldRegion.value) return null;
  return (
    <Link to={`/field-regions/${fieldRegion.value?.id}`}>
      {fieldRegion.value?.name.value}
    </Link>
  );
},
src/scenes/FieldRegions/Detail/Tabs/Profile/FieldRegionProfile.tsx (1)

81-109: Consider extracting the DisplayProperty component for reusability.

The DisplayProperty helper component is duplicated between FieldRegionProfile and FieldZoneProfile with identical implementation. This could be extracted to a shared utility.

Extract to a shared file like ~/components/DisplayProperty/DisplayProperty.tsx:

+export 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
+      }
+      LabelProps={{
+        color: 'textSecondary',
+        variant: 'body2',
+        ...props.LabelProps,
+      }}
+      ValueProps={{
+        color: 'textPrimary',
+        ...props.ValueProps,
+      }}
+    />
+  );
src/scenes/FieldZones/Detail/Tabs/Profile/FieldZoneProfile.tsx (1)

59-59: Fix typo in aria-label.

There's a minor capitalization inconsistency in the aria-label.

-            <IconButton aria-label="edit field Zone" onClick={editZone}>
+            <IconButton aria-label="edit field zone" onClick={editZone}>
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1627b84 and 8d1e71a.

📒 Files selected for processing (15)
  • src/api/schema/typePolicies/typePolicies.base.ts (1 hunks)
  • src/components/EngagementDataGrid/EngagementColumns.tsx (1 hunks)
  • src/components/EngagementDataGrid/engagementDataGridRow.graphql (1 hunks)
  • src/components/ProjectDataGrid/ProjectColumns.tsx (2 hunks)
  • src/components/ProjectDataGrid/projectDataGridRow.graphql (1 hunks)
  • src/scenes/FieldRegions/Detail/FieldRegionDetail.tsx (1 hunks)
  • src/scenes/FieldRegions/Detail/Tabs/Profile/FieldRegionProfile.graphql (1 hunks)
  • src/scenes/FieldRegions/Detail/Tabs/Profile/FieldRegionProfile.tsx (1 hunks)
  • src/scenes/FieldRegions/Detail/Tabs/Projects/FieldRegionProjects.graphql (1 hunks)
  • src/scenes/FieldRegions/Detail/Tabs/Projects/FieldRegionProjects.tsx (1 hunks)
  • src/scenes/FieldZones/Detail/FieldZoneDetail.tsx (1 hunks)
  • src/scenes/FieldZones/Detail/Tabs/Profile/FieldZoneProfile.graphql (1 hunks)
  • src/scenes/FieldZones/Detail/Tabs/Profile/FieldZoneProfile.tsx (1 hunks)
  • src/scenes/FieldZones/Detail/Tabs/Projects/FieldZoneProjects.graphql (1 hunks)
  • src/scenes/FieldZones/Detail/Tabs/Projects/FieldZoneProjects.tsx (1 hunks)
🧰 Additional context used
🧠 Learnings (11)
src/scenes/FieldZones/Detail/FieldZoneDetail.tsx (3)

Learnt from: CarsonF
PR: #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: #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.

Learnt from: CarsonF
PR: #1696
File: src/scenes/FieldZones/Detail/FieldZoneDetail.tsx:79-88
Timestamp: 2025-07-02T15:46:56.008Z
Learning: In this codebase, when using canEditAny() with components that have loading states (like FAB), passing true as the second argument when the first argument might be null during loading is intentional. This allows the component to render during loading and use its own loading prop to show loading state, then evaluate actual permissions once data loads. Example: canEditAny(fieldZone, true) with <Fab loading={!fieldZone}> allows the FAB to show loading state before permissions are determined.

src/scenes/FieldRegions/Detail/FieldRegionDetail.tsx (3)

Learnt from: CarsonF
PR: #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: #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.

Learnt from: CarsonF
PR: #1696
File: src/scenes/FieldZones/Detail/FieldZoneDetail.tsx:79-88
Timestamp: 2025-07-02T15:46:56.008Z
Learning: In this codebase, when using canEditAny() with components that have loading states (like FAB), passing true as the second argument when the first argument might be null during loading is intentional. This allows the component to render during loading and use its own loading prop to show loading state, then evaluate actual permissions once data loads. Example: canEditAny(fieldZone, true) with <Fab loading={!fieldZone}> allows the FAB to show loading state before permissions are determined.

src/scenes/FieldRegions/Detail/Tabs/Profile/FieldRegionProfile.tsx (3)

Learnt from: CarsonF
PR: #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: #1696
File: src/scenes/FieldZones/Detail/FieldZoneDetail.tsx:79-88
Timestamp: 2025-07-02T15:46:56.008Z
Learning: In this codebase, when using canEditAny() with components that have loading states (like FAB), passing true as the second argument when the first argument might be null during loading is intentional. This allows the component to render during loading and use its own loading prop to show loading state, then evaluate actual permissions once data loads. Example: canEditAny(fieldZone, true) with <Fab loading={!fieldZone}> allows the FAB to show loading state before permissions are determined.

Learnt from: CarsonF
PR: #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/FieldZones/Detail/Tabs/Profile/FieldZoneProfile.tsx (3)

Learnt from: CarsonF
PR: #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: #1696
File: src/scenes/FieldZones/Detail/FieldZoneDetail.tsx:79-88
Timestamp: 2025-07-02T15:46:56.008Z
Learning: In this codebase, when using canEditAny() with components that have loading states (like FAB), passing true as the second argument when the first argument might be null during loading is intentional. This allows the component to render during loading and use its own loading prop to show loading state, then evaluate actual permissions once data loads. Example: canEditAny(fieldZone, true) with <Fab loading={!fieldZone}> allows the FAB to show loading state before permissions are determined.

Learnt from: CarsonF
PR: #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/FieldZones/Detail/Tabs/Projects/FieldZoneProjects.graphql (1)

Learnt from: CarsonF
PR: #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/FieldRegions/Detail/Tabs/Profile/FieldRegionProfile.graphql (1)

Learnt from: CarsonF
PR: #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/FieldZones/Detail/Tabs/Profile/FieldZoneProfile.graphql (1)

Learnt from: CarsonF
PR: #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/FieldZones/Detail/Tabs/Projects/FieldZoneProjects.tsx (2)

Learnt from: CarsonF
PR: #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.

Learnt from: CarsonF
PR: #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.

src/scenes/FieldRegions/Detail/Tabs/Projects/FieldRegionProjects.graphql (1)

Learnt from: CarsonF
PR: #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/api/schema/typePolicies/typePolicies.base.ts (1)

Learnt from: CarsonF
PR: #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/FieldRegions/Detail/Tabs/Projects/FieldRegionProjects.tsx (2)

Learnt from: CarsonF
PR: #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: #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.

🧬 Code Graph Analysis (2)
src/scenes/FieldZones/Detail/Tabs/Profile/FieldZoneProfile.tsx (5)
src/components/Dialog/useDialog.tsx (1)
  • useDialog (4-33)
src/common/secured.ts (1)
  • canEditAny (85-97)
src/components/Routing/Link.tsx (1)
  • Link (27-42)
src/components/FieldZone/EditFieldZone/EditFieldZone.tsx (1)
  • EditFieldZone (17-55)
src/components/DisplaySimpleProperty/DisplaySimpleProperty.tsx (2)
  • DisplaySimplePropertyProps (4-12)
  • DisplaySimpleProperty (14-50)
src/components/ProjectDataGrid/ProjectColumns.tsx (2)
src/components/Grid/ColumnTypes/textColumn.tsx (1)
  • textColumn (17-20)
src/components/Routing/Link.tsx (1)
  • Link (27-42)
🪛 Biome (2.1.2)
src/scenes/FieldZones/Detail/FieldZoneDetail.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)

src/scenes/FieldRegions/Detail/FieldRegionDetail.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 (18)
src/scenes/FieldZones/Detail/Tabs/Profile/FieldZoneProfile.graphql (1)

1-4: LGTM! Clean fragment composition pattern.

The fragment properly aggregates existing fragments for the tabbed profile view, following GraphQL best practices for reusability.

src/scenes/FieldRegions/Detail/Tabs/Profile/FieldRegionProfile.graphql (1)

1-4: LGTM! Consistent fragment composition.

The fragment follows the same clean pattern as the FieldZone equivalent, maintaining consistency across the codebase.

src/components/EngagementDataGrid/engagementDataGridRow.graphql (1)

29-36: LGTM! Consistent field addition.

The fieldRegion field follows the same nested structure pattern as primaryLocation, maintaining consistency in the GraphQL schema design.

src/components/ProjectDataGrid/projectDataGridRow.graphql (1)

21-28: LGTM! Consistent GraphQL pattern.

The fieldRegion field addition mirrors the structure of primaryLocation and aligns with the corresponding change in the engagement data grid fragment.

src/components/ProjectDataGrid/ProjectColumns.tsx (1)

30-30: LGTM! Proper import addition.

The Link import is correctly added to support the field region navigation functionality.

src/api/schema/typePolicies/typePolicies.base.ts (1)

88-97: LGTM! Consistent with existing patterns.

The new type policies for FieldRegion and FieldZone correctly follow the same pattern as the existing Partner type policy, using empty objects for the projects field to support infinite scroll behavior in data grids.

src/components/EngagementDataGrid/EngagementColumns.tsx (2)

158-158: Good consistency improvement.

Explicitly setting the width for the Country column creates visual consistency with the new Field Region column.


161-175: Well-implemented Field Region column.

The new column follows established patterns perfectly:

  • Proper null-safe data access with optional chaining
  • Consistent Link rendering for navigation
  • Appropriate styling and width matching other columns
  • Clean separation of valueGetter and renderCell logic
src/scenes/FieldZones/Detail/Tabs/Projects/FieldZoneProjects.graphql (1)

1-17: Well-structured GraphQL query and fragment.

The query follows established patterns with proper parameter typing and pagination fields. The fragment reuse of projectDataGridRow promotes consistency across data grids and reduces duplication.

src/scenes/FieldRegions/Detail/Tabs/Projects/FieldRegionProjects.tsx (1)

26-65: Excellent implementation following established patterns.

The component properly:

  • Extracts URL parameters with appropriate defaults
  • Uses useDataGridSource hook correctly with proper initial sorting
  • Optimizes rendering with useMemo for slots/slotProps
  • Follows consistent styling patterns with DefaultDataGridStyles
  • Integrates well with existing ProjectColumns and toolbar components
  • Uses proper TypeScript generics only where needed (DataGrid component)
src/scenes/FieldRegions/Detail/Tabs/Projects/FieldRegionProjects.graphql (1)

1-17: Excellent consistency with field zone implementation.

The query structure perfectly mirrors the FieldZoneProjects query, maintaining consistency across similar features. Proper parameter typing, pagination fields, and fragment reuse follow established patterns.

src/scenes/FieldRegions/Detail/Tabs/Profile/FieldRegionProfile.tsx (1)

25-79: LGTM! Well-structured profile component with good separation of concerns.

The component effectively separates profile display from editing functionality using the dialog pattern. The layout, permission handling, and routing integration are all implemented correctly.

src/scenes/FieldZones/Detail/Tabs/Profile/FieldZoneProfile.tsx (1)

25-68: LGTM! Consistent implementation with FieldRegionProfile.

The component follows the same well-established patterns as FieldRegionProfile with appropriate permission handling and dialog integration.

src/scenes/FieldZones/Detail/FieldZoneDetail.tsx (2)

14-16: Well-implemented tab state management.

Using query parameters to persist tab state provides a good user experience with shareable URLs and browser back/forward navigation support.


75-93: Excellent tabbed interface implementation.

The tab structure is well-organized with proper accessibility attributes and conditional rendering. The separation of concerns between profile and projects views improves maintainability.

src/scenes/FieldZones/Detail/Tabs/Projects/FieldZoneProjects.tsx (1)

26-65: LGTM! Well-implemented data grid with proper configuration.

The component correctly uses the established data grid patterns with:

  • Proper hook usage for data source management
  • Correct merging of default styles and custom configurations
  • Appropriate TypeScript generics for type safety
  • Good integration with the tab panel structure
src/scenes/FieldRegions/Detail/FieldRegionDetail.tsx (2)

14-16: Consistent tab state management implementation.

The query parameter-based tab state management matches the pattern used in FieldZoneDetail, providing consistency across the application.


75-95: Excellent consistency with FieldZoneDetail implementation.

The tabbed interface implementation mirrors the FieldZoneDetail component perfectly, ensuring a consistent user experience across field regions and field zones.

Copy link
Member

@CarsonF CarsonF left a comment

Choose a reason for hiding this comment

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

💪

);
};

const DisplayProperty = (props: DisplaySimplePropertyProps) =>
Copy link
Member

Choose a reason for hiding this comment

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

Will you take another stab at DRYing this in another PR?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Can do!

@rdonigian rdonigian force-pushed the region-zone-project-grid branch from 8d1e71a to 5611407 Compare July 30, 2025 14:26
Copy link
Contributor

@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

♻️ Duplicate comments (1)
src/scenes/FieldRegions/Detail/FieldRegionDetail.tsx (1)

8-8: Fix Error import shadowing global Error.

Same issue as in FieldZoneDetail.tsx - the Error import shadows the global Error constructor.

-import { Error } from '../../../components/Error';
+import { Error as ErrorComponent } from '../../../components/Error';

And update the usage accordingly.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8d1e71a and 5611407.

📒 Files selected for processing (15)
  • src/api/schema/typePolicies/typePolicies.base.ts (1 hunks)
  • src/components/EngagementDataGrid/EngagementColumns.tsx (1 hunks)
  • src/components/EngagementDataGrid/engagementDataGridRow.graphql (1 hunks)
  • src/components/ProjectDataGrid/ProjectColumns.tsx (2 hunks)
  • src/components/ProjectDataGrid/projectDataGridRow.graphql (1 hunks)
  • src/scenes/FieldRegions/Detail/FieldRegionDetail.tsx (1 hunks)
  • src/scenes/FieldRegions/Detail/Tabs/Profile/FieldRegionProfile.graphql (1 hunks)
  • src/scenes/FieldRegions/Detail/Tabs/Profile/FieldRegionProfile.tsx (1 hunks)
  • src/scenes/FieldRegions/Detail/Tabs/Projects/FieldRegionProjects.graphql (1 hunks)
  • src/scenes/FieldRegions/Detail/Tabs/Projects/FieldRegionProjects.tsx (1 hunks)
  • src/scenes/FieldZones/Detail/FieldZoneDetail.tsx (1 hunks)
  • src/scenes/FieldZones/Detail/Tabs/Profile/FieldZoneProfile.graphql (1 hunks)
  • src/scenes/FieldZones/Detail/Tabs/Profile/FieldZoneProfile.tsx (1 hunks)
  • src/scenes/FieldZones/Detail/Tabs/Projects/FieldZoneProjects.graphql (1 hunks)
  • src/scenes/FieldZones/Detail/Tabs/Projects/FieldZoneProjects.tsx (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • src/components/EngagementDataGrid/engagementDataGridRow.graphql
🚧 Files skipped from review as they are similar to previous changes (12)
  • src/components/ProjectDataGrid/ProjectColumns.tsx
  • src/scenes/FieldRegions/Detail/Tabs/Projects/FieldRegionProjects.graphql
  • src/scenes/FieldZones/Detail/Tabs/Projects/FieldZoneProjects.graphql
  • src/components/ProjectDataGrid/projectDataGridRow.graphql
  • src/scenes/FieldZones/Detail/Tabs/Projects/FieldZoneProjects.tsx
  • src/scenes/FieldZones/Detail/Tabs/Profile/FieldZoneProfile.graphql
  • src/scenes/FieldRegions/Detail/Tabs/Profile/FieldRegionProfile.graphql
  • src/api/schema/typePolicies/typePolicies.base.ts
  • src/scenes/FieldRegions/Detail/Tabs/Projects/FieldRegionProjects.tsx
  • src/scenes/FieldRegions/Detail/Tabs/Profile/FieldRegionProfile.tsx
  • src/components/EngagementDataGrid/EngagementColumns.tsx
  • src/scenes/FieldZones/Detail/Tabs/Profile/FieldZoneProfile.tsx
🧰 Additional context used
🧠 Learnings (2)
src/scenes/FieldRegions/Detail/FieldRegionDetail.tsx (3)

Learnt from: CarsonF
PR: #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: #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.

Learnt from: CarsonF
PR: #1696
File: src/scenes/FieldZones/Detail/FieldZoneDetail.tsx:79-88
Timestamp: 2025-07-02T15:46:56.008Z
Learning: In this codebase, when using canEditAny() with components that have loading states (like FAB), passing true as the second argument when the first argument might be null during loading is intentional. This allows the component to render during loading and use its own loading prop to show loading state, then evaluate actual permissions once data loads. Example: canEditAny(fieldZone, true) with <Fab loading={!fieldZone}> allows the FAB to show loading state before permissions are determined.

src/scenes/FieldZones/Detail/FieldZoneDetail.tsx (3)

Learnt from: CarsonF
PR: #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: #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.

Learnt from: CarsonF
PR: #1696
File: src/scenes/FieldZones/Detail/FieldZoneDetail.tsx:79-88
Timestamp: 2025-07-02T15:46:56.008Z
Learning: In this codebase, when using canEditAny() with components that have loading states (like FAB), passing true as the second argument when the first argument might be null during loading is intentional. This allows the component to render during loading and use its own loading prop to show loading state, then evaluate actual permissions once data loads. Example: canEditAny(fieldZone, true) with <Fab loading={!fieldZone}> allows the FAB to show loading state before permissions are determined.

🪛 Biome (2.1.2)
src/scenes/FieldRegions/Detail/FieldRegionDetail.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)

src/scenes/FieldZones/Detail/FieldZoneDetail.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)

⏰ 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: run
🔇 Additional comments (6)
src/scenes/FieldZones/Detail/FieldZoneDetail.tsx (3)

14-16: LGTM on query handler implementation.

The tab state management using makeQueryHandler with URL query parameters is well-implemented and provides good UX with bookmarkable URLs.


30-38: Approve the layout improvements.

The change from Box to Stack with proper flex layout, overflow handling, and max-width constraint improves the overall UX and responsive design.


75-93: Discard conditional‐render suggestion for Profile tab.

FieldZoneProfileProps explicitly accept fieldZone: … | undefined, and the component internally handles the loading state (e.g. via optional chaining or built-in skeletons). Wrapping it in {fieldZone && …} would prevent its loading UI from appearing. By contrast, FieldZoneProjects requires a fully loaded fieldZone (e.g. to drive its own queries), so it’s correctly guarded.

No changes needed.

Likely an incorrect or invalid review comment.

src/scenes/FieldRegions/Detail/FieldRegionDetail.tsx (3)

21-21: Good addition of loading state.

Adding the loading state from useQuery addresses the past review comment about loading states and improves the user experience.


63-67: Excellent loading state handling.

The explicit loading checks with proper skeleton rendering provide better UX compared to the FieldZoneDetail implementation. This pattern should be consistent across both components.


87-92: Ignore conditional guard for FieldRegionProjects

FieldRegionProjects fetches its own data based solely on the URL param and renders its own loading/error states. It does not depend on the parent’s fieldRegion prop, so wrapping it in a fieldRegion && … guard (as done in FieldZoneDetail) isn’t needed here. The current pattern is intentional and safe.

Likely an incorrect or invalid review comment.

import { Link } from '~/components/Routing';
import { Tab, TabsContainer } from '~/components/Tabs';
import { EnumParam, makeQueryHandler, withDefault } from '~/hooks';
import { Error } from '../../../components/Error';
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix Error import shadowing global Error.

The static analysis tool correctly identifies that importing Error shadows the global Error constructor, which can lead to confusion.

-import { Error } from '../../../components/Error';
+import { Error as ErrorComponent } from '../../../components/Error';

And update the usage:

-      <Error error={error}>
+      <ErrorComponent error={error}>
         {{
           NotFound: 'Could not find field zone',
           Default: 'Error loading field zone',
         }}
-      </Error>
+      </ErrorComponent>
📝 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.

Suggested change
import { Error } from '../../../components/Error';
// src/scenes/FieldZones/Detail/FieldZoneDetail.tsx
// --- at the top of the file ---
-import { Error } from '../../../components/Error';
+import { Error as ErrorComponent } from '../../../components/Error';
// …later in your JSX render…
- <Error error={error}>
+ <ErrorComponent error={error}>
{{
NotFound: 'Could not find field zone',
Default: 'Error loading field zone',
}}
- </Error>
+ </ErrorComponent>
🧰 Tools
🪛 Biome (2.1.2)

[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)

🤖 Prompt for AI Agents
In src/scenes/FieldZones/Detail/FieldZoneDetail.tsx at line 8, the import of
`Error` shadows the global JavaScript `Error` constructor. Rename the imported
component to a different name, such as `ErrorComponent`, and update all its
usages in the file accordingly to avoid confusion and conflicts with the global
`Error`.

@rdonigian rdonigian requested a review from CarsonF August 6, 2025 16:53
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