321 lines
22 KiB
HTML
321 lines
22 KiB
HTML
{% extends "base.html" %}
|
||
|
||
{% block title %}Gedeelde drives{% endblock %}
|
||
{% block page_title %}Gedeelde drives{% endblock %}
|
||
{% block main_class %}wide{% endblock %}
|
||
{% block loader_text %}Gedeelde drives ophalen bij Google...{% endblock %}
|
||
|
||
{% block extra_css %}
|
||
<style>
|
||
[hidden] { display: none !important; }
|
||
.balk { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; margin: 12px 0; }
|
||
.balk input[type=search] { flex: 0 1 320px; margin: 0; }
|
||
.filters { display: flex; flex-wrap: wrap; gap: 8px; }
|
||
.filters button { width: auto; margin: 0; padding: 4px 12px; border-radius: 999px; background: var(--surface-muted);
|
||
border: 1px solid var(--border); font-size: .88em; color: inherit; font-weight: 400; cursor: pointer; }
|
||
.filters button[aria-pressed="true"] { border-color: var(--primary-color); background: var(--primary-light); color: var(--primary-color); font-weight: 600; }
|
||
.filters button.let { background: #fef3c7; border-color: #fcd34d; }
|
||
.filters button.let[aria-pressed="true"] { background: #fde68a; color: #92400e; }
|
||
th.sorteer { cursor: pointer; user-select: none; white-space: nowrap; }
|
||
th.sorteer:hover { color: var(--primary-color); }
|
||
th.sorteer .pijl::after { content: "↕"; opacity: .35; margin-left: 2px; }
|
||
th.sorteer.op .pijl::after { content: "▲"; opacity: 1; }
|
||
th.sorteer.af .pijl::after { content: "▼"; opacity: 1; }
|
||
td.getal { text-align: right; white-space: nowrap; }
|
||
tr.klik { cursor: pointer; }
|
||
tr.klik:hover td { background: var(--primary-light); }
|
||
.tabel-voet { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: 10px; margin-top: 12px; }
|
||
.paginering { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
|
||
.toevoegen { display: grid; grid-template-columns: minmax(220px, 2fr) minmax(160px, 1fr) auto auto; gap: 10px; align-items: end; }
|
||
.toevoegen .field { margin: 0; }
|
||
@media (max-width: 800px) { .toevoegen { grid-template-columns: 1fr; } }
|
||
td.acties { white-space: nowrap; text-align: right; }
|
||
td.acties form { display: inline; margin: 0; }
|
||
td.acties select { width: auto; margin: 0; padding: 4px 8px; font-size: 13px; }
|
||
.type { font-size: .8em; padding: 1px 8px; border-radius: 999px; background: var(--surface-muted); }
|
||
</style>
|
||
{% endblock %}
|
||
|
||
{% block content %}
|
||
{% if lid_van is not none %}
|
||
{# ======================= Waar is iemand lid van? ======================= #}
|
||
<div class="card">
|
||
<div class="page-head">
|
||
<h2>🔎 {{ lid }}</h2>
|
||
<div class="actions"><a class="btn btn-light btn-sm" href="{{ url_for('gedeelde_drives.overzicht') }}">← Alle gedeelde drives</a></div>
|
||
</div>
|
||
{% if fout %}<div class="alert alert-danger">{{ fout }}</div>
|
||
{% elif not lid_van %}
|
||
<p class="muted">{{ lid }} is op geen enkele gedeelde drive lid (rechtstreeks; lidmaatschap via een Google-groep telt hier niet mee).</p>
|
||
{% else %}
|
||
<p class="muted small" style="margin-top:-6px">Lid van {{ lid_van|length }} gedeelde drive(s) (rechtstreeks; lidmaatschap via een Google-groep telt hier niet mee).</p>
|
||
<div class="table-wrap"><table>
|
||
{% set meerdere = (lid_van|map(attribute='email')|unique|list|length) > 1 or '@' not in lid %}
|
||
<thead><tr><th>Drive</th>{% if meerdere %}<th>Lid</th>{% endif %}<th>Rol</th><th></th></tr></thead>
|
||
<tbody>{% for d in lid_van %}
|
||
<tr><td><a href="{{ url_for('gedeelde_drives.overzicht', drive=d.drive) }}" onclick="showLoader()"><strong>{{ d.naam }}</strong></a></td>
|
||
{% if meerdere %}<td class="small">{{ d.wie }}{% if d.wie != d.email %}<br><span class="muted">{{ d.email }}</span>{% endif %}</td>{% endif %}
|
||
<td>{{ d.rol_naam }}</td>
|
||
<td class="acties"><a class="btn btn-light btn-sm" href="https://drive.google.com/drive/folders/{{ d.drive }}" target="_blank" rel="noopener">Openen in Drive ↗</a></td></tr>
|
||
{% endfor %}</tbody>
|
||
</table></div>
|
||
{% if '@' in lid %}
|
||
<form class="balk" method="GET" action="{{ url_for('gedeelde_drives.overzicht') }}" onsubmit="showLoader()" style="margin-top:14px">
|
||
<input type="hidden" name="oud" value="{{ lid }}">
|
||
<span>🔁 Op al deze drives vervangen door</span>
|
||
<input type="email" name="nieuw" required placeholder="nieuwe gebruiker (e-mail)" style="flex:0 1 280px;margin:0">
|
||
<button type="submit" class="btn-light btn-sm" style="margin:0">Verder</button>
|
||
</form>
|
||
{% endif %}
|
||
{% endif %}
|
||
</div>
|
||
|
||
{% elif vervang %}
|
||
{# ======================= Gebruiker vervangen ======================= #}
|
||
<div class="card">
|
||
<div class="page-head">
|
||
<h2>🔁 {{ vervang.oud }} → {{ vervang.nieuw or '?' }}</h2>
|
||
<div class="actions"><a class="btn btn-light btn-sm" href="{{ url_for('gedeelde_drives.overzicht') }}">← Alle gedeelde drives</a></div>
|
||
</div>
|
||
{% if fout %}<div class="alert alert-danger">{{ fout }}</div>
|
||
{% elif resultaat is not none %}
|
||
{% set ok = resultaat|selectattr('ok')|list|length %}
|
||
<div class="alert {{ 'alert-success' if ok == resultaat|length else 'alert-warning' }}">{{ ok }} van {{ resultaat|length }} drive(s) aangepast.</div>
|
||
<div class="table-wrap"><table>
|
||
<thead><tr><th>Drive</th><th></th><th>Resultaat</th></tr></thead>
|
||
<tbody>{% for r in resultaat %}<tr><td><strong>{{ r.naam }}</strong></td><td>{{ '✅' if r.ok else '⚠️' }}</td><td class="small">{{ r.melding }}</td></tr>{% endfor %}</tbody>
|
||
</table></div>
|
||
{% elif not vervang.drives %}
|
||
<p class="muted">{{ vervang.oud }} is op geen enkele gedeelde drive lid.</p>
|
||
{% else %}
|
||
<p class="muted small" style="margin-top:-6px">{{ vervang.oud }} is lid van {{ vervang.drives|length }} gedeelde drive(s).
|
||
{{ vervang.nieuw }} krijgt op elke aangevinkte drive exact dezelfde rol (ook als die er al lid van was).</p>
|
||
<form method="POST" action="{{ url_for('gedeelde_drives.vervangen') }}"
|
||
onsubmit="if (!this.querySelector('input[name=drive]:checked')) { alert('Vink minstens één drive aan.'); return false; }
|
||
if (!confirm({{ (vervang.oud ~ ' vervangen door ' ~ vervang.nieuw ~ ' op de aangevinkte drives?')|tojson|forceescape }})) return false; showLoader('Vervangen...');">
|
||
<input type="hidden" name="oud" value="{{ vervang.oud }}"><input type="hidden" name="nieuw" value="{{ vervang.nieuw }}">
|
||
<div class="table-wrap"><table>
|
||
<thead><tr><th style="width:28px"><input type="checkbox" checked style="width:auto;margin:0" onchange="this.closest('table').querySelectorAll('input[name=drive]').forEach(x => x.checked = this.checked)"></th>
|
||
<th>Drive</th><th>Rol van {{ vervang.oud }}</th></tr></thead>
|
||
<tbody>{% for d in vervang.drives %}
|
||
<tr><td><input type="checkbox" name="drive" value="{{ d.drive }}" checked style="width:auto;margin:0"></td>
|
||
<td><a href="{{ url_for('gedeelde_drives.overzicht', drive=d.drive) }}">{{ d.naam }}</a></td><td>{{ d.rol_naam }}</td></tr>
|
||
{% endfor %}</tbody>
|
||
</table></div>
|
||
<div class="balk">
|
||
<label style="display:flex;gap:6px;align-items:center;margin:0;font-weight:400"><input type="checkbox" name="verwijderen" value="1" checked style="width:auto;margin:0"> {{ vervang.oud }} daarna verwijderen</label>
|
||
<label style="display:flex;gap:6px;align-items:center;margin:0;font-weight:400"><input type="checkbox" name="melding" value="1" style="width:auto;margin:0"> e-mail sturen naar {{ vervang.nieuw }}</label>
|
||
<button type="submit" class="btn-success" style="margin:0 0 0 auto">🔁 Vervangen</button>
|
||
</div>
|
||
</form>
|
||
{% endif %}
|
||
</div>
|
||
|
||
{% elif gekozen %}
|
||
{# ======================= Detail van één drive ======================= #}
|
||
<div class="card">
|
||
<div class="page-head">
|
||
<h2>🗂️ {{ gekozen.naam }}</h2>
|
||
<div class="actions">
|
||
<a class="btn btn-light btn-sm" href="{{ url_for('gedeelde_drives.overzicht') }}">← Alle gedeelde drives</a>
|
||
<a class="btn btn-light btn-sm" href="https://drive.google.com/drive/folders/{{ gekozen.id }}" target="_blank" rel="noopener">Openen in Drive ↗</a>
|
||
</div>
|
||
</div>
|
||
<p class="muted small" style="margin-top:-6px">{{ gekozen.leden }} lid/leden · {{ gekozen.beheerders }} beheerder(s)
|
||
{% if gekozen.aangemaakt %} · aangemaakt {{ gekozen.aangemaakt }}{% endif %}</p>
|
||
{% if not gekozen.beheerders %}<div class="alert alert-warning">⚠️ Deze drive heeft geen beheerder. Voeg hieronder iemand toe als <strong>Beheerder</strong>.</div>{% endif %}
|
||
{% if gekozen.extern %}<div class="alert alert-warning">🌍 {{ gekozen.extern }} lid/leden van buiten de school.</div>{% endif %}
|
||
|
||
<form class="toevoegen" method="POST" action="{{ url_for('gedeelde_drives.lid_toevoegen') }}" onsubmit="showLoader('Toevoegen...')">
|
||
<input type="hidden" name="drive" value="{{ gekozen.id }}"><input type="hidden" name="naam" value="{{ gekozen.naam }}">
|
||
<div class="field"><label for="email">Persoon of groep (e-mailadres)</label>
|
||
<input type="email" id="email" name="email" required placeholder="bv. jan.peeters@school.be of leerkrachten@school.be"></div>
|
||
<div class="field"><label for="rol">Rol</label>
|
||
<select id="rol" name="rol">{% for r, n in rollen %}<option value="{{ r }}" {{ 'selected' if r == 'writer' }}>{{ n }}</option>{% endfor %}</select></div>
|
||
<label style="display:flex;gap:6px;align-items:center;margin:0 0 10px;font-weight:400"><input type="checkbox" name="melding" value="1" style="width:auto;margin:0"> e-mail sturen</label>
|
||
<button type="submit" class="btn-success" style="margin:0 0 2px">➕ Toevoegen</button>
|
||
</form>
|
||
|
||
<div class="table-wrap" style="margin-top:16px">
|
||
<table>
|
||
<thead><tr><th>Naam</th><th>E-mail</th><th>Soort</th><th>Rol</th><th></th></tr></thead>
|
||
<tbody>
|
||
{% for l in leden %}
|
||
<tr>
|
||
<td><strong>{{ l.naam or '—' }}</strong>{% if l.extern %} <span class="badge badge-warning" title="Buiten de school">extern</span>{% endif %}
|
||
{% if l.verwijderd %} <span class="badge badge-danger">account verwijderd</span>{% endif %}</td>
|
||
<td class="small">{{ l.email }}</td>
|
||
<td><span class="type">{{ {'user': 'persoon', 'group': 'groep', 'domain': 'domein', 'anyone': 'iedereen met link'}.get(l.type, l.type) }}</span></td>
|
||
<td class="acties" style="text-align:left">
|
||
<form method="POST" action="{{ url_for('gedeelde_drives.lid_wijzigen') }}">
|
||
<input type="hidden" name="drive" value="{{ gekozen.id }}"><input type="hidden" name="naam" value="{{ gekozen.naam }}">
|
||
<input type="hidden" name="perm" value="{{ l.id }}"><input type="hidden" name="email" value="{{ l.email or l.naam }}">
|
||
<select name="rol" onchange="if (confirm({{ ('Rol van ' ~ (l.email or l.naam) ~ ' wijzigen?')|tojson|forceescape }})) { showLoader(); this.form.submit(); } else { this.value = {{ l.rol|tojson|forceescape }}; }">
|
||
{% for r, n in rollen %}<option value="{{ r }}" {{ 'selected' if r == l.rol }}>{{ n }}</option>{% endfor %}
|
||
</select>
|
||
</form>
|
||
</td>
|
||
<td class="acties">
|
||
<form method="POST" action="{{ url_for('gedeelde_drives.lid_verwijderen') }}"
|
||
onsubmit="if (!confirm({{ ((l.email or l.naam) ~ ' uit ' ~ gekozen.naam ~ ' verwijderen?')|tojson|forceescape }})) return false; showLoader();">
|
||
<input type="hidden" name="drive" value="{{ gekozen.id }}"><input type="hidden" name="naam" value="{{ gekozen.naam }}">
|
||
<input type="hidden" name="perm" value="{{ l.id }}"><input type="hidden" name="email" value="{{ l.email or l.naam }}">
|
||
<button type="submit" class="btn-sm btn-ghost" title="Verwijderen">🗑️</button>
|
||
</form>
|
||
</td>
|
||
</tr>
|
||
{% else %}
|
||
<tr><td colspan="5" class="muted">Deze drive heeft geen leden.</td></tr>
|
||
{% endfor %}
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
<p class="field-hint" style="margin-top:12px"><strong>Beheerder</strong>: alles, ook leden beheren · <strong>Inhoudsbeheerder</strong>:
|
||
bestanden toevoegen, bewerken, verplaatsen en verwijderen · <strong>Bijdrager</strong>: toevoegen en bewerken ·
|
||
<strong>Reageerder</strong>: bekijken en reageren · <strong>Lezer</strong>: enkel bekijken.</p>
|
||
</div>
|
||
|
||
{% else %}
|
||
{# ======================= Overzicht ======================= #}
|
||
<div class="card">
|
||
<div class="page-head">
|
||
<h2>🗂️ Gedeelde drives <span class="muted small">({{ drives|length }})</span></h2>
|
||
<div class="actions">
|
||
<button type="button" class="btn-success btn-sm" onclick="document.getElementById('nieuwVenster').style.display='block'">➕ Nieuwe gedeelde drive</button>
|
||
<a class="btn btn-secondary btn-sm" href="{{ url_for('gedeelde_drives.overzicht', vernieuw=1) }}" onclick="showLoader()">🔄 Opnieuw ophalen</a>
|
||
</div>
|
||
</div>
|
||
<form class="balk" method="GET" action="{{ url_for('gedeelde_drives.overzicht') }}" onsubmit="showLoader('Drives van deze gebruiker zoeken...')"
|
||
style="padding:12px 14px;border:1px solid var(--border);border-radius:var(--radius);margin:0 0 10px">
|
||
<strong style="white-space:nowrap">🔎 Waar is iemand lid van?</strong>
|
||
<input type="text" name="lid" required placeholder="e-mailadres, of een deel van de naam of het adres" style="flex:1 1 300px;margin:0">
|
||
<button type="submit" class="btn-light btn-sm" style="margin:0">Zoeken</button>
|
||
</form>
|
||
<form class="balk" method="GET" action="{{ url_for('gedeelde_drives.overzicht') }}" onsubmit="showLoader('Drives van deze gebruiker zoeken...')"
|
||
style="padding:12px 14px;border:1px solid var(--border);border-radius:var(--radius);margin-top:0">
|
||
<strong style="white-space:nowrap">🔁 Gebruiker vervangen</strong>
|
||
<input type="email" name="oud" required placeholder="oude gebruiker (e-mail)" style="flex:1 1 220px;margin:0">
|
||
<span>→</span>
|
||
<input type="email" name="nieuw" required placeholder="nieuwe gebruiker (e-mail)" style="flex:1 1 220px;margin:0">
|
||
<button type="submit" class="btn-light btn-sm" style="margin:0">Drives zoeken</button>
|
||
</form>
|
||
{% if fout %}
|
||
<div class="alert alert-danger">{{ fout }}</div>
|
||
{% elif not drives %}
|
||
<p class="muted">Er zijn nog geen gedeelde drives in dit domein.</p>
|
||
{% else %}
|
||
{% set zonder = drives|selectattr('beheerders', 'equalto', 0)|list|length %}
|
||
{% set ext = drives|selectattr('extern')|list|length %}
|
||
<div class="balk">
|
||
<input type="search" id="zoek" placeholder="Zoek een drive..." aria-label="Zoeken">
|
||
<div class="filters" id="filters">
|
||
<button type="button" data-filter="" aria-pressed="true">Alle <b>{{ drives|length }}</b></button>
|
||
{% if zonder %}<button type="button" class="let" data-filter="zonder" aria-pressed="false">Zonder beheerder <b>{{ zonder }}</b></button>{% endif %}
|
||
{% if ext %}<button type="button" class="let" data-filter="extern" aria-pressed="false">Met externe leden <b>{{ ext }}</b></button>{% endif %}
|
||
</div>
|
||
<span id="perPagina"></span>
|
||
<span class="muted small">Opgehaald op {{ opgehaald }}</span>
|
||
</div>
|
||
<div class="table-wrap">
|
||
<table>
|
||
<thead><tr>
|
||
<th class="sorteer" data-tekst>Naam <span class="pijl"></span></th>
|
||
<th class="sorteer">Leden <span class="pijl"></span></th>
|
||
<th class="sorteer">Beheerders <span class="pijl"></span></th>
|
||
<th class="sorteer">Groepen <span class="pijl"></span></th>
|
||
<th class="sorteer">Extern <span class="pijl"></span></th>
|
||
<th class="sorteer">Aangemaakt <span class="pijl"></span></th>
|
||
</tr></thead>
|
||
<tbody id="body">
|
||
{% for d in drives %}
|
||
<tr class="klik" data-href="{{ url_for('gedeelde_drives.overzicht', drive=d.id) }}"
|
||
data-filters="{{ 'zonder' if not d.beheerders }} {{ 'extern' if d.extern }}">
|
||
<td data-sort="{{ d.naam }}"><strong>{{ d.naam }}</strong>{% if d.fout %} <span class="badge badge-danger" title="{{ d.fout }}">leden niet op te halen</span>{% endif %}</td>
|
||
<td class="getal" data-sort="{{ d.leden }}">{{ d.leden }}</td>
|
||
<td class="getal" data-sort="{{ d.beheerders }}">{% if d.beheerders %}{{ d.beheerders }}{% else %}<span class="badge badge-danger">geen</span>{% endif %}</td>
|
||
<td class="getal" data-sort="{{ d.groepen }}">{{ d.groepen or '' }}</td>
|
||
<td class="getal" data-sort="{{ d.extern }}">{% if d.extern %}<span class="badge badge-warning">{{ d.extern }}</span>{% endif %}</td>
|
||
<td data-sort="{{ d.aangemaakt }}" class="small">{{ d.aangemaakt }}</td>
|
||
</tr>
|
||
{% endfor %}
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
<div class="tabel-voet">
|
||
<div class="muted small" id="teller"></div>
|
||
<nav class="paginering" id="paginering" aria-label="Pagina's"></nav>
|
||
</div>
|
||
{% endif %}
|
||
<p class="field-hint" style="margin-top:14px">Vereist in de domeinbrede delegatie: <code>https://www.googleapis.com/auth/drive</code>,
|
||
en de <strong>Google Drive API</strong> moet aanstaan in het Cloud-project van het serviceaccount.</p>
|
||
</div>
|
||
{% endif %}
|
||
{% endblock %}
|
||
|
||
{% block modals %}
|
||
<div id="nieuwVenster" class="modal">
|
||
<div class="modal-content">
|
||
<span class="close" onclick="document.getElementById('nieuwVenster').style.display='none'">×</span>
|
||
<h3>➕ Nieuwe gedeelde drive</h3>
|
||
<form method="POST" action="{{ url_for('gedeelde_drives.nieuw') }}" onsubmit="showLoader('Aanmaken...')">
|
||
<div class="field"><label>Naam</label><input type="text" name="naam" required maxlength="100"></div>
|
||
<div class="field"><label>Beheerder (optioneel)</label><input type="email" name="beheerder" placeholder="e-mailadres van persoon of groep">
|
||
<p class="field-hint">De beheerder van PIVOT wordt automatisch ook beheerder van de nieuwe drive.</p></div>
|
||
<button type="submit" class="btn-block">Aanmaken</button>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
{% endblock %}
|
||
|
||
{% block scripts %}
|
||
<script>
|
||
window.addEventListener('click', e => { if (e.target.id === 'nieuwVenster') e.target.style.display = 'none'; });
|
||
(function () {
|
||
const body = document.getElementById('body');
|
||
if (!body) return;
|
||
const rijen = Array.from(body.rows), zoek = document.getElementById('zoek');
|
||
let PER = perPagina('gedeelde-drives', 25), pagina = 1, filter = '';
|
||
body.addEventListener('click', e => { const tr = e.target.closest('tr.klik'); if (tr) { showLoader(); location.href = tr.dataset.href; } });
|
||
document.querySelectorAll('#filters button').forEach(b => b.addEventListener('click', () => {
|
||
filter = b.dataset.filter;
|
||
document.querySelectorAll('#filters button').forEach(x => x.setAttribute('aria-pressed', String(x === b)));
|
||
pagina = 1; toon();
|
||
}));
|
||
let kol = null, op = true;
|
||
document.querySelectorAll('th.sorteer').forEach(th => th.addEventListener('click', () => {
|
||
const k = th.cellIndex;
|
||
op = kol === k ? !op : 'tekst' in th.dataset; kol = k;
|
||
document.querySelectorAll('th.sorteer').forEach(x => x.classList.remove('op', 'af'));
|
||
th.classList.add(op ? 'op' : 'af');
|
||
rijen.sort((a, b) => {
|
||
const c = (a.cells[k].dataset.sort || '').localeCompare(b.cells[k].dataset.sort || '', 'nl', { numeric: true, sensitivity: 'base' });
|
||
return op ? c : -c;
|
||
}).forEach(tr => body.appendChild(tr));
|
||
pagina = 1; toon();
|
||
}));
|
||
function toon() {
|
||
const z = zoek.value.trim().toLowerCase();
|
||
const lijst = rijen.filter(tr => (!z || tr.cells[0].textContent.toLowerCase().includes(z))
|
||
&& (!filter || tr.dataset.filters.split(' ').includes(filter)));
|
||
const grootte = PER || Infinity, paginas = Math.max(1, Math.ceil(lijst.length / grootte));
|
||
pagina = Math.min(Math.max(1, pagina), paginas);
|
||
const van = PER ? (pagina - 1) * PER : 0, tot = van + grootte;
|
||
rijen.forEach(tr => tr.style.display = 'none');
|
||
lijst.forEach((tr, i) => tr.style.display = i >= van && i < tot ? '' : 'none');
|
||
document.getElementById('teller').textContent = lijst.length ? `${van + 1}–${Math.min(tot, lijst.length)} van ${lijst.length}` : 'Niets gevonden';
|
||
const nav = document.getElementById('paginering'); nav.innerHTML = '';
|
||
if (paginas > 1) {
|
||
const knop = (t, p, a) => { const b = document.createElement('button'); b.type = 'button'; b.textContent = t;
|
||
b.className = 'btn-sm ' + (a ? 'btn-secondary' : 'btn-light'); b.onclick = () => { pagina = p; toon(); }; nav.appendChild(b); };
|
||
if (pagina > 1) { knop('«', 1); knop('‹', pagina - 1); }
|
||
for (let p = Math.max(1, pagina - 2); p <= Math.min(paginas, pagina + 2); p++) knop(String(p), p, p === pagina);
|
||
if (pagina < paginas) { knop('›', pagina + 1); knop('»', paginas); }
|
||
}
|
||
}
|
||
zoek.addEventListener('input', () => { pagina = 1; toon(); });
|
||
perPaginaKiezer(document.getElementById('perPagina'), 'gedeelde-drives', n => { PER = n; pagina = 1; toon(); }, 25);
|
||
toon();
|
||
})();
|
||
</script>
|
||
{% endblock %}
|