feat(diarization-ui): restyle library to project-list style table with toolbar filters

This commit is contained in:
2026-03-21 15:41:12 +01:00
parent bd152429d6
commit a1e35e98f3

55
app.py
View File

@@ -517,34 +517,53 @@ def library(project_id: Optional[str] = None, q_title: str = "", q_content: str
p_opts = "<option value=''>Alle</option>" + "".join( p_opts = "<option value=''>Alle</option>" + "".join(
[f"<option value='{p['id']}' {'selected' if project_id_int==p['id'] else ''}>{p['name']}</option>" for p in projects] [f"<option value='{p['id']}' {'selected' if project_id_int==p['id'] else ''}>{p['name']}</option>" for p in projects]
) )
items = "".join( rows = "".join(
[ [
f"<div class='card'><b>#{d['id']}</b> [{d['kind']}] {d['title']}<br><small>{d['project']} · {d['created_at']}</small><br>" f"<tr>"
f"<div class='row' style='margin-top:8px'>" f"<td>#{d['id']}</td>"
f"<a href='/document/{d['id']}' style='text-decoration:none'><button type='button'>👁️ Ansehen</button></a>" f"<td>{d['title']}</td>"
f"<td>{d['kind']}</td>"
f"<td>{d['project']}</td>"
f"<td><small>{d['created_at']}</small></td>"
f"<td class='row'>"
f"<a href='/document/{d['id']}' class='iconbtn' title='Ansehen'>👁️</a>"
f"<a href='/document/{d['id']}/download.md' class='iconbtn' title='Download'>⬇️</a>" f"<a href='/document/{d['id']}/download.md' class='iconbtn' title='Download'>⬇️</a>"
f"<a href='#' class='iconbtn' title='Umbenennen' onclick=\"libRename({d['id']}, {json.dumps(d['title'])});return false;\">✏️</a>" f"<a href='#' class='iconbtn' title='Umbenennen' onclick='libRename({d['id']}, {json.dumps(d['title'])});return false;'>✏️</a>"
f"<a href='#' class='iconbtn' title='Verschieben' onclick=\"libMove({d['id']});return false;\">📁</a>" f"<a href='#' class='iconbtn' title='Verschieben' onclick='libMove({d['id']});return false;'>📁</a>"
f"<a href='#' class='iconbtn' title='Löschen' onclick=\"libDelete({d['id']});return false;\">🗑️</a>" f"<a href='#' class='iconbtn' title='Löschen' onclick='libDelete({d['id']});return false;'>🗑️</a>"
f"</div></div>" f"</td>"
f"</tr>"
for d in docs for d in docs
] ]
) )
project_js = json.dumps([{"value": p["id"], "label": p["name"]} for p in projects], ensure_ascii=False) project_js = json.dumps([{"value": p["id"], "label": p["name"]} for p in projects], ensure_ascii=False)
body = f""" body = f"""
<h2>Datenbank / Dokumente</h2> <style>
<form method='get' class='card'> .toolbar{{display:flex;gap:8px;flex-wrap:wrap;align-items:center;margin-bottom:10px}}
<div class='row'> .toolbar .spacer{{flex:1}}
<label>Projekt:</label> .gridcard{{padding:0;overflow:auto}}
.grid{{width:100%;border-collapse:collapse;min-width:860px}}
.grid th,.grid td{{padding:10px 12px;border-bottom:1px solid #1f2937;text-align:left}}
.grid th{{position:sticky;top:0;background:#0b1222;color:#94a3b8;font-size:12px;text-transform:uppercase;letter-spacing:.04em}}
.grid tr:hover{{background:rgba(56,189,248,.06)}}
</style>
<h2 style='margin-bottom:6px'>Projekte · Dokumente</h2>
<div class='hint' style='margin-bottom:10px'>Ansicht im Projektlisten-Stil mit Schnellaktionen.</div>
<form method='get' class='card toolbar'>
<select name='project_id'>{p_opts}</select> <select name='project_id'>{p_opts}</select>
</div> <input name='q_title' placeholder='Titel enthält …' value='{title_q.replace("'", "&#39;")}' style='min-width:220px'>
<div class='row' style='margin-top:8px'> <input name='q_content' placeholder='Inhalt enthält …' value='{content_q.replace("'", "&#39;")}' style='min-width:260px'>
<input name='q_title' placeholder='Titel enthält …' value='{title_q.replace("'", "&#39;")}'>
<input name='q_content' placeholder='Inhalt enthält …' value='{content_q.replace("'", "&#39;")}'>
<button type='submit'>Filtern</button> <button type='submit'>Filtern</button>
</div> <a class='iconbtn' href='/library' title='Filter zurücksetzen'>↺</a>
<div class='spacer'></div>
<small>{len(docs)} Treffer</small>
</form> </form>
{items or '<p>Keine Einträge.</p>'} <div class='card gridcard'>
<table class='grid'>
<thead><tr><th>ID</th><th>Titel</th><th>Typ</th><th>Projekt</th><th>Erstellt</th><th>Aktionen</th></tr></thead>
<tbody>{rows or "<tr><td colspan='6'>Keine Einträge.</td></tr>"}</tbody>
</table>
</div>
<script> <script>
async function libPost(url, data) {{ async function libPost(url, data) {{
const r = await fetch(url, {{method:'POST', headers:{{'Content-Type':'application/x-www-form-urlencoded'}}, body:new URLSearchParams(data)}}); const r = await fetch(url, {{method:'POST', headers:{{'Content-Type':'application/x-www-form-urlencoded'}}, body:new URLSearchParams(data)}});