341 lines
13 KiB
HTML
341 lines
13 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>Custom Task Types Test</title>
|
||
<style>
|
||
body {
|
||
font-family: Arial, sans-serif;
|
||
max-width: 1200px;
|
||
margin: 0 auto;
|
||
padding: 20px;
|
||
background-color: #f5f5f5;
|
||
}
|
||
.container {
|
||
background: white;
|
||
padding: 30px;
|
||
border-radius: 8px;
|
||
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||
}
|
||
h1 {
|
||
color: #333;
|
||
margin-bottom: 10px;
|
||
}
|
||
.description {
|
||
color: #666;
|
||
margin-bottom: 30px;
|
||
}
|
||
.section {
|
||
margin-bottom: 40px;
|
||
}
|
||
.section-header {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
margin-bottom: 15px;
|
||
}
|
||
.section-title {
|
||
font-size: 18px;
|
||
font-weight: 600;
|
||
color: #333;
|
||
}
|
||
.task-list {
|
||
border: 1px solid #e0e0e0;
|
||
border-radius: 6px;
|
||
overflow: hidden;
|
||
}
|
||
.task-item {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
padding: 12px 16px;
|
||
border-bottom: 1px solid #e0e0e0;
|
||
transition: background-color 0.2s;
|
||
}
|
||
.task-item:last-child {
|
||
border-bottom: none;
|
||
}
|
||
.task-item:hover {
|
||
background-color: #f9f9f9;
|
||
}
|
||
.task-info {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 12px;
|
||
}
|
||
.task-name {
|
||
font-weight: 500;
|
||
text-transform: capitalize;
|
||
}
|
||
.badge {
|
||
padding: 4px 8px;
|
||
border-radius: 4px;
|
||
font-size: 12px;
|
||
font-weight: 500;
|
||
}
|
||
.badge-standard {
|
||
background-color: #e3f2fd;
|
||
color: #1976d2;
|
||
}
|
||
.badge-custom {
|
||
background-color: #f3e5f5;
|
||
color: #7b1fa2;
|
||
}
|
||
.task-actions {
|
||
display: flex;
|
||
gap: 8px;
|
||
}
|
||
button {
|
||
padding: 8px 16px;
|
||
border: none;
|
||
border-radius: 4px;
|
||
cursor: pointer;
|
||
font-size: 14px;
|
||
transition: all 0.2s;
|
||
}
|
||
.btn-primary {
|
||
background-color: #1976d2;
|
||
color: white;
|
||
}
|
||
.btn-primary:hover {
|
||
background-color: #1565c0;
|
||
}
|
||
.btn-icon {
|
||
background-color: transparent;
|
||
color: #666;
|
||
padding: 6px;
|
||
width: 32px;
|
||
height: 32px;
|
||
}
|
||
.btn-icon:hover {
|
||
background-color: #f0f0f0;
|
||
}
|
||
.btn-delete {
|
||
color: #d32f2f;
|
||
}
|
||
.btn-delete:hover {
|
||
background-color: #ffebee;
|
||
}
|
||
.info-box {
|
||
background-color: #e3f2fd;
|
||
border-left: 4px solid #1976d2;
|
||
padding: 16px;
|
||
border-radius: 4px;
|
||
margin-top: 30px;
|
||
}
|
||
.info-box h3 {
|
||
margin: 0 0 8px 0;
|
||
color: #1976d2;
|
||
font-size: 16px;
|
||
}
|
||
.info-box p {
|
||
margin: 0;
|
||
color: #555;
|
||
line-height: 1.6;
|
||
}
|
||
.empty-state {
|
||
text-align: center;
|
||
padding: 40px;
|
||
color: #999;
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div class="container">
|
||
<h1>Custom Task Types Manager</h1>
|
||
<p class="description">
|
||
Add custom task types beyond the standard types to adapt the pipeline to your project needs
|
||
</p>
|
||
|
||
<!-- Asset Task Types Section -->
|
||
<div class="section">
|
||
<div class="section-header">
|
||
<div class="section-title">📦 Asset Task Types</div>
|
||
<button class="btn-primary">+ Add Task Type</button>
|
||
</div>
|
||
<div class="task-list">
|
||
<div class="task-item">
|
||
<div class="task-info">
|
||
<span class="task-name">Modeling</span>
|
||
<span class="badge badge-standard">Standard</span>
|
||
</div>
|
||
</div>
|
||
<div class="task-item">
|
||
<div class="task-info">
|
||
<span class="task-name">Surfacing</span>
|
||
<span class="badge badge-standard">Standard</span>
|
||
</div>
|
||
</div>
|
||
<div class="task-item">
|
||
<div class="task-info">
|
||
<span class="task-name">Rigging</span>
|
||
<span class="badge badge-standard">Standard</span>
|
||
</div>
|
||
</div>
|
||
<div class="task-item">
|
||
<div class="task-info">
|
||
<span class="task-name">Grooming</span>
|
||
<span class="badge badge-custom">Custom</span>
|
||
</div>
|
||
<div class="task-actions">
|
||
<button class="btn-icon" title="Edit">✏️</button>
|
||
<button class="btn-icon btn-delete" title="Delete">🗑️</button>
|
||
</div>
|
||
</div>
|
||
<div class="task-item">
|
||
<div class="task-info">
|
||
<span class="task-name">Look Dev</span>
|
||
<span class="badge badge-custom">Custom</span>
|
||
</div>
|
||
<div class="task-actions">
|
||
<button class="btn-icon" title="Edit">✏️</button>
|
||
<button class="btn-icon btn-delete" title="Delete">🗑️</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<hr style="border: none; border-top: 1px solid #e0e0e0; margin: 40px 0;">
|
||
|
||
<!-- Shot Task Types Section -->
|
||
<div class="section">
|
||
<div class="section-header">
|
||
<div class="section-title">🎬 Shot Task Types</div>
|
||
<button class="btn-primary">+ Add Task Type</button>
|
||
</div>
|
||
<div class="task-list">
|
||
<div class="task-item">
|
||
<div class="task-info">
|
||
<span class="task-name">Layout</span>
|
||
<span class="badge badge-standard">Standard</span>
|
||
</div>
|
||
</div>
|
||
<div class="task-item">
|
||
<div class="task-info">
|
||
<span class="task-name">Animation</span>
|
||
<span class="badge badge-standard">Standard</span>
|
||
</div>
|
||
</div>
|
||
<div class="task-item">
|
||
<div class="task-info">
|
||
<span class="task-name">Simulation</span>
|
||
<span class="badge badge-standard">Standard</span>
|
||
</div>
|
||
</div>
|
||
<div class="task-item">
|
||
<div class="task-info">
|
||
<span class="task-name">Lighting</span>
|
||
<span class="badge badge-standard">Standard</span>
|
||
</div>
|
||
</div>
|
||
<div class="task-item">
|
||
<div class="task-info">
|
||
<span class="task-name">Compositing</span>
|
||
<span class="badge badge-standard">Standard</span>
|
||
</div>
|
||
</div>
|
||
<div class="task-item">
|
||
<div class="task-info">
|
||
<span class="task-name">Previz</span>
|
||
<span class="badge badge-custom">Custom</span>
|
||
</div>
|
||
<div class="task-actions">
|
||
<button class="btn-icon" title="Edit">✏️</button>
|
||
<button class="btn-icon btn-delete" title="Delete">🗑️</button>
|
||
</div>
|
||
</div>
|
||
<div class="task-item">
|
||
<div class="task-info">
|
||
<span class="task-name">Matchmove</span>
|
||
<span class="badge badge-custom">Custom</span>
|
||
</div>
|
||
<div class="task-actions">
|
||
<button class="btn-icon" title="Edit">✏️</button>
|
||
<button class="btn-icon btn-delete" title="Delete">🗑️</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Info Box -->
|
||
<div class="info-box">
|
||
<h3>ℹ️ About Custom Task Types</h3>
|
||
<p>
|
||
<strong>Standard task types</strong> are built-in and cannot be edited or deleted.
|
||
<strong>Custom task types</strong> can be added, renamed, or removed to match your project's specific workflow.
|
||
Custom task types will appear in the task template editor and can be enabled for specific asset categories or shots.
|
||
</p>
|
||
</div>
|
||
</div>
|
||
|
||
<script>
|
||
// Add some interactivity for demonstration
|
||
document.querySelectorAll('.btn-icon').forEach(button => {
|
||
button.addEventListener('click', function(e) {
|
||
const action = this.title;
|
||
const taskItem = this.closest('.task-item');
|
||
const taskName = taskItem.querySelector('.task-name').textContent;
|
||
|
||
if (action === 'Delete') {
|
||
if (confirm(`Are you sure you want to delete the task type "${taskName}"?`)) {
|
||
taskItem.style.opacity = '0';
|
||
setTimeout(() => taskItem.remove(), 300);
|
||
}
|
||
} else if (action === 'Edit') {
|
||
const newName = prompt(`Enter new name for "${taskName}":`, taskName.toLowerCase().replace(/ /g, '_'));
|
||
if (newName) {
|
||
taskItem.querySelector('.task-name').textContent = newName.replace(/_/g, ' ');
|
||
}
|
||
}
|
||
});
|
||
});
|
||
|
||
document.querySelectorAll('.btn-primary').forEach(button => {
|
||
button.addEventListener('click', function() {
|
||
const section = this.closest('.section');
|
||
const sectionTitle = section.querySelector('.section-title').textContent;
|
||
const taskName = prompt(`Enter name for new ${sectionTitle} task type:\n(Use lowercase letters, numbers, and underscores only)`);
|
||
|
||
if (taskName && /^[a-z0-9_]{3,50}$/.test(taskName)) {
|
||
const taskList = section.querySelector('.task-list');
|
||
const newItem = document.createElement('div');
|
||
newItem.className = 'task-item';
|
||
newItem.innerHTML = `
|
||
<div class="task-info">
|
||
<span class="task-name">${taskName.replace(/_/g, ' ')}</span>
|
||
<span class="badge badge-custom">Custom</span>
|
||
</div>
|
||
<div class="task-actions">
|
||
<button class="btn-icon" title="Edit">✏️</button>
|
||
<button class="btn-icon btn-delete" title="Delete">🗑️</button>
|
||
</div>
|
||
`;
|
||
taskList.appendChild(newItem);
|
||
|
||
// Re-attach event listeners
|
||
newItem.querySelectorAll('.btn-icon').forEach(btn => {
|
||
btn.addEventListener('click', function() {
|
||
const action = this.title;
|
||
if (action === 'Delete') {
|
||
if (confirm(`Are you sure you want to delete "${taskName}"?`)) {
|
||
newItem.style.opacity = '0';
|
||
setTimeout(() => newItem.remove(), 300);
|
||
}
|
||
} else if (action === 'Edit') {
|
||
const updatedName = prompt(`Enter new name for "${taskName}":`, taskName);
|
||
if (updatedName) {
|
||
newItem.querySelector('.task-name').textContent = updatedName.replace(/_/g, ' ');
|
||
}
|
||
}
|
||
});
|
||
});
|
||
} else if (taskName) {
|
||
alert('Invalid task type name. Use 3-50 characters, lowercase alphanumeric with underscores only.');
|
||
}
|
||
});
|
||
});
|
||
</script>
|
||
</body>
|
||
</html>
|