feat(static-wado): add support for case-insensitive searching (#4603)

[OHI-1357]
This commit is contained in:
Ibrahim 2025-01-27 11:20:00 -05:00 committed by GitHub
parent 316cf0a7bd
commit ac6e674b4d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 42 additions and 7 deletions

View File

@ -151,6 +151,7 @@ function createDicomWebApi(dicomWebConfig: DicomWebConfig, servicesManager) {
singlepart: dicomWebConfig.singlepart, singlepart: dicomWebConfig.singlepart,
headers: userAuthenticationService.getAuthorizationHeader(), headers: userAuthenticationService.getAuthorizationHeader(),
errorInterceptor: errorHandler.getHTTPErrorHandler(), errorInterceptor: errorHandler.getHTTPErrorHandler(),
supportsFuzzyMatching: dicomWebConfig.supportsFuzzyMatching,
}; };
wadoConfig = { wadoConfig = {
@ -159,6 +160,7 @@ function createDicomWebApi(dicomWebConfig: DicomWebConfig, servicesManager) {
singlepart: dicomWebConfig.singlepart, singlepart: dicomWebConfig.singlepart,
headers: userAuthenticationService.getAuthorizationHeader(), headers: userAuthenticationService.getAuthorizationHeader(),
errorInterceptor: errorHandler.getHTTPErrorHandler(), errorInterceptor: errorHandler.getHTTPErrorHandler(),
supportsFuzzyMatching: dicomWebConfig.supportsFuzzyMatching,
}; };
// TODO -> Two clients sucks, but its better than 1000. // TODO -> Two clients sucks, but its better than 1000.

View File

@ -156,18 +156,40 @@ export default class StaticWadoClient extends api.DICOMwebClient {
* *
* @param {*} desired * @param {*} desired
* @param {*} actual * @param {*} actual
* @param {*} options - fuzzyMatching: if true, then do a sub-string match
* @returns true if the values match * @returns true if the values match
*/ */
compareValues(desired, actual) { compareValues(desired, actual, options) {
const { fuzzyMatching } = options;
if (Array.isArray(desired)) { if (Array.isArray(desired)) {
return desired.find(item => this.compareValues(item, actual)); return desired.find(item => this.compareValues(item, actual, options));
} }
if (Array.isArray(actual)) { if (Array.isArray(actual)) {
return actual.find(actualItem => this.compareValues(desired, actualItem)); return actual.find(actualItem => this.compareValues(desired, actualItem, options));
} }
if (actual?.Alphabetic) { if (actual?.Alphabetic) {
actual = actual.Alphabetic; actual = actual.Alphabetic;
} }
if (fuzzyMatching && typeof actual === 'string' && typeof desired === 'string') {
const normalizeValue = str => {
return str.toLowerCase();
};
const normalizedDesired = normalizeValue(desired);
const normalizedActual = normalizeValue(actual);
const tokenizeAndNormalize = str => str.split(/[\s^]+/).filter(Boolean);
const desiredTokens = tokenizeAndNormalize(normalizedDesired);
const actualTokens = tokenizeAndNormalize(normalizedActual);
return desiredTokens.every(desiredToken =>
actualTokens.some(actualToken => actualToken.startsWith(desiredToken))
);
}
if (typeof actual == 'string') { if (typeof actual == 'string') {
if (actual.length === 0) { if (actual.length === 0) {
return true; return true;
@ -194,7 +216,7 @@ export default class StaticWadoClient extends api.DICOMwebClient {
} }
const dash = range.indexOf('-'); const dash = range.indexOf('-');
if (dash === -1) { if (dash === -1) {
return this.compareValues(range, value); return this.compareValues(range, value, {});
} }
const start = range.substring(0, dash); const start = range.substring(0, dash);
const end = range.substring(dash + 1); const end = range.substring(dash + 1);
@ -211,6 +233,14 @@ export default class StaticWadoClient extends api.DICOMwebClient {
* @returns * @returns
*/ */
filterItem(key: string, queryParams, study, sourceFilterMap) { filterItem(key: string, queryParams, study, sourceFilterMap) {
const isName = (key: string) => key.indexOf('name') !== -1;
const { supportsFuzzyMatching = false } = this.config;
const options = {
fuzzyMatching: isName(key) && supportsFuzzyMatching,
};
const altKey = sourceFilterMap[key] || key; const altKey = sourceFilterMap[key] || key;
if (!queryParams) { if (!queryParams) {
return true; return true;
@ -227,7 +257,8 @@ export default class StaticWadoClient extends api.DICOMwebClient {
return this.compareDateRange(testValue, valueElem.Value[0]); return this.compareDateRange(testValue, valueElem.Value[0]);
} }
const value = valueElem.Value; const value = valueElem.Value;
return this.compareValues(testValue, value);
return this.compareValues(testValue, value, options);
} }
/** Converts the query parameters to lower case query parameters */ /** Converts the query parameters to lower case query parameters */

View File

@ -111,8 +111,8 @@ window.config = {
imageRendering: 'wadors', imageRendering: 'wadors',
thumbnailRendering: 'wadors', thumbnailRendering: 'wadors',
enableStudyLazyLoad: true, enableStudyLazyLoad: true,
supportsFuzzyMatching: false, supportsFuzzyMatching: true,
supportsWildcard: true, supportsWildcard: false,
staticWado: true, staticWado: true,
singlepart: 'bulkdata,video', singlepart: 'bulkdata,video',
// whether the data source should use retrieveBulkData to grab metadata, // whether the data source should use retrieveBulkData to grab metadata,

View File

@ -44,6 +44,8 @@ Below the study list are pagination options for 25, 50, or 100 studies per page.
![user-study-next](../assets/img/user-study-next.png) ![user-study-next](../assets/img/user-study-next.png)
For static wado servers, you can enable fuzzy matching by setting the `supportsFuzzyMatching` property to true, after enabling it, fuzzy matching will be peformed on the patient name field, for example, if PatientName is "John^Doe", then "jo", "Do" and "John Doe" will all match. However "ohn" will not match.
## Study Summary ## Study Summary
Click on a study to expand the study summary panel. Click on a study to expand the study summary panel.