diff options
Diffstat (limited to 'weed/admin/view/app/maintenance_queue.templ')
| -rw-r--r-- | weed/admin/view/app/maintenance_queue.templ | 269 |
1 files changed, 201 insertions, 68 deletions
diff --git a/weed/admin/view/app/maintenance_queue.templ b/weed/admin/view/app/maintenance_queue.templ index 2c72c17ff..f16a72381 100644 --- a/weed/admin/view/app/maintenance_queue.templ +++ b/weed/admin/view/app/maintenance_queue.templ @@ -70,43 +70,118 @@ templ MaintenanceQueue(data *maintenance.MaintenanceQueueData) { </div> </div> - <!-- Simple task queue display --> - <div class="row"> + <!-- Pending Tasks --> + <div class="row mb-4"> <div class="col-12"> <div class="card"> - <div class="card-header"> - <h5 class="mb-0">Task Queue</h5> + <div class="card-header bg-primary text-white"> + <h5 class="mb-0"> + <i class="fas fa-clock me-2"></i> + Pending Tasks + </h5> </div> <div class="card-body"> - if len(data.Tasks) == 0 { + if data.Stats.PendingTasks == 0 { <div class="text-center text-muted py-4"> <i class="fas fa-clipboard-list fa-3x mb-3"></i> - <p>No maintenance tasks in queue</p> - <small>Tasks will appear here when the system detects maintenance needs</small> + <p>No pending maintenance tasks</p> + <small>Pending tasks will appear here when the system detects maintenance needs</small> </div> } else { <div class="table-responsive"> <table class="table table-hover"> <thead> <tr> - <th>ID</th> <th>Type</th> - <th>Status</th> + <th>Priority</th> <th>Volume</th> <th>Server</th> + <th>Reason</th> <th>Created</th> </tr> </thead> <tbody> for _, task := range data.Tasks { - <tr> - <td><code>{task.ID[:8]}...</code></td> - <td>{string(task.Type)}</td> - <td>{string(task.Status)}</td> - <td>{fmt.Sprintf("%d", task.VolumeID)}</td> - <td>{task.Server}</td> - <td>{task.CreatedAt.Format("2006-01-02 15:04")}</td> - </tr> + if string(task.Status) == "pending" { + <tr> + <td> + @TaskTypeIcon(task.Type) + {string(task.Type)} + </td> + <td>@PriorityBadge(task.Priority)</td> + <td>{fmt.Sprintf("%d", task.VolumeID)}</td> + <td><small>{task.Server}</small></td> + <td><small>{task.Reason}</small></td> + <td>{task.CreatedAt.Format("2006-01-02 15:04")}</td> + </tr> + } + } + </tbody> + </table> + </div> + } + </div> + </div> + </div> + </div> + + <!-- Active Tasks --> + <div class="row mb-4"> + <div class="col-12"> + <div class="card"> + <div class="card-header bg-warning text-dark"> + <h5 class="mb-0"> + <i class="fas fa-running me-2"></i> + Active Tasks + </h5> + </div> + <div class="card-body"> + if data.Stats.RunningTasks == 0 { + <div class="text-center text-muted py-4"> + <i class="fas fa-tasks fa-3x mb-3"></i> + <p>No active maintenance tasks</p> + <small>Active tasks will appear here when workers start processing them</small> + </div> + } else { + <div class="table-responsive"> + <table class="table table-hover"> + <thead> + <tr> + <th>Type</th> + <th>Status</th> + <th>Progress</th> + <th>Volume</th> + <th>Worker</th> + <th>Started</th> + </tr> + </thead> + <tbody> + for _, task := range data.Tasks { + if string(task.Status) == "assigned" || string(task.Status) == "in_progress" { + <tr> + <td> + @TaskTypeIcon(task.Type) + {string(task.Type)} + </td> + <td>@StatusBadge(task.Status)</td> + <td>@ProgressBar(task.Progress, task.Status)</td> + <td>{fmt.Sprintf("%d", task.VolumeID)}</td> + <td> + if task.WorkerID != "" { + <small>{task.WorkerID}</small> + } else { + <span class="text-muted">-</span> + } + </td> + <td> + if task.StartedAt != nil { + {task.StartedAt.Format("2006-01-02 15:04")} + } else { + <span class="text-muted">-</span> + } + </td> + </tr> + } } </tbody> </table> @@ -117,36 +192,104 @@ templ MaintenanceQueue(data *maintenance.MaintenanceQueueData) { </div> </div> - <!-- Workers Summary --> - <div class="row mt-4"> + <!-- Completed Tasks --> + <div class="row mb-4"> <div class="col-12"> <div class="card"> - <div class="card-header"> - <h5 class="mb-0">Active Workers</h5> + <div class="card-header bg-success text-white"> + <h5 class="mb-0"> + <i class="fas fa-check-circle me-2"></i> + Completed Tasks + </h5> </div> <div class="card-body"> - if len(data.Workers) == 0 { + if data.Stats.CompletedToday == 0 && data.Stats.FailedToday == 0 { <div class="text-center text-muted py-4"> - <i class="fas fa-robot fa-3x mb-3"></i> - <p>No workers are currently active</p> - <small>Start workers using: <code>weed worker -admin=localhost:9333</code></small> + <i class="fas fa-check-circle fa-3x mb-3"></i> + <p>No completed maintenance tasks today</p> + <small>Completed tasks will appear here after workers finish processing them</small> </div> } else { - <div class="row"> - for _, worker := range data.Workers { - <div class="col-md-4 mb-3"> - <div class="card"> - <div class="card-body"> - <h6 class="card-title">{worker.ID}</h6> - <p class="card-text"> - <small class="text-muted">{worker.Address}</small><br/> - Status: {worker.Status}<br/> - Load: {fmt.Sprintf("%d/%d", worker.CurrentLoad, worker.MaxConcurrent)} - </p> - </div> - </div> - </div> - } + <div class="table-responsive"> + <table class="table table-hover"> + <thead> + <tr> + <th>Type</th> + <th>Status</th> + <th>Volume</th> + <th>Worker</th> + <th>Duration</th> + <th>Completed</th> + </tr> + </thead> + <tbody> + for _, task := range data.Tasks { + if string(task.Status) == "completed" || string(task.Status) == "failed" || string(task.Status) == "cancelled" { + if string(task.Status) == "failed" { + <tr class="table-danger"> + <td> + @TaskTypeIcon(task.Type) + {string(task.Type)} + </td> + <td>@StatusBadge(task.Status)</td> + <td>{fmt.Sprintf("%d", task.VolumeID)}</td> + <td> + if task.WorkerID != "" { + <small>{task.WorkerID}</small> + } else { + <span class="text-muted">-</span> + } + </td> + <td> + if task.StartedAt != nil && task.CompletedAt != nil { + {formatDuration(task.CompletedAt.Sub(*task.StartedAt))} + } else { + <span class="text-muted">-</span> + } + </td> + <td> + if task.CompletedAt != nil { + {task.CompletedAt.Format("2006-01-02 15:04")} + } else { + <span class="text-muted">-</span> + } + </td> + </tr> + } else { + <tr> + <td> + @TaskTypeIcon(task.Type) + {string(task.Type)} + </td> + <td>@StatusBadge(task.Status)</td> + <td>{fmt.Sprintf("%d", task.VolumeID)}</td> + <td> + if task.WorkerID != "" { + <small>{task.WorkerID}</small> + } else { + <span class="text-muted">-</span> + } + </td> + <td> + if task.StartedAt != nil && task.CompletedAt != nil { + {formatDuration(task.CompletedAt.Sub(*task.StartedAt))} + } else { + <span class="text-muted">-</span> + } + </td> + <td> + if task.CompletedAt != nil { + {task.CompletedAt.Format("2006-01-02 15:04")} + } else { + <span class="text-muted">-</span> + } + </td> + </tr> + } + } + } + </tbody> + </table> </div> } </div> @@ -156,6 +299,9 @@ templ MaintenanceQueue(data *maintenance.MaintenanceQueueData) { </div> <script> + // Debug output to browser console + console.log("DEBUG: Maintenance Queue Template loaded"); + // Auto-refresh every 10 seconds setInterval(function() { if (!document.hidden) { @@ -163,7 +309,8 @@ templ MaintenanceQueue(data *maintenance.MaintenanceQueueData) { } }, 10000); - function triggerScan() { + window.triggerScan = function() { + console.log("triggerScan called"); fetch('/api/maintenance/scan', { method: 'POST', headers: { @@ -182,7 +329,12 @@ templ MaintenanceQueue(data *maintenance.MaintenanceQueueData) { .catch(error => { alert('Error: ' + error.message); }); - } + }; + + window.refreshPage = function() { + console.log("refreshPage called"); + window.location.reload(); + }; </script> } @@ -243,32 +395,13 @@ templ ProgressBar(progress float64, status maintenance.MaintenanceTaskStatus) { } } -templ WorkerStatusBadge(status string) { - switch status { - case "active": - <span class="badge bg-success">Active</span> - case "busy": - <span class="badge bg-warning">Busy</span> - case "inactive": - <span class="badge bg-secondary">Inactive</span> - default: - <span class="badge bg-light text-dark">Unknown</span> - } -} - -// Helper functions (would be defined in Go) - - -func getWorkerStatusColor(status string) string { - switch status { - case "active": - return "success" - case "busy": - return "warning" - case "inactive": - return "secondary" - default: - return "light" +func formatDuration(d time.Duration) string { + if d < time.Minute { + return fmt.Sprintf("%.0fs", d.Seconds()) + } else if d < time.Hour { + return fmt.Sprintf("%.1fm", d.Minutes()) + } else { + return fmt.Sprintf("%.1fh", d.Hours()) } } |
