Promote develop → main (2026-05-09 15:05 UTC) #2
@@ -715,7 +715,7 @@
|
|||||||
|
|
||||||
<script src="/static/js/app.js?v=20260509d"></script>
|
<script src="/static/js/app.js?v=20260509d"></script>
|
||||||
<script src="/static/js/sources.js?v=20260509d"></script>
|
<script src="/static/js/sources.js?v=20260509d"></script>
|
||||||
<script src="/static/js/source-health.js?v=20260509g"></script>
|
<script src="/static/js/source-health.js?v=20260509h"></script>
|
||||||
<script src="/static/js/audit.js?v=20260509d"></script>
|
<script src="/static/js/audit.js?v=20260509d"></script>
|
||||||
<div id="toastContainer" class="toast-container" aria-live="polite" aria-atomic="true"></div>
|
<div id="toastContainer" class="toast-container" aria-live="polite" aria-atomic="true"></div>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
@@ -143,13 +143,13 @@ function renderHealthDashboard() {
|
|||||||
<tr>
|
<tr>
|
||||||
<td><span class="badge badge-suggestion-${s.suggestion_type}">${SUGGESTION_TYPE_LABELS[s.suggestion_type] || s.suggestion_type}</span></td>
|
<td><span class="badge badge-suggestion-${s.suggestion_type}">${SUGGESTION_TYPE_LABELS[s.suggestion_type] || s.suggestion_type}</span></td>
|
||||||
<td>${esc(s.title)}</td>
|
<td>${esc(s.title)}</td>
|
||||||
<td class="text-secondary" style="max-width:300px;">${esc(s.description || "")}</td>
|
<td class="text-secondary" style="max-width:300px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;" title="${esc(s.description || "")}">${esc(s.description || "")}</td>
|
||||||
<td><span class="badge badge-priority-${s.priority}">${PRIORITY_LABELS[s.priority] || s.priority}</span></td>
|
<td><span class="badge badge-priority-${s.priority}">${PRIORITY_LABELS[s.priority] || s.priority}</span></td>
|
||||||
<td class="text-secondary">${formatDateTime(s.created_at)}</td>
|
<td class="text-secondary">${formatDateTime(s.created_at)}</td>
|
||||||
<td style="white-space:nowrap;">
|
<td style="white-space:nowrap;">
|
||||||
${s.suggestion_type === "deactivate_source" && s.source_id ? `<button class="btn btn-secondary btn-small" data-source-id="${s.source_id}" data-source-name="${esc(s.title.split(':')[0] || s.title)}" onclick="searchFix(this)">Lösung suchen</button> ` : ""}
|
${s.suggestion_type === "deactivate_source" && s.source_id ? `<button class="btn btn-secondary btn-small" data-source-id="${s.source_id}" data-source-name="${esc(s.title.split(':')[0] || s.title)}" onclick="searchFix(this)" title="Lösung suchen">🔍</button> ` : ""}
|
||||||
<button class="btn btn-success btn-small" onclick="handleSuggestion(${s.id}, true)">Annehmen</button>
|
<button class="btn btn-success btn-small" onclick="handleSuggestion(${s.id}, true)" title="Annehmen">✓</button>
|
||||||
<button class="btn btn-danger btn-small" onclick="handleSuggestion(${s.id}, false)">Ablehnen</button>
|
<button class="btn btn-danger btn-small" onclick="handleSuggestion(${s.id}, false)" title="Ablehnen">×</button>
|
||||||
</td>
|
</td>
|
||||||
</tr>`,
|
</tr>`,
|
||||||
)
|
)
|
||||||
@@ -166,20 +166,23 @@ function renderHealthDashboard() {
|
|||||||
</div>`;
|
</div>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Vergangene Vorschläge
|
// Vergangene Vorschläge - eingeklappt by default, weil rein historisch.
|
||||||
let historyHtml = "";
|
let historyHtml = "";
|
||||||
if (recentSuggestions.length > 0) {
|
if (recentSuggestions.length > 0) {
|
||||||
|
const shown = recentSuggestions.slice(0, 20);
|
||||||
historyHtml = `
|
historyHtml = `
|
||||||
<div class="card" style="margin-bottom:16px;">
|
<details class="card" style="margin-bottom:16px;">
|
||||||
<div class="card-header"><h2>Verlauf</h2></div>
|
<summary style="cursor:pointer; padding:14px 18px; list-style:none;">
|
||||||
<div class="table-wrap">
|
<span style="color:var(--accent, #C8A851); font-weight:600; font-size:1.02rem;">Verlauf</span>
|
||||||
|
<span class="text-secondary" style="font-size:13px; margin-left:8px;">(${recentSuggestions.length} erledigte Vorschläge - klick zum Aufklappen)</span>
|
||||||
|
</summary>
|
||||||
|
<div class="table-wrap" style="border-top:1px solid var(--border, rgba(255,255,255,0.08));">
|
||||||
<table>
|
<table>
|
||||||
<thead>
|
<thead>
|
||||||
<tr><th>Typ</th><th>Titel</th><th>Status</th><th>Bearbeitet</th></tr>
|
<tr><th>Typ</th><th>Titel</th><th>Status</th><th>Bearbeitet</th></tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
${recentSuggestions
|
${shown
|
||||||
.slice(0, 20)
|
|
||||||
.map(
|
.map(
|
||||||
(s) => `
|
(s) => `
|
||||||
<tr>
|
<tr>
|
||||||
@@ -193,7 +196,7 @@ function renderHealthDashboard() {
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>`;
|
</details>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Health-Check Ergebnisse
|
// Health-Check Ergebnisse
|
||||||
@@ -268,22 +271,27 @@ function renderHealthDashboard() {
|
|||||||
<div class="table-wrap">
|
<div class="table-wrap">
|
||||||
<table>
|
<table>
|
||||||
<thead>
|
<thead>
|
||||||
<tr><th>Quelle</th><th>Domain</th><th>Typ</th><th>Org</th><th>Sprache</th><th>Status</th><th>Details</th><th>Aktionen</th></tr>
|
<tr><th>Quelle</th><th>Typ</th><th>Org</th><th>Status</th><th>Details</th><th>Aktion</th></tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
${filtered
|
${filtered
|
||||||
.map(
|
.map(
|
||||||
(c) => `
|
(c) => {
|
||||||
|
// Domain + Sprache in Tooltip vom Quellnamen, statt eigene Spalten.
|
||||||
|
const tipParts = [];
|
||||||
|
if (c.domain) tipParts.push(c.domain);
|
||||||
|
if (c.language) tipParts.push(c.language);
|
||||||
|
const nameTip = tipParts.length ? ` title="${esc(tipParts.join(" · "))}"` : "";
|
||||||
|
return `
|
||||||
<tr>
|
<tr>
|
||||||
<td>${esc(c.name)}</td>
|
<td${nameTip}>${esc(c.name)}</td>
|
||||||
<td class="text-secondary">${esc(c.domain || "-")}</td>
|
|
||||||
<td>${CHECK_TYPE_LABELS[c.check_type] || c.check_type}</td>
|
<td>${CHECK_TYPE_LABELS[c.check_type] || c.check_type}</td>
|
||||||
<td class="text-secondary">${c.tenant_id == null ? '<span style="color:#94a3b8;">global</span>' : esc(c.org_name || ("Org " + c.tenant_id))}</td>
|
<td class="text-secondary">${c.tenant_id == null ? '<span style="color:#94a3b8;">global</span>' : esc(c.org_name || ("Org " + c.tenant_id))}</td>
|
||||||
<td class="text-secondary">${esc(c.language || "-")}</td>
|
|
||||||
<td><span class="badge badge-health-${c.status}">${c.status === "error" ? "Fehler" : (c.status === "warning" ? "Warnung" : "OK")}</span></td>
|
<td><span class="badge badge-health-${c.status}">${c.status === "error" ? "Fehler" : (c.status === "warning" ? "Warnung" : "OK")}</span></td>
|
||||||
<td class="text-secondary" style="max-width:250px;" title="${esc(c.message || "")}">${esc(c.message || "")}</td>
|
<td class="text-secondary" style="max-width:300px;" title="${esc(c.message || "")}">${esc(c.message || "")}</td>
|
||||||
<td>${c.status === "error" && c.check_type === "reachability" ? `<button class="btn btn-secondary btn-small" data-source-id="${c.source_id}" data-source-name="${esc(c.name)}" onclick="searchFix(this)">Lösung suchen</button>` : ""}</td>
|
<td>${c.status === "error" && c.check_type === "reachability" ? `<button class="btn btn-secondary btn-small" data-source-id="${c.source_id}" data-source-name="${esc(c.name)}" onclick="searchFix(this)" title="Lösung suchen">🔍</button>` : ""}</td>
|
||||||
</tr>`,
|
</tr>`;
|
||||||
|
}
|
||||||
)
|
)
|
||||||
.join("")}
|
.join("")}
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|||||||
In neuem Issue referenzieren
Einen Benutzer sperren