778b35f15a
Deploy to VPS / deploy (push) Has been cancelled
The unified bucket browser graduated from "acceptable" to "actually
useful for bulk work". Editors can now manage dozens of files in a
single session without dragging each one through a modal.
NEW FEATURES (frontend)
1. BULK SELECTION
- Click on a file when nothing's selected → opens it as before.
- Click on the corner checkbox, or click the file once selection is
active → toggle that one in/out.
- Shift-click → range select between last anchor and current item.
- Cmd/Ctrl-click → toggle without affecting others.
- "Select all" toggle in the toolbar respects the search filter.
2. BULK ACTIONS TOOLBAR
When at least one file is selected the toolbar morphs into:
[N selected] [Delete] [Move to: Videos | Renders | …]
Delete fires the new bulk DELETE endpoint with filePaths[], shows
a single toast for the whole batch + per-file failure breakdown.
Move iterates PATCH /api/assets per file (sequential, with a 'Moving…'
indicator in the bucket helper bar).
3. DRAG TO MOVE BETWEEN BUCKETS
Drag any file (or the whole selection if you started the drag from
a selected file) onto another bucket tab. The tab highlights green
with 'drop to move' while you hover. Drop fires the same per-file
PATCH flow. No dialog, no friction.
4. RENAME IN PLACE
Double-click a filename (in either grid or list view) → input opens
in place. Enter saves, Escape cancels, blur saves. Sanitizes to
safe characters. PATCH endpoint refuses to overwrite an existing
file (returns 409, surfaced as a toast).
5. KEYBOARD HINT FOOTER
Bottom-of-modal cheat sheet: Click / ⇧Click / ⌘Click / 2× click /
drag onto another tab. So new editors don't have to discover the
power-user features.
NEW BACKEND (src/app/api/assets/route.ts)
PATCH method
{ scope, slug, fromPath, toPath } → fs.renameSync.
Used for both rename (same dir, new name) and move (different bucket).
Refuses to overwrite an existing destination (409 conflict).
Creates intermediate folders if needed.
DELETE extended
Now accepts either { filePath: "x" } or { filePaths: ["a", "b"] }.
Bulk path deletes one-by-one and returns per-file success/failure
so the UI can show a precise toast.
REVIEWED FOR REGRESSIONS
- Single-file API still works — old { filePath } DELETE shape preserved.
- The 4 inline AssetManager call sites (network, news, applications,
parts) use AssetBucketBrowser via the alias added in the previous
commit; their integration is unchanged. Same props, same onSelect
callback shape.
- Toast/Confirm calls go through the existing HqUiProvider mounted in
hq-command/layout.tsx — no extra wiring.