Merged LesionTracker and OHIF Viewer, refactored out common components

This commit is contained in:
Erik Ziegler committed 2015-10-13 14:14:50 +02:00
1 parent 34adbe3fbc
commit b774c22593
144 files changed
+27820

No files matched your search

@@ -0,0 +1,15 @@
<template name="worklist">
<div class="tabbable">
<ul id="tabs" class="nav nav-tabs" style="width:100%;">
<li class="active">
<a id="tabList" data-toggle="tab">Study List</a>
</li>
</ul>
<div id="tabs-content" class="tab-content">
<div id="contentList" class="tab-pane active">
{{> worklistSearch }}
{{> worklistResult }}
</div>
</div>
</div>
</template>
+110
View File
@@ -0,0 +1,110 @@
var contentID = "";
//Generate UUID to create unique tabs
function generateUUID () {
var d = new Date().getTime();
var uuid = 'xxxxxxxx'.replace(/[xy]/g, function(c) {
var r = (d + Math.random()*8)%8 | 0;
d = Math.floor(d/8);
return (c=='x' ? r : (r&0x3|0x8)).toString(8);
});
return uuid;
}
//Remove tab
function removeTab (uuid) {
var removedTabIndex = $("#tab"+uuid).index();
//Remove tab
$("#tab"+uuid).remove();
//Remove Content
$("#content"+uuid).remove();
//TODO:Activate previous tab
}
//Add new tab
function addNewTab (data) {
//Make inactive all tabs
$("#tabs > li").removeClass("active");
$("#tabs-content > div").removeClass("active");
//Create new li element for tab
var tabli = document.createElement("li");
$(tabli).addClass("active");
$("#tabs").append(tabli);
//a element inside li
var taba = document.createElement("a");
var uuid = generateUUID();
var tabId = "tab"+uuid;
//activeTabId provides unique tabs content and encapsulates templates in tabs
Session.set("activeTabId", tabId);
console.log(Session.get("activeTabId"));
//Create tab
taba.setAttribute("data-toggle","tab");
taba.setAttribute("id",tabId);
taba.innerHTML = data.patientName;
tabli.appendChild(taba);
//Create close button
var btnClose = document.createElement('button');
$(btnClose).addClass("btnClose");
btnClose.innerHTML = "x";
btnClose.onclick = function() { // Note this is a function
removeTab(uuid);
};
taba.appendChild(btnClose);
//Create div content
var tabContent = document.createElement("div");
var contentId = "content"+uuid;
tabContent.setAttribute("id",contentId);
$(tabContent).css("background-color", "black");
$(tabContent).addClass("tab-pane");
$(tabContent).addClass("active");
$("#tabs-content").append(tabContent);
contentID = contentId;
}
function insertContent () {
//Include imageViewer template
UI.insert( UI.render( Template.viewer ), $( '#'+contentID ).get(0) );
}
Template.worklist.events({
'click ul#tabs>li>a': function (event){
var tabId = $(event.target).attr("id");
if ( tabId !== undefined ) {
//Save activeTabId to load correct study for each tab
Session.set("activeTabId", tabId);
var splitTabId = tabId.split("tab");
var contentId = "content"+splitTabId[1];
//Make inactive all tab-pane divs
$("#tabs-content>div").removeClass("active");
$("#"+contentId).addClass("active");
}
}
});
Tracker.autorun(function () {
var data = Session.get('openNewTabEvent');
var content = Session.get('showContentInTab');
if ( data ) {
addNewTab(data);
}
if (content) {
insertContent();
}
Session.set('openNewTabEvent', false);
Session.set('showContentInTab', false);
});
@@ -0,0 +1,50 @@
html, body
height: 100%
margin: 0
padding: 0
background-color: white
color: black
div
margin: 0
padding: 0
/***********************************************/
/* CSS3 Close button */
/***********************************************/
.btnClose
top: 0
right: 0
bottom: 0
width: 20px
height: 20px
text-decoration: none
border: none
background-color: #fcfcfc
-moz-border-radius: 10px
-webkit-border-radius: 10px
border-radius: 10px
margin-left: 5px
font-weight: bold
.tabbable
cursor: pointer
position: absolute
top:0
left:0
bottom: 0
right: 0
width: 100%
height: 100%
color: black
.tab-content
position: absolute
top: 42px
left: 0
right: 0
bottom: 3px
width: 100%
@@ -0,0 +1,20 @@
<template name="worklistResult">
<table id="tblStudyList" class="table table-striped">
<thead>
<tr>
<th>Patient Name</th>
<th>Patient ID</th>
<th>Accession#</th>
<th>Study Date</th>
<th>Modality</th>
<th>Study Description</th>
<th># Images</th>
</tr>
</thead>
<tbody id="studyListData">
{{#each studies}}
{{> worklistStudy }}
{{/each}}
</tbody>
</table>
</template>
@@ -0,0 +1,7 @@
Studies = new Mongo.Collection(null);
Template.worklistResult.helpers({
studies : function() {
return Studies.find();
}
});
@@ -0,0 +1,6 @@
table#tblStudyList
color: black
tbody tr:hover
background-color: #009BD2
color: white
@@ -0,0 +1,88 @@
<template name="worklistSearch">
<!--Search Panel-->
<div class="panel panel-default">
<div class="panel-heading" id="search-panel-head">Search</div>
<div class="panel-body">
<div style="padding: 10px;">
<div class="row">
<div class="col-lg-8 col-md-8 col-xs-12">
<div class="row">
<div class="col-lg-3 col-md-3 col-xs-10">
<div class="form-group">
<label for="patientId">Patient ID</label>
<input type="text" class="form-control" id="patientId" placeholder="Patient ID">
</div>
</div>
<div class="col-lg-3 col-md-3 col-xs-10">
<div class="form-group">
<label for="patientName">Name</label>
<input type="text" class="form-control" id="patientName" placeholder="Name">
</div>
</div>
<div class="col-lg-3 col-md-3 col-xs-10">
<div class="form-group">
<label for="patientAccessionNumber">Accession #</label>
<input type="text" class="form-control" id="patientAccessionNumber" placeholder="Accession #">
</div>
</div>
<div class="col-lg-3 col-md-3 col-xs-10">
<div class="form-group">
<label for="studyDescription">Study Description</label>
<input type="text" class="form-control" id="studyDescription" placeholder="Study Description">
</div>
</div>
</div>
<div class="row">
<div class="col-lg-3 col-md-3 col-xs-10">
<!--Add calendar ui-->
<div class="form-group">
<label for="">Study Date(from)</label>
<p><input type="checkbox" id="checkFrom"><input id="studyDateFrom" type="date" class="form-control" style="padding-left: 30px;"></p>
</div>
</div>
<div class="col-lg-3 col-md-3 col-xs-10">
<div class="form-group">
<label for="">Study Date(to)</label>
<p><input type="checkbox" id="checkTo"><input id="studyDateTo" type="date" class="form-control" style="padding-left:30px;"></p>
</div>
</div>
<div class="col-lg-3 col-md-3 col-xs-10">
<div class="form-group">
<label for="referringPhysician">Referring Physician</label>
<input type="text" class="form-control" id="referringPhysician" placeholder="Referring Physician">
</div>
</div>
<div class="col-lg-3 col-md-3 col-xs-10">
<div class="form-group">
<label for="modality">Modality</label>
<input type="text" class="form-control" id="modality" placeholder="Modality">
</div>
</div>
</div>
</div>
<div class="col-lg-4 col-md-4 col-xs-12">
<div class="row" style="margin-top: 25px;margin-bottom: 25px;">
<div class="col-lg-4 col-md-6 col-xs-6">
<button class="btn btn-primary" id="btnSearch">Search</button>
</div>
<div class="col-lg-4 col-md-6 col-xs-6">
<button class="btn btn-primary" id="btnToday">Today</button>
</div>
</div>
<div class="row">
<div class="col-lg-4 col-md-6 col-xs-6">
<button class="btn btn-primary" id="btnClear">Clear</button>
</div>
<div class="col-lg-4 col-md-6 col-xs-6">
<button class="btn btn-primary" id="btnLastSevenDays">Last 7 Days</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!--Search panel ends-->
</template>
@@ -0,0 +1,124 @@
//Get all studies
search();
var studyDateFrom;
var studyDateTo;
var checkFrom = false;
var checkTo = false;
function getFilter(filter) {
if(filter && filter.length && filter.substr(filter.length - 1) !== '*') {
filter += '*';
}
return filter;
}
//Search value
function isIndexOf(mainVal, searchVal) {
if(mainVal === undefined || mainVal === '' || mainVal.indexOf(searchVal) > -1){
return true;
}
return false;
}
//Replace object is undefined
function replaceUndefinedColumnValue (text) {
if (text == undefined || text === "undefined") {
return "";
} else {
return text;
}
}
//Convert string to study date
function convertStringToStudyDate (dateStr) {
var y = dateStr.substring(0,4);
var m = dateStr.substring(4,6);
var d = dateStr.substring(6,8);
var newDateStr = y+"/"+m+"/"+d;
var date_ = new Date(newDateStr);
return date_;
}
function search() {
var filter = {
patientName: getFilter($('#patientName').val()),
patientId: getFilter($('#patientId').val()),
accessionNumber: getFilter($('#patientAccessionNumber').val())
};
var modality = replaceUndefinedColumnValue($('#modality').val());
Studies.remove({});
Meteor.call('WorklistSearch', filter, function(error, studies) {
if (studies) {
studies.forEach(function(study) {
if(isIndexOf(study.modalities, modality) &&
(new Date(studyDateFrom).setHours(0,0,0,0) <= convertStringToStudyDate(study.studyDate) || !checkFrom) &&
(convertStringToStudyDate(study.studyDate) <= new Date(studyDateTo).setHours(0,0,0,0) || !checkTo)) {
Studies.insert(study);
}
});
}
});
}
Template.worklistSearch.events({
//Search
'click button#btnSearch' :function(event) {
studyDateFrom = $('#studyDateFrom').val();
studyDateTo = $('#studyDateTo').val();
checkFrom = $('#checkFrom').is(':checked');
checkTo = $('#checkTo').is(':checked');
search();
return false;
},
//Today
'click button#btnToday' :function(event) {
studyDateTo = new Date();
studyDateFrom = studyDateTo;
checkFrom = true;
checkTo = true;
search();
return false;
},
//Clear
'click button#btnClear' :function(event) {
$("#patientId").val("");
$("#patientName").val("");
$("#patientAccessionNumber").val("");
$("#studyDescription").val("");
$("#referringPhysician").val("");
$("#studyDateFrom").val("");
$("#studyDateTo").val("");
$("#modality").val("");
$('#checkFrom').prop('checked', false);
$('#checkTo').prop('checked', false);
},
//Last 7 Days
'click button#btnLastSevenDays' :function(event) {
studyDateTo = new Date();
studyDateFrom = new Date();
studyDateFrom.setDate(studyDateFrom.getDate()-7);
checkFrom = true;
checkTo = true;
search();
return false;
}
});
@@ -0,0 +1,35 @@
/***********************************************/
/* Search Panel */
/***********************************************/
#search-panel-head{
background-color: #337ab7;
color: white;
font-weight: 500;
font-size: 20px;
line-height: 20px;
box-shadow: 2px 2px 2px #888888;
}
#btnSearch, #btnToday, #btnClear, #btnLastSevenDays{
width: 100%;
}
#checkFrom, #checkTo{
width:20px;
height:20px;
position:absolute;
left:20px;
bottom: 22px;
}
/***********************************************/
/* Tabs */
/***********************************************/
.tab-pane{
position:absolute;
width: 100%;
height:100%;
}
.nav > li > a {
padding: 10px 5px;
}
@@ -0,0 +1,25 @@
<template name="worklistStudy">
<tr>
<td>
{{patientName}}
</td>
<td>
{{patientId}}
</td>
<td>
{{accessionNumber}}
</td>
<td>
{{studyDate}}
</td>
<td>
{{modalities}}
</td>
<td>
{{studyDescription}}
</td>
<td>
{{imageCount}}
</td>
</tr>
</template>
@@ -0,0 +1,5 @@
Template.worklistStudy.events({
'click': function (){
Router.go('viewer', {_id: this.studyInstanceUid});
}
});
@@ -0,0 +1 @@
+31
View File
@@ -0,0 +1,31 @@
Package.describe({
name: "worklist",
summary: "Basic worklist for web-based DICOM viewers",
version: '0.0.1'
});
Package.onUse(function (api) {
api.versionsFrom('1.2.0.2');
api.use('standard-app-packages');
api.use('jquery');
api.use('stylus');
// Components
api.addFiles('components/worklist.html', 'client');
api.addFiles('components/worklist.js', 'client');
api.addFiles('components/worklist.styl', 'client');
api.addFiles('components/worklistStudy/worklistStudy.html', 'client');
api.addFiles('components/worklistStudy/worklistStudy.js', 'client');
api.addFiles('components/worklistStudy/worklistStudy.styl', 'client');
api.addFiles('components/worklistResult/worklistResult.html', 'client');
api.addFiles('components/worklistResult/worklistResult.js', 'client');
api.addFiles('components/worklistResult/worklistResult.styl', 'client');
api.addFiles('components/worklistSearch/worklistSearch.html', 'client');
api.addFiles('components/worklistSearch/worklistSearch.js', 'client');
api.addFiles('components/worklistSearch/worklistSearch.styl', 'client');
});