LinkDesk/frontend/test-custom-task-columns.html

365 lines
14 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Test Custom Task Columns in Asset Browser</title>
<style>
body {
font-family: Arial, sans-serif;
max-width: 1400px;
margin: 0 auto;
padding: 20px;
background-color: #f5f5f5;
}
.container {
background: white;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
margin-bottom: 20px;
}
h1 {
color: #333;
border-bottom: 2px solid #4CAF50;
padding-bottom: 10px;
}
h2 {
color: #555;
margin-top: 20px;
}
.test-section {
margin: 20px 0;
padding: 15px;
background: #f9f9f9;
border-left: 4px solid #4CAF50;
}
.success {
color: #4CAF50;
font-weight: bold;
}
.error {
color: #f44336;
font-weight: bold;
}
.info {
color: #2196F3;
}
button {
background-color: #4CAF50;
color: white;
padding: 10px 20px;
border: none;
border-radius: 4px;
cursor: pointer;
margin: 5px;
}
button:hover {
background-color: #45a049;
}
button:disabled {
background-color: #cccccc;
cursor: not-allowed;
}
table {
width: 100%;
border-collapse: collapse;
margin: 10px 0;
}
th, td {
border: 1px solid #ddd;
padding: 8px;
text-align: left;
}
th {
background-color: #4CAF50;
color: white;
}
tr:nth-child(even) {
background-color: #f2f2f2;
}
.column-toggle {
margin: 10px 0;
padding: 10px;
background: #e3f2fd;
border-radius: 4px;
}
.column-toggle label {
display: inline-block;
margin-right: 15px;
}
</style>
</head>
<body>
<div class="container">
<h1>🎬 Custom Task Columns Test</h1>
<p>This page tests the custom task type columns in the asset browser</p>
<div class="test-section">
<h2>Authentication</h2>
<div id="auth-status">Not logged in</div>
<button onclick="login()">Login as Admin</button>
</div>
<div class="test-section">
<h2>Test 1: Load Project Custom Task Types</h2>
<button onclick="loadCustomTaskTypes()" id="test1-btn" disabled>Load Custom Task Types</button>
<div id="test1-results"></div>
</div>
<div class="test-section">
<h2>Test 2: Column Visibility Control</h2>
<div class="column-toggle" id="column-controls">
<button onclick="toggleAllTaskColumns()" id="toggle-all-btn" disabled>
Show/Hide All Task Columns
</button>
<div id="column-checkboxes" style="margin-top: 10px;"></div>
</div>
<div id="test2-results"></div>
</div>
<div class="test-section">
<h2>Test 3: Asset Table with Custom Columns</h2>
<button onclick="loadAssetsWithCustomColumns()" id="test3-btn" disabled>Load Assets</button>
<div id="test3-results"></div>
</div>
</div>
<script>
const API_BASE = 'http://localhost:8000';
let token = null;
let projectId = null;
let customTaskTypes = [];
let visibleColumns = {
name: true,
category: true,
status: true,
modeling: true,
surfacing: true,
rigging: true,
description: true
};
let savedTaskColumnStates = {};
async function login() {
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) {
const data = await response.json();
token = data.access_token;
document.getElementById('auth-status').innerHTML = '<span class="success">✅ Logged in successfully</span>';
// Get project
await getProject();
// Enable test buttons
document.getElementById('test1-btn').disabled = false;
document.getElementById('test2-btn').disabled = false;
document.getElementById('test3-btn').disabled = false;
document.getElementById('toggle-all-btn').disabled = false;
} else {
document.getElementById('auth-status').innerHTML = '<span class="error">❌ Login failed</span>';
}
} catch (error) {
document.getElementById('auth-status').innerHTML = `<span class="error">❌ Error: ${error.message}</span>`;
}
}
async function getProject() {
const response = await fetch(`${API_BASE}/projects/`, {
headers: { 'Authorization': `Bearer ${token}` }
});
const projects = await response.json();
if (projects.length > 0) {
projectId = projects[0].id;
document.getElementById('auth-status').innerHTML += `<br><span class="info">Using project: ${projects[0].name} (ID: ${projectId})</span>`;
}
}
async function loadCustomTaskTypes() {
const resultsDiv = document.getElementById('test1-results');
resultsDiv.innerHTML = '<p>Loading custom task types...</p>';
try {
const response = await fetch(`${API_BASE}/projects/${projectId}`, {
headers: { 'Authorization': `Bearer ${token}` }
});
if (response.ok) {
const project = await response.json();
customTaskTypes = project.custom_asset_task_types || [];
let results = `<p class="success">✅ Loaded ${customTaskTypes.length} custom task types</p>`;
if (customTaskTypes.length > 0) {
results += '<p><strong>Custom Task Types:</strong></p><ul>';
customTaskTypes.forEach(type => {
results += `<li>${type}</li>`;
// Initialize visibility for custom types
if (!(type in visibleColumns)) {
visibleColumns[type] = true;
}
});
results += '</ul>';
} else {
results += '<p class="info">No custom task types defined for this project</p>';
}
resultsDiv.innerHTML = results;
updateColumnCheckboxes();
} else {
resultsDiv.innerHTML = '<p class="error">❌ Failed to load project</p>';
}
} catch (error) {
resultsDiv.innerHTML = `<p class="error">❌ Error: ${error.message}</p>`;
}
}
function updateColumnCheckboxes() {
const checkboxesDiv = document.getElementById('column-checkboxes');
const standardTypes = ['modeling', 'surfacing', 'rigging'];
const allTypes = [...standardTypes, ...customTaskTypes];
let html = '<strong>Task Columns:</strong><br>';
allTypes.forEach(type => {
const checked = visibleColumns[type] ? 'checked' : '';
const label = type.split('_').map(w => w.charAt(0).toUpperCase() + w.slice(1)).join(' ');
html += `
<label>
<input type="checkbox" ${checked} onchange="toggleColumn('${type}')" />
${label}
</label>
`;
});
checkboxesDiv.innerHTML = html;
}
function toggleColumn(column) {
visibleColumns[column] = !visibleColumns[column];
updateColumnCheckboxes();
const resultsDiv = document.getElementById('test2-results');
resultsDiv.innerHTML = `<p class="info">Column "${column}" is now ${visibleColumns[column] ? 'visible' : 'hidden'}</p>`;
}
function toggleAllTaskColumns() {
const standardTypes = ['modeling', 'surfacing', 'rigging'];
const allTypes = [...standardTypes, ...customTaskTypes];
// Check if all are visible
const allVisible = allTypes.every(type => visibleColumns[type]);
if (allVisible) {
// Hide all and save states
savedTaskColumnStates = {};
allTypes.forEach(type => {
savedTaskColumnStates[type] = visibleColumns[type];
visibleColumns[type] = false;
});
} else {
// Restore saved states or show all
allTypes.forEach(type => {
if (type in savedTaskColumnStates) {
visibleColumns[type] = savedTaskColumnStates[type];
} else {
visibleColumns[type] = true;
}
});
savedTaskColumnStates = {};
}
updateColumnCheckboxes();
const resultsDiv = document.getElementById('test2-results');
resultsDiv.innerHTML = `<p class="success">✅ ${allVisible ? 'Hidden' : 'Shown'} all task columns</p>`;
}
async function loadAssetsWithCustomColumns() {
const resultsDiv = document.getElementById('test3-results');
resultsDiv.innerHTML = '<p>Loading assets...</p>';
try {
const response = await fetch(`${API_BASE}/assets/?project_id=${projectId}`, {
headers: { 'Authorization': `Bearer ${token}` }
});
if (response.ok) {
const assets = await response.json();
if (assets.length === 0) {
resultsDiv.innerHTML = '<p class="info">No assets found</p>';
return;
}
// Build table with dynamic columns
const standardTypes = ['modeling', 'surfacing', 'rigging'];
const allTaskTypes = [...standardTypes, ...customTaskTypes];
let html = `<p class="success">✅ Loaded ${assets.length} assets</p>`;
html += '<table><thead><tr>';
// Basic columns
if (visibleColumns.name) html += '<th>Name</th>';
if (visibleColumns.category) html += '<th>Category</th>';
if (visibleColumns.status) html += '<th>Status</th>';
// Task columns
allTaskTypes.forEach(type => {
if (visibleColumns[type]) {
const label = type.split('_').map(w => w.charAt(0).toUpperCase() + w.slice(1)).join(' ');
html += `<th>${label}</th>`;
}
});
if (visibleColumns.description) html += '<th>Description</th>';
html += '</tr></thead><tbody>';
// Asset rows
assets.slice(0, 10).forEach(asset => {
html += '<tr>';
if (visibleColumns.name) html += `<td>${asset.name}</td>`;
if (visibleColumns.category) html += `<td>${asset.category}</td>`;
if (visibleColumns.status) html += `<td>${asset.status}</td>`;
// Task status cells
allTaskTypes.forEach(type => {
if (visibleColumns[type]) {
const status = asset.task_status?.[type] || 'not_started';
html += `<td>${status}</td>`;
}
});
if (visibleColumns.description) html += `<td>${asset.description || '-'}</td>`;
html += '</tr>';
});
html += '</tbody></table>';
if (assets.length > 10) {
html += `<p class="info">Showing first 10 of ${assets.length} assets</p>`;
}
resultsDiv.innerHTML = html;
} else {
resultsDiv.innerHTML = '<p class="error">❌ Failed to load assets</p>';
}
} catch (error) {
resultsDiv.innerHTML = `<p class="error">❌ Error: ${error.message}</p>`;
}
}
</script>
</body>
</html>