diff --git a/LesionTracker/.meteor/.finished-upgraders b/LesionTracker/.meteor/.finished-upgraders
index 3e712bc5a..a541808f2 100644
--- a/LesionTracker/.meteor/.finished-upgraders
+++ b/LesionTracker/.meteor/.finished-upgraders
@@ -13,3 +13,4 @@ notices-for-facebook-graph-api-2
1.3.0-split-minifiers-package
1.3.5-remove-old-dev-bundle-link
1.4.0-remove-old-dev-bundle-link
+1.4.1-add-shell-server-package
diff --git a/LesionTracker/.meteor/packages b/LesionTracker/.meteor/packages
index 9dceea041..7a8c5460b 100644
--- a/LesionTracker/.meteor/packages
+++ b/LesionTracker/.meteor/packages
@@ -4,18 +4,18 @@
# 'meteor add' and 'meteor remove' will edit this file for you,
# but you can also edit it by hand.
-npm-bcrypt@0.8.7
+npm-bcrypt@0.9.1
meteor-base@1.0.4 # Packages every Meteor app needs to have
mobile-experience@1.0.4 # Packages for a great mobile UX
-mongo@1.1.10 # The database Meteor supports right now
+mongo@1.1.12 # The database Meteor supports right now
blaze-html-templates@1.0.4 # Compile .html files into Meteor Blaze views
session@1.1.6 # Client-side reactive dictionary for your app
-jquery@1.11.9 # Helpful client-side library
+jquery@1.11.9 # Helpful client-side library
tracker@1.1.0 # Meteor's client-side reactive programming library
-es5-shim@4.6.13 # ECMAScript 5 compatibility for older browsers.
-ecmascript@0.5.7 # Enable ECMAScript2015+ syntax in app code
+es5-shim@4.6.14 # ECMAScript 5 compatibility for older browsers.
+ecmascript@0.5.8 # Enable ECMAScript2015+ syntax in app code
clinical:router
clinical:extended-api
@@ -26,6 +26,8 @@ clinical:fonts
clinical:hipaa-audit-log
clinical:hipaa-logger
+aldeed:simple-schema # Third party package to deal with schemas
+
design
ohif:core
@@ -34,15 +36,15 @@ cornerstone
worklist
viewerbase
dicomweb
-accounts-base@1.2.9
-accounts-password@1.2.12
+accounts-base@1.2.11
+accounts-password@1.3.0
ian:accounts-ui-bootstrap-3
twbs:bootstrap
-http@1.2.8
+http@1.2.9
arsnebula:reactive-promise
-promise@0.8.3
-stylus@2.513.4
+promise@0.8.4
+stylus@2.513.5
fortawesome:fontawesome
random@1.0.10
reactive-var@1.0.10
@@ -56,11 +58,13 @@ check@1.2.3
aldeed:template-extension@4.0.0
zuuk:stale-session
gilbertwat:bootstrap3-daterangepicker
-email@1.1.16
+email@1.1.17
peppelg:bootstrap-3-modal
simple:reactive-method
hangingprotocols
fastclick@1.0.12
-standard-minifier-css@1.1.8
-standard-minifier-js@1.1.8
+standard-minifier-css@1.2.0
+standard-minifier-js@1.2.0
johdirr:meteor-git-rev
+u2622:persistent-session
+shell-server
diff --git a/LesionTracker/.meteor/release b/LesionTracker/.meteor/release
index c85944c1d..72980bc2f 100644
--- a/LesionTracker/.meteor/release
+++ b/LesionTracker/.meteor/release
@@ -1 +1 @@
-METEOR@1.4.0.1
+METEOR@1.4.1.1
diff --git a/LesionTracker/.meteor/versions b/LesionTracker/.meteor/versions
index 7d4b6c902..23dedb6c0 100644
--- a/LesionTracker/.meteor/versions
+++ b/LesionTracker/.meteor/versions
@@ -1,21 +1,22 @@
-accounts-base@1.2.9
-accounts-password@1.2.12
+accounts-base@1.2.11
+accounts-password@1.3.0
aldeed:simple-schema@1.5.3
aldeed:template-extension@4.0.0
allow-deny@1.0.5
+amplify@1.0.0
anti:gagarin@0.4.11
anti:i18n@0.4.3
arsnebula:reactive-promise@0.9.1
autoupdate@1.3.11
-babel-compiler@6.9.0
-babel-runtime@0.1.10
+babel-compiler@6.9.1
+babel-runtime@0.1.11
base64@1.0.9
binary-heap@1.0.9
blaze@2.1.8
blaze-html-templates@1.0.4
blaze-tools@1.0.9
boilerplate-generator@1.0.9
-caching-compiler@1.1.6
+caching-compiler@1.1.7
caching-html-compiler@1.0.6
callback-hook@1.0.9
check@1.2.3
@@ -31,23 +32,23 @@ clinical:router-location@2.1.0
clinical:router-middleware-stack@2.1.2
clinical:router-url@2.1.0
clinical:theming@0.4.10
-coffeescript@1.2.3
+coffeescript@1.2.4_1
cornerstone@0.0.1
ddp@1.2.5
-ddp-client@1.3.0
+ddp-client@1.3.1
ddp-common@1.2.6
ddp-rate-limiter@1.0.5
-ddp-server@1.3.9
+ddp-server@1.3.10
deps@1.0.12
design@0.0.1
dicomweb@0.0.1
diff-sequence@1.0.6
dimseservice@0.0.1
-ecmascript@0.5.7
-ecmascript-runtime@0.3.12
+ecmascript@0.5.8
+ecmascript-runtime@0.3.14
ejson@1.0.12
-email@1.1.16
-es5-shim@4.6.13
+email@1.1.17
+es5-shim@4.6.14
fastclick@1.0.12
fortawesome:fontawesome@4.5.0
geojson-utils@1.0.9
@@ -57,7 +58,7 @@ hangingprotocols@0.0.1
hot-code-push@1.0.4
html-tools@1.0.10
htmljs@1.0.10
-http@1.2.8
+http@1.2.9
ian:accounts-ui-bootstrap-3@1.2.89
id-map@1.0.8
insecure@1.0.7
@@ -71,25 +72,25 @@ launch-screen@1.0.12
lesiontracker@0.0.1
livedata@1.0.18
localstorage@1.0.11
-logging@1.1.14
+logging@1.1.15
mdg:validation-error@0.5.1
-meteor@1.2.16
+meteor@1.2.17
meteor-base@1.0.4
meteor-platform@1.2.6
-minifier-css@1.2.13
-minifier-js@1.2.13
+minifier-css@1.2.14
+minifier-js@1.2.14
minimongo@1.0.17
mobile-experience@1.0.4
mobile-status-bar@1.0.12
-modules@0.7.5
-modules-runtime@0.7.5
+modules@0.7.6
+modules-runtime@0.7.6
momentjs:moment@2.14.4
-mongo@1.1.10
+mongo@1.1.12
mongo-id@1.0.5
mrt:moment@2.8.1
-natestrauser:select2@4.0.2
-npm-bcrypt@0.8.7
-npm-mongo@1.5.45
+natestrauser:select2@4.0.3
+npm-bcrypt@0.9.1
+npm-mongo@1.5.49
observe-sequence@1.0.12
ohif:core@0.0.1
ordered-dict@1.0.8
@@ -97,7 +98,7 @@ orthanc-remote@0.0.1
peppelg:bootstrap-3-modal@1.0.4
practicalmeteor:chai@2.1.0_1
practicalmeteor:loglevel@1.2.0_2
-promise@0.8.3
+promise@0.8.4
random@1.0.10
rate-limit@1.0.5
reactive-dict@1.1.8
@@ -109,27 +110,30 @@ rwatts:uuid@0.1.0
service-configuration@1.0.10
session@1.1.6
sha@1.0.8
+shell-server@0.2.1
silentcicero:jszip@0.0.4
simple:reactive-method@1.0.2
spacebars@1.0.12
spacebars-compiler@1.0.12
srp@1.0.9
standard-app-packages@1.0.9
-standard-minifier-css@1.1.8
-standard-minifier-js@1.1.8
-stylus@2.513.4
-templating@1.2.13
+standard-minifier-css@1.2.0
+standard-minifier-js@1.2.0
+stylus@2.513.5
+templating@1.2.14
templating-tools@1.0.4
tracker@1.1.0
twbs:bootstrap@3.3.6
typ:accounts-ldap@1.0.1
typ:ldapjs@0.7.3
+u2622:persistent-session@0.4.4
ui@1.0.11
underscore@1.0.9
url@1.0.10
validatejs@0.0.1
viewerbase@0.0.1
-webapp@1.3.10
+wadoproxy@0.0.1
+webapp@1.3.11
webapp-hashing@1.0.9
worklist@0.0.1
zuuk:stale-session@1.0.8
diff --git a/LesionTracker/client/routes.js b/LesionTracker/client/routes.js
index 04516d6d3..3da643097 100644
--- a/LesionTracker/client/routes.js
+++ b/LesionTracker/client/routes.js
@@ -16,7 +16,8 @@ var data = {
'optionsModal',
'serverInformationModal',
'confirmRemoveTimepointAssociation',
- 'lastLoginModal'
+ 'lastLoginModal',
+ 'viewSeriesDetailsModal'
]
};
diff --git a/OHIFViewer/.meteor/.finished-upgraders b/OHIFViewer/.meteor/.finished-upgraders
index 3e712bc5a..a541808f2 100644
--- a/OHIFViewer/.meteor/.finished-upgraders
+++ b/OHIFViewer/.meteor/.finished-upgraders
@@ -13,3 +13,4 @@ notices-for-facebook-graph-api-2
1.3.0-split-minifiers-package
1.3.5-remove-old-dev-bundle-link
1.4.0-remove-old-dev-bundle-link
+1.4.1-add-shell-server-package
diff --git a/OHIFViewer/.meteor/packages b/OHIFViewer/.meteor/packages
index edd4b466c..69073452a 100644
--- a/OHIFViewer/.meteor/packages
+++ b/OHIFViewer/.meteor/packages
@@ -5,20 +5,20 @@
# but you can also edit it by hand.
twbs:bootstrap
-http@1.2.8
+http@1.2.9
arsnebula:reactive-promise
-promise@0.8.3
-stylus@2.513.4
+promise@0.8.4
+stylus@2.513.5
fortawesome:fontawesome
mrt:moment
meteor-base@1.0.4
mobile-experience@1.0.4
-mongo@1.1.10
+mongo@1.1.12
blaze-html-templates@1.0.4
session@1.1.6
jquery@1.11.9
tracker@1.1.0
-logging@1.1.14
+logging@1.1.15
reload@1.1.10
random@1.0.10
ejson@1.0.12
@@ -26,9 +26,10 @@ spacebars@1.0.12
check@1.2.3
cornerstone
dicomweb
+aldeed:simple-schema # Third party package to deal with schemas
design
ohif:core
-ecmascript@0.5.7
+ecmascript@0.5.8
viewerbase
worklist
reactive-var@1.0.10
@@ -37,7 +38,10 @@ hangingprotocols
reactive-dict@1.1.8
clinical:router
fastclick@1.0.12
-standard-minifier-css@1.1.8
-standard-minifier-js@1.1.8
-aldeed:simple-schema
+standard-minifier-css@1.2.0
+standard-minifier-js@1.2.0
johdirr:meteor-git-rev
+wadoproxy
+aldeed:template-extension
+peppelg:bootstrap-3-modal
+shell-server
diff --git a/OHIFViewer/.meteor/release b/OHIFViewer/.meteor/release
index c85944c1d..72980bc2f 100644
--- a/OHIFViewer/.meteor/release
+++ b/OHIFViewer/.meteor/release
@@ -1 +1 @@
-METEOR@1.4.0.1
+METEOR@1.4.1.1
diff --git a/OHIFViewer/.meteor/versions b/OHIFViewer/.meteor/versions
index 4bc7a8cbb..6d529819e 100644
--- a/OHIFViewer/.meteor/versions
+++ b/OHIFViewer/.meteor/versions
@@ -1,16 +1,17 @@
aldeed:simple-schema@1.5.3
+aldeed:template-extension@4.0.0
allow-deny@1.0.5
arsnebula:reactive-promise@0.9.1
autoupdate@1.3.11
-babel-compiler@6.9.0
-babel-runtime@0.1.10
+babel-compiler@6.9.1
+babel-runtime@0.1.11
base64@1.0.9
binary-heap@1.0.9
blaze@2.1.8
blaze-html-templates@1.0.4
blaze-tools@1.0.9
boilerplate-generator@1.0.9
-caching-compiler@1.1.6
+caching-compiler@1.1.7
caching-html-compiler@1.0.6
callback-hook@1.0.9
check@1.2.3
@@ -18,19 +19,19 @@ clinical:router@2.0.19
clinical:router-location@2.1.0
clinical:router-middleware-stack@2.1.2
clinical:router-url@2.1.0
-coffeescript@1.2.3
+coffeescript@1.2.4_1
cornerstone@0.0.1
ddp@1.2.5
-ddp-client@1.3.0
+ddp-client@1.3.1
ddp-common@1.2.6
-ddp-server@1.3.9
+ddp-server@1.3.10
deps@1.0.12
design@0.0.1
dicomweb@0.0.1
diff-sequence@1.0.6
dimseservice@0.0.1
-ecmascript@0.5.7
-ecmascript-runtime@0.3.12
+ecmascript@0.5.8
+ecmascript-runtime@0.3.14
ejson@1.0.12
fastclick@1.0.12
fortawesome:fontawesome@4.5.0
@@ -40,7 +41,7 @@ hangingprotocols@0.0.1
hot-code-push@1.0.4
html-tools@1.0.10
htmljs@1.0.10
-http@1.2.8
+http@1.2.9
id-map@1.0.8
iron:controller@1.0.12
iron:core@1.0.11
@@ -50,31 +51,32 @@ johdirr:meteor-git-rev@0.0.4
jquery@1.11.9
launch-screen@1.0.12
livedata@1.0.18
-logging@1.1.14
-mdg:validation-error@0.2.0
-meteor@1.2.16
+logging@1.1.15
+mdg:validation-error@0.5.1
+meteor@1.2.17
meteor-base@1.0.4
meteor-platform@1.2.6
-minifier-css@1.2.13
-minifier-js@1.2.13
+minifier-css@1.2.14
+minifier-js@1.2.14
minimongo@1.0.17
mobile-experience@1.0.4
mobile-status-bar@1.0.12
-modules@0.7.5
-modules-runtime@0.7.5
+modules@0.7.6
+modules-runtime@0.7.6
momentjs:moment@2.14.4
-mongo@1.1.10
+mongo@1.1.12
mongo-id@1.0.5
mrt:moment@2.8.1
-natestrauser:select2@4.0.2
-npm-mongo@1.5.45
+natestrauser:select2@4.0.3
+npm-mongo@1.5.49
observe-sequence@1.0.12
ohif:core@0.0.1
ordered-dict@1.0.8
orthanc-remote@0.0.1
+peppelg:bootstrap-3-modal@1.0.4
practicalmeteor:chai@2.1.0_1
practicalmeteor:loglevel@1.2.0_2
-promise@0.8.3
+promise@0.8.4
random@1.0.10
reactive-dict@1.1.8
reactive-var@1.0.10
@@ -83,14 +85,15 @@ retry@1.0.8
routepolicy@1.0.11
rwatts:uuid@0.1.0
session@1.1.6
+shell-server@0.2.1
silentcicero:jszip@0.0.4
spacebars@1.0.12
spacebars-compiler@1.0.12
standard-app-packages@1.0.9
-standard-minifier-css@1.1.8
-standard-minifier-js@1.1.8
-stylus@2.513.4
-templating@1.2.13
+standard-minifier-css@1.2.0
+standard-minifier-js@1.2.0
+stylus@2.513.5
+templating@1.2.14
templating-tools@1.0.4
tracker@1.1.0
twbs:bootstrap@3.3.6
@@ -99,6 +102,7 @@ underscore@1.0.9
url@1.0.10
validatejs@0.0.1
viewerbase@0.0.1
-webapp@1.3.10
+wadoproxy@0.0.1
+webapp@1.3.11
webapp-hashing@1.0.9
worklist@0.0.1
diff --git a/OHIFViewer/client/components/flexboxLayout/flexboxLayout.styl b/OHIFViewer/client/components/flexboxLayout/flexboxLayout.styl
index 39dbec75d..bc608d9b9 100644
--- a/OHIFViewer/client/components/flexboxLayout/flexboxLayout.styl
+++ b/OHIFViewer/client/components/flexboxLayout/flexboxLayout.styl
@@ -27,11 +27,11 @@ $lesionsSidebarMenuWidth = 450px
transform(translateX(0%))
.sidebar-left
- max-width: $studiesSidebarMenuWidth
- order: 1
+ theme('border-right', '%s solid $uiBorderColor' % $uiBorderThickness)
flex: 1
margin-left: - $studiesSidebarMenuWidth
- border-right: $uiBorderThickness $uiBorderColor solid
+ max-width: $studiesSidebarMenuWidth
+ order: 1
&.sidebar-open
margin-left: 0
@@ -62,7 +62,7 @@ $lesionsSidebarMenuWidth = 450px
max-width: $lesionsSidebarMenuWidth + 270px
&:before
- background-color: $uiBorderColor
+ theme('background-color', '$uiBorderColor')
content: ''
display: block
height: 100%
@@ -75,6 +75,6 @@ $lesionsSidebarMenuWidth = 450px
margin-right: 0
.studiesListedChanger
+ theme('border-bottom', '%s solid $uiBorderColor' % $uiBorderThickness)
padding: 20px 10px
text-align: center
- border-bottom: $uiBorderThickness $uiBorderColor solid
diff --git a/OHIFViewer/client/components/ohifViewer/ohifViewer.html b/OHIFViewer/client/components/ohifViewer/ohifViewer.html
index 1525ea0d7..e0bbad1db 100644
--- a/OHIFViewer/client/components/ohifViewer/ohifViewer.html
+++ b/OHIFViewer/client/components/ohifViewer/ohifViewer.html
@@ -25,4 +25,5 @@
{{> worklist }}
{{> aboutModal }}
+ {{> viewSeriesDetailsModal }}
\ No newline at end of file
diff --git a/OHIFViewer/client/components/ohifViewer/ohifViewer.styl b/OHIFViewer/client/components/ohifViewer/ohifViewer.styl
index df922b898..a8c2b9261 100644
--- a/OHIFViewer/client/components/ohifViewer/ohifViewer.styl
+++ b/OHIFViewer/client/components/ohifViewer/ohifViewer.styl
@@ -9,8 +9,8 @@ $expandedHeight = 160px
.topBar
height: $topBarHeight
- color: $textPrimaryColor
- background-color: $primaryBackgroundColor
+ theme('color', '$textPrimaryColor')
+ theme('background-color', '$primaryBackgroundColor')
transition(all 0.5s ease)
.brandSection
@@ -26,14 +26,14 @@ $expandedHeight = 160px
display: inline-block
font-family: $logoFontFamily
font-weight: $logoFontWeight
- color: $textPrimaryColor
+ theme('color', '$textPrimaryColor')
line-height: 30px
.studyListLinkSection
- border-left: $uiBorderThickness solid $uiBorderColor;
-
+ theme('border-left', '%s solid $uiBorderColor' % $uiBorderThickness)
+
.btn
- color: $textSecondaryColor
+ theme('color', '$textSecondaryColor')
cursor: pointer
font-size: 13px
font-weight: 500
@@ -41,10 +41,10 @@ $expandedHeight = 160px
margin-top: 3px
&:hover
- color: $hoverColor
+ theme('color', '$hoverColor')
&:active
- color: $activeColor
+ theme('color', '$activeColor')
&.studyList
background-color: rgba(21, 25, 30, 0.7)
@@ -75,5 +75,5 @@ $expandedHeight = 160px
.tab-pane
.viewerContainer
.loadingTextDiv
- color: $textSecondaryColor
- font-size: 30px
\ No newline at end of file
+ theme('color', '$textSecondaryColor')
+ font-size: 30px
diff --git a/OHIFViewer/client/components/toolbarSection/toolbarSection.styl b/OHIFViewer/client/components/toolbarSection/toolbarSection.styl
index 886b938e2..e6ac4b683 100644
--- a/OHIFViewer/client/components/toolbarSection/toolbarSection.styl
+++ b/OHIFViewer/client/components/toolbarSection/toolbarSection.styl
@@ -1,7 +1,7 @@
@import "{design}/app"
.toolbarSection
- border-bottom: $uiBorderColor $uiBorderThickness solid
+ theme('border-bottom', '%s solid $uiBorderColor' % $uiBorderThickness)
flex: 0 0 auto
height: $toolbarHeight
overflow: hidden
@@ -11,4 +11,4 @@
width: 100%
&.expanded
- height: $toolbarHeight + $toolbarDrawerHeight
\ No newline at end of file
+ height: $toolbarHeight + $toolbarDrawerHeight
diff --git a/OHIFViewer/client/components/viewer/viewer.styl b/OHIFViewer/client/components/viewer/viewer.styl
index e42b65915..6847a00d1 100644
--- a/OHIFViewer/client/components/viewer/viewer.styl
+++ b/OHIFViewer/client/components/viewer/viewer.styl
@@ -6,5 +6,5 @@
width: 100%
.loadingTextDiv
- color: $textSecondaryColor
+ theme('color', '$textSecondaryColor')
font-size: 30px
diff --git a/Packages/active-entry/package.js b/Packages/active-entry/package.js
index 1c549ad7c..8f78f11bc 100755
--- a/Packages/active-entry/package.js
+++ b/Packages/active-entry/package.js
@@ -26,7 +26,8 @@ Package.onUse(function (api) {
api.use([
'zuuk:stale-session@1.0.8',
- 'typ:accounts-ldap'
+ 'typ:accounts-ldap',
+ 'random'
], ['client', 'server']);
api.addFiles([
diff --git a/Packages/design/components/roundedButtonGroup/roundedButtonGroup.styl b/Packages/design/components/roundedButtonGroup/roundedButtonGroup.styl
index 6226a603f..d4d3a9225 100644
--- a/Packages/design/components/roundedButtonGroup/roundedButtonGroup.styl
+++ b/Packages/design/components/roundedButtonGroup/roundedButtonGroup.styl
@@ -1,7 +1,7 @@
@import "{design}/app"
$height = 25px
-$textColorActive = #2D2D2D
+$textColorButtonActive = #2D2D2D
.roundedButtonGroup
@@ -15,9 +15,9 @@ $textColorActive = #2D2D2D
.roundedButton
align-items: center
- background-color: $uiGrayDark
- border: 2px $uiBorderColorDark solid
- color: $textSecondaryColor
+ theme('background-color', '$uiGrayDark')
+ theme('border', '2px solid $uiBorderColorDark')
+ theme('color', '$textSecondaryColor')
display: flex
font-size: 11px
font-weight: 500
@@ -29,19 +29,19 @@ $textColorActive = #2D2D2D
transition: transition($sidebarTransition)
svg
- fill: $defaultColor
- stroke: $defaultColor
+ theme('fill', '$defaultColor')
+ theme('stroke', '$defaultColor')
svg
span
margin: 0 2px
-
+
i
line-height: 15px
font-size: 15px
.bottomLabel
- color: $textSecondaryColor
+ theme('color', '$textSecondaryColor')
font-size: 12px
font-weight: 500
line-height: 12px
@@ -58,16 +58,16 @@ $textColorActive = #2D2D2D
border-top-right-radius: $height
&:hover .roundedButton
- background-color: $boxBackgroundColor
- color: $uiGrayDark
+ theme('color', '$uiGrayDark')
+ theme('background-color', '$boxBackgroundColor')
&.active .roundedButton
- background-color: $activeColor
- border-color: $uiBorderColorActive
- color: $textColorActive
+ theme('background-color', '$activeColor')
+ theme('border-color', '$uiBorderColorActive')
+ color: $textColorButtonActive
&:hover .roundedButton
&.active .roundedButton
svg
- fill: $uiGrayDark
- stroke: $uiGrayDark
+ theme('fill', '$uiGrayDark')
+ theme('stroke', '$uiGrayDark')
diff --git a/Packages/design/package.js b/Packages/design/package.js
index 41de0594b..77f3ee544 100644
--- a/Packages/design/package.js
+++ b/Packages/design/package.js
@@ -18,7 +18,9 @@ Package.onUse(function(api) {
'styles/imports/mixins.styl',
'styles/imports/spacings.styl',
'styles/imports/variables.styl',
+ 'styles/imports/theming.styl',
'styles/imports/theme-tide.styl',
+ 'styles/imports/theme-tigerlilly.styl'
], 'client', {
isImport: true
});
@@ -35,7 +37,8 @@ Package.onUse(function(api) {
api.addFiles([
'styles/components/radio.styl',
'styles/components/select2.styl',
- 'styles/components/selectTree.styl'
+ 'styles/components/selectTree.styl',
+ 'styles/components/states.styl'
], 'client');
// Rounded Button Group
diff --git a/Packages/design/styles/common/global.styl b/Packages/design/styles/common/global.styl
index b703af0d1..e5b22e4e6 100644
--- a/Packages/design/styles/common/global.styl
+++ b/Packages/design/styles/common/global.styl
@@ -2,11 +2,26 @@
html body
font-family: 'Roboto', 'OpenSans', 'HelveticaNeue-Light', 'Helvetica Neue Light', 'Helvetica Neue', Helvetica, Arial, 'Lucida Grande', sans-serif
- // Try to fix LT-273, need a monitor to test on though.
- //text-rendering: optimizeLegibility
html hr
- border-top: 1px solid $uiBorderColor
+ theme('border-top', '1px solid $uiBorderColor')
+
+label.form-group
+ width: 100%
+
+ &>span.select2
+ display: block
+ width: 100% !important
+
+ span.select2-selection
+ min-height: 34px
+
+ span.select2-selection__rendered
+ height: 34px
+ line-height: 34px
+
+ span.select2-selection__arrow
+ height: 34px
.center-table
display: table
@@ -32,9 +47,9 @@ html hr
.modal-dialog
.modal-content
- background: $primaryBackgroundColor
- border-color: $uiBorderColor
- color: $textSecondaryColor
+ theme('background', '$primaryBackgroundColor')
+ theme('border-color', '$uiBorderColor')
+ theme('color', '$textSecondaryColor')
.modal-header, .modal-footer
- border-color: $uiBorderColor
+ theme('border-color', '$uiBorderColor')
diff --git a/Packages/design/styles/components/radio.styl b/Packages/design/styles/components/radio.styl
index 0756f7854..5f0c14970 100644
--- a/Packages/design/styles/components/radio.styl
+++ b/Packages/design/styles/components/radio.styl
@@ -3,12 +3,12 @@
.group-radio
label
cursor: pointer
-
+
input
height: 0
width: 0
visibility: hidden
-
+
span
padding-left: 23px
position: relative
@@ -23,14 +23,14 @@
top: 50%
transform(translateY(-50%))
width: 16px
-
+
input:focus + span:before
// TODO: [design] define a outline for the design
+ theme('box-shadow', '0 0 2px 2px $textSecondaryColor')
outline: none
- box-shadow: 0 0 2px 2px $textSecondaryColor
-
+
input:checked + span:after
- background: $uiBorderColorDark
+ theme('background', '$uiBorderColorDark')
border-radius: 5px
content: ''
height: 10px
diff --git a/Packages/design/styles/components/select2.styl b/Packages/design/styles/components/select2.styl
index a1ef36961..6dc188eb1 100644
--- a/Packages/design/styles/components/select2.styl
+++ b/Packages/design/styles/components/select2.styl
@@ -22,8 +22,8 @@ span.select2.select2-container
padding-left: 11px
span.select2-selection__arrow
+ theme('border-left', '1px solid $primaryBackgroundColor')
background-color: $gray1
- border-left: 1px solid $primaryBackgroundColor
border-top-right-radius: $borderRadius
border-bottom-right-radius: $borderRadius
right: 0
@@ -42,8 +42,8 @@ span.select2.select2-container
placeholder-color($gray4)
li.select2-selection__choice
+ theme('border-color', '$uiGray')
background-color: #FFF
- border-color: $uiGray
border-radius: $borderRadius
color: $gray4
font-size: 12px
diff --git a/Packages/design/styles/components/selectTree.styl b/Packages/design/styles/components/selectTree.styl
index 0dfe25a85..bd4011610 100644
--- a/Packages/design/styles/components/selectTree.styl
+++ b/Packages/design/styles/components/selectTree.styl
@@ -76,6 +76,7 @@ $gray6 = #303030
display: block
margin: 0
padding: 5px
+ position: relative
text-align: center
span
@@ -85,6 +86,14 @@ $gray6 = #303030
input
border-color: $gray5
font-weight: normal
+ padding-left: 34px
+
+ & ~ i
+ color: $gray1
+ font-size: 18px
+ left: 16px
+ position: absolute
+ top: 37px
.tree-breadcrumb
line-height: 32px
@@ -146,7 +155,6 @@ $gray6 = #303030
&.active
box-shadow: 0 0 0 200px white, inset 0 0 0 200px white
- position: fixed
transition(box-shadow 0.3s ease)
z-index: 0
@@ -172,7 +180,7 @@ $gray6 = #303030
border-radius: 5px
color: white
opacity: 0.9
- padding: 5px 12px 12px
+ padding: 0 15px 12px
position: absolute
top: 50%
transform(translateY(-50%))
@@ -180,13 +188,21 @@ $gray6 = #303030
h5.title
color: $gray5
- font-size: 12px
font-weight: normal
line-height: 20px
- margin: 0
+ margin: 12px 0 16px
label
+ cursor: pointer
display: block
+ font-weight: 300
+ line-height: 26px
+ margin: 0
+ padding-left: 3px
+ transition(padding 0.3s ease)
+
+ &:hover
+ padding-left: 0
.select-tree-root
@@ -218,7 +234,7 @@ $gray6 = #303030
.content
margin-left: 0
- &.interacted
+ &.interacted, &.selected
.select-tree-common
z-index: 1
diff --git a/Packages/design/styles/components/states.styl b/Packages/design/styles/components/states.styl
new file mode 100644
index 000000000..1915cdea8
--- /dev/null
+++ b/Packages/design/styles/components/states.styl
@@ -0,0 +1,29 @@
+@import "{design}/app"
+
+.state-error
+ &+.tooltip
+
+ .tooltip-inner
+ color: white
+ theme('background-color', '$uiStateErrorBorder')
+
+ &.top .tooltip-arrow
+ theme('border-top-color', '$uiStateErrorBorder')
+ &.right .tooltip-arrow
+ theme('border-right-color', '$uiStateErrorBorder')
+ &.bottom .tooltip-arrow
+ theme('border-bottom-color', '$uiStateErrorBorder')
+ &.left .tooltip-arrow
+ theme('border-left-color', '$uiStateErrorBorder')
+
+
+ &:not(.component-group)
+ &.form-control, .form-control
+ theme('background-color', '$uiStateError')
+ theme('border-color', '$uiStateErrorBorder')
+ theme('color', '$uiStateErrorText')
+
+ .select2-selection
+ theme('background-color', '$uiStateError')
+ theme('border-color', '$uiStateErrorBorder')
+ theme('color', '$uiStateErrorText')
diff --git a/Packages/design/styles/imports/theme-tide.styl b/Packages/design/styles/imports/theme-tide.styl
index 7aa395feb..6f7d9d203 100644
--- a/Packages/design/styles/imports/theme-tide.styl
+++ b/Packages/design/styles/imports/theme-tide.styl
@@ -1,54 +1,34 @@
-// Common pallete
-$uiYellow = #E29E4A
-$uiSkyBlue = #6FBDE2
+$themes['tide'] = {
+ // Common pallete
+ $uiYellow: #E29E4A
+ $uiSkyBlue: #6FBDE2
-$uiLightGray = #516873
-$uiGray = #263340
-$uiGrayDark = #16202B
-$uiGrayDarker = #151A1F
-$uiGrayDarkest = #14191E
+ // State pallete
+ $uiStateError: #FFCCCC
+ $uiStateErrorBorder: #993333
+ $uiStateErrorText: #661111
-// Interface UI Colors
-$defaultColor = #9cd0fe
-$hoverColor = #ffffff
-$activeColor = #00a4d9
-$uiBorderColor = #436270
-$uiBorderColorDark = #3C5D80
-$uiBorderColorActive = #00a4d9
-$primaryBackgroundColor = #000000
-$boxBackgroundColor = #344a61
-$boxBackgroundColorDark = #22374D
+ $uiLightGray: #516873
+ $uiGray: #263340
+ $uiGrayDark: #16202B
+ $uiGrayDarker: #151A1F
+ $uiGrayDarkest: #14191E
-// Text Colors
-$textColorActive = black //#89bae5
-$textPrimaryColor = #ffffff
-$textSecondaryColor = #6a8fb1
+ // Interface UI Colors
+ $defaultColor: #9cd0fe
+ $hoverColor: #ffffff
+ $activeColor: #00a4d9
+ $uiBorderColor: #436270
+ $uiBorderColorDark: #3C5D80
+ $uiBorderColorActive: #00a4d9
+ $primaryBackgroundColor: #000000
+ $boxBackgroundColor: #344a61
-// Other Colors
-$menuBackgroundColor = #F2F2F2
-$imageSliderColor = #163239
+ // Text Colors
+ $textColorActive: black //#89bae5
+ $textPrimaryColor: #ffffff
+ $textSecondaryColor: #6a8fb1
-// Viewport Settings
-$viewportBorderThickness = 1px
-$viewportBorderColor = $uiBorderColorDark
-$viewportBorderColorHover = $uiBorderColor
-$viewportBorderColorActive = $uiBorderColorActive
-
-// Sizes
-$topBarHeight = 40px
-$toolbarHeight = 78px
-$toolbarDrawerHeight = 62px
-
-// Thicknesses
-$uiBorderThickness = 1px
-
-// Fonts
-$logoFontFamily = "Sanchez"
-$logoFontWeight = 300
-
-// Transitions
-$transitionDuration = 0.3s
-$transitionEffect = ease
-$sidebarTransition = all $transitionDuration $transitionEffect
-$studiesSidebarMenuWidth = 307px
-$lesionsSidebarMenuWidth = 323px
+ // Other Colors
+ $imageSliderColor: #163239
+}
diff --git a/Packages/design/styles/imports/theme-tigerlilly.styl b/Packages/design/styles/imports/theme-tigerlilly.styl
index e305a9878..21292a45c 100644
--- a/Packages/design/styles/imports/theme-tigerlilly.styl
+++ b/Packages/design/styles/imports/theme-tigerlilly.styl
@@ -1,54 +1,34 @@
-// Common pallete
-$uiYellow = #E29E4A
-$uiSkyBlue = #6FBDE2
+$themes['tigerlilly'] = {
+ // Common pallete
+ $uiYellow: #E29E4A
+ $uiSkyBlue: #6FBDE2
-$uiLightGray = #516873
-$uiGray = #263340
-$uiGrayDark = #16202B
-$uiGrayDarker = #151A1F
-$uiGrayDarkest = #14191E
+ // State pallete
+ $uiStateError: #FFCCCC
+ $uiStateErrorBorder: #CC6666
+ $uiStateErrorText: #661111
-// Interface UI Colors
-$defaultColor = #98ceff
-$hoverColor = #ffffff
-$activeColor = #ff8a3d
-$uiBorderColor = #744b71
-$uiBorderColorDark = #744b71
-$uiBorderColorActive = #ff8a3d
-$primaryBackgroundColor = #000000
-$boxBackgroundColor = #5b3a59
-$boxBackgroundColorDark = #4b2f40
+ $uiLightGray: #516873
+ $uiGray: #263340
+ $uiGrayDark: #16202B
+ $uiGrayDarker: #151A1F
+ $uiGrayDarkest: #14191E
-// Text Colors
-$textColorActive = #ff8a3d
-$textPrimaryColor = #ffffff
-$textSecondaryColor = #6a8fb1
+ // Interface UI Colors
+ $defaultColor: #98ceff
+ $hoverColor: #ffffff
+ $activeColor: #ff8a3d
+ $uiBorderColor: #744b71
+ $uiBorderColorDark: #744b71
+ $uiBorderColorActive: #ff8a3d
+ $primaryBackgroundColor: #000000
+ $boxBackgroundColor: #5b3a59
-// Other Colors
-$menuBackgroundColor = #F2F2F2
-$imageSliderColor = #4b2c3c //#163239
+ // Text Colors
+ $textColorActive: black
+ $textPrimaryColor: #ffffff
+ $textSecondaryColor: #6a8fb1
-// Viewport Settings
-$viewportBorderThickness = 1px
-$viewportBorderColor = $uiBorderColorDark
-$viewportBorderColorHover = $uiBorderColor
-$viewportBorderColorActive = $uiBorderColorActive
-
-// Sizes
-$topBarHeight = 40px
-$toolbarHeight = 78px
-$toolbarDrawerHeight = 62px
-
-// Thicknesses
-$uiBorderThickness = 1px
-
-// Fonts
-$logoFontFamily = "Sanchez"
-$logoFontWeight = 300
-
-// Transitions
-$transitionDuration = 0.3s
-$transitionEffect = ease
-$sidebarTransition = all $transitionDuration $transitionEffect
-$studiesSidebarMenuWidth = 307px
-$lesionsSidebarMenuWidth = 323px
\ No newline at end of file
+ // Other Colors
+ $imageSliderColor: #4b2c3c //#163239
+}
diff --git a/Packages/design/styles/imports/theming.styl b/Packages/design/styles/imports/theming.styl
new file mode 100644
index 000000000..68b752750
--- /dev/null
+++ b/Packages/design/styles/imports/theming.styl
@@ -0,0 +1,32 @@
+$themes = {}
+$defaultTheme = 'tide'
+
+@import "./theme-tide.styl"
+@import "./theme-tigerlilly.styl"
+
+parseSpaceVars($theme, $value)
+ $valueSplit = split(' ', $value)
+ $list = ''
+ pop($list)
+ for $property in $valueSplit
+ if ($theme[$property])
+ push($list, $theme[$property])
+ else
+ push($list, $property)
+ join(' ', $list)
+
+parseCommaVars($theme, $value)
+ $valueSplit = split(',', $value)
+ $list = ''
+ pop($list)
+ for $sentence in $valueSplit
+ push($list, parseSpaceVars($theme, $sentence))
+ unquote(join(',', $list))
+
+theme($property, $value)
+ / {selector()}
+ {$property}: parseCommaVars($themes[$defaultTheme], $value)
+ for $themeName, $theme in $themes
+ for $selectorPiece in split(',', selector())
+ / body.theme-{$themeName} {$selectorPiece}
+ {$property}: parseCommaVars($theme, $value)
diff --git a/Packages/design/styles/imports/variables.styl b/Packages/design/styles/imports/variables.styl
index 621d56a85..9a5d3896b 100644
--- a/Packages/design/styles/imports/variables.styl
+++ b/Packages/design/styles/imports/variables.styl
@@ -1,2 +1,22 @@
-//@import "./theme-tigerlilly.styl"
-@import "./theme-tide.styl"
\ No newline at end of file
+@import "./theming.styl"
+
+// Sizes
+$topBarHeight = 40px
+$toolbarHeight = 78px
+$toolbarDrawerHeight = 62px
+$studiesSidebarMenuWidth = 307px
+$lesionsSidebarMenuWidth = 323px
+
+// Fonts
+$logoFontFamily = "Sanchez"
+$logoFontWeight = 300
+
+// Transitions
+$transitionDuration = 0.3s
+$transitionEffect = ease
+$sidebarTransition = all $transitionDuration $transitionEffect
+
+
+// Thicknesses
+$viewportBorderThickness = 1px
+$uiBorderThickness = 1px
diff --git a/Packages/hangingprotocols/client/components/protocolEditor/protocolEditor.styl b/Packages/hangingprotocols/client/components/protocolEditor/protocolEditor.styl
index 6a1061a22..9c5bdb8dc 100644
--- a/Packages/hangingprotocols/client/components/protocolEditor/protocolEditor.styl
+++ b/Packages/hangingprotocols/client/components/protocolEditor/protocolEditor.styl
@@ -3,12 +3,12 @@
$height = 20px
#protocolEditor
+ theme('background', '$primaryBackgroundColor')
height: 100%
width: 450px
padding: 10px 0
position: absolute
top: 0
- background: $primaryBackgroundColor
.navigationButtons
ul
@@ -35,27 +35,27 @@ $height = 20px
cursor: pointer
text-decoration: none
outline: none
- background-color: $uiGrayDark
- border: 2px $uiBorderColorDark solid
- color: $textSecondaryColor
+ theme('background-color', '$uiGrayDark')
+ theme('border', '2px solid $uiBorderColorDark')
+ theme('color', '$textSecondaryColor')
transition: transition($sidebarTransition)
border-radius: $height
&.active a
- background-color: $activeColor
- border-color: $uiBorderColorActive
- color: $textColorActive
+ theme('background-color', '$activeColor')
+ theme('border-color', '$uiBorderColorActive')
+ theme('color', '$textColorActive')
transition: transition($sidebarTransition)
p
h2
h3
h4
- color: $defaultColor
+ theme('color', '$defaultColor')
label
ul
- color: $defaultColor
+ theme('color', '$defaultColor')
font-weight: 400
label
@@ -68,7 +68,7 @@ $height = 20px
width: 40%
border: none
background: #212121
- color: $defaultColor
+ theme('color', '$defaultColor')
text-align: center
button.btn
@@ -85,11 +85,11 @@ $height = 20px
bottom: 0
width: 100%
margin-bottom: 0
- background: $uiGrayDarker
+ theme('background', '$uiGrayDarker')
p
font-size: 8pt
- color: $defaultColor
+ theme('color', '$defaultColor')
margin: 0 10px
display: inline-block
@@ -107,11 +107,11 @@ $height = 20px
#selectProtocol
text-align: center
- .btn-file
+ .btn-file
position: relative
overflow: hidden
-
- .btn-file input[type=file]
+
+ .btn-file input[type=file]
position: absolute
top: 0
right: 0
@@ -141,4 +141,4 @@ $height = 20px
padding: 40px
h3
- color: $defaultColor
\ No newline at end of file
+ theme('color', '$defaultColor')
diff --git a/Packages/hangingprotocols/client/components/ruleEntryDialog/ruleEntryDialog.styl b/Packages/hangingprotocols/client/components/ruleEntryDialog/ruleEntryDialog.styl
index 51b5164a5..7d7681269 100644
--- a/Packages/hangingprotocols/client/components/ruleEntryDialog/ruleEntryDialog.styl
+++ b/Packages/hangingprotocols/client/components/ruleEntryDialog/ruleEntryDialog.styl
@@ -1,6 +1,9 @@
@import "{design}/app.styl"
.ruleEntryDialog
+ theme('background', '$uiGrayDarkest')
+ theme('border', '1px solid $uiBorderColor')
+ theme('color', '$textSecondaryColor')
display: none
position: absolute
top: 0
@@ -14,12 +17,8 @@
padding: 10px
background-color: rgba(255,255,255,1)
outline: none
-
opacity: 0.95
border-radius: 8px
- border: 1px solid $uiBorderColor
- background: $uiGrayDarkest
- color: $textSecondaryColor
.dialogContent
text-align: center
@@ -44,4 +43,4 @@
color: black
height: 30px
border-radius: 2px
- border: 0
\ No newline at end of file
+ border: 0
diff --git a/Packages/hangingprotocols/client/components/ruleTable/ruleTable.styl b/Packages/hangingprotocols/client/components/ruleTable/ruleTable.styl
index 5b92f45cc..0a6f57387 100644
--- a/Packages/hangingprotocols/client/components/ruleTable/ruleTable.styl
+++ b/Packages/hangingprotocols/client/components/ruleTable/ruleTable.styl
@@ -4,7 +4,7 @@ table.ruleTable
thead
tr
th
- color: $defaultColor
+ theme('color', '$defaultColor')
text-align: center
th:first-child
@@ -13,7 +13,7 @@ table.ruleTable
tbody
tr
td
- color: $defaultColor
+ theme('color', '$defaultColor')
text-align: center
.failWarning
@@ -26,10 +26,10 @@ table.ruleTable
transition(all 0.1s ease)
&:hover
- color: $hoverColor
+ theme('color', '$hoverColor')
&:active
- color: $activeColor
+ theme('color', '$activeColor')
td:first-child
text-align: left
@@ -37,14 +37,14 @@ table.ruleTable
.addRuleContainer
margin: 10px 0
text-align: center
- color: $defaultColor
+ theme('color', '$defaultColor')
.addRule
cursor: pointer
transition(all 0.1s ease)
&:hover
- color: $hoverColor
+ theme('color', '$hoverColor')
&:active
- color: $activeColor
\ No newline at end of file
+ theme('color', '$activeColor')
\ No newline at end of file
diff --git a/Packages/hangingprotocols/client/components/settingEntryDialog/settingEntryDialog.styl b/Packages/hangingprotocols/client/components/settingEntryDialog/settingEntryDialog.styl
index 31d543b13..be233ff38 100644
--- a/Packages/hangingprotocols/client/components/settingEntryDialog/settingEntryDialog.styl
+++ b/Packages/hangingprotocols/client/components/settingEntryDialog/settingEntryDialog.styl
@@ -1,6 +1,9 @@
@import "{design}/app.styl"
.settingEntryDialog
+ theme('border', '1px solid $uiBorderColor')
+ theme('background', '$uiGrayDarkest')
+ theme('color', '$textSecondaryColor')
display: none
position: absolute
top: 0
@@ -13,12 +16,8 @@
margin: auto
padding: 10px
outline: none
-
opacity: 0.95
border-radius: 8px
- border: 1px solid $uiBorderColor
- background: $uiGrayDarkest
- color: $textSecondaryColor
.dialogContent
text-align: center
@@ -43,4 +42,4 @@
color: black
height: 30px
border-radius: 2px
- border: 0
\ No newline at end of file
+ border: 0
diff --git a/Packages/hangingprotocols/client/components/settingsTable/settingsTable.styl b/Packages/hangingprotocols/client/components/settingsTable/settingsTable.styl
index c57ee1895..801b6f7d6 100644
--- a/Packages/hangingprotocols/client/components/settingsTable/settingsTable.styl
+++ b/Packages/hangingprotocols/client/components/settingsTable/settingsTable.styl
@@ -4,7 +4,7 @@ table.settingsTable
thead
tr
th
- color: $defaultColor
+ theme('color', '$defaultColor')
text-align: center
th:first-child
@@ -15,7 +15,7 @@ table.settingsTable
tr
td
- color: $defaultColor
+ theme('color', '$defaultColor')
text-align: center
.editSetting
@@ -24,10 +24,10 @@ table.settingsTable
transition(all 0.1s ease)
&:hover
- color: $hoverColor
+ theme('color', '$hoverColor')
&:active
- color: $activeColor
+ theme('color', '$activeColor')
td:first-child
text-align: left
@@ -35,14 +35,14 @@ table.settingsTable
.addSettingContainer
margin: 10px 0
text-align: center
- color: $defaultColor
+ theme('color', '$defaultColor')
.addSetting
cursor: pointer
transition(all 0.1s ease)
&:hover
- color: $hoverColor
+ theme('color', '$hoverColor')
&:active
- color: $activeColor
\ No newline at end of file
+ theme('color', '$activeColor')
\ No newline at end of file
diff --git a/Packages/hangingprotocols/client/components/stageDetails/stageDetails.styl b/Packages/hangingprotocols/client/components/stageDetails/stageDetails.styl
index e9c6d0190..ea8dc373e 100644
--- a/Packages/hangingprotocols/client/components/stageDetails/stageDetails.styl
+++ b/Packages/hangingprotocols/client/components/stageDetails/stageDetails.styl
@@ -14,19 +14,19 @@
h3
label
- color: $defaultColor
+ theme('color', '$defaultColor')
label
margin-right: 10px
width: 25%
input
+ theme('background-color', '$boxBackgroundColor')Dark
min-width: 50px
width: 40%
border: none
- background: $boxBackgroundColorDark
- color: $defaultColor
+ theme('color', '$defaultColor')
text-align: center
.stageEditorSection
- margin: 30px 0
\ No newline at end of file
+ margin: 30px 0
diff --git a/Packages/hangingprotocols/client/components/stageSortable/stageSortable.styl b/Packages/hangingprotocols/client/components/stageSortable/stageSortable.styl
index c283529ef..e5d24a7a1 100644
--- a/Packages/hangingprotocols/client/components/stageSortable/stageSortable.styl
+++ b/Packages/hangingprotocols/client/components/stageSortable/stageSortable.styl
@@ -8,14 +8,14 @@
padding: 3px
span
- color: $defaultColor
+ theme('color', '$defaultColor')
cursor: pointer
&:hover
- color: $hoverColor
+ theme('color', '$hoverColor')
&.active
- color: $activeColor
+ theme('color', '$activeColor')
.sortable-handle
cursor: move
@@ -36,44 +36,44 @@
.deleteStage
cursor: pointer
- color: $defaultColor
+ theme('color', '$defaultColor')
transition(all 0.1s ease)
&:hover
- color: $hoverColor
+ theme('color', '$hoverColor')
&:active
- color: $activeColor
+ theme('color', '$activeColor')
.addStage
margin: 10px 0
text-align: center
- color: $defaultColor
+ theme('color', '$defaultColor')
#addStage
transition(all 0.1s ease)
&:hover
- color: $hoverColor
+ theme('color', '$hoverColor')
&:active
- color: $activeColor
+ theme('color', '$activeColor')
.moveStageButtons
margin: 10px 0
text-align: center
a
- color: $defaultColor
+ theme('color', '$defaultColor')
cursor: pointer
text-decoration: none
transition(all 0.1s ease)
&:hover
- color: $hoverColor
+ theme('color', '$hoverColor')
&:active
- color: $activeColor
+ theme('color', '$activeColor')
&[disabled="true"]
opacity: 0.7
diff --git a/Packages/hangingprotocols/client/components/textEntryDialog/textEntryDialog.styl b/Packages/hangingprotocols/client/components/textEntryDialog/textEntryDialog.styl
index 8ae55fe18..f64cdb223 100644
--- a/Packages/hangingprotocols/client/components/textEntryDialog/textEntryDialog.styl
+++ b/Packages/hangingprotocols/client/components/textEntryDialog/textEntryDialog.styl
@@ -1,6 +1,9 @@
@import "{design}/app.styl"
.textEntryDialog
+ theme('border', '1px solid $uiBorderColor')
+ theme('background', '$uiGrayDarkest')
+ theme('color', '$textSecondaryColor')
display: none
position: absolute
top: 0
@@ -13,12 +16,8 @@
margin: auto
padding: 10px
outline: none
-
opacity: 0.95
border-radius: 8px
- border: 1px solid $uiBorderColor
- background: $uiGrayDarkest
- color: $textSecondaryColor
.dialogContent
margin-bottom: 10px
@@ -36,4 +35,4 @@
color: black
height: 30px
border-radius: 2px
- border: 0
\ No newline at end of file
+ border: 0
diff --git a/Packages/lesiontracker/both/collections.js b/Packages/lesiontracker/both/collections.js
index 4e734d327..c4f742aa4 100644
--- a/Packages/lesiontracker/both/collections.js
+++ b/Packages/lesiontracker/both/collections.js
@@ -1,5 +1,8 @@
import { Mongo } from 'meteor/mongo';
+// Servers describe the DICOM servers configurations
+Servers = new Mongo.Collection('servers');
+
Timepoints = new Mongo.Collection('timepoints');
Studies = new Mongo.Collection('studies');
Measurements = new Mongo.Collection('measurements');
@@ -12,6 +15,5 @@ ImageMeasurements = new Mongo.Collection('imageMeasurements');
// panel, and represents items such as data quality,
AdditionalFindings = new Mongo.Collection('additionalFindings');
-Servers = new Mongo.Collection('servers');
WorklistSubscriptions = ['studies', 'timepoints'];
Reviewers = new Mongo.Collection('reviewers');
diff --git a/Packages/lesiontracker/client/api/timepoint.js b/Packages/lesiontracker/client/api/timepoint.js
index 5499da0ee..ac4bd84b5 100644
--- a/Packages/lesiontracker/client/api/timepoint.js
+++ b/Packages/lesiontracker/client/api/timepoint.js
@@ -26,8 +26,14 @@ class TimepointApi {
});
}
+ // Return the prior timepoint
prior() {
- const latestDate = this.current().latestDate;
+ const current = this.current();
+ if (!current) {
+ return;
+ }
+
+ const latestDate = current.latestDate;
return this.timepoints.findOne({
latestDate: {
$lt: latestDate
@@ -41,9 +47,15 @@ class TimepointApi {
// Return only the current and prior Timepoints
currentAndPrior() {
- let timepoints = [this.current()];
+ const timepoints = [];
+
+ const current = this.current();
+ if (current) {
+ timepoints.push(current);
+ }
+
const prior = this.prior();
- if (prior) {
+ if (current && prior && prior._id !== current._id) {
timepoints.push(prior);
}
diff --git a/Packages/lesiontracker/client/components/activeEntry/activeEntrySignIn/activeEntrySignIn.js b/Packages/lesiontracker/client/components/activeEntry/activeEntrySignIn/activeEntrySignIn.js
new file mode 100644
index 000000000..0894f4ff8
--- /dev/null
+++ b/Packages/lesiontracker/client/components/activeEntry/activeEntrySignIn/activeEntrySignIn.js
@@ -0,0 +1,25 @@
+import { Template } from 'meteor/templating';
+import { ActiveEntry } from 'meteor/clinical:active-entry';
+
+
+Template.entrySignIn.hooks({
+
+ rendered: function () {
+ // Create Test Drive button dynamically
+ let btnTestDrive = $('', {
+ id: 'btnTestDrive',
+ text: 'Test Drive',
+ class: 'btn btn-primary',
+ style: 'position: absolute; width: 150px; top: 20px; right: 20px; padding-left: 0;',
+ title: 'Login with Demo User',
+ click: function () {
+ // Login with demo user
+ ActiveEntry.signIn('demo@ohif.org', '12345678aA*');
+ }
+ });
+
+ const entrySignIn = this.find('#entrySignIn');
+ $(entrySignIn).append(btnTestDrive);
+ }
+
+});
\ No newline at end of file
diff --git a/Packages/lesiontracker/client/components/additionalFindings/additionalFindings.html b/Packages/lesiontracker/client/components/additionalFindings/additionalFindings.html
index 6c50cc4de..dcd49b839 100644
--- a/Packages/lesiontracker/client/components/additionalFindings/additionalFindings.html
+++ b/Packages/lesiontracker/client/components/additionalFindings/additionalFindings.html
@@ -15,7 +15,7 @@
key='regionsOfMetastaticDisease'
multiple=true
options=(clone
- placeholder='Choose a region...'
+ placeholder='Choose a region'
allowClear=true
)
}}
diff --git a/Packages/lesiontracker/client/components/additionalFindings/additionalFindings.styl b/Packages/lesiontracker/client/components/additionalFindings/additionalFindings.styl
index 0b8428f90..d1bb55b7b 100644
--- a/Packages/lesiontracker/client/components/additionalFindings/additionalFindings.styl
+++ b/Packages/lesiontracker/client/components/additionalFindings/additionalFindings.styl
@@ -22,22 +22,22 @@
display: none
.header
+ theme('background-color', '$uiGray')
+ theme('color', '$textPrimaryColor')
height: 33px
line-height: 33px
font-weight: bold
font-size: 14px
padding: 1px 13px 0
- color: $textPrimaryColor
- background-color: $uiGray
.form-group
- color: $textPrimaryColor
+ theme('color', '$textPrimaryColor')
margin-bottom: 0
padding: 7px 27px 7px 11px
width: 100%
&:not(:last-child)
- border-bottom: $uiBorderThickness solid $uiBorderColorDark
+ theme('border-bottom', '%s solid $uiBorderColorDark' % $uiBorderThickness)
& > .wrapperText
display: block
@@ -81,21 +81,21 @@
.buttonSection
cursor: pointer
height: 90px
- color: $defaultColor
+ theme('color', '$defaultColor')
&:hover
- color: $hoverColor
+ theme('color', '$hoverColor')
.svgContainer
svg
- fill: $hoverColor
+ theme('fill', '$hoverColor')
&:active
- color: $activeColor
+ theme('color', '$activeColor')
.svgContainer
svg
- fill: $activeColor
+ theme('fill', '$activeColor')
div
float: left
@@ -112,4 +112,4 @@
svg
width: 36px
height: 36px
- fill: $textPrimaryColor
+ theme('fill', '$textPrimaryColor')
diff --git a/Packages/lesiontracker/client/components/caseProgress/caseProgress.js b/Packages/lesiontracker/client/components/caseProgress/caseProgress.js
index 0f7303aa8..9ca6c6aef 100644
--- a/Packages/lesiontracker/client/components/caseProgress/caseProgress.js
+++ b/Packages/lesiontracker/client/components/caseProgress/caseProgress.js
@@ -7,7 +7,14 @@ Template.caseProgress.onCreated(() => {
instance.progressText = new ReactiveVar();
instance.isLocked = new ReactiveVar();
+ // Get the current timepoint
const current = instance.data.timepointApi.current();
+
+ // Stop here if no timepoint was found
+ if (!current) {
+ return;
+ }
+
if (!current.timepointId) {
console.warn('Case has no timepointId');
return;
diff --git a/Packages/lesiontracker/client/components/caseProgress/caseProgress.styl b/Packages/lesiontracker/client/components/caseProgress/caseProgress.styl
index 528e032df..3fe96cb04 100644
--- a/Packages/lesiontracker/client/components/caseProgress/caseProgress.styl
+++ b/Packages/lesiontracker/client/components/caseProgress/caseProgress.styl
@@ -13,15 +13,15 @@
margin-left: 22px
h5
- color: $textPrimaryColor
+ theme('color', '$textPrimaryColor')
line-height: 46px
margin: 0
font-size: 15px
font-weight: bold
button.btn
- background-color: $activeColor
- border: 1px solid $uiBorderColorActive
+ theme('background-color', '$activeColor')
+ theme('border', '1px solid $uiBorderColorActive')
color: #000
cursor: pointer
font-size: 15px
diff --git a/Packages/lesiontracker/client/components/flexboxLayout/flexboxLayout.styl b/Packages/lesiontracker/client/components/flexboxLayout/flexboxLayout.styl
index 69807f422..70b178a6a 100644
--- a/Packages/lesiontracker/client/components/flexboxLayout/flexboxLayout.styl
+++ b/Packages/lesiontracker/client/components/flexboxLayout/flexboxLayout.styl
@@ -25,11 +25,11 @@
transform(translateX(0%))
.sidebar-left
+ theme('border-right', '%s solid $uiBorderColor' % $uiBorderThickness)
max-width: $studiesSidebarMenuWidth
order: 1
flex: 1
margin-left: - $studiesSidebarMenuWidth
- border-right: $uiBorderThickness $uiBorderColor solid
&.sidebar-open
margin-left: 0
@@ -60,7 +60,7 @@
max-width: $lesionsSidebarMenuWidth + 270px
&:before
- background-color: $uiBorderColor
+ theme('background-color', '$uiBorderColor')
content: ''
display: block
height: 100%
@@ -73,6 +73,6 @@
margin-right: 0
.studiesListedChanger
+ theme('border-bottom', '%s solid $uiBorderColor' % $uiBorderThickness)
padding: 20px 10px
text-align: center
- border-bottom: $uiBorderThickness $uiBorderColor solid
diff --git a/Packages/lesiontracker/client/components/lastLoginModal/lastLoginModal.js b/Packages/lesiontracker/client/components/lastLoginModal/lastLoginModal.js
deleted file mode 100644
index 388677bf0..000000000
--- a/Packages/lesiontracker/client/components/lastLoginModal/lastLoginModal.js
+++ /dev/null
@@ -1,9 +0,0 @@
-Template.lastLoginModal.helpers({
- lastLoginDate: function() {
- var userLoginDate = ReactiveMethod.call('getPriorLoginDate');
- if (userLoginDate && userLoginDate.priorLoginDate) {
- return moment(userLoginDate.priorLoginDate).format("MMMM Do YYYY, HH:mm:ss A");
- }
- return;
- }
-});
\ No newline at end of file
diff --git a/Packages/lesiontracker/client/components/lesionTable/lesionTable.html b/Packages/lesiontracker/client/components/lesionTable/lesionTable.html
index 2034895b9..39bcb5f32 100644
--- a/Packages/lesiontracker/client/components/lesionTable/lesionTable.html
+++ b/Packages/lesiontracker/client/components/lesionTable/lesionTable.html
@@ -1,13 +1,17 @@
-
- {{>roundedButtonGroup buttonGroupData}}
-
-
- {{>lesionTableView (clone this)}}
+ {{#if this.timepoints.get.length}}
+
+ {{>roundedButtonGroup buttonGroupData}}
+
+
+ {{>lesionTableView (clone this)}}
+ {{else}}
+
No associated timepoint
+ {{/if}}
diff --git a/Packages/lesiontracker/client/components/lesionTable/lesionTable.styl b/Packages/lesiontracker/client/components/lesionTable/lesionTable.styl
index fc37495bc..27fa6756a 100644
--- a/Packages/lesiontracker/client/components/lesionTable/lesionTable.styl
+++ b/Packages/lesiontracker/client/components/lesionTable/lesionTable.styl
@@ -1,7 +1,7 @@
@import "{design}/app"
#lesionTableContainer
- background-color: $primaryBackgroundColor
+ theme('background-color', '$primaryBackgroundColor')
height: 100%
width: 100%
diff --git a/Packages/lesiontracker/client/components/lesionTableHUD/lesionTableHUD.styl b/Packages/lesiontracker/client/components/lesionTableHUD/lesionTableHUD.styl
index 08c47f4f5..edbc8416f 100644
--- a/Packages/lesiontracker/client/components/lesionTableHUD/lesionTableHUD.styl
+++ b/Packages/lesiontracker/client/components/lesionTableHUD/lesionTableHUD.styl
@@ -22,9 +22,9 @@ $borderColor = rgba(77, 99, 110, 0.81)
padding-left: 0
.header
- background: $uiGrayDarkest
+ theme('background', '$uiGrayDarkest')
+ theme('color', '$textSecondaryColor')
border-bottom: $uiBorderThickness solid $borderColor
- color: $textSecondaryColor
font-weight: 300
font-size: 20px
height: 55px
@@ -34,12 +34,12 @@ $borderColor = rgba(77, 99, 110, 0.81)
width: 100%
svg.buttonClose
- color: $defaultColor
+ theme('color', '$defaultColor')
cursor: pointer
height: 14px
position: absolute
right: 14px
- stroke: $defaultColor
+ theme('stroke', '$defaultColor')
top: 20px
width: 14px
@@ -48,19 +48,19 @@ $borderColor = rgba(77, 99, 110, 0.81)
padding-bottom: 20px
.footer
+ theme('background', '$uiGrayDarkest')
+ border-top: $uiBorderThickness solid $borderColor
width: 100%
height: 70px
position: absolute
bottom: 0
- background: $uiGrayDarkest
- border-top: $uiBorderThickness solid $borderColor
padding: 10px
.toolbarSectionButton
display: inline-block
- color: $defaultColor
- fill: $defaultColor
- stroke: $defaultColor
+ theme('color', '$defaultColor')
+ theme('fill', '$defaultColor')
+ theme('stroke', '$defaultColor')
padding: 0 10px
height: $toolbarHeight
min-width: 30px
@@ -85,15 +85,15 @@ $borderColor = rgba(77, 99, 110, 0.81)
height: 21px
&:active, &.active
- color: $activeColor
+ theme('color', '$activeColor')
svg
- fill: $activeColor
- stroke: $activeColor
+ theme('fill', '$activeColor')
+ theme('stroke', '$activeColor')
&:hover
- color: $hoverColor
+ theme('color', '$hoverColor')
svg
- fill: $hoverColor
- stroke: $hoverColor
+ theme('fill', '$hoverColor')
+ theme('stroke', '$hoverColor')
diff --git a/Packages/lesiontracker/client/components/lesionTableHeaderRow/lesionTableHeaderRow.js b/Packages/lesiontracker/client/components/lesionTableHeaderRow/lesionTableHeaderRow.js
index 441045710..2db4de0b6 100644
--- a/Packages/lesiontracker/client/components/lesionTableHeaderRow/lesionTableHeaderRow.js
+++ b/Packages/lesiontracker/client/components/lesionTableHeaderRow/lesionTableHeaderRow.js
@@ -16,7 +16,14 @@ Template.lesionTableHeaderRow.onCreated(() => {
const instance = Template.instance();
instance.maxNumLesions = new ReactiveVar();
+ // Get the current timepoint
const current = instance.data.timepointApi.current();
+
+ // Stop here if no timepoint was found
+ if (!current) {
+ return;
+ }
+
const timepointType = current.timepointType;
if (!instance.data.currentTimepointId) {
diff --git a/Packages/lesiontracker/client/components/lesionTableHeaderRow/lesionTableHeaderRow.styl b/Packages/lesiontracker/client/components/lesionTableHeaderRow/lesionTableHeaderRow.styl
index 8352934cf..9d8d65a25 100644
--- a/Packages/lesiontracker/client/components/lesionTableHeaderRow/lesionTableHeaderRow.styl
+++ b/Packages/lesiontracker/client/components/lesionTableHeaderRow/lesionTableHeaderRow.styl
@@ -3,10 +3,10 @@
$headerRowHeight = 63px
.lesionTableHeaderRow
- background-color: $uiGrayDarker
- color: $textSecondaryColor
+ theme('background-color', '$uiGrayDarker')
+ theme('color', '$textSecondaryColor')
display: flex
- fill: $textSecondaryColor
+ theme('fill', '$textSecondaryColor')
height: $headerRowHeight
line-height: $headerRowHeight
margin-top: 2px
@@ -35,13 +35,13 @@ $headerRowHeight = 63px
max-width: 11px
&:hover
- fill: $hoverColor
+ theme('fill', '$hoverColor')
&:active
- fill: $activeColor
+ theme('fill', '$activeColor')
.type
- color: $textSecondaryColor
+ theme('color', '$textSecondaryColor')
font-size: 22px
font-weight: 300
line-height: $headerRowHeight
@@ -49,8 +49,8 @@ $headerRowHeight = 63px
text-align: left
.numberOfLesions
+ theme('color', '$uiSkyBlue')
float: right
- color: $uiSkyBlue
font-weight: 300
font-size: 40px
max-width: 54px
@@ -63,7 +63,7 @@ $headerRowHeight = 63px
text-align: right
.maxNumLesions
- background-color: $textSecondaryColor
+ theme('background-color', '$textSecondaryColor')
border-radius: 3px
color: black
display: table
@@ -79,5 +79,5 @@ $headerRowHeight = 63px
&.warning
.maxNumLesions
- color: $textPrimaryColor
- background-color: $uiYellow
\ No newline at end of file
+ theme('background-color', '$uiYellow')
+ theme('color', '$textPrimaryColor')
diff --git a/Packages/lesiontracker/client/components/lesionTableRow/lesionTableRow.styl b/Packages/lesiontracker/client/components/lesionTableRow/lesionTableRow.styl
index aa9ca8ba9..5e38b2c4e 100644
--- a/Packages/lesiontracker/client/components/lesionTableRow/lesionTableRow.styl
+++ b/Packages/lesiontracker/client/components/lesionTableRow/lesionTableRow.styl
@@ -10,7 +10,7 @@
width: calc(100% + 6px)
&:before
- background-color: $activeColor
+ theme('background-color', '$activeColor')
border-top-left-radius: 7px
border-bottom-left-radius: 7px
content: ''
@@ -30,16 +30,16 @@
opacity: 1
.lesionRowSidebar
- color: $activeColor
+ theme('color', '$activeColor')
.rowOptions
height: 35px
visibility: visible
&.response-status .lesionRowSidebar .response-status-icon
- background-color: $defaultColor
+ theme('background-color', '$defaultColor')
+ theme('color', '$uiGray')
border-radius: 11px
- color: $uiGray
font-size: 12px
font-weight: 700
height: 21px
@@ -49,8 +49,8 @@
width: 21px
&.warning .lesionRowSidebar
- color: $textPrimaryColor
- background-color: $uiYellow
+ theme('background-color', '$uiYellow')
+ theme('color', '$textPrimaryColor')
.warning-icon, svg
width: 22px
@@ -60,31 +60,31 @@
margin: 7px auto 0
svg
- fill: $textPrimaryColor
+ theme('fill', '$textPrimaryColor')
.rowOptions
- background-color: $uiGrayDarker
+ theme('background-color', '$uiGrayDarker')
height: 0
overflow: hidden
transition(all 0.3s ease)
visibility: hidden
.rowAction
- color: $defaultColor
+ theme('color', '$defaultColor')
cursor: pointer
line-height: 35px
transition(all 0.3s ease)
&:hover, &:active
- color: $textPrimaryColor
+ theme('color', '$textPrimaryColor')
svg
- fill: $textPrimaryColor
- stroke: $textPrimaryColor
+ theme('fill', '$textPrimaryColor')
+ theme('stroke', '$textPrimaryColor')
svg
- fill: $defaultColor
- stroke: $defaultColor
+ theme('fill', '$defaultColor')
+ theme('stroke', '$defaultColor')
transition(all 0.3s ease)
&.edit-icon
@@ -96,8 +96,8 @@
height: 11px
.lesionRowSidebar
- background: $uiGray
- color: $textSecondaryColor
+ theme('background', '$uiGray')
+ theme('color', '$textSecondaryColor')
cursor: pointer
flex: 1
max-width: 30px
@@ -120,7 +120,7 @@
.location
font-weight: 400
font-size: 14px
- color: $textSecondaryColor
+ theme('color', '$textSecondaryColor')
height: 30px
line-height: 30px
margin-left: -2px
diff --git a/Packages/lesiontracker/client/components/lesionTableTimepointCell/lesionTableTimepointCell.styl b/Packages/lesiontracker/client/components/lesionTableTimepointCell/lesionTableTimepointCell.styl
index 0457b0c3f..622c188a0 100644
--- a/Packages/lesiontracker/client/components/lesionTableTimepointCell/lesionTableTimepointCell.styl
+++ b/Packages/lesiontracker/client/components/lesionTableTimepointCell/lesionTableTimepointCell.styl
@@ -1,6 +1,6 @@
@import "{design}/app"
.lesionTableTimepointCell
- border-left: $uiBorderThickness $uiBorderColor solid
- color: $textPrimaryColor
+ theme('border-left', '%s solid $uiBorderColor' % $uiBorderThickness)
+ theme('color', '$textPrimaryColor')
padding: 0 10px
diff --git a/Packages/lesiontracker/client/components/lesionTableTimepointHeader/lesionTableTimepointHeader.styl b/Packages/lesiontracker/client/components/lesionTableTimepointHeader/lesionTableTimepointHeader.styl
index 93e732fc5..18811e41e 100644
--- a/Packages/lesiontracker/client/components/lesionTableTimepointHeader/lesionTableTimepointHeader.styl
+++ b/Packages/lesiontracker/client/components/lesionTableTimepointHeader/lesionTableTimepointHeader.styl
@@ -5,18 +5,18 @@
justify-content: space-around
div
- border-left: $uiBorderColor $uiBorderThickness solid
+ theme('border-left', '%s solid $uiBorderColor' % $uiBorderThickness)
font-weight: 400
padding-left: 12px
text-align: left
.timepointName
- color: $textSecondaryColor
+ theme('color', '$textSecondaryColor')
font-size: 12px
line-height: 12px
.timepointDate
- color: $textPrimaryColor
+ theme('color', '$textPrimaryColor')
font-size: 14px
line-height: 20px
padding-bottom: 6px
diff --git a/Packages/lesiontracker/client/components/lesionTracker/lesionTracker.html b/Packages/lesiontracker/client/components/lesionTracker/lesionTracker.html
index 48021f2d9..b14819565 100644
--- a/Packages/lesiontracker/client/components/lesionTracker/lesionTracker.html
+++ b/Packages/lesiontracker/client/components/lesionTracker/lesionTracker.html
@@ -38,4 +38,5 @@
{{ >lastLoginModal }}
{{ >studyContextMenu }}
{{ >progressDialog}}
+ {{ >viewSeriesDetailsModal }}
diff --git a/Packages/lesiontracker/client/components/lesionTracker/lesionTracker.styl b/Packages/lesiontracker/client/components/lesionTracker/lesionTracker.styl
index 1619a3359..a8c2b9261 100644
--- a/Packages/lesiontracker/client/components/lesionTracker/lesionTracker.styl
+++ b/Packages/lesiontracker/client/components/lesionTracker/lesionTracker.styl
@@ -9,8 +9,8 @@ $expandedHeight = 160px
.topBar
height: $topBarHeight
- color: $textPrimaryColor
- background-color: $primaryBackgroundColor
+ theme('color', '$textPrimaryColor')
+ theme('background-color', '$primaryBackgroundColor')
transition(all 0.5s ease)
.brandSection
@@ -26,14 +26,14 @@ $expandedHeight = 160px
display: inline-block
font-family: $logoFontFamily
font-weight: $logoFontWeight
- color: $textPrimaryColor
+ theme('color', '$textPrimaryColor')
line-height: 30px
.studyListLinkSection
- border-left: $uiBorderThickness solid $uiBorderColor;
-
+ theme('border-left', '%s solid $uiBorderColor' % $uiBorderThickness)
+
.btn
- color: $textSecondaryColor
+ theme('color', '$textSecondaryColor')
cursor: pointer
font-size: 13px
font-weight: 500
@@ -41,10 +41,10 @@ $expandedHeight = 160px
margin-top: 3px
&:hover
- color: $hoverColor
+ theme('color', '$hoverColor')
&:active
- color: $activeColor
+ theme('color', '$activeColor')
&.studyList
background-color: rgba(21, 25, 30, 0.7)
@@ -75,5 +75,5 @@ $expandedHeight = 160px
.tab-pane
.viewerContainer
.loadingTextDiv
- color: $textSecondaryColor
+ theme('color', '$textSecondaryColor')
font-size: 30px
diff --git a/Packages/lesiontracker/client/components/lesionTrackerWorklistContextMenu/lesionTrackerWorklistContextMenu.html b/Packages/lesiontracker/client/components/lesionTrackerWorklistContextMenu/lesionTrackerWorklistContextMenu.html
index 44c8d699d..fe8671094 100644
--- a/Packages/lesiontracker/client/components/lesionTrackerWorklistContextMenu/lesionTrackerWorklistContextMenu.html
+++ b/Packages/lesiontracker/client/components/lesionTrackerWorklistContextMenu/lesionTrackerWorklistContextMenu.html
@@ -24,7 +24,10 @@
Remove Association
- View Series Details
+
+ View Series Details
+
Anonymize
Send
diff --git a/Packages/lesiontracker/client/components/measureFlow/measureFlow.html b/Packages/lesiontracker/client/components/measureFlow/measureFlow.html
index 964454710..17bca7d28 100644
--- a/Packages/lesiontracker/client/components/measureFlow/measureFlow.html
+++ b/Packages/lesiontracker/client/components/measureFlow/measureFlow.html
@@ -1,8 +1,9 @@
-
+
{{#if eq instance.state.get 'selected'}}
+
{{instance.value.label}}
{{#if instance.descriptionEdit.get}}
diff --git a/Packages/lesiontracker/client/components/measureFlow/measureFlow.js b/Packages/lesiontracker/client/components/measureFlow/measureFlow.js
index d52219261..f6df8dee1 100644
--- a/Packages/lesiontracker/client/components/measureFlow/measureFlow.js
+++ b/Packages/lesiontracker/client/components/measureFlow/measureFlow.js
@@ -55,6 +55,7 @@ Template.measureFlow.onCreated(() => {
}];
const items = [
+ 'Abdomen/Chest Wall',
'Adrenal',
'Bladder',
'Bone',
@@ -68,9 +69,10 @@ Template.measureFlow.onCreated(() => {
'Liver',
'Lung',
'Lymph Node',
+ 'Mediastinum/Hilum',
'Muscle',
'Neck',
- 'Other: Soft Tissue',
+ 'Other Soft Tissue',
'Ovary',
'Pancreas',
'Pelvis',
@@ -90,6 +92,25 @@ Template.measureFlow.onCreated(() => {
value: item
});
});
+
+ const commonItems = [
+ 'Abdomen/Chest Wall',
+ 'Lung',
+ 'Lymph Node',
+ 'Liver',
+ 'Mediastinum/Hilum',
+ 'Pelvis',
+ 'Peritoneum/Omentum',
+ 'Retroperitoneum'
+ ];
+
+ instance.commonItems = [];
+ _.each(commonItems, item => {
+ instance.commonItems.push({
+ label: item,
+ value: item
+ });
+ });
});
Template.measureFlow.onRendered(() => {
@@ -116,9 +137,12 @@ Template.measureFlow.events({
const data = {
key: 'label',
items: instance.items,
+ commonItems: instance.commonItems,
+ hideCommon: instance.data.hideCommon,
label: 'Assign label',
searchPlaceholder: 'Search labels',
storageKey: 'measureLabelCommon',
+ treeColumns: instance.data.treeColumns,
position
};
@@ -206,14 +230,14 @@ Template.measureFlow.events({
// Change the measure flow state to selected
instance.state.set('selected');
+ // Get the clicked label window offset
+ const labelOffset = $label.offset();
+
// Wait for the DOM re-rendering
Tracker.afterFlush(() => {
// Get the measure flow div
const $measureFlow = instance.$('.measure-flow');
- // Get the clicked label window offset
- const labelOffset = $label.offset();
-
// Subtract the label box shadow height from the label's position
labelOffset.top -= 10;
diff --git a/Packages/lesiontracker/client/components/measureFlow/measureFlow.styl b/Packages/lesiontracker/client/components/measureFlow/measureFlow.styl
index 5fbe75f6b..502d0f3a6 100644
--- a/Packages/lesiontracker/client/components/measureFlow/measureFlow.styl
+++ b/Packages/lesiontracker/client/components/measureFlow/measureFlow.styl
@@ -10,10 +10,10 @@
opacity: 0
.btn-add
- background-color: $activeColor
- border: 2px solid $uiBorderColor
+ theme('color', '$textColorActive')
+ theme('background-color', '$activeColor')
+ theme('border', '2px solid $uiBorderColor')
border-radius: 14px
- color: $textColorActive
cursor: pointer
font-weight: bold
height: 24px
@@ -26,14 +26,13 @@
transition(opacity 0.3s ease)
white-space: nowrap
+ // / {selector()}
+ // color: $themes['tide']['uiYellow'] !important
+
.select-tree-root>.tree-content
width: 213px
&>.tree-options
- margin-right: -17px
- max-height: 250px
- overflow-x: hidden
- overflow-y: scroll
position: relative
z-index: 2
@@ -43,22 +42,11 @@
&>.tree-leaf
position: relative
- &:before
- animateZoomIn()
- background-color: $activeColor
- border-radius: 20px
- color: $uiGray
- content: '\f00c'
- display: block
- font-family: FontAwesome
- font-size: 24px
- height: 40px
+ .icon-check
+ theme('background-color', '$activeColor')
left: -46px
- line-height: 40px
position: absolute
- text-align: center
top: 3px
- width: 40px
span
background: white
@@ -82,10 +70,10 @@
animateFadeOut()
button
+ theme('border', '1px solid $uiBorderColor')
+ theme('color', '$textPrimaryColor')
background-color: transparent
border-radius: 16px
- border: 1px solid $uiBorderColor
- color: $textPrimaryColor
font-weight: normal
height: 31px
line-height: 31px
@@ -120,3 +108,80 @@
span
display: block
+
+ &.tree-columns
+
+ .select-tree-root
+
+ &.interacted .select-tree-common .content
+ animation-name: none
+
+ &.selected .select-tree-common .content
+ animation-name: selectTreeCommonCloseLeft
+
+ .tree-search
+ input, i
+ display: none
+
+ .select-tree-common
+ padding-left: 0
+ padding-right: 6px
+ right: auto
+ left: 0
+ width: 33.333333333333%
+
+ &>.tree-content
+ transform-origin(0% 50%)
+ width: 426px
+
+ .select-tree-common .content
+ right: -100%
+
+ &.started .select-tree-common .content
+ right: 6px
+
+ &.interacted .select-tree-common .content
+ animation-name: selectTreeCommonCloseRight
+
+ .tree-inputs>label
+ float: left
+ width: 50%
+
+@keyframes selectTreeCommonCloseRight {
+ from {
+ height: 37px
+ display: table
+ right: 6px
+ opacity: 1
+ visibility: visible
+ }
+ to {
+ height: 100%
+ right: -100%
+ opacity: 0
+ visibility: hidden
+ width: calc(100% - 6px)
+ }
+}
+
+.icon-check
+ background-color: white
+ border-radius: 20px
+ display: block
+ height: 40px
+ overflow: hidden
+ position: relative
+ width: 40px
+
+ &:before
+ border: 2px solid black
+ border-left-width: 0
+ border-top-width: 0
+ content: ''
+ display: block
+ height: 18px
+ left: 15px
+ position: absolute
+ top: 9px
+ transform(rotate(45deg))
+ width: 9px
diff --git a/Packages/lesiontracker/client/components/radialProgressBar/radialProgressBar.styl b/Packages/lesiontracker/client/components/radialProgressBar/radialProgressBar.styl
index 09bc9fb27..465ef4aef 100644
--- a/Packages/lesiontracker/client/components/radialProgressBar/radialProgressBar.styl
+++ b/Packages/lesiontracker/client/components/radialProgressBar/radialProgressBar.styl
@@ -11,12 +11,12 @@ $circleSize = 46px
#svg circle
stroke-dashoffset: 0
- stroke: $uiBorderColorDark
+ theme('stroke', '$uiBorderColorDark')
stroke-width: 3px
vendorize(transition, stroke-dashoffset 1s linear)
#svg #bar
- stroke: $activeColor
+ theme('stroke', '$activeColor')
vendorize(transform, rotate(270deg))
vendorize(transform-origin, center center)
@@ -28,14 +28,14 @@ $circleSize = 46px
font-weight: 700
font-size: 17px
text-align: center
- color: $activeColor
+ theme('color', '$activeColor')
top: 0
svg
- fill: $activeColor
+ theme('fill', '$activeColor')
left: 50%
position: absolute
- stroke: $activeColor
+ theme('stroke', '$activeColor')
top: 50%
transform(translateX(-50%) translateY(-50%))
diff --git a/Packages/lesiontracker/client/components/serverInformation/serverInformationDicomWeb/serverInformationDicomWeb.html b/Packages/lesiontracker/client/components/serverInformation/serverInformationDicomWeb/serverInformationDicomWeb.html
index 5efd42467..8a2dc16be 100644
--- a/Packages/lesiontracker/client/components/serverInformation/serverInformationDicomWeb/serverInformationDicomWeb.html
+++ b/Packages/lesiontracker/client/components/serverInformation/serverInformationDicomWeb/serverInformationDicomWeb.html
@@ -1,30 +1,27 @@
- {{>serverInformationFormField name="wadoUriRoot" label="WADO URI root"}}
- {{>serverInformationFormField name="wadoUriRootNOTE" label="WADO URI root note"}}
- {{>serverInformationFormField name="wadoRoot" label="WADO root"}}
-
-
-
+ {{>inputText labelClass='form-group' key='wadoUriRoot'}}
+
+
+ {{>inputText labelClass='form-group' key='wadoUriRootNOTE'}}
+
+
+ {{>inputText labelClass='form-group' key='wadoRoot'}}
+
+
+ {{>inputSelect labelClass='form-group' key='imageRendering' hideSearch=true
+ options=(clone placeholder='Select an option')}}
+
+
+ {{>inputText labelClass='form-group' key='qidoRoot'}}
- {{>serverInformationFormField name="qidoRoot" label="QIDO root"}}
QIDO options
@@ -32,32 +29,25 @@
Request options
-
- {{>serverInformationFormField name="requestOptions.auth" label="Authentication"}}
+ {{#group class='row' key='requestOptions'}}
+
+ {{>inputText labelClass='form-group' key='auth'}}
+
-
+ {{/group}}
diff --git a/Packages/lesiontracker/client/components/serverInformation/serverInformationDicomWeb/serverInformationDicomWeb.js b/Packages/lesiontracker/client/components/serverInformation/serverInformationDicomWeb/serverInformationDicomWeb.js
index d067f8f0f..09c315466 100644
--- a/Packages/lesiontracker/client/components/serverInformation/serverInformationDicomWeb/serverInformationDicomWeb.js
+++ b/Packages/lesiontracker/client/components/serverInformation/serverInformationDicomWeb/serverInformationDicomWeb.js
@@ -1,10 +1,10 @@
-Template.serverInformationDicomWeb.onRendered(function() {
- var instance = Template.instance();
+Template.serverInformationDicomWeb.onRendered(() => {
+ const instance = Template.instance();
instance.autorun(function() {
- var mode = instance.data.mode.get();
+ const mode = instance.data.mode.get();
if (mode === 'edit') {
- var data = instance.data.currentItem.get();
- FormUtils.setFormData(instance.data.$form, data);
+ const data = instance.data.currentItem.get();
+ instance.data.form.value(data);
}
});
});
diff --git a/Packages/lesiontracker/client/components/serverInformation/serverInformationDimse/serverInformationDimse.html b/Packages/lesiontracker/client/components/serverInformation/serverInformationDimse/serverInformationDimse.html
index c5caeabc5..5b94094f0 100644
--- a/Packages/lesiontracker/client/components/serverInformation/serverInformationDimse/serverInformationDimse.html
+++ b/Packages/lesiontracker/client/components/serverInformation/serverInformationDimse/serverInformationDimse.html
@@ -1,43 +1,45 @@
-
Peer list
+ Peer List
-
+ {{#group class='row' key='peers' arrayValues=true}}
{{#each peer in instance.peers.get}}
-
+ {{#group class='col-lg-6'}}
- {{>serverInformationFormField name=(concat "peers[]." @index ".aeTitle") label="AE title"}}
- {{>serverInformationFormField name=(concat "peers[]." @index ".hostAE") label="AE host"}}
- {{>serverInformationFormField name=(concat "peers[]." @index ".host") label="Host"}}
- {{>serverInformationFormField name=(concat "peers[]." @index ".port") label="Port"}}
+
+ {{>inputText class='form-control' key='aeTitle'}}
+
+
+ {{>inputText class='form-control' key='hostAE'}}
+
+
+ {{>inputText class='form-control' key='host'}}
+
+
+ {{>inputText class='form-control' key='port'}}
+
-
+ {{/group}}
{{/each}}
-
+ {{/group}}
diff --git a/Packages/lesiontracker/client/components/serverInformation/serverInformationDimse/serverInformationDimse.js b/Packages/lesiontracker/client/components/serverInformation/serverInformationDimse/serverInformationDimse.js
index 29b32aa1b..0249b580c 100644
--- a/Packages/lesiontracker/client/components/serverInformation/serverInformationDimse/serverInformationDimse.js
+++ b/Packages/lesiontracker/client/components/serverInformation/serverInformationDimse/serverInformationDimse.js
@@ -1,29 +1,29 @@
-Template.serverInformationDimse.onCreated(function() {
- var instance = Template.instance();
+Template.serverInformationDimse.onCreated(() => {
+ const instance = Template.instance();
instance.peers = new ReactiveVar([]);
- instance.autorun(function() {
- var currentItem = instance.data.currentItem.get();
+ instance.autorun(() => {
+ const currentItem = instance.data.currentItem.get();
if (currentItem) {
instance.peers.set(currentItem.peers || []);
}
});
});
-Template.serverInformationDimse.onRendered(function() {
- var instance = Template.instance();
- instance.autorun(function() {
- var mode = instance.data.mode.get();
+Template.serverInformationDimse.onRendered(() => {
+ const instance = Template.instance();
+ instance.autorun(() => {
+ const mode = instance.data.mode.get();
if (mode === 'edit') {
- var data = instance.data.currentItem.get();
- FormUtils.setFormData(instance.data.$form, data);
+ const data = instance.data.currentItem.get();
+ instance.data.form.value(data);
}
});
});
Template.serverInformationDimse.events({
- 'click .js-new-peer': function(event, instance) {
+ 'click .js-new-peer'(event, instance) {
event.preventDefault();
- var peers = instance.peers.get();
+ const peers = instance.peers.get();
peers.push({});
instance.peers.set(peers);
}
diff --git a/Packages/lesiontracker/client/components/serverInformation/serverInformationForm/serverInformationForm.html b/Packages/lesiontracker/client/components/serverInformation/serverInformationForm/serverInformationForm.html
index 435b795a4..132a6b5da 100644
--- a/Packages/lesiontracker/client/components/serverInformation/serverInformationForm/serverInformationForm.html
+++ b/Packages/lesiontracker/client/components/serverInformation/serverInformationForm/serverInformationForm.html
@@ -1,33 +1,21 @@
-
{{/if}}
-
+ {{/form}}
diff --git a/Packages/lesiontracker/client/components/serverInformation/serverInformationForm/serverInformationForm.js b/Packages/lesiontracker/client/components/serverInformation/serverInformationForm/serverInformationForm.js
index 69a8c1465..49a70d5ea 100644
--- a/Packages/lesiontracker/client/components/serverInformation/serverInformationForm/serverInformationForm.js
+++ b/Packages/lesiontracker/client/components/serverInformation/serverInformationForm/serverInformationForm.js
@@ -1,24 +1,68 @@
-Template.serverInformationForm.onRendered(function() {
- var instance = Template.instance();
+import { Template } from 'meteor/templating';
+import { ReactiveVar } from 'meteor/reactive-var';
+import { Tracker } from 'meteor/tracker';
+import { DICOMWebServer as dicomSchema } from 'meteor/worklist/both/schema';
+import { DIMSEServer as dimseSchema } from 'meteor/worklist/both/schema';
- instance.data.$form = instance.$('form');
- instance.autorun(function() {
- var mode = instance.data.mode.get();
+Template.serverInformationForm.onCreated(() => {
+ const instance = Template.instance();
+
+ instance.currentSchema = new ReactiveVar(dicomSchema);
+});
+
+Template.serverInformationForm.onRendered(() => {
+ const instance = Template.instance();
+
+ instance.data.$form = instance.$('form:first');
+ instance.data.form = instance.data.$form.data('component');
+
+ // Handle the server type
+ instance.autorun(() => {
+ // Get the server type component
+ const typeComponent = instance.$('[data-key=type] :input').data('component');
+
+ // Run this computation every time the user change the server type
+ typeComponent.depend();
+
+ // Get the current server type value
+ const type = typeComponent.value();
+
+ // Set the serverType reactive value
+ instance.data.serverType.set(type);
+
+ // Change the schema based on the selected server type
+ if (type === 'dimse') {
+ instance.currentSchema.set(dimseSchema);
+ } else {
+ instance.currentSchema.set(dicomSchema);
+ }
+ });
+
+ // Handle the form mode (edit or add)
+ instance.autorun(() => {
+ const mode = instance.data.mode.get();
+
+ // Check if it is on edit mode and load the saved data
if (mode === 'edit') {
- var data = instance.data.currentItem.get();
- FormUtils.setFormData(instance.data.$form, data);
+ const data = instance.data.currentItem.get();
+ instance.data.form.value(data);
}
});
});
Template.serverInformationForm.events({
- 'change .js-server-type': function(event, instance) {
- var value = $(event.currentTarget).val();
- instance.data.serverType.set(value);
- },
- submit: function(event, instance) {
+ submit(event, instance) {
event.preventDefault();
- var formData = FormUtils.getFormData(instance.data.$form);
+
+ // Stop here if the form validation fails
+ if (!instance.data.form.validate()) {
+ return;
+ }
+
+ // Get the current form data
+ const formData = instance.data.form.value();
+
+ // Call the save method
Meteor.call('serverSave', formData, function(error) {
if (error) {
// TODO: check for errors: not-authorized, data-write
diff --git a/Packages/lesiontracker/client/components/studySeriesQuickSwitch/studySeriesQuickSwitch.styl b/Packages/lesiontracker/client/components/studySeriesQuickSwitch/studySeriesQuickSwitch.styl
index 13a5ca71d..00da950df 100644
--- a/Packages/lesiontracker/client/components/studySeriesQuickSwitch/studySeriesQuickSwitch.styl
+++ b/Packages/lesiontracker/client/components/studySeriesQuickSwitch/studySeriesQuickSwitch.styl
@@ -15,7 +15,7 @@ $seriesSpacing = 2px
transform(translateX(-50%))
&.left
- border-right: 1px solid $uiBorderColor
+ theme('border-right', '1px solid $uiBorderColor')
right: 50%
&.right
@@ -26,7 +26,7 @@ $seriesSpacing = 2px
z-index: 3
&:before
- background-color: $primaryBackgroundColor
+ theme('background-color', '$primaryBackgroundColor')
bottom: 0
content: ''
left: 0
@@ -98,10 +98,10 @@ $seriesSpacing = 2px
.studyTimepointBrowser
background-color: transparent
.studyTimepointStudy.active .studyModality
- box-shadow: inset 0 0 0 3px $activeColor
+ theme('box-shadow', 'inset 0 0 0 3px $activeColor')
.studyBox
- background-color: $uiGrayDark
- border: solid 1px $activeColor
+ theme('background-color', '$uiGrayDark')
+ theme('border', 'solid 1px $activeColor')
border-radius: 11px
display: block
height: $switchSize
@@ -113,7 +113,7 @@ $seriesSpacing = 2px
width: $switchSize + $seriesSpacing
.seriesItem
- background-color: $boxBackgroundColorDark
+ theme('background-color', '$boxBackgroundColor')Dark
border-radius: 3px
height: 15px
margin: $seriesSpacing
@@ -121,17 +121,17 @@ $seriesSpacing = 2px
&.count
background-color: transparent
- color: $textPrimaryColor
+ theme('color', '$textPrimaryColor')
font-size: 12px
font-weight: 500
line-height: 17px
text-align: center
&.active
- background-color: $activeColor
+ theme('background-color', '$activeColor')
.label
- color: $textSecondaryColor
+ theme('color', '$textSecondaryColor')
display: block
font-size: 12px
font-weight: 300
diff --git a/Packages/lesiontracker/client/components/studyTimepointBrowser/studyTimepointBrowser.styl b/Packages/lesiontracker/client/components/studyTimepointBrowser/studyTimepointBrowser.styl
index 17223a024..4d736d99e 100644
--- a/Packages/lesiontracker/client/components/studyTimepointBrowser/studyTimepointBrowser.styl
+++ b/Packages/lesiontracker/client/components/studyTimepointBrowser/studyTimepointBrowser.styl
@@ -3,15 +3,15 @@
$timepointButtonHeight = 55px
.studyTimepointBrowser
- background-color: $primaryBackgroundColor
+ theme('background-color', '$primaryBackgroundColor')
float: left
height: 100%
position: relative
width: 100%
.timepointButtonContainer
- background-color: $primaryBackgroundColor
- border-bottom: 1px solid $uiBorderColor
+ theme('background-color', '$primaryBackgroundColor')
+ theme('border-bottom', '1px solid $uiBorderColor')
display: none
height: $timepointButtonHeight
left: 10px
@@ -38,7 +38,7 @@ $timepointButtonHeight = 55px
transform: rotateX(180deg)
.timepointFollowupTitle
font-size: 14px
- color: $textSecondaryColor
+ theme('color', '$textSecondaryColor')
text-transform: uppercase
.timepointHeader
@@ -50,7 +50,7 @@ $timepointButtonHeight = 55px
.timepointFollowupTitle
.timepointDate
.timepointModalities
- color: $textSecondaryColor
+ theme('color', '$textSecondaryColor')
transition($sidebarTransition)
&:hover
@@ -59,7 +59,7 @@ $timepointButtonHeight = 55px
.expandIcon i
.timepointDate
.timepointModalities
- color: $textPrimaryColor !important
+ theme('color', '$textPrimaryColor') !important
.timepointDetails
.timepointModalities
@@ -70,10 +70,10 @@ $timepointButtonHeight = 55px
overflow: hidden
.expandIcon i
- color: $defaultColor
+ theme('color', '$defaultColor')
.timepointFollowupTitle
- color: $textPrimaryColor
+ theme('color', '$textPrimaryColor')
padding-top: 2px
.studyTimepointScrollArea
@@ -91,7 +91,7 @@ $timepointButtonHeight = 55px
margin-right: 16px
.studySidebarTimepoint .thumbnailEntry.active:before
- background-color: $activeColor
+ theme('background-color', '$activeColor')
border-top-right-radius: 7px
border-bottom-right-radius: 7px
content: ''
diff --git a/Packages/lesiontracker/client/components/studyTimepointBrowser/studyTimepointStudy.styl b/Packages/lesiontracker/client/components/studyTimepointBrowser/studyTimepointStudy.styl
index 2d058dae9..e1d31d584 100644
--- a/Packages/lesiontracker/client/components/studyTimepointBrowser/studyTimepointStudy.styl
+++ b/Packages/lesiontracker/client/components/studyTimepointBrowser/studyTimepointStudy.styl
@@ -3,8 +3,6 @@
$boxBorderColor = transparent
$boxHoverBackgroundColor = #14191E
$boxHoverBorderColor = #2d4660
-$boxActiveBackgroundColor = $activeColor
-$boxActiveTextColor = $primaryBackgroundColor
$boxActiveBorderColor = #131D29
$boxWidth = 50px
$borderThickness = 2px
@@ -41,11 +39,11 @@ $spacerY = 12px
&.active
.studyModality
.studyModalityBox
- color: $boxActiveTextColor
+ theme('color', '$primaryBackgroundColor')
&
&:before
&:after
- background-color: $boxActiveBackgroundColor
+ theme('background-color', '$activeColor')
border-color: $boxActiveBorderColor
&:not(.active) .studyTimepointThumbnails
@@ -69,10 +67,10 @@ $spacerY = 12px
border-color: $boxHoverBorderColor
&.additional
- color: $textSecondaryColor
+ theme('color', '$textSecondaryColor')
&.additional
- color: $textPrimaryColor
+ theme('color', '$textPrimaryColor')
font-size: 16px
font-weight: normal
height: 91px
@@ -89,13 +87,13 @@ $spacerY = 12px
top: $spacerY
.studyDate
margin-top: 8px
- color: $textSecondaryColor
+ theme('color', '$textSecondaryColor')
.studyDescription
margin-top: 8px
- color: $textPrimaryColor
+ theme('color', '$textPrimaryColor')
.studyModalityBox
- color: $textSecondaryColor
+ theme('color', '$textSecondaryColor')
line-height: $boxWidth
margin-left: $nestingMargin * 2
margin-top: $nestingMargin * 2
@@ -109,8 +107,8 @@ $spacerY = 12px
&
&:before
&:after
- background-color: $boxBackgroundColor
- border: $borderThickness solid $primaryBackgroundColor
+ theme('border', '$borderThickness solid $primaryBackgroundColor')
+ theme('background-color', '$boxBackgroundColor')
border-radius: $boxBorderRadius
height: $boxWidth + ($borderThickness * 2)
transition($sidebarTransition)
diff --git a/Packages/lesiontracker/client/components/toolbarSection/toolbarSection.js b/Packages/lesiontracker/client/components/toolbarSection/toolbarSection.js
index 8fc3b88f3..c90de53af 100644
--- a/Packages/lesiontracker/client/components/toolbarSection/toolbarSection.js
+++ b/Packages/lesiontracker/client/components/toolbarSection/toolbarSection.js
@@ -53,7 +53,10 @@ Template.toolbarSection.helpers({
},
toolbarButtons() {
- var buttonData = [];
+ // Check if the measure tools shall be disabled
+ const isMesureDisabled = !Template.instance().data.timepointApi.currentTimepointId;
+ const buttonData = [];
+
buttonData.push({
id: 'zoom',
title: 'Zoom',
@@ -86,14 +89,16 @@ Template.toolbarSection.helpers({
id: 'bidirectional',
title: 'Target',
classes: 'imageViewerTool rm-l-3',
- svgLink: '/packages/viewerbase/assets/icons.svg#icon-tools-measure-target'
+ svgLink: '/packages/viewerbase/assets/icons.svg#icon-tools-measure-target',
+ disabled: isMesureDisabled
});
buttonData.push({
id: 'nonTarget',
title: 'Non-Target',
classes: 'imageViewerTool toolbarSectionButton',
- svgLink: '/packages/viewerbase/assets/icons.svg#icon-tools-measure-non-target'
+ svgLink: '/packages/viewerbase/assets/icons.svg#icon-tools-measure-non-target',
+ disabled: isMesureDisabled
});
buttonData.push({
@@ -107,28 +112,33 @@ Template.toolbarSection.helpers({
},
extraToolbarButtons() {
- let buttonData = [];
+ // Check if the measure tools shall be disabled
+ const isMesureDisabled = !Template.instance().data.timepointApi.currentTimepointId;
+ const buttonData = [];
// TODO: Get real icons for CR / UN / EX
buttonData.push({
id: 'crTool',
title: 'CR Tool',
classes: 'imageViewerTool toolbarSectionButton',
- svgLink: '/packages/viewerbase/assets/icons.svg#icon-tools-measure-temp'
+ svgLink: '/packages/viewerbase/assets/icons.svg#icon-tools-measure-temp',
+ disabled: isMesureDisabled
});
buttonData.push({
id: 'unTool',
title: 'UN Tool',
classes: 'imageViewerTool toolbarSectionButton',
- svgLink: '/packages/viewerbase/assets/icons.svg#icon-tools-measure-temp'
+ svgLink: '/packages/viewerbase/assets/icons.svg#icon-tools-measure-temp',
+ disabled: isMesureDisabled
});
buttonData.push({
id: 'exTool',
title: 'EX Tool',
classes: 'imageViewerTool toolbarSectionButton',
- svgLink: '/packages/viewerbase/assets/icons.svg#icon-tools-measure-temp'
+ svgLink: '/packages/viewerbase/assets/icons.svg#icon-tools-measure-temp',
+ disabled: isMesureDisabled
});
return buttonData;
diff --git a/Packages/lesiontracker/client/components/toolbarSection/toolbarSection.styl b/Packages/lesiontracker/client/components/toolbarSection/toolbarSection.styl
index 389e1ecec..f093294e2 100644
--- a/Packages/lesiontracker/client/components/toolbarSection/toolbarSection.styl
+++ b/Packages/lesiontracker/client/components/toolbarSection/toolbarSection.styl
@@ -1,7 +1,7 @@
@import "{design}/app"
.toolbarSection
- border-bottom: $uiBorderColor $uiBorderThickness solid
+ theme('border-bottom', '%s solid $uiBorderColor' % $uiBorderThickness)
flex: 0 0 auto
height: $toolbarHeight
overflow: hidden
@@ -14,11 +14,11 @@
height: $toolbarHeight + $toolbarDrawerHeight
.toolbarSectionEntry
- color: $defaultColor
+ theme('color', '$defaultColor')
cursor: pointer
display: inline-block
- fill: $defaultColor
+ theme('fill', '$defaultColor')
margin-top: 3px
min-width: 30px
- stroke: $defaultColor
- text-align: center
\ No newline at end of file
+ theme('stroke', '$defaultColor')
+ text-align: center
diff --git a/Packages/lesiontracker/client/components/userAccountMenu/userAccountMenu.js b/Packages/lesiontracker/client/components/userAccountMenu/userAccountMenu.js
index 58ec7edaf..6d75389fb 100644
--- a/Packages/lesiontracker/client/components/userAccountMenu/userAccountMenu.js
+++ b/Packages/lesiontracker/client/components/userAccountMenu/userAccountMenu.js
@@ -1,3 +1,10 @@
+import { Template } from 'meteor/templating';
+import { ReactiveVar } from 'meteor/reactive-var';
+import { Session } from 'meteor/session';
+
+// Display the last login modal as default
+Session.setDefault('displayLastLoginModal', true);
+
Template.userAccountMenu.helpers({
name: function() {
var nameSplit = Meteor.user().profile.fullName.split(' ');
@@ -29,68 +36,87 @@ Template.userAccountMenu.events({
$('#serverInformationModal').modal('show');
},
'click #logoutButton': function() {
- // Remove reviewers info for the user
- Meteor.call('removeUserFromReviewers', Meteor.userId());
-
Meteor.logout(function() {
Router.go('/entrySignIn');
});
}
});
-Template.userAccountMenu.onRendered(function() {
- var oldUserId;
- var lastLoginModalInterval;
+Template.userAccountMenu.onCreated(function userAccountMenuCreated() {
+ const instance = Template.instance();
- this.autorun(function() {
- // Hook login/logout
- var user = Meteor.user();
- if (!user) {
+ // Create reactive last login date
+ instance.lastLoginDate = new ReactiveVar();
+
+ // We need oldUser to remove Reviewers if the user logged out
+ let oldUser;
+
+ // Get last login date
+ Meteor.call('getPriorLoginDate', function(error, lastLoginDate){
+ if (error) {
+ console.log(error);
return;
}
- var newUserId = user._id;
+ // Format the last login date
+ const formattedLastLoginDate = moment(lastLoginDate).format("MMMM Do YYYY, HH:mm:ss A");
- if (oldUserId === null && newUserId) {
- Session.set('showLastLoginModal', true);
+ instance.lastLoginDate.set(formattedLastLoginDate);
- // Log
- HipaaLogger.logEvent({
- eventType: 'init',
- userId: user._id,
- userName: user.fullName
- });
+ });
- } else if (newUserId === null && oldUserId) {
- // Set showLastLoginModal as null
- Session.set('showLastLoginModal', null);
-
- // Destroy interval for last login modal
- Meteor.clearInterval(lastLoginModalInterval);
- console.log('The user logged out');
-
- // Log
- // TODO: eventType is not defined for logout in hipaa-audit-log
- /*HipaaLogger.logEvent({
- eventType: 'logout',
- userId: oldUserId,
- userName: userName
- });*/
-
- // Remove the user from Reviewers
- Meteor.call('removeUserFromReviewers', oldUserId);
+ instance.autorun(function() {
+ const lastLoginDate = instance.lastLoginDate.get();
+ if (!lastLoginDate) {
+ return;
}
- oldUserId = Meteor.userId();
+ // Hook login/logout
+ var user = Meteor.user();
+ if (!user) {
+ // Display last login modal for the next login
+ Session.setPersistent('displayLastLoginModal', true);
+
+ if (oldUser) {
+ // Log Signout
+ // TODO: eventType for logout is not defined
+ // HipaaLogger.logEvent({
+ // eventType: 'logout',
+ // userId: oldUser._id,
+ // userName: oldUser.profile.fullName
+ // });
+
+ // Remove the user by oldUserId from Reviewers
+ Meteor.call('removeUserFromReviewers', oldUser._id);
+ }
+ return;
+ }
+
+ // Set oldUser
+ oldUser = user;
// Trigger last login date popup
- if (Session.get('showLastLoginModal')) {
- Modal.show('lastLoginModal');
-
- lastLoginModalInterval = Meteor.setInterval(function() {
- Modal.hide('lastLoginModal');
- Session.set('showLastLoginModal', null);
- }, 3000);
+ if (!Session.get('displayLastLoginModal')) {
+ return;
}
+
+ // Displaye the modal
+ Modal.show('lastLoginModal', {
+ lastLoginDate: lastLoginDate
+ });
+
+ // Hide the modal after 5sec
+ Meteor.setTimeout(() => {
+ Modal.hide('lastLoginModal');
+ Session.setPersistent('displayLastLoginModal', false);
+ }, 5000);
+
+ // Log signin
+ HipaaLogger.logEvent({
+ eventType: 'init',
+ userId: user._id,
+ userName: user.profile.fullName
+ });
+
});
});
\ No newline at end of file
diff --git a/Packages/lesiontracker/client/components/userAccountMenu/userAccountMenu.styl b/Packages/lesiontracker/client/components/userAccountMenu/userAccountMenu.styl
index c55aa873e..45a733782 100644
--- a/Packages/lesiontracker/client/components/userAccountMenu/userAccountMenu.styl
+++ b/Packages/lesiontracker/client/components/userAccountMenu/userAccountMenu.styl
@@ -5,7 +5,7 @@
height: 100%
.dropdown-toggle
- color: $defaultColor
+ theme('color', '$defaultColor')
cursor: pointer
font-size: 13px
font-weight: 400
@@ -13,19 +13,19 @@
text-decoration: none
.menuButton
- border-left: solid 1px $defaultColor
+ theme('border-left', 'solid 1px $defaultColor')
display: inline-block
height: 18px
padding: 0 8px
.fa
- color: $defaultColor
+ theme('color', '$defaultColor')
font-size: 17px
line-height: 18px
.caret-down
+ theme('color', '$uiLightGray')
margin: 0 4px 4px 2px
- color: $uiLightGray
ul.dropdown-menu
li
diff --git a/Packages/lesiontracker/client/components/viewer/viewer.styl b/Packages/lesiontracker/client/components/viewer/viewer.styl
index 250aa52d7..0e2f65bb1 100644
--- a/Packages/lesiontracker/client/components/viewer/viewer.styl
+++ b/Packages/lesiontracker/client/components/viewer/viewer.styl
@@ -19,4 +19,4 @@
&:not(:last-child)
.removable
.imageViewerViewport
- border-right: $uiBorderThickness solid $uiBorderColor
+ theme('border-right', '%s solid $uiBorderColor' % $uiBorderThickness)
diff --git a/Packages/lesiontracker/client/utils/form.js b/Packages/lesiontracker/client/utils/form.js
deleted file mode 100644
index 80a790594..000000000
--- a/Packages/lesiontracker/client/utils/form.js
+++ /dev/null
@@ -1,105 +0,0 @@
-class Form {
-
- // Identify the element's type and get its value
- static getElementValue($element) {
- var type = $element.attr('type');
- var value;
- switch (type) {
- case 'checkbox':
- value = $element.is(':checked');
- break;
- default:
- value = $element.val();
- }
- return value;
- };
-
- // Identify the element's type and get its value
- static setElementValue($element, value) {
- if (!$element.length) {
- return;
- }
-
- var type = $element.attr('type');
- switch (type) {
- case 'checkbox':
- $element.prop('checked', !!value);
- break;
- default:
- $element.val(value);
- }
- $element.trigger('change');
- };
-
- // Transforms a shallow object with keys separated by "." into a nested object
- static getNestedObject(shallowObject) {
- var nestedObject = {};
- for (var key in shallowObject) {
- var value = shallowObject[key];
- var propertyArray = key.split('.');
- var currentObject = nestedObject;
- while (propertyArray.length) {
- var currentProperty = propertyArray.shift();
- if (!propertyArray.length) {
- currentObject[currentProperty] = value;
- } else {
- if (!currentObject[currentProperty]) {
- currentObject[currentProperty] = {};
- }
-
- currentObject = currentObject[currentProperty];
- }
- }
- }
-
- return nestedObject;
- };
-
- // Transforms a nested object into a shallowObject merging its keys with "." character
- static getShallowObject(nestedObject) {
- var shallowObject = {};
- var putValues = function(baseKey, nestedObject, resultObject) {
- for (var key in nestedObject) {
- var currentKey = baseKey ? baseKey + '.' + key : key;
- var currentValue = nestedObject[key];
- if (typeof currentValue === 'object') {
- if (currentValue instanceof Array) {
- currentKey += '[]';
- }
-
- putValues(currentKey, currentValue, resultObject);
- } else {
- resultObject[currentKey] = currentValue;
- }
- }
- };
-
- putValues('', nestedObject, shallowObject);
- return shallowObject;
- }
-
- // Gets the nested data for the given form
- static getFormData($form) {
- var data = {};
- $form.find(':input[name]').each((index, element) => {
- var $element = $(element);
- var value = this.getElementValue($element);
- var name = $element.attr('name');
- data[name] = value;
- });
- return this.getNestedObject(data);
- }
-
- // Sets the nested data in the given form
- static setFormData($form, data) {
- var shallowData = this.getShallowObject(data);
- for (var key in shallowData) {
- var value = shallowData[key];
- var $element = $form.find(':input[name="' + key + '"]');
- this.setElementValue($element, value);
- }
- }
-
-}
-
-FormUtils = Form;
diff --git a/Packages/lesiontracker/package.js b/Packages/lesiontracker/package.js
index ad16e3a8a..8fc480663 100644
--- a/Packages/lesiontracker/package.js
+++ b/Packages/lesiontracker/package.js
@@ -58,9 +58,6 @@ Package.onUse(function(api) {
api.addFiles('client/tools.js', 'client');
- // Utility classes
- api.addFiles('client/utils/form.js', 'client');
-
// UI Components
api.addFiles('client/components/viewer/viewer.html', 'client');
api.addFiles('client/components/viewer/viewer.styl', 'client');
@@ -101,6 +98,8 @@ Package.onUse(function(api) {
api.addFiles('client/components/activeEntry/activeEntry.styl', 'client');
api.addFiles('client/components/activeEntry/activeEntry.js', 'client');
+ api.addFiles('client/components/activeEntry/activeEntrySignIn/activeEntrySignIn.js', 'client');
+
api.addFiles('client/components/hipaaLogPage/hipaaLogPage.styl', 'client');
api.addFiles('client/components/hipaaLogPage/hipaaLogPage.js', 'client');
@@ -197,7 +196,6 @@ Package.onUse(function(api) {
api.addFiles('client/components/confirmRemoveTimepointAssociation/confirmRemoveTimepointAssociation.js', 'client');
api.addFiles('client/components/lastLoginModal/lastLoginModal.html', 'client');
- api.addFiles('client/components/lastLoginModal/lastLoginModal.js', 'client');
api.addFiles('client/components/confirmDeleteDialog/confirmDeleteDialog.html', 'client');
api.addFiles('client/components/confirmDeleteDialog/confirmDeleteDialog.styl', 'client');
@@ -208,10 +206,11 @@ Package.onUse(function(api) {
api.addFiles('client/components/emailVerification/emailVerification.js', 'client');
// Server functions
- api.addFiles('server/servers.js', 'server');
api.addFiles('server/publications.js', 'server');
+ api.addFiles('server/servers.js', 'server');
api.addFiles('server/methods.js', [ 'server' ]);
api.addFiles('server/reviewers.js', [ 'server' ]);
+ api.addFiles('server/createDemoUser.js', [ 'server' ]);
// Both client and server functions
api.addFiles('both/collections.js', [ 'client', 'server' ]);
diff --git a/Packages/lesiontracker/server/createDemoUser.js b/Packages/lesiontracker/server/createDemoUser.js
new file mode 100644
index 000000000..9c0e5f2b6
--- /dev/null
+++ b/Packages/lesiontracker/server/createDemoUser.js
@@ -0,0 +1,39 @@
+import { Accounts } from 'meteor/accounts-base';
+
+
+Meteor.startup(function() {
+ const options = {
+ email: 'demo@ohif.org',
+ password: '12345678aA*',
+ profile: {
+ fullName: 'Demo User'
+ }
+ };
+
+ createDemoUser = function() {
+ const user = Meteor.users.findOne({
+ emails: {
+ $elemMatch: {
+ address: 'demo@ohif.org'
+ }
+ }
+ });
+ if (user) {
+ return;
+ }
+ console.log('create user!');
+
+ // Create user
+ const userId = Accounts.createUser(options);
+
+ if (!userId) {
+ console.log('Demo user cannot be created');
+ return;
+ }
+ };
+
+ // Create demo user
+ createDemoUser();
+
+});
+
diff --git a/Packages/lesiontracker/server/reviewers.js b/Packages/lesiontracker/server/reviewers.js
index 27aa79d84..fb228c166 100644
--- a/Packages/lesiontracker/server/reviewers.js
+++ b/Packages/lesiontracker/server/reviewers.js
@@ -85,7 +85,13 @@ Meteor.methods({
},
getPriorLoginDate: function() {
- return Meteor.users.findOne({_id: Meteor.userId()}, {fields: {priorLoginDate: 1}});
+ return Meteor.users.findOne({
+ _id: Meteor.userId()
+ }, {
+ fields: {
+ priorLoginDate: 1
+ }
+ }).priorLoginDate;
}
});
diff --git a/Packages/lesiontracker/server/servers.js b/Packages/lesiontracker/server/servers.js
index 35aecefc7..5e10fc48d 100644
--- a/Packages/lesiontracker/server/servers.js
+++ b/Packages/lesiontracker/server/servers.js
@@ -69,4 +69,4 @@ Meteor.methods({
serverSave: serverSettings => ServersControl.save(serverSettings),
serverSetActive: serverId => ServersControl.setActive(serverId),
serverRemove: serverId => ServersControl.remove(serverId)
-});
\ No newline at end of file
+});
diff --git a/Packages/ohif-core/both/index.js b/Packages/ohif-core/both/index.js
new file mode 100644
index 000000000..94b130b86
--- /dev/null
+++ b/Packages/ohif-core/both/index.js
@@ -0,0 +1 @@
+import './schema.js';
diff --git a/Packages/ohif-core/both/schema.js b/Packages/ohif-core/both/schema.js
new file mode 100644
index 000000000..ea60afe58
--- /dev/null
+++ b/Packages/ohif-core/both/schema.js
@@ -0,0 +1,34 @@
+import { SimpleSchema } from 'meteor/aldeed:simple-schema';
+
+/*
+ Extend the available options on schema definitions:
+
+ * valuesLabels: Used in conjunction with allowedValues to define the text
+ label for each value (used on forms)
+
+ * textOptional: Used to allow empty strings
+
+ */
+SimpleSchema.extendOptions({
+ valuesLabels: Match.Optional([String]),
+ textOptional: Match.Optional(Boolean)
+});
+
+// Add default required validation for empty strings which can be bypassed
+// using textOptional=true definition
+SimpleSchema.addValidator(function() {
+ if (
+ this.definition.optional !== true &&
+ this.definition.textOptional !== true &&
+ this.value === ''
+ ) {
+ return 'required';
+ }
+});
+
+// Including [label] for some messages
+SimpleSchema.messages({
+ maxCount: '[label] can not have more than [maxCount] values',
+ minCount: '[label] must have at least [minCount] values',
+ notAllowed: '[label] has an invalid value: "[value]"'
+});
diff --git a/Packages/ohif-core/client/components/base/index.js b/Packages/ohif-core/client/components/base/index.js
index bdc4cb34a..bc57de0ae 100644
--- a/Packages/ohif-core/client/components/base/index.js
+++ b/Packages/ohif-core/client/components/base/index.js
@@ -10,6 +10,7 @@ import './mixins/formItem.js';
import './mixins/group.js';
import './mixins/groupRadio.js';
import './mixins/input.js';
+import './mixins/checkbox.js';
import './mixins/schemaData.js';
import './mixins/select.js';
import './mixins/select2.js';
diff --git a/Packages/ohif-core/client/components/base/mixins/checkbox.js b/Packages/ohif-core/client/components/base/mixins/checkbox.js
new file mode 100644
index 000000000..0b05a65d3
--- /dev/null
+++ b/Packages/ohif-core/client/components/base/mixins/checkbox.js
@@ -0,0 +1,26 @@
+import { OHIF } from 'meteor/ohif:core';
+import { Template } from 'meteor/templating';
+import { _ } from 'meteor/underscore';
+
+/*
+ * inputCheckbox: controls a checkbox input
+ */
+OHIF.mixins.checkbox = new OHIF.Mixin({
+ dependencies: 'input',
+ composition: {
+ onCreated() {
+ const instance = Template.instance();
+ const component = instance.component;
+
+ // Get or set the checked state using jQuery's prop method
+ component.value = value => {
+ const isGet = _.isUndefined(value);
+ if (isGet) {
+ return component.parseData(component.$element.is(':checked'));
+ }
+
+ component.$element.prop('checked', value);
+ };
+ }
+ }
+});
diff --git a/Packages/ohif-core/client/components/base/mixins/form.js b/Packages/ohif-core/client/components/base/mixins/form.js
index 2e04a6f50..ab9bfbeb0 100644
--- a/Packages/ohif-core/client/components/base/mixins/form.js
+++ b/Packages/ohif-core/client/components/base/mixins/form.js
@@ -1,5 +1,8 @@
import { OHIF } from 'meteor/ohif:core';
import { Template } from 'meteor/templating';
+import { Tracker } from 'meteor/tracker';
+import { _ } from 'meteor/underscore';
+import { $ } from 'meteor/jquery';
/*
* form: controls a form and its registered inputs
@@ -11,40 +14,83 @@ OHIF.mixins.form = new OHIF.Mixin({
const instance = Template.instance();
const component = instance.component;
- // Define the form's data schema
- const schema = instance.data.schema;
- component.schema = schema && schema.newContext();
+ // Set the form identifier flag
+ component.isForm = true;
- // Check if the form data is valid in its schema
+ component.validationObserver = new Tracker.Dependency();
+
+ // Reset the pathKey
+ instance.data.pathKey = '';
+
+ // Debound the observer call to prevent tons of re-rendering
+ component.validationRan = _.debounce(() => {
+ // Enable reactivity by changing a Tracker.Dependency observer
+ component.validationObserver.changed();
+ }, 200);
+
+ // Change the validation function to focus the fields with error
+ const validateSelf = component.validate;
component.validate = () => {
- // Assume validation result as true
- let result = true;
+ // Call the original validation function
+ validateSelf();
- // Return true if there's no data schema defined
- if (!component.schema) {
- return result;
+ // Focus the first error field if some validation failed
+ if (component.schema && component.schema._invalidKeys.length) {
+ instance.$('.state-error :input:first').focus();
}
-
- // Iterate over each registered form item and validate it
- component.registeredItems.forEach(child => {
- const key = child.templateInstance.data.key;
-
- // Change result to false if any form item is invalid
- if (key && !child.validate()) {
- result = false;
- }
- });
-
- // Return the validation result
- return result;
};
},
+
onRendered() {
const instance = Template.instance();
const component = instance.component;
// Set the component main and style elements
component.$style = component.$element = instance.$('form:first');
+ },
+
+ events: {
+ 'click .validation-error-container a'(event, instance) {
+ // Get the target key
+ const targetKey = $(event.currentTarget).attr('data-target');
+
+ // Focus the first input inside the element with error state
+ instance.$(`.state-error[data-key="${targetKey}"] :input:first`).focus();
+ }
+ },
+
+ helpers: {
+ validationErrors() {
+ const instance = Template.instance();
+ const component = instance.component;
+
+ // Create a dependency on child components validation
+ component.validationObserver.depend();
+
+ // Stop here if no schema was defined for the form
+ if (!component.schema) {
+ return;
+ }
+
+ // Check if there were some validation errors
+ if (component.schema._invalidKeys.length) {
+ const result = [];
+
+ // Iterate over each validation error and add to result
+ component.schema._invalidKeys.forEach(item => {
+ const label = component.schema._schema[item.name].label;
+ let message = component.schema.keyErrorMessage(item.name);
+ message = message.replace(label, `
${label}`);
+ result.push({
+ key: item.name,
+ message: Spacebars.SafeString(message)
+ });
+ });
+
+ // Return the resulting validation errors
+ return result;
+ }
+ }
}
}
});
diff --git a/Packages/ohif-core/client/components/base/mixins/formItem.js b/Packages/ohif-core/client/components/base/mixins/formItem.js
index fd1f4c76e..88b7c4ae8 100644
--- a/Packages/ohif-core/client/components/base/mixins/formItem.js
+++ b/Packages/ohif-core/client/components/base/mixins/formItem.js
@@ -1,6 +1,7 @@
import { OHIF } from 'meteor/ohif:core';
import { Template } from 'meteor/templating';
-import { Tracker } from "meteor/tracker";
+import { Tracker } from 'meteor/tracker';
+import { Meteor } from 'meteor/meteor';
import { _ } from 'meteor/underscore';
import { $ } from 'meteor/jquery';
@@ -31,7 +32,7 @@ OHIF.mixins.formItem = new OHIF.Mixin({
component.value = value => {
const isGet = _.isUndefined(value);
if (isGet) {
- return component.$element.val();
+ return component.parseData(component.$element.val());
}
component.$element.val(value).trigger('change');
@@ -53,6 +54,19 @@ OHIF.mixins.formItem = new OHIF.Mixin({
component.$wrapper[method]();
};
+ // Check if the focus is inside this element
+ component.hasFocus = () => {
+ // Get the focused element
+ const focused = $(':focus')[0];
+
+ // Check if the focused element is inside the component
+ const contains = $.contains(component.$wrapper[0], focused);
+ const isEqual = component.$wrapper[0] === focused;
+
+ // Return true if he component has the focus
+ return contains || isEqual;
+ };
+
// Add or remove a state from the component
component.state = (state, flag) => {
component.$wrapper.toggleClass(`state-${state}`, !!flag);
@@ -65,24 +79,77 @@ OHIF.mixins.formItem = new OHIF.Mixin({
// Set or remove the error message
if (errorMessage) {
- component.$element.trigger('errorin');
component.$wrapper.attr('data-error', errorMessage);
} else {
- component.$element.trigger('errorout');
component.$wrapper.removeAttr('data-error', errorMessage);
}
};
+ // Toggle the tooltip over the component
+ component.toggleTooltip = (isShow, message) => {
+ if (isShow && message) {
+ // Stop here if the tooltip is already created
+ if (component.$wrapper.next('.tooltip').length) {
+ return;
+ }
+
+ // Create the tooltip
+ component.$wrapper.tooltip({
+ trigger: 'manual',
+ title: message
+ }).tooltip('show');
+ } else {
+ // Destroy the tooltip
+ component.$wrapper.tooltip('destroy');
+ }
+ };
+
+ // Toggle a state message as a tooltip over the component
+ component.toggleMessage = isShow => {
+ // Check if the action is to hide
+ if (!isShow) {
+ Meteor.setTimeout(() => {
+ // Check if the component has the focus
+ if (component.hasFocus()) {
+ // Prevent the tooltip from being hidden
+ return;
+ }
+
+ // Hide the tooltip
+ component.toggleTooltip(false);
+ }, 100);
+ return;
+ }
+
+ // Check for error state and message
+ const errorMessage = component.$wrapper.attr('data-error');
+ if (errorMessage) {
+ // Show the tooltip with the error message
+ component.toggleTooltip(true, errorMessage);
+ }
+ },
+
+ // Search for the parent form component
+ component.getForm = () => {
+ let currentComponent = component;
+ while (currentComponent) {
+ currentComponent = currentComponent.parent;
+ if (currentComponent && currentComponent.isForm) {
+ return currentComponent;
+ }
+ }
+ };
+
// Check if the component value is valid in its form's schema
component.validate = () => {
// Get the component's form
- const form = component.parent;
+ const form = component.getForm();
// Get the form's data schema
const schema = form && form.schema;
// Get the current component's key
- const key = instance.data.key;
+ const key = instance.data.pathKey;
// Return true if validation is not needed
if (!key || !schema || !component.$wrapper.is(':visible')) {
@@ -90,12 +157,18 @@ OHIF.mixins.formItem = new OHIF.Mixin({
}
// Create the data document for validation
- const document = {
+ const document = OHIF.blaze.getNestedObject({
[key]: component.value()
- };
+ });
+
+ // Get the validation result
+ const validationResult = schema.validateOne(document, key);
+
+ // Notify the form that the validation ran
+ form.validationRan();
// Check if the document validation failed
- if (!schema.validateOne(document, key)) {
+ if (!validationResult) {
// Set the component in error state and display the message
component.error(schema.keyErrorMessage(key));
@@ -125,6 +198,9 @@ OHIF.mixins.formItem = new OHIF.Mixin({
// Set the most outer wrapper element
component.$wrapper = instance.wrapper.$('*').first();
+
+ // Add the pathKey to the wrapper element
+ component.$wrapper.attr('data-key', instance.data.pathKey);
},
onDestroyed() {
@@ -143,24 +219,55 @@ OHIF.mixins.formItem = new OHIF.Mixin({
component.$style = component.$element;
}
- // Set the component in jQuery data after all mixins are rendered
+ // Set the component in element and wrapper jQuery data
component.$element.data('component', component);
+ component.$wrapper.data('component', component);
},
events: {
- // Enable reactivity by changing a Tracker.Dependency observer
+ // Handle the change event for the component
change(event, instance) {
- instance.component.changeObserver.changed();
+ const component = instance.component;
+
+ // Prevent execution on upper components
+ if (event.currentTarget === component.$element[0]) {
+ // Enable reactivity by changing a Tracker.Dependency observer
+ component.changeObserver.changed();
+
+ // Revalidate the component
+ component.validate();
+ }
},
- // TODO: [design] remove log, show error box/hint over the wrapper
- errorin(event, instance) {
- console.log('ERROR when validating component', instance.component);
+ focus(event, instance) {
+ const component = instance.component;
+
+ // Stop here if it is an group
+ if (component.isGroup || component.isCustomFocus) {
+ return;
+ }
+
+ // Prevent event bubbling
+ event.stopPropagation();
+
+ // Check for state messages and show it
+ component.toggleMessage(true);
},
- // TODO: [design] hide error box/hint
- errorout(event, instance) {
+ blur(event, instance) {
+ const component = instance.component;
+
+ // Stop here if it is an group
+ if (component.isGroup || component.isCustomFocus) {
+ return;
+ }
+
+ // Prevent event bubbling
+ event.stopPropagation();
+
+ // Hide state messages
+ component.toggleMessage(false);
}
}
diff --git a/Packages/ohif-core/client/components/base/mixins/group.js b/Packages/ohif-core/client/components/base/mixins/group.js
index 4e212cd2c..c2e87a981 100644
--- a/Packages/ohif-core/client/components/base/mixins/group.js
+++ b/Packages/ohif-core/client/components/base/mixins/group.js
@@ -12,29 +12,124 @@ OHIF.mixins.group = new OHIF.Mixin({
const instance = Template.instance();
const component = instance.component;
+ // Set the group identifier flag
+ component.isGroup = true;
+
+ // Run this computation every time the schema property is changed
+ instance.autorun(() => {
+ let schema = instance.data.schema;
+
+ // Check if the schema is reactive
+ if (schema instanceof ReactiveVar) {
+ // Register a dependency on schema property
+ schema = schema.get();
+ }
+
+ // Set the form's data schema
+ component.schema = schema && schema.newContext();
+ });
+
// Get or set the child components values
component.value = value => {
const isGet = _.isUndefined(value);
+ const isArray = instance.data.arrayValues;
+
+ // Create the result data as array or object
+ const result = isArray ? [] : {};
+
+ // Get the group current value and return it
if (isGet) {
- const result = {};
+ // Iterate over each registered item and extract its value
component.registeredItems.forEach(child => {
- const key = child.templateInstance.data.key;
- if (key) {
- result[key] = child.value();
+ // Check if it is an array or an object group
+ if (isArray) {
+ // Push the item value to the result array
+ result.push(child.value());
+ } else {
+ // Get the item key
+ const key = child.templateInstance.data.key;
+
+ //Check if a key is set for the item
+ if (key) {
+ // Add the item value to the result object
+ result[key] = child.value();
+ }
}
});
+
+ // Return the resulting data as array or object
return result;
}
- const groupValue = typeof value === 'object' ? value : {};
+ // Get the group current value
+ const groupValue = typeof value === 'object' ? value : result;
+
+ // Stop here if there is no value defined for this group
+ if (!groupValue) {
+ return;
+ }
+
+ // Iterate over each registered item and set its value
+ let i = 0;
component.registeredItems.forEach(child => {
- const key = child.templateInstance.data.key;
+ const key = isArray ? i : child.templateInstance.data.key;
const childValue = _.isUndefined(groupValue[key]) ? null : groupValue[key];
child.value(childValue);
+ i++;
});
+
+ // Trigger the change event after setting the new value
component.$element.trigger('change');
};
+ // Get a registered item in form by its key
+ component.item = itemKey => {
+ let found;
+
+ // Iterate over each registered form item
+ component.registeredItems.forEach(child => {
+ const key = child.templateInstance.data.key;
+
+ // Change the found item if current key is the same as given
+ if (key === itemKey) {
+ found = child;
+ }
+ });
+
+ // Return the found item or undefined if it was not found
+ return found;
+ };
+
+ // Check if the form data is valid in its schema
+ const validateSelf = component.validate;
+ component.validate = () => {
+ // Assume validation result as true
+ let result = true;
+
+ // Return true if there's no data schema defined
+ if (component.isForm && !component.schema) {
+ return result;
+ }
+
+ // Validate the component itself if it has a key
+ if (instance.data.pathKey && !validateSelf()) {
+ result = false;
+ }
+
+ // Iterate over each registered form item and validate it
+ component.registeredItems.forEach(child => {
+ const key = child.templateInstance.data.key;
+
+ // Change result to false if any form item is invalid
+ if ((key || instance.data.arrayValues) && !child.validate()) {
+ result = false;
+ }
+ });
+
+ // Return the validation result
+ return result;
+ };
+
// Disable or enable the component
component.disable = isDisable => {
component.registeredItems.forEach(child => child.disable(isDisable));
diff --git a/Packages/ohif-core/client/components/base/mixins/groupRadio.js b/Packages/ohif-core/client/components/base/mixins/groupRadio.js
index ecedc5fd2..c366d75ce 100644
--- a/Packages/ohif-core/client/components/base/mixins/groupRadio.js
+++ b/Packages/ohif-core/client/components/base/mixins/groupRadio.js
@@ -21,7 +21,7 @@ OHIF.mixins.groupRadio = new OHIF.Mixin({
component.registeredItems.forEach(child => elements.push(child.$element[0]));
const $elements = $(elements);
if (isGet) {
- return $elements.filter(':checked').val();
+ return component.parseData($elements.filter(':checked').val());
}
$elements.filter(`[value='${value}']`).prop('checked', true).trigger('change');
diff --git a/Packages/ohif-core/client/components/base/mixins/schemaData.js b/Packages/ohif-core/client/components/base/mixins/schemaData.js
index bb6cacc5b..cf50265c2 100644
--- a/Packages/ohif-core/client/components/base/mixins/schemaData.js
+++ b/Packages/ohif-core/client/components/base/mixins/schemaData.js
@@ -7,7 +7,13 @@ import { _ } from 'meteor/underscore';
// Helper function to get the component's current schema
const getCurrentSchema = (parentComponent, key) => {
// Get the parent component schema
- const schema = parentComponent && parentComponent.schema;
+ let schema = parentComponent && parentComponent.schema;
+
+ // Try to get the form schema if it was not found
+ if (parentComponent && !schema) {
+ const form = parentComponent.getForm();
+ schema = form && form.schema;
+ }
// Stop here if there's no key or schema defined
if (!key || !schema) {
@@ -17,6 +23,11 @@ const getCurrentSchema = (parentComponent, key) => {
// Get the current schema data using component's key
const currentSchema = _.clone(schema._schema[key]);
+ // Stop here if no schema was found for the given key
+ if (!currentSchema) {
+ return;
+ }
+
// Merge the sub-schema properties if it's an array
if (Array.isArray(currentSchema.type())) {
_.extend(currentSchema, schema._schema[key + '.$']);
@@ -40,8 +51,21 @@ OHIF.mixins.schemaData = new OHIF.Mixin({
// Get the parent component
const parent = OHIF.blaze.getParentComponent(Blaze.currentView);
+ // Get he parent component key
+ const parentKey = parent && parent.templateInstance.data.pathKey;
+
+ // Check if the parent is an array group
+ const isParentArray = parent && parent.templateInstance.data.arrayValues;
+
+ // Set the path key for this component
+ data.pathKey = data.key || (isParentArray ? '$' : '');
+ if (data.pathKey && typeof parentKey === 'string') {
+ const prefix = parentKey ? `${parentKey}.` : '';
+ data.pathKey = `${prefix}${data.pathKey}`;
+ }
+
// Get the current schema data using component's key
- const currentSchema = getCurrentSchema(parent, data.key);
+ const currentSchema = getCurrentSchema(parent, data.pathKey);
// Stop here if there's no schema data for current key
if (!currentSchema) {
@@ -53,6 +77,11 @@ OHIF.mixins.schemaData = new OHIF.Mixin({
data.label = new ReactiveVar(currentSchema.label);
}
+ // Set the emptyOption data attribute if given on schema
+ if (currentSchema.emptyOption) {
+ data.emptyOption = currentSchema.emptyOption;
+ }
+
// Fill the items if it's an array schema
if (!data.items && Array.isArray(currentSchema.allowedValues)) {
// Initialize the items array
@@ -76,12 +105,41 @@ OHIF.mixins.schemaData = new OHIF.Mixin({
}
},
+ onCreated() {
+ const instance = Template.instance();
+ const component = instance.component;
+
+ // Create a data parser according to current schema key
+ component.parseData = value => {
+ // Get the current schema data using component's key
+ const currentSchema = getCurrentSchema(component.parent, instance.data.pathKey);
+
+ // Stop here if there's no schema data for current key
+ if (!currentSchema) {
+ return;
+ }
+
+ // Check if the schema is a Number
+ if (currentSchema.type === Number) {
+ return parseFloat(value);
+ }
+
+ // Check if the schema is a Boolean
+ if (currentSchema.type === Boolean) {
+ return !!value;
+ }
+
+ // Return the original value if none of the checks matched
+ return value;
+ };
+ },
+
onMixins() {
const instance = Template.instance();
const component = instance.component;
// Get the current schema data using component's key
- const currentSchema = getCurrentSchema(component.parent, instance.data.key);
+ const currentSchema = getCurrentSchema(component.parent, instance.data.pathKey);
// Stop here if there's no schema data for current key
if (!currentSchema) {
diff --git a/Packages/ohif-core/client/components/base/mixins/select2.js b/Packages/ohif-core/client/components/base/mixins/select2.js
index 7fab646d1..987495dd1 100644
--- a/Packages/ohif-core/client/components/base/mixins/select2.js
+++ b/Packages/ohif-core/client/components/base/mixins/select2.js
@@ -8,6 +8,46 @@ import { $ } from 'meteor/jquery';
OHIF.mixins.select2 = new OHIF.Mixin({
dependencies: 'select',
composition: {
+ onCreated() {
+ const instance = Template.instance();
+
+ // Set the custom focus flag
+ instance.component.isCustomFocus = true;
+
+ // Check if this select will include a placeholder
+ const placeholder = instance.data.options && instance.data.options.placeholder;
+ if (placeholder) {
+ // Get the option items
+ let items = instance.data.items;
+
+ // Check if the items are reactive and get them if true
+ const isReactive = items instanceof ReactiveVar;
+ if (isReactive) {
+ items = items.get();
+ }
+
+ // Check if there is already an empty option on items list
+ const query = {
+ value: ''
+ };
+ if (!_.findWhere(items, query)) {
+ // Clone the current items
+ const newItems = _.clone(items) || [];
+ newItems.unshift({
+ label: placeholder,
+ value: ''
+ });
+
+ // Set the new items list including the empty option
+ if (isReactive) {
+ instance.data.items.set(newItems);
+ } else {
+ instance.data.items = newItems;
+ }
+ }
+ }
+ },
+
onRendered() {
const instance = Template.instance();
const component = instance.component;
@@ -17,6 +57,22 @@ OHIF.mixins.select2 = new OHIF.Mixin({
// Store the select2 instance to allow its further destruction
component.select2Instance = component.$element.data('select2');
+
+ // Get the focusable elements
+ const elements = [];
+ elements.push(component.$element[0]);
+ elements.push(component.$element.nextAll('.select2:first').find('.select2-selection')[0]);
+
+ // Attach focus and blur handlers to focusable elements
+ $(elements).on('focus', event => {
+ event.stopPropagation();
+ // Show the state message on elements focus
+ component.toggleMessage(true);
+ }).on('blur', event => {
+ event.stopPropagation();
+ // Hide the state message on elements blur
+ component.toggleMessage(false);
+ });
},
onDestroyed() {
@@ -25,14 +81,6 @@ OHIF.mixins.select2 = new OHIF.Mixin({
// Destroy the select2 instance to remove unwanted DOM elements
component.select2Instance.destroy();
- },
-
- events: {
- 'focus .select2-hidden-accessible'(event, instance) {
- // Redirect the focus to select2 focus control in case of hidden
- // accessible being focused (e.g. clicking on outer label)
- $(event.currentTarget).nextAll('.select2:first').find('.select2-selection').focus();
- }
}
}
});
diff --git a/Packages/ohif-core/client/components/base/mixins/selectTree.js b/Packages/ohif-core/client/components/base/mixins/selectTree.js
index 2e8320964..319800632 100644
--- a/Packages/ohif-core/client/components/base/mixins/selectTree.js
+++ b/Packages/ohif-core/client/components/base/mixins/selectTree.js
@@ -30,7 +30,7 @@ OHIF.mixins.selectTree = new OHIF.Mixin({
// Return the current value
if (isGet) {
- return rootInstance.currentValue;
+ return component.parseData(rootInstance.currentValue);
}
// Change the current value
diff --git a/Packages/ohif-core/client/components/base/templates/form.html b/Packages/ohif-core/client/components/base/templates/form.html
index b198b345b..e5a4e0e4a 100644
--- a/Packages/ohif-core/client/components/base/templates/form.html
+++ b/Packages/ohif-core/client/components/base/templates/form.html
@@ -11,6 +11,13 @@
target="{{this.target}}"
{{this.tagAttributes}}
>
+ {{#if validationErrors}}
+
+ {{/if}}
{{>UI.contentBlock}}
diff --git a/Packages/ohif-core/client/components/base/templates/select.html b/Packages/ohif-core/client/components/base/templates/select.html
index 99536a06a..938b3d9be 100644
--- a/Packages/ohif-core/client/components/base/templates/select.html
+++ b/Packages/ohif-core/client/components/base/templates/select.html
@@ -4,6 +4,7 @@
class="{{this.class}}"
name="{{this.name}}"
multiple="{{#if this.multiple}}multiple{{/if}}"
+ disabled="{{#if this.disabled}}disabled{{/if}}"
{{this.tagAttributes}}
>
{{>UI.contentBlock}}
diff --git a/Packages/ohif-core/client/components/bootstrap/index.js b/Packages/ohif-core/client/components/bootstrap/index.js
index 6bc4a245e..2baa5508b 100644
--- a/Packages/ohif-core/client/components/bootstrap/index.js
+++ b/Packages/ohif-core/client/components/bootstrap/index.js
@@ -1,6 +1,8 @@
import './form/form.html';
import './form/group.html';
+import './input/checkbox.html';
+import './input/hidden.html';
import './input/groupRadio.html';
import './input/radio.html';
import './input/select.html';
diff --git a/Packages/ohif-core/client/components/bootstrap/input/checkbox.html b/Packages/ohif-core/client/components/bootstrap/input/checkbox.html
new file mode 100644
index 000000000..038312206
--- /dev/null
+++ b/Packages/ohif-core/client/components/bootstrap/input/checkbox.html
@@ -0,0 +1,15 @@
+
+ {{#baseComponent (extend this
+ base='baseInput'
+ type='checkbox'
+ mixins=(concat 'checkbox ' this.mixins)
+ labelAfter=(valueIf (isUndefined this.labelAfter) true this.labelAfter)
+ labelClass=(concat 'checkboxLabel ' this.labelClass)
+ wrappers=(concat ''
+ (valueIf reactive this.label 'wrapperLabel ' '')
+ this.wrappers
+ )
+ )}}
+ {{>UI.contentBlock}}
+ {{/baseComponent}}
+
diff --git a/Packages/ohif-core/client/components/bootstrap/input/hidden.html b/Packages/ohif-core/client/components/bootstrap/input/hidden.html
new file mode 100644
index 000000000..01ec712ea
--- /dev/null
+++ b/Packages/ohif-core/client/components/bootstrap/input/hidden.html
@@ -0,0 +1,7 @@
+
+ {{>baseComponent (extend this
+ base='baseInput'
+ type='hidden'
+ mixins=(concat 'input ' this.mixins)
+ )}}
+
diff --git a/Packages/ohif-core/client/components/bootstrap/input/radio.html b/Packages/ohif-core/client/components/bootstrap/input/radio.html
index 4e72172df..d2377667e 100644
--- a/Packages/ohif-core/client/components/bootstrap/input/radio.html
+++ b/Packages/ohif-core/client/components/bootstrap/input/radio.html
@@ -4,7 +4,7 @@
type='radio'
mixins=(concat 'input ' this.mixins)
labelAfter=(valueIf (isUndefined this.labelAfter) true this.labelAfter)
- labelClass=(concat 'checkboxLabel ' this.labelClass)
+ labelClass=(concat 'radioLabel ' this.labelClass)
wrappers=(concat ''
(valueIf reactive this.label 'wrapperLabel ' '')
this.wrappers
diff --git a/Packages/ohif-core/client/components/bootstrap/input/selectTree.html b/Packages/ohif-core/client/components/bootstrap/input/selectTree.html
index fe1f10849..f0cf042b3 100644
--- a/Packages/ohif-core/client/components/bootstrap/input/selectTree.html
+++ b/Packages/ohif-core/client/components/bootstrap/input/selectTree.html
@@ -11,17 +11,19 @@
{{#let currentNode=this.currentNode.get}}
{{#if (and (not this.root) (ne this.search false))}}
- {{>inputText
+ {{#inputText
label=this.label
labelClass='tree-search'
placeholder=(choose this.searchPlaceholder 'Search')
}}
+
+ {{/inputText}}
{{/if}}
{{#if this.root}}
{{>selectTreeBreadcrumb component=this.component}}
{{/if}}
-
- {{#if (and (not this.root) this.storageKey)}}
- {{>selectTreeCommon (clone this component=this.component)}}
+ {{#if (and (not this.root) (or this.storageKey this.commonItems))}}
+ {{>selectTreeCommon (clone this component=this.component treeInstance=instance)}}
{{/if}}
{{/group}}
diff --git a/Packages/ohif-core/client/components/bootstrap/input/selectTree.js b/Packages/ohif-core/client/components/bootstrap/input/selectTree.js
index 9fa7a776c..2a1bb6741 100644
--- a/Packages/ohif-core/client/components/bootstrap/input/selectTree.js
+++ b/Packages/ohif-core/client/components/bootstrap/input/selectTree.js
@@ -11,6 +11,45 @@ import transition from 'meteor/ohif:core/client/lib/third-party/transition-to-fr
Template.selectTree.onCreated(() => {
const instance = Template.instance();
+ // Return the common items
+ instance.getCommonItems = () => {
+ const instance = Template.instance();
+
+ // Return the common items if given
+ if (instance.data.commonItems) {
+ return instance.data.commonItems;
+ }
+
+ // Get all the tree leaves
+ const leaves = instance.data.component.getLeaves();
+
+ // Generate an object with encoded keys from the tree leaves
+ leavesObject = {};
+ _.each(leaves, leaf => {
+ leavesObject[OHIF.string.encodeId(leaf.value)] = leaf;
+ });
+
+ // Get the current items ranking
+ const ranking = OHIF.user.getData(instance.data.storageKey);
+
+ // Sort the items based on how many times each one was used
+ const sorted = [];
+ _.each(ranking, (count, key) => sorted.push([key, count]));
+ sorted.sort((a, b) => b[1] - a[1]);
+
+ // Create the result and push every item respecting the ranking order
+ const result = [];
+ _.each(sorted, item => {
+ const current = leavesObject[item[0]];
+ if (current) {
+ result.push(current);
+ }
+ });
+
+ // Return the resulting array
+ return result;
+ };
+
// Create a reactive variable to control the search
instance.searchTerm = new ReactiveVar('');
});
@@ -25,7 +64,10 @@ Template.selectTree.onRendered(() => {
instance.component = component;
// Set the margin to display the common section
- $treeRoot.children('.tree-content').css('margin-right', $treeRoot.width());
+ const isTreeColumns = instance.data.treeColumns;
+ const marginProperty = isTreeColumns ? 'margin-left' : 'margin-right';
+ const marginWidth = isTreeColumns ? $treeRoot.width() / 2 : $treeRoot.width();
+ $treeRoot.children('.tree-content').css(marginProperty, marginWidth);
// Make the component respect the window boundaries
$treeRoot.bounded();
@@ -144,6 +186,18 @@ Template.selectTree.events({
$treeRoot.addClass('interacted');
},
+ 'keydown .tree-search input'(event, instance) {
+ // Get the search term
+ const searchTerm = $(event.currentTarget).val().trim();
+
+ const $labels = instance.$('.tree-inputs:first>label');
+
+ // Select the label if ENTER was pressed and there is only one result
+ if (searchTerm.length && $labels.length === 1 && event.which === 13) {
+ $labels.find('input').click();
+ }
+ },
+
'change .select-tree:first>.tree-content>.tree-options>.tree-inputs>label>input'(event, instance) {
const component = instance.component;
const $target = $(event.currentTarget);
@@ -235,27 +289,6 @@ Template.selectTree.events({
currentInstance = currentInstance.component.parent.templateInstance;
}
}
- },
-
- 'click .select-tree-common label'(event, instance) {
- // Get the clicked label
- const $target = $(event.currentTarget);
-
- // Build the input selector based on the label target
- const inputSelector = '#' + $target.attr('for');
-
- // Check if the input is not rendered
- if (!$(inputSelector).length) {
- // Change the search terms with the clicked label string
-
- instance.$('.tree-search input').val($target.text()).trigger('input');
- // Wait for options rerendering
-
- Tracker.afterFlush(() => {
- // Wait for components initialization
- Meteor.defer(() => $(inputSelector).click());
- });
- }
}
});
@@ -276,6 +309,23 @@ Template.selectTree.helpers({
// Filter only the tree leaves
items = _.filter(items, item => !item.items);
+ } else if (instance.data.hideCommon) {
+ // Get the values of common items
+ const commonValues = _.pluck(instance.getCommonItems(), 'value');
+
+ // Filter only the items that are not common
+ items = _.filter(items, item => !_.contains(commonValues, item.value));
+ }
+
+ // Return the items sorted for tree columns
+ if (instance.data.treeColumns) {
+ const begin = items.splice(0, Math.ceil(items.length / 2));
+ const sortedItems = [];
+ _.each(begin, (item, index) => {
+ sortedItems.push(item);
+ items[index] && sortedItems.push(items[index]);
+ });
+ items = sortedItems;
}
// Return the tree items
diff --git a/Packages/ohif-core/client/components/bootstrap/input/selectTreeCommon.js b/Packages/ohif-core/client/components/bootstrap/input/selectTreeCommon.js
index b2f7feee4..534aec32a 100644
--- a/Packages/ohif-core/client/components/bootstrap/input/selectTreeCommon.js
+++ b/Packages/ohif-core/client/components/bootstrap/input/selectTreeCommon.js
@@ -2,38 +2,35 @@ import { OHIF } from 'meteor/ohif:core';
import { Template } from 'meteor/templating';
import { _ } from 'meteor/underscore';
-Template.selectTreeCommon.helpers({
- // Get the common items ordered by use history
- items() {
- const instance = Template.instance();
+Template.selectTreeCommon.events({
+ 'click .select-tree-common label'(event, instance) {
+ // Get the clicked label
+ const $target = $(event.currentTarget);
- // Get all the tree leaves
- const leaves = instance.data.component.getLeaves();
+ // Build the input selector based on the label target
+ const inputSelector = '#' + $target.attr('for');
- // Generate an object with encoded keys from the tree leaves
- leavesObject = {};
- _.each(leaves, leaf => {
- leavesObject[OHIF.string.encodeId(leaf.value)] = leaf;
- });
+ // Get the tree instance
+ const treeInstance = instance.data.treeInstance;
- // Get the current items ranking
- const ranking = OHIF.user.getData(instance.data.storageKey);
+ // Check if the input is not rendered
+ if (!$(inputSelector).length) {
+ // Change the search terms with the clicked label string
- // Sort the items based on how many times each one was used
- const sorted = [];
- _.each(ranking, (count, key) => sorted.push([key, count]));
- sorted.sort((a, b) => b[1] - a[1]);
+ treeInstance.$('.tree-search input').val($target.text()).trigger('input');
+ // Wait for options rerendering
- // Create the result and push every item respecting the ranking order
- const result = [];
- _.each(sorted, item => {
- const current = leavesObject[item[0]];
- if (current) {
- result.push(current);
- }
- });
-
- // Return the resulting array
- return result;
+ Tracker.afterFlush(() => {
+ // Wait for components initialization
+ Meteor.defer(() => $(inputSelector).click());
+ });
+ }
+ }
+});
+
+Template.selectTreeCommon.helpers({
+ // Get the common items
+ items() {
+ return Template.instance().data.treeInstance.getCommonItems();
}
});
diff --git a/Packages/ohif-core/client/components/playground/playground.html b/Packages/ohif-core/client/components/playground/playground.html
index 07b5941a6..b72f3c364 100644
--- a/Packages/ohif-core/client/components/playground/playground.html
+++ b/Packages/ohif-core/client/components/playground/playground.html
@@ -1,6 +1,6 @@
- {{>measureFlow}}
+ {{>measureFlow treeColumns=true hideCommon=true}}
+ {{> worklistPagination }}
+
{{#if session "showLoadingText"}}
{{>loadingText}}
{{ else }}
diff --git a/Packages/worklist/client/components/worklistResult/worklistResult.js b/Packages/worklist/client/components/worklistResult/worklistResult.js
index 5edb2c79c..3f8301ed9 100644
--- a/Packages/worklist/client/components/worklistResult/worklistResult.js
+++ b/Packages/worklist/client/components/worklistResult/worklistResult.js
@@ -6,19 +6,37 @@ Template.worklistResult.helpers({
* by Patient name and Study Date in Ascending order.
*/
studies() {
- const sortOption = Session.get('sortOption');
- if (sortOption) {
- return WorklistStudies.find({}, {
- sort: sortOption
- });
+ const instance = Template.instance();
+ let studies;
+ let sortOption = {
+ patientName: 1,
+ studyDate: 1
+ };
+
+ // Update sort option if session is defined
+ if (Session.get('sortOption')) {
+ sortOption = Session.get('sortOption');
}
- return WorklistStudies.find({}, {
- sort: {
- patientName: 1,
- studyDate: 1
- }
- });
+ // Pagination parameters
+ const rowsPerPage = instance.rowsPerPage.get();
+ const currentPage = instance.currentPage.get();
+ const offset = rowsPerPage * currentPage;
+ const limit = offset + rowsPerPage;
+
+ studies = WorklistStudies.find({}, {
+ sort: sortOption
+ }).fetch();
+
+ if (!studies) {
+ return;
+ }
+
+ // Update record count
+ instance.recordCount.set(studies.length);
+
+ // Limit studies
+ return studies.slice(offset, limit);
},
numberOfStudies() {
@@ -149,7 +167,7 @@ function search() {
(convertStringToStudyDate(study.studyDate) <= new Date(studyDateTo).setHours(0, 0, 0, 0) || !studyDateTo || studyDateTo === '')) {
// Convert numberOfStudyRelatedInstance string into integer
- study.numberOfStudyRelatedInstances = parseInt(study.numberOfStudyRelatedInstances);
+ study.numberOfStudyRelatedInstances = !isNaN(study.numberOfStudyRelatedInstances) ? parseInt(study.numberOfStudyRelatedInstances) : 0;
// Insert any matching studies into the WorklistStudies Collection
WorklistStudies.insert(study);
@@ -163,6 +181,15 @@ Template.worklistResult.onCreated(() => {
instance.sortOption = new ReactiveVar();
instance.sortingColumns = new ReactiveDict();
+ // Pagination parameters
+
+ // Rows per page is 25 as default
+ instance.rowsPerPage = new ReactiveVar(25);
+
+ // Set currentPage indexed 0
+ instance.currentPage = new ReactiveVar(0);
+ instance.recordCount = new ReactiveVar();
+
// Set sortOption
const sortOptionSession = Session.get('sortOption');
if (sortOptionSession) {
diff --git a/Packages/worklist/client/components/worklistResult/worklistResult.styl b/Packages/worklist/client/components/worklistResult/worklistResult.styl
index 186ac3771..dab56222a 100644
--- a/Packages/worklist/client/components/worklistResult/worklistResult.styl
+++ b/Packages/worklist/client/components/worklistResult/worklistResult.styl
@@ -1,20 +1,19 @@
@import "{design}/app"
-$hoverColor = #2c363f
-$textPrimaryColor = white
-$textSecondaryColor = #91b9cd
+$tableHoverColor = #2c363f
+$tableTextPrimaryColor = white
+$tableTextSecondaryColor = #91b9cd
$inputBackgroundColor = #2c363f
$inputPlaceholderColor = lightgray
$studyListToolbarHeight = 75px
-$theadBackgroundColor = $uiGrayDarker
$tablePadding = 8%
$bodyCellHeight = 40px
.studyListToolbar
+ theme('background', '$uiGrayDarker')
height: $studyListToolbarHeight
- background: $uiGrayDarker
border-bottom: 2px solid black
padding: 0 30px
@@ -24,7 +23,7 @@ $bodyCellHeight = 40px
.header
font-size: 22px
font-weight: 300
- color: $textSecondaryColor
+ color: $tableTextSecondaryColor
padding: 0 10px
line-height: $studyListToolbarHeight
@@ -33,14 +32,14 @@ $bodyCellHeight = 40px
line-height: $studyListToolbarHeight
.studyCount
+ theme('color', '$uiSkyBlue')
font-size: 40px
font-weight: 100
- color: $uiSkyBlue
padding: 0 10px
line-height: $studyListToolbarHeight
.theadBackground
- background-color: $theadBackgroundColor
+ theme('background-color', '$uiGrayDarker')
width: 100%
height: 122px
position: absolute
@@ -54,18 +53,18 @@ $bodyCellHeight = 40px
z-index: 2
.loadingTextDiv
- color: $textSecondaryColor
+ color: $tableTextSecondaryColor
font-size: 30px
.notFound
- color: $textSecondaryColor
+ color: $tableTextSecondaryColor
font-size: 30px
font-weight: 200
text-align: center
table#tblStudyList
thead
- background-color: $theadBackgroundColor
+ theme('background-color', '$uiGrayDarker')
white-space: nowrap
tr
@@ -85,7 +84,7 @@ $bodyCellHeight = 40px
width: 100%
min-width: 95px
margin: 0 auto
- color: $textPrimaryColor
+ color: $tableTextPrimaryColor
font-weight: 400
padding: 20px
@@ -97,10 +96,10 @@ $bodyCellHeight = 40px
margin: 0 5px
&:hover
- color: $activeColor
+ theme('color', '$activeColor')
&.active, &:active
- color: $activeColor
+ theme('color', '$activeColor')
input.worklist-search
height: 34px
@@ -136,16 +135,15 @@ $bodyCellHeight = 40px
background-color: black
&:nth-child(even)
- background-color: $uiGrayDarker
+ theme('background-color', '$uiGrayDarker')
td
height: $bodyCellHeight
line-height: $bodyCellHeight
- color: $textPrimaryColor
+ color: $tableTextPrimaryColor
font-weight: 300
border-top: 1px solid #436270
white-space: nowrap
-
transition(all 0.1s ease)
&:first-child
@@ -155,15 +153,14 @@ $bodyCellHeight = 40px
padding-right: $tablePadding
&:hover, &:active, &.active
- background-color: $hoverColor
+ background-color: $tableHoverColor
color: white
td
// This selector is necessary to override bootstrap's 'table' class
border-top: 1px solid #436270
border-bottom: 1px solid #436270
- background-color: $hoverColor
-
+ background-color: $tableHoverColor
@media only screen and (max-width: 1000px)
$tablePaddingMediumScreen = 10px
@@ -188,4 +185,4 @@ $bodyCellHeight = 40px
th.accessionNumber, td.accessionNumber,
th.modalities, td.modalities,
th.numberOfStudyRelatedInstances, td.numberOfStudyRelatedInstances
- display: none
\ No newline at end of file
+ display: none
diff --git a/Packages/worklist/client/components/worklistToolbar/worklistToolbar.styl b/Packages/worklist/client/components/worklistToolbar/worklistToolbar.styl
index 825737701..990c37355 100644
--- a/Packages/worklist/client/components/worklistToolbar/worklistToolbar.styl
+++ b/Packages/worklist/client/components/worklistToolbar/worklistToolbar.styl
@@ -5,7 +5,7 @@
margin: 0 10px
label
- color: $textSecondaryColor
+ theme('color', '$textSecondaryColor')
font-weight: 400
cursor: pointer
@@ -13,10 +13,10 @@
pointer-events: none
&:hover
- color: $hoverColor
+ theme('color', '$hoverColor')
&:active
- color: $activeColor
+ theme('color', '$activeColor')
input
width: 0.1px;
diff --git a/Packages/worklist/client/lib/jquery.twbsPagination/jquery.twbsPagination.min.js b/Packages/worklist/client/lib/jquery.twbsPagination/jquery.twbsPagination.min.js
new file mode 100644
index 000000000..7cc71f9c4
--- /dev/null
+++ b/Packages/worklist/client/lib/jquery.twbsPagination/jquery.twbsPagination.min.js
@@ -0,0 +1,9 @@
+/*
+ * jQuery Bootstrap Pagination v1.3.1
+ * https://github.com/esimakin/twbs-pagination
+ *
+ * Copyright 2014-2015 Eugene Simakin
+ * Released under Apache 2.0 license
+ * http://apache.org/licenses/LICENSE-2.0.html
+ */
+!function(a,b,c,d){"use strict";var e=a.fn.twbsPagination,f=function(c,d){if(this.$element=a(c),this.options=a.extend({},a.fn.twbsPagination.defaults,d),this.options.startPage<1||this.options.startPage>this.options.totalPages)throw new Error("Start page option is incorrect");if(this.options.totalPages=parseInt(this.options.totalPages),isNaN(this.options.totalPages))throw new Error("Total pages option is not correct!");if(this.options.visiblePages=parseInt(this.options.visiblePages),isNaN(this.options.visiblePages))throw new Error("Visible pages option is not correct!");if(this.options.totalPages"),this.$listContainer.addClass(this.options.paginationClass),"UL"!==g&&this.$element.append(this.$listContainer),this.render(this.getPages(this.options.startPage)),this.setupEvents(),this.options.initiateStartPageClick&&this.$element.trigger("page",this.options.startPage),this};f.prototype={constructor:f,destroy:function(){return this.$element.empty(),this.$element.removeData("twbs-pagination"),this.$element.off("page"),this},show:function(a){if(1>a||a>this.options.totalPages)throw new Error("Page is incorrect.");return this.render(this.getPages(a)),this.setupEvents(),this.$element.trigger("page",a),this},buildListItems:function(a){var b=[];if(this.options.first&&b.push(this.buildItem("first",1)),this.options.prev){var c=a.currentPage>1?a.currentPage-1:this.options.loop?this.options.totalPages:1;b.push(this.buildItem("prev",c))}for(var d=0;d"),e=a(""),f=null;switch(b){case"page":f=c,d.addClass(this.options.pageClass);break;case"first":f=this.options.first,d.addClass(this.options.firstClass);break;case"prev":f=this.options.prev,d.addClass(this.options.prevClass);break;case"next":f=this.options.next,d.addClass(this.options.nextClass);break;case"last":f=this.options.last,d.addClass(this.options.lastClass)}return d.data("page",c),d.data("page-type",b),d.append(e.attr("href",this.makeHref(c)).html(f)),d},getPages:function(a){var b=[],c=Math.floor(this.options.visiblePages/2),d=a-c+1-this.options.visiblePages%2,e=a+c;0>=d&&(d=1,e=this.options.visiblePages),e>this.options.totalPages&&(d=this.options.totalPages-this.options.visiblePages+1,e=this.options.totalPages);for(var f=d;e>=f;)b.push(f),f++;return{currentPage:a,numeric:b}},render:function(b){var c=this;this.$listContainer.children().remove(),this.$listContainer.append(this.buildListItems(b)),this.$listContainer.children().each(function(){var d=a(this),e=d.data("page-type");switch(e){case"page":d.data("page")===b.currentPage&&d.addClass(c.options.activeClass);break;case"first":d.toggleClass(c.options.disabledClass,1===b.currentPage);break;case"last":d.toggleClass(c.options.disabledClass,b.currentPage===c.options.totalPages);break;case"prev":d.toggleClass(c.options.disabledClass,!c.options.loop&&1===b.currentPage);break;case"next":d.toggleClass(c.options.disabledClass,!c.options.loop&&b.currentPage===c.options.totalPages)}})},setupEvents:function(){var b=this;this.$listContainer.find("li").each(function(){var c=a(this);return c.off(),c.hasClass(b.options.disabledClass)||c.hasClass(b.options.activeClass)?void c.on("click",!1):void c.click(function(a){!b.options.href&&a.preventDefault(),b.show(parseInt(c.data("page")))})})},makeHref:function(a){return this.options.href?this.options.href.replace(this.options.hrefVariable,a):"#"}},a.fn.twbsPagination=function(b){var c,e=Array.prototype.slice.call(arguments,1),g=a(this),h=g.data("twbs-pagination"),i="object"==typeof b&&b;return h||g.data("twbs-pagination",h=new f(this,i)),"string"==typeof b&&(c=h[b].apply(h,e)),c===d?g:c},a.fn.twbsPagination.defaults={totalPages:0,startPage:1,visiblePages:5,initiateStartPageClick:!0,href:!1,hrefVariable:"{{number}}",first:"First",prev:"Previous",next:"Next",last:"Last",loop:!1,onPageClick:null,paginationClass:"pagination",nextClass:"next",prevClass:"prev",lastClass:"last",firstClass:"first",pageClass:"page",activeClass:"active",disabledClass:"disabled"},a.fn.twbsPagination.Constructor=f,a.fn.twbsPagination.noConflict=function(){return a.fn.twbsPagination=e,this}}(window.jQuery,window,document);
\ No newline at end of file
diff --git a/Packages/worklist/package.js b/Packages/worklist/package.js
index 520b5106e..c6245d51c 100644
--- a/Packages/worklist/package.js
+++ b/Packages/worklist/package.js
@@ -29,6 +29,7 @@ Package.onUse(function (api) {
api.use('dimseservice');
api.use('orthanc-remote');
api.use('viewerbase');
+ api.use('wadoproxy');
// TODO: Replace with NPM dependency
api.use('cornerstone'); // Only for HammerJS
@@ -69,6 +70,16 @@ Package.onUse(function (api) {
api.addFiles('client/components/progressDialog/progressDialog.html', 'client');
api.addFiles('client/components/progressDialog/progressDialog.styl', 'client');
api.addFiles('client/components/progressDialog/progressDialog.js', 'client');
+
+ api.addFiles('client/components/worklistPagination/worklistPagination.html', 'client');
+ api.addFiles('client/components/worklistPagination/worklistPagination.styl', 'client');
+ api.addFiles('client/components/worklistPagination/worklistPagination.js', 'client');
+
+ api.addFiles('client/components/viewSeriesDetailsModal/viewSeriesDetailsModal.html', 'client');
+
+ api.addFiles('client/components/seriesDetailsTable/seriesDetailsTable.html', 'client');
+ api.addFiles('client/components/seriesDetailsTable/seriesDetailsTable.styl', 'client');
+ api.addFiles('client/components/seriesDetailsTable/seriesDetailsTable.js', 'client');
// Client-side library functions
api.addFiles('client/lib/getStudyMetadata.js', 'client');
@@ -79,6 +90,7 @@ Package.onUse(function (api) {
api.addFiles('client/lib/worklist.js', 'client');
api.addFiles('client/lib/queryStudies.js', 'client');
api.addFiles('client/lib/importStudies.js', 'client');
+ api.addFiles('client/lib/jquery.twbsPagination/jquery.twbsPagination.min.js', 'client');
// Server-side functions
api.addFiles('server/publications.js', 'server');
diff --git a/Packages/worklist/server/services/dimse/retrieveMetadata.js b/Packages/worklist/server/services/dimse/retrieveMetadata.js
index 07b6ea8b4..44fd9c4b8 100755
--- a/Packages/worklist/server/services/dimse/retrieveMetadata.js
+++ b/Packages/worklist/server/services/dimse/retrieveMetadata.js
@@ -111,7 +111,7 @@ function resultDataToStudyMetadata(studyInstanceUid, resultData) {
// Retrieve the actual data over WADO-URI
var server = Meteor.settings.servers.dicomWeb[0];
- instanceSummary.wadouri = server.wadoUriRoot + '?requestType=WADO&studyUID=' + studyInstanceUid + '&seriesUID=' + seriesInstanceUid + '&objectUID=' + sopInstanceUid + "&contentType=application%2Fdicom";
+ instanceSummary.wadouri = WADOProxy.convertURL(server.wadoUriRoot + '?requestType=WADO&studyUID=' + studyInstanceUid + '&seriesUID=' + seriesInstanceUid + '&objectUID=' + sopInstanceUid + "&contentType=application%2Fdicom", server.requestOptions);
series.instances.push(instanceSummary);
});
diff --git a/Packages/worklist/server/services/wado/retrieveMetadata.js b/Packages/worklist/server/services/wado/retrieveMetadata.js
index 92405fbff..7658cba26 100644
--- a/Packages/worklist/server/services/wado/retrieveMetadata.js
+++ b/Packages/worklist/server/services/wado/retrieveMetadata.js
@@ -116,7 +116,7 @@ function resultDataToStudyMetadata(server, studyInstanceUid, resultData) {
};
if (server.imageRendering === 'wadouri') {
- instanceSummary.wadouri = server.wadoUriRoot + '?requestType=WADO&studyUID=' + studyInstanceUid + '&seriesUID=' + seriesInstanceUid + '&objectUID=' + sopInstanceUid + '&contentType=application%2Fdicom';
+ instanceSummary.wadouri = WADOProxy.convertURL(server.wadoUriRoot + '?requestType=WADO&studyUID=' + studyInstanceUid + '&seriesUID=' + seriesInstanceUid + '&objectUID=' + sopInstanceUid + '&contentType=application%2Fdicom', server.requestOptions);
} else {
instanceSummary.wadorsuri = server.wadoRoot + '/studies/' + studyInstanceUid + '/series/' + seriesInstanceUid + '/instances/' + sopInstanceUid + '/frames/1';
}
diff --git a/config/dcm4cheeDIMSE.json b/config/dcm4cheeDIMSE.json
index 4e9615ac9..450bf189a 100644
--- a/config/dcm4cheeDIMSE.json
+++ b/config/dcm4cheeDIMSE.json
@@ -4,7 +4,7 @@
{
"name": "DCM4CHEE",
"wadoUriRootNOTE": "either this uri is not correct for wado-uri or wado-uri is not configured on orthanc currently",
- "wadoUriRoot": "http://localhost:8043/dcm4chee-arc/aets/DCM4CHEE/wado",
+ "wadoUriRoot": "http://localhost:8080/dcm4chee-arc/aets/DCM4CHEE/wado",
"qidoRoot": "http://localhost:8080/dcm4chee-arc/aets/DCM4CHEE/rs",
"wadoRoot": "http://localhost:8080/dcm4chee-arc/aets/DCM4CHEE/rs",
"qidoSupportsIncludeField": false,
diff --git a/config/medkenOrthanc.json b/config/medkenOrthanc.json
index 6bb678173..f80d1ef9e 100644
--- a/config/medkenOrthanc.json
+++ b/config/medkenOrthanc.json
@@ -15,20 +15,26 @@
"logTiming": true
}
}
- ]
+ ],
+ "dimse" : [{
+ "name": "ORTHANC_DIMSE",
+ "peers": [
+ {
+ "host": "208.100.41.100",
+ "port": 4242,
+ "aeTitle": "MKORTHANC",
+ "default": true
+ },
+ {
+ "host": "0.0.0.0",
+ "port": 11119,
+ "aeTitle": "OHIFDCM",
+ "default": true,
+ "server": true
+ }
+ ]
+ }]
},
- "dimse" : [{
- "host" : "208.100.41.100",
- "port" : 4242,
- "aeTitle" : "MKORTHANC",
- "default": true
- },{
- "host" : "0.0.0.0",
- "port" : 11112,
- "aeTitle" : "OHIFDCM",
- "default" : true,
- "server" : true
- }],
"defaultServiceType": "dimse",
"medkenpanel" : {
"prefix" : "admin"
diff --git a/config/orthancDICOMWeb.json b/config/orthancDICOMWeb.json
index 367c03522..a27157e41 100644
--- a/config/orthancDICOMWeb.json
+++ b/config/orthancDICOMWeb.json
@@ -4,7 +4,7 @@
{
"name": "Orthanc",
"wadoUriRootNOTE": "either this uri is not correct for wado-uri or wado-uri is not configured on orthanc currently",
- "wadoUriRoot": "http://localhost:8043/wado",
+ "wadoUriRoot": "http://localhost:8042/wado",
"qidoRoot": "http://localhost:8042/dicom-web",
"wadoRoot": "http://localhost:8042/dicom-web",
"qidoSupportsIncludeField": false,
diff --git a/config/orthancDIMSE.json b/config/orthancDIMSE.json
index 8d713c603..895e46155 100644
--- a/config/orthancDIMSE.json
+++ b/config/orthancDIMSE.json
@@ -4,7 +4,7 @@
{
"name": "Orthanc",
"wadoUriRootNOTE": "either this uri is not correct for wado-uri or wado-uri is not configured on orthanc currently",
- "wadoUriRoot": "http://localhost:8043/wado",
+ "wadoUriRoot": "http://localhost:8042/wado",
"qidoRoot": "http://localhost:8042/dicom-web",
"wadoRoot": "http://localhost:8042/dicom-web",
"qidoSupportsIncludeField": false,
@@ -28,7 +28,7 @@
},
{
"host": "0.0.0.0",
- "port": 11112,
+ "port": 11119,
"aeTitle": "OHIFDCM",
"default": true,
"server": true
diff --git a/etc/OrthancProxy.js b/etc/OrthancProxy.js
deleted file mode 100644
index be7c16053..000000000
--- a/etc/OrthancProxy.js
+++ /dev/null
@@ -1,20 +0,0 @@
-// This sets up a proxy to work around CORS.
-// See http://chafey.blogspot.be/2014/09/working-around-cors.html
-// For more information
-var http = require('http'),
- httpProxy = require('http-proxy');
-
-var proxy = httpProxy.createProxyServer({
- target: 'http://localhost:8042',
- auth: 'orthanc:orthanc'
-}).listen(8043);
-
-proxy.on('proxyRes', function(proxyReq, req, res, options) {
- // add the CORS header to the response
- res.setHeader('Access-Control-Allow-Origin', '*');
-});
-
-proxy.on('error', function(e) {
- // suppress errors
- console.log(e);
-});
diff --git a/etc/dcm4cheCORSproxy.js b/etc/dcm4cheCORSproxy.js
deleted file mode 100644
index d47fbeed3..000000000
--- a/etc/dcm4cheCORSproxy.js
+++ /dev/null
@@ -1,20 +0,0 @@
-// This sets up a proxy to work around CORS.
-// See http://chafey.blogspot.be/2014/09/working-around-cors.html
-// For more information
-var http = require('http'),
- httpProxy = require('http-proxy');
-
-var proxy = httpProxy.createProxyServer({
- target: 'http://localhost:8080',
- auth: 'user:user'
-}).listen(8043);
-
-proxy.on('proxyRes', function(proxyReq, req, res, options) {
- // add the CORS header to the response
- res.setHeader('Access-Control-Allow-Origin', '*');
-});
-
-proxy.on('error', function(e) {
- // suppress errors
- console.log(e);
-});
diff --git a/etc/nodeCORSProxy.example b/etc/nodeCORSProxy.example
deleted file mode 100644
index ae50b166e..000000000
--- a/etc/nodeCORSProxy.example
+++ /dev/null
@@ -1,20 +0,0 @@
-// This sets up a proxy to work around CORS.
-// See http://chafey.blogspot.be/2014/09/working-around-cors.html
-// For more information
-var http = require('http'),
- httpProxy = require('http-proxy');
-
-var proxy = httpProxy.createProxyServer({
- target: 'http://localhost:8042',
- auth: 'orthanc:orthanc'
-}).listen(8042);
-
-proxy.on('proxyRes', function(proxyReq, req, res, options) {
- // add the CORS header to the response
- res.setHeader('Access-Control-Allow-Origin', '*');
-});
-
-proxy.on('error', function(e) {
- // suppress errors
- console.log(e);
-});
diff --git a/etc/nodeCORSProxy.js b/etc/nodeCORSProxy.js
deleted file mode 100644
index be7c16053..000000000
--- a/etc/nodeCORSProxy.js
+++ /dev/null
@@ -1,20 +0,0 @@
-// This sets up a proxy to work around CORS.
-// See http://chafey.blogspot.be/2014/09/working-around-cors.html
-// For more information
-var http = require('http'),
- httpProxy = require('http-proxy');
-
-var proxy = httpProxy.createProxyServer({
- target: 'http://localhost:8042',
- auth: 'orthanc:orthanc'
-}).listen(8043);
-
-proxy.on('proxyRes', function(proxyReq, req, res, options) {
- // add the CORS header to the response
- res.setHeader('Access-Control-Allow-Origin', '*');
-});
-
-proxy.on('error', function(e) {
- // suppress errors
- console.log(e);
-});
diff --git a/etc/setupLocalOrthanc.sh b/etc/setupLocalOrthanc.sh
deleted file mode 100755
index 269371c68..000000000
--- a/etc/setupLocalOrthanc.sh
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/bin/bash
-echo "Retrieving docker default machine IP address..."
-MACHINEIP=$(docker-machine ip default)
-echo "Copying nodeCORSProxy.example to nodeCORSProxy.js"
-cp nodeCORSProxy.example nodeCORSProxy.js
-sed -i '' "s/localhost:8042/$MACHINEIP:8042/g" nodeCORSProxy.js
-echo "Installing node http-proxy from npm..."
-npm install http-proxy
-echo "Running proxy server..."
-echo "In a separate tab/terminal, go to /main and run ./bin/orthancDICOMWeb.sh to start the Meteor server"
-node nodeCORSProxy.js