fix(admin): harden clothing/pets/effects/clone imports

Align grids on data.items, only treat SSE done as success, hard-fail
clothing sets when libs fail, and add Cancel via AbortController.

Co-authored-by: Cursor <[email protected]>
This commit is contained in:
SimoandCursor committed 2026-08-01 15:56:38 +02:00
1 parent 9c4949186c
commit 16191cef14
8 files changed
+344 -173

No files matched your search

+19 -5
View File
@@ -50,6 +50,7 @@ export async function runSseImport(
onDone: (classname: string) => void,
onComplete: (succeeded: number, failed: number) => void,
signal?: AbortSignal,
onFailed?: (classname: string, error?: string) => void,
): Promise<void> {
const res = await adminFetch(url, {
method: "POST",
@@ -57,8 +58,19 @@ export async function runSseImport(
body: JSON.stringify(body),
signal,
});
if (!res.ok) {
const data = await res.json().catch(() => ({}));
toast.error(
typeof data.error === "string"
? data.error
: `Import failed (${res.status})`,
);
onComplete(0, 0);
return;
}
if (!res.body) {
toast.error("No response stream");
onComplete(0, 0);
return;
}
@@ -68,11 +80,13 @@ export async function runSseImport(
await readSseStream(
res.body,
(evt) => {
if (
evt.type === "item_progress" &&
(evt.status === "done" || evt.status === "failed")
) {
onDone(String(evt.classname ?? ""));
if (evt.type === "item_progress") {
const classname = String(evt.classname ?? "");
if (evt.status === "done") {
onDone(classname);
} else if (evt.status === "failed") {
onFailed?.(classname, String(evt.error ?? ""));
}
}
if (evt.type === "batch_complete") {
succeeded = Number(evt.succeeded ?? 0);