@3cr/viewer-browser 0.0.61 → 0.0.86

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 (59) hide show
  1. package/components.d.ts +0 -1
  2. package/coverage/3cr-viewer-browser/index.html +5 -5
  3. package/coverage/3cr-viewer-browser/index.ts.html +14 -26
  4. package/coverage/3cr-viewer-browser/src/App.vue.html +51 -48
  5. package/coverage/3cr-viewer-browser/src/components/WebGL3DR.vue.html +1 -1
  6. package/coverage/3cr-viewer-browser/src/components/icons/index.html +1 -1
  7. package/coverage/3cr-viewer-browser/src/components/icons/liver.vue.html +1 -1
  8. package/coverage/3cr-viewer-browser/src/components/index.html +1 -1
  9. package/coverage/3cr-viewer-browser/src/components/loading/LoadingSpinner.vue.html +82 -16
  10. package/coverage/3cr-viewer-browser/src/components/loading/index.html +5 -5
  11. package/coverage/3cr-viewer-browser/src/components/modal/MftpWebGL3DRModal.vue.html +238 -1123
  12. package/coverage/3cr-viewer-browser/src/components/modal/index.html +19 -19
  13. package/coverage/3cr-viewer-browser/src/components/selectors/ValueSelector.vue.html +47 -20
  14. package/coverage/3cr-viewer-browser/src/components/selectors/index.html +7 -7
  15. package/coverage/3cr-viewer-browser/src/components/sliders/DoubleSliderSelector.vue.html +62 -20
  16. package/coverage/3cr-viewer-browser/src/components/sliders/VerticalSliderSelector.vue.html +16 -7
  17. package/coverage/3cr-viewer-browser/src/components/sliders/index.html +10 -10
  18. package/coverage/3cr-viewer-browser/src/dataLayer/iconData.ts.html +118 -0
  19. package/coverage/3cr-viewer-browser/src/dataLayer/index.html +146 -0
  20. package/coverage/3cr-viewer-browser/src/dataLayer/payloadHandler.ts.html +352 -0
  21. package/coverage/3cr-viewer-browser/src/dataLayer/scanState.ts.html +628 -0
  22. package/coverage/3cr-viewer-browser/src/helpers/index.html +1 -1
  23. package/coverage/3cr-viewer-browser/src/helpers/layoutOverlayStyle.ts.html +1 -1
  24. package/coverage/3cr-viewer-browser/src/helpers/modelHelper.ts.html +105 -105
  25. package/coverage/3cr-viewer-browser/src/helpers/utils.ts.html +3 -3
  26. package/coverage/3cr-viewer-browser/src/index.html +5 -5
  27. package/coverage/3cr-viewer-browser/src/main.ts.html +1 -1
  28. package/coverage/3cr-viewer-browser/src/models/LoadViewerOptions.ts.html +166 -0
  29. package/coverage/3cr-viewer-browser/src/models/index.html +116 -0
  30. package/coverage/3cr-viewer-browser/src/notifications/index.html +116 -0
  31. package/coverage/3cr-viewer-browser/src/notifications/notification.ts.html +229 -0
  32. package/coverage/3cr-viewer-browser/src/plugins/index.html +5 -5
  33. package/coverage/3cr-viewer-browser/src/plugins/index.ts.html +14 -8
  34. package/coverage/3cr-viewer-browser/src/plugins/vuetify.ts.html +1 -1
  35. package/coverage/index.html +78 -33
  36. package/dist/Viewer3CR.js +12 -12
  37. package/dist/Viewer3CR.mjs +10004 -9916
  38. package/dist/Viewer3CR.umd.js +12 -12
  39. package/index.ts +7 -42
  40. package/package.json +2 -1
  41. package/src/App.vue +6 -2
  42. package/src/components/modal/MftpWebGL3DRModal.vue +137 -452
  43. package/src/components/modal/__tests__/mftp-webgl-3dr-modal.spec.ts +114 -83
  44. package/src/components/selectors/ValueSelector.vue +4 -0
  45. package/src/components/selectors/__tests__/value-selector.spec.ts +18 -0
  46. package/src/components/sliders/DoubleSliderSelector.vue +10 -4
  47. package/src/components/sliders/__tests__/double-slider-selector.spec.ts +32 -0
  48. package/src/dataLayer/__tests__/payload-handler.spec.ts +98 -0
  49. package/src/dataLayer/iconData.ts +11 -0
  50. package/src/dataLayer/payloadHandler.ts +89 -0
  51. package/src/dataLayer/scanState.ts +181 -0
  52. package/src/demo/DemoPatientModal.vue +59 -0
  53. package/src/demo/options.ts +93 -0
  54. package/src/models/Callbacks.ts +2 -0
  55. package/src/models/LoadViewerOptions.ts +27 -0
  56. package/src/models/LoadViewerPayload.ts +8 -0
  57. package/src/notifications/notification.ts +48 -0
  58. package/vitest.config.mts +1 -0
  59. /package/src/{components/modal → demo}/DemoModal.vue +0 -0
@@ -9,15 +9,25 @@ import {
9
9
  AnchorPoint,
10
10
  FileManagementActions,
11
11
  FrontEndInterfaces,
12
+ InteractivityActions,
13
+ NotificationPayload,
12
14
  PositionData,
13
15
  PresetsActions,
14
16
  ScanMovementActions,
15
- ScanOrientationActions,
16
17
  ScanStateActions,
17
18
  ScanView,
18
19
  SlidersActions,
19
20
  } from "@3cr/types-ts";
20
21
  import { flushPromises } from "@vue/test-utils";
22
+ import { PayloadHandler } from "@/dataLayer/payloadHandler";
23
+ import { spyOn } from "@vitest/spy";
24
+ import {
25
+ currentGreyscalePreset,
26
+ isLayout1x3,
27
+ isLayout2x2,
28
+ setScanState,
29
+ } from "@/dataLayer/scanState";
30
+ import { unref } from "vue";
21
31
 
22
32
  vi.mock("@3cr/sdk-browser", async (importOriginal) => {
23
33
  const mod = (await importOriginal()) as object;
@@ -29,8 +39,21 @@ vi.mock("@3cr/sdk-browser", async (importOriginal) => {
29
39
  registerOnPayloadHandler: vi.fn(),
30
40
  };
31
41
  });
42
+ vi.mock("@kyvg/vue3-notification", async (importOriginal) => {
43
+ const mod = (await importOriginal()) as object;
44
+ return {
45
+ ...mod,
46
+ useNotification: vi.fn().mockReturnValue({
47
+ notify: vi.fn(),
48
+ }),
49
+ };
50
+ });
32
51
 
33
52
  describe("MftpWebGL3DRModal.vue", () => {
53
+ let spy = spyOn(PayloadHandler.prototype, "sendPayload").mockImplementation(
54
+ (interfaceType: string, actionType: string, message: any) =>
55
+ Promise.resolve()
56
+ );
34
57
  let wrapper = shallowMountVuetify(
35
58
  MftpWebGL3DRModal,
36
59
  {}
@@ -38,6 +61,11 @@ describe("MftpWebGL3DRModal.vue", () => {
38
61
  );
39
62
 
40
63
  beforeEach(() => {
64
+ spy = spyOn(PayloadHandler.prototype, "sendPayload").mockImplementation(
65
+ (interfaceType: string, actionType: string, message: any) =>
66
+ Promise.resolve()
67
+ );
68
+
41
69
  wrapper = shallowMountVuetify(
42
70
  MftpWebGL3DRModal,
43
71
  {}
@@ -292,6 +320,14 @@ describe("MftpWebGL3DRModal.vue", () => {
292
320
  wrapper.findComponent("#close-dialog-prompt");
293
321
  });
294
322
 
323
+ it("should closeModal", async () => {
324
+ wrapper.vm.closeModal();
325
+ wrapper.vm.alterValue(false);
326
+
327
+ await flushPromises();
328
+ wrapper.findComponent("#close-dialog-prompt");
329
+ });
330
+
295
331
  it("should handleOnPayload file_management", async () => {
296
332
  wrapper.vm.handleOnPayload(
297
333
  FrontEndInterfaces.file_management,
@@ -308,7 +344,24 @@ describe("MftpWebGL3DRModal.vue", () => {
308
344
  );
309
345
  });
310
346
  it("should handleOnPayload notifications", async () => {
311
- wrapper.vm.handleOnPayload(FrontEndInterfaces.notifications, "123", "123");
347
+ wrapper.vm.handleOnPayload(
348
+ FrontEndInterfaces.notifications,
349
+ "123",
350
+ JSON.stringify({
351
+ Action: InteractivityActions.in01,
352
+ Code: "S00000",
353
+ } as NotificationPayload)
354
+ );
355
+ });
356
+ it("should handleOnPayload notifications", async () => {
357
+ wrapper.vm.handleOnPayload(
358
+ FrontEndInterfaces.notifications,
359
+ "123",
360
+ JSON.stringify({
361
+ Action: InteractivityActions.in02,
362
+ Code: "S00000",
363
+ } as NotificationPayload)
364
+ );
312
365
  });
313
366
 
314
367
  it("should handleOnPayload scan_state", async () => {
@@ -328,9 +381,10 @@ describe("MftpWebGL3DRModal.vue", () => {
328
381
  { Anchor: AnchorPoint.BOTTOM_RIGHT } as PositionData,
329
382
  ];
330
383
 
331
- wrapper.vm.setScanState(JSON.stringify(scanState));
384
+ setScanState(JSON.stringify(scanState));
332
385
 
333
- expect(wrapper.vm.isLayout2x2).toBeTruthy();
386
+ expect(unref(isLayout2x2)).toBeTruthy();
387
+ expect(unref(isLayout1x3)).toBeFalsy();
334
388
  });
335
389
 
336
390
  it("should isLayout1x3", async () => {
@@ -342,9 +396,10 @@ describe("MftpWebGL3DRModal.vue", () => {
342
396
  { Anchor: AnchorPoint.BOTTOM_RIGHT } as PositionData,
343
397
  ];
344
398
 
345
- wrapper.vm.setScanState(JSON.stringify(scanState));
399
+ setScanState(JSON.stringify(scanState));
346
400
 
347
- expect(wrapper.vm.isLayout1x3).toBeTruthy();
401
+ expect(unref(isLayout1x3)).toBeTruthy();
402
+ expect(unref(isLayout2x2)).toBeFalsy();
348
403
  });
349
404
 
350
405
  it("should snap", async () => {
@@ -371,9 +426,9 @@ describe("MftpWebGL3DRModal.vue", () => {
371
426
  scanState.Display.WindowLower = 30;
372
427
  scanState.Display.WindowUpper = 60;
373
428
 
374
- wrapper.vm.setScanState(JSON.stringify(scanState));
429
+ setScanState(JSON.stringify(scanState));
375
430
  await flushPromises();
376
- expect(wrapper.vm.getCurrentGreyscalePreset()).toBe("testing");
431
+ expect(unref(currentGreyscalePreset)).toBe("testing");
377
432
  });
378
433
 
379
434
  it("should getCurrentGreyscalePreset", async () => {
@@ -396,9 +451,9 @@ describe("MftpWebGL3DRModal.vue", () => {
396
451
  scanState.Display.WindowLower = 40;
397
452
  scanState.Display.WindowUpper = 50;
398
453
 
399
- wrapper.vm.setScanState(JSON.stringify(scanState));
454
+ setScanState(JSON.stringify(scanState));
400
455
  await flushPromises();
401
- expect(wrapper.vm.getCurrentGreyscalePreset()).toBe("testing");
456
+ expect(unref(currentGreyscalePreset)).toBe("testing");
402
457
  });
403
458
 
404
459
  it("should getCurrentGreyscalePreset", async () => {
@@ -421,66 +476,42 @@ describe("MftpWebGL3DRModal.vue", () => {
421
476
  scanState.Display.WindowLower = 45;
422
477
  scanState.Display.WindowUpper = 46;
423
478
 
424
- wrapper.vm.setScanState(JSON.stringify(scanState));
479
+ setScanState(JSON.stringify(scanState));
425
480
  await flushPromises();
426
- expect(wrapper.vm.getCurrentGreyscalePreset()).toBe(undefined);
427
- });
428
-
429
- it("should rotateByDeg", async () => {
430
- const view = ScanView.Coronal;
431
- const deg = 10;
432
-
433
- vi.spyOn(wrapper.vm, "sendPayload").mockImplementation(
434
- (it: string, a: string, m: any) => {
435
- expect(it).toBe(FrontEndInterfaces.scan_orientation);
436
- expect(a).toBe(ScanOrientationActions.so01);
437
- expect(m).toStrictEqual({
438
- Version: "0.0.1",
439
- View: view,
440
- Angle: deg,
441
- });
442
- return Promise.resolve();
443
- }
444
- );
445
-
446
- await wrapper.vm.rotateByDeg(view, deg);
481
+ expect(unref(currentGreyscalePreset)).toBe(undefined);
447
482
  });
448
483
 
449
484
  it("should fullscreenLayout", async () => {
450
485
  const view = ScanView.Coronal;
451
-
452
- vi.spyOn(wrapper.vm, "sendPayload")
453
- .mockImplementationOnce((it: string, a: string, m: any) => {
454
- expect(it).toBe(FrontEndInterfaces.layout);
455
- expect(a).toBe("lo_01");
456
- expect(m).toStrictEqual({
457
- Version: "0.0.1",
458
- });
459
- return Promise.resolve();
460
- })
461
- .mockImplementationOnce((it: string, a: string, m: any) => {
462
- expect(it).toBe(FrontEndInterfaces.view_selection);
463
- expect(a).toBe(`vs_0${view + 1}`);
464
- expect(m).toStrictEqual({
465
- Version: "0.0.1",
466
- });
467
- return Promise.resolve();
468
- });
469
-
470
486
  await wrapper.vm.fullscreenLayout(view);
487
+ // expect(spy).toHaveBeenNthCalledWith(
488
+ // 1,
489
+ // FrontEndInterfaces.view_selection,
490
+ // `vs_0${view + 1}`,
491
+ // {
492
+ // Version: "1.1.0",
493
+ // }
494
+ // );
495
+ expect(spy).toHaveBeenCalledWith(
496
+ FrontEndInterfaces.view_selection,
497
+ `vs_0${view + 1}`,
498
+ {
499
+ Version: "1.1.0",
500
+ }
501
+ );
471
502
  });
472
503
 
473
504
  it("should layouts", async () => {
474
- vi.spyOn(wrapper.vm, "sendPayload").mockImplementationOnce(
475
- (it: string, a: string, m: any) => {
476
- expect(it).toBe(FrontEndInterfaces.layout);
477
- expect(a).toBe("lo_02");
478
- expect(m).toStrictEqual({
479
- Version: "0.0.1",
480
- });
481
- return Promise.resolve();
482
- }
483
- );
505
+ // vi.spyOn(wrapper.vm, "sendPayload").mockImplementationOnce(
506
+ // (it: string, a: string, m: any) => {
507
+ // expect(it).toBe(FrontEndInterfaces.layout);
508
+ // expect(a).toBe("lo_02");
509
+ // expect(m).toStrictEqual({
510
+ // Version: "0.0.1",
511
+ // });
512
+ // return Promise.resolve();
513
+ // }
514
+ // );
484
515
 
485
516
  await wrapper.vm.layouts("lo_02");
486
517
  });
@@ -489,14 +520,14 @@ describe("MftpWebGL3DRModal.vue", () => {
489
520
  const action = PresetsActions.pr01;
490
521
  const preset = {};
491
522
 
492
- vi.spyOn(wrapper.vm, "sendPayload").mockImplementationOnce(
493
- (it: string, a: string, m: any) => {
494
- expect(it).toBe(FrontEndInterfaces.presets);
495
- expect(a).toBe(action);
496
- expect(m).toStrictEqual(preset);
497
- return Promise.resolve();
498
- }
499
- );
523
+ // vi.spyOn(wrapper.vm, "sendPayload").mockImplementationOnce(
524
+ // (it: string, a: string, m: any) => {
525
+ // expect(it).toBe(FrontEndInterfaces.presets);
526
+ // expect(a).toBe(action);
527
+ // expect(m).toStrictEqual(preset);
528
+ // return Promise.resolve();
529
+ // }
530
+ // );
500
531
 
501
532
  await wrapper.vm.setPreset(action, preset);
502
533
  });
@@ -505,20 +536,20 @@ describe("MftpWebGL3DRModal.vue", () => {
505
536
  const action = PresetsActions.pr02;
506
537
  const preset = {};
507
538
 
508
- vi.spyOn(wrapper.vm, "sendPayload").mockImplementationOnce(
509
- (it: string, a: string, m: any) => {
510
- expect(it).toBe(FrontEndInterfaces.presets);
511
- expect(a).toBe(action);
512
- expect(m).toStrictEqual(preset);
513
- return Promise.resolve();
514
- }
515
- );
539
+ // vi.spyOn(wrapper.vm, "sendPayload").mockImplementationOnce(
540
+ // (it: string, a: string, m: any) => {
541
+ // expect(it).toBe(FrontEndInterfaces.presets);
542
+ // expect(a).toBe(action);
543
+ // expect(m).toStrictEqual(preset);
544
+ // return Promise.resolve();
545
+ // }
546
+ // );
516
547
 
517
548
  await wrapper.vm.setPreset(action, preset);
518
549
  });
519
550
 
520
551
  it("should getCurrentGreyscalePreset", async () => {
521
- expect(wrapper.vm.getCurrentGreyscalePreset()).toBe(undefined);
552
+ expect(unref(currentGreyscalePreset)).toBe(undefined);
522
553
  });
523
554
 
524
555
  it("should getViewName 3D Volume", async () => {
@@ -574,7 +605,7 @@ describe("MftpWebGL3DRModal.vue", () => {
574
605
  Version: "1.0.0",
575
606
  },
576
607
  ];
577
- await wrapper.vm.setScanState(JSON.stringify(initalState));
608
+ await setScanState(JSON.stringify(initalState));
578
609
 
579
610
  expect(
580
611
  wrapper.vm.getCurrentActiveView({
@@ -619,7 +650,7 @@ async function testWatcherForDisplay(
619
650
  Version: "0.0.1",
620
651
  Value: (scanState.Display as any)[key],
621
652
  });
622
- wrapper.vm.setScanState(JSON.stringify(scanState));
653
+ setScanState(JSON.stringify(scanState));
623
654
 
624
655
  await flushPromises();
625
656
  }
@@ -636,7 +667,7 @@ async function testWatcherForSlice(
636
667
  Version: "0.0.1",
637
668
  Value: (scanState.Slice as any)[key],
638
669
  });
639
- wrapper.vm.setScanState(JSON.stringify(scanState));
670
+ setScanState(JSON.stringify(scanState));
640
671
 
641
672
  await flushPromises();
642
673
  }
@@ -653,7 +684,7 @@ async function testWatcherForOrientation(
653
684
  Version: "0.0.1",
654
685
  Value: (scanState.Orientations as any)[key].Slice,
655
686
  });
656
- wrapper.vm.setScanState(JSON.stringify(scanState));
687
+ setScanState(JSON.stringify(scanState));
657
688
 
658
689
  await flushPromises();
659
690
  }
@@ -670,7 +701,7 @@ async function testWatcherForInteractionSettings(
670
701
  Version: "0.0.1",
671
702
  Value: (scanState.InteractionSettings as any)[key],
672
703
  });
673
- wrapper.vm.setScanState(JSON.stringify(scanState));
704
+ setScanState(JSON.stringify(scanState));
674
705
 
675
706
  await flushPromises();
676
707
  }
@@ -35,6 +35,10 @@ const sliderValue = computed({
35
35
  emit("update:value", Math.floor(val));
36
36
  },
37
37
  });
38
+
39
+ defineExpose({
40
+ sliderValue,
41
+ });
38
42
  </script>
39
43
 
40
44
  <template>
@@ -7,11 +7,15 @@ import { flushPromises } from "@vue/test-utils";
7
7
  describe("ValueSelector.vue", () => {
8
8
  let wrapper = mountVuetify(ValueSelector, {
9
9
  value: 1,
10
+ min: 0,
11
+ max: 100,
10
12
  });
11
13
 
12
14
  beforeEach(() => {
13
15
  wrapper = mountVuetify(ValueSelector, {
14
16
  value: [0, 0],
17
+ min: 0,
18
+ max: 100,
15
19
  });
16
20
  });
17
21
 
@@ -27,6 +31,20 @@ describe("ValueSelector.vue", () => {
27
31
  expect(wrapper.vm.value).toStrictEqual(1);
28
32
  });
29
33
 
34
+ it("should set text lower than min limits", async () => {
35
+ wrapper.vm.sliderValue = -100;
36
+ await flushPromises();
37
+
38
+ expect(wrapper.emitted()["update:value"]).toStrictEqual([[0]]);
39
+ });
40
+
41
+ it("should set text higher than max limits", async () => {
42
+ wrapper.vm.sliderValue = 9000;
43
+ await flushPromises();
44
+
45
+ expect(wrapper.emitted()["update:value"]).toStrictEqual([[100]]);
46
+ });
47
+
30
48
  it("should set text", async () => {
31
49
  const slider = wrapper.findAllComponents(".v-text-field");
32
50
 
@@ -35,10 +35,12 @@ const sliderValue = computed({
35
35
  },
36
36
  set(value: Array<number>) {
37
37
  let val = value;
38
- if (value[0] > props.max) val[0] = props.max;
39
- if (value[1] > props.max) val[1] = props.max;
40
- if (value[0] < props.min) val[0] = props.min;
41
- if (value[1] < props.min) val[1] = props.min;
38
+ if (val[0] > props.max) val[0] = props.max;
39
+ if (val[1] > props.max) val[1] = props.max;
40
+ if (val[0] < props.min) val[0] = props.min;
41
+ if (val[1] < props.min) val[1] = props.min;
42
+ console.log(val);
43
+ console.log(props);
42
44
  const normalised = [Math.floor(val[0]), Math.floor(val[1])];
43
45
  emit("update:value", normalised);
44
46
  },
@@ -57,6 +59,10 @@ watch(
57
59
  },
58
60
  { deep: true }
59
61
  );
62
+
63
+ defineExpose({
64
+ sliderValue,
65
+ });
60
66
  </script>
61
67
 
62
68
  <template>
@@ -7,11 +7,15 @@ import { flushPromises } from "@vue/test-utils";
7
7
  describe("DoubleSliderSelector.vue", () => {
8
8
  let wrapper = mountVuetify(DoubleSliderSelector, {
9
9
  value: [0, 0],
10
+ min: 0,
11
+ max: 100,
10
12
  });
11
13
 
12
14
  beforeEach(() => {
13
15
  wrapper = mountVuetify(DoubleSliderSelector, {
14
16
  value: [0, 0],
17
+ min: 0,
18
+ max: 100,
15
19
  });
16
20
  vi.useFakeTimers();
17
21
  });
@@ -59,6 +63,34 @@ describe("DoubleSliderSelector.vue", () => {
59
63
  await slider.setValue([1, 2]);
60
64
  });
61
65
 
66
+ it("should set min text lower than min limits", async () => {
67
+ wrapper.vm.sliderValue = [-10, 0];
68
+ await flushPromises();
69
+
70
+ expect(wrapper.emitted()["update:value"]).toStrictEqual([[[0, 0]]]);
71
+ });
72
+
73
+ it("should set max text lower than min limits", async () => {
74
+ wrapper.vm.sliderValue = [-100, -10];
75
+ await flushPromises();
76
+
77
+ expect(wrapper.emitted()["update:value"]).toStrictEqual([[[0, 0]]]);
78
+ });
79
+
80
+ it("should set min text higher than max limits", async () => {
81
+ wrapper.vm.sliderValue = [9000, 9001];
82
+ await flushPromises();
83
+
84
+ expect(wrapper.emitted()["update:value"]).toStrictEqual([[[100, 100]]]);
85
+ });
86
+
87
+ it("should set max text higher than max limits", async () => {
88
+ wrapper.vm.sliderValue = [50, 9000];
89
+ await flushPromises();
90
+
91
+ expect(wrapper.emitted()["update:value"]).toStrictEqual([[[50, 100]]]);
92
+ });
93
+
62
94
  it("should set min text", async () => {
63
95
  const slider = wrapper.findAllComponents(".v-text-field");
64
96
 
@@ -0,0 +1,98 @@
1
+ import { beforeEach, describe, expect, it, vi } from "vitest";
2
+ import { PayloadHandler } from "@/dataLayer/payloadHandler";
3
+ import { Ref, UnwrapRef } from "vue";
4
+ import WebGL3DR from "@/components/WebGL3DR.vue";
5
+ import { spyOn } from "@vitest/spy";
6
+ import {
7
+ FrontEndInterfaces,
8
+ ScanOrientationActions,
9
+ ScanView,
10
+ SlidersActions,
11
+ } from "@3cr/types-ts";
12
+ import { toNumber } from "@/helpers/utils";
13
+ import { transactionStarted } from "@/dataLayer/scanState";
14
+
15
+ const sendPayloadFunction = vi.fn();
16
+ const mockWebglInstance = {
17
+ value: {
18
+ sendPayload: sendPayloadFunction,
19
+ },
20
+ } as unknown as Ref<UnwrapRef<typeof WebGL3DR | null>>;
21
+
22
+ describe("payloadHandler.ts", () => {
23
+ it("should create instance", () => {
24
+ expect(new PayloadHandler(mockWebglInstance)).toBeTruthy();
25
+ });
26
+
27
+ describe("payload functions", () => {
28
+ let instance: PayloadHandler;
29
+ beforeEach(() => {
30
+ vi.resetAllMocks();
31
+ instance = new PayloadHandler(mockWebglInstance);
32
+ console.log(instance);
33
+ });
34
+
35
+ it("should sendPayload", async () => {
36
+ expect(sendPayloadFunction).not.toHaveBeenCalled();
37
+
38
+ await instance.sendPayload("123", "123", {});
39
+
40
+ expect(sendPayloadFunction).toHaveBeenCalledWith(
41
+ JSON.stringify({
42
+ Version: "0.0.1",
43
+ Interface: "123",
44
+ Action: "123",
45
+ Message: JSON.stringify({}),
46
+ })
47
+ );
48
+ });
49
+
50
+ it("should rotateByDeg", async () => {
51
+ const view = ScanView.Coronal;
52
+ const deg = 100;
53
+ const spy = spyOn(instance, "sendPayload");
54
+ expect(spy).not.toHaveBeenCalled();
55
+
56
+ await instance.rotateByDeg(view, deg);
57
+
58
+ expect(spy).toHaveBeenCalledWith(
59
+ FrontEndInterfaces.scan_orientation,
60
+ ScanOrientationActions.so01,
61
+ {
62
+ Version: "0.0.1",
63
+ View: view,
64
+ Angle: deg,
65
+ }
66
+ );
67
+ });
68
+
69
+ it("should sliderHandler", async () => {
70
+ const action = SlidersActions.sl08;
71
+ const value = 100;
72
+ const spy = spyOn(instance, "sendPayload");
73
+ expect(spy).not.toHaveBeenCalled();
74
+
75
+ await instance.sliderHandler(action, value);
76
+
77
+ expect(spy).toHaveBeenCalledWith(FrontEndInterfaces.sliders, action, {
78
+ Version: "0.0.1",
79
+ Value: toNumber(value),
80
+ });
81
+ });
82
+
83
+ it("should not sliderHandler transactionStarted", async () => {
84
+ transactionStarted.value = true;
85
+ const action = SlidersActions.sl08;
86
+ const value = 100;
87
+ const spy = spyOn(instance, "sendPayload");
88
+ expect(spy).not.toHaveBeenCalled();
89
+
90
+ await instance.sliderHandler(action, value);
91
+
92
+ expect(spy).not.toHaveBeenCalledWith(FrontEndInterfaces.sliders, action, {
93
+ Version: "0.0.1",
94
+ Value: toNumber(value),
95
+ });
96
+ });
97
+ });
98
+ });
@@ -0,0 +1,11 @@
1
+ export function getIconForPreset(presetName: string): string | undefined {
2
+ if (presetName === "Bone") return "fa:fas fa-bone";
3
+ if (presetName === "Brain") return "fa:fas fa-brain";
4
+ if (presetName === "Liver") return "custom:liver_icon";
5
+ if (presetName === "Lungs") return "fa:fas fa-lungs";
6
+ if (presetName === "Muscle") return "custom:muscle_icon";
7
+ if (presetName === "Temporal Bones") return "custom:temporal_bones_icon";
8
+ if (presetName === "Soft Tissue") return "custom:torso_icon";
9
+ if (presetName === "Skin") return "custom:skin_icon";
10
+ return undefined;
11
+ }
@@ -0,0 +1,89 @@
1
+ import { Ref, unref, UnwrapRef } from "vue";
2
+ import WebGL3DR from "@/components/WebGL3DR.vue";
3
+ import {
4
+ FrontEndInterfaces,
5
+ ScanMovementActions,
6
+ ScanOrientationActions,
7
+ ScanView,
8
+ SlidersActions,
9
+ ViewSelectionActions,
10
+ } from "@3cr/types-ts";
11
+ import { transactionStarted } from "@/dataLayer/scanState";
12
+ import { toNumber } from "@/helpers/utils";
13
+
14
+ const emptyPayload = { Version: "1.1.0" };
15
+
16
+ export class PayloadHandler {
17
+ private readonly instance: Ref<UnwrapRef<typeof WebGL3DR | null>>;
18
+ constructor(protected webglInstance: Ref<UnwrapRef<typeof WebGL3DR | null>>) {
19
+ this.instance = webglInstance;
20
+ }
21
+
22
+ async sendPayload(interfaceType: string, actionType: string, message: any) {
23
+ await this.instance.value?.sendPayload(
24
+ JSON.stringify({
25
+ Version: "0.0.1",
26
+ Interface: interfaceType,
27
+ Action: actionType,
28
+ Message: JSON.stringify(message),
29
+ })
30
+ );
31
+ }
32
+ async rotateByDeg(view: ScanView, deg: number) {
33
+ await this.sendPayload(
34
+ FrontEndInterfaces.scan_orientation,
35
+ ScanOrientationActions.so01,
36
+ {
37
+ Version: "0.0.1",
38
+ View: view,
39
+ Angle: deg,
40
+ }
41
+ );
42
+ }
43
+ async viewSelection(action: ViewSelectionActions) {
44
+ await this.sendPayload(
45
+ FrontEndInterfaces.view_selection,
46
+ action,
47
+ emptyPayload
48
+ );
49
+ }
50
+
51
+ async sliderHandler(action: SlidersActions, value: number) {
52
+ if (unref(transactionStarted)) return;
53
+ await this.slider(action, value);
54
+ }
55
+
56
+ async scanMovementHandler(action: ScanMovementActions, value: number) {
57
+ if (unref(transactionStarted)) return;
58
+ await this.scanMovement(action, value);
59
+ }
60
+
61
+ private async scanMovement(action: ScanMovementActions, value: number) {
62
+ await this.sendPayload(FrontEndInterfaces.scan_movement, action, {
63
+ Version: "0.0.1",
64
+ Value: toNumber(value),
65
+ });
66
+ }
67
+ private async slider(action: SlidersActions, value: number) {
68
+ await this.sendPayload(FrontEndInterfaces.sliders, action, {
69
+ Version: "0.0.1",
70
+ Value: toNumber(value),
71
+ });
72
+ }
73
+ }
74
+
75
+ export async function sendPayload(
76
+ instance: Ref<UnwrapRef<typeof WebGL3DR | null>>,
77
+ interfaceType: string,
78
+ actionType: string,
79
+ message: any
80
+ ) {
81
+ await unref(instance)?.sendPayload(
82
+ JSON.stringify({
83
+ Version: "0.0.1",
84
+ Interface: interfaceType,
85
+ Action: actionType,
86
+ Message: JSON.stringify(message),
87
+ })
88
+ );
89
+ }