Skip to content

Conversation

@kylengn
Copy link
Contributor

@kylengn kylengn commented Jan 14, 2026

Summary by CodeRabbit

  • New Features
    • Added a new interval selector component to the UI library. Users can select from predefined time periods (1 hour, 6 hours, 12 hours, 1 day, 2 days, 1 week, or 1 month) or define custom date ranges using an integrated calendar interface.

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


Note

Introduces a new IntervalSelector component suite and replaces dashboard "time period" with a shared IntervalSelection state.

  • New components/interval-selector (input, suggestions, calendar, hooks, types, stories) with keyboard navigation, popover container support, and invalid-input shake animation (index.css)
  • Dashboard updates: context now exposes selection (replaces timePeriod), PageToolbar embeds IntervalSelector, AnalyticsPage/JobsPage simplified to use context-driven interval
  • Popover updated to accept optional container; components index exports interval-selector
  • Date/time utils enhanced: parse duration shortcuts and natural language intervals, improved range/datetime formatting, and robust unit shortcut generation; comprehensive unit tests added
  • Build/test: add @radix-ui/react-dismissable-layer dependency, vitest split configs (storybook/unit) with setup cleanup; changeset for minor release

Written by Cursor Bugbot for commit 103793b. This will update automatically on new commits. Configure here.

@kylengn kylengn self-assigned this Jan 14, 2026
Copilot AI review requested due to automatic review settings January 14, 2026 07:13
@kylengn kylengn requested a review from dvxam as a code owner January 14, 2026 07:13
@vercel
Copy link

vercel bot commented Jan 14, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
react-ui Ready Ready Preview, Comment Jan 21, 2026 10:46am

Request Review

@kylengn kylengn changed the title feat(ui): add IntervalSelector component for selecting time intervals feat(ui): add IntervalSelector component Jan 14, 2026
@coderabbitai
Copy link

coderabbitai bot commented Jan 14, 2026

Important

Review skipped

Auto incremental reviews are disabled on this repository.

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.

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

A new interval selector component system is introduced, featuring a Select-based control that enables users to choose from predefined past intervals (1h, 6h, 12h, 1d, 2d, 1w, 1mo) or select custom ranges via an integrated calendar picker, with state management and utility functions for interval matching and option discovery.

Changes

Cohort / File(s) Summary
Core Components
libs/react/ui/src/components/interval-selector/interval-selector.tsx, interval-selector-content.tsx
New IntervalSelector wrapper component managing dropdown and calendar visibility states, coordinating selection events and interval updates. IntervalSelectorContent sub-component renders either a calendar (when open) or predefined interval options with keyboard shortcuts.
Utilities & Types
libs/react/ui/src/components/interval-selector/interval-selector.utils.ts
New types (IntervalOptionType, IntervalOption) and constants (PAST_INTERVALS with 7 predefined intervals). Utility functions: findOption() for lookup and findOptionValueForInterval() for mapping intervals to matching predefined options within tolerance.
Exports
libs/react/ui/src/components/interval-selector/index.ts, libs/react/ui/src/components/index.ts
Barrel files re-exporting interval-selector module and utilities; makes IntervalSelector available as public API.
Storybook
libs/react/ui/src/components/interval-selector/interval-selector.stories.tsx
Story file with ControlledIntervalSelector component managing internal interval state and demonstrating default use case with 1-hour initial interval.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant IntervalSelector
    participant IntervalSelectorContent
    participant Calendar

    User->>IntervalSelector: Click preset option
    IntervalSelector->>IntervalSelector: Update value & state
    IntervalSelector->>User: Call onIntervalChange callback

    User->>IntervalSelectorContent: Click calendar button
    IntervalSelectorContent->>IntervalSelectorContent: Set calendarOpen = true
    IntervalSelectorContent->>Calendar: Render calendar in range mode

    User->>Calendar: Select date range
    Calendar->>IntervalSelectorContent: Range selection (from, to)
    IntervalSelectorContent->>IntervalSelectorContent: Validate range
    IntervalSelectorContent->>User: Call onCalendarSelect callback
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

Suggested reviewers

  • noe-charmet
  • EnzalRad
  • dvxam

Poem

🐰 A selector hops with intervals in hand,
Picking past moments or futures yet unplanned.
With calendar clicks and preset delight,
Time ranges flow smooth—chef's kiss—just right! 🗓️

🚥 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 title clearly and concisely summarizes the main change: adding a new IntervalSelector component to the UI library. It directly reflects the primary purpose of the changeset.

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


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.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR introduces a new IntervalSelector component for selecting time intervals. The component supports both predefined time intervals (like "Past 1 hour", "Past 6 hours") and custom date ranges via a calendar picker.

Changes:

  • New IntervalSelector component with utility functions, main component, content subcomponent, and Storybook story
  • Exports added to main component index

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
interval-selector.utils.ts Defines interval options and utility functions for finding and matching intervals
interval-selector.tsx Main component with state management for select and calendar open states
interval-selector-content.tsx Renders either calendar or list of preset intervals based on state
interval-selector.stories.tsx Storybook story demonstrating component usage
interval-selector/index.ts Exports component and utilities
components/index.ts Adds IntervalSelector to main exports

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link

@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 `@libs/react/ui/src/components/interval-selector/interval-selector.tsx`:
- Around line 47-52: The calendar selection handler handleCalendarSelect doesn't
close the dropdown after a full range is chosen; update it so that when
range?.from and range?.to are present you call onIntervalChange({start:
range.from, end: range.to}), onValueChange?.('custom') and then call
setSelectOpen(false) (same behavior as handleOptionSelect) to ensure the
dropdown is dismissed immediately after selection.
🧹 Nitpick comments (2)
libs/react/ui/src/components/interval-selector/interval-selector.stories.tsx (1)

36-42: Consider removing unused args since render overrides them.

The args object at lines 37-40 is not used because the render function returns <ControlledIntervalSelector /> which manages its own state. These args appear in Storybook's Controls panel but don't affect the rendered component.

♻️ Suggested simplification
 export const Default: Story = {
-  args: {
-    interval: intervalToNowFromDuration({hours: 1}),
-    onIntervalChange: () => undefined,
-  },
   render: () => <ControlledIntervalSelector />,
 };
libs/react/ui/src/components/interval-selector/interval-selector-content.tsx (1)

50-60: Unnecessary truthiness check for required prop.

The interval prop is required (not optional) in IntervalSelectorContentProps, so the interval ? ... : undefined check is redundant.

♻️ Suggested simplification
         <Calendar
           mode="range"
-          selected={
-            interval
-              ? ({
-                  from: interval.start,
-                  to: interval.end,
-                } as DayPickerDateRange)
-              : undefined
-          }
+          selected={{
+            from: interval.start,
+            to: interval.end,
+          } as DayPickerDateRange}
           onSelect={handleCalendarSelect}
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4524cca and d7d06d4.

📒 Files selected for processing (6)
  • libs/react/ui/src/components/index.ts
  • libs/react/ui/src/components/interval-selector/index.ts
  • libs/react/ui/src/components/interval-selector/interval-selector-content.tsx
  • libs/react/ui/src/components/interval-selector/interval-selector.stories.tsx
  • libs/react/ui/src/components/interval-selector/interval-selector.tsx
  • libs/react/ui/src/components/interval-selector/interval-selector.utils.ts
🧰 Additional context used
📓 Path-based instructions (1)
**/*

⚙️ CodeRabbit configuration file

We handle errors at the edge of our applications in most cases. Do not recommend to add error handling around every single function. We prefer them to bubble up and be handled at upper layers.

Files:

  • libs/react/ui/src/components/interval-selector/index.ts
  • libs/react/ui/src/components/interval-selector/interval-selector-content.tsx
  • libs/react/ui/src/components/interval-selector/interval-selector.tsx
  • libs/react/ui/src/components/index.ts
  • libs/react/ui/src/components/interval-selector/interval-selector.utils.ts
  • libs/react/ui/src/components/interval-selector/interval-selector.stories.tsx
🧬 Code graph analysis (4)
libs/react/ui/src/components/interval-selector/interval-selector-content.tsx (3)
libs/react/ui/src/components/select/select.tsx (3)
  • SelectContent (212-212)
  • SelectItem (214-214)
  • SelectSeparator (215-215)
libs/react/ui/src/components/calendar/calendar.tsx (1)
  • Calendar (8-90)
libs/react/ui/src/components/interval-selector/interval-selector.utils.ts (1)
  • PAST_INTERVALS (14-22)
libs/react/ui/src/components/interval-selector/interval-selector.tsx (4)
libs/react/ui/src/components/interval-selector/interval-selector.utils.ts (1)
  • findOption (24-26)
libs/react/ui/src/utils/date.ts (1)
  • intervalToNowFromDuration (34-51)
libs/react/ui/src/components/select/select.tsx (3)
  • Select (208-208)
  • SelectTrigger (211-211)
  • SelectValue (210-210)
libs/react/ui/src/components/interval-selector/interval-selector-content.tsx (1)
  • IntervalSelectorContent (20-97)
libs/react/ui/src/components/interval-selector/interval-selector.utils.ts (1)
libs/react/ui/src/utils/date.ts (1)
  • intervalToNowFromDuration (34-51)
libs/react/ui/src/components/interval-selector/interval-selector.stories.tsx (2)
libs/react/ui/src/utils/date.ts (1)
  • intervalToNowFromDuration (34-51)
libs/react/ui/src/components/interval-selector/interval-selector.utils.ts (1)
  • findOptionValueForInterval (28-54)
⏰ 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). (2)
  • GitHub Check: Agent
  • GitHub Check: Continuous integration
🔇 Additional comments (12)
libs/react/ui/src/components/interval-selector/interval-selector.utils.ts (3)

1-12: LGTM!

The type definitions are well-structured. IntervalOptionType clearly distinguishes between predefined past intervals and custom ranges, and IntervalOption captures all necessary properties including the optional duration for past intervals.


14-26: LGTM!

The PAST_INTERVALS constant provides a comprehensive set of commonly used time intervals, and findOption is a clean lookup implementation.


28-54: This concern is theoretical and not applicable to the actual data flow.

While NormalizedInterval type definition does allow start and end as numbers, the function only receives intervals from intervalToNowFromDuration(), which always returns Date objects. All code paths in the codebase produce Date objects, never raw timestamps. Adding defensive type checks here contradicts the project's error handling approach (errors should bubble up at application edges, not be handled throughout).

Likely an incorrect or invalid review comment.

libs/react/ui/src/components/index.ts (1)

26-26: LGTM!

The export is correctly placed in alphabetical order, following the existing barrel export pattern.

libs/react/ui/src/components/interval-selector/index.ts (1)

1-2: LGTM!

Clean barrel export that exposes both the component and its utilities.

libs/react/ui/src/components/interval-selector/interval-selector.stories.tsx (1)

19-34: LGTM!

The ControlledIntervalSelector demonstrates a clean pattern for managing the bidirectional state between interval and value, correctly falling back to 'custom' when the interval doesn't match a predefined option.

libs/react/ui/src/components/interval-selector/interval-selector-content.tsx (2)

32-36: Consider UX for partial range selection.

handleCalendarSelect silently ignores selections until both from and to are defined. This is correct for ensuring a complete range, but the user receives no visual feedback when clicking a single date. This is a common pattern for range pickers though.


73-96: LGTM!

The dropdown list view cleanly renders predefined intervals with keyboard shortcuts and provides a clear button to open the calendar picker.

libs/react/ui/src/components/interval-selector/interval-selector.tsx (4)

1-19: LGTM!

Clean imports and a well-structured interface. The separation of required interval/onIntervalChange (for the actual date range) from optional value/onValueChange (for tracking selected option) provides good flexibility for consumers.


30-33: LGTM!

Good separation of local UI state (selectOpen, calendarOpen) from the controlled interval data. Deriving intervalDisplay from the interval prop ensures the display always reflects the actual data state.


35-45: LGTM!

The handler correctly:

  1. Notifies the parent of the value change
  2. Derives the new interval from the option's duration
  3. Closes the dropdown

The guard on option?.duration is defensive, though in practice findOption should always succeed since the Select options come from PAST_INTERVALS.


54-78: LGTM!

The JSX structure is well-organized:

  • The onOpenChange guard on line 61 correctly prevents the Select from closing while the calendar is active, which is needed to keep the calendar overlay visible.
  • Props are properly wired to IntervalSelectorContent.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

@argos-ci
Copy link

argos-ci bot commented Jan 14, 2026

The latest updates on your projects. Learn more about Argos notifications ↗︎

Build Status Details Updated (UTC)
default (Inspect) 👍 Changes approved 12 changed, 3 added Jan 21, 2026, 10:47 AM

@noe-charmet
Copy link
Contributor

It looks like the implementation does not exactly match the expected outcome,
I have opened a discussion here on Slack to go through this.

…estions components for enhanced interval selection
cursor[bot]

This comment was marked as outdated.

cursor[bot]

This comment was marked as outdated.

… and maintainability (#334)

* refactor(interval-selector): restructure interval selector hooks for improved modularity and maintainability

* refactor(interval-selector): ensure selectedLabel is cleared consistently and improve navigation handling

* refactor(interval-selector): remove selection prop from IntervalSelectorCalendar and streamline date range handling

* refactor(interval-selector): modularize utility functions and enhance calendar interval handling

* Ensure correct behaviour of calendar selector

* Move tests to correct location

* Do not make calendarInterval a function

* Refactor to have a manageable state

* Fix type

* Ensure shortcut is linked with current focus state

* minor fixes

* Approximate interval to closest duration shortcut

---------

Co-authored-by: Noe Charmet <noe.charmet@shipfox.io>
cursor[bot]

This comment was marked as outdated.

cursor[bot]

This comment was marked as outdated.

cursor[bot]

This comment was marked as outdated.

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

@kylengn kylengn requested a review from noe-charmet January 21, 2026 11:34
@kylengn kylengn merged commit 2d34b03 into main Jan 21, 2026
6 checks passed
@kylengn kylengn deleted the feat/interval-selector branch January 21, 2026 12:42
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.

3 participants