@ohif/app 3.8.0-beta.8 → 3.8.0-beta.81
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/{220.bundle.f7e1c96c94245e70f2be.js → 109.bundle.b4fee2a22b622839baf5.js} +4466 -3715
- package/dist/{471.bundle.49c8d281adbae4a2c4df.js → 121.bundle.47f05840a5b3cdf75543.js} +94 -113
- package/dist/141.bundle.556b4c1e4cab770417ac.js +8620 -0
- package/dist/{687.bundle.9065db35c01823286f08.js → 164.bundle.fadc7c5d634402c73b5f.js} +22 -38
- package/dist/17dd54813d5acc10bf8f.wasm +0 -0
- package/dist/183.bundle.a3e238998be71c4b2af8.js +30410 -0
- package/dist/{506.bundle.5731bb4349e266491225.js → 188.bundle.51dc4b37920f45594393.js} +23 -28
- package/dist/{342.bundle.e7c3d500f86fdfcc62b5.js → 206.bundle.fcaa081a0d1f68095c31.js} +1991 -1145
- package/dist/20fc4c659b85ccd2a9c0.wasm +0 -0
- package/dist/217.bundle.d44bbaa50b6fa563fe15.js +115126 -0
- package/dist/{451.bundle.57c21db5d003c75e9d61.js → 295.bundle.5ace95771ced62bdcab8.js} +111 -128
- package/dist/{125.bundle.253395f320b72180da63.js → 297.bundle.194d8985ab974839b5b6.js} +7 -8
- package/dist/{19.bundle.f77c5787b6d8ac0b638b.js → 325.bundle.fd8e0c18db4708d03a91.js} +477 -373
- package/dist/335.bundle.8400aa5a88697a6b9d53.js +2590 -0
- package/dist/{202.bundle.d3490836f71e001dd30f.js → 342.bundle.e6d0bba29351b5650a8c.js} +566 -868
- package/dist/{776.bundle.a2dedb405a12ffd7699b.js → 41.bundle.0905b258a90a7c6437bb.js} +7453 -3624
- package/dist/422.bundle.c6fd037b075dd54f1ba7.js +865 -0
- package/dist/{957.bundle.9ea4506963ef8b2d84ba.js → 433.bundle.e0018820758f5a86fa7f.js} +14797 -27561
- package/dist/445.bundle.38c6d2af64e41cd7c614.js +7835 -0
- package/dist/{126.bundle.6e7111d58bcc937ffd80.js → 448.bundle.5e6da31477887bf53016.js} +356 -430
- package/dist/487.bundle.89d973049defb3ba6cb7.js +1876 -0
- package/dist/{886.bundle.c8dd3ecc42a4253de278.js → 530.bundle.207b38c15c4c01e4db0e.js} +104 -121
- package/dist/{250.bundle.aea3335667054bdefe36.js → 544.bundle.1c1f57118560046649c1.js} +37 -62
- package/dist/574.bundle.d648fea691d6709bf2b4.js +2652 -0
- package/dist/{181.css → 574.css} +1 -1
- package/dist/{410.bundle.15c855b0ff4a1a674fb8.js → 594.bundle.84076375b127b9c7f673.js} +183 -221
- package/dist/{221.bundle.aef554202c58483cb34e.js → 633.bundle.acab89baaa06a299d679.js} +365 -553
- package/dist/{774.bundle.4b2dc46a35012b898e1a.js → 644.bundle.1e77691d2eeb96a423b0.js} +1852 -8945
- package/dist/{663.bundle.d7be28450db14266cdd0.js → 669.bundle.b17e8a621e38d92c653f.js} +310 -265
- package/dist/699.bundle.9367d7ef9f7615b2e733.js +772 -0
- package/dist/702.bundle.963481fbf871984b646f.js +8426 -0
- package/dist/722.bundle.afab1fe6bfcd569130ac.js +1083 -0
- package/dist/{359.bundle.45ecb3d28e8c22142606.js → 724.bundle.55f9f49816de931af91a.js} +165 -260
- package/dist/{757.bundle.ec8301d8e70d2b990f65.js → 726.bundle.0b3d9277d22fe7e15b89.js} +512 -879
- package/dist/{530.bundle.a03b6f942ace3e1baa1e.js → 835.bundle.15aff0b7433bb0dd6d6d.js} +37 -30
- package/dist/{822.bundle.82cdc418f8f56da6060b.js → 862.bundle.d32ab08e64806b2e964d.js} +81 -97
- package/dist/{236.bundle.4e9924934a747afac132.js → 889.bundle.8ef8b723d0163d5d135c.js} +207 -199
- package/dist/{281.bundle.deb7492d143e7768d8bf.js → 905.bundle.8a96e1a75b7cfe5ec093.js} +157 -124
- package/dist/{814.bundle.c8c951d20039b63b865a.js → 907.bundle.5c88ed911bed18582da4.js} +16 -30
- package/dist/{417.bundle.af0a207c29b109f84159.js → 931.bundle.d270a1fda9a2836c3cc5.js} +26 -26
- package/dist/{686.bundle.dccef1f36e4bc79bcc48.js → 939.bundle.9d93b2e47c52338747a2.js} +7 -8
- package/dist/94.bundle.f5f2479c214180d05d42.js +778 -0
- package/dist/{12.bundle.b5ca13e5363f170ecb3b.js → 961.bundle.f4e52bc76d3044d05372.js} +20 -33
- package/dist/app-config.js +1 -0
- package/dist/app.bundle.css +16 -13
- package/dist/{app.bundle.a978edc59b9d82f2eb22.js → app.bundle.ed937512f7d19d61c411.js} +183396 -87682
- package/dist/assets/images/CT-AAA.png +0 -0
- package/dist/assets/images/CT-AAA2.png +0 -0
- package/dist/assets/images/CT-Air.png +0 -0
- package/dist/assets/images/CT-Bone.png +0 -0
- package/dist/assets/images/CT-Bones.png +0 -0
- package/dist/assets/images/CT-Cardiac.png +0 -0
- package/dist/assets/images/CT-Cardiac2.png +0 -0
- package/dist/assets/images/CT-Cardiac3.png +0 -0
- package/dist/assets/images/CT-Chest-Contrast-Enhanced.png +0 -0
- package/dist/assets/images/CT-Chest-Vessels.png +0 -0
- package/dist/assets/images/CT-Coronary-Arteries-2.png +0 -0
- package/dist/assets/images/CT-Coronary-Arteries-3.png +0 -0
- package/dist/assets/images/CT-Coronary-Arteries.png +0 -0
- package/dist/assets/images/CT-Cropped-Volume-Bone.png +0 -0
- package/dist/assets/images/CT-Fat.png +0 -0
- package/dist/assets/images/CT-Liver-Vasculature.png +0 -0
- package/dist/assets/images/CT-Lung.png +0 -0
- package/dist/assets/images/CT-MIP.png +0 -0
- package/dist/assets/images/CT-Muscle.png +0 -0
- package/dist/assets/images/CT-Pulmonary-Arteries.png +0 -0
- package/dist/assets/images/CT-Soft-Tissue.png +0 -0
- package/dist/assets/images/DTI-FA-Brain.png +0 -0
- package/dist/assets/images/MR-Angio.png +0 -0
- package/dist/assets/images/MR-Default.png +0 -0
- package/dist/assets/images/MR-MIP.png +0 -0
- package/dist/assets/images/MR-T2-Brain.png +0 -0
- package/dist/assets/images/VolumeRendering.png +0 -0
- 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.d3a56dc9f62df5e11019.js} +3 -3
- package/dist/histogram-worker.bundle.829e14ec12c2b41a4323.js +359 -0
- 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/polySeg.bundle.f1a6ece1396dc1385155.js +249 -0
- package/dist/serve.json +12 -0
- package/dist/sw.js +1 -1
- package/package.json +26 -22
- package/dist/181.bundle.a62b9f0ec692299acb35.js +0 -1527
- package/dist/23.bundle.e008ad788170f2ed5569.js +0 -900
- package/dist/604.bundle.a51f83e64004bca5f497.js +0 -1848
- package/dist/613.bundle.9e7072e5b575354fe51e.js +0 -532
- package/dist/743.bundle.489f7df3a089d4d374e1.js +0 -78007
- package/dist/75788f12450d4c5ed494.wasm +0 -0
- package/dist/775.bundle.2285e7e0e67878948c0d.js +0 -1009
- package/dist/788.bundle.207ac23c0dfa70cbe3fb.js +0 -2682
- package/dist/82.bundle.d6fdcca0f67540bb226a.js +0 -1049
- package/dist/index.worker.e62ecca63f1a2e124230.worker.js.map +0 -1
- /package/dist/{19.css → 325.css} +0 -0
- /package/dist/{776.css → 41.css} +0 -0
- /package/dist/{579.css → 481.css} +0 -0
- /package/dist/{250.css → 544.css} +0 -0
- /package/dist/{221.css → 633.css} +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
(
|
|
2
|
+
(globalThis["webpackChunk"] = globalThis["webpackChunk"] || []).push([[206],{
|
|
3
3
|
|
|
4
|
-
/***/
|
|
4
|
+
/***/ 7206:
|
|
5
5
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
6
6
|
|
|
7
7
|
// ESM COMPAT FLAG
|
|
@@ -11,6 +11,7 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
11
11
|
__webpack_require__.d(__webpack_exports__, {
|
|
12
12
|
ContextMenuController: () => (/* reexport */ ContextMenuController),
|
|
13
13
|
CustomizableContextMenuTypes: () => (/* reexport */ types_namespaceObject),
|
|
14
|
+
StaticWadoClient: () => (/* reexport */ StaticWadoClient),
|
|
14
15
|
createReportAsync: () => (/* reexport */ Actions_createReportAsync),
|
|
15
16
|
createReportDialogPrompt: () => (/* reexport */ CreateReportDialogPrompt),
|
|
16
17
|
"default": () => (/* binding */ default_src),
|
|
@@ -30,11 +31,11 @@ __webpack_require__.d(utils_namespaceObject, {
|
|
|
30
31
|
});
|
|
31
32
|
|
|
32
33
|
// EXTERNAL MODULE: ../../../node_modules/dicomweb-client/build/dicomweb-client.es.js
|
|
33
|
-
var dicomweb_client_es = __webpack_require__(
|
|
34
|
-
// EXTERNAL MODULE: ../../core/src/index.ts +
|
|
35
|
-
var src = __webpack_require__(
|
|
34
|
+
var dicomweb_client_es = __webpack_require__(36922);
|
|
35
|
+
// EXTERNAL MODULE: ../../core/src/index.ts + 70 modules
|
|
36
|
+
var src = __webpack_require__(55411);
|
|
36
37
|
// EXTERNAL MODULE: ../../core/src/utils/sortStudy.ts
|
|
37
|
-
var sortStudy = __webpack_require__(
|
|
38
|
+
var sortStudy = __webpack_require__(45476);
|
|
38
39
|
;// CONCATENATED MODULE: ../../../extensions/default/src/DicomWebDataSource/qido.js
|
|
39
40
|
/**
|
|
40
41
|
* QIDO - Query based on ID for DICOM Objects
|
|
@@ -125,7 +126,7 @@ function processSeriesResults(qidoSeries) {
|
|
|
125
126
|
description: getString(qidoSeries['0008103E'])
|
|
126
127
|
}));
|
|
127
128
|
}
|
|
128
|
-
(0,sortStudy/* sortStudySeries */.
|
|
129
|
+
(0,sortStudy/* sortStudySeries */.LM)(series);
|
|
129
130
|
return series;
|
|
130
131
|
}
|
|
131
132
|
|
|
@@ -179,8 +180,7 @@ function searchStudies(server, filter) {
|
|
|
179
180
|
* @param serverSupportsQIDOIncludeField
|
|
180
181
|
* @returns {string} The URL with encoded filter query data
|
|
181
182
|
*/
|
|
182
|
-
function mapParams(params) {
|
|
183
|
-
let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
183
|
+
function mapParams(params, options = {}) {
|
|
184
184
|
if (!params) {
|
|
185
185
|
return;
|
|
186
186
|
}
|
|
@@ -354,13 +354,12 @@ function buildInstanceWadoUrl(config, instance) {
|
|
|
354
354
|
* @param thumbnail
|
|
355
355
|
* @returns {string} The imageId to be used by Cornerstone
|
|
356
356
|
*/
|
|
357
|
-
function getImageId(
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
} = _ref;
|
|
357
|
+
function getImageId({
|
|
358
|
+
instance,
|
|
359
|
+
frame,
|
|
360
|
+
config,
|
|
361
|
+
thumbnail = false
|
|
362
|
+
}) {
|
|
364
363
|
if (!instance) {
|
|
365
364
|
return;
|
|
366
365
|
}
|
|
@@ -380,7 +379,7 @@ function getImageId(_ref) {
|
|
|
380
379
|
}
|
|
381
380
|
}
|
|
382
381
|
// EXTERNAL MODULE: ../../../node_modules/dcmjs/build/dcmjs.es.js
|
|
383
|
-
var dcmjs_es = __webpack_require__(
|
|
382
|
+
var dcmjs_es = __webpack_require__(31426);
|
|
384
383
|
;// CONCATENATED MODULE: ../../../extensions/default/src/DicomWebDataSource/wado/retrieveMetadataLoader.js
|
|
385
384
|
/**
|
|
386
385
|
* Class to define inheritance of load retrieve strategy.
|
|
@@ -395,13 +394,11 @@ class RetrieveMetadataLoader {
|
|
|
395
394
|
* @param {Object} client The dicomweb-client.
|
|
396
395
|
* @param {Array} studyInstanceUID Study instance ui to be retrieved
|
|
397
396
|
* @param {Object} [filters] - Object containing filters to be applied on retrieve metadata process
|
|
398
|
-
* @param {string} [
|
|
399
|
-
* @param {
|
|
397
|
+
* @param {string} [filters.seriesInstanceUID] - series instance uid to filter results against
|
|
398
|
+
* @param {Object} [sortCriteria] - Custom sort criteria used for series
|
|
399
|
+
* @param {Function} [sortFunction] - Custom sort function for series
|
|
400
400
|
*/
|
|
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;
|
|
401
|
+
constructor(client, studyInstanceUID, filters = {}, sortCriteria = undefined, sortFunction = undefined) {
|
|
405
402
|
this.client = client;
|
|
406
403
|
this.studyInstanceUID = studyInstanceUID;
|
|
407
404
|
this.filters = filters;
|
|
@@ -422,13 +419,9 @@ class RetrieveMetadataLoader {
|
|
|
422
419
|
async runLoaders(loaders) {
|
|
423
420
|
let result;
|
|
424
421
|
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;
|
|
422
|
+
result = await loader();
|
|
423
|
+
if (result && result.length) {
|
|
424
|
+
break; // closes iterator in case data is retrieved successfully
|
|
432
425
|
}
|
|
433
426
|
}
|
|
434
427
|
if (loaders.next().done && !result) {
|
|
@@ -511,11 +504,64 @@ class RetrieveMetadataLoaderSync extends RetrieveMetadataLoader {
|
|
|
511
504
|
|
|
512
505
|
|
|
513
506
|
|
|
507
|
+
// Series Date, Series Time, Series Description and Series Number to be included
|
|
508
|
+
// in the series metadata query result
|
|
509
|
+
const includeField = ['00080021', '00080031', '0008103E', '00200011'].join(',');
|
|
510
|
+
class DeferredPromise {
|
|
511
|
+
constructor() {
|
|
512
|
+
this.metadata = undefined;
|
|
513
|
+
this.processFunction = undefined;
|
|
514
|
+
this.internalPromise = undefined;
|
|
515
|
+
this.thenFunction = undefined;
|
|
516
|
+
this.rejectFunction = undefined;
|
|
517
|
+
}
|
|
518
|
+
setMetadata(metadata) {
|
|
519
|
+
this.metadata = metadata;
|
|
520
|
+
}
|
|
521
|
+
setProcessFunction(func) {
|
|
522
|
+
this.processFunction = func;
|
|
523
|
+
}
|
|
524
|
+
getPromise() {
|
|
525
|
+
return this.start();
|
|
526
|
+
}
|
|
527
|
+
start() {
|
|
528
|
+
if (this.internalPromise) {
|
|
529
|
+
return this.internalPromise;
|
|
530
|
+
}
|
|
531
|
+
this.internalPromise = this.processFunction();
|
|
532
|
+
// in case then and reject functions called before start
|
|
533
|
+
if (this.thenFunction) {
|
|
534
|
+
this.then(this.thenFunction);
|
|
535
|
+
this.thenFunction = undefined;
|
|
536
|
+
}
|
|
537
|
+
if (this.rejectFunction) {
|
|
538
|
+
this.reject(this.rejectFunction);
|
|
539
|
+
this.rejectFunction = undefined;
|
|
540
|
+
}
|
|
541
|
+
return this.internalPromise;
|
|
542
|
+
}
|
|
543
|
+
then(func) {
|
|
544
|
+
if (this.internalPromise) {
|
|
545
|
+
return this.internalPromise.then(func);
|
|
546
|
+
} else {
|
|
547
|
+
this.thenFunction = func;
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
reject(func) {
|
|
551
|
+
if (this.internalPromise) {
|
|
552
|
+
return this.internalPromise.reject(func);
|
|
553
|
+
} else {
|
|
554
|
+
this.rejectFunction = func;
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
}
|
|
514
558
|
/**
|
|
515
|
-
* Creates an immutable series loader object which loads each series sequentially using the iterator interface
|
|
559
|
+
* Creates an immutable series loader object which loads each series sequentially using the iterator interface.
|
|
560
|
+
*
|
|
516
561
|
* @param {DICOMWebClient} dicomWebClient The DICOMWebClient instance to be used for series load
|
|
517
562
|
* @param {string} studyInstanceUID The Study Instance UID from which series will be loaded
|
|
518
563
|
* @param {Array} seriesInstanceUIDList A list of Series Instance UIDs
|
|
564
|
+
*
|
|
519
565
|
* @returns {Object} Returns an object which supports loading of instances from each of given Series Instance UID
|
|
520
566
|
*/
|
|
521
567
|
function makeSeriesAsyncLoader(client, studyInstanceUID, seriesInstanceUIDList) {
|
|
@@ -523,12 +569,20 @@ function makeSeriesAsyncLoader(client, studyInstanceUID, seriesInstanceUIDList)
|
|
|
523
569
|
hasNext() {
|
|
524
570
|
return seriesInstanceUIDList.length > 0;
|
|
525
571
|
},
|
|
526
|
-
|
|
527
|
-
const
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
572
|
+
next() {
|
|
573
|
+
const {
|
|
574
|
+
seriesInstanceUID,
|
|
575
|
+
metadata
|
|
576
|
+
} = seriesInstanceUIDList.shift();
|
|
577
|
+
const promise = new DeferredPromise();
|
|
578
|
+
promise.setMetadata(metadata);
|
|
579
|
+
promise.setProcessFunction(() => {
|
|
580
|
+
return client.retrieveSeriesMetadata({
|
|
581
|
+
studyInstanceUID,
|
|
582
|
+
seriesInstanceUID
|
|
583
|
+
});
|
|
531
584
|
});
|
|
585
|
+
return promise;
|
|
532
586
|
}
|
|
533
587
|
});
|
|
534
588
|
}
|
|
@@ -552,19 +606,22 @@ class RetrieveMetadataLoaderAsync extends RetrieveMetadataLoader {
|
|
|
552
606
|
} = {},
|
|
553
607
|
client
|
|
554
608
|
} = this;
|
|
609
|
+
|
|
610
|
+
// asking to include Series Date, Series Time, Series Description
|
|
611
|
+
// and Series Number in the series metadata returned to better sort series
|
|
612
|
+
// in preLoad function
|
|
613
|
+
let options = {
|
|
614
|
+
studyInstanceUID,
|
|
615
|
+
queryParams: {
|
|
616
|
+
includefield: includeField
|
|
617
|
+
}
|
|
618
|
+
};
|
|
555
619
|
if (seriesInstanceUID) {
|
|
556
|
-
|
|
557
|
-
studyInstanceUID,
|
|
558
|
-
queryParams: {
|
|
559
|
-
SeriesInstanceUID: seriesInstanceUID
|
|
560
|
-
}
|
|
561
|
-
};
|
|
620
|
+
options.queryParams.SeriesInstanceUID = seriesInstanceUID;
|
|
562
621
|
preLoaders.push(client.searchForSeries.bind(client, options));
|
|
563
622
|
}
|
|
564
623
|
// Fallback preloader
|
|
565
|
-
preLoaders.push(client.searchForSeries.bind(client,
|
|
566
|
-
studyInstanceUID
|
|
567
|
-
}));
|
|
624
|
+
preLoaders.push(client.searchForSeries.bind(client, options));
|
|
568
625
|
yield* preLoaders;
|
|
569
626
|
}
|
|
570
627
|
async preLoad() {
|
|
@@ -574,31 +631,36 @@ class RetrieveMetadataLoaderAsync extends RetrieveMetadataLoader {
|
|
|
574
631
|
const sortFunction = this.sortFunction;
|
|
575
632
|
const {
|
|
576
633
|
naturalizeDataset
|
|
577
|
-
} = dcmjs_es
|
|
634
|
+
} = dcmjs_es/* default.data */.Ay.data.DicomMetaDictionary;
|
|
578
635
|
const naturalized = result.map(naturalizeDataset);
|
|
579
|
-
return (0,sortStudy/* sortStudySeries */.
|
|
636
|
+
return (0,sortStudy/* sortStudySeries */.LM)(naturalized, sortCriteria, sortFunction);
|
|
580
637
|
}
|
|
581
638
|
async load(preLoadData) {
|
|
582
639
|
const {
|
|
583
640
|
client,
|
|
584
641
|
studyInstanceUID
|
|
585
642
|
} = this;
|
|
586
|
-
const seriesInstanceUIDs = preLoadData.map(
|
|
643
|
+
const seriesInstanceUIDs = preLoadData.map(seriesMetadata => {
|
|
644
|
+
return {
|
|
645
|
+
seriesInstanceUID: seriesMetadata.SeriesInstanceUID,
|
|
646
|
+
metadata: seriesMetadata
|
|
647
|
+
};
|
|
648
|
+
});
|
|
587
649
|
const seriesAsyncLoader = makeSeriesAsyncLoader(client, studyInstanceUID, seriesInstanceUIDs);
|
|
588
650
|
const promises = [];
|
|
589
651
|
while (seriesAsyncLoader.hasNext()) {
|
|
590
|
-
|
|
652
|
+
const promise = seriesAsyncLoader.next();
|
|
653
|
+
promises.push(promise);
|
|
591
654
|
}
|
|
592
655
|
return {
|
|
593
656
|
preLoadData,
|
|
594
657
|
promises
|
|
595
658
|
};
|
|
596
659
|
}
|
|
597
|
-
async posLoad(
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
} = _ref;
|
|
660
|
+
async posLoad({
|
|
661
|
+
preLoadData,
|
|
662
|
+
promises
|
|
663
|
+
}) {
|
|
602
664
|
return {
|
|
603
665
|
preLoadData,
|
|
604
666
|
promises
|
|
@@ -613,40 +675,91 @@ class RetrieveMetadataLoaderAsync extends RetrieveMetadataLoader {
|
|
|
613
675
|
* Retrieve Study metadata from a DICOM server. If the server is configured to use lazy load, only the first series
|
|
614
676
|
* will be loaded and the property "studyLoader" will be set to let consumer load remaining series as needed.
|
|
615
677
|
*
|
|
616
|
-
* @param {
|
|
617
|
-
* @param {
|
|
618
|
-
* @param {
|
|
619
|
-
* @param {
|
|
620
|
-
* @
|
|
678
|
+
* @param {*} dicomWebClient The DICOMWebClient instance to be used for series load
|
|
679
|
+
* @param {*} StudyInstanceUID The UID of the Study to be retrieved
|
|
680
|
+
* @param {*} enableStudyLazyLoad Whether the study metadata should be loaded asynchronously
|
|
681
|
+
* @param {object} filters Object containing filters to be applied on retrieve metadata process
|
|
682
|
+
* @param {string} [filters.seriesInstanceUID] Series instance uid to filter results against
|
|
683
|
+
* @param {array} [filters.SeriesInstanceUIDs] Series instance uids to filter results against
|
|
684
|
+
* @param {function} [sortCriteria] Sort criteria function
|
|
685
|
+
* @param {function} [sortFunction] Sort function
|
|
686
|
+
*
|
|
687
|
+
* @returns {Promise} A promises that resolves the study descriptor object
|
|
621
688
|
*/
|
|
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;
|
|
689
|
+
async function RetrieveMetadata(dicomWebClient, StudyInstanceUID, enableStudyLazyLoad, filters = {}, sortCriteria, sortFunction) {
|
|
626
690
|
const RetrieveMetadataLoader = enableStudyLazyLoad !== false ? RetrieveMetadataLoaderAsync : RetrieveMetadataLoaderSync;
|
|
627
|
-
const retrieveMetadataLoader = new RetrieveMetadataLoader(dicomWebClient,
|
|
691
|
+
const retrieveMetadataLoader = new RetrieveMetadataLoader(dicomWebClient, StudyInstanceUID, filters, sortCriteria, sortFunction);
|
|
628
692
|
const data = await retrieveMetadataLoader.execLoad();
|
|
629
693
|
return data;
|
|
630
694
|
}
|
|
631
695
|
/* harmony default export */ const retrieveMetadata = (RetrieveMetadata);
|
|
696
|
+
;// CONCATENATED MODULE: ../../../extensions/default/src/DicomWebDataSource/utils/retrieveMetadataFiltered.js
|
|
697
|
+
|
|
698
|
+
|
|
699
|
+
/**
|
|
700
|
+
* Retrieve metadata filtered.
|
|
701
|
+
*
|
|
702
|
+
* @param {*} dicomWebClient The DICOMWebClient instance to be used for series load
|
|
703
|
+
* @param {*} StudyInstanceUID The UID of the Study to be retrieved
|
|
704
|
+
* @param {*} enableStudyLazyLoad Whether the study metadata should be loaded asynchronously
|
|
705
|
+
* @param {object} filters Object containing filters to be applied on retrieve metadata process
|
|
706
|
+
* @param {string} [filters.seriesInstanceUID] Series instance uid to filter results against
|
|
707
|
+
* @param {array} [filters.SeriesInstanceUIDs] Series instance uids to filter results against
|
|
708
|
+
* @param {function} [sortCriteria] Sort criteria function
|
|
709
|
+
* @param {function} [sortFunction] Sort function
|
|
710
|
+
*
|
|
711
|
+
* @returns
|
|
712
|
+
*/
|
|
713
|
+
function retrieveMetadataFiltered(dicomWebClient, StudyInstanceUID, enableStudyLazyLoad, filters, sortCriteria, sortFunction) {
|
|
714
|
+
const {
|
|
715
|
+
SeriesInstanceUIDs
|
|
716
|
+
} = filters;
|
|
717
|
+
return new Promise((resolve, reject) => {
|
|
718
|
+
const promises = SeriesInstanceUIDs.map(uid => {
|
|
719
|
+
const seriesSpecificFilters = Object.assign({}, filters, {
|
|
720
|
+
seriesInstanceUID: uid
|
|
721
|
+
});
|
|
722
|
+
return retrieveMetadata(dicomWebClient, StudyInstanceUID, enableStudyLazyLoad, seriesSpecificFilters, sortCriteria, sortFunction);
|
|
723
|
+
});
|
|
724
|
+
Promise.all(promises).then(results => {
|
|
725
|
+
const aggregatedResult = {
|
|
726
|
+
preLoadData: [],
|
|
727
|
+
promises: []
|
|
728
|
+
};
|
|
729
|
+
results.forEach(({
|
|
730
|
+
preLoadData,
|
|
731
|
+
promises
|
|
732
|
+
}) => {
|
|
733
|
+
aggregatedResult.preLoadData = aggregatedResult.preLoadData.concat(preLoadData);
|
|
734
|
+
aggregatedResult.promises = aggregatedResult.promises.concat(promises);
|
|
735
|
+
});
|
|
736
|
+
resolve(aggregatedResult);
|
|
737
|
+
}, reject);
|
|
738
|
+
});
|
|
739
|
+
}
|
|
740
|
+
/* harmony default export */ const utils_retrieveMetadataFiltered = (retrieveMetadataFiltered);
|
|
632
741
|
;// CONCATENATED MODULE: ../../../extensions/default/src/DicomWebDataSource/retrieveStudyMetadata.js
|
|
633
742
|
|
|
743
|
+
|
|
634
744
|
const moduleName = 'RetrieveStudyMetadata';
|
|
635
745
|
// Cache for promises. Prevents unnecessary subsequent calls to the server
|
|
636
746
|
const StudyMetaDataPromises = new Map();
|
|
637
747
|
|
|
638
748
|
/**
|
|
639
|
-
* Retrieves study metadata
|
|
749
|
+
* Retrieves study metadata.
|
|
640
750
|
*
|
|
641
|
-
* @param {Object}
|
|
751
|
+
* @param {Object} dicomWebClient The DICOMWebClient instance to be used for series load
|
|
642
752
|
* @param {string} StudyInstanceUID The UID of the Study to be retrieved
|
|
643
|
-
* @param {boolean}
|
|
644
|
-
* @param {
|
|
645
|
-
* @param {
|
|
646
|
-
* @param {
|
|
753
|
+
* @param {boolean} enableStudyLazyLoad Whether the study metadata should be loaded asynchronously.
|
|
754
|
+
* @param {Object} [filters] Object containing filters to be applied on retrieve metadata process
|
|
755
|
+
* @param {string} [filters.seriesInstanceUID] Series instance uid to filter results against
|
|
756
|
+
* @param {array} [filters.SeriesInstanceUIDs] Series instance uids to filter results against
|
|
757
|
+
* @param {function} [sortCriteria] Sort criteria function
|
|
758
|
+
* @param {function} [sortFunction] Sort function
|
|
759
|
+
*
|
|
647
760
|
* @returns {Promise} that will be resolved with the metadata or rejected with the error
|
|
648
761
|
*/
|
|
649
|
-
function retrieveStudyMetadata(dicomWebClient, StudyInstanceUID, enableStudyLazyLoad, filters, sortCriteria, sortFunction) {
|
|
762
|
+
function retrieveStudyMetadata(dicomWebClient, StudyInstanceUID, enableStudyLazyLoad, filters, sortCriteria, sortFunction, dicomWebConfig = {}) {
|
|
650
763
|
// @TODO: Whenever a study metadata request has failed, its related promise will be rejected once and for all
|
|
651
764
|
// and further requests for that metadata will always fail. On failure, we probably need to remove the
|
|
652
765
|
// corresponding promise from the "StudyMetaDataPromises" map...
|
|
@@ -657,39 +770,157 @@ function retrieveStudyMetadata(dicomWebClient, StudyInstanceUID, enableStudyLazy
|
|
|
657
770
|
if (!StudyInstanceUID) {
|
|
658
771
|
throw new Error(`${moduleName}: Required 'StudyInstanceUID' parameter not provided.`);
|
|
659
772
|
}
|
|
773
|
+
const promiseId = `${dicomWebConfig.name}:${StudyInstanceUID}`;
|
|
660
774
|
|
|
661
775
|
// Already waiting on result? Return cached promise
|
|
662
|
-
if (StudyMetaDataPromises.has(
|
|
663
|
-
return StudyMetaDataPromises.get(
|
|
776
|
+
if (StudyMetaDataPromises.has(promiseId)) {
|
|
777
|
+
return StudyMetaDataPromises.get(promiseId);
|
|
778
|
+
}
|
|
779
|
+
let promise;
|
|
780
|
+
if (filters && filters.SeriesInstanceUIDs) {
|
|
781
|
+
promise = utils_retrieveMetadataFiltered(dicomWebClient, StudyInstanceUID, enableStudyLazyLoad, filters, sortCriteria, sortFunction);
|
|
782
|
+
} else {
|
|
783
|
+
// Create a promise to handle the data retrieval
|
|
784
|
+
promise = new Promise((resolve, reject) => {
|
|
785
|
+
retrieveMetadata(dicomWebClient, StudyInstanceUID, enableStudyLazyLoad, filters, sortCriteria, sortFunction).then(function (data) {
|
|
786
|
+
resolve(data);
|
|
787
|
+
}, reject);
|
|
788
|
+
});
|
|
664
789
|
}
|
|
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
790
|
|
|
673
791
|
// Store the promise in cache
|
|
674
|
-
StudyMetaDataPromises.set(
|
|
792
|
+
StudyMetaDataPromises.set(promiseId, promise);
|
|
675
793
|
return promise;
|
|
676
794
|
}
|
|
677
795
|
|
|
678
796
|
/**
|
|
679
797
|
* Delete the cached study metadata retrieval promise to ensure that the browser will
|
|
680
|
-
* re-retrieve the study metadata when it is next requested
|
|
798
|
+
* re-retrieve the study metadata when it is next requested.
|
|
681
799
|
*
|
|
682
800
|
* @param {String} StudyInstanceUID The UID of the Study to be removed from cache
|
|
683
|
-
*
|
|
684
801
|
*/
|
|
685
802
|
function deleteStudyMetadataPromise(StudyInstanceUID) {
|
|
686
803
|
if (StudyMetaDataPromises.has(StudyInstanceUID)) {
|
|
687
804
|
StudyMetaDataPromises.delete(StudyInstanceUID);
|
|
688
805
|
}
|
|
689
806
|
}
|
|
807
|
+
;// CONCATENATED MODULE: ../../../extensions/default/src/DicomWebDataSource/utils/findIndexOfString.ts
|
|
808
|
+
function checkToken(token, data, dataOffset) {
|
|
809
|
+
if (dataOffset + token.length > data.length) {
|
|
810
|
+
return false;
|
|
811
|
+
}
|
|
812
|
+
let endIndex = dataOffset;
|
|
813
|
+
for (let i = 0; i < token.length; i++) {
|
|
814
|
+
if (token[i] !== data[endIndex++]) {
|
|
815
|
+
return false;
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
return true;
|
|
819
|
+
}
|
|
820
|
+
function stringToUint8Array(str) {
|
|
821
|
+
const uint = new Uint8Array(str.length);
|
|
822
|
+
for (let i = 0, j = str.length; i < j; i++) {
|
|
823
|
+
uint[i] = str.charCodeAt(i);
|
|
824
|
+
}
|
|
825
|
+
return uint;
|
|
826
|
+
}
|
|
827
|
+
function findIndexOfString(data, str, offset) {
|
|
828
|
+
offset = offset || 0;
|
|
829
|
+
const token = stringToUint8Array(str);
|
|
830
|
+
for (let i = offset; i < data.length; i++) {
|
|
831
|
+
if (token[0] === data[i]) {
|
|
832
|
+
// console.log('match @', i);
|
|
833
|
+
if (checkToken(token, data, i)) {
|
|
834
|
+
return i;
|
|
835
|
+
}
|
|
836
|
+
}
|
|
837
|
+
}
|
|
838
|
+
return -1;
|
|
839
|
+
}
|
|
840
|
+
/* harmony default export */ const utils_findIndexOfString = (findIndexOfString);
|
|
841
|
+
;// CONCATENATED MODULE: ../../../extensions/default/src/DicomWebDataSource/utils/fixMultipart.ts
|
|
842
|
+
|
|
843
|
+
|
|
844
|
+
/**
|
|
845
|
+
* Fix multipart data coming back from the retrieve bulkdata request, but
|
|
846
|
+
* incorrectly tagged as application/octet-stream. Some servers don't handle
|
|
847
|
+
* the response type correctly, and this method is relatively robust about
|
|
848
|
+
* detecting multipart data correctly. It will only extract one value.
|
|
849
|
+
*/
|
|
850
|
+
function fixMultipart(arrayData) {
|
|
851
|
+
const data = new Uint8Array(arrayData[0]);
|
|
852
|
+
// Don't know the exact minimum length, but it is at least 25 to encode multipart
|
|
853
|
+
if (data.length < 25) {
|
|
854
|
+
return arrayData;
|
|
855
|
+
}
|
|
856
|
+
const dashIndex = utils_findIndexOfString(data, '--');
|
|
857
|
+
if (dashIndex > 6) {
|
|
858
|
+
return arrayData;
|
|
859
|
+
}
|
|
860
|
+
const tokenIndex = utils_findIndexOfString(data, '\r\n\r\n', dashIndex);
|
|
861
|
+
if (tokenIndex > 512) {
|
|
862
|
+
// Allow for 512 characters in the header - there is no apriori limit, but
|
|
863
|
+
// this seems ok for now as we only expect it to have content type in it.
|
|
864
|
+
return arrayData;
|
|
865
|
+
}
|
|
866
|
+
const header = uint8ArrayToString(data, 0, tokenIndex);
|
|
867
|
+
// Now find the boundary marker
|
|
868
|
+
const responseHeaders = header.split('\r\n');
|
|
869
|
+
const boundary = findBoundary(responseHeaders);
|
|
870
|
+
if (!boundary) {
|
|
871
|
+
return arrayData;
|
|
872
|
+
}
|
|
873
|
+
// Start of actual data is 4 characters after the token
|
|
874
|
+
const offset = tokenIndex + 4;
|
|
875
|
+
const endIndex = utils_findIndexOfString(data, boundary, offset);
|
|
876
|
+
if (endIndex === -1) {
|
|
877
|
+
return arrayData;
|
|
878
|
+
}
|
|
879
|
+
return [data.slice(offset, endIndex - 2).buffer];
|
|
880
|
+
}
|
|
881
|
+
function findBoundary(header) {
|
|
882
|
+
for (let i = 0; i < header.length; i++) {
|
|
883
|
+
if (header[i].substr(0, 2) === '--') {
|
|
884
|
+
return header[i];
|
|
885
|
+
}
|
|
886
|
+
}
|
|
887
|
+
}
|
|
888
|
+
function findContentType(header) {
|
|
889
|
+
for (let i = 0; i < header.length; i++) {
|
|
890
|
+
if (header[i].substr(0, 13) === 'Content-Type:') {
|
|
891
|
+
return header[i].substr(13).trim();
|
|
892
|
+
}
|
|
893
|
+
}
|
|
894
|
+
}
|
|
895
|
+
function uint8ArrayToString(data, offset, length) {
|
|
896
|
+
offset = offset || 0;
|
|
897
|
+
length = length || data.length - offset;
|
|
898
|
+
let str = '';
|
|
899
|
+
for (let i = offset; i < offset + length; i++) {
|
|
900
|
+
str += String.fromCharCode(data[i]);
|
|
901
|
+
}
|
|
902
|
+
return str;
|
|
903
|
+
}
|
|
690
904
|
;// CONCATENATED MODULE: ../../../extensions/default/src/DicomWebDataSource/utils/StaticWadoClient.ts
|
|
691
905
|
|
|
692
906
|
|
|
907
|
+
const {
|
|
908
|
+
DICOMwebClient
|
|
909
|
+
} = dicomweb_client_es/* api */.FH;
|
|
910
|
+
const anyDicomwebClient = DICOMwebClient;
|
|
911
|
+
|
|
912
|
+
// Ugly over-ride, but the internals aren't otherwise accessible.
|
|
913
|
+
if (!anyDicomwebClient._orig_buildMultipartAcceptHeaderFieldValue) {
|
|
914
|
+
anyDicomwebClient._orig_buildMultipartAcceptHeaderFieldValue = anyDicomwebClient._buildMultipartAcceptHeaderFieldValue;
|
|
915
|
+
anyDicomwebClient._buildMultipartAcceptHeaderFieldValue = function (mediaTypes, acceptableTypes) {
|
|
916
|
+
if (mediaTypes.length === 1 && mediaTypes[0].mediaType.endsWith('/*')) {
|
|
917
|
+
return '*/*';
|
|
918
|
+
} else {
|
|
919
|
+
return anyDicomwebClient._orig_buildMultipartAcceptHeaderFieldValue(mediaTypes, acceptableTypes);
|
|
920
|
+
}
|
|
921
|
+
};
|
|
922
|
+
}
|
|
923
|
+
|
|
693
924
|
/**
|
|
694
925
|
* An implementation of the static wado client, that fetches data from
|
|
695
926
|
* a static response rather than actually doing real queries. This allows
|
|
@@ -697,10 +928,53 @@ function deleteStudyMetadataPromise(StudyInstanceUID) {
|
|
|
697
928
|
* performing searches doesn't work. This version fixes the query issue
|
|
698
929
|
* by manually implementing a query option.
|
|
699
930
|
*/
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
931
|
+
|
|
932
|
+
class StaticWadoClient extends dicomweb_client_es/* api */.FH.DICOMwebClient {
|
|
933
|
+
constructor(config) {
|
|
934
|
+
super(config);
|
|
935
|
+
this.config = void 0;
|
|
936
|
+
this.staticWado = void 0;
|
|
937
|
+
this.staticWado = config.staticWado;
|
|
938
|
+
this.config = config;
|
|
939
|
+
}
|
|
940
|
+
|
|
941
|
+
/**
|
|
942
|
+
* Handle improperly specified multipart/related return type.
|
|
943
|
+
* Note if the response is SUPPOSED to be multipart encoded already, then this
|
|
944
|
+
* will double-decode it.
|
|
945
|
+
*
|
|
946
|
+
* @param options
|
|
947
|
+
* @returns De-multiparted response data.
|
|
948
|
+
*
|
|
949
|
+
*/
|
|
950
|
+
retrieveBulkData(options) {
|
|
951
|
+
const shouldFixMultipart = this.config.fixBulkdataMultipart !== false;
|
|
952
|
+
const useOptions = {
|
|
953
|
+
...options
|
|
954
|
+
};
|
|
955
|
+
if (this.staticWado) {
|
|
956
|
+
useOptions.mediaTypes = [{
|
|
957
|
+
mediaType: 'application/*'
|
|
958
|
+
}];
|
|
959
|
+
}
|
|
960
|
+
return super.retrieveBulkData(useOptions).then(result => shouldFixMultipart ? fixMultipart(result) : result);
|
|
961
|
+
}
|
|
962
|
+
|
|
963
|
+
/**
|
|
964
|
+
* Retrieves instance frames using the image/* media type when configured
|
|
965
|
+
* to do so (static wado back end).
|
|
966
|
+
*/
|
|
967
|
+
retrieveInstanceFrames(options) {
|
|
968
|
+
if (this.staticWado) {
|
|
969
|
+
return super.retrieveInstanceFrames({
|
|
970
|
+
...options,
|
|
971
|
+
mediaTypes: [{
|
|
972
|
+
mediaType: 'image/*'
|
|
973
|
+
}]
|
|
974
|
+
});
|
|
975
|
+
} else {
|
|
976
|
+
return super.retrieveInstanceFrames(options);
|
|
977
|
+
}
|
|
704
978
|
}
|
|
705
979
|
|
|
706
980
|
/**
|
|
@@ -841,8 +1115,7 @@ class StaticWadoClient extends dicomweb_client_es.api.DICOMwebClient {
|
|
|
841
1115
|
/** Converts the query parameters to lower case query parameters */
|
|
842
1116
|
toLowerParams(queryParams) {
|
|
843
1117
|
const lowerParams = {};
|
|
844
|
-
Object.entries(queryParams).forEach(
|
|
845
|
-
let [key, value] = _ref;
|
|
1118
|
+
Object.entries(queryParams).forEach(([key, value]) => {
|
|
846
1119
|
lowerParams[key.toLowerCase()] = value;
|
|
847
1120
|
});
|
|
848
1121
|
return lowerParams;
|
|
@@ -875,6 +1148,7 @@ StaticWadoClient.seriesFilterKeys = {
|
|
|
875
1148
|
* @param {string} params.defaultType is the mime type of the response
|
|
876
1149
|
* @param {string} params.singlepart is the type of the part to retrieve
|
|
877
1150
|
* @param {string} params.fetchPart unknown?
|
|
1151
|
+
* @param {string} params.url unknown?
|
|
878
1152
|
* @returns an absolute URL to the resource, if the absolute URL can be retrieved as singlepart,
|
|
879
1153
|
* or is already retrieved, or a promise to a URL for such use if a BulkDataURI
|
|
880
1154
|
*/
|
|
@@ -888,8 +1162,12 @@ const getDirectURL = (config, params) => {
|
|
|
888
1162
|
tag = 'PixelData',
|
|
889
1163
|
defaultPath = '/pixeldata',
|
|
890
1164
|
defaultType = 'video/mp4',
|
|
891
|
-
singlepart: fetchPart = 'video'
|
|
1165
|
+
singlepart: fetchPart = 'video',
|
|
1166
|
+
url = null
|
|
892
1167
|
} = params;
|
|
1168
|
+
if (url) {
|
|
1169
|
+
return url;
|
|
1170
|
+
}
|
|
893
1171
|
const value = instance[tag];
|
|
894
1172
|
if (!value) {
|
|
895
1173
|
return undefined;
|
|
@@ -904,7 +1182,11 @@ const getDirectURL = (config, params) => {
|
|
|
904
1182
|
}
|
|
905
1183
|
if (!singlepart || singlepart !== true && singlepart.indexOf(fetchPart) === -1) {
|
|
906
1184
|
if (value.retrieveBulkData) {
|
|
907
|
-
|
|
1185
|
+
// Try the specified retrieve type.
|
|
1186
|
+
const options = {
|
|
1187
|
+
mediaType: defaultType
|
|
1188
|
+
};
|
|
1189
|
+
return value.retrieveBulkData(options).then(arr => {
|
|
908
1190
|
value.DirectRetrieveURL = URL.createObjectURL(new Blob([arr], {
|
|
909
1191
|
type: defaultType
|
|
910
1192
|
}));
|
|
@@ -995,7 +1277,7 @@ function fixBulkDataURI(value, instance, dicomWebConfig) {
|
|
|
995
1277
|
const {
|
|
996
1278
|
DicomMetaDictionary,
|
|
997
1279
|
DicomDict
|
|
998
|
-
} = dcmjs_es
|
|
1280
|
+
} = dcmjs_es/* default.data */.Ay.data;
|
|
999
1281
|
const {
|
|
1000
1282
|
naturalizeDataset,
|
|
1001
1283
|
denaturalizeDataset
|
|
@@ -1006,26 +1288,47 @@ const EXPLICIT_VR_LITTLE_ENDIAN = '1.2.840.10008.1.2.1';
|
|
|
1006
1288
|
const metadataProvider = src.classes.MetadataProvider;
|
|
1007
1289
|
|
|
1008
1290
|
/**
|
|
1291
|
+
* Creates a DICOM Web API based on the provided configuration.
|
|
1009
1292
|
*
|
|
1010
|
-
* @param {
|
|
1011
|
-
* @param {string}
|
|
1012
|
-
* @param {string}
|
|
1013
|
-
* @param {string}
|
|
1014
|
-
* @param {
|
|
1015
|
-
* @param {string}
|
|
1016
|
-
* @param {
|
|
1017
|
-
* @param {
|
|
1018
|
-
* @param {
|
|
1019
|
-
* @param {
|
|
1293
|
+
* @param {object} dicomWebConfig - Configuration for the DICOM Web API
|
|
1294
|
+
* @param {string} dicomWebConfig.name - Data source name
|
|
1295
|
+
* @param {string} dicomWebConfig.wadoUriRoot - Legacy? (potentially unused/replaced)
|
|
1296
|
+
* @param {string} dicomWebConfig.qidoRoot - Base URL to use for QIDO requests
|
|
1297
|
+
* @param {string} dicomWebConfig.wadoRoot - Base URL to use for WADO requests
|
|
1298
|
+
* @param {string} dicomWebConfig.wadoUri - Base URL to use for WADO URI requests
|
|
1299
|
+
* @param {boolean} dicomWebConfig.qidoSupportsIncludeField - Whether QIDO supports the "Include" option to request additional fields in response
|
|
1300
|
+
* @param {string} dicomWebConfig.imageRendering - wadors | ? (unsure of where/how this is used)
|
|
1301
|
+
* @param {string} dicomWebConfig.thumbnailRendering - wadors | ? (unsure of where/how this is used)
|
|
1302
|
+
* @param {boolean} dicomWebConfig.supportsReject - Whether the server supports reject calls (i.e. DCM4CHEE)
|
|
1303
|
+
* @param {boolean} dicomWebConfig.lazyLoadStudy - "enableStudyLazyLoad"; Request series meta async instead of blocking
|
|
1304
|
+
* @param {string|boolean} dicomWebConfig.singlepart - indicates if the retrieves can fetch singlepart. Options are bulkdata, video, image, or boolean true
|
|
1305
|
+
* @param {string} dicomWebConfig.requestTransferSyntaxUID - Transfer syntax to request from the server
|
|
1306
|
+
* @param {object} dicomWebConfig.acceptHeader - Accept header to use for requests
|
|
1307
|
+
* @param {boolean} dicomWebConfig.omitQuotationForMultipartRequest - Whether to omit quotation marks for multipart requests
|
|
1308
|
+
* @param {boolean} dicomWebConfig.supportsFuzzyMatching - Whether the server supports fuzzy matching
|
|
1309
|
+
* @param {boolean} dicomWebConfig.supportsWildcard - Whether the server supports wildcard matching
|
|
1310
|
+
* @param {boolean} dicomWebConfig.supportsNativeDICOMModel - Whether the server supports the native DICOM model
|
|
1311
|
+
* @param {boolean} dicomWebConfig.enableStudyLazyLoad - Whether to enable study lazy loading
|
|
1312
|
+
* @param {boolean} dicomWebConfig.enableRequestTag - Whether to enable request tag
|
|
1313
|
+
* @param {boolean} dicomWebConfig.enableStudyLazyLoad - Whether to enable study lazy loading
|
|
1314
|
+
* @param {boolean} dicomWebConfig.bulkDataURI - Whether to enable bulkDataURI
|
|
1315
|
+
* @param {function} dicomWebConfig.onConfiguration - Function that is called after the configuration is initialized
|
|
1316
|
+
* @param {boolean} dicomWebConfig.staticWado - Whether to use the static WADO client
|
|
1317
|
+
* @param {object} userAuthenticationService - User authentication service
|
|
1318
|
+
* @param {object} userAuthenticationService.getAuthorizationHeader - Function that returns the authorization header
|
|
1319
|
+
* @returns {object} - DICOM Web API object
|
|
1020
1320
|
*/
|
|
1021
|
-
function createDicomWebApi(dicomWebConfig,
|
|
1321
|
+
function createDicomWebApi(dicomWebConfig, servicesManager) {
|
|
1322
|
+
const {
|
|
1323
|
+
userAuthenticationService,
|
|
1324
|
+
customizationService
|
|
1325
|
+
} = servicesManager.services;
|
|
1022
1326
|
let dicomWebConfigCopy, qidoConfig, wadoConfig, qidoDicomWebClient, wadoDicomWebClient, getAuthrorizationHeader, generateWadoHeader;
|
|
1023
1327
|
const implementation = {
|
|
1024
|
-
initialize:
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
} = _ref;
|
|
1328
|
+
initialize: ({
|
|
1329
|
+
params,
|
|
1330
|
+
query
|
|
1331
|
+
}) => {
|
|
1029
1332
|
if (dicomWebConfig.onConfiguration && typeof dicomWebConfig.onConfiguration === 'function') {
|
|
1030
1333
|
dicomWebConfig = dicomWebConfig.onConfiguration(dicomWebConfig, {
|
|
1031
1334
|
params,
|
|
@@ -1055,20 +1358,20 @@ function createDicomWebApi(dicomWebConfig, userAuthenticationService) {
|
|
|
1055
1358
|
staticWado: dicomWebConfig.staticWado,
|
|
1056
1359
|
singlepart: dicomWebConfig.singlepart,
|
|
1057
1360
|
headers: userAuthenticationService.getAuthorizationHeader(),
|
|
1058
|
-
errorInterceptor: src/* errorHandler */.
|
|
1361
|
+
errorInterceptor: src/* errorHandler */.r_.getHTTPErrorHandler()
|
|
1059
1362
|
};
|
|
1060
1363
|
wadoConfig = {
|
|
1061
1364
|
url: dicomWebConfig.wadoRoot,
|
|
1062
1365
|
staticWado: dicomWebConfig.staticWado,
|
|
1063
1366
|
singlepart: dicomWebConfig.singlepart,
|
|
1064
1367
|
headers: userAuthenticationService.getAuthorizationHeader(),
|
|
1065
|
-
errorInterceptor: src/* errorHandler */.
|
|
1368
|
+
errorInterceptor: src/* errorHandler */.r_.getHTTPErrorHandler()
|
|
1066
1369
|
};
|
|
1067
1370
|
|
|
1068
1371
|
// TODO -> Two clients sucks, but its better than 1000.
|
|
1069
1372
|
// TODO -> We'll need to merge auth later.
|
|
1070
|
-
qidoDicomWebClient = dicomWebConfig.staticWado ? new StaticWadoClient(qidoConfig) : new dicomweb_client_es
|
|
1071
|
-
wadoDicomWebClient = dicomWebConfig.staticWado ? new StaticWadoClient(wadoConfig) : new dicomweb_client_es
|
|
1373
|
+
qidoDicomWebClient = dicomWebConfig.staticWado ? new StaticWadoClient(qidoConfig) : new dicomweb_client_es/* api */.FH.DICOMwebClient(qidoConfig);
|
|
1374
|
+
wadoDicomWebClient = dicomWebConfig.staticWado ? new StaticWadoClient(wadoConfig) : new dicomweb_client_es/* api */.FH.DICOMwebClient(wadoConfig);
|
|
1072
1375
|
},
|
|
1073
1376
|
query: {
|
|
1074
1377
|
studies: {
|
|
@@ -1097,11 +1400,10 @@ function createDicomWebApi(dicomWebConfig, userAuthenticationService) {
|
|
|
1097
1400
|
}
|
|
1098
1401
|
// processResults: processResults.bind(),
|
|
1099
1402
|
},
|
|
1100
|
-
|
|
1101
1403
|
instances: {
|
|
1102
1404
|
search: (studyInstanceUid, queryParameters) => {
|
|
1103
1405
|
qidoDicomWebClient.headers = getAuthrorizationHeader();
|
|
1104
|
-
search.call(undefined, qidoDicomWebClient, studyInstanceUid, null, queryParameters);
|
|
1406
|
+
return search.call(undefined, qidoDicomWebClient, studyInstanceUid, null, queryParameters);
|
|
1105
1407
|
}
|
|
1106
1408
|
}
|
|
1107
1409
|
},
|
|
@@ -1123,11 +1425,10 @@ function createDicomWebApi(dicomWebConfig, userAuthenticationService) {
|
|
|
1123
1425
|
singlepart: dicomWebConfig.singlepart
|
|
1124
1426
|
}, params);
|
|
1125
1427
|
},
|
|
1126
|
-
bulkDataURI: async
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
} = _ref2;
|
|
1428
|
+
bulkDataURI: async ({
|
|
1429
|
+
StudyInstanceUID,
|
|
1430
|
+
BulkDataURI
|
|
1431
|
+
}) => {
|
|
1131
1432
|
qidoDicomWebClient.headers = getAuthrorizationHeader();
|
|
1132
1433
|
const options = {
|
|
1133
1434
|
multipart: false,
|
|
@@ -1140,26 +1441,26 @@ function createDicomWebApi(dicomWebConfig, userAuthenticationService) {
|
|
|
1140
1441
|
});
|
|
1141
1442
|
},
|
|
1142
1443
|
series: {
|
|
1143
|
-
metadata: async
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1444
|
+
metadata: async ({
|
|
1445
|
+
StudyInstanceUID,
|
|
1446
|
+
filters,
|
|
1447
|
+
sortCriteria,
|
|
1448
|
+
sortFunction,
|
|
1449
|
+
madeInClient = false,
|
|
1450
|
+
returnPromises = false
|
|
1451
|
+
} = {}) => {
|
|
1151
1452
|
if (!StudyInstanceUID) {
|
|
1152
1453
|
throw new Error('Unable to query for SeriesMetadata without StudyInstanceUID');
|
|
1153
1454
|
}
|
|
1154
1455
|
if (dicomWebConfig.enableStudyLazyLoad) {
|
|
1155
|
-
return implementation._retrieveSeriesMetadataAsync(StudyInstanceUID, filters, sortCriteria, sortFunction, madeInClient);
|
|
1456
|
+
return implementation._retrieveSeriesMetadataAsync(StudyInstanceUID, filters, sortCriteria, sortFunction, madeInClient, returnPromises);
|
|
1156
1457
|
}
|
|
1157
1458
|
return implementation._retrieveSeriesMetadataSync(StudyInstanceUID, filters, sortCriteria, sortFunction, madeInClient);
|
|
1158
1459
|
}
|
|
1159
1460
|
}
|
|
1160
1461
|
},
|
|
1161
1462
|
store: {
|
|
1162
|
-
dicom: async (dataset, request) => {
|
|
1463
|
+
dicom: async (dataset, request, dicomDict) => {
|
|
1163
1464
|
wadoDicomWebClient.headers = getAuthrorizationHeader();
|
|
1164
1465
|
if (dataset instanceof ArrayBuffer) {
|
|
1165
1466
|
const options = {
|
|
@@ -1168,18 +1469,22 @@ function createDicomWebApi(dicomWebConfig, userAuthenticationService) {
|
|
|
1168
1469
|
};
|
|
1169
1470
|
await wadoDicomWebClient.storeInstances(options);
|
|
1170
1471
|
} else {
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1472
|
+
let effectiveDicomDict = dicomDict;
|
|
1473
|
+
if (!dicomDict) {
|
|
1474
|
+
const meta = {
|
|
1475
|
+
FileMetaInformationVersion: dataset._meta?.FileMetaInformationVersion?.Value,
|
|
1476
|
+
MediaStorageSOPClassUID: dataset.SOPClassUID,
|
|
1477
|
+
MediaStorageSOPInstanceUID: dataset.SOPInstanceUID,
|
|
1478
|
+
TransferSyntaxUID: EXPLICIT_VR_LITTLE_ENDIAN,
|
|
1479
|
+
ImplementationClassUID,
|
|
1480
|
+
ImplementationVersionName
|
|
1481
|
+
};
|
|
1482
|
+
const denaturalized = denaturalizeDataset(meta);
|
|
1483
|
+
const defaultDicomDict = new DicomDict(denaturalized);
|
|
1484
|
+
defaultDicomDict.dict = denaturalizeDataset(dataset);
|
|
1485
|
+
effectiveDicomDict = defaultDicomDict;
|
|
1486
|
+
}
|
|
1487
|
+
const part10Buffer = effectiveDicomDict.write();
|
|
1183
1488
|
const options = {
|
|
1184
1489
|
datasets: [part10Buffer],
|
|
1185
1490
|
request
|
|
@@ -1192,7 +1497,7 @@ function createDicomWebApi(dicomWebConfig, userAuthenticationService) {
|
|
|
1192
1497
|
const enableStudyLazyLoad = false;
|
|
1193
1498
|
wadoDicomWebClient.headers = generateWadoHeader();
|
|
1194
1499
|
// data is all SOPInstanceUIDs
|
|
1195
|
-
const data = await retrieveStudyMetadata(wadoDicomWebClient, StudyInstanceUID, enableStudyLazyLoad, filters, sortCriteria, sortFunction);
|
|
1500
|
+
const data = await retrieveStudyMetadata(wadoDicomWebClient, StudyInstanceUID, enableStudyLazyLoad, filters, sortCriteria, sortFunction, dicomWebConfig);
|
|
1196
1501
|
|
|
1197
1502
|
// first naturalize the data
|
|
1198
1503
|
const naturalizedInstancesMetadata = data.map(naturalizeDataset);
|
|
@@ -1233,16 +1538,16 @@ function createDicomWebApi(dicomWebConfig, userAuthenticationService) {
|
|
|
1233
1538
|
const seriesMetadata = Object.values(seriesSummaryMetadata);
|
|
1234
1539
|
src.DicomMetadataStore.addSeriesMetadata(seriesMetadata, madeInClient);
|
|
1235
1540
|
Object.keys(instancesPerSeries).forEach(seriesInstanceUID => src.DicomMetadataStore.addInstances(instancesPerSeries[seriesInstanceUID], madeInClient));
|
|
1541
|
+
return seriesSummaryMetadata;
|
|
1236
1542
|
},
|
|
1237
|
-
_retrieveSeriesMetadataAsync: async
|
|
1238
|
-
let madeInClient = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;
|
|
1543
|
+
_retrieveSeriesMetadataAsync: async (StudyInstanceUID, filters, sortCriteria, sortFunction, madeInClient = false, returnPromises = false) => {
|
|
1239
1544
|
const enableStudyLazyLoad = true;
|
|
1240
1545
|
wadoDicomWebClient.headers = generateWadoHeader();
|
|
1241
1546
|
// Get Series
|
|
1242
1547
|
const {
|
|
1243
1548
|
preLoadData: seriesSummaryMetadata,
|
|
1244
1549
|
promises: seriesPromises
|
|
1245
|
-
} = await retrieveStudyMetadata(wadoDicomWebClient, StudyInstanceUID, enableStudyLazyLoad, filters, sortCriteria, sortFunction);
|
|
1550
|
+
} = await retrieveStudyMetadata(wadoDicomWebClient, StudyInstanceUID, enableStudyLazyLoad, filters, sortCriteria, sortFunction, dicomWebConfig);
|
|
1246
1551
|
|
|
1247
1552
|
/**
|
|
1248
1553
|
* naturalizes the dataset, and adds a retrieve bulkdata method
|
|
@@ -1264,10 +1569,13 @@ function createDicomWebApi(dicomWebConfig, userAuthenticationService) {
|
|
|
1264
1569
|
// in which case it isn't necessary to re-read this.
|
|
1265
1570
|
if (value && value.BulkDataURI && !value.Value) {
|
|
1266
1571
|
// Provide a method to fetch bulkdata
|
|
1267
|
-
value.retrieveBulkData = () => {
|
|
1572
|
+
value.retrieveBulkData = (options = {}) => {
|
|
1268
1573
|
// handle the scenarios where bulkDataURI is relative path
|
|
1269
1574
|
fixBulkDataURI(value, naturalized, dicomWebConfig);
|
|
1270
|
-
const
|
|
1575
|
+
const {
|
|
1576
|
+
mediaType
|
|
1577
|
+
} = options;
|
|
1578
|
+
const useOptions = {
|
|
1271
1579
|
// The bulkdata fetches work with either multipart or
|
|
1272
1580
|
// singlepart, so set multipart to false to let the server
|
|
1273
1581
|
// decide which type to respond with.
|
|
@@ -1277,10 +1585,16 @@ function createDicomWebApi(dicomWebConfig, userAuthenticationService) {
|
|
|
1277
1585
|
// is relative - that isn't disallowed by DICOMweb, but
|
|
1278
1586
|
// isn't well specified in the standard, but is needed in
|
|
1279
1587
|
// any implementation that stores static copies of the metadata
|
|
1280
|
-
StudyInstanceUID: naturalized.StudyInstanceUID
|
|
1588
|
+
StudyInstanceUID: naturalized.StudyInstanceUID,
|
|
1589
|
+
mediaTypes: mediaType ? [{
|
|
1590
|
+
mediaType
|
|
1591
|
+
}, {
|
|
1592
|
+
mediaType: 'application/octet-stream'
|
|
1593
|
+
}] : undefined,
|
|
1594
|
+
...options
|
|
1281
1595
|
};
|
|
1282
1596
|
// Todo: this needs to be from wado dicom web client
|
|
1283
|
-
return qidoDicomWebClient.retrieveBulkData(
|
|
1597
|
+
return qidoDicomWebClient.retrieveBulkData(useOptions).then(val => {
|
|
1284
1598
|
// There are DICOM PDF cases where the first ArrayBuffer in the array is
|
|
1285
1599
|
// the bulk data and DICOM video cases where the second ArrayBuffer is
|
|
1286
1600
|
// the bulk data. Here we play it safe and do a find.
|
|
@@ -1299,7 +1613,7 @@ function createDicomWebApi(dicomWebConfig, userAuthenticationService) {
|
|
|
1299
1613
|
const naturalizedInstances = instances.map(addRetrieveBulkData);
|
|
1300
1614
|
|
|
1301
1615
|
// Adding instanceMetadata to OHIF MetadataProvider
|
|
1302
|
-
naturalizedInstances.forEach(
|
|
1616
|
+
naturalizedInstances.forEach(instance => {
|
|
1303
1617
|
instance.wadoRoot = dicomWebConfig.wadoRoot;
|
|
1304
1618
|
instance.wadoUri = dicomWebConfig.wadoUri;
|
|
1305
1619
|
const imageId = implementation.getImageIdsForInstance({
|
|
@@ -1323,7 +1637,10 @@ function createDicomWebApi(dicomWebConfig, userAuthenticationService) {
|
|
|
1323
1637
|
src.DicomMetadataStore.addInstances(naturalizedInstances, madeInClient);
|
|
1324
1638
|
}
|
|
1325
1639
|
function setSuccessFlag() {
|
|
1326
|
-
const study = src.DicomMetadataStore.getStudy(StudyInstanceUID
|
|
1640
|
+
const study = src.DicomMetadataStore.getStudy(StudyInstanceUID);
|
|
1641
|
+
if (!study) {
|
|
1642
|
+
return;
|
|
1643
|
+
}
|
|
1327
1644
|
study.isLoaded = true;
|
|
1328
1645
|
}
|
|
1329
1646
|
|
|
@@ -1333,11 +1650,22 @@ function createDicomWebApi(dicomWebConfig, userAuthenticationService) {
|
|
|
1333
1650
|
aSeries.StudyInstanceUID = StudyInstanceUID;
|
|
1334
1651
|
});
|
|
1335
1652
|
src.DicomMetadataStore.addSeriesMetadata(seriesSummaryMetadata, madeInClient);
|
|
1336
|
-
const seriesDeliveredPromises = seriesPromises.map(promise =>
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1653
|
+
const seriesDeliveredPromises = seriesPromises.map(promise => {
|
|
1654
|
+
if (!returnPromises) {
|
|
1655
|
+
promise?.start();
|
|
1656
|
+
}
|
|
1657
|
+
return promise.then(instances => {
|
|
1658
|
+
storeInstances(instances);
|
|
1659
|
+
});
|
|
1660
|
+
});
|
|
1661
|
+
if (returnPromises) {
|
|
1662
|
+
Promise.all(seriesDeliveredPromises).then(() => setSuccessFlag());
|
|
1663
|
+
return seriesPromises;
|
|
1664
|
+
} else {
|
|
1665
|
+
await Promise.all(seriesDeliveredPromises);
|
|
1666
|
+
setSuccessFlag();
|
|
1667
|
+
}
|
|
1668
|
+
return seriesSummaryMetadata;
|
|
1341
1669
|
},
|
|
1342
1670
|
deleteStudyMetadataPromise: deleteStudyMetadataPromise,
|
|
1343
1671
|
getImageIdsForDisplaySet(displaySet) {
|
|
@@ -1365,11 +1693,10 @@ function createDicomWebApi(dicomWebConfig, userAuthenticationService) {
|
|
|
1365
1693
|
});
|
|
1366
1694
|
return imageIds;
|
|
1367
1695
|
},
|
|
1368
|
-
getImageIdsForInstance(
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
} = _ref3;
|
|
1696
|
+
getImageIdsForInstance({
|
|
1697
|
+
instance,
|
|
1698
|
+
frame = undefined
|
|
1699
|
+
}) {
|
|
1373
1700
|
const imageIds = getImageId({
|
|
1374
1701
|
instance,
|
|
1375
1702
|
frame,
|
|
@@ -1380,11 +1707,10 @@ function createDicomWebApi(dicomWebConfig, userAuthenticationService) {
|
|
|
1380
1707
|
getConfig() {
|
|
1381
1708
|
return dicomWebConfigCopy;
|
|
1382
1709
|
},
|
|
1383
|
-
getStudyInstanceUIDs(
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
} = _ref4;
|
|
1710
|
+
getStudyInstanceUIDs({
|
|
1711
|
+
params,
|
|
1712
|
+
query
|
|
1713
|
+
}) {
|
|
1388
1714
|
const {
|
|
1389
1715
|
StudyInstanceUIDs: paramsStudyInstanceUIDs
|
|
1390
1716
|
} = params;
|
|
@@ -1397,7 +1723,7 @@ function createDicomWebApi(dicomWebConfig, userAuthenticationService) {
|
|
|
1397
1723
|
if (dicomWebConfig.supportsReject) {
|
|
1398
1724
|
implementation.reject = dcm4cheeReject(dicomWebConfig.wadoRoot);
|
|
1399
1725
|
}
|
|
1400
|
-
return src/* IWebApiDataSource */.
|
|
1726
|
+
return src/* IWebApiDataSource */.pt.create(implementation);
|
|
1401
1727
|
}
|
|
1402
1728
|
|
|
1403
1729
|
;// CONCATENATED MODULE: ../../../extensions/default/src/DicomJSONDataSource/index.js
|
|
@@ -1405,7 +1731,7 @@ function createDicomWebApi(dicomWebConfig, userAuthenticationService) {
|
|
|
1405
1731
|
|
|
1406
1732
|
|
|
1407
1733
|
|
|
1408
|
-
const DicomJSONDataSource_metadataProvider = src
|
|
1734
|
+
const DicomJSONDataSource_metadataProvider = src/* default.classes */.Ay.classes.MetadataProvider;
|
|
1409
1735
|
const mappings = {
|
|
1410
1736
|
studyInstanceUid: 'StudyInstanceUID',
|
|
1411
1737
|
patientId: 'PatientID'
|
|
@@ -1423,7 +1749,20 @@ let _store = {
|
|
|
1423
1749
|
// }
|
|
1424
1750
|
// }
|
|
1425
1751
|
};
|
|
1426
|
-
|
|
1752
|
+
function wrapSequences(obj) {
|
|
1753
|
+
return Object.keys(obj).reduce((acc, key) => {
|
|
1754
|
+
if (typeof obj[key] === 'object' && obj[key] !== null) {
|
|
1755
|
+
// Recursively wrap sequences for nested objects
|
|
1756
|
+
acc[key] = wrapSequences(obj[key]);
|
|
1757
|
+
} else {
|
|
1758
|
+
acc[key] = obj[key];
|
|
1759
|
+
}
|
|
1760
|
+
if (key.endsWith('Sequence')) {
|
|
1761
|
+
acc[key] = src/* default.utils */.Ay.utils.addAccessors(acc[key]);
|
|
1762
|
+
}
|
|
1763
|
+
return acc;
|
|
1764
|
+
}, Array.isArray(obj) ? [] : {});
|
|
1765
|
+
}
|
|
1427
1766
|
const getMetaDataByURL = url => {
|
|
1428
1767
|
return _store.urls.find(metaData => metaData.url === url);
|
|
1429
1768
|
};
|
|
@@ -1443,11 +1782,10 @@ function createDicomJSONApi(dicomJsonConfig) {
|
|
|
1443
1782
|
wadoRoot
|
|
1444
1783
|
} = dicomJsonConfig;
|
|
1445
1784
|
const implementation = {
|
|
1446
|
-
initialize: async
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
} = _ref;
|
|
1785
|
+
initialize: async ({
|
|
1786
|
+
query,
|
|
1787
|
+
url
|
|
1788
|
+
}) => {
|
|
1451
1789
|
if (!url) {
|
|
1452
1790
|
url = query.get('url');
|
|
1453
1791
|
}
|
|
@@ -1545,15 +1883,14 @@ function createDicomJSONApi(dicomJsonConfig) {
|
|
|
1545
1883
|
* or is already retrieved, or a promise to a URL for such use if a BulkDataURI
|
|
1546
1884
|
*/
|
|
1547
1885
|
directURL: params => {
|
|
1548
|
-
return utils_getDirectURL(
|
|
1886
|
+
return utils_getDirectURL(dicomJsonConfig, params);
|
|
1549
1887
|
},
|
|
1550
1888
|
series: {
|
|
1551
|
-
metadata: async
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
} = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
1889
|
+
metadata: async ({
|
|
1890
|
+
StudyInstanceUID,
|
|
1891
|
+
madeInClient = false,
|
|
1892
|
+
customSort
|
|
1893
|
+
} = {}) => {
|
|
1557
1894
|
if (!StudyInstanceUID) {
|
|
1558
1895
|
throw new Error('Unable to query for SeriesMetadata without StudyInstanceUID');
|
|
1559
1896
|
}
|
|
@@ -1585,8 +1922,13 @@ function createDicomJSONApi(dicomJsonConfig) {
|
|
|
1585
1922
|
const numberOfSeries = series.length;
|
|
1586
1923
|
series.forEach((series, index) => {
|
|
1587
1924
|
const instances = series.instances.map(instance => {
|
|
1925
|
+
// for instance.metadata if the key ends with sequence then
|
|
1926
|
+
// we need to add a proxy to the first item in the sequence
|
|
1927
|
+
// so that we can access the value of the sequence
|
|
1928
|
+
// by using sequenceName.value
|
|
1929
|
+
const modifiedMetadata = wrapSequences(instance.metadata);
|
|
1588
1930
|
const obj = {
|
|
1589
|
-
...
|
|
1931
|
+
...modifiedMetadata,
|
|
1590
1932
|
url: instance.url,
|
|
1591
1933
|
imageId: instance.url,
|
|
1592
1934
|
...series,
|
|
@@ -1636,34 +1978,32 @@ function createDicomJSONApi(dicomJsonConfig) {
|
|
|
1636
1978
|
});
|
|
1637
1979
|
return imageIds;
|
|
1638
1980
|
},
|
|
1639
|
-
getImageIdsForInstance(
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
} = _ref2;
|
|
1981
|
+
getImageIdsForInstance({
|
|
1982
|
+
instance,
|
|
1983
|
+
frame
|
|
1984
|
+
}) {
|
|
1644
1985
|
const imageIds = getImageId({
|
|
1645
1986
|
instance,
|
|
1646
1987
|
frame
|
|
1647
1988
|
});
|
|
1648
1989
|
return imageIds;
|
|
1649
1990
|
},
|
|
1650
|
-
getStudyInstanceUIDs:
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
} = _ref3;
|
|
1991
|
+
getStudyInstanceUIDs: ({
|
|
1992
|
+
params,
|
|
1993
|
+
query
|
|
1994
|
+
}) => {
|
|
1655
1995
|
const url = query.get('url');
|
|
1656
1996
|
return _store.studyInstanceUIDMap.get(url);
|
|
1657
1997
|
}
|
|
1658
1998
|
};
|
|
1659
|
-
return src/* IWebApiDataSource */.
|
|
1999
|
+
return src/* IWebApiDataSource */.pt.create(implementation);
|
|
1660
2000
|
}
|
|
1661
2001
|
|
|
1662
2002
|
;// CONCATENATED MODULE: ../../../extensions/default/src/DicomLocalDataSource/index.js
|
|
1663
2003
|
|
|
1664
2004
|
|
|
1665
2005
|
|
|
1666
|
-
const DicomLocalDataSource_metadataProvider = src
|
|
2006
|
+
const DicomLocalDataSource_metadataProvider = src/* default.classes */.Ay.classes.MetadataProvider;
|
|
1667
2007
|
const {
|
|
1668
2008
|
EVENTS
|
|
1669
2009
|
} = src.DicomMetadataStore;
|
|
@@ -1672,8 +2012,7 @@ const END_MODALITIES = {
|
|
|
1672
2012
|
SEG: true,
|
|
1673
2013
|
DOC: true
|
|
1674
2014
|
};
|
|
1675
|
-
const compareValue =
|
|
1676
|
-
let def = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
|
|
2015
|
+
const compareValue = (v1, v2, def = 0) => {
|
|
1677
2016
|
if (v1 === v2) {
|
|
1678
2017
|
return def;
|
|
1679
2018
|
}
|
|
@@ -1705,12 +2044,10 @@ function createDicomLocalApi(dicomLocalConfig) {
|
|
|
1705
2044
|
name
|
|
1706
2045
|
} = dicomLocalConfig;
|
|
1707
2046
|
const implementation = {
|
|
1708
|
-
initialize:
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
} = _ref;
|
|
1713
|
-
},
|
|
2047
|
+
initialize: ({
|
|
2048
|
+
params,
|
|
2049
|
+
query
|
|
2050
|
+
}) => {},
|
|
1714
2051
|
query: {
|
|
1715
2052
|
studies: {
|
|
1716
2053
|
mapParams: () => {},
|
|
@@ -1789,11 +2126,10 @@ function createDicomLocalApi(dicomLocalConfig) {
|
|
|
1789
2126
|
}
|
|
1790
2127
|
},
|
|
1791
2128
|
series: {
|
|
1792
|
-
metadata: async
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
} = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
2129
|
+
metadata: async ({
|
|
2130
|
+
StudyInstanceUID,
|
|
2131
|
+
madeInClient = false
|
|
2132
|
+
} = {}) => {
|
|
1797
2133
|
if (!StudyInstanceUID) {
|
|
1798
2134
|
throw new Error('Unable to query for SeriesMetadata without StudyInstanceUID');
|
|
1799
2135
|
}
|
|
@@ -1839,7 +2175,7 @@ function createDicomLocalApi(dicomLocalConfig) {
|
|
|
1839
2175
|
},
|
|
1840
2176
|
store: {
|
|
1841
2177
|
dicom: naturalizedReport => {
|
|
1842
|
-
const reportBlob = dcmjs_es
|
|
2178
|
+
const reportBlob = dcmjs_es/* default.data */.Ay.data.datasetToBlob(naturalizedReport);
|
|
1843
2179
|
|
|
1844
2180
|
//Create a URL for the binary.
|
|
1845
2181
|
var objectUrl = URL.createObjectURL(reportBlob);
|
|
@@ -1872,11 +2208,10 @@ function createDicomLocalApi(dicomLocalConfig) {
|
|
|
1872
2208
|
});
|
|
1873
2209
|
return imageIds;
|
|
1874
2210
|
},
|
|
1875
|
-
getImageIdsForInstance(
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
} = _ref2;
|
|
2211
|
+
getImageIdsForInstance({
|
|
2212
|
+
instance,
|
|
2213
|
+
frame
|
|
2214
|
+
}) {
|
|
1880
2215
|
const {
|
|
1881
2216
|
StudyInstanceUID,
|
|
1882
2217
|
SeriesInstanceUID,
|
|
@@ -1892,11 +2227,10 @@ function createDicomLocalApi(dicomLocalConfig) {
|
|
|
1892
2227
|
deleteStudyMetadataPromise() {
|
|
1893
2228
|
console.log('deleteStudyMetadataPromise not implemented');
|
|
1894
2229
|
},
|
|
1895
|
-
getStudyInstanceUIDs:
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
} = _ref3;
|
|
2230
|
+
getStudyInstanceUIDs: ({
|
|
2231
|
+
params,
|
|
2232
|
+
query
|
|
2233
|
+
}) => {
|
|
1900
2234
|
const {
|
|
1901
2235
|
StudyInstanceUIDs: paramsStudyInstanceUIDs
|
|
1902
2236
|
} = params;
|
|
@@ -1916,7 +2250,7 @@ function createDicomLocalApi(dicomLocalConfig) {
|
|
|
1916
2250
|
return isStudyInCache ? StudyInstanceUIDsAsArray : [];
|
|
1917
2251
|
}
|
|
1918
2252
|
};
|
|
1919
|
-
return src/* IWebApiDataSource */.
|
|
2253
|
+
return src/* IWebApiDataSource */.pt.create(implementation);
|
|
1920
2254
|
}
|
|
1921
2255
|
|
|
1922
2256
|
;// CONCATENATED MODULE: ../../../extensions/default/src/DicomWebProxyDataSource/index.js
|
|
@@ -1931,17 +2265,16 @@ function createDicomLocalApi(dicomLocalConfig) {
|
|
|
1931
2265
|
* dicomWeb configuration array
|
|
1932
2266
|
*
|
|
1933
2267
|
*/
|
|
1934
|
-
function createDicomWebProxyApi(dicomWebProxyConfig,
|
|
2268
|
+
function createDicomWebProxyApi(dicomWebProxyConfig, servicesManager) {
|
|
1935
2269
|
const {
|
|
1936
2270
|
name
|
|
1937
2271
|
} = dicomWebProxyConfig;
|
|
1938
2272
|
let dicomWebDelegate = undefined;
|
|
1939
2273
|
const implementation = {
|
|
1940
|
-
initialize: async
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
} = _ref;
|
|
2274
|
+
initialize: async ({
|
|
2275
|
+
params,
|
|
2276
|
+
query
|
|
2277
|
+
}) => {
|
|
1945
2278
|
const url = query.get('url');
|
|
1946
2279
|
if (!url) {
|
|
1947
2280
|
throw new Error(`No url for '${name}'`);
|
|
@@ -1951,7 +2284,7 @@ function createDicomWebProxyApi(dicomWebProxyConfig, UserAuthenticationService)
|
|
|
1951
2284
|
if (!data.servers?.dicomWeb?.[0]) {
|
|
1952
2285
|
throw new Error('Invalid configuration returned by url');
|
|
1953
2286
|
}
|
|
1954
|
-
dicomWebDelegate = createDicomWebApi(data.servers.dicomWeb[0].configuration,
|
|
2287
|
+
dicomWebDelegate = createDicomWebApi(data.servers.dicomWeb[0].configuration, servicesManager);
|
|
1955
2288
|
dicomWebDelegate.initialize({
|
|
1956
2289
|
params,
|
|
1957
2290
|
query
|
|
@@ -1963,43 +2296,28 @@ function createDicomWebProxyApi(dicomWebProxyConfig, UserAuthenticationService)
|
|
|
1963
2296
|
search: params => dicomWebDelegate.query.studies.search(params)
|
|
1964
2297
|
},
|
|
1965
2298
|
series: {
|
|
1966
|
-
search:
|
|
1967
|
-
return dicomWebDelegate.query.series.search(...arguments);
|
|
1968
|
-
}
|
|
2299
|
+
search: (...args) => dicomWebDelegate.query.series.search(...args)
|
|
1969
2300
|
},
|
|
1970
2301
|
instances: {
|
|
1971
2302
|
search: (studyInstanceUid, queryParameters) => dicomWebDelegate.query.instances.search(studyInstanceUid, queryParameters)
|
|
1972
2303
|
}
|
|
1973
2304
|
},
|
|
1974
2305
|
retrieve: {
|
|
1975
|
-
directURL:
|
|
1976
|
-
return dicomWebDelegate.retrieve.directURL(...arguments);
|
|
1977
|
-
},
|
|
2306
|
+
directURL: (...args) => dicomWebDelegate.retrieve.directURL(...args),
|
|
1978
2307
|
series: {
|
|
1979
|
-
metadata: async
|
|
1980
|
-
return dicomWebDelegate.retrieve.series.metadata(...arguments);
|
|
1981
|
-
}
|
|
2308
|
+
metadata: async (...args) => dicomWebDelegate.retrieve.series.metadata(...args)
|
|
1982
2309
|
}
|
|
1983
2310
|
},
|
|
1984
2311
|
store: {
|
|
1985
|
-
dicom:
|
|
1986
|
-
return dicomWebDelegate.store(...arguments);
|
|
1987
|
-
}
|
|
1988
|
-
},
|
|
1989
|
-
deleteStudyMetadataPromise: function () {
|
|
1990
|
-
return dicomWebDelegate.deleteStudyMetadataPromise(...arguments);
|
|
2312
|
+
dicom: (...args) => dicomWebDelegate.store(...args)
|
|
1991
2313
|
},
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
let {
|
|
2000
|
-
params,
|
|
2001
|
-
query
|
|
2002
|
-
} = _ref2;
|
|
2314
|
+
deleteStudyMetadataPromise: (...args) => dicomWebDelegate.deleteStudyMetadataPromise(...args),
|
|
2315
|
+
getImageIdsForDisplaySet: (...args) => dicomWebDelegate.getImageIdsForDisplaySet(...args),
|
|
2316
|
+
getImageIdsForInstance: (...args) => dicomWebDelegate.getImageIdsForInstance(...args),
|
|
2317
|
+
getStudyInstanceUIDs({
|
|
2318
|
+
params,
|
|
2319
|
+
query
|
|
2320
|
+
}) {
|
|
2003
2321
|
let studyInstanceUIDs = [];
|
|
2004
2322
|
|
|
2005
2323
|
// there seem to be a couple of variations of the case for this parameter
|
|
@@ -2011,7 +2329,278 @@ function createDicomWebProxyApi(dicomWebProxyConfig, UserAuthenticationService)
|
|
|
2011
2329
|
return studyInstanceUIDs;
|
|
2012
2330
|
}
|
|
2013
2331
|
};
|
|
2014
|
-
return src/* IWebApiDataSource */.
|
|
2332
|
+
return src/* IWebApiDataSource */.pt.create(implementation);
|
|
2333
|
+
}
|
|
2334
|
+
|
|
2335
|
+
// EXTERNAL MODULE: ../../../node_modules/lodash/lodash.js
|
|
2336
|
+
var lodash = __webpack_require__(5517);
|
|
2337
|
+
;// CONCATENATED MODULE: ../../../extensions/default/src/MergeDataSource/index.ts
|
|
2338
|
+
|
|
2339
|
+
|
|
2340
|
+
const mergeMap = {
|
|
2341
|
+
'query.studies.search': {
|
|
2342
|
+
mergeKey: 'studyInstanceUid',
|
|
2343
|
+
tagFunc: x => x
|
|
2344
|
+
},
|
|
2345
|
+
'query.series.search': {
|
|
2346
|
+
mergeKey: 'seriesInstanceUid',
|
|
2347
|
+
tagFunc: (series, sourceName) => {
|
|
2348
|
+
series.forEach(series => {
|
|
2349
|
+
series.RetrieveAETitle = sourceName;
|
|
2350
|
+
src.DicomMetadataStore.updateSeriesMetadata(series);
|
|
2351
|
+
});
|
|
2352
|
+
return series;
|
|
2353
|
+
}
|
|
2354
|
+
}
|
|
2355
|
+
};
|
|
2356
|
+
|
|
2357
|
+
/**
|
|
2358
|
+
* Calls all data sources asynchronously and merges the results.
|
|
2359
|
+
* @param {CallForAllDataSourcesAsyncOptions} options - The options for calling all data sources.
|
|
2360
|
+
* @param {string} options.path - The path to the function to be called on each data source.
|
|
2361
|
+
* @param {unknown[]} options.args - The arguments to be passed to the function.
|
|
2362
|
+
* @param {ExtensionManager} options.extensionManager - The extension manager.
|
|
2363
|
+
* @param {string[]} options.dataSourceNames - The names of the data sources to be called.
|
|
2364
|
+
* @param {string} options.defaultDataSourceName - The name of the default data source.
|
|
2365
|
+
* @returns {Promise<unknown[]>} - A promise that resolves to the merged data from all data sources.
|
|
2366
|
+
*/
|
|
2367
|
+
const callForAllDataSourcesAsync = async ({
|
|
2368
|
+
mergeMap,
|
|
2369
|
+
path,
|
|
2370
|
+
args,
|
|
2371
|
+
extensionManager,
|
|
2372
|
+
dataSourceNames,
|
|
2373
|
+
defaultDataSourceName
|
|
2374
|
+
}) => {
|
|
2375
|
+
const {
|
|
2376
|
+
mergeKey,
|
|
2377
|
+
tagFunc
|
|
2378
|
+
} = mergeMap[path] || {
|
|
2379
|
+
tagFunc: x => x
|
|
2380
|
+
};
|
|
2381
|
+
|
|
2382
|
+
/** Sort by default data source */
|
|
2383
|
+
const defs = Object.values(extensionManager.dataSourceDefs);
|
|
2384
|
+
const defaultDataSourceDef = defs.find(def => def.sourceName === defaultDataSourceName);
|
|
2385
|
+
const dataSourceDefs = defs.filter(def => def.sourceName !== defaultDataSourceName);
|
|
2386
|
+
if (defaultDataSourceDef) {
|
|
2387
|
+
dataSourceDefs.unshift(defaultDataSourceDef);
|
|
2388
|
+
}
|
|
2389
|
+
const promises = [];
|
|
2390
|
+
const sourceNames = [];
|
|
2391
|
+
for (const dataSourceDef of dataSourceDefs) {
|
|
2392
|
+
const {
|
|
2393
|
+
configuration,
|
|
2394
|
+
sourceName
|
|
2395
|
+
} = dataSourceDef;
|
|
2396
|
+
if (!!configuration && dataSourceNames.includes(sourceName)) {
|
|
2397
|
+
const [dataSource] = extensionManager.getDataSources(sourceName);
|
|
2398
|
+
const func = (0,lodash.get)(dataSource, path);
|
|
2399
|
+
const promise = func.apply(dataSource, args);
|
|
2400
|
+
promises.push(promise);
|
|
2401
|
+
sourceNames.push(sourceName);
|
|
2402
|
+
}
|
|
2403
|
+
}
|
|
2404
|
+
const data = await Promise.allSettled(promises);
|
|
2405
|
+
const mergedData = data.map((data, i) => tagFunc(data.value, sourceNames[i]));
|
|
2406
|
+
let results = [];
|
|
2407
|
+
if (mergeKey) {
|
|
2408
|
+
results = (0,lodash.uniqBy)(mergedData.flat(), obj => (0,lodash.get)(obj, mergeKey));
|
|
2409
|
+
} else {
|
|
2410
|
+
results = mergedData.flat();
|
|
2411
|
+
}
|
|
2412
|
+
return results;
|
|
2413
|
+
};
|
|
2414
|
+
|
|
2415
|
+
/**
|
|
2416
|
+
* Calls all data sources that match the provided names and merges their data.
|
|
2417
|
+
* @param options - The options for calling all data sources.
|
|
2418
|
+
* @param options.path - The path to the function to be called on each data source.
|
|
2419
|
+
* @param options.args - The arguments to be passed to the function.
|
|
2420
|
+
* @param options.extensionManager - The extension manager instance.
|
|
2421
|
+
* @param options.dataSourceNames - The names of the data sources to be called.
|
|
2422
|
+
* @param options.defaultDataSourceName - The name of the default data source.
|
|
2423
|
+
* @returns The merged data from all the matching data sources.
|
|
2424
|
+
*/
|
|
2425
|
+
const callForAllDataSources = ({
|
|
2426
|
+
path,
|
|
2427
|
+
args,
|
|
2428
|
+
extensionManager,
|
|
2429
|
+
dataSourceNames,
|
|
2430
|
+
defaultDataSourceName
|
|
2431
|
+
}) => {
|
|
2432
|
+
/** Sort by default data source */
|
|
2433
|
+
const defs = Object.values(extensionManager.dataSourceDefs);
|
|
2434
|
+
const defaultDataSourceDef = defs.find(def => def.sourceName === defaultDataSourceName);
|
|
2435
|
+
const dataSourceDefs = defs.filter(def => def.sourceName !== defaultDataSourceName);
|
|
2436
|
+
if (defaultDataSourceDef) {
|
|
2437
|
+
dataSourceDefs.unshift(defaultDataSourceDef);
|
|
2438
|
+
}
|
|
2439
|
+
const mergedData = [];
|
|
2440
|
+
for (const dataSourceDef of dataSourceDefs) {
|
|
2441
|
+
const {
|
|
2442
|
+
configuration,
|
|
2443
|
+
sourceName
|
|
2444
|
+
} = dataSourceDef;
|
|
2445
|
+
if (!!configuration && dataSourceNames.includes(sourceName)) {
|
|
2446
|
+
const [dataSource] = extensionManager.getDataSources(sourceName);
|
|
2447
|
+
const func = (0,lodash.get)(dataSource, path);
|
|
2448
|
+
const data = func.apply(dataSource, args);
|
|
2449
|
+
mergedData.push(data);
|
|
2450
|
+
}
|
|
2451
|
+
}
|
|
2452
|
+
return mergedData.flat();
|
|
2453
|
+
};
|
|
2454
|
+
|
|
2455
|
+
/**
|
|
2456
|
+
* Calls the default data source function specified by the given path with the provided arguments.
|
|
2457
|
+
* @param {CallForDefaultDataSourceOptions} options - The options for calling the default data source.
|
|
2458
|
+
* @param {string} options.path - The path to the function within the default data source.
|
|
2459
|
+
* @param {unknown[]} options.args - The arguments to pass to the function.
|
|
2460
|
+
* @param {string} options.defaultDataSourceName - The name of the default data source.
|
|
2461
|
+
* @param {ExtensionManager} options.extensionManager - The extension manager instance.
|
|
2462
|
+
* @returns {unknown} - The result of calling the default data source function.
|
|
2463
|
+
*/
|
|
2464
|
+
const callForDefaultDataSource = ({
|
|
2465
|
+
path,
|
|
2466
|
+
args,
|
|
2467
|
+
defaultDataSourceName,
|
|
2468
|
+
extensionManager
|
|
2469
|
+
}) => {
|
|
2470
|
+
const [dataSource] = extensionManager.getDataSources(defaultDataSourceName);
|
|
2471
|
+
const func = (0,lodash.get)(dataSource, path);
|
|
2472
|
+
return func.apply(dataSource, args);
|
|
2473
|
+
};
|
|
2474
|
+
|
|
2475
|
+
/**
|
|
2476
|
+
* Calls the data source specified by the RetrieveAETitle of the given display set.
|
|
2477
|
+
* @typedef {Object} CallByRetrieveAETitleOptions
|
|
2478
|
+
* @property {string} path - The path of the method to call on the data source.
|
|
2479
|
+
* @property {any[]} args - The arguments to pass to the method.
|
|
2480
|
+
* @property {string} defaultDataSourceName - The name of the default data source.
|
|
2481
|
+
* @property {ExtensionManager} extensionManager - The extension manager.
|
|
2482
|
+
*/
|
|
2483
|
+
const callByRetrieveAETitle = ({
|
|
2484
|
+
path,
|
|
2485
|
+
args,
|
|
2486
|
+
defaultDataSourceName,
|
|
2487
|
+
extensionManager
|
|
2488
|
+
}) => {
|
|
2489
|
+
const [displaySet] = args;
|
|
2490
|
+
const seriesMetadata = src.DicomMetadataStore.getSeries(displaySet.StudyInstanceUID, displaySet.SeriesInstanceUID);
|
|
2491
|
+
const [dataSource] = extensionManager.getDataSources(seriesMetadata.RetrieveAETitle || defaultDataSourceName);
|
|
2492
|
+
return dataSource[path](...args);
|
|
2493
|
+
};
|
|
2494
|
+
function createMergeDataSourceApi(mergeConfig, servicesManager, extensionManager) {
|
|
2495
|
+
const {
|
|
2496
|
+
seriesMerge
|
|
2497
|
+
} = mergeConfig;
|
|
2498
|
+
const {
|
|
2499
|
+
dataSourceNames,
|
|
2500
|
+
defaultDataSourceName
|
|
2501
|
+
} = seriesMerge;
|
|
2502
|
+
const implementation = {
|
|
2503
|
+
initialize: (...args) => callForAllDataSources({
|
|
2504
|
+
path: 'initialize',
|
|
2505
|
+
args,
|
|
2506
|
+
extensionManager,
|
|
2507
|
+
dataSourceNames,
|
|
2508
|
+
defaultDataSourceName
|
|
2509
|
+
}),
|
|
2510
|
+
query: {
|
|
2511
|
+
studies: {
|
|
2512
|
+
search: (...args) => callForAllDataSourcesAsync({
|
|
2513
|
+
mergeMap,
|
|
2514
|
+
path: 'query.studies.search',
|
|
2515
|
+
args,
|
|
2516
|
+
extensionManager,
|
|
2517
|
+
dataSourceNames,
|
|
2518
|
+
defaultDataSourceName
|
|
2519
|
+
})
|
|
2520
|
+
},
|
|
2521
|
+
series: {
|
|
2522
|
+
search: (...args) => callForAllDataSourcesAsync({
|
|
2523
|
+
mergeMap,
|
|
2524
|
+
path: 'query.series.search',
|
|
2525
|
+
args,
|
|
2526
|
+
extensionManager,
|
|
2527
|
+
dataSourceNames,
|
|
2528
|
+
defaultDataSourceName
|
|
2529
|
+
})
|
|
2530
|
+
},
|
|
2531
|
+
instances: {
|
|
2532
|
+
search: (...args) => callForAllDataSourcesAsync({
|
|
2533
|
+
mergeMap,
|
|
2534
|
+
path: 'query.instances.search',
|
|
2535
|
+
args,
|
|
2536
|
+
extensionManager,
|
|
2537
|
+
dataSourceNames,
|
|
2538
|
+
defaultDataSourceName
|
|
2539
|
+
})
|
|
2540
|
+
}
|
|
2541
|
+
},
|
|
2542
|
+
retrieve: {
|
|
2543
|
+
bulkDataURI: (...args) => callForAllDataSourcesAsync({
|
|
2544
|
+
mergeMap,
|
|
2545
|
+
path: 'retrieve.bulkDataURI',
|
|
2546
|
+
args,
|
|
2547
|
+
extensionManager,
|
|
2548
|
+
dataSourceNames,
|
|
2549
|
+
defaultDataSourceName
|
|
2550
|
+
}),
|
|
2551
|
+
directURL: (...args) => callForDefaultDataSource({
|
|
2552
|
+
path: 'retrieve.directURL',
|
|
2553
|
+
args,
|
|
2554
|
+
defaultDataSourceName,
|
|
2555
|
+
extensionManager
|
|
2556
|
+
}),
|
|
2557
|
+
series: {
|
|
2558
|
+
metadata: (...args) => callForAllDataSourcesAsync({
|
|
2559
|
+
mergeMap,
|
|
2560
|
+
path: 'retrieve.series.metadata',
|
|
2561
|
+
args,
|
|
2562
|
+
extensionManager,
|
|
2563
|
+
dataSourceNames,
|
|
2564
|
+
defaultDataSourceName
|
|
2565
|
+
})
|
|
2566
|
+
}
|
|
2567
|
+
},
|
|
2568
|
+
store: {
|
|
2569
|
+
dicom: (...args) => callForDefaultDataSource({
|
|
2570
|
+
path: 'store.dicom',
|
|
2571
|
+
args,
|
|
2572
|
+
defaultDataSourceName,
|
|
2573
|
+
extensionManager
|
|
2574
|
+
})
|
|
2575
|
+
},
|
|
2576
|
+
deleteStudyMetadataPromise: (...args) => callForAllDataSources({
|
|
2577
|
+
path: 'deleteStudyMetadataPromise',
|
|
2578
|
+
args,
|
|
2579
|
+
extensionManager,
|
|
2580
|
+
dataSourceNames,
|
|
2581
|
+
defaultDataSourceName
|
|
2582
|
+
}),
|
|
2583
|
+
getImageIdsForDisplaySet: (...args) => callByRetrieveAETitle({
|
|
2584
|
+
path: 'getImageIdsForDisplaySet',
|
|
2585
|
+
args,
|
|
2586
|
+
defaultDataSourceName,
|
|
2587
|
+
extensionManager
|
|
2588
|
+
}),
|
|
2589
|
+
getImageIdsForInstance: (...args) => callByRetrieveAETitle({
|
|
2590
|
+
path: 'getImageIdsForDisplaySet',
|
|
2591
|
+
args,
|
|
2592
|
+
defaultDataSourceName,
|
|
2593
|
+
extensionManager
|
|
2594
|
+
}),
|
|
2595
|
+
getStudyInstanceUIDs: (...args) => callForAllDataSources({
|
|
2596
|
+
path: 'getStudyInstanceUIDs',
|
|
2597
|
+
args,
|
|
2598
|
+
extensionManager,
|
|
2599
|
+
dataSourceNames,
|
|
2600
|
+
defaultDataSourceName
|
|
2601
|
+
})
|
|
2602
|
+
};
|
|
2603
|
+
return src/* IWebApiDataSource */.pt.create(implementation);
|
|
2015
2604
|
}
|
|
2016
2605
|
|
|
2017
2606
|
;// CONCATENATED MODULE: ../../../extensions/default/src/getDataSourcesModule.js
|
|
@@ -2024,6 +2613,7 @@ function createDicomWebProxyApi(dicomWebProxyConfig, UserAuthenticationService)
|
|
|
2024
2613
|
|
|
2025
2614
|
|
|
2026
2615
|
|
|
2616
|
+
|
|
2027
2617
|
/**
|
|
2028
2618
|
*
|
|
2029
2619
|
*/
|
|
@@ -2044,77 +2634,66 @@ function getDataSourcesModule() {
|
|
|
2044
2634
|
name: 'dicomlocal',
|
|
2045
2635
|
type: 'localApi',
|
|
2046
2636
|
createDataSource: createDicomLocalApi
|
|
2637
|
+
}, {
|
|
2638
|
+
name: 'merge',
|
|
2639
|
+
type: 'mergeApi',
|
|
2640
|
+
createDataSource: createMergeDataSourceApi
|
|
2047
2641
|
}];
|
|
2048
2642
|
}
|
|
2049
2643
|
/* harmony default export */ const src_getDataSourcesModule = (getDataSourcesModule);
|
|
2050
2644
|
// EXTERNAL MODULE: ../../../node_modules/react/index.js
|
|
2051
|
-
var react = __webpack_require__(
|
|
2645
|
+
var react = __webpack_require__(41766);
|
|
2052
2646
|
// EXTERNAL MODULE: ../../../node_modules/prop-types/index.js
|
|
2053
|
-
var prop_types = __webpack_require__(
|
|
2647
|
+
var prop_types = __webpack_require__(11374);
|
|
2054
2648
|
var prop_types_default = /*#__PURE__*/__webpack_require__.n(prop_types);
|
|
2055
|
-
// EXTERNAL MODULE: ../../ui/src/index.js +
|
|
2056
|
-
var ui_src = __webpack_require__(
|
|
2649
|
+
// EXTERNAL MODULE: ../../ui/src/index.js + 785 modules
|
|
2650
|
+
var ui_src = __webpack_require__(5085);
|
|
2057
2651
|
// EXTERNAL MODULE: ./state/index.js + 1 modules
|
|
2058
|
-
var state = __webpack_require__(
|
|
2652
|
+
var state = __webpack_require__(15575);
|
|
2059
2653
|
// EXTERNAL MODULE: ../node_modules/react-router-dom/dist/index.js
|
|
2060
|
-
var dist = __webpack_require__(
|
|
2654
|
+
var dist = __webpack_require__(37396);
|
|
2061
2655
|
// EXTERNAL MODULE: ../../../node_modules/react-i18next/dist/es/index.js + 15 modules
|
|
2062
|
-
var es = __webpack_require__(
|
|
2656
|
+
var es = __webpack_require__(80619);
|
|
2063
2657
|
// EXTERNAL MODULE: ../node_modules/react-router/dist/index.js
|
|
2064
|
-
var react_router_dist = __webpack_require__(
|
|
2065
|
-
// EXTERNAL MODULE: ../../i18n/src/index.js +
|
|
2066
|
-
var i18n_src = __webpack_require__(
|
|
2067
|
-
// EXTERNAL MODULE: ../../../node_modules/classnames/index.js
|
|
2068
|
-
var classnames = __webpack_require__(44921);
|
|
2069
|
-
var classnames_default = /*#__PURE__*/__webpack_require__.n(classnames);
|
|
2658
|
+
var react_router_dist = __webpack_require__(10971);
|
|
2659
|
+
// EXTERNAL MODULE: ../../i18n/src/index.js + 150 modules
|
|
2660
|
+
var i18n_src = __webpack_require__(912);
|
|
2070
2661
|
;// CONCATENATED MODULE: ../../../extensions/default/src/Toolbar/Toolbar.tsx
|
|
2071
2662
|
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
2663
|
|
|
2073
2664
|
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
} = _ref;
|
|
2665
|
+
function Toolbar({
|
|
2666
|
+
servicesManager,
|
|
2667
|
+
buttonSection = 'primary'
|
|
2668
|
+
}) {
|
|
2079
2669
|
const {
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
const {
|
|
2090
|
-
unsubscribe
|
|
2091
|
-
} = toolbarService.subscribe(toolbarService.EVENTS.TOOL_BAR_MODIFIED, updateToolbar);
|
|
2092
|
-
updateToolbar();
|
|
2093
|
-
return () => {
|
|
2094
|
-
unsubscribe();
|
|
2095
|
-
};
|
|
2096
|
-
}, [toolbarService, viewportGrid]);
|
|
2097
|
-
const onInteraction = (0,react.useCallback)(args => toolbarService.recordInteraction(args), [toolbarService]);
|
|
2670
|
+
toolbarButtons,
|
|
2671
|
+
onInteraction
|
|
2672
|
+
} = (0,src/* useToolbar */.tR)({
|
|
2673
|
+
servicesManager,
|
|
2674
|
+
buttonSection
|
|
2675
|
+
});
|
|
2676
|
+
if (!toolbarButtons.length) {
|
|
2677
|
+
return null;
|
|
2678
|
+
}
|
|
2098
2679
|
return /*#__PURE__*/react.createElement(react.Fragment, null, toolbarButtons.map(toolDef => {
|
|
2680
|
+
if (!toolDef) {
|
|
2681
|
+
return null;
|
|
2682
|
+
}
|
|
2099
2683
|
const {
|
|
2100
2684
|
id,
|
|
2101
2685
|
Component,
|
|
2102
2686
|
componentProps
|
|
2103
2687
|
} = toolDef;
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
}, componentProps, {
|
|
2114
|
-
onInteraction: onInteraction,
|
|
2115
|
-
servicesManager: servicesManager
|
|
2116
|
-
})))
|
|
2117
|
-
);
|
|
2688
|
+
const tool = /*#__PURE__*/react.createElement(Component, _extends({
|
|
2689
|
+
key: id,
|
|
2690
|
+
id: id,
|
|
2691
|
+
onInteraction: onInteraction,
|
|
2692
|
+
servicesManager: servicesManager
|
|
2693
|
+
}, componentProps));
|
|
2694
|
+
return /*#__PURE__*/react.createElement("div", {
|
|
2695
|
+
key: id
|
|
2696
|
+
}, tool);
|
|
2118
2697
|
}));
|
|
2119
2698
|
}
|
|
2120
2699
|
;// CONCATENATED MODULE: ../../../extensions/default/src/ViewerLayout/ViewerHeader.tsx
|
|
@@ -2126,21 +2705,19 @@ function Toolbar(_ref) {
|
|
|
2126
2705
|
|
|
2127
2706
|
|
|
2128
2707
|
|
|
2129
|
-
|
|
2130
2708
|
const {
|
|
2131
2709
|
availableLanguages,
|
|
2132
2710
|
defaultLanguage,
|
|
2133
2711
|
currentLanguage
|
|
2134
|
-
} = i18n_src
|
|
2135
|
-
function ViewerHeader(
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
const
|
|
2142
|
-
const
|
|
2143
|
-
const location = (0,react_router_dist/* useLocation */.TH)();
|
|
2712
|
+
} = i18n_src/* default */.A;
|
|
2713
|
+
function ViewerHeader({
|
|
2714
|
+
hotkeysManager,
|
|
2715
|
+
extensionManager,
|
|
2716
|
+
servicesManager,
|
|
2717
|
+
appConfig
|
|
2718
|
+
}) {
|
|
2719
|
+
const navigate = (0,dist/* useNavigate */.Zp)();
|
|
2720
|
+
const location = (0,react_router_dist/* useLocation */.zy)();
|
|
2144
2721
|
const onClickReturnButton = () => {
|
|
2145
2722
|
const {
|
|
2146
2723
|
pathname
|
|
@@ -2164,34 +2741,35 @@ function ViewerHeader(_ref) {
|
|
|
2164
2741
|
};
|
|
2165
2742
|
const {
|
|
2166
2743
|
t
|
|
2167
|
-
} = (0,es/* useTranslation
|
|
2744
|
+
} = (0,es/* useTranslation */.Bd)();
|
|
2168
2745
|
const {
|
|
2169
2746
|
show,
|
|
2170
2747
|
hide
|
|
2171
|
-
} = (0,ui_src/* useModal */.
|
|
2748
|
+
} = (0,ui_src/* useModal */.hS)();
|
|
2172
2749
|
const {
|
|
2173
2750
|
hotkeyDefinitions,
|
|
2174
2751
|
hotkeyDefaults
|
|
2175
2752
|
} = hotkeysManager;
|
|
2176
|
-
const versionNumber = "3.8.0-beta.
|
|
2177
|
-
const commitHash = "
|
|
2753
|
+
const versionNumber = "3.8.0-beta.81";
|
|
2754
|
+
const commitHash = "f99a0bfb31434aa137bbb3ed1f9eef1dfcc09025";
|
|
2178
2755
|
const menuOptions = [{
|
|
2179
2756
|
title: t('Header:About'),
|
|
2180
2757
|
icon: 'info',
|
|
2181
2758
|
onClick: () => show({
|
|
2182
|
-
content: ui_src/* AboutModal */.
|
|
2759
|
+
content: ui_src/* AboutModal */.VT,
|
|
2183
2760
|
title: t('AboutModal:About OHIF Viewer'),
|
|
2184
2761
|
contentProps: {
|
|
2185
2762
|
versionNumber,
|
|
2186
2763
|
commitHash
|
|
2187
|
-
}
|
|
2764
|
+
},
|
|
2765
|
+
containerDimensions: 'max-w-4xl max-h-4xl'
|
|
2188
2766
|
})
|
|
2189
2767
|
}, {
|
|
2190
2768
|
title: t('Header:Preferences'),
|
|
2191
2769
|
icon: 'settings',
|
|
2192
2770
|
onClick: () => show({
|
|
2193
2771
|
title: t('UserPreferencesModal:User preferences'),
|
|
2194
|
-
content: ui_src/* UserPreferences */.
|
|
2772
|
+
content: ui_src/* UserPreferences */.im,
|
|
2195
2773
|
contentProps: {
|
|
2196
2774
|
hotkeyDefaults: hotkeysManager.getValidHotkeyDefinitions(hotkeyDefaults),
|
|
2197
2775
|
hotkeyDefinitions,
|
|
@@ -2199,23 +2777,22 @@ function ViewerHeader(_ref) {
|
|
|
2199
2777
|
availableLanguages,
|
|
2200
2778
|
defaultLanguage,
|
|
2201
2779
|
onCancel: () => {
|
|
2202
|
-
src/* hotkeys */.
|
|
2203
|
-
src/* hotkeys */.
|
|
2780
|
+
src/* hotkeys */.ot.stopRecord();
|
|
2781
|
+
src/* hotkeys */.ot.unpause();
|
|
2204
2782
|
hide();
|
|
2205
2783
|
},
|
|
2206
|
-
onSubmit:
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
} = _ref2;
|
|
2784
|
+
onSubmit: ({
|
|
2785
|
+
hotkeyDefinitions,
|
|
2786
|
+
language
|
|
2787
|
+
}) => {
|
|
2211
2788
|
if (language.value !== currentLanguage().value) {
|
|
2212
|
-
i18n_src
|
|
2789
|
+
i18n_src/* default */.A.changeLanguage(language.value);
|
|
2213
2790
|
}
|
|
2214
2791
|
hotkeysManager.setHotkeys(hotkeyDefinitions);
|
|
2215
2792
|
hide();
|
|
2216
2793
|
},
|
|
2217
2794
|
onReset: () => hotkeysManager.restoreDefaultBindings(),
|
|
2218
|
-
hotkeysModule: src/* hotkeys */.
|
|
2795
|
+
hotkeysModule: src/* hotkeys */.ot
|
|
2219
2796
|
}
|
|
2220
2797
|
})
|
|
2221
2798
|
}];
|
|
@@ -2228,61 +2805,93 @@ function ViewerHeader(_ref) {
|
|
|
2228
2805
|
}
|
|
2229
2806
|
});
|
|
2230
2807
|
}
|
|
2231
|
-
return /*#__PURE__*/react.createElement(ui_src/* Header */.
|
|
2808
|
+
return /*#__PURE__*/react.createElement(ui_src/* Header */.Y9, {
|
|
2232
2809
|
menuOptions: menuOptions,
|
|
2233
2810
|
isReturnEnabled: !!appConfig.showStudyList,
|
|
2234
2811
|
onClickReturnButton: onClickReturnButton,
|
|
2235
|
-
WhiteLabeling: appConfig.whiteLabeling
|
|
2236
|
-
|
|
2812
|
+
WhiteLabeling: appConfig.whiteLabeling,
|
|
2813
|
+
showPatientInfo: appConfig.showPatientInfo,
|
|
2814
|
+
servicesManager: servicesManager,
|
|
2815
|
+
Secondary: /*#__PURE__*/react.createElement(Toolbar, {
|
|
2816
|
+
servicesManager: servicesManager,
|
|
2817
|
+
buttonSection: "secondary"
|
|
2818
|
+
}),
|
|
2819
|
+
appConfig: appConfig
|
|
2820
|
+
}, /*#__PURE__*/react.createElement(ui_src/* ErrorBoundary */.tH, {
|
|
2237
2821
|
context: "Primary Toolbar"
|
|
2238
2822
|
}, /*#__PURE__*/react.createElement("div", {
|
|
2239
|
-
className: "relative flex justify-center"
|
|
2823
|
+
className: "relative flex justify-center gap-[4px]"
|
|
2240
2824
|
}, /*#__PURE__*/react.createElement(Toolbar, {
|
|
2241
2825
|
servicesManager: servicesManager
|
|
2242
2826
|
}))));
|
|
2243
2827
|
}
|
|
2244
2828
|
/* harmony default export */ const ViewerLayout_ViewerHeader = (ViewerHeader);
|
|
2245
2829
|
;// CONCATENATED MODULE: ../../../extensions/default/src/Components/SidePanelWithServices.tsx
|
|
2830
|
+
function SidePanelWithServices_extends() { SidePanelWithServices_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 SidePanelWithServices_extends.apply(this, arguments); }
|
|
2246
2831
|
|
|
2247
2832
|
|
|
2248
|
-
const SidePanelWithServices =
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2833
|
+
const SidePanelWithServices = ({
|
|
2834
|
+
servicesManager,
|
|
2835
|
+
side,
|
|
2836
|
+
activeTabIndex: activeTabIndexProp,
|
|
2837
|
+
tabs: tabsProp,
|
|
2838
|
+
expandedWidth,
|
|
2839
|
+
...props
|
|
2840
|
+
}) => {
|
|
2256
2841
|
const panelService = servicesManager?.services?.panelService;
|
|
2257
2842
|
|
|
2258
2843
|
// Tracks whether this SidePanel has been opened at least once since this SidePanel was inserted into the DOM.
|
|
2259
2844
|
// Thus going to the Study List page and back to the viewer resets this flag for a SidePanel.
|
|
2260
2845
|
const [hasBeenOpened, setHasBeenOpened] = (0,react.useState)(false);
|
|
2261
2846
|
const [activeTabIndex, setActiveTabIndex] = (0,react.useState)(activeTabIndexProp);
|
|
2847
|
+
const [tabs, setTabs] = (0,react.useState)(tabsProp ?? panelService.getPanels(side));
|
|
2848
|
+
const handleSidePanelOpen = (0,react.useCallback)(() => {
|
|
2849
|
+
setHasBeenOpened(true);
|
|
2850
|
+
}, []);
|
|
2851
|
+
const handleActiveTabIndexChange = (0,react.useCallback)(({
|
|
2852
|
+
activeTabIndex
|
|
2853
|
+
}) => {
|
|
2854
|
+
setActiveTabIndex(activeTabIndex);
|
|
2855
|
+
}, []);
|
|
2856
|
+
|
|
2857
|
+
/** update the active tab index from outside */
|
|
2262
2858
|
(0,react.useEffect)(() => {
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2859
|
+
setActiveTabIndex(activeTabIndexProp);
|
|
2860
|
+
}, [activeTabIndexProp]);
|
|
2861
|
+
(0,react.useEffect)(() => {
|
|
2862
|
+
const {
|
|
2863
|
+
unsubscribe
|
|
2864
|
+
} = panelService.subscribe(panelService.EVENTS.PANELS_CHANGED, panelChangedEvent => {
|
|
2865
|
+
if (panelChangedEvent.position !== side) {
|
|
2866
|
+
return;
|
|
2867
|
+
}
|
|
2868
|
+
setTabs(panelService.getPanels(side));
|
|
2869
|
+
});
|
|
2870
|
+
return () => {
|
|
2871
|
+
unsubscribe();
|
|
2872
|
+
};
|
|
2873
|
+
}, [panelService, side]);
|
|
2874
|
+
(0,react.useEffect)(() => {
|
|
2875
|
+
const activatePanelSubscription = panelService.subscribe(panelService.EVENTS.ACTIVATE_PANEL, activatePanelEvent => {
|
|
2876
|
+
if (!hasBeenOpened || activatePanelEvent.forceActive) {
|
|
2877
|
+
const tabIndex = tabs.findIndex(tab => tab.id === activatePanelEvent.panelId);
|
|
2878
|
+
if (tabIndex !== -1) {
|
|
2879
|
+
setActiveTabIndex(tabIndex);
|
|
2270
2880
|
}
|
|
2271
|
-
}
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
}
|
|
2881
|
+
}
|
|
2882
|
+
});
|
|
2883
|
+
return () => {
|
|
2884
|
+
activatePanelSubscription.unsubscribe();
|
|
2885
|
+
};
|
|
2276
2886
|
}, [tabs, hasBeenOpened, panelService]);
|
|
2277
|
-
return /*#__PURE__*/react.createElement(ui_src/* SidePanel */.
|
|
2887
|
+
return /*#__PURE__*/react.createElement(ui_src/* SidePanel */.wv, SidePanelWithServices_extends({}, props, {
|
|
2278
2888
|
side: side,
|
|
2279
|
-
className: className,
|
|
2280
|
-
activeTabIndex: activeTabIndex,
|
|
2281
2889
|
tabs: tabs,
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2890
|
+
activeTabIndex: activeTabIndex,
|
|
2891
|
+
onOpen: handleSidePanelOpen,
|
|
2892
|
+
onActiveTabIndexChange: handleActiveTabIndexChange,
|
|
2893
|
+
expandedWidth: expandedWidth
|
|
2894
|
+
}));
|
|
2286
2895
|
};
|
|
2287
2896
|
/* harmony default export */ const Components_SidePanelWithServices = (SidePanelWithServices);
|
|
2288
2897
|
;// CONCATENATED MODULE: ../../../extensions/default/src/ViewerLayout/index.tsx
|
|
@@ -2293,26 +2902,29 @@ const SidePanelWithServices = _ref => {
|
|
|
2293
2902
|
|
|
2294
2903
|
|
|
2295
2904
|
|
|
2296
|
-
function ViewerLayout(
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
rightPanelDefaultClosed = false
|
|
2310
|
-
} = _ref;
|
|
2311
|
-
const [appConfig] = (0,state/* useAppConfig */.M)();
|
|
2905
|
+
function ViewerLayout({
|
|
2906
|
+
// From Extension Module Params
|
|
2907
|
+
extensionManager,
|
|
2908
|
+
servicesManager,
|
|
2909
|
+
hotkeysManager,
|
|
2910
|
+
commandsManager,
|
|
2911
|
+
// From Modes
|
|
2912
|
+
viewports,
|
|
2913
|
+
ViewportGridComp,
|
|
2914
|
+
leftPanelClosed = false,
|
|
2915
|
+
rightPanelClosed = false
|
|
2916
|
+
}) {
|
|
2917
|
+
const [appConfig] = (0,state/* useAppConfig */.r)();
|
|
2312
2918
|
const {
|
|
2919
|
+
panelService,
|
|
2313
2920
|
hangingProtocolService
|
|
2314
2921
|
} = servicesManager.services;
|
|
2315
2922
|
const [showLoadingIndicator, setShowLoadingIndicator] = (0,react.useState)(appConfig.showLoadingIndicator);
|
|
2923
|
+
const hasPanels = (0,react.useCallback)(side => !!panelService.getPanels(side).length, [panelService]);
|
|
2924
|
+
const [hasRightPanels, setHasRightPanels] = (0,react.useState)(hasPanels('right'));
|
|
2925
|
+
const [hasLeftPanels, setHasLeftPanels] = (0,react.useState)(hasPanels('left'));
|
|
2926
|
+
const [leftPanelClosedState, setLeftPanelClosed] = (0,react.useState)(leftPanelClosed);
|
|
2927
|
+
const [rightPanelClosedState, setRightPanelClosed] = (0,react.useState)(rightPanelClosed);
|
|
2316
2928
|
|
|
2317
2929
|
/**
|
|
2318
2930
|
* Set body classes (tailwindcss) that don't allow vertical
|
|
@@ -2329,38 +2941,18 @@ function ViewerLayout(_ref) {
|
|
|
2329
2941
|
}, []);
|
|
2330
2942
|
const getComponent = id => {
|
|
2331
2943
|
const entry = extensionManager.getModuleEntry(id);
|
|
2332
|
-
if (!entry) {
|
|
2333
|
-
throw new Error(`${id} is not valid for an extension module. Please verify your configuration or ensure that the extension is properly registered. It's also possible that your mode is utilizing a module from an extension that hasn't been included in its dependencies (add the extension to the "extensionDependencies" array in your mode's index.js file)`);
|
|
2334
|
-
}
|
|
2335
|
-
let content;
|
|
2336
|
-
if (entry && entry.component) {
|
|
2337
|
-
content = entry.component;
|
|
2338
|
-
} else {
|
|
2339
|
-
throw new Error(`No component found from extension ${id}. Check the reference string to the extension in your Mode configuration`);
|
|
2944
|
+
if (!entry || !entry.component) {
|
|
2945
|
+
throw new Error(`${id} is not valid for an extension module or no component found from extension ${id}. Please verify your configuration or ensure that the extension is properly registered. It's also possible that your mode is utilizing a module from an extension that hasn't been included in its dependencies (add the extension to the "extensionDependencies" array in your mode's index.js file). Check the reference string to the extension in your Mode configuration`);
|
|
2340
2946
|
}
|
|
2341
2947
|
return {
|
|
2342
2948
|
entry,
|
|
2343
|
-
content
|
|
2344
|
-
};
|
|
2345
|
-
};
|
|
2346
|
-
const getPanelData = id => {
|
|
2347
|
-
const {
|
|
2348
|
-
content,
|
|
2349
|
-
entry
|
|
2350
|
-
} = getComponent(id);
|
|
2351
|
-
return {
|
|
2352
|
-
id: entry.id,
|
|
2353
|
-
iconName: entry.iconName,
|
|
2354
|
-
iconLabel: entry.iconLabel,
|
|
2355
|
-
label: entry.label,
|
|
2356
|
-
name: entry.name,
|
|
2357
|
-
content
|
|
2949
|
+
content: entry.component
|
|
2358
2950
|
};
|
|
2359
2951
|
};
|
|
2360
2952
|
(0,react.useEffect)(() => {
|
|
2361
2953
|
const {
|
|
2362
2954
|
unsubscribe
|
|
2363
|
-
} = hangingProtocolService.subscribe(src/* HangingProtocolService */.
|
|
2955
|
+
} = hangingProtocolService.subscribe(src/* HangingProtocolService */.Qe.EVENTS.PROTOCOL_CHANGED,
|
|
2364
2956
|
// Todo: right now to set the loading indicator to false, we need to wait for the
|
|
2365
2957
|
// hangingProtocolService to finish applying the viewport matching to each viewport,
|
|
2366
2958
|
// however, this might not be the only approach to set the loading indicator to false. we need to explore this further.
|
|
@@ -2380,58 +2972,76 @@ function ViewerLayout(_ref) {
|
|
|
2380
2972
|
displaySetsToDisplay: viewportComponent.displaySetsToDisplay
|
|
2381
2973
|
};
|
|
2382
2974
|
};
|
|
2383
|
-
|
|
2384
|
-
|
|
2975
|
+
(0,react.useEffect)(() => {
|
|
2976
|
+
const {
|
|
2977
|
+
unsubscribe
|
|
2978
|
+
} = panelService.subscribe(panelService.EVENTS.PANELS_CHANGED, ({
|
|
2979
|
+
options
|
|
2980
|
+
}) => {
|
|
2981
|
+
setHasLeftPanels(hasPanels('left'));
|
|
2982
|
+
setHasRightPanels(hasPanels('right'));
|
|
2983
|
+
if (options?.leftPanelClosed !== undefined) {
|
|
2984
|
+
setLeftPanelClosed(options.leftPanelClosed);
|
|
2985
|
+
}
|
|
2986
|
+
if (options?.rightPanelClosed !== undefined) {
|
|
2987
|
+
setRightPanelClosed(options.rightPanelClosed);
|
|
2988
|
+
}
|
|
2989
|
+
});
|
|
2990
|
+
return () => {
|
|
2991
|
+
unsubscribe();
|
|
2992
|
+
};
|
|
2993
|
+
}, [panelService, hasPanels]);
|
|
2385
2994
|
const viewportComponents = viewports.map(getViewportComponentData);
|
|
2386
2995
|
return /*#__PURE__*/react.createElement("div", null, /*#__PURE__*/react.createElement(ViewerLayout_ViewerHeader, {
|
|
2387
2996
|
hotkeysManager: hotkeysManager,
|
|
2388
2997
|
extensionManager: extensionManager,
|
|
2389
|
-
servicesManager: servicesManager
|
|
2998
|
+
servicesManager: servicesManager,
|
|
2999
|
+
appConfig: appConfig
|
|
2390
3000
|
}), /*#__PURE__*/react.createElement("div", {
|
|
2391
3001
|
className: "relative flex w-full flex-row flex-nowrap items-stretch overflow-hidden bg-black",
|
|
2392
3002
|
style: {
|
|
2393
3003
|
height: 'calc(100vh - 52px'
|
|
2394
3004
|
}
|
|
2395
|
-
}, /*#__PURE__*/react.createElement(react.Fragment, null, showLoadingIndicator && /*#__PURE__*/react.createElement(ui_src/* LoadingIndicatorProgress */.
|
|
3005
|
+
}, /*#__PURE__*/react.createElement(react.Fragment, null, showLoadingIndicator && /*#__PURE__*/react.createElement(ui_src/* LoadingIndicatorProgress */.Jx, {
|
|
2396
3006
|
className: "h-full w-full bg-black"
|
|
2397
|
-
}),
|
|
3007
|
+
}), hasLeftPanels ? /*#__PURE__*/react.createElement(ui_src/* ErrorBoundary */.tH, {
|
|
2398
3008
|
context: "Left Panel"
|
|
2399
3009
|
}, /*#__PURE__*/react.createElement(Components_SidePanelWithServices, {
|
|
2400
3010
|
side: "left",
|
|
2401
|
-
activeTabIndex:
|
|
2402
|
-
tabs: leftPanelComponents,
|
|
3011
|
+
activeTabIndex: leftPanelClosedState ? null : 0,
|
|
2403
3012
|
servicesManager: servicesManager
|
|
2404
3013
|
})) : null, /*#__PURE__*/react.createElement("div", {
|
|
2405
3014
|
className: "flex h-full flex-1 flex-col"
|
|
2406
3015
|
}, /*#__PURE__*/react.createElement("div", {
|
|
2407
3016
|
className: "relative flex h-full flex-1 items-center justify-center overflow-hidden bg-black"
|
|
2408
|
-
}, /*#__PURE__*/react.createElement(ui_src/* ErrorBoundary */.
|
|
3017
|
+
}, /*#__PURE__*/react.createElement(ui_src/* ErrorBoundary */.tH, {
|
|
2409
3018
|
context: "Grid"
|
|
2410
3019
|
}, /*#__PURE__*/react.createElement(ViewportGridComp, {
|
|
2411
3020
|
servicesManager: servicesManager,
|
|
2412
3021
|
viewportComponents: viewportComponents,
|
|
2413
3022
|
commandsManager: commandsManager
|
|
2414
|
-
})))),
|
|
3023
|
+
})))), hasRightPanels ? /*#__PURE__*/react.createElement(ui_src/* ErrorBoundary */.tH, {
|
|
2415
3024
|
context: "Right Panel"
|
|
2416
3025
|
}, /*#__PURE__*/react.createElement(Components_SidePanelWithServices, {
|
|
2417
3026
|
side: "right",
|
|
2418
|
-
activeTabIndex:
|
|
2419
|
-
tabs: rightPanelComponents,
|
|
3027
|
+
activeTabIndex: rightPanelClosedState ? null : 0,
|
|
2420
3028
|
servicesManager: servicesManager
|
|
2421
|
-
})) : null))
|
|
3029
|
+
})) : null)), /*#__PURE__*/react.createElement(ui_src/* InvestigationalUseDialog */.j, {
|
|
3030
|
+
dialogConfiguration: appConfig?.investigationalUseDialog
|
|
3031
|
+
}));
|
|
2422
3032
|
}
|
|
2423
3033
|
ViewerLayout.propTypes = {
|
|
2424
3034
|
// From extension module params
|
|
2425
3035
|
extensionManager: prop_types_default().shape({
|
|
2426
3036
|
getModuleEntry: (prop_types_default()).func.isRequired
|
|
2427
3037
|
}).isRequired,
|
|
2428
|
-
commandsManager: prop_types_default().instanceOf(src/* CommandsManager */.
|
|
2429
|
-
servicesManager: prop_types_default().instanceOf(src/* ServicesManager */.
|
|
3038
|
+
commandsManager: prop_types_default().instanceOf(src/* CommandsManager */.Sp),
|
|
3039
|
+
servicesManager: prop_types_default().instanceOf(src/* ServicesManager */.CS),
|
|
2430
3040
|
// From modes
|
|
2431
3041
|
leftPanels: (prop_types_default()).array,
|
|
2432
3042
|
rightPanels: (prop_types_default()).array,
|
|
2433
|
-
|
|
2434
|
-
|
|
3043
|
+
leftPanelClosed: (prop_types_default()).bool.isRequired,
|
|
3044
|
+
rightPanelClosed: (prop_types_default()).bool.isRequired,
|
|
2435
3045
|
/** Responsible for rendering our grid of viewports; provided by consuming application */
|
|
2436
3046
|
children: prop_types_default().oneOfType([(prop_types_default()).node, (prop_types_default()).func]).isRequired,
|
|
2437
3047
|
viewports: (prop_types_default()).array
|
|
@@ -2445,13 +3055,12 @@ ViewerLayout.propTypes = {
|
|
|
2445
3055
|
- Init layout based on the displaySets and the objects.
|
|
2446
3056
|
*/
|
|
2447
3057
|
|
|
2448
|
-
/* harmony default export */ function getLayoutTemplateModule(
|
|
2449
|
-
|
|
2450
|
-
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
} = _ref;
|
|
3058
|
+
/* harmony default export */ function getLayoutTemplateModule({
|
|
3059
|
+
servicesManager,
|
|
3060
|
+
extensionManager,
|
|
3061
|
+
commandsManager,
|
|
3062
|
+
hotkeysManager
|
|
3063
|
+
}) {
|
|
2455
3064
|
function ViewerLayoutWithServices(props) {
|
|
2456
3065
|
return src_ViewerLayout({
|
|
2457
3066
|
servicesManager,
|
|
@@ -2485,31 +3094,30 @@ const {
|
|
|
2485
3094
|
*
|
|
2486
3095
|
* @param {*} param0
|
|
2487
3096
|
*/
|
|
2488
|
-
function PanelStudyBrowser(
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
} = _ref;
|
|
3097
|
+
function PanelStudyBrowser({
|
|
3098
|
+
servicesManager,
|
|
3099
|
+
getImageSrc,
|
|
3100
|
+
getStudiesForPatientByMRN,
|
|
3101
|
+
requestDisplaySetCreationForStudy,
|
|
3102
|
+
dataSource
|
|
3103
|
+
}) {
|
|
2496
3104
|
const {
|
|
2497
3105
|
hangingProtocolService,
|
|
2498
3106
|
displaySetService,
|
|
2499
3107
|
uiNotificationService
|
|
2500
3108
|
} = servicesManager.services;
|
|
2501
|
-
const navigate = (0,dist/* useNavigate */.
|
|
3109
|
+
const navigate = (0,dist/* useNavigate */.Zp)();
|
|
2502
3110
|
|
|
2503
3111
|
// Normally you nest the components so the tree isn't so deep, and the data
|
|
2504
3112
|
// doesn't have to have such an intense shape. This works well enough for now.
|
|
2505
3113
|
// Tabs --> Studies --> DisplaySets --> Thumbnails
|
|
2506
3114
|
const {
|
|
2507
3115
|
StudyInstanceUIDs
|
|
2508
|
-
} = (0,ui_src/* useImageViewer */.
|
|
3116
|
+
} = (0,ui_src/* useImageViewer */.Bz)();
|
|
2509
3117
|
const [{
|
|
2510
3118
|
activeViewportId,
|
|
2511
3119
|
viewports
|
|
2512
|
-
}, viewportGridService] = (0,ui_src/* useViewportGrid */.
|
|
3120
|
+
}, viewportGridService] = (0,ui_src/* useViewportGrid */.ih)();
|
|
2513
3121
|
const [activeTabName, setActiveTabName] = (0,react.useState)('primary');
|
|
2514
3122
|
const [expandedStudyInstanceUIDs, setExpandedStudyInstanceUIDs] = (0,react.useState)([...StudyInstanceUIDs]);
|
|
2515
3123
|
const [studyDisplayList, setStudyDisplayList] = (0,react.useState)([]);
|
|
@@ -2675,7 +3283,7 @@ function PanelStudyBrowser(_ref) {
|
|
|
2675
3283
|
}
|
|
2676
3284
|
}
|
|
2677
3285
|
const activeDisplaySetInstanceUIDs = viewports.get(activeViewportId)?.displaySetInstanceUIDs;
|
|
2678
|
-
return /*#__PURE__*/react.createElement(ui_src/* StudyBrowser */.
|
|
3286
|
+
return /*#__PURE__*/react.createElement(ui_src/* StudyBrowser */.M4, {
|
|
2679
3287
|
tabs: tabs,
|
|
2680
3288
|
servicesManager: servicesManager,
|
|
2681
3289
|
activeTabName: activeTabName,
|
|
@@ -2745,7 +3353,6 @@ function _mapDisplaySets(displaySets, thumbnailImageSrcMap) {
|
|
|
2745
3353
|
displaySetInstanceUID: ds.displaySetInstanceUID
|
|
2746
3354
|
// .. Any other data to pass
|
|
2747
3355
|
},
|
|
2748
|
-
|
|
2749
3356
|
isHydratedForDerivedDisplaySet: ds.isHydrated
|
|
2750
3357
|
});
|
|
2751
3358
|
});
|
|
@@ -2814,7 +3421,8 @@ function getImageSrcFromImageId(cornerstone, imageId) {
|
|
|
2814
3421
|
const canvas = document.createElement('canvas');
|
|
2815
3422
|
cornerstone.utilities.loadImageToCanvas({
|
|
2816
3423
|
canvas,
|
|
2817
|
-
imageId
|
|
3424
|
+
imageId,
|
|
3425
|
+
thumbnail: true
|
|
2818
3426
|
}).then(imageId => {
|
|
2819
3427
|
resolve(canvas.toDataURL());
|
|
2820
3428
|
}).catch(reject);
|
|
@@ -2860,17 +3468,16 @@ function requestDisplaySetCreationForStudy(dataSource, displaySetService, StudyI
|
|
|
2860
3468
|
* @param {object} commandsManager
|
|
2861
3469
|
* @param {object} extensionManager
|
|
2862
3470
|
*/
|
|
2863
|
-
function WrappedPanelStudyBrowser(
|
|
2864
|
-
|
|
2865
|
-
|
|
2866
|
-
|
|
2867
|
-
|
|
2868
|
-
} = _ref;
|
|
3471
|
+
function WrappedPanelStudyBrowser({
|
|
3472
|
+
commandsManager,
|
|
3473
|
+
extensionManager,
|
|
3474
|
+
servicesManager
|
|
3475
|
+
}) {
|
|
2869
3476
|
// TODO: This should be made available a different way; route should have
|
|
2870
3477
|
// already determined our datasource
|
|
2871
3478
|
const dataSource = extensionManager.getDataSources()[0];
|
|
2872
3479
|
const _getStudiesForPatientByMRN = Panels_getStudiesForPatientByMRN.bind(null, dataSource);
|
|
2873
|
-
const _getImageSrcFromImageId = _createGetImageSrcFromImageIdFn(extensionManager);
|
|
3480
|
+
const _getImageSrcFromImageId = (0,react.useCallback)(_createGetImageSrcFromImageIdFn(extensionManager), []);
|
|
2874
3481
|
const _requestDisplaySetCreationForStudy = Panels_requestDisplaySetCreationForStudy.bind(null, dataSource);
|
|
2875
3482
|
return /*#__PURE__*/react.createElement(Panels_PanelStudyBrowser, {
|
|
2876
3483
|
servicesManager: servicesManager,
|
|
@@ -2907,41 +3514,8 @@ WrappedPanelStudyBrowser.propTypes = {
|
|
|
2907
3514
|
servicesManager: (prop_types_default()).object.isRequired
|
|
2908
3515
|
};
|
|
2909
3516
|
/* harmony default export */ const Panels_WrappedPanelStudyBrowser = (WrappedPanelStudyBrowser);
|
|
2910
|
-
;// CONCATENATED MODULE: ../../../extensions/default/src/Panels/ActionButtons.tsx
|
|
2911
|
-
|
|
2912
|
-
|
|
2913
|
-
|
|
2914
|
-
|
|
2915
|
-
function ActionButtons(_ref) {
|
|
2916
|
-
let {
|
|
2917
|
-
onExportClick,
|
|
2918
|
-
onCreateReportClick
|
|
2919
|
-
} = _ref;
|
|
2920
|
-
const {
|
|
2921
|
-
t
|
|
2922
|
-
} = (0,es/* useTranslation */.$G)('MeasurementTable');
|
|
2923
|
-
return /*#__PURE__*/react.createElement(react.Fragment, null, /*#__PURE__*/react.createElement(ui_src/* LegacyButtonGroup */.HO, {
|
|
2924
|
-
color: "black",
|
|
2925
|
-
size: "inherit"
|
|
2926
|
-
}, /*#__PURE__*/react.createElement(ui_src/* LegacyButton */.mN, {
|
|
2927
|
-
className: "px-2 py-2 text-base",
|
|
2928
|
-
onClick: onExportClick
|
|
2929
|
-
}, t('Export CSV')), /*#__PURE__*/react.createElement(ui_src/* LegacyButton */.mN, {
|
|
2930
|
-
className: "px-2 py-2 text-base",
|
|
2931
|
-
onClick: onCreateReportClick
|
|
2932
|
-
}, t('Create Report'))));
|
|
2933
|
-
}
|
|
2934
|
-
ActionButtons.propTypes = {
|
|
2935
|
-
onExportClick: (prop_types_default()).func,
|
|
2936
|
-
onCreateReportClick: (prop_types_default()).func
|
|
2937
|
-
};
|
|
2938
|
-
ActionButtons.defaultProps = {
|
|
2939
|
-
onExportClick: () => alert('Export'),
|
|
2940
|
-
onCreateReportClick: () => alert('Create Report')
|
|
2941
|
-
};
|
|
2942
|
-
/* harmony default export */ const Panels_ActionButtons = (ActionButtons);
|
|
2943
3517
|
// EXTERNAL MODULE: ../../../node_modules/lodash.debounce/index.js
|
|
2944
|
-
var lodash_debounce = __webpack_require__(
|
|
3518
|
+
var lodash_debounce = __webpack_require__(14771);
|
|
2945
3519
|
var lodash_debounce_default = /*#__PURE__*/__webpack_require__.n(lodash_debounce);
|
|
2946
3520
|
;// CONCATENATED MODULE: ../../../extensions/default/src/Panels/createReportDialogPrompt.tsx
|
|
2947
3521
|
|
|
@@ -2950,10 +3524,9 @@ const CREATE_REPORT_DIALOG_RESPONSE = {
|
|
|
2950
3524
|
CANCEL: 0,
|
|
2951
3525
|
CREATE_REPORT: 1
|
|
2952
3526
|
};
|
|
2953
|
-
function CreateReportDialogPrompt(uiDialogService,
|
|
2954
|
-
|
|
2955
|
-
|
|
2956
|
-
} = _ref;
|
|
3527
|
+
function CreateReportDialogPrompt(uiDialogService, {
|
|
3528
|
+
extensionManager
|
|
3529
|
+
}) {
|
|
2957
3530
|
return new Promise(function (resolve, reject) {
|
|
2958
3531
|
let dialogId = undefined;
|
|
2959
3532
|
const _handleClose = () => {
|
|
@@ -2974,11 +3547,10 @@ function CreateReportDialogPrompt(uiDialogService, _ref) {
|
|
|
2974
3547
|
* @param {string} param0.action - value of action performed
|
|
2975
3548
|
* @param {string} param0.value - value from input field
|
|
2976
3549
|
*/
|
|
2977
|
-
const _handleFormSubmit =
|
|
2978
|
-
|
|
2979
|
-
|
|
2980
|
-
|
|
2981
|
-
} = _ref2;
|
|
3550
|
+
const _handleFormSubmit = ({
|
|
3551
|
+
action,
|
|
3552
|
+
value
|
|
3553
|
+
}) => {
|
|
2982
3554
|
uiDialogService.dismiss({
|
|
2983
3555
|
id: dialogId
|
|
2984
3556
|
});
|
|
@@ -3013,7 +3585,7 @@ function CreateReportDialogPrompt(uiDialogService, _ref) {
|
|
|
3013
3585
|
dialogId = uiDialogService.create({
|
|
3014
3586
|
centralize: true,
|
|
3015
3587
|
isDraggable: false,
|
|
3016
|
-
content: ui_src/* Dialog */.
|
|
3588
|
+
content: ui_src/* Dialog */.lG,
|
|
3017
3589
|
useLastPosition: false,
|
|
3018
3590
|
showOverlay: true,
|
|
3019
3591
|
contentProps: {
|
|
@@ -3027,19 +3599,18 @@ function CreateReportDialogPrompt(uiDialogService, _ref) {
|
|
|
3027
3599
|
actions: [{
|
|
3028
3600
|
id: 'cancel',
|
|
3029
3601
|
text: 'Cancel',
|
|
3030
|
-
type: ui_src/* ButtonEnums.type */.
|
|
3602
|
+
type: ui_src/* ButtonEnums.type */.Ny.NW.secondary
|
|
3031
3603
|
}, {
|
|
3032
3604
|
id: 'save',
|
|
3033
3605
|
text: 'Save',
|
|
3034
|
-
type: ui_src/* ButtonEnums.type */.
|
|
3606
|
+
type: ui_src/* ButtonEnums.type */.Ny.NW.primary
|
|
3035
3607
|
}],
|
|
3036
3608
|
// TODO: Should be on button press...
|
|
3037
3609
|
onSubmit: _handleFormSubmit,
|
|
3038
|
-
body:
|
|
3039
|
-
|
|
3040
|
-
|
|
3041
|
-
|
|
3042
|
-
} = _ref3;
|
|
3610
|
+
body: ({
|
|
3611
|
+
value,
|
|
3612
|
+
setValue
|
|
3613
|
+
}) => {
|
|
3043
3614
|
const onChangeHandler = event => {
|
|
3044
3615
|
event.persist();
|
|
3045
3616
|
setValue(value => ({
|
|
@@ -3060,7 +3631,7 @@ function CreateReportDialogPrompt(uiDialogService, _ref) {
|
|
|
3060
3631
|
};
|
|
3061
3632
|
return /*#__PURE__*/react.createElement(react.Fragment, null, dataSourcesOpts.length > 1 && window.config?.allowMultiSelectExport && /*#__PURE__*/react.createElement("div", null, /*#__PURE__*/react.createElement("label", {
|
|
3062
3633
|
className: "text-[14px] leading-[1.2] text-white"
|
|
3063
|
-
}, "Data Source"), /*#__PURE__*/react.createElement(ui_src/* Select */.
|
|
3634
|
+
}, "Data Source"), /*#__PURE__*/react.createElement(ui_src/* Select */.l6, {
|
|
3064
3635
|
closeMenuOnSelect: true,
|
|
3065
3636
|
className: "border-primary-main mt-2 bg-black",
|
|
3066
3637
|
options: dataSourcesOpts,
|
|
@@ -3075,7 +3646,7 @@ function CreateReportDialogPrompt(uiDialogService, _ref) {
|
|
|
3075
3646
|
isClearable: false
|
|
3076
3647
|
})), /*#__PURE__*/react.createElement("div", {
|
|
3077
3648
|
className: "mt-3"
|
|
3078
|
-
}, /*#__PURE__*/react.createElement(ui_src/* Input */.
|
|
3649
|
+
}, /*#__PURE__*/react.createElement(ui_src/* Input */.pd, {
|
|
3079
3650
|
autoFocus: true,
|
|
3080
3651
|
label: "Enter the report name",
|
|
3081
3652
|
labelClassName: "text-white text-[14px] leading-[1.2]",
|
|
@@ -3099,12 +3670,11 @@ function CreateReportDialogPrompt(uiDialogService, _ref) {
|
|
|
3099
3670
|
*
|
|
3100
3671
|
* @param {*} servicesManager
|
|
3101
3672
|
*/
|
|
3102
|
-
async function createReportAsync(
|
|
3103
|
-
|
|
3104
|
-
|
|
3105
|
-
|
|
3106
|
-
|
|
3107
|
-
} = _ref;
|
|
3673
|
+
async function createReportAsync({
|
|
3674
|
+
servicesManager,
|
|
3675
|
+
getReport,
|
|
3676
|
+
reportType = 'measurement'
|
|
3677
|
+
}) {
|
|
3108
3678
|
const {
|
|
3109
3679
|
displaySetService,
|
|
3110
3680
|
uiNotificationService,
|
|
@@ -3218,13 +3788,15 @@ function findSRWithSameSeriesDescription(SeriesDescription, displaySetService) {
|
|
|
3218
3788
|
const {
|
|
3219
3789
|
downloadCSVReport
|
|
3220
3790
|
} = src.utils;
|
|
3221
|
-
function PanelMeasurementTable(
|
|
3222
|
-
|
|
3223
|
-
|
|
3224
|
-
|
|
3225
|
-
|
|
3226
|
-
|
|
3227
|
-
|
|
3791
|
+
function PanelMeasurementTable({
|
|
3792
|
+
servicesManager,
|
|
3793
|
+
commandsManager,
|
|
3794
|
+
extensionManager
|
|
3795
|
+
}) {
|
|
3796
|
+
const {
|
|
3797
|
+
t
|
|
3798
|
+
} = (0,es/* useTranslation */.Bd)('MeasurementTable');
|
|
3799
|
+
const [viewportGrid, viewportGridService] = (0,ui_src/* useViewportGrid */.ih)();
|
|
3228
3800
|
const {
|
|
3229
3801
|
activeViewportId,
|
|
3230
3802
|
viewports
|
|
@@ -3310,31 +3882,28 @@ function PanelMeasurementTable(_ref) {
|
|
|
3310
3882
|
});
|
|
3311
3883
|
}
|
|
3312
3884
|
}
|
|
3313
|
-
const jumpToImage =
|
|
3314
|
-
|
|
3315
|
-
|
|
3316
|
-
|
|
3317
|
-
} = _ref2;
|
|
3885
|
+
const jumpToImage = ({
|
|
3886
|
+
uid,
|
|
3887
|
+
isActive
|
|
3888
|
+
}) => {
|
|
3318
3889
|
measurementService.jumpToMeasurement(viewportGrid.activeViewportId, uid);
|
|
3319
3890
|
onMeasurementItemClickHandler({
|
|
3320
3891
|
uid,
|
|
3321
3892
|
isActive
|
|
3322
3893
|
});
|
|
3323
3894
|
};
|
|
3324
|
-
const onMeasurementItemEditHandler =
|
|
3325
|
-
|
|
3326
|
-
|
|
3327
|
-
|
|
3328
|
-
} = _ref3;
|
|
3895
|
+
const onMeasurementItemEditHandler = ({
|
|
3896
|
+
uid,
|
|
3897
|
+
isActive
|
|
3898
|
+
}) => {
|
|
3329
3899
|
const measurement = measurementService.getMeasurement(uid);
|
|
3330
3900
|
//Todo: why we are jumping to image?
|
|
3331
3901
|
// jumpToImage({ id, isActive });
|
|
3332
3902
|
|
|
3333
|
-
const onSubmitHandler =
|
|
3334
|
-
|
|
3335
|
-
|
|
3336
|
-
|
|
3337
|
-
} = _ref4;
|
|
3903
|
+
const onSubmitHandler = ({
|
|
3904
|
+
action,
|
|
3905
|
+
value
|
|
3906
|
+
}) => {
|
|
3338
3907
|
switch (action.id) {
|
|
3339
3908
|
case 'save':
|
|
3340
3909
|
{
|
|
@@ -3353,18 +3922,17 @@ function PanelMeasurementTable(_ref) {
|
|
|
3353
3922
|
centralize: true,
|
|
3354
3923
|
isDraggable: false,
|
|
3355
3924
|
showOverlay: true,
|
|
3356
|
-
content: ui_src/* Dialog */.
|
|
3925
|
+
content: ui_src/* Dialog */.lG,
|
|
3357
3926
|
contentProps: {
|
|
3358
3927
|
title: 'Annotation',
|
|
3359
3928
|
noCloseButton: true,
|
|
3360
3929
|
value: {
|
|
3361
3930
|
label: measurement.label || ''
|
|
3362
3931
|
},
|
|
3363
|
-
body:
|
|
3364
|
-
|
|
3365
|
-
|
|
3366
|
-
|
|
3367
|
-
} = _ref5;
|
|
3932
|
+
body: ({
|
|
3933
|
+
value,
|
|
3934
|
+
setValue
|
|
3935
|
+
}) => {
|
|
3368
3936
|
const onChangeHandler = event => {
|
|
3369
3937
|
event.persist();
|
|
3370
3938
|
setValue(value => ({
|
|
@@ -3382,7 +3950,7 @@ function PanelMeasurementTable(_ref) {
|
|
|
3382
3950
|
});
|
|
3383
3951
|
}
|
|
3384
3952
|
};
|
|
3385
|
-
return /*#__PURE__*/react.createElement(ui_src/* Input */.
|
|
3953
|
+
return /*#__PURE__*/react.createElement(ui_src/* Input */.pd, {
|
|
3386
3954
|
label: "Enter your annotation",
|
|
3387
3955
|
labelClassName: "text-white text-[14px] leading-[1.2]",
|
|
3388
3956
|
autoFocus: true,
|
|
@@ -3397,21 +3965,20 @@ function PanelMeasurementTable(_ref) {
|
|
|
3397
3965
|
actions: [{
|
|
3398
3966
|
id: 'cancel',
|
|
3399
3967
|
text: 'Cancel',
|
|
3400
|
-
type: ui_src/* ButtonEnums.type */.
|
|
3968
|
+
type: ui_src/* ButtonEnums.type */.Ny.NW.secondary
|
|
3401
3969
|
}, {
|
|
3402
3970
|
id: 'save',
|
|
3403
3971
|
text: 'Save',
|
|
3404
|
-
type: ui_src/* ButtonEnums.type */.
|
|
3972
|
+
type: ui_src/* ButtonEnums.type */.Ny.NW.primary
|
|
3405
3973
|
}],
|
|
3406
3974
|
onSubmit: onSubmitHandler
|
|
3407
3975
|
}
|
|
3408
3976
|
});
|
|
3409
3977
|
};
|
|
3410
|
-
const onMeasurementItemClickHandler =
|
|
3411
|
-
|
|
3412
|
-
|
|
3413
|
-
|
|
3414
|
-
} = _ref6;
|
|
3978
|
+
const onMeasurementItemClickHandler = ({
|
|
3979
|
+
uid,
|
|
3980
|
+
isActive
|
|
3981
|
+
}) => {
|
|
3415
3982
|
if (!isActive) {
|
|
3416
3983
|
const measurements = [...displayMeasurements];
|
|
3417
3984
|
const measurement = measurements.find(m => m.uid === uid);
|
|
@@ -3423,22 +3990,27 @@ function PanelMeasurementTable(_ref) {
|
|
|
3423
3990
|
return /*#__PURE__*/react.createElement(react.Fragment, null, /*#__PURE__*/react.createElement("div", {
|
|
3424
3991
|
className: "ohif-scrollbar overflow-y-auto overflow-x-hidden",
|
|
3425
3992
|
"data-cy": 'measurements-panel'
|
|
3426
|
-
}, /*#__PURE__*/react.createElement(ui_src/* MeasurementTable */.
|
|
3427
|
-
title:
|
|
3993
|
+
}, /*#__PURE__*/react.createElement(ui_src/* MeasurementTable */.V, {
|
|
3994
|
+
title: t('Measurements'),
|
|
3428
3995
|
servicesManager: servicesManager,
|
|
3429
3996
|
data: displayMeasurements,
|
|
3430
3997
|
onClick: jumpToImage,
|
|
3431
3998
|
onEdit: onMeasurementItemEditHandler
|
|
3432
3999
|
})), /*#__PURE__*/react.createElement("div", {
|
|
3433
4000
|
className: "flex justify-center p-4"
|
|
3434
|
-
}, /*#__PURE__*/react.createElement(
|
|
3435
|
-
|
|
3436
|
-
|
|
3437
|
-
|
|
4001
|
+
}, /*#__PURE__*/react.createElement(ui_src/* ActionButtons */.wr, {
|
|
4002
|
+
t: t,
|
|
4003
|
+
actions: [{
|
|
4004
|
+
label: 'Export',
|
|
4005
|
+
onClick: exportReport
|
|
4006
|
+
}, {
|
|
4007
|
+
label: 'Create Report',
|
|
4008
|
+
onClick: createReport
|
|
4009
|
+
}]
|
|
3438
4010
|
})));
|
|
3439
4011
|
}
|
|
3440
4012
|
PanelMeasurementTable.propTypes = {
|
|
3441
|
-
servicesManager: prop_types_default().instanceOf(src/* ServicesManager */.
|
|
4013
|
+
servicesManager: prop_types_default().instanceOf(src/* ServicesManager */.CS).isRequired
|
|
3442
4014
|
};
|
|
3443
4015
|
function _getMappedMeasurements(measurementService) {
|
|
3444
4016
|
const measurements = measurementService.getMeasurements();
|
|
@@ -3495,21 +4067,23 @@ function _mapMeasurementToDisplay(measurement, index, types) {
|
|
|
3495
4067
|
|
|
3496
4068
|
|
|
3497
4069
|
|
|
4070
|
+
// EXTERNAL MODULE: ../../../node_modules/i18next/dist/esm/i18next.js
|
|
4071
|
+
var i18next = __webpack_require__(92344);
|
|
3498
4072
|
;// CONCATENATED MODULE: ../../../extensions/default/src/getPanelModule.tsx
|
|
3499
4073
|
|
|
3500
4074
|
|
|
3501
4075
|
|
|
4076
|
+
|
|
3502
4077
|
// TODO:
|
|
3503
4078
|
// - No loading UI exists yet
|
|
3504
4079
|
// - cancel promises when component is destroyed
|
|
3505
4080
|
// - show errors in UI for thumbnails if promise fails
|
|
3506
4081
|
|
|
3507
|
-
function getPanelModule(
|
|
3508
|
-
|
|
3509
|
-
|
|
3510
|
-
|
|
3511
|
-
|
|
3512
|
-
} = _ref;
|
|
4082
|
+
function getPanelModule({
|
|
4083
|
+
commandsManager,
|
|
4084
|
+
extensionManager,
|
|
4085
|
+
servicesManager
|
|
4086
|
+
}) {
|
|
3513
4087
|
const wrappedMeasurementPanel = () => {
|
|
3514
4088
|
return /*#__PURE__*/react.createElement(PanelMeasurementTable, {
|
|
3515
4089
|
commandsManager: commandsManager,
|
|
@@ -3521,7 +4095,7 @@ function getPanelModule(_ref) {
|
|
|
3521
4095
|
name: 'seriesList',
|
|
3522
4096
|
iconName: 'tab-studies',
|
|
3523
4097
|
iconLabel: 'Studies',
|
|
3524
|
-
label: 'Studies',
|
|
4098
|
+
label: i18next/* default */.A.t('SidePanel:Studies'),
|
|
3525
4099
|
component: Panels_WrappedPanelStudyBrowser.bind(null, {
|
|
3526
4100
|
commandsManager,
|
|
3527
4101
|
extensionManager,
|
|
@@ -3531,28 +4105,28 @@ function getPanelModule(_ref) {
|
|
|
3531
4105
|
name: 'measure',
|
|
3532
4106
|
iconName: 'tab-linear',
|
|
3533
4107
|
iconLabel: 'Measure',
|
|
3534
|
-
label: 'Measurements',
|
|
3535
|
-
secondaryLabel: 'Measurements',
|
|
4108
|
+
label: i18next/* default */.A.t('SidePanel:Measurements'),
|
|
4109
|
+
secondaryLabel: i18next/* default */.A.t('SidePanel:Measurements'),
|
|
3536
4110
|
component: wrappedMeasurementPanel
|
|
3537
4111
|
}];
|
|
3538
4112
|
}
|
|
3539
4113
|
/* harmony default export */ const src_getPanelModule = (getPanelModule);
|
|
3540
4114
|
// EXTERNAL MODULE: ../../core/src/utils/isImage.js
|
|
3541
|
-
var isImage = __webpack_require__(
|
|
4115
|
+
var isImage = __webpack_require__(8094);
|
|
3542
4116
|
// EXTERNAL MODULE: ../../core/src/utils/sopClassDictionary.js
|
|
3543
|
-
var sopClassDictionary = __webpack_require__(
|
|
4117
|
+
var sopClassDictionary = __webpack_require__(48085);
|
|
3544
4118
|
// EXTERNAL MODULE: ../../core/src/classes/ImageSet.ts
|
|
3545
|
-
var ImageSet = __webpack_require__(
|
|
4119
|
+
var ImageSet = __webpack_require__(14169);
|
|
3546
4120
|
// EXTERNAL MODULE: ../../core/src/utils/isDisplaySetReconstructable.js
|
|
3547
|
-
var isDisplaySetReconstructable = __webpack_require__(
|
|
4121
|
+
var isDisplaySetReconstructable = __webpack_require__(13835);
|
|
3548
4122
|
;// CONCATENATED MODULE: ../../../extensions/default/package.json
|
|
3549
|
-
const package_namespaceObject = JSON.parse('{"
|
|
4123
|
+
const package_namespaceObject = /*#__PURE__*/JSON.parse('{"UU":"@ohif/extension-default"}');
|
|
3550
4124
|
;// CONCATENATED MODULE: ../../../extensions/default/src/id.js
|
|
3551
4125
|
|
|
3552
|
-
const id = package_namespaceObject.
|
|
4126
|
+
const id = package_namespaceObject.UU;
|
|
3553
4127
|
|
|
3554
4128
|
// EXTERNAL MODULE: ../../core/src/utils/sortInstancesByPosition.ts
|
|
3555
|
-
var sortInstancesByPosition = __webpack_require__(
|
|
4129
|
+
var sortInstancesByPosition = __webpack_require__(44563);
|
|
3556
4130
|
;// CONCATENATED MODULE: ../../../extensions/default/src/utils/validations/checkMultiframe.ts
|
|
3557
4131
|
|
|
3558
4132
|
|
|
@@ -3563,18 +4137,18 @@ var sortInstancesByPosition = __webpack_require__(87425);
|
|
|
3563
4137
|
* @param {*} warnings
|
|
3564
4138
|
*/
|
|
3565
4139
|
function checkMultiFrame(multiFrameInstance, messages) {
|
|
3566
|
-
if (!(0,isDisplaySetReconstructable/* hasPixelMeasurements */.
|
|
3567
|
-
messages.addMessage(src/* DisplaySetMessage */.
|
|
4140
|
+
if (!(0,isDisplaySetReconstructable/* hasPixelMeasurements */.Yt)(multiFrameInstance)) {
|
|
4141
|
+
messages.addMessage(src/* DisplaySetMessage */.Ob.CODES.MULTIFRAME_NO_PIXEL_MEASUREMENTS);
|
|
3568
4142
|
}
|
|
3569
|
-
if (!(0,isDisplaySetReconstructable/* hasOrientation */.
|
|
3570
|
-
messages.addMessage(src/* DisplaySetMessage */.
|
|
4143
|
+
if (!(0,isDisplaySetReconstructable/* hasOrientation */.VX)(multiFrameInstance)) {
|
|
4144
|
+
messages.addMessage(src/* DisplaySetMessage */.Ob.CODES.MULTIFRAME_NO_ORIENTATION);
|
|
3571
4145
|
}
|
|
3572
|
-
if (!(0,isDisplaySetReconstructable/* hasPosition */.
|
|
3573
|
-
messages.addMessage(src/* DisplaySetMessage */.
|
|
4146
|
+
if (!(0,isDisplaySetReconstructable/* hasPosition */.sL)(multiFrameInstance)) {
|
|
4147
|
+
messages.addMessage(src/* DisplaySetMessage */.Ob.CODES.MULTIFRAME_NO_POSITION_INFORMATION);
|
|
3574
4148
|
}
|
|
3575
4149
|
}
|
|
3576
4150
|
// EXTERNAL MODULE: ../../core/src/utils/toNumber.js
|
|
3577
|
-
var toNumber = __webpack_require__(
|
|
4151
|
+
var toNumber = __webpack_require__(58099);
|
|
3578
4152
|
;// CONCATENATED MODULE: ../../../extensions/default/src/utils/validations/areAllImageDimensionsEqual.ts
|
|
3579
4153
|
|
|
3580
4154
|
|
|
@@ -3588,8 +4162,8 @@ function areAllImageDimensionsEqual(instances) {
|
|
|
3588
4162
|
return false;
|
|
3589
4163
|
}
|
|
3590
4164
|
const firstImage = instances[0];
|
|
3591
|
-
const firstImageRows = (0,toNumber/* default */.
|
|
3592
|
-
const firstImageColumns = (0,toNumber/* default */.
|
|
4165
|
+
const firstImageRows = (0,toNumber/* default */.A)(firstImage.Rows);
|
|
4166
|
+
const firstImageColumns = (0,toNumber/* default */.A)(firstImage.Columns);
|
|
3593
4167
|
for (let i = 1; i < instances.length; i++) {
|
|
3594
4168
|
const instance = instances[i];
|
|
3595
4169
|
const {
|
|
@@ -3615,7 +4189,7 @@ function areAllImageComponentsEqual(instances) {
|
|
|
3615
4189
|
return false;
|
|
3616
4190
|
}
|
|
3617
4191
|
const firstImage = instances[0];
|
|
3618
|
-
const firstImageSamplesPerPixel = (0,toNumber/* default */.
|
|
4192
|
+
const firstImageSamplesPerPixel = (0,toNumber/* default */.A)(firstImage.SamplesPerPixel);
|
|
3619
4193
|
for (let i = 1; i < instances.length; i++) {
|
|
3620
4194
|
const instance = instances[i];
|
|
3621
4195
|
const {
|
|
@@ -3641,18 +4215,18 @@ function areAllImageOrientationsEqual(instances) {
|
|
|
3641
4215
|
return false;
|
|
3642
4216
|
}
|
|
3643
4217
|
const firstImage = instances[0];
|
|
3644
|
-
const firstImageOrientationPatient = (0,toNumber/* default */.
|
|
4218
|
+
const firstImageOrientationPatient = (0,toNumber/* default */.A)(firstImage.ImageOrientationPatient);
|
|
3645
4219
|
for (let i = 1; i < instances.length; i++) {
|
|
3646
4220
|
const instance = instances[i];
|
|
3647
|
-
const imageOrientationPatient = (0,toNumber/* default */.
|
|
3648
|
-
if (!(0,isDisplaySetReconstructable/* _isSameOrientation */.
|
|
4221
|
+
const imageOrientationPatient = (0,toNumber/* default */.A)(instance.ImageOrientationPatient);
|
|
4222
|
+
if (!(0,isDisplaySetReconstructable/* _isSameOrientation */.sW)(imageOrientationPatient, firstImageOrientationPatient)) {
|
|
3649
4223
|
return false;
|
|
3650
4224
|
}
|
|
3651
4225
|
}
|
|
3652
4226
|
return true;
|
|
3653
4227
|
}
|
|
3654
|
-
// EXTERNAL MODULE: ../../../node_modules/gl-matrix/esm/index.js +
|
|
3655
|
-
var esm = __webpack_require__(
|
|
4228
|
+
// EXTERNAL MODULE: ../../../node_modules/gl-matrix/esm/index.js + 1 modules
|
|
4229
|
+
var esm = __webpack_require__(44753);
|
|
3656
4230
|
;// CONCATENATED MODULE: ../../../extensions/default/src/utils/calculateScanAxisNormal.ts
|
|
3657
4231
|
|
|
3658
4232
|
|
|
@@ -3662,9 +4236,9 @@ var esm = __webpack_require__(45451);
|
|
|
3662
4236
|
* @returns
|
|
3663
4237
|
*/
|
|
3664
4238
|
function calculateScanAxisNormal(imageOrientation) {
|
|
3665
|
-
const rowCosineVec = esm/* vec3.fromValues */.
|
|
3666
|
-
const colCosineVec = esm/* vec3.fromValues */.
|
|
3667
|
-
return esm/* vec3.cross */.
|
|
4239
|
+
const rowCosineVec = esm/* vec3.fromValues */.eR.fromValues(imageOrientation[0], imageOrientation[1], imageOrientation[2]);
|
|
4240
|
+
const colCosineVec = esm/* vec3.fromValues */.eR.fromValues(imageOrientation[3], imageOrientation[4], imageOrientation[5]);
|
|
4241
|
+
return esm/* vec3.cross */.eR.cross(esm/* vec3.create */.eR.create(), rowCosineVec, colCosineVec);
|
|
3668
4242
|
}
|
|
3669
4243
|
;// CONCATENATED MODULE: ../../../extensions/default/src/utils/validations/areAllImagePositionsEqual.ts
|
|
3670
4244
|
|
|
@@ -3683,8 +4257,8 @@ function calculateScanAxisNormal(imageOrientation) {
|
|
|
3683
4257
|
function _checkSeriesPositionShift(previousPosition, actualPosition, scanAxisNormal, averageSpacingBetweenFrames) {
|
|
3684
4258
|
// predicted position should be the previous position added by the multiplication
|
|
3685
4259
|
// of the scanAxisNormal and the average spacing between frames
|
|
3686
|
-
const predictedPosition = esm/* vec3.scaleAndAdd */.
|
|
3687
|
-
return esm/* vec3.distance */.
|
|
4260
|
+
const predictedPosition = esm/* vec3.scaleAndAdd */.eR.scaleAndAdd(esm/* vec3.create */.eR.create(), previousPosition, scanAxisNormal, averageSpacingBetweenFrames);
|
|
4261
|
+
return esm/* vec3.distance */.eR.distance(actualPosition, predictedPosition) > averageSpacingBetweenFrames;
|
|
3688
4262
|
}
|
|
3689
4263
|
|
|
3690
4264
|
/**
|
|
@@ -3696,18 +4270,18 @@ function areAllImagePositionsEqual(instances) {
|
|
|
3696
4270
|
if (!instances?.length) {
|
|
3697
4271
|
return false;
|
|
3698
4272
|
}
|
|
3699
|
-
const firstImageOrientationPatient = (0,toNumber/* default */.
|
|
4273
|
+
const firstImageOrientationPatient = (0,toNumber/* default */.A)(instances[0].ImageOrientationPatient);
|
|
3700
4274
|
if (!firstImageOrientationPatient) {
|
|
3701
4275
|
return false;
|
|
3702
4276
|
}
|
|
3703
4277
|
const scanAxisNormal = calculateScanAxisNormal(firstImageOrientationPatient);
|
|
3704
|
-
const firstImagePositionPatient = (0,toNumber/* default */.
|
|
3705
|
-
const lastIpp = (0,toNumber/* default */.
|
|
3706
|
-
const averageSpacingBetweenFrames = (0,isDisplaySetReconstructable/* _getPerpendicularDistance */.
|
|
4278
|
+
const firstImagePositionPatient = (0,toNumber/* default */.A)(instances[0].ImagePositionPatient);
|
|
4279
|
+
const lastIpp = (0,toNumber/* default */.A)(instances[instances.length - 1].ImagePositionPatient);
|
|
4280
|
+
const averageSpacingBetweenFrames = (0,isDisplaySetReconstructable/* _getPerpendicularDistance */.jj)(firstImagePositionPatient, lastIpp) / (instances.length - 1);
|
|
3707
4281
|
let previousImagePositionPatient = firstImagePositionPatient;
|
|
3708
4282
|
for (let i = 1; i < instances.length; i++) {
|
|
3709
4283
|
const instance = instances[i];
|
|
3710
|
-
const imagePositionPatient = (0,toNumber/* default */.
|
|
4284
|
+
const imagePositionPatient = (0,toNumber/* default */.A)(instance.ImagePositionPatient);
|
|
3711
4285
|
if (_checkSeriesPositionShift(previousImagePositionPatient, imagePositionPatient, scanAxisNormal, averageSpacingBetweenFrames)) {
|
|
3712
4286
|
return false;
|
|
3713
4287
|
}
|
|
@@ -3728,29 +4302,29 @@ function areAllImageSpacingEqual(instances, messages) {
|
|
|
3728
4302
|
if (!instances?.length) {
|
|
3729
4303
|
return;
|
|
3730
4304
|
}
|
|
3731
|
-
const firstImagePositionPatient = (0,toNumber/* default */.
|
|
4305
|
+
const firstImagePositionPatient = (0,toNumber/* default */.A)(instances[0].ImagePositionPatient);
|
|
3732
4306
|
if (!firstImagePositionPatient) {
|
|
3733
4307
|
return;
|
|
3734
4308
|
}
|
|
3735
|
-
const lastIpp = (0,toNumber/* default */.
|
|
3736
|
-
const averageSpacingBetweenFrames = (0,isDisplaySetReconstructable/* _getPerpendicularDistance */.
|
|
4309
|
+
const lastIpp = (0,toNumber/* default */.A)(instances[instances.length - 1].ImagePositionPatient);
|
|
4310
|
+
const averageSpacingBetweenFrames = (0,isDisplaySetReconstructable/* _getPerpendicularDistance */.jj)(firstImagePositionPatient, lastIpp) / (instances.length - 1);
|
|
3737
4311
|
let previousImagePositionPatient = firstImagePositionPatient;
|
|
3738
4312
|
const issuesFound = [];
|
|
3739
4313
|
for (let i = 1; i < instances.length; i++) {
|
|
3740
4314
|
const instance = instances[i];
|
|
3741
|
-
const imagePositionPatient = (0,toNumber/* default */.
|
|
3742
|
-
const spacingBetweenFrames = (0,isDisplaySetReconstructable/* _getPerpendicularDistance */.
|
|
3743
|
-
const spacingIssue = (0,isDisplaySetReconstructable/* _getSpacingIssue */.
|
|
4315
|
+
const imagePositionPatient = (0,toNumber/* default */.A)(instance.ImagePositionPatient);
|
|
4316
|
+
const spacingBetweenFrames = (0,isDisplaySetReconstructable/* _getPerpendicularDistance */.jj)(imagePositionPatient, previousImagePositionPatient);
|
|
4317
|
+
const spacingIssue = (0,isDisplaySetReconstructable/* _getSpacingIssue */.Op)(spacingBetweenFrames, averageSpacingBetweenFrames);
|
|
3744
4318
|
if (spacingIssue) {
|
|
3745
4319
|
const issue = spacingIssue.issue;
|
|
3746
4320
|
|
|
3747
4321
|
// avoid multiple warning of the same thing
|
|
3748
4322
|
if (!issuesFound.includes(issue)) {
|
|
3749
4323
|
issuesFound.push(issue);
|
|
3750
|
-
if (issue === isDisplaySetReconstructable/* reconstructionIssues */.
|
|
3751
|
-
messages.addMessage(src/* DisplaySetMessage */.
|
|
3752
|
-
} else if (issue === isDisplaySetReconstructable/* reconstructionIssues */.
|
|
3753
|
-
messages.addMessage(src/* DisplaySetMessage */.
|
|
4324
|
+
if (issue === isDisplaySetReconstructable/* reconstructionIssues */.JG.MISSING_FRAMES) {
|
|
4325
|
+
messages.addMessage(src/* DisplaySetMessage */.Ob.CODES.MISSING_FRAMES);
|
|
4326
|
+
} else if (issue === isDisplaySetReconstructable/* reconstructionIssues */.JG.IRREGULAR_SPACING) {
|
|
4327
|
+
messages.addMessage(src/* DisplaySetMessage */.Ob.CODES.IRREGULAR_SPACING);
|
|
3754
4328
|
}
|
|
3755
4329
|
}
|
|
3756
4330
|
// we just want to find issues not how many
|
|
@@ -3777,16 +4351,16 @@ function areAllImageSpacingEqual(instances, messages) {
|
|
|
3777
4351
|
function checkSingleFrames(instances, messages) {
|
|
3778
4352
|
if (instances.length > 2) {
|
|
3779
4353
|
if (!areAllImageDimensionsEqual(instances)) {
|
|
3780
|
-
messages.addMessage(src/* DisplaySetMessage */.
|
|
4354
|
+
messages.addMessage(src/* DisplaySetMessage */.Ob.CODES.INCONSISTENT_DIMENSIONS);
|
|
3781
4355
|
}
|
|
3782
4356
|
if (!areAllImageComponentsEqual(instances)) {
|
|
3783
|
-
messages.addMessage(src/* DisplaySetMessage */.
|
|
4357
|
+
messages.addMessage(src/* DisplaySetMessage */.Ob.CODES.INCONSISTENT_COMPONENTS);
|
|
3784
4358
|
}
|
|
3785
4359
|
if (!areAllImageOrientationsEqual(instances)) {
|
|
3786
|
-
messages.addMessage(src/* DisplaySetMessage */.
|
|
4360
|
+
messages.addMessage(src/* DisplaySetMessage */.Ob.CODES.INCONSISTENT_ORIENTATIONS);
|
|
3787
4361
|
}
|
|
3788
4362
|
if (!areAllImagePositionsEqual(instances)) {
|
|
3789
|
-
messages.addMessage(src/* DisplaySetMessage */.
|
|
4363
|
+
messages.addMessage(src/* DisplaySetMessage */.Ob.CODES.INCONSISTENT_POSITION_INFORMATION);
|
|
3790
4364
|
}
|
|
3791
4365
|
areAllImageSpacingEqual(instances, messages);
|
|
3792
4366
|
}
|
|
@@ -3802,10 +4376,13 @@ function checkSingleFrames(instances, messages) {
|
|
|
3802
4376
|
*
|
|
3803
4377
|
* @param {Object[]} instances An array of `OHIFInstanceMetadata` objects.
|
|
3804
4378
|
*/
|
|
3805
|
-
function getDisplaySetMessages(instances, isReconstructable) {
|
|
3806
|
-
const messages = new src/* DisplaySetMessageList */.
|
|
4379
|
+
function getDisplaySetMessages(instances, isReconstructable, isDynamicVolume) {
|
|
4380
|
+
const messages = new src/* DisplaySetMessageList */.WZ();
|
|
4381
|
+
if (isDynamicVolume) {
|
|
4382
|
+
return messages;
|
|
4383
|
+
}
|
|
3807
4384
|
if (!instances.length) {
|
|
3808
|
-
messages.addMessage(src/* DisplaySetMessage */.
|
|
4385
|
+
messages.addMessage(src/* DisplaySetMessage */.Ob.CODES.NO_VALID_INSTANCES);
|
|
3809
4386
|
return;
|
|
3810
4387
|
}
|
|
3811
4388
|
const firstInstance = instances[0];
|
|
@@ -3818,18 +4395,18 @@ function getDisplaySetMessages(instances, isReconstructable) {
|
|
|
3818
4395
|
if (ImageType?.includes('LOCALIZER')) {
|
|
3819
4396
|
return messages;
|
|
3820
4397
|
}
|
|
3821
|
-
if (!isDisplaySetReconstructable/* constructableModalities */.
|
|
4398
|
+
if (!isDisplaySetReconstructable/* constructableModalities */.Hf.includes(Modality)) {
|
|
3822
4399
|
return messages;
|
|
3823
4400
|
}
|
|
3824
4401
|
const isMultiframe = NumberOfFrames > 1;
|
|
3825
4402
|
// Can't reconstruct if all instances don't have the ImagePositionPatient.
|
|
3826
4403
|
if (!isMultiframe && !instances.every(instance => instance.ImagePositionPatient)) {
|
|
3827
|
-
messages.addMessage(src/* DisplaySetMessage */.
|
|
4404
|
+
messages.addMessage(src/* DisplaySetMessage */.Ob.CODES.NO_POSITION_INFORMATION);
|
|
3828
4405
|
}
|
|
3829
|
-
const sortedInstances = (0,sortInstancesByPosition/* default */.
|
|
4406
|
+
const sortedInstances = (0,sortInstancesByPosition/* default */.A)(instances);
|
|
3830
4407
|
isMultiframe ? checkMultiFrame(sortedInstances[0], messages) : checkSingleFrames(sortedInstances, messages);
|
|
3831
4408
|
if (!isReconstructable) {
|
|
3832
|
-
messages.addMessage(src/* DisplaySetMessage */.
|
|
4409
|
+
messages.addMessage(src/* DisplaySetMessage */.Ob.CODES.NOT_RECONSTRUCTABLE);
|
|
3833
4410
|
}
|
|
3834
4411
|
return messages;
|
|
3835
4412
|
}
|
|
@@ -3840,9 +4417,9 @@ function getDisplaySetMessages(instances, isReconstructable) {
|
|
|
3840
4417
|
* Default handler for a instance list with an unsupported sopClassUID
|
|
3841
4418
|
*/
|
|
3842
4419
|
function getDisplaySetsFromUnsupportedSeries(instances) {
|
|
3843
|
-
const imageSet = new ImageSet/* default */.
|
|
3844
|
-
const messages = new src/* DisplaySetMessageList */.
|
|
3845
|
-
messages.addMessage(src/* DisplaySetMessage */.
|
|
4420
|
+
const imageSet = new ImageSet/* default */.A(instances);
|
|
4421
|
+
const messages = new src/* DisplaySetMessageList */.WZ();
|
|
4422
|
+
messages.addMessage(src/* DisplaySetMessage */.Ob.CODES.UNSUPPORTED_DISPLAYSET);
|
|
3846
4423
|
const instance = instances[0];
|
|
3847
4424
|
imageSet.setAttributes({
|
|
3848
4425
|
displaySetInstanceUID: imageSet.uid,
|
|
@@ -3864,6 +4441,85 @@ function getDisplaySetsFromUnsupportedSeries(instances) {
|
|
|
3864
4441
|
});
|
|
3865
4442
|
return [imageSet];
|
|
3866
4443
|
}
|
|
4444
|
+
;// CONCATENATED MODULE: ../../../extensions/default/src/SOPClassHandlers/chartSOPClassHandler.ts
|
|
4445
|
+
|
|
4446
|
+
|
|
4447
|
+
const SOPClassHandlerName = 'chart';
|
|
4448
|
+
const CHART_MODALITY = 'CHT';
|
|
4449
|
+
|
|
4450
|
+
// Private SOPClassUid for chart data
|
|
4451
|
+
const ChartDataSOPClassUid = '1.9.451.13215.7.3.2.7.6.1';
|
|
4452
|
+
const sopClassUids = [ChartDataSOPClassUid];
|
|
4453
|
+
const makeChartDataDisplaySet = (instance, sopClassUids) => {
|
|
4454
|
+
const {
|
|
4455
|
+
StudyInstanceUID,
|
|
4456
|
+
SeriesInstanceUID,
|
|
4457
|
+
SOPInstanceUID,
|
|
4458
|
+
SeriesDescription,
|
|
4459
|
+
SeriesNumber,
|
|
4460
|
+
SeriesDate,
|
|
4461
|
+
SOPClassUID
|
|
4462
|
+
} = instance;
|
|
4463
|
+
return {
|
|
4464
|
+
Modality: CHART_MODALITY,
|
|
4465
|
+
loading: false,
|
|
4466
|
+
isReconstructable: false,
|
|
4467
|
+
displaySetInstanceUID: src.utils.guid(),
|
|
4468
|
+
SeriesDescription,
|
|
4469
|
+
SeriesNumber,
|
|
4470
|
+
SeriesDate,
|
|
4471
|
+
SOPInstanceUID,
|
|
4472
|
+
SeriesInstanceUID,
|
|
4473
|
+
StudyInstanceUID,
|
|
4474
|
+
SOPClassHandlerId: `${id}.sopClassHandlerModule.${SOPClassHandlerName}`,
|
|
4475
|
+
SOPClassUID,
|
|
4476
|
+
isDerivedDisplaySet: true,
|
|
4477
|
+
isLoaded: true,
|
|
4478
|
+
sopClassUids,
|
|
4479
|
+
instance,
|
|
4480
|
+
instances: [instance],
|
|
4481
|
+
/**
|
|
4482
|
+
* Adds instances to the chart displaySet, rather than creating a new one
|
|
4483
|
+
* when user moves to a different workflow step and gets back to a step that
|
|
4484
|
+
* recreates the chart
|
|
4485
|
+
*/
|
|
4486
|
+
addInstances: function (instances, _displaySetService) {
|
|
4487
|
+
this.instances.push(...instances);
|
|
4488
|
+
this.instance = this.instances[this.instances.length - 1];
|
|
4489
|
+
return this;
|
|
4490
|
+
}
|
|
4491
|
+
};
|
|
4492
|
+
};
|
|
4493
|
+
function getSopClassUids(instances) {
|
|
4494
|
+
const uniqueSopClassUidsInSeries = new Set();
|
|
4495
|
+
instances.forEach(instance => {
|
|
4496
|
+
uniqueSopClassUidsInSeries.add(instance.SOPClassUID);
|
|
4497
|
+
});
|
|
4498
|
+
const sopClassUids = Array.from(uniqueSopClassUidsInSeries);
|
|
4499
|
+
return sopClassUids;
|
|
4500
|
+
}
|
|
4501
|
+
function _getDisplaySetsFromSeries(instances) {
|
|
4502
|
+
// If the series has no instances, stop here
|
|
4503
|
+
if (!instances || !instances.length) {
|
|
4504
|
+
throw new Error('No instances were provided');
|
|
4505
|
+
}
|
|
4506
|
+
const sopClassUids = getSopClassUids(instances);
|
|
4507
|
+
const displaySets = instances.map(instance => {
|
|
4508
|
+
if (instance.Modality === CHART_MODALITY) {
|
|
4509
|
+
return makeChartDataDisplaySet(instance, sopClassUids);
|
|
4510
|
+
}
|
|
4511
|
+
throw new Error('Unsupported modality');
|
|
4512
|
+
});
|
|
4513
|
+
return displaySets;
|
|
4514
|
+
}
|
|
4515
|
+
const chartHandler = {
|
|
4516
|
+
name: SOPClassHandlerName,
|
|
4517
|
+
sopClassUids,
|
|
4518
|
+
getDisplaySetsFromSeries: instances => {
|
|
4519
|
+
return _getDisplaySetsFromSeries(instances);
|
|
4520
|
+
}
|
|
4521
|
+
};
|
|
4522
|
+
|
|
3867
4523
|
;// CONCATENATED MODULE: ../../../extensions/default/src/getSopClassHandlerModule.js
|
|
3868
4524
|
|
|
3869
4525
|
|
|
@@ -3872,20 +4528,69 @@ function getDisplaySetsFromUnsupportedSeries(instances) {
|
|
|
3872
4528
|
|
|
3873
4529
|
|
|
3874
4530
|
|
|
4531
|
+
|
|
4532
|
+
const DEFAULT_VOLUME_LOADER_SCHEME = 'cornerstoneStreamingImageVolume';
|
|
4533
|
+
const DYNAMIC_VOLUME_LOADER_SCHEME = 'cornerstoneStreamingDynamicImageVolume';
|
|
3875
4534
|
const sopClassHandlerName = 'stack';
|
|
4535
|
+
let appContext = {};
|
|
4536
|
+
const getDynamicVolumeInfo = instances => {
|
|
4537
|
+
const {
|
|
4538
|
+
extensionManager
|
|
4539
|
+
} = appContext;
|
|
4540
|
+
if (!extensionManager) {
|
|
4541
|
+
throw new Error('extensionManager is not available');
|
|
4542
|
+
}
|
|
4543
|
+
const imageIds = instances.map(({
|
|
4544
|
+
imageId
|
|
4545
|
+
}) => imageId);
|
|
4546
|
+
const volumeLoaderUtility = extensionManager.getModuleEntry('@ohif/extension-cornerstone.utilityModule.volumeLoader');
|
|
4547
|
+
const {
|
|
4548
|
+
getDynamicVolumeInfo: csGetDynamicVolumeInfo
|
|
4549
|
+
} = volumeLoaderUtility.exports;
|
|
4550
|
+
return csGetDynamicVolumeInfo(imageIds);
|
|
4551
|
+
};
|
|
3876
4552
|
const isMultiFrame = instance => {
|
|
3877
4553
|
return instance.NumberOfFrames > 1;
|
|
3878
4554
|
};
|
|
4555
|
+
function getDisplaySetInfo(instances) {
|
|
4556
|
+
const dynamicVolumeInfo = getDynamicVolumeInfo(instances);
|
|
4557
|
+
const {
|
|
4558
|
+
isDynamicVolume,
|
|
4559
|
+
timePoints
|
|
4560
|
+
} = dynamicVolumeInfo;
|
|
4561
|
+
let displaySetInfo;
|
|
4562
|
+
if (isDynamicVolume) {
|
|
4563
|
+
const timePoint = timePoints[0];
|
|
4564
|
+
const instancesMap = new Map();
|
|
4565
|
+
|
|
4566
|
+
// O(n) to convert it into a map and O(1) to find each instance
|
|
4567
|
+
instances.forEach(instance => instancesMap.set(instance.imageId, instance));
|
|
4568
|
+
const firstTimePointInstances = timePoint.map(imageId => instancesMap.get(imageId));
|
|
4569
|
+
displaySetInfo = (0,isDisplaySetReconstructable/* default */.Ay)(firstTimePointInstances);
|
|
4570
|
+
} else {
|
|
4571
|
+
displaySetInfo = (0,isDisplaySetReconstructable/* default */.Ay)(instances);
|
|
4572
|
+
}
|
|
4573
|
+
return {
|
|
4574
|
+
isDynamicVolume,
|
|
4575
|
+
...displaySetInfo,
|
|
4576
|
+
dynamicVolumeInfo
|
|
4577
|
+
};
|
|
4578
|
+
}
|
|
3879
4579
|
const makeDisplaySet = instances => {
|
|
3880
4580
|
const instance = instances[0];
|
|
3881
|
-
const imageSet = new ImageSet/* default */.
|
|
4581
|
+
const imageSet = new ImageSet/* default */.A(instances);
|
|
3882
4582
|
const {
|
|
4583
|
+
isDynamicVolume,
|
|
3883
4584
|
value: isReconstructable,
|
|
3884
|
-
averageSpacingBetweenFrames
|
|
3885
|
-
|
|
4585
|
+
averageSpacingBetweenFrames,
|
|
4586
|
+
dynamicVolumeInfo
|
|
4587
|
+
} = getDisplaySetInfo(instances);
|
|
4588
|
+
const volumeLoaderSchema = isDynamicVolume ? DYNAMIC_VOLUME_LOADER_SCHEME : DEFAULT_VOLUME_LOADER_SCHEME;
|
|
4589
|
+
|
|
3886
4590
|
// set appropriate attributes to image set...
|
|
3887
|
-
const messages = getDisplaySetMessages(instances, isReconstructable);
|
|
4591
|
+
const messages = getDisplaySetMessages(instances, isReconstructable, isDynamicVolume);
|
|
3888
4592
|
imageSet.setAttributes({
|
|
4593
|
+
volumeLoaderSchema,
|
|
3889
4594
|
displaySetInstanceUID: imageSet.uid,
|
|
3890
4595
|
// create a local alias for the imageSet UID
|
|
3891
4596
|
SeriesDate: instance.SeriesDate,
|
|
@@ -3903,7 +4608,9 @@ const makeDisplaySet = instances => {
|
|
|
3903
4608
|
SOPClassHandlerId: `${id}.sopClassHandlerModule.${sopClassHandlerName}`,
|
|
3904
4609
|
isReconstructable,
|
|
3905
4610
|
messages,
|
|
3906
|
-
averageSpacingBetweenFrames: averageSpacingBetweenFrames || null
|
|
4611
|
+
averageSpacingBetweenFrames: averageSpacingBetweenFrames || null,
|
|
4612
|
+
isDynamicVolume,
|
|
4613
|
+
dynamicVolumeInfo
|
|
3907
4614
|
});
|
|
3908
4615
|
|
|
3909
4616
|
// Sort the images in this series if needed
|
|
@@ -3934,7 +4641,7 @@ const makeDisplaySet = instances => {
|
|
|
3934
4641
|
const isSingleImageModality = modality => {
|
|
3935
4642
|
return modality === 'CR' || modality === 'MG' || modality === 'DX';
|
|
3936
4643
|
};
|
|
3937
|
-
function
|
|
4644
|
+
function getSopClassHandlerModule_getSopClassUids(instances) {
|
|
3938
4645
|
const uniqueSopClassUidsInSeries = new Set();
|
|
3939
4646
|
instances.forEach(instance => {
|
|
3940
4647
|
uniqueSopClassUidsInSeries.add(instance.SOPClassUID);
|
|
@@ -3948,7 +4655,6 @@ function getSopClassUids(instances) {
|
|
|
3948
4655
|
* - For all Image types that are stackable, create
|
|
3949
4656
|
* a displaySet with a stack of images
|
|
3950
4657
|
*
|
|
3951
|
-
* @param {Array} sopClassHandlerModules List of SOP Class Modules
|
|
3952
4658
|
* @param {SeriesMetadata} series The series metadata object from which the display sets will be created
|
|
3953
4659
|
* @returns {Array} The list of display sets created for the given series object
|
|
3954
4660
|
*/
|
|
@@ -3958,7 +4664,7 @@ function getDisplaySetsFromSeries(instances) {
|
|
|
3958
4664
|
throw new Error('No instances were provided');
|
|
3959
4665
|
}
|
|
3960
4666
|
const displaySets = [];
|
|
3961
|
-
const sopClassUids =
|
|
4667
|
+
const sopClassUids = getSopClassHandlerModule_getSopClassUids(instances);
|
|
3962
4668
|
|
|
3963
4669
|
// Search through the instances (InstanceMetadata object) of this series
|
|
3964
4670
|
// Split Multi-frame instances and Single-image modalities
|
|
@@ -3967,7 +4673,7 @@ function getDisplaySetsFromSeries(instances) {
|
|
|
3967
4673
|
const stackableInstances = [];
|
|
3968
4674
|
instances.forEach(instance => {
|
|
3969
4675
|
// All imaging modalities must have a valid value for sopClassUid (x00080016) or rows (x00280010)
|
|
3970
|
-
if (!(0,isImage/* isImage */.
|
|
4676
|
+
if (!(0,isImage/* isImage */.w)(instance.SOPClassUID) && !instance.Rows) {
|
|
3971
4677
|
return;
|
|
3972
4678
|
}
|
|
3973
4679
|
let displaySet;
|
|
@@ -4003,16 +4709,21 @@ function getDisplaySetsFromSeries(instances) {
|
|
|
4003
4709
|
}
|
|
4004
4710
|
return displaySets;
|
|
4005
4711
|
}
|
|
4006
|
-
const
|
|
4007
|
-
function getSopClassHandlerModule() {
|
|
4712
|
+
const getSopClassHandlerModule_sopClassUids = [sopClassDictionary/* default */.A.ComputedRadiographyImageStorage, sopClassDictionary/* default */.A.DigitalXRayImageStorageForPresentation, sopClassDictionary/* default */.A.DigitalXRayImageStorageForProcessing, sopClassDictionary/* default */.A.DigitalMammographyXRayImageStorageForPresentation, sopClassDictionary/* default */.A.DigitalMammographyXRayImageStorageForProcessing, sopClassDictionary/* default */.A.DigitalIntraOralXRayImageStorageForPresentation, sopClassDictionary/* default */.A.DigitalIntraOralXRayImageStorageForProcessing, sopClassDictionary/* default */.A.CTImageStorage, sopClassDictionary/* default */.A.EnhancedCTImageStorage, sopClassDictionary/* default */.A.LegacyConvertedEnhancedCTImageStorage, sopClassDictionary/* default */.A.UltrasoundMultiframeImageStorage, sopClassDictionary/* default */.A.MRImageStorage, sopClassDictionary/* default */.A.EnhancedMRImageStorage, sopClassDictionary/* default */.A.EnhancedMRColorImageStorage, sopClassDictionary/* default */.A.LegacyConvertedEnhancedMRImageStorage, sopClassDictionary/* default */.A.UltrasoundImageStorage, sopClassDictionary/* default */.A.UltrasoundImageStorageRET, sopClassDictionary/* default */.A.SecondaryCaptureImageStorage, sopClassDictionary/* default */.A.MultiframeSingleBitSecondaryCaptureImageStorage, sopClassDictionary/* default */.A.MultiframeGrayscaleByteSecondaryCaptureImageStorage, sopClassDictionary/* default */.A.MultiframeGrayscaleWordSecondaryCaptureImageStorage, sopClassDictionary/* default */.A.MultiframeTrueColorSecondaryCaptureImageStorage, sopClassDictionary/* default */.A.XRayAngiographicImageStorage, sopClassDictionary/* default */.A.EnhancedXAImageStorage, sopClassDictionary/* default */.A.XRayRadiofluoroscopicImageStorage, sopClassDictionary/* default */.A.EnhancedXRFImageStorage, sopClassDictionary/* default */.A.XRay3DAngiographicImageStorage, sopClassDictionary/* default */.A.XRay3DCraniofacialImageStorage, sopClassDictionary/* default */.A.BreastTomosynthesisImageStorage, sopClassDictionary/* default */.A.BreastProjectionXRayImageStorageForPresentation, sopClassDictionary/* default */.A.BreastProjectionXRayImageStorageForProcessing, sopClassDictionary/* default */.A.IntravascularOpticalCoherenceTomographyImageStorageForPresentation, sopClassDictionary/* default */.A.IntravascularOpticalCoherenceTomographyImageStorageForProcessing, sopClassDictionary/* default */.A.NuclearMedicineImageStorage, sopClassDictionary/* default */.A.VLEndoscopicImageStorage, sopClassDictionary/* default */.A.VideoEndoscopicImageStorage, sopClassDictionary/* default */.A.VLMicroscopicImageStorage, sopClassDictionary/* default */.A.VideoMicroscopicImageStorage, sopClassDictionary/* default */.A.VLSlideCoordinatesMicroscopicImageStorage, sopClassDictionary/* default */.A.VLPhotographicImageStorage, sopClassDictionary/* default */.A.VideoPhotographicImageStorage, sopClassDictionary/* default */.A.OphthalmicPhotography8BitImageStorage, sopClassDictionary/* default */.A.OphthalmicPhotography16BitImageStorage, sopClassDictionary/* default */.A.OphthalmicTomographyImageStorage, sopClassDictionary/* default */.A.VLWholeSlideMicroscopyImageStorage, sopClassDictionary/* default */.A.PositronEmissionTomographyImageStorage, sopClassDictionary/* default */.A.EnhancedPETImageStorage, sopClassDictionary/* default */.A.LegacyConvertedEnhancedPETImageStorage, sopClassDictionary/* default */.A.RTImageStorage, sopClassDictionary/* default */.A.EnhancedUSVolumeStorage];
|
|
4713
|
+
function getSopClassHandlerModule(appContextParam) {
|
|
4714
|
+
appContext = appContextParam;
|
|
4008
4715
|
return [{
|
|
4009
4716
|
name: sopClassHandlerName,
|
|
4010
|
-
sopClassUids,
|
|
4717
|
+
sopClassUids: getSopClassHandlerModule_sopClassUids,
|
|
4011
4718
|
getDisplaySetsFromSeries
|
|
4012
4719
|
}, {
|
|
4013
4720
|
name: 'not-supported-display-sets-handler',
|
|
4014
4721
|
sopClassUids: [],
|
|
4015
4722
|
getDisplaySetsFromSeries: getDisplaySetsFromUnsupportedSeries
|
|
4723
|
+
}, {
|
|
4724
|
+
name: chartHandler.name,
|
|
4725
|
+
sopClassUids: chartHandler.sopClassUids,
|
|
4726
|
+
getDisplaySetsFromSeries: chartHandler.getDisplaySetsFromSeries
|
|
4016
4727
|
}];
|
|
4017
4728
|
}
|
|
4018
4729
|
/* harmony default export */ const src_getSopClassHandlerModule = (getSopClassHandlerModule);
|
|
@@ -4029,39 +4740,121 @@ function ToolbarLayoutSelector_extends() { ToolbarLayoutSelector_extends = Objec
|
|
|
4029
4740
|
|
|
4030
4741
|
|
|
4031
4742
|
|
|
4032
|
-
|
|
4033
|
-
|
|
4034
|
-
|
|
4035
|
-
|
|
4036
|
-
|
|
4743
|
+
const defaultCommonPresets = [{
|
|
4744
|
+
icon: 'layout-common-1x1',
|
|
4745
|
+
commandOptions: {
|
|
4746
|
+
numRows: 1,
|
|
4747
|
+
numCols: 1
|
|
4748
|
+
}
|
|
4749
|
+
}, {
|
|
4750
|
+
icon: 'layout-common-1x2',
|
|
4751
|
+
commandOptions: {
|
|
4752
|
+
numRows: 1,
|
|
4753
|
+
numCols: 2
|
|
4754
|
+
}
|
|
4755
|
+
}, {
|
|
4756
|
+
icon: 'layout-common-2x2',
|
|
4757
|
+
commandOptions: {
|
|
4758
|
+
numRows: 2,
|
|
4759
|
+
numCols: 2
|
|
4760
|
+
}
|
|
4761
|
+
}, {
|
|
4762
|
+
icon: 'layout-common-2x3',
|
|
4763
|
+
commandOptions: {
|
|
4764
|
+
numRows: 2,
|
|
4765
|
+
numCols: 3
|
|
4766
|
+
}
|
|
4767
|
+
}];
|
|
4768
|
+
const _areSelectorsValid = (hp, displaySets, hangingProtocolService) => {
|
|
4769
|
+
if (!hp.displaySetSelectors || Object.values(hp.displaySetSelectors).length === 0) {
|
|
4770
|
+
return true;
|
|
4771
|
+
}
|
|
4772
|
+
return hangingProtocolService.areRequiredSelectorsValid(Object.values(hp.displaySetSelectors), displaySets[0]);
|
|
4773
|
+
};
|
|
4774
|
+
const generateAdvancedPresets = ({
|
|
4775
|
+
servicesManager
|
|
4776
|
+
}) => {
|
|
4037
4777
|
const {
|
|
4038
|
-
|
|
4778
|
+
hangingProtocolService,
|
|
4779
|
+
viewportGridService,
|
|
4780
|
+
displaySetService
|
|
4039
4781
|
} = servicesManager.services;
|
|
4782
|
+
const hangingProtocols = Array.from(hangingProtocolService.protocols.values());
|
|
4783
|
+
const viewportId = viewportGridService.getActiveViewportId();
|
|
4784
|
+
if (!viewportId) {
|
|
4785
|
+
return [];
|
|
4786
|
+
}
|
|
4787
|
+
const displaySetInsaneUIDs = viewportGridService.getDisplaySetsUIDsForViewport(viewportId);
|
|
4788
|
+
const displaySets = displaySetInsaneUIDs.map(uid => displaySetService.getDisplaySetByUID(uid));
|
|
4789
|
+
return hangingProtocols.map(hp => {
|
|
4790
|
+
if (!hp.isPreset) {
|
|
4791
|
+
return null;
|
|
4792
|
+
}
|
|
4793
|
+
const areValid = _areSelectorsValid(hp, displaySets, hangingProtocolService);
|
|
4794
|
+
return {
|
|
4795
|
+
icon: hp.icon,
|
|
4796
|
+
title: hp.name,
|
|
4797
|
+
commandOptions: {
|
|
4798
|
+
protocolId: hp.id
|
|
4799
|
+
},
|
|
4800
|
+
disabled: !areValid
|
|
4801
|
+
};
|
|
4802
|
+
}).filter(preset => preset !== null);
|
|
4803
|
+
};
|
|
4804
|
+
function ToolbarLayoutSelectorWithServices({
|
|
4805
|
+
commandsManager,
|
|
4806
|
+
servicesManager,
|
|
4807
|
+
...props
|
|
4808
|
+
}) {
|
|
4809
|
+
const [isDisabled, setIsDisabled] = (0,react.useState)(false);
|
|
4810
|
+
const handleMouseEnter = () => {
|
|
4811
|
+
setIsDisabled(false);
|
|
4812
|
+
};
|
|
4040
4813
|
const onSelection = (0,react.useCallback)(props => {
|
|
4041
|
-
|
|
4042
|
-
|
|
4043
|
-
|
|
4044
|
-
|
|
4045
|
-
|
|
4046
|
-
...props
|
|
4047
|
-
},
|
|
4048
|
-
context: 'DEFAULT'
|
|
4049
|
-
}]
|
|
4814
|
+
commandsManager.run({
|
|
4815
|
+
commandName: 'setViewportGridLayout',
|
|
4816
|
+
commandOptions: {
|
|
4817
|
+
...props
|
|
4818
|
+
}
|
|
4050
4819
|
});
|
|
4051
|
-
|
|
4052
|
-
|
|
4053
|
-
|
|
4054
|
-
|
|
4820
|
+
setIsDisabled(true);
|
|
4821
|
+
}, []);
|
|
4822
|
+
const onSelectionPreset = (0,react.useCallback)(props => {
|
|
4823
|
+
commandsManager.run({
|
|
4824
|
+
commandName: 'setHangingProtocol',
|
|
4825
|
+
commandOptions: {
|
|
4826
|
+
...props
|
|
4827
|
+
}
|
|
4828
|
+
});
|
|
4829
|
+
setIsDisabled(true);
|
|
4830
|
+
}, []);
|
|
4831
|
+
return /*#__PURE__*/react.createElement("div", {
|
|
4832
|
+
onMouseEnter: handleMouseEnter
|
|
4833
|
+
}, /*#__PURE__*/react.createElement(LayoutSelector, ToolbarLayoutSelector_extends({}, props, {
|
|
4834
|
+
onSelection: onSelection,
|
|
4835
|
+
onSelectionPreset: onSelectionPreset,
|
|
4836
|
+
servicesManager: servicesManager,
|
|
4837
|
+
tooltipDisabled: isDisabled
|
|
4838
|
+
})));
|
|
4055
4839
|
}
|
|
4056
|
-
function LayoutSelector(
|
|
4057
|
-
|
|
4058
|
-
|
|
4059
|
-
|
|
4060
|
-
|
|
4061
|
-
|
|
4062
|
-
|
|
4063
|
-
|
|
4840
|
+
function LayoutSelector({
|
|
4841
|
+
rows,
|
|
4842
|
+
columns,
|
|
4843
|
+
className,
|
|
4844
|
+
onSelection,
|
|
4845
|
+
onSelectionPreset,
|
|
4846
|
+
servicesManager,
|
|
4847
|
+
tooltipDisabled,
|
|
4848
|
+
...rest
|
|
4849
|
+
}) {
|
|
4064
4850
|
const [isOpen, setIsOpen] = (0,react.useState)(false);
|
|
4851
|
+
const {
|
|
4852
|
+
customizationService
|
|
4853
|
+
} = servicesManager.services;
|
|
4854
|
+
const commonPresets = customizationService.get('commonPresets') || defaultCommonPresets;
|
|
4855
|
+
const advancedPresets = customizationService.get('advancedPresets') || generateAdvancedPresets({
|
|
4856
|
+
servicesManager
|
|
4857
|
+
});
|
|
4065
4858
|
const closeOnOutsideClick = () => {
|
|
4066
4859
|
if (isOpen) {
|
|
4067
4860
|
setIsOpen(false);
|
|
@@ -4073,20 +4866,57 @@ function LayoutSelector(_ref2) {
|
|
|
4073
4866
|
window.removeEventListener('click', closeOnOutsideClick);
|
|
4074
4867
|
};
|
|
4075
4868
|
}, [isOpen]);
|
|
4076
|
-
const onInteractionHandler = () =>
|
|
4077
|
-
|
|
4078
|
-
|
|
4869
|
+
const onInteractionHandler = () => {
|
|
4870
|
+
setIsOpen(!isOpen);
|
|
4871
|
+
};
|
|
4872
|
+
const DropdownContent = isOpen ? ui_src/* LayoutSelector */.sG : null;
|
|
4873
|
+
return /*#__PURE__*/react.createElement(ui_src/* ToolbarButton */.IB, {
|
|
4079
4874
|
id: "Layout",
|
|
4080
|
-
label: "
|
|
4875
|
+
label: "Layout",
|
|
4081
4876
|
icon: "tool-layout",
|
|
4082
4877
|
onInteraction: onInteractionHandler,
|
|
4083
4878
|
className: className,
|
|
4084
4879
|
rounded: rest.rounded,
|
|
4085
|
-
|
|
4880
|
+
disableToolTip: tooltipDisabled,
|
|
4881
|
+
dropdownContent: DropdownContent !== null && /*#__PURE__*/react.createElement("div", {
|
|
4882
|
+
className: "flex "
|
|
4883
|
+
}, /*#__PURE__*/react.createElement("div", {
|
|
4884
|
+
className: "bg-secondary-dark flex flex-col gap-2.5 p-2"
|
|
4885
|
+
}, /*#__PURE__*/react.createElement("div", {
|
|
4886
|
+
className: "text-aqua-pale text-xs"
|
|
4887
|
+
}, "Common"), /*#__PURE__*/react.createElement("div", {
|
|
4888
|
+
className: "flex gap-4"
|
|
4889
|
+
}, commonPresets.map((preset, index) => /*#__PURE__*/react.createElement(ui_src/* LayoutPreset */.qu, {
|
|
4890
|
+
key: index,
|
|
4891
|
+
classNames: "hover:bg-primary-dark group p-1 cursor-pointer",
|
|
4892
|
+
icon: preset.icon,
|
|
4893
|
+
commandOptions: preset.commandOptions,
|
|
4894
|
+
onSelection: onSelection
|
|
4895
|
+
}))), /*#__PURE__*/react.createElement("div", {
|
|
4896
|
+
className: "h-[2px] bg-black"
|
|
4897
|
+
}), /*#__PURE__*/react.createElement("div", {
|
|
4898
|
+
className: "text-aqua-pale text-xs"
|
|
4899
|
+
}, "Advanced"), /*#__PURE__*/react.createElement("div", {
|
|
4900
|
+
className: "flex flex-col gap-2.5"
|
|
4901
|
+
}, advancedPresets.map((preset, index) => /*#__PURE__*/react.createElement(ui_src/* LayoutPreset */.qu, {
|
|
4902
|
+
key: index + commonPresets.length,
|
|
4903
|
+
classNames: "hover:bg-primary-dark group flex gap-2 p-1 cursor-pointer",
|
|
4904
|
+
icon: preset.icon,
|
|
4905
|
+
title: preset.title,
|
|
4906
|
+
disabled: preset.disabled,
|
|
4907
|
+
commandOptions: preset.commandOptions,
|
|
4908
|
+
onSelection: onSelectionPreset
|
|
4909
|
+
})))), /*#__PURE__*/react.createElement("div", {
|
|
4910
|
+
className: "bg-primary-dark flex flex-col gap-2.5 border-l-2 border-solid border-black p-2"
|
|
4911
|
+
}, /*#__PURE__*/react.createElement("div", {
|
|
4912
|
+
className: "text-aqua-pale text-xs"
|
|
4913
|
+
}, "Custom"), /*#__PURE__*/react.createElement(DropdownContent, {
|
|
4086
4914
|
rows: rows,
|
|
4087
4915
|
columns: columns,
|
|
4088
4916
|
onSelection: onSelection
|
|
4089
|
-
}),
|
|
4917
|
+
}), /*#__PURE__*/react.createElement("p", {
|
|
4918
|
+
className: "text-aqua-pale text-xs leading-tight"
|
|
4919
|
+
}, "Hover to select ", /*#__PURE__*/react.createElement("br", null), "rows and columns ", /*#__PURE__*/react.createElement("br", null), " Click to apply"))),
|
|
4090
4920
|
isActive: isOpen,
|
|
4091
4921
|
type: "toggle"
|
|
4092
4922
|
});
|
|
@@ -4095,11 +4925,11 @@ LayoutSelector.propTypes = {
|
|
|
4095
4925
|
rows: (prop_types_default()).number,
|
|
4096
4926
|
columns: (prop_types_default()).number,
|
|
4097
4927
|
onLayoutChange: (prop_types_default()).func,
|
|
4098
|
-
servicesManager: prop_types_default().instanceOf(src/* ServicesManager */.
|
|
4928
|
+
servicesManager: prop_types_default().instanceOf(src/* ServicesManager */.CS)
|
|
4099
4929
|
};
|
|
4100
4930
|
LayoutSelector.defaultProps = {
|
|
4931
|
+
columns: 4,
|
|
4101
4932
|
rows: 3,
|
|
4102
|
-
columns: 3,
|
|
4103
4933
|
onLayoutChange: () => {}
|
|
4104
4934
|
};
|
|
4105
4935
|
/* harmony default export */ const ToolbarLayoutSelector = (ToolbarLayoutSelectorWithServices);
|
|
@@ -4108,122 +4938,39 @@ function ToolbarSplitButtonWithServices_extends() { ToolbarSplitButtonWithServic
|
|
|
4108
4938
|
|
|
4109
4939
|
|
|
4110
4940
|
|
|
4111
|
-
|
|
4112
|
-
|
|
4113
|
-
|
|
4114
|
-
|
|
4115
|
-
|
|
4116
|
-
|
|
4117
|
-
|
|
4118
|
-
|
|
4119
|
-
|
|
4120
|
-
renderer,
|
|
4121
|
-
onInteraction,
|
|
4122
|
-
servicesManager
|
|
4123
|
-
} = _ref;
|
|
4941
|
+
function ToolbarSplitButtonWithServices({
|
|
4942
|
+
groupId,
|
|
4943
|
+
primary,
|
|
4944
|
+
secondary,
|
|
4945
|
+
items,
|
|
4946
|
+
renderer,
|
|
4947
|
+
onInteraction,
|
|
4948
|
+
servicesManager
|
|
4949
|
+
}) {
|
|
4124
4950
|
const {
|
|
4125
4951
|
toolbarService
|
|
4126
4952
|
} = servicesManager?.services;
|
|
4127
|
-
const handleItemClick = (item, index) => {
|
|
4128
|
-
const {
|
|
4129
|
-
id,
|
|
4130
|
-
type,
|
|
4131
|
-
commands
|
|
4132
|
-
} = item;
|
|
4133
|
-
onInteraction({
|
|
4134
|
-
groupId,
|
|
4135
|
-
itemId: id,
|
|
4136
|
-
interactionType: type,
|
|
4137
|
-
commands
|
|
4138
|
-
});
|
|
4139
|
-
setState(state => ({
|
|
4140
|
-
...state,
|
|
4141
|
-
primary: !isAction && isRadio ? {
|
|
4142
|
-
...item,
|
|
4143
|
-
index
|
|
4144
|
-
} : state.primary,
|
|
4145
|
-
isExpanded: false,
|
|
4146
|
-
items: getSplitButtonItems(items).filter(item => isRadio && !isAction ? item.index !== index : true)
|
|
4147
|
-
}));
|
|
4148
|
-
};
|
|
4149
4953
|
|
|
4150
4954
|
/* Bubbles up individual item clicks */
|
|
4151
|
-
const getSplitButtonItems = items => items.map((item, index) => ({
|
|
4955
|
+
const getSplitButtonItems = (0,react.useCallback)(items => items.map((item, index) => ({
|
|
4152
4956
|
...item,
|
|
4153
4957
|
index,
|
|
4154
|
-
onClick: () =>
|
|
4155
|
-
|
|
4156
|
-
|
|
4157
|
-
|
|
4158
|
-
|
|
4159
|
-
groups: {}
|
|
4160
|
-
});
|
|
4161
|
-
const [state, setState] = (0,react.useState)({
|
|
4162
|
-
primary,
|
|
4163
|
-
items: getSplitButtonItems(items).filter(item => isRadio && !isAction ? item.id !== primary.id : true)
|
|
4164
|
-
});
|
|
4165
|
-
const {
|
|
4166
|
-
primaryToolId,
|
|
4167
|
-
toggles
|
|
4168
|
-
} = buttonsState;
|
|
4169
|
-
const isPrimaryToggle = state.primary.type === 'toggle';
|
|
4170
|
-
const isPrimaryActive = state.primary.type === 'tool' && primaryToolId === state.primary.id || isPrimaryToggle && toggles[state.primary.id] === true;
|
|
4171
|
-
const PrimaryButtonComponent = toolbarService?.getButtonComponentForUIType(state.primary.uiType) ?? ui_src/* ToolbarButton */.hA;
|
|
4172
|
-
(0,react.useEffect)(() => {
|
|
4173
|
-
const {
|
|
4174
|
-
unsubscribe
|
|
4175
|
-
} = toolbarService.subscribe(toolbarService.EVENTS.TOOL_BAR_STATE_MODIFIED, state => {
|
|
4176
|
-
setButtonState({
|
|
4177
|
-
...state
|
|
4958
|
+
onClick: () => {
|
|
4959
|
+
onInteraction({
|
|
4960
|
+
groupId,
|
|
4961
|
+
itemId: item.id,
|
|
4962
|
+
commands: item.commands
|
|
4178
4963
|
});
|
|
4179
|
-
}
|
|
4180
|
-
|
|
4181
|
-
|
|
4182
|
-
|
|
4183
|
-
|
|
4184
|
-
|
|
4185
|
-
const isActive = item.type === 'tool' && primaryToolId === item.id;
|
|
4186
|
-
|
|
4187
|
-
// We could have added the
|
|
4188
|
-
// item.type === 'toggle' && toggles[item.id] === true
|
|
4189
|
-
// too but that makes the button active when the toggle is active under it
|
|
4190
|
-
// which feels weird
|
|
4191
|
-
return {
|
|
4192
|
-
...item,
|
|
4193
|
-
isActive
|
|
4194
|
-
};
|
|
4195
|
-
});
|
|
4196
|
-
const DefaultListItemRenderer = _ref2 => {
|
|
4197
|
-
let {
|
|
4198
|
-
type,
|
|
4199
|
-
icon,
|
|
4200
|
-
label,
|
|
4201
|
-
t,
|
|
4202
|
-
id
|
|
4203
|
-
} = _ref2;
|
|
4204
|
-
const isActive = type === 'toggle' && toggles[id] === true;
|
|
4205
|
-
return /*#__PURE__*/react.createElement("div", {
|
|
4206
|
-
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')
|
|
4207
|
-
}, icon && /*#__PURE__*/react.createElement("span", {
|
|
4208
|
-
className: "mr-4"
|
|
4209
|
-
}, /*#__PURE__*/react.createElement(ui_src/* Icon */.JO, {
|
|
4210
|
-
name: icon,
|
|
4211
|
-
className: "h-5 w-5"
|
|
4212
|
-
})), /*#__PURE__*/react.createElement("span", {
|
|
4213
|
-
className: "mr-5"
|
|
4214
|
-
}, t(label)));
|
|
4215
|
-
};
|
|
4216
|
-
const listItemRenderer = renderer || DefaultListItemRenderer;
|
|
4217
|
-
return /*#__PURE__*/react.createElement(ui_src/* SplitButton */.aW, {
|
|
4218
|
-
isRadio: isRadio,
|
|
4219
|
-
isAction: isAction,
|
|
4220
|
-
primary: state.primary,
|
|
4964
|
+
}
|
|
4965
|
+
})), []);
|
|
4966
|
+
const PrimaryButtonComponent = toolbarService?.getButtonComponentForUIType(primary.uiType) ?? ui_src/* ToolbarButton */.IB;
|
|
4967
|
+
const listItemRenderer = renderer;
|
|
4968
|
+
return /*#__PURE__*/react.createElement(ui_src/* SplitButton */.fk, {
|
|
4969
|
+
primary: primary,
|
|
4221
4970
|
secondary: secondary,
|
|
4222
|
-
items:
|
|
4971
|
+
items: getSplitButtonItems(items),
|
|
4223
4972
|
groupId: groupId,
|
|
4224
4973
|
renderer: listItemRenderer,
|
|
4225
|
-
isActive: isPrimaryActive || updatedItems.some(item => item.isActive),
|
|
4226
|
-
isToggle: isPrimaryToggle,
|
|
4227
4974
|
onInteraction: onInteraction,
|
|
4228
4975
|
Component: props => /*#__PURE__*/react.createElement(PrimaryButtonComponent, ToolbarSplitButtonWithServices_extends({}, props, {
|
|
4229
4976
|
servicesManager: servicesManager
|
|
@@ -4232,11 +4979,9 @@ function ToolbarSplitButtonWithServices(_ref) {
|
|
|
4232
4979
|
}
|
|
4233
4980
|
ToolbarSplitButtonWithServices.propTypes = {
|
|
4234
4981
|
isRadio: (prop_types_default()).bool,
|
|
4235
|
-
isAction: (prop_types_default()).bool,
|
|
4236
4982
|
groupId: (prop_types_default()).string,
|
|
4237
4983
|
primary: prop_types_default().shape({
|
|
4238
4984
|
id: (prop_types_default()).string.isRequired,
|
|
4239
|
-
type: prop_types_default().oneOf(['tool', 'action', 'toggle']).isRequired,
|
|
4240
4985
|
uiType: (prop_types_default()).string
|
|
4241
4986
|
}),
|
|
4242
4987
|
secondary: prop_types_default().shape({
|
|
@@ -4244,14 +4989,16 @@ ToolbarSplitButtonWithServices.propTypes = {
|
|
|
4244
4989
|
icon: (prop_types_default()).string.isRequired,
|
|
4245
4990
|
label: (prop_types_default()).string,
|
|
4246
4991
|
tooltip: (prop_types_default()).string.isRequired,
|
|
4247
|
-
|
|
4992
|
+
disabled: (prop_types_default()).bool,
|
|
4993
|
+
className: (prop_types_default()).string
|
|
4248
4994
|
}),
|
|
4249
4995
|
items: prop_types_default().arrayOf(prop_types_default().shape({
|
|
4250
4996
|
id: (prop_types_default()).string.isRequired,
|
|
4251
|
-
type: prop_types_default().oneOf(['tool', 'action', 'toggle']).isRequired,
|
|
4252
4997
|
icon: (prop_types_default()).string,
|
|
4253
4998
|
label: (prop_types_default()).string,
|
|
4254
|
-
tooltip: (prop_types_default()).string
|
|
4999
|
+
tooltip: (prop_types_default()).string,
|
|
5000
|
+
disabled: (prop_types_default()).bool,
|
|
5001
|
+
className: (prop_types_default()).string
|
|
4255
5002
|
})),
|
|
4256
5003
|
renderer: (prop_types_default()).func,
|
|
4257
5004
|
onInteraction: (prop_types_default()).func.isRequired,
|
|
@@ -4266,108 +5013,194 @@ ToolbarSplitButtonWithServices.defaultProps = {
|
|
|
4266
5013
|
isAction: false
|
|
4267
5014
|
};
|
|
4268
5015
|
/* harmony default export */ const Toolbar_ToolbarSplitButtonWithServices = (ToolbarSplitButtonWithServices);
|
|
4269
|
-
;// CONCATENATED MODULE: ../../../extensions/default/src/Toolbar/
|
|
4270
|
-
|
|
4271
|
-
|
|
4272
|
-
|
|
4273
|
-
|
|
4274
|
-
|
|
4275
|
-
|
|
4276
|
-
|
|
4277
|
-
|
|
4278
|
-
|
|
4279
|
-
|
|
4280
|
-
|
|
4281
|
-
|
|
4282
|
-
|
|
4283
|
-
|
|
4284
|
-
|
|
4285
|
-
|
|
4286
|
-
|
|
4287
|
-
|
|
4288
|
-
|
|
4289
|
-
|
|
4290
|
-
|
|
5016
|
+
;// CONCATENATED MODULE: ../../../extensions/default/src/Toolbar/ToolbarButtonGroupWithServices.tsx
|
|
5017
|
+
|
|
5018
|
+
|
|
5019
|
+
function ToolbarButtonGroupWithServices({
|
|
5020
|
+
groupId,
|
|
5021
|
+
items,
|
|
5022
|
+
onInteraction,
|
|
5023
|
+
size
|
|
5024
|
+
}) {
|
|
5025
|
+
const getSplitButtonItems = (0,react.useCallback)(items => items.map((item, index) => /*#__PURE__*/react.createElement(ui_src/* ToolbarButton */.IB, {
|
|
5026
|
+
key: item.id,
|
|
5027
|
+
icon: item.icon,
|
|
5028
|
+
label: item.label,
|
|
5029
|
+
disabled: item.disabled,
|
|
5030
|
+
className: item.className,
|
|
5031
|
+
id: item.id,
|
|
5032
|
+
size: size,
|
|
5033
|
+
onClick: () => {
|
|
5034
|
+
onInteraction({
|
|
5035
|
+
groupId,
|
|
5036
|
+
itemId: item.id,
|
|
5037
|
+
commands: item.commands
|
|
5038
|
+
});
|
|
5039
|
+
}
|
|
5040
|
+
// Note: this is necessary since tooltip will add
|
|
5041
|
+
// default styles to the tooltip container which
|
|
5042
|
+
// we don't want for groups
|
|
5043
|
+
,
|
|
5044
|
+
toolTipClassName: ""
|
|
5045
|
+
})), [onInteraction, groupId]);
|
|
5046
|
+
return /*#__PURE__*/react.createElement(ui_src/* ButtonGroup */.e2, null, getSplitButtonItems(items));
|
|
5047
|
+
}
|
|
5048
|
+
/* harmony default export */ const Toolbar_ToolbarButtonGroupWithServices = (ToolbarButtonGroupWithServices);
|
|
5049
|
+
;// CONCATENATED MODULE: ../../../extensions/default/src/components/ProgressDropdownWithService/ProgressDropdownWithService.tsx
|
|
5050
|
+
|
|
5051
|
+
|
|
5052
|
+
const workflowStepsToDropdownOptions = (steps = []) => steps.map(step => ({
|
|
5053
|
+
label: step.name,
|
|
5054
|
+
value: step.id,
|
|
5055
|
+
info: step.info,
|
|
5056
|
+
activated: false,
|
|
5057
|
+
completed: false
|
|
5058
|
+
}));
|
|
5059
|
+
function ProgressDropdownWithService({
|
|
5060
|
+
servicesManager
|
|
5061
|
+
}) {
|
|
4291
5062
|
const {
|
|
4292
|
-
|
|
4293
|
-
} =
|
|
4294
|
-
const
|
|
5063
|
+
workflowStepsService
|
|
5064
|
+
} = servicesManager.services;
|
|
5065
|
+
const [activeStepId, setActiveStepId] = (0,react.useState)(workflowStepsService.activeWorkflowStep?.id);
|
|
5066
|
+
const [dropdownOptions, setDropdownOptions] = (0,react.useState)(workflowStepsToDropdownOptions(workflowStepsService.workflowSteps));
|
|
5067
|
+
const setCurrentAndPreviousOptionsAsCompleted = (0,react.useCallback)(currentOption => {
|
|
5068
|
+
if (currentOption.completed) {
|
|
5069
|
+
return;
|
|
5070
|
+
}
|
|
5071
|
+
setDropdownOptions(prevOptions => {
|
|
5072
|
+
const newOptionsState = [...prevOptions];
|
|
5073
|
+
const startIndex = newOptionsState.findIndex(option => option.value === currentOption.value);
|
|
5074
|
+
for (let i = startIndex; i >= 0; i--) {
|
|
5075
|
+
const option = newOptionsState[i];
|
|
5076
|
+
if (option.completed) {
|
|
5077
|
+
break;
|
|
5078
|
+
}
|
|
5079
|
+
newOptionsState[i] = {
|
|
5080
|
+
...option,
|
|
5081
|
+
completed: true
|
|
5082
|
+
};
|
|
5083
|
+
}
|
|
5084
|
+
return newOptionsState;
|
|
5085
|
+
});
|
|
5086
|
+
}, []);
|
|
5087
|
+
const handleDropdownChange = (0,react.useCallback)(({
|
|
5088
|
+
selectedOption
|
|
5089
|
+
}) => {
|
|
5090
|
+
if (!selectedOption) {
|
|
5091
|
+
return;
|
|
5092
|
+
}
|
|
5093
|
+
|
|
5094
|
+
// TODO: Steps should be marked as completed after user has
|
|
5095
|
+
// completed some action when required (not implemented)
|
|
5096
|
+
setCurrentAndPreviousOptionsAsCompleted(selectedOption);
|
|
5097
|
+
setActiveStepId(selectedOption.value);
|
|
5098
|
+
}, [setCurrentAndPreviousOptionsAsCompleted]);
|
|
5099
|
+
(0,react.useEffect)(() => {
|
|
5100
|
+
let timeoutId;
|
|
5101
|
+
if (activeStepId) {
|
|
5102
|
+
// We've used setTimeout to give it more time to update the UI since
|
|
5103
|
+
// create3DFilterableFromDataArray from Texture.js may take 600+ ms to run
|
|
5104
|
+
// when there is a new series to load in the next step but that resulted
|
|
5105
|
+
// in the followed React error when updating the content from left/right panels
|
|
5106
|
+
// and all component states were being lost:
|
|
5107
|
+
// Error: Can't perform a React state update on an unmounted component
|
|
5108
|
+
workflowStepsService.setActiveWorkflowStep(activeStepId);
|
|
5109
|
+
}
|
|
5110
|
+
return () => clearTimeout(timeoutId);
|
|
5111
|
+
}, [activeStepId, workflowStepsService]);
|
|
4295
5112
|
(0,react.useEffect)(() => {
|
|
4296
5113
|
const {
|
|
4297
|
-
unsubscribe
|
|
4298
|
-
} =
|
|
4299
|
-
|
|
4300
|
-
|
|
4301
|
-
|
|
4302
|
-
});
|
|
5114
|
+
unsubscribe: unsubStepsChanged
|
|
5115
|
+
} = workflowStepsService.subscribe(workflowStepsService.EVENTS.STEPS_CHANGED, () => setDropdownOptions(workflowStepsToDropdownOptions(workflowStepsService.workflowSteps)));
|
|
5116
|
+
const {
|
|
5117
|
+
unsubscribe: unsubActiveStepChanged
|
|
5118
|
+
} = workflowStepsService.subscribe(workflowStepsService.EVENTS.ACTIVE_STEP_CHANGED, () => setActiveStepId(workflowStepsService.activeWorkflowStep.id));
|
|
4303
5119
|
return () => {
|
|
4304
|
-
|
|
5120
|
+
unsubStepsChanged();
|
|
5121
|
+
unsubActiveStepChanged();
|
|
4305
5122
|
};
|
|
4306
|
-
}, [
|
|
4307
|
-
return /*#__PURE__*/react.createElement(ui_src/*
|
|
4308
|
-
|
|
4309
|
-
|
|
4310
|
-
|
|
4311
|
-
|
|
4312
|
-
onInteraction: onInteraction
|
|
4313
|
-
}, props));
|
|
5123
|
+
}, [servicesManager, workflowStepsService]);
|
|
5124
|
+
return /*#__PURE__*/react.createElement(ui_src/* ProgressDropdown */.LW, {
|
|
5125
|
+
options: dropdownOptions,
|
|
5126
|
+
value: activeStepId,
|
|
5127
|
+
onChange: handleDropdownChange
|
|
5128
|
+
});
|
|
4314
5129
|
}
|
|
4315
|
-
|
|
4316
|
-
|
|
4317
|
-
|
|
4318
|
-
commands: prop_types_default().arrayOf(prop_types_default().shape({
|
|
4319
|
-
commandName: (prop_types_default()).string.isRequired,
|
|
4320
|
-
context: (prop_types_default()).string
|
|
4321
|
-
})),
|
|
4322
|
-
onInteraction: (prop_types_default()).func.isRequired,
|
|
4323
|
-
servicesManager: prop_types_default().shape({
|
|
4324
|
-
services: prop_types_default().shape({
|
|
4325
|
-
toolbarService: prop_types_default().shape({
|
|
4326
|
-
subscribe: (prop_types_default()).func.isRequired,
|
|
4327
|
-
state: prop_types_default().shape({
|
|
4328
|
-
primaryToolId: (prop_types_default()).string,
|
|
4329
|
-
toggles: prop_types_default().objectOf((prop_types_default()).bool),
|
|
4330
|
-
groups: prop_types_default().objectOf((prop_types_default()).any)
|
|
4331
|
-
}).isRequired
|
|
4332
|
-
}).isRequired
|
|
4333
|
-
}).isRequired
|
|
4334
|
-
}).isRequired
|
|
4335
|
-
};
|
|
4336
|
-
/* harmony default export */ const Toolbar_ToolbarButtonWithServices = (ToolbarButtonWithServices);
|
|
5130
|
+
/* harmony default export */ const ProgressDropdownWithService_ProgressDropdownWithService = (ProgressDropdownWithService);
|
|
5131
|
+
;// CONCATENATED MODULE: ../../../extensions/default/src/components/ProgressDropdownWithService/index.js
|
|
5132
|
+
|
|
4337
5133
|
;// CONCATENATED MODULE: ../../../extensions/default/src/getToolbarModule.tsx
|
|
4338
5134
|
|
|
4339
5135
|
|
|
4340
5136
|
|
|
4341
5137
|
|
|
4342
|
-
|
|
4343
|
-
|
|
4344
|
-
|
|
4345
|
-
|
|
4346
|
-
|
|
5138
|
+
|
|
5139
|
+
|
|
5140
|
+
const getClassName = isToggled => {
|
|
5141
|
+
return {
|
|
5142
|
+
className: isToggled ? '!text-primary-active' : '!text-common-bright hover:!bg-primary-dark hover:text-primary-light'
|
|
5143
|
+
};
|
|
5144
|
+
};
|
|
5145
|
+
function getToolbarModule({
|
|
5146
|
+
commandsManager,
|
|
5147
|
+
servicesManager
|
|
5148
|
+
}) {
|
|
5149
|
+
const {
|
|
5150
|
+
cineService
|
|
5151
|
+
} = servicesManager.services;
|
|
4347
5152
|
return [{
|
|
4348
|
-
name: 'ohif.divider',
|
|
4349
|
-
defaultComponent: ToolbarDivider,
|
|
4350
|
-
clickHandler: () => {}
|
|
4351
|
-
}, {
|
|
4352
|
-
name: 'ohif.action',
|
|
4353
|
-
defaultComponent: Toolbar_ToolbarButtonWithServices,
|
|
4354
|
-
clickHandler: () => {}
|
|
4355
|
-
}, {
|
|
4356
5153
|
name: 'ohif.radioGroup',
|
|
4357
|
-
defaultComponent:
|
|
4358
|
-
|
|
5154
|
+
defaultComponent: ui_src/* ToolbarButton */.IB
|
|
5155
|
+
}, {
|
|
5156
|
+
name: 'ohif.divider',
|
|
5157
|
+
defaultComponent: ToolbarDivider
|
|
4359
5158
|
}, {
|
|
4360
5159
|
name: 'ohif.splitButton',
|
|
4361
|
-
defaultComponent: Toolbar_ToolbarSplitButtonWithServices
|
|
4362
|
-
clickHandler: () => {}
|
|
5160
|
+
defaultComponent: Toolbar_ToolbarSplitButtonWithServices
|
|
4363
5161
|
}, {
|
|
4364
5162
|
name: 'ohif.layoutSelector',
|
|
4365
|
-
defaultComponent: ToolbarLayoutSelector
|
|
4366
|
-
|
|
5163
|
+
defaultComponent: props => ToolbarLayoutSelector({
|
|
5164
|
+
...props,
|
|
5165
|
+
commandsManager,
|
|
5166
|
+
servicesManager
|
|
5167
|
+
})
|
|
5168
|
+
}, {
|
|
5169
|
+
name: 'ohif.buttonGroup',
|
|
5170
|
+
defaultComponent: Toolbar_ToolbarButtonGroupWithServices
|
|
5171
|
+
}, {
|
|
5172
|
+
name: 'ohif.progressDropdown',
|
|
5173
|
+
defaultComponent: ProgressDropdownWithService_ProgressDropdownWithService
|
|
4367
5174
|
}, {
|
|
4368
|
-
name: '
|
|
4369
|
-
|
|
4370
|
-
|
|
5175
|
+
name: 'evaluate.group.promoteToPrimary',
|
|
5176
|
+
evaluate: ({
|
|
5177
|
+
viewportId,
|
|
5178
|
+
button,
|
|
5179
|
+
itemId
|
|
5180
|
+
}) => {
|
|
5181
|
+
const {
|
|
5182
|
+
items
|
|
5183
|
+
} = button.props;
|
|
5184
|
+
if (!itemId) {
|
|
5185
|
+
return {
|
|
5186
|
+
primary: button.props.primary,
|
|
5187
|
+
items
|
|
5188
|
+
};
|
|
5189
|
+
}
|
|
5190
|
+
|
|
5191
|
+
// other wise we can move the clicked tool to the primary button
|
|
5192
|
+
const clickedItemProps = items.find(item => item.id === itemId || item.itemId === itemId);
|
|
5193
|
+
return {
|
|
5194
|
+
primary: clickedItemProps,
|
|
5195
|
+
items
|
|
5196
|
+
};
|
|
5197
|
+
}
|
|
5198
|
+
}, {
|
|
5199
|
+
name: 'evaluate.cine',
|
|
5200
|
+
evaluate: () => {
|
|
5201
|
+
const isToggled = cineService.getState().isCineEnabled;
|
|
5202
|
+
return getClassName(isToggled);
|
|
5203
|
+
}
|
|
4371
5204
|
}];
|
|
4372
5205
|
}
|
|
4373
5206
|
;// CONCATENATED MODULE: ../../../extensions/default/src/CustomizableContextMenu/ContextMenuItemsBuilder.ts
|
|
@@ -4433,7 +5266,6 @@ function findMenu(menus, props, menuIdFilter) {
|
|
|
4433
5266
|
}
|
|
4434
5267
|
current = findIt.next();
|
|
4435
5268
|
}
|
|
4436
|
-
console.log('Menu chosen', menu?.id || 'NONE');
|
|
4437
5269
|
return menu;
|
|
4438
5270
|
}
|
|
4439
5271
|
|
|
@@ -4536,8 +5368,12 @@ function adaptItem(item, subProps) {
|
|
|
4536
5368
|
return newItem;
|
|
4537
5369
|
}
|
|
4538
5370
|
// EXTERNAL MODULE: ../../ui/src/components/ContextMenu/ContextMenu.tsx
|
|
4539
|
-
var ContextMenu = __webpack_require__(
|
|
5371
|
+
var ContextMenu = __webpack_require__(59852);
|
|
5372
|
+
// EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/index.js + 18 modules
|
|
5373
|
+
var dist_esm = __webpack_require__(24542);
|
|
4540
5374
|
;// CONCATENATED MODULE: ../../../extensions/default/src/CustomizableContextMenu/ContextMenuController.tsx
|
|
5375
|
+
var _ContextMenuController;
|
|
5376
|
+
|
|
4541
5377
|
|
|
4542
5378
|
|
|
4543
5379
|
/**
|
|
@@ -4584,7 +5420,16 @@ class ContextMenuController {
|
|
|
4584
5420
|
menus,
|
|
4585
5421
|
selectorProps
|
|
4586
5422
|
} = contextMenuProps;
|
|
4587
|
-
|
|
5423
|
+
const annotationManager = dist_esm.annotation.state.getAnnotationManager();
|
|
5424
|
+
const {
|
|
5425
|
+
locking
|
|
5426
|
+
} = dist_esm.annotation;
|
|
5427
|
+
const targetAnnotationId = selectorProps?.nearbyToolData?.annotationUID;
|
|
5428
|
+
const isLocked = locking.isAnnotationLocked(annotationManager.getAnnotation(targetAnnotationId));
|
|
5429
|
+
if (isLocked) {
|
|
5430
|
+
console.warn('Annotation is locked.');
|
|
5431
|
+
return;
|
|
5432
|
+
}
|
|
4588
5433
|
const items = getMenuItems(selectorProps || contextMenuProps, event, menus, menuId);
|
|
4589
5434
|
this.services.uiDialogService.dismiss({
|
|
4590
5435
|
id: 'context-menu'
|
|
@@ -4596,7 +5441,7 @@ class ContextMenuController {
|
|
|
4596
5441
|
preventCutOf: true,
|
|
4597
5442
|
defaultPosition: ContextMenuController._getDefaultPosition(defaultPointsPosition, event?.detail, viewportElement),
|
|
4598
5443
|
event,
|
|
4599
|
-
content: ContextMenu/* default */.
|
|
5444
|
+
content: ContextMenu/* default */.A,
|
|
4600
5445
|
// This naming is part of the uiDialogService convention
|
|
4601
5446
|
// Clicking outside simply closes the dialog box.
|
|
4602
5447
|
onClickOutside: () => this.services.uiDialogService.dismiss({
|
|
@@ -4642,6 +5487,7 @@ class ContextMenuController {
|
|
|
4642
5487
|
});
|
|
4643
5488
|
}
|
|
4644
5489
|
}
|
|
5490
|
+
_ContextMenuController = ContextMenuController;
|
|
4645
5491
|
ContextMenuController.getDefaultPosition = () => {
|
|
4646
5492
|
return {
|
|
4647
5493
|
x: 0,
|
|
@@ -4665,16 +5511,14 @@ ContextMenuController._getElementDefaultPosition = element => {
|
|
|
4665
5511
|
y: undefined
|
|
4666
5512
|
};
|
|
4667
5513
|
};
|
|
4668
|
-
ContextMenuController._getCanvasPointsPosition =
|
|
4669
|
-
|
|
4670
|
-
let element = arguments.length > 1 ? arguments[1] : undefined;
|
|
4671
|
-
const viewerPos = ContextMenuController._getElementDefaultPosition(element);
|
|
5514
|
+
ContextMenuController._getCanvasPointsPosition = (points = [], element) => {
|
|
5515
|
+
const viewerPos = _ContextMenuController._getElementDefaultPosition(element);
|
|
4672
5516
|
for (let pointIndex = 0; pointIndex < points.length; pointIndex++) {
|
|
4673
5517
|
const point = {
|
|
4674
5518
|
x: points[pointIndex][0] || points[pointIndex]['x'],
|
|
4675
5519
|
y: points[pointIndex][1] || points[pointIndex]['y']
|
|
4676
5520
|
};
|
|
4677
|
-
if (
|
|
5521
|
+
if (_ContextMenuController._isValidPosition(point) && _ContextMenuController._isValidPosition(viewerPos)) {
|
|
4678
5522
|
return {
|
|
4679
5523
|
x: point.x + viewerPos.x,
|
|
4680
5524
|
y: point.y + viewerPos.y
|
|
@@ -4690,17 +5534,17 @@ ContextMenuController._isValidPosition = source => {
|
|
|
4690
5534
|
*/
|
|
4691
5535
|
ContextMenuController._getDefaultPosition = (canvasPoints, eventDetail, viewerElement) => {
|
|
4692
5536
|
function* getPositionIterator() {
|
|
4693
|
-
yield
|
|
4694
|
-
yield
|
|
4695
|
-
yield
|
|
4696
|
-
yield
|
|
5537
|
+
yield _ContextMenuController._getCanvasPointsPosition(canvasPoints, viewerElement);
|
|
5538
|
+
yield _ContextMenuController._getEventDefaultPosition(eventDetail);
|
|
5539
|
+
yield _ContextMenuController._getElementDefaultPosition(viewerElement);
|
|
5540
|
+
yield _ContextMenuController.getDefaultPosition();
|
|
4697
5541
|
}
|
|
4698
5542
|
const positionIterator = getPositionIterator();
|
|
4699
5543
|
let current = positionIterator.next();
|
|
4700
5544
|
let position = current.value;
|
|
4701
5545
|
while (!current.done) {
|
|
4702
5546
|
position = current.value;
|
|
4703
|
-
if (
|
|
5547
|
+
if (_ContextMenuController._isValidPosition(position)) {
|
|
4704
5548
|
positionIterator.return();
|
|
4705
5549
|
}
|
|
4706
5550
|
current = positionIterator.next();
|
|
@@ -4715,16 +5559,16 @@ const defaultContextMenu = {
|
|
|
4715
5559
|
// Get the items from the UI Customization for the menu name (and have a custom name)
|
|
4716
5560
|
{
|
|
4717
5561
|
id: 'forExistingMeasurement',
|
|
4718
|
-
selector:
|
|
4719
|
-
|
|
4720
|
-
|
|
4721
|
-
} = _ref;
|
|
4722
|
-
return !!nearbyToolData;
|
|
4723
|
-
},
|
|
5562
|
+
selector: ({
|
|
5563
|
+
nearbyToolData
|
|
5564
|
+
}) => !!nearbyToolData,
|
|
4724
5565
|
items: [{
|
|
4725
5566
|
label: 'Delete measurement',
|
|
4726
5567
|
commands: [{
|
|
4727
|
-
commandName: 'deleteMeasurement'
|
|
5568
|
+
commandName: 'deleteMeasurement',
|
|
5569
|
+
// we only have support for cornerstoneTools context menu since
|
|
5570
|
+
// they are svg based
|
|
5571
|
+
context: 'CORNERSTONE'
|
|
4728
5572
|
}]
|
|
4729
5573
|
}, {
|
|
4730
5574
|
label: 'Add Label',
|
|
@@ -4745,10 +5589,13 @@ const defaultContextMenu = {
|
|
|
4745
5589
|
|
|
4746
5590
|
|
|
4747
5591
|
// EXTERNAL MODULE: ../../../node_modules/moment/moment.js
|
|
4748
|
-
var moment = __webpack_require__(
|
|
5592
|
+
var moment = __webpack_require__(8291);
|
|
4749
5593
|
var moment_default = /*#__PURE__*/__webpack_require__.n(moment);
|
|
4750
5594
|
// EXTERNAL MODULE: ../../../node_modules/react-window/dist/index.esm.js
|
|
4751
|
-
var index_esm = __webpack_require__(
|
|
5595
|
+
var index_esm = __webpack_require__(6943);
|
|
5596
|
+
// EXTERNAL MODULE: ../../../node_modules/classnames/index.js
|
|
5597
|
+
var classnames = __webpack_require__(61466);
|
|
5598
|
+
var classnames_default = /*#__PURE__*/__webpack_require__.n(classnames);
|
|
4752
5599
|
;// CONCATENATED MODULE: ../../../extensions/default/src/DicomTagBrowser/DicomTagTable.tsx
|
|
4753
5600
|
|
|
4754
5601
|
|
|
@@ -4765,13 +5612,12 @@ const rowStyle = {
|
|
|
4765
5612
|
borderBottomWidth: `${rowBottomBorderPx}px`,
|
|
4766
5613
|
...rowVerticalPaddingStyle
|
|
4767
5614
|
};
|
|
4768
|
-
function ColumnHeaders(
|
|
4769
|
-
|
|
4770
|
-
|
|
4771
|
-
|
|
4772
|
-
|
|
4773
|
-
|
|
4774
|
-
} = _ref;
|
|
5615
|
+
function ColumnHeaders({
|
|
5616
|
+
tagRef,
|
|
5617
|
+
vrRef,
|
|
5618
|
+
keywordRef,
|
|
5619
|
+
valueRef
|
|
5620
|
+
}) {
|
|
4775
5621
|
return /*#__PURE__*/react.createElement("div", {
|
|
4776
5622
|
className: classnames_default()('bg-secondary-dark ohif-scrollbar flex w-full flex-row overflow-y-scroll'),
|
|
4777
5623
|
style: rowVerticalPaddingStyle
|
|
@@ -4805,10 +5651,9 @@ function ColumnHeaders(_ref) {
|
|
|
4805
5651
|
className: "flex flex-row items-center focus:outline-none"
|
|
4806
5652
|
}, "Value"))));
|
|
4807
5653
|
}
|
|
4808
|
-
function DicomTagTable(
|
|
4809
|
-
|
|
4810
|
-
|
|
4811
|
-
} = _ref2;
|
|
5654
|
+
function DicomTagTable({
|
|
5655
|
+
rows
|
|
5656
|
+
}) {
|
|
4812
5657
|
const listRef = (0,react.useRef)();
|
|
4813
5658
|
const canvasRef = (0,react.useRef)();
|
|
4814
5659
|
const [tagHeaderElem, setTagHeaderElem] = (0,react.useState)(null);
|
|
@@ -4862,11 +5707,10 @@ function DicomTagTable(_ref2) {
|
|
|
4862
5707
|
window.removeEventListener('resize', debouncedResize);
|
|
4863
5708
|
};
|
|
4864
5709
|
}, []);
|
|
4865
|
-
const Row = (0,react.useCallback)(
|
|
4866
|
-
|
|
4867
|
-
|
|
4868
|
-
|
|
4869
|
-
} = _ref3;
|
|
5710
|
+
const Row = (0,react.useCallback)(({
|
|
5711
|
+
index,
|
|
5712
|
+
style
|
|
5713
|
+
}) => {
|
|
4870
5714
|
const row = rows[index];
|
|
4871
5715
|
return /*#__PURE__*/react.createElement("div", {
|
|
4872
5716
|
style: {
|
|
@@ -4924,7 +5768,7 @@ function DicomTagTable(_ref2) {
|
|
|
4924
5768
|
style: {
|
|
4925
5769
|
height: '32rem'
|
|
4926
5770
|
}
|
|
4927
|
-
}, isHeaderRendered() && /*#__PURE__*/react.createElement(index_esm/* VariableSizeList */.
|
|
5771
|
+
}, isHeaderRendered() && /*#__PURE__*/react.createElement(index_esm/* VariableSizeList */._m, {
|
|
4928
5772
|
ref: listRef,
|
|
4929
5773
|
height: 500,
|
|
4930
5774
|
itemCount: rows.length,
|
|
@@ -4951,15 +5795,14 @@ const {
|
|
|
4951
5795
|
} = src.classes;
|
|
4952
5796
|
const {
|
|
4953
5797
|
DicomMetaDictionary: DicomTagBrowser_DicomMetaDictionary
|
|
4954
|
-
} = dcmjs_es
|
|
5798
|
+
} = dcmjs_es/* default.data */.Ay.data;
|
|
4955
5799
|
const {
|
|
4956
5800
|
nameMap
|
|
4957
5801
|
} = DicomTagBrowser_DicomMetaDictionary;
|
|
4958
|
-
const DicomTagBrowser =
|
|
4959
|
-
|
|
4960
|
-
|
|
4961
|
-
|
|
4962
|
-
} = _ref;
|
|
5802
|
+
const DicomTagBrowser = ({
|
|
5803
|
+
displaySets,
|
|
5804
|
+
displaySetInstanceUID
|
|
5805
|
+
}) => {
|
|
4963
5806
|
// The column indices that are to be excluded during a filter of the table.
|
|
4964
5807
|
// At present the column indices are:
|
|
4965
5808
|
// 0: DICOM tag
|
|
@@ -5042,12 +5885,12 @@ const DicomTagBrowser = _ref => {
|
|
|
5042
5885
|
className: "mb-6 flex flex-row items-center pl-1"
|
|
5043
5886
|
}, /*#__PURE__*/react.createElement("div", {
|
|
5044
5887
|
className: "flex w-1/2 flex-row items-center"
|
|
5045
|
-
}, /*#__PURE__*/react.createElement(ui_src/* Typography */.
|
|
5888
|
+
}, /*#__PURE__*/react.createElement(ui_src/* Typography */.o5, {
|
|
5046
5889
|
variant: "subtitle",
|
|
5047
5890
|
className: "mr-4"
|
|
5048
5891
|
}, "Series"), /*#__PURE__*/react.createElement("div", {
|
|
5049
5892
|
className: "mr-8 grow"
|
|
5050
|
-
}, /*#__PURE__*/react.createElement(ui_src/* Select */.
|
|
5893
|
+
}, /*#__PURE__*/react.createElement(ui_src/* Select */.l6, {
|
|
5051
5894
|
id: "display-set-selector",
|
|
5052
5895
|
isClearable: false,
|
|
5053
5896
|
onChange: onSelectChange,
|
|
@@ -5056,12 +5899,12 @@ const DicomTagBrowser = _ref => {
|
|
|
5056
5899
|
className: "text-white"
|
|
5057
5900
|
}))), /*#__PURE__*/react.createElement("div", {
|
|
5058
5901
|
className: "flex w-1/2 flex-row items-center"
|
|
5059
|
-
}, showInstanceList && /*#__PURE__*/react.createElement(ui_src/* Typography */.
|
|
5902
|
+
}, showInstanceList && /*#__PURE__*/react.createElement(ui_src/* Typography */.o5, {
|
|
5060
5903
|
variant: "subtitle",
|
|
5061
5904
|
className: "mr-4"
|
|
5062
5905
|
}, "Instance Number"), showInstanceList && /*#__PURE__*/react.createElement("div", {
|
|
5063
5906
|
className: "grow"
|
|
5064
|
-
}, /*#__PURE__*/react.createElement(ui_src/* InputRange */.
|
|
5907
|
+
}, /*#__PURE__*/react.createElement(ui_src/* InputRange */.Qr, {
|
|
5065
5908
|
value: instanceNumber,
|
|
5066
5909
|
key: selectedDisplaySetInstanceUID,
|
|
5067
5910
|
onChange: value => {
|
|
@@ -5077,7 +5920,7 @@ const DicomTagBrowser = _ref => {
|
|
|
5077
5920
|
className: "h-1 w-full bg-black"
|
|
5078
5921
|
}), /*#__PURE__*/react.createElement("div", {
|
|
5079
5922
|
className: "my-3 flex w-1/2 flex-row"
|
|
5080
|
-
}, /*#__PURE__*/react.createElement(ui_src/* InputFilterText */.
|
|
5923
|
+
}, /*#__PURE__*/react.createElement(ui_src/* InputFilterText */.Cv, {
|
|
5081
5924
|
className: "mr-8 block w-full",
|
|
5082
5925
|
placeholder: "Search metadata...",
|
|
5083
5926
|
onDebounceChange: setFilterValue
|
|
@@ -5101,7 +5944,7 @@ function getFormattedRowsFromTags(tags, metadata) {
|
|
|
5101
5944
|
} else {
|
|
5102
5945
|
if (tagInfo.vr === 'xs') {
|
|
5103
5946
|
try {
|
|
5104
|
-
const tag = dcmjs_es
|
|
5947
|
+
const tag = dcmjs_es/* default.data */.Ay.data.Tag.fromPString(tagInfo.tag).toCleanString();
|
|
5105
5948
|
const originalTagInfo = metadata[tag];
|
|
5106
5949
|
tagInfo.vr = originalTagInfo.vr;
|
|
5107
5950
|
} catch (error) {
|
|
@@ -5120,8 +5963,7 @@ function getSortedTags(metadata) {
|
|
|
5120
5963
|
_sortTagList(tagList);
|
|
5121
5964
|
return tagList;
|
|
5122
5965
|
}
|
|
5123
|
-
function getRows(metadata) {
|
|
5124
|
-
let depth = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
|
|
5966
|
+
function getRows(metadata, depth = 0) {
|
|
5125
5967
|
// Tag, Type, Value, Keyword
|
|
5126
5968
|
|
|
5127
5969
|
const keywords = Object.keys(metadata);
|
|
@@ -5132,7 +5974,6 @@ function getRows(metadata) {
|
|
|
5132
5974
|
if (depth > 0) {
|
|
5133
5975
|
tagIndent += ' '; // If indented, add a space after the indents.
|
|
5134
5976
|
}
|
|
5135
|
-
|
|
5136
5977
|
const rows = [];
|
|
5137
5978
|
for (let i = 0; i < keywords.length; i++) {
|
|
5138
5979
|
let keyword = keywords[i];
|
|
@@ -5259,6 +6100,9 @@ const reuseCachedLayout = (state, hangingProtocolService, syncService) => {
|
|
|
5259
6100
|
const {
|
|
5260
6101
|
protocol
|
|
5261
6102
|
} = hangingProtocolService.getActiveProtocol();
|
|
6103
|
+
if (!protocol) {
|
|
6104
|
+
return;
|
|
6105
|
+
}
|
|
5262
6106
|
const hpInfo = hangingProtocolService.getState();
|
|
5263
6107
|
const {
|
|
5264
6108
|
protocolId,
|
|
@@ -5361,6 +6205,13 @@ const findViewportsByPosition_findOrCreateViewport = (hangingProtocolService, vi
|
|
|
5361
6205
|
}
|
|
5362
6206
|
};
|
|
5363
6207
|
}
|
|
6208
|
+
|
|
6209
|
+
// and lastly if there is no default viewport, then we see if we can grab the
|
|
6210
|
+
// viewportsByPosition at the position index and use that
|
|
6211
|
+
// const candidate = Object.values(viewportsByPosition)[position];
|
|
6212
|
+
|
|
6213
|
+
// // if it has something to display, then we can use it
|
|
6214
|
+
// return candidate?.displaySetInstanceUIDs ? candidate : {};
|
|
5364
6215
|
return {};
|
|
5365
6216
|
};
|
|
5366
6217
|
|
|
@@ -5373,11 +6224,10 @@ const findViewportsByPosition_findOrCreateViewport = (hangingProtocolService, vi
|
|
|
5373
6224
|
* @returns Set of states that can be applied to the state sync to remember
|
|
5374
6225
|
* the current view state.
|
|
5375
6226
|
*/
|
|
5376
|
-
const findViewportsByPosition = (state,
|
|
5377
|
-
|
|
5378
|
-
|
|
5379
|
-
|
|
5380
|
-
} = _ref;
|
|
6227
|
+
const findViewportsByPosition = (state, {
|
|
6228
|
+
numRows,
|
|
6229
|
+
numCols
|
|
6230
|
+
}, syncService) => {
|
|
5381
6231
|
const {
|
|
5382
6232
|
viewports
|
|
5383
6233
|
} = state;
|
|
@@ -5414,8 +6264,8 @@ const findViewportsByPosition = (state, _ref, syncService) => {
|
|
|
5414
6264
|
};
|
|
5415
6265
|
};
|
|
5416
6266
|
/* harmony default export */ const src_findViewportsByPosition = (findViewportsByPosition);
|
|
5417
|
-
// EXTERNAL MODULE: ./index.js +
|
|
5418
|
-
var index = __webpack_require__(
|
|
6267
|
+
// EXTERNAL MODULE: ./index.js + 35 modules
|
|
6268
|
+
var index = __webpack_require__(68870);
|
|
5419
6269
|
;// CONCATENATED MODULE: ../../../extensions/default/src/commandsModule.ts
|
|
5420
6270
|
|
|
5421
6271
|
|
|
@@ -5426,17 +6276,10 @@ var index = __webpack_require__(59754);
|
|
|
5426
6276
|
const {
|
|
5427
6277
|
subscribeToNextViewportGridChange
|
|
5428
6278
|
} = src.utils;
|
|
5429
|
-
|
|
5430
|
-
|
|
5431
|
-
|
|
5432
|
-
|
|
5433
|
-
*/
|
|
5434
|
-
const isHangingProtocolCommand = command => command && (command.commandName === 'setHangingProtocol' || command.commandName === 'toggleHangingProtocol');
|
|
5435
|
-
const commandsModule = _ref => {
|
|
5436
|
-
let {
|
|
5437
|
-
servicesManager,
|
|
5438
|
-
commandsManager
|
|
5439
|
-
} = _ref;
|
|
6279
|
+
const commandsModule = ({
|
|
6280
|
+
servicesManager,
|
|
6281
|
+
commandsManager
|
|
6282
|
+
}) => {
|
|
5440
6283
|
const {
|
|
5441
6284
|
customizationService,
|
|
5442
6285
|
measurementService,
|
|
@@ -5444,8 +6287,7 @@ const commandsModule = _ref => {
|
|
|
5444
6287
|
uiNotificationService,
|
|
5445
6288
|
viewportGridService,
|
|
5446
6289
|
displaySetService,
|
|
5447
|
-
stateSyncService
|
|
5448
|
-
toolbarService
|
|
6290
|
+
stateSyncService
|
|
5449
6291
|
} = servicesManager.services;
|
|
5450
6292
|
|
|
5451
6293
|
// Define a context menu controller for use with any context menus
|
|
@@ -5491,12 +6333,11 @@ const commandsModule = _ref => {
|
|
|
5491
6333
|
closeContextMenu: () => {
|
|
5492
6334
|
contextMenuController.closeContextMenu();
|
|
5493
6335
|
},
|
|
5494
|
-
displayNotification:
|
|
5495
|
-
|
|
5496
|
-
|
|
5497
|
-
|
|
5498
|
-
|
|
5499
|
-
} = _ref2;
|
|
6336
|
+
displayNotification: ({
|
|
6337
|
+
text,
|
|
6338
|
+
title,
|
|
6339
|
+
type
|
|
6340
|
+
}) => {
|
|
5500
6341
|
uiNotificationService.show({
|
|
5501
6342
|
title: title,
|
|
5502
6343
|
message: text,
|
|
@@ -5506,41 +6347,6 @@ const commandsModule = _ref => {
|
|
|
5506
6347
|
clearMeasurements: () => {
|
|
5507
6348
|
measurementService.clear();
|
|
5508
6349
|
},
|
|
5509
|
-
/**
|
|
5510
|
-
* Toggles off all tools which contain a commandName of setHangingProtocol
|
|
5511
|
-
* or toggleHangingProtocol, and which match/don't match the protocol id/stage
|
|
5512
|
-
*/
|
|
5513
|
-
toggleHpTools: () => {
|
|
5514
|
-
const {
|
|
5515
|
-
protocol,
|
|
5516
|
-
stageIndex: toggleStageIndex,
|
|
5517
|
-
stage
|
|
5518
|
-
} = hangingProtocolService.getActiveProtocol();
|
|
5519
|
-
const enableListener = button => {
|
|
5520
|
-
if (!button.id) {
|
|
5521
|
-
return;
|
|
5522
|
-
}
|
|
5523
|
-
const {
|
|
5524
|
-
commands,
|
|
5525
|
-
items
|
|
5526
|
-
} = button.props || button;
|
|
5527
|
-
if (items) {
|
|
5528
|
-
items.forEach(enableListener);
|
|
5529
|
-
}
|
|
5530
|
-
const hpCommand = commands?.find?.(isHangingProtocolCommand);
|
|
5531
|
-
if (!hpCommand) {
|
|
5532
|
-
return;
|
|
5533
|
-
}
|
|
5534
|
-
const {
|
|
5535
|
-
protocolId,
|
|
5536
|
-
stageIndex,
|
|
5537
|
-
stageId
|
|
5538
|
-
} = hpCommand.commandOptions;
|
|
5539
|
-
const isActive = (!protocolId || protocolId === protocol.id) && (stageIndex === undefined || stageIndex === toggleStageIndex) && (!stageId || stageId === stage.id);
|
|
5540
|
-
toolbarService.setToggled(button.id, isActive);
|
|
5541
|
-
};
|
|
5542
|
-
Object.values(toolbarService.getButtons()).forEach(enableListener);
|
|
5543
|
-
},
|
|
5544
6350
|
/**
|
|
5545
6351
|
* Sets the specified protocol
|
|
5546
6352
|
* 1. Records any existing state using the viewport grid service
|
|
@@ -5565,24 +6371,19 @@ const commandsModule = _ref => {
|
|
|
5565
6371
|
* @param options.stageIndex - the index of the stage to go to.
|
|
5566
6372
|
* @param options.reset - flag to indicate if the HP should be reset to its original and not restored to a previous state
|
|
5567
6373
|
*/
|
|
5568
|
-
setHangingProtocol:
|
|
5569
|
-
|
|
5570
|
-
|
|
5571
|
-
|
|
5572
|
-
|
|
5573
|
-
|
|
5574
|
-
|
|
5575
|
-
} = _ref3;
|
|
5576
|
-
const primaryToolBeforeHPChange = toolbarService.getActivePrimaryTool();
|
|
6374
|
+
setHangingProtocol: ({
|
|
6375
|
+
activeStudyUID = '',
|
|
6376
|
+
protocolId,
|
|
6377
|
+
stageId,
|
|
6378
|
+
stageIndex,
|
|
6379
|
+
reset = false
|
|
6380
|
+
}) => {
|
|
5577
6381
|
try {
|
|
5578
6382
|
// Stores in the state the display set selector id to displaySetUID mapping
|
|
5579
6383
|
// Pass in viewportId for the active viewport. This item will get set as
|
|
5580
6384
|
// the activeViewportId
|
|
5581
6385
|
const state = viewportGridService.getState();
|
|
5582
6386
|
const hpInfo = hangingProtocolService.getState();
|
|
5583
|
-
const {
|
|
5584
|
-
protocol: oldProtocol
|
|
5585
|
-
} = hangingProtocolService.getActiveProtocol();
|
|
5586
6387
|
const stateSyncReduce = reuseCachedLayouts(state, hangingProtocolService, stateSyncService);
|
|
5587
6388
|
const {
|
|
5588
6389
|
hangingProtocolStageIndexMap,
|
|
@@ -5632,45 +6433,9 @@ const commandsModule = _ref => {
|
|
|
5632
6433
|
// multi-study display.
|
|
5633
6434
|
delete displaySetSelectorMap[`${activeStudyUID || hpInfo.activeStudyUID}:activeDisplaySet:0`];
|
|
5634
6435
|
stateSyncService.store(stateSyncReduce);
|
|
5635
|
-
// This is a default action applied
|
|
5636
|
-
const {
|
|
5637
|
-
protocol
|
|
5638
|
-
} = hangingProtocolService.getActiveProtocol();
|
|
5639
|
-
actions.toggleHpTools();
|
|
5640
|
-
|
|
5641
|
-
// try to use the same tool in the new hanging protocol stage
|
|
5642
|
-
const primaryButton = toolbarService.getButton(primaryToolBeforeHPChange);
|
|
5643
|
-
if (primaryButton) {
|
|
5644
|
-
// is there any type of interaction on this button, if not it might be in the
|
|
5645
|
-
// items. This is a bit of a hack, but it works for now.
|
|
5646
|
-
|
|
5647
|
-
let interactionType = primaryButton.props?.interactionType;
|
|
5648
|
-
if (!interactionType && primaryButton.props?.items) {
|
|
5649
|
-
const firstItem = primaryButton.props.items[0];
|
|
5650
|
-
interactionType = firstItem.props?.interactionType || firstItem.props?.type;
|
|
5651
|
-
}
|
|
5652
|
-
if (interactionType) {
|
|
5653
|
-
toolbarService.recordInteraction({
|
|
5654
|
-
interactionType,
|
|
5655
|
-
...primaryButton.props
|
|
5656
|
-
});
|
|
5657
|
-
}
|
|
5658
|
-
}
|
|
5659
|
-
|
|
5660
|
-
// Send the notification about updating the state
|
|
5661
|
-
if (protocolId !== hpInfo.protocolId) {
|
|
5662
|
-
// The old protocol callbacks are used for turning off things
|
|
5663
|
-
// like crosshairs when moving to the new HP
|
|
5664
|
-
commandsManager.run(oldProtocol.callbacks?.onProtocolExit);
|
|
5665
|
-
// The new protocol callback is used for things like
|
|
5666
|
-
// activating modes etc.
|
|
5667
|
-
}
|
|
5668
|
-
|
|
5669
|
-
commandsManager.run(protocol.callbacks?.onProtocolEnter);
|
|
5670
6436
|
return true;
|
|
5671
6437
|
} catch (e) {
|
|
5672
6438
|
console.error(e);
|
|
5673
|
-
actions.toggleHpTools();
|
|
5674
6439
|
uiNotificationService.show({
|
|
5675
6440
|
title: 'Apply Hanging Protocol',
|
|
5676
6441
|
message: 'The hanging protocol could not be applied.',
|
|
@@ -5680,11 +6445,10 @@ const commandsModule = _ref => {
|
|
|
5680
6445
|
return false;
|
|
5681
6446
|
}
|
|
5682
6447
|
},
|
|
5683
|
-
toggleHangingProtocol:
|
|
5684
|
-
|
|
5685
|
-
|
|
5686
|
-
|
|
5687
|
-
} = _ref4;
|
|
6448
|
+
toggleHangingProtocol: ({
|
|
6449
|
+
protocolId,
|
|
6450
|
+
stageIndex
|
|
6451
|
+
}) => {
|
|
5688
6452
|
const {
|
|
5689
6453
|
protocol,
|
|
5690
6454
|
stageIndex: desiredStageIndex,
|
|
@@ -5717,10 +6481,9 @@ const commandsModule = _ref => {
|
|
|
5717
6481
|
});
|
|
5718
6482
|
}
|
|
5719
6483
|
},
|
|
5720
|
-
deltaStage:
|
|
5721
|
-
|
|
5722
|
-
|
|
5723
|
-
} = _ref5;
|
|
6484
|
+
deltaStage: ({
|
|
6485
|
+
direction
|
|
6486
|
+
}) => {
|
|
5724
6487
|
const {
|
|
5725
6488
|
protocolId,
|
|
5726
6489
|
stageIndex: oldStageIndex
|
|
@@ -5746,11 +6509,11 @@ const commandsModule = _ref => {
|
|
|
5746
6509
|
/**
|
|
5747
6510
|
* Changes the viewport grid layout in terms of the MxN layout.
|
|
5748
6511
|
*/
|
|
5749
|
-
setViewportGridLayout:
|
|
5750
|
-
|
|
5751
|
-
|
|
5752
|
-
|
|
5753
|
-
|
|
6512
|
+
setViewportGridLayout: ({
|
|
6513
|
+
numRows,
|
|
6514
|
+
numCols,
|
|
6515
|
+
isHangingProtocolLayout = false
|
|
6516
|
+
}) => {
|
|
5754
6517
|
const {
|
|
5755
6518
|
protocol
|
|
5756
6519
|
} = hangingProtocolService.getActiveProtocol();
|
|
@@ -5773,7 +6536,8 @@ const commandsModule = _ref => {
|
|
|
5773
6536
|
viewportGridService.setLayout({
|
|
5774
6537
|
numRows,
|
|
5775
6538
|
numCols,
|
|
5776
|
-
findOrCreateViewport
|
|
6539
|
+
findOrCreateViewport,
|
|
6540
|
+
isHangingProtocolLayout
|
|
5777
6541
|
});
|
|
5778
6542
|
stateSyncService.store(stateReduce);
|
|
5779
6543
|
};
|
|
@@ -5838,7 +6602,8 @@ const commandsModule = _ref => {
|
|
|
5838
6602
|
numCols: toggleOneUpViewportGridStore.layout.numCols,
|
|
5839
6603
|
activeViewportId: viewportIdToUpdate,
|
|
5840
6604
|
layoutOptions,
|
|
5841
|
-
findOrCreateViewport
|
|
6605
|
+
findOrCreateViewport,
|
|
6606
|
+
isHangingProtocolLayout: true
|
|
5842
6607
|
});
|
|
5843
6608
|
} else {
|
|
5844
6609
|
// We are not in one-up, so toggle to one up.
|
|
@@ -5862,7 +6627,8 @@ const commandsModule = _ref => {
|
|
|
5862
6627
|
viewportGridService.setLayout({
|
|
5863
6628
|
numRows: 1,
|
|
5864
6629
|
numCols: 1,
|
|
5865
|
-
findOrCreateViewport
|
|
6630
|
+
findOrCreateViewport,
|
|
6631
|
+
isHangingProtocolLayout: true
|
|
5866
6632
|
});
|
|
5867
6633
|
|
|
5868
6634
|
// Subscribe to ANY (i.e. manual and hanging protocol) layout changes so that
|
|
@@ -5897,7 +6663,7 @@ const commandsModule = _ref => {
|
|
|
5897
6663
|
* for `replace` is false
|
|
5898
6664
|
*/
|
|
5899
6665
|
navigateHistory(historyArgs) {
|
|
5900
|
-
index/* history */.
|
|
6666
|
+
index/* history */.b.navigate(historyArgs.to, historyArgs.options);
|
|
5901
6667
|
},
|
|
5902
6668
|
openDICOMTagViewer() {
|
|
5903
6669
|
const {
|
|
@@ -5920,6 +6686,7 @@ const commandsModule = _ref => {
|
|
|
5920
6686
|
displaySetInstanceUID,
|
|
5921
6687
|
onClose: UIModalService.hide
|
|
5922
6688
|
},
|
|
6689
|
+
containerDimensions: 'max-w-4xl max-h-4xl',
|
|
5923
6690
|
title: 'DICOM Tag Browser'
|
|
5924
6691
|
});
|
|
5925
6692
|
},
|
|
@@ -5960,11 +6727,10 @@ const commandsModule = _ref => {
|
|
|
5960
6727
|
behavior: 'smooth'
|
|
5961
6728
|
});
|
|
5962
6729
|
},
|
|
5963
|
-
updateViewportDisplaySet:
|
|
5964
|
-
|
|
5965
|
-
|
|
5966
|
-
|
|
5967
|
-
} = _ref7;
|
|
6730
|
+
updateViewportDisplaySet: ({
|
|
6731
|
+
direction,
|
|
6732
|
+
excludeNonImageModalities
|
|
6733
|
+
}) => {
|
|
5968
6734
|
const nonImageModalities = ['SR', 'SEG', 'SM', 'RTSTRUCT', 'RTPLAN', 'RTDOSE'];
|
|
5969
6735
|
|
|
5970
6736
|
// Sort the display sets as per the hanging protocol service viewport/display set scoring system.
|
|
@@ -6016,61 +6782,43 @@ const commandsModule = _ref => {
|
|
|
6016
6782
|
commandFn: actions.closeContextMenu
|
|
6017
6783
|
},
|
|
6018
6784
|
clearMeasurements: {
|
|
6019
|
-
commandFn: actions.clearMeasurements
|
|
6020
|
-
storeContexts: [],
|
|
6021
|
-
options: {}
|
|
6785
|
+
commandFn: actions.clearMeasurements
|
|
6022
6786
|
},
|
|
6023
6787
|
displayNotification: {
|
|
6024
|
-
commandFn: actions.displayNotification
|
|
6025
|
-
storeContexts: [],
|
|
6026
|
-
options: {}
|
|
6788
|
+
commandFn: actions.displayNotification
|
|
6027
6789
|
},
|
|
6028
6790
|
setHangingProtocol: {
|
|
6029
|
-
commandFn: actions.setHangingProtocol
|
|
6030
|
-
storeContexts: [],
|
|
6031
|
-
options: {}
|
|
6791
|
+
commandFn: actions.setHangingProtocol
|
|
6032
6792
|
},
|
|
6033
6793
|
toggleHangingProtocol: {
|
|
6034
|
-
commandFn: actions.toggleHangingProtocol
|
|
6035
|
-
storeContexts: [],
|
|
6036
|
-
options: {}
|
|
6794
|
+
commandFn: actions.toggleHangingProtocol
|
|
6037
6795
|
},
|
|
6038
6796
|
navigateHistory: {
|
|
6039
|
-
commandFn: actions.navigateHistory
|
|
6040
|
-
storeContexts: [],
|
|
6041
|
-
options: {}
|
|
6797
|
+
commandFn: actions.navigateHistory
|
|
6042
6798
|
},
|
|
6043
6799
|
nextStage: {
|
|
6044
6800
|
commandFn: actions.deltaStage,
|
|
6045
|
-
storeContexts: [],
|
|
6046
6801
|
options: {
|
|
6047
6802
|
direction: 1
|
|
6048
6803
|
}
|
|
6049
6804
|
},
|
|
6050
6805
|
previousStage: {
|
|
6051
6806
|
commandFn: actions.deltaStage,
|
|
6052
|
-
storeContexts: [],
|
|
6053
6807
|
options: {
|
|
6054
6808
|
direction: -1
|
|
6055
6809
|
}
|
|
6056
6810
|
},
|
|
6057
6811
|
setViewportGridLayout: {
|
|
6058
|
-
commandFn: actions.setViewportGridLayout
|
|
6059
|
-
storeContexts: [],
|
|
6060
|
-
options: {}
|
|
6812
|
+
commandFn: actions.setViewportGridLayout
|
|
6061
6813
|
},
|
|
6062
6814
|
toggleOneUp: {
|
|
6063
|
-
commandFn: actions.toggleOneUp
|
|
6064
|
-
storeContexts: [],
|
|
6065
|
-
options: {}
|
|
6815
|
+
commandFn: actions.toggleOneUp
|
|
6066
6816
|
},
|
|
6067
6817
|
openDICOMTagViewer: {
|
|
6068
6818
|
commandFn: actions.openDICOMTagViewer
|
|
6069
6819
|
},
|
|
6070
6820
|
updateViewportDisplaySet: {
|
|
6071
|
-
commandFn: actions.updateViewportDisplaySet
|
|
6072
|
-
storeContexts: [],
|
|
6073
|
-
options: {}
|
|
6821
|
+
commandFn: actions.updateViewportDisplaySet
|
|
6074
6822
|
}
|
|
6075
6823
|
};
|
|
6076
6824
|
return {
|
|
@@ -6480,6 +7228,9 @@ const defaultProtocol = {
|
|
|
6480
7228
|
editableBy: {},
|
|
6481
7229
|
protocolMatchingRules: [],
|
|
6482
7230
|
toolGroupIds: ['default'],
|
|
7231
|
+
hpInitiationCriteria: {
|
|
7232
|
+
minSeriesLoaded: 1
|
|
7233
|
+
},
|
|
6483
7234
|
// -1 would be used to indicate active only, whereas other values are
|
|
6484
7235
|
// the number of required priors referenced - so 0 means active with
|
|
6485
7236
|
// 0 or more priors.
|
|
@@ -6524,7 +7275,6 @@ const defaultProtocol = {
|
|
|
6524
7275
|
// studyMatchingRules: [],
|
|
6525
7276
|
}
|
|
6526
7277
|
},
|
|
6527
|
-
|
|
6528
7278
|
stages: [{
|
|
6529
7279
|
name: 'default',
|
|
6530
7280
|
viewportStructure: {
|
|
@@ -6550,7 +7300,6 @@ const defaultProtocol = {
|
|
|
6550
7300
|
// preset: 'middle', // 'first', 'last', 'middle'
|
|
6551
7301
|
// },
|
|
6552
7302
|
},
|
|
6553
|
-
|
|
6554
7303
|
displaySets: [{
|
|
6555
7304
|
id: 'defaultDisplaySetId'
|
|
6556
7305
|
}]
|
|
@@ -6582,8 +7331,8 @@ function getHangingProtocolModule() {
|
|
|
6582
7331
|
|
|
6583
7332
|
|
|
6584
7333
|
function DataSourceSelector() {
|
|
6585
|
-
const [appConfig] = (0,state/* useAppConfig */.
|
|
6586
|
-
const navigate = (0,dist/* useNavigate */.
|
|
7334
|
+
const [appConfig] = (0,state/* useAppConfig */.r)();
|
|
7335
|
+
const navigate = (0,dist/* useNavigate */.Zp)();
|
|
6587
7336
|
|
|
6588
7337
|
// This is frowned upon, but the raw config is needed here to provide
|
|
6589
7338
|
// the selector
|
|
@@ -6607,8 +7356,8 @@ function DataSourceSelector() {
|
|
|
6607
7356
|
key: ds.sourceName
|
|
6608
7357
|
}, /*#__PURE__*/react.createElement("h1", {
|
|
6609
7358
|
className: "text-white"
|
|
6610
|
-
}, ds.configuration?.friendlyName || ds.friendlyName), /*#__PURE__*/react.createElement(ui_src/* Button
|
|
6611
|
-
type: ui_src/* ButtonEnums.type */.
|
|
7359
|
+
}, ds.configuration?.friendlyName || ds.friendlyName), /*#__PURE__*/react.createElement(ui_src/* Button */.$n, {
|
|
7360
|
+
type: ui_src/* ButtonEnums.type */.Ny.NW.primary,
|
|
6612
7361
|
className: classnames_default()('ml-2'),
|
|
6613
7362
|
onClick: () => {
|
|
6614
7363
|
navigate({
|
|
@@ -6624,15 +7373,14 @@ function DataSourceSelector() {
|
|
|
6624
7373
|
|
|
6625
7374
|
|
|
6626
7375
|
|
|
6627
|
-
function ItemListComponent(
|
|
6628
|
-
|
|
6629
|
-
|
|
6630
|
-
|
|
6631
|
-
|
|
6632
|
-
} = _ref;
|
|
7376
|
+
function ItemListComponent({
|
|
7377
|
+
itemLabel,
|
|
7378
|
+
itemList,
|
|
7379
|
+
onItemClicked
|
|
7380
|
+
}) {
|
|
6633
7381
|
const {
|
|
6634
7382
|
t
|
|
6635
|
-
} = (0,es/* useTranslation
|
|
7383
|
+
} = (0,es/* useTranslation */.Bd)('DataSourceConfiguration');
|
|
6636
7384
|
const [filterValue, setFilterValue] = (0,react.useState)('');
|
|
6637
7385
|
(0,react.useEffect)(() => {
|
|
6638
7386
|
setFilterValue('');
|
|
@@ -6643,18 +7391,18 @@ function ItemListComponent(_ref) {
|
|
|
6643
7391
|
className: "flex items-center justify-between"
|
|
6644
7392
|
}, /*#__PURE__*/react.createElement("div", {
|
|
6645
7393
|
className: "text-primary-light text-[20px]"
|
|
6646
|
-
}, t(`Select ${itemLabel}`)), /*#__PURE__*/react.createElement(ui_src/* InputFilterText */.
|
|
7394
|
+
}, t(`Select ${itemLabel}`)), /*#__PURE__*/react.createElement(ui_src/* InputFilterText */.Cv, {
|
|
6647
7395
|
className: "max-w-[40%] grow",
|
|
6648
7396
|
value: filterValue,
|
|
6649
7397
|
onDebounceChange: setFilterValue,
|
|
6650
7398
|
placeholder: t(`Search ${itemLabel} list`)
|
|
6651
7399
|
})), /*#__PURE__*/react.createElement("div", {
|
|
6652
7400
|
className: "relative flex min-h-[1px] grow flex-col bg-black text-[14px]"
|
|
6653
|
-
}, itemList == null ? /*#__PURE__*/react.createElement(ui_src/* LoadingIndicatorProgress */.
|
|
7401
|
+
}, itemList == null ? /*#__PURE__*/react.createElement(ui_src/* LoadingIndicatorProgress */.Jx, {
|
|
6654
7402
|
className: 'h-full w-full'
|
|
6655
7403
|
}) : itemList.length === 0 ? /*#__PURE__*/react.createElement("div", {
|
|
6656
7404
|
className: "text-primary-light flex h-full flex-col items-center justify-center px-6 py-4"
|
|
6657
|
-
}, /*#__PURE__*/react.createElement(ui_src/* Icon */.
|
|
7405
|
+
}, /*#__PURE__*/react.createElement(ui_src/* Icon */.In, {
|
|
6658
7406
|
name: "magnifier",
|
|
6659
7407
|
className: "mb-4"
|
|
6660
7408
|
}), /*#__PURE__*/react.createElement("span", null, t(`No ${itemLabel} available`))) : /*#__PURE__*/react.createElement(react.Fragment, null, /*#__PURE__*/react.createElement("div", {
|
|
@@ -6666,10 +7414,10 @@ function ItemListComponent(_ref) {
|
|
|
6666
7414
|
return /*#__PURE__*/react.createElement("div", {
|
|
6667
7415
|
className: classnames_default()('hover:text-primary-light hover:bg-primary-dark group mx-2 flex items-center justify-between px-6 py-2', border),
|
|
6668
7416
|
key: item.id
|
|
6669
|
-
}, /*#__PURE__*/react.createElement("div", null, item.name), /*#__PURE__*/react.createElement(ui_src/* Button
|
|
7417
|
+
}, /*#__PURE__*/react.createElement("div", null, item.name), /*#__PURE__*/react.createElement(ui_src/* Button */.$n, {
|
|
6670
7418
|
onClick: () => onItemClicked(item),
|
|
6671
7419
|
className: "invisible group-hover:visible",
|
|
6672
|
-
endIcon: /*#__PURE__*/react.createElement(ui_src/* Icon */.
|
|
7420
|
+
endIcon: /*#__PURE__*/react.createElement(ui_src/* Icon */.In, {
|
|
6673
7421
|
name: "arrow-left"
|
|
6674
7422
|
})
|
|
6675
7423
|
}, t('Select')));
|
|
@@ -6683,15 +7431,14 @@ function ItemListComponent(_ref) {
|
|
|
6683
7431
|
|
|
6684
7432
|
|
|
6685
7433
|
const NO_WRAP_ELLIPSIS_CLASS_NAMES = 'text-ellipsis whitespace-nowrap overflow-hidden';
|
|
6686
|
-
function DataSourceConfigurationModalComponent(
|
|
6687
|
-
|
|
6688
|
-
|
|
6689
|
-
|
|
6690
|
-
|
|
6691
|
-
} = _ref;
|
|
7434
|
+
function DataSourceConfigurationModalComponent({
|
|
7435
|
+
configurationAPI,
|
|
7436
|
+
configuredItems,
|
|
7437
|
+
onHide
|
|
7438
|
+
}) {
|
|
6692
7439
|
const {
|
|
6693
7440
|
t
|
|
6694
|
-
} = (0,es/* useTranslation
|
|
7441
|
+
} = (0,es/* useTranslation */.Bd)('DataSourceConfiguration');
|
|
6695
7442
|
const [itemList, setItemList] = (0,react.useState)();
|
|
6696
7443
|
const [selectedItems, setSelectedItems] = (0,react.useState)(configuredItems);
|
|
6697
7444
|
const [errorMessage, setErrorMessage] = (0,react.useState)();
|
|
@@ -6765,9 +7512,9 @@ function DataSourceConfigurationModalComponent(_ref) {
|
|
|
6765
7512
|
} : undefined
|
|
6766
7513
|
}, /*#__PURE__*/react.createElement("div", {
|
|
6767
7514
|
className: "text- flex items-center gap-2"
|
|
6768
|
-
}, itemLabelIndex < selectedItems.length ? /*#__PURE__*/react.createElement(ui_src/* Icon */.
|
|
7515
|
+
}, itemLabelIndex < selectedItems.length ? /*#__PURE__*/react.createElement(ui_src/* Icon */.In, {
|
|
6769
7516
|
name: "status-tracked"
|
|
6770
|
-
}) : /*#__PURE__*/react.createElement(ui_src/* Icon */.
|
|
7517
|
+
}) : /*#__PURE__*/react.createElement(ui_src/* Icon */.In, {
|
|
6771
7518
|
name: "status-untracked"
|
|
6772
7519
|
}), /*#__PURE__*/react.createElement("div", {
|
|
6773
7520
|
className: classnames_default()(NO_WRAP_ELLIPSIS_CLASS_NAMES)
|
|
@@ -6795,18 +7542,17 @@ function DataSourceConfigurationModalComponent(_ref) {
|
|
|
6795
7542
|
|
|
6796
7543
|
|
|
6797
7544
|
|
|
6798
|
-
function DataSourceConfigurationComponent(
|
|
6799
|
-
|
|
6800
|
-
|
|
6801
|
-
|
|
6802
|
-
} = _ref;
|
|
7545
|
+
function DataSourceConfigurationComponent({
|
|
7546
|
+
servicesManager,
|
|
7547
|
+
extensionManager
|
|
7548
|
+
}) {
|
|
6803
7549
|
const {
|
|
6804
7550
|
t
|
|
6805
|
-
} = (0,es/* useTranslation
|
|
7551
|
+
} = (0,es/* useTranslation */.Bd)('DataSourceConfiguration');
|
|
6806
7552
|
const {
|
|
6807
7553
|
show,
|
|
6808
7554
|
hide
|
|
6809
|
-
} = (0,ui_src/* useModal */.
|
|
7555
|
+
} = (0,ui_src/* useModal */.hS)();
|
|
6810
7556
|
const {
|
|
6811
7557
|
customizationService
|
|
6812
7558
|
} = servicesManager.services;
|
|
@@ -6865,7 +7611,7 @@ function DataSourceConfigurationComponent(_ref) {
|
|
|
6865
7611
|
}, [configurationAPI, configuredItems, showConfigurationModal]);
|
|
6866
7612
|
return configuredItems ? /*#__PURE__*/react.createElement("div", {
|
|
6867
7613
|
className: "text-aqua-pale flex items-center overflow-hidden"
|
|
6868
|
-
}, /*#__PURE__*/react.createElement(ui_src/* Icon */.
|
|
7614
|
+
}, /*#__PURE__*/react.createElement(ui_src/* Icon */.In, {
|
|
6869
7615
|
name: "settings",
|
|
6870
7616
|
className: "mr-2.5 h-3.5 w-3.5 shrink-0 cursor-pointer",
|
|
6871
7617
|
onClick: showConfigurationModal
|
|
@@ -7017,9 +7763,7 @@ class GoogleCloudDataSourceConfigurationAPI {
|
|
|
7017
7763
|
* @param fetchSearchParams any search query params; currently only used for paging results
|
|
7018
7764
|
* @returns an array of items of the specified type
|
|
7019
7765
|
*/
|
|
7020
|
-
static async _doFetch(urlStr, fetchItemType) {
|
|
7021
|
-
let fetchOptions = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
7022
|
-
let fetchSearchParams = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
|
|
7766
|
+
static async _doFetch(urlStr, fetchItemType, fetchOptions = {}, fetchSearchParams = {}) {
|
|
7023
7767
|
try {
|
|
7024
7768
|
const url = new URL(urlStr);
|
|
7025
7769
|
url.search = new URLSearchParams(fetchSearchParams).toString();
|
|
@@ -7055,6 +7799,7 @@ class GoogleCloudDataSourceConfigurationAPI {
|
|
|
7055
7799
|
|
|
7056
7800
|
|
|
7057
7801
|
|
|
7802
|
+
|
|
7058
7803
|
/**
|
|
7059
7804
|
*
|
|
7060
7805
|
* Note: this is an example of how the customization module can be used
|
|
@@ -7064,11 +7809,10 @@ class GoogleCloudDataSourceConfigurationAPI {
|
|
|
7064
7809
|
* custom page for the user to view their profile, or to add a custom
|
|
7065
7810
|
* page for login etc.
|
|
7066
7811
|
*/
|
|
7067
|
-
function getCustomizationModule(
|
|
7068
|
-
|
|
7069
|
-
|
|
7070
|
-
|
|
7071
|
-
} = _ref;
|
|
7812
|
+
function getCustomizationModule({
|
|
7813
|
+
servicesManager,
|
|
7814
|
+
extensionManager
|
|
7815
|
+
}) {
|
|
7072
7816
|
return [{
|
|
7073
7817
|
name: 'helloPage',
|
|
7074
7818
|
value: {
|
|
@@ -7193,14 +7937,65 @@ function getCustomizationModule(_ref) {
|
|
|
7193
7937
|
// The factory for creating an instance of a BaseDataSourceConfigurationAPI for Google Cloud Healthcare
|
|
7194
7938
|
id: 'ohif.dataSourceConfigurationAPI.google',
|
|
7195
7939
|
factory: dataSourceName => new GoogleCloudDataSourceConfigurationAPI(dataSourceName, servicesManager, extensionManager)
|
|
7940
|
+
}, {
|
|
7941
|
+
id: 'progressDropdownWithServiceComponent',
|
|
7942
|
+
component: ProgressDropdownWithService_ProgressDropdownWithService
|
|
7196
7943
|
}]
|
|
7197
7944
|
}];
|
|
7198
7945
|
}
|
|
7946
|
+
;// CONCATENATED MODULE: ../../../extensions/default/src/Components/LineChartViewport/LineChartViewport.tsx
|
|
7947
|
+
|
|
7948
|
+
|
|
7949
|
+
const LineChartViewport = ({
|
|
7950
|
+
displaySets
|
|
7951
|
+
}) => {
|
|
7952
|
+
const displaySet = displaySets[0];
|
|
7953
|
+
const {
|
|
7954
|
+
axis: chartAxis,
|
|
7955
|
+
series: chartSeries
|
|
7956
|
+
} = displaySet.instance.chartData;
|
|
7957
|
+
return /*#__PURE__*/react.createElement(ui_src/* LineChart */.bl, {
|
|
7958
|
+
showLegend: true,
|
|
7959
|
+
legendWidth: 150,
|
|
7960
|
+
axis: {
|
|
7961
|
+
x: {
|
|
7962
|
+
label: chartAxis.x.label,
|
|
7963
|
+
indexRef: 0,
|
|
7964
|
+
type: 'x',
|
|
7965
|
+
range: {
|
|
7966
|
+
min: 0
|
|
7967
|
+
}
|
|
7968
|
+
},
|
|
7969
|
+
y: {
|
|
7970
|
+
label: chartAxis.y.label,
|
|
7971
|
+
indexRef: 1,
|
|
7972
|
+
type: 'y'
|
|
7973
|
+
}
|
|
7974
|
+
},
|
|
7975
|
+
series: chartSeries
|
|
7976
|
+
});
|
|
7977
|
+
};
|
|
7978
|
+
|
|
7979
|
+
;// CONCATENATED MODULE: ../../../extensions/default/src/Components/LineChartViewport/index.ts
|
|
7980
|
+
|
|
7981
|
+
;// CONCATENATED MODULE: ../../../extensions/default/src/getViewportModule.tsx
|
|
7982
|
+
|
|
7983
|
+
const getViewportModule = ({
|
|
7984
|
+
servicesManager,
|
|
7985
|
+
commandsManager,
|
|
7986
|
+
extensionManager
|
|
7987
|
+
}) => {
|
|
7988
|
+
return [{
|
|
7989
|
+
name: 'chartViewport',
|
|
7990
|
+
component: LineChartViewport
|
|
7991
|
+
}];
|
|
7992
|
+
};
|
|
7993
|
+
|
|
7199
7994
|
// EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/calculate-suv/dist/calculate-suv.esm.js
|
|
7200
|
-
var calculate_suv_esm = __webpack_require__(
|
|
7995
|
+
var calculate_suv_esm = __webpack_require__(79717);
|
|
7201
7996
|
;// CONCATENATED MODULE: ../../../extensions/default/src/getPTImageIdInstanceMetadata.ts
|
|
7202
7997
|
|
|
7203
|
-
const getPTImageIdInstanceMetadata_metadataProvider = src
|
|
7998
|
+
const getPTImageIdInstanceMetadata_metadataProvider = src/* default.classes */.Ay.classes.MetadataProvider;
|
|
7204
7999
|
function getPTImageIdInstanceMetadata(imageId) {
|
|
7205
8000
|
const dicomMetaData = getPTImageIdInstanceMetadata_metadataProvider.get('instance', imageId);
|
|
7206
8001
|
if (!dicomMetaData) {
|
|
@@ -7276,14 +8071,18 @@ const init_metadataProvider = src.classes.MetadataProvider;
|
|
|
7276
8071
|
* @param {Object} servicesManager
|
|
7277
8072
|
* @param {Object} configuration
|
|
7278
8073
|
*/
|
|
7279
|
-
function init(
|
|
7280
|
-
|
|
7281
|
-
|
|
7282
|
-
|
|
7283
|
-
|
|
8074
|
+
function init({
|
|
8075
|
+
servicesManager,
|
|
8076
|
+
configuration = {},
|
|
8077
|
+
commandsManager
|
|
8078
|
+
}) {
|
|
7284
8079
|
const {
|
|
7285
|
-
stateSyncService
|
|
8080
|
+
stateSyncService,
|
|
8081
|
+
toolbarService,
|
|
8082
|
+
cineService,
|
|
8083
|
+
viewportGridService
|
|
7286
8084
|
} = servicesManager.services;
|
|
8085
|
+
toolbarService.registerEventForToolbarUpdate(cineService, [cineService.EVENTS.CINE_STATE_CHANGED]);
|
|
7287
8086
|
// Add
|
|
7288
8087
|
src.DicomMetadataStore.subscribe(src.DicomMetadataStore.EVENTS.INSTANCES_ADDED, handlePETImageMetadata);
|
|
7289
8088
|
|
|
@@ -7298,6 +8097,12 @@ function init(_ref) {
|
|
|
7298
8097
|
clearOnModeExit: true
|
|
7299
8098
|
});
|
|
7300
8099
|
|
|
8100
|
+
// uiStateStore is a sync state which stores the relevant
|
|
8101
|
+
// UI state for the viewer
|
|
8102
|
+
stateSyncService.register('uiStateStore', {
|
|
8103
|
+
clearOnModeExit: true
|
|
8104
|
+
});
|
|
8105
|
+
|
|
7301
8106
|
// displaySetSelectorMap stores a map from
|
|
7302
8107
|
// `<activeStudyUID>:<displaySetSelectorId>:<matchOffset>` to
|
|
7303
8108
|
// a displaySetInstanceUID, used to display named display sets in
|
|
@@ -7314,7 +8119,7 @@ function init(_ref) {
|
|
|
7314
8119
|
});
|
|
7315
8120
|
|
|
7316
8121
|
// Stores a map from the to be applied hanging protocols `<activeStudyUID>:<protocolId>`
|
|
7317
|
-
// to the previously applied hanging
|
|
8122
|
+
// to the previously applied hanging protocolStageIndexMap key, in order to toggle
|
|
7318
8123
|
// off the applied protocol and remember the old state.
|
|
7319
8124
|
stateSyncService.register('toggleHangingProtocol', {
|
|
7320
8125
|
clearOnModeExit: true
|
|
@@ -7326,44 +8131,83 @@ function init(_ref) {
|
|
|
7326
8131
|
stateSyncService.register('viewportsByPosition', {
|
|
7327
8132
|
clearOnModeExit: true
|
|
7328
8133
|
});
|
|
8134
|
+
|
|
8135
|
+
// Function to process and subscribe to events for a given set of commands and listeners
|
|
8136
|
+
const subscribeToEvents = listeners => {
|
|
8137
|
+
Object.entries(listeners).forEach(([event, commands]) => {
|
|
8138
|
+
const supportedEvents = [viewportGridService.EVENTS.ACTIVE_VIEWPORT_ID_CHANGED, viewportGridService.EVENTS.VIEWPORTS_READY];
|
|
8139
|
+
if (supportedEvents.includes(event)) {
|
|
8140
|
+
viewportGridService.subscribe(event, eventData => {
|
|
8141
|
+
const viewportId = eventData?.viewportId ?? viewportGridService.getActiveViewportId();
|
|
8142
|
+
commandsManager.run(commands, {
|
|
8143
|
+
viewportId
|
|
8144
|
+
});
|
|
8145
|
+
});
|
|
8146
|
+
}
|
|
8147
|
+
});
|
|
8148
|
+
};
|
|
8149
|
+
toolbarService.subscribe(toolbarService.EVENTS.TOOL_BAR_MODIFIED, state => {
|
|
8150
|
+
const {
|
|
8151
|
+
buttons
|
|
8152
|
+
} = state;
|
|
8153
|
+
for (const [id, button] of Object.entries(buttons)) {
|
|
8154
|
+
const {
|
|
8155
|
+
groupId,
|
|
8156
|
+
items,
|
|
8157
|
+
listeners
|
|
8158
|
+
} = button.props || {};
|
|
8159
|
+
|
|
8160
|
+
// Handle group items' listeners
|
|
8161
|
+
if (groupId && items) {
|
|
8162
|
+
items.forEach(item => {
|
|
8163
|
+
if (item.listeners) {
|
|
8164
|
+
subscribeToEvents(item.listeners);
|
|
8165
|
+
}
|
|
8166
|
+
});
|
|
8167
|
+
}
|
|
8168
|
+
|
|
8169
|
+
// Handle button listeners
|
|
8170
|
+
if (listeners) {
|
|
8171
|
+
subscribeToEvents(listeners);
|
|
8172
|
+
}
|
|
8173
|
+
}
|
|
8174
|
+
});
|
|
7329
8175
|
}
|
|
7330
|
-
const handlePETImageMetadata =
|
|
7331
|
-
|
|
7332
|
-
|
|
7333
|
-
|
|
7334
|
-
} = _ref2;
|
|
8176
|
+
const handlePETImageMetadata = ({
|
|
8177
|
+
SeriesInstanceUID,
|
|
8178
|
+
StudyInstanceUID
|
|
8179
|
+
}) => {
|
|
7335
8180
|
const {
|
|
7336
8181
|
instances
|
|
7337
8182
|
} = src.DicomMetadataStore.getSeries(StudyInstanceUID, SeriesInstanceUID);
|
|
8183
|
+
if (!instances?.length) {
|
|
8184
|
+
return;
|
|
8185
|
+
}
|
|
7338
8186
|
const modality = instances[0].Modality;
|
|
7339
|
-
if (modality !== 'PT') {
|
|
8187
|
+
if (!modality || modality !== 'PT') {
|
|
7340
8188
|
return;
|
|
7341
8189
|
}
|
|
7342
8190
|
const imageIds = instances.map(instance => instance.imageId);
|
|
7343
8191
|
const instanceMetadataArray = [];
|
|
7344
|
-
imageIds.forEach(imageId => {
|
|
7345
|
-
const instanceMetadata = getPTImageIdInstanceMetadata(imageId);
|
|
7346
|
-
if (instanceMetadata) {
|
|
7347
|
-
instanceMetadataArray.push(instanceMetadata);
|
|
7348
|
-
}
|
|
7349
|
-
});
|
|
7350
|
-
if (!instanceMetadataArray.length) {
|
|
7351
|
-
return;
|
|
7352
|
-
}
|
|
7353
8192
|
|
|
7354
8193
|
// try except block to prevent errors when the metadata is not correct
|
|
7355
|
-
let suvScalingFactors;
|
|
7356
8194
|
try {
|
|
7357
|
-
|
|
8195
|
+
imageIds.forEach(imageId => {
|
|
8196
|
+
const instanceMetadata = getPTImageIdInstanceMetadata(imageId);
|
|
8197
|
+
if (instanceMetadata) {
|
|
8198
|
+
instanceMetadataArray.push(instanceMetadata);
|
|
8199
|
+
}
|
|
8200
|
+
});
|
|
8201
|
+
if (!instanceMetadataArray.length) {
|
|
8202
|
+
return;
|
|
8203
|
+
}
|
|
8204
|
+
const suvScalingFactors = (0,calculate_suv_esm/* calculateSUVScalingFactors */.C)(instanceMetadataArray);
|
|
8205
|
+
instanceMetadataArray.forEach((instanceMetadata, index) => {
|
|
8206
|
+
init_metadataProvider.addCustomMetadata(imageIds[index], 'scalingModule', suvScalingFactors[index]);
|
|
8207
|
+
});
|
|
7358
8208
|
} catch (error) {
|
|
7359
8209
|
console.log(error);
|
|
7360
8210
|
}
|
|
7361
|
-
if (!suvScalingFactors) {
|
|
7362
|
-
return;
|
|
7363
|
-
}
|
|
7364
|
-
instanceMetadataArray.forEach((instanceMetadata, index) => {
|
|
7365
|
-
init_metadataProvider.addCustomMetadata(imageIds[index], 'scalingModule', suvScalingFactors[index]);
|
|
7366
|
-
});
|
|
7367
8211
|
};
|
|
7368
8212
|
;// CONCATENATED MODULE: ../../../extensions/default/src/DicomWebDataSource/utils/index.ts
|
|
7369
8213
|
|
|
@@ -7384,6 +8228,8 @@ const handlePETImageMetadata = _ref2 => {
|
|
|
7384
8228
|
|
|
7385
8229
|
|
|
7386
8230
|
|
|
8231
|
+
|
|
8232
|
+
|
|
7387
8233
|
const defaultExtension = {
|
|
7388
8234
|
/**
|
|
7389
8235
|
* Only required property. Should be a unique value across all extensions.
|
|
@@ -7391,16 +8237,16 @@ const defaultExtension = {
|
|
|
7391
8237
|
id: id,
|
|
7392
8238
|
preRegistration: init,
|
|
7393
8239
|
getDataSourcesModule: src_getDataSourcesModule,
|
|
8240
|
+
getViewportModule: getViewportModule,
|
|
7394
8241
|
getLayoutTemplateModule: getLayoutTemplateModule,
|
|
7395
8242
|
getPanelModule: src_getPanelModule,
|
|
7396
8243
|
getHangingProtocolModule: src_getHangingProtocolModule,
|
|
7397
8244
|
getSopClassHandlerModule: src_getSopClassHandlerModule,
|
|
7398
8245
|
getToolbarModule: getToolbarModule,
|
|
7399
8246
|
getCommandsModule: src_commandsModule,
|
|
7400
|
-
getUtilityModule(
|
|
7401
|
-
|
|
7402
|
-
|
|
7403
|
-
} = _ref;
|
|
8247
|
+
getUtilityModule({
|
|
8248
|
+
servicesManager
|
|
8249
|
+
}) {
|
|
7404
8250
|
return [{
|
|
7405
8251
|
name: 'common',
|
|
7406
8252
|
exports: {
|