Skip to content

Use specific rotation table selection state#435

Merged
SvenVw merged 7 commits into
release/2026-01from
FDM314-rotation-selection
Jan 28, 2026
Merged

Use specific rotation table selection state#435
SvenVw merged 7 commits into
release/2026-01from
FDM314-rotation-selection

Conversation

@BoraIneviNMI
Copy link
Copy Markdown
Collaborator

@BoraIneviNMI BoraIneviNMI commented Jan 28, 2026

Enhancements

  • Rotation state and field state are differently shaped. I think it is better to keep them separate.

Summary by CodeRabbit

  • Refactor
    • Restructured how the application manages rotation selection and filtering state for improved consistency and maintainability.

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

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Jan 28, 2026

⚠️ No Changeset found

Latest commit: 99b2d9b

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jan 28, 2026

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

🗂️ Base branches to auto review (2)
  • development
  • main

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

  • 🔍 Trigger a full review

Walkthrough

This change introduces rotation-specific state management by creating a factory pattern for filter stores, adding a new persistent rotation selection store with SSR-safe storage, and refactoring the rotation table component to use these new rotation-specific stores with proper TypeScript typing.

Changes

Cohort / File(s) Summary
Store Factory Pattern
fdm-app/app/store/field-filter.ts
Introduced createFilterStore(name: string) factory function to generate named filter stores with dynamic persistence keys. Exports both useFieldFilterStore and useRotationFilterStore instances from the factory.
New Rotation Selection Store
fdm-app/app/store/rotation-selection.ts
New store module implementing FieldSelectionState with nested selection structure (crop → field → boolean). Includes setSelection() and syncFarm() methods with SSR-safe persistent storage.
Rotation Table Component
fdm-app/app/components/blocks/rotation/table.tsx
Migrated to rotation-specific stores (useRotationFilterStore, useRotationSelectionStore). Added proper DataTableProps<TData, TValue> typing with destructured parameters. Implemented handleSelection() to synchronize per-row selections into nested per-crop/field structure.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

enhancement, fdm-app

Suggested reviewers

  • SvenVw

Poem

🐰 Stores now dance in rotation's way,
With factories fresh and selections at play,
Filter state flows where crops once lay,
SSR-safe storage comes out to stay! 🌾

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title 'Use specific rotation table selection state' accurately describes the main change: introducing separate rotation-specific selection state (useRotationSelectionStore) instead of using generic field selection state.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch FDM314-rotation-selection

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link
Copy Markdown

codecov Bot commented Jan 28, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 88.07%. Comparing base (a1f0e9b) to head (99b2d9b).
⚠️ Report is 8 commits behind head on release/2026-01.

Additional details and impacted files
@@               Coverage Diff                @@
##           release/2026-01     #435   +/-   ##
================================================
  Coverage            88.07%   88.07%           
================================================
  Files                   91       91           
  Lines                 4621     4621           
  Branches              1492     1492           
================================================
  Hits                  4070     4070           
  Misses                 551      551           
Flag Coverage Δ
fdm-calculator 88.76% <ø> (ø)
fdm-core 86.77% <ø> (ø)
fdm-data 92.12% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@BoraIneviNMI BoraIneviNMI changed the title Fdm314 rotation selection Use specific rotation table selection state Jan 28, 2026
@BoraIneviNMI
Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jan 28, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot added enhancement New feature or request fdm-app labels Jan 28, 2026
Copy link
Copy Markdown
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

🤖 Fix all issues with AI agents
In `@fdm-app/app/components/blocks/rotation/table.tsx`:
- Around line 107-123: The handleSelection function currently builds
newSelection only from table.getFilteredRowModel().rows and calls
setSelection(newSelection), which drops selection state for filtered-out rows;
fix this by merging the existing selection state with the computed newSelection
instead of replacing it (use the existing selection object available in scope or
read current state) so hidden rows are preserved when calling setSelection;
ensure you create a new object (immutable merge) rather than mutating state
directly and keep references to RowSelectionState and the fields derived from
(row.original as CropRow).b_lu_catalogue and (fieldRow.original as
FieldRow).b_id to locate where to merge.
🧹 Nitpick comments (2)
fdm-app/app/store/rotation-selection.ts (1)

5-10: Consider renaming the interface to match its purpose.

The interface is named FieldSelectionState but it's used for useRotationSelectionStore. For clarity and consistency with the store name, consider renaming it to RotationSelectionState.

Suggested rename
-interface FieldSelectionState {
+interface RotationSelectionState {
     farmId: string | null
     selection: Record<string, Record<string, boolean>>
     setSelection: (selection: Record<string, Record<string, boolean>>) => void
     syncFarm: (farmId: string) => void
 }
 
-export const useRotationSelectionStore = create<FieldSelectionState>()(
+export const useRotationSelectionStore = create<RotationSelectionState>()(
fdm-app/app/components/blocks/rotation/table.tsx (1)

96-101: Consider extracting fieldFilter.syncFarm for stable dependency reference.

While the current code works, directly referencing fieldFilter.syncFarm in the dependency array is safer when extracted like syncFarm was for the selection store.

Suggested change
+    const syncFilterFarm = useRotationFilterStore((state) => state.syncFarm)
+
     useEffect(() => {
         if (b_id_farm) {
             syncFarm(b_id_farm)
-            fieldFilter.syncFarm(b_id_farm)
+            syncFilterFarm(b_id_farm)
         }
-    }, [b_id_farm, syncFarm, fieldFilter.syncFarm])
+    }, [b_id_farm, syncFarm, syncFilterFarm])

Comment on lines +107 to +123
function handleSelection(rowSelection: RowSelectionState) {
// Sync to store
const newSelection = Object.fromEntries(
table
.getFilteredRowModel()
.rows.map((row) => [
(row.original as CropRow).b_lu_catalogue,
Object.fromEntries(
row.subRows.map((fieldRow) => [
(fieldRow.original as FieldRow).b_id,
rowSelection[fieldRow.id],
]),
),
]),
)
setSelection(newSelection)
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

cat -n fdm-app/app/components/blocks/rotation/table.tsx | head -150

Repository: SvenVw/fdm

Length of output: 6107


🏁 Script executed:

sed -n '150,250p' fdm-app/app/components/blocks/rotation/table.tsx

Repository: SvenVw/fdm

Length of output: 4004


🏁 Script executed:

sed -n '219,300p' fdm-app/app/components/blocks/rotation/table.tsx

Repository: SvenVw/fdm

Length of output: 3400


🏁 Script executed:

rg -n "setSelection|selection\[" fdm-app/app/components/blocks/rotation/table.tsx -A 2 -B 2

Repository: SvenVw/fdm

Length of output: 823


🏁 Script executed:

sed -n '107,130p' fdm-app/app/components/blocks/rotation/table.tsx | cat -n

Repository: SvenVw/fdm

Length of output: 1111


Confirm: selection state of filtered-out rows is indeed lost.

The handleSelection function builds newSelection only from table.getFilteredRowModel().rows, then calls setSelection(newSelection), which completely replaces the stored selection. Any rows currently filtered out are excluded from this new selection object, causing their selection state to be discarded.

To preserve selection for hidden rows, merge the new selection with the existing one instead of replacing it entirely:

setSelection({ ...selection, ...newSelection })
🤖 Prompt for AI Agents
In `@fdm-app/app/components/blocks/rotation/table.tsx` around lines 107 - 123, The
handleSelection function currently builds newSelection only from
table.getFilteredRowModel().rows and calls setSelection(newSelection), which
drops selection state for filtered-out rows; fix this by merging the existing
selection state with the computed newSelection instead of replacing it (use the
existing selection object available in scope or read current state) so hidden
rows are preserved when calling setSelection; ensure you create a new object
(immutable merge) rather than mutating state directly and keep references to
RowSelectionState and the fields derived from (row.original as
CropRow).b_lu_catalogue and (fieldRow.original as FieldRow).b_id to locate where
to merge.

@SvenVw SvenVw merged commit 59c21ac into release/2026-01 Jan 28, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request fdm-app

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants