sub-aligator/templates/index.html
SW 6e24ce541a feat: rename to SUB-ALIGATOR, dark theme, pool deletion, header nav
- Rename app title to SUB-ALIGATOR (header, page titles, exports, README)
- Add dark amber-terminal theme with a header toggle, persisted in localStorage
- Add pool deletion (soft delete): allocations are kept in history and
  block the address space again when the same or an overlapping pool is
  re-added (re-enable on exact CIDR match, re-attach contained allocations)
- Reject new pools that overlap an enabled pool
- Move Home link into the page header, keep other links in the footer
- Load app.js globally via base template, add theme.js (CSP-safe, no inline JS)
2026-10-01 18:00:32 +02:00

134 lines
4.7 KiB
HTML

{% extends "base.html" %}
{% block content %}
<div id="flash-container" hx-swap-oob="true">
{% include "fragments/flash.html" %}
</div>
{% if pools.len() == 0 %}
<section class="box">
<div class="box-title">No pools configured</div>
<p>Create at least one pool before allocating subnets.</p>
<a href="/pools" class="btn">Add a pool</a>
</section>
{% else %}
<section class="grid">
{% for pool in pools %}
<article class="box" id="pool-card-{{ pool.slug }}">
<div class="box-title">{{ pool.name }}</div>
<p><span class="label">Parent prefix:</span> <span class="value">{{ pool.cidr }}</span></p>
<p><span class="label">Type:</span> <span class="value">{{ pool.kind }}</span></p>
<form
hx-get="/partials/pools/{{ pool.slug }}/preview"
hx-target="#preview-{{ pool.slug }}"
hx-trigger="change from:select, load"
hx-indicator="#indicator-{{ pool.slug }}"
>
<label for="prefix-{{ pool.slug }}">Subnet size</label>
<select name="prefix_length" id="prefix-{{ pool.slug }}">
{% for pl in pool.allowed_prefixes %}
<option value="{{ pl }}" {% if pl == "24" %}selected{% endif %}>/{{ pl }}</option>
{% endfor %}
</select>
<div id="indicator-{{ pool.slug }}" class="small" style="display:none;">Loading...</div>
<div id="preview-{{ pool.slug }}"></div>
</form>
<button
class="btn allocate-btn"
style="margin-top: 1rem;"
data-slug="{{ pool.slug }}"
data-name="{{ pool.name }}"
>
[ Allocate next free subnet ]
</button>
</article>
{% endfor %}
</section>
{% endif %}
<section class="box">
<div class="box-title">Allocated subnets</div>
<form method="get" action="/" class="filters">
<div>
<label for="q">Search</label>
<input type="text" id="q" name="q" value="{{ query }}" placeholder="CIDR or note">
</div>
<div>
<label for="pool">Pool</label>
<select id="pool" name="pool">
<option value="" {% if pool_filter == "" %}selected{% endif %}>All</option>
{% for p in all_pools %}
<option value="{{ p.slug }}" {% if pool_filter == p.slug %}selected{% endif %}>{{ p.name }}</option>
{% endfor %}
</select>
</div>
<div>
<label for="status">Status</label>
<select id="status" name="status">
<option value="" {% if status_filter == "" %}selected{% endif %}>All</option>
<option value="active" {% if status_filter == "active" %}selected{% endif %}>active</option>
<option value="reserved" {% if status_filter == "reserved" %}selected{% endif %}>reserved</option>
<option value="released" {% if status_filter == "released" %}selected{% endif %}>released</option>
</select>
</div>
<div>
<button type="submit" class="btn">Filter</button>
<a href="/" class="btn btn-secondary">Reset</a>
</div>
</form>
<div id="allocations-table">
{% include "fragments/allocations_table.html" %}
</div>
</section>
<div id="allocate-modal" class="modal-overlay" style="display:none;">
<div class="modal">
<h2 class="modal-title">Confirm subnet allocation</h2>
<form method="post" action="/allocations" class="modal-body" id="allocate-form">
<input type="hidden" name="pool_slug" id="modal-pool-slug">
<input type="hidden" name="prefix_length" id="modal-prefix-length">
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
<div class="detail-grid">
<div class="detail-item">
<div class="label">Pool</div>
<div class="value" id="modal-pool-name"></div>
</div>
<div class="detail-item">
<div class="label">Prefix</div>
<div class="value" id="modal-prefix-display"></div>
</div>
<div class="detail-item">
<div class="label">Proposed subnet</div>
<div class="value" id="modal-cidr"></div>
</div>
<div class="detail-item">
<div class="label">Total addresses</div>
<div class="value" id="modal-address-count"></div>
</div>
<div class="detail-item">
<div class="label">Usable hosts</div>
<div class="value" id="modal-usable-hosts"></div>
</div>
</div>
<p class="small" id="modal-warning"></p>
<label for="note">Note *</label>
<textarea id="note" name="note" rows="3" required minlength="3" maxlength="500"></textarea>
<label for="ticket">Ticket / reference</label>
<input type="text" id="ticket" name="ticket" maxlength="100">
<div class="modal-actions">
<button type="button" class="btn btn-secondary cancel-btn" data-modal="allocate-modal">Cancel</button>
<button type="submit" class="btn">Confirm allocation</button>
</div>
</form>
</div>
</div>
{% endblock %}