@3cr/viewer-browser 0.0.200 → 0.0.246

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 (383) hide show
  1. package/.circleci/config.yml +46 -22
  2. package/.prettierrc +6 -0
  3. package/components.d.ts +27 -10
  4. package/dist/Viewer3CR.js +36 -45
  5. package/dist/Viewer3CR.mjs +26893 -21667
  6. package/dist/Viewer3CR.umd.js +36 -45
  7. package/dist/android-chrome-192x192.png +0 -0
  8. package/dist/android-chrome-512x512.png +0 -0
  9. package/dist/apple-touch-icon.png +0 -0
  10. package/dist/browserconfig.xml +9 -0
  11. package/dist/favicon-16x16.png +0 -0
  12. package/dist/favicon-32x32.png +0 -0
  13. package/dist/favicon.ico +0 -0
  14. package/dist/mstile-144x144.png +0 -0
  15. package/dist/mstile-150x150.png +0 -0
  16. package/dist/mstile-310x150.png +0 -0
  17. package/dist/mstile-310x310.png +0 -0
  18. package/dist/mstile-70x70.png +0 -0
  19. package/dist/safari-pinned-tab.svg +50 -0
  20. package/dist/site.webmanifest +19 -0
  21. package/index.html +34 -41
  22. package/package.json +24 -20
  23. package/playground/android-chrome-192x192.png +0 -0
  24. package/playground/android-chrome-512x512.png +0 -0
  25. package/playground/apple-touch-icon.png +0 -0
  26. package/playground/browserconfig.xml +9 -0
  27. package/playground/favicon-16x16.png +0 -0
  28. package/playground/favicon-32x32.png +0 -0
  29. package/playground/favicon.ico +0 -0
  30. package/playground/index.html +30 -41
  31. package/playground/mstile-144x144.png +0 -0
  32. package/playground/mstile-150x150.png +0 -0
  33. package/playground/mstile-310x150.png +0 -0
  34. package/playground/mstile-310x310.png +0 -0
  35. package/playground/mstile-70x70.png +0 -0
  36. package/playground/safari-pinned-tab.svg +50 -0
  37. package/playground/site.webmanifest +19 -0
  38. package/playground/sw.js +15 -1
  39. package/public/android-chrome-192x192.png +0 -0
  40. package/public/android-chrome-512x512.png +0 -0
  41. package/public/apple-touch-icon.png +0 -0
  42. package/public/browserconfig.xml +9 -0
  43. package/public/favicon-16x16.png +0 -0
  44. package/public/favicon-32x32.png +0 -0
  45. package/public/favicon.ico +0 -0
  46. package/public/mstile-144x144.png +0 -0
  47. package/public/mstile-150x150.png +0 -0
  48. package/public/mstile-310x150.png +0 -0
  49. package/public/mstile-310x310.png +0 -0
  50. package/public/mstile-70x70.png +0 -0
  51. package/public/safari-pinned-tab.svg +50 -0
  52. package/public/site.webmanifest +19 -0
  53. package/src/App.vue +55 -50
  54. package/src/__tests__/app.spec.ts +7 -8
  55. package/{__tests__/index.spec.ts → src/__tests__/main.spec.ts} +5 -6
  56. package/src/assets/logos/3dicom/white-mini.svg +20 -0
  57. package/src/assets/logos/3dicom/white.svg +30 -0
  58. package/src/assets/styles.scss +18 -4
  59. package/src/components/demo/DemoPatientModal.vue +12 -22
  60. package/src/components/demo/__tests__/DemoModal.spec.ts +9 -8
  61. package/src/components/demo/__tests__/DemoPatientModal.spec.ts +11 -10
  62. package/src/components/demo/__tests__/options.spec.ts +1 -1
  63. package/src/components/demo/licence/DemoLicenceInfoModal.vue +11 -29
  64. package/src/components/demo/licence/__tests__/DemoLicenceEnableCloudStorageModal.spec.ts +11 -10
  65. package/src/components/demo/licence/__tests__/DemoLicenceInfoModal.spec.ts +21 -11
  66. package/src/components/demo/licence/__tests__/DemoLicenceSendToPartyModal.spec.ts +10 -10
  67. package/src/components/demo/licence/__tests__/DemoLicenceShareToMobileModal.spec.ts +14 -13
  68. package/src/components/demo/options.ts +74 -76
  69. package/src/components/demo/patient/DemoPatientInfoModal.vue +11 -29
  70. package/src/components/demo/patient/__tests__/DemoPatientEnableCloudStorageModal.spec.ts +11 -10
  71. package/src/components/demo/patient/__tests__/DemoPatientInfoModal.spec.ts +12 -11
  72. package/src/components/demo/patient/__tests__/DemoPatientSendToPartyModal.spec.ts +10 -10
  73. package/src/components/demo/patient/__tests__/DemoPatientShareToMobileModal.spec.ts +14 -13
  74. package/src/components/modal/ActionRail.vue +7 -11
  75. package/src/components/modal/AskAI.vue +35 -50
  76. package/src/components/modal/CloseViewerModal.vue +22 -57
  77. package/src/components/modal/MftpWebGL3DRModal.vue +230 -635
  78. package/src/components/modal/ViewerActionRail.vue +44 -39
  79. package/src/components/modal/ViewerNavigationDrawer.vue +10 -8
  80. package/src/components/modal/ViewerNavigationDrawerContent.vue +91 -49
  81. package/src/components/modal/ViewerNavigationDrawerFooter.vue +83 -63
  82. package/src/components/modal/ViewerNavigationDrawerHeader.vue +14 -44
  83. package/src/components/modal/ViewerScanView.vue +114 -0
  84. package/src/components/modal/WebGL3DR.vue +91 -0
  85. package/src/components/modal/__tests__/ActionRail.spec.ts +10 -0
  86. package/src/components/modal/__tests__/AskAI.spec.ts +33 -0
  87. package/src/components/modal/__tests__/CloseViewerModal.spec.ts +24 -14
  88. package/src/components/modal/__tests__/MftpWebGL3DRModal.spec.ts +147 -176
  89. package/src/components/modal/__tests__/ViewerActionRail.spec.ts +11 -0
  90. package/src/components/modal/__tests__/ViewerNavigationDrawer.spec.ts +10 -12
  91. package/src/components/modal/__tests__/ViewerNavigationDrawerContent.spec.ts +4 -22
  92. package/src/components/modal/__tests__/ViewerNavigationDrawerFooter.spec.ts +35 -32
  93. package/src/components/modal/__tests__/ViewerNavigationDrawerHeader.spec.ts +14 -11
  94. package/src/components/modal/__tests__/ViewerScanView.spec.ts +60 -0
  95. package/src/components/modal/__tests__/WebGL3DR.spec.ts +57 -0
  96. package/src/components/modal/actions/Flip3dAction.vue +1 -1
  97. package/src/components/modal/actions/FlipHorizontalAction.vue +5 -10
  98. package/src/components/modal/actions/FlipVerticalAction.vue +5 -10
  99. package/src/components/modal/actions/FullscreenAction.vue +6 -11
  100. package/src/components/modal/actions/NavigationCubeAction.vue +7 -14
  101. package/src/components/modal/actions/PanAction.vue +4 -4
  102. package/src/components/modal/actions/ResetViewAction.vue +1 -1
  103. package/src/components/modal/actions/Rotate2dAction.vue +8 -20
  104. package/src/components/modal/actions/Slice3dAction.vue +10 -32
  105. package/src/components/modal/actions/ZoomAction.vue +1 -1
  106. package/src/components/modal/actions/__tests__/Action.spec.ts +8 -9
  107. package/src/components/modal/actions/__tests__/Flip3dAction.spec.ts +6 -8
  108. package/src/components/modal/actions/__tests__/FlipHorizontalAction.spec.ts +6 -7
  109. package/src/components/modal/actions/__tests__/FlipVerticalAction.spec.ts +6 -7
  110. package/src/components/modal/actions/__tests__/FullscreenAction.spec.ts +9 -10
  111. package/src/components/modal/actions/__tests__/NavigationCubeAction.spec.ts +11 -11
  112. package/src/components/modal/actions/__tests__/PanAction.spec.ts +9 -10
  113. package/src/components/modal/actions/__tests__/ResetViewAction.spec.ts +7 -7
  114. package/src/components/modal/actions/__tests__/Rotate2dAction.spec.ts +6 -8
  115. package/src/components/modal/actions/__tests__/Slice3dAction.spec.ts +23 -5
  116. package/src/components/modal/actions/__tests__/ZoomAction.spec.ts +8 -10
  117. package/src/components/modal/buttons/AutoAnnotateBtn.vue +197 -0
  118. package/src/components/modal/buttons/__tests__/AutoAnnotateBtn.spec.ts +28 -0
  119. package/src/components/modal/menus/FileMenu.vue +73 -0
  120. package/src/components/modal/menus/SettingsMenu.vue +106 -0
  121. package/src/components/modal/menus/__tests__/FileMenu.spec.ts +110 -0
  122. package/src/components/modal/menus/__tests__/SettingsMenu.spec.ts +71 -0
  123. package/src/components/navigation/mcad/McadGlobalActions.vue +20 -0
  124. package/src/components/navigation/mcad/McadGlobalOpacitySlider.vue +103 -0
  125. package/src/components/navigation/mcad/McadGlobalScanViewBtn.vue +28 -0
  126. package/src/components/navigation/mcad/McadGlobalVisibilityBtn.vue +38 -0
  127. package/src/components/shared/DoubleSliderSelector.vue +142 -0
  128. package/src/components/{loading → shared}/LoadingSpinner.vue +27 -36
  129. package/src/components/shared/UpdateSnackbar.vue +72 -0
  130. package/src/components/{selectors → shared}/ValueSelector.vue +9 -12
  131. package/src/components/shared/__tests__/DoubleSliderSelector.spec.ts +83 -0
  132. package/src/components/shared/__tests__/LoadingSpinner.spec.ts +9 -0
  133. package/src/components/shared/__tests__/UpdateSnackbar.spec.ts +116 -0
  134. package/src/components/shared/__tests__/ValueSelector.spec.ts +39 -0
  135. package/src/components/shared/__tests__/VerticalSliderSelector.spec.ts +50 -0
  136. package/src/components/views/AnnotationTreeView.vue +236 -0
  137. package/src/components/{modal/ViewerDisplaySettings.vue → views/DisplaySettings.vue} +7 -15
  138. package/src/components/views/MarkupTreeView.vue +201 -0
  139. package/src/components/views/McadObjectTreeView.vue +129 -0
  140. package/src/components/views/__tests__/AnnotationTreeView.spec.ts +62 -0
  141. package/src/components/{modal/__tests__/ViewerDisplaySettings.spec.ts → views/__tests__/DisplaySettings.spec.ts} +24 -20
  142. package/src/components/views/__tests__/MarkupTreeView.spec.ts +41 -0
  143. package/src/components/views/__tests__/McadObjectTreeView.spec.ts +47 -0
  144. package/src/components/views/modals/DataOverlayGeneralModal.vue +71 -0
  145. package/src/components/views/modals/DataOverlayMarkupModal.vue +60 -0
  146. package/src/components/views/modals/DataOverlayModal.vue +88 -0
  147. package/src/components/views/shared/MaskIcon.vue +44 -0
  148. package/src/components/views/shared/ObjectColor.vue +31 -0
  149. package/src/components/views/shared/ObjectLabel.vue +30 -0
  150. package/src/components/views/shared/Opacity.vue +65 -0
  151. package/src/components/views/shared/VisibilityBtn.vue +25 -0
  152. package/src/components/views/shared/__tests__/MaskIcon.spec.ts +10 -0
  153. package/src/components/views/shared/__tests__/ObjectColor.spec.ts +10 -0
  154. package/src/components/views/shared/__tests__/ObjectLabel.spec.ts +10 -0
  155. package/src/components/views/shared/__tests__/Opacity.spec.ts +24 -0
  156. package/src/components/views/shared/__tests__/VisibilityBtn.spec.ts +11 -0
  157. package/src/components/views/types/annotation-tree-view-item-child-action.ts +6 -0
  158. package/src/components/views/types/annotation-tree-view-item-child.ts +9 -0
  159. package/src/components/views/types/annotation-tree-view-item.ts +13 -0
  160. package/src/components/views/types/markup-tree-view-item-child.ts +6 -0
  161. package/src/components/views/types/markup-tree-view-item.ts +14 -0
  162. package/src/components/views/types/mcad-object-tree-view-item.ts +13 -0
  163. package/src/composables/__tests__/useAnnotations.spec.ts +35 -0
  164. package/src/composables/__tests__/useEventListener.spec.ts +32 -0
  165. package/src/composables/__tests__/useIntroJs.spec.ts +51 -0
  166. package/src/composables/__tests__/useMarkups.spec.ts +39 -0
  167. package/src/composables/__tests__/useMcadObjects.spec.ts +36 -0
  168. package/src/composables/__tests__/useMouse.spec.ts +20 -0
  169. package/src/{components/modal/composables → composables}/__tests__/useNavigationCubeObserver.spec.ts +17 -12
  170. package/src/{dataLayer → composables}/__tests__/useViewer3cr.spec.ts +1 -2
  171. package/src/composables/useAnnotations.ts +37 -0
  172. package/src/composables/useDebounce.ts +11 -0
  173. package/src/composables/useEventListener.ts +25 -0
  174. package/src/composables/useIntroJs.ts +142 -0
  175. package/src/composables/useMarkups.ts +41 -0
  176. package/src/composables/useMcadObjects.ts +32 -0
  177. package/src/composables/useMouse.ts +14 -0
  178. package/src/{components/modal/composables → composables}/useNavigationCubeObserver.ts +35 -25
  179. package/src/composables/useScanMovement.ts +25 -0
  180. package/src/composables/useScanSliders.ts +36 -0
  181. package/src/composables/useVersion3cr.ts +7 -0
  182. package/src/composables/useViewer3cr.ts +7 -0
  183. package/src/composables/useViewerOptions.ts +36 -0
  184. package/src/{dataLayer → functions}/__tests__/clamp.spec.ts +1 -2
  185. package/src/functions/__tests__/layoutOverlayStyle.spec.ts +325 -0
  186. package/src/{helpers/__tests__/model-helper.spec.ts → functions/__tests__/modelHelper.spec.ts} +77 -40
  187. package/src/{notifications → functions}/__tests__/notification.spec.ts +19 -29
  188. package/src/functions/__tests__/parseAction.spec.ts +9 -0
  189. package/src/functions/__tests__/parseCallToAction.spec.ts +11 -0
  190. package/src/functions/__tests__/parseDataOverlay.spec.ts +15 -0
  191. package/src/functions/__tests__/parseDataOverlayData.spec.ts +9 -0
  192. package/src/functions/__tests__/parseDataOverlayEvent.spec.ts +10 -0
  193. package/src/functions/__tests__/parseMcadEvent.spec.ts +10 -0
  194. package/src/functions/guards/isDataOverlayAngle.ts +6 -0
  195. package/src/functions/guards/isDataOverlayLength.ts +6 -0
  196. package/src/functions/guards/isDataOverlayPolygon.ts +6 -0
  197. package/src/functions/layoutOverlayStyle.ts +84 -0
  198. package/src/{helpers → functions}/modelHelper.ts +81 -18
  199. package/src/functions/notification.ts +82 -0
  200. package/src/functions/parseAction.ts +9 -0
  201. package/src/functions/parseCallToAction.ts +9 -0
  202. package/src/functions/parseDataOverlay.ts +10 -0
  203. package/src/functions/parseDataOverlayData.ts +10 -0
  204. package/src/functions/parseDataOverlayEvent.ts +17 -0
  205. package/src/functions/parseMcadEvent.ts +10 -0
  206. package/src/functions/rgbaToCss.ts +13 -0
  207. package/src/main.ts +57 -9
  208. package/src/{dataLayer → models}/__tests__/eventHandlers.spec.ts +2 -3
  209. package/src/models/__tests__/loadViewerOptions.spec.ts +72 -0
  210. package/src/models/__tests__/loadViewerPayload.spec.ts +10 -0
  211. package/src/models/__tests__/scanState.spec.ts +190 -0
  212. package/src/models/callbacks.ts +4 -0
  213. package/src/models/loadViewerOptions.ts +79 -0
  214. package/src/models/loadViewerPayload.ts +17 -0
  215. package/src/{dataLayer → models}/scanState.ts +63 -74
  216. package/src/plugins/__tests__/usePlugins.spec.ts +12 -0
  217. package/src/plugins/__tests__/vuetify.spec.ts +3 -4
  218. package/src/plugins/usePlugins.ts +8 -0
  219. package/src/plugins/vuetify.ts +31 -65
  220. package/src/services/{gpt/__tests__ → __tests__}/gpt.service.spec.ts +2 -2
  221. package/src/services/__tests__/service-worker.service.spec.ts +32 -0
  222. package/src/{dataLayer/__tests__/viewer3cr.spec.ts → services/__tests__/viewer-3cr.service.spec.ts} +97 -36
  223. package/src/services/gpt.service.ts +17 -0
  224. package/src/services/service-worker.service.ts +16 -0
  225. package/src/{dataLayer/viewer3cr.ts → services/viewer-3cr.service.ts} +281 -150
  226. package/src/tools/data-overlay.tool.ts +71 -0
  227. package/src/types/action.ts +13 -0
  228. package/src/types/call-to-action.ts +9 -0
  229. package/src/types/colour.ts +6 -0
  230. package/src/types/data-overlay-angle.ts +16 -0
  231. package/src/types/data-overlay-annotation.ts +18 -0
  232. package/src/types/data-overlay-data.ts +15 -0
  233. package/src/types/data-overlay-event.ts +5 -0
  234. package/src/types/data-overlay-info.ts +18 -0
  235. package/src/types/data-overlay-interaction.ts +15 -0
  236. package/src/types/data-overlay-length.ts +16 -0
  237. package/src/types/data-overlay-markup.ts +7 -0
  238. package/src/types/data-overlay-mcad.ts +20 -0
  239. package/src/types/data-overlay-polygon.ts +18 -0
  240. package/src/types/data-overlay.ts +16 -0
  241. package/src/types/demo-type.ts +4 -0
  242. package/src/types/gpt-question.ts +4 -0
  243. package/src/types/gpt-response-payload.ts +6 -0
  244. package/src/types/mcad-object-interaction.ts +15 -0
  245. package/src/types/segment-angle.ts +5 -0
  246. package/src/types/vector2.ts +4 -0
  247. package/src/types/vector3.ts +5 -0
  248. package/test/fakers/action-data.faker.ts +11 -0
  249. package/test/fakers/action.faker.ts +19 -0
  250. package/test/fakers/call-to-action.faker.ts +17 -0
  251. package/test/fakers/colour.faker.ts +17 -0
  252. package/test/fakers/data-overlay-angle.faker.ts +37 -0
  253. package/test/fakers/data-overlay-annotation.faker.ts +41 -0
  254. package/test/fakers/data-overlay-data.faker.ts +97 -0
  255. package/test/fakers/data-overlay-info.faker.ts +29 -0
  256. package/test/fakers/data-overlay-interaction.faker.ts +62 -0
  257. package/test/fakers/data-overlay-length.faker.ts +37 -0
  258. package/test/fakers/data-overlay-mcad.faker.ts +40 -0
  259. package/test/fakers/data-overlay-polygon.faker.ts +39 -0
  260. package/test/fakers/gpt-question.faker.ts +11 -0
  261. package/test/fakers/gpt-response.faker.ts +12 -0
  262. package/test/fakers/invert-transform.faker.ts +16 -0
  263. package/test/fakers/mcad-object-interaction.faker.ts +22 -0
  264. package/test/fakers/orientation.faker.ts +17 -0
  265. package/test/fakers/segment-angle.faker.ts +12 -0
  266. package/test/fakers/vector2.faker.ts +12 -0
  267. package/test/fakers/vector3.faker.ts +16 -0
  268. package/test/plugins/findByTestId.ts +25 -0
  269. package/test/plugins/vuetify.ts +16 -0
  270. package/test/setup.ts +16 -5
  271. package/tsconfig.json +4 -15
  272. package/vite.config.mts +20 -46
  273. package/vitest.config.mts +24 -43
  274. package/index.ts +0 -72
  275. package/src/assets/images/dark/3DICOM.png +0 -0
  276. package/src/assets/images/dark/3dicom-logo.svg +0 -1
  277. package/src/assets/images/light/3DICOM.png +0 -0
  278. package/src/assets/images/light/3dicom-logo.svg +0 -1
  279. package/src/assets/logo.png +0 -0
  280. package/src/assets/logo.svg +0 -6
  281. package/src/components/WebGL3DR.vue +0 -102
  282. package/src/components/__tests__/webgl3dr.spec.ts +0 -37
  283. package/src/components/icons/liver.vue +0 -21
  284. package/src/components/loading/__tests__/loading-spinner.spec.ts +0 -11
  285. package/src/components/modal/ViewerAnnotationModal.vue +0 -111
  286. package/src/components/modal/ViewerAnnotations.vue +0 -289
  287. package/src/components/modal/__tests__/ViewerAnnotationModal.spec.ts +0 -79
  288. package/src/components/modal/composables/useEventListener.ts +0 -22
  289. package/src/components/selectors/__tests__/value-selector.spec.ts +0 -53
  290. package/src/components/sliders/DoubleSliderSelector.vue +0 -141
  291. package/src/components/sliders/__tests__/double-slider-selector.spec.ts +0 -104
  292. package/src/components/sliders/__tests__/vertical-slider-selector.spec.ts +0 -61
  293. package/src/dataLayer/__tests__/getIconForPreset.spec.ts +0 -40
  294. package/src/dataLayer/__tests__/patchDataOverlay.spec.ts +0 -88
  295. package/src/dataLayer/__tests__/scanState.spec.ts +0 -93
  296. package/src/dataLayer/getIconForPreset.ts +0 -11
  297. package/src/dataLayer/patchDataOverlay.ts +0 -101
  298. package/src/dataLayer/useViewer3cr.ts +0 -7
  299. package/src/helpers/__tests__/layout-overlay-style.spec.ts +0 -290
  300. package/src/helpers/__tests__/utils.spec.ts +0 -70
  301. package/src/helpers/layoutOverlayStyle.ts +0 -96
  302. package/src/helpers/utils.ts +0 -16
  303. package/src/models/Callbacks.ts +0 -2
  304. package/src/models/LoadViewerOptions.ts +0 -31
  305. package/src/models/LoadViewerPayload.ts +0 -9
  306. package/src/models/__tests__/load-viewer-options.spec.ts +0 -22
  307. package/src/notifications/notification.ts +0 -50
  308. package/src/plugins/__tests__/index.spec.ts +0 -19
  309. package/src/plugins/index.ts +0 -17
  310. package/src/services/gpt/gpt.service.ts +0 -35
  311. package/static/3cr-types-browser/index.ts +0 -74
  312. package/static/3cr-types-browser/types/Action.ts +0 -6
  313. package/static/3cr-types-browser/types/AlphaKeys.ts +0 -5
  314. package/static/3cr-types-browser/types/AnchorPoint.ts +0 -12
  315. package/static/3cr-types-browser/types/CallToAction.ts +0 -5
  316. package/static/3cr-types-browser/types/ColourData.ts +0 -7
  317. package/static/3cr-types-browser/types/ColourPresetData.ts +0 -9
  318. package/static/3cr-types-browser/types/CurrentDataOverlayState.ts +0 -6
  319. package/static/3cr-types-browser/types/CurrentScanState.ts +0 -22
  320. package/static/3cr-types-browser/types/DataOverlay.ts +0 -22
  321. package/static/3cr-types-browser/types/DataOverlayActions.ts +0 -14
  322. package/static/3cr-types-browser/types/DataOverlayData.ts +0 -8
  323. package/static/3cr-types-browser/types/DataOverlayEvent.ts +0 -8
  324. package/static/3cr-types-browser/types/DecryptionKey.ts +0 -4
  325. package/static/3cr-types-browser/types/DisplaySettings.ts +0 -10
  326. package/static/3cr-types-browser/types/EmptyPayload.ts +0 -3
  327. package/static/3cr-types-browser/types/EnumPayload.ts +0 -4
  328. package/static/3cr-types-browser/types/FileManagementActions.ts +0 -11
  329. package/static/3cr-types-browser/types/FlipValue.ts +0 -7
  330. package/static/3cr-types-browser/types/FrontEndInterfaces.ts +0 -14
  331. package/static/3cr-types-browser/types/GradientKeys.ts +0 -7
  332. package/static/3cr-types-browser/types/GreyscalePresetData.ts +0 -6
  333. package/static/3cr-types-browser/types/InitialDataOverlayState.ts +0 -6
  334. package/static/3cr-types-browser/types/InitialScanState.ts +0 -19
  335. package/static/3cr-types-browser/types/InteractionType.ts +0 -8
  336. package/static/3cr-types-browser/types/InteractivityActions.ts +0 -6
  337. package/static/3cr-types-browser/types/InteractivityState.ts +0 -4
  338. package/static/3cr-types-browser/types/InvertTransformData.ts +0 -6
  339. package/static/3cr-types-browser/types/LayoutActions.ts +0 -6
  340. package/static/3cr-types-browser/types/LayoutData.ts +0 -7
  341. package/static/3cr-types-browser/types/LoadDataSet.ts +0 -6
  342. package/static/3cr-types-browser/types/LoadSessionState.ts +0 -4
  343. package/static/3cr-types-browser/types/LocalLoadDataset.ts +0 -3
  344. package/static/3cr-types-browser/types/MovementData.ts +0 -7
  345. package/static/3cr-types-browser/types/NavigationCubeActions.ts +0 -8
  346. package/static/3cr-types-browser/types/NavigationCubeData.ts +0 -12
  347. package/static/3cr-types-browser/types/NavigationCubeTransform.ts +0 -9
  348. package/static/3cr-types-browser/types/NotificationPayload.ts +0 -7
  349. package/static/3cr-types-browser/types/NotificationsActions.ts +0 -6
  350. package/static/3cr-types-browser/types/Object.ts +0 -1
  351. package/static/3cr-types-browser/types/ObjectColour.ts +0 -7
  352. package/static/3cr-types-browser/types/ObjectIcon.ts +0 -5
  353. package/static/3cr-types-browser/types/ObjectInvert.ts +0 -7
  354. package/static/3cr-types-browser/types/ObjectSize.ts +0 -7
  355. package/static/3cr-types-browser/types/ObjectSize2D.ts +0 -7
  356. package/static/3cr-types-browser/types/ObjectVisible.ts +0 -5
  357. package/static/3cr-types-browser/types/PositionData.ts +0 -14
  358. package/static/3cr-types-browser/types/PresetsActions.ts +0 -4
  359. package/static/3cr-types-browser/types/RotationValue.ts +0 -7
  360. package/static/3cr-types-browser/types/ScanMovementActions.ts +0 -27
  361. package/static/3cr-types-browser/types/ScanMovementData.ts +0 -3
  362. package/static/3cr-types-browser/types/ScanOrientationActions.ts +0 -6
  363. package/static/3cr-types-browser/types/ScanStateActions.ts +0 -4
  364. package/static/3cr-types-browser/types/ScanView.ts +0 -6
  365. package/static/3cr-types-browser/types/SettingsData.ts +0 -12
  366. package/static/3cr-types-browser/types/SlicerData.ts +0 -9
  367. package/static/3cr-types-browser/types/SliderValue.ts +0 -4
  368. package/static/3cr-types-browser/types/SlidersActions.ts +0 -18
  369. package/static/3cr-types-browser/types/Vector2Data.ts +0 -5
  370. package/static/3cr-types-browser/types/Vector3Data.ts +0 -6
  371. package/static/3cr-types-browser/types/VectorMovementData.ts +0 -8
  372. package/static/3cr-types-browser/types/ViewInteractiveMode.ts +0 -5
  373. package/static/3cr-types-browser/types/ViewOrientation.ts +0 -8
  374. package/static/3cr-types-browser/types/ViewOrientations.ts +0 -10
  375. package/static/3cr-types-browser/types/ViewSelectionActions.ts +0 -9
  376. package/static/3cr-types-browser/types/ViewToggleData.ts +0 -7
  377. package/static/3cr-types-browser/types/VolumeOrientation.ts +0 -7
  378. package/test/helper.ts +0 -44
  379. /package/src/components/{sliders → shared}/VerticalSliderSelector.vue +0 -0
  380. /package/{config.ts → src/config.ts} +0 -0
  381. /package/src/{dataLayer → functions}/clamp.ts +0 -0
  382. /package/src/{dataLayer → models}/eventHandlers.ts +0 -0
  383. /package/{static/3cr-types-browser/types/ActionData.ts → src/types/action-data.ts} +0 -0
@@ -1,28 +1,28 @@
1
- import { describe, it, expect, vi } from "vitest";
2
- import { mountVuetify, openAllModals } from "~/helper";
3
- import DemoLicenceEnableCloudStorageModal from "@/components/demo/licence/DemoLicenceEnableCloudStorageModal.vue";
4
- import { PRICING_URL } from "../../options";
1
+ import { PRICING_URL } from '../../options';
2
+ import { mount } from '@vue/test-utils';
3
+ import { VDialog } from 'vuetify/components';
4
+ import DemoLicenceEnableCloudStorageModal from '@/components/demo/licence/DemoLicenceEnableCloudStorageModal.vue';
5
5
 
6
6
  describe('DemoLicenceEnableCloudStorageModal tests', () => {
7
7
  it('should mount', () => {
8
8
  const props = { modal: true };
9
- const wrapper = mountVuetify(DemoLicenceEnableCloudStorageModal, props);
9
+ const wrapper = mount(DemoLicenceEnableCloudStorageModal, { props });
10
10
  expect(wrapper).toBeTruthy();
11
11
  });
12
12
 
13
13
  it('should close modal', async () => {
14
14
  const props = { modal: true };
15
- const wrapper = mountVuetify(DemoLicenceEnableCloudStorageModal, props);
15
+ const wrapper = mount(DemoLicenceEnableCloudStorageModal, { props });
16
16
  const close = wrapper.findComponent('[data-testid="close"]');
17
17
  await close.trigger('click');
18
- expect(wrapper.emitted()['update:modal']).toBeTruthy();
18
+ expect(wrapper.emitted('update:modal')).toBeTruthy();
19
19
  });
20
20
 
21
21
  it('should open pricing url', async () => {
22
22
  vi.stubGlobal('open', vi.fn());
23
23
  const spy = vi.spyOn(window, 'open');
24
24
  const props = { modal: true };
25
- const wrapper = mountVuetify(DemoLicenceEnableCloudStorageModal, props);
25
+ const wrapper = mount(DemoLicenceEnableCloudStorageModal, { props });
26
26
  const button = wrapper.findComponent('[data-testid="confirm"]');
27
27
  await button.trigger('click');
28
28
  expect(spy).toHaveBeenCalledWith(PRICING_URL, '_self');
@@ -31,7 +31,8 @@ describe('DemoLicenceEnableCloudStorageModal tests', () => {
31
31
 
32
32
  it('should open via input', async () => {
33
33
  const props = { modal: false };
34
- const wrapper = mountVuetify(DemoLicenceEnableCloudStorageModal, props);
35
- await openAllModals(wrapper);
34
+ const wrapper = mount(DemoLicenceEnableCloudStorageModal, { props });
35
+ const dialog = wrapper.findComponent(VDialog);
36
+ await dialog.setValue(true);
36
37
  });
37
38
  });
@@ -1,28 +1,28 @@
1
- import { describe, it, expect, vi } from "vitest";
2
- import { mountVuetify, openAllModals } from "~/helper";
3
- import { SUPPORT_URL } from "@/components/demo/options";
4
- import DemoLicenceInfoModal from "@/components/demo/licence/DemoLicenceInfoModal.vue";
1
+ import { demoLicenceSubtitles, demoLicenceTitle, SUPPORT_URL } from '@/components/demo/options';
2
+ import { mount } from '@vue/test-utils';
3
+ import { VCardText, VCardTitle, VDialog } from 'vuetify/components';
4
+ import DemoLicenceInfoModal from '@/components/demo/licence/DemoLicenceInfoModal.vue';
5
5
 
6
6
  describe('DemoLicenceInfoModal tests', () => {
7
7
  it('should mount', () => {
8
8
  const props = { modal: true, isModalOpen: true };
9
- const wrapper = mountVuetify(DemoLicenceInfoModal, props);
9
+ const wrapper = mount(DemoLicenceInfoModal, { props });
10
10
  expect(wrapper).toBeTruthy();
11
11
  });
12
12
 
13
13
  it('should close modal', async () => {
14
14
  const props = { modal: true, isModalOpen: true };
15
- const wrapper = mountVuetify(DemoLicenceInfoModal, props);
15
+ const wrapper = mount(DemoLicenceInfoModal, { props });
16
16
  const close = wrapper.findComponent('[data-testid="close"]');
17
17
  await close.trigger('click');
18
- expect(wrapper.emitted()['update:modal']).toBeTruthy();
18
+ expect(wrapper.emitted('update:modal')).toBeTruthy();
19
19
  });
20
20
 
21
21
  it('should open support url', async () => {
22
22
  vi.stubGlobal('open', vi.fn());
23
23
  const spy = vi.spyOn(window, 'open');
24
- const props = { modal: true };
25
- const wrapper = mountVuetify(DemoLicenceInfoModal, props);
24
+ const props = { modal: true, isModalOpen: true };
25
+ const wrapper = mount(DemoLicenceInfoModal, { props });
26
26
  const button = wrapper.findComponent('[data-testid="confirm"]');
27
27
  await button.trigger('click');
28
28
  expect(spy).toHaveBeenCalledWith(SUPPORT_URL, '_self');
@@ -31,7 +31,17 @@ describe('DemoLicenceInfoModal tests', () => {
31
31
 
32
32
  it('should open via input', async () => {
33
33
  const props = { modal: false, isModalOpen: true };
34
- const wrapper = mountVuetify(DemoLicenceInfoModal, props);
35
- await openAllModals(wrapper);
34
+ const wrapper = mount(DemoLicenceInfoModal, { props });
35
+ const dialog = wrapper.findComponent(VDialog);
36
+ await dialog.setValue(true);
37
+ });
38
+
39
+ it('should show title and subtitle', async () => {
40
+ vi.spyOn(demoLicenceTitle, 'value', 'get').mockReturnValue('Title');
41
+ vi.spyOn(demoLicenceSubtitles, 'value', 'get').mockReturnValue(['Subtitle']);
42
+ const props = { modal: true, isModalOpen: true };
43
+ const wrapper = mount(DemoLicenceInfoModal, { props });
44
+ expect(wrapper.findComponent(VCardTitle).text()).contains('Title');
45
+ expect(wrapper.findComponent(VCardText).text()).contains('Subtitle');
36
46
  });
37
47
  });
@@ -1,18 +1,17 @@
1
- import { describe, expect, it } from "vitest";
2
- import { mountVuetify, openAllModals } from "~/helper";
3
- import { VTextField } from "vuetify/components";
4
- import DemoLicenceSendToPartyModal from "@/components/demo/licence/DemoLicenceSendToPartyModal.vue";
1
+ import { VDialog, VTextField } from 'vuetify/components';
2
+ import { mount } from '@vue/test-utils';
3
+ import DemoLicenceSendToPartyModal from '@/components/demo/licence/DemoLicenceSendToPartyModal.vue';
5
4
 
6
5
  describe('DemoLicenceSendToPartyModal tests', () => {
7
6
  it('should mount', () => {
8
7
  const props = { modal: true };
9
- const wrapper = mountVuetify(DemoLicenceSendToPartyModal, props);
8
+ const wrapper = mount(DemoLicenceSendToPartyModal, { props });
10
9
  expect(wrapper).toBeTruthy();
11
10
  });
12
11
 
13
12
  it('should enter email', async () => {
14
13
  const props = { modal: true };
15
- const wrapper = mountVuetify(DemoLicenceSendToPartyModal, props);
14
+ const wrapper = mount(DemoLicenceSendToPartyModal, { props });
16
15
  const input = wrapper.getComponent(VTextField);
17
16
  await input.setValue('example@singular.health');
18
17
  await input.trigger('keyup.enter');
@@ -22,15 +21,16 @@ describe('DemoLicenceSendToPartyModal tests', () => {
22
21
 
23
22
  it('should close modal', async () => {
24
23
  const props = { modal: true };
25
- const wrapper = mountVuetify(DemoLicenceSendToPartyModal, props);
24
+ const wrapper = mount(DemoLicenceSendToPartyModal, { props });
26
25
  const close = wrapper.findComponent('[data-testid="close"]');
27
26
  await close.trigger('click');
28
- expect(wrapper.emitted()['update:modal']).toBeTruthy();
27
+ expect(wrapper.emitted('update:modal')).toBeTruthy();
29
28
  });
30
29
 
31
30
  it('should open via input', async () => {
32
31
  const props = { modal: false };
33
- const wrapper = mountVuetify(DemoLicenceSendToPartyModal, props);
34
- await openAllModals(wrapper);
32
+ const wrapper = mount(DemoLicenceSendToPartyModal, { props });
33
+ const dialog = wrapper.findComponent(VDialog);
34
+ await dialog.setValue(true);
35
35
  });
36
36
  });
@@ -1,31 +1,31 @@
1
- import { describe, expect, it, vi } from "vitest";
2
- import { mountVuetify, openAllModals } from "~/helper";
3
- import { PRICING_URL } from "../../options";
4
- import DemoLicenceShareToMobileModal from "@/components/demo/licence/DemoLicenceShareToMobileModal.vue";
1
+ import { PRICING_URL } from '../../options';
2
+ import { mount } from '@vue/test-utils';
3
+ import { VDialog } from 'vuetify/components';
4
+ import DemoLicenceShareToMobileModal from '@/components/demo/licence/DemoLicenceShareToMobileModal.vue';
5
5
 
6
6
  describe('DemoLicenceShareToMobileModal tests', () => {
7
7
  it('should mount', () => {
8
8
  const props = { modal: true };
9
- const wrapper = mountVuetify(DemoLicenceShareToMobileModal, props);
9
+ const wrapper = mount(DemoLicenceShareToMobileModal, { props });
10
10
  expect(wrapper).toBeTruthy();
11
11
  });
12
12
 
13
13
  it('should close modal', async () => {
14
14
  const props = { modal: true };
15
- const wrapper = mountVuetify(DemoLicenceShareToMobileModal, props);
15
+ const wrapper = mount(DemoLicenceShareToMobileModal, { props });
16
16
  const close = wrapper.findComponent('[data-testid="close-1"]');
17
17
  await close.trigger('click');
18
- expect(wrapper.emitted()['update:modal']).toBeTruthy();
18
+ expect(wrapper.emitted('update:modal')).toBeTruthy();
19
19
  });
20
20
 
21
21
  it('should go to next step and open url', async () => {
22
22
  vi.stubGlobal('open', vi.fn());
23
23
  const spy = vi.spyOn(window, 'open');
24
24
  const props = { modal: true };
25
- const wrapper = mountVuetify(DemoLicenceShareToMobileModal, props);
25
+ const wrapper = mount(DemoLicenceShareToMobileModal, { props });
26
26
  const confirm1 = wrapper.findComponent('[data-testid="confirm-1"]');
27
27
  await confirm1.trigger('click');
28
- expect(wrapper.emitted()['update:modal']).toBeTruthy();
28
+ expect(wrapper.emitted('update:modal')).toBeTruthy();
29
29
  const confirm2 = wrapper.findComponent('[data-testid="confirm-2"]');
30
30
  await confirm2.trigger('click');
31
31
  expect(spy).toHaveBeenCalledWith(PRICING_URL, '_self');
@@ -34,10 +34,10 @@ describe('DemoLicenceShareToMobileModal tests', () => {
34
34
 
35
35
  it('should go to next step and close', async () => {
36
36
  const props = { modal: true };
37
- const wrapper = mountVuetify(DemoLicenceShareToMobileModal, props);
37
+ const wrapper = mount(DemoLicenceShareToMobileModal, { props });
38
38
  const confirm1 = wrapper.findComponent('[data-testid="confirm-1"]');
39
39
  await confirm1.trigger('click');
40
- expect(wrapper.emitted()['update:modal']).toBeTruthy();
40
+ expect(wrapper.emitted('update:modal')).toBeTruthy();
41
41
  const close2 = wrapper.findComponent('[data-testid="close-2"]');
42
42
  await close2.trigger('click');
43
43
  expect(wrapper.text()).toBe('');
@@ -45,7 +45,8 @@ describe('DemoLicenceShareToMobileModal tests', () => {
45
45
 
46
46
  it('should open via input', async () => {
47
47
  const props = { modal: false };
48
- const wrapper = mountVuetify(DemoLicenceShareToMobileModal, props);
49
- await openAllModals(wrapper);
48
+ const wrapper = mount(DemoLicenceShareToMobileModal, { props });
49
+ const dialog = wrapper.findComponent(VDialog);
50
+ await dialog.setValue(true);
50
51
  });
51
52
  });
@@ -1,18 +1,20 @@
1
- import { computed, ref, unref, watch } from "vue";
2
- import { LoadViewerOptions } from "@/models/LoadViewerOptions";
3
- import { LoadViewerPayload } from "@/models/LoadViewerPayload";
1
+ import { computed, ref } from 'vue';
2
+ import { LoadViewerOptions } from '@/models/loadViewerOptions';
3
+ import { LoadViewerPayload } from '@/models/loadViewerPayload';
4
+ import { useViewer3cr } from '@/composables/useViewer3cr';
5
+ import { mockDemoViewerStlDecimator } from '@/composables/useViewerOptions';
6
+ import { DemoType } from '@/types/demo-type';
4
7
 
5
8
  export const PRICING_URL = 'https://3dicomviewer.com/pricing';
9
+
6
10
  export const SUPPORT_URL = 'https://3dicomviewer.com/contact-3dicom';
7
11
 
8
- export function checkIsDemo(payload: LoadViewerPayload) {
9
- isDemo.value =
10
- payload.Url ===
11
- "https://webgl-3dr.singular.health/test_scans/01440d4e-8b04-4b90-bb2c-698535ce16d6/CHEST.3vxl";
12
- }
12
+ const BASE_STATE_URL = 'https://webgl-3dr.singular.health/demo';
13
13
 
14
+ const viewer3cr = useViewer3cr();
14
15
  export const isDemo = ref<boolean>(false);
15
- export const m_demo = ref<boolean>(false);
16
+ export const show = ref<boolean>(true);
17
+ export const m_demoLicence = ref<boolean>(false);
16
18
  export const m_demoLicenceShareToMobile = ref<boolean>(false);
17
19
  export const m_demoLicenceSendToParty = ref<boolean>(false);
18
20
  export const m_demoLicenseEnableCloudStorage = ref<boolean>(false);
@@ -20,50 +22,47 @@ export const m_demoPatient = ref<boolean>(false);
20
22
  export const m_demoPatientShareToMobile = ref<boolean>(false);
21
23
  export const m_demoPatientSendToParty = ref<boolean>(false);
22
24
  export const m_demoPatientEnableCloudStorage = ref<boolean>(false);
23
- export const demoPatientTitle = ref<string>("");
25
+ export const demoPatientTitle = ref<string>('');
24
26
  export const demoPatientSubtitles = ref<Array<string>>([]);
25
- export const demoLicenceTitle = ref<string>("");
27
+ export const demoLicenceTitle = ref<string>('');
26
28
  export const demoLicenceSubtitles = ref<Array<string>>([]);
27
29
 
28
30
  export const demoLicenceOptions: LoadViewerOptions = {
29
- OnClosePopup: () => Promise.resolve(),
31
+ OnClosePopup: undefined,
30
32
  OnExitViewer: () => {
31
- demoLicenceTitle.value = "Thank you for trying the 3Dicom Licensing Demo.";
33
+ demoLicenceTitle.value = 'Thank you for trying the 3Dicom Licensing Demo.';
32
34
  demoLicenceSubtitles.value = [
33
- "Should you have any further questions or enquiries, please get in touch by emailing support@singular.health",
35
+ 'Should you have any further questions or enquiries, please get in touch by emailing support@singular.health'
34
36
  ];
35
- m_demo.value = true;
37
+ m_demoLicence.value = true;
38
+ show.value = false;
36
39
  },
37
40
  OnLoadNewDicomSeries: () => {
38
- demoLicenceTitle.value = "Support multiple medical imaging file types";
41
+ demoLicenceTitle.value = 'Support multiple medical imaging file types';
39
42
  demoLicenceSubtitles.value = [
40
- "3Dicom’s white-labelled online 2D / 3D DICOM viewer allows the loading of X-Ray (XR), Ultrasound (US), Computed Tomography (CT), Magnetic Resonance Imaging (MRI), and Positron Emitting Tomography (PET) using the global DICOM file format.",
43
+ '3Dicom’s white-labelled online 2D / 3D DICOM viewer allows the loading of X-Ray (XR), Ultrasound (US), Computed Tomography (CT), Magnetic Resonance Imaging (MRI), and Positron Emitting Tomography (PET) using the global DICOM file format.'
41
44
  ];
42
45
 
43
- m_demo.value = true;
46
+ m_demoLicence.value = true;
44
47
  },
45
48
  OnDownloadDicomSeries: () => {
46
- demoLicenceTitle.value =
47
- "Improve interoperability with local download of DICOM series";
49
+ demoLicenceTitle.value = 'Improve interoperability with local download of DICOM series';
48
50
  demoLicenceSubtitles.value = [
49
- "Integrate 3Dicom’s white-labelled online 2D/3D viewer into your PACS and/or medical records database to pull DICOM series and allow for local download direct from the viewer. This feature can be hidden upon request.",
51
+ 'Integrate 3Dicom’s white-labelled online 2D/3D viewer into your PACS and/or medical records database to pull DICOM series and allow for local download direct from the viewer. This feature can be hidden upon request.'
50
52
  ];
51
- m_demo.value = true;
53
+ m_demoLicence.value = true;
52
54
  },
53
55
  OnLoadSavedSession: () => {
54
- demoLicenceTitle.value =
55
- "Save previous progress and share particular sessions";
56
+ demoLicenceTitle.value = 'Save previous progress and share particular sessions';
56
57
  demoLicenceSubtitles.value = [
57
- "3Dicom’s viewer enables session-saving to record any changes made during the viewing of medical scans including orientation of views, editing of labels, visualisation settings, and density settings. Changes made during sessions preserve the integrity of the DICOM file and are overlaid in future sessions.",
58
+ '3Dicom’s viewer enables session-saving to record any changes made during the viewing of medical scans including orientation of views, editing of labels, visualisation settings, and density settings. Changes made during sessions preserve the integrity of the DICOM file and are overlaid in future sessions.'
58
59
  ];
59
- m_demo.value = true;
60
+ m_demoLicence.value = true;
60
61
  },
61
62
  OnSaveSession: () => {
62
- demoLicenceTitle.value = "Thank you for trying the 3Dicom Licensing Demo.";
63
- demoLicenceSubtitles.value = [
64
- "Each 3Dicom viewer session can be saved with your changes made for future viewing.",
65
- ];
66
- m_demo.value = true;
63
+ demoLicenceTitle.value = 'Thank you for trying the 3Dicom Licensing Demo.';
64
+ demoLicenceSubtitles.value = ['Each 3Dicom viewer session can be saved with your changes made for future viewing.'];
65
+ m_demoLicence.value = true;
67
66
  },
68
67
  OnSendTo3rdParty: () => {
69
68
  m_demoLicenceSendToParty.value = true;
@@ -74,60 +73,52 @@ export const demoLicenceOptions: LoadViewerOptions = {
74
73
  OnEnableCloudStorage: () => {
75
74
  m_demoLicenseEnableCloudStorage.value = true;
76
75
  },
77
- OnShare: () => {
78
- //TODO:
79
- // m_demo.value = true;
76
+ OnAutoAnnotate: async () => {
77
+ mockDemoViewerStlDecimator();
78
+ await viewer3cr.loadMcadObjects({ Url: `${BASE_STATE_URL}/state/TotalSegmentator_1722837421466.3crms` });
80
79
  },
80
+ OnShare: undefined,
81
81
  OnScreenshot: undefined,
82
- OnErrorClose: () => Promise.resolve(),
82
+ OnErrorClose: undefined
83
83
  };
84
84
 
85
85
  export const demoPatientOptions: LoadViewerOptions = {
86
- OnClosePopup: () => Promise.resolve(),
86
+ OnClosePopup: undefined,
87
87
  OnExitViewer: () => {
88
- demoPatientTitle.value = "Thank you for trying the 3Dicom Patient Demo.";
88
+ demoPatientTitle.value = 'Thank you for trying the 3Dicom Patient Demo.';
89
89
  demoPatientSubtitles.value = [
90
- "Should you have any further questions or enquiries, please get in touch by emailing support@singular.health",
90
+ 'Should you have any further questions or enquiries, please get in touch by emailing support@singular.health'
91
91
  ];
92
92
  m_demoPatient.value = true;
93
- watch(m_demoPatient, () => {
94
- if (!m_demoPatient) {
95
- window.close();
96
- }
97
- });
93
+ show.value = false;
98
94
  },
99
95
  OnLoadNewDicomSeries: () => {
100
- demoPatientTitle.value =
101
- "3Dicom Patient supports multiple Medical Imaging Formats";
96
+ demoPatientTitle.value = '3Dicom Patient supports multiple Medical Imaging Formats';
102
97
  demoPatientSubtitles.value = [
103
- "3Dicom Patient enables you to load of X-Ray (XR), Ultrasound (US), Computed Tomography (CT), Magnetic Resonance Imaging (MRI), and Positron Emitting Tomography (PET), using the global DICOM file format.",
104
- "Purchase 3Dicom Patient to load your own medical images and view in 2D / 3D.",
98
+ '3Dicom Patient enables you to load of X-Ray (XR), Ultrasound (US), Computed Tomography (CT), Magnetic Resonance Imaging (MRI), and Positron Emitting Tomography (PET), using the global DICOM file format.',
99
+ 'Purchase 3Dicom Patient to load your own medical images and view in 2D / 3D.'
105
100
  ];
106
101
  m_demoPatient.value = true;
107
102
  },
108
103
  OnDownloadDicomSeries: () => {
109
- demoPatientTitle.value =
110
- "3Dicom Patient enables on-demand download of DICOM series";
104
+ demoPatientTitle.value = '3Dicom Patient enables on-demand download of DICOM series';
111
105
  demoPatientSubtitles.value = [
112
- "3Dicom Patient enables you to store your medical imaging and related files / reports online or share them temporarily between devices. ",
113
- "DICOM files can be downloaded to your device for local storage and providing to 3rd parties via CD/USB.",
114
- "Purchase 3Dicom Patient to gain control over your DICOM file storage.",
106
+ '3Dicom Patient enables you to store your medical imaging and related files / reports online or share them temporarily between devices. ',
107
+ 'DICOM files can be downloaded to your device for local storage and providing to 3rd parties via CD/USB.',
108
+ 'Purchase 3Dicom Patient to gain control over your DICOM file storage.'
115
109
  ];
116
110
  m_demoPatient.value = true;
117
111
  },
118
112
  OnLoadSavedSession: () => {
119
- demoPatientTitle.value =
120
- "3Dicom Patient allows you to load previous Sessions";
113
+ demoPatientTitle.value = '3Dicom Patient allows you to load previous Sessions';
121
114
  demoPatientSubtitles.value = [
122
- "3Dicom Patient gives you to option to save any changes made during the viewing of your scan including orientation of views, editing of labels, visualisation settings, and density settings to easily view your scans the same way in the future. Session data can also be shared to 3rd parties so they see your scan the same way that you do.",
115
+ '3Dicom Patient gives you to option to save any changes made during the viewing of your scan including orientation of views, editing of labels, visualisation settings, and density settings to easily view your scans the same way in the future. Session data can also be shared to 3rd parties so they see your scan the same way that you do.'
123
116
  ];
124
117
  m_demoPatient.value = true;
125
118
  },
126
119
  OnSaveSession: () => {
127
- demoPatientTitle.value = "Thank you for trying the 3Dicom Patient Demo.";
128
- demoPatientSubtitles.value = [
129
- "Each 3Dicom viewer session can be saved with your changes made for future viewing.",
130
- ];
120
+ demoPatientTitle.value = 'Thank you for trying the 3Dicom Patient Demo.';
121
+ demoPatientSubtitles.value = ['Each 3Dicom viewer session can be saved with your changes made for future viewing.'];
131
122
  m_demoPatient.value = true;
132
123
  },
133
124
  OnSendTo3rdParty: () => {
@@ -139,34 +130,41 @@ export const demoPatientOptions: LoadViewerOptions = {
139
130
  OnEnableCloudStorage: () => {
140
131
  m_demoPatientEnableCloudStorage.value = true;
141
132
  },
142
- OnShare: () => {
143
- //TODO:
144
- // m_demoPatient.value = true;
145
- },
133
+ OnAutoAnnotate: demoLicenceOptions.OnAutoAnnotate,
134
+ OnShare: undefined,
146
135
  OnScreenshot: undefined,
147
- OnErrorClose: () => Promise.resolve(),
136
+ OnErrorClose: undefined
148
137
  };
149
138
 
150
- const optionalTypes = ["licence", "patient"];
139
+ export function checkIsDemo(payload: LoadViewerPayload) {
140
+ isDemo.value = payload.Url.startsWith('https://webgl-3dr.singular.health/demo');
141
+ }
151
142
 
152
143
  export const demoType = computed(() => {
153
144
  const urlParams = new URLSearchParams(window.location.search);
154
- let type = (urlParams.get("demoType") || "licence").toLowerCase();
155
-
156
- if (type === "license") type = optionalTypes[0];
157
- return optionalTypes.includes(type) ? type : optionalTypes[0];
145
+ if (urlParams.has('demoType')) {
146
+ const demoType = urlParams.get('demoType')!.toLowerCase();
147
+ switch (demoType) {
148
+ case 'patient':
149
+ return DemoType.Patient;
150
+ case 'licence':
151
+ return DemoType.Licence;
152
+ }
153
+ }
154
+ return DemoType.Patient;
158
155
  });
159
156
 
160
157
  export const demoOptions = computed(() => {
161
- if (unref(demoType) === "licence") {
162
- return demoLicenceOptions;
163
- } else if (unref(demoType) === "patient") {
164
- return demoPatientOptions;
165
- } else {
166
- throw new Error('Unknown demo type');
158
+ switch (demoType.value) {
159
+ case DemoType.Patient:
160
+ return demoPatientOptions;
161
+ case DemoType.Licence:
162
+ return demoLicenceOptions;
163
+ default:
164
+ throw new Error('Unknown demo type');
167
165
  }
168
166
  });
169
167
 
170
- export function openUrl(url: string, target: string = "_self") {
168
+ export function openUrl(url: string, target: string = '_self') {
171
169
  window.open(url, target);
172
170
  }
@@ -1,23 +1,19 @@
1
1
  <script setup lang="ts">
2
- import { computed } from "vue";
3
- import {
4
- demoPatientSubtitles,
5
- demoPatientTitle,
6
- openUrl, PRICING_URL,
7
- } from "@/components/demo/options";
2
+ import { computed } from 'vue';
3
+ import { demoPatientSubtitles, demoPatientTitle, openUrl, PRICING_URL } from '@/components/demo/options';
8
4
 
9
5
  export interface Props {
10
6
  modal: boolean;
11
- isModalOpen: boolean;
7
+ isModalOpen?: boolean;
12
8
  }
13
9
 
14
10
  const emit = defineEmits<{
15
- "update:modal": [value: boolean];
11
+ 'update:modal': [value: boolean];
16
12
  }>();
17
13
 
18
14
  const props = withDefaults(defineProps<Props>(), {
19
15
  modal: false,
20
- isModalOpen: true,
16
+ isModalOpen: true
21
17
  });
22
18
 
23
19
  const modalState = computed({
@@ -25,25 +21,16 @@ const modalState = computed({
25
21
  return props.modal;
26
22
  },
27
23
  set(value) {
28
- emit("update:modal", value);
29
- },
24
+ emit('update:modal', value);
25
+ }
30
26
  });
31
27
  </script>
32
28
 
33
29
  <template>
34
30
  <v-dialog v-model:model-value="modalState">
35
- <v-card
36
- class="pa-1 ma-auto position-relative motif-background card-bg-border"
37
- theme="dark"
38
- max-width="680"
39
- >
40
- <v-card-title class="text-center mb-4 mt-2 font-weight-bold">{{
41
- demoPatientTitle
42
- }}</v-card-title>
43
- <v-card-text
44
- class="text-justify"
45
- v-for="subtitle in demoPatientSubtitles"
46
- :key="subtitle"
31
+ <v-card class="pa-1 ma-auto position-relative motif-background card-bg-border" theme="dark" max-width="680">
32
+ <v-card-title class="text-center mb-4 mt-2 font-weight-bold">{{ demoPatientTitle }}</v-card-title>
33
+ <v-card-text class="text-justify" v-for="subtitle in demoPatientSubtitles" :key="subtitle"
47
34
  >{{ subtitle }}
48
35
  </v-card-text>
49
36
  <v-card-actions class="mt-4">
@@ -51,12 +38,7 @@ const modalState = computed({
51
38
  Continue with Demo
52
39
  </v-btn>
53
40
  <v-spacer />
54
- <v-btn
55
- data-testid="confirm"
56
- variant="flat"
57
- color="success"
58
- @click="openUrl(PRICING_URL)"
59
- >
41
+ <v-btn data-testid="confirm" variant="flat" color="success" @click="openUrl(PRICING_URL)">
60
42
  Purchase 3Dicom Patient
61
43
  </v-btn>
62
44
  </v-card-actions>
@@ -1,28 +1,28 @@
1
- import { describe, it, expect, vi } from "vitest";
2
- import { mountVuetify, openAllModals } from "~/helper";
3
- import DemoPatientEnableCloudStorageModal from "@/components/demo/patient/DemoPatientEnableCloudStorageModal.vue";
4
- import { PRICING_URL } from "../../options";
1
+ import { PRICING_URL } from '../../options';
2
+ import { mount } from '@vue/test-utils';
3
+ import DemoPatientEnableCloudStorageModal from '@/components/demo/patient/DemoPatientEnableCloudStorageModal.vue';
4
+ import { VDialog } from 'vuetify/components';
5
5
 
6
6
  describe('DemoPatientEnableCloudStorageModal tests', () => {
7
7
  it('should mount', () => {
8
8
  const props = { modal: true };
9
- const wrapper = mountVuetify(DemoPatientEnableCloudStorageModal, props);
9
+ const wrapper = mount(DemoPatientEnableCloudStorageModal, { props });
10
10
  expect(wrapper).toBeTruthy();
11
11
  });
12
12
 
13
13
  it('should close modal', async () => {
14
14
  const props = { modal: true };
15
- const wrapper = mountVuetify(DemoPatientEnableCloudStorageModal, props);
15
+ const wrapper = mount(DemoPatientEnableCloudStorageModal, { props });
16
16
  const close = wrapper.findComponent('[data-testid="close"]');
17
17
  await close.trigger('click');
18
- expect(wrapper.emitted()['update:modal']).toBeTruthy();
18
+ expect(wrapper.emitted('update:modal')).toBeTruthy();
19
19
  });
20
20
 
21
21
  it('should open pricing url', async () => {
22
22
  vi.stubGlobal('open', vi.fn());
23
23
  const spy = vi.spyOn(window, 'open');
24
24
  const props = { modal: true };
25
- const wrapper = mountVuetify(DemoPatientEnableCloudStorageModal, props);
25
+ const wrapper = mount(DemoPatientEnableCloudStorageModal, { props });
26
26
  const button = wrapper.findComponent('[data-testid="confirm"]');
27
27
  await button.trigger('click');
28
28
  expect(spy).toHaveBeenCalledWith(PRICING_URL, '_self');
@@ -31,7 +31,8 @@ describe('DemoPatientEnableCloudStorageModal tests', () => {
31
31
 
32
32
  it('should open via input', async () => {
33
33
  const props = { modal: false };
34
- const wrapper = mountVuetify(DemoPatientEnableCloudStorageModal, props);
35
- await openAllModals(wrapper);
34
+ const wrapper = mount(DemoPatientEnableCloudStorageModal, { props });
35
+ const dialog = wrapper.findComponent(VDialog);
36
+ await dialog.setValue(true);
36
37
  });
37
38
  });
@@ -1,28 +1,28 @@
1
- import { describe, it, expect, vi } from "vitest";
2
- import { mountVuetify, openAllModals } from "~/helper";
3
- import { PRICING_URL } from "@/components/demo/options";
4
- import DemoPatientInfoModal from "@/components/demo/patient/DemoPatientInfoModal.vue";
1
+ import { mount } from '@vue/test-utils';
2
+ import { PRICING_URL } from '@/components/demo/options';
3
+ import { VDialog } from 'vuetify/components';
4
+ import DemoPatientInfoModal from '@/components/demo/patient/DemoPatientInfoModal.vue';
5
5
 
6
6
  describe('DemoPatientInfoModal tests', () => {
7
7
  it('should mount', () => {
8
8
  const props = { modal: true, isModalOpen: true };
9
- const wrapper = mountVuetify(DemoPatientInfoModal, props);
9
+ const wrapper = mount(DemoPatientInfoModal, { props });
10
10
  expect(wrapper).toBeTruthy();
11
11
  });
12
12
 
13
13
  it('should close modal', async () => {
14
14
  const props = { modal: true, isModalOpen: true };
15
- const wrapper = mountVuetify(DemoPatientInfoModal, props);
15
+ const wrapper = mount(DemoPatientInfoModal, { props });
16
16
  const close = wrapper.findComponent('[data-testid="close"]');
17
17
  await close.trigger('click');
18
- expect(wrapper.emitted()['update:modal']).toBeTruthy();
18
+ expect(wrapper.emitted('update:modal')).toBeTruthy();
19
19
  });
20
20
 
21
21
  it('should open support url', async () => {
22
22
  vi.stubGlobal('open', vi.fn());
23
23
  const spy = vi.spyOn(window, 'open');
24
- const props = { modal: true };
25
- const wrapper = mountVuetify(DemoPatientInfoModal, props);
24
+ const props = { modal: true, isModalOpen: true };
25
+ const wrapper = mount(DemoPatientInfoModal, { props });
26
26
  const button = wrapper.findComponent('[data-testid="confirm"]');
27
27
  await button.trigger('click');
28
28
  expect(spy).toHaveBeenCalledWith(PRICING_URL, '_self');
@@ -31,7 +31,8 @@ describe('DemoPatientInfoModal tests', () => {
31
31
 
32
32
  it('should open via input', async () => {
33
33
  const props = { modal: false, isModalOpen: true };
34
- const wrapper = mountVuetify(DemoPatientInfoModal, props);
35
- await openAllModals(wrapper);
34
+ const wrapper = mount(DemoPatientInfoModal, { props });
35
+ const dialog = wrapper.findComponent(VDialog);
36
+ await dialog.setValue(true);
36
37
  });
37
38
  });