Files

58 lines
2.5 KiB
HTML

{% extends "base.html" %}
{% block title %}Admin — adgang til services{% endblock %}
{% block body %}
<p><a href="/admin" class="muted">← Admin</a></p>
<h1>Adgang til services</h1>
<p class="lead">Styr hvilke brugere og grupper der kan tilgå hver enkelt service.
Klik på en service for at redigere adgangen.</p>
{% if saved %}<div class="flash">{{ saved }}</div>{% endif %}
<div class="filter" style="max-width:22rem">
<span class="mag">⌕</span>
<input id="afilter" type="search" placeholder="Søg services…" autocomplete="off" aria-label="Søg services">
</div>
<div class="grid" id="acards">
{% for a in apps %}
<a class="card" href="/admin/access/{{ a.slug }}"
data-search="{{ ((a.name or '') ~ ' ' ~ a.slug ~ ' ' ~ (a.group or ''))|lower }}">
<div class="head">
<span class="ico">{% if a.icon %}<img src="{{ a.icon }}" alt="">{% else %}{{ (a.name or '?')[0]|upper }}{% endif %}</span>
<span class="name">{{ a.name }}</span>
</div>
<div class="sub" style="white-space:normal">
{% if a.open %}
<span class="tag open">🌐 åben for alle</span>
{% else %}
{% if a.n_groups %}<span class="tag">{{ a.n_groups }} gruppe{{ 'r' if a.n_groups != 1 }}</span>{% endif %}
{% if a.n_users %}<span class="tag">{{ a.n_users }} bruger{{ 'e' if a.n_users != 1 }}</span>{% endif %}
{% if a.n_other %}<span class="tag muted" title="policy-/negate-bindings styres i Authentik">+{{ a.n_other }} regel</span>{% endif %}
{% endif %}
</div>
<div class="go">Redigér adgang →</div>
</a>
{% endfor %}
</div>
<p id="anomatch" class="muted" style="display:none;margin-top:1rem">Ingen services matcher.</p>
<style>
.tag { display:inline-block; font-size:.74rem; border:1px solid var(--border); border-radius:999px;
padding:.08rem .55rem; margin:.15rem .25rem .15rem 0; color:var(--muted); }
.tag.open { color:#3ecf8e; border-color:color-mix(in srgb,#3ecf8e 40%,transparent);
background:color-mix(in srgb,#3ecf8e 10%,transparent); }
</style>
<script>
(function(){
var inp=document.getElementById('afilter'); if(!inp) return;
var cards=[].slice.call(document.querySelectorAll('#acards .card'));
var nm=document.getElementById('anomatch');
inp.addEventListener('input',function(){
var q=inp.value.trim().toLowerCase(), shown=0;
cards.forEach(function(c){ var hit=!q||c.getAttribute('data-search').indexOf(q)>-1;
c.classList.toggle('hidden',!hit); if(hit) shown++; });
nm.style.display=shown?'none':'block';
});
})();
</script>
{% endblock %}