Refactor case detail and document view

Introduce a `DocumentTemplate` struct for rendering the document view,
replacing inline HTML.
Introduce a `CaseFlags` struct to encapsulate the logic for determining
various UI states of a case (e.g., `has_document`, `analyzing`,
`can_close`, `llm_missing`).
Update `handle_case_detail` to use `compute_flags` for populating the
`CaseDetailTemplate`.
Update `scan_user_cases` to compute `analyzing` and `has_document` flags
for the `UserCaseView`.
Add new template logic in `case_detail.html` to display actions based on
`CaseFlags`.
Add new template logic in `my_cases.html` to display `analyzing` and
`done-doc` labels for cases.
Create a new `document.html` template.
Add a helper function `any_document_exists` to check for the presence of
a document file.
This commit is contained in:
2026-04-15 19:25:59 +02:00
parent aed4cd59d3
commit 4b554f04ff
5 changed files with 141 additions and 11 deletions
+18
View File
@@ -20,6 +20,12 @@ header form { margin: 0; }
.status-badge { display: inline-block; padding: 0.1em 0.6em; border-radius: 999px; font-size: 0.8em; font-weight: bold; color: white; }
.status-badge.open { background: #4a90e2; }
.status-badge.done { background: #7ed321; }
.actions { margin: 1em 0 1.5em; }
.actions form { margin: 0; display: inline; }
.actions button { font-size: 1em; padding: 0.5em 1em; }
.actions a.doc-link { display: inline-block; padding: 0.5em 1em; background: #7ed321; color: white; text-decoration: none; border-radius: 4px; font-weight: bold; }
.actions .analyzing { color: #888; font-style: italic; }
.actions .llm-missing { color: #a66; font-style: italic; }
</style>
</head>
<body>
@@ -36,6 +42,18 @@ header form { margin: 0; }
{% endmatch %}
<div class="meta">{{ case_id }}</div>
<div class="actions">
{% if has_document %}
<a class="doc-link" href="/web/cases/{{ case_id }}/document">Ergebnis öffnen</a>
{% else if analyzing %}
<span class="analyzing">wird analysiert …</span>
{% else if can_close %}
<form method="post" action="/web/cases/{{ case_id }}/close"><button type="submit">Fall abschließen</button></form>
{% else if llm_missing %}
<span class="llm-missing">LLM-Analyse nicht konfiguriert</span>
{% endif %}
</div>
<h2>Aufnahmen ({{ recordings.len() }})</h2>
{% for rec in recordings %}
<div class="recording{% if rec.failed %} failed-row{% endif %}">
+24
View File
@@ -0,0 +1,24 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="utf-8">
<title>Doctate — Dokument v{{ version }}</title>
<style>
body { font-family: sans-serif; max-width: 900px; margin: 2em auto; padding: 0 1em; }
header { display: flex; justify-content: space-between; align-items: center; }
header form { margin: 0; }
.back { color: #4a90e2; text-decoration: none; }
pre { white-space: pre-wrap; font-family: serif; font-size: 1.05em; line-height: 1.5; background: #f6f6f6; padding: 1em; border-radius: 4px; }
.meta { color: #666; font-family: monospace; font-size: 0.9em; margin-bottom: 1em; }
</style>
</head>
<body>
<header>
<div><a class="back" href="/web/cases/{{ case_id }}">&larr; Zurück zum Fall</a></div>
<form method="post" action="/web/logout"><button type="submit">Logout</button></form>
</header>
<h1>Dokument v{{ version }}</h1>
<div class="meta">{{ case_id }}</div>
<pre>{{ content }}</pre>
</body>
</html>
+5 -2
View File
@@ -17,6 +17,9 @@ header form { margin: 0; }
section { margin: 1.5em 0; }
section h2 { font-size: 1.1em; color: #555; border-bottom: 1px solid #ddd; padding-bottom: 0.2em; }
.empty { color: #888; font-style: italic; }
.label { display: inline-block; margin-left: 0.6em; padding: 0.05em 0.5em; border-radius: 999px; font-size: 0.75em; font-weight: bold; }
.label.analyzing { background: #eee; color: #555; }
.label.done-doc { background: #7ed321; color: white; }
</style>
</head>
<body>
@@ -32,7 +35,7 @@ section h2 { font-size: 1.1em; color: #555; border-bottom: 1px solid #ddd; paddi
{% else %}
{% for case in open %}
<a class="case status-{{ case.status }}" href="/web/cases/{{ case.case_id }}">
<h2>{{ case.case_id_short }} — {{ case.recordings.len() }} Aufnahme(n)</h2>
<h2>{{ case.case_id_short }} — {{ case.recordings.len() }} Aufnahme(n){% if case.has_document %}<span class="label done-doc">ausgewertet</span>{% else if case.analyzing %}<span class="label analyzing">wird analysiert</span>{% endif %}</h2>
{% match case.oneliner %}
{% when Some with (t) %}
<div class="oneliner">{{ t }}</div>
@@ -51,7 +54,7 @@ section h2 { font-size: 1.1em; color: #555; border-bottom: 1px solid #ddd; paddi
{% else %}
{% for case in done %}
<a class="case status-{{ case.status }}" href="/web/cases/{{ case.case_id }}">
<h2>{{ case.case_id_short }} — {{ case.recordings.len() }} Aufnahme(n)</h2>
<h2>{{ case.case_id_short }} — {{ case.recordings.len() }} Aufnahme(n){% if case.has_document %}<span class="label done-doc">ausgewertet</span>{% else if case.analyzing %}<span class="label analyzing">wird analysiert</span>{% endif %}</h2>
{% match case.oneliner %}
{% when Some with (t) %}
<div class="oneliner">{{ t }}</div>