358 lines
13 KiB
HTML
358 lines
13 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 Fix 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;
|
|
}
|
|
.comparison {
|
|
display: grid;
|
|
grid-template-columns: 1fr 1fr;
|
|
gap: 20px;
|
|
}
|
|
.table-sim {
|
|
border: 1px solid #ddd;
|
|
border-radius: 4px;
|
|
}
|
|
.row {
|
|
padding: 10px;
|
|
border-bottom: 1px solid #eee;
|
|
cursor: pointer;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 10px;
|
|
}
|
|
.row:hover {
|
|
background-color: #f8f9fa;
|
|
}
|
|
.row.selected {
|
|
background-color: #e3f2fd;
|
|
}
|
|
.checkbox {
|
|
width: 16px;
|
|
height: 16px;
|
|
}
|
|
.info {
|
|
background-color: #d1ecf1;
|
|
color: #0c5460;
|
|
padding: 10px;
|
|
border-radius: 4px;
|
|
margin: 10px 0;
|
|
}
|
|
.success {
|
|
background-color: #d4edda;
|
|
color: #155724;
|
|
padding: 10px;
|
|
border-radius: 4px;
|
|
margin: 10px 0;
|
|
}
|
|
.error {
|
|
background-color: #f8d7da;
|
|
color: #721c24;
|
|
padding: 10px;
|
|
border-radius: 4px;
|
|
margin: 10px 0;
|
|
}
|
|
button {
|
|
padding: 8px 16px;
|
|
margin: 5px;
|
|
border: none;
|
|
border-radius: 4px;
|
|
cursor: pointer;
|
|
background-color: #007bff;
|
|
color: white;
|
|
}
|
|
button:hover {
|
|
background-color: #0056b3;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="test-container">
|
|
<h1>Shot vs Task Selection Behavior Comparison</h1>
|
|
|
|
<div class="info">
|
|
<strong>Issue:</strong> Shot table selection doesn't clear other selections when clicking a selected row without modifiers.
|
|
<br><strong>Expected:</strong> Normal click should always result in single selection, even on already selected rows.
|
|
</div>
|
|
|
|
<div class="comparison">
|
|
<div>
|
|
<h3>Task Table (Working)</h3>
|
|
<div class="table-sim" id="task-table">
|
|
<div class="row" data-id="1">
|
|
<input type="checkbox" class="checkbox" id="task-1">
|
|
<span>Task 1</span>
|
|
</div>
|
|
<div class="row" data-id="2">
|
|
<input type="checkbox" class="checkbox" id="task-2">
|
|
<span>Task 2</span>
|
|
</div>
|
|
<div class="row" data-id="3">
|
|
<input type="checkbox" class="checkbox" id="task-3">
|
|
<span>Task 3</span>
|
|
</div>
|
|
</div>
|
|
<div>Selection: <span id="task-selection">{}</span></div>
|
|
</div>
|
|
|
|
<div>
|
|
<h3>Shot Table (Broken)</h3>
|
|
<div class="table-sim" id="shot-table">
|
|
<div class="row" data-id="1">
|
|
<input type="checkbox" class="checkbox" id="shot-1">
|
|
<span>Shot 1</span>
|
|
</div>
|
|
<div class="row" data-id="2">
|
|
<input type="checkbox" class="checkbox" id="shot-2">
|
|
<span>Shot 2</span>
|
|
</div>
|
|
<div class="row" data-id="3">
|
|
<input type="checkbox" class="checkbox" id="shot-3">
|
|
<span>Shot 3</span>
|
|
</div>
|
|
</div>
|
|
<div>Selection: <span id="shot-selection">{}</span></div>
|
|
</div>
|
|
</div>
|
|
|
|
<div>
|
|
<button onclick="testScenario1()">Test: Select multiple, then normal click</button>
|
|
<button onclick="testScenario2()">Test: Normal click same row twice</button>
|
|
<button onclick="clearAll()">Clear All</button>
|
|
</div>
|
|
|
|
<div id="test-results"></div>
|
|
</div>
|
|
|
|
<script>
|
|
// Simulate the selection states
|
|
let taskSelection = {};
|
|
let shotSelection = {};
|
|
let taskLastIndex = null;
|
|
let shotLastIndex = null;
|
|
|
|
function updateDisplay() {
|
|
document.getElementById('task-selection').textContent = JSON.stringify(taskSelection);
|
|
document.getElementById('shot-selection').textContent = JSON.stringify(shotSelection);
|
|
|
|
// Update visual state
|
|
updateVisualState('task-table', taskSelection);
|
|
updateVisualState('shot-table', shotSelection);
|
|
}
|
|
|
|
function updateVisualState(tableId, selection) {
|
|
const table = document.getElementById(tableId);
|
|
const rows = table.querySelectorAll('.row');
|
|
|
|
rows.forEach(row => {
|
|
const id = row.dataset.id;
|
|
const checkbox = row.querySelector('.checkbox');
|
|
const isSelected = selection[id] === true;
|
|
|
|
row.classList.toggle('selected', isSelected);
|
|
checkbox.checked = isSelected;
|
|
});
|
|
}
|
|
|
|
// Task table logic (working correctly)
|
|
function handleTaskSelection(rowId, event) {
|
|
const index = parseInt(rowId) - 1;
|
|
|
|
if (event.shiftKey && taskLastIndex !== null) {
|
|
// Range selection
|
|
const start = Math.min(taskLastIndex, index);
|
|
const end = Math.max(taskLastIndex, index);
|
|
const newSelection = {};
|
|
|
|
for (let i = start; i <= end; i++) {
|
|
newSelection[String(i + 1)] = true;
|
|
}
|
|
|
|
taskSelection = newSelection;
|
|
taskLastIndex = index;
|
|
} else if (event.ctrlKey || event.metaKey) {
|
|
// Toggle selection
|
|
const newSelection = { ...taskSelection };
|
|
|
|
if (newSelection[rowId]) {
|
|
delete newSelection[rowId];
|
|
} else {
|
|
newSelection[rowId] = true;
|
|
}
|
|
|
|
taskSelection = newSelection;
|
|
taskLastIndex = index;
|
|
} else {
|
|
// Single selection - ALWAYS results in only one selected row
|
|
taskSelection = { [rowId]: true };
|
|
taskLastIndex = index;
|
|
}
|
|
}
|
|
|
|
// Shot table logic (currently broken)
|
|
function handleShotSelection(rowId, event) {
|
|
const index = parseInt(rowId) - 1;
|
|
|
|
// This is the SAME logic as task table, but somehow not working in the real component
|
|
if (event.shiftKey && shotLastIndex !== null) {
|
|
// Range selection
|
|
const start = Math.min(shotLastIndex, index);
|
|
const end = Math.max(shotLastIndex, index);
|
|
const newSelection = {};
|
|
|
|
for (let i = start; i <= end; i++) {
|
|
newSelection[String(i + 1)] = true;
|
|
}
|
|
|
|
shotSelection = newSelection;
|
|
shotLastIndex = index;
|
|
} else if (event.ctrlKey || event.metaKey) {
|
|
// Toggle selection
|
|
const newSelection = { ...shotSelection };
|
|
|
|
if (newSelection[rowId]) {
|
|
delete newSelection[rowId];
|
|
} else {
|
|
newSelection[rowId] = true;
|
|
}
|
|
|
|
shotSelection = newSelection;
|
|
shotLastIndex = index;
|
|
} else {
|
|
// Single selection - this SHOULD work the same as task table
|
|
shotSelection = { [rowId]: true };
|
|
shotLastIndex = index;
|
|
}
|
|
}
|
|
|
|
// Add event listeners
|
|
document.getElementById('task-table').addEventListener('click', (e) => {
|
|
const row = e.target.closest('.row');
|
|
if (row && !e.target.matches('.checkbox')) {
|
|
e.preventDefault();
|
|
handleTaskSelection(row.dataset.id, e);
|
|
updateDisplay();
|
|
}
|
|
});
|
|
|
|
document.getElementById('shot-table').addEventListener('click', (e) => {
|
|
const row = e.target.closest('.row');
|
|
if (row && !e.target.matches('.checkbox')) {
|
|
e.preventDefault();
|
|
handleShotSelection(row.dataset.id, e);
|
|
updateDisplay();
|
|
}
|
|
});
|
|
|
|
function logResult(message, isSuccess = true) {
|
|
const resultsDiv = document.getElementById('test-results');
|
|
const resultDiv = document.createElement('div');
|
|
resultDiv.className = isSuccess ? 'success' : 'error';
|
|
resultDiv.textContent = message;
|
|
resultsDiv.appendChild(resultDiv);
|
|
}
|
|
|
|
function testScenario1() {
|
|
document.getElementById('test-results').innerHTML = '';
|
|
logResult('=== Test Scenario 1: Select multiple, then normal click ===');
|
|
|
|
// Clear selections
|
|
taskSelection = {};
|
|
shotSelection = {};
|
|
|
|
// Simulate Ctrl+click on multiple rows for both tables
|
|
handleTaskSelection('1', { ctrlKey: true });
|
|
handleTaskSelection('2', { ctrlKey: true });
|
|
handleShotSelection('1', { ctrlKey: true });
|
|
handleShotSelection('2', { ctrlKey: true });
|
|
updateDisplay();
|
|
|
|
logResult('Step 1: Selected rows 1 and 2 in both tables');
|
|
|
|
// Now normal click on row 2 (already selected)
|
|
handleTaskSelection('2', {});
|
|
handleShotSelection('2', {});
|
|
updateDisplay();
|
|
|
|
// Check results
|
|
const taskKeys = Object.keys(taskSelection).filter(k => taskSelection[k]);
|
|
const shotKeys = Object.keys(shotSelection).filter(k => shotSelection[k]);
|
|
|
|
if (taskKeys.length === 1 && taskKeys[0] === '2') {
|
|
logResult('✓ Task table: Normal click correctly resulted in single selection');
|
|
} else {
|
|
logResult('✗ Task table: Failed - expected single selection of row 2', false);
|
|
}
|
|
|
|
if (shotKeys.length === 1 && shotKeys[0] === '2') {
|
|
logResult('✓ Shot table: Normal click correctly resulted in single selection');
|
|
} else {
|
|
logResult('✗ Shot table: Failed - expected single selection of row 2, got: ' + shotKeys.join(', '), false);
|
|
}
|
|
}
|
|
|
|
function testScenario2() {
|
|
document.getElementById('test-results').innerHTML = '';
|
|
logResult('=== Test Scenario 2: Normal click same row twice ===');
|
|
|
|
// Clear selections
|
|
taskSelection = {};
|
|
shotSelection = {};
|
|
updateDisplay();
|
|
|
|
// First normal click
|
|
handleTaskSelection('1', {});
|
|
handleShotSelection('1', {});
|
|
updateDisplay();
|
|
logResult('Step 1: Normal click on row 1');
|
|
|
|
// Second normal click on same row
|
|
handleTaskSelection('1', {});
|
|
handleShotSelection('1', {});
|
|
updateDisplay();
|
|
logResult('Step 2: Normal click on row 1 again');
|
|
|
|
// Check results
|
|
const taskKeys = Object.keys(taskSelection).filter(k => taskSelection[k]);
|
|
const shotKeys = Object.keys(shotSelection).filter(k => shotSelection[k]);
|
|
|
|
if (taskKeys.length === 1 && taskKeys[0] === '1') {
|
|
logResult('✓ Task table: Double normal click maintained single selection');
|
|
} else {
|
|
logResult('✗ Task table: Failed - expected single selection of row 1', false);
|
|
}
|
|
|
|
if (shotKeys.length === 1 && shotKeys[0] === '1') {
|
|
logResult('✓ Shot table: Double normal click maintained single selection');
|
|
} else {
|
|
logResult('✗ Shot table: Failed - expected single selection of row 1', false);
|
|
}
|
|
}
|
|
|
|
function clearAll() {
|
|
taskSelection = {};
|
|
shotSelection = {};
|
|
taskLastIndex = null;
|
|
shotLastIndex = null;
|
|
updateDisplay();
|
|
document.getElementById('test-results').innerHTML = '';
|
|
}
|
|
|
|
// Initialize
|
|
updateDisplay();
|
|
</script>
|
|
</body>
|
|
</html> |