add tag assign to documents batch

This commit is contained in:
team 1
2026-02-25 15:37:29 +01:00
parent 4b5ad9b338
commit 3e264cbff4
4 changed files with 269 additions and 3 deletions

View File

@@ -0,0 +1,144 @@
{% extends 'admin/base.html.twig' %}
{% block title %}Tag zuweisen{% endblock %}
{% block body %}
<div class="d-flex justify-content-between align-items-center mb-4">
<h1 class="h3 mb-0">
Tag: {{ tag.label }}
</h1>
<a href="{{ path('admin_tags_index') }}"
class="btn btn-sm btn-outline-secondary">
Zurück
</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');
const source = new EventSource("{{ path('admin_tags_rebuild_stream') }}");
source.onmessage = function (event) {
const data = JSON.parse(event.data);
let html = '';
if (data.status === '{{ statusRunning }}') {
html = `
<div class="alert alert-info shadow-sm d-flex justify-content-between align-items-center">
<div>
<strong>Tag-Rebuild läuft</strong><br>
${data.startedAt ? 'Gestartet: ' + new Date(data.startedAt).toLocaleString() : ''}
</div>
<div class="spinner-border spinner-border-sm"></div>
</div>
`;
} else if (data.status === '{{ statusQueued }}') {
html = `
<div class="alert alert-secondary shadow-sm">
<strong>Tag-Rebuild in Warteschlange</strong>
</div>
`;
} else if (data.status === '{{ statusCompleted }}') {
html = `
<div class="alert alert-success shadow-sm">
<strong>Tag-Rebuild erfolgreich abgeschlossen</strong>
</div>
`;
} else if (data.status === '{{ statusFailed }}') {
html = `
<div class="alert alert-danger shadow-sm">
<strong>Tag-Rebuild fehlgeschlagen</strong><br>
${data.error ? '<code>' + data.error + '</code>' : ''}
</div>
`;
}
statusBox.innerHTML = html;
};
source.onerror = function () {
console.warn('SSE Verbindung verloren');
};
</script>
{# ============================= #}
{# Flash Messages #}
{# ============================= #}
{% for message in app.flashes('success') %}
<div class="alert alert-success">
{{ message }}
</div>
{% endfor %}
{% for message in app.flashes('danger') %}
<div class="alert alert-danger">
{{ message }}
</div>
{% endfor %}
{# ============================= #}
{# Tag → Dokumente #}
{# ============================= #}
<form method="post">
<input type="hidden"
name="_token"
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 %}
<tr>
<td>
<input type="checkbox"
name="documents[]"
value="{{ doc.id }}"
{% if doc.id in assignedDocIds %}checked{% endif %}>
</td>
<td>
{{ doc.title }}
</td>
</tr>
{% else %}
<tr>
<td colspan="2" class="text-center text-muted">
Keine Dokumente vorhanden.
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
<button class="btn btn-primary mt-3">
Speichern
</button>
</form>
{% endblock %}

View File

@@ -158,16 +158,26 @@
<td><code>{{ tag.slug }}</code></td>
<td>{{ tag.description ?: '-' }}</td>
<td class="text-end">
<a href="{{ path('admin_tags_assign', { id: tag.id }) }}"
class="btn btn-sm btn-outline-info me-2">
Zuweisen
</a>
<form method="post"
action="{{ path('admin_tags_delete', {id: tag.id}) }}">
action="{{ path('admin_tags_delete', {id: tag.id}) }}"
style="display:inline-block;">
<input type="hidden"
name="_token"
value="{{ csrf_token('admin_tag_delete_' ~ tag.id) }}"/>
<button class="btn btn-sm btn-outline-danger"
onclick="return confirm('Tag wirklich löschen? Zuweisungen werden entfernt.')">
Löschen
</button>
</form>
</td>
</tr>
{% else %}