From c7f31ddb0a5ffb6a32d2ef7d0763bc96e8b657b0 Mon Sep 17 00:00:00 2001 From: Bruno Alves de Faria Date: Mon, 6 Mar 2017 17:05:03 -0300 Subject: [PATCH] Removing progressDialog from DOM --- LesionTracker/client/components/app/app.html | 1 - .../components/bootstrap/dialog/progress.js | 125 +++++----- .../client/components/index.js | 1 - .../client/components/progressDialog/index.js | 3 - .../progressDialog/progressDialog.html | 18 -- .../progressDialog/progressDialog.js | 78 ------ .../progressDialog/progressDialog.styl | 23 -- .../components/studylist/studylist.html | 5 +- .../studylistToolbar/studylistToolbar.html | 18 +- .../studylistToolbar/studylistToolbar.js | 2 +- .../client/lib/importStudies.js | 225 +++++++++--------- 11 files changed, 186 insertions(+), 313 deletions(-) delete mode 100644 Packages/ohif-study-list/client/components/progressDialog/index.js delete mode 100644 Packages/ohif-study-list/client/components/progressDialog/progressDialog.html delete mode 100644 Packages/ohif-study-list/client/components/progressDialog/progressDialog.js delete mode 100644 Packages/ohif-study-list/client/components/progressDialog/progressDialog.styl diff --git a/LesionTracker/client/components/app/app.html b/LesionTracker/client/components/app/app.html index 1b091dc4d..17784434d 100644 --- a/LesionTracker/client/components/app/app.html +++ b/LesionTracker/client/components/app/app.html @@ -28,5 +28,4 @@
- {{>progressDialog}} diff --git a/Packages/ohif-core/client/components/bootstrap/dialog/progress.js b/Packages/ohif-core/client/components/bootstrap/dialog/progress.js index 7f488e05e..3c39297fa 100644 --- a/Packages/ohif-core/client/components/bootstrap/dialog/progress.js +++ b/Packages/ohif-core/client/components/bootstrap/dialog/progress.js @@ -1,82 +1,87 @@ import { Template } from 'meteor/templating'; -import { Session } from 'meteor/session'; +import { ReactiveVar } from 'meteor/reactive-var'; import { _ } from 'meteor/underscore'; Template.dialogProgress.onCreated(() => { - const instance = Template.instance(); + const instance = Template.instance(); - Session.set('progressDialogState', { - processed: 0, - total: instance.data.total, - message: instance.data.message - }); -}) + instance.state = new ReactiveVar({ + processed: 0, + total: instance.data.total, + message: instance.data.message + }); +}); Template.dialogProgress.onRendered(() => { - const instance = Template.instance(); - const task = instance.data.task; - const state = Session.get('progressDialogState'); + const instance = Template.instance(); + const task = instance.data.task; - const progressDialog = { - promise: instance.data.promise, + const progressDialog = { + promise: instance.data.promise, - done: value => { - // Hide the modal, removing the backdrop - instance.$('.modal').on('hidden.bs.modal', event => { - instance.data.promiseResolve(value); - }).modal('hide'); - }, + done: value => { + // Hide the modal, removing the backdrop + instance.$('.modal').on('hidden.bs.modal', event => { + instance.data.promiseResolve(value); + }).modal('hide'); + }, - cancel: () => { - // Hide the modal, removing the backdrop - instance.$('.modal').on('hidden.bs.modal', event => { - instance.data.promiseReject(); - }).modal('hide'); - }, + cancel: () => { + // Hide the modal, removing the backdrop + instance.$('.modal').on('hidden.bs.modal', event => { + instance.data.promiseReject(); + }).modal('hide'); + }, - update: _.throttle(processed => { - const state = Session.get('progressDialogState'); - state.processed = Math.max(0, processed); + update: _.throttle(processed => { + const state = instance.state.get(); + state.processed = Math.max(0, processed); - Session.set('progressDialogState', state); - }, 100), + instance.state.set(state); + }, 100), - setTotal: _.throttle(total => { - const state = Session.get('progressDialogState'); - state.total = total; + setTotal: _.throttle(total => { + const state = instance.state.get(); + state.total = total; - Session.set('progressDialogState', state); - }, 100), + instance.state.set(state); + }, 100), - setMessage: _.throttle(message => { - const state = Session.get('progressDialogState'); - state.message = message; + setMessage: _.throttle(message => { + const state = instance.state.get(); + state.message = message; - Session.set('progressDialogState', state); - }, 100) - } + instance.state.set(state); + }, 100) + }; - task.run(progressDialog); + task.run(progressDialog); }); Template.dialogProgress.helpers({ - progress() { - const state = Session.get('progressDialogState'); + progress() { + const instance = Template.instance(); + const state = instance.state.get(); - if (!state || !state.total) { - return 0; + if (!state || !state.total) { + return 0; + } + + return Math.min(1, state.processed / state.total) * 100; + }, + + message() { + const instance = Template.instance(); + const state = instance.state.get(); + + if (!state) { + return; + } + + if (typeof state.message === 'function') { + return state.message(state); + } + + return state.message; } - - return Math.min(1, state.processed / state.total) * 100; - }, - - message() { - const state = Session.get('progressDialogState'); - - if (!state) { - return; - } - - return state.message; - } -}) \ No newline at end of file +}); diff --git a/Packages/ohif-study-list/client/components/index.js b/Packages/ohif-study-list/client/components/index.js index 414b454e6..3682f21f9 100644 --- a/Packages/ohif-study-list/client/components/index.js +++ b/Packages/ohif-study-list/client/components/index.js @@ -1,4 +1,3 @@ -import './progressDialog'; import './seriesDetailsModal'; import './serverInformation'; import './studyContextMenu'; diff --git a/Packages/ohif-study-list/client/components/progressDialog/index.js b/Packages/ohif-study-list/client/components/progressDialog/index.js deleted file mode 100644 index 06f1e7aa0..000000000 --- a/Packages/ohif-study-list/client/components/progressDialog/index.js +++ /dev/null @@ -1,3 +0,0 @@ -import './progressDialog.html'; -import './progressDialog.styl'; -import './progressDialog.js'; diff --git a/Packages/ohif-study-list/client/components/progressDialog/progressDialog.html b/Packages/ohif-study-list/client/components/progressDialog/progressDialog.html deleted file mode 100644 index 118512142..000000000 --- a/Packages/ohif-study-list/client/components/progressDialog/progressDialog.html +++ /dev/null @@ -1,18 +0,0 @@ - diff --git a/Packages/ohif-study-list/client/components/progressDialog/progressDialog.js b/Packages/ohif-study-list/client/components/progressDialog/progressDialog.js deleted file mode 100644 index 4ad21a7c0..000000000 --- a/Packages/ohif-study-list/client/components/progressDialog/progressDialog.js +++ /dev/null @@ -1,78 +0,0 @@ -import { Template } from 'meteor/templating'; -import { Session } from 'meteor/session'; -import { _ } from 'meteor/underscore'; -import { OHIF } from 'meteor/ohif:core'; - -const updateProgress = numberOfCompleted => { - const progressDialogSettings = Session.get('progressDialogSettings'); - progressDialogSettings.numberOfCompleted = numberOfCompleted; - - Session.set('progressDialogSettings', progressDialogSettings); - - if (progressDialogSettings.numberOfCompleted === progressDialogSettings.numberOfTotal) { - OHIF.studylist.progressDialog.close(); - } -}; - -const setProgressMessage = message => { - let progressDialogSettings = Session.get('progressDialogSettings'); - progressDialogSettings.message = message; - Session.set('progressDialogSettings', progressDialogSettings); -}; - -OHIF.studylist.progressDialog = { - update: _.debounce(updateProgress, 100), - setMessage: _.debounce(setProgressMessage, 100), - show: function(title, numberOfTotal) { - Session.set('progressDialogSettings', { - title: title, - numberOfCompleted: 0, - numberOfTotal: numberOfTotal - }); - - $('#progressDialog').css('display', 'block'); - }, - close: function() { - Session.set('progressDialogSettings', { - title: '', - numberOfCompleted: 0, - numberOfTotal: 1 - }); - - $('#progressDialog').css('display', 'none'); - } -}; - -Template.progressDialog.helpers({ - progressDialogTitle() { - const settings = Session.get('progressDialogSettings'); - if (!settings) { - return; - } - - return settings.title; - }, - - progressStatus() { - const settings = Session.get('progressDialogSettings'); - if (!settings) { - return; - } - - if (settings.numberOfCompleted === undefined || - settings.numberOfTotal === undefined) { - return; - } - - return (settings.numberOfCompleted / settings.numberOfTotal) * 100; - }, - - progressMessage() { - const settings = Session.get('progressDialogSettings'); - if (!settings) { - return; - } - - return settings.message; - } -}); diff --git a/Packages/ohif-study-list/client/components/progressDialog/progressDialog.styl b/Packages/ohif-study-list/client/components/progressDialog/progressDialog.styl deleted file mode 100644 index d7e490ac2..000000000 --- a/Packages/ohif-study-list/client/components/progressDialog/progressDialog.styl +++ /dev/null @@ -1,23 +0,0 @@ -#progressDialog - display: none - position: fixed - left: 0 - right: 0 - margin: auto - width: 20% - min-height: 85px; - z-index: 100 - border-radius: 5px - padding: 10px 20px 10px 20px - background-color: rgba(255,255,255,1) - outline: none - - .dialogContent - margin-bottom: 20px - - #message - width: 100% - - span - display: inline-block; - width: 100% diff --git a/Packages/ohif-study-list/client/components/studylist/studylist.html b/Packages/ohif-study-list/client/components/studylist/studylist.html index a98507e59..10e47b76c 100644 --- a/Packages/ohif-study-list/client/components/studylist/studylist.html +++ b/Packages/ohif-study-list/client/components/studylist/studylist.html @@ -2,7 +2,7 @@
- {{> studylistResult (clone this)}} + {{>studylistResult (clone this)}}
@@ -11,7 +11,6 @@
{{#each templateName in additionalTemplates}} - {{> UI.dynamic template=templateName}} + {{>Template.dynamic template=templateName}} {{/each}} - {{>progressDialog}} diff --git a/Packages/ohif-study-list/client/components/studylist/studylistToolbar/studylistToolbar.html b/Packages/ohif-study-list/client/components/studylist/studylistToolbar/studylistToolbar.html index f470463d4..f62fbc760 100644 --- a/Packages/ohif-study-list/client/components/studylist/studylistToolbar/studylistToolbar.html +++ b/Packages/ohif-study-list/client/components/studylist/studylistToolbar/studylistToolbar.html @@ -1,12 +1,12 @@ \ No newline at end of file + diff --git a/Packages/ohif-study-list/client/components/studylist/studylistToolbar/studylistToolbar.js b/Packages/ohif-study-list/client/components/studylist/studylistToolbar/studylistToolbar.js index 8f5a0649c..a68b49885 100644 --- a/Packages/ohif-study-list/client/components/studylist/studylistToolbar/studylistToolbar.js +++ b/Packages/ohif-study-list/client/components/studylist/studylistToolbar/studylistToolbar.js @@ -19,7 +19,7 @@ Template.studylistToolbar.events({ // Get selected files located in the client machine const selectedFiles = $.map(event.currentTarget.files, value => value); - importStudies(selectedFiles); + OHIF.studylist.importStudies(selectedFiles); }, 'click .js-import-files'(event) { diff --git a/Packages/ohif-study-list/client/lib/importStudies.js b/Packages/ohif-study-list/client/lib/importStudies.js index 02d414d42..4a6b73f17 100644 --- a/Packages/ohif-study-list/client/lib/importStudies.js +++ b/Packages/ohif-study-list/client/lib/importStudies.js @@ -1,133 +1,126 @@ +import { Meteor } from 'meteor/meteor'; import { OHIF } from 'meteor/ohif:core'; /** * Imports selected studies from local into studylist * @param filesToImport Files located in the client machine to import */ -importStudies = function(filesToImport, importCallback) { - if (filesToImport.length < 1) { - return; +OHIF.studylist.importStudies = filesToImport => { + const numberOfFiles = filesToImport && filesToImport.length; + if (!numberOfFiles) { + return new Promise((resolve, reject) => reject('No files to upload')); } - var fileUploadStatus = { - numberOfFilesUploaded: 0, - numberOfFilesFailed: 0 + + const uploadMessage = ({ processed, total }) => `Uploaded files: ${processed} / ${total}`; + + const taskRunHandler = dialog => { + const uploadErrorHandler = fileNames => { + const names = fileNames.join('; '); + dialog.setMessage(`Failed to upload files: ${names}`); + }; + + const uploadSuccessHandler = studiesToImport => { + importStudiesInternal(studiesToImport, dialog).then(() => { + dialog.done(); + }).catch(errorMessage => { + dialog.setMessage(errorMessage); + }); + }; + + uploadFiles(filesToImport, dialog).then(uploadSuccessHandler).catch(uploadErrorHandler); }; - var numberOfFilesToUpload = filesToImport.length; - var studiesToImport = []; - OHIF.studylist.progressDialog.show({ - title: "Uploading Files...", - numberOfCompleted: 0, - numberOfTotal: numberOfFilesToUpload - }); - // Upload files to the server - filesToImport.forEach(function(fileToUpload) { - var xhr = new XMLHttpRequest(); - xhr.open('POST', "/uploadFilesToImport", true); - xhr.setRequestHeader("filename", fileToUpload.name); - - xhr.onload = function() { - // Failed to upload a file - if (xhr.readyState === 4 && xhr.status !== 200) { - updateFileUploadStatus(fileUploadStatus, false); - return; - } - - studiesToImport.push(xhr.responseText); - - updateFileUploadStatus(fileUploadStatus, true); - - var numberOfFilesProcessedToUpload = fileUploadStatus.numberOfFilesUploaded + fileUploadStatus.numberOfFilesFailed; - OHIF.studylist.progressDialog.update(numberOfFilesProcessedToUpload); - - if (numberOfFilesToUpload === numberOfFilesProcessedToUpload) { - // The upload is completed, so import files - importStudiesInternal(studiesToImport, importCallback); - - if (fileUploadStatus.numberOfFilesFailed > 0) { - //TODO: Some files failed to upload, so let user know - OHIF.log.info("Failed to upload " + fileUploadStatus.numberOfFilesFailed + " of " + numberOfFilesToUpload + " files"); - } - } - }; - - // Failed to upload a file - xhr.onerror = function() { - updateFileUploadStatus(fileUploadStatus, false); - }; - - xhr.send(fileToUpload); + return OHIF.ui.showDialog('dialogProgress', { + title: 'Importing Studies...', + message: uploadMessage, + total: numberOfFiles, + task: { run: taskRunHandler } }); }; -function updateFileUploadStatus(fileUploadStatus, isSuccess) { - if (!isSuccess) { - fileUploadStatus.numberOfFilesFailed++; - } else { - fileUploadStatus.numberOfFilesUploaded++; - } -} -function importStudiesInternal(studiesToImport, importCallback) { - if (!studiesToImport) { - return; - } +const uploadFiles = (files, dialog) => { + let processed = 0; - var numberOfStudiesToImport = studiesToImport.length; + const promise = new Promise((resolve, reject) => { + const promises = []; - OHIF.studylist.progressDialog.show({ - title: "Importing Studies...", - numberOfCompleted: 0, - numberOfTotal: numberOfStudiesToImport - }); - - // Create/Insert a new study import status item - Meteor.call("createStudyImportStatus", function(err, studyImportStatusId) { - if (err) { - // Hide dialog - OHIF.studylist.progressDialog.close(); - console.log(err.message); - return; - } - - // Handle when StudyImportStatus collection is updated - OHIF.studylist.collections.StudyImportStatus.find(studyImportStatusId).observe({ - changed: function(studyImportStatus) { - if (!studyImportStatus) { - return; - } - - var numberOfStudiesProcessedToImport = studyImportStatus.numberOfStudiesImported + studyImportStatus.numberOfStudiesFailed; - - // Show number of imported files - var successMessage = 'Imported '+studyImportStatus.numberOfStudiesImported+' of '+numberOfStudiesToImport; - OHIF.studylist.progressDialog.setMessage({ - message: successMessage, - messageType: 'success' - }); - OHIF.studylist.progressDialog.update(numberOfStudiesProcessedToImport); - - // Show number of failed files if there is at least one failed file - if (studyImportStatus.numberOfStudiesFailed > 0) { - var successMessage = 'Failed '+studyImportStatus.numberOfStudiesFailed+' of '+numberOfStudiesToImport; - OHIF.studylist.progressDialog.setMessage({ - message: successMessage, - messageType: 'warning' - }); - } - - if (numberOfStudiesProcessedToImport == numberOfStudiesToImport) { - // The entire import operation is completed, so remove the study import status item - Meteor.call("removeStudyImportStatus", studyImportStatus._id); - - // Let the caller know that import operation is completed - if (importCallback) { - importCallback(); - } - } - } + // Upload files to the server + files.forEach(file => { + const filePromise = uploadFile(file, dialog); + filePromise.then(() => dialog.update(++processed)); + promises.push(filePromise); }); - // Import studies with study import status id to get callbacks - Meteor.call("importStudies", studiesToImport, studyImportStatusId); + Promise.all(promises).then(resolve).catch(reject); }); -} + + return promise; +}; + +const uploadFile = file => { + return new Promise((resolve, reject) => { + const xhr = new XMLHttpRequest(); + xhr.open('POST', '/uploadFilesToImport', true); + xhr.setRequestHeader('filename', file.name); + + xhr.onload = () => { + if (xhr.readyState === 4 && xhr.status !== 200) { + // Failed to upload the file + reject(file.name); + } else { + // Success uploading the file + resolve(xhr.responseText); + } + }; + + // Failed to upload the file + xhr.onerror = () => reject(file.name); + + xhr.send(file); + }); +}; + +const importStudiesInternal = (studiesToImport, dialog) => { + const numberOfStudies = studiesToImport && studiesToImport.length; + if (!numberOfStudies) { + return new Promise((resolve, reject) => reject('No studies to import')); + } + + let processed = 0; + dialog.update(processed); + dialog.setTotal(numberOfStudies); + dialog.setMessage(({ processed, total }) => `Imported: ${processed} / ${total}`); + + return new Promise((resolve, reject) => { + // Create/Insert a new study import status item + Meteor.call('createStudyImportStatus', (error, studyImportStatusId) => { + if (error) { + return reject(error.message); + } + + // Handle when StudyImportStatus collection is updated + OHIF.studylist.collections.StudyImportStatus.find(studyImportStatusId).observe({ + changed(studyImportStatus) { + const { numberOfStudiesImported, numberOfStudiesFailed } = studyImportStatus; + dialog.update(numberOfStudiesImported); + + if (numberOfStudiesImported === numberOfStudies) { + // The entire import operation is completed, so remove the study import status item + Meteor.call('removeStudyImportStatus', studyImportStatus._id); + + // Show number of failed files if there is at least one failed file + if (studyImportStatus.numberOfStudiesFailed > 0) { + const failed = numberOfStudiesFailed; + reject(`Failed to import ${failed} of ${numberOfStudies} studies`); + } else { + resolve(); + } + } + } + }); + + // Import studies with study import status id to get callbacks + Meteor.call('importStudies', studiesToImport, studyImportStatusId); + }); + }); +};