boxwart: Updates-Tabelle am Handy als Bloecke, Knoepfe ohne seitliches Scrollen erreichbar
Ampel / ampel (push) Failing after 20s

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Hitonabi
2026-09-23 22:01:51 +02:00
co-authored by Claude Opus 5.5
parent 7135042752
commit ed6948429a
11 changed files with 55 additions and 48 deletions
+43 -36
View File
@@ -34,21 +34,31 @@ function BausteinZeile({ id, name, hatUpdate, fest, onStart, onFreigeben, laeuft
const was = !hatUpdate
? "Aktuell."
: data?.summary?.trim() || (id === "os" && data?.count ? "Paketliste unten in den Details." : isPending ? "Wird gelesen …" : "")
const neuText = neu ? <span className="text-cyan">{neu}</span> : <span className="text-text-3"></span>
// Am PC eine Tabellenzeile, am Handy ein Block: Name und Versionen oben, darunter was sich
// ändert, darunter die Knöpfe — ohne seitliches Scrollen.
return (
<tr className="border-t border-linie align-top">
<th scope="row" className="py-3.5 pr-4 text-left font-sans text-[15px] font-semibold">{name}</th>
<td className="ziffern py-3.5 pr-4 text-sm text-text-2">{v.laeuft}</td>
<td className="ziffern py-3.5 pr-4 text-sm">{neu ? <span className="text-cyan">{neu}</span> : <span className="text-text-3"></span>}</td>
<td className="py-3.5 pr-4 text-sm leading-relaxed text-text-2">
<div
role="row"
className="grid grid-cols-[minmax(0,1fr)_auto] items-baseline gap-x-4 gap-y-2 border-t border-linie py-3.5 md:grid-cols-[170px_100px_170px_minmax(0,1fr)_auto] md:items-start"
>
<span role="rowheader" className="text-[15px] font-semibold">{name}</span>
<span role="cell" className="ziffern text-right text-sm text-text-2 md:hidden">
{v.laeuft}
{neu && <> {neuText}</>}
</span>
<span role="cell" className="ziffern hidden text-sm text-text-2 md:block">{v.laeuft}</span>
<span role="cell" className="ziffern hidden text-sm md:block">{neuText}</span>
<span role="cell" className="col-span-2 text-sm leading-relaxed text-text-2 md:col-span-1">
{fest && (
<span className="mb-1.5 block text-bernstein">
Festgehalten seit {fest.seit} auf {fest.version}: {fest.grund}. Der Sonntags-Lauf überspringt {name}.
</span>
)}
<span className="line-clamp-3 whitespace-pre-line">{was}</span>
</td>
<td className="py-2.5 text-right">
<span className="inline-flex flex-col items-end gap-2">
</span>
{(fest || hatUpdate) && (
<span role="cell" className="col-span-2 flex flex-wrap gap-2 md:col-span-1 md:flex-col md:items-end">
{fest && (
<Button variant="outline" size="sm" onClick={onFreigeben}>
Freigeben
@@ -60,8 +70,8 @@ function BausteinZeile({ id, name, hatUpdate, fest, onStart, onFreigeben, laeuft
</Button>
)}
</span>
</td>
</tr>
)}
</div>
)
}
@@ -156,32 +166,29 @@ export function UpdatesSeite() {
{start.isPending ? (
<Zustandsfeld text="Updates werden gelesen …" />
) : (
<div className="overflow-x-auto">
<table className="w-full min-w-[680px] border-collapse">
<thead>
<tr className="schild text-left text-xs text-text-3">
<th scope="col" className="pb-2 font-semibold">Baustein</th>
<th scope="col" className="pb-2 font-semibold">Läuft</th>
<th scope="col" className="pb-2 font-semibold">Neu</th>
<th scope="col" className="pb-2 font-semibold">Was sich ändert</th>
<th scope="col" className="pb-2 text-right font-semibold"><span className="sr-only">Aktion</span></th>
</tr>
</thead>
<tbody>
{BAUSTEINE.map((b) => (
<BausteinZeile
key={b.id}
id={b.id}
name={b.name}
hatUpdate={mitUpdate.has(b.id)}
fest={festgehalten.get(b.id)}
laeuftGerade={laeuft}
onStart={() => updateStarten.mutate(b.id)}
onFreigeben={() => freigeben.mutate(b.id)}
/>
))}
</tbody>
</table>
<div role="table" aria-label="Bausteine und ihre Updates" className="flex flex-col">
<div
role="row"
className="schild hidden grid-cols-[170px_100px_170px_minmax(0,1fr)_auto] gap-x-4 pb-2 text-xs font-semibold text-text-3 md:grid"
>
<span role="columnheader">Baustein</span>
<span role="columnheader">Läuft</span>
<span role="columnheader">Neu</span>
<span role="columnheader">Was sich ändert</span>
<span role="columnheader" className="sr-only">Aktion</span>
</div>
{BAUSTEINE.map((b) => (
<BausteinZeile
key={b.id}
id={b.id}
name={b.name}
hatUpdate={mitUpdate.has(b.id)}
fest={festgehalten.get(b.id)}
laeuftGerade={laeuft}
onStart={() => updateStarten.mutate(b.id)}
onFreigeben={() => freigeben.mutate(b.id)}
/>
))}
</div>
)}
{wartungsJobs.length > 0 && (