Skip to content

Conversation

@Kneesal
Copy link
Member

@Kneesal Kneesal commented Jan 29, 2026

Summary by CodeRabbit

  • New Features

    • Added interactive date range picker to analytics overlay and support for custom date ranges in analytics queries
  • Bug Fixes

    • Improved error handling with a clear "Invalid date range" message when selections are invalid
  • Tests

    • Added tests covering date range construction, validation, fallback behavior, and analytics fetching with custom ranges
  • Localization

    • Added translation entry for "Invalid date range"

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

@Kneesal Kneesal requested a review from csiyang January 29, 2026 02:37
@Kneesal Kneesal self-assigned this Jan 29, 2026
@linear
Copy link

linear bot commented Jan 29, 2026

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 29, 2026

Walkthrough

Adds date-range filtering to the analytics overlay: new buildPlausibleDateRange utility, DateRangePicker state and UI in AnalyticsOverlaySwitch, GraphQL query support for custom periods using formatted dates, improved error handling, and tests for the utility and component behavior.

Changes

Cohort / File(s) Summary
Date Range Utility
apps/journeys-admin/src/components/Editor/Slider/JourneyFlow/AnalyticsOverlaySwitch/buildPlausibleDateRange/buildPlausibleDateRange.ts, apps/journeys-admin/src/components/Editor/Slider/JourneyFlow/AnalyticsOverlaySwitch/buildPlausibleDateRange/index.ts, apps/journeys-admin/src/components/Editor/Slider/JourneyFlow/AnalyticsOverlaySwitch/buildPlausibleDateRange/buildPlausibleDateRange.spec.ts
Adds buildPlausibleDateRange to produce a "YYYY-MM-DD,YYYY-MM-DD" range with fallbacks and validation; adds barrel export and unit tests covering valid, null, and invalid-order cases.
Analytics Overlay Component
apps/journeys-admin/src/components/Editor/Slider/JourneyFlow/AnalyticsOverlaySwitch/AnalyticsOverlaySwitch.tsx
Integrates start/end date state and DateRangePicker UI, computes formattedDateRange via buildPlausibleDateRange, includes date-validity in GraphQL skip logic, and distinguishes "Invalid date range" vs general fetch errors. Layout updated to vertical Stack.
Component Tests
apps/journeys-admin/src/components/Editor/Slider/JourneyFlow/AnalyticsOverlaySwitch/AnalyticsOverlaySwitch.spec.tsx
Adds imports and mocks for buildPlausibleDateRange, updates existing toggle test to mock plausible range, and adds a test verifying analytics fetch for a selected custom date range (uses formatted ISO dates).
Localization
libs/locales/en/apps-journeys-admin.json
Adds translation key "Invalid date range" used by the component error handling.

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant DateRangePicker as DateRangePicker
    participant Overlay as AnalyticsOverlaySwitch
    participant Formatter as buildPlausibleDateRange
    participant GraphQL as GraphQLQuery

    User->>DateRangePicker: Select start & end dates
    DateRangePicker->>Overlay: Update startDate/endDate
    User->>Overlay: Enable analytics (toggle on)
    Overlay->>Formatter: buildPlausibleDateRange(startDate,endDate,fallbacks)
    Formatter->>Formatter: Validate & format YYYY-MM-DD,YYYY-MM-DD
    Formatter-->>Overlay: Return formattedDateRange
    Overlay->>GraphQL: Fetch analytics(period='custom', date=formattedDateRange)
    GraphQL-->>Overlay: Return data or error
    alt Invalid date range
        Overlay->>User: Show "Invalid date range" snackbar
    else Fetch error
        Overlay->>User: Show "Error fetching analytics" snackbar
    else Success
        Overlay->>User: Render analytics overlay
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • csiyang
  • Ur-imazing
🚥 Pre-merge checks | ✅ 4 | ❌ 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 (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'fix: plausible date range filtering' directly reflects the main change: implementing date range filtering functionality for analytics, which aligns with the linked issue's requirement to add a date filter to the analytics overlay.
Linked Issues check ✅ Passed The PR successfully implements the core requirement from NES-1229: adding a date filter to the analytics overlay. Changes include DateRangePicker integration, date range validation, and UI updates to display the filter when analytics is enabled.
Out of Scope Changes check ✅ Passed All changes are directly related to implementing date range filtering for the analytics overlay. File modifications include the component update, date range utility function, test coverage, and translation strings—all necessary for the feature.

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

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch nisalcottingham/nes-1229-existing-feature-improvement

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.

@nx-cloud
Copy link

nx-cloud bot commented Jan 29, 2026

View your CI Pipeline Execution ↗ for commit a5badae

Command Status Duration Result
nx run watch-e2e:e2e ✅ Succeeded 21s View ↗
nx run journeys-admin-e2e:e2e ✅ Succeeded 28s View ↗
nx run journeys-e2e:e2e ✅ Succeeded 20s View ↗
nx run videos-admin-e2e:e2e ✅ Succeeded 4s View ↗
nx run resources-e2e:e2e ✅ Succeeded 9s View ↗
nx run player-e2e:e2e ✅ Succeeded 3s View ↗
nx run watch-modern-e2e:e2e ✅ Succeeded 4s View ↗
nx run-many --target=vercel-alias --projects=jo... ✅ Succeeded 2s View ↗
Additional runs (20) ✅ Succeeded ... View ↗

☁️ Nx Cloud last updated this comment at 2026-01-29 02:50:38 UTC

@github-actions github-actions bot requested a deployment to Preview - journeys-admin January 29, 2026 02:38 Pending
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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/journeys-admin/src/components/Editor/Slider/JourneyFlow/AnalyticsOverlaySwitch/AnalyticsOverlaySwitch.tsx (1)

58-70: Error handling logic appears inverted.

When isDateRangeValid is true (dates are valid), the code shows "Invalid date range" error. This is backwards:

  • If isDateRangeValid === false → show "Invalid date range"
  • If isDateRangeValid === true but query fails → show "Error fetching analytics"
🐛 Proposed fix
     onError: (_) => {
-      if (isDateRangeValid) {
+      if (!isDateRangeValid) {
         enqueueSnackbar(t('Invalid date range'), {
           variant: 'error',
           preventDuplicate: true
         })
         return
       }
       enqueueSnackbar(t('Error fetching analytics'), {
         variant: 'error',
         preventDuplicate: true
       })
     }
🤖 Fix all issues with AI agents
In
`@apps/journeys-admin/src/components/Editor/Slider/JourneyFlow/AnalyticsOverlaySwitch/buildPlausibleDateRange/buildPlausibleDateRange.spec.ts`:
- Around line 50-52: The test in buildPlausibleDateRange.spec.ts calls formatISO
on fallbackStart/fallbackEnd which are strings; update the expectation to match
the implementation by either converting those string fixtures to Date objects
before calling formatISO or (simpler) assert the raw string returned by
buildPlausibleDateRange: replace formatISO(fallbackStart/End, ...) with the
plain fallbackStart and fallbackEnd values so the expectation matches the
buildPlausibleDateRange behavior (refer to fallbackStart, fallbackEnd and the
buildPlausibleDateRange test case).
🧹 Nitpick comments (3)
apps/journeys-admin/src/components/Editor/Slider/JourneyFlow/AnalyticsOverlaySwitch/AnalyticsOverlaySwitch.tsx (1)

48-51: Note: The skip condition already prevents queries with invalid date ranges.

Since the query is skipped when isDateRangeValid !== true, the onError handler will only fire when the date range is valid. This makes the isDateRangeValid check inside onError (lines 59-65) effectively dead code—if the logic is corrected per the previous comment, the "Invalid date range" branch would never execute.

Consider simplifying the error handler to only show the general error message, or document why the defensive check is retained.

apps/journeys-admin/src/components/Editor/Slider/JourneyFlow/AnalyticsOverlaySwitch/AnalyticsOverlaySwitch.spec.tsx (2)

3-3: Unused import: userEvent is never used.

fireEvent is used on line 140 instead. Remove the unused import.

♻️ Proposed fix
-import userEvent from '@testing-library/user-event'

19-20: Consider moving imports before the mock setup.

While Jest hoists jest.mock calls, having regular imports scattered after the mock setup reduces readability. The conventional pattern groups all imports at the top before any mock setup.

♻️ Suggested import ordering
 import { MockedProvider } from '@apollo/client/testing'
 import { fireEvent, render, screen, waitFor } from '@testing-library/react'
-import userEvent from '@testing-library/user-event'
+import { formatISO } from 'date-fns'
 
 import { EditorProvider } from '@core/journeys/ui/EditorProvider'
 import { JourneyProvider } from '@core/journeys/ui/JourneyProvider'
 import { getJourneyAnalytics } from '@core/journeys/ui/useJourneyAnalyticsQuery/useJourneyAnalyticsQuery.mock'
 
 import { GetJourney_journey } from '../../../../../../__generated__/GetJourney'
 
 import { earliestStatsCollected } from './AnalyticsOverlaySwitch'
 import { buildPlausibleDateRange } from './buildPlausibleDateRange'
+import { AnalyticsOverlaySwitch } from '.'
 
 jest.mock('./buildPlausibleDateRange')
 
 const mockBuildPlausibleDateRange =
   buildPlausibleDateRange as jest.MockedFunction<typeof buildPlausibleDateRange>
 
-import { AnalyticsOverlaySwitch } from '.'
-import { formatISO } from 'date-fns'
-
 const mockCurrentDate = '2024-06-02'

Comment on lines +50 to +52
expect(result).toBe(
`${formatISO(fallbackStart, { representation: 'date' })},${formatISO(fallbackEnd, { representation: 'date' })}`
)
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 | 🟡 Minor

Test expectation is incorrect — formatISO is called on a string.

fallbackStart is a string ('2024-06-01'), but formatISO expects a Date object. The implementation in buildPlausibleDateRange.ts uses fallbackStartDate directly as a string without formatting.

This test will fail because formatISO(fallbackStart, ...) will throw or produce unexpected output.

🐛 Proposed fix
     expect(result).toBe(
-      `${formatISO(fallbackStart, { representation: 'date' })},${formatISO(fallbackEnd, { representation: 'date' })}`
+      `${fallbackStart},${formatISO(fallbackEnd, { representation: 'date' })}`
     )
📝 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
expect(result).toBe(
`${formatISO(fallbackStart, { representation: 'date' })},${formatISO(fallbackEnd, { representation: 'date' })}`
)
expect(result).toBe(
`${fallbackStart},${formatISO(fallbackEnd, { representation: 'date' })}`
)
🤖 Prompt for AI Agents
In
`@apps/journeys-admin/src/components/Editor/Slider/JourneyFlow/AnalyticsOverlaySwitch/buildPlausibleDateRange/buildPlausibleDateRange.spec.ts`
around lines 50 - 52, The test in buildPlausibleDateRange.spec.ts calls
formatISO on fallbackStart/fallbackEnd which are strings; update the expectation
to match the implementation by either converting those string fixtures to Date
objects before calling formatISO or (simpler) assert the raw string returned by
buildPlausibleDateRange: replace formatISO(fallbackStart/End, ...) with the
plain fallbackStart and fallbackEnd values so the expectation matches the
buildPlausibleDateRange behavior (refer to fallbackStart, fallbackEnd and the
buildPlausibleDateRange test case).

@github-actions
Copy link
Contributor

The latest updates on your projects.

Name Status Preview Updated (UTC)
watch-modern ✅ Ready watch-modern preview Thu Jan 29 15:45:26 NZDT 2026

@github-actions
Copy link
Contributor

The latest updates on your projects.

Name Status Preview Updated (UTC)
player ✅ Ready player preview Thu Jan 29 15:45:43 NZDT 2026

@github-actions
Copy link
Contributor

The latest updates on your projects.

Name Status Preview Updated (UTC)
journeys ✅ Ready journeys preview Thu Jan 29 15:46:10 NZDT 2026

@github-actions
Copy link
Contributor

The latest updates on your projects.

Name Status Preview Updated (UTC)
videos-admin ✅ Ready videos-admin preview Thu Jan 29 15:46:33 NZDT 2026

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/journeys-admin/src/components/Editor/Slider/JourneyFlow/AnalyticsOverlaySwitch/AnalyticsOverlaySwitch.tsx (1)

59-71: Inverted error handling logic.

The condition if (isDateRangeValid) will always be true when onError is called, because the query skips when isDateRangeValid !== true (line 52). This means the "Invalid date range" error message will display for all GraphQL errors, even server errors unrelated to the date range.

If the intent is to show "Invalid date range" only when the server rejects the date parameters, you should check the error object for a specific error code or message rather than relying on isDateRangeValid.

🐛 Proposed fix

Either remove the date range check entirely (since it's always true at this point):

    onError: (_) => {
-      if (isDateRangeValid) {
-        enqueueSnackbar(t('Invalid date range'), {
-          variant: 'error',
-          preventDuplicate: true
-        })
-        return
-      }
      enqueueSnackbar(t('Error fetching analytics'), {
        variant: 'error',
        preventDuplicate: true
      })
    }

Or if the API returns a specific error for invalid date ranges, check for it:

-    onError: (_) => {
-      if (isDateRangeValid) {
-        enqueueSnackbar(t('Invalid date range'), {
+    onError: (error) => {
+      // Check if the error is specifically about date range
+      if (error.message.includes('date range')) {
         enqueueSnackbar(t('Invalid date range'), {
🧹 Nitpick comments (1)
apps/journeys-admin/src/components/Editor/Slider/JourneyFlow/AnalyticsOverlaySwitch/AnalyticsOverlaySwitch.spec.tsx (1)

3-3: Remove unused import.

userEvent is imported but never used in the test file. Either remove it or consider using it instead of fireEvent for the checkbox click on line 140, as userEvent better simulates real user interactions.

♻️ Proposed fix

If removing:

-import userEvent from '@testing-library/user-event'

Or if using userEvent instead of fireEvent:

-    fireEvent.click(analyticsCheckbox)
+    await userEvent.click(analyticsCheckbox)

@github-actions
Copy link
Contributor

The latest updates on your projects.

Name Status Preview Updated (UTC)
resources ✅ Ready resources preview Thu Jan 29 15:47:01 NZDT 2026

@github-actions
Copy link
Contributor

The latest updates on your projects.

Name Status Preview Updated (UTC)
watch ✅ Ready watch preview Thu Jan 29 15:47:05 NZDT 2026

@github-actions
Copy link
Contributor

The latest updates on your projects.

Name Status Preview Updated (UTC)
journeys-admin ✅ Ready journeys-admin preview Thu Jan 29 15:47:36 NZDT 2026

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants