feat: Studio bulk ops, perf fixes, bug fixes, confirm dialog visibility
CI / runtime-diagnostics (push) Skipped
CI / check (push) Successful in 34s
CI / release (push) Skipped
CI / deploy (push) Successful in 1m3s

Confirm Dialog:
- Overlay opacity 80% -> 95% (solid black)
- Card uses bg-surface with glow shadow ring-primary/40
- Added AlertTriangle icon for danger variant
- Removed backdrop-blur for maximum opacity

Studio features:
- Bulk delete: select imported items and delete in batch
- Bulk nitro regen: select items missing .nitro and regenerate all
- Added Trash2 and RefreshCw toolbar buttons for bulk actions

Performance:
- BatchProgress: React.memo + useMemo for entries/total/completed/percent
- BatchProgress: ETA interval uses useRef to avoid re-creation per completed
- CatalogRail: React.memo + useCallback for toggle
- Removed redundant double setBatchProgress calls
- Removed redundant new Map(initial) wrapping

Bug fixes:
- importBatch: stale batchDone closure always cleared progress panel (use ref)
- importBatch: added missing toast.error on HTTP failure
- bulkRegenNitro: now checks per-item results instead of marking all as succeeded
- single deleteItem: now removes classname from selected set
- retryFailed: clears progress panel on HTTP error and stream error
- Removed unused 'done' variable (2x) from cloneAllMissing/retryFailed

Lint:
- biome format fixes for selectedMissingNitro and setItems
This commit is contained in:
openhands committed 2026-09-01 19:07:20 +02:00
1 parent 4863f78795
commit 93601e58e0
4 files changed
+214 -45

No files matched your search

+5 -5
View File
@@ -1,12 +1,12 @@
"use client";
import { ChevronDown, ChevronRight, FolderTree } from "lucide-react";
import { useMemo, useState } from "react";
import { memo, useCallback, useMemo, useState } from "react";
import { cn } from "@/lib/utils";
import type { TreeNode } from "@/types/catalog";
export function CatalogRail({
export const CatalogRail = memo(function CatalogRail({
tree,
selectedId,
onSelect,
@@ -31,14 +31,14 @@ export function CatalogRail({
return tree.filter((n) => !hidden.has(n.id));
}, [tree, collapsed]);
const toggle = (id: number) => {
const toggle = useCallback((id: number) => {
setCollapsed((prev) => {
const next = new Set(prev);
if (next.has(id)) next.delete(id);
else next.add(id);
return next;
});
};
}, []);
return (
<aside className="flex h-full min-h-0 w-64 shrink-0 flex-col border-r border-[var(--admin-border)] bg-[var(--admin-surface)]">
@@ -100,4 +100,4 @@ export function CatalogRail({
</div>
</aside>
);
}
});