feat&fix: update paths in configuration, enhance error handling, and improve UI elements
This commit is contained in:
0
monitor/static/favicon.ico
Normal file
0
monitor/static/favicon.ico
Normal file
BIN
monitor/static/favicon.png
Normal file
BIN
monitor/static/favicon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 9.7 KiB |
@@ -56,6 +56,17 @@ h2 { color: #0056b3; margin-top: 32px; font-size: 1.6em; }
|
||||
margin-bottom: 10px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* Specific colors for different stat cards */
|
||||
.stat-card:nth-child(4) i { color: #007bff; } /* Total - Blue */
|
||||
.stat-card:nth-child(4):hover { background: linear-gradient(135deg, #f0f7ff, #e6f0fb); }
|
||||
.stat-card:nth-child(1) i { color: #17a2b8; } /* Active - Cyan */
|
||||
.stat-card:nth-child(1):hover { background: linear-gradient(135deg, #e3fafd, #d1f2f6); }
|
||||
.stat-card:nth-child(2) i { color: #28a745; } /* Completed - Green */
|
||||
.stat-card:nth-child(2):hover { background: linear-gradient(135deg, #e6f9ea, #d4f7db); }
|
||||
.stat-card:nth-child(3) i { color: #dc3545; } /* Error - Red */
|
||||
.stat-card:nth-child(3):hover { background: linear-gradient(135deg, #feeaec, #fcd8db); }
|
||||
|
||||
.stat-card span {
|
||||
font-size: 2em;
|
||||
font-weight: 600;
|
||||
@@ -162,11 +173,12 @@ h2 { color: #0056b3; margin-top: 32px; font-size: 1.6em; }
|
||||
padding: 20px;
|
||||
transition: all 0.4s cubic-bezier(.4,0,.2,1);
|
||||
opacity: 1;
|
||||
max-height: 2000px;
|
||||
max-height: none;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.task-type.collapsed .tasks-container {
|
||||
max-height: 0;
|
||||
max-height: 0 !important;
|
||||
opacity: 0;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
@@ -187,6 +199,9 @@ h2 { color: #0056b3; margin-top: 32px; font-size: 1.6em; }
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
}
|
||||
.task-card:last-child {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.task-card:hover { box-shadow: 0 10px 30px rgba(0,123,255,0.12); transform: translateY(-3px); }
|
||||
.task-header { display: flex; justify-content: space-between; margin-bottom: 14px; align-items: center; }
|
||||
.task-title { font-size: 1.2em; font-weight: 600; color: #1a237e; }
|
||||
@@ -196,6 +211,8 @@ h2 { color: #0056b3; margin-top: 32px; font-size: 1.6em; }
|
||||
.status-running { background: linear-gradient(135deg, #e3f2fd, #bbdefb); color: #0d47a1; }
|
||||
.status-completed { background: linear-gradient(135deg, #e8f5e9, #c8e6c9); color: #1b5e20; }
|
||||
.status-error { background: linear-gradient(135deg, #ffebee, #ffcdd2); color: #b71c1c; }
|
||||
.status-unknown { background: linear-gradient(135deg, #e0e0e0, #bdbdbd); color: #424242; }
|
||||
.status-done-max-steps { background: linear-gradient(135deg, #e8f5e9, #c8e6c9); color: #1b5e20; }
|
||||
.task-details { margin-top: 16px; }
|
||||
.progress-bar { height: 12px; background-color: #eef2f7; border-radius: 6px; margin-top: 10px; overflow: hidden; box-shadow: inset 0 1px 3px rgba(0,0,0,0.1); }
|
||||
.progress-fill { height: 100%; background: linear-gradient(90deg, #007bff, #00c6ff); width: 0%; transition: width 0.6s ease; }
|
||||
@@ -302,3 +319,22 @@ h2 { color: #0056b3; margin-top: 32px; font-size: 1.6em; }
|
||||
color: #0078d7;
|
||||
}
|
||||
|
||||
/* Custom scrollbar for tasks container */
|
||||
.tasks-container::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
}
|
||||
|
||||
.tasks-container::-webkit-scrollbar-track {
|
||||
background: #f1f5f9;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.tasks-container::-webkit-scrollbar-thumb {
|
||||
background: #c0d6e8;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.tasks-container::-webkit-scrollbar-thumb:hover {
|
||||
background: #a5c7e5;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
document.getElementById('total-tasks').parentElement.addEventListener('click', () => setTaskFilter('all'));
|
||||
document.getElementById('active-tasks').parentElement.addEventListener('click', () => setTaskFilter('active'));
|
||||
document.getElementById('completed-tasks').parentElement.addEventListener('click', () => setTaskFilter('completed'));
|
||||
document.getElementById('error-tasks').parentElement.addEventListener('click', () => setTaskFilter('error'));
|
||||
});
|
||||
|
||||
let allTaskData = null;
|
||||
@@ -49,6 +50,8 @@ function setTaskFilter(filter) {
|
||||
document.getElementById('active-tasks').parentElement.classList.add('selected');
|
||||
} else if (filter === 'completed') {
|
||||
document.getElementById('completed-tasks').parentElement.classList.add('selected');
|
||||
} else if (filter === 'error') {
|
||||
document.getElementById('error-tasks').parentElement.classList.add('selected');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,14 +60,17 @@ function updateStatistics(data) {
|
||||
let totalTasks = 0;
|
||||
let activeTasks = 0;
|
||||
let completedTasks = 0;
|
||||
let errorTasks = 0;
|
||||
|
||||
Object.entries(data).forEach(([taskType, tasks]) => {
|
||||
totalTasks += tasks.length;
|
||||
tasks.forEach(task => {
|
||||
if (task.status.status === 'Running' || task.status.status === 'Preparing' || task.status.status === 'Initializing') {
|
||||
activeTasks++;
|
||||
} else if (task.status.status === 'Done') {
|
||||
} else if (task.status.status === 'Done' || task.status.status === 'Done (Message Exit)' || task.status.status === 'Done (Max Steps)') {
|
||||
completedTasks++;
|
||||
} else if (task.status.status === 'Error') {
|
||||
errorTasks++;
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -72,6 +78,19 @@ function updateStatistics(data) {
|
||||
document.getElementById('total-tasks').textContent = totalTasks;
|
||||
document.getElementById('active-tasks').textContent = activeTasks;
|
||||
document.getElementById('completed-tasks').textContent = completedTasks;
|
||||
document.getElementById('error-tasks').textContent = errorTasks;
|
||||
|
||||
// 高亮显示当前选中的统计卡片
|
||||
document.querySelectorAll('.stat-card').forEach(card => card.classList.remove('selected'));
|
||||
if (currentFilter === 'all') {
|
||||
document.getElementById('total-tasks').parentElement.classList.add('selected');
|
||||
} else if (currentFilter === 'active') {
|
||||
document.getElementById('active-tasks').parentElement.classList.add('selected');
|
||||
} else if (currentFilter === 'completed') {
|
||||
document.getElementById('completed-tasks').parentElement.classList.add('selected');
|
||||
} else if (currentFilter === 'error') {
|
||||
document.getElementById('error-tasks').parentElement.classList.add('selected');
|
||||
}
|
||||
}
|
||||
|
||||
function renderTasks(data) {
|
||||
@@ -86,7 +105,9 @@ function renderTasks(data) {
|
||||
if (currentFilter === 'active') {
|
||||
filteredTasks = tasks.filter(task => ['Running', 'Preparing', 'Initializing'].includes(task.status.status));
|
||||
} else if (currentFilter === 'completed') {
|
||||
filteredTasks = tasks.filter(task => task.status.status === 'Done');
|
||||
filteredTasks = tasks.filter(task => task.status.status === 'Done' || task.status.status === 'Done (Message Exit)' || task.status.status === 'Done (Max Steps)');
|
||||
} else if (currentFilter === 'error') {
|
||||
filteredTasks = tasks.filter(task => task.status.status === 'Error');
|
||||
}
|
||||
if (filteredTasks.length > 0) {
|
||||
filteredData[taskType] = filteredTasks;
|
||||
@@ -107,7 +128,7 @@ function renderTasks(data) {
|
||||
tasks.forEach(task => {
|
||||
if (task.status.status === 'Running' || task.status.status === 'Preparing' || task.status.status === 'Initializing') {
|
||||
runningCount++;
|
||||
} else if (task.status.status === 'Done') {
|
||||
} else if (task.status.status === 'Done' || task.status.status === 'Done (Message Exit)' || task.status.status === 'Done (Max Steps)') {
|
||||
completedCount++;
|
||||
} else if (task.status.status === 'Error') {
|
||||
errorCount++;
|
||||
@@ -146,6 +167,12 @@ function renderTasks(data) {
|
||||
noTasks.innerHTML = '<i class="fas fa-info-circle"></i> No Tasks Available';
|
||||
tasksContainer.appendChild(noTasks);
|
||||
} else {
|
||||
// Add scrolling for large task lists
|
||||
if (tasks.length > 10) {
|
||||
tasksContainer.style.maxHeight = '600px';
|
||||
tasksContainer.style.overflowY = 'auto';
|
||||
}
|
||||
|
||||
tasks.forEach(task => {
|
||||
const taskCard = document.createElement('div');
|
||||
taskCard.className = 'task-card';
|
||||
@@ -178,6 +205,8 @@ function renderTasks(data) {
|
||||
statusIcon = 'fa-running';
|
||||
break;
|
||||
case 'Done':
|
||||
case 'Done (Message Exit)':
|
||||
case 'Done (Max Steps)':
|
||||
statusClass = 'status-completed';
|
||||
statusIcon = 'fa-check-circle';
|
||||
break;
|
||||
@@ -185,6 +214,10 @@ function renderTasks(data) {
|
||||
statusClass = 'status-error';
|
||||
statusIcon = 'fa-exclamation-circle';
|
||||
break;
|
||||
default:
|
||||
statusClass = 'status-unknown';
|
||||
statusIcon = 'fa-question-circle';
|
||||
break;
|
||||
}
|
||||
|
||||
taskStatus.classList.add(statusClass);
|
||||
@@ -202,7 +235,7 @@ function renderTasks(data) {
|
||||
|
||||
if (task.status.progress > 0) {
|
||||
const progressText = document.createElement('div');
|
||||
progressText.innerHTML = `<i class="fas fa-chart-line"></i> Progress: ${task.status.progress} step(s)`;
|
||||
progressText.innerHTML = `<i class="fas fa-chart-line"></i> Progress: ${task.status.progress}/${task.status.max_steps} step(s)`;
|
||||
taskProgress.appendChild(progressText);
|
||||
|
||||
const progressBar = document.createElement('div');
|
||||
|
||||
@@ -49,6 +49,11 @@ h2 { color: #0056b3; margin-top: 36px; font-size: 1.6em; font-weight: 600; }
|
||||
.step-card {
|
||||
border: none;
|
||||
background: #fafdff;
|
||||
box-shadow: 0 4px 15px rgba(0,0,0,0.08);
|
||||
margin-bottom: 25px;
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
transition: all 0.3s;
|
||||
padding: 22px 26px;
|
||||
margin-bottom: 24px;
|
||||
border-radius: 10px;
|
||||
@@ -57,19 +62,29 @@ h2 { color: #0056b3; margin-top: 36px; font-size: 1.6em; font-weight: 600; }
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
.step-intent {
|
||||
padding: 10px 20px;
|
||||
background: #f0f7ff;
|
||||
border-left: 4px solid #4285f4;
|
||||
margin: 10px 20px;
|
||||
font-size: 0.95em;
|
||||
line-height: 1.5;
|
||||
color: #333;
|
||||
}
|
||||
.exit-condition {
|
||||
background: #fff8e1;
|
||||
padding: 8px 12px;
|
||||
border-radius: 6px;
|
||||
font-family: 'Courier New', monospace;
|
||||
font-size: 0.9em;
|
||||
border-left: 3px solid #ffa000;
|
||||
}
|
||||
|
||||
.step-card:hover {
|
||||
box-shadow: 0 10px 30px rgba(0,123,255,0.1);
|
||||
transform: translateY(-3px);
|
||||
}
|
||||
.step-card:before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
height: 100%;
|
||||
width: 4px;
|
||||
background: linear-gradient(to bottom, #007bff, #00c6ff);
|
||||
}
|
||||
|
||||
.step-header { display: flex; justify-content: space-between; margin-bottom: 12px; align-items: center; }
|
||||
.step-title { font-weight: 600; color: #1a237e; font-size: 1.1em; }
|
||||
.step-time { color: #6c757d; font-size: 0.92em; }
|
||||
@@ -90,10 +105,7 @@ pre {
|
||||
box-shadow: 0 5px 15px rgba(0,0,0,0.08);
|
||||
transition: all 0.3s;
|
||||
}
|
||||
.step-image:hover {
|
||||
transform: scale(1.01);
|
||||
box-shadow: 0 8px 25px rgba(0,0,0,0.12);
|
||||
}
|
||||
|
||||
.no-steps {
|
||||
color: #8492a6;
|
||||
font-style: italic;
|
||||
@@ -154,5 +166,142 @@ pre {
|
||||
.status-not-started { background: linear-gradient(135deg, #f0f0f0, #e6e6e6); color: #555; }
|
||||
.status-preparing, .status-initializing { background: linear-gradient(135deg, #fff7e0, #ffe8a3); color: #8a6d00; }
|
||||
.status-running { background: linear-gradient(135deg, #e3f2fd, #bbdefb); color: #0d47a1; }
|
||||
.status-done { background: linear-gradient(135deg, #e8f5e9, #c8e6c9); color: #1b5e20; }
|
||||
.status-done, .status-done-message-exit, .status-done-max-steps { background: linear-gradient(135deg, #e8f5e9, #c8e6c9); color: #1b5e20; }
|
||||
.status-error { background: linear-gradient(135deg, #ffebee, #ffcdd2); color: #b71c1c; }
|
||||
|
||||
.step-intent {
|
||||
padding: 10px 20px;
|
||||
background: #f0f7ff;
|
||||
border-left: 4px solid #4285f4;
|
||||
margin: 10px 0;
|
||||
font-size: 0.95em;
|
||||
line-height: 1.5;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.exit-condition {
|
||||
background: #fff8e1;
|
||||
padding: 8px 12px;
|
||||
border-radius: 6px;
|
||||
font-family: 'Courier New', monospace;
|
||||
font-size: 0.9em;
|
||||
border-left: 3px solid #ffa000;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.exit-message {
|
||||
background: #e8f5e9;
|
||||
padding: 12px 16px;
|
||||
border-radius: 6px;
|
||||
font-family: 'Segoe UI', Arial, sans-serif;
|
||||
font-size: 1em;
|
||||
border-left: 3px solid #4caf50;
|
||||
position: relative;
|
||||
line-height: 1.5;
|
||||
color: #1b5e20;
|
||||
margin-top: 4px;
|
||||
box-shadow: 0 2px 5px rgba(0,0,0,0.05);
|
||||
}
|
||||
|
||||
.exit-condition-help {
|
||||
margin-top: 8px;
|
||||
font-family: 'Segoe UI', Arial, sans-serif;
|
||||
font-size: 0.85em;
|
||||
color: #666;
|
||||
background: #f5f5f5;
|
||||
padding: 6px 10px;
|
||||
border-radius: 4px;
|
||||
border-left: 2px solid #9e9e9e;
|
||||
}
|
||||
|
||||
/* 工具提示样式 */
|
||||
.tooltip {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
margin-left: 8px;
|
||||
cursor: help;
|
||||
}
|
||||
|
||||
.tooltip .tooltip-text {
|
||||
visibility: hidden;
|
||||
min-width: 200px;
|
||||
max-width: 500px;
|
||||
width: max-content;
|
||||
background-color: #333;
|
||||
color: #fff;
|
||||
text-align: left;
|
||||
border-radius: 6px;
|
||||
padding: 10px 12px;
|
||||
position: absolute;
|
||||
z-index: 10;
|
||||
bottom: 125%;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s;
|
||||
font-weight: normal;
|
||||
font-size: 0.85em;
|
||||
white-space: normal;
|
||||
word-wrap: break-word;
|
||||
line-height: 1.4;
|
||||
box-shadow: 0 2px 10px rgba(0,0,0,0.2);
|
||||
}
|
||||
|
||||
.tooltip .tooltip-text::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
left: 50%;
|
||||
margin-left: -5px;
|
||||
border-width: 5px;
|
||||
border-style: solid;
|
||||
border-color: #333 transparent transparent transparent;
|
||||
}
|
||||
|
||||
.tooltip:hover .tooltip-text {
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/* 移动设备上的工具提示调整 */
|
||||
@media (max-width: 768px) {
|
||||
.tooltip .tooltip-text {
|
||||
width: auto;
|
||||
max-width: 250px;
|
||||
left: auto;
|
||||
right: 0;
|
||||
transform: none;
|
||||
}
|
||||
|
||||
.tooltip .tooltip-text::after {
|
||||
left: auto;
|
||||
right: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
/* 进度条样式 */
|
||||
.progress-bar {
|
||||
height: 12px;
|
||||
background-color: #eef2f7;
|
||||
border-radius: 6px;
|
||||
margin: 10px 0;
|
||||
overflow: hidden;
|
||||
box-shadow: inset 0 1px 3px rgba(0,0,0,0.1);
|
||||
width: 100%;
|
||||
max-width: 300px;
|
||||
}
|
||||
|
||||
.progress-fill {
|
||||
height: 100%;
|
||||
background: linear-gradient(90deg, #007bff, #00c6ff);
|
||||
width: 0%;
|
||||
transition: width 0.6s ease;
|
||||
}
|
||||
|
||||
.progress-percentage {
|
||||
text-align: right;
|
||||
font-size: 0.85em;
|
||||
color: #6c757d;
|
||||
margin-top: 4px;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user