You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Opening Manage Timings, Allocate or Reschedule drops you into a calendar showing an arbitrary week at an arbitrary scroll position. If the booking you came to edit is on Saturday at 10:30, you have to find Saturday and then scroll down past ten hours of empty night-time rows before you can see it.
The picker should open already looking at the thing you clicked.
What you see today
Two separate problems, and they need separate answers.
Vertical. The grid renders 00:00 through 23:30 and opens at the top. Every consultant's real working day is somewhere in the middle, so the first interaction on every visit is scrolling.
Horizontal. The week shown is the current week, not the week the booking is in. For a session next month you navigate week by week to reach it.
The screenshot that prompted this shows both: a booking at 10:30 on Saturday 1 August, in a grid scrolled to 09:00 with the row barely visible, on a week the user happened to already be in.
What it should do
Open focused on the subject of the page, then let the user navigate freely from there. Concretely: pick a target instant, move the visible week to contain it, and scroll the time axis so it sits comfortably in view rather than flush against the top edge.
The interesting part is choosing that instant, because it differs per surface and per offering type.
One-session bookings — consultation, webinar
Unambiguous. The target is the session's own start. Manage Timings and Reschedule both have exactly one thing being placed.
Prolonged bookings — subscription, class
This is the case that makes the feature non-trivial, and the reason it deserves a decision rather than an implementation guess. A subscription is N sessions spread over weeks or months, each on its own Appointment row. The picker shows one week. So "the booking" is not a single point on the grid.
Candidate targets, roughly in order of how defensible they are:
The next session that has not happened yet. Usually what a consultant means by "this booking" — the thing that is about to affect their week. Falls back to the most recent past session when they are all over.
The earliest session still awaiting a time. Right for Manage Timings on a partly-scheduled program, where the job is to fill the gaps rather than look at what is already placed.
The specific session that was clicked. Correct for Reschedule, where the user picked one session from the release step and that session is unambiguously the subject.
These are not competing — they are per-surface answers. Reschedule knows which session; Manage Timings on a partly-placed program means (2); Manage Timings on a fully-placed one means (1).
Worth deciding explicitly: on a subscription whose sessions run Tuesdays and Thursdays for three months, is jumping the user to week 7 helpful or disorienting? A defensible alternative is to focus the time of day always, but only move the week when the target is outside the currently visible one.
Nothing scheduled yet
An unscheduled class or webinar (the unscheduled-class-<id> / unscheduled-webinar-<id> synthetic ids) has no slot to focus. The sensible target is the start of the scheduling period, clamped to not be in the past — the picker already clamps selection to allowedStart/allowedEnd, so this reuses a bound it knows. Vertically, the consultant's own earliest published availability is a better anchor than 00:00.
Allocate
A pending request may carry requested times, in which case those are the target. If it does not, the same "first availability" fallback as above applies.
Why this is less complex than it looks
The pieces mostly exist. SlotPicker already receives a SlotPickerSubject carrying the slots, the event type and the scheduling period, so the target can be derived from data already on the page — no new query. The calendar already supports week navigation, so this is choosing an initial value rather than building a mechanism.
The genuinely fiddly parts are narrow:
Scrolling must happen after the grid has rendered its rows, and must not fight the user if they scroll immediately.
It must fire once per subject, not on every re-render, or the grid will yank itself back while someone is trying to look elsewhere.
Opening Manage Timings, Allocate or Reschedule drops you into a calendar showing an arbitrary week at an arbitrary scroll position. If the booking you came to edit is on Saturday at 10:30, you have to find Saturday and then scroll down past ten hours of empty night-time rows before you can see it.
The picker should open already looking at the thing you clicked.
What you see today
Two separate problems, and they need separate answers.
Vertical. The grid renders 00:00 through 23:30 and opens at the top. Every consultant's real working day is somewhere in the middle, so the first interaction on every visit is scrolling.
Horizontal. The week shown is the current week, not the week the booking is in. For a session next month you navigate week by week to reach it.
The screenshot that prompted this shows both: a booking at 10:30 on Saturday 1 August, in a grid scrolled to 09:00 with the row barely visible, on a week the user happened to already be in.
What it should do
Open focused on the subject of the page, then let the user navigate freely from there. Concretely: pick a target instant, move the visible week to contain it, and scroll the time axis so it sits comfortably in view rather than flush against the top edge.
The interesting part is choosing that instant, because it differs per surface and per offering type.
One-session bookings — consultation, webinar
Unambiguous. The target is the session's own start.
Manage TimingsandRescheduleboth have exactly one thing being placed.Prolonged bookings — subscription, class
This is the case that makes the feature non-trivial, and the reason it deserves a decision rather than an implementation guess. A subscription is N sessions spread over weeks or months, each on its own
Appointmentrow. The picker shows one week. So "the booking" is not a single point on the grid.Candidate targets, roughly in order of how defensible they are:
These are not competing — they are per-surface answers. Reschedule knows which session; Manage Timings on a partly-placed program means (2); Manage Timings on a fully-placed one means (1).
Worth deciding explicitly: on a subscription whose sessions run Tuesdays and Thursdays for three months, is jumping the user to week 7 helpful or disorienting? A defensible alternative is to focus the time of day always, but only move the week when the target is outside the currently visible one.
Nothing scheduled yet
An unscheduled class or webinar (the
unscheduled-class-<id>/unscheduled-webinar-<id>synthetic ids) has no slot to focus. The sensible target is the start of the scheduling period, clamped to not be in the past — the picker already clamps selection toallowedStart/allowedEnd, so this reuses a bound it knows. Vertically, the consultant's own earliest published availability is a better anchor than 00:00.Allocate
A pending request may carry requested times, in which case those are the target. If it does not, the same "first availability" fallback as above applies.
Why this is less complex than it looks
The pieces mostly exist.
SlotPickeralready receives aSlotPickerSubjectcarrying the slots, the event type and the scheduling period, so the target can be derived from data already on the page — no new query. The calendar already supports week navigation, so this is choosing an initial value rather than building a mechanism.The genuinely fiddly parts are narrow:
schedulingTimezone(ADR B9). Choosing the row must use the same timezone the columns were drawn in, or the focus will be off by the UTC offset — the same class of bug as thedatetime-localdefect fixed in feat(reschedule): dedicated pages, withdrawal, and an auto-confirm that cannot half-write #1064.Scope
Applies to all four picker surfaces, since they share one component: Manage Timings, Allocate, and both Reschedule routes.
Out of scope: any change to what is selectable, to the palette, or to the allocation rules. This is purely where the viewport starts.
Open questions for a decision before implementation