386 lines
15 KiB
HTML
386 lines
15 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 Default Asset Task Creation</title>
|
|
<style>
|
|
body {
|
|
font-family: Arial, sans-serif;
|
|
max-width: 1200px;
|
|
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;
|
|
}
|
|
.task-list {
|
|
list-style: none;
|
|
padding: 0;
|
|
}
|
|
.task-item {
|
|
padding: 8px;
|
|
margin: 5px 0;
|
|
background: white;
|
|
border: 1px solid #ddd;
|
|
border-radius: 4px;
|
|
}
|
|
.checkbox-group {
|
|
margin: 10px 0;
|
|
}
|
|
.checkbox-group label {
|
|
display: block;
|
|
margin: 5px 0;
|
|
}
|
|
input[type="text"], select {
|
|
width: 100%;
|
|
padding: 8px;
|
|
margin: 5px 0;
|
|
border: 1px solid #ddd;
|
|
border-radius: 4px;
|
|
}
|
|
.form-group {
|
|
margin: 15px 0;
|
|
}
|
|
.form-group label {
|
|
display: block;
|
|
margin-bottom: 5px;
|
|
font-weight: bold;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="container">
|
|
<h1>🎬 Default Asset Task Creation Test</h1>
|
|
<p>This page tests the default asset task creation functionality (Task 5.3)</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: Get Default Tasks for Categories</h2>
|
|
<button onclick="testDefaultTasks()" id="test1-btn" disabled>Run Test</button>
|
|
<div id="test1-results"></div>
|
|
</div>
|
|
|
|
<div class="test-section">
|
|
<h2>Test 2: Create Asset with Default Tasks</h2>
|
|
<div class="form-group">
|
|
<label>Asset Name:</label>
|
|
<input type="text" id="asset-name" value="Test Hero Character" />
|
|
</div>
|
|
<div class="form-group">
|
|
<label>Category:</label>
|
|
<select id="asset-category">
|
|
<option value="characters">Characters</option>
|
|
<option value="props">Props</option>
|
|
<option value="sets">Sets</option>
|
|
<option value="vehicles">Vehicles</option>
|
|
</select>
|
|
</div>
|
|
<div class="form-group">
|
|
<label>
|
|
<input type="checkbox" id="create-default-tasks" checked />
|
|
Create default tasks
|
|
</label>
|
|
</div>
|
|
<div class="form-group" id="task-selection" style="display: none;">
|
|
<label>Select Tasks to Create:</label>
|
|
<div class="checkbox-group" id="task-checkboxes"></div>
|
|
</div>
|
|
<button onclick="createAssetWithTasks()" id="test2-btn" disabled>Create Asset</button>
|
|
<div id="test2-results"></div>
|
|
</div>
|
|
|
|
<div class="test-section">
|
|
<h2>Test 3: Verify Created Tasks</h2>
|
|
<button onclick="verifyTasks()" id="test3-btn" disabled>Verify Tasks</button>
|
|
<div id="test3-results"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
const API_BASE = 'http://localhost:8000';
|
|
let token = null;
|
|
let projectId = null;
|
|
let createdAssetId = null;
|
|
|
|
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;
|
|
} 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 testDefaultTasks() {
|
|
const resultsDiv = document.getElementById('test1-results');
|
|
resultsDiv.innerHTML = '<p>Testing default tasks for each category...</p>';
|
|
|
|
const categories = ['characters', 'props', 'sets', 'vehicles'];
|
|
const expectedTasks = {
|
|
'characters': ['modeling', 'surfacing', 'rigging'],
|
|
'props': ['modeling', 'surfacing'],
|
|
'sets': ['modeling', 'surfacing'],
|
|
'vehicles': ['modeling', 'surfacing', 'rigging']
|
|
};
|
|
|
|
let results = '';
|
|
|
|
for (const category of categories) {
|
|
try {
|
|
const response = await fetch(
|
|
`${API_BASE}/assets/default-tasks/${category}?project_id=${projectId}`,
|
|
{ headers: { 'Authorization': `Bearer ${token}` } }
|
|
);
|
|
|
|
if (response.ok) {
|
|
const tasks = await response.json();
|
|
const expected = expectedTasks[category];
|
|
const standardTasks = tasks.slice(0, expected.length);
|
|
const hasExpected = expected.every(t => standardTasks.includes(t));
|
|
|
|
if (hasExpected) {
|
|
results += `<p class="success">✅ ${category}: ${tasks.join(', ')}</p>`;
|
|
} else {
|
|
results += `<p class="error">❌ ${category}: Expected ${expected.join(', ')}, got ${tasks.join(', ')}</p>`;
|
|
}
|
|
} else {
|
|
results += `<p class="error">❌ ${category}: Failed to fetch</p>`;
|
|
}
|
|
} catch (error) {
|
|
results += `<p class="error">❌ ${category}: ${error.message}</p>`;
|
|
}
|
|
}
|
|
|
|
resultsDiv.innerHTML = results;
|
|
}
|
|
|
|
// Update task checkboxes when category changes
|
|
document.getElementById('asset-category').addEventListener('change', async (e) => {
|
|
if (!token || !projectId) return;
|
|
|
|
const category = e.target.value;
|
|
const response = await fetch(
|
|
`${API_BASE}/assets/default-tasks/${category}?project_id=${projectId}`,
|
|
{ headers: { 'Authorization': `Bearer ${token}` } }
|
|
);
|
|
|
|
if (response.ok) {
|
|
const tasks = await response.json();
|
|
const checkboxesDiv = document.getElementById('task-checkboxes');
|
|
checkboxesDiv.innerHTML = tasks.map(task => `
|
|
<label>
|
|
<input type="checkbox" value="${task}" checked />
|
|
${task.charAt(0).toUpperCase() + task.slice(1)}
|
|
</label>
|
|
`).join('');
|
|
}
|
|
});
|
|
|
|
// Show/hide task selection based on checkbox
|
|
document.getElementById('create-default-tasks').addEventListener('change', (e) => {
|
|
document.getElementById('task-selection').style.display = e.target.checked ? 'block' : 'none';
|
|
if (e.target.checked) {
|
|
// Trigger category change to load tasks
|
|
document.getElementById('asset-category').dispatchEvent(new Event('change'));
|
|
}
|
|
});
|
|
|
|
async function createAssetWithTasks() {
|
|
const resultsDiv = document.getElementById('test2-results');
|
|
resultsDiv.innerHTML = '<p>Creating asset...</p>';
|
|
|
|
const name = document.getElementById('asset-name').value + ' ' + Date.now();
|
|
const category = document.getElementById('asset-category').value;
|
|
const createDefaultTasks = document.getElementById('create-default-tasks').checked;
|
|
|
|
let selectedTaskTypes = null;
|
|
if (createDefaultTasks) {
|
|
const checkboxes = document.querySelectorAll('#task-checkboxes input[type="checkbox"]:checked');
|
|
selectedTaskTypes = Array.from(checkboxes).map(cb => cb.value);
|
|
}
|
|
|
|
const assetData = {
|
|
name: name,
|
|
category: category,
|
|
description: 'Test asset for default task creation',
|
|
status: 'not_started',
|
|
create_default_tasks: createDefaultTasks,
|
|
selected_task_types: selectedTaskTypes
|
|
};
|
|
|
|
try {
|
|
const response = await fetch(
|
|
`${API_BASE}/assets/?project_id=${projectId}`,
|
|
{
|
|
method: 'POST',
|
|
headers: {
|
|
'Authorization': `Bearer ${token}`,
|
|
'Content-Type': 'application/json'
|
|
},
|
|
body: JSON.stringify(assetData)
|
|
}
|
|
);
|
|
|
|
if (response.ok) {
|
|
const asset = await response.json();
|
|
createdAssetId = asset.id;
|
|
resultsDiv.innerHTML = `
|
|
<p class="success">✅ Asset created successfully!</p>
|
|
<p class="info">Asset ID: ${asset.id}</p>
|
|
<p class="info">Name: ${asset.name}</p>
|
|
<p class="info">Category: ${asset.category}</p>
|
|
<p class="info">Tasks created: ${asset.task_count}</p>
|
|
`;
|
|
document.getElementById('test3-btn').disabled = false;
|
|
} else {
|
|
const error = await response.json();
|
|
resultsDiv.innerHTML = `<p class="error">❌ Failed to create asset: ${error.detail}</p>`;
|
|
}
|
|
} catch (error) {
|
|
resultsDiv.innerHTML = `<p class="error">❌ Error: ${error.message}</p>`;
|
|
}
|
|
}
|
|
|
|
async function verifyTasks() {
|
|
const resultsDiv = document.getElementById('test3-results');
|
|
resultsDiv.innerHTML = '<p>Verifying tasks...</p>';
|
|
|
|
if (!createdAssetId) {
|
|
resultsDiv.innerHTML = '<p class="error">❌ No asset created yet</p>';
|
|
return;
|
|
}
|
|
|
|
try {
|
|
const response = await fetch(
|
|
`${API_BASE}/assets/${createdAssetId}/task-status`,
|
|
{ headers: { 'Authorization': `Bearer ${token}` } }
|
|
);
|
|
|
|
if (response.ok) {
|
|
const taskDetails = await response.json();
|
|
|
|
let results = `<p class="success">✅ Found ${taskDetails.length} tasks</p>`;
|
|
results += '<ul class="task-list">';
|
|
|
|
for (const taskInfo of taskDetails) {
|
|
// Get full task details
|
|
const taskResponse = await fetch(
|
|
`${API_BASE}/tasks/${taskInfo.task_id}`,
|
|
{ headers: { 'Authorization': `Bearer ${token}` } }
|
|
);
|
|
|
|
if (taskResponse.ok) {
|
|
const task = await taskResponse.json();
|
|
const isUnassigned = task.assigned_user_id === null;
|
|
results += `
|
|
<li class="task-item">
|
|
<strong>${task.name}</strong><br>
|
|
Type: ${task.task_type}<br>
|
|
Status: ${task.status}<br>
|
|
Assigned: ${isUnassigned ? '<span class="success">✅ Unassigned</span>' : '<span class="error">❌ Assigned</span>'}
|
|
</li>
|
|
`;
|
|
}
|
|
}
|
|
|
|
results += '</ul>';
|
|
resultsDiv.innerHTML = results;
|
|
} else {
|
|
resultsDiv.innerHTML = '<p class="error">❌ Failed to fetch tasks</p>';
|
|
}
|
|
} catch (error) {
|
|
resultsDiv.innerHTML = `<p class="error">❌ Error: ${error.message}</p>`;
|
|
}
|
|
}
|
|
|
|
// Initialize
|
|
document.getElementById('create-default-tasks').dispatchEvent(new Event('change'));
|
|
</script>
|
|
</body>
|
|
</html>
|