@ohif/app 3.8.0-beta.73 → 3.8.0-beta.74

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.
Files changed (46) hide show
  1. package/dist/{121.bundle.21827fec690c01ee9ab3.js → 121.bundle.bd8acf52b6a7047ae832.js} +2 -2
  2. package/dist/141.bundle.556b4c1e4cab770417ac.js +8620 -0
  3. package/dist/{191.bundle.c0ea2d031ffddeca32c9.js → 183.bundle.25293de927ef032a6695.js} +195 -122
  4. package/dist/{188.bundle.acfe3c0e6eb9cc90aef1.js → 188.bundle.f1b3909e55be12d37c4a.js} +2 -2
  5. package/dist/{987.bundle.e19408decfd59aadd118.js → 217.bundle.9631d914f170f8d7ef63.js} +31558 -39396
  6. package/dist/{295.bundle.3a0d5062d65296c4bf5d.js → 295.bundle.688b6bbff493cd904ae7.js} +2 -2
  7. package/dist/{155.bundle.64e00e96835d61e99c0e.js → 325.bundle.3d260b1a7f80cfc892a0.js} +43 -58
  8. package/dist/{425.bundle.f796ed1020fbed0f1e71.js → 335.bundle.ec53cc58116ef1dc5fa3.js} +132 -518
  9. package/dist/{342.bundle.521c0217f82380c0c2ad.js → 342.bundle.c6165579c4ac3ef0d6a8.js} +2 -2
  10. package/dist/{41.bundle.8b3f6e6f4bd71b85ef14.js → 41.bundle.3c9bb4e3800dcea2c043.js} +28 -29
  11. package/dist/{433.bundle.6f2308ab10593784778c.js → 433.bundle.1474591f213852cffcba.js} +188 -172
  12. package/dist/{290.bundle.952de53057f98e2c5ef0.js → 445.bundle.38c6d2af64e41cd7c614.js} +1 -1049
  13. package/dist/{448.bundle.19df2fef38bb0f6a272a.js → 448.bundle.e6af6868af55a353b12b.js} +16 -22
  14. package/dist/487.bundle.de932b440ffc809978b5.js +1875 -0
  15. package/dist/{530.bundle.f4b7966fb33eafb8cd5d.js → 530.bundle.7c94543955552475c56a.js} +9 -9
  16. package/dist/{540.bundle.32224b29bfa11d1f1cec.js → 540.bundle.31780163f7065fd4d325.js} +15 -15
  17. package/dist/{544.bundle.1110b24e96863d719a95.js → 544.bundle.fcb790bae53294b49b05.js} +8 -8
  18. package/dist/{574.bundle.2b3369042aad5d553463.js → 574.bundle.b4eb8773d7741868e84b.js} +166 -45
  19. package/dist/{594.bundle.61a9f0567260e9bb4480.js → 594.bundle.6c0b915507752363e82a.js} +4 -4
  20. package/dist/{2.bundle.a849401e1fefc0898248.js → 633.bundle.7f782a390a22d9c7ec1d.js} +35 -43
  21. package/dist/{699.bundle.9f4eddf87548c0d0dca3.js → 699.bundle.7642c1505c1685f63897.js} +18 -35
  22. package/dist/702.bundle.963481fbf871984b646f.js +8426 -0
  23. package/dist/722.bundle.afab1fe6bfcd569130ac.js +1083 -0
  24. package/dist/{724.bundle.b57096deac9649aada4b.js → 724.bundle.ad52afcbec7501305d25.js} +20 -11
  25. package/dist/{90.bundle.70f4752bb4ac79aef269.js → 83.bundle.ff7db010621303a71a50.js} +419 -137
  26. package/dist/{862.bundle.47305c27f0fb939c2f97.js → 862.bundle.f49a379497bb3b43a942.js} +3 -3
  27. package/dist/{889.bundle.3816444220909bd1fc78.js → 889.bundle.67ca151a5e2d653b0021.js} +8 -8
  28. package/dist/{595.bundle.e8ff2d0672cb195d4ab8.js → 896.bundle.ba0b4c73e2331281159f.js} +686 -57
  29. package/dist/{905.bundle.2dd7f62cb6e49851926b.js → 905.bundle.e67fd55073b8ff735ed5.js} +4 -4
  30. package/dist/{907.bundle.d22edc6203167e985ab3.js → 907.bundle.0167da9471dcfa5c862e.js} +2 -2
  31. package/dist/94.bundle.ccec301dfb972a375ecc.js +784 -0
  32. package/dist/{961.bundle.f207f1ac54a174e67d82.js → 961.bundle.711da9767a4e31ea5aef.js} +2 -2
  33. package/dist/{app.bundle.5e5ee16c43a68961e8c4.js → app.bundle.c0c40b901a1bf1043f08.js} +98584 -89435
  34. package/dist/app.bundle.css +5 -4
  35. package/dist/cornerstoneDICOMImageLoader.min.js +1 -1
  36. package/dist/cornerstoneDICOMImageLoader.min.js.map +1 -1
  37. package/dist/histogram-worker.bundle.829e14ec12c2b41a4323.js +359 -0
  38. package/dist/index.html +1 -1
  39. package/dist/{polySeg.bundle.fe47718e6a8414f175b1.js → polySeg.bundle.c503e9460cef894737cd.js} +3 -6
  40. package/dist/sw.js +1 -1
  41. package/package.json +20 -19
  42. package/dist/425.css +0 -2
  43. /package/dist/{164.bundle.6b98e9caf53620fbd6ca.js → 164.bundle.55df0a2c8b3569d8e1f9.js} +0 -0
  44. /package/dist/{155.css → 325.css} +0 -0
  45. /package/dist/{2.css → 633.css} +0 -0
  46. /package/dist/{595.css → 896.css} +0 -0
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
- (globalThis["webpackChunk"] = globalThis["webpackChunk"] || []).push([[90],{
2
+ (globalThis["webpackChunk"] = globalThis["webpackChunk"] || []).push([[83],{
3
3
 
4
- /***/ 54090:
4
+ /***/ 88083:
5
5
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
6
6
 
7
7
  // ESM COMPAT FLAG
@@ -31,8 +31,8 @@ __webpack_require__.d(utils_namespaceObject, {
31
31
 
32
32
  // EXTERNAL MODULE: ../../../node_modules/dicomweb-client/build/dicomweb-client.es.js
33
33
  var dicomweb_client_es = __webpack_require__(36922);
34
- // EXTERNAL MODULE: ../../core/src/index.ts + 68 modules
35
- var src = __webpack_require__(85073);
34
+ // EXTERNAL MODULE: ../../core/src/index.ts + 70 modules
35
+ var src = __webpack_require__(55411);
36
36
  // EXTERNAL MODULE: ../../core/src/utils/sortStudy.ts
37
37
  var sortStudy = __webpack_require__(45476);
38
38
  ;// CONCATENATED MODULE: ../../../extensions/default/src/DicomWebDataSource/qido.js
@@ -2484,8 +2484,8 @@ var react = __webpack_require__(41766);
2484
2484
  // EXTERNAL MODULE: ../../../node_modules/prop-types/index.js
2485
2485
  var prop_types = __webpack_require__(11374);
2486
2486
  var prop_types_default = /*#__PURE__*/__webpack_require__.n(prop_types);
2487
- // EXTERNAL MODULE: ../../ui/src/index.js + 542 modules
2488
- var ui_src = __webpack_require__(48804);
2487
+ // EXTERNAL MODULE: ../../ui/src/index.js + 785 modules
2488
+ var ui_src = __webpack_require__(5085);
2489
2489
  // EXTERNAL MODULE: ./state/index.js + 1 modules
2490
2490
  var state = __webpack_require__(15575);
2491
2491
  // EXTERNAL MODULE: ../node_modules/react-router-dom/dist/index.js
@@ -2501,14 +2501,15 @@ function _extends() { _extends = Object.assign ? Object.assign.bind() : function
2501
2501
 
2502
2502
 
2503
2503
  function Toolbar({
2504
- servicesManager
2504
+ servicesManager,
2505
+ buttonSection = 'primary'
2505
2506
  }) {
2506
2507
  const {
2507
2508
  toolbarButtons,
2508
2509
  onInteraction
2509
2510
  } = (0,src/* useToolbar */.tR)({
2510
2511
  servicesManager,
2511
- buttonSection: 'primary'
2512
+ buttonSection
2512
2513
  });
2513
2514
  if (!toolbarButtons.length) {
2514
2515
  return null;
@@ -2542,7 +2543,6 @@ function Toolbar({
2542
2543
 
2543
2544
 
2544
2545
 
2545
-
2546
2546
  const {
2547
2547
  availableLanguages,
2548
2548
  defaultLanguage,
@@ -2551,9 +2551,9 @@ const {
2551
2551
  function ViewerHeader({
2552
2552
  hotkeysManager,
2553
2553
  extensionManager,
2554
- servicesManager
2554
+ servicesManager,
2555
+ appConfig
2555
2556
  }) {
2556
- const [appConfig] = (0,state/* useAppConfig */.r)();
2557
2557
  const navigate = (0,dist/* useNavigate */.Zp)();
2558
2558
  const location = (0,react_router_dist/* useLocation */.zy)();
2559
2559
  const onClickReturnButton = () => {
@@ -2588,8 +2588,8 @@ function ViewerHeader({
2588
2588
  hotkeyDefinitions,
2589
2589
  hotkeyDefaults
2590
2590
  } = hotkeysManager;
2591
- const versionNumber = "3.8.0-beta.73";
2592
- const commitHash = "dc37802ec1f739a6ed602363bdf231d6fe58827e";
2591
+ const versionNumber = "3.8.0-beta.74";
2592
+ const commitHash = "d57e8bc1571c6da4effaa492ee2d162c552365a2";
2593
2593
  const menuOptions = [{
2594
2594
  title: t('Header:About'),
2595
2595
  icon: 'info',
@@ -2648,7 +2648,12 @@ function ViewerHeader({
2648
2648
  onClickReturnButton: onClickReturnButton,
2649
2649
  WhiteLabeling: appConfig.whiteLabeling,
2650
2650
  showPatientInfo: appConfig.showPatientInfo,
2651
- servicesManager: servicesManager
2651
+ servicesManager: servicesManager,
2652
+ Secondary: /*#__PURE__*/react.createElement(Toolbar, {
2653
+ servicesManager: servicesManager,
2654
+ buttonSection: "secondary"
2655
+ }),
2656
+ appConfig: appConfig
2652
2657
  }, /*#__PURE__*/react.createElement(ui_src/* ErrorBoundary */.tH, {
2653
2658
  context: "Primary Toolbar"
2654
2659
  }, /*#__PURE__*/react.createElement("div", {
@@ -2659,15 +2664,16 @@ function ViewerHeader({
2659
2664
  }
2660
2665
  /* harmony default export */ const ViewerLayout_ViewerHeader = (ViewerHeader);
2661
2666
  ;// CONCATENATED MODULE: ../../../extensions/default/src/Components/SidePanelWithServices.tsx
2667
+ 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); }
2662
2668
 
2663
2669
 
2664
2670
  const SidePanelWithServices = ({
2665
2671
  servicesManager,
2666
2672
  side,
2667
- className,
2668
2673
  activeTabIndex: activeTabIndexProp,
2669
- tabs,
2670
- expandedWidth
2674
+ tabs: tabsProp,
2675
+ expandedWidth,
2676
+ ...props
2671
2677
  }) => {
2672
2678
  const panelService = servicesManager?.services?.panelService;
2673
2679
 
@@ -2675,31 +2681,54 @@ const SidePanelWithServices = ({
2675
2681
  // Thus going to the Study List page and back to the viewer resets this flag for a SidePanel.
2676
2682
  const [hasBeenOpened, setHasBeenOpened] = (0,react.useState)(false);
2677
2683
  const [activeTabIndex, setActiveTabIndex] = (0,react.useState)(activeTabIndexProp);
2684
+ const [tabs, setTabs] = (0,react.useState)(tabsProp ?? panelService.getPanels(side));
2685
+ const handleSidePanelOpen = (0,react.useCallback)(() => {
2686
+ setHasBeenOpened(true);
2687
+ }, []);
2688
+ const handleActiveTabIndexChange = (0,react.useCallback)(({
2689
+ activeTabIndex
2690
+ }) => {
2691
+ setActiveTabIndex(activeTabIndex);
2692
+ }, []);
2693
+
2694
+ /** update the active tab index from outside */
2678
2695
  (0,react.useEffect)(() => {
2679
- if (panelService) {
2680
- const activatePanelSubscription = panelService.subscribe(panelService.EVENTS.ACTIVATE_PANEL, activatePanelEvent => {
2681
- if (!hasBeenOpened || activatePanelEvent.forceActive) {
2682
- const tabIndex = tabs.findIndex(tab => tab.id === activatePanelEvent.panelId);
2683
- if (tabIndex !== -1) {
2684
- setActiveTabIndex(tabIndex);
2685
- }
2696
+ setActiveTabIndex(activeTabIndexProp);
2697
+ }, [activeTabIndexProp]);
2698
+ (0,react.useEffect)(() => {
2699
+ const {
2700
+ unsubscribe
2701
+ } = panelService.subscribe(panelService.EVENTS.PANELS_CHANGED, panelChangedEvent => {
2702
+ if (panelChangedEvent.position !== side) {
2703
+ return;
2704
+ }
2705
+ setTabs(panelService.getPanels(side));
2706
+ });
2707
+ return () => {
2708
+ unsubscribe();
2709
+ };
2710
+ }, [panelService, side]);
2711
+ (0,react.useEffect)(() => {
2712
+ const activatePanelSubscription = panelService.subscribe(panelService.EVENTS.ACTIVATE_PANEL, activatePanelEvent => {
2713
+ if (!hasBeenOpened || activatePanelEvent.forceActive) {
2714
+ const tabIndex = tabs.findIndex(tab => tab.id === activatePanelEvent.panelId);
2715
+ if (tabIndex !== -1) {
2716
+ setActiveTabIndex(tabIndex);
2686
2717
  }
2687
- });
2688
- return () => {
2689
- activatePanelSubscription.unsubscribe();
2690
- };
2691
- }
2718
+ }
2719
+ });
2720
+ return () => {
2721
+ activatePanelSubscription.unsubscribe();
2722
+ };
2692
2723
  }, [tabs, hasBeenOpened, panelService]);
2693
- return /*#__PURE__*/react.createElement(ui_src/* SidePanel */.wv, {
2724
+ return /*#__PURE__*/react.createElement(ui_src/* SidePanel */.wv, SidePanelWithServices_extends({}, props, {
2694
2725
  side: side,
2695
- className: className,
2696
- activeTabIndex: activeTabIndex,
2697
2726
  tabs: tabs,
2698
- onOpen: () => {
2699
- setHasBeenOpened(true);
2700
- },
2727
+ activeTabIndex: activeTabIndex,
2728
+ onOpen: handleSidePanelOpen,
2729
+ onActiveTabIndexChange: handleActiveTabIndexChange,
2701
2730
  expandedWidth: expandedWidth
2702
- });
2731
+ }));
2703
2732
  };
2704
2733
  /* harmony default export */ const Components_SidePanelWithServices = (SidePanelWithServices);
2705
2734
  ;// CONCATENATED MODULE: ../../../extensions/default/src/ViewerLayout/index.tsx
@@ -2719,16 +2748,20 @@ function ViewerLayout({
2719
2748
  // From Modes
2720
2749
  viewports,
2721
2750
  ViewportGridComp,
2722
- leftPanels = [],
2723
- rightPanels = [],
2724
- leftPanelDefaultClosed = false,
2725
- rightPanelDefaultClosed = false
2751
+ leftPanelClosed = false,
2752
+ rightPanelClosed = false
2726
2753
  }) {
2727
2754
  const [appConfig] = (0,state/* useAppConfig */.r)();
2728
2755
  const {
2756
+ panelService,
2729
2757
  hangingProtocolService
2730
2758
  } = servicesManager.services;
2731
2759
  const [showLoadingIndicator, setShowLoadingIndicator] = (0,react.useState)(appConfig.showLoadingIndicator);
2760
+ const hasPanels = (0,react.useCallback)(side => !!panelService.getPanels(side).length, [panelService]);
2761
+ const [hasRightPanels, setHasRightPanels] = (0,react.useState)(hasPanels('right'));
2762
+ const [hasLeftPanels, setHasLeftPanels] = (0,react.useState)(hasPanels('left'));
2763
+ const [leftPanelClosedState, setLeftPanelClosed] = (0,react.useState)(leftPanelClosed);
2764
+ const [rightPanelClosedState, setRightPanelClosed] = (0,react.useState)(rightPanelClosed);
2732
2765
 
2733
2766
  /**
2734
2767
  * Set body classes (tailwindcss) that don't allow vertical
@@ -2753,21 +2786,6 @@ function ViewerLayout({
2753
2786
  content: entry.component
2754
2787
  };
2755
2788
  };
2756
- const getPanelData = id => {
2757
- const {
2758
- content,
2759
- entry
2760
- } = getComponent(id);
2761
- return {
2762
- id: entry.id,
2763
- iconName: entry.iconName,
2764
- iconLabel: entry.iconLabel,
2765
- label: entry.label,
2766
- name: entry.name,
2767
- content,
2768
- contexts: entry.contexts
2769
- };
2770
- };
2771
2789
  (0,react.useEffect)(() => {
2772
2790
  const {
2773
2791
  unsubscribe
@@ -2791,13 +2809,31 @@ function ViewerLayout({
2791
2809
  displaySetsToDisplay: viewportComponent.displaySetsToDisplay
2792
2810
  };
2793
2811
  };
2794
- const leftPanelComponents = leftPanels.map(getPanelData);
2795
- const rightPanelComponents = rightPanels.map(getPanelData);
2812
+ (0,react.useEffect)(() => {
2813
+ const {
2814
+ unsubscribe
2815
+ } = panelService.subscribe(panelService.EVENTS.PANELS_CHANGED, ({
2816
+ options
2817
+ }) => {
2818
+ setHasLeftPanels(hasPanels('left'));
2819
+ setHasRightPanels(hasPanels('right'));
2820
+ if (options?.leftPanelClosed !== undefined) {
2821
+ setLeftPanelClosed(options.leftPanelClosed);
2822
+ }
2823
+ if (options?.rightPanelClosed !== undefined) {
2824
+ setRightPanelClosed(options.rightPanelClosed);
2825
+ }
2826
+ });
2827
+ return () => {
2828
+ unsubscribe();
2829
+ };
2830
+ }, [panelService, hasPanels]);
2796
2831
  const viewportComponents = viewports.map(getViewportComponentData);
2797
2832
  return /*#__PURE__*/react.createElement("div", null, /*#__PURE__*/react.createElement(ViewerLayout_ViewerHeader, {
2798
2833
  hotkeysManager: hotkeysManager,
2799
2834
  extensionManager: extensionManager,
2800
- servicesManager: servicesManager
2835
+ servicesManager: servicesManager,
2836
+ appConfig: appConfig
2801
2837
  }), /*#__PURE__*/react.createElement("div", {
2802
2838
  className: "relative flex w-full flex-row flex-nowrap items-stretch overflow-hidden bg-black",
2803
2839
  style: {
@@ -2805,12 +2841,11 @@ function ViewerLayout({
2805
2841
  }
2806
2842
  }, /*#__PURE__*/react.createElement(react.Fragment, null, showLoadingIndicator && /*#__PURE__*/react.createElement(ui_src/* LoadingIndicatorProgress */.Jx, {
2807
2843
  className: "h-full w-full bg-black"
2808
- }), leftPanelComponents.length ? /*#__PURE__*/react.createElement(ui_src/* ErrorBoundary */.tH, {
2844
+ }), hasLeftPanels ? /*#__PURE__*/react.createElement(ui_src/* ErrorBoundary */.tH, {
2809
2845
  context: "Left Panel"
2810
2846
  }, /*#__PURE__*/react.createElement(Components_SidePanelWithServices, {
2811
2847
  side: "left",
2812
- activeTabIndex: leftPanelDefaultClosed ? null : 0,
2813
- tabs: leftPanelComponents,
2848
+ activeTabIndex: leftPanelClosedState ? null : 0,
2814
2849
  servicesManager: servicesManager
2815
2850
  })) : null, /*#__PURE__*/react.createElement("div", {
2816
2851
  className: "flex h-full flex-1 flex-col"
@@ -2822,12 +2857,11 @@ function ViewerLayout({
2822
2857
  servicesManager: servicesManager,
2823
2858
  viewportComponents: viewportComponents,
2824
2859
  commandsManager: commandsManager
2825
- })))), rightPanelComponents.length ? /*#__PURE__*/react.createElement(ui_src/* ErrorBoundary */.tH, {
2860
+ })))), hasRightPanels ? /*#__PURE__*/react.createElement(ui_src/* ErrorBoundary */.tH, {
2826
2861
  context: "Right Panel"
2827
2862
  }, /*#__PURE__*/react.createElement(Components_SidePanelWithServices, {
2828
2863
  side: "right",
2829
- activeTabIndex: rightPanelDefaultClosed ? null : 0,
2830
- tabs: rightPanelComponents,
2864
+ activeTabIndex: rightPanelClosedState ? null : 0,
2831
2865
  servicesManager: servicesManager
2832
2866
  })) : null)), /*#__PURE__*/react.createElement(ui_src/* InvestigationalUseDialog */.j, {
2833
2867
  dialogConfiguration: appConfig?.investigationalUseDialog
@@ -2843,8 +2877,8 @@ ViewerLayout.propTypes = {
2843
2877
  // From modes
2844
2878
  leftPanels: (prop_types_default()).array,
2845
2879
  rightPanels: (prop_types_default()).array,
2846
- leftPanelDefaultClosed: (prop_types_default()).bool.isRequired,
2847
- rightPanelDefaultClosed: (prop_types_default()).bool.isRequired,
2880
+ leftPanelClosed: (prop_types_default()).bool.isRequired,
2881
+ rightPanelClosed: (prop_types_default()).bool.isRequired,
2848
2882
  /** Responsible for rendering our grid of viewports; provided by consuming application */
2849
2883
  children: prop_types_default().oneOfType([(prop_types_default()).node, (prop_types_default()).func]).isRequired,
2850
2884
  viewports: (prop_types_default()).array
@@ -3321,38 +3355,6 @@ WrappedPanelStudyBrowser.propTypes = {
3321
3355
  servicesManager: (prop_types_default()).object.isRequired
3322
3356
  };
3323
3357
  /* harmony default export */ const Panels_WrappedPanelStudyBrowser = (WrappedPanelStudyBrowser);
3324
- ;// CONCATENATED MODULE: ../../../extensions/default/src/Panels/ActionButtons.tsx
3325
-
3326
-
3327
-
3328
-
3329
- function ActionButtons({
3330
- onExportClick,
3331
- onCreateReportClick
3332
- }) {
3333
- const {
3334
- t
3335
- } = (0,es/* useTranslation */.Bd)('MeasurementTable');
3336
- return /*#__PURE__*/react.createElement(react.Fragment, null, /*#__PURE__*/react.createElement(ui_src/* LegacyButtonGroup */.xA, {
3337
- color: "black",
3338
- size: "inherit"
3339
- }, /*#__PURE__*/react.createElement(ui_src/* LegacyButton */._H, {
3340
- className: "px-2 py-2 text-base",
3341
- onClick: onExportClick
3342
- }, t('Export CSV')), /*#__PURE__*/react.createElement(ui_src/* LegacyButton */._H, {
3343
- className: "px-2 py-2 text-base",
3344
- onClick: onCreateReportClick
3345
- }, t('Create Report'))));
3346
- }
3347
- ActionButtons.propTypes = {
3348
- onExportClick: (prop_types_default()).func,
3349
- onCreateReportClick: (prop_types_default()).func
3350
- };
3351
- ActionButtons.defaultProps = {
3352
- onExportClick: () => alert('Export'),
3353
- onCreateReportClick: () => alert('Create Report')
3354
- };
3355
- /* harmony default export */ const Panels_ActionButtons = (ActionButtons);
3356
3358
  // EXTERNAL MODULE: ../../../node_modules/lodash.debounce/index.js
3357
3359
  var lodash_debounce = __webpack_require__(14771);
3358
3360
  var lodash_debounce_default = /*#__PURE__*/__webpack_require__.n(lodash_debounce);
@@ -3624,7 +3626,6 @@ function findSRWithSameSeriesDescription(SeriesDescription, displaySetService) {
3624
3626
 
3625
3627
 
3626
3628
 
3627
-
3628
3629
  const {
3629
3630
  downloadCSVReport
3630
3631
  } = src.utils;
@@ -3831,17 +3832,22 @@ function PanelMeasurementTable({
3831
3832
  className: "ohif-scrollbar overflow-y-auto overflow-x-hidden",
3832
3833
  "data-cy": 'measurements-panel'
3833
3834
  }, /*#__PURE__*/react.createElement(ui_src/* MeasurementTable */.V, {
3834
- title: t("Measurements"),
3835
+ title: t('Measurements'),
3835
3836
  servicesManager: servicesManager,
3836
3837
  data: displayMeasurements,
3837
3838
  onClick: jumpToImage,
3838
3839
  onEdit: onMeasurementItemEditHandler
3839
3840
  })), /*#__PURE__*/react.createElement("div", {
3840
3841
  className: "flex justify-center p-4"
3841
- }, /*#__PURE__*/react.createElement(Panels_ActionButtons, {
3842
- onExportClick: exportReport,
3843
- onClearMeasurementsClick: clearMeasurements,
3844
- onCreateReportClick: createReport
3842
+ }, /*#__PURE__*/react.createElement(ui_src/* ActionButtons */.wr, {
3843
+ t: t('MeasurementTable'),
3844
+ actions: [{
3845
+ label: 'Export',
3846
+ onClick: exportReport
3847
+ }, {
3848
+ label: 'Create Report',
3849
+ onClick: createReport
3850
+ }]
3845
3851
  })));
3846
3852
  }
3847
3853
  PanelMeasurementTable.propTypes = {
@@ -4060,8 +4066,8 @@ function areAllImageOrientationsEqual(instances) {
4060
4066
  }
4061
4067
  return true;
4062
4068
  }
4063
- // EXTERNAL MODULE: ../../../node_modules/gl-matrix/esm/index.js + 10 modules
4064
- var esm = __webpack_require__(83636);
4069
+ // EXTERNAL MODULE: ../../../node_modules/gl-matrix/esm/index.js + 1 modules
4070
+ var esm = __webpack_require__(44753);
4065
4071
  ;// CONCATENATED MODULE: ../../../extensions/default/src/utils/calculateScanAxisNormal.ts
4066
4072
 
4067
4073
 
@@ -4211,8 +4217,11 @@ function checkSingleFrames(instances, messages) {
4211
4217
  *
4212
4218
  * @param {Object[]} instances An array of `OHIFInstanceMetadata` objects.
4213
4219
  */
4214
- function getDisplaySetMessages(instances, isReconstructable) {
4220
+ function getDisplaySetMessages(instances, isReconstructable, isDynamicVolume) {
4215
4221
  const messages = new src/* DisplaySetMessageList */.WZ();
4222
+ if (isDynamicVolume) {
4223
+ return messages;
4224
+ }
4216
4225
  if (!instances.length) {
4217
4226
  messages.addMessage(src/* DisplaySetMessage */.Ob.CODES.NO_VALID_INSTANCES);
4218
4227
  return;
@@ -4273,6 +4282,86 @@ function getDisplaySetsFromUnsupportedSeries(instances) {
4273
4282
  });
4274
4283
  return [imageSet];
4275
4284
  }
4285
+ ;// CONCATENATED MODULE: ../../../extensions/default/src/SOPClassHandlers/chartSOPClassHandler.ts
4286
+
4287
+
4288
+ const SOPClassHandlerName = 'chart';
4289
+ const CHART_MODALITY = 'CHT';
4290
+
4291
+ // Private SOPClassUid for chart data
4292
+ const ChartDataSOPClassUid = '1.9.451.13215.7.3.2.7.6.1';
4293
+ const sopClassUids = [ChartDataSOPClassUid];
4294
+ const makeChartDataDisplaySet = (instance, sopClassUids) => {
4295
+ const {
4296
+ StudyInstanceUID,
4297
+ SeriesInstanceUID,
4298
+ SOPInstanceUID,
4299
+ SeriesDescription,
4300
+ SeriesNumber,
4301
+ SeriesDate,
4302
+ SOPClassUID
4303
+ } = instance;
4304
+ return {
4305
+ Modality: CHART_MODALITY,
4306
+ loading: false,
4307
+ isReconstructable: false,
4308
+ displaySetInstanceUID: src.utils.guid(),
4309
+ SeriesDescription,
4310
+ SeriesNumber,
4311
+ SeriesDate,
4312
+ SOPInstanceUID,
4313
+ SeriesInstanceUID,
4314
+ StudyInstanceUID,
4315
+ SOPClassHandlerId: `${id}.sopClassHandlerModule.${SOPClassHandlerName}`,
4316
+ SOPClassUID,
4317
+ isDerivedDisplaySet: true,
4318
+ isLoaded: true,
4319
+ sopClassUids,
4320
+ instance,
4321
+ instances: [instance],
4322
+ /**
4323
+ * Adds instances to the chart displaySet, rather than creating a new one
4324
+ * when user moves to a different workflow step and gets back to a step that
4325
+ * recreates the chart
4326
+ */
4327
+ addInstances: function (instances, _displaySetService) {
4328
+ this.instances.push(...instances);
4329
+ this.instance = this.instances[this.instances.length - 1];
4330
+ return this;
4331
+ }
4332
+ };
4333
+ };
4334
+ function getSopClassUids(instances) {
4335
+ const uniqueSopClassUidsInSeries = new Set();
4336
+ instances.forEach(instance => {
4337
+ uniqueSopClassUidsInSeries.add(instance.SOPClassUID);
4338
+ });
4339
+ const sopClassUids = Array.from(uniqueSopClassUidsInSeries);
4340
+ return sopClassUids;
4341
+ }
4342
+ function _getDisplaySetsFromSeries(instances) {
4343
+ debugger;
4344
+ // If the series has no instances, stop here
4345
+ if (!instances || !instances.length) {
4346
+ throw new Error('No instances were provided');
4347
+ }
4348
+ const sopClassUids = getSopClassUids(instances);
4349
+ const displaySets = instances.map(instance => {
4350
+ if (instance.Modality === CHART_MODALITY) {
4351
+ return makeChartDataDisplaySet(instance, sopClassUids);
4352
+ }
4353
+ throw new Error('Unsupported modality');
4354
+ });
4355
+ return displaySets;
4356
+ }
4357
+ const chartHandler = {
4358
+ name: SOPClassHandlerName,
4359
+ sopClassUids,
4360
+ getDisplaySetsFromSeries: instances => {
4361
+ return _getDisplaySetsFromSeries(instances);
4362
+ }
4363
+ };
4364
+
4276
4365
  ;// CONCATENATED MODULE: ../../../extensions/default/src/getSopClassHandlerModule.js
4277
4366
 
4278
4367
 
@@ -4281,20 +4370,69 @@ function getDisplaySetsFromUnsupportedSeries(instances) {
4281
4370
 
4282
4371
 
4283
4372
 
4373
+
4374
+ const DEFAULT_VOLUME_LOADER_SCHEME = 'cornerstoneStreamingImageVolume';
4375
+ const DYNAMIC_VOLUME_LOADER_SCHEME = 'cornerstoneStreamingDynamicImageVolume';
4284
4376
  const sopClassHandlerName = 'stack';
4377
+ let appContext = {};
4378
+ const getDynamicVolumeInfo = instances => {
4379
+ const {
4380
+ extensionManager
4381
+ } = appContext;
4382
+ if (!extensionManager) {
4383
+ throw new Error('extensionManager is not available');
4384
+ }
4385
+ const imageIds = instances.map(({
4386
+ imageId
4387
+ }) => imageId);
4388
+ const volumeLoaderUtility = extensionManager.getModuleEntry('@ohif/extension-cornerstone.utilityModule.volumeLoader');
4389
+ const {
4390
+ getDynamicVolumeInfo: csGetDynamicVolumeInfo
4391
+ } = volumeLoaderUtility.exports;
4392
+ return csGetDynamicVolumeInfo(imageIds);
4393
+ };
4285
4394
  const isMultiFrame = instance => {
4286
4395
  return instance.NumberOfFrames > 1;
4287
4396
  };
4397
+ function getDisplaySetInfo(instances) {
4398
+ const dynamicVolumeInfo = getDynamicVolumeInfo(instances);
4399
+ const {
4400
+ isDynamicVolume,
4401
+ timePoints
4402
+ } = dynamicVolumeInfo;
4403
+ let displaySetInfo;
4404
+ if (isDynamicVolume) {
4405
+ const timePoint = timePoints[0];
4406
+ const instancesMap = new Map();
4407
+
4408
+ // O(n) to convert it into a map and O(1) to find each instance
4409
+ instances.forEach(instance => instancesMap.set(instance.imageId, instance));
4410
+ const firstTimePointInstances = timePoint.map(imageId => instancesMap.get(imageId));
4411
+ displaySetInfo = (0,isDisplaySetReconstructable/* default */.Ay)(firstTimePointInstances);
4412
+ } else {
4413
+ displaySetInfo = (0,isDisplaySetReconstructable/* default */.Ay)(instances);
4414
+ }
4415
+ return {
4416
+ isDynamicVolume,
4417
+ ...displaySetInfo,
4418
+ dynamicVolumeInfo
4419
+ };
4420
+ }
4288
4421
  const makeDisplaySet = instances => {
4289
4422
  const instance = instances[0];
4290
4423
  const imageSet = new ImageSet/* default */.A(instances);
4291
4424
  const {
4425
+ isDynamicVolume,
4292
4426
  value: isReconstructable,
4293
- averageSpacingBetweenFrames
4294
- } = (0,isDisplaySetReconstructable/* default */.Ay)(instances);
4427
+ averageSpacingBetweenFrames,
4428
+ dynamicVolumeInfo
4429
+ } = getDisplaySetInfo(instances);
4430
+ const volumeLoaderSchema = isDynamicVolume ? DYNAMIC_VOLUME_LOADER_SCHEME : DEFAULT_VOLUME_LOADER_SCHEME;
4431
+
4295
4432
  // set appropriate attributes to image set...
4296
- const messages = getDisplaySetMessages(instances, isReconstructable);
4433
+ const messages = getDisplaySetMessages(instances, isReconstructable, isDynamicVolume);
4297
4434
  imageSet.setAttributes({
4435
+ volumeLoaderSchema,
4298
4436
  displaySetInstanceUID: imageSet.uid,
4299
4437
  // create a local alias for the imageSet UID
4300
4438
  SeriesDate: instance.SeriesDate,
@@ -4312,7 +4450,9 @@ const makeDisplaySet = instances => {
4312
4450
  SOPClassHandlerId: `${id}.sopClassHandlerModule.${sopClassHandlerName}`,
4313
4451
  isReconstructable,
4314
4452
  messages,
4315
- averageSpacingBetweenFrames: averageSpacingBetweenFrames || null
4453
+ averageSpacingBetweenFrames: averageSpacingBetweenFrames || null,
4454
+ isDynamicVolume,
4455
+ dynamicVolumeInfo
4316
4456
  });
4317
4457
 
4318
4458
  // Sort the images in this series if needed
@@ -4343,7 +4483,7 @@ const makeDisplaySet = instances => {
4343
4483
  const isSingleImageModality = modality => {
4344
4484
  return modality === 'CR' || modality === 'MG' || modality === 'DX';
4345
4485
  };
4346
- function getSopClassUids(instances) {
4486
+ function getSopClassHandlerModule_getSopClassUids(instances) {
4347
4487
  const uniqueSopClassUidsInSeries = new Set();
4348
4488
  instances.forEach(instance => {
4349
4489
  uniqueSopClassUidsInSeries.add(instance.SOPClassUID);
@@ -4357,7 +4497,6 @@ function getSopClassUids(instances) {
4357
4497
  * - For all Image types that are stackable, create
4358
4498
  * a displaySet with a stack of images
4359
4499
  *
4360
- * @param {Array} sopClassHandlerModules List of SOP Class Modules
4361
4500
  * @param {SeriesMetadata} series The series metadata object from which the display sets will be created
4362
4501
  * @returns {Array} The list of display sets created for the given series object
4363
4502
  */
@@ -4367,7 +4506,7 @@ function getDisplaySetsFromSeries(instances) {
4367
4506
  throw new Error('No instances were provided');
4368
4507
  }
4369
4508
  const displaySets = [];
4370
- const sopClassUids = getSopClassUids(instances);
4509
+ const sopClassUids = getSopClassHandlerModule_getSopClassUids(instances);
4371
4510
 
4372
4511
  // Search through the instances (InstanceMetadata object) of this series
4373
4512
  // Split Multi-frame instances and Single-image modalities
@@ -4412,16 +4551,21 @@ function getDisplaySetsFromSeries(instances) {
4412
4551
  }
4413
4552
  return displaySets;
4414
4553
  }
4415
- const 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];
4416
- function getSopClassHandlerModule() {
4554
+ 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];
4555
+ function getSopClassHandlerModule(appContextParam) {
4556
+ appContext = appContextParam;
4417
4557
  return [{
4418
4558
  name: sopClassHandlerName,
4419
- sopClassUids,
4559
+ sopClassUids: getSopClassHandlerModule_sopClassUids,
4420
4560
  getDisplaySetsFromSeries
4421
4561
  }, {
4422
4562
  name: 'not-supported-display-sets-handler',
4423
4563
  sopClassUids: [],
4424
4564
  getDisplaySetsFromSeries: getDisplaySetsFromUnsupportedSeries
4565
+ }, {
4566
+ name: chartHandler.name,
4567
+ sopClassUids: chartHandler.sopClassUids,
4568
+ getDisplaySetsFromSeries: chartHandler.getDisplaySetsFromSeries
4425
4569
  }];
4426
4570
  }
4427
4571
  /* harmony default export */ const src_getSopClassHandlerModule = (getSopClassHandlerModule);
@@ -4721,12 +4865,97 @@ function ToolbarButtonGroupWithServices({
4721
4865
  return /*#__PURE__*/react.createElement(ui_src/* ButtonGroup */.e2, null, getSplitButtonItems(items));
4722
4866
  }
4723
4867
  /* harmony default export */ const Toolbar_ToolbarButtonGroupWithServices = (ToolbarButtonGroupWithServices);
4868
+ ;// CONCATENATED MODULE: ../../../extensions/default/src/components/ProgressDropdownWithService/ProgressDropdownWithService.tsx
4869
+
4870
+
4871
+ const workflowStepsToDropdownOptions = (steps = []) => steps.map(step => ({
4872
+ label: step.name,
4873
+ value: step.id,
4874
+ info: step.info,
4875
+ activated: false,
4876
+ completed: false
4877
+ }));
4878
+ function ProgressDropdownWithService({
4879
+ servicesManager
4880
+ }) {
4881
+ const {
4882
+ workflowStepsService
4883
+ } = servicesManager.services;
4884
+ const [activeStepId, setActiveStepId] = (0,react.useState)(workflowStepsService.activeWorkflowStep?.id);
4885
+ const [dropdownOptions, setDropdownOptions] = (0,react.useState)(workflowStepsToDropdownOptions(workflowStepsService.workflowSteps));
4886
+ const setCurrentAndPreviousOptionsAsCompleted = (0,react.useCallback)(currentOption => {
4887
+ if (currentOption.completed) {
4888
+ return;
4889
+ }
4890
+ setDropdownOptions(prevOptions => {
4891
+ const newOptionsState = [...prevOptions];
4892
+ const startIndex = newOptionsState.findIndex(option => option.value === currentOption.value);
4893
+ for (let i = startIndex; i >= 0; i--) {
4894
+ const option = newOptionsState[i];
4895
+ if (option.completed) {
4896
+ break;
4897
+ }
4898
+ newOptionsState[i] = {
4899
+ ...option,
4900
+ completed: true
4901
+ };
4902
+ }
4903
+ return newOptionsState;
4904
+ });
4905
+ }, []);
4906
+ const handleDropdownChange = (0,react.useCallback)(({
4907
+ selectedOption
4908
+ }) => {
4909
+ if (!selectedOption) {
4910
+ return;
4911
+ }
4912
+
4913
+ // TODO: Steps should be marked as completed after user has
4914
+ // completed some action when required (not implemented)
4915
+ setCurrentAndPreviousOptionsAsCompleted(selectedOption);
4916
+ setActiveStepId(selectedOption.value);
4917
+ }, [setCurrentAndPreviousOptionsAsCompleted]);
4918
+ (0,react.useEffect)(() => {
4919
+ let timeoutId;
4920
+ if (activeStepId) {
4921
+ // We've used setTimeout to give it more time to update the UI since
4922
+ // create3DFilterableFromDataArray from Texture.js may take 600+ ms to run
4923
+ // when there is a new series to load in the next step but that resulted
4924
+ // in the followed React error when updating the content from left/right panels
4925
+ // and all component states were being lost:
4926
+ // Error: Can't perform a React state update on an unmounted component
4927
+ workflowStepsService.setActiveWorkflowStep(activeStepId);
4928
+ }
4929
+ return () => clearTimeout(timeoutId);
4930
+ }, [activeStepId, workflowStepsService]);
4931
+ (0,react.useEffect)(() => {
4932
+ const {
4933
+ unsubscribe: unsubStepsChanged
4934
+ } = workflowStepsService.subscribe(workflowStepsService.EVENTS.STEPS_CHANGED, () => setDropdownOptions(workflowStepsToDropdownOptions(workflowStepsService.workflowSteps)));
4935
+ const {
4936
+ unsubscribe: unsubActiveStepChanged
4937
+ } = workflowStepsService.subscribe(workflowStepsService.EVENTS.ACTIVE_STEP_CHANGED, () => setActiveStepId(workflowStepsService.activeWorkflowStep.id));
4938
+ return () => {
4939
+ unsubStepsChanged();
4940
+ unsubActiveStepChanged();
4941
+ };
4942
+ }, [servicesManager, workflowStepsService]);
4943
+ return /*#__PURE__*/react.createElement(ui_src/* ProgressDropdown */.LW, {
4944
+ options: dropdownOptions,
4945
+ value: activeStepId,
4946
+ onChange: handleDropdownChange
4947
+ });
4948
+ }
4949
+ /* harmony default export */ const ProgressDropdownWithService_ProgressDropdownWithService = (ProgressDropdownWithService);
4950
+ ;// CONCATENATED MODULE: ../../../extensions/default/src/components/ProgressDropdownWithService/index.js
4951
+
4724
4952
  ;// CONCATENATED MODULE: ../../../extensions/default/src/getToolbarModule.tsx
4725
4953
 
4726
4954
 
4727
4955
 
4728
4956
 
4729
4957
 
4958
+
4730
4959
  const getClassName = isToggled => {
4731
4960
  return {
4732
4961
  className: isToggled ? '!text-primary-active' : '!text-common-bright hover:!bg-primary-dark hover:text-primary-light'
@@ -4758,6 +4987,9 @@ function getToolbarModule({
4758
4987
  }, {
4759
4988
  name: 'ohif.buttonGroup',
4760
4989
  defaultComponent: Toolbar_ToolbarButtonGroupWithServices
4990
+ }, {
4991
+ name: 'ohif.progressDropdown',
4992
+ defaultComponent: ProgressDropdownWithService_ProgressDropdownWithService
4761
4993
  }, {
4762
4994
  name: 'evaluate.group.promoteToPrimary',
4763
4995
  evaluate: ({
@@ -4956,10 +5188,10 @@ function adaptItem(item, subProps) {
4956
5188
  }
4957
5189
  // EXTERNAL MODULE: ../../ui/src/components/ContextMenu/ContextMenu.tsx
4958
5190
  var ContextMenu = __webpack_require__(59852);
4959
- // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/index.js + 16 modules
4960
- var dist_esm = __webpack_require__(20767);
5191
+ // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/index.js + 18 modules
5192
+ var dist_esm = __webpack_require__(24542);
4961
5193
  ;// CONCATENATED MODULE: ../../../extensions/default/src/CustomizableContextMenu/ContextMenuController.tsx
4962
- var _class;
5194
+ var _ContextMenuController;
4963
5195
 
4964
5196
 
4965
5197
 
@@ -5074,7 +5306,7 @@ class ContextMenuController {
5074
5306
  });
5075
5307
  }
5076
5308
  }
5077
- _class = ContextMenuController;
5309
+ _ContextMenuController = ContextMenuController;
5078
5310
  ContextMenuController.getDefaultPosition = () => {
5079
5311
  return {
5080
5312
  x: 0,
@@ -5099,13 +5331,13 @@ ContextMenuController._getElementDefaultPosition = element => {
5099
5331
  };
5100
5332
  };
5101
5333
  ContextMenuController._getCanvasPointsPosition = (points = [], element) => {
5102
- const viewerPos = _class._getElementDefaultPosition(element);
5334
+ const viewerPos = _ContextMenuController._getElementDefaultPosition(element);
5103
5335
  for (let pointIndex = 0; pointIndex < points.length; pointIndex++) {
5104
5336
  const point = {
5105
5337
  x: points[pointIndex][0] || points[pointIndex]['x'],
5106
5338
  y: points[pointIndex][1] || points[pointIndex]['y']
5107
5339
  };
5108
- if (_class._isValidPosition(point) && _class._isValidPosition(viewerPos)) {
5340
+ if (_ContextMenuController._isValidPosition(point) && _ContextMenuController._isValidPosition(viewerPos)) {
5109
5341
  return {
5110
5342
  x: point.x + viewerPos.x,
5111
5343
  y: point.y + viewerPos.y
@@ -5121,17 +5353,17 @@ ContextMenuController._isValidPosition = source => {
5121
5353
  */
5122
5354
  ContextMenuController._getDefaultPosition = (canvasPoints, eventDetail, viewerElement) => {
5123
5355
  function* getPositionIterator() {
5124
- yield _class._getCanvasPointsPosition(canvasPoints, viewerElement);
5125
- yield _class._getEventDefaultPosition(eventDetail);
5126
- yield _class._getElementDefaultPosition(viewerElement);
5127
- yield _class.getDefaultPosition();
5356
+ yield _ContextMenuController._getCanvasPointsPosition(canvasPoints, viewerElement);
5357
+ yield _ContextMenuController._getEventDefaultPosition(eventDetail);
5358
+ yield _ContextMenuController._getElementDefaultPosition(viewerElement);
5359
+ yield _ContextMenuController.getDefaultPosition();
5128
5360
  }
5129
5361
  const positionIterator = getPositionIterator();
5130
5362
  let current = positionIterator.next();
5131
5363
  let position = current.value;
5132
5364
  while (!current.done) {
5133
5365
  position = current.value;
5134
- if (_class._isValidPosition(position)) {
5366
+ if (_ContextMenuController._isValidPosition(position)) {
5135
5367
  positionIterator.return();
5136
5368
  }
5137
5369
  current = positionIterator.next();
@@ -5684,6 +5916,9 @@ const reuseCachedLayout = (state, hangingProtocolService, syncService) => {
5684
5916
  const {
5685
5917
  protocol
5686
5918
  } = hangingProtocolService.getActiveProtocol();
5919
+ if (!protocol) {
5920
+ return;
5921
+ }
5687
5922
  const hpInfo = hangingProtocolService.getState();
5688
5923
  const {
5689
5924
  protocolId,
@@ -5857,12 +6092,6 @@ var index = __webpack_require__(68870);
5857
6092
  const {
5858
6093
  subscribeToNextViewportGridChange
5859
6094
  } = src.utils;
5860
- /**
5861
- * Determine if a command is a hanging protocol one.
5862
- * For now, just use the two hanging protocol commands that are in this
5863
- * commands module, but if others get added elsewhere this may need enhancing.
5864
- */
5865
- const isHangingProtocolCommand = command => command && (command.commandName === 'setHangingProtocol' || command.commandName === 'toggleHangingProtocol');
5866
6095
  const commandsModule = ({
5867
6096
  servicesManager,
5868
6097
  commandsManager
@@ -5874,8 +6103,7 @@ const commandsModule = ({
5874
6103
  uiNotificationService,
5875
6104
  viewportGridService,
5876
6105
  displaySetService,
5877
- stateSyncService,
5878
- toolbarService
6106
+ stateSyncService
5879
6107
  } = servicesManager.services;
5880
6108
 
5881
6109
  // Define a context menu controller for use with any context menus
@@ -7382,6 +7610,7 @@ class GoogleCloudDataSourceConfigurationAPI {
7382
7610
 
7383
7611
 
7384
7612
 
7613
+
7385
7614
  /**
7386
7615
  *
7387
7616
  * Note: this is an example of how the customization module can be used
@@ -7519,9 +7748,60 @@ function getCustomizationModule({
7519
7748
  // The factory for creating an instance of a BaseDataSourceConfigurationAPI for Google Cloud Healthcare
7520
7749
  id: 'ohif.dataSourceConfigurationAPI.google',
7521
7750
  factory: dataSourceName => new GoogleCloudDataSourceConfigurationAPI(dataSourceName, servicesManager, extensionManager)
7751
+ }, {
7752
+ id: 'progressDropdownWithServiceComponent',
7753
+ component: ProgressDropdownWithService_ProgressDropdownWithService
7522
7754
  }]
7523
7755
  }];
7524
7756
  }
7757
+ ;// CONCATENATED MODULE: ../../../extensions/default/src/Components/LineChartViewport/LineChartViewport.tsx
7758
+
7759
+
7760
+ const LineChartViewport = ({
7761
+ displaySets
7762
+ }) => {
7763
+ const displaySet = displaySets[0];
7764
+ const {
7765
+ axis: chartAxis,
7766
+ series: chartSeries
7767
+ } = displaySet.instance.chartData;
7768
+ return /*#__PURE__*/react.createElement(ui_src/* LineChart */.bl, {
7769
+ showLegend: true,
7770
+ legendWidth: 150,
7771
+ axis: {
7772
+ x: {
7773
+ label: chartAxis.x.label,
7774
+ indexRef: 0,
7775
+ type: 'x',
7776
+ range: {
7777
+ min: 0
7778
+ }
7779
+ },
7780
+ y: {
7781
+ label: chartAxis.y.label,
7782
+ indexRef: 1,
7783
+ type: 'y'
7784
+ }
7785
+ },
7786
+ series: chartSeries
7787
+ });
7788
+ };
7789
+
7790
+ ;// CONCATENATED MODULE: ../../../extensions/default/src/Components/LineChartViewport/index.ts
7791
+
7792
+ ;// CONCATENATED MODULE: ../../../extensions/default/src/getViewportModule.tsx
7793
+
7794
+ const getViewportModule = ({
7795
+ servicesManager,
7796
+ commandsManager,
7797
+ extensionManager
7798
+ }) => {
7799
+ return [{
7800
+ name: 'chartViewport',
7801
+ component: LineChartViewport
7802
+ }];
7803
+ };
7804
+
7525
7805
  // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/calculate-suv/dist/calculate-suv.esm.js
7526
7806
  var calculate_suv_esm = __webpack_require__(79717);
7527
7807
  ;// CONCATENATED MODULE: ../../../extensions/default/src/getPTImageIdInstanceMetadata.ts
@@ -7686,7 +7966,7 @@ function init({
7686
7966
  groupId,
7687
7967
  items,
7688
7968
  listeners
7689
- } = button.props;
7969
+ } = button.props || {};
7690
7970
 
7691
7971
  // Handle group items' listeners
7692
7972
  if (groupId && items) {
@@ -7759,6 +8039,7 @@ const handlePETImageMetadata = ({
7759
8039
 
7760
8040
 
7761
8041
 
8042
+
7762
8043
  const defaultExtension = {
7763
8044
  /**
7764
8045
  * Only required property. Should be a unique value across all extensions.
@@ -7766,6 +8047,7 @@ const defaultExtension = {
7766
8047
  id: id,
7767
8048
  preRegistration: init,
7768
8049
  getDataSourcesModule: src_getDataSourcesModule,
8050
+ getViewportModule: getViewportModule,
7769
8051
  getLayoutTemplateModule: getLayoutTemplateModule,
7770
8052
  getPanelModule: src_getPanelModule,
7771
8053
  getHangingProtocolModule: src_getHangingProtocolModule,