#600: move quick-note entry from floating side tab into meetings header
User reported the yellow vertical "اكتب ملاحظة…" tab pinned to the page edge (left-0 top-[40vh]) felt out of place and asked for it to live inside the Executive Meetings header in a clear spot. Changes (artifacts/tx-os/src/pages/executive-meetings.tsx): - Added an amber-tinted Button in the header action cluster, placed before the Export PDF button so it reads first in RTL. Uses bg-amber-100 / border-amber-300 to keep the original yellow visual identity while matching the other header buttons' shape and size. Reuses the existing `executiveMeetings.quickNote.label` i18n key — no new translations. testid: `em-quick-note-header`. - Same gating as the old floating tab: section === "schedule" && !isFullscreen && !bulkToolbarActive && !quickNoteOpen, so the button hides while the composer is open, in fullscreen, during bulk selection, and on non-schedule sub-pages. - Removed the `<MeetingsQuickNoteTab />` mount and the component definition itself. Updated the stale comment on `bulkToolbarActive` to refer to the header button. Verified: - `rg em-quick-note-tab|MeetingsQuickNoteTab` clean across repo (no tests referenced the old testid). - `pnpm --filter @workspace/tx-os exec tsc --noEmit` clean. No deviation from the plan.
This commit is contained in:
@@ -816,35 +816,6 @@ function HeaderClock({ lang, date }: { lang: "ar" | "en"; date: string }) {
|
||||
);
|
||||
}
|
||||
|
||||
function MeetingsQuickNoteTab({
|
||||
lang,
|
||||
onClick,
|
||||
}: {
|
||||
lang: "ar" | "en";
|
||||
onClick: () => void;
|
||||
}) {
|
||||
const { t } = useTranslation();
|
||||
const label = t("executiveMeetings.quickNote.label", lang === "ar" ? "اكتب ملاحظة…" : "Take a note…");
|
||||
// Tab sits on the page edge that is visually "left" in LTR and "right"
|
||||
// in RTL — but the spec calls for "left of meetings page", so we pin
|
||||
// to physical left in both directions. Hidden in print.
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
onClick={onClick}
|
||||
aria-label={label}
|
||||
title={label}
|
||||
data-testid="em-quick-note-tab"
|
||||
className="flex fixed left-0 top-[40vh] z-30 flex-col items-center justify-center gap-2 w-7 py-3 rounded-r-lg bg-amber-200 hover:bg-amber-300 border border-amber-300 border-l-0 text-[#0B1E3F] shadow-sm transition-all duration-150 hover:translate-x-0.5 print:hidden"
|
||||
style={{ writingMode: "vertical-rl" as const }}
|
||||
>
|
||||
<Plus className="w-4 h-4 rotate-90" aria-hidden="true" />
|
||||
<span className="text-xs font-medium tracking-wide select-none">{label}</span>
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
function ExecutiveMeetingsPageInner() {
|
||||
const { t, i18n } = useTranslation();
|
||||
const [, setLocation] = useLocation();
|
||||
@@ -911,8 +882,8 @@ function ExecutiveMeetingsPageInner() {
|
||||
|
||||
// The schedule section publishes whether its bulk-action toolbar is
|
||||
// currently visible (≥1 row selected in edit mode) so the page-level
|
||||
// MeetingsQuickNoteTab can step out of the way while the user works
|
||||
// with destructive bulk actions.
|
||||
// quick-note header button can step out of the way while the user
|
||||
// works with destructive bulk actions.
|
||||
const [bulkToolbarActive, setBulkToolbarActive] = useState(false);
|
||||
useEffect(() => {
|
||||
if (section !== "schedule" && bulkToolbarActive) setBulkToolbarActive(false);
|
||||
@@ -1031,15 +1002,8 @@ function ExecutiveMeetingsPageInner() {
|
||||
dir={isRtl ? "rtl" : "ltr"}
|
||||
style={{ ["--em-header-h" as string]: "0px", ["--em-heading-h" as string]: "0px" }}
|
||||
>
|
||||
{section === "schedule" && !isFullscreen && !bulkToolbarActive && !quickNoteOpen && (
|
||||
<MeetingsQuickNoteTab
|
||||
lang={lang}
|
||||
onClick={() => {
|
||||
setQuickNoteOpen(true);
|
||||
setQuickNoteTrigger((n) => n + 1);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{/* #600: yellow floating side tab removed — entry point is now
|
||||
the amber "Take a note" button in the header action cluster. */}
|
||||
{isFullscreen && (
|
||||
<button
|
||||
type="button"
|
||||
@@ -1098,6 +1062,27 @@ function ExecutiveMeetingsPageInner() {
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-2">
|
||||
{/* #600: quick-note entry point moved off the page edge
|
||||
into the header. Same gating as the old floating tab. */}
|
||||
{section === "schedule" && !isFullscreen && !bulkToolbarActive && !quickNoteOpen && (
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className="gap-1.5 bg-amber-100 hover:bg-amber-200 border-amber-300 text-[#0B1E3F]"
|
||||
onClick={() => {
|
||||
setQuickNoteOpen(true);
|
||||
setQuickNoteTrigger((n) => n + 1);
|
||||
}}
|
||||
aria-label={t("executiveMeetings.quickNote.label", lang === "ar" ? "اكتب ملاحظة…" : "Take a note…")}
|
||||
title={t("executiveMeetings.quickNote.label", lang === "ar" ? "اكتب ملاحظة…" : "Take a note…")}
|
||||
data-testid="em-quick-note-header"
|
||||
>
|
||||
<Plus className="w-4 h-4" />
|
||||
<span className="hidden sm:inline">
|
||||
{t("executiveMeetings.quickNote.label", lang === "ar" ? "اكتب ملاحظة…" : "Take a note…")}
|
||||
</span>
|
||||
</Button>
|
||||
)}
|
||||
{!isPresidentView && (
|
||||
<Button
|
||||
variant="outline"
|
||||
|
||||
Reference in New Issue
Block a user