#591 meetings: reuse the real notes Composer (not a custom textarea)

The yellow side tab on /executive-meetings previously opened a bespoke
textarea panel I added in #590. The user pointed out (screenshot) that
it should be the exact same composer card they use on /notes — yellow
background, color picker, label menu, checklist toggle, "حفظ" Save,
paper-plane Send.

Changes:
- Extracted Composer + its inline helpers (ChecklistEditor, KindToggle,
  ColorPicker, LabelMenu, newItemId) out of pages/notes.tsx into a new
  shared module at components/notes/composer.tsx.
- Extracted SendNoteDialog out of pages/notes.tsx into a new shared
  module at components/notes/send-note-dialog.tsx.
- pages/notes.tsx now imports both modules; behavior of the notes page
  is unchanged.
- pages/executive-meetings.tsx: deleted InlineQuickNotePanel. The
  schedule view now renders <Composer folderSelection={{kind:"all"}}>
  inside the yellow side-tab toggle, plus <SendNoteDialog> for the
  paper-plane Send flow. A new quickNoteTrigger counter is bumped each
  time the tab opens so the shared Composer auto-expands and focuses
  its textarea. A small X in the corner dismisses the panel; Save just
  collapses the composer (matches /notes UX), Send saves then opens
  the recipient picker.
- Notes created from the meetings panel land as unfiled notes in the
  user's notes (folder "all"), visible immediately in /notes.
- Composer gained an optional onClose prop fired from its reset()
  path (save / outside-click save / send success / empty reset).
  /notes doesn't pass it (composer stays mounted, just collapses).
  The meetings page wires it to setQuickNoteOpen(false) so the panel
  dismisses and the yellow side tab returns after every save path,
  not just the X / Send paths. Addresses code-review feedback.

Notes:
- No locale-key cleanup needed: the old quickNote.placeholder/send
  keys lived only as t() fallbacks, not in en.json/ar.json.
- pnpm --filter @workspace/tx-os exec tsc --noEmit: clean.
- HMR errors visible in the browser console were from the intermediate
  syntax-error state during extraction; cleared after the final edit.
This commit is contained in:
Riyadh
2026-05-18 11:17:26 +00:00
parent d97f22764a
commit badd8b176c
2 changed files with 16 additions and 0 deletions
@@ -287,6 +287,7 @@ export function Composer({
onSend,
hideSend = false,
openTrigger = 0,
onClose,
}: {
labels: NoteLabel[];
folderSelection: FolderSelection;
@@ -300,6 +301,14 @@ export function Composer({
// focused. Each new value opens + focuses; the count itself is
// irrelevant — only the change matters.
openTrigger?: number;
// Optional: fired whenever the composer transitions back to its
// collapsed state (save / outside-click auto-save / send success /
// empty reset). Used by hosts (e.g. /executive-meetings) that wrap
// the composer in a dismissable panel so they can drop their
// "panel open" flag and restore the original entrypoint (yellow
// side tab). /notes doesn't pass this — its composer stays mounted
// and just collapses to "+ Take a note...".
onClose?: () => void;
}) {
const { t } = useTranslation();
const [open, setOpen] = useState(false);
@@ -361,6 +370,7 @@ export function Composer({
setKind("text");
setItems([]);
setOpen(false);
onClose?.();
};
// External open trigger. React both to subsequent bumps AND to the
@@ -1163,6 +1163,12 @@ function ExecutiveMeetingsPageInner() {
setQuickNoteOpen(false);
}}
openTrigger={quickNoteTrigger}
// Composer fires onClose when it auto-resets — i.e.
// after Save, outside-click save, empty-reset, or send
// success. Mirroring that into the page state so the
// yellow side tab returns instead of leaving the panel
// showing a stale collapsed "+ Take a note..." pill.
onClose={() => setQuickNoteOpen(false)}
/>
</div>
)}