Skip to content
Merged
Show file tree
Hide file tree
Changes from 30 commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
302b355
feat(calendar): add booking-host overlay status and reciprocity checks
builderio-bot Sep 11, 2026
52193df
feat(calendar): send rate-limited overlay-add-back request emails
builderio-bot Sep 11, 2026
26b2907
feat(calendar): show host overlay status on booking links
builderio-bot Sep 11, 2026
5831a6c
fix(calendar): merge overlay and Google calendar visibility correctly
builderio-bot Sep 11, 2026
f30bfbd
fix(calendar): localize relative-time formatting and add missing strings
builderio-bot Sep 11, 2026
82ffeec
docs(calendar): document shared-availability and working-hours-status…
builderio-bot Sep 11, 2026
3aa4dff
fix: handle global navigation commands on deep links
builderio-bot Sep 11, 2026
aa6080b
fix(calendar): preserve add-person deep links across redirects
builderio-bot Sep 11, 2026
f4ad08c
Fix calendar availability requests with dedicated add page
builderio-bot Sep 11, 2026
5588870
fix(calendar): show errors when adding shared availability fails
builderio-bot Sep 11, 2026
4436dc7
Update visual edit skill for WebMCP workflows and revisions
builderio-bot Sep 11, 2026
43f9d97
Deduplicate shared calendars and overlay people in sidebar
builderio-bot Sep 11, 2026
ad7bb02
Merge shared calendars with matching overlay people
builderio-bot Sep 11, 2026
d543207
Fix calendar overlay batching and accessibility issues
builderio-bot Sep 11, 2026
a57e02e
Fix calendar overlay request reservation handling
builderio-bot Sep 11, 2026
3db8705
Merge remote-tracking branch 'refs/remotes/origin/main' into ai_main_…
builderio-bot Sep 14, 2026
b6d297c
Batch overlay calendar emails beyond the 10-email list-events limit
builderio-bot Sep 14, 2026
79f79ca
Move peer availability management to calendar controls
builderio-bot Sep 14, 2026
c704241
Clarify working hours in shared availability copy
builderio-bot Sep 14, 2026
84eab49
Clarify working hours in shared availability copy
builderio-bot Sep 14, 2026
497d904
Merge remote-tracking branch 'refs/remotes/origin/main' into ai_main_…
builderio-bot Sep 14, 2026
2721d7a
Address PR review feedback: fix prefill race, email timeout, hidden-p…
builderio-bot Sep 14, 2026
abeefef
Merge remote-tracking branch 'refs/remotes/origin/main' into ai_main_…
builderio-bot Sep 14, 2026
867b43e
Derive shared-editor host status from owner overlay list, not editor'…
builderio-bot Sep 14, 2026
8ef3b91
Merge remote-tracking branch 'refs/remotes/origin/main' into ai_main_…
builderio-bot Sep 14, 2026
c0ee561
Fix daily-cap legacy bypass, merged-row visibility default, stale bat…
builderio-bot Sep 14, 2026
1959705
Prevent overlay-people full-replacement writes from wiping data on a …
builderio-bot Sep 14, 2026
9da80d8
Merge remote-tracking branch 'refs/remotes/origin/main' into ai_main_…
builderio-bot Sep 14, 2026
9baef62
Fix lost-update race in overlay-people mutations with atomic server a…
builderio-bot Sep 14, 2026
b68ec34
Fix case-sensitive email matching in overlay actions and stale-reserv…
builderio-bot Sep 14, 2026
ec122ca
Merge remote-tracking branch 'refs/remotes/origin/main' into ai_main_…
builderio-bot Sep 14, 2026
f5e16ee
Merge branch 'main' into ai_main_60a606a93fe947758482
JasonYangCIS Sep 14, 2026
2861025
Merge branch 'main' into ai_main_60a606a93fe947758482
JasonYangCIS Sep 15, 2026
876bd68
Merge remote-tracking branch 'refs/remotes/origin/main' into ai_main_…
builderio-bot Sep 15, 2026
58ac45d
Merge remote-tracking branch 'refs/remotes/origin/main' into ai_main_…
builderio-bot Sep 15, 2026
e4171f6
Merge remote-tracking branch 'refs/remotes/origin/main' into ai_main_…
builderio-bot Sep 15, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/email-paragraphs-escaping-doc.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@agent-native/core": patch
---

Correct the `renderEmail` `paragraphs` doc comment: the strings are injected verbatim, not escaped, so callers must wrap user-supplied values in `emailStrong`/`emailQuote`.
104 changes: 104 additions & 0 deletions docs/plans/2025-06-12-shared-availability-tab.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
# Shared Availability Tab Implementation Plan

> **For the Fusion agent:** Execute this plan task-by-task. Each step is one action. Do not skip steps. Verify after each task.

**Goal:** Move peer-relationship management (the sidebar "People" group) into a new
"Shared availability" tab on the booking-links page, leaving the sidebar with only
grid controls (colour, show/hide) for those same peers.

**Architecture:** The overlay list (`calendar-overlay-people`) serves two jobs — it
renders peer events on the grid *and* gates whether a booking-link co-host's real
working hours are used. Splitting the surfaces by job: the booking-links page owns
add/remove/reciprocity/request, the sidebar keeps colour + visibility only. No
server or data-model changes; both surfaces already read the same action.

**Tech Stack:** React, `useActionQuery`/`useActionMutation`, shadcn Tabs/Popover/Tooltip,
Tabler icons, existing `get-overlay-people` / `get-host-overlay-status` /
`send-overlay-request` actions.

## Task 1: Localization keys

**Files:** Modify `templates/calendar/app/i18n-data.ts`, `templates/calendar/app/i18n/zh-TW.ts`

New keys under `bookingLinks`:

- `sharedAvailability` — tab label
- `sharedAvailabilityDescription` — card description
- `sharedAvailabilityEmpty` — empty state
- `addPeerCalendar` — add button
- `workingHoursAppliedLabel` — short row label for the applied state
- `workingHoursPendingScheduleLabel` — short row label, reciprocal but no schedule
- `workingHoursNotAppliedLabel` — short row label, not reciprocal
- `removePeerConfirm` — confirm copy for removing a peer

New keys under `sidebar`:

- `managePeerAvailability` — link from the sidebar to the new tab

Remove now-unused `sidebar.peopleGroup`, `sidebar.overlayReciprocalTooltip`,
`sidebar.overlayReciprocalAriaLabel` only if nothing else references them.

**Verify:** `pnpm guards` i18n check passes.

## Task 2: `SharedAvailabilityPanel` component

**Files:** Create `templates/calendar/app/components/booking/SharedAvailabilityPanel.tsx`

- `useOverlayPeople()` for the list.
- `useHostOverlayStatus(emails, undefined, emails.length > 0)` — with no
`bookingLinkId` the action resolves the owner to the caller, which is correct
here because the tab only ever manages the signed-in user's own peers.
- One row per peer: name/email, short status label, `HostOverlayStatusIcon`
(`variant="overlay"`, no `bookingLinkId`), remove button behind a confirm dialog.
- "Add a peer's calendar" opens the existing `AddCalendarDialog` with
`defaultTab="people"` rather than duplicating the people picker.
- Empty state when the overlay list is empty.

**Verify:** renders in the browser with real peers; status icons match the
booking-link chips for the same people.

## Task 3: Fourth tab + URL deep link

**Files:** Modify `templates/calendar/app/pages/BookingLinksPage.tsx`

- Extend `type Tab` (line 247) with `"shared"`.
- Add `TabsTrigger`/`TabsContent` (lines 1874-1884, 2287-2289).
- Read `?tab=` on mount so the sidebar can deep-link to `?tab=shared`, and keep
the param in sync on tab change.

**Verify:** `/calendar/booking-links?tab=shared` opens the new tab directly.

## Task 4: Demote the sidebar People rows

**Files:** Modify `templates/calendar/app/components/layout/Sidebar.tsx`

- Drop the `People` collapsible wrapper; render peer rows flat under
"Other Calendars" alongside the Google rows.
- Keep the colour picker and the eye toggle.
- Remove the `X`/`removePerson` button — severing the booking relationship must
not be a hover-target next to a plain hide toggle — and remove the reciprocity
exchange icon, whose job the new tab now does.
- Point the section's people `+` at `/calendar/booking-links?tab=shared`.
- Add a "Manage shared availability" link under the peer rows.
- Drop `useOverlayReciprocity`/`useRemoveOverlayPerson` usage and the
`peopleGroupOpen` state that only gated the reciprocity query.

**Verify:** no `People` sub-header; peers still toggle and recolour; group and
resource calendars unchanged.

## Task 5: Tests

**Files:** Create `templates/calendar/app/components/booking/SharedAvailabilityPanel.test.tsx`

Cover: empty state, one row per peer, status label per state, remove requires
confirmation, request button only on the non-reciprocal state.

**Verify:** `pnpm vitest run` in the template passes.

## Task 6: Full verification

- `npx vitest run` (calendar template)
- `npx tsc --noEmit -p tsconfig.json`
- `pnpm guards`
- Browser: sidebar has no People header, new tab lists peers with status,
removing a peer asks for confirmation, deep link works.
Loading
Loading