feat(calendar): side-by-side layout for overlapping appointments (PMS-598) #396

Merged
longjacksonle merged 3 commits from feat/PMS-598-overlap-appointments into main 2026-06-30 20:57:25 +02:00

PMS-598 (parent PMS-556 Calendar smoke)

When appointments shared a time slot, only one was visible: the positioned blocks all spanned the full column width and stacked, and the buttons had no key so Dioxus could collapse siblings.

Fix (frontend only)

  1. Lane layout (lanes_from_intervals / overlap_lanes + lane_h_geometry): an interval-partitioning pass assigns each appointment a column within its overlap cluster; the slot is split 1/lane_count wide so concurrent events sit side by side. Applied to the week and day time grids. Unit-tested (empty/single, sequential = one lane, two-overlap, freed-lane reuse, disjoint clusters).
  2. Stable keys: every per-appointment button (week, day, month chips, dispatch) now carries key="{appt.id}" so Dioxus keys siblings by identity.

Commits (small, logical)

  • Week lane layout + helper + tests
  • Day lane layout
  • Month-chip + dispatch keys

Scope

AC targets Week and Day (now side-by-side + clickable) and Month (each appointment its own chip, subject to the existing "+N more" cap). The dispatch board lays events horizontally by time per row; this PR gives it stable keys (vertical lane-splitting there is a larger, separate layout change if ever needed).

Verified

5 lane unit tests pass; dx build clean (33s), no warnings, fmt clean. Dev app serves this branch.

Test

Create two appointments at the same time on one day: in Week and Day they render in two columns, both clickable; in Month both appear as separate chips.

🤖 Generated with Claude Code

## PMS-598 (parent PMS-556 Calendar smoke) When appointments shared a time slot, only one was visible: the positioned blocks all spanned the full column width and stacked, and the buttons had no `key` so Dioxus could collapse siblings. ## Fix (frontend only) 1. **Lane layout** (`lanes_from_intervals` / `overlap_lanes` + `lane_h_geometry`): an interval-partitioning pass assigns each appointment a column within its overlap cluster; the slot is split `1/lane_count` wide so concurrent events sit side by side. Applied to the **week** and **day** time grids. Unit-tested (empty/single, sequential = one lane, two-overlap, freed-lane reuse, disjoint clusters). 2. **Stable keys**: every per-appointment button (week, day, month chips, dispatch) now carries `key="{appt.id}"` so Dioxus keys siblings by identity. ## Commits (small, logical) - Week lane layout + helper + tests - Day lane layout - Month-chip + dispatch keys ## Scope AC targets Week and Day (now side-by-side + clickable) and Month (each appointment its own chip, subject to the existing "+N more" cap). The dispatch board lays events horizontally by time per row; this PR gives it stable keys (vertical lane-splitting there is a larger, separate layout change if ever needed). ## Verified 5 lane unit tests pass; dx build clean (33s), no warnings, fmt clean. Dev app serves this branch. ## Test Create two appointments at the same time on one day: in Week and Day they render in two columns, both clickable; in Month both appear as separate chips. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Concurrent appointments stacked on one slot so only the last-painted was visible. Add a lane-assignment algorithm (lanes_from_intervals / overlap_lanes) that splits an overlap cluster into side-by-side columns, plus lane_h_geometry to turn a (lane, count) into left%/width%. Apply it to the week time-grid blocks and give each a stable `key` so Dioxus does not collapse siblings. Unit tests cover empty/single, sequential (one lane), two-overlap, freed-lane reuse, and disjoint clusters.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Apply the same overlap_lanes / lane_h_geometry split + stable key to the day time-grid blocks, so concurrent appointments render side by side and are each clickable instead of stacking.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
feat(calendar): stable keys on month chips and dispatch blocks (PMS-598)
All checks were successful
Check / fmt + clippy + tests (pull_request) Successful in 1m20s
Create release / Create release from merged PR (pull_request) Has been skipped
9d1d09ba32
Give the month-cell chips and the dispatch-board blocks stable `key` attributes (the appointment id) so Dioxus keys siblings by identity and does not collapse same-time appointments onto one node. Month already renders each appointment as its own chip (subject to the existing "+N more" cap); this makes that robust.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
longjacksonle deleted branch feat/PMS-598-overlap-appointments 2026-06-30 20:57:26 +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!396
No description provided.