feat: B4 - progressbar bij single file
This commit is contained in:
Binary file not shown.
Binary file not shown.
@@ -229,14 +229,18 @@ class UiSmokeGoldenTest(unittest.TestCase):
|
|||||||
self.assertIn('function closeFeedbackModal()', app_js)
|
self.assertIn('function closeFeedbackModal()', app_js)
|
||||||
self.assertIn('function downloadModalElements()', app_js)
|
self.assertIn('function downloadModalElements()', app_js)
|
||||||
self.assertIn('function isZipDownloadSelection(items)', app_js)
|
self.assertIn('function isZipDownloadSelection(items)', app_js)
|
||||||
|
self.assertIn('function singleFileDownloadRequestKey(path)', app_js)
|
||||||
self.assertIn('function archiveTaskStatusLabel(status)', app_js)
|
self.assertIn('function archiveTaskStatusLabel(status)', app_js)
|
||||||
self.assertIn('function archiveTaskCountText(task)', app_js)
|
self.assertIn('function archiveTaskCountText(task)', app_js)
|
||||||
self.assertIn('function archiveTaskCurrentItemText(task)', app_js)
|
self.assertIn('function archiveTaskCurrentItemText(task)', app_js)
|
||||||
self.assertIn('function archiveTaskProgressPercent(task)', app_js)
|
self.assertIn('function archiveTaskProgressPercent(task)', app_js)
|
||||||
self.assertIn('function openZipDownloadModal(selectedItems)', app_js)
|
self.assertIn('function openZipDownloadModal(selectedItems)', app_js)
|
||||||
|
self.assertIn('function openSingleFileDownloadModal(selectedItem)', app_js)
|
||||||
self.assertIn('function markZipDownloadReady(fileName)', app_js)
|
self.assertIn('function markZipDownloadReady(fileName)', app_js)
|
||||||
self.assertIn('function markZipDownloadFailed(err)', app_js)
|
self.assertIn('function markZipDownloadFailed(err)', app_js)
|
||||||
self.assertIn('function markZipDownloadCancelled()', app_js)
|
self.assertIn('function markZipDownloadCancelled()', app_js)
|
||||||
|
self.assertIn('function markSingleFileDownloadRequested(fileName, path)', app_js)
|
||||||
|
self.assertIn('function markSingleFileDownloadFailed(err, selectedItem)', app_js)
|
||||||
self.assertIn('function closeDownloadModal()', app_js)
|
self.assertIn('function closeDownloadModal()', app_js)
|
||||||
self.assertIn('function zipDownloadRequestKey(paths)', app_js)
|
self.assertIn('function zipDownloadRequestKey(paths)', app_js)
|
||||||
self.assertIn('async function createArchiveDownloadTask(paths)', app_js)
|
self.assertIn('async function createArchiveDownloadTask(paths)', app_js)
|
||||||
@@ -252,9 +256,14 @@ class UiSmokeGoldenTest(unittest.TestCase):
|
|||||||
self.assertIn('async function downloadFileRequest(paths)', app_js)
|
self.assertIn('async function downloadFileRequest(paths)', app_js)
|
||||||
self.assertIn('const zipDownload = isZipDownloadSelection(selectedItems);', app_js)
|
self.assertIn('const zipDownload = isZipDownloadSelection(selectedItems);', app_js)
|
||||||
self.assertIn('openZipDownloadModal(selectedItems);', app_js)
|
self.assertIn('openZipDownloadModal(selectedItems);', app_js)
|
||||||
|
self.assertIn('openSingleFileDownloadModal(selected);', app_js)
|
||||||
|
self.assertIn('const requestKey = zipDownload ? zipDownloadRequestKey(selectedPaths) : singleFileDownloadRequestKey(selected.path);', app_js)
|
||||||
self.assertIn('targetText: "Archive download requested"', app_js)
|
self.assertIn('targetText: "Archive download requested"', app_js)
|
||||||
|
self.assertIn('targetText: `File download requested: ${selectedItem.name}`', app_js)
|
||||||
self.assertIn('statusText: "Requested"', app_js)
|
self.assertIn('statusText: "Requested"', app_js)
|
||||||
|
self.assertIn('statusText: "Requesting download..."', app_js)
|
||||||
self.assertIn('countText: "Waiting for archive task"', app_js)
|
self.assertIn('countText: "Waiting for archive task"', app_js)
|
||||||
|
self.assertIn('countText: "Direct file download"', app_js)
|
||||||
self.assertIn('targetText: "Archive download task"', app_js)
|
self.assertIn('targetText: "Archive download task"', app_js)
|
||||||
self.assertIn('statusText: "Ready"', app_js)
|
self.assertIn('statusText: "Ready"', app_js)
|
||||||
self.assertIn('countText: "Browser download requested"', app_js)
|
self.assertIn('countText: "Browser download requested"', app_js)
|
||||||
@@ -266,6 +275,9 @@ class UiSmokeGoldenTest(unittest.TestCase):
|
|||||||
self.assertIn('return `Current: ${task.current_item}`;', app_js)
|
self.assertIn('return `Current: ${task.current_item}`;', app_js)
|
||||||
self.assertIn('downloadProgressState.requestKey === requestKey', app_js)
|
self.assertIn('downloadProgressState.requestKey === requestKey', app_js)
|
||||||
self.assertIn('setStatus("Preparing download...");', app_js)
|
self.assertIn('setStatus("Preparing download...");', app_js)
|
||||||
|
self.assertIn('setStatus("Requesting download...");', app_js)
|
||||||
|
self.assertIn('setStatus(zipDownload ? "Preparing download..." : "Requesting download...");', app_js)
|
||||||
|
self.assertIn('setStatus(`Download requested: ${anchor.download}`);', app_js)
|
||||||
self.assertIn('"/api/files/download/archive-prepare"', app_js)
|
self.assertIn('"/api/files/download/archive-prepare"', app_js)
|
||||||
self.assertIn('`/api/tasks/${encodeURIComponent(taskId)}`', app_js)
|
self.assertIn('`/api/tasks/${encodeURIComponent(taskId)}`', app_js)
|
||||||
self.assertIn('`/api/files/download/archive/${encodeURIComponent(taskId)}`', app_js)
|
self.assertIn('`/api/files/download/archive/${encodeURIComponent(taskId)}`', app_js)
|
||||||
|
|||||||
+64
-5
@@ -86,6 +86,7 @@ let downloadProgressState = {
|
|||||||
archiveLabel: "",
|
archiveLabel: "",
|
||||||
totalItems: 0,
|
totalItems: 0,
|
||||||
requestKey: null,
|
requestKey: null,
|
||||||
|
mode: null,
|
||||||
taskId: null,
|
taskId: null,
|
||||||
cancelRequested: false,
|
cancelRequested: false,
|
||||||
};
|
};
|
||||||
@@ -377,6 +378,10 @@ function zipDownloadRequestKey(paths) {
|
|||||||
return paths.join("\n");
|
return paths.join("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function singleFileDownloadRequestKey(path) {
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
function selectedItemCountLabel(totalItems) {
|
function selectedItemCountLabel(totalItems) {
|
||||||
return `${totalItems} selected item${totalItems === 1 ? "" : "s"}`;
|
return `${totalItems} selected item${totalItems === 1 ? "" : "s"}`;
|
||||||
}
|
}
|
||||||
@@ -465,6 +470,7 @@ function updateDownloadModalDisplay(info) {
|
|||||||
function openZipDownloadModal(selectedItems) {
|
function openZipDownloadModal(selectedItems) {
|
||||||
const requestPaths = selectedItems.map((item) => item.path);
|
const requestPaths = selectedItems.map((item) => item.path);
|
||||||
downloadProgressState.active = true;
|
downloadProgressState.active = true;
|
||||||
|
downloadProgressState.mode = "archive";
|
||||||
downloadProgressState.archiveLabel = "ZIP archive";
|
downloadProgressState.archiveLabel = "ZIP archive";
|
||||||
downloadProgressState.totalItems = selectedItems.length;
|
downloadProgressState.totalItems = selectedItems.length;
|
||||||
downloadProgressState.requestKey = zipDownloadRequestKey(requestPaths);
|
downloadProgressState.requestKey = zipDownloadRequestKey(requestPaths);
|
||||||
@@ -483,6 +489,26 @@ function openZipDownloadModal(selectedItems) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function openSingleFileDownloadModal(selectedItem) {
|
||||||
|
downloadProgressState.active = true;
|
||||||
|
downloadProgressState.mode = "single_file";
|
||||||
|
downloadProgressState.archiveLabel = selectedItem.name;
|
||||||
|
downloadProgressState.totalItems = 1;
|
||||||
|
downloadProgressState.requestKey = singleFileDownloadRequestKey(selectedItem.path);
|
||||||
|
downloadProgressState.taskId = null;
|
||||||
|
downloadProgressState.cancelRequested = false;
|
||||||
|
setDownloadModalVisible(true);
|
||||||
|
updateDownloadModalDisplay({
|
||||||
|
active: true,
|
||||||
|
targetText: `File download requested: ${selectedItem.name}`,
|
||||||
|
currentFileText: `File: ${selectedItem.path}`,
|
||||||
|
countText: "Direct file download",
|
||||||
|
statusText: "Requesting download...",
|
||||||
|
percent: 0,
|
||||||
|
cancelVisible: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function markZipDownloadReady(fileName) {
|
function markZipDownloadReady(fileName) {
|
||||||
downloadProgressState.active = false;
|
downloadProgressState.active = false;
|
||||||
downloadProgressState.cancelRequested = false;
|
downloadProgressState.cancelRequested = false;
|
||||||
@@ -527,6 +553,33 @@ function markZipDownloadCancelled() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function markSingleFileDownloadRequested(fileName, path) {
|
||||||
|
downloadProgressState.active = false;
|
||||||
|
updateDownloadModalDisplay({
|
||||||
|
active: false,
|
||||||
|
targetText: `File download requested: ${fileName}`,
|
||||||
|
currentFileText: `File: ${path}`,
|
||||||
|
countText: "Browser download requested",
|
||||||
|
statusText: "Download requested",
|
||||||
|
percent: 0,
|
||||||
|
cancelVisible: false,
|
||||||
|
});
|
||||||
|
window.setTimeout(closeDownloadModal, 480);
|
||||||
|
}
|
||||||
|
|
||||||
|
function markSingleFileDownloadFailed(err, selectedItem) {
|
||||||
|
downloadProgressState.active = false;
|
||||||
|
updateDownloadModalDisplay({
|
||||||
|
active: false,
|
||||||
|
targetText: "File download failed",
|
||||||
|
currentFileText: `File: ${selectedItem.path}`,
|
||||||
|
countText: "Direct file download",
|
||||||
|
statusText: `Failed: ${err.message || "Download failed"}`,
|
||||||
|
percent: 0,
|
||||||
|
cancelVisible: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function updateZipDownloadTaskProgress(task) {
|
function updateZipDownloadTaskProgress(task) {
|
||||||
if (!downloadProgressState.active) {
|
if (!downloadProgressState.active) {
|
||||||
return;
|
return;
|
||||||
@@ -572,6 +625,7 @@ function closeDownloadModal() {
|
|||||||
if (downloadProgressState.active) {
|
if (downloadProgressState.active) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
downloadProgressState.mode = null;
|
||||||
downloadProgressState.archiveLabel = "";
|
downloadProgressState.archiveLabel = "";
|
||||||
downloadProgressState.totalItems = 0;
|
downloadProgressState.totalItems = 0;
|
||||||
downloadProgressState.requestKey = null;
|
downloadProgressState.requestKey = null;
|
||||||
@@ -743,17 +797,20 @@ async function startDownloadSelected() {
|
|||||||
}
|
}
|
||||||
const zipDownload = isZipDownloadSelection(selectedItems);
|
const zipDownload = isZipDownloadSelection(selectedItems);
|
||||||
const selectedPaths = selectedItems.map((item) => item.path);
|
const selectedPaths = selectedItems.map((item) => item.path);
|
||||||
const requestKey = zipDownloadRequestKey(selectedPaths);
|
const selected = selectedItems[0];
|
||||||
if (zipDownload && downloadProgressState.active && downloadProgressState.requestKey === requestKey) {
|
const requestKey = zipDownload ? zipDownloadRequestKey(selectedPaths) : singleFileDownloadRequestKey(selected.path);
|
||||||
setStatus("Preparing download...");
|
if (downloadProgressState.active && downloadProgressState.requestKey === requestKey) {
|
||||||
|
setStatus(zipDownload ? "Preparing download..." : "Requesting download...");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (zipDownload) {
|
if (zipDownload) {
|
||||||
openZipDownloadModal(selectedItems);
|
openZipDownloadModal(selectedItems);
|
||||||
setStatus("Preparing download...");
|
setStatus("Preparing download...");
|
||||||
|
} else {
|
||||||
|
openSingleFileDownloadModal(selected);
|
||||||
|
setStatus("Requesting download...");
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const selected = selectedItems[0];
|
|
||||||
if (zipDownload) {
|
if (zipDownload) {
|
||||||
const created = await createArchiveDownloadTask(selectedPaths);
|
const created = await createArchiveDownloadTask(selectedPaths);
|
||||||
downloadProgressState.taskId = created.task_id;
|
downloadProgressState.taskId = created.task_id;
|
||||||
@@ -778,7 +835,8 @@ async function startDownloadSelected() {
|
|||||||
anchor.click();
|
anchor.click();
|
||||||
anchor.remove();
|
anchor.remove();
|
||||||
URL.revokeObjectURL(url);
|
URL.revokeObjectURL(url);
|
||||||
setStatus(`Download started: ${anchor.download}`);
|
markSingleFileDownloadRequested(anchor.download, selected.path);
|
||||||
|
setStatus(`Download requested: ${anchor.download}`);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (zipDownload) {
|
if (zipDownload) {
|
||||||
if (err.code === "download_cancelled") {
|
if (err.code === "download_cancelled") {
|
||||||
@@ -789,6 +847,7 @@ async function startDownloadSelected() {
|
|||||||
setStatus("Download failed");
|
setStatus("Download failed");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
markSingleFileDownloadFailed(err, selected);
|
||||||
setActionError("Download", err);
|
setActionError("Download", err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user