Skip to content

LF-5300: Extend DateRangeSelector with filtered options and dynamic year entries#4181

Open
litefarm-pr-bot wants to merge 1 commit into
integrationfrom
LF-5300-extend-daterangeselector-with-filtered-options-and-dynamic-year-entries
Open

LF-5300: Extend DateRangeSelector with filtered options and dynamic year entries#4181
litefarm-pr-bot wants to merge 1 commit into
integrationfrom
LF-5300-extend-daterangeselector-with-filtered-options-and-dynamic-year-entries

Conversation

@litefarm-pr-bot
Copy link
Copy Markdown
Collaborator

@litefarm-pr-bot litefarm-pr-bot commented May 25, 2026

Description

The shared DateRangeSelector currently hard-codes its dropdown contents to a fixed list of nine static options. Any consumer that wants a different subset, or that needs to inject ranges derived from data (for example, a list of calendar years for which transactions exist), has no way to do so without either forking the component or hiding rows in CSS. This change adds two opt-in props that close that gap without affecting any existing call site.

DateRangeInput now accepts an allowedOptions prop (an explicit allowlist of built-in DateRangeOptions, rendered in the order given) and a dynamicOptions prop (caller-supplied entries with pre-baked startDate/endDate, rendered between the static options and the CUSTOM row). When both are omitted, the dropdown renders exactly the same nine entries it did before, so no other consumer needs to change. A new LAST_12_MONTHS enum value and matching getLast12MonthsDateRange() method on DateRange are added at the same time — intentionally excluded from the default option set, so they only appear when a caller explicitly opts in via allowedOptions. The option-building and dynamic-value lookup logic was lifted into a helpers.ts module that can be unit-tested without rendering react-select, and useDateRange was hardened so that a persisted dynamic value (an arbitrary string that is not a known enum value) does not cause getDates(option) to throw when the hook recomputes on mount.

The convention this PR establishes is: when a shared component needs to support per-consumer variation, prefer additive opt-in props with backward-compatible defaults over a forked component. Adding new entries to a shared enum is fine, but only wire them into the default option list when every existing consumer is intended to see them — otherwise gate visibility behind the explicit allowedOptions allowlist so the default behaviour stays frozen.

Jira link: https://lite-farm.atlassian.net/browse/LF-5300

Type of change

  • New feature (non-breaking change which adds functionality)
  • Bug fix (non-breaking change which fixes an issue)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

How Has This Been Tested?

  • Passes test case
  • UI components visually reviewed on desktop view
  • UI components visually reviewed on mobile view
  • Other (please explain): pnpm exec vitest run src/tests/dateRange.test.js src/tests/dateRangeSelectorHelpers.test.js — 204 tests pass (192 existing DateRange cases plus three new LAST_12_MONTHS expectations, plus 12 new helpers tests covering allowedOptions filtering, dynamicOptions insertion before CUSTOM, dynamic-option label pass-through, isStaticDateRangeOption, and findDynamicDateRange). No local frontend was running; visual review of the rendered dropdown was not performed and should be confirmed when the dynamic-options consumer lands.

Checklist:

  • I have commented my code, particularly in hard-to-understand areas
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • The precommit and linting ran successfully
  • I have added or updated language tags for text that's part of the UI
  • I have ordered translation keys alphabetically (optional: run pnpm i18n to help with this)
  • I have added the GNU General Public License to all new files

…ear entries

Adds two new props to the shared DateRangeSelector: `allowedOptions` to
restrict which built-in options are rendered, and `dynamicOptions` for
caller-supplied entries (such as per-year ranges derived from data).
Selecting a dynamic entry persists its pre-baked startDate/endDate into the
date-range state without involving the DateRange utility class.

Also adds a `LAST_12_MONTHS` enum value with a corresponding
`getLast12MonthsDateRange()` method on the DateRange utility. This option
is intentionally excluded from the default option list — existing call
sites see no change in dropdown contents — and is available only when a
caller explicitly includes it via `allowedOptions`.

Option-building and value-resolution logic was extracted to a `helpers.ts`
module so it can be unit-tested without rendering react-select. The
`useDateRange` hook now skips the on-mount date recompute when the
persisted option is a caller-supplied dynamic value rather than a built-in
enum value, preventing a runtime error if such an option is restored from
Redux Persist.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@litefarm-pr-bot litefarm-pr-bot requested review from a team as code owners May 25, 2026 15:29
@litefarm-pr-bot litefarm-pr-bot requested review from kathyavini and removed request for a team May 25, 2026 15:29
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.

1 participant