diff --git a/public/components.js b/public/components.js index cdbaef1..69f35b4 100644 --- a/public/components.js +++ b/public/components.js @@ -1056,8 +1056,27 @@ class NodeDetailsComponent extends Component { if (tasks && tasks.length > 0) { const summaryHTML = summary ? `
- Total: ${summary.totalTasks ?? tasks.length} - Active: ${summary.activeTasks ?? tasks.filter(t => t.running).length} +
+
📋
+
+
Tasks Overview
+
System task management and monitoring
+
+
+
+
+
${summary.totalTasks ?? tasks.length}
+
Total
+
+
+
${summary.activeTasks ?? tasks.filter(t => t.running).length}
+
Active
+
+
+
${(summary.totalTasks ?? tasks.length) - (summary.activeTasks ?? tasks.filter(t => t.running).length)}
+
Stopped
+
+
` : ''; const tasksHTML = tasks.map(task => ` @@ -1083,6 +1102,29 @@ class NodeDetailsComponent extends Component { const total = summary?.totalTasks ?? 0; const active = summary?.activeTasks ?? 0; return ` +
+
+
📋
+
+
Tasks Overview
+
${total > 0 ? `Total tasks: ${total}, active: ${active}` : 'This node has no running tasks'}
+
+
+
+
+
${total}
+
Total
+
+
+
${active}
+
Active
+
+
+
${total - active}
+
Stopped
+
+
+
📋 No active tasks found
diff --git a/public/styles.css b/public/styles.css index 38f0a32..081eb60 100644 --- a/public/styles.css +++ b/public/styles.css @@ -515,6 +515,198 @@ p { margin-bottom: 0.75rem; } +/* Modern Tasks Summary Styles */ +.tasks-summary { + background: linear-gradient(135deg, rgba(255, 255, 255, 0.08) 0%, rgba(255, 255, 255, 0.04) 100%); + border: 1px solid rgba(255, 255, 255, 0.15); + border-radius: 12px; + padding: 1rem 1.25rem; + margin-bottom: 1.5rem; + display: flex; + align-items: center; + justify-content: space-between; + backdrop-filter: blur(10px); + box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2); + transition: all 0.3s ease; + position: relative; + overflow: hidden; +} + +.tasks-summary::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + height: 1px; + background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent); +} + +.tasks-summary:hover { + background: linear-gradient(135deg, rgba(255, 255, 255, 0.12) 0%, rgba(255, 255, 255, 0.06) 100%); + border-color: rgba(255, 255, 255, 0.2); + box-shadow: 0 6px 20px rgba(0, 0, 0, 0.3); + transform: translateY(-1px); +} + +.tasks-summary-left { + display: flex; + align-items: center; + gap: 1.5rem; +} + +.tasks-summary-right { + display: flex; + align-items: center; + gap: 1rem; +} + +.summary-stat { + display: flex; + flex-direction: column; + align-items: center; + gap: 0.25rem; + padding: 0.75rem 1rem; + background: rgba(255, 255, 255, 0.05); + border-radius: 8px; + border: 1px solid rgba(255, 255, 255, 0.1); + transition: all 0.2s ease; + min-width: 80px; +} + +.summary-stat:hover { + background: rgba(255, 255, 255, 0.08); + border-color: rgba(255, 255, 255, 0.15); + transform: translateY(-1px); + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2); +} + +.summary-stat-value { + font-size: 1.5rem; + font-weight: 700; + color: #ecf0f1; + line-height: 1; +} + +.summary-stat-label { + font-size: 0.75rem; + color: rgba(255, 255, 255, 0.7); + font-weight: 500; + text-transform: uppercase; + letter-spacing: 0.5px; +} + +.summary-stat.total .summary-stat-value { + color: #4ade80; +} + +.summary-stat.active .summary-stat-value { + color: #4ade80; +} + +.summary-stat.stopped .summary-stat-value { + color: #f87171; +} + +.summary-stat.disabled .summary-stat-value { + color: #fbbf24; +} + +.summary-icon { + display: flex; + align-items: center; + justify-content: center; + width: 48px; + height: 48px; + background: linear-gradient(135deg, rgba(255, 255, 255, 0.1) 0%, rgba(255, 255, 255, 0.05) 100%); + border-radius: 12px; + border: 1px solid rgba(255, 255, 255, 0.15); + margin-right: 1rem; + font-size: 1.5rem; +} + +.summary-title { + font-size: 1.1rem; + font-weight: 600; + color: #ecf0f1; + margin-bottom: 0.25rem; +} + +.summary-subtitle { + font-size: 0.9rem; + color: rgba(255, 255, 255, 0.7); + font-weight: 400; +} + +/* Responsive design for tasks summary */ +@media (max-width: 768px) { + .tasks-summary { + flex-direction: column; + gap: 1rem; + padding: 1rem; + text-align: center; + } + + .tasks-summary-left { + flex-direction: column; + gap: 1rem; + align-items: center; + } + + .tasks-summary-right { + flex-direction: column; + gap: 0.75rem; + align-items: center; + } + + .summary-stat { + min-width: 70px; + padding: 0.5rem 0.75rem; + } + + .summary-stat-value { + font-size: 1.25rem; + } + + .summary-stat-label { + font-size: 0.7rem; + } + + .summary-icon { + width: 40px; + height: 40px; + font-size: 1.25rem; + margin-right: 0; + margin-bottom: 0.5rem; + } +} + +@media (max-width: 480px) { + .tasks-summary { + padding: 0.75rem; + gap: 0.75rem; + } + + .summary-stat { + min-width: 60px; + padding: 0.4rem 0.6rem; + } + + .summary-stat-value { + font-size: 1.1rem; + } + + .summary-stat-label { + font-size: 0.65rem; + } + + .summary-icon { + width: 36px; + height: 36px; + font-size: 1.1rem; + } +} + .task-header { display: flex; justify-content: space-between;