diff --git a/shrine-webclient/src/main/html/js-i2b2/cells/CRC/CRC_ctrlr_QryStatus.js b/shrine-webclient/src/main/html/js-i2b2/cells/CRC/CRC_ctrlr_QryStatus.js index 696822570..34cfb6a25 100755 --- a/shrine-webclient/src/main/html/js-i2b2/cells/CRC/CRC_ctrlr_QryStatus.js +++ b/shrine-webclient/src/main/html/js-i2b2/cells/CRC/CRC_ctrlr_QryStatus.js @@ -1,734 +1,735 @@ /** * @projectDescription The Asynchronous Query Status controller (GUI-only controller). * @inherits i2b2.CRC.ctrlr * @namespace i2b2.CRC.ctrlr.QueryStatus * @author Nick Benik, Griffin Weber MD PhD * @version 1.0 * ---------------------------------------------------------------------------------------- * updated 8-10-09: Initial Creation [Nick Benik] */ function cgmUtcDateParser(dateString){ //Date format: 2011-02-21T14:35:03.480-05:00 try{ splitDateAndTime = dateString.split("T"); vrDate = splitDateAndTime[0].split("-"); vrTime = splitDateAndTime[1].split(":"); strYear = vrDate[0]; strMonth = vrDate[1] - 1; strDay = vrDate[2]; /* alert("Year: "+ strYear); alert("Month: "+ strMonth); alert("Day: "+ strDay);*/ strHours = vrTime[0]; strMins = vrTime[1]; strSecs = null; strMills = null; vSecs = vrTime[2].split("."); strSecs = vSecs[0]; vMills = vSecs[1].split("-"); strMills = vMills[0]; /* alert("Hours: "+ strHours); alert("Minutes: "+ strMins); alert("Seconds: "+ strSecs); alert("MilliSeconds: "+ strMills);*/ return new Date(strYear, strMonth, strDay, strHours, strMins, strSecs, strMills); } catch(e){ return null; } } i2b2.CRC.ctrlr.QueryStatus = function(dispDIV) { this.dispDIV = dispDIV; }; function trim(sString) { while (sString.substring(0,1) == '\n') { sString = sString.substring(1, sString.length); } while (sString.substring(sString.length-1, sString.length) == '\n') { sString = sString.substring(0,sString.length-1); } return sString; } i2b2.CRC.ctrlr.QueryStatus.prototype = function() { var private_singleton_isRunning = false; var private_startTime = false; var private_refreshInterrupt = false; function private_refresh_status() { // callback processor to check the Query Instance var scopedCallbackQRSI = new i2b2_scopedCallback(); scopedCallbackQRSI.scope = self; scopedCallbackQRSI.callback = function(results) { if (results.error) { alert(results.errorMsg); return; } else { // find our query instance var ri_list = results.refXML.getElementsByTagName('query_result_instance'); var l = ri_list.length; for (var i=0; i" + description + ""; } var crc_xml = results.refXML.getElementsByTagName('crc_xml_result'); l = crc_xml.length; for (var i=0; i" + params[i2].getAttribute("column") + ": " + value + ""; } var ri_id = i2b2.h.XPath(temp, 'descendant-or-self::result_instance_id')[0].firstChild.nodeValue; } //self.dispDIV.innerHTML += this.dispMsg; } } var self = i2b2.CRC.ctrlr.currentQueryStatus; // this private function refreshes the display DIV var d = new Date(); var t = Math.floor((d.getTime() - private_startTime)/100)/10; var s = t.toString(); if (s.indexOf('.') < 0) { s += '.0'; } if (private_singleton_isRunning) { self.dispDIV.innerHTML = '
Running Query: "'+self.QM.name+'"
'; // display the current run duration self.dispDIV.innerHTML += '
['+s+' secs]
'; } else { self.dispDIV.innerHTML = '
Finished Query: "'+self.QM.name+'"
'; self.dispDIV.innerHTML += '
['+s+' secs]
'; // self.dispDIV.innerHTML += '
Compute Time: ' + (Math.floor((self.QI.end_date - self.QI.start_date)/100))/10 + ' secs
'; // self.dispDIV.innerHTML += '
'; $('runBoxText').innerHTML = "Run Query"; } self.dispDIV.innerHTML += '
'; if ((!private_singleton_isRunning) && (undefined != self.QI.end_date)){ self.dispDIV.innerHTML += '
Compute Time: '+ (Math.floor((self.QI.end_date - self.QI.start_date)/100))/10 +' secs
'; } var foundError = false; for (var i=0; i < self.QRS.length; i++) { var rec = self.QRS[i]; if (rec.QRS_time) { var t = '
ERROR
'; // self.dispDIV.innerHTML += '
ERROR
'; //['+rec.QRS_time+' secs]'; foundError = true; break; case "COMPLETED": case "FINISHED": foundError = false; //t += '#0000dd">'+rec.QRS_Status; break; case "INCOMPLETE": case "WAITTOPROCESS": case "PROCESSING": self.dispDIV.innerHTML += '
'+rec.title+'
PROCESSING
'; // self.dispDIV.innerHTML += '
PROCESSING
'; //['+rec.QRS_time+' secs]
'; alert('Your query has timed out and has been rescheduled to run in the background. The results will appear in "Previous Queries"'); foundError = true; //t += '#00dd00">'+rec.QRS_Status; break; } t += '
'; //self.dispDIV.innerHTML += '
'+t+'['+rec.QRS_time+' secs]
'; } self.dispDIV.innerHTML += ''; if (foundError == false) { if (rec.QRS_DisplayType == "CATNUM") { //make call to get QRSI. i2b2.CRC.ajax.getQueryResultInstanceList_fromQueryResultInstanceId("CRC:QueryStatus", {qr_key_value: rec.QRS_ID}, scopedCallbackQRSI); } else if ((rec.QRS_DisplayType == "LIST") && (foundError == false)) { self.dispDIV.innerHTML += "
" + rec.QRS_Description + "
"; } else if (i2b2.h.isDQ) { self.dispDIV.innerHTML += "
" + rec.title + "
" + rec.QRS_Status + " [" + rec.QRS_time + " secs]
"; } if (rec.QRS_Type == "PATIENTSET") { // Check to see if timeline is checked off, if so switch to timeline var t2 = $('dialogQryRun').select('INPUT.chkQueryType'); for (var i=0;i 0) && (curItem == " timeline") && !(i2b2.h.isBadObjPath('i2b2.Timeline.cfg.config.plugin')) ) { i2b2.hive.MasterView.setViewMode('Analysis'); i2b2.PLUGINMGR.ctrlr.main.selectPlugin("Timeline"); //Process PatientSet rec.QM_id = self.QM.id; rec.QI_id = self.QI.id; rec.PRS_id = rec.QRS_ID; rec.result_instance_id = rec.PRS_id; var sdxData = {}; sdxData[0] = i2b2.sdx.Master.EncapsulateData('PRS', rec); i2b2.Timeline.prsDropped(sdxData); i2b2.Timeline.setShowMetadataDialog(false); //Process Concepts, put all concepts in one large set sdxData = {}; for (var j2 = 0; j2 < i2b2.CRC.model.queryCurrent.panels.length; j2++) { var panel_list = i2b2.CRC.model.queryCurrent.panels[j2] var panel_cnt = panel_list.length; for (var p2 = 0; p2 < panel_cnt; p2++) { // Concepts for (var i2=0; i2 < panel_list[p2].items.length; i2++) { sdxData[0] = panel_list[p2].items[i2]; i2b2.Timeline.conceptDropped(sdxData); } } } //$('Timeline-pgstart').value = '1'; //$('Timeline-pgsize').value = '10'; //i2b2.Timeline.pgGo(0); i2b2.Timeline.yuiTabs.set('activeIndex', 1); i2b2.Timeline.setShowMetadataDialog(true); } } } } } if ((undefined != self.QI.message) && (foundError == false)) { self.dispDIV.innerHTML += '
Status
'; var mySplitResult = self.QI.message.split("' + i2b2.h.XPath(xml_v, 'descendant::name/text()/..')[i2].firstChild.nodeValue + ': ' + value + ' secs'; //self.dispDIV.innerHTML += '
: ' + i2b2.h.XPath(xml_v, 'descendant::total_time_second/text()/..')[i2].firstChild.nodeValue + ' secs
'; } catch (e) {} } } } self.dispDIV.style.display = 'none'; self.dispDIV.style.display = 'block'; if (!private_singleton_isRunning && private_refreshInterrupt) { // make sure our refresh interrupt is turned off try { clearInterval(private_refreshInterrupt); private_refreshInterrupt = false; } catch (e) {} } } function private_cancelQuery() { if (private_singleton_isRunning) { try { var self = i2b2.CRC.ctrlr.currentQueryStatus; i2b2.CRC.ctrlr.history.queryDeleteNoPrompt(self.QM.id); clearInterval(private_refreshInterrupt); private_refreshInterrupt = false; private_singleton_isRunning = false; $('runBoxText').innerHTML = "Run Query"; self.dispDIV.innerHTML += '
QUERY CANCELLED
'; i2b2.CRC.ctrlr.currentQueryStatus = false; } catch (e) {} } } function private_startQuery() { var self = i2b2.CRC.ctrlr.currentQueryStatus; if (private_singleton_isRunning) { return false; } private_singleton_isRunning = true; self.dispDIV.innerHTML = 'Processing Query: "'+this.name+'"'; self.QM.name = this.name; self.QRS = []; self.QI = {}; // callback processor to run the query from definition this.callbackQueryDef = new i2b2_scopedCallback(); this.callbackQueryDef.scope = this; this.callbackQueryDef.callback = function(results) { //if error if (results.error) { var temp = results.refXML.getElementsByTagName('response_header')[0]; if (undefined != temp) { results.errorMsg = i2b2.h.XPath(temp, 'descendant-or-self::result_status/status')[0].firstChild.nodeValue; if (results.errorMsg.substring(0,9) == "LOCKEDOUT") { results.errorMsg = 'As an "obfuscated user" you have exceeded the allowed query repeat and are now LOCKED OUT, please notify your system administrator.'; } } alert(results.errorMsg); private_cancelQuery(); return; } //query was successful so update global settings. clearInterval(private_refreshInterrupt); private_refreshInterrupt = false; private_singleton_isRunning = false; //update the ui var self = i2b2.CRC.ctrlr.currentQueryStatus; // this private function refreshes the display DIV var d = new Date(); var t = Math.floor((d.getTime() - private_startTime)/100)/10; var s = t.toString(); if (s.indexOf('.') < 0) { s += '.0'; } self.dispDIV.innerHTML = '
Finished Query: "'+self.QM.name+'"
'; self.dispDIV.innerHTML += '
['+s+' secs]

'; $('runBoxText').innerHTML = "Run Query"; //------------ QI Logic -------------------// // find our query instance var qi_list = results.refXML.getElementsByTagName('query_instance'); var l = qi_list.length; for (var i=0; i'; // -- query result instance vars -- // var qriNodeList = results.refXML.getElementsByTagName('query_result_instance'), qriIdx, qriNode, qriObj, breakdownType, errorObjects = [], brdNodeList, brdNode, brdIdx, brdObj; //iterate through each query result. for (qriIdx = 0; qriIdx < qriNodeList.length; qriIdx++) { //init qri vars. qriNode = qriNodeList[qriIdx]; qriObj = parseQueryResultInstance(qriNode); breakdownType = ''; //which hospital self.dispDIV.innerHTML += '

' + qriObj.description + ' "' +self.QM.name+ '"
'; //if there was an error display it. if((qriObj.statusName == "ERROR") || (qriObj.statusName == "UNAVAILABLE")){ + // placeholder var errorObj = { shortDescription: "Desination site was unable to translate SHRINE query term to local ontology.", stackTrace: "Error mapping query terms from" + " network to local forms. request:" + "RunQueryRequest(I2B2_PROJECT_NAME,180000 milliseconds,"+ "AuthenticationInfo(*****,****,Credential(******,false)),"+ "QUERY_ID,None,Set(PATIENT_COUNT_XML)," + "QueryDefinition(QUERY_NAME,Some(" + "Term(\\PROJECT\\AND\\CONCEPT\\PATH\\OF\\UNMAPPED\\TERM),"+ "Some(ANY),None,None,None,List())))", longDescription: 'The site responding to the query does not understand how to map the SHRINE query term it was given to its own local i2b2 term.)', wikiUrl: 'https://open.med.harvard.edu/wiki/display/SHRINETEAM/Error+Types+for+Improved+Error+Messaging' }; errorObjects.push(errorObj); - self.dispDIV.innerHTML += " " + errorObj.shortDescription + ""; + self.dispDIV.innerHTML += " - " + errorObj.shortDescription + ""; continue; } else if((qriObj.statusName == "PROCESSING")){ self.dispDIV.innerHTML += " - Still Processing Request"; continue; } else if(["COMPLETED","FINISHED"].indexOf(qriObj.statusName) < 0){ self.dispDIV.innerHTML += " - Results not available"; continue; } self.dispDIV.innerHTML += "
" + "Patient Count" + ": " + getObfuscatedResult(qriObj.setSize, 10) + "
"; //grab breakdown data. brdNodeList = i2b2.h.XPath(qriNode, 'descendant-or-self::breakdown_data/column'); for(brdIdx = 0; brdIdx < brdNodeList.length; brdIdx ++){ //init brd vars. brdNode = brdNodeList[brdIdx]; brdObj = parseBreakdown(brdNode); if(brdObj.parentResultType !== breakdownType){ breakdownType = brdObj.parentResultType; self.dispDIV.innerHTML += "

" + getBreakdownTitle(brdObj.parentResultType) + ":
"; self.dispDIV.innerHTML += "
"; } self.dispDIV.innerHTML += "
" + brdObj.name + ": " + getObfuscatedResult(brdObj.value, 10) + "
"; } } createErrorDialogue(self.dispDIV, errorObjects); i2b2.CRC.ctrlr.history.Refresh(); } /** * Scope for error dialog. */ function createErrorDialogue (container, errorObjects) { // -- no errors abandon ship! -- // if(errorObjects.length < 1) { return; } var anchors, btnExpand, btnContract, errObjects = errorObjects, errorData; //this sets up the events. anchors = container.getElementsByClassName('query-error-anchor'); if(anchors.length == 0) { return; } addAnchorEvents(); function expandErrorDetailDiv (ev) { btnExpand.style.display = 'none'; btnContract.style.display = 'inline'; document.getElementById('errorDetailDiv').style.height = '200px'; - $('errorDetailDiv').innerHTML = '' +errorData.shortDescription + '

' + - errorData.longDescription + '

' + - errorData.stackTrace + '

Click here for more information.'; + $('errorDetailDiv').innerHTML = '
Name:
' +errorData.shortDescription + '

' + + '
Description:
' + errorData.longDescription + '

' + + '
Technical Details:
' + errorData.stackTrace + '

' + + '
For information on troubleshooting and resolution, check' + 'the SHRINE Error Codex.
'; } function retractErrorDetailDiv (ev) { btnExpand.style.display = 'inline'; btnContract.style.display = 'none'; document.getElementById('errorDetailDiv').style.height = '80px'; - $('errorDetailDiv').innerHTML = '' +errorData.shortDescription + '

' + - errorData.longDescription + '

' + $('errorDetailDiv').innerHTML = '
Name:
' +errorData.shortDescription + '

' + + '
Description:
' + errorData.longDescription + '
' } function onClick(event) { event.preventDefault(); errorData = event.currentTarget.__errorData__; btnExpand = document.getElementById('btnExpandErrorDetail'); btnContract = document.getElementById('btnContractErrorDetail'); // -- add event listeners for expand and contract as well --// btnExpand.addEventListener('click', expandErrorDetailDiv, false); btnContract.addEventListener('click', retractErrorDetailDiv, false); showErrorDetail(errorData); } function showErrorDetail(detailObj) { var handleCancel = function() { this.cancel(); removeAllEvents(); retractErrorDetailDiv(); }; var dialogErrorDetail = new YAHOO.widget.SimpleDialog("dialogErrorDetail", { width: "820px", fixedcenter: true, constraintoviewport: true, modal: true, zindex: 700, buttons: [ { text: "Done", handler: handleCancel, isDefault: true }] }); dialogErrorDetail._doClose = function (e) { e.preventDefault(); this.cancel(); removeAllEvents(); retractErrorDetailDiv(); } $('dialogErrorDetail').show(); dialogErrorDetail.validate = function(){ return true; }; dialogErrorDetail.render(document.body); // / display the dialoge dialogErrorDetail.center(); dialogErrorDetail.show(); - $('errorDetailDiv').innerHTML = '' + errorData.shortDescription + ''; + $('errorDetailDiv').innerHTML = '
Name:
' + errorData.shortDescription + '
'; } function addAnchorEvents () { var el, length = anchors.length; // -- will need to iterate over these once they are created and add event listeners. for(var i = 0; i < length; i ++) { var el = anchors[i]; el.__errorData__ = errorObjects[i]; el.addEventListener('click', onClick, false); } } function removeAllEvents () { btnExpand.removeEventListener('click', expandErrorDetailDiv); btnContract.removeEventListener('click', retractErrorDetailDiv); } } /** * * @param qriNode * @returns {{qiStatusName: string, qiStatusDescription: string, qiSetSize: string, qiDescription: string, qiResultName: string, qiResultDescription: string}} */ function parseQueryResultInstance(qriNode){ var qriObj = { statusName: grabXmlNodeData(qriNode, 'descendant-or-self::query_status_type/name'), statusDescription: grabXmlNodeData(qriNode, 'descendant-or-self::query_status_type/description'), description: grabXmlNodeData(qriNode, 'descendant-or-self::description') }; if(qriObj.statusName == "ERROR"){ return qriObj; } qriObj.setSize = grabXmlNodeData(qriNode, 'descendant-or-self::set_size'); qriObj.resultName = grabXmlNodeData(qriNode, 'descendant-or-self::query_result_type/name'); qriObj.resultDescription = grabXmlNodeData(qriNode, 'descendant-or-self::query_result_type/description'); //if is obfuscated. /*if (i2b2.PM.model.isObfuscated) { qriObj.setSize = (+qriObj.setSize < 4)? "<3" : qriObj.setSize + "+-3"; }*/ return qriObj; } /** * * @param brdNode */ function parseBreakdown(brdNode){ var brdObj = { name: grabXmlNodeData(brdNode, 'name'), value: grabXmlNodeData(brdNode, 'value'), parentResultType: grabXmlNodeData(brdNode, 'parent::breakdown_data/resultType') } return brdObj; } /** * Return breakdown title based on breakdown type. * @param breakdownType * @returns {*} */ function getBreakdownTitle(breakdownType) { return { 'PATIENT_AGE_COUNT_XML': 'Patient Age Count Breakdown', 'PATIENT_GENDER_COUNT_XML': 'Patient Gender Count Breakdown', 'PATIENT_RACE_COUNT_XML': 'Patient Race Count Breakdown', 'PATIENT_VITALSTATUS_COUNT_XML':'Patient Vital Status Count Breakdown' }[breakdownType]; }; /** * Method for hiding the precise value of a query below a certain result. * @param resultCount - the number of results from a query. * @param obfuscationSetting - do not reveal this number of results */ function getObfuscatedResult(resultCount, obfuscationSetting) { var resultTitle = " - ", name = " patients", offsetText = " +-3", isException = i2b2.PM.model.isObfuscated === false; //default to 10. obfuscationSetting = (arguments.length > 1) ? arguments[1] : 10; //if user role is an exception. return result. if (isException) { return resultTitle += resultCount + name; } resultTitle += ((resultCount >= obfuscationSetting)? resultCount + offsetText + name: obfuscationSetting + name + " or fewer"); return resultTitle; } /** * Grab data for node, return empty string if none. * @param node * @param xPathString * @returns {string} */ function grabXmlNodeData(node, xPathString){ return (i2b2.h.XPath(node, xPathString).length)? i2b2.h.XPath(node, xPathString)[0].firstChild.nodeValue : ''; } // switch to status tab i2b2.CRC.view.status.showDisplay(); // timer and display refresh stuff private_startTime = new Date(); private_refreshInterrupt = setInterval("i2b2.CRC.ctrlr.currentQueryStatus.refreshStatus()", 100); // AJAX call i2b2.CRC.ajax.runQueryInstance_fromQueryDefinition("CRC:QueryTool", this.params, this.callbackQueryDef); } return { name: "", polling_interval: 1000, QM: {id:false, status:""}, QI: {id:false, status:""}, QRS:{}, displayDIV: false, running: false, started: false, startQuery: function(queryName, ajaxParams) { this.name = queryName; this.params = ajaxParams; private_startQuery.call(this); }, cancelQuery: function() { private_cancelQuery(); }, isQueryRunning: function() { return private_singleton_isRunning; }, refreshStatus: function() { private_refresh_status(); } }; }(); i2b2.CRC.ctrlr.currentQueryStatus = false;