Host Status
+{{ effective_config.excludes|join:"
" }}
- {% else %}
- diff --git a/src/pobsync_backend/templates/pobsync_backend/base.html b/src/pobsync_backend/templates/pobsync_backend/base.html
index beef593..31b3ecd 100644
--- a/src/pobsync_backend/templates/pobsync_backend/base.html
+++ b/src/pobsync_backend/templates/pobsync_backend/base.html
@@ -370,6 +370,43 @@
gap: 10px;
justify-content: space-between;
padding-top: 8px;
+ }
+ .host-control-grid {
+ display: grid;
+ gap: 14px;
+ grid-template-columns: minmax(280px, 1.25fr) repeat(3, minmax(220px, 1fr));
+ margin-bottom: 20px;
+ }
+ .host-control-panel {
+ display: grid;
+ gap: 12px;
+ margin-bottom: 0;
+ }
+ .host-control-panel > h2:first-child { margin-bottom: 0; }
+ .host-control-primary {
+ display: grid;
+ gap: 8px;
+ }
+ .host-control-meta {
+ display: grid;
+ gap: 6px;
+ }
+ .host-control-meta > div {
+ align-items: baseline;
+ border-top: 1px solid var(--border);
+ display: flex;
+ gap: 10px;
+ justify-content: space-between;
+ padding-top: 7px;
+ }
+ .host-control-meta .label {
+ color: var(--muted);
+ font-size: 12px;
+ font-weight: 650;
+ text-transform: uppercase;
+ }
+ .host-control-meta strong {
+ text-align: right;
}
.status-summary {
align-items: center;
@@ -641,6 +678,7 @@
.page-header .actions { justify-content: flex-start; }
.two-col { grid-template-columns: 1fr; }
.dashboard-priority-grid { grid-template-columns: 1fr; }
+ .host-control-grid { grid-template-columns: 1fr; }
.schedule-row { grid-template-columns: 1fr; }
.schedule-time { justify-items: start; text-align: left; }
.host-card-header { display: grid; }
diff --git a/src/pobsync_backend/templates/pobsync_backend/host_detail.html b/src/pobsync_backend/templates/pobsync_backend/host_detail.html
index 60bbae8..899762b 100644
--- a/src/pobsync_backend/templates/pobsync_backend/host_detail.html
+++ b/src/pobsync_backend/templates/pobsync_backend/host_detail.html
@@ -32,47 +32,6 @@
-
No schedule configured.
- {% endif %} -{{ effective_config.includes|join:"
" }}
+ {{ effective_config.excludes|join:"
" }}
- {% else %}
- Wait for the active run to finish, or cancel it from the run detail page.
+ {% elif not can_queue_dry_run or not can_queue_real_backup %} + {% if not has_global_config %} +Create the default global config before queueing backups.
+ {% elif not host.enabled %} +Enable this host before queueing backups.
+ {% elif backup_gate.real_blockers %} +Real backups are blocked by failed preflight checks. Dry-runs may still be available when storage-only checks fail.
+ {% endif %} + {% endif %} +Evaluated by the pobsync scheduler service.
+ {% else %} +No schedule configured.
+ Add schedule + {% endif %} +No backup runs recorded for this host.
+ {% endif %} + {% if stats_summary.latest_run.duration_seconds is not None %} + {% endif %} -Wait for the active run to finish, or cancel it from the run detail page.
- {% elif not can_queue_dry_run or not can_queue_real_backup %} - {% if not has_global_config %} -Create the default global config before queueing backups.
- {% elif not host.enabled %} -Enable this host before queueing backups.
- {% elif backup_gate.real_blockers %} -Real backups are blocked by failed preflight checks. Dry-runs may still be available when storage-only checks fail.
- {% endif %} - {% endif %} +{{ effective_config.includes|join:"
" }}
+ {% else %}
+ {{ effective_config.excludes|join:"
" }}
+ {% else %}
+ Use this when the quick actions above need a custom label, include/exclude override, or prune limit.