Updating design of OHIF Viewer using (OHIF-49)

This commit is contained in:
Erik Ziegler 2016-07-22 14:26:29 +02:00
parent f53ee8e030
commit a6c45ddd27
59 changed files with 776 additions and 565 deletions

View File

@ -6,18 +6,6 @@ body
.logoContainer .logoContainer
width: 15% width: 15%
.navbar-brand
img
height: 20px
margin-top: 10px
margin-bottom: 10px
margin-right: 5px
h4.name
padding: 1px
font-size: 0.3em
width: 50%
table#tblStudyList table#tblStudyList
table-layout: fixed table-layout: fixed
font-size: 0.7em font-size: 0.7em
@ -25,14 +13,7 @@ body
#tablist #tablist
width: 85% width: 85%
overflow-x: auto overflow-x: auto
#toolbar .btn-group button
width: 40px
height: 40px
.studyDateList
margin-top: 5px
@media (max-device-width: 667px) @media (max-device-width: 667px)
#toolbar .btn-group button #toolbar .btn-group button
width: 35px width: 35px

View File

@ -1,3 +1,5 @@
import { Meteor } from 'meteor/meteor';
Meteor.startup(function() { Meteor.startup(function() {
var debug = false; var debug = false;

View File

@ -5,8 +5,6 @@
<!-- Prevents page zooming --> <!-- Prevents page zooming -->
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<!-- Enables page zooming -->
<!--<meta name="viewport" content="width=device-width, initial-scale=1">-->
<link rel="shortcut icon" type="image/png" href="images/logo.png" sizes="16x16 32x32 64x64"> <link rel="shortcut icon" type="image/png" href="images/logo.png" sizes="16x16 32x32 64x64">
<!--Best display for mobile devices--> <!--Best display for mobile devices-->
<meta http-equiv="cleartype" content="on"> <meta http-equiv="cleartype" content="on">

View File

@ -1,3 +1,5 @@
import { Meteor } from 'meteor/meteor';
Meteor.startup(function() { Meteor.startup(function() {
if (Object.keys(Meteor.settings).length > 1) { if (Object.keys(Meteor.settings).length > 1) {
console.log('Using custom LesionTracker settings'); console.log('Using custom LesionTracker settings');

3
OHIFViewer/.meteor/packages Executable file → Normal file
View File

@ -27,13 +27,14 @@ check
cornerstone cornerstone
dicomweb dicomweb
design design
ohif:core
ecmascript
viewerbase viewerbase
worklist worklist
reactive-var reactive-var
practicalmeteor:loglevel practicalmeteor:loglevel
hangingprotocols hangingprotocols
reactive-dict reactive-dict
gilbertwat:bootstrap3-daterangepicker
clinical:router clinical:router
fastclick fastclick
standard-minifier-css standard-minifier-css

View File

@ -66,6 +66,7 @@ mrt:moment@2.8.1
natestrauser:select2@4.0.2 natestrauser:select2@4.0.2
npm-mongo@1.4.45 npm-mongo@1.4.45
observe-sequence@1.0.12 observe-sequence@1.0.12
ohif:core@0.0.1
ordered-dict@1.0.8 ordered-dict@1.0.8
orthanc-remote@0.0.1 orthanc-remote@0.0.1
practicalmeteor:chai@2.1.0_1 practicalmeteor:chai@2.1.0_1

View File

@ -0,0 +1,13 @@
<template name="flexboxLayout">
<div class="viewerSection">
<div class="sidebarMenu sidebar-left {{#if leftSidebarOpen}}sidebar-open{{/if}}">
{{> studyBrowser (clone this)}}
</div>
<div class="mainContent {{#if leftSidebarOpen}}sidebar-left-open{{/if}} {{#if rightSidebarOpen}}sidebar-right-open{{/if}}">
{{> viewerMain (clone this)}}
</div>
<div class="sidebarMenu sidebar-right {{#if rightSidebarOpen}}sidebar-open{{/if}}">
{{> protocolEditor (clone this)}}
</div>
</div>
</template>

View File

@ -0,0 +1,19 @@
Template.flexboxLayout.events({
'transitionend .sidebarMenu'(event, instance) {
handleResize();
},
'transitionend .sidebar-option'(event, instance) {
// Prevent this event from bubbling
event.stopPropagation();
}
});
Template.flexboxLayout.helpers({
leftSidebarOpen() {
return Template.instance().data.state.get('leftSidebar');
},
rightSidebarOpen() {
return Template.instance().data.state.get('rightSidebar');
}
});

View File

@ -0,0 +1,80 @@
@import "{design}/app"
$lesionsSidebarMenuWidth = 450px
.viewerSection
display: flex
flex: 1
flex-flow: row nowrap
align-items: stretch
height: calc(100% - 78px);
width: 100%
.sidebarMenu
height: 100%
// required transformation to make inner fixed elements relative to this one
transform(scale(1))
transition($sidebarTransition)
.sidebar-option
height: 100%
position: fixed
transform(translateX(100%))
transition($sidebarTransition)
width: 100%
&.active
transform(translateX(0%))
.sidebar-left
max-width: $studiesSidebarMenuWidth
order: 1
flex: 1
margin-left: - $studiesSidebarMenuWidth
border-right: $uiBorderThickness $uiBorderColor solid
&.sidebar-open
margin-left: 0
.mainContent
flex: 1
order: 2
width: 100%
height: 100%
overflow: hidden
transition($sidebarTransition)
.sidebar-right
flex: 1
margin-left: -6px
margin-right: - $lesionsSidebarMenuWidth
max-width: $lesionsSidebarMenuWidth
order: 3
padding-left: 6px
position: relative
&[data-timepoints="3"]
margin-right: - ($lesionsSidebarMenuWidth + 135.5px)
max-width: $lesionsSidebarMenuWidth + 135.5px
&[data-timepoints="4"]
margin-right: - ($lesionsSidebarMenuWidth + 270px)
max-width: $lesionsSidebarMenuWidth + 270px
&:before
background-color: $uiBorderColor
content: ''
display: block
height: 100%
left: 5px
position: absolute
top: 0
width: $uiBorderThickness
&.sidebar-open
margin-right: 0
.studiesListedChanger
padding: 20px 10px
text-align: center
border-bottom: $uiBorderThickness $uiBorderColor solid

View File

@ -1,25 +1,12 @@
<template name="layout"> <template name="layout">
<nav class="navbar navbar-default noselect" role="navigation"> <nav class="topBar noselect" role="navigation">
<div class="container-fluid"> <div class="clearfix p-x-1 p-t-1">
<div class="navbar-header"> <a class="brandSection pull-left" href="http://www.ohif.org">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar"> <img class="logoImage" src="/images/logo.png">
<span class="sr-only">Toggle navigation</span> <div class="logoText">
<span class="icon-bar"></span> Open Health Imaging Foundation
<span class="icon-bar"></span> </div>
<span class="icon-bar"></span> </a>
</button>
<a class="navbar-brand" href="/">
<img height="30px" src="/images/logo.png">
<h4 class="name">Open Health Imaging Foundation</h4>
</a>
</div>
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav navbar-right">
<li>
<a href="http://www.ohif.org">About</a>
</li>
</ul>
</div>
</div> </div>
</nav> </nav>
{{> yield}} {{> yield}}

View File

@ -1,50 +1,27 @@
.noselect @import "{design}/app"
-webkit-touch-callout: none
-webkit-user-select: none
-khtml-user-select: none
-moz-user-select: none
-ms-user-select: none
user-select: none
.navbar .topBar
margin-bottom: 0 margin-bottom: 0
border-radius: 0 border-radius: 0
background-color: #060606 background-color: $primaryBackgroundColor
border: none border: none
font-family: "Sanchez" height: $topBarHeight
color: #C1C1C1 color: $textPrimaryColor
transition(all 0.3s ease)
-webkit-transition: all 0.3s ease
-moz-transition: all 0.3s ease
transition: all 0.3s ease
.navbar-default .navbar-nav > li > a
color: #C1C1C1
font-weight: bold
font-size: 12pt
.navbar-form
height: 50px
margin: 0
padding: 15px 3px
font-weight: bold
font-size: 12pt
line-height: 20px
.navbar-brand .brandSection
display: inline-block display: inline-block
height: 30px
img text-decoration: none
float: left
margin-right: 10px
margin-top: -5px
h4.name img.logoImage
float: left display: inline-block
margin: 0 height: 100%
font-family: "Sanchez" max-height: 50px
color: #C1C1C1 margin: 0 5px
@media (min-width: 768px) div.logoText
.navbar display: inline-block
border-radius: 0px font-family: $logoFontFamily
font-weight: $logoFontWeight
color: $textPrimaryColor

View File

@ -1,18 +1,26 @@
<template name="viewer"> <template name="viewer">
{{#if Template.subscriptionsReady}} {{#if Template.subscriptionsReady}}
<div class="viewerDialogs">
{{> cineDialog}}
</div>
<div id="viewer"> <div id="viewer">
<div class="studyBrowserSidebar"> <div id="toolbar">
{{ >relatedStudySelect }} <div class='pull-left'>
{{> studyBrowser }} <a class="btn btn-sm btn-secondary js-toggle-studies">
</div> Studies
{{> cineDialog }} </a>
<div class='viewerMain'> </div>
{{> toolbar }} <div class='pull-left'>
<div id='layoutManagerTarget'> {{> toolbar }}
</div>
<div class='pull-right'>
<a class='btn btn-sm btn-secondary js-toggle-protocol-editor'>
Hanging Protocols
</a>
</div> </div>
</div> </div>
{{> flexboxLayout (clone this)}}
</div> </div>
{{ >protocolEditor }}
{{else}} {{else}}
{{>loadingText}} {{>loadingText}}
{{/if}} {{/if}}

View File

@ -1,10 +1,19 @@
import { OHIF } from 'meteor/ohif:core'; import { OHIF } from 'meteor/ohif:core';
OHIF.viewer = OHIF.viewer || {}; OHIF.viewer = OHIF.viewer || {};
Template.viewer.onCreated(function() { Session.setDefault('activeViewport', false);
Session.setDefault('leftSidebar', false);
Session.setDefault('rightSidebar', false);
Template.viewer.onCreated(() => {
const instance = Template.instance();
// Attach the Window resize listener // Attach the Window resize listener
$(window).on('resize', handleResize); $(window).on('resize', handleResize);
$('.navbar').width('100%');
instance.data.state = new ReactiveDict();
instance.data.state.set('leftSidebar', Session.get('leftSidebar'));
instance.data.state.set('rightSidebar', Session.get('rightSidebar'));
Meteor.subscribe('hangingprotocols'); Meteor.subscribe('hangingprotocols');
@ -20,26 +29,27 @@ Template.viewer.onCreated(function() {
}; };
OHIF.viewer.functionList = { OHIF.viewer.functionList = {
invert: function(element) { invert: element => {
var viewport = cornerstone.getViewport(element); const viewport = cornerstone.getViewport(element);
viewport.invert = !viewport.invert; viewport.invert = !viewport.invert;
cornerstone.setViewport(element, viewport); cornerstone.setViewport(element, viewport);
}, },
resetViewport: function(element) { resetViewport: element => {
var enabledElement = cornerstone.getEnabledElement(element); const enabledElement = cornerstone.getEnabledElement(element);
if (enabledElement.fitToWindow === false) { if (enabledElement.fitToWindow === false) {
var imageId = enabledElement.image.imageId; const imageId = enabledElement.image.imageId;
var instance = cornerstoneTools.metaData.get('instance', imageId); const instance = cornerstoneTools.metaData.get('instance', imageId);
enabledElement.viewport = cornerstone.getDefaultViewport(enabledElement.canvas, enabledElement.image); enabledElement.viewport = cornerstone.getDefaultViewport(enabledElement.canvas, enabledElement.image);
var instanceClassDefaultViewport = getInstanceClassDefaultViewport(instance, enabledElement, imageId);
const instanceClassDefaultViewport = getInstanceClassDefaultViewport(instance, enabledElement, imageId);
cornerstone.setViewport(element, instanceClassDefaultViewport); cornerstone.setViewport(element, instanceClassDefaultViewport);
} else { } else {
cornerstone.reset(element); cornerstone.reset(element);
} }
}, },
clearTools: function(element) { clearTools: element => {
var toolStateManager = cornerstoneTools.globalImageIdSpecificToolStateManager; const toolStateManager = cornerstoneTools.globalImageIdSpecificToolStateManager;
toolStateManager.clear(element); toolStateManager.clear(element);
cornerstone.updateImage(element); cornerstone.updateImage(element);
} }
@ -55,7 +65,7 @@ Template.viewer.onCreated(function() {
}; };
} }
var contentId = this.data.contentId; const contentId = instance.data.contentId;
if (ViewerData[contentId].loadedSeriesData) { if (ViewerData[contentId].loadedSeriesData) {
log.info('Reloading previous loadedSeriesData'); log.info('Reloading previous loadedSeriesData');
@ -80,27 +90,42 @@ Template.viewer.onCreated(function() {
// Update the ViewerStudies collection with the loaded studies // Update the ViewerStudies collection with the loaded studies
ViewerStudies.remove({}); ViewerStudies.remove({});
this.data.studies.forEach(function(study) { instance.data.studies.forEach(study => {
study.selected = true; study.selected = true;
ViewerStudies.insert(study); ViewerStudies.insert(study);
}); });
}); });
Template.viewer.onRendered(function() { Template.viewer.onRendered(() => {
const instance = Template.instance();
// Enable hotkeys // Enable hotkeys
enableHotkeys(); enableHotkeys();
var parentNode = document.getElementById('layoutManagerTarget'); const parentNode = document.getElementById('layoutManagerTarget');
var studies = this.data.studies; const studies = instance.data.studies;
layoutManager = new LayoutManager(parentNode, studies); layoutManager = new LayoutManager(parentNode, studies);
ProtocolEngine = new HP.ProtocolEngine(layoutManager, studies); ProtocolEngine = new HP.ProtocolEngine(layoutManager, studies);
HP.setEngine(ProtocolEngine); HP.setEngine(ProtocolEngine);
}); });
Template.viewer.onDestroyed(function() { Template.viewer.onDestroyed(() => {
log.info('onDestroyed'); log.info('onDestroyed');
// Remove the Window resize listener // Remove the Window resize listener
$(window).off('resize', handleResize); $(window).off('resize', handleResize);
}); });
Template.viewer.events({
'click .js-toggle-studies'() {
const instance = Template.instance();
const current = instance.data.state.get('leftSidebar');
instance.data.state.set('leftSidebar', !current);
},
'click .js-toggle-protocol-editor'() {
const instance = Template.instance();
const current = instance.data.state.get('rightSidebar');
instance.data.state.set('rightSidebar', !current);
},
})

View File

@ -1,37 +1,31 @@
@import "{design}/app.styl"
#viewer #viewer
border-top: 1px solid #525252 border-top: 1px solid #525252
height: 100% height: 100%
width: 100% width: 100%
align-items: stretch
background-color: black
display: flex
flex-flow: column wrap
margin: 0
padding: 0
#toolbar
float: left
height: 30px
a.btn
text-align: center
color: $defaultColor
background-color: $primaryBackgroundColor
transition(all 0.1s ease)
// Prevent the blue outline in Chrome when a viewport is selected
outline: 0 !important
&:hover
color: $hoverColor
.noselect &.active, &:active
-webkit-touch-callout: none color: $activeColor
-webkit-user-select: none
-khtml-user-select: none
-moz-user-select: none
-ms-user-select: none
user-select: none
.studyBrowser
width: auto
.viewerMain
float: left
background-color: gray
height: 100%
width: calc(100% - 120px)
-webkit-transition: all 0.3s ease
-moz-transition: all 0.3s ease
transition: all 0.3s ease
#layoutManagerTarget
height: calc(100% - 30px)
width: 100%
.studyBrowserSidebar
float: left
height: 100%
width: 120px
overflow: hidden
background-color: #000
padding-top: 10px

View File

@ -1,5 +0,0 @@
Router.onBeforeAction(function() {
// User is logged in, go ahead and route them
this.next();
});

View File

@ -50,3 +50,9 @@ Router.route('/viewer/:_id', {
}); });
} }
}); });
Router.onBeforeAction(function() {
// User is logged in, go ahead and route them
this.next();
});

View File

@ -1,3 +1,5 @@
import { Meteor } from 'meteor/meteor';
Meteor.startup(function() { Meteor.startup(function() {
if (Object.keys(Meteor.settings).length > 1) { if (Object.keys(Meteor.settings).length > 1) {
console.log('Using custom LesionTracker settings: '); console.log('Using custom LesionTracker settings: ');

View File

@ -5,7 +5,7 @@ Package.describe({
}); });
Package.onUse(function(api) { Package.onUse(function(api) {
api.versionsFrom('1.3.4.1'); api.versionsFrom('1.3.5.1');
api.use('jquery'); api.use('jquery');
api.use('dicomweb'); api.use('dicomweb');

View File

@ -5,7 +5,7 @@ Package.describe({
}); });
Package.onUse(function(api) { Package.onUse(function(api) {
api.versionsFrom('1.3.4.1'); api.versionsFrom('1.3.5.1');
api.use('ecmascript'); api.use('ecmascript');
api.use('standard-app-packages'); api.use('standard-app-packages');

View File

@ -21,3 +21,11 @@ html hr
border-top: 5px solid border-top: 5px solid
border-right: 5px solid transparent border-right: 5px solid transparent
border-left: 5px solid transparent border-left: 5px solid transparent
.noselect
-webkit-touch-callout: none
-webkit-user-select: none
-khtml-user-select: none
-moz-user-select: none
-ms-user-select: none
user-select: none

View File

@ -19,12 +19,19 @@ $boxBackgroundColor = #3E5975
$boxBackgroundColorDark = #22374D $boxBackgroundColorDark = #22374D
// Text Colors // Text Colors
$textColorActive = #2D2D2D
$textPrimaryColor = #ffffff $textPrimaryColor = #ffffff
$textSecondaryColor = #91B9CD $textSecondaryColor = #91B9CD
// Other Colors // Other Colors
$menuBackgroundColor = #F2F2F2 $menuBackgroundColor = #F2F2F2
// Viewport Settings
$viewportBorderThickness = 1px
$viewportBorderColor = $uiBorderColorDark
$viewportBorderColorHover = $uiBorderColor
$viewportBorderColorActive = $uiBorderColorActive
// Sizes // Sizes
$topBarHeight = 40px $topBarHeight = 40px
$toolbarHeight = 78px $toolbarHeight = 78px

View File

@ -1,6 +1,6 @@
<template name="hangingProtocolButtons"> <template name="hangingProtocolButtons">
<button id="previousPresentationGroup" type="button" <button id="previousPresentationGroup" type="button"
class="btn btn-sm btn-default" class="btn btn-sm"
data-container="body" data-container="body"
data-toggle="tooltip" data-toggle="tooltip"
data-placement="bottom" data-placement="bottom"
@ -9,7 +9,7 @@
<span class="fa fa-step-backward"></span> <span class="fa fa-step-backward"></span>
</button> </button>
<button id="nextPresentationGroup" type="button" <button id="nextPresentationGroup" type="button"
class="btn btn-sm btn-default" class="btn btn-sm"
data-container="body" data-container="body"
data-toggle="tooltip" data-toggle="tooltip"
data-placement="bottom" data-placement="bottom"

View File

@ -19,11 +19,5 @@
{{ /each }} {{ /each }}
</ul> </ul>
{{ /if }} {{ /if }}
<button id="toggleProtocolEditor" type="button" class="btn btn-sm"
title="Toggle Hanging Protocol Editor"
data-toggle="tooltip">
<i class="fa fa-cog"></i>
</button>
</div> </div>
</template> </template>

View File

@ -1,14 +1,15 @@
import { OHIF } from 'meteor/ohif:core'; import { OHIF } from 'meteor/ohif:core';
Template.matchedProtocols.onRendered(function() { Template.matchedProtocols.onRendered(() => {
$('#matchedProtocols button').tooltip(OHIF.viewer.tooltipConfig); const instance = Template.instance();
instance.$('#matchedProtocols button').tooltip(OHIF.viewer.tooltipConfig);
}); });
Template.matchedProtocols.helpers({ Template.matchedProtocols.helpers({
/** /**
* Reactively re-render the MatchedProtocols Collection contents * Reactively re-render the MatchedProtocols Collection contents
*/ */
matchedProtocols: function() { matchedProtocols() {
return MatchedProtocols.find(); return MatchedProtocols.find();
} }
}); });
@ -20,33 +21,5 @@ Template.matchedProtocols.events({
'click .matchedProtocol': function() { 'click .matchedProtocol': function() {
var protocol = this; var protocol = this;
ProtocolEngine.setHangingProtocol(protocol); ProtocolEngine.setHangingProtocol(protocol);
},
/**
* Show/hide the Protocol Editor sidebar
*/
'click #toggleProtocolEditor': function() {
// Select the Protocol Editor DOM element
var editor = $('#protocolEditor');
// Modulate the main viewer width in response to the sidebar being open
// This code is commented out so that the protocol editor is an overlay, rather than a sidebar
// This is something that is debatable at the moment, so I am not removing the code just yet
//
/* if (editor.hasClass('cbp-spmenu-open')) {
// Set the Viewer widths to reflect a hidden Protocol Editor
$('.viewerMain').width('calc(100% - 120px)');
$('.navbar').width('100%');
} else {
// Set the Viewer widths to reflect an open Protocol Editor
$('.viewerMain').width('calc(100% - 120px - 450px)');
$('.navbar').width('calc(100% - 450px)');
}*/
// Toggle a class reflect whether or not the Protocol Editor is displayed
editor.toggleClass('cbp-spmenu-open');
// Fire the resize handler after a short delay so that the animation can complete
setTimeout(handleResize, 150);
} }
}); });

View File

@ -2,7 +2,7 @@
{{ >ruleEntryDialog }} {{ >ruleEntryDialog }}
{{ >settingEntryDialog }} {{ >settingEntryDialog }}
{{ >textEntryDialog }} {{ >textEntryDialog }}
<div id='protocolEditor' class="cbp-spmenu cbp-spmenu-right"> <div id='protocolEditor'>
<div class="row"> <div class="row">
<div class="navigationButtons col-xs-12"> <div class="navigationButtons col-xs-12">
<ul class="nav nav-pills"> <ul class="nav nav-pills">

View File

@ -1,10 +1,14 @@
@import "{design}/app.styl"
$height = 20px
#protocolEditor #protocolEditor
height: 100% height: 100%
width: 450px width: 450px
padding: 10px padding: 10px
position: absolute position: absolute
top: 0 top: 0
background: #212121 background: $primaryBackgroundCOlor
.navigationButtons .navigationButtons
ul ul
@ -31,29 +35,27 @@
cursor: pointer cursor: pointer
text-decoration: none text-decoration: none
outline: none outline: none
background: #3e3e3e background-color: $uiGrayDark
color: #ffffff border: 1px $uiBorderColorDark solid
color: $textSecondaryColor
transition: transition($sidebarTransition)
border-radius: $height
-webkit-transition: all 0.3s ease &.active a
-moz-transition: all 0.3s ease background-color: $activeColor
-o-transition: all 0.3s ease border-color: $uiBorderColorActive
-ms-transition: all 0.3s ease color: $textColorActive
transition: all 0.3s ease transition: transition($sidebarTransition)
&.active
a
background: #ffffff
color: #3e3e3e
p p
h2 h2
h3 h3
h4 h4
color: #f5f5f5 color: $defaultColor
label label
ul ul
color: #f5f5f5 color: $defaultColor
font-weight: 400 font-weight: 400
label label
@ -66,7 +68,7 @@
width: 40% width: 40%
border: none border: none
background: #212121 background: #212121
color: #ffffff color: $defaultColor
text-align: center text-align: center
button.btn button.btn
@ -85,7 +87,7 @@
p p
font-size: 8pt font-size: 8pt
color: #B3B3B3 color: $defaultColor
margin: 0 10px margin: 0 10px
display: inline-block display: inline-block
@ -137,18 +139,4 @@
padding: 40px padding: 40px
h3 h3
color: #f5f5f5 color: $defaultColor
.cbp-spmenu-right
right: -450px
.cbp-spmenu-right.cbp-spmenu-open
right: 0
/* Transitions */
.cbp-spmenu
-webkit-transition: all 0.3s ease
-moz-transition: all 0.3s ease
transition: all 0.3s ease

View File

@ -1,8 +1,10 @@
@import "{design}/app.styl"
table.ruleTable table.ruleTable
thead thead
tr tr
th th
color: whitesmoke color: $defaultColor
text-align: center text-align: center
th:first-child th:first-child
@ -11,7 +13,7 @@ table.ruleTable
tbody tbody
tr tr
td td
color: #ffffff color: $defaultColor
text-align: center text-align: center
.failWarning .failWarning
@ -21,12 +23,13 @@ table.ruleTable
.deleteRule .deleteRule
&:hover, &:active &:hover, &:active
cursor: pointer cursor: pointer
color: #48d3ff transition(all 0.1s ease)
-webkit-transition: all 0.1s ease &:hover
-moz-transition: all 0.1s ease color: $hoverColor
transition: all 0.1s ease
&:active
color: $activeColor
td:first-child td:first-child
text-align: left text-align: left
@ -34,13 +37,14 @@ table.ruleTable
.addRuleContainer .addRuleContainer
margin: 10px 0 margin: 10px 0
text-align: center text-align: center
color: #ffffff color: $defaultColor
.addRule .addRule
&:hover, &:active cursor: pointer
cursor: pointer transition(all 0.1s ease)
color: #48d3ff
&:hover
-webkit-transition: all 0.1s ease color: $hoverColor
-moz-transition: all 0.1s ease
transition: all 0.1s ease &:active
color: $activeColor

View File

@ -1,8 +1,10 @@
@import "{design}/app.styl"
table.settingsTable table.settingsTable
thead thead
tr tr
th th
color: whitesmoke color: $defaultColor
text-align: center text-align: center
th:first-child th:first-child
@ -13,32 +15,34 @@ table.settingsTable
tr tr
td td
color: #ffffff color: $defaultColor
text-align: center text-align: center
.editSetting .editSetting
.deleteSetting .deleteSetting
&:hover, &:active cursor: pointer
cursor:pointer transition(all 0.1s ease)
color: #48d3ff
&:hover
-webkit-transition: all 0.1s ease color: $hoverColor
-moz-transition: all 0.1s ease
transition: all 0.1s ease &:active
color: $activeColor
td:first-child td:first-child
text-align: left text-align: left
.addSettingContainer .addSettingContainer
margin: 10px 0 margin: 10px 0
text-align: center text-align: center
color: #ffffff color: $defaultColor
.addSetting .addSetting
&:hover, &:active cursor: pointer
cursor: pointer transition(all 0.1s ease)
color: #48d3ff
&:hover
-webkit-transition: all 0.1s ease color: $hoverColor
-moz-transition: all 0.1s ease
transition: all 0.1s ease &:active
color: $activeColor

View File

@ -1,3 +1,5 @@
@import "{design}/app.styl"
#stageDetails #stageDetails
overflow-y: auto overflow-y: auto
overflow-x: hidden overflow-x: hidden
@ -6,12 +8,13 @@
margin-right: -16px margin-right: -16px
width: 100% width: 100%
height: 100% height: 100%
&::-webkit-scrollbar &::-webkit-scrollbar
display: none display: none
h3 h3
label label
color: #f5f5f5 color: $defaultColor
label label
margin-right: 10px margin-right: 10px
@ -21,8 +24,8 @@
min-width: 50px min-width: 50px
width: 40% width: 40%
border: none border: none
background: #3e3e3e background: $boxBackgroundColorDark
color: #ffffff color: $defaultColor
text-align: center text-align: center
.stageEditorSection .stageEditorSection

View File

@ -1,14 +1,19 @@
@import "{design}/app.styl"
#stageSortingContainer #stageSortingContainer
#stageSortable #stageSortable
.sortable-item .sortable-item
padding: 3px padding: 3px
span span
color: #ffffff color: $defaultColor
cursor: pointer cursor: pointer
&:hover
color: $hoverColor
&.active &.active
color: #46e7ff color: $activeColor
.sortable-handle .sortable-handle
cursor: move cursor: move
@ -29,42 +34,43 @@
.deleteStage .deleteStage
cursor: pointer cursor: pointer
color: white color: $defaultColor
-webkit-transition: all 0.1s ease transition(all 0.1s ease)
-moz-transition: all 0.1s ease
transition: all 0.1s ease &:hover
color: $hoverColor
&:active, &:hover
color: #48d3ff &:active
color: $activeColor
.addStage .addStage
margin: 10px 0 margin: 10px 0
text-align: center text-align: center
#addStage #addStage
cursor: pointer transition(all 0.1s ease)
color: #ffffff
-webkit-transition: all 0.1s ease &:hover
-moz-transition: all 0.1s ease color: $hoverColor
transition: all 0.1s ease
&:active
&:active, &:hover color: $activeColor
color: #48d3ff
.moveStageButtons .moveStageButtons
margin: 10px 0 margin: 10px 0
text-align: center text-align: center
a a
color: $defaultColor
cursor: pointer cursor: pointer
color: #ffffff
text-decoration: none text-decoration: none
-webkit-transition: all 0.1s ease transition(all 0.1s ease)
-moz-transition: all 0.1s ease
transition: all 0.1s ease &:hover
color: $hoverColor
&:active, &:hover
color: #48d3ff &:active
color: $activeColor
&[disabled="true"] &[disabled="true"]
opacity: 0.7 opacity: 0.7

View File

@ -5,10 +5,10 @@ Package.describe({
}); });
Package.onUse(function(api) { Package.onUse(function(api) {
api.versionsFrom('1.3.4.1'); api.versionsFrom('1.3.5.1');
api.use('standard-app-packages');
api.use('ecmascript'); api.use('ecmascript');
api.use('standard-app-packages');
api.use('jquery'); api.use('jquery');
api.use('stylus'); api.use('stylus');
api.use('rwatts:uuid'); api.use('rwatts:uuid');

View File

@ -1,102 +0,0 @@
@import "{design}/app"
$viewportTagPadding = 20px
$imageSliderBorderRadius = 57px
$imageSliderColor = $boxBackgroundColorDark
$imageSliderTrackColor = rgba(0,0,0,0)
$imageSliderBorder = none
// Note that these are backwards due to the magic needed to make a cross-browser vertical slider
$imageSliderWidth = 12px
$imageSliderHeight = 39px
$imageSliderCursor = grab
.imageViewerViewportOverlay
color: $textSecondaryColor
.dicomTag
font-weight: 200
.topleft
top: $viewportTagPadding
left: $viewportTagPadding
.topright
top: $viewportTagPadding
right: $viewportTagPadding
text-align: right
.bottomleft
bottom: $viewportTagPadding
left: $viewportTagPadding
.bottomright
bottom: $viewportTagPadding
right: $viewportTagPadding
text-align: right
.imageControls
#scrollbar
#imageSlider
-webkit-appearance: none
background-color: $imageSliderTrackColor
// --- Style the range track --- //
&::-webkit-slider-runnable-track
height: 5px
border: none
cursor: pointer
background-color: $imageSliderTrackColor
z-index: 6
&::-moz-range-track
height: 2px
border: none
cursor: pointer
background-color: $imageSliderTrackColor
z-index: 6
&::-ms-track
width: 100%
height: 2px
border: none
cursor: pointer
animate: 0.2s
background: transparent
border-width: 15px 0
color: $imageSliderTrackColor
// Hide any fill IE tries to add
&::-ms-fill-lower
background: $imageSliderTrackColor
&::-ms-fill-upper
background: $imageSliderTrackColor
// --- Style the range thumb --- //
&::-webkit-slider-thumb
-webkit-appearance: none !important
background-color: $imageSliderColor
border-radius: $imageSliderBorderRadius
border: $imageSliderBorder
height: $imageSliderWidth
width: $imageSliderHeight
cursor: $imageSliderCursor
margin-top: -7px
&::-moz-range-thumb
background-color: $imageSliderColor
border-radius: $imageSliderBorderRadius
border: $imageSliderBorder
height: $imageSliderWidth
width: $imageSliderHeight
cursor: $imageSliderCursor
z-index: 7
&::-ms-thumb
background-color: $imageSliderColor
border-radius: $imageSliderBorderRadius
border: $imageSliderBorder
height: $imageSliderWidth
width: $imageSliderHeight
cursor: $imageSliderCursor

View File

@ -8,30 +8,4 @@
height: 100% height: 100%
margin: 0 margin: 0
padding: 0 padding: 0
width: 100% width: 100%
//font awesome icons
.fa-cr:before
content: 'CR'
font-weight: bold
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif
.fa-un:before
content: 'UN'
font-weight: bold
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif
.fa-ex:before
content: 'EX'
font-weight: bold
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif
#btnCollapse
background-color: #333
border-color: black
&.active
border-color: #333
.btnCollapseIcon
color: white

View File

@ -5,7 +5,7 @@ Package.describe({
}); });
Package.onUse(function(api) { Package.onUse(function(api) {
api.versionsFrom('1.3.4.1'); api.versionsFrom('1.3.5.1');
api.use('ecmascript'); api.use('ecmascript');
api.use('standard-app-packages'); api.use('standard-app-packages');
@ -83,10 +83,6 @@ Package.onUse(function(api) {
api.addFiles('client/components/caseProgress/caseProgress.styl', 'client'); api.addFiles('client/components/caseProgress/caseProgress.styl', 'client');
api.addFiles('client/components/caseProgress/caseProgress.js', 'client'); api.addFiles('client/components/caseProgress/caseProgress.js', 'client');
api.addFiles('client/components/viewerMain/viewerMain.html', 'client');
api.addFiles('client/components/viewerMain/viewerMain.styl', 'client');
api.addFiles('client/components/viewerMain/viewerMain.js', 'client');
api.addFiles('client/components/lesionTracker/lesionTracker.html', 'client'); api.addFiles('client/components/lesionTracker/lesionTracker.html', 'client');
api.addFiles('client/components/lesionTracker/lesionTracker.styl', 'client'); api.addFiles('client/components/lesionTracker/lesionTracker.styl', 'client');
api.addFiles('client/components/lesionTracker/lesionTracker.js', 'client'); api.addFiles('client/components/lesionTracker/lesionTracker.js', 'client');
@ -190,7 +186,6 @@ Package.onUse(function(api) {
api.addFiles('client/components/lesionTrackerWorklistContextMenu/lesionTrackerWorklistContextMenu.js', 'client'); api.addFiles('client/components/lesionTrackerWorklistContextMenu/lesionTrackerWorklistContextMenu.js', 'client');
api.addFiles('client/components/lesionTrackerViewportOverlay/lesionTrackerViewportOverlay.html', 'client'); api.addFiles('client/components/lesionTrackerViewportOverlay/lesionTrackerViewportOverlay.html', 'client');
api.addFiles('client/components/lesionTrackerViewportOverlay/lesionTrackerViewportOverlay.styl', 'client');
api.addFiles('client/components/lesionTrackerViewportOverlay/lesionTrackerViewportOverlay.js', 'client'); api.addFiles('client/components/lesionTrackerViewportOverlay/lesionTrackerViewportOverlay.js', 'client');
api.addFiles('client/components/serverInformationModal/serverInformationModal.html', 'client'); api.addFiles('client/components/serverInformationModal/serverInformationModal.html', 'client');

View File

@ -1,3 +1,5 @@
import { Meteor } from 'meteor/meteor';
Meteor.publish('timepoints', function() { Meteor.publish('timepoints', function() {
return Timepoints.find(); return Timepoints.find();
}); });

View File

@ -5,7 +5,7 @@ Package.describe({
}); });
Package.onUse(function(api) { Package.onUse(function(api) {
api.versionsFrom('1.3.4.1'); api.versionsFrom('1.3.5.1');
api.use('ecmascript'); api.use('ecmascript');
api.use('standard-app-packages'); api.use('standard-app-packages');

View File

@ -5,7 +5,7 @@ Package.describe({
}); });
Package.onUse(function(api) { Package.onUse(function(api) {
api.versionsFrom('1.3.4.1'); api.versionsFrom('1.3.5.1');
api.use('ecmascript'); api.use('ecmascript');

View File

@ -1,16 +1,18 @@
@import "{design}/app.styl"
#imageViewerViewports #imageViewerViewports
height: 100% height: 100%
width: 100% width: 100%
.viewportContainer .viewportContainer
float: left float: left
border: 2px solid #777 border: $viewportBorderThickness solid $viewportBorderColor
&.active, &:hover.active &.active, &:hover.active
border: 2px solid #9A6617 border: $viewportBorderThickness solid $viewportBorderColorActive
&:hover &:hover
border: 2px solid white border: $viewportBorderThickness solid $viewportBorderColorHover
.removable .removable
width: 100% width: 100%

View File

@ -1,10 +1,12 @@
@import "{design}/app.styl"
.imageViewerViewport .imageViewerViewport
width: 100% width: 100%
height: 100% height: 100%
background-color: black background-color: black
// Prevent the blue outline in Chrome when a viewport is selected // Prevent the blue outline in Chrome when a viewport is selected
outline: 0 !important; outline: 0 !important
// Prevents the entire page from getting larger // Prevents the entire page from getting larger
// when the magnify tool is near the sides/corners of the page // when the magnify tool is near the sides/corners of the page
@ -13,7 +15,7 @@
.viewportInstructions .viewportInstructions
display: none display: none
font-size: 13px font-size: 13px
color: #e4ad00 color: $textSecondaryColor
line-height: 18px line-height: 18px
pointer-events: none // Necessary for drag/drop through to cornerstone element below pointer-events: none // Necessary for drag/drop through to cornerstone element below
text-align: center text-align: center
@ -27,18 +29,9 @@
/* These are some good CSS settings for a circular magnifying glass /* These are some good CSS settings for a circular magnifying glass
Try removing the border-radius to make a square magnifying glass */ Try removing the border-radius to make a square magnifying glass */
.magnifyTool{ .magnifyTool
border: 4px white solid; border: 4px white solid
box-shadow: 2px 2px 10px #1e1e1e; box-shadow: 2px 2px 10px #1e1e1e
border-radius: 50%; border-radius: 50%
display: none; display: none
cursor: none; cursor: none
}
/* prevents selection when left click dragging */
.disable-selection {
-moz-user-select: none; -webkit-user-select: none; -ms-user-select:none; user-select:none;
}
/* prevents cursor from changing to the i bar on the overlays*/
.noIbar {
cursor:default;
}

View File

@ -1,18 +1,22 @@
@import "{design}/app.styl"
.layoutChooser .layoutChooser
width: 92px width: 92px
height: 92px height: 92px
min-width: 92px // to override bootstrap's dropdown-menu class min-width: 92px // to override bootstrap's dropdown-menu class
min-height: 92px min-height: 92px
background-color: $primaryBackgroundColor
border: 2px solid $uiBorderColorDark
table table
margin: 0 auto margin: 0 auto
td td
cursor: pointer cursor: pointer
border: 2px solid black border: 2px solid $uiBorderColorDark
width: 20px width: 20px
height: 20px height: 20px
transition: background-color 0.1s ease transition(background-color 0.1s ease)
&:hover, &.hover // Add the hover class here to be triggered by mouseenter/mouseleave &:hover, &.hover // Add the hover class here to be triggered by mouseenter/mouseleave
background-color: gray background-color: $activeColor

View File

@ -1,6 +1,8 @@
@import "{design}/app.styl"
.imageViewerLoadingIndicator .imageViewerLoadingIndicator
display: none display: none
color: #ffa500 color: $textPrimaryColor
.faded .faded
opacity: 0.5 opacity: 0.5
@ -11,7 +13,7 @@
p, h4 p, h4
text-align: center text-align: center
color: #ffa500 color: $textColorActive
padding: 4px 0px padding: 4px 0px
p p

View File

@ -1,14 +1,24 @@
<template name="playClipButton"> <template name="playClipButton">
<button id="playClip" type="button" class="imageViewerCommand btn btn-sm btn-default" <button id="playClip"
data-container="body" data-toggle="tooltip" data-placement="bottom" title="Play/Stop Clip"> type="button"
class="imageViewerCommand btn btn-sm {{ #if isPlaying }}active{{/if}}"
data-container="body"
data-toggle="tooltip"
data-placement="bottom"
title="Play/Stop Clip">
{{ #if isPlaying }} {{ #if isPlaying }}
<span class="fa fa-stop"></span> <span class="fa fa-stop"></span>
{{ else }} {{ else }}
<span class="fa fa-play"></span> <span class="fa fa-play"></span>
{{ /if }} {{ /if }}
</button> </button>
<button id="toggleCineDialog" type="button" class="imageViewerCommand btn btn-sm btn-default" <button id="toggleCineDialog"
data-container="body" data-toggle="tooltip" data-placement="bottom" title="Toggle CINE Dialog"> type="button"
class="imageViewerCommand btn btn-sm"
data-container="body"
data-toggle="tooltip"
data-placement="bottom"
title="Toggle CINE Dialog">
<span class="fa fa-youtube-play"></span> <span class="fa fa-youtube-play"></span>
</button> </button>
</template> </template>

View File

@ -1,5 +1,11 @@
<template name="simpleToolbarButton"> <template name="simpleToolbarButton">
<button id="{{id}}" type="button" class="{{classes}} btn btn-sm btn-default" data-container="body" data-toggle="tooltip" data-placement="bottom" title="{{title}}"> <button id="{{id}}"
type="button"
class="{{classes}} btn btn-sm {{activeClass}}"
data-container="body"
data-toggle="tooltip"
data-placement="bottom"
title="{{title}}">
<span class="{{iconClasses}}"></span> <span class="{{iconClasses}}"></span>
</button> </button>
</template> </template>

View File

@ -0,0 +1,13 @@
Template.simpleToolbarButton.helpers({
activeClass() {
const instance = Template.instance();
// Check if the current tool is the active one
if (instance.data.id === Session.get('ToolManagerActiveTool')) {
// Return the active class
return 'active';
}
return;
}
});

View File

@ -1,31 +1,37 @@
<template name="toolbar"> <template name="toolbar">
<div id='toolbar'> <div class="btn-group">
{{ #each button }}
{{ >simpleToolbarButton}}
{{ /each }}
{{ #if includePlayClipButton }}
{{ >playClipButton }}
{{ /if }}
{{ #if includeLayoutButton }}
<div class="btn-group"> <div class="btn-group">
{{ #each button }} <button id="layout"
{{ >simpleToolbarButton}} type="button"
{{ /each }} class="btn btn-sm dropdown-toggle"
data-container="body"
{{ #if includePlayClipButton }} data-toggle="dropdown"
{{ >playClipButton }} aria-expanded="false"
{{ /if }} data-placement="right"
title="Layout"
{{ #if includeLayoutButton }} rel="tooltip">
<div class="btn-group"> <span class="fa fa-th-large"></span>
<button id="layout" type="button" class="btn btn-sm btn-default dropdown-toggle" data-container="body" data-toggle="dropdown" aria-expanded="false" data-placement="right" title="Layout" rel="tooltip"> </button>
<span class="fa fa-th-large"></span> {{ >layoutChooser }}
</button>
{{ >layoutChooser }}
</div>
{{ /if }}
{{ #if includeHangingProtocolButtons }}
{{ >hangingProtocolButtons }}
{{ >matchedProtocols }}
{{ /if }}
{{ #each btnGroup }}
{{ >toolbarGroupButton}}
{{ /each }}
</div> </div>
{{ /if }}
{{ #if includeHangingProtocolButtons }}
{{ >hangingProtocolButtons }}
{{ >matchedProtocols }}
{{ /if }}
{{ #each btnGroup }}
{{ >toolbarGroupButton}}
{{ /each }}
</div> </div>
</template> </template>

View File

@ -1,16 +1,21 @@
#toolbar @import "{design}/app.styl"
background-color: black
text-align: center .btn-group
background-color: $primaryBackgroundColor
display: inline-block
.btn-group button
display: inline-block text-align: center
color: $defaultColor
background-color: $primaryBackgroundColor
border-color: $uiBorderColor
transition(all 0.1s ease)
button // Prevent the blue outline in Chrome when a viewport is selected
text-align: center outline: 0 !important
color: #ffffff
background-color: #424242 &:hover
border-color: #424242 color: $hoverColor
outline: none
&.active, &:active
&.active, &:active color: $activeColor
background-color: #3B678E

View File

@ -1,12 +0,0 @@
<template name="toolbarGroupButton">
<div id="toolbarGroupButton" class="btn-group">
<button class="btn btn-secondary btn-sm dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" id="{{id}}" title="{{title}}">
<i class="{{groupIcon}}"></i>
</button>
<div class="dropdown-menu">
{{#each tools}}
<div><a class="dropdown-item" href="#">{{> simpleToolbarButton}}</a></div>
{{/each}}
</div>
</div>
</template>

View File

@ -1,14 +0,0 @@
#toolbarGroupButton
button
&.active, &:active
background-color: #3B678E
.dropdown-menu
background-color: black
border: solid 1px #333
padding: 5px
margin-top: 0
div
padding: 5px
float: left

View File

@ -1,31 +1,107 @@
@import "{design}/app"
$viewportTagPadding = 20px
$imageSliderBorderRadius = 57px
$imageSliderColor = $boxBackgroundColorDark
$imageSliderTrackColor = rgba(0,0,0,0)
$imageSliderBorder = none
// Note that these are backwards due to the magic needed to make a cross-browser vertical slider
$imageSliderWidth = 12px
$imageSliderHeight = 39px
$imageSliderCursor = grab
.imageViewerViewportOverlay .imageViewerViewportOverlay
font-size: 18px color: $textSecondaryColor
color: #979797
line-height: 1.4
display: none // Shown when an image is loaded
.dicomTag .dicomTag
pointer-events: none // Necessary for drag/drop through to cornerstone element below
position: absolute position: absolute
font-weight: 200
.topleft .topleft
top: 3px top: $viewportTagPadding
left: 3px left: $viewportTagPadding
.topright .topright
top: 3px top: $viewportTagPadding
right: 3px right: $viewportTagPadding
text-align: right
.bottomleft
bottom: 3px
left: 3px
.bottomright
bottom: 3px
right: 3px
text-align: right text-align: right
.bottomleft
bottom: $viewportTagPadding
left: $viewportTagPadding
.bottomright
bottom: $viewportTagPadding
right: $viewportTagPadding
text-align: right
.priorIndicator .priorIndicator
font-weight: bold font-weight: bold
color: yellow color: yellow
.imageControls
#scrollbar
#imageSlider
-webkit-appearance: none
background-color: $imageSliderTrackColor
// --- Style the range track --- //
&::-webkit-slider-runnable-track
height: 5px
border: none
cursor: pointer
background-color: $imageSliderTrackColor
z-index: 6
&::-moz-range-track
height: 2px
border: none
cursor: pointer
background-color: $imageSliderTrackColor
z-index: 6
&::-ms-track
width: 100%
height: 2px
border: none
cursor: pointer
animate: 0.2s
background: transparent
border-width: 15px 0
color: $imageSliderTrackColor
// Hide any fill IE tries to add
&::-ms-fill-lower
background: $imageSliderTrackColor
&::-ms-fill-upper
background: $imageSliderTrackColor
// --- Style the range thumb --- //
&::-webkit-slider-thumb
-webkit-appearance: none !important
background-color: $imageSliderColor
border-radius: $imageSliderBorderRadius
border: $imageSliderBorder
height: $imageSliderWidth
width: $imageSliderHeight
cursor: $imageSliderCursor
margin-top: -7px
&::-moz-range-thumb
background-color: $imageSliderColor
border-radius: $imageSliderBorderRadius
border: $imageSliderBorder
height: $imageSliderWidth
width: $imageSliderHeight
cursor: $imageSliderCursor
z-index: 7
&::-ms-thumb
background-color: $imageSliderColor
border-radius: $imageSliderBorderRadius
border: $imageSliderBorder
height: $imageSliderWidth
width: $imageSliderHeight
cursor: $imageSliderCursor

View File

@ -0,0 +1,59 @@
/**
* Checks whether dicom files with specified SOP Class UID have image data
* @param {string} sopClassUid - SOP Class UID to be checked
* @returns {boolean} - true if it has image data
*/
isImage = function(sopClassUid) {
if (sopClassUid == sopClassDictionary.ComputedRadiographyImageStorage
|| sopClassUid == sopClassDictionary.DigitalXRayImageStorageForPresentation
|| sopClassUid == sopClassDictionary.DigitalXRayImageStorageForProcessing
|| sopClassUid == sopClassDictionary.DigitalMammographyXRayImageStorageForPresentation
|| sopClassUid == sopClassDictionary.DigitalMammographyXRayImageStorageForProcessing
|| sopClassUid == sopClassDictionary.DigitalIntraOralXRayImageStorageForPresentation
|| sopClassUid == sopClassDictionary.DigitalIntraOralXRayImageStorageForProcessing
|| sopClassUid == sopClassDictionary.CTImageStorage
|| sopClassUid == sopClassDictionary.EnhancedCTImageStorage
|| sopClassUid == sopClassDictionary.LegacyConvertedEnhancedCTImageStorage
|| sopClassUid == sopClassDictionary.UltrasoundMultiframeImageStorage
|| sopClassUid == sopClassDictionary.MRImageStorage
|| sopClassUid == sopClassDictionary.EnhancedMRImageStorage
|| sopClassUid == sopClassDictionary.EnhancedMRColorImageStorage
|| sopClassUid == sopClassDictionary.LegacyConvertedEnhancedMRImageStorage
|| sopClassUid == sopClassDictionary.UltrasoundImageStorage
|| sopClassUid == sopClassDictionary.SecondaryCaptureImageStorage
|| sopClassUid == sopClassDictionary.MultiframeSingleBitSecondaryCaptureImageStorage
|| sopClassUid == sopClassDictionary.MultiframeGrayscaleByteSecondaryCaptureImageStorage
|| sopClassUid == sopClassDictionary.MultiframeGrayscaleWordSecondaryCaptureImageStorage
|| sopClassUid == sopClassDictionary.MultiframeTrueColorSecondaryCaptureImageStorage
|| sopClassUid == sopClassDictionary.XRayAngiographicImageStorage
|| sopClassUid == sopClassDictionary.EnhancedXAImageStorage
|| sopClassUid == sopClassDictionary.XRayRadiofluoroscopicImageStorage
|| sopClassUid == sopClassDictionary.EnhancedXRFImageStorage
|| sopClassUid == sopClassDictionary.XRay3DAngiographicImageStorage
|| sopClassUid == sopClassDictionary.XRay3DCraniofacialImageStorage
|| sopClassUid == sopClassDictionary.BreastTomosynthesisImageStorage
|| sopClassUid == sopClassDictionary.BreastProjectionXRayImageStorageForPresentation
|| sopClassUid == sopClassDictionary.BreastProjectionXRayImageStorageForProcessing
|| sopClassUid == sopClassDictionary.IntravascularOpticalCoherenceTomographyImageStorageForPresentation
|| sopClassUid == sopClassDictionary.IntravascularOpticalCoherenceTomographyImageStorageForProcessing
|| sopClassUid == sopClassDictionary.NuclearMedicineImageStorage
|| sopClassUid == sopClassDictionary.VLEndoscopicImageStorage
|| sopClassUid == sopClassDictionary.VideoEndoscopicImageStorage
|| sopClassUid == sopClassDictionary.VLMicroscopicImageStorage
|| sopClassUid == sopClassDictionary.VideoMicroscopicImageStorage
|| sopClassUid == sopClassDictionary.VLSlideCoordinatesMicroscopicImageStorage
|| sopClassUid == sopClassDictionary.VLPhotographicImageStorage
|| sopClassUid == sopClassDictionary.VideoPhotographicImageStorage
|| sopClassUid == sopClassDictionary.OphthalmicPhotography8BitImageStorage
|| sopClassUid == sopClassDictionary.OphthalmicPhotography16BitImageStorage
|| sopClassUid == sopClassDictionary.OphthalmicTomographyImageStorage
|| sopClassUid == sopClassDictionary.VLWholeSlideMicroscopyImageStorage
|| sopClassUid == sopClassDictionary.PositronEmissionTomographyImageStorage
|| sopClassUid == sopClassDictionary.EnhancedPETImageStorage
|| sopClassUid == sopClassDictionary.LegacyConvertedEnhancedPETImageStorage
|| sopClassUid == sopClassDictionary.RTImageStorage) {
return true;
}
return false;
};

View File

@ -0,0 +1,115 @@
sopClassDictionary = {
ComputedRadiographyImageStorage: "1.2.840.10008.5.1.4.1.1.1",
DigitalXRayImageStorageForPresentation: "1.2.840.10008.5.1.4.1.1.1.1",
DigitalXRayImageStorageForProcessing: "1.2.840.10008.5.1.4.1.1.1.1.1",
DigitalMammographyXRayImageStorageForPresentation: "1.2.840.10008.5.1.4.1.1.1.2",
DigitalMammographyXRayImageStorageForProcessing: "1.2.840.10008.5.1.4.1.1.1.2.1",
DigitalIntraOralXRayImageStorageForPresentation: "1.2.840.10008.5.1.4.1.1.1.3",
DigitalIntraOralXRayImageStorageForProcessing: "1.2.840.10008.5.1.4.1.1.1.3.1",
CTImageStorage: "1.2.840.10008.5.1.4.1.1.2",
EnhancedCTImageStorage: "1.2.840.10008.5.1.4.1.1.2.1",
LegacyConvertedEnhancedCTImageStorage: "1.2.840.10008.5.1.4.1.1.2.2",
UltrasoundMultiframeImageStorage: "1.2.840.10008.5.1.4.1.1.3.1",
MRImageStorage: "1.2.840.10008.5.1.4.1.1.4",
EnhancedMRImageStorage: "1.2.840.10008.5.1.4.1.1.4.1",
MRSpectroscopyStorage: "1.2.840.10008.5.1.4.1.1.4.2",
EnhancedMRColorImageStorage: "1.2.840.10008.5.1.4.1.1.4.3",
LegacyConvertedEnhancedMRImageStorage: "1.2.840.10008.5.1.4.1.1.4.4",
UltrasoundImageStorage: "1.2.840.10008.5.1.4.1.1.6.1",
EnhancedUSVolumeStorage: "1.2.840.10008.5.1.4.1.1.6.2",
SecondaryCaptureImageStorage: "1.2.840.10008.5.1.4.1.1.7",
MultiframeSingleBitSecondaryCaptureImageStorage: "1.2.840.10008.5.1.4.1.1.7.1",
MultiframeGrayscaleByteSecondaryCaptureImageStorage: "1.2.840.10008.5.1.4.1.1.7.2",
MultiframeGrayscaleWordSecondaryCaptureImageStorage: "1.2.840.10008.5.1.4.1.1.7.3",
MultiframeTrueColorSecondaryCaptureImageStorage: "1.2.840.10008.5.1.4.1.1.7.4",
Sop12LeadECGWaveformStorage: "1.2.840.10008.5.1.4.1.1.9.1.1",
GeneralECGWaveformStorage: "1.2.840.10008.5.1.4.1.1.9.1.2",
AmbulatoryECGWaveformStorage: "1.2.840.10008.5.1.4.1.1.9.1.3",
HemodynamicWaveformStorage: "1.2.840.10008.5.1.4.1.1.9.2.1",
CardiacElectrophysiologyWaveformStorage: "1.2.840.10008.5.1.4.1.1.9.3.1",
BasicVoiceAudioWaveformStorage: "1.2.840.10008.5.1.4.1.1.9.4.1",
GeneralAudioWaveformStorage: "1.2.840.10008.5.1.4.1.1.9.4.2",
ArterialPulseWaveformStorage: "1.2.840.10008.5.1.4.1.1.9.5.1",
RespiratoryWaveformStorage: "1.2.840.10008.5.1.4.1.1.9.6.1",
GrayscaleSoftcopyPresentationStateStorage: "1.2.840.10008.5.1.4.1.1.11.1",
ColorSoftcopyPresentationStateStorage: "1.2.840.10008.5.1.4.1.1.11.2",
PseudoColorSoftcopyPresentationStateStorage: "1.2.840.10008.5.1.4.1.1.11.3",
BlendingSoftcopyPresentationStateStorage: "1.2.840.10008.5.1.4.1.1.11.4",
XAXRFGrayscaleSoftcopyPresentationStateStorage: "1.2.840.10008.5.1.4.1.1.11.5",
XRayAngiographicImageStorage: "1.2.840.10008.5.1.4.1.1.12.1",
EnhancedXAImageStorage: "1.2.840.10008.5.1.4.1.1.12.1.1",
XRayRadiofluoroscopicImageStorage: "1.2.840.10008.5.1.4.1.1.12.2",
EnhancedXRFImageStorage: "1.2.840.10008.5.1.4.1.1.12.2.1",
XRay3DAngiographicImageStorage: "1.2.840.10008.5.1.4.1.1.13.1.1",
XRay3DCraniofacialImageStorage: "1.2.840.10008.5.1.4.1.1.13.1.2",
BreastTomosynthesisImageStorage: "1.2.840.10008.5.1.4.1.1.13.1.3",
BreastProjectionXRayImageStorageForPresentation: "1.2.840.10008.5.1.4.1.1.13.1.4",
BreastProjectionXRayImageStorageForProcessing: "1.2.840.10008.5.1.4.1.1.13.1.5",
IntravascularOpticalCoherenceTomographyImageStorageForPresentation: "1.2.840.10008.5.1.4.1.1.14.1",
IntravascularOpticalCoherenceTomographyImageStorageForProcessing: "1.2.840.10008.5.1.4.1.1.14.2",
NuclearMedicineImageStorage: "1.2.840.10008.5.1.4.1.1.20",
RawDataStorage: "1.2.840.10008.5.1.4.1.1.66",
SpatialRegistrationStorage: "1.2.840.10008.5.1.4.1.1.66.1",
SpatialFiducialsStorage: "1.2.840.10008.5.1.4.1.1.66.2",
DeformableSpatialRegistrationStorage: "1.2.840.10008.5.1.4.1.1.66.3",
SegmentationStorage: "1.2.840.10008.5.1.4.1.1.66.4",
SurfaceSegmentationStorage: "1.2.840.10008.5.1.4.1.1.66.5",
RealWorldValueMappingStorage: "1.2.840.10008.5.1.4.1.1.67",
SurfaceScanMeshStorage: "1.2.840.10008.5.1.4.1.1.68.1",
SurfaceScanPointCloudStorage: "1.2.840.10008.5.1.4.1.1.68.2",
VLEndoscopicImageStorage: "1.2.840.10008.5.1.4.1.1.77.1.1",
VideoEndoscopicImageStorage: "1.2.840.10008.5.1.4.1.1.77.1.1.1",
VLMicroscopicImageStorage: "1.2.840.10008.5.1.4.1.1.77.1.2",
VideoMicroscopicImageStorage: "1.2.840.10008.5.1.4.1.1.77.1.2.1",
VLSlideCoordinatesMicroscopicImageStorage: "1.2.840.10008.5.1.4.1.1.77.1.3",
VLPhotographicImageStorage: "1.2.840.10008.5.1.4.1.1.77.1.4",
VideoPhotographicImageStorage: "1.2.840.10008.5.1.4.1.1.77.1.4.1",
OphthalmicPhotography8BitImageStorage: "1.2.840.10008.5.1.4.1.1.77.1.5.1",
OphthalmicPhotography16BitImageStorage: "1.2.840.10008.5.1.4.1.1.77.1.5.2",
StereometricRelationshipStorage: "1.2.840.10008.5.1.4.1.1.77.1.5.3",
OphthalmicTomographyImageStorage: "1.2.840.10008.5.1.4.1.1.77.1.5.4",
VLWholeSlideMicroscopyImageStorage: "1.2.840.10008.5.1.4.1.1.77.1.6",
LensometryMeasurementsStorage: "1.2.840.10008.5.1.4.1.1.78.1",
AutorefractionMeasurementsStorage: "1.2.840.10008.5.1.4.1.1.78.2",
KeratometryMeasurementsStorage: "1.2.840.10008.5.1.4.1.1.78.3",
SubjectiveRefractionMeasurementsStorage: "1.2.840.10008.5.1.4.1.1.78.4",
VisualAcuityMeasurementsStorage: "1.2.840.10008.5.1.4.1.1.78.5",
SpectaclePrescriptionReportStorage: "1.2.840.10008.5.1.4.1.1.78.6",
OphthalmicAxialMeasurementsStorage: "1.2.840.10008.5.1.4.1.1.78.7",
IntraocularLensCalculationsStorage: "1.2.840.10008.5.1.4.1.1.78.8",
MacularGridThicknessandVolumeReport: "1.2.840.10008.5.1.4.1.1.79.1",
OphthalmicVisualFieldStaticPerimetryMeasurementsStorage: "1.2.840.10008.5.1.4.1.1.80.1",
OphthalmicThicknessMapStorage: "1.2.840.10008.5.1.4.1.1.81.1",
CornealTopographyMapStorage: "1.2.840.10008.5.1.4.1.1.82.1",
BasicTextSR: "1.2.840.10008.5.1.4.1.1.88.11",
EnhancedSR: "1.2.840.10008.5.1.4.1.1.88.22",
ComprehensiveSR: "1.2.840.10008.5.1.4.1.1.88.33",
Comprehensive3DSR: "1.2.840.10008.5.1.4.1.1.88.34",
ProcedureLog: "1.2.840.10008.5.1.4.1.1.88.40",
MammographyCADSR: "1.2.840.10008.5.1.4.1.1.88.50",
KeyObjectSelection: "1.2.840.10008.5.1.4.1.1.88.59",
ChestCADSR: "1.2.840.10008.5.1.4.1.1.88.65",
XRayRadiationDoseSR: "1.2.840.10008.5.1.4.1.1.88.67",
RadiopharmaceuticalRadiationDoseSR: "1.2.840.10008.5.1.4.1.1.88.68",
ColonCADSR: "1.2.840.10008.5.1.4.1.1.88.69",
ImplantationPlanSRDocumentStorage: "1.2.840.10008.5.1.4.1.1.88.70",
EncapsulatedPDFStorage: "1.2.840.10008.5.1.4.1.1.104.1",
EncapsulatedCDAStorage: "1.2.840.10008.5.1.4.1.1.104.2",
PositronEmissionTomographyImageStorage: "1.2.840.10008.5.1.4.1.1.128",
EnhancedPETImageStorage: "1.2.840.10008.5.1.4.1.1.130",
LegacyConvertedEnhancedPETImageStorage: "1.2.840.10008.5.1.4.1.1.128.1",
BasicStructuredDisplayStorage: "1.2.840.10008.5.1.4.1.1.131",
RTImageStorage: "1.2.840.10008.5.1.4.1.1.481.1",
RTDoseStorage: "1.2.840.10008.5.1.4.1.1.481.2",
RTStructureSetStorage: "1.2.840.10008.5.1.4.1.1.481.3",
RTBeamsTreatmentRecordStorage: "1.2.840.10008.5.1.4.1.1.481.4",
RTPlanStorage: "1.2.840.10008.5.1.4.1.1.481.5",
RTBrachyTreatmentRecordStorage: "1.2.840.10008.5.1.4.1.1.481.6",
RTTreatmentSummaryRecordStorage: "1.2.840.10008.5.1.4.1.1.481.7",
RTIonPlanStorage: "1.2.840.10008.5.1.4.1.1.481.8",
RTIonBeamsTreatmentRecordStorage: "1.2.840.10008.5.1.4.1.1.481.9",
RTBeamsDeliveryInstructionStorage: "1.2.840.10008.5.1.4.34.7",
GenericImplantTemplateStorage: "1.2.840.10008.5.1.4.43.1",
ImplantAssemblyTemplateStorage: "1.2.840.10008.5.1.4.44.1",
ImplantTemplateGroupStorage: "1.2.840.10008.5.1.4.45.1"
};

View File

@ -5,19 +5,20 @@ Package.describe({
}); });
Package.onUse(function(api) { Package.onUse(function(api) {
api.versionsFrom('1.3.4.1'); api.versionsFrom('1.3.5.1');
api.use('standard-app-packages');
api.use('ecmascript'); api.use('ecmascript');
api.use('standard-app-packages');
api.use('http'); api.use('http');
api.use('jquery'); api.use('jquery');
api.use('stylus'); api.use('stylus');
api.use('practicalmeteor:loglevel'); api.use('practicalmeteor:loglevel');
api.use('momentjs:moment'); api.use('momentjs:moment');
api.use('validatejs'); api.use('validatejs');
api.use('design');
// Our custom packages // Our custom packages
api.use('design');
api.use('ohif:core');
api.use('cornerstone'); api.use('cornerstone');
api.addFiles('log.js'); api.addFiles('log.js');
@ -25,9 +26,6 @@ Package.onUse(function(api) {
// TODO: Use NPM depends for these // TODO: Use NPM depends for these
api.addFiles('client/compatibility/jquery.hotkeys.js', 'client'); api.addFiles('client/compatibility/jquery.hotkeys.js', 'client');
// Data validation (the Meteor package is currently out-of-date)
//api.addFiles('client/compatibility/validate.js', 'client');
// ---------- Collections ---------- // ---------- Collections ----------
api.addFiles('client/collections.js', 'client'); api.addFiles('client/collections.js', 'client');
@ -82,6 +80,10 @@ Package.onUse(function(api) {
api.addFiles('client/components/viewer/viewportOverlay/viewportOverlay.js', 'client'); api.addFiles('client/components/viewer/viewportOverlay/viewportOverlay.js', 'client');
api.addFiles('client/components/viewer/viewportOverlay/viewportOverlay.styl', 'client'); api.addFiles('client/components/viewer/viewportOverlay/viewportOverlay.styl', 'client');
api.addFiles('client/components/viewer/viewerMain/viewerMain.html', 'client');
api.addFiles('client/components/viewer/viewerMain/viewerMain.js', 'client');
api.addFiles('client/components/viewer/viewerMain/viewerMain.styl', 'client');
api.addFiles('client/components/viewer/imageControls/imageControls.html', 'client'); api.addFiles('client/components/viewer/imageControls/imageControls.html', 'client');
api.addFiles('client/components/viewer/imageControls/imageControls.js', 'client'); api.addFiles('client/components/viewer/imageControls/imageControls.js', 'client');
api.addFiles('client/components/viewer/imageControls/imageControls.styl', 'client'); api.addFiles('client/components/viewer/imageControls/imageControls.styl', 'client');
@ -95,6 +97,7 @@ Package.onUse(function(api) {
api.addFiles('client/components/viewer/cineDialog/cineDialog.styl', 'client'); api.addFiles('client/components/viewer/cineDialog/cineDialog.styl', 'client');
api.addFiles('client/components/viewer/simpleToolbarButton/simpleToolbarButton.html', 'client'); api.addFiles('client/components/viewer/simpleToolbarButton/simpleToolbarButton.html', 'client');
api.addFiles('client/components/viewer/simpleToolbarButton/simpleToolbarButton.js', 'client');
api.addFiles('client/components/viewer/playClipButton/playClipButton.html', 'client'); api.addFiles('client/components/viewer/playClipButton/playClipButton.html', 'client');
api.addFiles('client/components/viewer/playClipButton/playClipButton.js', 'client'); api.addFiles('client/components/viewer/playClipButton/playClipButton.js', 'client');
@ -103,10 +106,6 @@ Package.onUse(function(api) {
api.addFiles('client/components/viewer/toolbar/toolbar.js', 'client'); api.addFiles('client/components/viewer/toolbar/toolbar.js', 'client');
api.addFiles('client/components/viewer/toolbar/toolbar.styl', 'client'); api.addFiles('client/components/viewer/toolbar/toolbar.styl', 'client');
api.addFiles('client/components/viewer/toolbarGroupButton/toolbarGroupButton.html', 'client');
api.addFiles('client/components/viewer/toolbarGroupButton/toolbarGroupButton.styl', 'client');
api.addFiles('client/components/viewer/toolbarGroupButton/toolbarGroupButton.js', 'client');
// Library functions // Library functions
api.addFiles('lib/layoutManager.js', 'client'); api.addFiles('lib/layoutManager.js', 'client');
api.addFiles('lib/createStacks.js', 'client'); api.addFiles('lib/createStacks.js', 'client');
@ -132,6 +131,8 @@ Package.onUse(function(api) {
//api.addFiles('lib/validators.js', 'client'); //api.addFiles('lib/validators.js', 'client');
api.addFiles('lib/instanceClassSpecificViewport.js', 'client'); api.addFiles('lib/instanceClassSpecificViewport.js', 'client');
api.addFiles('lib/setMammogramViewportAlignment.js', 'client'); api.addFiles('lib/setMammogramViewportAlignment.js', 'client');
api.addFiles('lib/isImage.js', 'client');
api.addFiles('lib/sopClassDictionary.js', 'client');
api.export('resizeViewportElements', 'client'); api.export('resizeViewportElements', 'client');
api.export('handleResize', 'client'); api.export('handleResize', 'client');
@ -156,9 +157,8 @@ Package.onUse(function(api) {
api.export('showConfirmDialog', 'client'); api.export('showConfirmDialog', 'client');
api.export('applyWLPreset', 'client'); api.export('applyWLPreset', 'client');
api.export('toggleDialog', 'client'); api.export('toggleDialog', 'client');
api.export('isImage', 'client');
// Export the ValidateJS Library with our added validators api.export('sopClassDictionary', 'client');
//api.export('validate', 'client');
// Viewer management objects // Viewer management objects
api.export('toolManager', 'client'); api.export('toolManager', 'client');

View File

@ -1,14 +1,6 @@
body body
background-color: black background-color: black
.noselect
-webkit-touch-callout: none
-webkit-user-select: none
-khtml-user-select: none
-moz-user-select: none
-ms-user-select: none
user-select: none
#tblStudyList #tblStudyList
tr tr
height: 20px height: 20px
@ -74,7 +66,6 @@ body
&:hover &:hover
color: red color: red
.tab-content .tab-content
width: 100% width: 100%
height: calc(100% - 91px) height: calc(100% - 91px)

View File

@ -203,8 +203,10 @@ Template.worklistResult.onCreated(function() {
}); });
Template.worklistResult.onRendered(function() { Template.worklistResult.onRendered(function() {
const instance = Template.instance();
// Initialize daterangepicker // Initialize daterangepicker
$('#studyDate').daterangepicker({ instance.$('#studyDate').daterangepicker({
ranges: { ranges: {
Today: [moment(), moment()], Today: [moment(), moment()],
'Last 7 Days': [moment().subtract(6, 'days'), moment()], 'Last 7 Days': [moment().subtract(6, 'days'), moment()],

View File

@ -5,8 +5,9 @@ Package.describe({
}); });
Package.onUse(function (api) { Package.onUse(function (api) {
api.versionsFrom('1.2.1'); api.versionsFrom('1.3.5.1');
api.use('ecmascript');
api.use('standard-app-packages'); api.use('standard-app-packages');
api.use('jquery'); api.use('jquery');
api.use('stylus'); api.use('stylus');
@ -15,6 +16,11 @@ Package.onUse(function (api) {
api.use('rwatts:uuid'); api.use('rwatts:uuid');
api.use('silentcicero:jszip'); api.use('silentcicero:jszip');
// Note: MomentJS appears to be required for Bootstrap3 Datepicker, but not a dependency for some reason
api.use('momentjs:moment');
api.use('gilbertwat:bootstrap3-daterangepicker');
// Our custom packages // Our custom packages
api.use('design'); api.use('design');
api.use('dicomweb'); api.use('dicomweb');