# Context Menu Popover Fix ## Issue The context menu was not showing when right-clicking on selected tasks in the TaskBrowser. ## Root Cause Analysis After reviewing the shadcn-vue documentation and comparing with our implementation, the following issues were identified: ### Problems with DropdownMenu Approach: 1. **Missing Trigger Element**: DropdownMenu requires a DropdownMenuTrigger component. Our implementation used `v-model:open` to control the menu programmatically, but DropdownMenu expects to be triggered by a trigger element. 2. **Incorrect Positioning**: We attempted to use fixed positioning with inline styles on DropdownMenuContent, but DropdownMenu uses Radix UI's portal-based positioning logic, which conflicts with manual positioning. 3. **Programmatic Control Limitations**: The `v-model:open` pattern doesn't work well with DropdownMenu without a proper trigger element. 4. **Wrong Component Choice**: DropdownMenu is designed for click-triggered dropdowns with a visible trigger button, not for programmatic context menus triggered by right-click events. ## Solution Replaced **DropdownMenu** with **Popover** component and simplified the menu structure to use native buttons instead of DropdownMenu submenus. ### Why Popover is Better: 1. ✅ **Programmatic Control**: Supports `v-model:open` for programmatic control 2. ✅ **Custom Positioning**: Works with PopoverAnchor for custom positioning 3. ✅ **Flexible Triggers**: Works well with custom triggers like right-click events 4. ✅ **Dynamic Positioning**: Can position based on mouse coordinates using a fixed-position anchor 5. ✅ **No Trigger Required**: Doesn't require wrapping trigger elements ## Implementation Changes ### TaskBulkActionsMenu.vue **Before (DropdownMenu):** ```vue ``` **After (Popover):** ```vue ``` ### Key Changes: 1. **Replaced DropdownMenu with Popover**: Changed the wrapper component 2. **Added PopoverAnchor**: Creates a 1px invisible anchor point at the mouse cursor position 3. **Updated PopoverContent**: Replaced DropdownMenuContent with PopoverContent 4. **Removed Manual Positioning Logic**: Removed the `adjustedPosition` computed property since Popover handles positioning automatically 5. **Updated Imports**: Changed from DropdownMenu imports to Popover imports ### How It Works: 1. User right-clicks on a table row 2. `handleContextMenu` in TaskBrowser captures the mouse coordinates 3. `contextMenuPosition` is updated with `{ x: event.clientX, y: event.clientY }` 4. `showContextMenu` is set to `true` 5. PopoverAnchor creates an invisible 1px element at the cursor position 6. PopoverContent appears relative to the anchor 7. Popover's built-in positioning logic handles viewport boundaries automatically ## Benefits - ✅ Context menu now appears at cursor position - ✅ Automatic viewport boundary detection - ✅ Proper z-index and portal rendering - ✅ Maintains all existing functionality (status update, assignment) - ✅ Cleaner code (removed manual positioning logic) - ✅ Better accessibility ## Testing To test the fix: 1. Open TaskBrowser in the application 2. Select one or more tasks using checkboxes 3. Right-click on a selected task 4. Context menu should appear at the cursor position 5. Verify "Set Status" submenu works 6. Verify "Assign To" submenu works 7. Verify menu closes when clicking outside 8. Verify menu closes after selecting an action ## Files Modified - `frontend/src/components/task/TaskBulkActionsMenu.vue` - Replaced DropdownMenu with Popover ## Related Documentation - shadcn-vue Popover: https://www.shadcn-vue.com/docs/components/popover - Radix UI Popover: https://www.radix-vue.com/components/popover.html ## Additional Fix: Menu Structure ### Issue with DropdownMenu Submenus After initial implementation, we encountered an error: ``` Error: Injection `Symbol(MenuContext)` not found. Component must be used within MenuRoot ``` **Cause**: DropdownMenuSub, DropdownMenuSubTrigger, and DropdownMenuSubContent components require a MenuRoot context (provided by DropdownMenu). They cannot be used inside a Popover. ### Solution Replaced DropdownMenu submenu components with simple native button elements styled to match the design system: **Before:** ```vue Set Status ... ``` **After:** ```vue
Set Status
``` ### Benefits of Simplified Structure 1. ✅ No dependency on DropdownMenu context 2. ✅ Simpler, more maintainable code 3. ✅ Better performance (fewer components) 4. ✅ Same visual appearance 5. ✅ Full control over styling and behavior