fix(study-list): Use offset and limit in the dicomweb queries used to search studies with next/prev pagination in study list (#290)

This commit is contained in:
Evren Ozkan 2018-11-08 17:43:26 -05:00
parent 6ad7586d25
commit 99041bebde
6 changed files with 97 additions and 66 deletions

View File

@ -8,13 +8,22 @@
<span>rows per page</span>
</div>
</div>
<div class="col-xs-8 col-sm-9 col-md-9">
<div class="form-inline form-group page-number">
<label>
<ul class="pagination-control no-margins"></ul>
</label>
{{#if paginationButtonsEnabled}}
<div class="col-xs-8 col-sm-9 col-md-9">
<div class="form-inline form-group page-buttons noselect">
<label>
<ul class="pagination-control no-margins">
<li class="page-item prev disabled">
<a href="#" class="page-link">Previous</a>
</li>
<li class="page-item next disabled">
<a href="#" class="page-link">Next</a>
</li>
</ul>
</label>
</div>
</div>
</div>
{{/if}}
</div>
{{/form}}
</template>

View File

@ -1,8 +1,6 @@
import { Template } from 'meteor/templating';
import { SimpleSchema } from 'meteor/aldeed:simple-schema';
import 'twbs-pagination';
const visiblePages = 10;
import { $ } from 'meteor/jquery';
Template.paginationArea.onCreated(function() {
const instance = Template.instance();
@ -19,60 +17,66 @@ Template.paginationArea.onCreated(function() {
Template.paginationArea.onRendered(() => {
const instance = Template.instance();
instance.$paginationControl = instance.$('.pagination-control');
// Track changes on recordCount and rowsPerPage
instance.autorun(() => {
const recordCount = instance.data.recordCount.get();
const rowsPerPage = instance.data.rowsPerPage.get();
const currentPage = instance.data.currentPage.get();
// Destroy plugin if exists
if (instance.$paginationControl.data().twbsPagination) {
instance.$paginationControl.twbsPagination('destroy');
}
Meteor.defer(() => {
const prevButton = instance.$('.prev')[0];
const nextButton = instance.$('.next')[0];
if (!prevButton || !nextButton) {
return;
}
if (recordCount && rowsPerPage) {
const totalPages = Math.ceil(recordCount / rowsPerPage);
// Enable if there are potentially more records, otherwise disable it
if (recordCount >= rowsPerPage) {
nextButton.classList.remove('disabled');
} else {
nextButton.classList.add('disabled');
}
// Initialize plugin
instance.$paginationControl.twbsPagination({
totalPages,
visiblePages,
onPageClick: (event, page) => {
// Update currentPage
// Decrease page by 1 to set currentPage
// Since reactive table current page index starts by 0
instance.data.currentPage.set(page - 1);
}
});
}
// Enable the previous button if it is not the first page, otherwise disable it
if (currentPage > 0) {
prevButton.classList.remove('disabled');
} else {
prevButton.classList.add('disabled');
}
});
});
});
Template.paginationArea.onDestroyed(() => {
const instance = Template.instance();
if (instance.$paginationControl.data().twbsPagination) {
instance.$paginationControl.twbsPagination('destroy');
}
});
Template.paginationArea.helpers({
recordCount() {
paginationButtonsEnabled() {
const instance = Template.instance();
return instance.data.recordCount.get();
},
isRowsPerPageSelected(rowsPerPage) {
const instance = Template.instance();
return rowsPerPage === instance.data.rowsPerPage.get();
const recordCount = instance.data.recordCount.get();
const rowsPerPage = instance.data.rowsPerPage.get();
const currentPage = instance.data.currentPage.get();
// Show pagination if it is not first page or there are potentially more records
return currentPage > 0 || recordCount >= rowsPerPage;
}
});
Template.paginationArea.events({
'click .prev > a'(event, instance) {
const currentPage = instance.data.currentPage.get();
instance.data.currentPage.set(currentPage - 1);
},
'click .next > a'(event, instance) {
const currentPage = instance.data.currentPage.get();
instance.data.currentPage.set(currentPage + 1);
},
'change [data-key=rowsPerPage]'(event, instance) {
const rowsPerPage = $(event.currentTarget).data('component').value();
// Update rowsPerPage
instance.data.rowsPerPage.set(parseInt(rowsPerPage, 10));
instance.data.currentPage.set(0);
}
});

View File

@ -18,7 +18,7 @@
select
width: 42px
.page-number
.page-buttons
margin: 0
text-align: right
@ -29,28 +29,34 @@
margin: 0
li
display: table-cell
padding: 5px 2px
a
padding: 4px 8px
theme('background-color', '$primaryBackgroundColor')
theme('border-color', '$uiGray')
theme('background-color', '$uiGrayDarkest')
color: white
padding: 4px 8px
text-decoration: none
&:hover
theme('color', '$activeColor')
.active
a
theme('background-color', '$uiGray')
border-color: #ddd
color: white
.active
a
theme('background-color', '$uiGray')
border-color: #ddd
color: white
.disabled
cursor: not-allowed
a, a:hover, a:focus, a:active
theme('background-color', '$uiGrayDarkest')
theme('border-color', '$uiGray')
theme('color', '$uiGrayLight')
pointer-events: none
&:not(.disabled):hover a
theme('background-color', '$uiGrayDark')

View File

@ -1,5 +1,4 @@
Npm.depends({
'twbs-pagination': '1.4.1',
'isomorphic-base64': '1.0.2',
});

View File

@ -32,8 +32,8 @@ function dateToString(date) {
* Produces a QIDO URL given server details and a set of specified search filter
* items
*
* @param server
* @param filter
* @param serverSupportsQIDOIncludeField
* @returns {string} The URL with encoded filter query data
*/
function getQIDOQueryParams(filter, serverSupportsQIDOIncludeField) {
@ -50,6 +50,7 @@ function getQIDOQueryParams(filter, serverSupportsQIDOIncludeField) {
StudyDescription: filter.studyDescription,
ModalitiesInStudy: filter.modalitiesInStudy,
limit: filter.limit,
offset: filter.offset,
includefield: serverSupportsQIDOIncludeField ? commaSeparatedFields : 'all'
};

View File

@ -25,12 +25,6 @@ Template.studylistResult.helpers({
sortOption = Session.get('sortOption');
}
// Pagination parameters
const rowsPerPage = instance.paginationData.rowsPerPage.get();
const currentPage = instance.paginationData.currentPage.get();
const offset = rowsPerPage * currentPage;
const limit = offset + rowsPerPage;
const studies = OHIF.studylist.collections.Studies.find({}, {
sort: sortOption
}).fetch();
@ -42,8 +36,7 @@ Template.studylistResult.helpers({
// Update record count
instance.paginationData.recordCount.set(studies.length);
// Limit studies
return studies.slice(offset, limit);
return studies;
},
numberOfStudies() {
@ -104,7 +97,7 @@ function replaceUndefinedColumnValue(text) {
* Runs a search for studies matching the studylist query parameters
* Inserts the identified studies into the Studies Collection
*/
function search() {
function search(instance) {
OHIF.log.info('search()');
// Show loading message
@ -113,8 +106,14 @@ function search() {
// Hiding error message
Session.set('serverError', false);
// Pagination parameters
const rowsPerPage = instance.paginationData.rowsPerPage.get();
const currentPage = instance.paginationData.currentPage.get();
// Create the filters to be used for the StudyList Search
filter = {
offset: rowsPerPage * currentPage,
limit: rowsPerPage,
patientName: getFilter($('input#patientName').val()),
patientId: getFilter($('input#patientId').val()),
accessionNumber: getFilter($('input#accessionNumber').val()),
@ -259,7 +258,20 @@ Template.studylistResult.onRendered(() => {
}
}).data('daterangepicker');
search();
search(instance);
// Search when rowsPerPage or currentPage is changed
instance.autorun(computation => {
instance.paginationData.rowsPerPage.dep.depend();
instance.paginationData.currentPage.dep.depend();
// Stop here if it is the first run
if (computation.firstRun) {
return;
}
search(instance);
});
});
Template.studylistResult.onDestroyed(() => {
@ -278,17 +290,17 @@ function resetSortingColumns(instance, sortingColumn) {
}
Template.studylistResult.events({
'keydown input'(event) {
'keydown input'(event, instance) {
if (event.which === 13) { // Enter
search();
search(instance);
}
},
'onsearch input'() {
search();
'onsearch input'(event, instance) {
search(instance);
},
'change #studyDate'(event) {
'change #studyDate'(event, instance) {
let dateRange = $(event.currentTarget).val();
// Remove all space chars
@ -300,7 +312,7 @@ Template.studylistResult.events({
studyDateTo = dates[1];
if (dateRange !== '') {
search();
search(instance);
}
},