optimize ux

This commit is contained in:
team 1
2026-04-05 19:37:50 +02:00
parent 41d4e1991d
commit bd818f5228
15 changed files with 323 additions and 271 deletions

View File

@@ -4,9 +4,18 @@
{% block body %}
{# ========================================================= #}
{# LIVE REBUILD STATUS (SSE) #}
{# ========================================================= #}
<div id="rebuild-status" class="mb-5">
<div class="alert alert-secondary shadow-sm">
Status wird geladen…
</div>
</div>
<div class="d-flex justify-content-between align-items-center mb-4">
<h1 class="h3 mb-0">
Tag: {{ tag.label }}
<i class="bi bi-tag-fill"></i> Tag: {{ tag.label }}
</h1>
<a href="{{ path('admin_tags_index') }}"
@@ -15,15 +24,6 @@
</a>
</div>
{# ========================================================= #}
{# LIVE REBUILD STATUS (SSE) #}
{# ========================================================= #}
<div id="rebuild-status">
<div class="alert alert-secondary shadow-sm">
Status wird geladen…
</div>
</div>
<script>
const statusBox = document.getElementById('rebuild-status');
@@ -37,7 +37,7 @@
html = `
<div class="alert alert-info shadow-sm d-flex justify-content-between align-items-center">
<div>
<strong>Tag-Rebuild läuft</strong><br>
Tag-Rebuild läuft<br>
${data.startedAt ? 'Gestartet: ' + new Date(data.startedAt).toLocaleString() : ''}
</div>
<div class="spinner-border spinner-border-sm"></div>
@@ -46,19 +46,19 @@
} else if (data.status === '{{ statusQueued }}') {
html = `
<div class="alert alert-secondary shadow-sm">
<strong>Tag-Rebuild in Warteschlange</strong>
Tag-Rebuild in Warteschlange
</div>
`;
} else if (data.status === '{{ statusCompleted }}') {
html = `
<div class="alert alert-success shadow-sm">
<strong>Tag-Rebuild erfolgreich abgeschlossen</strong>
<i class="bi bi-check-lg"></i> Tag-Rebuild erfolgreich abgeschlossen
</div>
`;
} else if (data.status === '{{ statusFailed }}') {
html = `
<div class="alert alert-danger shadow-sm">
<strong>Tag-Rebuild fehlgeschlagen</strong><br>
Tag-Rebuild fehlgeschlagen<br>
${data.error ? '<code>' + data.error + '</code>' : ''}
</div>
`;
@@ -99,39 +99,64 @@
value="{{ csrf_token('assign_tag_' ~ tag.id) }}">
<div class="card bg-black border-secondary">
<div class="card-body p-0">
<table class="table table-dark table-striped table-hover mb-0 align-middle">
<thead class="table-secondary text-dark">
<tr>
<th style="width:60px;"></th>
<th>Dokument</th>
</tr>
</thead>
<tbody>
{% for doc in documents %}
<div class="card-body p-0 row">
<div class=" col-lg-6">
<table class="table table-dark table-striped table-hover mb-0 align-middle">
<thead class="table-secondary text-dark">
<tr>
<td>
<input type="checkbox"
name="documents[]"
value="{{ doc.id }}"
{% if doc.id in assignedDocIds %}checked{% endif %}>
</td>
<td>
{{ doc.title }}
</td>
<th style="width:60px;"><i class="bi bi-three-dots"></i></th>
<th>Zugewiesene Dokumente</th>
</tr>
{% else %}
<tr>
<td colspan="2" class="text-center text-muted">
Keine Dokumente vorhanden.
</td>
</tr>
{% endfor %}
</tbody>
</table>
</thead>
<tbody>
{% for doc in documents %}
{% if doc.id in assignedDocIds %}
<tr>
<td>
<input type="checkbox"
name="documents[]"
value="{{ doc.id }}"
checked>
</td>
<td>
{{ doc.title }}
</td>
</tr>
{% endif %}
{% endfor %}
</tbody>
</table>
</div>
<div class=" col-lg-6">
<table class="table table-dark table-striped table-hover mb-0 align-middle col-lg-6">
<thead class="table-secondary text-dark">
<tr>
<th style="width:60px;"><i class="bi bi-three-dots"></i></th>
<th>Nicht zugewiesene Dokumente</th>
</tr>
</thead>
<tbody>
{% for doc in documents %}
{% if doc.id not in assignedDocIds %}
<tr>
<td>
<input type="checkbox"
name="documents[]"
value="{{ doc.id }}"
>
</td>
<td class="opacity-50">
{{ doc.title }}
</td>
</tr>
{% endif %}
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>

View File

@@ -4,75 +4,79 @@
{% block body %}
<div class="d-flex justify-content-between align-items-center mb-4">
<h1 class="h3 mb-0">Tag-Management</h1>
</div>
{# ========================================================= #}
{# LIVE REBUILD STATUS (SSE) #}
{# ========================================================= #}
<div id="rebuild-status">
<div id="rebuild-status" class="mb-5">
{% if latestJob %}
<div class="alert alert-secondary shadow-sm">
Status wird geladen…
</div>
{% endif %}
</div>
<div class="d-flex justify-content-between align-items-center mb-4">
<h1 class="h3 mb-0"><i class="bi bi-tag-fill"></i> Tag-Management</h1>
</div>
{# ========================================================= #}
{# TAG SYSTEM DESCRIPTION #}
{# ========================================================= #}
<div class="card bg-black border-secondary text-light mb-4 shadow-sm">
<div class="card-body">
<h5 class="text-info mb-3">Was machen Tags im System?</h5>
<div class="card bg-dark border-secondary text-light mb-4 shadow-sm">
<div class="card-body row">
<div class="col-lg-6">
<h5 class="text-info mb-3">Was machen Tags im System?</h5>
<p class="small text-light mb-2">
Tags dienen als semantische Routing-Ebene innerhalb des RAG-Systems.
Sie strukturieren Dokumente thematisch und beeinflussen,
welche Inhalte bei einer Nutzeranfrage priorisiert werden.
</p>
<p class="small text-light mb-2">
Tags dienen als semantische Routing-Ebene innerhalb des RAG-Systems.
Sie strukturieren Dokumente thematisch und beeinflussen,
welche Inhalte bei einer Nutzeranfrage priorisiert werden.
</p>
<ul class="small text-light mb-3">
<li>
Tags werden Dokumenten manuell zugewiesen.
</li>
<li>
Beim Rebuild wird aus allen Tags eine eigene
<code>tags.ndjson</code> erzeugt.
</li>
<li>
Zusätzlich wird ein separater Vektorindex
(<code>vector_tags.index</code>) aufgebaut.
</li>
<li>
Bei einer Anfrage erfolgt zunächst ein Tag-Matching,
danach wird das Chunk-Retrieval entsprechend gewichtet.
</li>
</ul>
<ul class="small text-light mb-3">
<li>
Tags werden Dokumenten manuell zugewiesen.
</li>
<li>
Beim Rebuild wird aus allen Tags eine eigene
<code>tags.ndjson</code> erzeugt.
</li>
<li>
Zusätzlich wird ein separater Vektorindex
(<code>vector_tags.index</code>) aufgebaut.
</li>
<li>
Bei einer Anfrage erfolgt zunächst ein Tag-Matching,
danach wird das Chunk-Retrieval entsprechend gewichtet.
</li>
</ul>
</div>
<div class="col-lg-6">
<h6 class="text-info mt-3">Wie werden Tags bewertet?</h6>
<h6 class="text-info mt-3">Wie werden Tags bewertet?</h6>
<p class="small text-light mb-2">
Die Bewertung erfolgt über einen eigenen Vektor-Similarity-Score
im Tag-Index. Das System berechnet:
</p>
<p class="small text-light mb-2">
Die Bewertung erfolgt über einen eigenen Vektor-Similarity-Score
im Tag-Index. Das System berechnet:
</p>
<ul class="small text-light">
<li>
Ähnlichkeit zwischen Nutzeranfrage und Tag-Embedding
</li>
<li>
Top-K Treffer im Tag-Index
</li>
<li>
Gewichtete Übergabe an das Chunk-Retrieval
</li>
</ul>
<ul class="small text-light">
<li>
Ähnlichkeit zwischen Nutzeranfrage und Tag-Embedding
</li>
<li>
Top-K Treffer im Tag-Index
</li>
<li>
Gewichtete Übergabe an das Chunk-Retrieval
</li>
</ul>
<p class="small text-light mt-2 mb-0">
Tags wirken somit als semantischer Verstärker.
Sie ersetzen kein Chunk-Retrieval, sondern steuern dessen Priorisierung.
</p>
<p class="small text-light mt-2 mb-0">
Tags wirken somit als semantischer Verstärker.
Sie ersetzen kein Chunk-Retrieval, sondern steuern dessen Priorisierung.
</p>
</div>
</div>
</div>
@@ -88,7 +92,7 @@
html = `
<div class="alert alert-info shadow-sm d-flex justify-content-between align-items-center">
<div>
<strong>Tag-Rebuild läuft</strong><br>
Tag-Rebuild läuft<br>
${data.startedAt ? 'Gestartet: ' + new Date(data.startedAt).toLocaleString() : ''}
</div>
<div class="spinner-border spinner-border-sm"></div>
@@ -97,19 +101,19 @@
} else if (data.status === '{{ statusQueued }}') {
html = `
<div class="alert alert-secondary shadow-sm">
<strong>Tag-Rebuild in Warteschlange</strong>
Tag-Rebuild in Warteschlange
</div>
`;
} else if (data.status === '{{ statusCompleted }}') {
html = `
<div class="alert alert-success shadow-sm">
<strong>Tag-Rebuild erfolgreich abgeschlossen</strong>
<i class="bi bi-check-lg"></i> Tag-Rebuild erfolgreich abgeschlossen
</div>
`;
} else if (data.status === '{{ statusFailed }}') {
html = `
<div class="alert alert-danger shadow-sm">
<strong>Tag-Rebuild fehlgeschlagen</strong><br>
Tag-Rebuild fehlgeschlagen<br>
${data.error ? '<code>' + data.error + '</code>' : ''}
</div>
`;
@@ -128,7 +132,7 @@
{# ========================================================= #}
<div class="card bg-black border-secondary text-light mb-4 shadow-sm">
<div class="card-body">
<h5 class="text-info mb-3">Neuen Tag erstellen</h5>
<h5 class="text-info mb-3">Neuen Tag hinzufügen</h5>
<form method="post" action="{{ path('admin_tags_create') }}" class="row g-3">
<input type="hidden" name="_token" value="{{ csrf_token('admin_tag_create') }}"/>
@@ -179,10 +183,10 @@
{# Tag Table #}
{# ========================================================= #}
<div class="card bg-black border-secondary text-light shadow-sm">
<div class="card-body p-0">
<div class="card-body">
<div class="px-3 py-2 border-bottom border-secondary">
<strong>Vorhandene Tags</strong>
<div class="mb-3">
<strong class="text-info">Vorhandene Tags:</strong>
<span class="text-muted small ms-2">
{{ tags|length }} Einträge
</span>