layout: 320 px ohne Ueberstand, Schubladen in voller Breite, Doppelklick-Sperre greift sofort
Befunde aus der Sichtpruefung (Attrappe des Backends, 320/768/1024/1440 px):
- Zaehlwerk: Das "H" ragte bei 320 px 30 px ueber sein Feld. Ziffern skalieren jetzt
mit der Feldbreite (Container-Einheiten), am PC bleibt es bei 38 x 56 px.
- Flugplan und Update-Verlauf: Der Text bekam schmal nur ~50 px und lief in den Zustand.
Schmales Feld: Zeit und Zustand oben, Text darunter (nach Feldbreite, nicht Bildschirm).
- Update-Zeilen am Handy: Name und Version stiessen aneinander ("BetriebssystemUbuntu"),
die Version steht jetzt darunter; scheitert die Pruefung, heisst sie "unbekannt" statt "-".
- Schubladen (Modell-Suche, Dienste, Einstellungen, Protokoll) waren am Handy nur 75 %
und am PC hoechstens 384 px breit - die shadcn-Grundklassen schlugen die eigenen.
- Doppelklick: Die Sperre beim Installieren haengt jetzt an einem Ref und greift sofort
(vorher starteten zwei Klicks im selben Takt zwei Downloads); die Ja-Knoepfe von
"Alles aktualisieren" und "Auftrag abbrechen" ignorieren den zweiten Klick.
- Balken eines abgebrochenen Downloads grau statt cyan.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
634ad27302
commit
a091ccb3b8
@@ -130,7 +130,9 @@ function BausteinZeile({ id, name, neuLautStart, fest, gesperrt, onStart, onFrei
|
||||
const neu = hatUpdate ? v?.neu ?? neuLautStart ?? null : null
|
||||
const summary = zusammenfassung(d?.summary)
|
||||
|
||||
const laeuftZelle = laedt ? <Skelett /> : <>{v?.laeuft ?? "–"}</>
|
||||
// Scheitert die Prüfung, kennt das Backend oft nicht einmal die laufende Version (Hermes: git fetch).
|
||||
const laeuftText = v && v.laeuft !== "–" ? v.laeuft : fehler ? "unbekannt" : "–"
|
||||
const laeuftZelle = laedt ? <Skelett /> : <>{laeuftText}</>
|
||||
const neuZelle = laedt ? (
|
||||
<Skelett breit="w-20" />
|
||||
) : neu ? (
|
||||
@@ -165,22 +167,22 @@ function BausteinZeile({ id, name, neuLautStart, fest, gesperrt, onStart, onFrei
|
||||
)
|
||||
}
|
||||
|
||||
// Am PC eine Tabellenzeile, am Handy ein Block: Name und Versionen oben, darunter was sich
|
||||
// ändert, darunter die Knöpfe — ohne seitliches Scrollen.
|
||||
// Am PC eine Tabellenzeile, am Handy ein Block: Name, darunter die Versionen, darunter was sich
|
||||
// ändert, darunter die Knöpfe — ohne seitliches Scrollen und ohne dass Name und Version aneinanderstoßen.
|
||||
return (
|
||||
<div
|
||||
role="row"
|
||||
aria-busy={laedt || undefined}
|
||||
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"
|
||||
className="grid grid-cols-1 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">
|
||||
<span role="cell" className="ziffern -mt-1 text-sm text-text-2 md:hidden">
|
||||
{laeuftZelle}
|
||||
{!laedt && (neu || fehler) && <> {neu ? "→" : "·"} {neuZelle}</>}
|
||||
</span>
|
||||
<span role="cell" className="ziffern hidden text-sm text-text-2 md:block">{laeuftZelle}</span>
|
||||
<span role="cell" className="ziffern hidden text-sm md:block">{neuZelle}</span>
|
||||
<div role="cell" className="col-span-2 text-sm leading-relaxed text-text-2 md:col-span-1">
|
||||
<div role="cell" className="text-sm leading-relaxed text-text-2">
|
||||
{fest && (
|
||||
<span className="mb-1.5 block text-bernstein">
|
||||
Festgehalten seit {fest.seit} auf {fest.version}: {fest.grund}. Der Sonntags-Lauf überspringt {name}.
|
||||
@@ -189,7 +191,7 @@ function BausteinZeile({ id, name, neuLautStart, fest, gesperrt, onStart, onFrei
|
||||
{was}
|
||||
</div>
|
||||
{(fest || hatUpdate) && (
|
||||
<span role="cell" className="col-span-2 flex flex-wrap gap-2 md:col-span-1 md:flex-col md:items-end">
|
||||
<span role="cell" className="flex flex-wrap gap-2 md:flex-col md:items-end">
|
||||
{fest && (
|
||||
<Button variant="outline" size="sm" onClick={onFreigeben}>
|
||||
Freigeben
|
||||
@@ -217,18 +219,18 @@ const PUNKT: Record<UpdateLauf["stufe"], string> = {
|
||||
function LaufEintrag({ lauf }: { lauf: UpdateLauf }) {
|
||||
return (
|
||||
<li className="flex flex-col gap-2 border-t border-linie py-3">
|
||||
{/* Handy: Zeit und Ergebnis oben, der Anlass darunter über die volle Breite. */}
|
||||
<div className="grid grid-cols-[minmax(0,1fr)_auto] items-center gap-x-3 gap-y-1 md:grid-cols-[112px_minmax(0,1fr)_auto]">
|
||||
{/* Schmales Feld: Zeit und Ergebnis oben, der Anlass darunter über die volle Breite. */}
|
||||
<div className="grid grid-cols-[minmax(0,1fr)_auto] items-center gap-x-3 gap-y-1 @sm:grid-cols-[112px_minmax(0,1fr)_auto]">
|
||||
<span className="ziffern col-start-1 row-start-1 text-sm text-text-3">{flugplanZeit(lauf.start)}</span>
|
||||
<span className="col-span-2 row-start-2 min-w-0 text-[15px] break-words md:col-span-1 md:col-start-2 md:row-start-1">
|
||||
<span className="col-span-2 row-start-2 min-w-0 text-[15px] break-words @sm:col-span-1 @sm:col-start-2 @sm:row-start-1">
|
||||
{lauf.anlass}
|
||||
</span>
|
||||
<span className="col-start-2 row-start-1 justify-self-end md:col-start-3">
|
||||
<span className="col-start-2 row-start-1 justify-self-end @sm:col-start-3">
|
||||
<Chip art={LAUF_ART[lauf.stufe]}>{lauf.titel}</Chip>
|
||||
</span>
|
||||
</div>
|
||||
{lauf.stufe !== "grau" && lauf.zeilen.length > 0 && (
|
||||
<ul className="m-0 flex list-none flex-col gap-1 p-0 md:pl-[124px]">
|
||||
<ul className="m-0 flex list-none flex-col gap-1 p-0 @sm:pl-[124px]">
|
||||
{lauf.zeilen.map((z) => (
|
||||
<li key={`${z.baustein}-${z.text}`} className="flex items-baseline gap-2 text-sm leading-snug text-text-2">
|
||||
<span aria-hidden className={cn("size-1.5 shrink-0 -translate-y-px rounded-full", PUNKT[z.stufe])} />
|
||||
@@ -322,7 +324,7 @@ export function UpdatesSeite() {
|
||||
verlaufInhalt = <p className="text-[15px] text-text-2">Noch keine Update-Läufe aufgezeichnet.</p>
|
||||
} else {
|
||||
verlaufInhalt = (
|
||||
<ol className="m-0 flex list-none flex-col p-0">
|
||||
<ol className="@container m-0 flex list-none flex-col p-0">
|
||||
{verlauf.data.laeufe.map((l) => <LaufEintrag key={l.start} lauf={l} />)}
|
||||
</ol>
|
||||
)
|
||||
@@ -416,7 +418,8 @@ export function UpdatesSeite() {
|
||||
gesperrt={gesperrt}
|
||||
onNein={() => setFrage(null)}
|
||||
onJa={() => {
|
||||
updateStarten.mutate("alle")
|
||||
// Die Abfrage auf `frage` fängt den zweiten Klick eines Doppelklicks: Dann ist sie schon null.
|
||||
if (frage?.art === "alle") updateStarten.mutate("alle")
|
||||
setFrage(null)
|
||||
}}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user