[pending-judge] feat(DC-168): calendar widget UX + theming — "No upcoming appointments" state, month grid with highlighted appointment days, theme-correct styling

Owner directives (2026-10-10/11, verbatim in brief): show "no upcoming
appointments" when empty; show a month calendar with days and times
highlighted when there are events; stylize to fit every theme; keep the
widget weather-widget-sized.

Changes (status/ frontend + tests):
- status/js/calendar-widget.js: rewritten render path — chip states ("No
  upcoming appointments" / next appointment with highlighted when-span),
  month grid modal (cal-grid + prev/next nav, appointment days highlighted,
  per-event time dots), upcoming list with day/time emphasis, 60-day+
  month-following fetch with window-authoritative event merge (via
  calendar-cache.js), forced refresh on periodic tick + source mutations,
  local escapeHtml (was an undefined global).
- status/js/calendar-cache.js (new): uid+start-keyed event cache; fetched
  window is authoritative for entries starting inside it (deletions and
  reschedules propagate), entries outside survive. Dual export (module +
  window) for tests and browser bundle.
- status/build.js: calendar-cache.js bundled before calendar-widget.js.
- status/css/dashboard.css: DC-168 block — chip states, month grid, day
  highlight states, dots, list/source rows, universal light-bg contrast
  rules (color-mix; WCAG >= 4.5:1 verified for all 10 builtin themes,
  worst 4.60:1 ocean) + light-surface rules.
- Tests (20 total in __tests__/calendar): 9-test ns suite (extraction incl.
  mixed docs, empty multistatus, namespace-aware fixture validation,
  undeclared-prefix rejection both quote styles, positive declared-attr),
  4-test dc168-cache contract (merge, duplicate suppression, recurring
  uid+start, window-authoritative removal, cross-window survival, ended-
  exclusion), 4-test widget contract + 2-test integration/gap (repo root
  derived from __dirname; smoke takes argv/env; zero hardcoded /root paths).

Existing suites pass unmodified; eslint 0 errors on touched files.
This commit is contained in:
Hermes committed 2026-10-12 00:48:58 -07:00
1 parent 2adbbd9384
commit dff143ddb8
9 files changed
+1099 -304

No files matched your search

+3
View File
@@ -81,6 +81,9 @@ const bundles = {
JS('deploys.js'),
JS('weather.js'),
JS('clock.js'),
// DC-168: calendar event-cache semantics (uid+start keys, window-
// authoritative merge) — must precede calendar-widget.js.
JS('calendar-cache.js'),
// DC-161: calendar widget — top-bar display + sources modal. Reads
// /api/v1/calendar/*; auto-shows Radicale calendars deployed via DashCaddy.
JS('calendar-widget.js'),