riyadhafraa b5de44485e Task #140: 3 attendees-cell refinements in Executive Meetings schedule
(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).
2026-04-29 12:42:45 +00:00
2026-04-21 12:16:59 +00:00
2026-04-18 02:00:09 +00:00
2026-04-28 20:58:08 +00:00
2026-04-18 02:00:09 +00:00
2026-04-18 02:00:09 +00:00
S
Description
No description provided
139 MiB
Languages
TypeScript 69.4%
JavaScript 29%
CSS 0.6%
Shell 0.6%
Dockerfile 0.2%
Other 0.2%