Skip to content

Calendar: event dots + configurable day-cell click in Day Panel - #299

Merged
h4yfans merged 2 commits into
mainfrom
bold-moser-c6dba9
Apr 21, 2026
Merged

Calendar: event dots + configurable day-cell click in Day Panel#299
h4yfans merged 2 commits into
mainfrom
bold-moser-c6dba9

Conversation

@h4yfans

@h4yfans h4yfans commented Apr 20, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Calendar tab — Day Panel mini-calendar now shows dots driven by event counts (from useCalendarRange) instead of the journal heatmap. Other tabs keep the journal heatmap unchanged.
  • Configurable day-cell click — clicking a day in the Day Panel now routes through a new user preference:
    • Global setting: journal (default) or calendar.
    • Calendar-page override: inherit / journal / calendar. Default calendar so today's behavior is preserved when the Calendar tab is active.
  • Clicking a day from a non-calendar tab with global = calendar opens a Calendar tab and sets the anchor date.
  • New Calendar section in Settings (side nav → Workspace → below Tasks) with two selects.

Why

The right-sidebar Day Panel is useful on every tab, but on the Calendar tab the journal heatmap dots don't match what the user is actually looking at. The user also wanted control over where a day click leads — Journal for note-centric users, Calendar for calendar-centric users — with a per-page override so the Calendar tab can always mean "stay in Calendar."

What changed

Contracts / RPC

  • packages/contracts/src/settings-schemas.ts — adds CalendarSettingsSchema + CALENDAR_SETTINGS_DEFAULTS (distinct from existing calendar.google group).
  • packages/contracts/src/ipc-channels.ts — adds GET_CALENDAR_SETTINGS / SET_CALENDAR_SETTINGS.
  • packages/rpc/src/settings.ts — exposes the new methods on the generated RPC API.

Main (Electron)

  • apps/desktop/src/main/ipc/settings-handlers.ts — registers + tears down the two handlers using existing readGroupSettings / writeGroupSettings helpers with key 'calendar'.

Renderer

  • apps/desktop/src/renderer/src/hooks/use-calendar-preferences.ts — new hook + pure resolveDayCellClickBehavior(settings, isCalendarTabActive) helper.
  • apps/desktop/src/renderer/src/hooks/use-calendar-preferences.test.ts — 7 unit tests covering the full truth table (global × override × tab-active).
  • apps/desktop/src/renderer/src/pages/settings/calendar-section.tsx — new settings UI (two Select rows).
  • apps/desktop/src/renderer/src/pages/settings.tsx — adds Calendar nav entry (uses existing CalendarDays icon).
  • apps/desktop/src/renderer/src/contexts/settings-modal-context.tsx — extends SettingsSection union with 'calendar'.
  • apps/desktop/src/renderer/src/components/day-panel/global-day-panel.tsx — queries the visible month via useCalendarRange, swaps activity source based on isCalendarTabActive, and routes clicks + today through the resolver. Opens a new Calendar tab when needed.

Tests

  • apps/desktop/tests/setup-dom.ts — adds getCalendarSettings / setCalendarSettings to the window.api.settings mock so existing tests that touch the Day Panel keep working.

Generated-file churn (flagging for reviewer)

apps/desktop/src/main/ipc/generated-ipc-invoke-map.ts and apps/desktop/src/preload/generated-rpc.ts have a ~3100-line drop that is not my hand edit. Running pnpm ipc:generate produced a different format than what was stored in the repo, suggesting pre-existing drift between the committed files and the current generator output. pnpm ipc:check passes after regeneration. Happy to revert if there's a preferred CI path (e.g., regenerate in a follow-up) — flagging so it isn't a surprise in review.

Test plan

  • pnpm typecheck:node + pnpm typecheck:web — both clean.
  • pnpm ipc:check — up to date.
  • pnpm exec vitest run — 7139 pass. The 3 failures in calendar-page.test.tsx are pre-existing (window.api.showContextMenu is not a function — unrelated to this PR).
  • New resolver tests — 7 / 7 pass.
  • Manual smoke (pnpm dev):
    • Calendar tab + Day Panel open → dots reflect event counts per day; click a day → stays in calendar, anchor moves.
    • Notes tab + Day Panel open → dots reflect journal activity (unchanged); click a day → opens Journal at that date.
    • Change override to journal in Settings → click day on Calendar tab opens Journal.
    • Change global to calendar → click day from Notes tab opens a Calendar tab.
    • Toggle settings live → Day Panel updates without reload (via onSettingsChanged broadcast).
  • E2E (follow-up — planned specs: right-sidebar-event-dots.spec.ts, sidebar-day-click-behavior.spec.ts). Not included here to keep this PR focused; remember npx electron-vite build before pnpm test:e2e per CLAUDE.md.

Open design question

Event dots and journal dots currently share the ACTIVITY_DOT_COLORS ramp (green-family, quantized 0–4). Consider adding a distinct ramp (e.g., tint/blue) for events so the swap is visually obvious. Trivial to add a dotColorVariant prop on DatePickerCalendar if desired.

h4yfans added 2 commits April 21, 2026 02:22
On the Calendar tab, the Day Panel mini-calendar now shows per-day event
counts (from useCalendarRange) instead of the journal heatmap. Other tabs
keep the journal heatmap unchanged.

Day-cell click behavior is now user-configurable:
- Global setting: journal (default) or calendar
- Calendar-page override: inherit / journal / calendar (default: calendar,
  preserves current behavior)

Click from a non-calendar tab with global=calendar now opens a Calendar
tab and sets the anchor date.

Adds a 'Calendar' settings section, new 'calendar' settings group (distinct
from existing calendar.google), IPC get/set handlers, and a
useCalendarPreferences hook exposing a pure resolveDayCellClickBehavior
helper covered by 7 unit tests.

Regenerates the IPC invoke map + preload RPC bindings (drift from the
current generator output — pnpm ipc:check now passes).
…in tests

The CalendarItemChip refactor to native Electron menu dropped the
canDeleteEvent() guard (wiring delete on task/reminder/snooze chips)
and left renderer tests without a showContextMenu mock, so three
tests failed in CI and a fourth passed vacuously. Add the mock to
the global test setup, restore the guard, and rewrite the 4 affected
tests to drive through the IPC mock instead of looking for DOM
menuitems that native menus don't render.
@h4yfans
h4yfans merged commit 102c8a5 into main Apr 21, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant