diff --git a/modules/imaging_uploader/js/index.js b/modules/imaging_uploader/js/index.js index 2bb05e5bcaa..6a3be07bfc8 100644 --- a/modules/imaging_uploader/js/index.js +++ b/modules/imaging_uploader/js/index.js @@ -1,3 +1,3 @@ -!function(modules){function __webpack_require__(moduleId){if(installedModules[moduleId])return installedModules[moduleId].exports;var module=installedModules[moduleId]={exports:{},id:moduleId,loaded:!1};return modules[moduleId].call(module.exports,module,module.exports,__webpack_require__),module.loaded=!0,module.exports}var installedModules={};return __webpack_require__.m=modules,__webpack_require__.c=installedModules,__webpack_require__.p="",__webpack_require__(0)}([function(module,exports,__webpack_require__){"use strict";function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}var _ImagingUploader=__webpack_require__(14),_ImagingUploader2=_interopRequireDefault(_ImagingUploader);$(function(){var imagingUploader=React.createElement("div",{className:"page-imaging-uploader"},React.createElement(_ImagingUploader2.default,{Module:"imaging_uploader",DataURL:loris.BaseURL+"/imaging_uploader/?format=json"}));ReactDOM.render(imagingUploader,document.getElementById("lorisworkspace"))})},,,,,,,function(module,exports){"use strict";function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor))throw new TypeError("Cannot call a class as a function")}function _possibleConstructorReturn(self,call){if(!self)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!call||"object"!=typeof call&&"function"!=typeof call?self:call}function _inherits(subClass,superClass){if("function"!=typeof superClass&&null!==superClass)throw new TypeError("Super expression must either be null or a function, not "+typeof superClass);subClass.prototype=Object.create(superClass&&superClass.prototype,{constructor:{value:subClass,enumerable:!1,writable:!0,configurable:!0}}),superClass&&(Object.setPrototypeOf?Object.setPrototypeOf(subClass,superClass):subClass.__proto__=superClass)}Object.defineProperty(exports,"__esModule",{value:!0});var _createClass=function(){function defineProperties(target,props){for(var i=0;i0&&(activeTab=_this.props.tabs[0].id),_this.state={activeTab:activeTab},_this.handleClick=_this.handleClick.bind(_this),_this.getTabs=_this.getTabs.bind(_this),_this.getTabPanes=_this.getTabPanes.bind(_this),_this}return _inherits(Tabs,_React$Component),_createClass(Tabs,[{key:"handleClick",value:function(tabId,e){if(this.setState({activeTab:tabId}),this.props.onTabChange(tabId),this.props.updateURL){var scrollDistance=$("body").scrollTop()||$("html").scrollTop();window.location.hash=e.target.hash,$("html,body").scrollTop(scrollDistance)}}},{key:"getTabs",value:function(){var tabs=this.props.tabs.map(function(tab){var tabClass=this.state.activeTab===tab.id?"active":null,href="#"+tab.id,tabID="tab-"+tab.id;return React.createElement("li",{role:"presentation",className:tabClass,key:tab.id},React.createElement("a",{id:tabID,href:href,role:"tab","data-toggle":"tab",onClick:this.handleClick.bind(null,tab.id)},tab.label))}.bind(this));return tabs}},{key:"getTabPanes",value:function(){var tabPanes=React.Children.map(this.props.children,function(child,key){if(child)return React.cloneElement(child,{activeTab:this.state.activeTab,key:key})}.bind(this));return tabPanes}},{key:"render",value:function(){var tabs=this.getTabs(),tabPanes=this.getTabPanes(),tabStyle={marginLeft:0,marginBottom:"5px"};return React.createElement("div",null,React.createElement("ul",{className:"nav nav-tabs",role:"tablist",style:tabStyle},tabs),React.createElement("div",{className:"tab-content"},tabPanes))}}]),Tabs}(React.Component);Tabs.propTypes={tabs:React.PropTypes.array.isRequired,defaultTab:React.PropTypes.string,updateURL:React.PropTypes.bool},Tabs.defaultProps={onTabChange:function(){},updateURL:!1};var TabPane=function(_React$Component2){function TabPane(){return _classCallCheck(this,TabPane),_possibleConstructorReturn(this,(TabPane.__proto__||Object.getPrototypeOf(TabPane)).apply(this,arguments))}return _inherits(TabPane,_React$Component2),_createClass(TabPane,[{key:"render",value:function(){var classList="tab-pane",title=void 0;return this.props.TabId===this.props.activeTab&&(classList+=" active"),this.props.Title&&(title=React.createElement("h1",null,this.props.Title)),React.createElement("div",{role:"tabpanel",className:classList,id:this.props.TabId},title,this.props.children)}}]),TabPane}(React.Component);TabPane.propTypes={TabId:React.PropTypes.string.isRequired,Title:React.PropTypes.string,activeTab:React.PropTypes.string},exports.Tabs=Tabs,exports.TabPane=TabPane},,,,function(module,exports,__webpack_require__){"use strict";function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor))throw new TypeError("Cannot call a class as a function")}function _possibleConstructorReturn(self,call){if(!self)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!call||"object"!=typeof call&&"function"!=typeof call?self:call}function _inherits(subClass,superClass){if("function"!=typeof superClass&&null!==superClass)throw new TypeError("Super expression must either be null or a function, not "+typeof superClass);subClass.prototype=Object.create(superClass&&superClass.prototype,{constructor:{value:subClass,enumerable:!1,writable:!0,configurable:!0}}),superClass&&(Object.setPrototypeOf?Object.setPrototypeOf(subClass,superClass):subClass.__proto__=superClass)}Object.defineProperty(exports,"__esModule",{value:!0});var _createClass=function(){function defineProperties(target,props){for(var i=0;i",logType:"summary"},_this.initHelper=_this.initHelper.bind(_this),_this.onLogTypeChange=_this.onLogTypeChange.bind(_this),_this.setServerPolling=_this.setServerPolling.bind(_this),_this.monitorProgress=_this.monitorProgress.bind(_this),_this}return _inherits(LogPanel,_React$Component),_createClass(LogPanel,[{key:"componentDidMount",value:function(){this.initHelper()}},{key:"initHelper",value:function(){var uploadProgress=new UploadProgress;this.uploadProgress=uploadProgress,$("#mri_upload_table").on("click","tbody tr",function(event){return null!==uploadProgress.getUploadRow()&&($(uploadProgress.getUploadRow()).css("background-color","white"),this.setServerPolling(!1)),event.currentTarget===uploadProgress.getUploadRow()?(uploadProgress.setUploadRow(null),uploadProgress.setProgressFromServer(null),void this.setState({logText:""})):(uploadProgress.setUploadRow(event.currentTarget),$(event.currentTarget).css("background-color","#EFEFFB"),void this.monitorProgress(this.state.logType))}.bind(this))}},{key:"monitorProgress",value:function(logType){var summary="summary"===logType,uploadProgress=this.uploadProgress,uploadId=uploadProgress.getUploadId();uploadId&&$.post(loris.BaseURL+"/imaging_uploader/ajax/getUploadSummary.php",{uploadId:uploadId,summary:summary},function(data){uploadProgress.setProgressFromServer(data),this.setState({logText:uploadProgress.getProgressText()}),this.setServerPolling(uploadProgress.getPipelineStatus()===UploadProgress.PIPELINE_STATUS_RUNNING)}.bind(this))}},{key:"setServerPolling",value:function(poll){var uploadProgress=this.uploadProgress;poll?(this.setServerPolling.getSummaryInterval||(this.setServerPolling.getSummaryInterval=setInterval(this.monitorProgress,5e3)),this.setServerPolling.dotUpdateInterval||(this.setServerPolling.dotUpdateInterval=setInterval(function(){uploadProgress.updateDots(),this.setState({logText:uploadProgress.getProgressText()})},3e3)),this.setServerPolling.animatedCharInterval||(this.setServerPolling.animatedCharInterval=setInterval(function(){uploadProgress.updateAnimatedCharIndex(),this.setState({logText:uploadProgress.getProgressText()})},250))):(this.setServerPolling.getSummaryInterval&&(clearInterval(this.setServerPolling.getSummaryInterval),this.setServerPolling.getSummaryInterval=null),this.setServerPolling.dotUpdateInterval&&(clearInterval(this.setServerPolling.dotUpdateInterval),this.setServerPolling.dotUpdateInterval=null),this.setServerPolling.animatedCharInterval&&(clearInterval(this.setServerPolling.animatedCharInterval),this.setServerPolling.animatedCharInterval=null))}},{key:"onLogTypeChange",value:function(name,value){this.monitorProgress(value),this.setState({logType:value})}},{key:"render",value:function(){var logTypes={summary:"Summary",detailed:"Detailed"};return React.createElement(_Panel2.default,{id:"log_panel",title:"Log Viewer"},React.createElement(FormElement,{name:"log_form"},React.createElement(SelectElement,{name:"LogType",label:"Logs to display",options:logTypes,onUserInput:this.onLogTypeChange,value:this.state.logType,emptyOption:!1}),React.createElement(TextareaElement,{name:"UploadLogs",disabled:!0,id:"mri_upload_logs",value:this.state.logText,rows:6})))}}]),LogPanel}(React.Component);LogPanel.propTypes={},LogPanel.defaultProps={},exports.default=LogPanel},function(module,exports,__webpack_require__){"use strict";function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor))throw new TypeError("Cannot call a class as a function")}function _possibleConstructorReturn(self,call){if(!self)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!call||"object"!=typeof call&&"function"!=typeof call?self:call}function _inherits(subClass,superClass){if("function"!=typeof superClass&&null!==superClass)throw new TypeError("Super expression must either be null or a function, not "+typeof superClass);subClass.prototype=Object.create(superClass&&superClass.prototype,{constructor:{value:subClass,enumerable:!1,writable:!0,configurable:!0}}),superClass&&(Object.setPrototypeOf?Object.setPrototypeOf(subClass,superClass):subClass.__proto__=superClass)}Object.defineProperty(exports,"__esModule",{value:!0});var _createClass=function(){function defineProperties(target,props){for(var i=0;i-1});if(!mriFile)return void this.uploadFile();if("Success"===mriFile.status)return void swal({title:"File already exists!",text:"A file with this name has already successfully passed the MRI pipeline!\n",type:"error",confirmButtonText:"OK"});if("In Progress..."===mriFile.status)return void swal({title:"File is currently processing!",text:"A file with this name is currently going through the MRI pipeline!\n",type:"error",confirmButtonText:"OK"});"Failure"===mriFile.status&&swal({title:"Are you sure?",text:"A file with this name already exists!\n Would you like to override existing file?",type:"warning",showCancelButton:!0,confirmButtonText:"Yes, I am sure!",cancelButtonText:"No, cancel it!"},function(isConfirm){isConfirm?this.uploadFile(!0):swal("Cancelled","Your imaginary file is safe :)","error")}.bind(this)),"Not Started"===mriFile.status&&swal({title:"Are you sure?",text:"A file with this name has been uploaded but has not yet started the MRI pipeline.\n Would you like to override the existing file?",type:"warning",showCancelButton:!0,confirmButtonText:"Yes, I am sure!",cancelButtonText:"No, cancel it!"},function(isConfirm){isConfirm?this.uploadFile(!0):swal("Cancelled","Your upload has been cancelled.","error")}.bind(this))}}},{key:"uploadFile",value:function(overwriteFile){var formData=this.state.formData,formObj=new FormData;for(var key in formData)""!==formData[key]&&formObj.append(key,formData[key]);formObj.append("fire_away","Upload"),overwriteFile&&formObj.append("overwrite",!0),$.ajax({type:"POST",url:loris.BaseURL+"/imaging_uploader/",data:formObj,cache:!1,contentType:!1,processData:!1,xhr:function(){var xhr=new window.XMLHttpRequest;return xhr.upload.addEventListener("progress",function(evt){if(evt.lengthComputable){var percentage=Math.round(evt.loaded/evt.total*100);this.setState({uploadProgress:percentage})}}.bind(this),!1),xhr}.bind(this),success:function(data){var errMessage="The following errors occured while attempting to display this page:";data.indexOf(errMessage)>-1?(data=data.replace("history.back()","location.reload()"),document.open(),document.write(data),document.close()):swal({title:"Upload Successful!",type:"success"},function(){window.location.assign(loris.BaseURL+"/imaging_uploader/")})},error:function(err){console.error(err),this.setState({uploadProgress:-1})}.bind(this)})}},{key:"render",value:function(){var form=this.state.form;form.IsPhantom.value=this.state.formData.IsPhantom,form.candID.value=this.state.formData.candID,form.pSCID.value=this.state.formData.pSCID,form.visitLabel.value=this.state.formData.visitLabel,form.mri_file.value=this.state.formData.mri_file;var btnClass=this.state.uploadProgress>-1?"btn btn-primary hide":void 0;return React.createElement("div",{className:"row"},React.createElement("div",{className:"col-md-7"},React.createElement("h3",null,"Upload an imaging scan"),React.createElement("br",null),React.createElement(FormElement,{name:"upload_form",formElements:form,fileUpload:!0,onUserInput:this.onFormChange},React.createElement(StaticElement,{label:"Notes",text:"File name should be of type .tgz or tar.gz or .zip"}),React.createElement("div",{className:"row"},React.createElement("div",{className:"col-sm-9 col-sm-offset-3"},React.createElement(_ProgressBar2.default,{value:this.state.uploadProgress}))),React.createElement(ButtonElement,{onUserInput:this.submitForm,buttonClass:btnClass}))))}}]),UploadForm}(React.Component);UploadForm.propTypes={},UploadForm.defaultProps={},exports.default=UploadForm},function(module,exports){"use strict";function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor))throw new TypeError("Cannot call a class as a function")}function _possibleConstructorReturn(self,call){if(!self)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!call||"object"!=typeof call&&"function"!=typeof call?self:call}function _inherits(subClass,superClass){if("function"!=typeof superClass&&null!==superClass)throw new TypeError("Super expression must either be null or a function, not "+typeof superClass);subClass.prototype=Object.create(superClass&&superClass.prototype,{constructor:{value:subClass,enumerable:!1,writable:!0,configurable:!0}}),superClass&&(Object.setPrototypeOf?Object.setPrototypeOf(subClass,superClass):subClass.__proto__=superClass)}Object.defineProperty(exports,"__esModule",{value:!0});var _createClass=function(){function defineProperties(target,props){for(var i=0;i-1)return null;var row={};rowHeaders.forEach(function(header,index){row[header]=rowData[index]},this);var cellStyle={whiteSpace:"nowrap"};if("Progress"===column){if("Failure"===cell)return cellStyle.color="#fff",React.createElement("td",{className:"label-danger",style:cellStyle},cell);if("In Progress..."===cell)return cellStyle.color="#fff",React.createElement("td",{className:"label-warning",style:cellStyle},cell);var created=row["Number Of MincCreated"],inserted=row["Number Of MincInserted"];return React.createElement("td",{style:cellStyle},cell," (",inserted," out of ",created,")")}if("Tarchive Info"===column){if(!cell||"0"===cell)return React.createElement("td",null);var url=loris.BaseURL+"/dicom_archive/viewDetails/?tarchiveID="+cell;return React.createElement("td",{style:cellStyle},React.createElement("a",{href:url},"View Details"))}if("Number Of MincInserted"===column&&cell>0)return React.createElement("td",{style:cellStyle},React.createElement("a",{onClick:handleClick.bind(null,row.CandID)},cell));if("Number Of MincCreated"===column){var violatedScans=void 0;if(row["Number Of MincCreated"]-row["Number Of MincInserted"]>0){var numViolatedScans=row["Number Of MincCreated"]-row["Number Of MincInserted"],patientName=row.PatientName;violatedScans=React.createElement("a",{onClick:openViolatedScans.bind(null,patientName)},"(",numViolatedScans," violated scans)")}return React.createElement("td",{style:cellStyle},cell," ",violatedScans)}return React.createElement("td",{style:cellStyle},cell)}Object.defineProperty(exports,"__esModule",{value:!0}),loris.hiddenHeaders=["PatientName"],exports.default=formatColumn}]); //# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/modules/imaging_uploader/jsx/UploadForm.js b/modules/imaging_uploader/jsx/UploadForm.js index 757d325e4c5..d82c79f9899 100644 --- a/modules/imaging_uploader/jsx/UploadForm.js +++ b/modules/imaging_uploader/jsx/UploadForm.js @@ -101,6 +101,17 @@ class UploadForm extends React.Component { return; } + // File in the middle of insertion pipeline + if (mriFile.status === "In Progress...") { + swal({ + title: "File is currently processing!", + text: "A file with this name is currently going through the MRI pipeline!\n", + type: "error", + confirmButtonText: 'OK' + }); + return; + } + // File uploaded but failed during mri pipeline if (mriFile.status === "Failure") { swal({ @@ -117,8 +128,28 @@ class UploadForm extends React.Component { swal("Cancelled", "Your imaginary file is safe :)", "error"); } }.bind(this)); - return; } + + // Pipeline has not been triggered yet + if (mriFile.status === "Not Started") { + swal({ + title: "Are you sure?", + text: "A file with this name has been uploaded but has not yet started the MRI pipeline." + + "\n Would you like to override the existing file?", + type: "warning", + showCancelButton: true, + confirmButtonText: 'Yes, I am sure!', + cancelButtonText: 'No, cancel it!' + }, function(isConfirm) { + if (isConfirm) { + this.uploadFile(true); + } else { + swal("Cancelled", "Your upload has been cancelled.", "error"); + } + }.bind(this)); + } + + return; } /* diff --git a/modules/imaging_uploader/php/NDB_Menu_Filter_imaging_uploader.class.inc b/modules/imaging_uploader/php/NDB_Menu_Filter_imaging_uploader.class.inc index 623920953c8..814dfb8f93c 100644 --- a/modules/imaging_uploader/php/NDB_Menu_Filter_imaging_uploader.class.inc +++ b/modules/imaging_uploader/php/NDB_Menu_Filter_imaging_uploader.class.inc @@ -596,14 +596,12 @@ class NDB_Menu_Filter_Imaging_Uploader extends NDB_Menu_Filter_Form */ function _getFileList($data) { - $files = array(); - foreach ($data as $row) { + $uploadStatus = $row[1]; $filePath = $row[5]; + $mincInserted = $row[10]; $fileName = basename($filePath); - $uploadStatus = $row[1]; - // Checks if a file is already in files array $isDuplicate = ( array_search( @@ -612,7 +610,12 @@ class NDB_Menu_Filter_Imaging_Uploader extends NDB_Menu_Filter_Form ) > -1 ); - if (file_exists($filePath) && !$isDuplicate) { + // If file successfully completed pipeline, then filePath is no longer + // valid as the file would have been deleted. + // Check that mincInserted > 0 in mri_upload to handle Successful uploads + if ((file_exists($filePath) || $mincInserted) + && !$isDuplicate + ) { array_push( $files, [