Ansible schedule form: structured playbook-variable fields + first-item dropdown defaults #2

Merged
bvandeusen merged 126 commits from dev into main 2026-06-30 23:44:04 -04:00
19 changed files with 16 additions and 29 deletions
Showing only changes of commit 88091936c5 - Show all commits
@@ -1,12 +1,10 @@
{# docker/container_detail.html — full detail page for one container #}
{% extends "base.html" %}
{% from "_macros.html" import crumbs %}
{% block title %}{{ name }} — Docker — Steward{% endblock %}
{% block breadcrumb %}{{ crumbs([("Docker", "/plugins/docker/"), (name, "")]) }}{% endblock %}
{% block content %}
<div style="margin-bottom:1rem;">
<a href="/plugins/docker/" style="font-size:0.82rem;color:var(--text-muted);text-decoration:none;">← All containers</a>
</div>
{% if container is none %}
<div class="card" style="text-align:center;padding:3rem;">
<div style="font-weight:600;margin-bottom:0.4rem;">Container not found</div>
+2 -3
View File
@@ -1,11 +1,10 @@
{# docker/disk.html — image/disk usage: reclaimable space, per-image sizes #}
{% extends "base.html" %}
{% from "_macros.html" import crumbs %}
{% block title %}Disk — Docker — Steward{% endblock %}
{% block breadcrumb %}{{ crumbs([("Docker", "/plugins/docker/"), ("Image & disk usage", "")]) }}{% endblock %}
{% block content %}
<div style="margin-bottom:1rem;">
<a href="/plugins/docker/" style="font-size:0.82rem;color:var(--text-muted);text-decoration:none;">← All containers</a>
</div>
<h1 class="page-title" style="margin-bottom:0.4rem;">Image &amp; disk usage</h1>
<p style="font-size:0.82rem;color:var(--text-muted);margin-bottom:1.5rem;">
Reclaimable = space held by images no container references. Cleanup actions
+2 -3
View File
@@ -1,11 +1,10 @@
{# docker/swarm.html — Swarm topology: services, replica health, nodes, placement #}
{% extends "base.html" %}
{% from "_macros.html" import crumbs %}
{% block title %}Swarm — Docker — Steward{% endblock %}
{% block breadcrumb %}{{ crumbs([("Docker", "/plugins/docker/"), ("Swarm", "")]) }}{% endblock %}
{% block content %}
<div style="margin-bottom:1rem;">
<a href="/plugins/docker/" style="font-size:0.82rem;color:var(--text-muted);text-decoration:none;">← All containers</a>
</div>
<h1 class="page-title" style="margin-bottom:1.5rem;">Swarm</h1>
{% if host_groups %}
@@ -27,7 +27,6 @@
{% block content %}
<div style="display:flex;align-items:center;justify-content:space-between;gap:1rem;flex-wrap:wrap;margin-bottom:0.75rem;">
<div style="display:flex;align-items:center;gap:0.6rem;">
<a href="/hosts/{{ host.id }}" class="btn btn-ghost btn-sm">← Host</a>
<h1 class="page-title" style="margin-bottom:0;">{{ host.name }}</h1>
{% if stale %}<span class="badge badge-red">stale</span>{% else %}<span class="badge badge-green">live</span>{% endif %}
</div>
@@ -5,7 +5,6 @@
{% block content %}
<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:1rem;gap:1rem;flex-wrap:wrap;">
<h1 class="page-title" style="margin-bottom:0;">Agent fleet</h1>
<a href="/hosts/" class="btn btn-ghost btn-sm">← Hosts</a>
</div>
<p style="color:var(--text-muted);font-size:0.84rem;margin:-0.4rem 0 1.25rem;">
Bulk agent operations across your inventory. For a single host, use its
+2 -1
View File
@@ -1,9 +1,10 @@
{# plugins/snmp/templates/snmp/device.html #}
{% extends "base.html" %}
{% from "_macros.html" import crumbs %}
{% block title %}SNMP — {{ device_name }} — Steward{% endblock %}
{% block breadcrumb %}{{ crumbs([("SNMP", "/plugins/snmp/"), (device_name, "")]) }}{% endblock %}
{% block content %}
<div style="display:flex;align-items:center;gap:1rem;margin-bottom:1.5rem;flex-wrap:wrap;">
<a href="/plugins/snmp/" style="color:var(--text-muted);font-size:0.85rem;">&#8592; SNMP</a>
<h1 class="page-title" style="margin:0;">{{ device_name }}</h1>
<span style="font-size:0.8rem;color:var(--text-dim);">{{ device.host }}</span>
<div style="margin-left:auto;display:flex;gap:0.5rem;">
@@ -6,7 +6,6 @@
<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:1.5rem;">
<h1 class="page-title" style="margin-bottom:0;">Maintenance Windows</h1>
<div style="display:flex;gap:0.5rem;">
<a class="btn btn-ghost" href="/alerts/">← Alerts</a>
<a class="btn" href="/alerts/maintenance/new">New Window</a>
</div>
</div>
-2
View File
@@ -17,7 +17,6 @@
{% endif %}
<a href="/ansible/inventory/targets" class="btn btn-ghost btn-sm">Inventory</a>
<a href="/ansible/schedules" class="btn btn-ghost btn-sm">Schedules</a>
<a href="/ansible/" class="btn btn-ghost btn-sm">← Run History</a>
</div>
</div>
@@ -35,7 +34,6 @@
<button type="submit" class="btn btn-sm btn-danger">Delete</button>
</form>
{% endif %}
<a href="/ansible/browse" class="btn btn-ghost btn-sm">← Back to browse</a>
</div>
</div>
<pre style="background:var(--bg);padding:1rem;border-radius:4px;overflow-x:auto;font-size:0.8rem;color:var(--text-muted);max-height:600px;overflow-y:auto;">{{ view_contents }}</pre>
@@ -5,7 +5,6 @@
{% block content %}
<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:1.5rem;">
<h1 class="page-title" style="margin-bottom:0;">Group: {{ group.name }}</h1>
<a href="/ansible/inventory/groups" class="btn btn-ghost btn-sm">← Groups</a>
</div>
<form method="post" action="/ansible/inventory/groups/{{ group.id }}">
@@ -7,7 +7,6 @@
<h1 class="page-title" style="margin-bottom:0;">Inventory Groups</h1>
<div style="display:flex;gap:0.5rem;">
<a href="/ansible/inventory/targets" class="btn btn-ghost btn-sm">Targets</a>
<a href="/ansible/" class="btn btn-ghost btn-sm">← Ansible</a>
</div>
</div>
@@ -5,7 +5,6 @@
{% block content %}
<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:1.5rem;">
<h1 class="page-title" style="margin-bottom:0;">Target: {{ target.name }}</h1>
<a href="/ansible/inventory/targets" class="btn btn-ghost btn-sm">← Targets</a>
</div>
<form method="post" action="/ansible/inventory/targets/{{ target.id }}">
@@ -7,7 +7,6 @@
<h1 class="page-title" style="margin-bottom:0;">Inventory Targets</h1>
<div style="display:flex;gap:0.5rem;">
<a href="/ansible/inventory/groups" class="btn btn-ghost btn-sm">Groups</a>
<a href="/ansible/" class="btn btn-ghost btn-sm">← Ansible</a>
</div>
</div>
@@ -5,7 +5,6 @@
{% block content %}
<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:1.25rem;gap:1rem;flex-wrap:wrap;">
<h1 class="page-title" style="margin-bottom:0;">{{ "Edit playbook" if editing else "New playbook" }}</h1>
<a href="/ansible/browse" class="btn btn-ghost btn-sm">← Browse</a>
</div>
{% if error %}<div class="alert alert-error">{{ error }}</div>{% endif %}
@@ -4,7 +4,6 @@
{% block breadcrumb %}{{ crumbs([("Ansible", "/ansible/"), ("Run " ~ run.id[:8], "")]) }}{% endblock %}
{% block content %}
<div style="display:flex;align-items:center;gap:1rem;margin-bottom:1.5rem;">
<a href="/ansible/" class="btn btn-ghost btn-sm">← Runs</a>
<h1 class="page-title" style="margin-bottom:0;">Run Detail</h1>
<div style="margin-left:auto;display:flex;gap:0.5rem;">
{% if run.status.value in ("running", "queued") and session.user_role in ("operator", "admin") %}
-1
View File
@@ -14,7 +14,6 @@
<div style="display:flex;gap:0.5rem;">
<a href="/ansible/inventory/targets" class="btn btn-ghost">Inventory</a>
<a href="/ansible/browse" class="btn btn-ghost">Browse</a>
<a href="/ansible/" class="btn btn-ghost">← Runs</a>
</div>
</div>
+2 -1
View File
@@ -1,9 +1,10 @@
{% extends "base.html" %}
{% from "_macros.html" import crumbs %}
{% block title %}Uptime / SLA — Steward{% endblock %}
{% block breadcrumb %}{{ crumbs([("Hosts", "/hosts/"), ("Uptime / SLA", "")]) }}{% endblock %}
{% block content %}
<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:1.5rem;">
<h1 class="page-title" style="margin-bottom:0;">Uptime / SLA</h1>
<a class="btn btn-ghost" href="/hosts/">← Hosts</a>
</div>
{# ── Summary pills ──────────────────────────────────────────────────────────── #}
+3 -2
View File
@@ -1,10 +1,11 @@
{% extends "base.html" %}
{% from "_macros.html" import crumbs %}
{% from "monitors/_fields.html" import type_fields, toggle_script %}
{% block title %}Edit Monitor — Steward{% endblock %}
{% block breadcrumb %}{{ crumbs([("Monitors", "/monitors/"), ("Edit monitor", "")]) }}{% endblock %}
{% block content %}
<div style="margin-bottom:1.25rem;">
<a href="/monitors/" style="color:var(--text-muted);font-size:0.85rem;"> Monitors</a>
<h1 class="page-title" style="margin:0.4rem 0 0;">Edit Monitor</h1>
<h1 class="page-title" style="margin-bottom:0;">Edit Monitor</h1>
</div>
{% set inp = "width:100%;padding:0.4rem 0.65rem;background:var(--bg);border:1px solid var(--border-mid);border-radius:4px;color:var(--text);font-size:0.88rem;" %}
+3 -2
View File
@@ -1,5 +1,6 @@
{# settings/_tabs.html — include at top of each settings section #}
<h1 class="page-title">Settings</h1>
{# settings/_tabs.html — include at top of each settings section.
No section <h1>: the breadcrumb kicker ("Settings …") names the section and
the tab strip is the visual header, so we don't stack a redundant title. #}
<div style="display:flex;gap:0;border-bottom:1px solid var(--border-mid);margin-bottom:1.5rem;">
{% set tabs = [
("general", "General", "/settings/general/"),
@@ -8,7 +8,6 @@
{% include "settings/_tabs.html" %}
<div style="display:flex;align-items:center;gap:1rem;margin-bottom:1.5rem;">
<a href="/settings/plugins/" class="btn btn-ghost btn-sm">← Plugins</a>
<h1 class="page-title" style="margin-bottom:0;">{{ plugin.get('name', plugin._dir) }}</h1>
<span style="color:var(--text-muted);font-size:0.82rem;">v{{ plugin.get('version', '?') }}</span>
{% if fail_reason %}