modelle: Aufraeumen auf Knopfdruck, geteilte Gewichte bleiben beim Loeschen liegen
Ampel / ampel (push) Failing after 21s
Ampel / ampel (push) Failing after 21s
Neuer Bereich "Aufraeumen" auf der Modelle-Seite: Eintraege ohne heutige Rolle und Ordner, auf die kein Eintrag zeigt, mit Groesse und Erklaerung (Rueckweg, Reserve, alte Drafts). Geloescht wird nur auf Knopfdruck mit Rueckfrage. delete_model loescht keine Dateien mehr, die ein anderer Eintrag nennt - seit den Bild-Zwillingen haette sonst das Loeschen eines Zwillings den Coder mitgerissen. Der Projektor des Hirn-Zwillings liegt jetzt neben den Hirn-Gewichten, damit der Original-Ordner loeschbar bleibt. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
133a491aca
commit
42363229d4
@@ -8,7 +8,7 @@ import { api, post } from "./api"
|
||||
import { melden } from "./meldungen"
|
||||
import { stromVerbunden } from "./strom"
|
||||
import type {
|
||||
AktionsErgebnis, Job, Modell, Nutzung, Radar, Sicherung, Start,
|
||||
AktionsErgebnis, AufraeumKandidat, Job, Modell, Nutzung, Radar, Sicherung, Start,
|
||||
} from "./typen"
|
||||
|
||||
const takt = (ms: number) => () => (stromVerbunden() ? ms * 5 : ms)
|
||||
@@ -146,6 +146,19 @@ export const useUpdateStarten = () =>
|
||||
neuLaden: ["jobs", "start"],
|
||||
})
|
||||
|
||||
export const useAufraeumen = () =>
|
||||
useQuery({
|
||||
queryKey: ["aufraeumen"],
|
||||
queryFn: () => api<{ kandidaten: AufraeumKandidat[] }>("/api/modelle/aufraeumen"),
|
||||
staleTime: 60_000,
|
||||
})
|
||||
|
||||
export const useAufraeumenLoeschen = () =>
|
||||
useAktion(
|
||||
(k: AufraeumKandidat) => post<AktionsErgebnis>("/api/modelle/aufraeumen/loeschen", { art: k.art, name: k.name }),
|
||||
{ erfolg: (_, e) => (e as AktionsErgebnis).text ?? "Gelöscht.", neuLaden: ["aufraeumen", "models", "start"] },
|
||||
)
|
||||
|
||||
export const useFreigeben = () =>
|
||||
useAktion(
|
||||
(baustein: string) => post<AktionsErgebnis>(`/api/updates/festgehalten/${encodeURIComponent(baustein)}/freigeben`),
|
||||
|
||||
@@ -82,6 +82,14 @@ export interface Festgehalten {
|
||||
grund: string
|
||||
}
|
||||
|
||||
/** Etwas auf der Modell-Platte, das ungenutzt Platz belegt (Box-Wart, Aufräumen). */
|
||||
export interface AufraeumKandidat {
|
||||
art: "eintrag" | "ordner"
|
||||
name: string
|
||||
groesse_gb: number
|
||||
hinweis: string
|
||||
}
|
||||
|
||||
export interface AktionsErgebnis {
|
||||
ok: boolean
|
||||
text?: string
|
||||
|
||||
@@ -5,11 +5,12 @@ import { Chip, type ChipArt, Zustandsfeld } from "@/components/cockpit/Chip"
|
||||
import { Panel } from "@/components/cockpit/Panel"
|
||||
import { Button } from "@/components/ui/button"
|
||||
import {
|
||||
useModellLaden, useModelle, useNutzung, useRadar, useRadarAktion, useRadarSuche, useStart,
|
||||
useAufraeumen, useAufraeumenLoeschen, useModellLaden, useModelle, useNutzung, useRadar, useRadarAktion,
|
||||
useRadarSuche, useStart,
|
||||
} from "@/lib/abfragen"
|
||||
import { messwert, RADAR_STATUS_TEXT, rolleVon } from "@/lib/anzeige"
|
||||
import { useLetzteMetrik } from "@/lib/strom"
|
||||
import type { Modell, Nutzung, RadarKandidat, RadarTest } from "@/lib/typen"
|
||||
import type { AufraeumKandidat, Modell, Nutzung, RadarKandidat, RadarTest } from "@/lib/typen"
|
||||
import { flugplanZeit, gb, gbText, zahl } from "@/lib/zeit"
|
||||
import { ModellSuche } from "./ModellSuche"
|
||||
|
||||
@@ -273,6 +274,65 @@ function RadarPanel({ hirn, coder }: { hirn: string | undefined; coder: string |
|
||||
)
|
||||
}
|
||||
|
||||
/** Was ungenutzt Platz belegt. Gelöscht wird nur auf Knopfdruck, mit Rückfrage — Löschen ist endgültig. */
|
||||
function AufraeumenPanel() {
|
||||
const liste = useAufraeumen()
|
||||
const loeschen = useAufraeumenLoeschen()
|
||||
const [frage, setFrage] = useState<AufraeumKandidat | null>(null)
|
||||
const kandidaten = liste.data?.kandidaten ?? []
|
||||
const summe = kandidaten.reduce((s, k) => s + k.groesse_gb, 0)
|
||||
if (liste.isError) return null
|
||||
return (
|
||||
<Panel
|
||||
titel="Aufräumen"
|
||||
rechts={kandidaten.length > 0
|
||||
? <span className="ziffern text-sm text-text-2">bis zu {summe.toLocaleString("de-DE", { maximumFractionDigits: 0 })} GB frei</span>
|
||||
: undefined}
|
||||
>
|
||||
<p className="-mt-2 text-sm text-text-2">
|
||||
Modelle und Ordner, die gerade niemand nutzt. Nichts davon wird von selbst gelöscht, das entscheidest du je Eintrag.
|
||||
</p>
|
||||
{liste.isPending ? (
|
||||
<p className="text-[15px] text-text-2">Wird gelesen …</p>
|
||||
) : kandidaten.length === 0 ? (
|
||||
<p className="text-[15px] text-text-2">Nichts aufzuräumen.</p>
|
||||
) : (
|
||||
<ul className="m-0 flex list-none flex-col p-0">
|
||||
{kandidaten.map((k) => (
|
||||
<li key={`${k.art}-${k.name}`} className="flex flex-wrap items-center justify-between gap-3 border-t border-linie py-3">
|
||||
<span className="flex min-w-0 flex-1 flex-col gap-1">
|
||||
<span className="flex flex-wrap items-center gap-2">
|
||||
<span className="ziffern text-sm break-all">{k.name}</span>
|
||||
<Chip>{k.art === "eintrag" ? "Eintrag" : "Ordner"}</Chip>
|
||||
</span>
|
||||
<span className="text-sm text-text-2">{k.hinweis}</span>
|
||||
</span>
|
||||
<span className="flex items-center gap-3">
|
||||
<span className="ziffern text-sm text-text-2">{k.groesse_gb.toLocaleString("de-DE")} GB</span>
|
||||
<Button variant="gefahr" size="sm" disabled={loeschen.isPending} onClick={() => setFrage(k)}>
|
||||
Löschen
|
||||
</Button>
|
||||
</span>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
)}
|
||||
<Bestaetigen
|
||||
offen={frage !== null}
|
||||
gefahr
|
||||
titel={`${frage?.name ?? ""} löschen?`}
|
||||
text={`${frage?.hinweis ?? ""} Es werden ${frage?.groesse_gb.toLocaleString("de-DE") ?? ""} GB frei. Das lässt sich nicht rückgängig machen — zurück ginge es nur mit einem neuen Download.`}
|
||||
knopf="Endgültig löschen"
|
||||
onNein={() => setFrage(null)}
|
||||
onJa={() => {
|
||||
if (frage) loeschen.mutate(frage)
|
||||
setFrage(null)
|
||||
}}
|
||||
/>
|
||||
</Panel>
|
||||
)
|
||||
}
|
||||
|
||||
export function ModelleSeite() {
|
||||
const modelle = useModelle()
|
||||
const nutzung = useNutzung()
|
||||
@@ -324,6 +384,7 @@ export function ModelleSeite() {
|
||||
))}
|
||||
</ul>
|
||||
</Panel>
|
||||
<AufraeumenPanel />
|
||||
<ModellSuche offen={suche} onSchliessen={() => setSuche(false)} />
|
||||
</>
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user