feat(calendar): autoscroll week view to first available slot#29559
feat(calendar): autoscroll week view to first available slot#29559GAURAV07C wants to merge 1 commit into
Conversation
|
Welcome to Cal.diy, @GAURAV07C! Thanks for opening this pull request. A few things to keep in mind:
A maintainer will review your PR soon. Thanks for contributing! |
|
Hey there and thank you for opening this pull request! 👋🏼 We require pull request titles to follow the Conventional Commits specification and it looks like your proposed title needs to be adjusted. Details: |
📝 WalkthroughWalkthroughThe weekly calendar now computes the earliest available timeslot from 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@apps/web/modules/calendars/weeklyview/components/Calendar.tsx`:
- Around line 77-84: The scroll effect in Calendar.tsx leaves a pending
setTimeout in the useEffect callback, so add cleanup in that effect to clear the
timer if the component unmounts or dependencies change. Update the effect around
dummyScrollRef, firstAvailableSlot, and hasScrolledToAvailableSlot to store the
timeout id, clear it in the returned cleanup function, and keep the existing
scrollIntoView/setHasScrolledToAvailableSlot behavior unchanged.
- Around line 91-93: The `hasAvailableTimeslots` check on line 91 only verifies
that the `availableTimeslots` object has keys, but does not validate that those
keys contain non-empty slot arrays. When `firstAvailableSlot` function returns
null because every `slots` array is empty, `hasAvailableTimeslots` can still
evaluate to true, incorrectly causing `shouldScrollToCurrentTime` to be false
and suppressing the current time auto-scroll behavior. Update the
`hasAvailableTimeslots` logic to check not only for the existence of keys in
`availableTimeslots`, but also that at least one of the slot arrays within that
object actually contains values (is non-empty). This will align the check with
the actual availability determination in `firstAvailableSlot`.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 5ca099cd-bd25-4663-9460-3bac44ea528f
📒 Files selected for processing (1)
apps/web/modules/calendars/weeklyview/components/Calendar.tsx
| useEffect(() => { | ||
| if (firstAvailableSlot !== null && dummyScrollRef.current && !hasScrolledToAvailableSlot) { | ||
| setTimeout(() => { | ||
| dummyScrollRef.current?.scrollIntoView({ block: "start", behavior: "smooth" }); | ||
| setHasScrolledToAvailableSlot(true); | ||
| }, 100); | ||
| } | ||
| }, [firstAvailableSlot, hasScrolledToAvailableSlot]); |
There was a problem hiding this comment.
Add timeout cleanup in the scroll effect to avoid stale async callbacks.
The setTimeout on Line 79 is never cleared. If the component unmounts or state changes before it fires, the callback still runs and can trigger stale scroll/state updates.
Suggested fix
useEffect(() => {
- if (firstAvailableSlot !== null && dummyScrollRef.current && !hasScrolledToAvailableSlot) {
- setTimeout(() => {
- dummyScrollRef.current?.scrollIntoView({ block: "start", behavior: "smooth" });
- setHasScrolledToAvailableSlot(true);
- }, 100);
- }
+ if (firstAvailableSlot === null || !dummyScrollRef.current || hasScrolledToAvailableSlot) return;
+
+ const timeoutId = window.setTimeout(() => {
+ dummyScrollRef.current?.scrollIntoView({ block: "start", behavior: "smooth" });
+ setHasScrolledToAvailableSlot(true);
+ }, 100);
+
+ return () => window.clearTimeout(timeoutId);
}, [firstAvailableSlot, hasScrolledToAvailableSlot]);🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@apps/web/modules/calendars/weeklyview/components/Calendar.tsx` around lines
77 - 84, The scroll effect in Calendar.tsx leaves a pending setTimeout in the
useEffect callback, so add cleanup in that effect to clear the timer if the
component unmounts or dependencies change. Update the effect around
dummyScrollRef, firstAvailableSlot, and hasScrolledToAvailableSlot to store the
timeout id, clear it in the returned cleanup function, and keep the existing
scrollIntoView/setHasScrolledToAvailableSlot behavior unchanged.
| const hasAvailableTimeslots = availableTimeslots && Object.keys(availableTimeslots).length > 0; | ||
| const shouldScrollToCurrentTime = scrollToCurrentTime && !hasAvailableTimeslots; | ||
|
|
There was a problem hiding this comment.
hasAvailableTimeslots can suppress both scroll paths when all day arrays are empty.
Line 91 treats any keyed object as “has availability”, but firstAvailableSlot (Line 44-62) returns null when every slots array is empty. In that case, CurrentTime auto-scroll is disabled and the dummy anchor is not rendered, so no auto-scroll happens at all.
Suggested fix
- const hasAvailableTimeslots = availableTimeslots && Object.keys(availableTimeslots).length > 0;
+ const hasAvailableTimeslots = firstAvailableSlot !== null;
const shouldScrollToCurrentTime = scrollToCurrentTime && !hasAvailableTimeslots;📝 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.
| const hasAvailableTimeslots = availableTimeslots && Object.keys(availableTimeslots).length > 0; | |
| const shouldScrollToCurrentTime = scrollToCurrentTime && !hasAvailableTimeslots; | |
| const hasAvailableTimeslots = firstAvailableSlot !== null; | |
| const shouldScrollToCurrentTime = scrollToCurrentTime && !hasAvailableTimeslots; | |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@apps/web/modules/calendars/weeklyview/components/Calendar.tsx` around lines
91 - 93, The `hasAvailableTimeslots` check on line 91 only verifies that the
`availableTimeslots` object has keys, but does not validate that those keys
contain non-empty slot arrays. When `firstAvailableSlot` function returns null
because every `slots` array is empty, `hasAvailableTimeslots` can still evaluate
to true, incorrectly causing `shouldScrollToCurrentTime` to be false and
suppressing the current time auto-scroll behavior. Update the
`hasAvailableTimeslots` logic to check not only for the existence of keys in
`availableTimeslots`, but also that at least one of the slot arrays within that
object actually contains values (is non-empty). This will align the check with
the actual availability determination in `firstAvailableSlot`.
|
issue has a needs approval tag. Please don't start until the tag is removed. Closing |
feat(calendar): autoscroll week view to first available slot #29551
Description
Currently, on the week layout booking page, the time grid loads showing times starting from midnight. If a host's availability starts later in the day (e.g., 09:00), the booker has to manually scroll down to see the bookable times. This PR improves the UX by anchoring the initial view to the host's first available slot, matching the auto-scroll behavior on mobile.
Changes Made
Calendar.tsxto calculate thefirstAvailableSlotfor the displayed week.scrollIntoView({ block: "start", behavior: "smooth" })on an invisible anchor element positioned150 minutesprior to thefirstAvailableSlot.CurrentTimemarker auto-scroll behavior without yanking the parent browser window layout.Before and After
Before
(Grid opens showing 00:00 to 12:00, requiring manual scrolling to find availability)
Recording.2026-06-14.042841.mp4
After
(Grid elegantly auto-scrolls to display the first available slot perfectly below the sticky header)
Recording.2026-06-14.042458.mp4
Type of Change
Checklist