Drop files anywhere on a browse page; if the current scope is inside
a working/, staging/, or incoming/ subtree the files are PUT to the
current directory via the existing file API. Per-file ACL is enforced
server-side (authorizeAction); a 403 surfaces as a per-file error
toast and the rest of the batch proceeds.
UX:
- dragenter → semi-transparent overlay with a dashed-border panel
showing the destination path. Hides immediately on dragleave or
drop.
- drop → "Uploading N files…" toast, then per-file failure toasts
inline, then a summary toast (success / partial / all-failed).
- listing auto-refreshes after the batch so new files appear in
the tree without a manual reload.
Scope:
- upload-eligible paths are matched by /\/(working|staging|incoming)
(\/|$)/i — same convention as the new grid-mode URL token.
- 256 MiB per-file cap (UPLOAD_MAX_BYTES) since browse's single-
body PUT loads the file as a Blob in the tab; larger uploads
should use a dedicated client.
- Outside the upload-eligible set the overlay never appears; drops
are silently ignored (drag effect = none).
Sequential uploads keep progress predictable; parallel batching can
land later if needed. The module hooks document-level dragenter/leave
/over/drop so it works regardless of which pane the user drags over.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>