LinkDesk/frontend/test-popover-debug-detailed...

469 lines
19 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Detailed Popover Debug</title>
<style>
body {
font-family: Arial, sans-serif;
max-width: 1200px;
margin: 0 auto;
padding: 20px;
background-color: #f5f5f5;
}
.debug-container {
background: white;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
margin-bottom: 20px;
}
.debug-title {
color: #333;
border-bottom: 2px solid #dc3545;
padding-bottom: 10px;
margin-bottom: 20px;
}
.debug-section {
margin-bottom: 30px;
padding: 15px;
border: 1px solid #ddd;
border-radius: 5px;
}
.debug-step {
margin-bottom: 15px;
padding: 10px;
background-color: #f8f9fa;
border-left: 4px solid #dc3545;
}
.success {
color: #28a745;
font-weight: bold;
}
.error {
color: #dc3545;
font-weight: bold;
}
.warning {
color: #ffc107;
font-weight: bold;
}
.info {
color: #17a2b8;
font-weight: bold;
}
.code {
background-color: #f1f1f1;
padding: 2px 4px;
border-radius: 3px;
font-family: monospace;
}
.button {
background-color: #dc3545;
color: white;
padding: 8px 16px;
border: none;
border-radius: 4px;
cursor: pointer;
margin: 5px;
}
.button:hover {
background-color: #c82333;
}
.test-results {
background-color: #f8f9fa;
border: 1px solid #dee2e6;
border-radius: 4px;
padding: 15px;
margin-top: 15px;
max-height: 400px;
overflow-y: auto;
}
.log-entry {
margin: 5px 0;
padding: 5px;
border-radius: 3px;
}
.log-error {
background-color: #f8d7da;
color: #721c24;
}
.log-success {
background-color: #d4edda;
color: #155724;
}
.log-info {
background-color: #d1ecf1;
color: #0c5460;
}
.log-warning {
background-color: #fff3cd;
color: #856404;
}
</style>
</head>
<body>
<div class="debug-container">
<h1 class="debug-title">🔍 Detailed Popover Debug</h1>
<div class="debug-section">
<h2>🚨 Issue: Assignment Button Popover Not Showing</h2>
<p>The assignment button is clicked but the popover doesn't appear. Let's diagnose the exact cause.</p>
</div>
<div class="debug-section">
<h2>🛠️ Diagnostic Tools</h2>
<button class="button" onclick="runFullDiagnostic()">Run Full Diagnostic</button>
<button class="button" onclick="checkPopoverComponents()">Check Popover Components</button>
<button class="button" onclick="checkEventListeners()">Check Event Listeners</button>
<button class="button" onclick="testPopoverManually()">Test Popover Manually</button>
<button class="button" onclick="checkConsoleErrors()">Check Console Errors</button>
<button class="button" onclick="clearResults()">Clear Results</button>
<div id="testResults" class="test-results" style="display: none;">
<h4>Diagnostic Results:</h4>
<div id="resultsContent"></div>
</div>
</div>
<div class="debug-section">
<h2>🔍 Step-by-Step Diagnosis</h2>
<div class="debug-step">
<h3>Step 1: Check if EditableTaskStatus components exist</h3>
<p>Looking for components with <code>data-testid="editable-task-status"</code></p>
<button class="button" onclick="checkComponents()">Check Components</button>
</div>
<div class="debug-step">
<h3>Step 2: Check if assignment buttons exist</h3>
<p>Looking for buttons within EditableTaskStatus components</p>
<button class="button" onclick="checkButtons()">Check Buttons</button>
</div>
<div class="debug-step">
<h3>Step 3: Check Popover component structure</h3>
<p>Verify Popover, PopoverTrigger, and PopoverContent are present</p>
<button class="button" onclick="checkPopoverStructure()">Check Structure</button>
</div>
<div class="debug-step">
<h3>Step 4: Test button click events</h3>
<p>Simulate clicks and monitor for popover state changes</p>
<button class="button" onclick="testButtonClicks()">Test Clicks</button>
</div>
<div class="debug-step">
<h3>Step 5: Check for JavaScript errors</h3>
<p>Look for any errors that might prevent popover from working</p>
<button class="button" onclick="checkJSErrors()">Check Errors</button>
</div>
</div>
<div class="debug-section">
<h2>🎯 Potential Issues & Solutions</h2>
<div class="debug-step">
<h3>Issue 1: Popover Components Not Imported</h3>
<p><span class="error">Symptom:</span> No popover elements found in DOM</p>
<p><span class="info">Check:</span> Verify Popover, PopoverTrigger, PopoverContent imports</p>
</div>
<div class="debug-step">
<h3>Issue 2: Event Propagation Problems</h3>
<p><span class="error">Symptom:</span> Button clicks don't trigger popover</p>
<p><span class="info">Check:</span> Event listeners and stopPropagation calls</p>
</div>
<div class="debug-step">
<h3>Issue 3: Z-Index or CSS Issues</h3>
<p><span class="error">Symptom:</span> Popover opens but is hidden</p>
<p><span class="info">Check:</span> Z-index values and CSS positioning</p>
</div>
<div class="debug-step">
<h3>Issue 4: Vue Reactivity Issues</h3>
<p><span class="error">Symptom:</span> State changes don't trigger UI updates</p>
<p><span class="info">Check:</span> Reactive refs and computed properties</p>
</div>
</div>
</div>
<script>
let diagnosticResults = [];
function log(message, type = 'info') {
const timestamp = new Date().toLocaleTimeString();
const entry = { timestamp, message, type };
diagnosticResults.push(entry);
console.log(`[${timestamp}] ${message}`);
updateResults();
}
function updateResults() {
const resultsDiv = document.getElementById('testResults');
const contentDiv = document.getElementById('resultsContent');
if (diagnosticResults.length === 0) {
resultsDiv.style.display = 'none';
return;
}
resultsDiv.style.display = 'block';
contentDiv.innerHTML = diagnosticResults.map(entry =>
`<div class="log-entry log-${entry.type}">
<strong>[${entry.timestamp}]</strong> ${entry.message}
</div>`
).join('');
// Scroll to bottom
contentDiv.scrollTop = contentDiv.scrollHeight;
}
function clearResults() {
diagnosticResults = [];
updateResults();
}
function checkComponents() {
const components = document.querySelectorAll('[data-testid="editable-task-status"]');
log(`Found ${components.length} EditableTaskStatus components`, components.length > 0 ? 'success' : 'error');
if (components.length === 0) {
log('❌ No EditableTaskStatus components found. Make sure you\'re on the shots table view.', 'error');
return false;
}
components.forEach((comp, index) => {
log(` Component ${index + 1}: ${comp.tagName} with classes: ${comp.className}`, 'info');
});
return components;
}
function checkButtons() {
const components = checkComponents();
if (!components) return false;
let totalButtons = 0;
components.forEach((comp, index) => {
const buttons = comp.querySelectorAll('button');
totalButtons += buttons.length;
log(` Component ${index + 1}: ${buttons.length} buttons found`, buttons.length > 0 ? 'success' : 'warning');
buttons.forEach((btn, btnIndex) => {
const hasUserIcon = btn.querySelector('[data-lucide="user"]');
const hasAvatar = btn.querySelector('[class*="avatar"]');
const isDisabled = btn.disabled;
log(` Button ${btnIndex + 1}: ${hasUserIcon ? '👤 User' : hasAvatar ? '🔵 Avatar' : '❓ Unknown'} ${isDisabled ? '(disabled)' : '(enabled)'}`, 'info');
});
});
log(`Total buttons found: ${totalButtons}`, totalButtons > 0 ? 'success' : 'error');
return totalButtons > 0;
}
function checkPopoverStructure() {
const popovers = document.querySelectorAll('[data-radix-popover-trigger], [role="button"][aria-haspopup="dialog"]');
log(`Found ${popovers.length} popover triggers`, popovers.length > 0 ? 'success' : 'error');
const popoverContents = document.querySelectorAll('[data-radix-popover-content], [role="dialog"]');
log(`Found ${popoverContents.length} popover contents`, 'info');
// Check for Vue components
const vuePopovers = document.querySelectorAll('[data-v-*]');
log(`Found ${vuePopovers.length} Vue components (may include popovers)`, 'info');
// Check for specific popover classes
const popoverElements = document.querySelectorAll('[class*="popover"]');
log(`Found ${popoverElements.length} elements with popover classes`, 'info');
return popovers.length > 0;
}
function testButtonClicks() {
const components = document.querySelectorAll('[data-testid="editable-task-status"]');
if (components.length === 0) {
log('❌ No components found to test', 'error');
return;
}
let buttonsTested = 0;
components.forEach((comp, compIndex) => {
const buttons = comp.querySelectorAll('button');
buttons.forEach((btn, btnIndex) => {
if (btn.disabled) {
log(` Skipping disabled button ${compIndex + 1}.${btnIndex + 1}`, 'warning');
return;
}
log(` Testing button ${compIndex + 1}.${btnIndex + 1}...`, 'info');
// Add event listener to detect clicks
const clickHandler = (e) => {
log(` ✅ Click event fired on button ${compIndex + 1}.${btnIndex + 1}`, 'success');
btn.removeEventListener('click', clickHandler);
};
btn.addEventListener('click', clickHandler);
// Simulate click
try {
btn.click();
buttonsTested++;
log(` 🖱️ Simulated click on button ${compIndex + 1}.${btnIndex + 1}`, 'info');
// Check if popover appeared after a short delay
setTimeout(() => {
const newPopovers = document.querySelectorAll('[data-radix-popper-content-wrapper], [role="dialog"]');
if (newPopovers.length > 0) {
log(` ✅ Popover appeared after clicking button ${compIndex + 1}.${btnIndex + 1}!`, 'success');
} else {
log(` ❌ No popover appeared after clicking button ${compIndex + 1}.${btnIndex + 1}`, 'error');
}
}, 100);
} catch (error) {
log(` ❌ Error clicking button ${compIndex + 1}.${btnIndex + 1}: ${error.message}`, 'error');
}
});
});
log(`Tested ${buttonsTested} buttons`, buttonsTested > 0 ? 'success' : 'warning');
}
function checkEventListeners() {
log('Checking for event listeners...', 'info');
// Check for click event listeners
const buttons = document.querySelectorAll('[data-testid="editable-task-status"] button');
buttons.forEach((btn, index) => {
const listeners = getEventListeners ? getEventListeners(btn) : null;
if (listeners) {
log(` Button ${index + 1}: ${Object.keys(listeners).length} event types`, 'info');
Object.keys(listeners).forEach(eventType => {
log(` - ${eventType}: ${listeners[eventType].length} listeners`, 'info');
});
} else {
log(` Button ${index + 1}: Cannot inspect event listeners (getEventListeners not available)`, 'warning');
}
});
}
function checkJSErrors() {
log('Checking for JavaScript errors...', 'info');
// Override console.error to catch errors
const originalError = console.error;
const errors = [];
console.error = function(...args) {
errors.push(args.join(' '));
originalError.apply(console, args);
};
// Check for Vue errors
if (window.Vue && window.Vue.config) {
const originalErrorHandler = window.Vue.config.errorHandler;
window.Vue.config.errorHandler = function(err, vm, info) {
errors.push(`Vue Error: ${err.message} (${info})`);
if (originalErrorHandler) originalErrorHandler(err, vm, info);
};
}
setTimeout(() => {
if (errors.length > 0) {
log(`Found ${errors.length} JavaScript errors:`, 'error');
errors.forEach(error => log(` - ${error}`, 'error'));
} else {
log('No JavaScript errors detected', 'success');
}
// Restore original console.error
console.error = originalError;
}, 1000);
}
function checkConsoleErrors() {
log('Monitoring console for errors...', 'info');
log('Click an assignment button now and watch for errors', 'info');
checkJSErrors();
}
function checkPopoverComponents() {
log('Checking Popover component imports and structure...', 'info');
// Check for Radix UI elements
const radixElements = document.querySelectorAll('[data-radix-popover-root], [data-radix-popover-trigger], [data-radix-popover-content]');
log(`Found ${radixElements.length} Radix Popover elements`, radixElements.length > 0 ? 'success' : 'warning');
// Check for shadcn-vue popover classes
const shadcnElements = document.querySelectorAll('[class*="popover"]');
log(`Found ${shadcnElements.length} elements with popover classes`, 'info');
// Check for Vue component markers
const vueMarkers = document.querySelectorAll('[data-v-]');
log(`Found ${vueMarkers.length} Vue component markers`, 'info');
checkPopoverStructure();
}
function testPopoverManually() {
log('Manual popover test - please click an assignment button now', 'info');
// Monitor for DOM changes
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
if (mutation.type === 'childList') {
mutation.addedNodes.forEach((node) => {
if (node.nodeType === 1) { // Element node
if (node.matches && (
node.matches('[data-radix-popper-content-wrapper]') ||
node.matches('[role="dialog"]') ||
node.matches('[class*="popover"]')
)) {
log('✅ Popover element detected in DOM!', 'success');
log(` Element: ${node.tagName} with classes: ${node.className}`, 'info');
}
}
});
}
});
});
observer.observe(document.body, {
childList: true,
subtree: true
});
// Stop observing after 10 seconds
setTimeout(() => {
observer.disconnect();
log('Stopped monitoring for popover changes', 'info');
}, 10000);
}
function runFullDiagnostic() {
log('🚀 Starting full diagnostic...', 'info');
// Run all checks
checkComponents();
checkButtons();
checkPopoverComponents();
checkEventListeners();
testButtonClicks();
checkJSErrors();
log('🏁 Full diagnostic complete', 'success');
log('If popover still doesn\'t work, check the detailed logs above', 'info');
}
// Auto-run basic checks on page load
document.addEventListener('DOMContentLoaded', function() {
log('🔍 Detailed Popover Debug loaded', 'info');
log('Click "Run Full Diagnostic" to start comprehensive testing', 'info');
});
</script>
</body>
</html>