From bdbdff784201425c406938283b19cce94dac6238 Mon Sep 17 00:00:00 2001 From: jasonMPM Date: Fri, 6 Mar 2026 00:38:31 -0600 Subject: [PATCH] Add files via upload --- .../components/FocusView/DeliverableCard.jsx | 19 ++++++-- frontend/src/components/UI/ContextMenu.jsx | 47 ++++++++++--------- 2 files changed, 40 insertions(+), 26 deletions(-) diff --git a/frontend/src/components/FocusView/DeliverableCard.jsx b/frontend/src/components/FocusView/DeliverableCard.jsx index 239df78..8f51905 100644 --- a/frontend/src/components/FocusView/DeliverableCard.jsx +++ b/frontend/src/components/FocusView/DeliverableCard.jsx @@ -17,10 +17,15 @@ export default function DeliverableCard({ deliverable, isActive, index, projectC x: e.clientX, y: e.clientY, items: [ - { icon: '\u270e', label: 'Edit Deliverable', highlight: true, action: () => onEdit(deliverable) }, + { + icon: '✎', + label: 'Edit Deliverable', + highlight: true, + action: () => onEdit(deliverable), + }, { separator: true }, ...STATUS_OPTIONS.map(s => ({ - icon: s.value === deliverable.status ? '\u25cf' : '\u25cb', + icon: s.value === deliverable.status ? '●' : '○', label: `Mark ${s.label}`, action: async () => { storeUpdate(await updateDeliverable(deliverable.id, { status: s.value })) @@ -28,7 +33,7 @@ export default function DeliverableCard({ deliverable, isActive, index, projectC })), { separator: true }, { - icon: '\u2715', + icon: '✕', label: 'Delete Deliverable', danger: true, action: async () => { @@ -60,7 +65,6 @@ export default function DeliverableCard({ deliverable, isActive, index, projectC Selected )} -
Deliverable {index + 1}
{deliverable.title}
{formatDate(deliverable.due_date)}
@@ -68,7 +72,12 @@ export default function DeliverableCard({ deliverable, isActive, index, projectC {ctxMenu && ( - setCtxMenu(null)} /> + setCtxMenu(null)} + /> )} ) diff --git a/frontend/src/components/UI/ContextMenu.jsx b/frontend/src/components/UI/ContextMenu.jsx index fe97c5a..4c3a2bd 100644 --- a/frontend/src/components/UI/ContextMenu.jsx +++ b/frontend/src/components/UI/ContextMenu.jsx @@ -1,11 +1,16 @@ import { useEffect, useRef } from 'react' +import { createPortal } from 'react-dom' export default function ContextMenu({ x, y, items, onClose }) { const ref = useRef(null) useEffect(() => { - const onMouseDown = (e) => { if (ref.current && !ref.current.contains(e.target)) onClose() } - const onKey = (e) => { if (e.key === 'Escape') onClose() } + const onMouseDown = (e) => { + if (ref.current && !ref.current.contains(e.target)) onClose() + } + const onKey = (e) => { + if (e.key === 'Escape') onClose() + } document.addEventListener('mousedown', onMouseDown) document.addEventListener('keydown', onKey) return () => { @@ -15,41 +20,41 @@ export default function ContextMenu({ x, y, items, onClose }) { }, [onClose]) // Keep menu inside viewport - const W = 192 - const H = items.length * 34 + const W = 192 + const H = items.length * 34 const adjX = Math.min(x, window.innerWidth - W - 8) const adjY = Math.min(y, window.innerHeight - H - 8) - return ( + // Portal to document.body — escapes any CSS transform stacking context + // (e.g. the Drawer slide-in animation uses translateX which traps fixed children) + return createPortal(
{items.map((item, i) => item.separator ? ( -
+
) : ( ) )} -
+
, + document.body ) }