feat: Filter und Paginierung für den Werkzeugkatalog, Claude Code als Katalogeintrag

Beide Katalog-Ansichten (Betreiber + Mandant) haben jetzt eine
Filterleiste (Freitext über Name/Anbieter/Verarbeitungsländer,
Zweck-Dropdown) und serverseitige Paginierung (20/Seite) über ein
GET-Formular, kein JavaScript. pagination.go ist generisch gehalten
(Go-Generics) für Wiederverwendung in weiteren Listen.

Claude Code als eigener Katalogeintrag ergänzt (nicht identisch mit
Claude for Work: läuft lokal, hat Dateizugriff, lokale Sitzungs-
protokolle mit eigenem Aufbewahrungsrisiko).
This commit is contained in:
noroot
2026-08-31 15:09:23 +02:00
parent 08c7721165
commit 3aecbb446c
8 changed files with 390 additions and 44 deletions

View File

@@ -12,8 +12,20 @@
zentralen Katalog unverändert — es wird nur für diesen Mandanten aus
der Werkzeugsuche ausgeblendet.
</p>
<form method="get" class="filter-bar">
<input type="search" name="q" value="{{.Filter.Suche}}" placeholder="Suche (Name, Anbieter, Land)">
<select name="zweck">
<option value="">Alle Zwecke</option>
{{$zweck := .Filter.Zweck}}
{{range .ZweckeOptionen}}
<option value="{{.}}" {{if eq . $zweck}}selected{{end}}>{{.}}</option>
{{end}}
</select>
<button type="submit">Filtern</button>
{{if .Filter.Aktiv}}<a href="/verwaltung/werkzeuge">Zurücksetzen</a>{{end}}
</form>
{{if not .Werkzeuge}}
<p class="hinweis">Der zentrale Katalog ist noch leer.</p>
<p class="hinweis">{{if .Filter.Aktiv}}Keine Treffer für diese Filter.{{else}}Der zentrale Katalog ist noch leer.{{end}}</p>
{{else}}
<div class="table-scroll">
<table>
@@ -52,6 +64,27 @@
</tbody>
</table>
</div>
<div class="pagination">
<span class="hinweis">Seite {{.Pagination.Page}} von {{.Pagination.TotalPages}} ({{.Pagination.Total}} Einträge)</span>
<span>
{{if .Pagination.HasPrev}}
<form method="get" style="display:inline">
<input type="hidden" name="q" value="{{.Filter.Suche}}">
<input type="hidden" name="zweck" value="{{.Filter.Zweck}}">
<input type="hidden" name="page" value="{{.Pagination.PrevPage}}">
<button type="submit">&larr; Zurück</button>
</form>
{{end}}
{{if .Pagination.HasNext}}
<form method="get" style="display:inline">
<input type="hidden" name="q" value="{{.Filter.Suche}}">
<input type="hidden" name="zweck" value="{{.Filter.Zweck}}">
<input type="hidden" name="page" value="{{.Pagination.NextPage}}">
<button type="submit">Weiter &rarr;</button>
</form>
{{end}}
</span>
</div>
{{end}}
<h2>Eigene Werkzeuge</h2>