Skip to content

Spec Scheduler

oldmangan edited this page Oct 8, 2026 · 2 revisions

Status: built in #67 (2026-10-08): see Scheduler for how to use it. This page keeps the design and the decisions; the resource timeline is still to come.

dhxpyt's calendar is a date picker only (DHTMLX sells its Scheduler separately and dhxpyt does not wrap it), so this would be a wapyt-only widget (⭐ in the dhxpyt comparison).

Goal

A Scheduler widget that shows appointments on a time grid and lets people create, move, resize and open them by mouse, touch or keyboard, with the app (BFF) as the source of truth.

Views

View Shows
Day One column of time slots
Week / work week Seven (or five) day columns of time slots, all-day row on top
Month A grid of days; items as chips, "+3 more" when a day overflows
Agenda A scrolling list of upcoming items, grouped by day
Resource timeline (later) Rows per resource (person, room), time running sideways

A toolbar with Today, previous/next, the date range title, and a view switch. A compact month mini-calendar is the date picker the old Calendar candidate was meant to be, and could ship first on its own.

Items (appointments)

ScheduleItem(id, title, start, end, all_day=False, color=None, resource=None, editable=True, data=None): start/end as naive datetime or ISO strings, the same convention as the Form date fields. Recurring items arrive already expanded (series_id + occurrence date); the widget does not compute recurrence rules.

  • Overlapping items in a day column sit side by side (column packing), not on top of each other.
  • Items crossing midnight or days render as continued segments.
  • Text is set as text, as everywhere in wapyt.

Interaction

Action Mouse / touch Keyboard Event
Create Drag across empty slots, or double-click a slot Enter on a focused slot on_create {start, end, all_day, resource}
Move Drag an item (to another time, day or resource) Arrows move by a slot / a day, Enter commits on_move {id, start, end, resource, old}
Resize Drag an item's top or bottom edge Shift+arrows on_resize {id, start, end, old}
Open Click or double-click Enter on_open {id, item} (the app shows a Popup or ModalWindow with a Form)
Delete From the app's own UI or a ContextMenu Delete on_delete {id}
  • Snapping to slot_minutes (default 30), with a live time label while dragging.
  • Confirm or revert: moves and resizes apply optimistically and fire their event; the app persists, and on failure calls revert(id) (or set_item(id, ...)) plus set_item_error(id, message), the same pattern as DataTable's set_cell / set_cell_error.
  • Read-only items (editable=False) and a whole read-only mode.
  • Escape cancels a drag in progress; dragging near an edge scrolls the grid.

Options

view, date, week_start (Monday by default), work_week, day_start / day_end (visible hours), slot_minutes, time_format (12/24), locale, now_indicator, min_item_minutes, resources, height.

Data loading

The visible range changes as people navigate: on_range_change {start, end, view} asks the app for items in that window, and set_items(items) / add_item / update_item / remove_item update the view without a full reload.

Accessibility

A grid role structure with labelled slots ("Tuesday 7 October, 9:30"), a roving focus across slots and items, items announced with their time range, keyboard equivalents for every drag, and reduced-motion respected.

Decisions (2026-10-08)

  • Time zones: naive local times only, like the Form pickers. The app converts to the viewer's zone before handing items over; aware datetimes are refused.
  • First version: day, week, work week, month and agenda, with the toolbar and a mini month. The resource timeline comes later.
  • Conflicts: overlaps are shown side by side, and the app decides: a drop applies, the event fires, and the app calls revert(id) if the server refuses (the act-then-revert shape of Listbox, Kanban and Tree).
  • Export: both iCal export (export_ics) and a print view (print()).

Building on

Popup (item details), ContextMenu (item actions), Form date/time fields (edit dialog), Toolbar (navigation), the splitter and DataTable drag code (pointer capture, rAF-throttled moves), and tooltip (truncated titles).

Clone this wiki locally