diff --git a/extensions/default/src/DicomWebDataSource/utils/StaticWadoClient.js b/extensions/default/src/DicomWebDataSource/utils/StaticWadoClient.js index bc2dd60d0..ca4ffdab6 100644 --- a/extensions/default/src/DicomWebDataSource/utils/StaticWadoClient.js +++ b/extensions/default/src/DicomWebDataSource/utils/StaticWadoClient.js @@ -13,6 +13,7 @@ export default class StaticWadoClient extends api.DICOMwebClient { "PatientName": "00100010", "00100020": "mrn", "StudyDescription": "00081030", + "StudyDate": "00080020", "ModalitiesInStudy": "00080061", }; @@ -21,6 +22,12 @@ export default class StaticWadoClient extends api.DICOMwebClient { this.staticWado = qidoConfig.staticWado; } + /** + * Replace the search for studies remote query with a local version which + * retrieves a complete query list and then sub-selects from it locally. + * @param {*} options + * @returns + */ async searchForStudies(options) { if (!this.staticWado) return super.searchForStudies(options); @@ -36,6 +43,53 @@ export default class StaticWadoClient extends api.DICOMwebClient { return filtered; } + /** + * Compares values, matching any instance of desired to any instance of + * actual by recursively go through the paired set of values. That is, + * this is O(m*n) where m is how many items in desired and n is the length of actual + * Then, at the individual item node, compares the Alphabetic name if present, + * and does a sub-string matching on string values, and otherwise does an + * exact match comparison. + * + * @param {*} desired + * @param {*} actual + * @returns true if the values match + */ + compareValues(desired, actual) { + if (Array.isArray(desired)) { + return desired.find(item => this.compareValues(item, actual)); + } + if (Array.isArray(actual)) { + return actual.find(actualItem => this.compareValues(desired, actualItem)); + } + if (actual?.Alphabetic) { + actual = actual.Alphabetic; + } + if (typeof (actual) == 'string') { + return actual.indexOf(desired) != -1; + } + return desired === actual; + } + + /** Compares a pair of dates to see if the value is within the range */ + compareDateRange(range, value) { + if (!value) return true; + const dash = range.indexOf('-'); + if (dash === -1) return this.compareValues(range, value); + const start = range.substring(0, dash); + const end = range.substring(dash + 1); + return (!start || value >= start) && + (!end || value <= end); + } + + /** + * Filters the return list by the query parameters. + * + * @param {*} key + * @param {*} queryParams + * @param {*} study + * @returns + */ filterItem(key, queryParams, study) { const altKey = StaticWadoClient.filterKeys[key] || key; if (!queryParams) return true; @@ -43,7 +97,8 @@ export default class StaticWadoClient extends api.DICOMwebClient { if (!testValue) return true; const valueElem = study[key] || study[altKey]; if (!valueElem) return false; + if (valueElem.vr == 'DA') return this.compareDateRange(testValue, valueElem.Value[0]); const value = valueElem.Value; - return value === testValue || (value.indexOf && value.indexOf(testValue) >= 0); + return this.compareValues(testValue, value) && true; } }