From e77ad7c809d7e4811b2014661e801ca9cc8d3b2b Mon Sep 17 00:00:00 2001 From: timmy Date: Fri, 21 Aug 2026 03:16:40 +0000 Subject: [PATCH] feat: import private calendar capacity for Week Ahead (Closes #1206) --- README.md | 5 +- frontend/dashboard.css | 14 +++ frontend/index.html | 20 ++++ frontend/service-worker.js | 1 + frontend/week-calendar-import.js | 111 ++++++++++++++++++++ frontend/week-plan.js | 17 ++- src/frontend_bundle.py | 2 +- tests/e2e/test_mobile_week_ahead_release.py | 36 ++++++- tests/test_service_worker.py | 1 + tests/test_week_calendar.py | 2 +- tests/test_week_calendar_import.py | 108 +++++++++++++++++++ tests/test_week_plan_frontend.py | 25 +++++ 12 files changed, 336 insertions(+), 6 deletions(-) create mode 100644 frontend/week-calendar-import.js create mode 100644 tests/test_week_calendar_import.py diff --git a/README.md b/README.md index 83b7204..4846453 100644 --- a/README.md +++ b/README.md @@ -173,7 +173,10 @@ and flags work assigned to more than one date. Operators can move an item to ano the estimate follows the item and the server rejects duplicate cross-day assignments without advancing the week revision. Confirmation remains disabled while duplicates exist or the account-bound week is still syncing. Rapid saves and review moves use one network flight plus a coalesced latest-state delivery, so later staged days -are not stranded behind an earlier request. +are not stranded behind an earlier request. From the same review, **Set capacity from calendar** reads a local +`.ics` file on-device, unions overlapping busy periods within chosen working hours, and previews seven daily +availability totals before one atomic apply. Raw calendar data and event metadata are never persisted or sent; +only the reviewed capacity-minute totals use the existing encrypted, account-bound Week Ahead sync. Planning edits can remain offline for up to 30 days. After that, the expired edit is discarded visibly and the account plan is kept rather than replaying stale intent. The server retains no more than 4,096 operation receipts per account and removes diff --git a/frontend/dashboard.css b/frontend/dashboard.css index fbebfe3..d7521d3 100644 --- a/frontend/dashboard.css +++ b/frontend/dashboard.css @@ -337,6 +337,20 @@ textarea { resize: vertical; min-height: 120px; } .week-review-duplicates { margin:12px 0; padding:12px; border:1px solid #f59e0b; border-radius:10px; background:#2a1c12; } .week-review-status { min-height:1.4em; margin:10px 0; } #confirm-week-plan { width:100%; min-height:48px; position:sticky; bottom:0; } +#open-week-capacity-import { width:100%; min-height:44px; margin:8px 0 12px; } +.week-capacity-import { position:fixed; z-index:121; inset:0; box-sizing:border-box; width:100%; max-width:560px; margin-inline:auto; padding:18px; padding-bottom:calc(18px + env(safe-area-inset-bottom)); background:#0b1526; overflow:auto; overflow-x:hidden; } +.week-capacity-import[hidden] { display:none; } +.week-capacity-import > header { display:flex; align-items:flex-start; justify-content:space-between; gap:12px; } +.week-capacity-import h2 { margin:.2rem 0; } +.week-capacity-import > label, .week-capacity-hours label { display:grid; min-width:0; gap:6px; margin:12px 0; } +.week-capacity-import input, .week-capacity-import button { box-sizing:border-box; min-width:0; min-height:44px; max-width:100%; } +.week-capacity-hours { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:10px; } +.week-capacity-days { display:grid; gap:8px; margin:10px 0 14px; } +.week-capacity-day { display:grid; min-width:0; gap:3px; padding:10px; border:1px solid #31577f; border-radius:10px; background:#10233a; overflow-wrap:anywhere; } +.week-capacity-day span { color:#bfdbfe; font-weight:700; } +.week-capacity-day small { color:#a9bdd3; } +#apply-week-capacities { width:100%; min-height:48px; position:sticky; bottom:0; } +@media (max-width:359px) { .week-capacity-hours { grid-template-columns:1fr; } } .week-calendar-handoff h2 { margin-bottom:6px; } .week-calendar-days { display:grid; gap:12px; margin:14px 0; } .week-calendar-day { min-width:0; padding:12px; border:1px solid #31577f; border-radius:12px; background:#10233a; } diff --git a/frontend/index.html b/frontend/index.html index b373e58..b64beb3 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -509,11 +509,30 @@
Final planning step

Review & rebalance Week Ahead

Check each day’s load. Move work instead of copying it, then confirm one executable week.

+
+