@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.
- package/components.d.ts +0 -1
- package/coverage/3cr-viewer-browser/index.html +5 -5
- package/coverage/3cr-viewer-browser/index.ts.html +14 -26
- package/coverage/3cr-viewer-browser/src/App.vue.html +51 -48
- package/coverage/3cr-viewer-browser/src/components/WebGL3DR.vue.html +1 -1
- package/coverage/3cr-viewer-browser/src/components/icons/index.html +1 -1
- package/coverage/3cr-viewer-browser/src/components/icons/liver.vue.html +1 -1
- package/coverage/3cr-viewer-browser/src/components/index.html +1 -1
- package/coverage/3cr-viewer-browser/src/components/loading/LoadingSpinner.vue.html +82 -16
- package/coverage/3cr-viewer-browser/src/components/loading/index.html +5 -5
- package/coverage/3cr-viewer-browser/src/components/modal/MftpWebGL3DRModal.vue.html +238 -1123
- package/coverage/3cr-viewer-browser/src/components/modal/index.html +19 -19
- package/coverage/3cr-viewer-browser/src/components/selectors/ValueSelector.vue.html +47 -20
- package/coverage/3cr-viewer-browser/src/components/selectors/index.html +7 -7
- package/coverage/3cr-viewer-browser/src/components/sliders/DoubleSliderSelector.vue.html +62 -20
- package/coverage/3cr-viewer-browser/src/components/sliders/VerticalSliderSelector.vue.html +16 -7
- package/coverage/3cr-viewer-browser/src/components/sliders/index.html +10 -10
- package/coverage/3cr-viewer-browser/src/dataLayer/iconData.ts.html +118 -0
- package/coverage/3cr-viewer-browser/src/dataLayer/index.html +146 -0
- package/coverage/3cr-viewer-browser/src/dataLayer/payloadHandler.ts.html +352 -0
- package/coverage/3cr-viewer-browser/src/dataLayer/scanState.ts.html +628 -0
- package/coverage/3cr-viewer-browser/src/helpers/index.html +1 -1
- package/coverage/3cr-viewer-browser/src/helpers/layoutOverlayStyle.ts.html +1 -1
- package/coverage/3cr-viewer-browser/src/helpers/modelHelper.ts.html +105 -105
- package/coverage/3cr-viewer-browser/src/helpers/utils.ts.html +3 -3
- package/coverage/3cr-viewer-browser/src/index.html +5 -5
- package/coverage/3cr-viewer-browser/src/main.ts.html +1 -1
- package/coverage/3cr-viewer-browser/src/models/LoadViewerOptions.ts.html +166 -0
- package/coverage/3cr-viewer-browser/src/models/index.html +116 -0
- package/coverage/3cr-viewer-browser/src/notifications/index.html +116 -0
- package/coverage/3cr-viewer-browser/src/notifications/notification.ts.html +229 -0
- package/coverage/3cr-viewer-browser/src/plugins/index.html +5 -5
- package/coverage/3cr-viewer-browser/src/plugins/index.ts.html +14 -8
- package/coverage/3cr-viewer-browser/src/plugins/vuetify.ts.html +1 -1
- package/coverage/index.html +78 -33
- package/dist/Viewer3CR.js +12 -12
- package/dist/Viewer3CR.mjs +10004 -9916
- package/dist/Viewer3CR.umd.js +12 -12
- package/index.ts +7 -42
- package/package.json +2 -1
- package/src/App.vue +6 -2
- package/src/components/modal/MftpWebGL3DRModal.vue +137 -452
- package/src/components/modal/__tests__/mftp-webgl-3dr-modal.spec.ts +114 -83
- package/src/components/selectors/ValueSelector.vue +4 -0
- package/src/components/selectors/__tests__/value-selector.spec.ts +18 -0
- package/src/components/sliders/DoubleSliderSelector.vue +10 -4
- package/src/components/sliders/__tests__/double-slider-selector.spec.ts +32 -0
- package/src/dataLayer/__tests__/payload-handler.spec.ts +98 -0
- package/src/dataLayer/iconData.ts +11 -0
- package/src/dataLayer/payloadHandler.ts +89 -0
- package/src/dataLayer/scanState.ts +181 -0
- package/src/demo/DemoPatientModal.vue +59 -0
- package/src/demo/options.ts +93 -0
- package/src/models/Callbacks.ts +2 -0
- package/src/models/LoadViewerOptions.ts +27 -0
- package/src/models/LoadViewerPayload.ts +8 -0
- package/src/notifications/notification.ts +48 -0
- package/vitest.config.mts +1 -0
- /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(
|
|
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
|
-
|
|
384
|
+
setScanState(JSON.stringify(scanState));
|
|
332
385
|
|
|
333
|
-
expect(
|
|
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
|
-
|
|
399
|
+
setScanState(JSON.stringify(scanState));
|
|
346
400
|
|
|
347
|
-
expect(
|
|
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
|
-
|
|
429
|
+
setScanState(JSON.stringify(scanState));
|
|
375
430
|
await flushPromises();
|
|
376
|
-
expect(
|
|
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
|
-
|
|
454
|
+
setScanState(JSON.stringify(scanState));
|
|
400
455
|
await flushPromises();
|
|
401
|
-
expect(
|
|
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
|
-
|
|
479
|
+
setScanState(JSON.stringify(scanState));
|
|
425
480
|
await flushPromises();
|
|
426
|
-
expect(
|
|
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
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
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
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
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
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
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(
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
704
|
+
setScanState(JSON.stringify(scanState));
|
|
674
705
|
|
|
675
706
|
await flushPromises();
|
|
676
707
|
}
|
|
@@ -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 (
|
|
39
|
-
if (
|
|
40
|
-
if (
|
|
41
|
-
if (
|
|
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
|
+
}
|