From b9edf97931e46cb18d56c033b271d0e1eb0eb0a1 Mon Sep 17 00:00:00 2001 From: oleg-odysseus Date: Fri, 30 Aug 2024 12:08:53 +0200 Subject: [PATCH] Added new operation loadZipNoRename to FileService which takes the downloaded filename from Content-Disposition header, used this operation in all shiny apps downloads --- .../analysis-execution-list.js | 11 +--- .../cohort-definition-manager.js | 5 +- .../iranalysis/components/results.js | 5 +- js/services/file.js | 64 ++++++++++++++----- 4 files changed, 54 insertions(+), 31 deletions(-) diff --git a/js/components/analysisExecution/analysis-execution-list.js b/js/components/analysisExecution/analysis-execution-list.js index 4a2f0c819..135007634 100644 --- a/js/components/analysisExecution/analysis-execution-list.js +++ b/js/components/analysisExecution/analysis-execution-list.js @@ -174,19 +174,14 @@ define([ if (submission) { submissionId = submission.id; } - let currentAnalysisId = this.analysisId(); + let resultsPathPrefix = this.resultsPathPrefix; let apiPath = (resultsPathPrefix && resultsPathPrefix.includes('characterizations')) ? shinyConsts.apiPaths.downloadShinyCC(submissionId, source.sourceKey) : shinyConsts.apiPaths.downloadShinyPW(submissionId, source.sourceKey); - let filePrefix = (resultsPathPrefix && resultsPathPrefix.includes('characterizations')) - ? "Characterization_" - : "Pathway_"; - - FileService.loadZip( - config.api.url + apiPath, - filePrefix + currentAnalysisId + "_gv" + submissionId + "_" + source.sourceKey + ".zip" + FileService.loadZipNoRename( + config.api.url + apiPath ) .catch((e) => console.error("error when downloading: " + e)) .finally(() => this.loading(false)); diff --git a/js/pages/cohort-definitions/cohort-definition-manager.js b/js/pages/cohort-definitions/cohort-definition-manager.js index 87ada1531..ca96a2500 100644 --- a/js/pages/cohort-definitions/cohort-definition-manager.js +++ b/js/pages/cohort-definitions/cohort-definition-manager.js @@ -1198,9 +1198,8 @@ define(['jquery', 'knockout', 'text!./cohort-definition-manager.html', } downloadShinyApp(source) { - FileService.loadZip( - config.api.url + constants.paths.downloadShiny(this.currentCohortDefinition().id(), source.sourceKey), - "Cohort_" + this.currentCohortDefinition().id() + "_" + source.sourceKey + ".zip" + FileService.loadZipNoRename( + config.api.url + constants.paths.downloadShiny(this.currentCohortDefinition().id(), source.sourceKey) ) .catch((e) => console.error("error when downloading: " + e)) .finally(() => this.loading(false)); diff --git a/js/pages/incidence-rates/components/iranalysis/components/results.js b/js/pages/incidence-rates/components/iranalysis/components/results.js index eb9434916..f030033a9 100644 --- a/js/pages/incidence-rates/components/iranalysis/components/results.js +++ b/js/pages/incidence-rates/components/iranalysis/components/results.js @@ -174,9 +174,8 @@ define([ downloadShinyApp(source) { let analysisId = source.info().executionInfo.id.analysisId; - FileService.loadZip( - config.api.url + constants.apiPaths.downloadShiny(analysisId, source.source.sourceKey), - "Incidence_" + analysisId + "_" + source.source.sourceKey + ".zip" + FileService.loadZipNoRename( + config.api.url + constants.apiPaths.downloadShiny(analysisId, source.source.sourceKey) ) .catch((e) => console.error("error when downloading: " + e)) .finally(() => this.isLoading(false)); diff --git a/js/services/file.js b/js/services/file.js index ce18e6624..5981c209a 100644 --- a/js/services/file.js +++ b/js/services/file.js @@ -7,33 +7,63 @@ define( authApi, ) => { class FileService { - // jQuery won't allow to set responseType other than 'text' + // Helper function to simplify setting up and making the XMLHttpRequest + _makeRequest(url, method, params, callback) { + const xhr = new XMLHttpRequest(); + xhr.open(method, url, true); + xhr.setRequestHeader("Authorization", authApi.getAuthorizationHeader()); + xhr.setRequestHeader("Content-type", "application/json"); + xhr.setRequestHeader("Action-Location", location); + xhr.onreadystatechange = () => { + if (xhr.readyState === 4) { + callback(xhr); + } + }; + xhr.onerror = () => reject({ + status: xhr.status, + statusText: xhr.statusText + }); + xhr.responseType = "arraybuffer"; + xhr.send(JSON.stringify(params)); + } + loadZip(url, filename, method = 'GET', params = {}) { - const promise = new Promise((resolve, reject) => { - const xhr = new XMLHttpRequest(); - xhr.open(method, url, true); - xhr.setRequestHeader("Authorization", authApi.getAuthorizationHeader()); - xhr.setRequestHeader("Content-type", "application/json"); - xhr.setRequestHeader("Action-Location", location); - xhr.onreadystatechange = function() { - if (xhr.readyState === 4 && xhr.status === 200) { + return new Promise((resolve, reject) => { + this._makeRequest(url, method, params, (xhr) => { + if (xhr.status === 200) { resolve(); const blob = new Blob([xhr.response], { type: "octet/stream" }); saveAs(blob, filename); - } else if (xhr.readyState === 4) { - reject({status: xhr.status, statusText: xhr.statusText}); + } else { + reject({ status: xhr.status, statusText: xhr.statusText }); } - } - xhr.onerror = reject; - xhr.responseType = "arraybuffer"; - xhr.send(JSON.stringify(params)); + }); }); + } - return promise; + loadZipNoRename(url, method = 'GET', params = {}) { + return new Promise((resolve, reject) => { + this._makeRequest(url, method, params, (xhr) => { + if (xhr.status === 200) { + const filename = xhr.getResponseHeader('Content-Disposition') + .split('filename=')[1] + .split(';')[0] + .replace(/\"/g, ''); // Clean up filename string + const blob = new Blob([xhr.response], { type: "octet/stream" }); + saveAs(blob, filename); + resolve(); + } else { + reject({ + status: xhr.status, + statusText: xhr.statusText + }); + } + }); + }); } saveAsJson(data) { - const blob = new Blob([JSON.stringify(data)], {type: "text/json;charset=utf-8"}); + const blob = new Blob([JSON.stringify(data)], { type: "text/json;charset=utf-8" }); saveAs(blob, 'data.json'); } }