feat: Add Static WADO display (#2499)
* Rebased to have just the static view changes * Changes based on the PR * Couple more changes for the PR * Removed an extraneous log * Fix the study worklist display when returning to the page * Added some documentation on the static wado data source setup, and a bounds check change on the Queue test which was failing * PR updates - change the undefined study description to '' and remove the aws deploy * Fixed the e2e tests to actually pass/fail correctly on actual results
This commit is contained in:
1 parent
ca900f80e1
commit
2327b4ae12
21 files changed
+483
-41
No files matched your search
@@ -15,6 +15,7 @@ import {
|
||||
retrieveStudyMetadata,
|
||||
deleteStudyMetadataPromise,
|
||||
} from './retrieveStudyMetadata.js';
|
||||
import StaticWadoClient from './utils/StaticWadoClient.js';
|
||||
|
||||
const { DicomMetaDictionary, DicomDict } = dcmjs.data;
|
||||
|
||||
@@ -46,14 +47,14 @@ function createDicomWebApi(dicomWebConfig, UserAuthenticationService) {
|
||||
supportsFuzzyMatching,
|
||||
supportsWildcard,
|
||||
supportsReject,
|
||||
requestOptions,
|
||||
staticWado,
|
||||
} = dicomWebConfig;
|
||||
|
||||
const qidoConfig = {
|
||||
url: qidoRoot,
|
||||
staticWado,
|
||||
headers: UserAuthenticationService.getAuthorizationHeader(),
|
||||
errorInterceptor: errorHandler.getHTTPErrorHandler(),
|
||||
|
||||
};
|
||||
|
||||
const wadoConfig = {
|
||||
@@ -64,7 +65,7 @@ function createDicomWebApi(dicomWebConfig, UserAuthenticationService) {
|
||||
|
||||
// TODO -> Two clients sucks, but its better than 1000.
|
||||
// TODO -> We'll need to merge auth later.
|
||||
const qidoDicomWebClient = new api.DICOMwebClient(qidoConfig);
|
||||
const qidoDicomWebClient = staticWado ? new StaticWadoClient(qidoConfig) : new api.DICOMwebClient(wadoConfig);
|
||||
const wadoDicomWebClient = new api.DICOMwebClient(wadoConfig);
|
||||
|
||||
const implementation = {
|
||||
@@ -83,7 +84,7 @@ function createDicomWebApi(dicomWebConfig, UserAuthenticationService) {
|
||||
query: {
|
||||
studies: {
|
||||
mapParams: mapParams.bind(),
|
||||
search: async function(origParams) {
|
||||
search: async function (origParams) {
|
||||
const headers = UserAuthenticationService.getAuthorizationHeader();
|
||||
if (headers) {
|
||||
qidoDicomWebClient.headers = headers;
|
||||
@@ -108,7 +109,7 @@ function createDicomWebApi(dicomWebConfig, UserAuthenticationService) {
|
||||
},
|
||||
series: {
|
||||
// mapParams: mapParams.bind(),
|
||||
search: async function(studyInstanceUid) {
|
||||
search: async function (studyInstanceUid) {
|
||||
const headers = UserAuthenticationService.getAuthorizationHeader();
|
||||
if (headers) {
|
||||
qidoDicomWebClient.headers = headers;
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
import { api } from 'dicomweb-client';
|
||||
|
||||
/**
|
||||
* An implementation of the static wado client, that fetches data from
|
||||
* a static response rather than actually doing real queries. This allows
|
||||
* fast encoding of test data, but because it is static, anything actually
|
||||
* performing searches doesn't work. This version fixes the query issue
|
||||
* by manually implementing a query option.
|
||||
*/
|
||||
export default class StaticWadoClient extends api.DICOMwebClient {
|
||||
static filterKeys = {
|
||||
"StudyInstanceUID": "0020000D",
|
||||
"PatientName": "00100010",
|
||||
"00100020": "mrn",
|
||||
"StudyDescription": "00081030",
|
||||
"ModalitiesInStudy": "00080061",
|
||||
};
|
||||
|
||||
constructor(qidoConfig) {
|
||||
super(qidoConfig);
|
||||
this.staticWado = qidoConfig.staticWado;
|
||||
}
|
||||
|
||||
async searchForStudies(options) {
|
||||
if (!this.staticWado) return super.searchForStudies(options);
|
||||
|
||||
let searchResult = await super.searchForStudies(options);
|
||||
const { queryParams } = options;
|
||||
if (!queryParams) return searchResult;
|
||||
const filtered = searchResult.filter(study => {
|
||||
for (const key of Object.keys(StaticWadoClient.filterKeys)) {
|
||||
if (!this.filterItem(key, queryParams, study)) return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
return filtered;
|
||||
}
|
||||
|
||||
filterItem(key, queryParams, study) {
|
||||
const altKey = StaticWadoClient.filterKeys[key] || key;
|
||||
if (!queryParams) return true;
|
||||
const testValue = queryParams[key] || queryParams[altKey];
|
||||
if (!testValue) return true;
|
||||
const valueElem = study[key] || study[altKey];
|
||||
if (!valueElem) return false;
|
||||
const value = valueElem.Value;
|
||||
return value === testValue || (value.indexOf && value.indexOf(testValue) >= 0);
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@ function buildInstanceWadoRsUri(instance, config) {
|
||||
function buildInstanceFrameWadoRsUri(instance, config, frame) {
|
||||
const baseWadoRsUri = buildInstanceWadoRsUri(instance, config);
|
||||
|
||||
frame = frame != null || 1;
|
||||
frame = frame || 1;
|
||||
|
||||
return `${baseWadoRsUri}/frames/${frame}`;
|
||||
}
|
||||
|
||||
@@ -165,11 +165,11 @@ function PanelStudyBrowser({
|
||||
);
|
||||
const updatedExpandedStudyInstanceUIDs = shouldCollapseStudy
|
||||
? // eslint-disable-next-line prettier/prettier
|
||||
[
|
||||
...expandedStudyInstanceUIDs.filter(
|
||||
stdyUid => stdyUid !== StudyInstanceUID
|
||||
),
|
||||
]
|
||||
[
|
||||
...expandedStudyInstanceUIDs.filter(
|
||||
stdyUid => stdyUid !== StudyInstanceUID
|
||||
),
|
||||
]
|
||||
: [...expandedStudyInstanceUIDs, StudyInstanceUID];
|
||||
|
||||
setExpandedStudyInstanceUIDs(updatedExpandedStudyInstanceUIDs);
|
||||
@@ -247,7 +247,7 @@ function _mapDisplaySets(displaySets, thumbnailImageSrcMap) {
|
||||
|
||||
array.push({
|
||||
displaySetInstanceUID: ds.displaySetInstanceUID,
|
||||
description: ds.SeriesDescription,
|
||||
description: ds.SeriesDescription || '',
|
||||
seriesNumber: ds.SeriesNumber,
|
||||
modality: ds.Modality,
|
||||
seriesDate: ds.SeriesDate,
|
||||
|
||||
@@ -20,9 +20,9 @@ const makeDisplaySet = instances => {
|
||||
SeriesTime: instance.SeriesTime,
|
||||
SeriesInstanceUID: instance.SeriesInstanceUID,
|
||||
StudyInstanceUID: instance.StudyInstanceUID,
|
||||
SeriesNumber: instance.SeriesNumber,
|
||||
SeriesNumber: instance.SeriesNumber || 0,
|
||||
FrameRate: instance.FrameTime,
|
||||
SeriesDescription: instance.SeriesDescription,
|
||||
SeriesDescription: instance.SeriesDescription || '',
|
||||
Modality: instance.Modality,
|
||||
isMultiFrame: isMultiFrame(instance),
|
||||
numImageFrames: instances.length,
|
||||
|
||||
Reference in new issue
Block a user