242 lines
8.1 KiB
HTML
242 lines
8.1 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Context Menu Test - Task Browser</title>
|
|
<style>
|
|
body {
|
|
font-family: Arial, sans-serif;
|
|
max-width: 1200px;
|
|
margin: 20px auto;
|
|
padding: 20px;
|
|
background: #f5f5f5;
|
|
}
|
|
.test-section {
|
|
background: white;
|
|
padding: 20px;
|
|
margin-bottom: 20px;
|
|
border-radius: 8px;
|
|
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
|
}
|
|
h1 {
|
|
color: #333;
|
|
border-bottom: 2px solid #007bff;
|
|
padding-bottom: 10px;
|
|
}
|
|
h2 {
|
|
color: #555;
|
|
margin-top: 0;
|
|
}
|
|
.test-case {
|
|
margin: 15px 0;
|
|
padding: 15px;
|
|
background: #f8f9fa;
|
|
border-left: 4px solid #007bff;
|
|
}
|
|
.test-case h3 {
|
|
margin-top: 0;
|
|
color: #007bff;
|
|
}
|
|
.requirement {
|
|
background: #e7f3ff;
|
|
padding: 10px;
|
|
margin: 10px 0;
|
|
border-radius: 4px;
|
|
}
|
|
.code {
|
|
background: #f4f4f4;
|
|
padding: 10px;
|
|
border-radius: 4px;
|
|
font-family: 'Courier New', monospace;
|
|
overflow-x: auto;
|
|
}
|
|
.success {
|
|
color: #28a745;
|
|
font-weight: bold;
|
|
}
|
|
.info {
|
|
color: #17a2b8;
|
|
}
|
|
ul {
|
|
line-height: 1.8;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<h1>🖱️ Context Menu Implementation Test</h1>
|
|
|
|
<div class="test-section">
|
|
<h2>Implementation Summary</h2>
|
|
<p>Task 8: Implement context menu trigger in TaskBrowser</p>
|
|
<p class="success">✅ Implementation Complete</p>
|
|
|
|
<h3>Changes Made:</h3>
|
|
<ul>
|
|
<li>Added <code>@contextmenu</code> event handler to table rows</li>
|
|
<li>Implemented <code>handleContextMenu</code> method with position tracking</li>
|
|
<li>Added automatic selection of right-clicked unselected rows</li>
|
|
<li>Added context menu state management (showContextMenu, contextMenuPosition)</li>
|
|
<li>Integrated TaskBulkActionsMenu component</li>
|
|
<li>Added fetchProjectMembers to load assignee options</li>
|
|
<li>Implemented closeContextMenu handler</li>
|
|
</ul>
|
|
</div>
|
|
|
|
<div class="test-section">
|
|
<h2>Requirements Coverage</h2>
|
|
|
|
<div class="test-case">
|
|
<h3>Requirement 3.1: Right-click on selected task</h3>
|
|
<div class="requirement">
|
|
<strong>Requirement:</strong> WHEN a user right-clicks on a selected task row THEN the system SHALL display a context menu at the cursor position
|
|
</div>
|
|
<p><strong>Implementation:</strong></p>
|
|
<div class="code">
|
|
@contextmenu="handleContextMenu($event, index)"
|
|
|
|
const handleContextMenu = (event: MouseEvent, rowIndex: number) => {
|
|
event.preventDefault()
|
|
contextMenuPosition.value = { x: event.clientX, y: event.clientY }
|
|
showContextMenu.value = true
|
|
}
|
|
</div>
|
|
<p class="success">✅ Implemented - Context menu appears at cursor position</p>
|
|
</div>
|
|
|
|
<div class="test-case">
|
|
<h3>Requirement 3.2: Right-click on unselected task</h3>
|
|
<div class="requirement">
|
|
<strong>Requirement:</strong> WHEN a user right-clicks on an unselected task row THEN the system SHALL select that task and display the context menu
|
|
</div>
|
|
<p><strong>Implementation:</strong></p>
|
|
<div class="code">
|
|
// Ensure right-clicked unselected row gets selected before menu shows
|
|
if (!rowSelection.value[rowIndex]) {
|
|
rowSelection.value = { [rowIndex]: true }
|
|
}
|
|
</div>
|
|
<p class="success">✅ Implemented - Unselected rows are automatically selected on right-click</p>
|
|
</div>
|
|
|
|
<div class="test-case">
|
|
<h3>Requirement 3.3: Click outside closes menu</h3>
|
|
<div class="requirement">
|
|
<strong>Requirement:</strong> WHEN the context menu is open and the user clicks outside THEN the system SHALL close the context menu
|
|
</div>
|
|
<p><strong>Implementation:</strong></p>
|
|
<div class="code">
|
|
// TaskBulkActionsMenu handles this via DropdownMenuContent's @interact-outside
|
|
// The menu component emits 'update:open' with false value
|
|
v-model:open="showContextMenu"
|
|
</div>
|
|
<p class="success">✅ Implemented - Menu closes via v-model binding and interact-outside handler</p>
|
|
</div>
|
|
|
|
<div class="test-case">
|
|
<h3>Requirement 3.4: No menu on empty space</h3>
|
|
<div class="requirement">
|
|
<strong>Requirement:</strong> WHEN no tasks are selected and the user right-clicks empty space THEN the system SHALL not display the context menu
|
|
</div>
|
|
<p><strong>Implementation:</strong></p>
|
|
<div class="code">
|
|
// Prevent context menu on empty table areas
|
|
if (filteredTasks.value.length === 0) {
|
|
return
|
|
}
|
|
|
|
// Context menu only attached to TableRow elements, not empty space
|
|
@contextmenu="handleContextMenu($event, index)"
|
|
</div>
|
|
<p class="success">✅ Implemented - Menu only appears when right-clicking actual rows</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="test-section">
|
|
<h2>Testing Instructions</h2>
|
|
|
|
<h3>Manual Testing Steps:</h3>
|
|
<ol>
|
|
<li><strong>Start the application:</strong>
|
|
<div class="code">cd frontend && npm run dev</div>
|
|
</li>
|
|
<li><strong>Navigate to a project's Tasks view</strong></li>
|
|
<li><strong>Test Requirement 3.1:</strong>
|
|
<ul>
|
|
<li>Click checkbox to select a task</li>
|
|
<li>Right-click on the selected task row</li>
|
|
<li>Verify context menu appears at cursor position</li>
|
|
<li>Verify menu shows "X tasks selected" header</li>
|
|
</ul>
|
|
</li>
|
|
<li><strong>Test Requirement 3.2:</strong>
|
|
<ul>
|
|
<li>Clear all selections (if any)</li>
|
|
<li>Right-click on an unselected task row</li>
|
|
<li>Verify the row becomes selected (highlighted)</li>
|
|
<li>Verify context menu appears</li>
|
|
<li>Verify menu shows "1 task selected"</li>
|
|
</ul>
|
|
</li>
|
|
<li><strong>Test Requirement 3.3:</strong>
|
|
<ul>
|
|
<li>Open context menu by right-clicking a task</li>
|
|
<li>Click anywhere outside the menu</li>
|
|
<li>Verify menu closes</li>
|
|
</ul>
|
|
</li>
|
|
<li><strong>Test Requirement 3.4:</strong>
|
|
<ul>
|
|
<li>Apply filters to show no tasks (empty table)</li>
|
|
<li>Right-click in the empty table area</li>
|
|
<li>Verify no context menu appears</li>
|
|
<li>Right-click on the "No tasks found" message</li>
|
|
<li>Verify no context menu appears</li>
|
|
</ul>
|
|
</li>
|
|
</ol>
|
|
</div>
|
|
|
|
<div class="test-section">
|
|
<h2>Integration Points</h2>
|
|
|
|
<h3>Components Integrated:</h3>
|
|
<ul>
|
|
<li><strong>TaskBulkActionsMenu:</strong> Context menu component with status and assignee submenus</li>
|
|
<li><strong>Project Service:</strong> Fetches project members for assignee list</li>
|
|
<li><strong>TanStack Table:</strong> Row selection state management</li>
|
|
</ul>
|
|
|
|
<h3>State Management:</h3>
|
|
<ul>
|
|
<li><code>showContextMenu</code>: Controls menu visibility</li>
|
|
<li><code>contextMenuPosition</code>: Tracks cursor position for menu placement</li>
|
|
<li><code>rowSelection</code>: TanStack Table selection state</li>
|
|
<li><code>projectMembers</code>: List of users for assignment submenu</li>
|
|
</ul>
|
|
</div>
|
|
|
|
<div class="test-section">
|
|
<h2>Next Steps</h2>
|
|
<p class="info">The following tasks will implement the actual bulk action handlers:</p>
|
|
<ul>
|
|
<li><strong>Task 9:</strong> Implement bulk status update action</li>
|
|
<li><strong>Task 10:</strong> Implement bulk assignment action</li>
|
|
<li><strong>Task 11:</strong> Implement keyboard shortcuts</li>
|
|
</ul>
|
|
<p>Currently, the context menu appears correctly but the action handlers are placeholder functions that will be implemented in subsequent tasks.</p>
|
|
</div>
|
|
|
|
<div class="test-section">
|
|
<h2>Code Quality</h2>
|
|
<ul>
|
|
<li class="success">✅ TypeScript compilation: No errors</li>
|
|
<li class="success">✅ Vue diagnostics: No issues</li>
|
|
<li class="success">✅ Event handlers properly typed</li>
|
|
<li class="success">✅ Requirements documented in code comments</li>
|
|
<li class="success">✅ Follows existing code patterns</li>
|
|
</ul>
|
|
</div>
|
|
</body>
|
|
</html>
|