ad4fcd1cfd
First-party plugins for Fabled Scryer (https://github.com/bvandeusen/fabledscryer). traefik: Prometheus metrics scraping, stats history, access log parsing (GeoIP optional) unifi: UniFi controller integration — WAN health, devices, clients, DPI, events ups: UPS monitoring via NUT (Network UPS Tools), Ansible shutdown automation Each plugin follows the Fabled Scryer plugin contract: setup(app), get_scheduled_tasks(), get_blueprint() index.yaml lists all three plugins in the catalog format. Populate checksum_sha256 entries once release zips are published via GitHub Releases. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
64 lines
2.5 KiB
HTML
64 lines
2.5 KiB
HTML
{# plugins/unifi/templates/unifi/index.html #}
|
|
{% extends "base.html" %}
|
|
{% block title %}UniFi — Fabled Scryer{% endblock %}
|
|
{% block content %}
|
|
<div style="display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:0.75rem;margin-bottom:1.25rem;">
|
|
<div style="display:flex;align-items:baseline;gap:1rem;">
|
|
<h1 class="page-title" style="margin-bottom:0;">UniFi Network</h1>
|
|
<span style="color:var(--text-muted);font-size:0.85rem;">polling every {{ poll_interval }}s</span>
|
|
</div>
|
|
{% include "_time_range.html" %}
|
|
</div>
|
|
|
|
{# Tab nav #}
|
|
<div style="display:flex;gap:0.25rem;margin-bottom:1.25rem;border-bottom:1px solid var(--border);padding-bottom:0;">
|
|
{% set tabs = [
|
|
("overview", "Overview", "/plugins/unifi/rows"),
|
|
("events", "Events", "/plugins/unifi/events"),
|
|
("dpi", "Traffic", "/plugins/unifi/dpi"),
|
|
("security", "Security", "/plugins/unifi/security"),
|
|
("inventory", "Inventory", "/plugins/unifi/inventory"),
|
|
] %}
|
|
{% for tab_id, label, url in tabs %}
|
|
<button
|
|
class="tab-btn{% if loop.first %} tab-active{% endif %}"
|
|
data-tab="{{ tab_id }}"
|
|
data-url="{{ url }}"
|
|
onclick="setUnifiTab(this)"
|
|
style="background:none;border:none;border-bottom:2px solid {% if loop.first %}var(--accent){% else %}transparent{% endif %};padding:0.4rem 0.9rem;cursor:pointer;font-size:0.88rem;color:{% if loop.first %}var(--text){% else %}var(--text-muted){% endif %};margin-bottom:-1px;">
|
|
{{ label }}
|
|
</button>
|
|
{% endfor %}
|
|
</div>
|
|
|
|
<div id="unifi-content"
|
|
hx-get="/plugins/unifi/rows"
|
|
hx-trigger="load, every {{ poll_interval }}s, rangeChange from:body"
|
|
hx-include="#time-range"
|
|
hx-swap="innerHTML">
|
|
</div>
|
|
|
|
<script>
|
|
function setUnifiTab(btn) {
|
|
document.querySelectorAll('.tab-btn').forEach(function(b) {
|
|
b.style.borderBottomColor = 'transparent';
|
|
b.style.color = 'var(--text-muted)';
|
|
});
|
|
btn.style.borderBottomColor = 'var(--accent)';
|
|
btn.style.color = 'var(--text)';
|
|
|
|
var el = document.getElementById('unifi-content');
|
|
el.setAttribute('hx-get', btn.dataset.url);
|
|
// Remove auto-poll on non-overview tabs (inventory/security don't change rapidly)
|
|
var isLive = btn.dataset.tab === 'overview' || btn.dataset.tab === 'events';
|
|
el.setAttribute('hx-trigger',
|
|
isLive
|
|
? 'tabActivated, every {{ poll_interval }}s, rangeChange from:body'
|
|
: 'tabActivated, rangeChange from:body'
|
|
);
|
|
htmx.process(el);
|
|
htmx.trigger(el, 'tabActivated');
|
|
}
|
|
</script>
|
|
{% endblock %}
|