Skip to content

feat(calendar): autoscroll week view to first available slot#29559

Closed
GAURAV07C wants to merge 1 commit into
calcom:mainfrom
GAURAV07C:feat/calendar-autoscroll
Closed

feat(calendar): autoscroll week view to first available slot#29559
GAURAV07C wants to merge 1 commit into
calcom:mainfrom
GAURAV07C:feat/calendar-autoscroll

Conversation

@GAURAV07C

Copy link
Copy Markdown

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

  • Added logic in Calendar.tsx to calculate the firstAvailableSlot for the displayed week.
  • Used scrollIntoView({ block: "start", behavior: "smooth" }) on an invisible anchor element positioned 150 minutes prior to the firstAvailableSlot.
  • The 150-minute offset provides clean visual breathing room and ensures the time slot isn't hidden under the sticky days-of-the-week header.
  • Maintained the native DOM traversal for scrolling because the time grid itself is not an internally scrollable container (the browser window/main layout handles the scroll). This exactly mimics the existing and stable CurrentTime marker 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

  • Bug fix
  • New feature / UX Improvement
  • Refactoring

Checklist

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have tested the changes locally

@github-actions

Copy link
Copy Markdown
Contributor

Welcome to Cal.diy, @GAURAV07C! Thanks for opening this pull request.

A few things to keep in mind:

  • This is Cal.diy, not Cal.com. Cal.diy is a community-driven, fully open-source fork of Cal.com licensed under MIT. Your changes here will be part of Cal.diy — they will not be deployed to the Cal.com production app.
  • Please review our Contributing Guidelines if you haven't already.
  • Make sure your PR title follows the Conventional Commits format.

A maintainer will review your PR soon. Thanks for contributing!

@github-actions

Copy link
Copy Markdown
Contributor

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:

No release type found in pull request title " feat(calendar): autoscroll week view to first available slot". Add a prefix to indicate what kind of release this pull request corresponds to. For reference, see https://www.conventionalcommits.org/

Available types:
 - feat: A new feature
 - fix: A bug fix
 - docs: Documentation only changes
 - style: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)
 - refactor: A code change that neither fixes a bug nor adds a feature
 - perf: A code change that improves performance
 - test: Adding missing tests or correcting existing tests
 - build: Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm)
 - ci: Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs)
 - chore: Other changes that don't modify src or test files
 - revert: Reverts a previous commit

@coderabbitai

coderabbitai Bot commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The weekly calendar now computes the earliest available timeslot from availableTimeslots using the selected timezone. It adds state, a ref, and an effect to scroll once to that slot through a hidden positioned element. The current-time auto-scroll logic is now conditional on whether availability exists. Rendering was updated to pass shouldScrollToCurrentTime to CurrentTime and to insert the hidden scroll target at the computed vertical position for the earliest slot.

🚥 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
Title check ✅ Passed The title accurately summarizes the main change: adding auto-scroll functionality to the calendar week view to jump to the first available slot.
Description check ✅ Passed The description is directly related to the changeset, explaining the problem, the solution implemented, and the expected UX improvements with before/after examples.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@coderabbitai coderabbitai Bot left a comment

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.

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

📥 Commits

Reviewing files that changed from the base of the PR and between 9104545 and ffebfa1.

📒 Files selected for processing (1)
  • apps/web/modules/calendars/weeklyview/components/Calendar.tsx

Comment on lines +77 to +84
useEffect(() => {
if (firstAvailableSlot !== null && dummyScrollRef.current && !hasScrolledToAvailableSlot) {
setTimeout(() => {
dummyScrollRef.current?.scrollIntoView({ block: "start", behavior: "smooth" });
setHasScrolledToAvailableSlot(true);
}, 100);
}
}, [firstAvailableSlot, hasScrolledToAvailableSlot]);

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 | 🟡 Minor | ⚡ Quick win

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.

Comment on lines +91 to +93
const hasAvailableTimeslots = availableTimeslots && Object.keys(availableTimeslots).length > 0;
const shouldScrollToCurrentTime = scrollToCurrentTime && !hasAvailableTimeslots;

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 | ⚡ Quick win

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.

Suggested change
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`.

@CLAassistant

CLAassistant commented Jun 14, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@bandhan-majumder

Copy link
Copy Markdown
Member

issue has a needs approval tag. Please don't start until the tag is removed. Closing

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants