feat: Ansible source manager UI — replace raw JSON textarea

- Replace the raw JSON textarea in Settings → Ansible with a proper
  per-source card UI: add, inline-edit, remove, and git-sync each
  source independently via HTMX without a page reload
- Each source card shows type badge (git/local), URL or path, branch,
  and pull interval; git sources get a Sync button that triggers
  git pull and returns inline status
- Add source form uses a type-aware select that shows URL/branch/interval
  fields for git or path field for local, collapsed in a details accordion
- Add new settings routes: sources/add, sources/<idx>/remove,
  sources/<idx>/save, sources/<idx>/sync
- Update browse.html and run_detail.html to use CSS vars throughout
  (removed hardcoded hex colors); link empty state to Settings page

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-23 17:24:35 -04:00
parent edc9b752d2
commit 56283df5a1
5 changed files with 338 additions and 48 deletions
+9 -12
View File
@@ -5,18 +5,15 @@
{% set active_tab = "ansible" %}
{% include "settings/_tabs.html" %}
<form method="post" action="/settings/ansible/">
<div class="card" style="max-width:720px;">
<h2 class="section-title" style="margin-bottom:0.5rem;">Ansible Sources</h2>
<p style="color:var(--text-muted);font-size:0.85rem;margin-bottom:1rem;">
JSON array of source objects. Each requires <code>name</code>, <code>type</code>
(<code>git</code> or <code>local</code>), and either <code>url</code> or <code>path</code>.
<div style="max-width:720px;">
<div style="display:flex;align-items:baseline;justify-content:space-between;margin-bottom:0.75rem;">
<div class="section-title">Ansible Sources</div>
<a href="/ansible/" class="btn btn-ghost btn-sm" style="font-size:0.78rem;">Run History →</a>
</div>
<p style="color:var(--text-muted);font-size:0.84rem;margin-bottom:1rem;">
Sources are directories of playbooks — either a local path or a git repository
cloned automatically. Add as many as you need; each can be browsed and run independently.
</p>
<textarea name="ansible.sources" rows="12"
style="font-family:ui-monospace,monospace;font-size:0.85rem;width:100%;">{{ settings['ansible.sources'] | tojson(indent=2) }}</textarea>
{% include "settings/_ansible_sources.html" %}
</div>
<div style="margin-top:1rem;">
<button type="submit" class="btn">Save</button>
</div>
</form>
{% endblock %}