@ohif/app 3.8.0-beta.5 → 3.8.0-beta.51
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{12.bundle.1c0fcebb2e63f538b03b.js → 12.bundle.505ff8d33e3b91db6c4b.js} +9 -11
- package/dist/{125.bundle.253395f320b72180da63.js → 125.bundle.df666cb677e5a8982157.js} +4 -5
- package/dist/{663.bundle.68a67d3504dc24cccc1a.js → 170.bundle.3364dca0af95fde51ec6.js} +97 -89
- package/dist/{181.bundle.2ddc6f90740895a3949c.js → 181.bundle.aff453c348111303ceac.js} +107 -74
- package/dist/181.css +1 -1
- package/dist/{370.bundle.085badd6055e8feea84f.js → 185.bundle.892c8cbfeaaa14540821.js} +338 -209
- package/dist/{19.bundle.05ccf775cb70682dfcdf.js → 19.bundle.15ee26f7912d361e90b6.js} +127 -136
- package/dist/{99.bundle.51efd3493cd1de6bf63c.js → 199.bundle.a6fc393364e32b43a307.js} +215 -162
- package/dist/202.bundle.495cba6bbee744cf8f72.js +18239 -0
- package/dist/20fc4c659b85ccd2a9c0.wasm +0 -0
- package/dist/{220.bundle.f7e1c96c94245e70f2be.js → 223.bundle.d4ac6ef2cfe47a9c4afc.js} +4422 -3671
- package/dist/{23.bundle.e008ad788170f2ed5569.js → 23.bundle.9d989522a6e4fdcb9c72.js} +1 -1
- package/dist/{250.bundle.8084960e3318cda37317.js → 250.bundle.577da106dd763c7bf9d0.js} +22 -27
- package/dist/{281.bundle.64640869327edc0d2cae.js → 281.bundle.849a5e58fb2c0a9012dc.js} +23 -25
- package/dist/{82.bundle.9e269153bafc15562988.js → 290.bundle.744ac8d04daee807702f.js} +1244 -695
- package/dist/{359.bundle.e2f5680a854894c32944.js → 359.bundle.59878f46325c60f5d603.js} +27 -30
- package/dist/{410.bundle.8bb12b01e1f838340950.js → 410.bundle.ac46ff16910fa2785bcc.js} +24 -28
- package/dist/{417.bundle.af0a207c29b109f84159.js → 417.bundle.5c66801d23d0e98c00e6.js} +2 -2
- package/dist/{451.bundle.9fd36f52ff69594f0669.js → 451.bundle.311cd3be9916e08450e9.js} +28 -41
- package/dist/{221.bundle.da7732c6f158b6f2b0d8.js → 466.bundle.43f3b29a2e1665bb9a65.js} +161 -151
- package/dist/{471.bundle.b3d77b83b1593c09a504.js → 471.bundle.eeb78105b59e688832a6.js} +31 -35
- package/dist/{788.bundle.428c065311327135d817.js → 483.bundle.3a3d61f78d5f1f8ad574.js} +131 -180
- package/dist/{506.bundle.c3d01c4b6cc01096ce9e.js → 506.bundle.97b3dd0fd0f4467dc21c.js} +13 -18
- package/dist/{530.bundle.a03b6f942ace3e1baa1e.js → 530.bundle.f904325ef4195d69ac0e.js} +10 -3
- package/dist/{613.bundle.de79995392c3fd2e9637.js → 613.bundle.72d635ed76fa208309f7.js} +76 -50
- package/dist/{774.bundle.4b2dc46a35012b898e1a.js → 661.bundle.949c984fe2f9f753b65c.js} +1851 -8944
- package/dist/{686.bundle.dccef1f36e4bc79bcc48.js → 686.bundle.62c827fe4f0d054c164e.js} +4 -5
- package/dist/{687.bundle.763e03b2624b6cc03ad2.js → 687.bundle.a0c6c77073595745e58e.js} +19 -35
- package/dist/{342.bundle.22d2df5cf6d83b24acee.js → 738.bundle.bf1d2c76e385a091999d.js} +938 -571
- package/dist/{814.bundle.d45ba7f8b856fbd4e75d.js → 814.bundle.477d51b23a2fe79a5b96.js} +9 -11
- package/dist/{822.bundle.891f2e57b1b7bc2f4cb4.js → 822.bundle.8b745e28bc9eb9afbc61.js} +14 -16
- package/dist/{757.bundle.ec8301d8e70d2b990f65.js → 831.bundle.127a3064e8844d6d2c82.js} +1 -368
- package/dist/{886.bundle.d5116d9b8ea4964b68a0.js → 886.bundle.94a4536167d0f8cae1ae.js} +19 -23
- package/dist/95.bundle.2236101be3cc36b322e8.js +8769 -0
- package/dist/{236.bundle.09d155c6f44b5a44e4bf.js → 965.bundle.5a31aeb079b7e72cec9c.js} +104 -126
- package/dist/app.bundle.css +11 -11
- package/dist/{app.bundle.671d2bb084d88c0cf3b7.js → app.bundle.ef06991fb9bbafce36ed.js} +185194 -61390
- package/dist/cornerstoneDICOMImageLoader.min.js +1 -1
- package/dist/cornerstoneDICOMImageLoader.min.js.map +1 -1
- package/dist/{dicom-microscopy-viewer.bundle.2c146384eb9466d02ff8.js → dicom-microscopy-viewer.bundle.a7d5060eead13771e784.js} +1 -1
- package/dist/index.html +1 -1
- package/dist/{index.worker.e62ecca63f1a2e124230.worker.js → index.worker.64c896c4316fcd506666.worker.js} +2 -2
- package/dist/index.worker.64c896c4316fcd506666.worker.js.map +1 -0
- package/dist/serve.json +12 -0
- package/dist/sw.js +1 -1
- package/package.json +21 -21
- package/dist/202.bundle.d3490836f71e001dd30f.js +0 -6336
- package/dist/604.bundle.a51f83e64004bca5f497.js +0 -1848
- package/dist/743.bundle.489f7df3a089d4d374e1.js +0 -78007
- package/dist/75788f12450d4c5ed494.wasm +0 -0
- package/dist/775.bundle.2285e7e0e67878948c0d.js +0 -1009
- package/dist/957.bundle.9ea4506963ef8b2d84ba.js +0 -30077
- package/dist/index.worker.e62ecca63f1a2e124230.worker.js.map +0 -1
- /package/dist/{82.css → 290.css} +0 -0
- /package/dist/{221.css → 466.css} +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
(
|
|
2
|
+
(globalThis["webpackChunk"] = globalThis["webpackChunk"] || []).push([[738],{
|
|
3
3
|
|
|
4
|
-
/***/
|
|
4
|
+
/***/ 78738:
|
|
5
5
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
6
6
|
|
|
7
7
|
// ESM COMPAT FLAG
|
|
@@ -179,8 +179,7 @@ function searchStudies(server, filter) {
|
|
|
179
179
|
* @param serverSupportsQIDOIncludeField
|
|
180
180
|
* @returns {string} The URL with encoded filter query data
|
|
181
181
|
*/
|
|
182
|
-
function mapParams(params) {
|
|
183
|
-
let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
182
|
+
function mapParams(params, options = {}) {
|
|
184
183
|
if (!params) {
|
|
185
184
|
return;
|
|
186
185
|
}
|
|
@@ -354,13 +353,12 @@ function buildInstanceWadoUrl(config, instance) {
|
|
|
354
353
|
* @param thumbnail
|
|
355
354
|
* @returns {string} The imageId to be used by Cornerstone
|
|
356
355
|
*/
|
|
357
|
-
function getImageId(
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
} = _ref;
|
|
356
|
+
function getImageId({
|
|
357
|
+
instance,
|
|
358
|
+
frame,
|
|
359
|
+
config,
|
|
360
|
+
thumbnail = false
|
|
361
|
+
}) {
|
|
364
362
|
if (!instance) {
|
|
365
363
|
return;
|
|
366
364
|
}
|
|
@@ -395,13 +393,11 @@ class RetrieveMetadataLoader {
|
|
|
395
393
|
* @param {Object} client The dicomweb-client.
|
|
396
394
|
* @param {Array} studyInstanceUID Study instance ui to be retrieved
|
|
397
395
|
* @param {Object} [filters] - Object containing filters to be applied on retrieve metadata process
|
|
398
|
-
* @param {string} [
|
|
399
|
-
* @param {
|
|
396
|
+
* @param {string} [filters.seriesInstanceUID] - series instance uid to filter results against
|
|
397
|
+
* @param {Object} [sortCriteria] - Custom sort criteria used for series
|
|
398
|
+
* @param {Function} [sortFunction] - Custom sort function for series
|
|
400
399
|
*/
|
|
401
|
-
constructor(client, studyInstanceUID) {
|
|
402
|
-
let filters = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
403
|
-
let sortCriteria = arguments.length > 3 ? arguments[3] : undefined;
|
|
404
|
-
let sortFunction = arguments.length > 4 ? arguments[4] : undefined;
|
|
400
|
+
constructor(client, studyInstanceUID, filters = {}, sortCriteria = undefined, sortFunction = undefined) {
|
|
405
401
|
this.client = client;
|
|
406
402
|
this.studyInstanceUID = studyInstanceUID;
|
|
407
403
|
this.filters = filters;
|
|
@@ -422,13 +418,9 @@ class RetrieveMetadataLoader {
|
|
|
422
418
|
async runLoaders(loaders) {
|
|
423
419
|
let result;
|
|
424
420
|
for (const loader of loaders) {
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
break; // closes iterator in case data is retrieved successfully
|
|
429
|
-
}
|
|
430
|
-
} catch (e) {
|
|
431
|
-
throw e;
|
|
421
|
+
result = await loader();
|
|
422
|
+
if (result && result.length) {
|
|
423
|
+
break; // closes iterator in case data is retrieved successfully
|
|
432
424
|
}
|
|
433
425
|
}
|
|
434
426
|
if (loaders.next().done && !result) {
|
|
@@ -511,11 +503,64 @@ class RetrieveMetadataLoaderSync extends RetrieveMetadataLoader {
|
|
|
511
503
|
|
|
512
504
|
|
|
513
505
|
|
|
506
|
+
// Series Date, Series Time, Series Description and Series Number to be included
|
|
507
|
+
// in the series metadata query result
|
|
508
|
+
const includeField = ['00080021', '00080031', '0008103E', '00200011'].join(',');
|
|
509
|
+
class DeferredPromise {
|
|
510
|
+
constructor() {
|
|
511
|
+
this.metadata = undefined;
|
|
512
|
+
this.processFunction = undefined;
|
|
513
|
+
this.internalPromise = undefined;
|
|
514
|
+
this.thenFunction = undefined;
|
|
515
|
+
this.rejectFunction = undefined;
|
|
516
|
+
}
|
|
517
|
+
setMetadata(metadata) {
|
|
518
|
+
this.metadata = metadata;
|
|
519
|
+
}
|
|
520
|
+
setProcessFunction(func) {
|
|
521
|
+
this.processFunction = func;
|
|
522
|
+
}
|
|
523
|
+
getPromise() {
|
|
524
|
+
return this.start();
|
|
525
|
+
}
|
|
526
|
+
start() {
|
|
527
|
+
if (this.internalPromise) {
|
|
528
|
+
return this.internalPromise;
|
|
529
|
+
}
|
|
530
|
+
this.internalPromise = this.processFunction();
|
|
531
|
+
// in case then and reject functions called before start
|
|
532
|
+
if (this.thenFunction) {
|
|
533
|
+
this.then(this.thenFunction);
|
|
534
|
+
this.thenFunction = undefined;
|
|
535
|
+
}
|
|
536
|
+
if (this.rejectFunction) {
|
|
537
|
+
this.reject(this.rejectFunction);
|
|
538
|
+
this.rejectFunction = undefined;
|
|
539
|
+
}
|
|
540
|
+
return this.internalPromise;
|
|
541
|
+
}
|
|
542
|
+
then(func) {
|
|
543
|
+
if (this.internalPromise) {
|
|
544
|
+
return this.internalPromise.then(func);
|
|
545
|
+
} else {
|
|
546
|
+
this.thenFunction = func;
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
reject(func) {
|
|
550
|
+
if (this.internalPromise) {
|
|
551
|
+
return this.internalPromise.reject(func);
|
|
552
|
+
} else {
|
|
553
|
+
this.rejectFunction = func;
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
}
|
|
514
557
|
/**
|
|
515
|
-
* Creates an immutable series loader object which loads each series sequentially using the iterator interface
|
|
558
|
+
* Creates an immutable series loader object which loads each series sequentially using the iterator interface.
|
|
559
|
+
*
|
|
516
560
|
* @param {DICOMWebClient} dicomWebClient The DICOMWebClient instance to be used for series load
|
|
517
561
|
* @param {string} studyInstanceUID The Study Instance UID from which series will be loaded
|
|
518
562
|
* @param {Array} seriesInstanceUIDList A list of Series Instance UIDs
|
|
563
|
+
*
|
|
519
564
|
* @returns {Object} Returns an object which supports loading of instances from each of given Series Instance UID
|
|
520
565
|
*/
|
|
521
566
|
function makeSeriesAsyncLoader(client, studyInstanceUID, seriesInstanceUIDList) {
|
|
@@ -523,12 +568,20 @@ function makeSeriesAsyncLoader(client, studyInstanceUID, seriesInstanceUIDList)
|
|
|
523
568
|
hasNext() {
|
|
524
569
|
return seriesInstanceUIDList.length > 0;
|
|
525
570
|
},
|
|
526
|
-
|
|
527
|
-
const
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
571
|
+
next() {
|
|
572
|
+
const {
|
|
573
|
+
seriesInstanceUID,
|
|
574
|
+
metadata
|
|
575
|
+
} = seriesInstanceUIDList.shift();
|
|
576
|
+
const promise = new DeferredPromise();
|
|
577
|
+
promise.setMetadata(metadata);
|
|
578
|
+
promise.setProcessFunction(() => {
|
|
579
|
+
return client.retrieveSeriesMetadata({
|
|
580
|
+
studyInstanceUID,
|
|
581
|
+
seriesInstanceUID
|
|
582
|
+
});
|
|
531
583
|
});
|
|
584
|
+
return promise;
|
|
532
585
|
}
|
|
533
586
|
});
|
|
534
587
|
}
|
|
@@ -552,19 +605,22 @@ class RetrieveMetadataLoaderAsync extends RetrieveMetadataLoader {
|
|
|
552
605
|
} = {},
|
|
553
606
|
client
|
|
554
607
|
} = this;
|
|
608
|
+
|
|
609
|
+
// asking to include Series Date, Series Time, Series Description
|
|
610
|
+
// and Series Number in the series metadata returned to better sort series
|
|
611
|
+
// in preLoad function
|
|
612
|
+
let options = {
|
|
613
|
+
studyInstanceUID,
|
|
614
|
+
queryParams: {
|
|
615
|
+
includefield: includeField
|
|
616
|
+
}
|
|
617
|
+
};
|
|
555
618
|
if (seriesInstanceUID) {
|
|
556
|
-
|
|
557
|
-
studyInstanceUID,
|
|
558
|
-
queryParams: {
|
|
559
|
-
SeriesInstanceUID: seriesInstanceUID
|
|
560
|
-
}
|
|
561
|
-
};
|
|
619
|
+
options.queryParams.SeriesInstanceUID = seriesInstanceUID;
|
|
562
620
|
preLoaders.push(client.searchForSeries.bind(client, options));
|
|
563
621
|
}
|
|
564
622
|
// Fallback preloader
|
|
565
|
-
preLoaders.push(client.searchForSeries.bind(client,
|
|
566
|
-
studyInstanceUID
|
|
567
|
-
}));
|
|
623
|
+
preLoaders.push(client.searchForSeries.bind(client, options));
|
|
568
624
|
yield* preLoaders;
|
|
569
625
|
}
|
|
570
626
|
async preLoad() {
|
|
@@ -576,29 +632,34 @@ class RetrieveMetadataLoaderAsync extends RetrieveMetadataLoader {
|
|
|
576
632
|
naturalizeDataset
|
|
577
633
|
} = dcmjs_es["default"].data.DicomMetaDictionary;
|
|
578
634
|
const naturalized = result.map(naturalizeDataset);
|
|
579
|
-
return (0,sortStudy/* sortStudySeries */.IO)(naturalized, sortCriteria
|
|
635
|
+
return (0,sortStudy/* sortStudySeries */.IO)(naturalized, sortCriteria, sortFunction);
|
|
580
636
|
}
|
|
581
637
|
async load(preLoadData) {
|
|
582
638
|
const {
|
|
583
639
|
client,
|
|
584
640
|
studyInstanceUID
|
|
585
641
|
} = this;
|
|
586
|
-
const seriesInstanceUIDs = preLoadData.map(
|
|
642
|
+
const seriesInstanceUIDs = preLoadData.map(seriesMetadata => {
|
|
643
|
+
return {
|
|
644
|
+
seriesInstanceUID: seriesMetadata.SeriesInstanceUID,
|
|
645
|
+
metadata: seriesMetadata
|
|
646
|
+
};
|
|
647
|
+
});
|
|
587
648
|
const seriesAsyncLoader = makeSeriesAsyncLoader(client, studyInstanceUID, seriesInstanceUIDs);
|
|
588
649
|
const promises = [];
|
|
589
650
|
while (seriesAsyncLoader.hasNext()) {
|
|
590
|
-
|
|
651
|
+
const promise = seriesAsyncLoader.next();
|
|
652
|
+
promises.push(promise);
|
|
591
653
|
}
|
|
592
654
|
return {
|
|
593
655
|
preLoadData,
|
|
594
656
|
promises
|
|
595
657
|
};
|
|
596
658
|
}
|
|
597
|
-
async posLoad(
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
} = _ref;
|
|
659
|
+
async posLoad({
|
|
660
|
+
preLoadData,
|
|
661
|
+
promises
|
|
662
|
+
}) {
|
|
602
663
|
return {
|
|
603
664
|
preLoadData,
|
|
604
665
|
promises
|
|
@@ -613,40 +674,91 @@ class RetrieveMetadataLoaderAsync extends RetrieveMetadataLoader {
|
|
|
613
674
|
* Retrieve Study metadata from a DICOM server. If the server is configured to use lazy load, only the first series
|
|
614
675
|
* will be loaded and the property "studyLoader" will be set to let consumer load remaining series as needed.
|
|
615
676
|
*
|
|
616
|
-
* @param {
|
|
617
|
-
* @param {
|
|
618
|
-
* @param {
|
|
619
|
-
* @param {
|
|
620
|
-
* @
|
|
677
|
+
* @param {*} dicomWebClient The DICOMWebClient instance to be used for series load
|
|
678
|
+
* @param {*} StudyInstanceUID The UID of the Study to be retrieved
|
|
679
|
+
* @param {*} enableStudyLazyLoad Whether the study metadata should be loaded asynchronously
|
|
680
|
+
* @param {object} filters Object containing filters to be applied on retrieve metadata process
|
|
681
|
+
* @param {string} [filters.seriesInstanceUID] Series instance uid to filter results against
|
|
682
|
+
* @param {array} [filters.SeriesInstanceUIDs] Series instance uids to filter results against
|
|
683
|
+
* @param {function} [sortCriteria] Sort criteria function
|
|
684
|
+
* @param {function} [sortFunction] Sort function
|
|
685
|
+
*
|
|
686
|
+
* @returns {Promise} A promises that resolves the study descriptor object
|
|
621
687
|
*/
|
|
622
|
-
async function RetrieveMetadata(dicomWebClient,
|
|
623
|
-
let filters = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
|
|
624
|
-
let sortCriteria = arguments.length > 4 ? arguments[4] : undefined;
|
|
625
|
-
let sortFunction = arguments.length > 5 ? arguments[5] : undefined;
|
|
688
|
+
async function RetrieveMetadata(dicomWebClient, StudyInstanceUID, enableStudyLazyLoad, filters = {}, sortCriteria, sortFunction) {
|
|
626
689
|
const RetrieveMetadataLoader = enableStudyLazyLoad !== false ? RetrieveMetadataLoaderAsync : RetrieveMetadataLoaderSync;
|
|
627
|
-
const retrieveMetadataLoader = new RetrieveMetadataLoader(dicomWebClient,
|
|
690
|
+
const retrieveMetadataLoader = new RetrieveMetadataLoader(dicomWebClient, StudyInstanceUID, filters, sortCriteria, sortFunction);
|
|
628
691
|
const data = await retrieveMetadataLoader.execLoad();
|
|
629
692
|
return data;
|
|
630
693
|
}
|
|
631
694
|
/* harmony default export */ const retrieveMetadata = (RetrieveMetadata);
|
|
695
|
+
;// CONCATENATED MODULE: ../../../extensions/default/src/DicomWebDataSource/utils/retrieveMetadataFiltered.js
|
|
696
|
+
|
|
697
|
+
|
|
698
|
+
/**
|
|
699
|
+
* Retrieve metadata filtered.
|
|
700
|
+
*
|
|
701
|
+
* @param {*} dicomWebClient The DICOMWebClient instance to be used for series load
|
|
702
|
+
* @param {*} StudyInstanceUID The UID of the Study to be retrieved
|
|
703
|
+
* @param {*} enableStudyLazyLoad Whether the study metadata should be loaded asynchronously
|
|
704
|
+
* @param {object} filters Object containing filters to be applied on retrieve metadata process
|
|
705
|
+
* @param {string} [filters.seriesInstanceUID] Series instance uid to filter results against
|
|
706
|
+
* @param {array} [filters.SeriesInstanceUIDs] Series instance uids to filter results against
|
|
707
|
+
* @param {function} [sortCriteria] Sort criteria function
|
|
708
|
+
* @param {function} [sortFunction] Sort function
|
|
709
|
+
*
|
|
710
|
+
* @returns
|
|
711
|
+
*/
|
|
712
|
+
function retrieveMetadataFiltered(dicomWebClient, StudyInstanceUID, enableStudyLazyLoad, filters, sortCriteria, sortFunction) {
|
|
713
|
+
const {
|
|
714
|
+
SeriesInstanceUIDs
|
|
715
|
+
} = filters;
|
|
716
|
+
return new Promise((resolve, reject) => {
|
|
717
|
+
const promises = SeriesInstanceUIDs.map(uid => {
|
|
718
|
+
const seriesSpecificFilters = Object.assign({}, filters, {
|
|
719
|
+
seriesInstanceUID: uid
|
|
720
|
+
});
|
|
721
|
+
return retrieveMetadata(dicomWebClient, StudyInstanceUID, enableStudyLazyLoad, seriesSpecificFilters, sortCriteria, sortFunction);
|
|
722
|
+
});
|
|
723
|
+
Promise.all(promises).then(results => {
|
|
724
|
+
const aggregatedResult = {
|
|
725
|
+
preLoadData: [],
|
|
726
|
+
promises: []
|
|
727
|
+
};
|
|
728
|
+
results.forEach(({
|
|
729
|
+
preLoadData,
|
|
730
|
+
promises
|
|
731
|
+
}) => {
|
|
732
|
+
aggregatedResult.preLoadData = aggregatedResult.preLoadData.concat(preLoadData);
|
|
733
|
+
aggregatedResult.promises = aggregatedResult.promises.concat(promises);
|
|
734
|
+
});
|
|
735
|
+
resolve(aggregatedResult);
|
|
736
|
+
}, reject);
|
|
737
|
+
});
|
|
738
|
+
}
|
|
739
|
+
/* harmony default export */ const utils_retrieveMetadataFiltered = (retrieveMetadataFiltered);
|
|
632
740
|
;// CONCATENATED MODULE: ../../../extensions/default/src/DicomWebDataSource/retrieveStudyMetadata.js
|
|
633
741
|
|
|
742
|
+
|
|
634
743
|
const moduleName = 'RetrieveStudyMetadata';
|
|
635
744
|
// Cache for promises. Prevents unnecessary subsequent calls to the server
|
|
636
745
|
const StudyMetaDataPromises = new Map();
|
|
637
746
|
|
|
638
747
|
/**
|
|
639
|
-
* Retrieves study metadata
|
|
748
|
+
* Retrieves study metadata.
|
|
640
749
|
*
|
|
641
|
-
* @param {Object}
|
|
750
|
+
* @param {Object} dicomWebClient The DICOMWebClient instance to be used for series load
|
|
642
751
|
* @param {string} StudyInstanceUID The UID of the Study to be retrieved
|
|
643
|
-
* @param {boolean}
|
|
644
|
-
* @param {
|
|
645
|
-
* @param {
|
|
646
|
-
* @param {
|
|
752
|
+
* @param {boolean} enableStudyLazyLoad Whether the study metadata should be loaded asynchronously.
|
|
753
|
+
* @param {Object} [filters] Object containing filters to be applied on retrieve metadata process
|
|
754
|
+
* @param {string} [filters.seriesInstanceUID] Series instance uid to filter results against
|
|
755
|
+
* @param {array} [filters.SeriesInstanceUIDs] Series instance uids to filter results against
|
|
756
|
+
* @param {function} [sortCriteria] Sort criteria function
|
|
757
|
+
* @param {function} [sortFunction] Sort function
|
|
758
|
+
*
|
|
647
759
|
* @returns {Promise} that will be resolved with the metadata or rejected with the error
|
|
648
760
|
*/
|
|
649
|
-
function retrieveStudyMetadata(dicomWebClient, StudyInstanceUID, enableStudyLazyLoad, filters, sortCriteria, sortFunction) {
|
|
761
|
+
function retrieveStudyMetadata(dicomWebClient, StudyInstanceUID, enableStudyLazyLoad, filters, sortCriteria, sortFunction, dicomWebConfig = {}) {
|
|
650
762
|
// @TODO: Whenever a study metadata request has failed, its related promise will be rejected once and for all
|
|
651
763
|
// and further requests for that metadata will always fail. On failure, we probably need to remove the
|
|
652
764
|
// corresponding promise from the "StudyMetaDataPromises" map...
|
|
@@ -657,30 +769,34 @@ function retrieveStudyMetadata(dicomWebClient, StudyInstanceUID, enableStudyLazy
|
|
|
657
769
|
if (!StudyInstanceUID) {
|
|
658
770
|
throw new Error(`${moduleName}: Required 'StudyInstanceUID' parameter not provided.`);
|
|
659
771
|
}
|
|
772
|
+
const promiseId = `${dicomWebConfig.name}:${StudyInstanceUID}`;
|
|
660
773
|
|
|
661
774
|
// Already waiting on result? Return cached promise
|
|
662
|
-
if (StudyMetaDataPromises.has(
|
|
663
|
-
return StudyMetaDataPromises.get(
|
|
775
|
+
if (StudyMetaDataPromises.has(promiseId)) {
|
|
776
|
+
return StudyMetaDataPromises.get(promiseId);
|
|
777
|
+
}
|
|
778
|
+
let promise;
|
|
779
|
+
if (filters && filters.SeriesInstanceUIDs) {
|
|
780
|
+
promise = utils_retrieveMetadataFiltered(dicomWebClient, StudyInstanceUID, enableStudyLazyLoad, filters, sortCriteria, sortFunction);
|
|
781
|
+
} else {
|
|
782
|
+
// Create a promise to handle the data retrieval
|
|
783
|
+
promise = new Promise((resolve, reject) => {
|
|
784
|
+
retrieveMetadata(dicomWebClient, StudyInstanceUID, enableStudyLazyLoad, filters, sortCriteria, sortFunction).then(function (data) {
|
|
785
|
+
resolve(data);
|
|
786
|
+
}, reject);
|
|
787
|
+
});
|
|
664
788
|
}
|
|
665
|
-
|
|
666
|
-
// Create a promise to handle the data retrieval
|
|
667
|
-
const promise = new Promise((resolve, reject) => {
|
|
668
|
-
retrieveMetadata(dicomWebClient, StudyInstanceUID, enableStudyLazyLoad, filters, sortCriteria, sortFunction).then(function (data) {
|
|
669
|
-
resolve(data);
|
|
670
|
-
}, reject);
|
|
671
|
-
});
|
|
672
789
|
|
|
673
790
|
// Store the promise in cache
|
|
674
|
-
StudyMetaDataPromises.set(
|
|
791
|
+
StudyMetaDataPromises.set(promiseId, promise);
|
|
675
792
|
return promise;
|
|
676
793
|
}
|
|
677
794
|
|
|
678
795
|
/**
|
|
679
796
|
* Delete the cached study metadata retrieval promise to ensure that the browser will
|
|
680
|
-
* re-retrieve the study metadata when it is next requested
|
|
797
|
+
* re-retrieve the study metadata when it is next requested.
|
|
681
798
|
*
|
|
682
799
|
* @param {String} StudyInstanceUID The UID of the Study to be removed from cache
|
|
683
|
-
*
|
|
684
800
|
*/
|
|
685
801
|
function deleteStudyMetadataPromise(StudyInstanceUID) {
|
|
686
802
|
if (StudyMetaDataPromises.has(StudyInstanceUID)) {
|
|
@@ -697,6 +813,7 @@ function deleteStudyMetadataPromise(StudyInstanceUID) {
|
|
|
697
813
|
* performing searches doesn't work. This version fixes the query issue
|
|
698
814
|
* by manually implementing a query option.
|
|
699
815
|
*/
|
|
816
|
+
|
|
700
817
|
class StaticWadoClient extends dicomweb_client_es.api.DICOMwebClient {
|
|
701
818
|
constructor(qidoConfig) {
|
|
702
819
|
super(qidoConfig);
|
|
@@ -841,8 +958,7 @@ class StaticWadoClient extends dicomweb_client_es.api.DICOMwebClient {
|
|
|
841
958
|
/** Converts the query parameters to lower case query parameters */
|
|
842
959
|
toLowerParams(queryParams) {
|
|
843
960
|
const lowerParams = {};
|
|
844
|
-
Object.entries(queryParams).forEach(
|
|
845
|
-
let [key, value] = _ref;
|
|
961
|
+
Object.entries(queryParams).forEach(([key, value]) => {
|
|
846
962
|
lowerParams[key.toLowerCase()] = value;
|
|
847
963
|
});
|
|
848
964
|
return lowerParams;
|
|
@@ -904,7 +1020,11 @@ const getDirectURL = (config, params) => {
|
|
|
904
1020
|
}
|
|
905
1021
|
if (!singlepart || singlepart !== true && singlepart.indexOf(fetchPart) === -1) {
|
|
906
1022
|
if (value.retrieveBulkData) {
|
|
907
|
-
|
|
1023
|
+
// Try the specified retrieve type.
|
|
1024
|
+
const options = {
|
|
1025
|
+
mediaType: defaultType
|
|
1026
|
+
};
|
|
1027
|
+
return value.retrieveBulkData(options).then(arr => {
|
|
908
1028
|
value.DirectRetrieveURL = URL.createObjectURL(new Blob([arr], {
|
|
909
1029
|
type: defaultType
|
|
910
1030
|
}));
|
|
@@ -1006,26 +1126,47 @@ const EXPLICIT_VR_LITTLE_ENDIAN = '1.2.840.10008.1.2.1';
|
|
|
1006
1126
|
const metadataProvider = src.classes.MetadataProvider;
|
|
1007
1127
|
|
|
1008
1128
|
/**
|
|
1129
|
+
* Creates a DICOM Web API based on the provided configuration.
|
|
1009
1130
|
*
|
|
1010
|
-
* @param {
|
|
1011
|
-
* @param {string}
|
|
1012
|
-
* @param {string}
|
|
1013
|
-
* @param {string}
|
|
1014
|
-
* @param {
|
|
1015
|
-
* @param {string}
|
|
1016
|
-
* @param {
|
|
1017
|
-
* @param {
|
|
1018
|
-
* @param {
|
|
1019
|
-
* @param {
|
|
1131
|
+
* @param {object} dicomWebConfig - Configuration for the DICOM Web API
|
|
1132
|
+
* @param {string} dicomWebConfig.name - Data source name
|
|
1133
|
+
* @param {string} dicomWebConfig.wadoUriRoot - Legacy? (potentially unused/replaced)
|
|
1134
|
+
* @param {string} dicomWebConfig.qidoRoot - Base URL to use for QIDO requests
|
|
1135
|
+
* @param {string} dicomWebConfig.wadoRoot - Base URL to use for WADO requests
|
|
1136
|
+
* @param {string} dicomWebConfig.wadoUri - Base URL to use for WADO URI requests
|
|
1137
|
+
* @param {boolean} dicomWebConfig.qidoSupportsIncludeField - Whether QIDO supports the "Include" option to request additional fields in response
|
|
1138
|
+
* @param {string} dicomWebConfig.imageRendering - wadors | ? (unsure of where/how this is used)
|
|
1139
|
+
* @param {string} dicomWebConfig.thumbnailRendering - wadors | ? (unsure of where/how this is used)
|
|
1140
|
+
* @param {boolean} dicomWebConfig.supportsReject - Whether the server supports reject calls (i.e. DCM4CHEE)
|
|
1141
|
+
* @param {boolean} dicomWebConfig.lazyLoadStudy - "enableStudyLazyLoad"; Request series meta async instead of blocking
|
|
1142
|
+
* @param {string|boolean} dicomWebConfig.singlepart - indicates if the retrieves can fetch singlepart. Options are bulkdata, video, image, or boolean true
|
|
1143
|
+
* @param {string} dicomWebConfig.requestTransferSyntaxUID - Transfer syntax to request from the server
|
|
1144
|
+
* @param {object} dicomWebConfig.acceptHeader - Accept header to use for requests
|
|
1145
|
+
* @param {boolean} dicomWebConfig.omitQuotationForMultipartRequest - Whether to omit quotation marks for multipart requests
|
|
1146
|
+
* @param {boolean} dicomWebConfig.supportsFuzzyMatching - Whether the server supports fuzzy matching
|
|
1147
|
+
* @param {boolean} dicomWebConfig.supportsWildcard - Whether the server supports wildcard matching
|
|
1148
|
+
* @param {boolean} dicomWebConfig.supportsNativeDICOMModel - Whether the server supports the native DICOM model
|
|
1149
|
+
* @param {boolean} dicomWebConfig.enableStudyLazyLoad - Whether to enable study lazy loading
|
|
1150
|
+
* @param {boolean} dicomWebConfig.enableRequestTag - Whether to enable request tag
|
|
1151
|
+
* @param {boolean} dicomWebConfig.enableStudyLazyLoad - Whether to enable study lazy loading
|
|
1152
|
+
* @param {boolean} dicomWebConfig.bulkDataURI - Whether to enable bulkDataURI
|
|
1153
|
+
* @param {function} dicomWebConfig.onConfiguration - Function that is called after the configuration is initialized
|
|
1154
|
+
* @param {boolean} dicomWebConfig.staticWado - Whether to use the static WADO client
|
|
1155
|
+
* @param {object} userAuthenticationService - User authentication service
|
|
1156
|
+
* @param {object} userAuthenticationService.getAuthorizationHeader - Function that returns the authorization header
|
|
1157
|
+
* @returns {object} - DICOM Web API object
|
|
1020
1158
|
*/
|
|
1021
|
-
function createDicomWebApi(dicomWebConfig,
|
|
1159
|
+
function createDicomWebApi(dicomWebConfig, servicesManager) {
|
|
1160
|
+
const {
|
|
1161
|
+
userAuthenticationService,
|
|
1162
|
+
customizationService
|
|
1163
|
+
} = servicesManager.services;
|
|
1022
1164
|
let dicomWebConfigCopy, qidoConfig, wadoConfig, qidoDicomWebClient, wadoDicomWebClient, getAuthrorizationHeader, generateWadoHeader;
|
|
1023
1165
|
const implementation = {
|
|
1024
|
-
initialize:
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
} = _ref;
|
|
1166
|
+
initialize: ({
|
|
1167
|
+
params,
|
|
1168
|
+
query
|
|
1169
|
+
}) => {
|
|
1029
1170
|
if (dicomWebConfig.onConfiguration && typeof dicomWebConfig.onConfiguration === 'function') {
|
|
1030
1171
|
dicomWebConfig = dicomWebConfig.onConfiguration(dicomWebConfig, {
|
|
1031
1172
|
params,
|
|
@@ -1097,11 +1238,10 @@ function createDicomWebApi(dicomWebConfig, userAuthenticationService) {
|
|
|
1097
1238
|
}
|
|
1098
1239
|
// processResults: processResults.bind(),
|
|
1099
1240
|
},
|
|
1100
|
-
|
|
1101
1241
|
instances: {
|
|
1102
1242
|
search: (studyInstanceUid, queryParameters) => {
|
|
1103
1243
|
qidoDicomWebClient.headers = getAuthrorizationHeader();
|
|
1104
|
-
search.call(undefined, qidoDicomWebClient, studyInstanceUid, null, queryParameters);
|
|
1244
|
+
return search.call(undefined, qidoDicomWebClient, studyInstanceUid, null, queryParameters);
|
|
1105
1245
|
}
|
|
1106
1246
|
}
|
|
1107
1247
|
},
|
|
@@ -1123,11 +1263,10 @@ function createDicomWebApi(dicomWebConfig, userAuthenticationService) {
|
|
|
1123
1263
|
singlepart: dicomWebConfig.singlepart
|
|
1124
1264
|
}, params);
|
|
1125
1265
|
},
|
|
1126
|
-
bulkDataURI: async
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
} = _ref2;
|
|
1266
|
+
bulkDataURI: async ({
|
|
1267
|
+
StudyInstanceUID,
|
|
1268
|
+
BulkDataURI
|
|
1269
|
+
}) => {
|
|
1131
1270
|
qidoDicomWebClient.headers = getAuthrorizationHeader();
|
|
1132
1271
|
const options = {
|
|
1133
1272
|
multipart: false,
|
|
@@ -1140,26 +1279,26 @@ function createDicomWebApi(dicomWebConfig, userAuthenticationService) {
|
|
|
1140
1279
|
});
|
|
1141
1280
|
},
|
|
1142
1281
|
series: {
|
|
1143
|
-
metadata: async
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1282
|
+
metadata: async ({
|
|
1283
|
+
StudyInstanceUID,
|
|
1284
|
+
filters,
|
|
1285
|
+
sortCriteria,
|
|
1286
|
+
sortFunction,
|
|
1287
|
+
madeInClient = false,
|
|
1288
|
+
returnPromises = false
|
|
1289
|
+
} = {}) => {
|
|
1151
1290
|
if (!StudyInstanceUID) {
|
|
1152
1291
|
throw new Error('Unable to query for SeriesMetadata without StudyInstanceUID');
|
|
1153
1292
|
}
|
|
1154
1293
|
if (dicomWebConfig.enableStudyLazyLoad) {
|
|
1155
|
-
return implementation._retrieveSeriesMetadataAsync(StudyInstanceUID, filters, sortCriteria, sortFunction, madeInClient);
|
|
1294
|
+
return implementation._retrieveSeriesMetadataAsync(StudyInstanceUID, filters, sortCriteria, sortFunction, madeInClient, returnPromises);
|
|
1156
1295
|
}
|
|
1157
1296
|
return implementation._retrieveSeriesMetadataSync(StudyInstanceUID, filters, sortCriteria, sortFunction, madeInClient);
|
|
1158
1297
|
}
|
|
1159
1298
|
}
|
|
1160
1299
|
},
|
|
1161
1300
|
store: {
|
|
1162
|
-
dicom: async (dataset, request) => {
|
|
1301
|
+
dicom: async (dataset, request, dicomDict) => {
|
|
1163
1302
|
wadoDicomWebClient.headers = getAuthrorizationHeader();
|
|
1164
1303
|
if (dataset instanceof ArrayBuffer) {
|
|
1165
1304
|
const options = {
|
|
@@ -1168,18 +1307,22 @@ function createDicomWebApi(dicomWebConfig, userAuthenticationService) {
|
|
|
1168
1307
|
};
|
|
1169
1308
|
await wadoDicomWebClient.storeInstances(options);
|
|
1170
1309
|
} else {
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1310
|
+
let effectiveDicomDict = dicomDict;
|
|
1311
|
+
if (!dicomDict) {
|
|
1312
|
+
const meta = {
|
|
1313
|
+
FileMetaInformationVersion: dataset._meta?.FileMetaInformationVersion?.Value,
|
|
1314
|
+
MediaStorageSOPClassUID: dataset.SOPClassUID,
|
|
1315
|
+
MediaStorageSOPInstanceUID: dataset.SOPInstanceUID,
|
|
1316
|
+
TransferSyntaxUID: EXPLICIT_VR_LITTLE_ENDIAN,
|
|
1317
|
+
ImplementationClassUID,
|
|
1318
|
+
ImplementationVersionName
|
|
1319
|
+
};
|
|
1320
|
+
const denaturalized = denaturalizeDataset(meta);
|
|
1321
|
+
const defaultDicomDict = new DicomDict(denaturalized);
|
|
1322
|
+
defaultDicomDict.dict = denaturalizeDataset(dataset);
|
|
1323
|
+
effectiveDicomDict = defaultDicomDict;
|
|
1324
|
+
}
|
|
1325
|
+
const part10Buffer = effectiveDicomDict.write();
|
|
1183
1326
|
const options = {
|
|
1184
1327
|
datasets: [part10Buffer],
|
|
1185
1328
|
request
|
|
@@ -1192,7 +1335,7 @@ function createDicomWebApi(dicomWebConfig, userAuthenticationService) {
|
|
|
1192
1335
|
const enableStudyLazyLoad = false;
|
|
1193
1336
|
wadoDicomWebClient.headers = generateWadoHeader();
|
|
1194
1337
|
// data is all SOPInstanceUIDs
|
|
1195
|
-
const data = await retrieveStudyMetadata(wadoDicomWebClient, StudyInstanceUID, enableStudyLazyLoad, filters, sortCriteria, sortFunction);
|
|
1338
|
+
const data = await retrieveStudyMetadata(wadoDicomWebClient, StudyInstanceUID, enableStudyLazyLoad, filters, sortCriteria, sortFunction, dicomWebConfig);
|
|
1196
1339
|
|
|
1197
1340
|
// first naturalize the data
|
|
1198
1341
|
const naturalizedInstancesMetadata = data.map(naturalizeDataset);
|
|
@@ -1233,16 +1376,16 @@ function createDicomWebApi(dicomWebConfig, userAuthenticationService) {
|
|
|
1233
1376
|
const seriesMetadata = Object.values(seriesSummaryMetadata);
|
|
1234
1377
|
src.DicomMetadataStore.addSeriesMetadata(seriesMetadata, madeInClient);
|
|
1235
1378
|
Object.keys(instancesPerSeries).forEach(seriesInstanceUID => src.DicomMetadataStore.addInstances(instancesPerSeries[seriesInstanceUID], madeInClient));
|
|
1379
|
+
return seriesSummaryMetadata;
|
|
1236
1380
|
},
|
|
1237
|
-
_retrieveSeriesMetadataAsync: async
|
|
1238
|
-
let madeInClient = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;
|
|
1381
|
+
_retrieveSeriesMetadataAsync: async (StudyInstanceUID, filters, sortCriteria, sortFunction, madeInClient = false, returnPromises = false) => {
|
|
1239
1382
|
const enableStudyLazyLoad = true;
|
|
1240
1383
|
wadoDicomWebClient.headers = generateWadoHeader();
|
|
1241
1384
|
// Get Series
|
|
1242
1385
|
const {
|
|
1243
1386
|
preLoadData: seriesSummaryMetadata,
|
|
1244
1387
|
promises: seriesPromises
|
|
1245
|
-
} = await retrieveStudyMetadata(wadoDicomWebClient, StudyInstanceUID, enableStudyLazyLoad, filters, sortCriteria, sortFunction);
|
|
1388
|
+
} = await retrieveStudyMetadata(wadoDicomWebClient, StudyInstanceUID, enableStudyLazyLoad, filters, sortCriteria, sortFunction, dicomWebConfig);
|
|
1246
1389
|
|
|
1247
1390
|
/**
|
|
1248
1391
|
* naturalizes the dataset, and adds a retrieve bulkdata method
|
|
@@ -1264,10 +1407,13 @@ function createDicomWebApi(dicomWebConfig, userAuthenticationService) {
|
|
|
1264
1407
|
// in which case it isn't necessary to re-read this.
|
|
1265
1408
|
if (value && value.BulkDataURI && !value.Value) {
|
|
1266
1409
|
// Provide a method to fetch bulkdata
|
|
1267
|
-
value.retrieveBulkData = () => {
|
|
1410
|
+
value.retrieveBulkData = (options = {}) => {
|
|
1268
1411
|
// handle the scenarios where bulkDataURI is relative path
|
|
1269
1412
|
fixBulkDataURI(value, naturalized, dicomWebConfig);
|
|
1270
|
-
const
|
|
1413
|
+
const {
|
|
1414
|
+
mediaType
|
|
1415
|
+
} = options;
|
|
1416
|
+
const useOptions = {
|
|
1271
1417
|
// The bulkdata fetches work with either multipart or
|
|
1272
1418
|
// singlepart, so set multipart to false to let the server
|
|
1273
1419
|
// decide which type to respond with.
|
|
@@ -1277,10 +1423,16 @@ function createDicomWebApi(dicomWebConfig, userAuthenticationService) {
|
|
|
1277
1423
|
// is relative - that isn't disallowed by DICOMweb, but
|
|
1278
1424
|
// isn't well specified in the standard, but is needed in
|
|
1279
1425
|
// any implementation that stores static copies of the metadata
|
|
1280
|
-
StudyInstanceUID: naturalized.StudyInstanceUID
|
|
1426
|
+
StudyInstanceUID: naturalized.StudyInstanceUID,
|
|
1427
|
+
mediaTypes: mediaType ? [{
|
|
1428
|
+
mediaType
|
|
1429
|
+
}, {
|
|
1430
|
+
mediaType: 'application/octet-stream'
|
|
1431
|
+
}] : undefined,
|
|
1432
|
+
...options
|
|
1281
1433
|
};
|
|
1282
1434
|
// Todo: this needs to be from wado dicom web client
|
|
1283
|
-
return qidoDicomWebClient.retrieveBulkData(
|
|
1435
|
+
return qidoDicomWebClient.retrieveBulkData(useOptions).then(val => {
|
|
1284
1436
|
// There are DICOM PDF cases where the first ArrayBuffer in the array is
|
|
1285
1437
|
// the bulk data and DICOM video cases where the second ArrayBuffer is
|
|
1286
1438
|
// the bulk data. Here we play it safe and do a find.
|
|
@@ -1299,7 +1451,7 @@ function createDicomWebApi(dicomWebConfig, userAuthenticationService) {
|
|
|
1299
1451
|
const naturalizedInstances = instances.map(addRetrieveBulkData);
|
|
1300
1452
|
|
|
1301
1453
|
// Adding instanceMetadata to OHIF MetadataProvider
|
|
1302
|
-
naturalizedInstances.forEach(
|
|
1454
|
+
naturalizedInstances.forEach(instance => {
|
|
1303
1455
|
instance.wadoRoot = dicomWebConfig.wadoRoot;
|
|
1304
1456
|
instance.wadoUri = dicomWebConfig.wadoUri;
|
|
1305
1457
|
const imageId = implementation.getImageIdsForInstance({
|
|
@@ -1323,7 +1475,10 @@ function createDicomWebApi(dicomWebConfig, userAuthenticationService) {
|
|
|
1323
1475
|
src.DicomMetadataStore.addInstances(naturalizedInstances, madeInClient);
|
|
1324
1476
|
}
|
|
1325
1477
|
function setSuccessFlag() {
|
|
1326
|
-
const study = src.DicomMetadataStore.getStudy(StudyInstanceUID
|
|
1478
|
+
const study = src.DicomMetadataStore.getStudy(StudyInstanceUID);
|
|
1479
|
+
if (!study) {
|
|
1480
|
+
return;
|
|
1481
|
+
}
|
|
1327
1482
|
study.isLoaded = true;
|
|
1328
1483
|
}
|
|
1329
1484
|
|
|
@@ -1333,11 +1488,22 @@ function createDicomWebApi(dicomWebConfig, userAuthenticationService) {
|
|
|
1333
1488
|
aSeries.StudyInstanceUID = StudyInstanceUID;
|
|
1334
1489
|
});
|
|
1335
1490
|
src.DicomMetadataStore.addSeriesMetadata(seriesSummaryMetadata, madeInClient);
|
|
1336
|
-
const seriesDeliveredPromises = seriesPromises.map(promise =>
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1491
|
+
const seriesDeliveredPromises = seriesPromises.map(promise => {
|
|
1492
|
+
if (!returnPromises) {
|
|
1493
|
+
promise?.start();
|
|
1494
|
+
}
|
|
1495
|
+
return promise.then(instances => {
|
|
1496
|
+
storeInstances(instances);
|
|
1497
|
+
});
|
|
1498
|
+
});
|
|
1499
|
+
if (returnPromises) {
|
|
1500
|
+
Promise.all(seriesDeliveredPromises).then(() => setSuccessFlag());
|
|
1501
|
+
return seriesPromises;
|
|
1502
|
+
} else {
|
|
1503
|
+
await Promise.all(seriesDeliveredPromises);
|
|
1504
|
+
setSuccessFlag();
|
|
1505
|
+
}
|
|
1506
|
+
return seriesSummaryMetadata;
|
|
1341
1507
|
},
|
|
1342
1508
|
deleteStudyMetadataPromise: deleteStudyMetadataPromise,
|
|
1343
1509
|
getImageIdsForDisplaySet(displaySet) {
|
|
@@ -1365,11 +1531,10 @@ function createDicomWebApi(dicomWebConfig, userAuthenticationService) {
|
|
|
1365
1531
|
});
|
|
1366
1532
|
return imageIds;
|
|
1367
1533
|
},
|
|
1368
|
-
getImageIdsForInstance(
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
} = _ref3;
|
|
1534
|
+
getImageIdsForInstance({
|
|
1535
|
+
instance,
|
|
1536
|
+
frame = undefined
|
|
1537
|
+
}) {
|
|
1373
1538
|
const imageIds = getImageId({
|
|
1374
1539
|
instance,
|
|
1375
1540
|
frame,
|
|
@@ -1380,11 +1545,10 @@ function createDicomWebApi(dicomWebConfig, userAuthenticationService) {
|
|
|
1380
1545
|
getConfig() {
|
|
1381
1546
|
return dicomWebConfigCopy;
|
|
1382
1547
|
},
|
|
1383
|
-
getStudyInstanceUIDs(
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
} = _ref4;
|
|
1548
|
+
getStudyInstanceUIDs({
|
|
1549
|
+
params,
|
|
1550
|
+
query
|
|
1551
|
+
}) {
|
|
1388
1552
|
const {
|
|
1389
1553
|
StudyInstanceUIDs: paramsStudyInstanceUIDs
|
|
1390
1554
|
} = params;
|
|
@@ -1423,7 +1587,20 @@ let _store = {
|
|
|
1423
1587
|
// }
|
|
1424
1588
|
// }
|
|
1425
1589
|
};
|
|
1426
|
-
|
|
1590
|
+
function wrapSequences(obj) {
|
|
1591
|
+
return Object.keys(obj).reduce((acc, key) => {
|
|
1592
|
+
if (typeof obj[key] === 'object' && obj[key] !== null) {
|
|
1593
|
+
// Recursively wrap sequences for nested objects
|
|
1594
|
+
acc[key] = wrapSequences(obj[key]);
|
|
1595
|
+
} else {
|
|
1596
|
+
acc[key] = obj[key];
|
|
1597
|
+
}
|
|
1598
|
+
if (key.endsWith('Sequence')) {
|
|
1599
|
+
acc[key] = src["default"].utils.addAccessors(acc[key]);
|
|
1600
|
+
}
|
|
1601
|
+
return acc;
|
|
1602
|
+
}, Array.isArray(obj) ? [] : {});
|
|
1603
|
+
}
|
|
1427
1604
|
const getMetaDataByURL = url => {
|
|
1428
1605
|
return _store.urls.find(metaData => metaData.url === url);
|
|
1429
1606
|
};
|
|
@@ -1443,11 +1620,10 @@ function createDicomJSONApi(dicomJsonConfig) {
|
|
|
1443
1620
|
wadoRoot
|
|
1444
1621
|
} = dicomJsonConfig;
|
|
1445
1622
|
const implementation = {
|
|
1446
|
-
initialize: async
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
} = _ref;
|
|
1623
|
+
initialize: async ({
|
|
1624
|
+
query,
|
|
1625
|
+
url
|
|
1626
|
+
}) => {
|
|
1451
1627
|
if (!url) {
|
|
1452
1628
|
url = query.get('url');
|
|
1453
1629
|
}
|
|
@@ -1548,12 +1724,11 @@ function createDicomJSONApi(dicomJsonConfig) {
|
|
|
1548
1724
|
return utils_getDirectURL(wadoRoot, params);
|
|
1549
1725
|
},
|
|
1550
1726
|
series: {
|
|
1551
|
-
metadata: async
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
} = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
1727
|
+
metadata: async ({
|
|
1728
|
+
StudyInstanceUID,
|
|
1729
|
+
madeInClient = false,
|
|
1730
|
+
customSort
|
|
1731
|
+
} = {}) => {
|
|
1557
1732
|
if (!StudyInstanceUID) {
|
|
1558
1733
|
throw new Error('Unable to query for SeriesMetadata without StudyInstanceUID');
|
|
1559
1734
|
}
|
|
@@ -1585,8 +1760,13 @@ function createDicomJSONApi(dicomJsonConfig) {
|
|
|
1585
1760
|
const numberOfSeries = series.length;
|
|
1586
1761
|
series.forEach((series, index) => {
|
|
1587
1762
|
const instances = series.instances.map(instance => {
|
|
1763
|
+
// for instance.metadata if the key ends with sequence then
|
|
1764
|
+
// we need to add a proxy to the first item in the sequence
|
|
1765
|
+
// so that we can access the value of the sequence
|
|
1766
|
+
// by using sequenceName.value
|
|
1767
|
+
const modifiedMetadata = wrapSequences(instance.metadata);
|
|
1588
1768
|
const obj = {
|
|
1589
|
-
...
|
|
1769
|
+
...modifiedMetadata,
|
|
1590
1770
|
url: instance.url,
|
|
1591
1771
|
imageId: instance.url,
|
|
1592
1772
|
...series,
|
|
@@ -1636,22 +1816,20 @@ function createDicomJSONApi(dicomJsonConfig) {
|
|
|
1636
1816
|
});
|
|
1637
1817
|
return imageIds;
|
|
1638
1818
|
},
|
|
1639
|
-
getImageIdsForInstance(
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
} = _ref2;
|
|
1819
|
+
getImageIdsForInstance({
|
|
1820
|
+
instance,
|
|
1821
|
+
frame
|
|
1822
|
+
}) {
|
|
1644
1823
|
const imageIds = getImageId({
|
|
1645
1824
|
instance,
|
|
1646
1825
|
frame
|
|
1647
1826
|
});
|
|
1648
1827
|
return imageIds;
|
|
1649
1828
|
},
|
|
1650
|
-
getStudyInstanceUIDs:
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
} = _ref3;
|
|
1829
|
+
getStudyInstanceUIDs: ({
|
|
1830
|
+
params,
|
|
1831
|
+
query
|
|
1832
|
+
}) => {
|
|
1655
1833
|
const url = query.get('url');
|
|
1656
1834
|
return _store.studyInstanceUIDMap.get(url);
|
|
1657
1835
|
}
|
|
@@ -1672,8 +1850,7 @@ const END_MODALITIES = {
|
|
|
1672
1850
|
SEG: true,
|
|
1673
1851
|
DOC: true
|
|
1674
1852
|
};
|
|
1675
|
-
const compareValue =
|
|
1676
|
-
let def = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
|
|
1853
|
+
const compareValue = (v1, v2, def = 0) => {
|
|
1677
1854
|
if (v1 === v2) {
|
|
1678
1855
|
return def;
|
|
1679
1856
|
}
|
|
@@ -1705,12 +1882,10 @@ function createDicomLocalApi(dicomLocalConfig) {
|
|
|
1705
1882
|
name
|
|
1706
1883
|
} = dicomLocalConfig;
|
|
1707
1884
|
const implementation = {
|
|
1708
|
-
initialize:
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
} = _ref;
|
|
1713
|
-
},
|
|
1885
|
+
initialize: ({
|
|
1886
|
+
params,
|
|
1887
|
+
query
|
|
1888
|
+
}) => {},
|
|
1714
1889
|
query: {
|
|
1715
1890
|
studies: {
|
|
1716
1891
|
mapParams: () => {},
|
|
@@ -1789,11 +1964,10 @@ function createDicomLocalApi(dicomLocalConfig) {
|
|
|
1789
1964
|
}
|
|
1790
1965
|
},
|
|
1791
1966
|
series: {
|
|
1792
|
-
metadata: async
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
} = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
1967
|
+
metadata: async ({
|
|
1968
|
+
StudyInstanceUID,
|
|
1969
|
+
madeInClient = false
|
|
1970
|
+
} = {}) => {
|
|
1797
1971
|
if (!StudyInstanceUID) {
|
|
1798
1972
|
throw new Error('Unable to query for SeriesMetadata without StudyInstanceUID');
|
|
1799
1973
|
}
|
|
@@ -1872,11 +2046,10 @@ function createDicomLocalApi(dicomLocalConfig) {
|
|
|
1872
2046
|
});
|
|
1873
2047
|
return imageIds;
|
|
1874
2048
|
},
|
|
1875
|
-
getImageIdsForInstance(
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
} = _ref2;
|
|
2049
|
+
getImageIdsForInstance({
|
|
2050
|
+
instance,
|
|
2051
|
+
frame
|
|
2052
|
+
}) {
|
|
1880
2053
|
const {
|
|
1881
2054
|
StudyInstanceUID,
|
|
1882
2055
|
SeriesInstanceUID,
|
|
@@ -1892,11 +2065,10 @@ function createDicomLocalApi(dicomLocalConfig) {
|
|
|
1892
2065
|
deleteStudyMetadataPromise() {
|
|
1893
2066
|
console.log('deleteStudyMetadataPromise not implemented');
|
|
1894
2067
|
},
|
|
1895
|
-
getStudyInstanceUIDs:
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
} = _ref3;
|
|
2068
|
+
getStudyInstanceUIDs: ({
|
|
2069
|
+
params,
|
|
2070
|
+
query
|
|
2071
|
+
}) => {
|
|
1900
2072
|
const {
|
|
1901
2073
|
StudyInstanceUIDs: paramsStudyInstanceUIDs
|
|
1902
2074
|
} = params;
|
|
@@ -1931,17 +2103,16 @@ function createDicomLocalApi(dicomLocalConfig) {
|
|
|
1931
2103
|
* dicomWeb configuration array
|
|
1932
2104
|
*
|
|
1933
2105
|
*/
|
|
1934
|
-
function createDicomWebProxyApi(dicomWebProxyConfig,
|
|
2106
|
+
function createDicomWebProxyApi(dicomWebProxyConfig, servicesManager) {
|
|
1935
2107
|
const {
|
|
1936
2108
|
name
|
|
1937
2109
|
} = dicomWebProxyConfig;
|
|
1938
2110
|
let dicomWebDelegate = undefined;
|
|
1939
2111
|
const implementation = {
|
|
1940
|
-
initialize: async
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
} = _ref;
|
|
2112
|
+
initialize: async ({
|
|
2113
|
+
params,
|
|
2114
|
+
query
|
|
2115
|
+
}) => {
|
|
1945
2116
|
const url = query.get('url');
|
|
1946
2117
|
if (!url) {
|
|
1947
2118
|
throw new Error(`No url for '${name}'`);
|
|
@@ -1951,7 +2122,7 @@ function createDicomWebProxyApi(dicomWebProxyConfig, UserAuthenticationService)
|
|
|
1951
2122
|
if (!data.servers?.dicomWeb?.[0]) {
|
|
1952
2123
|
throw new Error('Invalid configuration returned by url');
|
|
1953
2124
|
}
|
|
1954
|
-
dicomWebDelegate = createDicomWebApi(data.servers.dicomWeb[0].configuration,
|
|
2125
|
+
dicomWebDelegate = createDicomWebApi(data.servers.dicomWeb[0].configuration, servicesManager);
|
|
1955
2126
|
dicomWebDelegate.initialize({
|
|
1956
2127
|
params,
|
|
1957
2128
|
query
|
|
@@ -1963,43 +2134,28 @@ function createDicomWebProxyApi(dicomWebProxyConfig, UserAuthenticationService)
|
|
|
1963
2134
|
search: params => dicomWebDelegate.query.studies.search(params)
|
|
1964
2135
|
},
|
|
1965
2136
|
series: {
|
|
1966
|
-
search:
|
|
1967
|
-
return dicomWebDelegate.query.series.search(...arguments);
|
|
1968
|
-
}
|
|
2137
|
+
search: (...args) => dicomWebDelegate.query.series.search(...args)
|
|
1969
2138
|
},
|
|
1970
2139
|
instances: {
|
|
1971
2140
|
search: (studyInstanceUid, queryParameters) => dicomWebDelegate.query.instances.search(studyInstanceUid, queryParameters)
|
|
1972
2141
|
}
|
|
1973
2142
|
},
|
|
1974
2143
|
retrieve: {
|
|
1975
|
-
directURL:
|
|
1976
|
-
return dicomWebDelegate.retrieve.directURL(...arguments);
|
|
1977
|
-
},
|
|
2144
|
+
directURL: (...args) => dicomWebDelegate.retrieve.directURL(...args),
|
|
1978
2145
|
series: {
|
|
1979
|
-
metadata: async
|
|
1980
|
-
return dicomWebDelegate.retrieve.series.metadata(...arguments);
|
|
1981
|
-
}
|
|
2146
|
+
metadata: async (...args) => dicomWebDelegate.retrieve.series.metadata(...args)
|
|
1982
2147
|
}
|
|
1983
2148
|
},
|
|
1984
2149
|
store: {
|
|
1985
|
-
dicom:
|
|
1986
|
-
return dicomWebDelegate.store(...arguments);
|
|
1987
|
-
}
|
|
1988
|
-
},
|
|
1989
|
-
deleteStudyMetadataPromise: function () {
|
|
1990
|
-
return dicomWebDelegate.deleteStudyMetadataPromise(...arguments);
|
|
2150
|
+
dicom: (...args) => dicomWebDelegate.store(...args)
|
|
1991
2151
|
},
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
let {
|
|
2000
|
-
params,
|
|
2001
|
-
query
|
|
2002
|
-
} = _ref2;
|
|
2152
|
+
deleteStudyMetadataPromise: (...args) => dicomWebDelegate.deleteStudyMetadataPromise(...args),
|
|
2153
|
+
getImageIdsForDisplaySet: (...args) => dicomWebDelegate.getImageIdsForDisplaySet(...args),
|
|
2154
|
+
getImageIdsForInstance: (...args) => dicomWebDelegate.getImageIdsForInstance(...args),
|
|
2155
|
+
getStudyInstanceUIDs({
|
|
2156
|
+
params,
|
|
2157
|
+
query
|
|
2158
|
+
}) {
|
|
2003
2159
|
let studyInstanceUIDs = [];
|
|
2004
2160
|
|
|
2005
2161
|
// there seem to be a couple of variations of the case for this parameter
|
|
@@ -2014,6 +2170,250 @@ function createDicomWebProxyApi(dicomWebProxyConfig, UserAuthenticationService)
|
|
|
2014
2170
|
return src/* IWebApiDataSource */.Is.create(implementation);
|
|
2015
2171
|
}
|
|
2016
2172
|
|
|
2173
|
+
// EXTERNAL MODULE: ../../../node_modules/lodash/lodash.js
|
|
2174
|
+
var lodash = __webpack_require__(44379);
|
|
2175
|
+
;// CONCATENATED MODULE: ../../../extensions/default/src/MergeDataSource/index.ts
|
|
2176
|
+
|
|
2177
|
+
|
|
2178
|
+
const mergeMap = {
|
|
2179
|
+
'query.studies.search': {
|
|
2180
|
+
mergeKey: 'studyInstanceUid',
|
|
2181
|
+
tagFunc: x => x
|
|
2182
|
+
},
|
|
2183
|
+
'query.series.search': {
|
|
2184
|
+
mergeKey: 'seriesInstanceUid',
|
|
2185
|
+
tagFunc: (series, sourceName) => {
|
|
2186
|
+
series.forEach(series => {
|
|
2187
|
+
series.RetrieveAETitle = sourceName;
|
|
2188
|
+
src.DicomMetadataStore.updateSeriesMetadata(series);
|
|
2189
|
+
});
|
|
2190
|
+
return series;
|
|
2191
|
+
}
|
|
2192
|
+
}
|
|
2193
|
+
};
|
|
2194
|
+
|
|
2195
|
+
/**
|
|
2196
|
+
* Calls all data sources asynchronously and merges the results.
|
|
2197
|
+
* @param {CallForAllDataSourcesAsyncOptions} options - The options for calling all data sources.
|
|
2198
|
+
* @param {string} options.path - The path to the function to be called on each data source.
|
|
2199
|
+
* @param {unknown[]} options.args - The arguments to be passed to the function.
|
|
2200
|
+
* @param {ExtensionManager} options.extensionManager - The extension manager.
|
|
2201
|
+
* @param {string[]} options.dataSourceNames - The names of the data sources to be called.
|
|
2202
|
+
* @returns {Promise<unknown[]>} - A promise that resolves to the merged data from all data sources.
|
|
2203
|
+
*/
|
|
2204
|
+
const callForAllDataSourcesAsync = async ({
|
|
2205
|
+
mergeMap,
|
|
2206
|
+
path,
|
|
2207
|
+
args,
|
|
2208
|
+
extensionManager,
|
|
2209
|
+
dataSourceNames
|
|
2210
|
+
}) => {
|
|
2211
|
+
const {
|
|
2212
|
+
mergeKey,
|
|
2213
|
+
tagFunc
|
|
2214
|
+
} = mergeMap[path] || {
|
|
2215
|
+
tagFunc: x => x
|
|
2216
|
+
};
|
|
2217
|
+
const dataSourceDefs = Object.values(extensionManager.dataSourceDefs);
|
|
2218
|
+
const promises = [];
|
|
2219
|
+
const mergedData = [];
|
|
2220
|
+
for (const dataSourceDef of dataSourceDefs) {
|
|
2221
|
+
const {
|
|
2222
|
+
configuration,
|
|
2223
|
+
sourceName
|
|
2224
|
+
} = dataSourceDef;
|
|
2225
|
+
if (!!configuration && dataSourceNames.includes(sourceName)) {
|
|
2226
|
+
const [dataSource] = extensionManager.getDataSources(sourceName);
|
|
2227
|
+
const func = (0,lodash.get)(dataSource, path);
|
|
2228
|
+
const promise = func.apply(dataSource, args);
|
|
2229
|
+
promises.push(promise.then(data => mergedData.push(tagFunc(data, sourceName))));
|
|
2230
|
+
}
|
|
2231
|
+
}
|
|
2232
|
+
await Promise.allSettled(promises);
|
|
2233
|
+
let results = [];
|
|
2234
|
+
if (mergeKey) {
|
|
2235
|
+
results = (0,lodash.uniqBy)(mergedData.flat(), obj => (0,lodash.get)(obj, mergeKey));
|
|
2236
|
+
} else {
|
|
2237
|
+
results = mergedData.flat();
|
|
2238
|
+
}
|
|
2239
|
+
return results;
|
|
2240
|
+
};
|
|
2241
|
+
|
|
2242
|
+
/**
|
|
2243
|
+
* Calls all data sources that match the provided names and merges their data.
|
|
2244
|
+
* @param options - The options for calling all data sources.
|
|
2245
|
+
* @param options.path - The path to the function to be called on each data source.
|
|
2246
|
+
* @param options.args - The arguments to be passed to the function.
|
|
2247
|
+
* @param options.extensionManager - The extension manager instance.
|
|
2248
|
+
* @param options.dataSourceNames - The names of the data sources to be called.
|
|
2249
|
+
* @returns The merged data from all the matching data sources.
|
|
2250
|
+
*/
|
|
2251
|
+
const callForAllDataSources = ({
|
|
2252
|
+
path,
|
|
2253
|
+
args,
|
|
2254
|
+
extensionManager,
|
|
2255
|
+
dataSourceNames
|
|
2256
|
+
}) => {
|
|
2257
|
+
const dataSourceDefs = Object.values(extensionManager.dataSourceDefs);
|
|
2258
|
+
const mergedData = [];
|
|
2259
|
+
for (const dataSourceDef of dataSourceDefs) {
|
|
2260
|
+
const {
|
|
2261
|
+
configuration,
|
|
2262
|
+
sourceName
|
|
2263
|
+
} = dataSourceDef;
|
|
2264
|
+
if (!!configuration && dataSourceNames.includes(sourceName)) {
|
|
2265
|
+
const [dataSource] = extensionManager.getDataSources(sourceName);
|
|
2266
|
+
const func = (0,lodash.get)(dataSource, path);
|
|
2267
|
+
const data = func.apply(dataSource, args);
|
|
2268
|
+
mergedData.push(data);
|
|
2269
|
+
}
|
|
2270
|
+
}
|
|
2271
|
+
return mergedData.flat();
|
|
2272
|
+
};
|
|
2273
|
+
|
|
2274
|
+
/**
|
|
2275
|
+
* Calls the default data source function specified by the given path with the provided arguments.
|
|
2276
|
+
* @param {CallForDefaultDataSourceOptions} options - The options for calling the default data source.
|
|
2277
|
+
* @param {string} options.path - The path to the function within the default data source.
|
|
2278
|
+
* @param {unknown[]} options.args - The arguments to pass to the function.
|
|
2279
|
+
* @param {string} options.defaultDataSourceName - The name of the default data source.
|
|
2280
|
+
* @param {ExtensionManager} options.extensionManager - The extension manager instance.
|
|
2281
|
+
* @returns {unknown} - The result of calling the default data source function.
|
|
2282
|
+
*/
|
|
2283
|
+
const callForDefaultDataSource = ({
|
|
2284
|
+
path,
|
|
2285
|
+
args,
|
|
2286
|
+
defaultDataSourceName,
|
|
2287
|
+
extensionManager
|
|
2288
|
+
}) => {
|
|
2289
|
+
const [dataSource] = extensionManager.getDataSources(defaultDataSourceName);
|
|
2290
|
+
const func = (0,lodash.get)(dataSource, path);
|
|
2291
|
+
return func.apply(dataSource, args);
|
|
2292
|
+
};
|
|
2293
|
+
|
|
2294
|
+
/**
|
|
2295
|
+
* Calls the data source specified by the RetrieveAETitle of the given display set.
|
|
2296
|
+
* @typedef {Object} CallByRetrieveAETitleOptions
|
|
2297
|
+
* @property {string} path - The path of the method to call on the data source.
|
|
2298
|
+
* @property {unknown[]} args - The arguments to pass to the method.
|
|
2299
|
+
* @property {string} defaultDataSourceName - The name of the default data source.
|
|
2300
|
+
* @property {ExtensionManager} extensionManager - The extension manager.
|
|
2301
|
+
*/
|
|
2302
|
+
const callByRetrieveAETitle = ({
|
|
2303
|
+
path,
|
|
2304
|
+
args,
|
|
2305
|
+
defaultDataSourceName,
|
|
2306
|
+
extensionManager
|
|
2307
|
+
}) => {
|
|
2308
|
+
const [displaySet] = args;
|
|
2309
|
+
const seriesMetadata = src.DicomMetadataStore.getSeries(displaySet.StudyInstanceUID, displaySet.SeriesInstanceUID);
|
|
2310
|
+
const [dataSource] = extensionManager.getDataSources(seriesMetadata.RetrieveAETitle || defaultDataSourceName);
|
|
2311
|
+
return dataSource[path](...args);
|
|
2312
|
+
};
|
|
2313
|
+
function createMergeDataSourceApi(mergeConfig, servicesManager, extensionManager) {
|
|
2314
|
+
const {
|
|
2315
|
+
seriesMerge
|
|
2316
|
+
} = mergeConfig;
|
|
2317
|
+
const {
|
|
2318
|
+
dataSourceNames,
|
|
2319
|
+
defaultDataSourceName
|
|
2320
|
+
} = seriesMerge;
|
|
2321
|
+
const implementation = {
|
|
2322
|
+
initialize: (...args) => callForAllDataSources({
|
|
2323
|
+
path: 'initialize',
|
|
2324
|
+
args,
|
|
2325
|
+
extensionManager,
|
|
2326
|
+
dataSourceNames
|
|
2327
|
+
}),
|
|
2328
|
+
query: {
|
|
2329
|
+
studies: {
|
|
2330
|
+
search: (...args) => callForAllDataSourcesAsync({
|
|
2331
|
+
mergeMap,
|
|
2332
|
+
path: 'query.studies.search',
|
|
2333
|
+
args,
|
|
2334
|
+
extensionManager,
|
|
2335
|
+
dataSourceNames
|
|
2336
|
+
})
|
|
2337
|
+
},
|
|
2338
|
+
series: {
|
|
2339
|
+
search: (...args) => callForAllDataSourcesAsync({
|
|
2340
|
+
mergeMap,
|
|
2341
|
+
path: 'query.series.search',
|
|
2342
|
+
args,
|
|
2343
|
+
extensionManager,
|
|
2344
|
+
dataSourceNames
|
|
2345
|
+
})
|
|
2346
|
+
},
|
|
2347
|
+
instances: {
|
|
2348
|
+
search: (...args) => callForAllDataSourcesAsync({
|
|
2349
|
+
mergeMap,
|
|
2350
|
+
path: 'query.instances.search',
|
|
2351
|
+
args,
|
|
2352
|
+
extensionManager,
|
|
2353
|
+
dataSourceNames
|
|
2354
|
+
})
|
|
2355
|
+
}
|
|
2356
|
+
},
|
|
2357
|
+
retrieve: {
|
|
2358
|
+
bulkDataURI: (...args) => callForAllDataSourcesAsync({
|
|
2359
|
+
mergeMap,
|
|
2360
|
+
path: 'retrieve.bulkDataURI',
|
|
2361
|
+
args,
|
|
2362
|
+
extensionManager,
|
|
2363
|
+
dataSourceNames
|
|
2364
|
+
}),
|
|
2365
|
+
directURL: (...args) => callForDefaultDataSource({
|
|
2366
|
+
path: 'retrieve.directURL',
|
|
2367
|
+
args,
|
|
2368
|
+
defaultDataSourceName,
|
|
2369
|
+
extensionManager
|
|
2370
|
+
}),
|
|
2371
|
+
series: {
|
|
2372
|
+
metadata: (...args) => callForAllDataSourcesAsync({
|
|
2373
|
+
mergeMap,
|
|
2374
|
+
path: 'retrieve.series.metadata',
|
|
2375
|
+
args,
|
|
2376
|
+
extensionManager,
|
|
2377
|
+
dataSourceNames
|
|
2378
|
+
})
|
|
2379
|
+
}
|
|
2380
|
+
},
|
|
2381
|
+
store: {
|
|
2382
|
+
dicom: (...args) => callForDefaultDataSource({
|
|
2383
|
+
path: 'store.dicom',
|
|
2384
|
+
args,
|
|
2385
|
+
defaultDataSourceName,
|
|
2386
|
+
extensionManager
|
|
2387
|
+
})
|
|
2388
|
+
},
|
|
2389
|
+
deleteStudyMetadataPromise: (...args) => callForAllDataSources({
|
|
2390
|
+
path: 'deleteStudyMetadataPromise',
|
|
2391
|
+
args,
|
|
2392
|
+
extensionManager,
|
|
2393
|
+
dataSourceNames
|
|
2394
|
+
}),
|
|
2395
|
+
getImageIdsForDisplaySet: (...args) => callByRetrieveAETitle({
|
|
2396
|
+
path: 'getImageIdsForDisplaySet',
|
|
2397
|
+
args,
|
|
2398
|
+
defaultDataSourceName,
|
|
2399
|
+
extensionManager
|
|
2400
|
+
}),
|
|
2401
|
+
getImageIdsForInstance: (...args) => callByRetrieveAETitle({
|
|
2402
|
+
path: 'getImageIdsForDisplaySet',
|
|
2403
|
+
args,
|
|
2404
|
+
defaultDataSourceName,
|
|
2405
|
+
extensionManager
|
|
2406
|
+
}),
|
|
2407
|
+
getStudyInstanceUIDs: (...args) => callForAllDataSources({
|
|
2408
|
+
path: 'getStudyInstanceUIDs',
|
|
2409
|
+
args,
|
|
2410
|
+
extensionManager,
|
|
2411
|
+
dataSourceNames
|
|
2412
|
+
})
|
|
2413
|
+
};
|
|
2414
|
+
return src/* IWebApiDataSource */.Is.create(implementation);
|
|
2415
|
+
}
|
|
2416
|
+
|
|
2017
2417
|
;// CONCATENATED MODULE: ../../../extensions/default/src/getDataSourcesModule.js
|
|
2018
2418
|
// TODO: Pull in IWebClientApi from @ohif/core
|
|
2019
2419
|
// TODO: Use constructor to create an instance of IWebClientApi
|
|
@@ -2024,6 +2424,7 @@ function createDicomWebProxyApi(dicomWebProxyConfig, UserAuthenticationService)
|
|
|
2024
2424
|
|
|
2025
2425
|
|
|
2026
2426
|
|
|
2427
|
+
|
|
2027
2428
|
/**
|
|
2028
2429
|
*
|
|
2029
2430
|
*/
|
|
@@ -2044,6 +2445,10 @@ function getDataSourcesModule() {
|
|
|
2044
2445
|
name: 'dicomlocal',
|
|
2045
2446
|
type: 'localApi',
|
|
2046
2447
|
createDataSource: createDicomLocalApi
|
|
2448
|
+
}, {
|
|
2449
|
+
name: 'merge',
|
|
2450
|
+
type: 'mergeApi',
|
|
2451
|
+
createDataSource: createMergeDataSourceApi
|
|
2047
2452
|
}];
|
|
2048
2453
|
}
|
|
2049
2454
|
/* harmony default export */ const src_getDataSourcesModule = (getDataSourcesModule);
|
|
@@ -2052,8 +2457,8 @@ var react = __webpack_require__(43001);
|
|
|
2052
2457
|
// EXTERNAL MODULE: ../../../node_modules/prop-types/index.js
|
|
2053
2458
|
var prop_types = __webpack_require__(3827);
|
|
2054
2459
|
var prop_types_default = /*#__PURE__*/__webpack_require__.n(prop_types);
|
|
2055
|
-
// EXTERNAL MODULE: ../../ui/src/index.js +
|
|
2056
|
-
var ui_src = __webpack_require__(
|
|
2460
|
+
// EXTERNAL MODULE: ../../ui/src/index.js + 487 modules
|
|
2461
|
+
var ui_src = __webpack_require__(18414);
|
|
2057
2462
|
// EXTERNAL MODULE: ./state/index.js + 1 modules
|
|
2058
2463
|
var state = __webpack_require__(62657);
|
|
2059
2464
|
// EXTERNAL MODULE: ../node_modules/react-router-dom/dist/index.js
|
|
@@ -2062,31 +2467,37 @@ var dist = __webpack_require__(62474);
|
|
|
2062
2467
|
var es = __webpack_require__(69190);
|
|
2063
2468
|
// EXTERNAL MODULE: ../node_modules/react-router/dist/index.js
|
|
2064
2469
|
var react_router_dist = __webpack_require__(85066);
|
|
2065
|
-
// EXTERNAL MODULE: ../../i18n/src/index.js +
|
|
2066
|
-
var i18n_src = __webpack_require__(
|
|
2470
|
+
// EXTERNAL MODULE: ../../i18n/src/index.js + 148 modules
|
|
2471
|
+
var i18n_src = __webpack_require__(68311);
|
|
2067
2472
|
// EXTERNAL MODULE: ../../../node_modules/classnames/index.js
|
|
2068
|
-
var classnames = __webpack_require__(
|
|
2473
|
+
var classnames = __webpack_require__(33901);
|
|
2069
2474
|
var classnames_default = /*#__PURE__*/__webpack_require__.n(classnames);
|
|
2070
2475
|
;// CONCATENATED MODULE: ../../../extensions/default/src/Toolbar/Toolbar.tsx
|
|
2071
2476
|
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
|
2072
2477
|
|
|
2073
2478
|
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2479
|
+
|
|
2480
|
+
function Toolbar({
|
|
2481
|
+
servicesManager
|
|
2482
|
+
}) {
|
|
2078
2483
|
const {
|
|
2079
2484
|
toolbarService
|
|
2080
2485
|
} = servicesManager.services;
|
|
2486
|
+
const [viewportGrid, viewportGridService] = (0,ui_src/* useViewportGrid */.O_)();
|
|
2081
2487
|
const [toolbarButtons, setToolbarButtons] = (0,react.useState)([]);
|
|
2082
2488
|
(0,react.useEffect)(() => {
|
|
2489
|
+
const updateToolbar = () => {
|
|
2490
|
+
const toolGroupId = viewportGridService.getActiveViewportOptionByKey('toolGroupId') ?? 'default';
|
|
2491
|
+
setToolbarButtons(toolbarService.getButtonSection(toolGroupId));
|
|
2492
|
+
};
|
|
2083
2493
|
const {
|
|
2084
2494
|
unsubscribe
|
|
2085
|
-
} = toolbarService.subscribe(toolbarService.EVENTS.TOOL_BAR_MODIFIED,
|
|
2495
|
+
} = toolbarService.subscribe(toolbarService.EVENTS.TOOL_BAR_MODIFIED, updateToolbar);
|
|
2496
|
+
updateToolbar();
|
|
2086
2497
|
return () => {
|
|
2087
2498
|
unsubscribe();
|
|
2088
2499
|
};
|
|
2089
|
-
}, [toolbarService]);
|
|
2500
|
+
}, [toolbarService, viewportGrid]);
|
|
2090
2501
|
const onInteraction = (0,react.useCallback)(args => toolbarService.recordInteraction(args), [toolbarService]);
|
|
2091
2502
|
return /*#__PURE__*/react.createElement(react.Fragment, null, toolbarButtons.map(toolDef => {
|
|
2092
2503
|
const {
|
|
@@ -2125,12 +2536,11 @@ const {
|
|
|
2125
2536
|
defaultLanguage,
|
|
2126
2537
|
currentLanguage
|
|
2127
2538
|
} = i18n_src["default"];
|
|
2128
|
-
function ViewerHeader(
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
} = _ref;
|
|
2539
|
+
function ViewerHeader({
|
|
2540
|
+
hotkeysManager,
|
|
2541
|
+
extensionManager,
|
|
2542
|
+
servicesManager
|
|
2543
|
+
}) {
|
|
2134
2544
|
const [appConfig] = (0,state/* useAppConfig */.M)();
|
|
2135
2545
|
const navigate = (0,dist/* useNavigate */.s0)();
|
|
2136
2546
|
const location = (0,react_router_dist/* useLocation */.TH)();
|
|
@@ -2166,14 +2576,14 @@ function ViewerHeader(_ref) {
|
|
|
2166
2576
|
hotkeyDefinitions,
|
|
2167
2577
|
hotkeyDefaults
|
|
2168
2578
|
} = hotkeysManager;
|
|
2169
|
-
const versionNumber = "3.8.0-beta.
|
|
2170
|
-
const commitHash = "
|
|
2579
|
+
const versionNumber = "3.8.0-beta.51";
|
|
2580
|
+
const commitHash = "a47aeb8bd729dcb8d2cfc13b27a31b0dd88f11ad";
|
|
2171
2581
|
const menuOptions = [{
|
|
2172
2582
|
title: t('Header:About'),
|
|
2173
2583
|
icon: 'info',
|
|
2174
2584
|
onClick: () => show({
|
|
2175
2585
|
content: ui_src/* AboutModal */.tk,
|
|
2176
|
-
title: 'About OHIF Viewer',
|
|
2586
|
+
title: t('AboutModal:About OHIF Viewer'),
|
|
2177
2587
|
contentProps: {
|
|
2178
2588
|
versionNumber,
|
|
2179
2589
|
commitHash
|
|
@@ -2183,7 +2593,7 @@ function ViewerHeader(_ref) {
|
|
|
2183
2593
|
title: t('Header:Preferences'),
|
|
2184
2594
|
icon: 'settings',
|
|
2185
2595
|
onClick: () => show({
|
|
2186
|
-
title: t('UserPreferencesModal:User
|
|
2596
|
+
title: t('UserPreferencesModal:User preferences'),
|
|
2187
2597
|
content: ui_src/* UserPreferences */.i1,
|
|
2188
2598
|
contentProps: {
|
|
2189
2599
|
hotkeyDefaults: hotkeysManager.getValidHotkeyDefinitions(hotkeyDefaults),
|
|
@@ -2196,11 +2606,10 @@ function ViewerHeader(_ref) {
|
|
|
2196
2606
|
src/* hotkeys */.dD.unpause();
|
|
2197
2607
|
hide();
|
|
2198
2608
|
},
|
|
2199
|
-
onSubmit:
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
} = _ref2;
|
|
2609
|
+
onSubmit: ({
|
|
2610
|
+
hotkeyDefinitions,
|
|
2611
|
+
language
|
|
2612
|
+
}) => {
|
|
2204
2613
|
if (language.value !== currentLanguage().value) {
|
|
2205
2614
|
i18n_src["default"].changeLanguage(language.value);
|
|
2206
2615
|
}
|
|
@@ -2238,14 +2647,14 @@ function ViewerHeader(_ref) {
|
|
|
2238
2647
|
;// CONCATENATED MODULE: ../../../extensions/default/src/Components/SidePanelWithServices.tsx
|
|
2239
2648
|
|
|
2240
2649
|
|
|
2241
|
-
const SidePanelWithServices =
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2650
|
+
const SidePanelWithServices = ({
|
|
2651
|
+
servicesManager,
|
|
2652
|
+
side,
|
|
2653
|
+
className,
|
|
2654
|
+
activeTabIndex: activeTabIndexProp,
|
|
2655
|
+
tabs,
|
|
2656
|
+
expandedWidth
|
|
2657
|
+
}) => {
|
|
2249
2658
|
const panelService = servicesManager?.services?.panelService;
|
|
2250
2659
|
|
|
2251
2660
|
// Tracks whether this SidePanel has been opened at least once since this SidePanel was inserted into the DOM.
|
|
@@ -2274,7 +2683,8 @@ const SidePanelWithServices = _ref => {
|
|
|
2274
2683
|
tabs: tabs,
|
|
2275
2684
|
onOpen: () => {
|
|
2276
2685
|
setHasBeenOpened(true);
|
|
2277
|
-
}
|
|
2686
|
+
},
|
|
2687
|
+
expandedWidth: expandedWidth
|
|
2278
2688
|
});
|
|
2279
2689
|
};
|
|
2280
2690
|
/* harmony default export */ const Components_SidePanelWithServices = (SidePanelWithServices);
|
|
@@ -2286,21 +2696,20 @@ const SidePanelWithServices = _ref => {
|
|
|
2286
2696
|
|
|
2287
2697
|
|
|
2288
2698
|
|
|
2289
|
-
function ViewerLayout(
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
} = _ref;
|
|
2699
|
+
function ViewerLayout({
|
|
2700
|
+
// From Extension Module Params
|
|
2701
|
+
extensionManager,
|
|
2702
|
+
servicesManager,
|
|
2703
|
+
hotkeysManager,
|
|
2704
|
+
commandsManager,
|
|
2705
|
+
// From Modes
|
|
2706
|
+
viewports,
|
|
2707
|
+
ViewportGridComp,
|
|
2708
|
+
leftPanels = [],
|
|
2709
|
+
rightPanels = [],
|
|
2710
|
+
leftPanelDefaultClosed = false,
|
|
2711
|
+
rightPanelDefaultClosed = false
|
|
2712
|
+
}) {
|
|
2304
2713
|
const [appConfig] = (0,state/* useAppConfig */.M)();
|
|
2305
2714
|
const {
|
|
2306
2715
|
hangingProtocolService
|
|
@@ -2438,13 +2847,12 @@ ViewerLayout.propTypes = {
|
|
|
2438
2847
|
- Init layout based on the displaySets and the objects.
|
|
2439
2848
|
*/
|
|
2440
2849
|
|
|
2441
|
-
/* harmony default export */ function getLayoutTemplateModule(
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
} = _ref;
|
|
2850
|
+
/* harmony default export */ function getLayoutTemplateModule({
|
|
2851
|
+
servicesManager,
|
|
2852
|
+
extensionManager,
|
|
2853
|
+
commandsManager,
|
|
2854
|
+
hotkeysManager
|
|
2855
|
+
}) {
|
|
2448
2856
|
function ViewerLayoutWithServices(props) {
|
|
2449
2857
|
return src_ViewerLayout({
|
|
2450
2858
|
servicesManager,
|
|
@@ -2478,14 +2886,13 @@ const {
|
|
|
2478
2886
|
*
|
|
2479
2887
|
* @param {*} param0
|
|
2480
2888
|
*/
|
|
2481
|
-
function PanelStudyBrowser(
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
} = _ref;
|
|
2889
|
+
function PanelStudyBrowser({
|
|
2890
|
+
servicesManager,
|
|
2891
|
+
getImageSrc,
|
|
2892
|
+
getStudiesForPatientByMRN,
|
|
2893
|
+
requestDisplaySetCreationForStudy,
|
|
2894
|
+
dataSource
|
|
2895
|
+
}) {
|
|
2489
2896
|
const {
|
|
2490
2897
|
hangingProtocolService,
|
|
2491
2898
|
displaySetService,
|
|
@@ -2738,7 +3145,6 @@ function _mapDisplaySets(displaySets, thumbnailImageSrcMap) {
|
|
|
2738
3145
|
displaySetInstanceUID: ds.displaySetInstanceUID
|
|
2739
3146
|
// .. Any other data to pass
|
|
2740
3147
|
},
|
|
2741
|
-
|
|
2742
3148
|
isHydratedForDerivedDisplaySet: ds.isHydrated
|
|
2743
3149
|
});
|
|
2744
3150
|
});
|
|
@@ -2853,17 +3259,16 @@ function requestDisplaySetCreationForStudy(dataSource, displaySetService, StudyI
|
|
|
2853
3259
|
* @param {object} commandsManager
|
|
2854
3260
|
* @param {object} extensionManager
|
|
2855
3261
|
*/
|
|
2856
|
-
function WrappedPanelStudyBrowser(
|
|
2857
|
-
|
|
2858
|
-
|
|
2859
|
-
|
|
2860
|
-
|
|
2861
|
-
} = _ref;
|
|
3262
|
+
function WrappedPanelStudyBrowser({
|
|
3263
|
+
commandsManager,
|
|
3264
|
+
extensionManager,
|
|
3265
|
+
servicesManager
|
|
3266
|
+
}) {
|
|
2862
3267
|
// TODO: This should be made available a different way; route should have
|
|
2863
3268
|
// already determined our datasource
|
|
2864
3269
|
const dataSource = extensionManager.getDataSources()[0];
|
|
2865
3270
|
const _getStudiesForPatientByMRN = Panels_getStudiesForPatientByMRN.bind(null, dataSource);
|
|
2866
|
-
const _getImageSrcFromImageId = _createGetImageSrcFromImageIdFn(extensionManager);
|
|
3271
|
+
const _getImageSrcFromImageId = (0,react.useCallback)(_createGetImageSrcFromImageIdFn(extensionManager), []);
|
|
2867
3272
|
const _requestDisplaySetCreationForStudy = Panels_requestDisplaySetCreationForStudy.bind(null, dataSource);
|
|
2868
3273
|
return /*#__PURE__*/react.createElement(Panels_PanelStudyBrowser, {
|
|
2869
3274
|
servicesManager: servicesManager,
|
|
@@ -2905,11 +3310,10 @@ WrappedPanelStudyBrowser.propTypes = {
|
|
|
2905
3310
|
|
|
2906
3311
|
|
|
2907
3312
|
|
|
2908
|
-
function ActionButtons(
|
|
2909
|
-
|
|
2910
|
-
|
|
2911
|
-
|
|
2912
|
-
} = _ref;
|
|
3313
|
+
function ActionButtons({
|
|
3314
|
+
onExportClick,
|
|
3315
|
+
onCreateReportClick
|
|
3316
|
+
}) {
|
|
2913
3317
|
const {
|
|
2914
3318
|
t
|
|
2915
3319
|
} = (0,es/* useTranslation */.$G)('MeasurementTable');
|
|
@@ -2943,10 +3347,9 @@ const CREATE_REPORT_DIALOG_RESPONSE = {
|
|
|
2943
3347
|
CANCEL: 0,
|
|
2944
3348
|
CREATE_REPORT: 1
|
|
2945
3349
|
};
|
|
2946
|
-
function CreateReportDialogPrompt(uiDialogService,
|
|
2947
|
-
|
|
2948
|
-
|
|
2949
|
-
} = _ref;
|
|
3350
|
+
function CreateReportDialogPrompt(uiDialogService, {
|
|
3351
|
+
extensionManager
|
|
3352
|
+
}) {
|
|
2950
3353
|
return new Promise(function (resolve, reject) {
|
|
2951
3354
|
let dialogId = undefined;
|
|
2952
3355
|
const _handleClose = () => {
|
|
@@ -2967,11 +3370,10 @@ function CreateReportDialogPrompt(uiDialogService, _ref) {
|
|
|
2967
3370
|
* @param {string} param0.action - value of action performed
|
|
2968
3371
|
* @param {string} param0.value - value from input field
|
|
2969
3372
|
*/
|
|
2970
|
-
const _handleFormSubmit =
|
|
2971
|
-
|
|
2972
|
-
|
|
2973
|
-
|
|
2974
|
-
} = _ref2;
|
|
3373
|
+
const _handleFormSubmit = ({
|
|
3374
|
+
action,
|
|
3375
|
+
value
|
|
3376
|
+
}) => {
|
|
2975
3377
|
uiDialogService.dismiss({
|
|
2976
3378
|
id: dialogId
|
|
2977
3379
|
});
|
|
@@ -3028,11 +3430,10 @@ function CreateReportDialogPrompt(uiDialogService, _ref) {
|
|
|
3028
3430
|
}],
|
|
3029
3431
|
// TODO: Should be on button press...
|
|
3030
3432
|
onSubmit: _handleFormSubmit,
|
|
3031
|
-
body:
|
|
3032
|
-
|
|
3033
|
-
|
|
3034
|
-
|
|
3035
|
-
} = _ref3;
|
|
3433
|
+
body: ({
|
|
3434
|
+
value,
|
|
3435
|
+
setValue
|
|
3436
|
+
}) => {
|
|
3036
3437
|
const onChangeHandler = event => {
|
|
3037
3438
|
event.persist();
|
|
3038
3439
|
setValue(value => ({
|
|
@@ -3092,12 +3493,11 @@ function CreateReportDialogPrompt(uiDialogService, _ref) {
|
|
|
3092
3493
|
*
|
|
3093
3494
|
* @param {*} servicesManager
|
|
3094
3495
|
*/
|
|
3095
|
-
async function createReportAsync(
|
|
3096
|
-
|
|
3097
|
-
|
|
3098
|
-
|
|
3099
|
-
|
|
3100
|
-
} = _ref;
|
|
3496
|
+
async function createReportAsync({
|
|
3497
|
+
servicesManager,
|
|
3498
|
+
getReport,
|
|
3499
|
+
reportType = 'measurement'
|
|
3500
|
+
}) {
|
|
3101
3501
|
const {
|
|
3102
3502
|
displaySetService,
|
|
3103
3503
|
uiNotificationService,
|
|
@@ -3208,15 +3608,18 @@ function findSRWithSameSeriesDescription(SeriesDescription, displaySetService) {
|
|
|
3208
3608
|
|
|
3209
3609
|
|
|
3210
3610
|
|
|
3611
|
+
|
|
3211
3612
|
const {
|
|
3212
3613
|
downloadCSVReport
|
|
3213
3614
|
} = src.utils;
|
|
3214
|
-
function PanelMeasurementTable(
|
|
3215
|
-
|
|
3216
|
-
|
|
3217
|
-
|
|
3218
|
-
|
|
3219
|
-
|
|
3615
|
+
function PanelMeasurementTable({
|
|
3616
|
+
servicesManager,
|
|
3617
|
+
commandsManager,
|
|
3618
|
+
extensionManager
|
|
3619
|
+
}) {
|
|
3620
|
+
const {
|
|
3621
|
+
t
|
|
3622
|
+
} = (0,es/* useTranslation */.$G)('MeasurementTable');
|
|
3220
3623
|
const [viewportGrid, viewportGridService] = (0,ui_src/* useViewportGrid */.O_)();
|
|
3221
3624
|
const {
|
|
3222
3625
|
activeViewportId,
|
|
@@ -3303,31 +3706,28 @@ function PanelMeasurementTable(_ref) {
|
|
|
3303
3706
|
});
|
|
3304
3707
|
}
|
|
3305
3708
|
}
|
|
3306
|
-
const jumpToImage =
|
|
3307
|
-
|
|
3308
|
-
|
|
3309
|
-
|
|
3310
|
-
} = _ref2;
|
|
3709
|
+
const jumpToImage = ({
|
|
3710
|
+
uid,
|
|
3711
|
+
isActive
|
|
3712
|
+
}) => {
|
|
3311
3713
|
measurementService.jumpToMeasurement(viewportGrid.activeViewportId, uid);
|
|
3312
3714
|
onMeasurementItemClickHandler({
|
|
3313
3715
|
uid,
|
|
3314
3716
|
isActive
|
|
3315
3717
|
});
|
|
3316
3718
|
};
|
|
3317
|
-
const onMeasurementItemEditHandler =
|
|
3318
|
-
|
|
3319
|
-
|
|
3320
|
-
|
|
3321
|
-
} = _ref3;
|
|
3719
|
+
const onMeasurementItemEditHandler = ({
|
|
3720
|
+
uid,
|
|
3721
|
+
isActive
|
|
3722
|
+
}) => {
|
|
3322
3723
|
const measurement = measurementService.getMeasurement(uid);
|
|
3323
3724
|
//Todo: why we are jumping to image?
|
|
3324
3725
|
// jumpToImage({ id, isActive });
|
|
3325
3726
|
|
|
3326
|
-
const onSubmitHandler =
|
|
3327
|
-
|
|
3328
|
-
|
|
3329
|
-
|
|
3330
|
-
} = _ref4;
|
|
3727
|
+
const onSubmitHandler = ({
|
|
3728
|
+
action,
|
|
3729
|
+
value
|
|
3730
|
+
}) => {
|
|
3331
3731
|
switch (action.id) {
|
|
3332
3732
|
case 'save':
|
|
3333
3733
|
{
|
|
@@ -3353,11 +3753,10 @@ function PanelMeasurementTable(_ref) {
|
|
|
3353
3753
|
value: {
|
|
3354
3754
|
label: measurement.label || ''
|
|
3355
3755
|
},
|
|
3356
|
-
body:
|
|
3357
|
-
|
|
3358
|
-
|
|
3359
|
-
|
|
3360
|
-
} = _ref5;
|
|
3756
|
+
body: ({
|
|
3757
|
+
value,
|
|
3758
|
+
setValue
|
|
3759
|
+
}) => {
|
|
3361
3760
|
const onChangeHandler = event => {
|
|
3362
3761
|
event.persist();
|
|
3363
3762
|
setValue(value => ({
|
|
@@ -3400,11 +3799,10 @@ function PanelMeasurementTable(_ref) {
|
|
|
3400
3799
|
}
|
|
3401
3800
|
});
|
|
3402
3801
|
};
|
|
3403
|
-
const onMeasurementItemClickHandler =
|
|
3404
|
-
|
|
3405
|
-
|
|
3406
|
-
|
|
3407
|
-
} = _ref6;
|
|
3802
|
+
const onMeasurementItemClickHandler = ({
|
|
3803
|
+
uid,
|
|
3804
|
+
isActive
|
|
3805
|
+
}) => {
|
|
3408
3806
|
if (!isActive) {
|
|
3409
3807
|
const measurements = [...displayMeasurements];
|
|
3410
3808
|
const measurement = measurements.find(m => m.uid === uid);
|
|
@@ -3417,7 +3815,7 @@ function PanelMeasurementTable(_ref) {
|
|
|
3417
3815
|
className: "ohif-scrollbar overflow-y-auto overflow-x-hidden",
|
|
3418
3816
|
"data-cy": 'measurements-panel'
|
|
3419
3817
|
}, /*#__PURE__*/react.createElement(ui_src/* MeasurementTable */.wt, {
|
|
3420
|
-
title: "Measurements",
|
|
3818
|
+
title: t("Measurements"),
|
|
3421
3819
|
servicesManager: servicesManager,
|
|
3422
3820
|
data: displayMeasurements,
|
|
3423
3821
|
onClick: jumpToImage,
|
|
@@ -3488,21 +3886,23 @@ function _mapMeasurementToDisplay(measurement, index, types) {
|
|
|
3488
3886
|
|
|
3489
3887
|
|
|
3490
3888
|
|
|
3889
|
+
// EXTERNAL MODULE: ../../../node_modules/i18next/dist/esm/i18next.js
|
|
3890
|
+
var i18next = __webpack_require__(73577);
|
|
3491
3891
|
;// CONCATENATED MODULE: ../../../extensions/default/src/getPanelModule.tsx
|
|
3492
3892
|
|
|
3493
3893
|
|
|
3494
3894
|
|
|
3895
|
+
|
|
3495
3896
|
// TODO:
|
|
3496
3897
|
// - No loading UI exists yet
|
|
3497
3898
|
// - cancel promises when component is destroyed
|
|
3498
3899
|
// - show errors in UI for thumbnails if promise fails
|
|
3499
3900
|
|
|
3500
|
-
function getPanelModule(
|
|
3501
|
-
|
|
3502
|
-
|
|
3503
|
-
|
|
3504
|
-
|
|
3505
|
-
} = _ref;
|
|
3901
|
+
function getPanelModule({
|
|
3902
|
+
commandsManager,
|
|
3903
|
+
extensionManager,
|
|
3904
|
+
servicesManager
|
|
3905
|
+
}) {
|
|
3506
3906
|
const wrappedMeasurementPanel = () => {
|
|
3507
3907
|
return /*#__PURE__*/react.createElement(PanelMeasurementTable, {
|
|
3508
3908
|
commandsManager: commandsManager,
|
|
@@ -3514,7 +3914,7 @@ function getPanelModule(_ref) {
|
|
|
3514
3914
|
name: 'seriesList',
|
|
3515
3915
|
iconName: 'tab-studies',
|
|
3516
3916
|
iconLabel: 'Studies',
|
|
3517
|
-
label: 'Studies',
|
|
3917
|
+
label: i18next/* default */.Z.t('SidePanel:Studies'),
|
|
3518
3918
|
component: Panels_WrappedPanelStudyBrowser.bind(null, {
|
|
3519
3919
|
commandsManager,
|
|
3520
3920
|
extensionManager,
|
|
@@ -3524,8 +3924,8 @@ function getPanelModule(_ref) {
|
|
|
3524
3924
|
name: 'measure',
|
|
3525
3925
|
iconName: 'tab-linear',
|
|
3526
3926
|
iconLabel: 'Measure',
|
|
3527
|
-
label: 'Measurements',
|
|
3528
|
-
secondaryLabel: 'Measurements',
|
|
3927
|
+
label: i18next/* default */.Z.t('SidePanel:Measurements'),
|
|
3928
|
+
secondaryLabel: i18next/* default */.Z.t('SidePanel:Measurements'),
|
|
3529
3929
|
component: wrappedMeasurementPanel
|
|
3530
3930
|
}];
|
|
3531
3931
|
}
|
|
@@ -4022,11 +4422,10 @@ function ToolbarLayoutSelector_extends() { ToolbarLayoutSelector_extends = Objec
|
|
|
4022
4422
|
|
|
4023
4423
|
|
|
4024
4424
|
|
|
4025
|
-
function ToolbarLayoutSelectorWithServices(
|
|
4026
|
-
|
|
4027
|
-
|
|
4028
|
-
|
|
4029
|
-
} = _ref;
|
|
4425
|
+
function ToolbarLayoutSelectorWithServices({
|
|
4426
|
+
servicesManager,
|
|
4427
|
+
...props
|
|
4428
|
+
}) {
|
|
4030
4429
|
const {
|
|
4031
4430
|
toolbarService
|
|
4032
4431
|
} = servicesManager.services;
|
|
@@ -4046,14 +4445,13 @@ function ToolbarLayoutSelectorWithServices(_ref) {
|
|
|
4046
4445
|
onSelection: onSelection
|
|
4047
4446
|
}));
|
|
4048
4447
|
}
|
|
4049
|
-
function LayoutSelector(
|
|
4050
|
-
|
|
4051
|
-
|
|
4052
|
-
|
|
4053
|
-
|
|
4054
|
-
|
|
4055
|
-
|
|
4056
|
-
} = _ref2;
|
|
4448
|
+
function LayoutSelector({
|
|
4449
|
+
rows,
|
|
4450
|
+
columns,
|
|
4451
|
+
className,
|
|
4452
|
+
onSelection,
|
|
4453
|
+
...rest
|
|
4454
|
+
}) {
|
|
4057
4455
|
const [isOpen, setIsOpen] = (0,react.useState)(false);
|
|
4058
4456
|
const closeOnOutsideClick = () => {
|
|
4059
4457
|
if (isOpen) {
|
|
@@ -4102,18 +4500,17 @@ function ToolbarSplitButtonWithServices_extends() { ToolbarSplitButtonWithServic
|
|
|
4102
4500
|
|
|
4103
4501
|
|
|
4104
4502
|
|
|
4105
|
-
function ToolbarSplitButtonWithServices(
|
|
4106
|
-
|
|
4107
|
-
|
|
4108
|
-
|
|
4109
|
-
|
|
4110
|
-
|
|
4111
|
-
|
|
4112
|
-
|
|
4113
|
-
|
|
4114
|
-
|
|
4115
|
-
|
|
4116
|
-
} = _ref;
|
|
4503
|
+
function ToolbarSplitButtonWithServices({
|
|
4504
|
+
isRadio,
|
|
4505
|
+
isAction,
|
|
4506
|
+
groupId,
|
|
4507
|
+
primary,
|
|
4508
|
+
secondary,
|
|
4509
|
+
items,
|
|
4510
|
+
renderer,
|
|
4511
|
+
onInteraction,
|
|
4512
|
+
servicesManager
|
|
4513
|
+
}) {
|
|
4117
4514
|
const {
|
|
4118
4515
|
toolbarService
|
|
4119
4516
|
} = servicesManager?.services;
|
|
@@ -4186,14 +4583,13 @@ function ToolbarSplitButtonWithServices(_ref) {
|
|
|
4186
4583
|
isActive
|
|
4187
4584
|
};
|
|
4188
4585
|
});
|
|
4189
|
-
const DefaultListItemRenderer =
|
|
4190
|
-
|
|
4191
|
-
|
|
4192
|
-
|
|
4193
|
-
|
|
4194
|
-
|
|
4195
|
-
|
|
4196
|
-
} = _ref2;
|
|
4586
|
+
const DefaultListItemRenderer = ({
|
|
4587
|
+
type,
|
|
4588
|
+
icon,
|
|
4589
|
+
label,
|
|
4590
|
+
t,
|
|
4591
|
+
id
|
|
4592
|
+
}) => {
|
|
4197
4593
|
const isActive = type === 'toggle' && toggles[id] === true;
|
|
4198
4594
|
return /*#__PURE__*/react.createElement("div", {
|
|
4199
4595
|
className: classnames_default()('hover:bg-primary-dark flex h-8 w-full flex-row items-center p-3', 'whitespace-pre text-base', isActive && 'bg-primary-dark', isActive ? 'text-[#348CFD]' : 'text-common-bright hover:bg-primary-dark hover:text-primary-light')
|
|
@@ -4264,15 +4660,14 @@ function ToolbarButtonWithServices_extends() { ToolbarButtonWithServices_extends
|
|
|
4264
4660
|
|
|
4265
4661
|
|
|
4266
4662
|
|
|
4267
|
-
function ToolbarButtonWithServices(
|
|
4268
|
-
|
|
4269
|
-
|
|
4270
|
-
|
|
4271
|
-
|
|
4272
|
-
|
|
4273
|
-
|
|
4274
|
-
|
|
4275
|
-
} = _ref;
|
|
4663
|
+
function ToolbarButtonWithServices({
|
|
4664
|
+
id,
|
|
4665
|
+
type,
|
|
4666
|
+
commands,
|
|
4667
|
+
onInteraction,
|
|
4668
|
+
servicesManager,
|
|
4669
|
+
...props
|
|
4670
|
+
}) {
|
|
4276
4671
|
const {
|
|
4277
4672
|
toolbarService
|
|
4278
4673
|
} = servicesManager?.services || {};
|
|
@@ -4320,7 +4715,7 @@ ToolbarButtonWithServices.propTypes = {
|
|
|
4320
4715
|
state: prop_types_default().shape({
|
|
4321
4716
|
primaryToolId: (prop_types_default()).string,
|
|
4322
4717
|
toggles: prop_types_default().objectOf((prop_types_default()).bool),
|
|
4323
|
-
groups: prop_types_default().objectOf((prop_types_default()).
|
|
4718
|
+
groups: prop_types_default().objectOf((prop_types_default()).any)
|
|
4324
4719
|
}).isRequired
|
|
4325
4720
|
}).isRequired
|
|
4326
4721
|
}).isRequired
|
|
@@ -4332,11 +4727,10 @@ ToolbarButtonWithServices.propTypes = {
|
|
|
4332
4727
|
|
|
4333
4728
|
|
|
4334
4729
|
|
|
4335
|
-
function getToolbarModule(
|
|
4336
|
-
|
|
4337
|
-
|
|
4338
|
-
|
|
4339
|
-
} = _ref;
|
|
4730
|
+
function getToolbarModule({
|
|
4731
|
+
commandsManager,
|
|
4732
|
+
servicesManager
|
|
4733
|
+
}) {
|
|
4340
4734
|
return [{
|
|
4341
4735
|
name: 'ohif.divider',
|
|
4342
4736
|
defaultComponent: ToolbarDivider,
|
|
@@ -4530,7 +4924,11 @@ function adaptItem(item, subProps) {
|
|
|
4530
4924
|
}
|
|
4531
4925
|
// EXTERNAL MODULE: ../../ui/src/components/ContextMenu/ContextMenu.tsx
|
|
4532
4926
|
var ContextMenu = __webpack_require__(5638);
|
|
4927
|
+
// EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/index.js + 454 modules
|
|
4928
|
+
var dist_esm = __webpack_require__(76634);
|
|
4533
4929
|
;// CONCATENATED MODULE: ../../../extensions/default/src/CustomizableContextMenu/ContextMenuController.tsx
|
|
4930
|
+
var _class;
|
|
4931
|
+
|
|
4534
4932
|
|
|
4535
4933
|
|
|
4536
4934
|
/**
|
|
@@ -4577,6 +4975,16 @@ class ContextMenuController {
|
|
|
4577
4975
|
menus,
|
|
4578
4976
|
selectorProps
|
|
4579
4977
|
} = contextMenuProps;
|
|
4978
|
+
const annotationManager = dist_esm.annotation.state.getAnnotationManager();
|
|
4979
|
+
const {
|
|
4980
|
+
locking
|
|
4981
|
+
} = dist_esm.annotation;
|
|
4982
|
+
const targetAnnotationId = selectorProps?.nearbyToolData?.annotationUID;
|
|
4983
|
+
const isLocked = locking.isAnnotationLocked(annotationManager.getAnnotation(targetAnnotationId));
|
|
4984
|
+
if (isLocked) {
|
|
4985
|
+
console.warn('Annotation is locked.');
|
|
4986
|
+
return;
|
|
4987
|
+
}
|
|
4580
4988
|
console.log('Getting items from', menus);
|
|
4581
4989
|
const items = getMenuItems(selectorProps || contextMenuProps, event, menus, menuId);
|
|
4582
4990
|
this.services.uiDialogService.dismiss({
|
|
@@ -4635,6 +5043,7 @@ class ContextMenuController {
|
|
|
4635
5043
|
});
|
|
4636
5044
|
}
|
|
4637
5045
|
}
|
|
5046
|
+
_class = ContextMenuController;
|
|
4638
5047
|
ContextMenuController.getDefaultPosition = () => {
|
|
4639
5048
|
return {
|
|
4640
5049
|
x: 0,
|
|
@@ -4658,16 +5067,14 @@ ContextMenuController._getElementDefaultPosition = element => {
|
|
|
4658
5067
|
y: undefined
|
|
4659
5068
|
};
|
|
4660
5069
|
};
|
|
4661
|
-
ContextMenuController._getCanvasPointsPosition =
|
|
4662
|
-
|
|
4663
|
-
let element = arguments.length > 1 ? arguments[1] : undefined;
|
|
4664
|
-
const viewerPos = ContextMenuController._getElementDefaultPosition(element);
|
|
5070
|
+
ContextMenuController._getCanvasPointsPosition = (points = [], element) => {
|
|
5071
|
+
const viewerPos = _class._getElementDefaultPosition(element);
|
|
4665
5072
|
for (let pointIndex = 0; pointIndex < points.length; pointIndex++) {
|
|
4666
5073
|
const point = {
|
|
4667
5074
|
x: points[pointIndex][0] || points[pointIndex]['x'],
|
|
4668
5075
|
y: points[pointIndex][1] || points[pointIndex]['y']
|
|
4669
5076
|
};
|
|
4670
|
-
if (
|
|
5077
|
+
if (_class._isValidPosition(point) && _class._isValidPosition(viewerPos)) {
|
|
4671
5078
|
return {
|
|
4672
5079
|
x: point.x + viewerPos.x,
|
|
4673
5080
|
y: point.y + viewerPos.y
|
|
@@ -4683,17 +5090,17 @@ ContextMenuController._isValidPosition = source => {
|
|
|
4683
5090
|
*/
|
|
4684
5091
|
ContextMenuController._getDefaultPosition = (canvasPoints, eventDetail, viewerElement) => {
|
|
4685
5092
|
function* getPositionIterator() {
|
|
4686
|
-
yield
|
|
4687
|
-
yield
|
|
4688
|
-
yield
|
|
4689
|
-
yield
|
|
5093
|
+
yield _class._getCanvasPointsPosition(canvasPoints, viewerElement);
|
|
5094
|
+
yield _class._getEventDefaultPosition(eventDetail);
|
|
5095
|
+
yield _class._getElementDefaultPosition(viewerElement);
|
|
5096
|
+
yield _class.getDefaultPosition();
|
|
4690
5097
|
}
|
|
4691
5098
|
const positionIterator = getPositionIterator();
|
|
4692
5099
|
let current = positionIterator.next();
|
|
4693
5100
|
let position = current.value;
|
|
4694
5101
|
while (!current.done) {
|
|
4695
5102
|
position = current.value;
|
|
4696
|
-
if (
|
|
5103
|
+
if (_class._isValidPosition(position)) {
|
|
4697
5104
|
positionIterator.return();
|
|
4698
5105
|
}
|
|
4699
5106
|
current = positionIterator.next();
|
|
@@ -4708,12 +5115,9 @@ const defaultContextMenu = {
|
|
|
4708
5115
|
// Get the items from the UI Customization for the menu name (and have a custom name)
|
|
4709
5116
|
{
|
|
4710
5117
|
id: 'forExistingMeasurement',
|
|
4711
|
-
selector:
|
|
4712
|
-
|
|
4713
|
-
|
|
4714
|
-
} = _ref;
|
|
4715
|
-
return !!nearbyToolData;
|
|
4716
|
-
},
|
|
5118
|
+
selector: ({
|
|
5119
|
+
nearbyToolData
|
|
5120
|
+
}) => !!nearbyToolData,
|
|
4717
5121
|
items: [{
|
|
4718
5122
|
label: 'Delete measurement',
|
|
4719
5123
|
commands: [{
|
|
@@ -4758,13 +5162,12 @@ const rowStyle = {
|
|
|
4758
5162
|
borderBottomWidth: `${rowBottomBorderPx}px`,
|
|
4759
5163
|
...rowVerticalPaddingStyle
|
|
4760
5164
|
};
|
|
4761
|
-
function ColumnHeaders(
|
|
4762
|
-
|
|
4763
|
-
|
|
4764
|
-
|
|
4765
|
-
|
|
4766
|
-
|
|
4767
|
-
} = _ref;
|
|
5165
|
+
function ColumnHeaders({
|
|
5166
|
+
tagRef,
|
|
5167
|
+
vrRef,
|
|
5168
|
+
keywordRef,
|
|
5169
|
+
valueRef
|
|
5170
|
+
}) {
|
|
4768
5171
|
return /*#__PURE__*/react.createElement("div", {
|
|
4769
5172
|
className: classnames_default()('bg-secondary-dark ohif-scrollbar flex w-full flex-row overflow-y-scroll'),
|
|
4770
5173
|
style: rowVerticalPaddingStyle
|
|
@@ -4798,10 +5201,9 @@ function ColumnHeaders(_ref) {
|
|
|
4798
5201
|
className: "flex flex-row items-center focus:outline-none"
|
|
4799
5202
|
}, "Value"))));
|
|
4800
5203
|
}
|
|
4801
|
-
function DicomTagTable(
|
|
4802
|
-
|
|
4803
|
-
|
|
4804
|
-
} = _ref2;
|
|
5204
|
+
function DicomTagTable({
|
|
5205
|
+
rows
|
|
5206
|
+
}) {
|
|
4805
5207
|
const listRef = (0,react.useRef)();
|
|
4806
5208
|
const canvasRef = (0,react.useRef)();
|
|
4807
5209
|
const [tagHeaderElem, setTagHeaderElem] = (0,react.useState)(null);
|
|
@@ -4855,11 +5257,10 @@ function DicomTagTable(_ref2) {
|
|
|
4855
5257
|
window.removeEventListener('resize', debouncedResize);
|
|
4856
5258
|
};
|
|
4857
5259
|
}, []);
|
|
4858
|
-
const Row = (0,react.useCallback)(
|
|
4859
|
-
|
|
4860
|
-
|
|
4861
|
-
|
|
4862
|
-
} = _ref3;
|
|
5260
|
+
const Row = (0,react.useCallback)(({
|
|
5261
|
+
index,
|
|
5262
|
+
style
|
|
5263
|
+
}) => {
|
|
4863
5264
|
const row = rows[index];
|
|
4864
5265
|
return /*#__PURE__*/react.createElement("div", {
|
|
4865
5266
|
style: {
|
|
@@ -4948,11 +5349,10 @@ const {
|
|
|
4948
5349
|
const {
|
|
4949
5350
|
nameMap
|
|
4950
5351
|
} = DicomTagBrowser_DicomMetaDictionary;
|
|
4951
|
-
const DicomTagBrowser =
|
|
4952
|
-
|
|
4953
|
-
|
|
4954
|
-
|
|
4955
|
-
} = _ref;
|
|
5352
|
+
const DicomTagBrowser = ({
|
|
5353
|
+
displaySets,
|
|
5354
|
+
displaySetInstanceUID
|
|
5355
|
+
}) => {
|
|
4956
5356
|
// The column indices that are to be excluded during a filter of the table.
|
|
4957
5357
|
// At present the column indices are:
|
|
4958
5358
|
// 0: DICOM tag
|
|
@@ -5113,8 +5513,7 @@ function getSortedTags(metadata) {
|
|
|
5113
5513
|
_sortTagList(tagList);
|
|
5114
5514
|
return tagList;
|
|
5115
5515
|
}
|
|
5116
|
-
function getRows(metadata) {
|
|
5117
|
-
let depth = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
|
|
5516
|
+
function getRows(metadata, depth = 0) {
|
|
5118
5517
|
// Tag, Type, Value, Keyword
|
|
5119
5518
|
|
|
5120
5519
|
const keywords = Object.keys(metadata);
|
|
@@ -5125,7 +5524,6 @@ function getRows(metadata) {
|
|
|
5125
5524
|
if (depth > 0) {
|
|
5126
5525
|
tagIndent += ' '; // If indented, add a space after the indents.
|
|
5127
5526
|
}
|
|
5128
|
-
|
|
5129
5527
|
const rows = [];
|
|
5130
5528
|
for (let i = 0; i < keywords.length; i++) {
|
|
5131
5529
|
let keyword = keywords[i];
|
|
@@ -5366,11 +5764,10 @@ const findViewportsByPosition_findOrCreateViewport = (hangingProtocolService, vi
|
|
|
5366
5764
|
* @returns Set of states that can be applied to the state sync to remember
|
|
5367
5765
|
* the current view state.
|
|
5368
5766
|
*/
|
|
5369
|
-
const findViewportsByPosition = (state,
|
|
5370
|
-
|
|
5371
|
-
|
|
5372
|
-
|
|
5373
|
-
} = _ref;
|
|
5767
|
+
const findViewportsByPosition = (state, {
|
|
5768
|
+
numRows,
|
|
5769
|
+
numCols
|
|
5770
|
+
}, syncService) => {
|
|
5374
5771
|
const {
|
|
5375
5772
|
viewports
|
|
5376
5773
|
} = state;
|
|
@@ -5425,11 +5822,10 @@ const {
|
|
|
5425
5822
|
* commands module, but if others get added elsewhere this may need enhancing.
|
|
5426
5823
|
*/
|
|
5427
5824
|
const isHangingProtocolCommand = command => command && (command.commandName === 'setHangingProtocol' || command.commandName === 'toggleHangingProtocol');
|
|
5428
|
-
const commandsModule =
|
|
5429
|
-
|
|
5430
|
-
|
|
5431
|
-
|
|
5432
|
-
} = _ref;
|
|
5825
|
+
const commandsModule = ({
|
|
5826
|
+
servicesManager,
|
|
5827
|
+
commandsManager
|
|
5828
|
+
}) => {
|
|
5433
5829
|
const {
|
|
5434
5830
|
customizationService,
|
|
5435
5831
|
measurementService,
|
|
@@ -5484,12 +5880,11 @@ const commandsModule = _ref => {
|
|
|
5484
5880
|
closeContextMenu: () => {
|
|
5485
5881
|
contextMenuController.closeContextMenu();
|
|
5486
5882
|
},
|
|
5487
|
-
displayNotification:
|
|
5488
|
-
|
|
5489
|
-
|
|
5490
|
-
|
|
5491
|
-
|
|
5492
|
-
} = _ref2;
|
|
5883
|
+
displayNotification: ({
|
|
5884
|
+
text,
|
|
5885
|
+
title,
|
|
5886
|
+
type
|
|
5887
|
+
}) => {
|
|
5493
5888
|
uiNotificationService.show({
|
|
5494
5889
|
title: title,
|
|
5495
5890
|
message: text,
|
|
@@ -5558,14 +5953,13 @@ const commandsModule = _ref => {
|
|
|
5558
5953
|
* @param options.stageIndex - the index of the stage to go to.
|
|
5559
5954
|
* @param options.reset - flag to indicate if the HP should be reset to its original and not restored to a previous state
|
|
5560
5955
|
*/
|
|
5561
|
-
setHangingProtocol:
|
|
5562
|
-
|
|
5563
|
-
|
|
5564
|
-
|
|
5565
|
-
|
|
5566
|
-
|
|
5567
|
-
|
|
5568
|
-
} = _ref3;
|
|
5956
|
+
setHangingProtocol: ({
|
|
5957
|
+
activeStudyUID = '',
|
|
5958
|
+
protocolId,
|
|
5959
|
+
stageId,
|
|
5960
|
+
stageIndex,
|
|
5961
|
+
reset = false
|
|
5962
|
+
}) => {
|
|
5569
5963
|
const primaryToolBeforeHPChange = toolbarService.getActivePrimaryTool();
|
|
5570
5964
|
try {
|
|
5571
5965
|
// Stores in the state the display set selector id to displaySetUID mapping
|
|
@@ -5626,9 +6020,6 @@ const commandsModule = _ref => {
|
|
|
5626
6020
|
delete displaySetSelectorMap[`${activeStudyUID || hpInfo.activeStudyUID}:activeDisplaySet:0`];
|
|
5627
6021
|
stateSyncService.store(stateSyncReduce);
|
|
5628
6022
|
// This is a default action applied
|
|
5629
|
-
const {
|
|
5630
|
-
protocol
|
|
5631
|
-
} = hangingProtocolService.getActiveProtocol();
|
|
5632
6023
|
actions.toggleHpTools();
|
|
5633
6024
|
|
|
5634
6025
|
// try to use the same tool in the new hanging protocol stage
|
|
@@ -5649,17 +6040,6 @@ const commandsModule = _ref => {
|
|
|
5649
6040
|
});
|
|
5650
6041
|
}
|
|
5651
6042
|
}
|
|
5652
|
-
|
|
5653
|
-
// Send the notification about updating the state
|
|
5654
|
-
if (protocolId !== hpInfo.protocolId) {
|
|
5655
|
-
// The old protocol callbacks are used for turning off things
|
|
5656
|
-
// like crosshairs when moving to the new HP
|
|
5657
|
-
commandsManager.run(oldProtocol.callbacks?.onProtocolExit);
|
|
5658
|
-
// The new protocol callback is used for things like
|
|
5659
|
-
// activating modes etc.
|
|
5660
|
-
}
|
|
5661
|
-
|
|
5662
|
-
commandsManager.run(protocol.callbacks?.onProtocolEnter);
|
|
5663
6043
|
return true;
|
|
5664
6044
|
} catch (e) {
|
|
5665
6045
|
console.error(e);
|
|
@@ -5673,11 +6053,10 @@ const commandsModule = _ref => {
|
|
|
5673
6053
|
return false;
|
|
5674
6054
|
}
|
|
5675
6055
|
},
|
|
5676
|
-
toggleHangingProtocol:
|
|
5677
|
-
|
|
5678
|
-
|
|
5679
|
-
|
|
5680
|
-
} = _ref4;
|
|
6056
|
+
toggleHangingProtocol: ({
|
|
6057
|
+
protocolId,
|
|
6058
|
+
stageIndex
|
|
6059
|
+
}) => {
|
|
5681
6060
|
const {
|
|
5682
6061
|
protocol,
|
|
5683
6062
|
stageIndex: desiredStageIndex,
|
|
@@ -5710,10 +6089,9 @@ const commandsModule = _ref => {
|
|
|
5710
6089
|
});
|
|
5711
6090
|
}
|
|
5712
6091
|
},
|
|
5713
|
-
deltaStage:
|
|
5714
|
-
|
|
5715
|
-
|
|
5716
|
-
} = _ref5;
|
|
6092
|
+
deltaStage: ({
|
|
6093
|
+
direction
|
|
6094
|
+
}) => {
|
|
5717
6095
|
const {
|
|
5718
6096
|
protocolId,
|
|
5719
6097
|
stageIndex: oldStageIndex
|
|
@@ -5739,11 +6117,10 @@ const commandsModule = _ref => {
|
|
|
5739
6117
|
/**
|
|
5740
6118
|
* Changes the viewport grid layout in terms of the MxN layout.
|
|
5741
6119
|
*/
|
|
5742
|
-
setViewportGridLayout:
|
|
5743
|
-
|
|
5744
|
-
|
|
5745
|
-
|
|
5746
|
-
} = _ref6;
|
|
6120
|
+
setViewportGridLayout: ({
|
|
6121
|
+
numRows,
|
|
6122
|
+
numCols
|
|
6123
|
+
}) => {
|
|
5747
6124
|
const {
|
|
5748
6125
|
protocol
|
|
5749
6126
|
} = hangingProtocolService.getActiveProtocol();
|
|
@@ -5953,11 +6330,10 @@ const commandsModule = _ref => {
|
|
|
5953
6330
|
behavior: 'smooth'
|
|
5954
6331
|
});
|
|
5955
6332
|
},
|
|
5956
|
-
updateViewportDisplaySet:
|
|
5957
|
-
|
|
5958
|
-
|
|
5959
|
-
|
|
5960
|
-
} = _ref7;
|
|
6333
|
+
updateViewportDisplaySet: ({
|
|
6334
|
+
direction,
|
|
6335
|
+
excludeNonImageModalities
|
|
6336
|
+
}) => {
|
|
5961
6337
|
const nonImageModalities = ['SR', 'SEG', 'SM', 'RTSTRUCT', 'RTPLAN', 'RTDOSE'];
|
|
5962
6338
|
|
|
5963
6339
|
// Sort the display sets as per the hanging protocol service viewport/display set scoring system.
|
|
@@ -6473,6 +6849,9 @@ const defaultProtocol = {
|
|
|
6473
6849
|
editableBy: {},
|
|
6474
6850
|
protocolMatchingRules: [],
|
|
6475
6851
|
toolGroupIds: ['default'],
|
|
6852
|
+
hpInitiationCriteria: {
|
|
6853
|
+
minSeriesLoaded: 1
|
|
6854
|
+
},
|
|
6476
6855
|
// -1 would be used to indicate active only, whereas other values are
|
|
6477
6856
|
// the number of required priors referenced - so 0 means active with
|
|
6478
6857
|
// 0 or more priors.
|
|
@@ -6517,7 +6896,6 @@ const defaultProtocol = {
|
|
|
6517
6896
|
// studyMatchingRules: [],
|
|
6518
6897
|
}
|
|
6519
6898
|
},
|
|
6520
|
-
|
|
6521
6899
|
stages: [{
|
|
6522
6900
|
name: 'default',
|
|
6523
6901
|
viewportStructure: {
|
|
@@ -6543,7 +6921,6 @@ const defaultProtocol = {
|
|
|
6543
6921
|
// preset: 'middle', // 'first', 'last', 'middle'
|
|
6544
6922
|
// },
|
|
6545
6923
|
},
|
|
6546
|
-
|
|
6547
6924
|
displaySets: [{
|
|
6548
6925
|
id: 'defaultDisplaySetId'
|
|
6549
6926
|
}]
|
|
@@ -6617,12 +6994,11 @@ function DataSourceSelector() {
|
|
|
6617
6994
|
|
|
6618
6995
|
|
|
6619
6996
|
|
|
6620
|
-
function ItemListComponent(
|
|
6621
|
-
|
|
6622
|
-
|
|
6623
|
-
|
|
6624
|
-
|
|
6625
|
-
} = _ref;
|
|
6997
|
+
function ItemListComponent({
|
|
6998
|
+
itemLabel,
|
|
6999
|
+
itemList,
|
|
7000
|
+
onItemClicked
|
|
7001
|
+
}) {
|
|
6626
7002
|
const {
|
|
6627
7003
|
t
|
|
6628
7004
|
} = (0,es/* useTranslation */.$G)('DataSourceConfiguration');
|
|
@@ -6676,12 +7052,11 @@ function ItemListComponent(_ref) {
|
|
|
6676
7052
|
|
|
6677
7053
|
|
|
6678
7054
|
const NO_WRAP_ELLIPSIS_CLASS_NAMES = 'text-ellipsis whitespace-nowrap overflow-hidden';
|
|
6679
|
-
function DataSourceConfigurationModalComponent(
|
|
6680
|
-
|
|
6681
|
-
|
|
6682
|
-
|
|
6683
|
-
|
|
6684
|
-
} = _ref;
|
|
7055
|
+
function DataSourceConfigurationModalComponent({
|
|
7056
|
+
configurationAPI,
|
|
7057
|
+
configuredItems,
|
|
7058
|
+
onHide
|
|
7059
|
+
}) {
|
|
6685
7060
|
const {
|
|
6686
7061
|
t
|
|
6687
7062
|
} = (0,es/* useTranslation */.$G)('DataSourceConfiguration');
|
|
@@ -6788,11 +7163,10 @@ function DataSourceConfigurationModalComponent(_ref) {
|
|
|
6788
7163
|
|
|
6789
7164
|
|
|
6790
7165
|
|
|
6791
|
-
function DataSourceConfigurationComponent(
|
|
6792
|
-
|
|
6793
|
-
|
|
6794
|
-
|
|
6795
|
-
} = _ref;
|
|
7166
|
+
function DataSourceConfigurationComponent({
|
|
7167
|
+
servicesManager,
|
|
7168
|
+
extensionManager
|
|
7169
|
+
}) {
|
|
6796
7170
|
const {
|
|
6797
7171
|
t
|
|
6798
7172
|
} = (0,es/* useTranslation */.$G)('DataSourceConfiguration');
|
|
@@ -7010,9 +7384,7 @@ class GoogleCloudDataSourceConfigurationAPI {
|
|
|
7010
7384
|
* @param fetchSearchParams any search query params; currently only used for paging results
|
|
7011
7385
|
* @returns an array of items of the specified type
|
|
7012
7386
|
*/
|
|
7013
|
-
static async _doFetch(urlStr, fetchItemType) {
|
|
7014
|
-
let fetchOptions = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
7015
|
-
let fetchSearchParams = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
|
|
7387
|
+
static async _doFetch(urlStr, fetchItemType, fetchOptions = {}, fetchSearchParams = {}) {
|
|
7016
7388
|
try {
|
|
7017
7389
|
const url = new URL(urlStr);
|
|
7018
7390
|
url.search = new URLSearchParams(fetchSearchParams).toString();
|
|
@@ -7057,11 +7429,10 @@ class GoogleCloudDataSourceConfigurationAPI {
|
|
|
7057
7429
|
* custom page for the user to view their profile, or to add a custom
|
|
7058
7430
|
* page for login etc.
|
|
7059
7431
|
*/
|
|
7060
|
-
function getCustomizationModule(
|
|
7061
|
-
|
|
7062
|
-
|
|
7063
|
-
|
|
7064
|
-
} = _ref;
|
|
7432
|
+
function getCustomizationModule({
|
|
7433
|
+
servicesManager,
|
|
7434
|
+
extensionManager
|
|
7435
|
+
}) {
|
|
7065
7436
|
return [{
|
|
7066
7437
|
name: 'helloPage',
|
|
7067
7438
|
value: {
|
|
@@ -7269,11 +7640,10 @@ const init_metadataProvider = src.classes.MetadataProvider;
|
|
|
7269
7640
|
* @param {Object} servicesManager
|
|
7270
7641
|
* @param {Object} configuration
|
|
7271
7642
|
*/
|
|
7272
|
-
function init(
|
|
7273
|
-
|
|
7274
|
-
|
|
7275
|
-
|
|
7276
|
-
} = _ref;
|
|
7643
|
+
function init({
|
|
7644
|
+
servicesManager,
|
|
7645
|
+
configuration = {}
|
|
7646
|
+
}) {
|
|
7277
7647
|
const {
|
|
7278
7648
|
stateSyncService
|
|
7279
7649
|
} = servicesManager.services;
|
|
@@ -7320,43 +7690,41 @@ function init(_ref) {
|
|
|
7320
7690
|
clearOnModeExit: true
|
|
7321
7691
|
});
|
|
7322
7692
|
}
|
|
7323
|
-
const handlePETImageMetadata =
|
|
7324
|
-
|
|
7325
|
-
|
|
7326
|
-
|
|
7327
|
-
} = _ref2;
|
|
7693
|
+
const handlePETImageMetadata = ({
|
|
7694
|
+
SeriesInstanceUID,
|
|
7695
|
+
StudyInstanceUID
|
|
7696
|
+
}) => {
|
|
7328
7697
|
const {
|
|
7329
7698
|
instances
|
|
7330
7699
|
} = src.DicomMetadataStore.getSeries(StudyInstanceUID, SeriesInstanceUID);
|
|
7700
|
+
if (!instances?.length) {
|
|
7701
|
+
return;
|
|
7702
|
+
}
|
|
7331
7703
|
const modality = instances[0].Modality;
|
|
7332
|
-
if (modality !== 'PT') {
|
|
7704
|
+
if (!modality || modality !== 'PT') {
|
|
7333
7705
|
return;
|
|
7334
7706
|
}
|
|
7335
7707
|
const imageIds = instances.map(instance => instance.imageId);
|
|
7336
7708
|
const instanceMetadataArray = [];
|
|
7337
|
-
imageIds.forEach(imageId => {
|
|
7338
|
-
const instanceMetadata = getPTImageIdInstanceMetadata(imageId);
|
|
7339
|
-
if (instanceMetadata) {
|
|
7340
|
-
instanceMetadataArray.push(instanceMetadata);
|
|
7341
|
-
}
|
|
7342
|
-
});
|
|
7343
|
-
if (!instanceMetadataArray.length) {
|
|
7344
|
-
return;
|
|
7345
|
-
}
|
|
7346
7709
|
|
|
7347
7710
|
// try except block to prevent errors when the metadata is not correct
|
|
7348
|
-
let suvScalingFactors;
|
|
7349
7711
|
try {
|
|
7350
|
-
|
|
7712
|
+
imageIds.forEach(imageId => {
|
|
7713
|
+
const instanceMetadata = getPTImageIdInstanceMetadata(imageId);
|
|
7714
|
+
if (instanceMetadata) {
|
|
7715
|
+
instanceMetadataArray.push(instanceMetadata);
|
|
7716
|
+
}
|
|
7717
|
+
});
|
|
7718
|
+
if (!instanceMetadataArray.length) {
|
|
7719
|
+
return;
|
|
7720
|
+
}
|
|
7721
|
+
const suvScalingFactors = (0,calculate_suv_esm/* calculateSUVScalingFactors */.d)(instanceMetadataArray);
|
|
7722
|
+
instanceMetadataArray.forEach((instanceMetadata, index) => {
|
|
7723
|
+
init_metadataProvider.addCustomMetadata(imageIds[index], 'scalingModule', suvScalingFactors[index]);
|
|
7724
|
+
});
|
|
7351
7725
|
} catch (error) {
|
|
7352
7726
|
console.log(error);
|
|
7353
7727
|
}
|
|
7354
|
-
if (!suvScalingFactors) {
|
|
7355
|
-
return;
|
|
7356
|
-
}
|
|
7357
|
-
instanceMetadataArray.forEach((instanceMetadata, index) => {
|
|
7358
|
-
init_metadataProvider.addCustomMetadata(imageIds[index], 'scalingModule', suvScalingFactors[index]);
|
|
7359
|
-
});
|
|
7360
7728
|
};
|
|
7361
7729
|
;// CONCATENATED MODULE: ../../../extensions/default/src/DicomWebDataSource/utils/index.ts
|
|
7362
7730
|
|
|
@@ -7390,10 +7758,9 @@ const defaultExtension = {
|
|
|
7390
7758
|
getSopClassHandlerModule: src_getSopClassHandlerModule,
|
|
7391
7759
|
getToolbarModule: getToolbarModule,
|
|
7392
7760
|
getCommandsModule: src_commandsModule,
|
|
7393
|
-
getUtilityModule(
|
|
7394
|
-
|
|
7395
|
-
|
|
7396
|
-
} = _ref;
|
|
7761
|
+
getUtilityModule({
|
|
7762
|
+
servicesManager
|
|
7763
|
+
}) {
|
|
7397
7764
|
return [{
|
|
7398
7765
|
name: 'common',
|
|
7399
7766
|
exports: {
|