b5de44485e25aa1dbc5de4089f28f668400d202d
(1) Clearing an attendee's name now removes the attendee row instead of
saving an empty record. saveAttendeeName detects empty stripped HTML
(tags + + whitespace) and PUTs the array with the row removed
and sortOrder repacked.
(2) Inline "+ Add attendee" button next to each attendee group, plus
"+ Virtual / + Internal / + External" chips for groups not yet present
in a split cell. Implemented as an optimistic ghost row — clicking +
sets a single global pendingAttendee state and renders a synthetic
EditableCell at the end of the matching group. Only when the user
types a non-empty name and blurs do we PUT the new attendee. Empty
blur or Escape just clears the pending state — no orphan rows reach
the API. The API stays strict (name.min(1)).
(3) Always-visible dashed underline on each attendee EditableCell
makes the multi-attendee wrapped layout discoverable as click targets;
hidden in edit mode (data-[editing=true]) and on print. The group
label ("— Virtual attendance — Webex —") is now pointer-events:none
so clicks pass through to whatever sits underneath instead of being
swallowed by the header text.
Implementation notes:
- EditableCell gained two new props (forceSaveOnBlur, onCancel) so the
ghost row can commit/discard cleanly even when the editor is empty.
- pendingAttendee is a single global state (only one ghost open at a
time across the whole page). All other rows hide their + buttons
while a ghost is open to prevent the user from orphaning typing.
- Locale keys added in ar.json + en.json under
executiveMeetings.schedule.{addAttendee, addVirtualAttendee, …,
newAttendeeAria, editAttendeeAria}.
- Backend executive-meetings.ts unchanged — attendeeSchema still
requires non-empty name.
Verified end-to-end:
- Add attendee, commit on blur, delete by clearing, cancel by Escape
on empty.
- Cross-row gating: opening a ghost in row A hides "+" buttons in
row B until the ghost is committed/cancelled.
- Webex/virtual header click no longer enters edit mode.
Pre-existing TypeScript errors in admin.tsx (codegen drift from #96)
and 3 failing api-server tests are unrelated and out of scope.
Follow-ups proposed: #144 (inline edit attendee titles),
#145 (move attendees between virtual/internal/external groups).
Description
No description provided
Languages
TypeScript
69.4%
JavaScript
29%
CSS
0.6%
Shell
0.6%
Dockerfile
0.2%
Other
0.2%