- /ansible/playbooks lists every playbook across sources: what it says it does, its category and destructive flag, how it last ran; the whole row opens the playbook. A source with none is one quiet line. - /ansible/playbooks/<source>/<path>: the verdict (what it does, flagged destructive, last ran), the run form in place (dry run beside the button, options folded), the schedules that use it, its recent runs, the playbook itself folded. ?from=<run> fills the form from that run: Run again on a run's page. - /ansible/browse, its view page and the /run-form fragment are gone, not redirected (rule 122); every link points at the new pages. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
58 lines
2.8 KiB
HTML
58 lines
2.8 KiB
HTML
{# ansible/playbooks.html — the Playbooks tab (#5331): every playbook across
|
|
its sources in one list, what each says it does and how it last ran; the
|
|
whole row opens the playbook's page, where it is run. A source with no
|
|
playbooks is one quiet line under the list. #}
|
|
{% extends "base.html" %}
|
|
{% from "_macros.html" import crumbs, page_header, status_badge, empty_state %}
|
|
{% from "ansible/_tabs.html" import ansible_tabs %}
|
|
{% block title %}Playbooks — Steward{% endblock %}
|
|
{% block breadcrumb %}{{ crumbs([("Ansible", "/ansible/"), ("Playbooks", "")]) }}{% endblock %}
|
|
{% block content %}
|
|
{{ ansible_tabs("playbooks") }}
|
|
{% call page_header("Playbooks") %}
|
|
{% if can_add %}<a href="/ansible/playbooks/new" class="btn">New playbook</a>{% endif %}
|
|
{% endcall %}
|
|
|
|
{% if not sources %}
|
|
<div class="card">{{ empty_state("No playbook sources are set up.", "Add one in Settings", "/settings/ansible/") }}</div>
|
|
{% else %}
|
|
{% set n_src = rows|map(attribute="source")|unique|list|length %}
|
|
{% set n_bad = rows|selectattr("confirm")|list|length %}
|
|
<p class="page-verdict">
|
|
{{- rows|length }} playbook{{ 's' if rows|length != 1 }}{% if n_src %} from {{ n_src }} source{{ 's' if n_src != 1 }}{% endif %}
|
|
{%- if n_bad %} · <span class="tone-warn">{{ n_bad }} flagged destructive by {{ 'their authors' if n_bad > 1 else 'its author' }}</span>{% endif -%}
|
|
</p>
|
|
|
|
{% if rows %}
|
|
<div class="card-flush">
|
|
<table class="table">
|
|
<thead><tr><th>Playbook</th><th>Source</th><th>Last run</th></tr></thead>
|
|
<tbody>
|
|
{% for r in rows %}
|
|
<tr class="row-link">
|
|
<td class="cell-name playbook-cell">
|
|
<a class="row-target mono" href="/ansible/playbooks/{{ r.source }}/{{ r.path }}" title="{{ r.path }}">{{ r.path }}</a>
|
|
{% if r.description %}<div class="cell-sub" title="{{ r.description }}">{{ r.description }}</div>{% endif %}
|
|
</td>
|
|
<td>
|
|
<span class="tone-muted">{{ r.source }}</span>
|
|
{%- if r.category %} <span class="chip">{{ r.category }}</span>{% endif %}
|
|
{%- if r.confirm %} {{ status_badge('warn', 'destructive', 'Its author flagged it as making significant or destructive changes: a real run asks for confirmation') }}{% endif %}
|
|
</td>
|
|
<td class="nowrap">
|
|
{%- if r.last %}{{ status_badge(r.last.status) }} <span class="tone-muted">{{ r.last.started_at|ago }}</span>
|
|
{%- else %}<span class="tone-dim">never run</span>{% endif -%}
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
{% endif %}
|
|
{% for s in empty_sources %}
|
|
<p class="field-hint">{{ s.name }} (<span class="mono">{{ s.path }}</span>) has no playbooks yet.
|
|
{%- if can_add and s.editable %} <a href="/ansible/playbooks/new">Write one</a>{% endif %}</p>
|
|
{% endfor %}
|
|
{% endif %}
|
|
{% endblock %}
|