241 lines
8.9 KiB
HTML
241 lines
8.9 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Shot Selection Debug Test</title>
|
|
<style>
|
|
body {
|
|
font-family: Arial, sans-serif;
|
|
margin: 20px;
|
|
background-color: #f5f5f5;
|
|
}
|
|
.test-container {
|
|
background: white;
|
|
padding: 20px;
|
|
border-radius: 8px;
|
|
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
|
margin-bottom: 20px;
|
|
}
|
|
.test-result {
|
|
padding: 10px;
|
|
margin: 10px 0;
|
|
border-radius: 4px;
|
|
}
|
|
.success { background-color: #d4edda; color: #155724; }
|
|
.error { background-color: #f8d7da; color: #721c24; }
|
|
.info { background-color: #d1ecf1; color: #0c5460; }
|
|
button {
|
|
padding: 8px 16px;
|
|
margin: 5px;
|
|
border: none;
|
|
border-radius: 4px;
|
|
cursor: pointer;
|
|
background-color: #007bff;
|
|
color: white;
|
|
}
|
|
button:hover {
|
|
background-color: #0056b3;
|
|
}
|
|
.selection-state {
|
|
background-color: #f8f9fa;
|
|
padding: 10px;
|
|
border-radius: 4px;
|
|
margin: 10px 0;
|
|
font-family: monospace;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="test-container">
|
|
<h1>Shot Table Selection Debug Test</h1>
|
|
<p>This test helps debug the shot table selection behavior by simulating the selection logic.</p>
|
|
|
|
<div class="test-result info">
|
|
<strong>Test Scenario:</strong> Verify that normal click (without modifiers) results in single selection, even on already selected rows.
|
|
</div>
|
|
|
|
<div id="selection-display" class="selection-state">
|
|
Current Selection: {}
|
|
</div>
|
|
|
|
<div>
|
|
<button onclick="testNormalClick(0)">Normal Click Row 0</button>
|
|
<button onclick="testNormalClick(1)">Normal Click Row 1</button>
|
|
<button onclick="testNormalClick(2)">Normal Click Row 2</button>
|
|
</div>
|
|
|
|
<div>
|
|
<button onclick="testShiftClick(0, 2)">Shift+Click Range 0-2</button>
|
|
<button onclick="testCtrlClick(1)">Ctrl+Click Row 1</button>
|
|
</div>
|
|
|
|
<div>
|
|
<button onclick="clearSelection()">Clear Selection</button>
|
|
<button onclick="runFullTest()">Run Full Test</button>
|
|
</div>
|
|
|
|
<div id="test-results"></div>
|
|
</div>
|
|
|
|
<script>
|
|
// Simulate the shot selection logic
|
|
let rowSelection = {};
|
|
let lastSelectedIndex = null;
|
|
|
|
// Mock data
|
|
const mockRows = [
|
|
{ id: '0', index: 0, original: { id: 1, name: 'Shot_001' } },
|
|
{ id: '1', index: 1, original: { id: 2, name: 'Shot_002' } },
|
|
{ id: '2', index: 2, original: { id: 3, name: 'Shot_003' } },
|
|
];
|
|
|
|
function updateDisplay() {
|
|
document.getElementById('selection-display').textContent =
|
|
'Current Selection: ' + JSON.stringify(rowSelection, null, 2);
|
|
}
|
|
|
|
function logResult(message, isSuccess = true) {
|
|
const resultsDiv = document.getElementById('test-results');
|
|
const resultDiv = document.createElement('div');
|
|
resultDiv.className = `test-result ${isSuccess ? 'success' : 'error'}`;
|
|
resultDiv.textContent = message;
|
|
resultsDiv.appendChild(resultDiv);
|
|
}
|
|
|
|
// Simulate the handleRowSelection logic from ShotsDataTable
|
|
function handleRowSelection(row, event = {}) {
|
|
const currentIndex = row.index;
|
|
const shotId = String(row.id);
|
|
|
|
if (event.shiftKey && lastSelectedIndex !== null) {
|
|
// Range selection
|
|
const startIndex = Math.min(lastSelectedIndex, currentIndex);
|
|
const endIndex = Math.max(lastSelectedIndex, currentIndex);
|
|
|
|
const newSelection = {};
|
|
for (let i = startIndex; i <= endIndex; i++) {
|
|
if (mockRows[i]) {
|
|
newSelection[mockRows[i].id] = true;
|
|
}
|
|
}
|
|
|
|
rowSelection = newSelection;
|
|
lastSelectedIndex = currentIndex;
|
|
} else if (event.ctrlKey || event.metaKey) {
|
|
// Toggle selection
|
|
const newSelection = { ...rowSelection };
|
|
|
|
if (newSelection[shotId]) {
|
|
delete newSelection[shotId];
|
|
} else {
|
|
newSelection[shotId] = true;
|
|
}
|
|
|
|
rowSelection = newSelection;
|
|
lastSelectedIndex = currentIndex;
|
|
} else {
|
|
// Single selection - this should ALWAYS result in only one selected row
|
|
rowSelection = { [shotId]: true };
|
|
lastSelectedIndex = currentIndex;
|
|
}
|
|
|
|
updateDisplay();
|
|
}
|
|
|
|
function testNormalClick(rowIndex) {
|
|
const row = mockRows[rowIndex];
|
|
const wasSelected = rowSelection[row.id] === true;
|
|
|
|
logResult(`Testing normal click on row ${rowIndex} (${row.original.name}) - Was selected: ${wasSelected}`);
|
|
|
|
handleRowSelection(row, {});
|
|
|
|
// Verify single selection
|
|
const selectedKeys = Object.keys(rowSelection).filter(key => rowSelection[key]);
|
|
if (selectedKeys.length === 1 && selectedKeys[0] === row.id) {
|
|
logResult(`✓ SUCCESS: Single selection working correctly. Only row ${rowIndex} is selected.`);
|
|
} else {
|
|
logResult(`✗ FAILED: Expected single selection of row ${rowIndex}, but got: ${selectedKeys.join(', ')}`, false);
|
|
}
|
|
}
|
|
|
|
function testShiftClick(startIndex, endIndex) {
|
|
// First select the start row
|
|
handleRowSelection(mockRows[startIndex], {});
|
|
logResult(`Set initial selection to row ${startIndex}`);
|
|
|
|
// Then shift-click the end row
|
|
handleRowSelection(mockRows[endIndex], { shiftKey: true });
|
|
|
|
const selectedKeys = Object.keys(rowSelection).filter(key => rowSelection[key]);
|
|
const expectedCount = Math.abs(endIndex - startIndex) + 1;
|
|
|
|
if (selectedKeys.length === expectedCount) {
|
|
logResult(`✓ SUCCESS: Range selection working. Selected ${selectedKeys.length} rows.`);
|
|
} else {
|
|
logResult(`✗ FAILED: Expected ${expectedCount} rows selected, got ${selectedKeys.length}`, false);
|
|
}
|
|
}
|
|
|
|
function testCtrlClick(rowIndex) {
|
|
const row = mockRows[rowIndex];
|
|
const wasSelected = rowSelection[row.id] === true;
|
|
const initialCount = Object.keys(rowSelection).filter(key => rowSelection[key]).length;
|
|
|
|
handleRowSelection(row, { ctrlKey: true });
|
|
|
|
const finalCount = Object.keys(rowSelection).filter(key => rowSelection[key]).length;
|
|
|
|
if (wasSelected && finalCount === initialCount - 1) {
|
|
logResult(`✓ SUCCESS: Ctrl+click deselected row ${rowIndex}`);
|
|
} else if (!wasSelected && finalCount === initialCount + 1) {
|
|
logResult(`✓ SUCCESS: Ctrl+click selected row ${rowIndex}`);
|
|
} else {
|
|
logResult(`✗ FAILED: Ctrl+click behavior incorrect for row ${rowIndex}`, false);
|
|
}
|
|
}
|
|
|
|
function clearSelection() {
|
|
rowSelection = {};
|
|
lastSelectedIndex = null;
|
|
updateDisplay();
|
|
logResult('Selection cleared');
|
|
}
|
|
|
|
function runFullTest() {
|
|
document.getElementById('test-results').innerHTML = '';
|
|
|
|
logResult('=== Starting Full Test Suite ===');
|
|
|
|
// Test 1: Normal click on empty selection
|
|
clearSelection();
|
|
testNormalClick(0);
|
|
|
|
// Test 2: Normal click on different row (should clear previous)
|
|
testNormalClick(1);
|
|
|
|
// Test 3: Normal click on same row (should still be single selection)
|
|
testNormalClick(1);
|
|
|
|
// Test 4: Range selection
|
|
clearSelection();
|
|
testShiftClick(0, 2);
|
|
|
|
// Test 5: Normal click after range selection (should clear range)
|
|
testNormalClick(1);
|
|
|
|
// Test 6: Ctrl+click behavior
|
|
clearSelection();
|
|
testNormalClick(0);
|
|
testCtrlClick(1); // Add to selection
|
|
testCtrlClick(0); // Remove from selection
|
|
|
|
logResult('=== Test Suite Complete ===');
|
|
}
|
|
|
|
// Initialize display
|
|
updateDisplay();
|
|
</script>
|
|
</body>
|
|
</html> |