feat(calendar): full-day scheduling grid that scrolls in its box (MAPPS-387) #448

Merged
longjacksonle merged 3 commits from feat/MAPPS-387-full-day-scheduling-grid into main 2026-07-30 16:13:18 +02:00

MAPPS-387: scheduling grid spans midnight to midnight and scrolls in its box

Replaces the fixed 7 AM to 7 PM scheduling window with a full 24-hour axis across the week grid, day grid, and dispatch timeline. Every hour is now schedulable; hours outside typical working hours are visually de-emphasized rather than treated as unavailable. Axis labels stay 12-hour AM/PM (no 24-hour "18" for 6 PM).

What changed

  • Time axis spans midnight to midnight in the day/week grid and the dispatch timeline (GRID_START_HOUR/GRID_END_HOUR are now 0/24).
  • The grid scrolls inside its own container (max-h-[70vh]) instead of the page; the week view's day-of-week header sticks to the top. On mount each grid/timeline defaults its scroll to the working-hours window (7 AM to 7 PM).
  • Out-of-hours slots are muted (bg-surface-2), not struck through, and remain fully selectable (the create-on-click path still fires on them).
  • Appointments starting or ending outside 7 to 18 render at their true offset: the clamp that squeezed them into the old window is gone, replaced by a shared span_geometry used by both the vertical blocks and the horizontal dispatch bars. An appointment crossing local midnight fills to end-of-grid instead of inverting.
  • Working hours stay a display-only constant (WORK_START_HOUR/WORK_END_HOUR) pending a per-user / per-workspace setting, which should be filed separately.

Tests

  • New grid_geometry_tests: full-range rendering, in-hours and out-of-hours offsets, no-clamp behavior, grid-edge clamping, min-size floor, and the working-hours window / shading helpers. cargo test --lib green (230 passed).
  • cargo fmt --all --check, cargo clippy --all-targets -- -D warnings, and cargo check --target wasm32-unknown-unknown all pass on the 1.94.1 toolchain (matches CI).

Commits

Split into three logical steps: (1) full-day geometry + working-hours constants + tests, (2) day/week grid scroll-in-box + off-hours shading, (3) dispatch timeline full-day + shading.

Acceptance criteria

  • Time axis spans midnight to midnight in both the day/week grid and the dispatch timeline.
  • Grid scrolls within its container, defaulting to the working-hours window.
  • Out-of-hours slots are selectable and visually de-emphasized rather than struck through.
  • Appointments starting or ending outside 7 to 18 render at the correct offset instead of being clamped.
  • Tests covering rendering of the full range and scheduling into an out-of-hours slot.
## MAPPS-387: scheduling grid spans midnight to midnight and scrolls in its box Replaces the fixed 7 AM to 7 PM scheduling window with a full 24-hour axis across the week grid, day grid, and dispatch timeline. Every hour is now schedulable; hours outside typical working hours are visually de-emphasized rather than treated as unavailable. Axis labels stay 12-hour AM/PM (no 24-hour "18" for 6 PM). ### What changed - Time axis spans midnight to midnight in the day/week grid and the dispatch timeline (`GRID_START_HOUR`/`GRID_END_HOUR` are now 0/24). - The grid scrolls inside its own container (`max-h-[70vh]`) instead of the page; the week view's day-of-week header sticks to the top. On mount each grid/timeline defaults its scroll to the working-hours window (7 AM to 7 PM). - Out-of-hours slots are muted (`bg-surface-2`), not struck through, and remain fully selectable (the create-on-click path still fires on them). - Appointments starting or ending outside 7 to 18 render at their true offset: the clamp that squeezed them into the old window is gone, replaced by a shared `span_geometry` used by both the vertical blocks and the horizontal dispatch bars. An appointment crossing local midnight fills to end-of-grid instead of inverting. - Working hours stay a display-only constant (`WORK_START_HOUR`/`WORK_END_HOUR`) pending a per-user / per-workspace setting, which should be filed separately. ### Tests - New `grid_geometry_tests`: full-range rendering, in-hours and out-of-hours offsets, no-clamp behavior, grid-edge clamping, min-size floor, and the working-hours window / shading helpers. `cargo test --lib` green (230 passed). - `cargo fmt --all --check`, `cargo clippy --all-targets -- -D warnings`, and `cargo check --target wasm32-unknown-unknown` all pass on the 1.94.1 toolchain (matches CI). ### Commits Split into three logical steps: (1) full-day geometry + working-hours constants + tests, (2) day/week grid scroll-in-box + off-hours shading, (3) dispatch timeline full-day + shading. ### Acceptance criteria - [x] Time axis spans midnight to midnight in both the day/week grid and the dispatch timeline. - [x] Grid scrolls within its container, defaulting to the working-hours window. - [x] Out-of-hours slots are selectable and visually de-emphasized rather than struck through. - [x] Appointments starting or ending outside 7 to 18 render at the correct offset instead of being clamped. - [x] Tests covering rendering of the full range and scheduling into an out-of-hours slot.
Replace the fixed 7 AM to 7 PM scheduling window with a full midnight-to-midnight axis so every hour is schedulable, and factor the offset math into one shared helper for the vertical day/week blocks and the horizontal dispatch bars.

`GRID_START_HOUR`/`GRID_END_HOUR` become 0/24; `span_geometry` maps an hour span linearly onto 0..100% with no clamp into a daytime sub-window, so a 2 AM or 11 PM slot lands at its true offset instead of being pinned to the old edges (fixes the clamp that squeezed out-of-hours appointments). `local_hour_span` also extends an appointment that crosses local midnight to end-of-grid so it fills to the bottom rather than inverting.

Add `WORK_START_HOUR`/`WORK_END_HOUR` (7 to 19) as a display-only working-hours hint plus `is_work_hour`/`hour_shade_class` helpers and a `scroll_grid_to_work_hours` DOM helper, consumed by the render changes in the following commits. Axis labels stay 12-hour AM/PM via the existing `hour_label`.

Unit-test the geometry: full-range rendering, in-hours and out-of-hours offsets, no-clamp behavior, grid-edge clamping, and the min-size floor.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QvB249F2SV9SBe3cBKRjcS
Render all 24 hour rows in the week and day views and move the scroll from the page into the grid's own container (`max-h-[70vh] overflow-y-auto`), so the grid no longer drives page scroll. The week view's day-of-week header sticks to the top of that box. On mount each grid defaults its scroll position to the working-hours window via `scroll_grid_to_work_hours`.

Out-of-hours rows are muted with `bg-surface-2` rather than struck through, keeping them visually de-emphasized while fully selectable (the column-level create click still fires on them). Appointment blocks now position with the un-clamped `span_geometry` from the previous commit, so an early-morning or late-evening event renders at its true offset.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QvB249F2SV9SBe3cBKRjcS
feat(calendar): full-day dispatch timeline with off-hours shading (MAPPS-387)
All checks were successful
Check / fmt + clippy + tests (pull_request) Successful in 10m21s
Create release / Create release from merged PR (pull_request) Has been skipped
8f95d6c192
Extend the dispatch timeline to the same midnight-to-midnight axis: 24 hourly columns, a wider `min-w` so they stay legible, and horizontal scroll inside the timeline box that opens on the working-hours window on mount. Working-hours header cells read as plain surface and out-of-hours columns are muted, matching the day/week grid.

Appointment and availability bars use the un-clamped `span_geometry`, so an out-of-hours dispatch renders at its true horizontal offset instead of being pinned to the old 7 AM / 7 PM edges.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QvB249F2SV9SBe3cBKRjcS
longjacksonle scheduled this pull request to auto merge when all checks succeed 2026-07-30 16:03:34 +02:00
longjacksonle deleted branch feat/MAPPS-387-full-day-scheduling-grid 2026-07-30 16:13:19 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
psa-systems/mokosh-apps!448
No description provided.