Add directory ZIP downloads to file browser

Expose a directory-only Download ZIP action in the file browser menu and make folder downloads use a stable .zip filename from the existing download endpoint.

Alessandro committed May 2, 2026 at 19:30 UTC ff1f26f6acc99e062641586a5ee0382fa2d71657
3 files changed +15 -3
api/download_work_dir_file.py
+4 -2
@@ -133,17 +133,19 @@ class DownloadFile(ApiHandler):
133
134 if file["is_dir"]:
135 zip_file = await runtime.call_development_function(files.zip_dir, file["abs_path"])
136 + directory_name = os.path.basename(file_path.rstrip("/")) or "directory"
137 + download_name = f"{directory_name}.zip"
138 if runtime.is_development():
139 b64 = await runtime.call_development_function(fetch_file, zip_file)
140 file_data = BytesIO(base64.b64decode(b64))
141 return stream_file_download(
142 file_data,
141 - download_name=os.path.basename(zip_file)
143 + download_name=download_name
144 )
145 else:
146 return stream_file_download(
147 zip_file,
146 - download_name=f"{os.path.basename(file_path)}.zip"
148 + download_name=download_name
149 )
150 elif file["is_file"]:
151 if runtime.is_development():
webui/components/modals/file-browser/file-browser-store.js
+1 -1
@@ -454,7 +454,7 @@ const model = {
454 downloadFile(file) {
455 const link = document.createElement("a");
456 link.href = `/api/download_work_dir_file?path=${encodeURIComponent(file.path)}`;
457 - link.download = file.name;
457 + link.download = file.is_dir ? `${file.name}.zip` : file.name;
458 document.body.appendChild(link);
459 link.click();
460 document.body.removeChild(link);
webui/components/modals/file-browser/file-browser.html
+10
@@ -93,6 +93,16 @@
93 <span>Edit</span>
94 </button>
95
96 + <button
97 + type="button"
98 + class="dropdown-item"
99 + x-show="file.is_dir"
100 + @click="$store.fileBrowser.downloadFile(file)"
101 + >
102 + <span class="material-symbols-outlined">folder_zip</span>
103 + <span>Download ZIP</span>
104 + </button>
105 +
106 <button
107 type="button"
108 class="dropdown-item"