@ohif/app 3.13.0-beta.42 → 3.13.0-beta.43
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/{3461.bundle.d418652280863f312da3.js → 3461.bundle.829d07239cde6238db7b.js} +24 -47
- package/dist/{4688.bundle.114adcc40c407ed7d18c.js → 4688.bundle.4e3a2e7fe6353e18fc9d.js} +1 -35
- package/dist/{4819.bundle.0cd1049e47d4d46ef63a.js → 4819.bundle.cdf38c8daa32fe3750a1.js} +3 -2
- package/dist/{8305.bundle.d907ab2a252d536ac865.js → 8305.bundle.ac779a289cb3546a1c6f.js} +50 -47
- package/dist/{8963.bundle.bc2e871cbd92e9fdbbf5.js → 8963.bundle.0a71d2361f66b5b7cafb.js} +2 -10
- package/dist/{9195.bundle.5c8fc381c7a8b1b81c43.js → 9195.bundle.dba57be4160f9d16add7.js} +131 -33
- package/dist/{app.bundle.ced82ce0abbd3feb867e.js → app.bundle.b46025f18465373b69c8.js} +2 -2
- package/dist/app.bundle.css +1 -1
- package/dist/index.html +1 -1
- package/dist/sw.js +1 -1
- package/package.json +20 -20
- /package/dist/{1459.bundle.725b4e9d2776ac9063c5.js → 1459.bundle.4c73589f64b0a48f4909.js} +0 -0
- /package/dist/{1933.bundle.928939cb97edcea28e7b.js → 1933.bundle.562738060267f493cc6e.js} +0 -0
- /package/dist/{2018.bundle.4b011332d36e85206cad.js → 2018.bundle.10ef888cc022e5747c50.js} +0 -0
- /package/dist/{213.bundle.9ef487e1b9adb9381590.js → 213.bundle.544cda23ae0bd2ba23c0.js} +0 -0
- /package/dist/{2424.bundle.9fbd98a379415bcd4ba9.js → 2424.bundle.f17b736977f093c8a9e8.js} +0 -0
- /package/dist/{3138.bundle.55d79e6af7d392cef911.js → 3138.bundle.dbfd7894410e6cd46a7d.js} +0 -0
- /package/dist/{4507.bundle.f78fab196e3f5ed59403.js → 4507.bundle.03dcbcf3c4f91798eff6.js} +0 -0
- /package/dist/{5015.bundle.34a8788caa0bf258d194.js → 5015.bundle.29198e03f89301ce5bd3.js} +0 -0
- /package/dist/{5028.bundle.1778b95ef2d721eff71c.js → 5028.bundle.8760e2ac53c879ec1691.js} +0 -0
- /package/dist/{5457.bundle.ee27e2890a04e64a44bf.js → 5457.bundle.38d66e2219fe030a96f8.js} +0 -0
- /package/dist/{5485.bundle.079cc5bd705f725c8f5d.js → 5485.bundle.f6e2a62b3098278eb7a0.js} +0 -0
- /package/dist/{6027.bundle.ce0fd76251e773c5d5e4.js → 6027.bundle.2cac6718b062d2fe3049.js} +0 -0
- /package/dist/{7639.bundle.d2d03567252e749428a6.js → 7639.bundle.c3e8537955e4865b9112.js} +0 -0
- /package/dist/{8499.bundle.4cbe5e98f5046cd25fc6.js → 8499.bundle.f15599f9f64bea98bfdb.js} +0 -0
- /package/dist/{85.bundle.79c5681051a031061e4d.js → 85.bundle.32beb09c95da00fcf5a1.js} +0 -0
- /package/dist/{8558.bundle.8124019bdb429709a049.js → 8558.bundle.723cdf968e65ae08468b.js} +0 -0
- /package/dist/{8583.bundle.6b74cee293a1a1e950af.js → 8583.bundle.e80cd615ebfc5ee5c18a.js} +0 -0
- /package/dist/{9927.bundle.7af41804c41122527790.js → 9927.bundle.6a13238e6d47189e4e89.js} +0 -0
|
@@ -980,16 +980,25 @@ function _processNonGeometricallyDefinedMeasurement(mergedContentSequence) {
|
|
|
980
980
|
MeasuredValueSequence
|
|
981
981
|
} = item;
|
|
982
982
|
|
|
983
|
-
// Handle spatial reference ONLY if ContentSequence exists
|
|
983
|
+
// Handle spatial reference ONLY if ContentSequence exists.
|
|
984
|
+
// ContentSequence may be a scalar SCOORD or an array when additional named
|
|
985
|
+
// SCOORDs (e.g. control points) are nested alongside the primary geometry.
|
|
986
|
+
// Pick the primary geometry entry: prefer the SCOORD without a
|
|
987
|
+
// ConceptNameCodeSequence (plain polyline), falling back to the first SCOORD.
|
|
984
988
|
if (ContentSequence) {
|
|
989
|
+
const scoordItem = Array.isArray(ContentSequence) ? ContentSequence.find(cs => (cs.ValueType === 'SCOORD' || cs.ValueType === 'SCOORD3D') && !cs.ConceptNameCodeSequence) ?? ContentSequence.find(cs => cs.ValueType === 'SCOORD' || cs.ValueType === 'SCOORD3D') : ContentSequence;
|
|
990
|
+
if (!scoordItem) {
|
|
991
|
+
console.warn('ContentSequence array contains no SCOORD or SCOORD3D entry, skipping annotation.');
|
|
992
|
+
return;
|
|
993
|
+
}
|
|
985
994
|
const {
|
|
986
995
|
ValueType
|
|
987
|
-
} =
|
|
996
|
+
} = scoordItem;
|
|
988
997
|
if (ValueType !== 'SCOORD' && ValueType !== 'SCOORD3D') {
|
|
989
998
|
console.warn(`Graphic ${ValueType} not currently supported, skipping annotation.`);
|
|
990
999
|
return;
|
|
991
1000
|
}
|
|
992
|
-
const coords = _getCoordsFromSCOORDOrSCOORD3D(
|
|
1001
|
+
const coords = _getCoordsFromSCOORDOrSCOORD3D(scoordItem);
|
|
993
1002
|
if (coords) {
|
|
994
1003
|
measurement.coords.push(coords);
|
|
995
1004
|
}
|
|
@@ -1190,8 +1199,6 @@ function onModeEnter({
|
|
|
1190
1199
|
ds.isHydrated = false;
|
|
1191
1200
|
});
|
|
1192
1201
|
}
|
|
1193
|
-
// EXTERNAL MODULE: ../../../node_modules/dcmjs/build/dcmjs.es.js
|
|
1194
|
-
var dcmjs_es = __webpack_require__(5842);
|
|
1195
1202
|
;// ../../../extensions/cornerstone-dicom-sr/src/utils/getFilteredCornerstoneToolState.ts
|
|
1196
1203
|
|
|
1197
1204
|
|
|
@@ -1680,10 +1687,6 @@ function choosePoints(points) {
|
|
|
1680
1687
|
|
|
1681
1688
|
|
|
1682
1689
|
|
|
1683
|
-
|
|
1684
|
-
const {
|
|
1685
|
-
downloadBlob
|
|
1686
|
-
} = src/* utils */.Wp;
|
|
1687
1690
|
const {
|
|
1688
1691
|
MeasurementReport: commandsModule_MeasurementReport
|
|
1689
1692
|
} = esm/* adaptersSR */.QX.Cornerstone3D;
|
|
@@ -1745,29 +1748,8 @@ const commandsModule = props => {
|
|
|
1745
1748
|
/**
|
|
1746
1749
|
*
|
|
1747
1750
|
* @param measurementData An array of measurements from the measurements service
|
|
1748
|
-
* @param additionalFindingTypes toolTypes that should be stored with labels as Findings
|
|
1749
|
-
* @param options Naturalized DICOM JSON headers to merge into the displaySet.
|
|
1750
|
-
* as opposed to Finding Sites.
|
|
1751
1751
|
* that you wish to serialize.
|
|
1752
|
-
|
|
1753
|
-
downloadReport: ({
|
|
1754
|
-
measurementData,
|
|
1755
|
-
additionalFindingTypes,
|
|
1756
|
-
options = {}
|
|
1757
|
-
}) => {
|
|
1758
|
-
const srDataset = _generateReport(measurementData, additionalFindingTypes, options);
|
|
1759
|
-
const reportBlob = dcmjs_es/* default.data */.Ay.data.datasetToBlob(srDataset);
|
|
1760
|
-
|
|
1761
|
-
//Create a URL for the binary.
|
|
1762
|
-
downloadBlob(reportBlob, {
|
|
1763
|
-
filename: 'dicom-sr.dcm'
|
|
1764
|
-
});
|
|
1765
|
-
},
|
|
1766
|
-
/**
|
|
1767
|
-
*
|
|
1768
|
-
* @param measurementData An array of measurements from the measurements service
|
|
1769
|
-
* that you wish to serialize.
|
|
1770
|
-
* @param dataSource The dataSource that you wish to use to persist the data.
|
|
1752
|
+
* @param dataSource The data source name ('download', 'copyToClipboard', or a named data source).
|
|
1771
1753
|
* @param additionalFindingTypes toolTypes that should be stored with labels as Findings
|
|
1772
1754
|
* @param options Naturalized DICOM JSON headers to merge into the displaySet.
|
|
1773
1755
|
* @return The naturalized report
|
|
@@ -1778,23 +1760,24 @@ const commandsModule = props => {
|
|
|
1778
1760
|
additionalFindingTypes,
|
|
1779
1761
|
options = {}
|
|
1780
1762
|
}) => {
|
|
1781
|
-
// Use the @cornerstonejs adapter for converting to/from DICOM
|
|
1782
|
-
// But it is good enough for now whilst we only have cornerstone as a datasource.
|
|
1783
1763
|
log.info('[DICOMSR] storeMeasurements');
|
|
1784
|
-
|
|
1785
|
-
|
|
1764
|
+
const storeFn = commandsManager.runCommand('createStoreFunction', {
|
|
1765
|
+
dataSource,
|
|
1766
|
+
defaultFileName: 'dicom-sr.dcm'
|
|
1767
|
+
});
|
|
1768
|
+
if (!storeFn) {
|
|
1769
|
+
log.error('[DICOMSR] No valid store for dataSource:', dataSource);
|
|
1786
1770
|
return Promise.reject({});
|
|
1787
1771
|
}
|
|
1788
1772
|
try {
|
|
1789
1773
|
const naturalizedReport = _generateReport(measurementData, additionalFindingTypes, options);
|
|
1790
1774
|
const {
|
|
1791
|
-
StudyInstanceUID,
|
|
1792
1775
|
ContentSequence
|
|
1793
1776
|
} = naturalizedReport;
|
|
1794
1777
|
// The content sequence has 5 or more elements, of which
|
|
1795
1778
|
// the `[4]` element contains the annotation data, so this is
|
|
1796
1779
|
// checking that there is some annotation data present.
|
|
1797
|
-
if (!ContentSequence?.[4]
|
|
1780
|
+
if (!ContentSequence?.[4]?.ContentSequence?.length) {
|
|
1798
1781
|
console.log('naturalizedReport missing imaging content', naturalizedReport);
|
|
1799
1782
|
throw new Error('Invalid report, no content');
|
|
1800
1783
|
}
|
|
@@ -1810,15 +1793,10 @@ const commandsModule = props => {
|
|
|
1810
1793
|
naturalizedReport
|
|
1811
1794
|
});
|
|
1812
1795
|
}
|
|
1813
|
-
await
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
}
|
|
1817
|
-
|
|
1818
|
-
// The "Mode" route listens for DicomMetadataStore changes
|
|
1819
|
-
// When a new instance is added, it listens and
|
|
1820
|
-
// automatically calls makeDisplaySets
|
|
1821
|
-
src/* DicomMetadataStore */.H8.addInstances([naturalizedReport], true);
|
|
1796
|
+
await storeFn(naturalizedReport, {
|
|
1797
|
+
measurementData,
|
|
1798
|
+
dicomDict
|
|
1799
|
+
});
|
|
1822
1800
|
return naturalizedReport;
|
|
1823
1801
|
} catch (error) {
|
|
1824
1802
|
console.warn(error);
|
|
@@ -1841,7 +1819,6 @@ const commandsModule = props => {
|
|
|
1841
1819
|
}
|
|
1842
1820
|
};
|
|
1843
1821
|
const definitions = {
|
|
1844
|
-
downloadReport: actions.downloadReport,
|
|
1845
1822
|
storeMeasurements: actions.storeMeasurements,
|
|
1846
1823
|
hydrateStructuredReport: actions.hydrateStructuredReport
|
|
1847
1824
|
};
|
|
@@ -7442,37 +7442,13 @@ const ExportSegmentationSubMenuItem = ({
|
|
|
7442
7442
|
className: "text-foreground"
|
|
7443
7443
|
}), /*#__PURE__*/react.createElement("span", {
|
|
7444
7444
|
className: "pl-2"
|
|
7445
|
-
}, t('
|
|
7446
|
-
className: "flex items-center pl-0"
|
|
7447
|
-
}, /*#__PURE__*/react.createElement(ui_next_src/* Icons */.FI1.Download, {
|
|
7448
|
-
className: "h-5 w-5"
|
|
7449
|
-
}), /*#__PURE__*/react.createElement("span", {
|
|
7450
|
-
className: "pl-1"
|
|
7451
|
-
}, t('Download'))), segmentationRepresentationType === esm_enums.SegmentationRepresentations.Labelmap && /*#__PURE__*/react.createElement(ui_next_src/* DropdownMenuItem */._26, {
|
|
7445
|
+
}, t('Export'))), /*#__PURE__*/react.createElement(ui_next_src/* DropdownMenuPortal */.dce, null, /*#__PURE__*/react.createElement(ui_next_src/* DropdownMenuSubContent */.M56, null, segmentationRepresentationType === esm_enums.SegmentationRepresentations.Labelmap && /*#__PURE__*/react.createElement(ui_next_src/* DropdownMenuItem */._26, {
|
|
7452
7446
|
onClick: e => {
|
|
7453
7447
|
e.preventDefault();
|
|
7454
7448
|
actions.downloadCSVSegmentationReport(segmentationId);
|
|
7455
7449
|
},
|
|
7456
7450
|
disabled: !allowExport
|
|
7457
7451
|
}, t('CSV Report')), segmentationRepresentationType === esm_enums.SegmentationRepresentations.Labelmap && /*#__PURE__*/react.createElement(ui_next_src/* DropdownMenuItem */._26, {
|
|
7458
|
-
onClick: e => {
|
|
7459
|
-
e.preventDefault();
|
|
7460
|
-
actions.onSegmentationDownload(segmentationId);
|
|
7461
|
-
},
|
|
7462
|
-
disabled: !allowExport
|
|
7463
|
-
}, t('DICOM SEG')), /*#__PURE__*/react.createElement(ui_next_src/* DropdownMenuItem */._26, {
|
|
7464
|
-
onClick: e => {
|
|
7465
|
-
e.preventDefault();
|
|
7466
|
-
actions.onSegmentationDownloadRTSS(segmentationId);
|
|
7467
|
-
},
|
|
7468
|
-
disabled: !allowExport
|
|
7469
|
-
}, t('DICOM RTSS')), /*#__PURE__*/react.createElement(ui_next_src/* DropdownMenuSeparator */.mBJ, null), /*#__PURE__*/react.createElement(ui_next_src/* DropdownMenuLabel */.lpj, {
|
|
7470
|
-
className: "flex items-center pl-0"
|
|
7471
|
-
}, /*#__PURE__*/react.createElement(ui_next_src/* Icons */.FI1.Export, {
|
|
7472
|
-
className: "h-5 w-5"
|
|
7473
|
-
}), /*#__PURE__*/react.createElement("span", {
|
|
7474
|
-
className: "pl-1 pt-1"
|
|
7475
|
-
}, t('Export'))), segmentationRepresentationType === esm_enums.SegmentationRepresentations.Labelmap && /*#__PURE__*/react.createElement(ui_next_src/* DropdownMenuItem */._26, {
|
|
7476
7452
|
onClick: e => {
|
|
7477
7453
|
e.preventDefault();
|
|
7478
7454
|
actions.storeSegmentation(segmentationId, 'SEG');
|
|
@@ -7549,16 +7525,6 @@ const CustomDropdownMenuContent = () => {
|
|
|
7549
7525
|
context: 'CORNERSTONE'
|
|
7550
7526
|
});
|
|
7551
7527
|
},
|
|
7552
|
-
onSegmentationDownloadRTSS: segmentationId => {
|
|
7553
|
-
commandsManager.run('downloadRTSS', {
|
|
7554
|
-
segmentationId
|
|
7555
|
-
});
|
|
7556
|
-
},
|
|
7557
|
-
onSegmentationDownload: segmentationId => {
|
|
7558
|
-
commandsManager.run('downloadSegmentation', {
|
|
7559
|
-
segmentationId
|
|
7560
|
-
});
|
|
7561
|
-
},
|
|
7562
7528
|
downloadCSVSegmentationReport: segmentationId => {
|
|
7563
7529
|
commandsManager.run('downloadCSVSegmentationReport', {
|
|
7564
7530
|
segmentationId
|
|
@@ -803,8 +803,9 @@ function TrackedMeasurementsContextProvider({
|
|
|
803
803
|
});
|
|
804
804
|
},
|
|
805
805
|
showStructuredReportDisplaySetInActiveViewport: (ctx, evt) => {
|
|
806
|
-
|
|
807
|
-
|
|
806
|
+
const uids = evt.data?.createdDisplaySetInstanceUIDs;
|
|
807
|
+
if (uids?.length > 0) {
|
|
808
|
+
const StructuredReportDisplaySetInstanceUID = uids[0];
|
|
808
809
|
viewportGridService.setDisplaySetsForViewport({
|
|
809
810
|
viewportId: evt.data.viewportId,
|
|
810
811
|
displaySetInstanceUIDs: [StructuredReportDisplaySetInstanceUID]
|
|
@@ -363,7 +363,6 @@ var PROMPT_RESPONSES = __webpack_require__(96357);
|
|
|
363
363
|
|
|
364
364
|
|
|
365
365
|
|
|
366
|
-
|
|
367
366
|
const getTargetViewport = ({
|
|
368
367
|
viewportId,
|
|
369
368
|
viewportGridService
|
|
@@ -390,12 +389,10 @@ const {
|
|
|
390
389
|
}
|
|
391
390
|
}
|
|
392
391
|
} = adapters_dist_esm/* adaptersRT */.f_;
|
|
393
|
-
const {
|
|
394
|
-
/* downloadDICOMData */ "vk": downloadDICOMData
|
|
395
|
-
} = adapters_dist_esm/* helpers */._$;
|
|
396
392
|
const commandsModule = ({
|
|
397
393
|
servicesManager,
|
|
398
|
-
extensionManager
|
|
394
|
+
extensionManager,
|
|
395
|
+
commandsManager
|
|
399
396
|
}) => {
|
|
400
397
|
const {
|
|
401
398
|
segmentationService,
|
|
@@ -548,7 +545,11 @@ const commandsModule = ({
|
|
|
548
545
|
const generatedSegmentation = actions.generateSegmentation({
|
|
549
546
|
segmentationId
|
|
550
547
|
});
|
|
551
|
-
|
|
548
|
+
const storeFn = commandsManager.runCommand('createStoreFunction', {
|
|
549
|
+
dataSource: 'download',
|
|
550
|
+
defaultFileName: `${segmentationInOHIF.label}.dcm`
|
|
551
|
+
});
|
|
552
|
+
storeFn(generatedSegmentation.dataset);
|
|
552
553
|
},
|
|
553
554
|
/**
|
|
554
555
|
* Stores a segmentation based on the provided segmentationId into a specified data source.
|
|
@@ -575,10 +576,9 @@ const commandsModule = ({
|
|
|
575
576
|
label,
|
|
576
577
|
predecessorImageId
|
|
577
578
|
} = segmentation;
|
|
578
|
-
const defaultDataSource = dataSource ?? extensionManager.getActiveDataSource()[0];
|
|
579
579
|
const {
|
|
580
580
|
value: reportName,
|
|
581
|
-
dataSourceName
|
|
581
|
+
dataSourceName,
|
|
582
582
|
series,
|
|
583
583
|
priorSeriesNumber,
|
|
584
584
|
action
|
|
@@ -587,42 +587,47 @@ const commandsModule = ({
|
|
|
587
587
|
extensionManager,
|
|
588
588
|
predecessorImageId,
|
|
589
589
|
title: 'Store Segmentation',
|
|
590
|
-
modality
|
|
590
|
+
modality,
|
|
591
|
+
enableDownload: true
|
|
591
592
|
});
|
|
592
|
-
if (action
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
} = generatedData;
|
|
611
|
-
|
|
612
|
-
// DCMJS assigns a dummy study id during creation, and this can cause problems, so clearing it out
|
|
613
|
-
if (naturalizedReport.StudyID === 'No Study ID') {
|
|
614
|
-
naturalizedReport.StudyID = '';
|
|
593
|
+
if (action !== PROMPT_RESPONSES/* default */.A.CREATE_REPORT) {
|
|
594
|
+
return;
|
|
595
|
+
}
|
|
596
|
+
const defaultFileName = modality === 'RTSTRUCT' ? `rtss-${segmentationId}.dcm` : `${label || 'segmentation'}.dcm`;
|
|
597
|
+
const storeFn = commandsManager.runCommand('createStoreFunction', {
|
|
598
|
+
dataSource: dataSourceName,
|
|
599
|
+
defaultFileName
|
|
600
|
+
});
|
|
601
|
+
if (!storeFn) {
|
|
602
|
+
throw new Error(`No valid store for dataSource: ${dataSourceName}`);
|
|
603
|
+
}
|
|
604
|
+
try {
|
|
605
|
+
const args = {
|
|
606
|
+
segmentationId,
|
|
607
|
+
options: {
|
|
608
|
+
SeriesDescription: series ? undefined : reportName || label || 'Contour Series',
|
|
609
|
+
SeriesNumber: series ? undefined : 1 + priorSeriesNumber,
|
|
610
|
+
predecessorImageId: series
|
|
615
611
|
}
|
|
616
|
-
|
|
612
|
+
};
|
|
613
|
+
const generatedDataAsync = modality === 'SEG' && actions.generateSegmentation(args) || modality === 'RTSTRUCT' && actions.generateContour(args);
|
|
614
|
+
const generatedData = await generatedDataAsync;
|
|
615
|
+
if (!generatedData?.dataset) {
|
|
616
|
+
throw new Error('Error during segmentation generation');
|
|
617
|
+
}
|
|
618
|
+
const {
|
|
619
|
+
dataset: naturalizedReport
|
|
620
|
+
} = generatedData;
|
|
617
621
|
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
return naturalizedReport;
|
|
622
|
-
} catch (error) {
|
|
623
|
-
console.debug('Error storing segmentation:', error);
|
|
624
|
-
throw error;
|
|
622
|
+
// DCMJS assigns a dummy study id during creation, and this can cause problems, so clearing it out
|
|
623
|
+
if (naturalizedReport.StudyID === 'No Study ID') {
|
|
624
|
+
naturalizedReport.StudyID = '';
|
|
625
625
|
}
|
|
626
|
+
await storeFn(naturalizedReport, {});
|
|
627
|
+
return naturalizedReport;
|
|
628
|
+
} catch (error) {
|
|
629
|
+
console.debug('Error storing segmentation:', error);
|
|
630
|
+
throw error;
|
|
626
631
|
}
|
|
627
632
|
},
|
|
628
633
|
generateContour: async args => {
|
|
@@ -658,13 +663,11 @@ const commandsModule = ({
|
|
|
658
663
|
InstanceNumber: instanceNumber = 1,
|
|
659
664
|
SeriesInstanceUID: seriesUID
|
|
660
665
|
} = dataset;
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
console.warn(e);
|
|
667
|
-
}
|
|
666
|
+
const storeFn = commandsManager.runCommand('createStoreFunction', {
|
|
667
|
+
dataSource: 'download',
|
|
668
|
+
defaultFileName: `rtss-${seriesUID}-${instanceNumber}.dcm`
|
|
669
|
+
});
|
|
670
|
+
await storeFn(dataset);
|
|
668
671
|
},
|
|
669
672
|
toggleActiveSegmentationUtility: ({
|
|
670
673
|
itemId: buttonId
|
|
@@ -12,11 +12,10 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
12
12
|
X6: () => (/* reexport */ adaptersPMAP),
|
|
13
13
|
f_: () => (/* reexport */ adaptersRT),
|
|
14
14
|
ql: () => (/* reexport */ adaptersSEG),
|
|
15
|
-
QX: () => (/* reexport */ adaptersSR)
|
|
16
|
-
_$: () => (/* reexport */ helpers_namespaceObject)
|
|
15
|
+
QX: () => (/* reexport */ adaptersSR)
|
|
17
16
|
});
|
|
18
17
|
|
|
19
|
-
// UNUSED EXPORTS: utilities
|
|
18
|
+
// UNUSED EXPORTS: helpers, utilities
|
|
20
19
|
|
|
21
20
|
// NAMESPACE OBJECT: ../../../node_modules/@cornerstonejs/adapters/dist/esm/adapters/Cornerstone/Segmentation.js
|
|
22
21
|
var Segmentation_namespaceObject = {};
|
|
@@ -63,13 +62,6 @@ __webpack_require__.d(enums_namespaceObject, {
|
|
|
63
62
|
s: () => (Events)
|
|
64
63
|
});
|
|
65
64
|
|
|
66
|
-
// NAMESPACE OBJECT: ../../../node_modules/@cornerstonejs/adapters/dist/esm/adapters/helpers/index.js
|
|
67
|
-
var helpers_namespaceObject = {};
|
|
68
|
-
__webpack_require__.r(helpers_namespaceObject);
|
|
69
|
-
__webpack_require__.d(helpers_namespaceObject, {
|
|
70
|
-
vk: () => (downloadDICOMData)
|
|
71
|
-
});
|
|
72
|
-
|
|
73
65
|
// EXTERNAL MODULE: ../../../node_modules/dcmjs/build/dcmjs.es.js
|
|
74
66
|
var dcmjs_es = __webpack_require__(5842);
|
|
75
67
|
;// ../../../node_modules/@cornerstonejs/adapters/dist/esm/adapters/helpers/toArray.js
|
|
@@ -4663,7 +4663,8 @@ function CreateReportDialogPrompt({
|
|
|
4663
4663
|
minSeriesNumber = 0,
|
|
4664
4664
|
predecessorImageId,
|
|
4665
4665
|
extensionManager,
|
|
4666
|
-
servicesManager
|
|
4666
|
+
servicesManager,
|
|
4667
|
+
enableDownload = false
|
|
4667
4668
|
}) {
|
|
4668
4669
|
const {
|
|
4669
4670
|
uiDialogService,
|
|
@@ -4683,6 +4684,7 @@ function CreateReportDialogPrompt({
|
|
|
4683
4684
|
predecessorImageId,
|
|
4684
4685
|
minSeriesNumber,
|
|
4685
4686
|
modality,
|
|
4687
|
+
enableDownload,
|
|
4686
4688
|
onSave: async ({
|
|
4687
4689
|
reportName,
|
|
4688
4690
|
dataSource: selectedDataSource,
|
|
@@ -7516,8 +7518,6 @@ const useToggleOneUpViewportGridStore = (0,zustand_esm/* create */.vt)(set => ({
|
|
|
7516
7518
|
})
|
|
7517
7519
|
}));
|
|
7518
7520
|
;// ../../../extensions/default/src/Actions/createReportAsync.tsx
|
|
7519
|
-
|
|
7520
|
-
|
|
7521
7521
|
/**
|
|
7522
7522
|
*
|
|
7523
7523
|
* @param {*} servicesManager
|
|
@@ -7525,7 +7525,8 @@ const useToggleOneUpViewportGridStore = (0,zustand_esm/* create */.vt)(set => ({
|
|
|
7525
7525
|
async function createReportAsync({
|
|
7526
7526
|
servicesManager,
|
|
7527
7527
|
getReport,
|
|
7528
|
-
reportType = '
|
|
7528
|
+
reportType = 'Measurements',
|
|
7529
|
+
successMessage
|
|
7529
7530
|
}) {
|
|
7530
7531
|
const {
|
|
7531
7532
|
displaySetService,
|
|
@@ -7538,15 +7539,13 @@ async function createReportAsync({
|
|
|
7538
7539
|
return;
|
|
7539
7540
|
}
|
|
7540
7541
|
|
|
7541
|
-
//
|
|
7542
|
-
//
|
|
7543
|
-
// automatically calls makeDisplaySets
|
|
7544
|
-
src/* DicomMetadataStore */.H8.addInstances([naturalizedReport], true);
|
|
7542
|
+
// addInstances is called by the store command (storeMeasurements/storeSegmentation),
|
|
7543
|
+
// so the display set should already exist at this point.
|
|
7545
7544
|
const displaySet = displaySetService.getMostRecentDisplaySet();
|
|
7546
7545
|
const displaySetInstanceUID = displaySet.displaySetInstanceUID;
|
|
7547
7546
|
uiNotificationService.show({
|
|
7548
7547
|
title: 'Create Report',
|
|
7549
|
-
message: `${reportType} saved successfully`,
|
|
7548
|
+
message: successMessage ?? `${reportType} saved successfully`,
|
|
7550
7549
|
type: 'success'
|
|
7551
7550
|
});
|
|
7552
7551
|
return [displaySetInstanceUID];
|
|
@@ -7602,34 +7601,32 @@ async function promptSaveReport({
|
|
|
7602
7601
|
predecessorImageId,
|
|
7603
7602
|
minSeriesNumber: 3000,
|
|
7604
7603
|
extensionManager,
|
|
7605
|
-
servicesManager
|
|
7604
|
+
servicesManager,
|
|
7605
|
+
enableDownload: true
|
|
7606
7606
|
});
|
|
7607
7607
|
if (promptResult.action === PROMPT_RESPONSES/* default */.A.CREATE_REPORT) {
|
|
7608
|
-
const dataSources = extensionManager.getDataSources(promptResult.dataSourceName);
|
|
7609
|
-
const dataSource = dataSources[0];
|
|
7610
7608
|
const {
|
|
7611
7609
|
series,
|
|
7612
7610
|
priorSeriesNumber,
|
|
7613
|
-
value: reportName
|
|
7611
|
+
value: reportName,
|
|
7612
|
+
dataSourceName
|
|
7614
7613
|
} = promptResult;
|
|
7615
7614
|
const SeriesDescription = reportName || defaultSaveTitle;
|
|
7616
|
-
const getReport = async () => {
|
|
7617
|
-
|
|
7618
|
-
|
|
7619
|
-
|
|
7620
|
-
|
|
7621
|
-
|
|
7622
|
-
|
|
7623
|
-
|
|
7624
|
-
|
|
7625
|
-
|
|
7626
|
-
}, 'CORNERSTONE_STRUCTURED_REPORT');
|
|
7627
|
-
};
|
|
7615
|
+
const getReport = async () => commandsManager.runCommand('storeMeasurements', {
|
|
7616
|
+
measurementData,
|
|
7617
|
+
dataSource: dataSourceName,
|
|
7618
|
+
additionalFindingTypes: ['ArrowAnnotate'],
|
|
7619
|
+
options: {
|
|
7620
|
+
SeriesDescription,
|
|
7621
|
+
SeriesNumber: 1 + priorSeriesNumber,
|
|
7622
|
+
predecessorImageId: series
|
|
7623
|
+
}
|
|
7624
|
+
}, 'CORNERSTONE_STRUCTURED_REPORT');
|
|
7628
7625
|
displaySetInstanceUIDs = await Actions_createReportAsync({
|
|
7629
7626
|
servicesManager,
|
|
7630
7627
|
getReport
|
|
7631
7628
|
});
|
|
7632
|
-
} else if (promptResult.action ===
|
|
7629
|
+
} else if (promptResult.action === PROMPT_RESPONSES/* default */.A.CANCEL) {
|
|
7633
7630
|
// Do nothing
|
|
7634
7631
|
}
|
|
7635
7632
|
return {
|
|
@@ -7661,6 +7658,10 @@ function findPredecessorImageId(annotations) {
|
|
|
7661
7658
|
;// ../../../extensions/default/src/commandsModule.ts
|
|
7662
7659
|
|
|
7663
7660
|
|
|
7661
|
+
const {
|
|
7662
|
+
downloadBlob
|
|
7663
|
+
} = src/* utils */.Wp;
|
|
7664
|
+
|
|
7664
7665
|
|
|
7665
7666
|
|
|
7666
7667
|
|
|
@@ -8381,6 +8382,74 @@ const commandsModule = ({
|
|
|
8381
8382
|
viewportsToUpdate: updatedViewports
|
|
8382
8383
|
});
|
|
8383
8384
|
setTimeout(() => actions.scrollActiveThumbnailIntoView(), 0);
|
|
8385
|
+
},
|
|
8386
|
+
/**
|
|
8387
|
+
* Creates a store function based on the data source type.
|
|
8388
|
+
* @param dataSource - 'download', 'copyToClipboard', or a named data source
|
|
8389
|
+
* @param defaultFileName - Default filename for download/clipboard
|
|
8390
|
+
* @param defaultContentType - Default content type for clipboard
|
|
8391
|
+
* @returns A store function, or null if no valid store exists
|
|
8392
|
+
*/
|
|
8393
|
+
createStoreFunction: ({
|
|
8394
|
+
dataSource,
|
|
8395
|
+
defaultFileName,
|
|
8396
|
+
defaultContentType
|
|
8397
|
+
}) => {
|
|
8398
|
+
if (dataSource === 'download') {
|
|
8399
|
+
return async dicom => {
|
|
8400
|
+
const instances = Array.isArray(dicom) ? dicom : [dicom];
|
|
8401
|
+
src/* DicomMetadataStore */.H8.addInstances(instances, true);
|
|
8402
|
+
if (instances.length !== 1) {
|
|
8403
|
+
throw new Error('Download only supports a single DICOM instance');
|
|
8404
|
+
}
|
|
8405
|
+
const reportBlob = dcmjs_es/* default.data */.Ay.data.datasetToBlob(instances[0]);
|
|
8406
|
+
downloadBlob(reportBlob, {
|
|
8407
|
+
filename: defaultFileName || 'dicom.dcm'
|
|
8408
|
+
});
|
|
8409
|
+
};
|
|
8410
|
+
}
|
|
8411
|
+
if (dataSource === 'copyToClipboard') {
|
|
8412
|
+
return async dicom => {
|
|
8413
|
+
const instances = Array.isArray(dicom) ? dicom : [dicom];
|
|
8414
|
+
src/* DicomMetadataStore */.H8.addInstances(instances, true);
|
|
8415
|
+
if (instances.length !== 1) {
|
|
8416
|
+
throw new Error('Copy to clipboard only supports a single DICOM instance');
|
|
8417
|
+
}
|
|
8418
|
+
const reportBlob = dcmjs_es/* default.data */.Ay.data.datasetToBlob(instances[0]);
|
|
8419
|
+
const type = defaultContentType || 'application/dicom';
|
|
8420
|
+
await navigator.clipboard.write([new ClipboardItem({
|
|
8421
|
+
[type]: new Blob([reportBlob], {
|
|
8422
|
+
type
|
|
8423
|
+
})
|
|
8424
|
+
})]);
|
|
8425
|
+
};
|
|
8426
|
+
}
|
|
8427
|
+
|
|
8428
|
+
// DICOM STOW path — resolve the named data source
|
|
8429
|
+
const dataSources = extensionManager.getDataSources(dataSource);
|
|
8430
|
+
const resolvedDataSource = dataSources?.[0];
|
|
8431
|
+
if (!resolvedDataSource?.store?.dicom) {
|
|
8432
|
+
return null;
|
|
8433
|
+
}
|
|
8434
|
+
return async (dicom, {
|
|
8435
|
+
dicomDict
|
|
8436
|
+
} = {}) => {
|
|
8437
|
+
const instances = Array.isArray(dicom) ? dicom : [dicom];
|
|
8438
|
+
const config = resolvedDataSource.getConfig?.();
|
|
8439
|
+
if (config?.wadoRoot) {
|
|
8440
|
+
instances.forEach(instance => {
|
|
8441
|
+
instance.wadoRoot = config.wadoRoot;
|
|
8442
|
+
});
|
|
8443
|
+
}
|
|
8444
|
+
src/* DicomMetadataStore */.H8.addInstances(instances, true);
|
|
8445
|
+
for (const instance of instances) {
|
|
8446
|
+
await resolvedDataSource.store.dicom(instance, null, dicomDict);
|
|
8447
|
+
}
|
|
8448
|
+
const studyUIDs = new Set(instances.map(i => i.StudyInstanceUID).filter(Boolean));
|
|
8449
|
+
for (const uid of studyUIDs) {
|
|
8450
|
+
resolvedDataSource.deleteStudyMetadataPromise(uid);
|
|
8451
|
+
}
|
|
8452
|
+
};
|
|
8384
8453
|
}
|
|
8385
8454
|
};
|
|
8386
8455
|
const definitions = {
|
|
@@ -8412,7 +8481,8 @@ const commandsModule = ({
|
|
|
8412
8481
|
updateViewportDisplaySet: actions.updateViewportDisplaySet,
|
|
8413
8482
|
scrollActiveThumbnailIntoView: actions.scrollActiveThumbnailIntoView,
|
|
8414
8483
|
addDisplaySetAsLayer: actions.addDisplaySetAsLayer,
|
|
8415
|
-
removeDisplaySetLayer: actions.removeDisplaySetLayer
|
|
8484
|
+
removeDisplaySetLayer: actions.removeDisplaySetLayer,
|
|
8485
|
+
createStoreFunction: actions.createStoreFunction
|
|
8416
8486
|
};
|
|
8417
8487
|
return {
|
|
8418
8488
|
actions,
|
|
@@ -10402,8 +10472,8 @@ function AboutModalDefault() {
|
|
|
10402
10472
|
name
|
|
10403
10473
|
} = (0,browser_detect_es5/* default */.A)();
|
|
10404
10474
|
const browser = `${name[0].toUpperCase()}${name.substr(1)} ${version}`;
|
|
10405
|
-
const versionNumber = "3.13.0-beta.
|
|
10406
|
-
const commitHash = "
|
|
10475
|
+
const versionNumber = "3.13.0-beta.43";
|
|
10476
|
+
const commitHash = "1d4802c2a38dd75dca7afca87913e100453c9135";
|
|
10407
10477
|
const [main, beta] = versionNumber.split('-');
|
|
10408
10478
|
return /*#__PURE__*/react.createElement(ui_next_src/* AboutModal */.VTU, {
|
|
10409
10479
|
className: "w-[400px]"
|
|
@@ -10576,6 +10646,7 @@ function UserPreferencesModalDefault({
|
|
|
10576
10646
|
|
|
10577
10647
|
|
|
10578
10648
|
|
|
10649
|
+
|
|
10579
10650
|
function ReportDialog({
|
|
10580
10651
|
dataSources,
|
|
10581
10652
|
modality = 'SR',
|
|
@@ -10583,11 +10654,16 @@ function ReportDialog({
|
|
|
10583
10654
|
minSeriesNumber = 3000,
|
|
10584
10655
|
hide,
|
|
10585
10656
|
onSave,
|
|
10586
|
-
onCancel
|
|
10657
|
+
onCancel,
|
|
10658
|
+
enableDownload = false
|
|
10587
10659
|
}) {
|
|
10660
|
+
const {
|
|
10661
|
+
t
|
|
10662
|
+
} = (0,es/* useTranslation */.Bd)('Buttons');
|
|
10588
10663
|
const {
|
|
10589
10664
|
servicesManager
|
|
10590
10665
|
} = (0,src/* useSystem */.Jg)();
|
|
10666
|
+
const actionTakenRef = (0,react.useRef)(false);
|
|
10591
10667
|
const [selectedDataSource, setSelectedDataSource] = (0,react.useState)(dataSources?.[0]?.value ?? null);
|
|
10592
10668
|
const {
|
|
10593
10669
|
displaySetService
|
|
@@ -10616,6 +10692,7 @@ function ReportDialog({
|
|
|
10616
10692
|
setReportName(newReportName);
|
|
10617
10693
|
}, [selectedSeries, seriesOptions]);
|
|
10618
10694
|
const handleSave = (0,react.useCallback)(() => {
|
|
10695
|
+
actionTakenRef.current = true;
|
|
10619
10696
|
onSave({
|
|
10620
10697
|
reportName,
|
|
10621
10698
|
dataSource: selectedDataSource,
|
|
@@ -10625,10 +10702,31 @@ function ReportDialog({
|
|
|
10625
10702
|
hide();
|
|
10626
10703
|
}, [selectedDataSource, selectedSeries, reportName, hide, onSave]);
|
|
10627
10704
|
const handleCancel = (0,react.useCallback)(() => {
|
|
10705
|
+
actionTakenRef.current = true;
|
|
10628
10706
|
onCancel();
|
|
10629
10707
|
hide();
|
|
10630
10708
|
}, [onCancel, hide]);
|
|
10709
|
+
const handleDownload = (0,react.useCallback)(() => {
|
|
10710
|
+
actionTakenRef.current = true;
|
|
10711
|
+
onSave({
|
|
10712
|
+
reportName,
|
|
10713
|
+
dataSource: 'download',
|
|
10714
|
+
priorSeriesNumber: Math.max(...seriesOptions.map(it => it.seriesNumber)),
|
|
10715
|
+
series: selectedSeries
|
|
10716
|
+
});
|
|
10717
|
+
hide();
|
|
10718
|
+
}, [selectedDataSource, selectedSeries, reportName, hide, onSave]);
|
|
10719
|
+
|
|
10720
|
+
// Handles the close dialog button/external close as a cancel
|
|
10721
|
+
(0,react.useEffect)(() => {
|
|
10722
|
+
return () => {
|
|
10723
|
+
if (!actionTakenRef.current) {
|
|
10724
|
+
onCancel();
|
|
10725
|
+
}
|
|
10726
|
+
};
|
|
10727
|
+
}, [onCancel]);
|
|
10631
10728
|
const showDataSourceSelect = dataSources?.length > 1;
|
|
10729
|
+
const showDownloadButton = enableDownload;
|
|
10632
10730
|
return /*#__PURE__*/react.createElement("div", {
|
|
10633
10731
|
className: "text-foreground flex min-w-[400px] max-w-md flex-col"
|
|
10634
10732
|
}, /*#__PURE__*/react.createElement("div", {
|
|
@@ -10685,9 +10783,9 @@ function ReportDialog({
|
|
|
10685
10783
|
disabled: !!selectedSeries
|
|
10686
10784
|
})))), /*#__PURE__*/react.createElement("div", {
|
|
10687
10785
|
className: "flex justify-end gap-2"
|
|
10688
|
-
}, /*#__PURE__*/react.createElement(ui_next_src/* InputDialog */.fa0, null, /*#__PURE__*/react.createElement(ui_next_src/* InputDialog */.fa0.Actions, null, /*#__PURE__*/react.createElement(ui_next_src/* InputDialog */.fa0.ActionsSecondary, {
|
|
10689
|
-
onClick:
|
|
10690
|
-
},
|
|
10786
|
+
}, /*#__PURE__*/react.createElement(ui_next_src/* InputDialog */.fa0, null, /*#__PURE__*/react.createElement(ui_next_src/* InputDialog */.fa0.Actions, null, showDownloadButton && /*#__PURE__*/react.createElement(ui_next_src/* InputDialog */.fa0.ActionsSecondary, {
|
|
10787
|
+
onClick: handleDownload
|
|
10788
|
+
}, t('Download')), /*#__PURE__*/react.createElement(ui_next_src/* InputDialog */.fa0.ActionsPrimary, {
|
|
10691
10789
|
onClick: handleSave
|
|
10692
10790
|
}, "Save"))))));
|
|
10693
10791
|
}
|