From 2d48d0aa379383f5a0e58c9426d723259434b90f Mon Sep 17 00:00:00 2001 From: David Wire Date: Mon, 8 Jul 2019 10:15:06 -0600 Subject: [PATCH] feat(StudyList): Add QIDO style query parameters to set initial filters (#543) This pull request adds the ability to use query parameters to pass filters into the StudyList from the url. These parameters are of the same form used by the QIDO requests to apply the filters. This solution seemed to me to be the most obvious way to manage them. There's one open question however, around what to do with the parameters after the initial load. For now, the URL parameters are overridden the moment the user tries to add another filter. Depending on review feedback it seems like it may make more sense for those query parameter filters to be "permanent" and so any further filtering would augment those parameters rather than replace them. --- src/studylist/StudyListRouting.js | 34 +++++++++++++++++++++--------- src/studylist/StudyListWithData.js | 24 +++++++++++---------- 2 files changed, 37 insertions(+), 21 deletions(-) diff --git a/src/studylist/StudyListRouting.js b/src/studylist/StudyListRouting.js index 357d1eb0f..e156592fc 100644 --- a/src/studylist/StudyListRouting.js +++ b/src/studylist/StudyListRouting.js @@ -1,22 +1,36 @@ import React from 'react'; import PropTypes from 'prop-types'; +import { withRouter } from 'react-router-dom'; +import queryString from 'query-string'; import ConnectedStudyList from './ConnectedStudyList'; // TODO: Move to react-viewerbase -function StudyListRouting({ match }) { - // TODO: Figure out which filters we want to pass in via a URL - //const { patientId } = match.params; +function toLowerCaseFirstLetter(word) { + return word[0].toLowerCase() + word.slice(1); +} - return ; +function getFilters({ search }) { + const searchParameters = queryString.parse(search); + const filters = {}; + + Object.entries(searchParameters).forEach(([key, value]) => { + filters[toLowerCaseFirstLetter(key)] = value; + }); + + return filters; +} + +function StudyListRouting({ location }) { + const filters = location ? getFilters(location) : undefined; + + return ; } StudyListRouting.propTypes = { - match: PropTypes.shape({ - params: PropTypes.shape({ - patientIds: PropTypes.string, - }), - }), + location: PropTypes.shape({ + search: PropTypes.string, + }).isRequired, }; -export default StudyListRouting; +export default withRouter(StudyListRouting); diff --git a/src/studylist/StudyListWithData.js b/src/studylist/StudyListWithData.js index c9b005296..38c630eb6 100644 --- a/src/studylist/StudyListWithData.js +++ b/src/studylist/StudyListWithData.js @@ -8,12 +8,12 @@ import moment from 'moment'; class StudyListWithData extends Component { state = { - searchData: {}, studies: null, error: null, }; static propTypes = { + filters: PropTypes.object, patientId: PropTypes.string, server: PropTypes.object, user: PropTypes.object, @@ -28,23 +28,25 @@ class StudyListWithData extends Component { .subtract(StudyListWithData.studyListDateFilterNumDays, 'days') .toDate(); static defaultStudyDateTo = new Date(); + static defaultSearchData = { + currentPage: 0, + rowsPerPage: StudyListWithData.rowsPerPage, + studyDateFrom: StudyListWithData.defaultStudyDateFrom, + studyDateTo: StudyListWithData.defaultStudyDateTo, + sortData: StudyListWithData.defaultSort, + }; componentDidMount() { // TODO: Avoid using timepoints here //const params = { studyInstanceUids, seriesInstanceUids, timepointId, timepointsFilter={} }; - this.searchForStudies(); + this.searchForStudies({ + ...StudyListWithData.defaultSearchData, + ...(this.props.filters || {}), + }); } - searchForStudies = ( - searchData = { - currentPage: 0, - rowsPerPage: StudyListWithData.rowsPerPage, - studyDateFrom: StudyListWithData.defaultStudyDateFrom, - studyDateTo: StudyListWithData.defaultStudyDateTo, - sortData: StudyListWithData.defaultSort, - } - ) => { + searchForStudies = (searchData = StudyListWithData.defaultSearchData) => { const { server } = this.props; const filter = { patientId: searchData.patientId,