@3cr/viewer-browser 0.0.161 → 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 (229) hide show
  1. package/.circleci/config.yml +53 -0
  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 +22734 -17747
  6. package/dist/Viewer3CR.umd.js +44 -27
  7. package/index.html +6 -8
  8. package/index.ts +9 -5
  9. package/package.json +5 -2
  10. package/playground/index.html +7 -10
  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/coverage/3cr-viewer-browser/index.html +0 -116
  187. package/coverage/3cr-viewer-browser/index.ts.html +0 -199
  188. package/coverage/3cr-viewer-browser/src/App.vue.html +0 -316
  189. package/coverage/3cr-viewer-browser/src/components/WebGL3DR.vue.html +0 -442
  190. package/coverage/3cr-viewer-browser/src/components/icons/index.html +0 -116
  191. package/coverage/3cr-viewer-browser/src/components/icons/liver.vue.html +0 -148
  192. package/coverage/3cr-viewer-browser/src/components/index.html +0 -116
  193. package/coverage/3cr-viewer-browser/src/components/loading/LoadingSpinner.vue.html +0 -622
  194. package/coverage/3cr-viewer-browser/src/components/loading/index.html +0 -116
  195. package/coverage/3cr-viewer-browser/src/components/modal/MftpWebGL3DRModal.vue.html +0 -3118
  196. package/coverage/3cr-viewer-browser/src/components/modal/index.html +0 -116
  197. package/coverage/3cr-viewer-browser/src/components/selectors/ValueSelector.vue.html +0 -358
  198. package/coverage/3cr-viewer-browser/src/components/selectors/index.html +0 -116
  199. package/coverage/3cr-viewer-browser/src/components/sliders/DoubleSliderSelector.vue.html +0 -487
  200. package/coverage/3cr-viewer-browser/src/components/sliders/VerticalSliderSelector.vue.html +0 -358
  201. package/coverage/3cr-viewer-browser/src/components/sliders/index.html +0 -131
  202. package/coverage/3cr-viewer-browser/src/dataLayer/iconData.ts.html +0 -118
  203. package/coverage/3cr-viewer-browser/src/dataLayer/index.html +0 -146
  204. package/coverage/3cr-viewer-browser/src/dataLayer/payloadHandler.ts.html +0 -463
  205. package/coverage/3cr-viewer-browser/src/dataLayer/scanState.ts.html +0 -598
  206. package/coverage/3cr-viewer-browser/src/helpers/index.html +0 -146
  207. package/coverage/3cr-viewer-browser/src/helpers/layoutOverlayStyle.ts.html +0 -406
  208. package/coverage/3cr-viewer-browser/src/helpers/modelHelper.ts.html +0 -412
  209. package/coverage/3cr-viewer-browser/src/helpers/utils.ts.html +0 -133
  210. package/coverage/3cr-viewer-browser/src/index.html +0 -131
  211. package/coverage/3cr-viewer-browser/src/main.ts.html +0 -124
  212. package/coverage/3cr-viewer-browser/src/models/LoadViewerOptions.ts.html +0 -166
  213. package/coverage/3cr-viewer-browser/src/models/index.html +0 -116
  214. package/coverage/3cr-viewer-browser/src/notifications/index.html +0 -116
  215. package/coverage/3cr-viewer-browser/src/notifications/notification.ts.html +0 -238
  216. package/coverage/3cr-viewer-browser/src/plugins/index.html +0 -131
  217. package/coverage/3cr-viewer-browser/src/plugins/index.ts.html +0 -136
  218. package/coverage/3cr-viewer-browser/src/plugins/vuetify.ts.html +0 -220
  219. package/coverage/base.css +0 -224
  220. package/coverage/block-navigation.js +0 -87
  221. package/coverage/favicon.png +0 -0
  222. package/coverage/index.html +0 -296
  223. package/coverage/prettify.css +0 -1
  224. package/coverage/prettify.js +0 -2
  225. package/coverage/sort-arrow-sprite.png +0 -0
  226. package/coverage/sorter.js +0 -196
  227. package/src/dataLayer/__tests__/payload-handler.spec.ts +0 -214
  228. package/src/dataLayer/payloadHandler.ts +0 -138
  229. /package/src/dataLayer/{iconData.ts → getIconForPreset.ts} +0 -0
@@ -1,9 +1,54 @@
1
+ <template>
2
+ <v-row class="flex-column double-slider-selector" no-gutters>
3
+ <v-row no-gutters justify="start">
4
+ <v-col>
5
+ <span class="text-caption">{{ label }}</span>
6
+ </v-col>
7
+ </v-row>
8
+ <v-row class="py-2" no-gutters>
9
+ <v-col>
10
+ <v-text-field
11
+ :model-value="sliderValue[0]"
12
+ @update:modelValue="onUpdate($event, sliderValue[1])"
13
+ density="compact"
14
+ hide-details
15
+ variant="outlined"
16
+ type="number"
17
+ />
18
+ </v-col>
19
+ <v-spacer />
20
+ <v-col>
21
+ <v-text-field
22
+ :model-value="sliderValue[1]"
23
+ @update:modelValue="onUpdate(sliderValue[0], $event)"
24
+ density="compact"
25
+ hide-details
26
+ variant="outlined"
27
+ type="number"
28
+ />
29
+ </v-col>
30
+ </v-row>
31
+ <v-row class="pb-4" no-gutters>
32
+ <v-range-slider
33
+ v-model="sliderValue"
34
+ :loading="loading"
35
+ :thumb-label="showThumb"
36
+ thumb-color="blue"
37
+ :min="min"
38
+ :max="max"
39
+ hide-details
40
+ />
41
+ </v-row>
42
+ </v-row>
43
+ </template>
44
+
1
45
  <script setup lang="ts">
2
- import { computed, defineEmits, ref, unref, watch } from "vue";
46
+ import { computed, ref, unref, watch } from "vue";
3
47
  import { toNumber } from "@vue/shared";
48
+ import { clamp } from "@/dataLayer/clamp";
4
49
 
5
50
  export interface Props {
6
- value: Array<number>;
51
+ value: [number, number];
7
52
  loading?: boolean;
8
53
  label?: string;
9
54
  lower?: number;
@@ -23,89 +68,39 @@ const props = withDefaults(defineProps<Props>(), {
23
68
  });
24
69
 
25
70
  const emit = defineEmits<{
26
- "update:value": [Array<number>];
71
+ "update:value": [[number, number]];
27
72
  }>();
28
73
 
29
- const prevValue = ref<Array<number>>([]);
30
74
  const showThumb = ref<"always" | boolean>(false);
31
75
  const showThumbTimeout = ref<NodeJS.Timeout | undefined>(undefined);
76
+
32
77
  const sliderValue = computed({
33
78
  get() {
34
79
  return props.value;
35
80
  },
36
- set(value: Array<number>) {
37
- let val = value;
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);
44
- emit("update:value", [val[0], val[1]]);
81
+ set(value: [number, number]) {
82
+ const val = value.map(v => clamp(v, props.min, props.max)) as [number, number];
83
+ emit("update:value", val);
45
84
  },
46
85
  });
47
- watch(
48
- sliderValue,
49
- async (currentValue: Array<number>) => {
50
- if (JSON.stringify(unref(prevValue)) !== JSON.stringify(currentValue)) {
51
- clearTimeout(unref(showThumbTimeout));
52
- showThumb.value = "always";
53
- showThumbTimeout.value = setTimeout(() => {
54
- showThumb.value = true;
55
- }, 1000);
56
- }
57
- prevValue.value = currentValue;
58
- },
59
- { deep: true }
60
- );
61
86
 
62
- defineExpose({
63
- sliderValue,
87
+ watch([
88
+ () => sliderValue.value[0],
89
+ () => sliderValue.value[1]
90
+ ], () => {
91
+ clearTimeout(unref(showThumbTimeout));
92
+ showThumb.value = "always";
93
+ showThumbTimeout.value = setTimeout(() => {
94
+ showThumb.value = false;
95
+ }, 1000);
64
96
  });
65
- </script>
66
97
 
67
- <template>
68
- <div class="double-slider-selector">
69
- <v-card-subtitle class="pb-0 pt-1 text-caption">{{
70
- label
71
- }}</v-card-subtitle>
72
- <v-card-actions class="px-2 pb-0">
73
- <v-text-field
74
- :model-value="sliderValue[0]"
75
- @update:modelValue="sliderValue = [toNumber($event), sliderValue[1]]"
76
- density="compact"
77
- class="mt-0 pt-0"
78
- hide-details
79
- variant="outlined"
80
- type="number"
81
- style="width: 44px"
82
- ></v-text-field>
83
- <v-spacer />
84
- <v-text-field
85
- :model-value="sliderValue[1]"
86
- @update:modelValue="sliderValue = [sliderValue[0], toNumber($event)]"
87
- density="compact"
88
- class="mt-0 pt-0"
89
- hide-details
90
- variant="outlined"
91
- type="number"
92
- style="width: 44px"
93
- ></v-text-field>
94
- </v-card-actions>
98
+ function onUpdate(first: string | number, second: string | number): void {
99
+ sliderValue.value = [toNumber(first), toNumber(second)];
100
+ }
95
101
 
96
- <v-range-slider
97
- v-model="sliderValue"
98
- :loading="loading"
99
- :thumb-label="showThumb"
100
- thumb-color="blue"
101
- :min="min"
102
- hide-details
103
- :max="max"
104
- class="align-center px-2"
105
- >
106
- </v-range-slider>
107
- </div>
108
- </template>
102
+ defineExpose({ sliderValue });
103
+ </script>
109
104
 
110
105
  <style>
111
106
  .double-slider-selector
@@ -125,6 +120,19 @@ defineExpose({
125
120
  min-height: 32px !important;
126
121
  }
127
122
 
123
+ .double-slider-selector .v-slider-thumb__label {
124
+ transform: translateX(-50%) rotate(180deg) translateY(-85%) !important;
125
+ top: calc(var(--v-slider-thumb-size) / 2) !important;
126
+ bottom: unset !important;
127
+ font-size: 0.6rem !important;
128
+ padding: 2px 4px !important;
129
+ height: 20px !important;
130
+ }
131
+
132
+ .double-slider-selector .v-slider-thumb__label div {
133
+ transform: rotate(180deg) !important;
134
+ }
135
+
128
136
  .double-slider-selector .v-slider__thumb-label {
129
137
  color: black;
130
138
  width: 40px !important;
@@ -1,5 +1,5 @@
1
1
  <script setup lang="ts">
2
- import { computed, defineEmits, ref, unref, watch } from "vue";
2
+ import { computed, ref, unref, watch } from "vue";
3
3
 
4
4
  export interface Props {
5
5
  value: number;
@@ -25,9 +25,9 @@ const emit = defineEmits<{
25
25
  "update:value": [number];
26
26
  }>();
27
27
 
28
- const prevValue = ref<number>(0);
29
28
  const showThumb = ref<"always" | boolean>(true);
30
29
  const showThumbTimeout = ref<NodeJS.Timeout | undefined>(undefined);
30
+
31
31
  const sliderValue = computed({
32
32
  get() {
33
33
  return Math.floor(props.value);
@@ -37,25 +37,17 @@ const sliderValue = computed({
37
37
  },
38
38
  });
39
39
 
40
- watch(
41
- sliderValue,
42
- async (currentValue: number) => {
43
- if (JSON.stringify(unref(prevValue)) !== JSON.stringify(currentValue)) {
44
- clearTimeout(unref(showThumbTimeout));
45
- showThumb.value = "always";
46
- showThumbTimeout.value = setTimeout(() => {
47
- showThumb.value = true;
48
- }, 1000);
49
- }
50
- prevValue.value = currentValue;
51
- },
52
- { deep: true }
53
- );
40
+ watch(() => sliderValue.value, () => {
41
+ clearTimeout(unref(showThumbTimeout));
42
+ showThumb.value = "always";
43
+ showThumbTimeout.value = setTimeout(() => {
44
+ showThumb.value = false;
45
+ }, 1000);
46
+ });
54
47
  </script>
55
48
 
56
49
  <template>
57
50
  <v-slider
58
- style="position: absolute; right: 0px; top: 0; height: calc(100% - 20px)"
59
51
  v-model="sliderValue"
60
52
  :thumb-label="showThumb"
61
53
  :min="min"
@@ -80,6 +72,9 @@ watch(
80
72
 
81
73
  <style lang="scss">
82
74
  .vertical-slider-selector {
75
+ display: flex;
76
+ flex-direction: column-reverse;
77
+ align-items: center;
83
78
  & .v-input__control {
84
79
  min-height: 32px !important;
85
80
  height: 100% !important;
@@ -55,7 +55,7 @@ describe("DoubleSliderSelector.vue", () => {
55
55
  vi.advanceTimersByTime(1);
56
56
  await flushPromises();
57
57
  expect(wrapper.vm.value).toStrictEqual([1, 1]);
58
- checkComponentProps(slider, "thumbLabel", true);
58
+ checkComponentProps(slider, "thumbLabel", false);
59
59
  });
60
60
 
61
61
  it("should set slider value", async () => {
@@ -51,7 +51,7 @@ describe("VerticalSliderSelector.vue", () => {
51
51
  vi.advanceTimersByTime(1);
52
52
  await flushPromises();
53
53
  expect(wrapper.vm.value).toStrictEqual(1);
54
- checkComponentProps(slider, "thumbLabel", true);
54
+ checkComponentProps(slider, "thumbLabel", false);
55
55
  });
56
56
 
57
57
  it("should set slider value", async () => {
@@ -0,0 +1,16 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { clamp } from '@/dataLayer/clamp';
3
+
4
+ describe('clamp tests', () => {
5
+ it('should clamp min', () => {
6
+ expect(clamp(-1, 0, 100)).toEqual(0);
7
+ });
8
+
9
+ it('should clamp max', () => {
10
+ expect(clamp(101, 0, 100)).toEqual(100);
11
+ });
12
+
13
+ it('should not clamp within range', () => {
14
+ expect(clamp(50, 0, 100)).toEqual(50);
15
+ });
16
+ });
@@ -0,0 +1,38 @@
1
+ import { describe, expect, it, vi} from 'vitest';
2
+ import { EventHandlers } from '@/dataLayer/eventHandlers';
3
+
4
+ describe('eventHandlers tests', () => {
5
+ it('should add the same key and handler only once', async () => {
6
+ const handlers = new EventHandlers();
7
+ const fn = vi.fn();
8
+ handlers.add('fn', fn);
9
+ handlers.add('fn', fn);
10
+ await handlers.call('fn');
11
+ expect(fn).toHaveBeenCalledOnce();
12
+ });
13
+
14
+ it('should add different handlers', async () => {
15
+ const handlers = new EventHandlers();
16
+ const a = vi.fn();
17
+ const b = vi.fn();
18
+ handlers.add('fn', a);
19
+ handlers.add('fn', b);
20
+ await handlers.call('fn');
21
+ expect(a).toHaveBeenCalledOnce();
22
+ expect(b).toHaveBeenCalledOnce();
23
+ })
24
+
25
+ it('should add/remove the same key and handler', () => {
26
+ const handlers = new EventHandlers();
27
+ const fn = vi.fn();
28
+ handlers.add('fn', fn);
29
+ expect(handlers.remove('fn', fn)).toBeTruthy();
30
+ });
31
+
32
+ it('should not remove handler of different key', () => {
33
+ const handlers = new EventHandlers();
34
+ const fn = vi.fn();
35
+ handlers.add('foo', fn);
36
+ expect(handlers.remove('bar', vi.fn())).toBeFalsy();
37
+ });
38
+ });
@@ -0,0 +1,40 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { getIconForPreset } from '@/dataLayer/getIconForPreset';
3
+
4
+ describe('getIconForPreset tests', () => {
5
+ it("should get bone icon", () => {
6
+ expect(getIconForPreset("Bone")).toBe("fa:fas fa-bone");
7
+ });
8
+
9
+ it("should get brain icon", () => {
10
+ expect(getIconForPreset("Brain")).toBe("fa:fas fa-brain");
11
+ });
12
+
13
+ it("should get liver icon", () => {
14
+ expect(getIconForPreset("Liver")).toBe("custom:liver_icon");
15
+ });
16
+
17
+ it("should get lungs icon", () => {
18
+ expect(getIconForPreset("Lungs")).toBe("fa:fas fa-lungs");
19
+ });
20
+
21
+ it("should get muscle icon", () => {
22
+ expect(getIconForPreset("Muscle")).toBe("custom:muscle_icon");
23
+ });
24
+
25
+ it("should get temporal bones icon", () => {
26
+ expect(getIconForPreset("Temporal Bones")).toBe("custom:temporal_bones_icon");
27
+ });
28
+
29
+ it("should get soft tissue icon", () => {
30
+ expect(getIconForPreset("Soft Tissue")).toBe("custom:torso_icon");
31
+ });
32
+
33
+ it("should get skin icon", () => {
34
+ expect(getIconForPreset("Skin")).toBe("custom:skin_icon");
35
+ });
36
+
37
+ it("should get undefined icon", () => {
38
+ expect(getIconForPreset("AKJSDHLKAJSDLJ")).toBe(undefined);
39
+ });
40
+ });
@@ -0,0 +1,88 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import {
3
+ DataOverlayEventUnpatched,
4
+ InitialDataOverlayStateUnpatched,
5
+ patchDataOverlayEvent,
6
+ patchInitialDataOverlay
7
+ } from "@/dataLayer/patchDataOverlay";
8
+
9
+ const unpatchedState: InitialDataOverlayStateUnpatched = {
10
+ Version: '1.0.0',
11
+ DataOverlay: {
12
+ Version: '1.0.0',
13
+ DataOverlay: [
14
+ {
15
+ Version: '1.0.0',
16
+ Id: '0',
17
+ DataType: 0,
18
+ Data: JSON.stringify({
19
+ Colour2d: { },
20
+ Colour3d: { },
21
+ Description: '',
22
+ Icon2d: '',
23
+ Id: ',',
24
+ Inverted: { },
25
+ Position: { },
26
+ Size2d: { },
27
+ Size3d: { },
28
+ Title: '',
29
+ Version: '',
30
+ Visibility2d: false,
31
+ Visibility3d: false,
32
+ CallToAction: JSON.stringify({
33
+ Actions: [
34
+ {
35
+ ActionType: 0,
36
+ ActionData: JSON.stringify({
37
+ Description: '',
38
+ Url: '',
39
+ })
40
+ }
41
+ ]
42
+ }),
43
+ })
44
+ }
45
+ ]
46
+ }
47
+ };
48
+
49
+ const unpatchedEvent: DataOverlayEventUnpatched = {
50
+ Version: '1.0.0',
51
+ Interaction: 0,
52
+ Annotation: {
53
+ Colour2d: { } as any,
54
+ Colour3d: { } as any,
55
+ Description: '',
56
+ Icon2d: '',
57
+ Id: ',',
58
+ Inverted: { } as any,
59
+ Position: { } as any,
60
+ Size2d: { } as any,
61
+ Size3d: { } as any,
62
+ Title: '',
63
+ Version: '',
64
+ Visibility2d: false,
65
+ Visibility3d: false,
66
+ CallToAction: JSON.stringify({
67
+ Actions: [
68
+ {
69
+ ActionType: 0,
70
+ ActionData: JSON.stringify({
71
+ Description: '',
72
+ Url: '',
73
+ })
74
+ }
75
+ ]
76
+ }),
77
+ }
78
+ }
79
+
80
+ describe('patchDataOverlay tests', () => {
81
+ it('should patch data overlay state', () => {
82
+ expect(() => patchInitialDataOverlay(unpatchedState)).not.toThrow();
83
+ });
84
+
85
+ it('should patch data overlay event', () => {
86
+ expect(() => patchDataOverlayEvent(unpatchedEvent)).not.toThrow();
87
+ });
88
+ });
@@ -0,0 +1,93 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { inflateScanState } from "@/helpers/modelHelper";
3
+ import { AnchorPoint, ScanView } from "@3cr/types-ts";
4
+ import {cSlider, getCurrentView, setScanState, sSlider, tSlider} from "@/dataLayer/scanState";
5
+
6
+ describe('scanState tests', () => {
7
+ it("should getCurrentView Sagittal", () => {
8
+ expect(
9
+ getCurrentView({
10
+ Anchor: AnchorPoint.CENTER,
11
+ ActiveView: true,
12
+ AspectRatio: 1,
13
+ MaxSize: {
14
+ Version: "0.0.1",
15
+ X: 1,
16
+ Y: 1,
17
+ },
18
+ DefaultView: ScanView.Coronal,
19
+ Priority: 1,
20
+ Version: "0.0.1",
21
+ Offset: {
22
+ Version: "0.0.1",
23
+ X: 1,
24
+ Y: 1,
25
+ },
26
+ })
27
+ ).toBe(3);
28
+ });
29
+
30
+ it("should getCurrentView Sagittal", () => {
31
+ const initalState = inflateScanState();
32
+ initalState.Layout.PositionData = [
33
+ {
34
+ Anchor: AnchorPoint.CENTER,
35
+ ActiveView: true,
36
+ AspectRatio: 1,
37
+ MaxSize: {
38
+ Version: "1.0.0",
39
+ X: 1,
40
+ Y: 1,
41
+ },
42
+ DefaultView: ScanView.Coronal,
43
+ Priority: 1,
44
+ Offset: {
45
+ Version: "1.0.0",
46
+ X: 1,
47
+ Y: 1,
48
+ },
49
+ Version: "1.0.0",
50
+ },
51
+ ];
52
+ setScanState(JSON.stringify(initalState));
53
+
54
+ expect(
55
+ getCurrentView({
56
+ Anchor: AnchorPoint.CENTER,
57
+ ActiveView: true,
58
+ AspectRatio: 1,
59
+ MaxSize: {
60
+ Version: "0.0.1",
61
+ X: 1,
62
+ Y: 1,
63
+ },
64
+ DefaultView: ScanView.Coronal,
65
+ Priority: 1,
66
+ Version: "0.0.1",
67
+ Offset: {
68
+ Version: "0.0.1",
69
+ X: 1,
70
+ Y: 1,
71
+ },
72
+ })
73
+ ).toBe(0);
74
+ });
75
+
76
+ it('should get/set sagittal slider', () => {
77
+ sSlider.value = [0, 100];
78
+ expect(sSlider.value[0]).toBe(0);
79
+ expect(sSlider.value[1]).toBe(100);
80
+ });
81
+
82
+ it('should get/set coronal slider', () => {
83
+ cSlider.value = [0, 100];
84
+ expect(cSlider.value[0]).toBe(0);
85
+ expect(cSlider.value[1]).toBe(100);
86
+ });
87
+
88
+ it('should get/set transverse slider', () => {
89
+ tSlider.value = [0, 100];
90
+ expect(tSlider.value[0]).toBe(0);
91
+ expect(tSlider.value[1]).toBe(100);
92
+ });
93
+ });
@@ -0,0 +1,10 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { useViewer3cr } from '@/dataLayer/useViewer3cr';
3
+
4
+ describe('useViewer3cr tests', () => {
5
+ it('should return same service instance', () => {
6
+ const a = useViewer3cr();
7
+ const b = useViewer3cr();
8
+ expect(a).eq(b);
9
+ });
10
+ });