fix(webui): Bugtracker-Tabellen nutzen die Bildschirmbreite und stehen still
Vier Ursachen fuer ein Bild, das gestaucht und verschoben aussah: 1. .main-content war bei 1600px gedeckelt. Auf einem 2000px-Schirm blieb rechts ein leerer Streifen, waehrend acht Spalten sich links draengten. Jetzt 2400px - ganz ohne Grenze wandert das Auge bei 3400px quer ueber den Tisch. 2. Ohne table-layout:fixed verteilte der Browser die Breite nach Inhalt. Eine lange Exception-Meldung oder ein Pfad wie "public/api/bugtracker/v1/manage/index.php:407" zog die Titelspalte auf und quetschte den Rest - je Zeile anders weit, weshalb die Spalten von oben nach unten wanderten. Das war das "Verschobene". Die schmalen Spalten haben jetzt feste Breiten, "Projekt & Titel" bekommt bewusst keine und damit den Rest: Sie waechst mit dem Bildschirm, gemessen 1079px bei 2000px Viewport. 3. Die Aktionsknoepfe brachen um, weil die Zelle enger wurde als ihr Inhalt - Stift oben, Lupe und Haken darunter. Feste Spaltenbreite plus nowrap. 4. min-width:0 auf .main-content. Der unscheinbare, aber wichtigere Teil: body ist ein Flex-Container, .main-content also ein Flex-Element mit min-width:auto - es weigerte sich, unter seine Inhaltsbreite zu schrumpfen. Eine breite Tabelle schob deshalb die ganze SEITE quer, statt im eigenen Behaelter zu scrollen, und beim Scrollen wanderte die Seitenleiste aus dem Bild. Der Titel wird per CSS nach zwei Zeilen gekuerzt statt per mb_strimwidth nach 90 Zeichen - eine feste Zeichenzahl ist auf einem breiten Schirm zu wenig und auf einem schmalen zu viel. Der vollstaendige Text haengt im title=. Nachgemessen im Browser gegen das echte Stylesheet, bei 1250px und 2000px: Seite laeuft nicht mehr quer, die Tabelle bekommt bei Bedarf ihre eigene Leiste, Knoepfe bleiben einreihig, 94% Breitenausnutzung. Gilt fuer die Item-Liste und den Fehlerstrom - dieselbe Tabelle, dieselben Ursachen. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
57aa0bc5be
commit
7fff13ee20
+112
-27
@@ -2249,7 +2249,30 @@ $csrfField = Csrf::field();
|
||||
.btn-autorefresh { background: rgba(255,255,255,0.04); border: 1px solid var(--border-glass); color: var(--text-main); font-size: 0.75rem; font-weight: 700; padding: 0.5rem 0.85rem; border-radius: 8px; cursor: pointer; display: flex; align-items: center; gap: 0.5rem; transition: all 0.2s; font-family: 'Roboto Mono', monospace; }
|
||||
.btn-autorefresh.active { background: rgba(18,212,138,0.15); border-color: var(--success); color: var(--success); }
|
||||
|
||||
.main-content { padding: 1.75rem 2rem; max-width: 1600px; }
|
||||
/*
|
||||
Die Obergrenze lag bei 1600px. Auf einem breiten Schirm blieb rechts
|
||||
ein leerer Streifen, waehrend die Tabellen links zusammengedrueckt
|
||||
standen - besonders im Bugtracker, wo eine Zeile acht Spalten hat.
|
||||
|
||||
Ganz ohne Grenze wird es allerdings unlesbar: Bei 3400px wandert das
|
||||
Auge von der Item-Nummer bis zur Statusspalte quer ueber den Tisch.
|
||||
2400px ist der Kompromiss - fuellt jeden ueblichen Schirm und
|
||||
bremst erst darueber.
|
||||
*/
|
||||
/*
|
||||
min-width:0 ist der unscheinbare Teil und der wichtigere.
|
||||
|
||||
body ist ein Flex-Container (Seitenleiste + Inhalt), .main-content
|
||||
also ein Flex-Element - und die haben von Haus aus min-width:auto,
|
||||
weigern sich also, unter ihre Inhaltsbreite zu schrumpfen. Folge:
|
||||
Eine breite Tabelle schob den ganzen Inhaltsbereich auf, statt in
|
||||
ihrem eigenen Behaelter zu scrollen, und die SEITE lief quer. Damit
|
||||
wandert beim Scrollen auch die Seitenleiste aus dem Bild.
|
||||
|
||||
Mit min-width:0 gibt .main-content nach, und .tabelle-scroll tut,
|
||||
wofuer es da ist.
|
||||
*/
|
||||
.main-content { padding: 1.75rem 2rem; max-width: 2400px; min-width: 0; }
|
||||
|
||||
/* Stats & KPI Grid */
|
||||
.stats-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 1.25rem; margin-bottom: 1.75rem; }
|
||||
@@ -2350,6 +2373,49 @@ $csrfField = Csrf::field();
|
||||
*/
|
||||
.hilfe { cursor: help; border-bottom: 1px dotted rgba(255,255,255,0.28); }
|
||||
|
||||
/* ---------------------------------------------------------------
|
||||
Breite Datentabellen (Bugtracker, Fehlerstrom)
|
||||
|
||||
Ohne table-layout:fixed verteilt der Browser die Breite nach
|
||||
Inhalt. Eine einzige lange Exception-Meldung oder ein Dateipfad
|
||||
wie "public/api/bugtracker/v1/manage/index.php:407" zog damit die
|
||||
Titelspalte auf und quetschte alle anderen zusammen - je Zeile
|
||||
anders, weshalb die Spalten von oben nach unten wanderten.
|
||||
|
||||
Mit fester Verteilung stehen die schmalen Spalten still, und die
|
||||
Titelspalte bekommt, was uebrig ist. Sie muss dafuer kuerzen
|
||||
koennen - siehe .zelle-titel.
|
||||
--------------------------------------------------------------- */
|
||||
.tabelle-scroll { overflow-x: auto; }
|
||||
table.tabelle-fest { table-layout: fixed; min-width: 1180px; }
|
||||
table.tabelle-fest td { overflow-wrap: anywhere; }
|
||||
|
||||
/*
|
||||
Der Titel wird nach zwei Zeilen abgeschnitten, nicht nach einer:
|
||||
Eine Exception-Meldung ist in der ersten Zeile oft nur Namensraum
|
||||
und sagt noch nichts. Der vollstaendige Text haengt im title=.
|
||||
*/
|
||||
.zelle-titel .titel {
|
||||
display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
|
||||
overflow: hidden; color: #fff; font-weight: 700;
|
||||
}
|
||||
.zelle-titel .meta {
|
||||
font-size: 0.75rem; color: var(--text-muted); margin-top: 0.25rem;
|
||||
display: flex; flex-wrap: wrap; gap: 0.4rem; align-items: center;
|
||||
overflow: hidden;
|
||||
}
|
||||
/* Ein langer Dateipfad darf die Zeile nicht in die Hoehe treiben. */
|
||||
.zelle-titel .meta .badge { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
||||
|
||||
/*
|
||||
Die Knoepfe brachen um, weil die Zelle enger wurde als ihr Inhalt -
|
||||
daher das Verschobene im Screenshot: Stift oben, Lupe und Haken in
|
||||
der Zeile darunter. Sie bleiben jetzt in einer Reihe, und die Spalte
|
||||
ist breit genug dafuer.
|
||||
*/
|
||||
.zelle-aktionen { white-space: nowrap; }
|
||||
.zelle-aktionen > div { display: flex; gap: 0.3rem; flex-wrap: nowrap; }
|
||||
|
||||
.tab-content, .subtab-content { display: none; }
|
||||
.tab-content.active, .subtab-content.active { display: block; }
|
||||
</style>
|
||||
@@ -4667,17 +4733,26 @@ chmod +x update-agent
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<table>
|
||||
<!--
|
||||
Die Breiten stehen hier und nicht im Stylesheet, weil
|
||||
sie zu dieser Tabelle gehoeren und zu keiner anderen.
|
||||
"Projekt & Titel" bekommt bewusst keine: Bei
|
||||
table-layout:fixed nimmt die Spalte ohne Angabe den
|
||||
Rest - sie waechst also mit dem Bildschirm, waehrend
|
||||
die uebrigen stehen bleiben.
|
||||
-->
|
||||
<div class="tabelle-scroll">
|
||||
<table class="tabelle-fest">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID / Typ</th>
|
||||
<th>Umgebung</th>
|
||||
<th style="width:92px;">ID / Typ</th>
|
||||
<th style="width:96px;">Umgebung</th>
|
||||
<th>Projekt & Titel</th>
|
||||
<th>Build</th>
|
||||
<th>Schweregrad</th>
|
||||
<th>Anzahl</th>
|
||||
<th>Status</th>
|
||||
<th>Aktionen</th>
|
||||
<th style="width:104px;">Build</th>
|
||||
<th style="width:124px;">Schweregrad</th>
|
||||
<th style="width:82px;">Anzahl</th>
|
||||
<th style="width:160px;">Status</th>
|
||||
<th style="width:150px;">Aktionen</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="btTableBody">
|
||||
@@ -4735,9 +4810,9 @@ chmod +x update-agent
|
||||
<tr class="bt-row">
|
||||
<td>#<?= (int)$item['id'] ?><br><?= $typeBadge ?></td>
|
||||
<td><?= $envBadge ?></td>
|
||||
<td>
|
||||
<strong style="color:#fff;"><?= e((string)$item['title']) ?></strong>
|
||||
<div style="font-size:0.75rem; color:var(--text-muted); margin-top:0.2rem; display:flex; flex-wrap:wrap; gap:0.4rem; align-items:center;">
|
||||
<td class="zelle-titel">
|
||||
<div class="titel" title="<?= e((string)$item['title']) ?>"><?= e((string)$item['title']) ?></div>
|
||||
<div class="meta">
|
||||
<span>Projekt: <code><?= e((string)$item['project_slug']) ?></code></span>
|
||||
<span>Von: <?= e((string)$item['created_by']) ?></span>
|
||||
<span title="Zuletzt gesehen"><?= e(dc_ago($item['last_seen_at'] ?? null)) ?></span>
|
||||
@@ -4770,9 +4845,9 @@ chmod +x update-agent
|
||||
</span>
|
||||
</td>
|
||||
<td><?= $statusBadge ?></td>
|
||||
<td>
|
||||
<div style="display:flex; gap:0.3rem; flex-wrap:wrap;">
|
||||
<button type="button" class="btn btn-sm btn-secondary" onclick="openEditBugtrackerModal(<?= $jsonItem ?>)">✏️</button>
|
||||
<td class="zelle-aktionen">
|
||||
<div>
|
||||
<button type="button" class="btn btn-sm btn-secondary" title="Bearbeiten" onclick="openEditBugtrackerModal(<?= $jsonItem ?>)">✏️</button>
|
||||
<button type="button" class="btn btn-sm btn-secondary" onclick="openBugtrackerModal(<?= (int)$item['id'] ?>)">🔍</button>
|
||||
<?php if (!in_array((string)$item['status'], ['resolved', 'closed'], true)): ?>
|
||||
<button type="button" class="btn btn-sm" onclick="openResolveModal(<?= (int)$item['id'] ?>, <?= $jsTitle ?>)">✔</button>
|
||||
@@ -4792,6 +4867,7 @@ chmod +x update-agent
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<?php if ($bugtrackerPages > 1): ?>
|
||||
<div style="display:flex; justify-content:space-between; align-items:center; margin-top:1rem; padding-top:1rem; border-top:1px solid var(--border-soft);">
|
||||
@@ -5003,16 +5079,20 @@ chmod +x update-agent
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<table>
|
||||
<!-- Dieselbe feste Verteilung wie im Bugtracker: Ohne sie zieht
|
||||
eine lange Exception-Meldung die Fehlerspalte auf und quetscht
|
||||
den Rest zusammen, je Zeile unterschiedlich weit. -->
|
||||
<div class="tabelle-scroll">
|
||||
<table class="tabelle-fest">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Klasse</th>
|
||||
<th style="width:110px;">Klasse</th>
|
||||
<th>Fehler</th>
|
||||
<th>Projekt / Umgebung</th>
|
||||
<th>Build</th>
|
||||
<th>Anzahl</th>
|
||||
<th>Zuletzt</th>
|
||||
<th>Aktionen</th>
|
||||
<th style="width:180px;">Projekt / Umgebung</th>
|
||||
<th style="width:104px;">Build</th>
|
||||
<th style="width:82px;">Anzahl</th>
|
||||
<th style="width:120px;">Zuletzt</th>
|
||||
<th style="width:150px;">Aktionen</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@@ -5045,9 +5125,13 @@ chmod +x update-agent
|
||||
?>
|
||||
<tr style="<?= $isIgnored ? 'opacity:0.55;' : '' ?>">
|
||||
<td><?= $levelBadge ?></td>
|
||||
<td>
|
||||
<strong style="color:#fff;"><?= e(mb_strimwidth((string)$item['title'], 0, 90, '…')) ?></strong>
|
||||
<div style="font-size:0.72rem; color:var(--text-muted); margin-top:0.2rem; display:flex; flex-wrap:wrap; gap:0.4rem; align-items:center;">
|
||||
<td class="zelle-titel">
|
||||
<?php // Kein mb_strimwidth mehr - die Kuerzung macht jetzt CSS,
|
||||
// und zwar passend zur tatsaechlichen Spaltenbreite. 90 Zeichen
|
||||
// waren auf einem breiten Schirm zu wenig und auf einem
|
||||
// schmalen zu viel. ?>
|
||||
<div class="titel" title="<?= e((string)$item['title']) ?>"><?= e((string)$item['title']) ?></div>
|
||||
<div class="meta">
|
||||
<?php if ($isIgnored): ?>
|
||||
<span class="badge" style="background:rgba(255,255,255,0.06); font-size:0.68rem;">
|
||||
🔇 stummgeschaltet<?= !empty($item['ignore_rule_id']) ? ' (Regel #' . (int)$item['ignore_rule_id'] . ')' : '' ?>
|
||||
@@ -5074,8 +5158,8 @@ chmod +x update-agent
|
||||
</span>
|
||||
</td>
|
||||
<td style="font-size:0.75rem; color:var(--text-muted);"><?= e(dc_ago($item['last_seen_at'] ?? null)) ?></td>
|
||||
<td>
|
||||
<div style="display:flex; gap:0.3rem; flex-wrap:wrap;">
|
||||
<td class="zelle-aktionen">
|
||||
<div>
|
||||
<button type="button" class="btn btn-sm btn-secondary"
|
||||
onclick="openBugtrackerModal(<?= (int)$item['id'] ?>)" title="Details">🔍</button>
|
||||
|
||||
@@ -5095,6 +5179,7 @@ chmod +x update-agent
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<?php if ($errorPages > 1): ?>
|
||||
<div style="display:flex; justify-content:space-between; align-items:center; margin-top:1rem; padding-top:1rem; border-top:1px solid var(--border-soft);">
|
||||
|
||||
Reference in New Issue
Block a user