Init Repo
This commit is contained in:
@@ -0,0 +1,256 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>ShotDetailPanel Optimization Test</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 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;
|
||||
border-radius: 4px;
|
||||
margin: 10px 0;
|
||||
}
|
||||
.success {
|
||||
background-color: #d4edda;
|
||||
color: #155724;
|
||||
border: 1px solid #c3e6cb;
|
||||
}
|
||||
.error {
|
||||
background-color: #f8d7da;
|
||||
color: #721c24;
|
||||
border: 1px solid #f5c6cb;
|
||||
}
|
||||
.info {
|
||||
background-color: #d1ecf1;
|
||||
color: #0c5460;
|
||||
border: 1px solid #bee5eb;
|
||||
}
|
||||
.code {
|
||||
background-color: #f8f9fa;
|
||||
padding: 10px;
|
||||
border-radius: 4px;
|
||||
font-family: monospace;
|
||||
white-space: pre-wrap;
|
||||
border: 1px solid #e9ecef;
|
||||
}
|
||||
button {
|
||||
background-color: #007bff;
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 10px 20px;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
margin: 5px;
|
||||
}
|
||||
button:hover {
|
||||
background-color: #0056b3;
|
||||
}
|
||||
.network-log {
|
||||
max-height: 300px;
|
||||
overflow-y: auto;
|
||||
background-color: #f8f9fa;
|
||||
padding: 10px;
|
||||
border: 1px solid #e9ecef;
|
||||
border-radius: 4px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>ShotDetailPanel Optimization Test</h1>
|
||||
<p>This test verifies that ShotDetailPanel uses embedded task data instead of making redundant API calls.</p>
|
||||
|
||||
<div class="test-container">
|
||||
<h2>Test Setup</h2>
|
||||
<p>We'll monitor network requests to ensure no redundant task API calls are made when loading shot details.</p>
|
||||
<button onclick="startTest()">Start Test</button>
|
||||
<button onclick="clearLog()">Clear Log</button>
|
||||
</div>
|
||||
|
||||
<div class="test-container">
|
||||
<h2>Network Request Monitor</h2>
|
||||
<div id="networkLog" class="network-log">
|
||||
<p>Click "Start Test" to begin monitoring...</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="test-container">
|
||||
<h2>Test Results</h2>
|
||||
<div id="testResults">
|
||||
<p>No tests run yet.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="test-container">
|
||||
<h2>Expected Behavior</h2>
|
||||
<div class="info">
|
||||
<strong>✅ Optimized Behavior:</strong>
|
||||
<ul>
|
||||
<li>Only one API call to <code>/api/shots/{shotId}</code> should be made</li>
|
||||
<li>No separate calls to <code>/api/tasks/?shot_id={shotId}</code> should occur</li>
|
||||
<li>Task data should be displayed using embedded <code>task_details</code> from shot response</li>
|
||||
<li>Component should render task information without additional network requests</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="error">
|
||||
<strong>❌ Non-Optimized Behavior (what we're avoiding):</strong>
|
||||
<ul>
|
||||
<li>Multiple API calls: first <code>/api/shots/{shotId}</code>, then <code>/api/tasks/?shot_id={shotId}</code></li>
|
||||
<li>N+1 query pattern causing performance issues</li>
|
||||
<li>Redundant network requests for data already available</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
let networkRequests = [];
|
||||
let originalFetch = window.fetch;
|
||||
let originalXHROpen = XMLHttpRequest.prototype.open;
|
||||
let testStartTime = null;
|
||||
|
||||
// Override fetch to monitor requests
|
||||
window.fetch = function(...args) {
|
||||
if (testStartTime) {
|
||||
logRequest('FETCH', args[0], args[1]);
|
||||
}
|
||||
return originalFetch.apply(this, args);
|
||||
};
|
||||
|
||||
// Override XMLHttpRequest to monitor requests
|
||||
XMLHttpRequest.prototype.open = function(method, url, ...args) {
|
||||
if (testStartTime) {
|
||||
logRequest('XHR', url, { method });
|
||||
}
|
||||
return originalXHROpen.apply(this, [method, url, ...args]);
|
||||
};
|
||||
|
||||
function logRequest(type, url, options = {}) {
|
||||
const timestamp = new Date().toISOString();
|
||||
const request = {
|
||||
type,
|
||||
url: url.toString(),
|
||||
method: options.method || 'GET',
|
||||
timestamp
|
||||
};
|
||||
|
||||
networkRequests.push(request);
|
||||
updateNetworkLog();
|
||||
}
|
||||
|
||||
function updateNetworkLog() {
|
||||
const logElement = document.getElementById('networkLog');
|
||||
if (networkRequests.length === 0) {
|
||||
logElement.innerHTML = '<p>No requests captured yet...</p>';
|
||||
return;
|
||||
}
|
||||
|
||||
let html = '<h4>Captured Requests:</h4>';
|
||||
networkRequests.forEach((req, index) => {
|
||||
const isTaskRequest = req.url.includes('/tasks') && req.url.includes('shot_id');
|
||||
const isShotRequest = req.url.includes('/shots/') && !req.url.includes('/tasks');
|
||||
|
||||
let className = '';
|
||||
if (isTaskRequest) {
|
||||
className = 'error'; // This should not happen in optimized version
|
||||
} else if (isShotRequest) {
|
||||
className = 'success'; // This is expected
|
||||
}
|
||||
|
||||
html += `<div class="${className}" style="margin: 5px 0; padding: 5px; border-radius: 3px;">
|
||||
<strong>${index + 1}.</strong> ${req.method} ${req.url}
|
||||
<br><small>${req.timestamp}</small>
|
||||
</div>`;
|
||||
});
|
||||
|
||||
logElement.innerHTML = html;
|
||||
}
|
||||
|
||||
function analyzeRequests() {
|
||||
const shotRequests = networkRequests.filter(req =>
|
||||
req.url.includes('/shots/') && !req.url.includes('/tasks')
|
||||
);
|
||||
const taskRequests = networkRequests.filter(req =>
|
||||
req.url.includes('/tasks') && req.url.includes('shot_id')
|
||||
);
|
||||
|
||||
let results = '<h4>Analysis Results:</h4>';
|
||||
|
||||
if (shotRequests.length > 0) {
|
||||
results += `<div class="success">✅ Found ${shotRequests.length} shot request(s) - Expected</div>`;
|
||||
} else {
|
||||
results += `<div class="error">❌ No shot requests found - Unexpected</div>`;
|
||||
}
|
||||
|
||||
if (taskRequests.length === 0) {
|
||||
results += `<div class="success">✅ No redundant task requests found - Optimization working!</div>`;
|
||||
} else {
|
||||
results += `<div class="error">❌ Found ${taskRequests.length} redundant task request(s) - Optimization needed</div>`;
|
||||
taskRequests.forEach(req => {
|
||||
results += `<div class="code">Redundant request: ${req.method} ${req.url}</div>`;
|
||||
});
|
||||
}
|
||||
|
||||
// Check for other API requests that might be relevant
|
||||
const otherRequests = networkRequests.filter(req =>
|
||||
req.url.includes('/api/') &&
|
||||
!req.url.includes('/shots/') &&
|
||||
!req.url.includes('/tasks')
|
||||
);
|
||||
|
||||
if (otherRequests.length > 0) {
|
||||
results += `<div class="info">ℹ️ Other API requests: ${otherRequests.length}</div>`;
|
||||
}
|
||||
|
||||
document.getElementById('testResults').innerHTML = results;
|
||||
}
|
||||
|
||||
function startTest() {
|
||||
testStartTime = Date.now();
|
||||
networkRequests = [];
|
||||
|
||||
document.getElementById('testResults').innerHTML = '<p>Test in progress... Please navigate to a shot detail view in the application.</p>';
|
||||
document.getElementById('networkLog').innerHTML = '<p>Monitoring network requests...</p>';
|
||||
|
||||
// Auto-analyze after 30 seconds
|
||||
setTimeout(() => {
|
||||
if (networkRequests.length > 0) {
|
||||
analyzeRequests();
|
||||
} else {
|
||||
document.getElementById('testResults').innerHTML =
|
||||
'<div class="info">No requests captured. Make sure to interact with the ShotDetailPanel in the application.</div>';
|
||||
}
|
||||
}, 30000);
|
||||
}
|
||||
|
||||
function clearLog() {
|
||||
networkRequests = [];
|
||||
testStartTime = null;
|
||||
document.getElementById('networkLog').innerHTML = '<p>Log cleared. Click "Start Test" to begin monitoring...</p>';
|
||||
document.getElementById('testResults').innerHTML = '<p>No tests run yet.</p>';
|
||||
}
|
||||
|
||||
// Manual analysis button
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const container = document.querySelector('.test-container:nth-child(2)');
|
||||
const button = document.createElement('button');
|
||||
button.textContent = 'Analyze Current Requests';
|
||||
button.onclick = analyzeRequests;
|
||||
container.appendChild(button);
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user