@3cr/viewer-browser 0.0.162 → 0.0.194

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 (188) hide show
  1. package/.circleci/config.yml +8 -6
  2. package/__tests__/index.spec.ts +31 -24
  3. package/components.d.ts +32 -0
  4. package/dist/Viewer3CR.js +44 -27
  5. package/dist/Viewer3CR.mjs +22731 -17742
  6. package/dist/Viewer3CR.umd.js +44 -27
  7. package/index.html +5 -8
  8. package/index.ts +7 -2
  9. package/package.json +4 -2
  10. package/playground/index.html +6 -4
  11. package/src/App.vue +12 -4
  12. package/src/__tests__/app.spec.ts +2 -13
  13. package/src/assets/magic_wand.svg +24 -0
  14. package/src/components/WebGL3DR.vue +53 -92
  15. package/src/components/__tests__/webgl3dr.spec.ts +29 -48
  16. package/src/{demo → components/demo}/DemoModal.vue +1 -1
  17. package/src/{demo → components/demo}/DemoPatientModal.vue +4 -1
  18. package/src/components/demo/__tests__/DemoModal.spec.ts +25 -0
  19. package/src/components/demo/__tests__/DemoPatientModal.spec.ts +37 -0
  20. package/src/components/demo/__tests__/options.spec.ts +25 -0
  21. package/src/components/demo/licence/DemoLicenceEnableCloudStorageModal.vue +64 -0
  22. package/src/{demo → components/demo}/licence/DemoLicenceInfoModal.vue +5 -4
  23. package/src/{demo → components/demo}/licence/DemoLicenceSendToPartyModal.vue +6 -4
  24. package/src/{demo → components/demo}/licence/DemoLicenceShareToMobileModal.vue +8 -6
  25. package/src/components/demo/licence/__tests__/DemoLicenceEnableCloudStorageModal.spec.ts +37 -0
  26. package/src/components/demo/licence/__tests__/DemoLicenceInfoModal.spec.ts +37 -0
  27. package/src/components/demo/licence/__tests__/DemoLicenceSendToPartyModal.spec.ts +36 -0
  28. package/src/components/demo/licence/__tests__/DemoLicenceShareToMobileModal.spec.ts +51 -0
  29. package/src/{demo → components/demo}/options.ts +18 -20
  30. package/src/components/demo/patient/DemoPatientEnableCloudStorageModal.vue +64 -0
  31. package/src/{demo → components/demo}/patient/DemoPatientInfoModal.vue +5 -4
  32. package/src/{demo → components/demo}/patient/DemoPatientSendToPartyModal.vue +4 -3
  33. package/src/{demo → components/demo}/patient/DemoPatientShareToMobileModal.vue +8 -6
  34. package/src/components/demo/patient/__tests__/DemoPatientEnableCloudStorageModal.spec.ts +37 -0
  35. package/src/components/demo/patient/__tests__/DemoPatientInfoModal.spec.ts +37 -0
  36. package/src/components/demo/patient/__tests__/DemoPatientSendToPartyModal.spec.ts +36 -0
  37. package/src/components/demo/patient/__tests__/DemoPatientShareToMobileModal.spec.ts +51 -0
  38. package/src/components/loading/LoadingSpinner.vue +1 -1
  39. package/src/components/modal/ActionRail.vue +96 -0
  40. package/src/components/modal/AskAI.vue +250 -0
  41. package/src/components/modal/CloseViewerModal.vue +104 -0
  42. package/src/components/modal/MftpWebGL3DRModal.vue +415 -834
  43. package/src/components/modal/ViewerActionRail.vue +123 -0
  44. package/src/components/modal/ViewerAnnotationModal.vue +115 -0
  45. package/src/components/modal/ViewerAnnotations.vue +283 -0
  46. package/src/components/modal/ViewerDisplaySettings.vue +102 -0
  47. package/src/components/modal/ViewerNavigationDrawer.vue +90 -0
  48. package/src/components/modal/ViewerNavigationDrawerContent.vue +126 -0
  49. package/src/components/modal/ViewerNavigationDrawerFooter.vue +111 -0
  50. package/src/components/modal/ViewerNavigationDrawerHeader.vue +63 -0
  51. package/src/components/modal/__tests__/CloseViewerModal.spec.ts +60 -0
  52. package/src/components/modal/__tests__/{mftp-webgl-3dr-modal.spec.ts → MftpWebGL3DRModal.spec.ts} +47 -298
  53. package/src/components/modal/__tests__/ViewerAnnotationModal.spec.ts +79 -0
  54. package/src/components/modal/__tests__/ViewerDisplaySettings.spec.ts +61 -0
  55. package/src/components/modal/__tests__/ViewerNavigationDrawer.spec.ts +32 -0
  56. package/src/components/modal/__tests__/ViewerNavigationDrawerContent.spec.ts +29 -0
  57. package/src/components/modal/__tests__/ViewerNavigationDrawerFooter.spec.ts +43 -0
  58. package/src/components/modal/__tests__/ViewerNavigationDrawerHeader.spec.ts +37 -0
  59. package/src/components/modal/actions/Action.vue +40 -0
  60. package/src/components/modal/actions/Flip3dAction.vue +79 -0
  61. package/src/components/modal/actions/FlipHorizontalAction.vue +36 -0
  62. package/src/components/modal/actions/FlipVerticalAction.vue +36 -0
  63. package/src/components/modal/actions/FullscreenAction.vue +47 -0
  64. package/src/components/modal/actions/NavigationCubeAction.vue +33 -0
  65. package/src/components/modal/actions/PanAction.vue +78 -0
  66. package/src/components/modal/actions/ResetViewAction.vue +29 -0
  67. package/src/components/modal/actions/Rotate2dAction.vue +78 -0
  68. package/src/components/modal/actions/Slice3dAction.vue +71 -0
  69. package/src/components/modal/actions/ZoomAction.vue +70 -0
  70. package/src/components/modal/actions/__tests__/Action.spec.ts +29 -0
  71. package/src/components/modal/actions/__tests__/Flip3dAction.spec.ts +48 -0
  72. package/src/components/modal/actions/__tests__/FlipHorizontalAction.spec.ts +17 -0
  73. package/src/components/modal/actions/__tests__/FlipVerticalAction.spec.ts +17 -0
  74. package/src/components/modal/actions/__tests__/FullscreenAction.spec.ts +28 -0
  75. package/src/components/modal/actions/__tests__/NavigationCubeAction.spec.ts +25 -0
  76. package/src/components/modal/actions/__tests__/PanAction.spec.ts +46 -0
  77. package/src/components/modal/actions/__tests__/ResetViewAction.spec.ts +17 -0
  78. package/src/components/modal/actions/__tests__/Rotate2dAction.spec.ts +23 -0
  79. package/src/components/modal/actions/__tests__/Slice3dAction.spec.ts +14 -0
  80. package/src/components/modal/actions/__tests__/ZoomAction.spec.ts +34 -0
  81. package/src/components/modal/composables/__tests__/useNavigationCubeObserver.spec.ts +56 -0
  82. package/src/components/modal/composables/useEventListener.ts +22 -0
  83. package/src/components/modal/composables/useNavigationCubeObserver.ts +104 -0
  84. package/src/components/selectors/ValueSelector.vue +30 -33
  85. package/src/components/selectors/__tests__/value-selector.spec.ts +1 -1
  86. package/src/components/sliders/DoubleSliderSelector.vue +79 -71
  87. package/src/components/sliders/VerticalSliderSelector.vue +12 -17
  88. package/src/components/sliders/__tests__/double-slider-selector.spec.ts +1 -1
  89. package/src/components/sliders/__tests__/vertical-slider-selector.spec.ts +1 -1
  90. package/src/dataLayer/__tests__/clamp.spec.ts +16 -0
  91. package/src/dataLayer/__tests__/eventHandlers.spec.ts +38 -0
  92. package/src/dataLayer/__tests__/getIconForPreset.spec.ts +40 -0
  93. package/src/dataLayer/__tests__/patchDataOverlay.spec.ts +88 -0
  94. package/src/dataLayer/__tests__/scanState.spec.ts +93 -0
  95. package/src/dataLayer/__tests__/useViewer3cr.spec.ts +10 -0
  96. package/src/dataLayer/__tests__/viewer3cr.spec.ts +331 -0
  97. package/src/dataLayer/clamp.ts +9 -0
  98. package/src/dataLayer/eventHandlers.ts +26 -0
  99. package/src/dataLayer/patchDataOverlay.ts +101 -0
  100. package/src/dataLayer/scanState.ts +105 -26
  101. package/src/dataLayer/useViewer3cr.ts +7 -0
  102. package/src/dataLayer/viewer3cr.ts +410 -0
  103. package/src/helpers/__tests__/layout-overlay-style.spec.ts +24 -22
  104. package/src/helpers/__tests__/model-helper.spec.ts +44 -13
  105. package/src/helpers/layoutOverlayStyle.ts +16 -27
  106. package/src/helpers/modelHelper.ts +62 -10
  107. package/src/models/Callbacks.ts +2 -2
  108. package/src/models/LoadViewerOptions.ts +2 -0
  109. package/src/models/LoadViewerPayload.ts +1 -0
  110. package/src/notifications/notification.ts +3 -4
  111. package/src/plugins/vuetify.ts +5 -0
  112. package/src/services/gpt/__tests__/gpt.service.spec.ts +27 -0
  113. package/src/services/gpt/gpt.service.ts +27 -0
  114. package/static/3cr-types-browser/index.ts +74 -0
  115. package/static/3cr-types-browser/types/Action.ts +6 -0
  116. package/static/3cr-types-browser/types/ActionData.ts +4 -0
  117. package/static/3cr-types-browser/types/AlphaKeys.ts +5 -0
  118. package/static/3cr-types-browser/types/AnchorPoint.ts +12 -0
  119. package/static/3cr-types-browser/types/CallToAction.ts +5 -0
  120. package/static/3cr-types-browser/types/ColourData.ts +7 -0
  121. package/static/3cr-types-browser/types/ColourPresetData.ts +9 -0
  122. package/static/3cr-types-browser/types/CurrentDataOverlayState.ts +6 -0
  123. package/static/3cr-types-browser/types/CurrentScanState.ts +22 -0
  124. package/static/3cr-types-browser/types/DataOverlay.ts +22 -0
  125. package/static/3cr-types-browser/types/DataOverlayActions.ts +14 -0
  126. package/static/3cr-types-browser/types/DataOverlayData.ts +8 -0
  127. package/static/3cr-types-browser/types/DataOverlayEvent.ts +8 -0
  128. package/static/3cr-types-browser/types/DecryptionKey.ts +4 -0
  129. package/static/3cr-types-browser/types/DisplaySettings.ts +10 -0
  130. package/static/3cr-types-browser/types/EmptyPayload.ts +3 -0
  131. package/static/3cr-types-browser/types/EnumPayload.ts +4 -0
  132. package/static/3cr-types-browser/types/FileManagementActions.ts +11 -0
  133. package/static/3cr-types-browser/types/FlipValue.ts +7 -0
  134. package/static/3cr-types-browser/types/FrontEndInterfaces.ts +14 -0
  135. package/static/3cr-types-browser/types/GradientKeys.ts +7 -0
  136. package/static/3cr-types-browser/types/GreyscalePresetData.ts +6 -0
  137. package/static/3cr-types-browser/types/InitialDataOverlayState.ts +6 -0
  138. package/static/3cr-types-browser/types/InitialScanState.ts +19 -0
  139. package/static/3cr-types-browser/types/InteractionType.ts +8 -0
  140. package/static/3cr-types-browser/types/InteractivityActions.ts +6 -0
  141. package/static/3cr-types-browser/types/InteractivityState.ts +4 -0
  142. package/static/3cr-types-browser/types/InvertTransformData.ts +6 -0
  143. package/static/3cr-types-browser/types/LayoutActions.ts +6 -0
  144. package/static/3cr-types-browser/types/LayoutData.ts +7 -0
  145. package/static/3cr-types-browser/types/LoadDataSet.ts +6 -0
  146. package/static/3cr-types-browser/types/LoadSessionState.ts +4 -0
  147. package/static/3cr-types-browser/types/LocalLoadDataset.ts +3 -0
  148. package/static/3cr-types-browser/types/MovementData.ts +7 -0
  149. package/static/3cr-types-browser/types/NavigationCubeActions.ts +8 -0
  150. package/static/3cr-types-browser/types/NavigationCubeData.ts +12 -0
  151. package/static/3cr-types-browser/types/NavigationCubeTransform.ts +9 -0
  152. package/static/3cr-types-browser/types/NotificationPayload.ts +7 -0
  153. package/static/3cr-types-browser/types/NotificationsActions.ts +6 -0
  154. package/static/3cr-types-browser/types/Object.ts +1 -0
  155. package/static/3cr-types-browser/types/ObjectColour.ts +7 -0
  156. package/static/3cr-types-browser/types/ObjectIcon.ts +5 -0
  157. package/static/3cr-types-browser/types/ObjectInvert.ts +7 -0
  158. package/static/3cr-types-browser/types/ObjectSize.ts +7 -0
  159. package/static/3cr-types-browser/types/ObjectSize2D.ts +7 -0
  160. package/static/3cr-types-browser/types/ObjectVisible.ts +5 -0
  161. package/static/3cr-types-browser/types/PositionData.ts +14 -0
  162. package/static/3cr-types-browser/types/PresetsActions.ts +4 -0
  163. package/static/3cr-types-browser/types/RotationValue.ts +7 -0
  164. package/static/3cr-types-browser/types/ScanMovementActions.ts +27 -0
  165. package/static/3cr-types-browser/types/ScanMovementData.ts +3 -0
  166. package/static/3cr-types-browser/types/ScanOrientationActions.ts +6 -0
  167. package/static/3cr-types-browser/types/ScanStateActions.ts +4 -0
  168. package/static/3cr-types-browser/types/ScanView.ts +6 -0
  169. package/static/3cr-types-browser/types/SettingsData.ts +12 -0
  170. package/static/3cr-types-browser/types/SlicerData.ts +9 -0
  171. package/static/3cr-types-browser/types/SliderValue.ts +4 -0
  172. package/static/3cr-types-browser/types/SlidersActions.ts +18 -0
  173. package/static/3cr-types-browser/types/Vector2Data.ts +5 -0
  174. package/static/3cr-types-browser/types/Vector3Data.ts +6 -0
  175. package/static/3cr-types-browser/types/VectorMovementData.ts +8 -0
  176. package/static/3cr-types-browser/types/ViewInteractiveMode.ts +5 -0
  177. package/static/3cr-types-browser/types/ViewOrientation.ts +8 -0
  178. package/static/3cr-types-browser/types/ViewOrientations.ts +10 -0
  179. package/static/3cr-types-browser/types/ViewSelectionActions.ts +9 -0
  180. package/static/3cr-types-browser/types/ViewToggleData.ts +7 -0
  181. package/static/3cr-types-browser/types/VolumeOrientation.ts +7 -0
  182. package/test/helper.ts +10 -1
  183. package/test/setup.ts +13 -0
  184. package/tsconfig.json +1 -0
  185. package/vite.config.mts +1 -0
  186. package/src/dataLayer/__tests__/payload-handler.spec.ts +0 -214
  187. package/src/dataLayer/payloadHandler.ts +0 -138
  188. /package/src/dataLayer/{iconData.ts → getIconForPreset.ts} +0 -0
@@ -1,48 +1,32 @@
1
1
  import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
2
- import { shallowMountVuetify } from "~/helper";
3
- import MftpWebGL3DRModal from "../MftpWebGL3DRModal.vue";
4
- import {
5
- inflateInitialScanState,
6
- inflateScanState,
7
- } from "@/helpers/modelHelper";
2
+ import { mountVuetify, shallowMountVuetify } from "~/helper";
3
+ import { inflateInitialScanState, inflateScanState } from "@/helpers/modelHelper";
8
4
  import {
9
5
  AnchorPoint,
10
- FileManagementActions,
11
6
  FrontEndInterfaces,
12
- InteractivityActions,
13
- NotificationPayload,
14
7
  PositionData,
15
8
  ScanMovementActions,
16
- ScanStateActions,
17
- ScanView,
18
9
  SlidersActions,
19
10
  } from "@3cr/types-ts";
20
11
  import { flushPromises } from "@vue/test-utils";
21
- import { PayloadHandler } from "@/dataLayer/payloadHandler";
22
12
  import { spyOn } from "@vitest/spy";
23
13
  import {
24
14
  cSlider,
25
15
  currentGreyscalePreset,
26
16
  isLayout1x3,
27
17
  isLayout2x2,
18
+ setInitialScanStateFromPayload,
28
19
  setScanState,
29
20
  sSlider,
30
21
  transactionStarted,
31
22
  tSlider,
32
23
  } from "@/dataLayer/scanState";
33
24
  import { unref } from "vue";
34
- import { isDemo } from "@/demo/options";
25
+ import { isDemo } from "@/components/demo/options";
26
+ import { Viewer3cr } from "@/dataLayer/viewer3cr";
27
+ import MftpWebGL3DRModal from "../MftpWebGL3DRModal.vue";
28
+ import { VDialog } from "vuetify/components";
35
29
 
36
- vi.mock("@3cr/sdk-browser", async (importOriginal) => {
37
- const mod = (await importOriginal()) as object;
38
- return {
39
- ...mod,
40
- registerVersion: vi.fn(),
41
- createInstance: vi.fn(),
42
- executePayload: vi.fn(),
43
- registerOnPayloadHandler: vi.fn(),
44
- };
45
- });
46
30
  vi.mock("@kyvg/vue3-notification", async (importOriginal) => {
47
31
  const mod = (await importOriginal()) as object;
48
32
  return {
@@ -52,29 +36,16 @@ vi.mock("@kyvg/vue3-notification", async (importOriginal) => {
52
36
  }),
53
37
  };
54
38
  });
55
- let spy = spyOn(PayloadHandler.prototype, "sendPayload").mockImplementation(
56
- (interfaceType: string, actionType: string, message: any) => Promise.resolve()
57
- );
39
+
40
+ let spy = spyOn(Viewer3cr.prototype, "sendPayload").mockResolvedValue();
41
+
58
42
  describe("MftpWebGL3DRModal.vue", () => {
59
- let wrapper = shallowMountVuetify(
60
- MftpWebGL3DRModal,
61
- {}
62
- // { WebGL3DR: true, LoadingSpinner: true }
63
- );
43
+ let wrapper = shallowMountVuetify(MftpWebGL3DRModal);
64
44
 
65
45
  beforeEach(() => {
66
46
  transactionStarted.value = false;
67
- spy = spyOn(PayloadHandler.prototype, "sendPayload").mockImplementation(
68
- (interfaceType: string, actionType: string, message: any) =>
69
- Promise.resolve()
70
- );
71
-
72
- wrapper = shallowMountVuetify(
73
- MftpWebGL3DRModal,
74
- {}
75
- // { WebGL3DR: true, LoadingSpinner: true }
76
- );
77
- // wrapper.vm.alterValue(true);
47
+ spy = spyOn(Viewer3cr.prototype, "sendPayload").mockResolvedValue();
48
+ wrapper = shallowMountVuetify( MftpWebGL3DRModal);
78
49
  vi.useFakeTimers();
79
50
  });
80
51
 
@@ -86,6 +57,7 @@ describe("MftpWebGL3DRModal.vue", () => {
86
57
  it("inflates", () => {
87
58
  expect(wrapper).toBeTruthy();
88
59
  });
60
+
89
61
  describe("watchers", () => {
90
62
  it("scanState.value.Display.Brightness", async () => {
91
63
  await testWatcherForDisplay("Brightness", SlidersActions.sl01);
@@ -193,50 +165,11 @@ describe("MftpWebGL3DRModal.vue", () => {
193
165
  );
194
166
  });
195
167
  });
168
+
196
169
  it("watches scanState", () => {
197
170
  expect(wrapper).toBeTruthy();
198
171
  });
199
172
 
200
- it("getIconForPreset Bone", () => {
201
- expect(wrapper.vm.getIconForPreset("Bone")).toBe("fa:fas fa-bone");
202
- });
203
-
204
- it("getIconForPreset Brain", () => {
205
- expect(wrapper.vm.getIconForPreset("Brain")).toBe("fa:fas fa-brain");
206
- });
207
-
208
- it("getIconForPreset Liver", () => {
209
- expect(wrapper.vm.getIconForPreset("Liver")).toBe("custom:liver_icon");
210
- });
211
-
212
- it("getIconForPreset Lungs", () => {
213
- expect(wrapper.vm.getIconForPreset("Lungs")).toBe("fa:fas fa-lungs");
214
- });
215
-
216
- it("getIconForPreset Muscle", () => {
217
- expect(wrapper.vm.getIconForPreset("Muscle")).toBe("custom:muscle_icon");
218
- });
219
-
220
- it("getIconForPreset Temporal Bones", () => {
221
- expect(wrapper.vm.getIconForPreset("Temporal Bones")).toBe(
222
- "custom:temporal_bones_icon"
223
- );
224
- });
225
-
226
- it("getIconForPreset Soft Tissue", () => {
227
- expect(wrapper.vm.getIconForPreset("Soft Tissue")).toBe(
228
- "custom:torso_icon"
229
- );
230
- });
231
-
232
- it("getIconForPreset Skin", () => {
233
- expect(wrapper.vm.getIconForPreset("Skin")).toBe("custom:skin_icon");
234
- });
235
-
236
- it("getIconForPreset AKJSDHLKAJSDLJ", () => {
237
- expect(wrapper.vm.getIconForPreset("AKJSDHLKAJSDLJ")).toBe(undefined);
238
- });
239
-
240
173
  it("windowSlider should be set", () => {
241
174
  expect(wrapper.vm.windowSlider).toStrictEqual([0, 100]);
242
175
  });
@@ -258,14 +191,14 @@ describe("MftpWebGL3DRModal.vue", () => {
258
191
  });
259
192
 
260
193
  it("windowSlider should set", async () => {
261
- const newVals = [20, 20];
194
+ const newVals: [number, number] = [20, 20];
262
195
  wrapper.vm.windowSlider = newVals;
263
196
  await flushPromises();
264
197
  expect(wrapper.vm.windowSlider).toStrictEqual(newVals);
265
198
  });
266
199
 
267
200
  it("thresholdSlider should set", async () => {
268
- const newVals = [20, 20];
201
+ const newVals: [number, number] = [20, 20];
269
202
  wrapper.vm.thresholdSlider = newVals;
270
203
  await flushPromises();
271
204
  expect(wrapper.vm.thresholdSlider).toStrictEqual(newVals);
@@ -292,66 +225,6 @@ describe("MftpWebGL3DRModal.vue", () => {
292
225
  expect(wrapper.vm.cSlider).toStrictEqual(newVals);
293
226
  });
294
227
 
295
- it("should closeModal", async () => {
296
- wrapper.vm.closeModal();
297
- wrapper.vm.m_closeDialog = true;
298
-
299
- await flushPromises();
300
- wrapper.findComponent("#close-dialog-prompt");
301
- });
302
-
303
- it("should closeModal", async () => {
304
- wrapper.vm.closeModal();
305
- wrapper.vm.alterValue(false);
306
-
307
- await flushPromises();
308
- wrapper.findComponent("#close-dialog-prompt");
309
- });
310
-
311
- it("should handleOnPayload file_management", async () => {
312
- wrapper.vm.handleOnPayload(
313
- FrontEndInterfaces.file_management,
314
- "123",
315
- "123"
316
- );
317
- });
318
-
319
- it("should handleOnPayload file_management", async () => {
320
- wrapper.vm.handleOnPayload(
321
- FrontEndInterfaces.file_management,
322
- FileManagementActions.fm02,
323
- JSON.stringify(inflateInitialScanState())
324
- );
325
- });
326
- it("should handleOnPayload notifications", async () => {
327
- wrapper.vm.handleOnPayload(
328
- FrontEndInterfaces.notifications,
329
- "123",
330
- JSON.stringify({
331
- Action: InteractivityActions.in01,
332
- Code: "S00000",
333
- } as NotificationPayload)
334
- );
335
- });
336
- it("should handleOnPayload notifications", async () => {
337
- wrapper.vm.handleOnPayload(
338
- FrontEndInterfaces.notifications,
339
- "123",
340
- JSON.stringify({
341
- Action: InteractivityActions.in02,
342
- Code: "S00000",
343
- } as NotificationPayload)
344
- );
345
- });
346
-
347
- it("should handleOnPayload scan_state", async () => {
348
- wrapper.vm.handleOnPayload(
349
- FrontEndInterfaces.scan_state,
350
- ScanStateActions.ss01,
351
- JSON.stringify(inflateScanState())
352
- );
353
- });
354
-
355
228
  it("should isLayout2x2", async () => {
356
229
  const scanState = inflateScanState();
357
230
  scanState.Layout.PositionData = [
@@ -362,7 +235,6 @@ describe("MftpWebGL3DRModal.vue", () => {
362
235
  ];
363
236
 
364
237
  setScanState(JSON.stringify(scanState));
365
-
366
238
  expect(unref(isLayout2x2)).toBeTruthy();
367
239
  expect(unref(isLayout1x3)).toBeFalsy();
368
240
  });
@@ -384,101 +256,51 @@ describe("MftpWebGL3DRModal.vue", () => {
384
256
 
385
257
  it("should getCurrentGreyscalePreset", async () => {
386
258
  const initial = inflateInitialScanState();
387
-
388
- initial.GreyscalePresets = [
389
- { Name: "testing", Lower: 30, Upper: 60, Version: "1.0.0" },
390
- ];
391
-
392
- wrapper.vm.handleOnPayload(
393
- FrontEndInterfaces.file_management,
394
- FileManagementActions.fm02,
395
- JSON.stringify(initial)
396
- );
259
+ initial.GreyscalePresets = [{ Name: "testing", Lower: 30, Upper: 60, Version: "1.0.0" }];
260
+ setInitialScanStateFromPayload(JSON.stringify(initial));
397
261
  await flushPromises();
398
262
 
399
263
  const scanState = inflateScanState();
400
264
  scanState.Display.WindowLower = 30;
401
265
  scanState.Display.WindowUpper = 60;
402
-
403
266
  setScanState(JSON.stringify(scanState));
404
267
  await flushPromises();
405
- expect(unref(currentGreyscalePreset)).toBe("testing");
406
- });
407
-
408
- it("should isDemo execute option", async () => {
409
- isDemo.value = true;
410
268
 
411
- wrapper.vm.closeModal();
269
+ expect(unref(currentGreyscalePreset)?.Name).toBe("testing");
412
270
  });
413
271
 
414
272
  it("should getCurrentGreyscalePreset", async () => {
415
273
  const initial = inflateInitialScanState();
416
-
417
- initial.GreyscalePresets = [
418
- { Name: "testing", Lower: 30, Upper: 60, Version: "1.0.0" },
419
- ];
274
+ initial.GreyscalePresets = [{ Name: "testing", Lower: 30, Upper: 60, Version: "1.0.0" }];
420
275
  initial.HuLower = 40;
421
276
  initial.HuUpper = 50;
422
-
423
- wrapper.vm.handleOnPayload(
424
- FrontEndInterfaces.file_management,
425
- FileManagementActions.fm02,
426
- JSON.stringify(initial)
427
- );
277
+ setInitialScanStateFromPayload(JSON.stringify(initial));
428
278
  await flushPromises();
429
279
 
430
280
  const scanState = inflateScanState();
431
281
  scanState.Display.WindowLower = 40;
432
282
  scanState.Display.WindowUpper = 50;
433
-
434
283
  setScanState(JSON.stringify(scanState));
435
284
  await flushPromises();
436
- expect(unref(currentGreyscalePreset)).toBe("testing");
285
+
286
+ expect(unref(currentGreyscalePreset)?.Name).toBe("testing");
437
287
  });
438
288
 
439
289
  it("should getCurrentGreyscalePreset", async () => {
440
290
  const initial = inflateInitialScanState();
441
-
442
- initial.GreyscalePresets = [
443
- { Name: "testing", Lower: 30, Upper: 60, Version: "1.0.0" },
444
- ];
291
+ initial.GreyscalePresets = [{ Name: "testing", Lower: 30, Upper: 60, Version: "1.0.0" }];
445
292
  initial.HuLower = 40;
446
293
  initial.HuUpper = 50;
447
-
448
- wrapper.vm.handleOnPayload(
449
- FrontEndInterfaces.file_management,
450
- FileManagementActions.fm02,
451
- JSON.stringify(initial)
452
- );
294
+ setInitialScanStateFromPayload(JSON.stringify(initial));
453
295
  await flushPromises();
454
296
 
455
297
  const scanState = inflateScanState();
456
298
  scanState.Display.WindowLower = 45;
457
299
  scanState.Display.WindowUpper = 46;
458
-
459
300
  setScanState(JSON.stringify(scanState));
460
301
  await flushPromises();
461
- expect(unref(currentGreyscalePreset)).toBe(undefined);
462
- });
463
302
 
464
- it("should fullscreenLayout", async () => {
465
- const view = ScanView.Coronal;
466
- await wrapper.vm.fullscreenLayout(view);
467
- // expect(spy).toHaveBeenNthCalledWith(
468
- // 1,
469
- // FrontEndInterfaces.view_selection,
470
- // `vs_0${view + 1}`,
471
- // {
472
- // Version: "1.1.0",
473
- // }
474
- // );
475
- expect(spy).toHaveBeenCalledWith(
476
- FrontEndInterfaces.view_selection,
477
- `vs_0${view + 1}`,
478
- {
479
- Version: "1.1.0",
480
- }
481
- );
303
+ expect(unref(currentGreyscalePreset)).toBe(undefined);
482
304
  });
483
305
 
484
306
  it("should getCurrentGreyscalePreset", async () => {
@@ -492,96 +314,35 @@ describe("MftpWebGL3DRModal.vue", () => {
492
314
  it("should getViewName Sagittal", async () => {
493
315
  expect(wrapper.vm.getViewName(2)).toBe("Sagittal");
494
316
  });
317
+ });
495
318
 
496
- it("should getCurrentActiveView Sagittal", async () => {
497
- expect(
498
- wrapper.vm.getCurrentActiveView({
499
- Anchor: AnchorPoint.CENTER,
500
- ActiveView: true,
501
- AspectRatio: 1,
502
- MaxSize: {
503
- Version: "0.0.1",
504
- X: 1,
505
- Y: 1,
506
- },
507
- DefaultView: ScanView.Coronal,
508
- Priority: 1,
509
- Version: "0.0.1",
510
- Offset: {
511
- Version: "0.0.1",
512
- X: 1,
513
- Y: 1,
514
- },
515
- })
516
- ).toBe(3);
319
+ describe('MftpWebGL3DRModal tests', () => {
320
+ it('should mount', () => {
321
+ const wrapper = mountVuetify(MftpWebGL3DRModal);
322
+ expect(wrapper).toBeTruthy();
517
323
  });
518
324
 
519
- it("should getCurrentActiveView Sagittal", async () => {
520
- const initalState = inflateScanState();
521
- initalState.Layout.PositionData = [
522
- {
523
- Anchor: AnchorPoint.CENTER,
524
- ActiveView: true,
525
- AspectRatio: 1,
526
- MaxSize: {
527
- Version: "1.0.0",
528
- X: 1,
529
- Y: 1,
530
- },
531
- DefaultView: ScanView.Coronal,
532
- Priority: 1,
533
- Offset: {
534
- Version: "1.0.0",
535
- X: 1,
536
- Y: 1,
537
- },
538
- Version: "1.0.0",
539
- },
540
- ];
541
- await setScanState(JSON.stringify(initalState));
542
-
543
- expect(
544
- wrapper.vm.getCurrentActiveView({
545
- Anchor: AnchorPoint.CENTER,
546
- ActiveView: true,
547
- AspectRatio: 1,
548
- MaxSize: {
549
- Version: "0.0.1",
550
- X: 1,
551
- Y: 1,
552
- },
553
- DefaultView: ScanView.Coronal,
554
- Priority: 1,
555
- Version: "0.0.1",
556
- Offset: {
557
- Version: "0.0.1",
558
- X: 1,
559
- Y: 1,
560
- },
561
- })
562
- ).toBe(0);
325
+ it('should v-model modals', async () => {
326
+ const wrapper = mountVuetify(MftpWebGL3DRModal);
327
+ const modals = wrapper.findAllComponents(VDialog);
328
+ for (const modal of modals) {
329
+ await modal.setValue(false);
330
+ }
563
331
  });
564
332
 
565
- it("should footerItems", async () => {
566
- for (const footerItem of wrapper.vm.footerItems) {
567
- const promise = footerItem.click();
568
- expect(promise).toBeTruthy();
569
- await promise;
570
- }
333
+ it('should start introjs', () => {
334
+ const wrapper = mountVuetify(MftpWebGL3DRModal);
335
+ expect(wrapper.vm.startIntro()).resolves.not.toThrow();
571
336
  });
572
337
  });
573
338
 
574
- async function testWatcherForDisplay(
575
- key: string,
576
- action: SlidersActions,
577
- not: boolean = false
578
- ) {
339
+ async function testWatcherForDisplay(key: string, action: SlidersActions, not: boolean = false) {
579
340
  const scanState = inflateScanState();
580
341
  (scanState.Display as any)[key] = 60;
581
342
 
582
- await setScanState(JSON.stringify(scanState));
583
-
343
+ setScanState(JSON.stringify(scanState));
584
344
  await flushPromises();
345
+
585
346
  if (not) {
586
347
  expect(spy).not.toHaveBeenCalledWith(FrontEndInterfaces.sliders, action, {
587
348
  Version: "0.0.1",
@@ -595,11 +356,7 @@ async function testWatcherForDisplay(
595
356
  }
596
357
  }
597
358
 
598
- async function testWatcherForSlice(
599
- key: string,
600
- action: SlidersActions,
601
- not: boolean = false
602
- ) {
359
+ async function testWatcherForSlice(key: string, action: SlidersActions, not: boolean = false) {
603
360
  const scanState = inflateScanState();
604
361
  (scanState.Slice as any)[key] = 100;
605
362
 
@@ -620,11 +377,7 @@ async function testWatcherForSlice(
620
377
  }
621
378
  }
622
379
 
623
- async function testWatcherForOrientation(
624
- key: string,
625
- action: SlidersActions,
626
- not: boolean = false
627
- ) {
380
+ async function testWatcherForOrientation(key: string, action: SlidersActions, not: boolean = false) {
628
381
  const scanState = inflateScanState();
629
382
  (scanState.Orientations as any)[key].Slice = 100;
630
383
 
@@ -644,11 +397,7 @@ async function testWatcherForOrientation(
644
397
  }
645
398
  }
646
399
 
647
- async function testWatcherForInteractionSettings(
648
- key: string,
649
- action: ScanMovementActions,
650
- not: boolean = false
651
- ) {
400
+ async function testWatcherForInteractionSettings(key: string, action: ScanMovementActions, not: boolean = false) {
652
401
  const scanState = inflateScanState();
653
402
  (scanState.InteractionSettings as any)[key] = 100;
654
403
 
@@ -0,0 +1,79 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { mountVuetify } from "~/helper";
3
+ import { dataOverlayEvent } from "@/dataLayer/scanState";
4
+ import { DataOverlay, DataOverlayEvent, InteractionType } from "@3cr/types-ts";
5
+ import { flushPromises } from "@vue/test-utils";
6
+ import { VMenu } from "vuetify/components";
7
+ import ViewerAnnotationModal from "../ViewerAnnotationModal.vue";
8
+
9
+ const DATA_OVERLAY: DataOverlay = {
10
+ Version: '1.1.0',
11
+ Id: '0',
12
+ Title: 'Data Overlay',
13
+ Description: 'Data Overlay',
14
+ Colour2d: { Version: '1.1.0', R: 255, B: 255, G: 255, A: 255 },
15
+ Colour3d: { Version: '1.1.0', R: 255, B: 255, G: 255, A: 255 },
16
+ Icon2d: '',
17
+ Visibility2d: true,
18
+ Visibility3d: true,
19
+ Inverted: { Version: '1.1.0', InvertedCoronal: false, InvertedSagittal: false, InvertedTransverse: false },
20
+ Position: { Version: '1.1.0', X: 0, Y: 0, Z: 0 },
21
+ Size2d: { Version: '1.1.0', X: 0, Y: 0 },
22
+ Size3d: { Version: '1.1.0', X: 0, Y: 0, Z: 0 },
23
+ CallToAction: {
24
+ Actions: [
25
+ {
26
+ ActionType: 1,
27
+ ActionData: {
28
+ Description: 'Test',
29
+ Url: ''
30
+ }
31
+ }
32
+ ]
33
+ }
34
+ };
35
+
36
+ const POINTER_DOWN_EVENT: DataOverlayEvent = {
37
+ Version: '1.1.0',
38
+ Interaction: InteractionType.PointerDown,
39
+ Annotation: DATA_OVERLAY
40
+ }
41
+
42
+ const POINTER_UP_EVENT: DataOverlayEvent = {
43
+ Version: '1.1.0',
44
+ Interaction: InteractionType.PointerUp,
45
+ Annotation: DATA_OVERLAY
46
+ }
47
+
48
+ describe('ViewerAnnotationModal tests', () => {
49
+ it('should mount', () => {
50
+ const wrapper = mountVuetify(ViewerAnnotationModal);
51
+ expect(wrapper).toBeTruthy();
52
+ });
53
+
54
+ it('should show on data overlay event', async () => {
55
+ const wrapper = mountVuetify(ViewerAnnotationModal);
56
+ dataOverlayEvent.value = POINTER_DOWN_EVENT;
57
+ document.dispatchEvent(new MouseEvent('click', { clientX: 0, clientY: 0 }));
58
+ await flushPromises();
59
+ dataOverlayEvent.value = POINTER_UP_EVENT;
60
+ expect(wrapper.isVisible()).toBeTruthy();
61
+ });
62
+
63
+ it('should dismiss on click', async () => {
64
+ dataOverlayEvent.value = POINTER_UP_EVENT;
65
+ const wrapper = mountVuetify(ViewerAnnotationModal);
66
+ document.dispatchEvent(new MouseEvent('click', { clientX: 0, clientY: 0 }));
67
+ await flushPromises();
68
+ expect(wrapper.html()).toBe('');
69
+ });
70
+
71
+ it('should close via menu state', async () => {
72
+ dataOverlayEvent.value = null;
73
+ const wrapper = mountVuetify(ViewerAnnotationModal);
74
+ const menu = wrapper.getComponent(VMenu);
75
+ await menu.setValue(true);
76
+ await menu.setValue(false);
77
+ expect(menu.html()).toBe('');
78
+ });
79
+ });
@@ -0,0 +1,61 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { mountVuetify } from "~/helper";
3
+ import { inflateInitialScanState, inflateScanState } from "@/helpers/modelHelper";
4
+ import { currentColourPreset, currentGreyscalePreset, setInitialScanStateFromPayload, setScanState, thresholdSlider, windowSlider } from "@/dataLayer/scanState";
5
+ import { ColourPresetData } from "@3cr/types-ts";
6
+ import { VTextField } from "vuetify/components";
7
+ import ViewerDisplaySettings from "@/components/modal/ViewerDisplaySettings.vue";
8
+ import DoubleSliderSelector from "@/components/sliders/DoubleSliderSelector.vue";
9
+
10
+ describe('ViewerDisplaySettings tests', () => {
11
+ it('should mount', () => {
12
+ const wrapper = mountVuetify(ViewerDisplaySettings);
13
+ expect(wrapper).toBeTruthy();
14
+ });
15
+
16
+ describe('sliders', async () => {
17
+ const wrapper = mountVuetify(ViewerDisplaySettings);
18
+ const sliders = wrapper.findAllComponents(DoubleSliderSelector);
19
+
20
+ it('should test window slider', async () => {
21
+ const textFields = sliders[0].findAllComponents(VTextField);
22
+ await textFields[0].setValue(20);
23
+ await textFields[1].setValue(40);
24
+ expect(windowSlider.value).toStrictEqual([20, 40]);
25
+ });
26
+
27
+ it('should test threshold slider', async () => {
28
+ const textFields = sliders[1].findAllComponents(VTextField);
29
+ await textFields[0].setValue(50);
30
+ await textFields[1].setValue(80);
31
+ expect(thresholdSlider.value).toStrictEqual([50, 80]);
32
+ });
33
+ });
34
+
35
+ it('should set greyscale preset', async () => {
36
+ const initial = inflateInitialScanState();
37
+ initial.GreyscalePresets = [{ Name: "testing", Lower: 30, Upper: 60, Version: "1.0.0" }];
38
+ setInitialScanStateFromPayload(JSON.stringify(initial));
39
+
40
+ const scanState = inflateScanState();
41
+ scanState.Display.WindowLower = 30;
42
+ scanState.Display.WindowUpper = 60;
43
+ setScanState(JSON.stringify(scanState));
44
+
45
+ const wrapper = mountVuetify(ViewerDisplaySettings);
46
+ const greyscale = wrapper.findComponent('[data-testid="greyscale"]');
47
+ await greyscale.setValue(initial.GreyscalePresets[0]);
48
+ expect(currentGreyscalePreset.value).toStrictEqual(initial.GreyscalePresets[0]);
49
+ });
50
+
51
+ it('should set colour preset', async () => {
52
+ const initial = inflateInitialScanState();
53
+ initial.ColourPresets = [{ Name: "testing" } as ColourPresetData];
54
+ setInitialScanStateFromPayload(JSON.stringify(initial));
55
+
56
+ const wrapper = mountVuetify(ViewerDisplaySettings);
57
+ const colour = wrapper.findComponent('[data-testid="colour"]');
58
+ await colour.setValue(initial.ColourPresets[0]);
59
+ expect(currentColourPreset.value).toStrictEqual(initial.ColourPresets[0]);
60
+ });
61
+ });
@@ -0,0 +1,32 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { VApp } from "vuetify/components";
3
+ import { h } from "vue";
4
+ import { VueWrapper, mount } from "@vue/test-utils";
5
+ import { createVuetify } from "vuetify";
6
+ import { demoOptions } from "@/components/demo/options";
7
+ import ViewerNavigationDrawer from "@/components/modal/ViewerNavigationDrawer.vue";
8
+
9
+ function factory(component: any, props?: Record<string, any>): VueWrapper {
10
+ return mount(VApp, {
11
+ slots: { default: h(component, props) },
12
+ global: { plugins: [createVuetify({})] },
13
+ });
14
+ }
15
+
16
+ describe('ViewerNavigationDrawer tests', () => {
17
+ it('should mount', () => {
18
+ const wrapper = factory(ViewerNavigationDrawer, { options: demoOptions.value, drawer: true });
19
+ expect(wrapper).toBeTruthy();
20
+ });
21
+
22
+ it('should toggle drawer', async () => {
23
+ const wrapper = factory(ViewerNavigationDrawer, { options: demoOptions.value, drawer: false });
24
+ const nav = wrapper.findComponent(ViewerNavigationDrawer);
25
+ expect(nav.vm.drawer).toBeFalsy();
26
+ const toggle = nav.findComponent('[data-testid="toggle"]');
27
+ await toggle.trigger('click');
28
+ expect(nav.vm.drawer).toBeTruthy();
29
+ await toggle.trigger('click');
30
+ expect(nav.vm.drawer).toBeFalsy();
31
+ });
32
+ });