AWV-3: Merging changes from upstream

This commit is contained in:
Bruno Alves de Faria committed 2016-09-03 14:47:39 -03:00
commit 176b503c5a
153 files changed
+2377 -1125

No files matched your search

@@ -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 = $('<button/>', {
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);
}
});
@@ -15,7 +15,7 @@
key='regionsOfMetastaticDisease'
multiple=true
options=(clone
placeholder='Choose a region...'
placeholder='Choose a region'
allowClear=true
)
}}
@@ -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')
@@ -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;
@@ -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
@@ -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
@@ -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;
}
});
@@ -1,13 +1,17 @@
<template name="lesionTable">
<div id="lesionTableContainer">
<div class="lesionTableLayoutChanger viewerRoundedButtonGroup">
{{>roundedButtonGroup buttonGroupData}}
</div>
<div class="lesionTableTimepointHeaderRow">
{{#each this.timepoints.get}}
{{>lesionTableTimepointHeader}}
{{/each}}
</div>
{{>lesionTableView (clone this)}}
{{#if this.timepoints.get.length}}
<div class="lesionTableLayoutChanger viewerRoundedButtonGroup">
{{>roundedButtonGroup buttonGroupData}}
</div>
<div class="lesionTableTimepointHeaderRow">
{{#each this.timepoints.get}}
{{>lesionTableTimepointHeader}}
{{/each}}
</div>
{{>lesionTableView (clone this)}}
{{else}}
<h3 class="p-x-1 text-center">No associated timepoint</h3>
{{/if}}
</div>
</template>
@@ -1,7 +1,7 @@
@import "{design}/app"
#lesionTableContainer
background-color: $primaryBackgroundColor
theme('background-color', '$primaryBackgroundColor')
height: 100%
width: 100%
@@ -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')
@@ -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) {
@@ -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
theme('background-color', '$uiYellow')
theme('color', '$textPrimaryColor')
@@ -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
@@ -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
@@ -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
@@ -38,4 +38,5 @@
{{ >lastLoginModal }}
{{ >studyContextMenu }}
{{ >progressDialog}}
{{ >viewSeriesDetailsModal }}
</template>
@@ -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
@@ -24,7 +24,10 @@
Remove Association
</a>
<hr/>
<a class="disabled">View Series Details</a>
<a id="viewSeriesDetails" type="button"
title="View Series Details">
View Series Details
</a>
<a class="disabled">Anonymize</a>
<a class="disabled">Send</a>
<hr/>
@@ -1,8 +1,9 @@
<template name="measureFlow">
<div class="measure-flow {{instance.state.get}}" style="position:fixed; top:200px; left:400px">
<div class="measure-flow {{#if this.treeColumns}}tree-columns{{/if}} {{instance.state.get}}" style="position:fixed; top:200px; left:400px">
<button class="btn-add">Add label</button>
{{#if eq instance.state.get 'selected'}}
<div class="tree-leaf">
<i class="icon-check"></i>
<span>{{instance.value.label}}</span>
{{#if instance.descriptionEdit.get}}
<div class="description clearfix">
@@ -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;
@@ -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
@@ -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%))
@@ -1,30 +1,27 @@
<template name="serverInformationDicomWeb">
<div class="row">
{{>serverInformationFormField name="wadoUriRoot" label="WADO URI root"}}
{{>serverInformationFormField name="wadoUriRootNOTE" label="WADO URI root note"}}
{{>serverInformationFormField name="wadoRoot" label="WADO root"}}
<div class="col-lg-6">
<div class="form-group">
<label class="wrapper">
<strong>Image rendering</strong>
<select name="imageRendering" class="form-control">
<option>Select</option>
<option value="wadouri">WADO URI</option>
<option value="orthanc">ORTHANC</option>
</select>
</label>
</div>
{{>inputText labelClass='form-group' key='wadoUriRoot'}}
</div>
<div class="col-lg-6">
{{>inputText labelClass='form-group' key='wadoUriRootNOTE'}}
</div>
<div class="col-lg-6">
{{>inputText labelClass='form-group' key='wadoRoot'}}
</div>
<div class="col-lg-6">
{{>inputSelect labelClass='form-group' key='imageRendering' hideSearch=true
options=(clone placeholder='Select an option')}}
</div>
<div class="col-lg-6">
{{>inputText labelClass='form-group' key='qidoRoot'}}
</div>
{{>serverInformationFormField name="qidoRoot" label="QIDO root"}}
<div class="col-lg-6">
<strong>QIDO options</strong>
<div class="form-group">
<div class="form-control">
<div class="checkbox">
<label>
<input type="checkbox" name="qidoSupportsIncludeField">
<span>QIDO supports including fields</span>
</label>
{{>inputCheckbox key='qidoSupportsIncludeField'}}
</div>
</div>
</div>
@@ -32,32 +29,25 @@
</div>
<hr>
<h4>Request options</h4>
<div class="row">
{{>serverInformationFormField name="requestOptions.auth" label="Authentication"}}
{{#group class='row' key='requestOptions'}}
<div class="col-lg-6">
{{>inputText labelClass='form-group' key='auth'}}
</div>
<div class="col-lg-6">
<strong>Logging options</strong>
<div class="form-group">
<div class="form-control clearfix">
<div class="checkbox pull-left">
<label>
<input type="checkbox" name="requestOptions.logRequests">
<span>Requests</span>
</label>
{{>inputCheckbox key='logRequests'}}
</div>
<div class="checkbox pull-left">
<label>
<input type="checkbox" name="requestOptions.logResponses">
<span>Responses</span>
</label>
{{>inputCheckbox key='logResponses'}}
</div>
<div class="checkbox pull-left">
<label>
<input type="checkbox" name="requestOptions.logTiming">
<span>Timing</span>
</label>
{{>inputCheckbox key='logTiming'}}
</div>
</div>
</div>
</div>
</div>
{{/group}}
</template>
@@ -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);
}
});
});
@@ -1,43 +1,45 @@
<template name="serverInformationDimse">
<div class="panel panel-default panel-body">
<div class="clearfix">
<h4 class="pull-left">Peer list</h4>
<h4 class="pull-left">Peer List</h4>
<button class="btn btn-primary pull-right js-new-peer">New peer</button>
</div>
<hr>
<div class="row">
{{#group class='row' key='peers' arrayValues=true}}
{{#each peer in instance.peers.get}}
<div class="col-lg-6">
{{#group class='col-lg-6'}}
<div class="panel panel-default panel-body">
<div class="row">
{{>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"}}
<div class="col-lg-6">
{{>inputText class='form-control' key='aeTitle'}}
</div>
<div class="col-lg-6">
{{>inputText class='form-control' key='hostAE'}}
</div>
<div class="col-lg-6">
{{>inputText class='form-control' key='host'}}
</div>
<div class="col-lg-6">
{{>inputText class='form-control' key='port'}}
</div>
<div class="col-lg-12">
<strong>Settings</strong>
<div class="form-group">
<div class="form-control clearfix">
<div class="checkbox pull-left">
<label>
<input type="checkbox" name="peers[].{{@index}}.default">
<span>Default</span>
</label>
{{>inputCheckbox key='default'}}
</div>
<div class="checkbox pull-left">
<label>
<input type="checkbox" name="peers[].{{@index}}.server">
<span>Server</span>
</label>
{{>inputCheckbox key='server'}}
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{{/group}}
{{/each}}
</div>
{{/group}}
</div>
<hr>
</template>
@@ -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);
}
@@ -1,33 +1,21 @@
<template name="serverInformationForm">
<form class="server-information-form">
<input type="hidden" name="_id">
{{#form class='server-information-form' schema=instance.currentSchema}}
{{>inputHidden key='_id'}}
<div class="row">
<div class="col-lg-6">
<div class="form-group">
<label class="wrapper">
<strong>Server Name</strong>
<input type="text" name="name" class="form-control">
</label>
</div>
{{>inputText labelClass='form-group' key='name'}}
</div>
<div class="col-lg-6">
<div class="form-group">
<label class="wrapper">
<strong>Server Type</strong>
<select name="type" class="form-control js-server-type">
<option>Select</option>
<option value="dicomWeb">DICOM Web</option>
<option value="dimse">DIMSE</option>
</select>
</label>
</div>
{{>inputSelect labelClass='form-group' key='type'
hideSearch=true disabled=(eq this.mode.get 'edit')
options=(clone placeholder='Choose a server type')}}
</div>
</div>
<hr>
{{#if eq this.serverType.get "dicomWeb"}}
{{#if eq this.serverType.get 'dicomWeb'}}
{{>serverInformationDicomWeb this}}
{{/if}}
{{#if eq this.serverType.get "dimse"}}
{{#if eq this.serverType.get 'dimse'}}
{{>serverInformationDimse this}}
{{/if}}
{{#if this.serverType.get}}
@@ -35,5 +23,5 @@
<input type="submit" class="btn btn-primary" value="Save">
</div>
{{/if}}
</form>
{{/form}}
</template>
@@ -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
@@ -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
@@ -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: ''
@@ -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)
@@ -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;
@@ -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
theme('stroke', '$defaultColor')
text-align: center
@@ -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
});
});
});
@@ -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
@@ -19,4 +19,4 @@
&:not(:last-child)
.removable
.imageViewerViewport
border-right: $uiBorderThickness solid $uiBorderColor
theme('border-right', '%s solid $uiBorderColor' % $uiBorderThickness)