AWV-3: Merging changes from upstream
This commit is contained in:
commit
176b503c5a
153 files changed
+2377
-1125
No files matched your search
@@ -0,0 +1,104 @@
|
||||
<template name="seriesDetailsTable">
|
||||
{{#unless selectedStudies.length}}
|
||||
<p align="center">Series details not found</p>
|
||||
{{/unless}}
|
||||
{{#each selectedStudies}}
|
||||
<div class="selectedStudyContainer">
|
||||
<table class="table table-responsive tblStudyDetails">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="center patientID">
|
||||
<div>
|
||||
<span>Patient ID</span>
|
||||
</div>
|
||||
<input type="text"
|
||||
class="form-control"
|
||||
id="patientID"
|
||||
placeholder="Patient ID"
|
||||
disabled="disabled"
|
||||
value="{{ patientId }}">
|
||||
</td>
|
||||
<td class="patientName">
|
||||
<div>
|
||||
<span>Patient Name</span>
|
||||
</div>
|
||||
<input type="text"
|
||||
class="form-control"
|
||||
id="patientName"
|
||||
placeholder="Patient Name"
|
||||
disabled="disabled"
|
||||
value="{{ formatPN patientName }}">
|
||||
</td>
|
||||
<td class="accessionNumber">
|
||||
<div>
|
||||
<span>Accession Number</span>
|
||||
</div>
|
||||
<input type="text"
|
||||
class="form-control"
|
||||
id="accessionNumber"
|
||||
placeholder="Accession Number"
|
||||
disabled="disabled"
|
||||
value="{{ accessionNumber }}">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="studyDescription">
|
||||
<div>
|
||||
<span>Study Description</span>
|
||||
</div>
|
||||
<input type="text"
|
||||
class="form-control"
|
||||
id="studyDescription"
|
||||
placeholder="Study Description"
|
||||
disabled="disabled"
|
||||
value="{{ studyDescription }}">
|
||||
</td>
|
||||
<td class="studyDate">
|
||||
<div>
|
||||
<span>Study Date</span>
|
||||
</div>
|
||||
<input type="text"
|
||||
class="form-control"
|
||||
id="studyDate"
|
||||
placeholder="Study Date"
|
||||
disabled="disabled"
|
||||
value="{{ formatDA studyDate }}">
|
||||
</td>
|
||||
|
||||
<td></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<table class="table table-responsive tblSeriesDetails">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="header">Number</th>
|
||||
<th class="header">Modality</th>
|
||||
<th class="header">Description</th>
|
||||
<th class="header">Instances</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
{{#if displaySeriesLoadingText}}
|
||||
<tr>
|
||||
<td colspan="4" class="center">
|
||||
{{> loadingText }}
|
||||
</td>
|
||||
</tr>
|
||||
{{/if}}
|
||||
|
||||
{{#each seriesList}}
|
||||
<tr>
|
||||
<td class="center">{{ seriesNumber }}</td>
|
||||
<td class="center">{{ modality }}</td>
|
||||
<td class="center">{{ seriesDescription }}</td>
|
||||
<td class="center">{{ instances.length }}</td>
|
||||
</tr>
|
||||
{{/each}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{{/each}}
|
||||
</template>
|
||||
@@ -0,0 +1,51 @@
|
||||
Template.seriesDetailsTable.onCreated(() => {
|
||||
const instance = Template.instance();
|
||||
|
||||
// Create selected studies
|
||||
instance.selectedStudies = new ReactiveDict();
|
||||
|
||||
let selectedStudiesData = instance.data.selectedStudies;
|
||||
|
||||
if (!selectedStudiesData) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Display loading text while getting series
|
||||
_.each(selectedStudiesData, selectedStudy => {
|
||||
|
||||
selectedStudy.displaySeriesLoadingText = true;
|
||||
});
|
||||
|
||||
// Set reactive selected studies
|
||||
instance.selectedStudies.set('studies', selectedStudiesData);
|
||||
});
|
||||
|
||||
Template.seriesDetailsTable.onRendered(() => {
|
||||
const instance = Template.instance();
|
||||
const studies = instance.selectedStudies.get('studies');
|
||||
|
||||
if (!studies) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get series list for the study
|
||||
_.map(studies, (selectedStudy, index) => {
|
||||
studies[index].seriesList = [];
|
||||
getStudyMetadata(selectedStudy.studyInstanceUid, study => {
|
||||
|
||||
// Set series list
|
||||
studies[index].seriesList = study.seriesList;
|
||||
studies[index].displaySeriesLoadingText = false;
|
||||
|
||||
// Update selected studies
|
||||
instance.selectedStudies.set('studies', studies);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Template.seriesDetailsTable.helpers({
|
||||
selectedStudies() {
|
||||
const instance = Template.instance();
|
||||
return instance.selectedStudies.get('studies');
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,30 @@
|
||||
@import "{design}/app"
|
||||
|
||||
.selectedStudyContainer
|
||||
margin-bottom: 15px;
|
||||
|
||||
.tblStudyDetails
|
||||
tbody > tr > td > label
|
||||
color: $textPrimaryColor
|
||||
|
||||
tbody > tr > td > input[type="text"]
|
||||
height: 28px
|
||||
background-color: $primaryBackgroundColor
|
||||
color: $textPrimaryColor
|
||||
width: calc(100% - 10px)
|
||||
border-radius: 4px
|
||||
box-sizing: border-box
|
||||
|
||||
.tblSeriesDetails
|
||||
thead > tr > th
|
||||
text-align: center
|
||||
|
||||
tbody > tr
|
||||
|
||||
td
|
||||
text-align: center
|
||||
color: $textPrimaryColor
|
||||
|
||||
.loadingTextDiv
|
||||
font-size: 13px
|
||||
color: $textSecondaryColor
|
||||
@@ -6,6 +6,10 @@
|
||||
onselectstart='return false;'>
|
||||
<ul>
|
||||
<li>
|
||||
<a id="viewSeriesDetails" type="button"
|
||||
title="View Series Details">
|
||||
View Series Details
|
||||
</a>
|
||||
<a class="disabled">Anonymize</a>
|
||||
<a class="disabled">Send</a>
|
||||
<hr/>
|
||||
|
||||
@@ -13,6 +13,8 @@ function closeHandler(dialog) {
|
||||
*/
|
||||
openStudyContextMenu = function(e) {
|
||||
Worklist.functions['exportSelectedStudies'] = exportSelectedStudies;
|
||||
Worklist.functions['viewSeriesDetails'] = viewSeriesDetails;
|
||||
|
||||
|
||||
Template.studyContextMenu.study = $(e.currentTarget);
|
||||
|
||||
@@ -68,6 +70,25 @@ function exportSelectedStudies() {
|
||||
exportStudies(selectedStudies);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display series details of study in modal
|
||||
*/
|
||||
function viewSeriesDetails() {
|
||||
var selectedStudies = WorklistSelectedStudies.find({}, {
|
||||
sort: {
|
||||
studyDate: 1
|
||||
}
|
||||
}).fetch();
|
||||
|
||||
if (!selectedStudies) {
|
||||
return;
|
||||
}
|
||||
|
||||
Modal.show('viewSeriesDetailsModal', {
|
||||
selectedStudies: selectedStudies
|
||||
});
|
||||
}
|
||||
|
||||
Template.studyContextMenu.events({
|
||||
'click a': function(e) {
|
||||
var study = Template.studyContextMenu.study;
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
color: black
|
||||
|
||||
&:not(.disabled):hover
|
||||
color: $activeColor
|
||||
theme('color', '$activeColor')
|
||||
text-decoration: none
|
||||
|
||||
&.disabled
|
||||
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
<template name="viewSeriesDetailsModal">
|
||||
<div class="modal" id="viewSeriesDetailsModal" tabindex="-1" role="dialog" aria-labelledby="viewSeriesDetailsModalLabel">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||
<h4 class="modal-title" id="associationModalLabel">Series Details</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
{{> seriesDetailsTable
|
||||
selectedStudies=selectedStudies
|
||||
}}
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-dismiss="modal" id='cancelAssociation'>Close</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -1,17 +1,17 @@
|
||||
@import "{design}/app"
|
||||
|
||||
body
|
||||
background-color: $primaryBackgroundColor
|
||||
theme('background-color', '$primaryBackgroundColor')
|
||||
|
||||
#tblStudyList
|
||||
tr
|
||||
height: 20px
|
||||
|
||||
#worklistTab
|
||||
background-color: $primaryBackgroundColor
|
||||
theme('background-color', '$primaryBackgroundColor')
|
||||
|
||||
.worklistContainer
|
||||
background-color: $primaryBackgroundColor
|
||||
theme('background-color', '$primaryBackgroundColor')
|
||||
margin: 0 auto
|
||||
color: white
|
||||
float: left;
|
||||
@@ -22,7 +22,7 @@ body
|
||||
height: calc(100% - 91px)
|
||||
|
||||
.loadingTextDiv
|
||||
color: $textSecondaryColor
|
||||
theme('color', '$textSecondaryColor')
|
||||
font-size: 30px
|
||||
|
||||
.tab-pane
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
<template name="worklistPagination">
|
||||
<div class="worklistPagination">
|
||||
<div class="row">
|
||||
<div class="col-xs-4 col-sm-3 col-md-3">
|
||||
{{#with recordCount}}
|
||||
<div class="form-inline form-group rows-per-page">
|
||||
<label>
|
||||
<span>Show</span>
|
||||
<select class="js-select-rows-per-page">
|
||||
<option value="25">25</option>
|
||||
<option value="50">50</option>
|
||||
<option value="100">100</option>
|
||||
</select>
|
||||
|
||||
<span class="rows-per-page-label">rows per page</span>
|
||||
</label>
|
||||
</div>
|
||||
{{/with}}
|
||||
</div>
|
||||
<div class="col-xs-8 col-sm-9 col-md-9">
|
||||
<div class="form-inline form-group page-number">
|
||||
<label>
|
||||
<ul id="pagination" class="no-margins"></ul>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -0,0 +1,58 @@
|
||||
import { Template } from 'meteor/templating';
|
||||
|
||||
import './worklistPagination.html';
|
||||
|
||||
const visiblePages = 10;
|
||||
Template.worklistPagination.onCreated(function() {
|
||||
let instance = Template.instance();
|
||||
// replace parentVariable with the name of the instance variable
|
||||
instance.parent = this.parent(1);
|
||||
});
|
||||
|
||||
Template.worklistPagination.onRendered(function() {
|
||||
const instance = Template.instance();
|
||||
const $paginationControl = instance.$('#pagination');
|
||||
|
||||
// Track changes on recordCount and rowsPerPage
|
||||
instance.autorun(function() {
|
||||
const recordCount = instance.parent.recordCount.get();
|
||||
const rowsPerPage = instance.parent.rowsPerPage.get();
|
||||
|
||||
// Destroy plugin if exists
|
||||
if ($paginationControl.data().twbsPagination) {
|
||||
$paginationControl.twbsPagination('destroy');
|
||||
}
|
||||
|
||||
if (recordCount && rowsPerPage) {
|
||||
const totalPageNumber = Math.ceil(recordCount / rowsPerPage);
|
||||
|
||||
// Initialize plugin
|
||||
$paginationControl.twbsPagination({
|
||||
totalPages: totalPageNumber,
|
||||
visiblePages: visiblePages,
|
||||
onPageClick: function (event, page) {
|
||||
// Update currentPage
|
||||
// Decrease page by 1 to set currentPage
|
||||
// Since reactive table current page index starts by 0
|
||||
instance.parent.currentPage.set(page - 1);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
Template.worklistPagination.helpers({
|
||||
recordCount() {
|
||||
const instance = Template.instance();
|
||||
return instance.parent.recordCount.get();
|
||||
}
|
||||
});
|
||||
|
||||
Template.worklistPagination.events({
|
||||
'change .js-select-rows-per-page'(event, instance) {
|
||||
const rowsPerPage = $(event.currentTarget).val();
|
||||
|
||||
// Update rowsPerPage of parent
|
||||
instance.parent.rowsPerPage.set(parseInt(rowsPerPage, 10));
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,39 @@
|
||||
@import "{design}/app"
|
||||
|
||||
.worklistPagination
|
||||
font-size: 13px
|
||||
font-weight: normal !important
|
||||
|
||||
.rows-per-page
|
||||
padding-top: 20px
|
||||
|
||||
label
|
||||
font-weight: normal
|
||||
|
||||
select
|
||||
background-color: $primaryBackgroundColor
|
||||
color: white
|
||||
|
||||
.page-number
|
||||
text-align: right
|
||||
|
||||
label
|
||||
font-weight: normal
|
||||
|
||||
ul#pagination
|
||||
|
||||
li
|
||||
a
|
||||
padding: 4px 8px
|
||||
background-color: $primaryBackgroundColor
|
||||
color: white
|
||||
|
||||
&:hover
|
||||
color: $activeColor
|
||||
|
||||
.active
|
||||
|
||||
a
|
||||
background-color: $uiGrayDarker
|
||||
color: white
|
||||
|
||||
@@ -92,6 +92,10 @@
|
||||
{{/each}}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<!-- Pagination -->
|
||||
{{> worklistPagination }}
|
||||
|
||||
{{#if session "showLoadingText"}}
|
||||
{{>loadingText}}
|
||||
{{ else }}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
display: none
|
||||
@@ -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;
|
||||
|
||||
Reference in new issue
Block a user