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..f2453d6 100644 --- a/src/pobsync_backend/templates/pobsync_backend/base.html +++ b/src/pobsync_backend/templates/pobsync_backend/base.html @@ -241,6 +241,13 @@ .stack { display: grid; gap: 5px; } .stack.spaced { margin-bottom: 14px; } .two-col { display: grid; gap: 18px; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); } + .panel-grid { + display: grid; + gap: 18px; + grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); + margin-bottom: 18px; + } + .panel-grid .panel { margin-bottom: 0; } .actions { align-items: center; display: flex; @@ -303,6 +310,53 @@ display: grid; gap: 8px; } + .record-list { + display: grid; + gap: 10px; + } + .record-card { + border: 1px solid var(--border); + border-radius: var(--radius); + display: grid; + gap: 10px; + padding: 12px; + } + .record-card-header { + align-items: start; + display: flex; + gap: 12px; + justify-content: space-between; + } + .record-title { + display: grid; + gap: 3px; + min-width: 0; + } + .record-title a { + font-weight: 750; + overflow-wrap: anywhere; + } + .record-facts { + display: grid; + gap: 8px 16px; + grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); + } + .record-fact { + display: grid; + gap: 2px; + min-width: 0; + } + .record-fact .label { + color: var(--muted); + font-size: 11px; + font-weight: 700; + letter-spacing: 0.04em; + text-transform: uppercase; + } + .record-fact strong, + .record-fact span { + overflow-wrap: anywhere; + } .action-row, .activity-row, .schedule-row { @@ -370,6 +424,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; @@ -639,8 +730,10 @@ display: grid; } .page-header .actions { justify-content: flex-start; } - .two-col { grid-template-columns: 1fr; } + .two-col, + .panel-grid { 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..316fde3 100644 --- a/src/pobsync_backend/templates/pobsync_backend/host_detail.html +++ b/src/pobsync_backend/templates/pobsync_backend/host_detail.html @@ -9,70 +9,8 @@
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 %} -| Status | -Check | -Message | -Detail | -
|---|---|---|---|
| {{ check.status }} | -{{ check.name }} | -{{ check.message }} | -{{ check.detail }} | -
| Status | -Check | -Message | -Detail | -
|---|---|---|---|
| {% if check.ok %}ok{% else %}failed{% endif %} | -{{ check.name }} | -{{ check.message }} | -{{ check.detail }} | -
Runtime settings after global defaults and host overrides are combined.
+{{ effective_config.includes|join:"
" }}
+ {% else %}
+ {{ 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 %} - -Use this when the quick actions above need a custom label, include/exclude override, or prune limit.
| Status | -Started | -Ended | -Snapshot | -Base | -
|---|---|---|---|---|
| {{ run.status }} | -{{ run.started_at|default:"" }} | -{{ run.ended_at|default:"" }} | -{% if run.snapshot %}{{ run.snapshot.dirname }}{% else %}{{ run.snapshot_path }}{% endif %} | -{{ run.base_path|default:"" }} | -
| No backup runs recorded for this host. | ||||
No backup runs recorded for this host.
+ {% endfor %} +| Kind | -Status | -Started | -Dirname | -Base | -
|---|---|---|---|---|
| {{ snapshot.kind }} | -{{ snapshot.status }} | -{{ snapshot.started_at|default:"" }} | -{{ snapshot.dirname }} | -{% if snapshot.base %}{{ snapshot.base.dirname }}{% else %}{{ snapshot.base_dirname }}{% endif %} | -
| No snapshots discovered for this host. | ||||
No snapshots discovered for this host.
+ {% endfor %} +