diff --git a/gateway/sds_gateway/static/js/actions/DownloadActionManager.js b/gateway/sds_gateway/static/js/actions/DownloadActionManager.js index 370112f00..ca33ca45d 100644 --- a/gateway/sds_gateway/static/js/actions/DownloadActionManager.js +++ b/gateway/sds_gateway/static/js/actions/DownloadActionManager.js @@ -80,7 +80,6 @@ class DownloadActionManager { e.stopPropagation(); const captureUuid = button.getAttribute("data-capture-uuid"); - const captureName = button.getAttribute("data-capture-name"); if (!this.permissions.canDownload()) { this.showToast( @@ -90,7 +89,7 @@ class DownloadActionManager { return; } - this.handleCaptureDownload(captureUuid, captureName, button); + this.handleCaptureDownload(captureUuid, button); }); } } @@ -181,60 +180,101 @@ class DownloadActionManager { } /** - * Handle capture download + * Handle capture download (modal copy comes from web_download_modal.html) * @param {string} captureUuid - Capture UUID - * @param {string} captureName - Capture name + * @param {Element} [button] - Optional row action button for loading state */ - async handleCaptureDownload(captureUuid, captureName) { - // Update modal content for capture - const modalTitleElement = document.getElementById("webDownloadModalLabel"); - const modalNameElement = document.getElementById("webDownloadDatasetName"); - const confirmBtn = document.getElementById("confirmWebDownloadBtn"); - - if (modalTitleElement) { - await window.DOMUtils.renderContent(modalTitleElement, { - icon: "download", - text: "Download Capture", - }); + async handleCaptureDownload(captureUuid, button) { + const modalId = `webDownloadModal-${captureUuid}`; + const modal = document.getElementById(modalId); + if (!modal) { + console.warn(`Web download modal not found for capture ${captureUuid}`); + return; } - if (modalNameElement) { - modalNameElement.textContent = captureName || "Unnamed Capture"; + const confirmBtn = document.getElementById( + `confirmWebDownloadBtn-${captureUuid}`, + ); + + if (!confirmBtn) { + console.warn( + `Web download confirm button not found for capture ${captureUuid}`, + ); + return; } - if (confirmBtn) { - // Update button text for capture - await window.DOMUtils.renderContent(confirmBtn, { - icon: "download", - text: "Yes, Download Capture", - }); + const newConfirmBtn = confirmBtn.cloneNode(true); + confirmBtn.parentNode.replaceChild(newConfirmBtn, confirmBtn); - // Update the dataset UUID to capture UUID for the API call - confirmBtn.dataset.datasetUuid = captureUuid; - confirmBtn.dataset.datasetName = captureName; - - // Override the API endpoint for captures by temporarily modifying the fetch URL - const originalFetch = window.fetch; - window.fetch = (url, options) => { - const modifiedUrl = url.includes( - `/users/download-item/dataset/${captureUuid}/`, - ) - ? `/users/download-item/capture/${captureUuid}/` - : url; - return originalFetch(modifiedUrl, options); - }; - - // Restore fetch after modal is hidden - const modal = document.getElementById("webDownloadModal"); - const restoreFetch = () => { - window.fetch = originalFetch; - modal.removeEventListener("hidden.bs.modal", restoreFetch); - }; - modal.addEventListener("hidden.bs.modal", restoreFetch); - } + const originalRowButtonContent = button?.innerHTML; - // Show the modal - window.DOMUtils.openModal("webDownloadModal"); + newConfirmBtn.onclick = async () => { + window.DOMUtils.closeModal(modalId); + + if (button) { + await window.DOMUtils.renderLoading(button, "Processing...", { + format: "spinner", + size: "sm", + }); + button.disabled = true; + } + + try { + const response = await window.APIClient.post( + `/users/download-item/capture/${captureUuid}/`, + {}, + ); + + if (response.success === true) { + if (button) { + await window.DOMUtils.renderContent(button, { + icon: "check-circle", + color: "success", + text: "Download Requested", + }); + } + this.showToast( + response.message || + "Download request submitted successfully! You will receive an email when ready.", + "success", + ); + } else { + if (button) { + await window.DOMUtils.renderContent(button, { + icon: "exclamation-triangle", + color: "danger", + text: "Request Failed", + }); + } + this.showToast( + response.message || "Download request failed. Please try again.", + "danger", + ); + } + } catch (error) { + console.error("Download error:", error); + if (button) { + await window.DOMUtils.renderContent(button, { + icon: "exclamation-triangle", + color: "danger", + text: "Request Failed", + }); + } + this.showToast( + error.message || "An error occurred while processing your request.", + "danger", + ); + } finally { + if (button && originalRowButtonContent !== undefined) { + setTimeout(() => { + button.innerHTML = originalRowButtonContent; + button.disabled = false; + }, 3000); + } + } + }; + + window.DOMUtils.openModal(modalId); } /** @@ -258,14 +298,13 @@ class DownloadActionManager { e.stopPropagation(); const datasetUuid = button.getAttribute("data-dataset-uuid"); - const datasetName = button.getAttribute("data-dataset-name"); if (!datasetUuid) { console.warn("Web download button missing dataset-uuid attribute"); return; } - this.openWebDownloadModal(datasetUuid, datasetName); + this.openWebDownloadModal(datasetUuid); }); } } @@ -303,11 +342,10 @@ class DownloadActionManager { } /** - * Open web download modal for a specific dataset + * Open web download modal for a specific dataset (labels from web_download_modal.html) * @param {string} datasetUuid - Dataset UUID - * @param {string} datasetName - Dataset name */ - openWebDownloadModal(datasetUuid, datasetName) { + openWebDownloadModal(datasetUuid) { const modalId = `webDownloadModal-${datasetUuid}`; const modal = document.getElementById(modalId); if (!modal) { @@ -315,23 +353,15 @@ class DownloadActionManager { return; } - // Set the dataset name in the modal (find within this specific modal) - const nameElement = modal.querySelector("#webDownloadDatasetName"); - if (nameElement) { - nameElement.textContent = datasetName || "this dataset"; - } - - // Store dataset info in the download button (find within this specific modal) - const confirmBtn = modal.querySelector("#confirmWebDownloadBtn"); + const confirmBtn = document.getElementById( + `confirmWebDownloadBtn-${datasetUuid}`, + ); if (!confirmBtn) { console.warn(`Confirm button not found for dataset ${datasetUuid}`); return; } - confirmBtn.dataset.datasetUuid = datasetUuid; - confirmBtn.dataset.datasetName = datasetName; - // Remove any existing event listeners by cloning const newConfirmBtn = confirmBtn.cloneNode(true); confirmBtn.parentNode.replaceChild(newConfirmBtn, confirmBtn); @@ -490,7 +520,6 @@ class DownloadActionManager { e.stopPropagation(); const captureUuid = button.getAttribute("data-capture-uuid"); - const captureName = button.getAttribute("data-capture-name"); if (!this.permissions.canDownload()) { this.showToast( @@ -500,7 +529,7 @@ class DownloadActionManager { return; } - this.handleCaptureDownload(captureUuid, captureName, button); + this.handleCaptureDownload(captureUuid, button); }); } } diff --git a/gateway/sds_gateway/static/js/actions/__tests__/DownloadActionManager.test.js b/gateway/sds_gateway/static/js/actions/__tests__/DownloadActionManager.test.js index 7a6546bf0..8db67530c 100644 --- a/gateway/sds_gateway/static/js/actions/__tests__/DownloadActionManager.test.js +++ b/gateway/sds_gateway/static/js/actions/__tests__/DownloadActionManager.test.js @@ -66,10 +66,10 @@ describe("DownloadActionManager", () => { if (id === "downloadModal") return mockModal; if (id === "downloadDatasetName") return { textContent: "" }; if (id === "confirmDownloadBtn") return mockButton; - if (id === "webDownloadModal") return mockModal; - if (id === "webDownloadModalLabel") return { innerHTML: "" }; - if (id === "webDownloadDatasetName") return { textContent: "" }; - if (id === "confirmWebDownloadBtn") return mockButton; + if (id.startsWith("webDownloadModal-")) return mockModal; + if (id.startsWith("webDownloadModalLabel-")) return { innerHTML: "" }; + if (id.startsWith("webDownloadDatasetName-")) return { textContent: "" }; + if (id.startsWith("confirmWebDownloadBtn-")) return mockButton; return null; }); @@ -102,7 +102,6 @@ describe("DownloadActionManager", () => { Promise.resolve({ success: true, message: "Download requested" }), }), ); - global.window.showWebDownloadModal = jest.fn(); global.window.showAlert = jest.fn(); // Mock bootstrap globally @@ -319,18 +318,13 @@ describe("DownloadActionManager", () => { test("should handle capture download click with permissions", async () => { const captureUuid = "test-capture-uuid"; - const captureName = "Test Capture"; // Ensure window.DOMUtils is properly set up window.DOMUtils = global.window.DOMUtils; // Test that the method exists and can be called without throwing await expect( - downloadManager.handleCaptureDownload( - captureUuid, - captureName, - mockButton, - ), + downloadManager.handleCaptureDownload(captureUuid, mockButton), ).resolves.not.toThrow(); }); @@ -385,15 +379,20 @@ describe("DownloadActionManager", () => { innerHTML: "", disabled: false, }; - document.getElementById = jest.fn(() => ({ - id: modalId, - querySelector: jest.fn((sel) => - sel === "#confirmWebDownloadBtn" ? confirmBtn : { textContent: "" }, - ), - addEventListener: jest.fn(), - })); + document.getElementById = jest.fn((id) => { + if (id === modalId) { + return { id: modalId, addEventListener: jest.fn() }; + } + if (id === "webDownloadDatasetName-test-uuid") { + return { textContent: "" }; + } + if (id === "confirmWebDownloadBtn-test-uuid") { + return confirmBtn; + } + return null; + }); - downloadManager.openWebDownloadModal("test-uuid", "Test Dataset"); + downloadManager.openWebDownloadModal("test-uuid"); expect(global.window.DOMUtils.openModal).toHaveBeenCalledWith(modalId); }); diff --git a/gateway/sds_gateway/static/js/file-list.js b/gateway/sds_gateway/static/js/file-list.js index 9997466cd..aba3069c9 100644 --- a/gateway/sds_gateway/static/js/file-list.js +++ b/gateway/sds_gateway/static/js/file-list.js @@ -824,7 +824,7 @@ class FileListCapturesTableManager extends CapturesTableManager { diff --git a/gateway/sds_gateway/templates/pages/home.html b/gateway/sds_gateway/templates/pages/home.html index e7e16ecc8..3b5a825fa 100644 --- a/gateway/sds_gateway/templates/pages/home.html +++ b/gateway/sds_gateway/templates/pages/home.html @@ -59,7 +59,7 @@