Promote develop → main (2026-07-25 22:22 UTC) #16

Zusammengeführt
IntelSight_Admin hat 41 Commits von develop nach main 2026-07-26 00:22:10 +02:00 zusammengeführt
3 geänderte Dateien mit 99 neuen und 33 gelöschten Zeilen
Nur Änderungen aus Commit bc3b0bb9ee werden angezeigt - Alle Commits anzeigen

Datei anzeigen

@@ -928,47 +928,75 @@ input[type="date"].filter-select { padding: 6px 10px; }
.health-run-item { display: inline-flex; align-items: center; gap: 8px; }
.health-run-item #healthRunInfo { font-size: 12px; }
/* Checkbox-Filterleisten (Standard fuer alle Filter im Portal) */
/* Checkbox-Dropdowns (Standard fuer alle Filter im Portal) */
.filter-bar {
display: flex;
flex-direction: column;
gap: 4px;
padding: 10px 14px;
align-items: flex-start;
gap: 8px;
flex-wrap: wrap;
margin-bottom: 14px;
}
.filter-dd { position: relative; }
.filter-dd-btn {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 7px 12px;
background: var(--bg-secondary);
border: 1px solid var(--border);
border-radius: 6px;
color: var(--text-primary);
font-size: 13px;
cursor: pointer;
}
.filter-dd-btn:hover { background: var(--bg-tertiary); }
.filter-dd-btn.has-selection { border-color: var(--accent); }
.filter-dd-count {
background: var(--accent);
color: #1A1A1A; /* Text auf Gold immer dunkel (ON_ACCENT) */
border-radius: 999px;
font-size: 11px;
font-weight: 700;
padding: 0 6px;
line-height: 16px;
}
.filter-dd-caret { font-size: 10px; color: var(--text-secondary); }
.filter-dd-panel {
display: none;
position: absolute;
top: calc(100% + 4px);
left: 0;
z-index: 60;
min-width: 210px;
max-height: 320px;
overflow-y: auto;
padding: 8px;
background: var(--bg-secondary);
border: 1px solid var(--border);
border-radius: 8px;
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
flex-direction: column;
gap: 2px;
}
.filter-group {
display: flex;
align-items: baseline;
gap: 4px 10px;
flex-wrap: wrap;
}
.filter-group-label {
font-size: 11px;
font-weight: 600;
color: var(--text-secondary);
text-transform: uppercase;
letter-spacing: 0.4px;
min-width: 92px;
cursor: default;
}
.filter-dd.open .filter-dd-panel { display: flex; }
[data-theme="light"] .filter-dd-panel { box-shadow: 0 8px 24px rgba(26, 26, 26, 0.18); }
.filter-check {
display: inline-flex;
display: flex;
align-items: center;
gap: 5px;
gap: 7px;
font-size: 13px;
cursor: pointer;
padding: 2px 7px;
padding: 4px 8px;
border-radius: 6px;
user-select: none;
white-space: nowrap;
}
.filter-check:hover { background: var(--bg-tertiary); }
.filter-check input {
accent-color: var(--accent);
cursor: pointer;
margin: 0;
flex-shrink: 0;
}
/* Checkbox-Spalte: nur sichtbar bei Herkunfts-Filter "Kundenquellen" */

Datei anzeigen

@@ -6,7 +6,7 @@
<title>AegisSight Monitor-Verwaltung</title>
<link rel="icon" type="image/svg+xml" href="/static/favicon.svg">
<link rel="apple-touch-icon" href="/static/favicon.svg">
<link rel="stylesheet" href="/static/css/style.css?v=20260725k">
<link rel="stylesheet" href="/static/css/style.css?v=20260725l">
<script>(function(){var t=localStorage.getItem('portal_theme');if(t==='light')document.documentElement.setAttribute('data-theme','light');try{var a=JSON.parse(localStorage.getItem('osint_a11y')||'{}');Object.keys(a).forEach(function(k){if(a[k])document.documentElement.setAttribute('data-a11y-'+k,'true');});}catch(e){}})()</script>
<style>
@@ -970,7 +970,7 @@
</div>
<script src="/static/js/a11y.js?v=20260725a"></script>
<script src="/static/js/app.js?v=20260725t"></script>
<script src="/static/js/app.js?v=20260725u"></script>
<script src="/static/js/sources.js?v=20260725e"></script>
<script src="/static/js/aufgaben.js?v=20260725b"></script>
<script src="/static/js/x-scraper.js?v=20260522a"></script>

Datei anzeigen

@@ -1375,18 +1375,30 @@ function populateSelect(el, items, allLabel) {
if (current && items.some(it => it.key === current)) el.value = current;
}
// Checkbox-Filtergruppe (Standard für alle Filter im Portal, statt Dropdowns).
// Checkbox-Dropdown (Standard für alle Filter im Portal). Ein Knopf mit dem
// Filternamen klappt eine Liste von Checkboxen auf (Mehrfachauswahl).
// selected ist ein Set mit den angehakten Keys. Nichts angehakt = keine
// Einschränkung. onChange wird nach jedem Toggle aufgerufen.
// Einschränkung. onChange wird nach jedem Toggle aufgerufen, das Panel
// bleibt dabei offen.
function renderFilterGroup(container, title, items, selected, onChange) {
if (!container) return;
const wrap = document.createElement("div");
wrap.className = "filter-group";
const lbl = document.createElement("span");
lbl.className = "filter-group-label";
lbl.textContent = title;
lbl.title = "Nichts angehakt = alle";
wrap.appendChild(lbl);
wrap.className = "filter-dd";
const btn = document.createElement("button");
btn.type = "button";
btn.className = "filter-dd-btn";
btn.title = "Nichts angehakt = alle";
const updateBtn = () => {
btn.innerHTML = esc(title)
+ (selected.size ? ` <span class="filter-dd-count">${selected.size}</span>` : "")
+ ' <span class="filter-dd-caret">&#9662;</span>';
btn.classList.toggle("has-selection", selected.size > 0);
};
updateBtn();
const panel = document.createElement("div");
panel.className = "filter-dd-panel";
(items || []).forEach((it) => {
const label = document.createElement("label");
label.className = "filter-check";
@@ -1396,15 +1408,41 @@ function renderFilterGroup(container, title, items, selected, onChange) {
cb.addEventListener("change", () => {
if (cb.checked) selected.add(it.key);
else selected.delete(it.key);
updateBtn();
onChange();
});
label.appendChild(cb);
label.appendChild(document.createTextNode(it.label));
wrap.appendChild(label);
panel.appendChild(label);
});
if (!(items || []).length) {
const empty = document.createElement("div");
empty.className = "text-muted";
empty.style.fontSize = "12px";
empty.textContent = "Keine Werte vorhanden";
panel.appendChild(empty);
}
btn.addEventListener("click", (e) => {
e.stopPropagation();
const wasOpen = wrap.classList.contains("open");
closeAllFilterDropdowns();
if (!wasOpen) wrap.classList.add("open");
});
panel.addEventListener("click", (e) => e.stopPropagation());
wrap.appendChild(btn);
wrap.appendChild(panel);
container.appendChild(wrap);
}
function closeAllFilterDropdowns() {
document.querySelectorAll(".filter-dd.open").forEach((el) => el.classList.remove("open"));
}
// Klick irgendwo anders schließt offene Filter-Dropdowns
document.addEventListener("click", () => closeAllFilterDropdowns());
document.addEventListener("DOMContentLoaded", () => {
// Beim Page-Load Meta einmalig laden (asynchron, blockiert nicht)
if (window.API && (localStorage.getItem("token") || window.location.pathname === "/dashboard")) {