LinkDesk/frontend/test-shot-table-view.html

364 lines
13 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Shot Table View Test</title>
<style>
body {
font-family: Arial, sans-serif;
max-width: 1200px;
margin: 20px auto;
padding: 20px;
}
.test-section {
margin-bottom: 30px;
padding: 20px;
border: 1px solid #ddd;
border-radius: 8px;
}
.test-section h2 {
margin-top: 0;
color: #333;
}
.success {
color: green;
font-weight: bold;
}
.error {
color: red;
font-weight: bold;
}
.info {
color: blue;
}
pre {
background: #f5f5f5;
padding: 10px;
border-radius: 4px;
overflow-x: auto;
}
button {
background: #007bff;
color: white;
border: none;
padding: 10px 20px;
border-radius: 4px;
cursor: pointer;
margin-right: 10px;
}
button:hover {
background: #0056b3;
}
.result {
margin-top: 10px;
padding: 10px;
background: #f9f9f9;
border-left: 4px solid #007bff;
}
</style>
</head>
<body>
<h1>Shot Table View - Implementation Test</h1>
<p class="info">This page tests the shot table view implementation with task status display.</p>
<div class="test-section">
<h2>Test 1: Backend API - Get Shots with Task Status</h2>
<button onclick="testGetShots()">Run Test</button>
<div id="test1-result" class="result" style="display:none;"></div>
</div>
<div class="test-section">
<h2>Test 2: Backend API - Filter by Task Status</h2>
<button onclick="testFilterByTaskStatus()">Run Test</button>
<div id="test2-result" class="result" style="display:none;"></div>
</div>
<div class="test-section">
<h2>Test 3: Backend API - Sort by Task Status</h2>
<button onclick="testSortByTaskStatus()">Run Test</button>
<div id="test3-result" class="result" style="display:none;"></div>
</div>
<div class="test-section">
<h2>Test 4: Backend API - Sort by Name</h2>
<button onclick="testSortByName()">Run Test</button>
<div id="test4-result" class="result" style="display:none;"></div>
</div>
<div class="test-section">
<h2>Test 5: Custom Task Types Support</h2>
<button onclick="testCustomTaskTypes()">Run Test</button>
<div id="test5-result" class="result" style="display:none;"></div>
</div>
<script>
const API_BASE = 'http://localhost:8000';
let authToken = null;
// Login first
async function login() {
if (authToken) return authToken;
try {
const response = await fetch(`${API_BASE}/auth/login`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
email: 'admin@vfx.com',
password: 'admin123'
})
});
if (!response.ok) {
throw new Error('Login failed');
}
const data = await response.json();
authToken = data.access_token;
return authToken;
} catch (error) {
console.error('Login error:', error);
throw error;
}
}
async function testGetShots() {
const resultDiv = document.getElementById('test1-result');
resultDiv.style.display = 'block';
resultDiv.innerHTML = '<p>Running test...</p>';
try {
const token = await login();
const response = await fetch(`${API_BASE}/shots/`, {
headers: {
'Authorization': `Bearer ${token}`
}
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
const shots = await response.json();
let html = `<p class="success">✓ Test Passed</p>`;
html += `<p>Found ${shots.length} shots</p>`;
if (shots.length > 0) {
const shot = shots[0];
html += `<p><strong>First Shot:</strong></p>`;
html += `<pre>${JSON.stringify({
id: shot.id,
name: shot.name,
episode_id: shot.episode_id,
frame_range: `${shot.frame_start}-${shot.frame_end}`,
task_count: shot.task_count,
task_status: shot.task_status,
task_details_count: shot.task_details?.length || 0
}, null, 2)}</pre>`;
if (shot.task_status) {
html += `<p class="success">✓ Task status included</p>`;
} else {
html += `<p class="error">✗ Task status missing</p>`;
}
if (shot.task_details && shot.task_details.length > 0) {
html += `<p class="success">✓ Task details included (${shot.task_details.length} tasks)</p>`;
} else {
html += `<p class="error">✗ Task details missing</p>`;
}
}
resultDiv.innerHTML = html;
} catch (error) {
resultDiv.innerHTML = `<p class="error">✗ Test Failed: ${error.message}</p>`;
}
}
async function testFilterByTaskStatus() {
const resultDiv = document.getElementById('test2-result');
resultDiv.style.display = 'block';
resultDiv.innerHTML = '<p>Running test...</p>';
try {
const token = await login();
const response = await fetch(`${API_BASE}/shots/?task_status_filter=layout:not_started`, {
headers: {
'Authorization': `Bearer ${token}`
}
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
const shots = await response.json();
let html = `<p class="success">✓ Test Passed</p>`;
html += `<p>Found ${shots.length} shots with layout task not started</p>`;
if (shots.length > 0) {
const allMatch = shots.every(shot =>
shot.task_status && shot.task_status.layout === 'not_started'
);
if (allMatch) {
html += `<p class="success">✓ All shots match filter criteria</p>`;
} else {
html += `<p class="error">✗ Some shots don't match filter</p>`;
}
}
resultDiv.innerHTML = html;
} catch (error) {
resultDiv.innerHTML = `<p class="error">✗ Test Failed: ${error.message}</p>`;
}
}
async function testSortByTaskStatus() {
const resultDiv = document.getElementById('test3-result');
resultDiv.style.display = 'block';
resultDiv.innerHTML = '<p>Running test...</p>';
try {
const token = await login();
const response = await fetch(`${API_BASE}/shots/?sort_by=layout_status&sort_direction=asc`, {
headers: {
'Authorization': `Bearer ${token}`
}
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
const shots = await response.json();
let html = `<p class="success">✓ Test Passed</p>`;
html += `<p>Sorted ${shots.length} shots by layout task status</p>`;
if (shots.length > 0) {
html += `<p><strong>First 5 shots (sorted by layout status):</strong></p>`;
html += '<ul>';
shots.slice(0, 5).forEach(shot => {
html += `<li>${shot.name}: ${shot.task_status?.layout || 'N/A'}</li>`;
});
html += '</ul>';
}
resultDiv.innerHTML = html;
} catch (error) {
resultDiv.innerHTML = `<p class="error">✗ Test Failed: ${error.message}</p>`;
}
}
async function testSortByName() {
const resultDiv = document.getElementById('test4-result');
resultDiv.style.display = 'block';
resultDiv.innerHTML = '<p>Running test...</p>';
try {
const token = await login();
const response = await fetch(`${API_BASE}/shots/?sort_by=name&sort_direction=asc`, {
headers: {
'Authorization': `Bearer ${token}`
}
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
const shots = await response.json();
let html = `<p class="success">✓ Test Passed</p>`;
html += `<p>Sorted ${shots.length} shots by name</p>`;
if (shots.length > 0) {
html += `<p><strong>First 5 shots (sorted by name):</strong></p>`;
html += '<ul>';
shots.slice(0, 5).forEach(shot => {
html += `<li>${shot.name}</li>`;
});
html += '</ul>';
// Check if sorted
const names = shots.map(s => s.name);
const sortedNames = [...names].sort();
const isSorted = JSON.stringify(names) === JSON.stringify(sortedNames);
if (isSorted) {
html += `<p class="success">✓ Shots are correctly sorted</p>`;
} else {
html += `<p class="error">✗ Shots are not correctly sorted</p>`;
}
}
resultDiv.innerHTML = html;
} catch (error) {
resultDiv.innerHTML = `<p class="error">✗ Test Failed: ${error.message}</p>`;
}
}
async function testCustomTaskTypes() {
const resultDiv = document.getElementById('test5-result');
resultDiv.style.display = 'block';
resultDiv.innerHTML = '<p>Running test...</p>';
try {
const token = await login();
const response = await fetch(`${API_BASE}/shots/`, {
headers: {
'Authorization': `Bearer ${token}`
}
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
const shots = await response.json();
let html = `<p class="success">✓ Test Passed</p>`;
if (shots.length > 0) {
const shot = shots[0];
const taskTypes = Object.keys(shot.task_status || {});
html += `<p>Found ${taskTypes.length} task types in shot data</p>`;
html += `<p><strong>Task Types:</strong></p>`;
html += '<ul>';
taskTypes.forEach(type => {
html += `<li>${type}</li>`;
});
html += '</ul>';
// Check for custom task types (non-standard)
const standardTypes = ['layout', 'animation', 'simulation', 'lighting', 'compositing'];
const customTypes = taskTypes.filter(t => !standardTypes.includes(t));
if (customTypes.length > 0) {
html += `<p class="success">✓ Custom task types found: ${customTypes.join(', ')}</p>`;
} else {
html += `<p class="info"> No custom task types in this project (only standard types)</p>`;
}
}
resultDiv.innerHTML = html;
} catch (error) {
resultDiv.innerHTML = `<p class="error">✗ Test Failed: ${error.message}</p>`;
}
}
// Auto-run first test on page load
window.addEventListener('load', () => {
console.log('Page loaded. Ready to run tests.');
});
</script>
</body>
</html>