optimize tag and rebuilding
This commit is contained in:
@@ -5,80 +5,179 @@
|
||||
{% block body %}
|
||||
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
<h1 class="h3">Tags</h1>
|
||||
<h1 class="h3 mb-0">Tag-Management</h1>
|
||||
</div>
|
||||
|
||||
{# ========================================================= #}
|
||||
{# Flash Messages #}
|
||||
{# ========================================================= #}
|
||||
{% for message in app.flashes('success') %}
|
||||
<div class="alert alert-success">{{ message }}</div>
|
||||
<div class="alert alert-success shadow-sm">{{ message }}</div>
|
||||
{% endfor %}
|
||||
{% for message in app.flashes('danger') %}
|
||||
<div class="alert alert-danger">{{ message }}</div>
|
||||
<div class="alert alert-danger shadow-sm">{{ message }}</div>
|
||||
{% endfor %}
|
||||
|
||||
<div class="card bg-black border-secondary mb-4 text-light">
|
||||
{# ========================================================= #}
|
||||
{# LIVE REBUILD STATUS (SSE) #}
|
||||
{# ========================================================= #}
|
||||
|
||||
<div id="rebuild-status">
|
||||
{% if latestJob %}
|
||||
<div class="alert alert-secondary shadow-sm">
|
||||
Status wird geladen…
|
||||
</div>
|
||||
{% endif %}
|
||||
</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>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>Rebuild in Warteschlange</strong>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
else if (data.status === '{{ statusCompleted }}') {
|
||||
html = `
|
||||
<div class="alert alert-success shadow-sm">
|
||||
<strong>Rebuild erfolgreich abgeschlossen</strong>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
else if (data.status === '{{ statusFailed }}') {
|
||||
html = `
|
||||
<div class="alert alert-danger shadow-sm">
|
||||
<strong>Rebuild fehlgeschlagen</strong><br>
|
||||
${data.error ? '<code>' + data.error + '</code>' : ''}
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
statusBox.innerHTML = html;
|
||||
};
|
||||
|
||||
source.onerror = function () {
|
||||
console.warn('SSE Verbindung verloren');
|
||||
};
|
||||
</script>
|
||||
|
||||
{# ========================================================= #}
|
||||
{# Create Tag Card #}
|
||||
{# ========================================================= #}
|
||||
<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>
|
||||
|
||||
<form method="post" action="{{ path('admin_tags_create') }}" class="row g-2">
|
||||
<form method="post" action="{{ path('admin_tags_create') }}" class="row g-3">
|
||||
<input type="hidden" name="_token" value="{{ csrf_token('admin_tag_create') }}"/>
|
||||
|
||||
<div class="col-md-3">
|
||||
<input class="form-control form-control-sm" name="label" placeholder="Label (z.B. Testomat 808)" required />
|
||||
<label class="form-label small text-muted">Label</label>
|
||||
<input class="form-control form-control-sm"
|
||||
name="label"
|
||||
placeholder="z. B. Testomat 808"
|
||||
required />
|
||||
</div>
|
||||
|
||||
<div class="col-md-3">
|
||||
<input class="form-control form-control-sm" name="slug" placeholder="Slug (z.B. testomat-808)" required />
|
||||
<label class="form-label small text-muted">Slug</label>
|
||||
<input class="form-control form-control-sm"
|
||||
name="slug"
|
||||
placeholder="z. B. testomat-808"
|
||||
required />
|
||||
</div>
|
||||
|
||||
<div class="col-md-4">
|
||||
<input class="form-control form-control-sm" name="description" placeholder="Beschreibung (optional)" />
|
||||
<label class="form-label small text-muted">Beschreibung</label>
|
||||
<input class="form-control form-control-sm"
|
||||
name="description"
|
||||
placeholder="Optional" />
|
||||
</div>
|
||||
|
||||
<div class="col-md-2 d-grid">
|
||||
<button class="btn btn-sm btn-outline-info" type="submit">Anlegen</button>
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<small class="text-light">
|
||||
Hinweis: Nach Änderungen an Tags/Zuweisungen bitte <code>bin/console mto:agent:tags:rebuild</code> ausführen.
|
||||
</small>
|
||||
<div class="col-md-2 d-grid align-items-end">
|
||||
<button class="btn btn-sm btn-outline-info">
|
||||
Anlegen
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card bg-black border-secondary text-light">
|
||||
{# ========================================================= #}
|
||||
{# Tag Table #}
|
||||
{# ========================================================= #}
|
||||
<div class="card bg-black border-secondary text-light shadow-sm">
|
||||
<div class="card-body p-0">
|
||||
|
||||
<div class="px-3 py-2 border-bottom border-secondary">
|
||||
<strong>Vorhandene Tags</strong>
|
||||
<span class="text-muted small ms-2">
|
||||
{{ tags|length }} Einträge
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<table class="table table-dark table-striped table-hover mb-0 align-middle">
|
||||
<thead class="table-secondary text-dark">
|
||||
<tr>
|
||||
<th>Label</th>
|
||||
<th>Slug</th>
|
||||
<th>Beschreibung</th>
|
||||
<th class="text-end">Aktion</th>
|
||||
<th style="width: 25%">Label</th>
|
||||
<th style="width: 25%">Slug</th>
|
||||
<th style="width: 35%">Beschreibung</th>
|
||||
<th class="text-end" style="width: 15%">Aktion</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for tag in tags %}
|
||||
<tr>
|
||||
<td>{{ tag.label }}</td>
|
||||
<td class="fw-semibold">{{ tag.label }}</td>
|
||||
<td><code>{{ tag.slug }}</code></td>
|
||||
<td class="text-light">{{ tag.description ?: '' }}</td>
|
||||
<td>{{ tag.description ?: '-' }}</td>
|
||||
<td class="text-end">
|
||||
<form method="post" action="{{ path('admin_tags_delete', {id: tag.id}) }}" style="display:inline">
|
||||
<input type="hidden" name="_token" value="{{ csrf_token('admin_tag_delete_' ~ tag.id) }}"/>
|
||||
<button class="btn btn-sm btn-outline-danger" type="submit"
|
||||
onclick="return confirm('Tag wirklich löschen? (Zuweisungen werden mit gelöscht)')">
|
||||
<form method="post"
|
||||
action="{{ path('admin_tags_delete', {id: tag.id}) }}">
|
||||
<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 %}
|
||||
<tr><td colspan="4" class="text-light p-3">Noch keine Tags vorhanden.</td></tr>
|
||||
<tr>
|
||||
<td colspan="4" class="p-4 text-center text-muted">
|
||||
Noch keine Tags vorhanden.
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user