@3cr/viewer-browser 0.0.112 → 0.0.113

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@3cr/viewer-browser",
3
- "version": "0.0.112",
3
+ "version": "0.0.113",
4
4
  "main": "./dist/Viewer3CR.umd.js",
5
5
  "module": "dist/Viewer3CR.umd.js",
6
6
  "homepage": "https://docs.3cr.singular.health",
@@ -22,20 +22,30 @@
22
22
  id="close-dialog-prompt"
23
23
  data-test="closemodal"
24
24
  >
25
- <v-card class="pa-1 ma-auto position-relative" max-width="450">
25
+ <v-card
26
+ class="pa-1 ma-auto position-relative motif-background"
27
+ width="600"
28
+ theme="dark"
29
+ >
26
30
  <v-card-title>Close Viewer?</v-card-title>
27
31
  <v-card-text
28
32
  >Are you sure you want to close the Online Viewer?</v-card-text
29
33
  >
30
34
  <v-card-actions>
31
- <v-btn variant="text" color="red" @click="m_closeDialog = false">
35
+ <v-btn
36
+ variant="tonal"
37
+ color="secondary"
38
+ @click="m_closeDialog = false"
39
+ >
32
40
  Cancel
33
41
  </v-btn>
34
42
  <v-spacer />
35
- <v-btn color="primary" @click="closeModal">
43
+ <v-btn color="red" variant="tonal" @click="closeModal">
36
44
  Close without saving
37
45
  </v-btn>
38
- <v-btn color="primary" @click="closeModal"> Save Session </v-btn>
46
+ <v-btn color="primary" variant="tonal" @click="closeModal">
47
+ Save Session
48
+ </v-btn>
39
49
  </v-card-actions>
40
50
  </v-card>
41
51
  </v-dialog>
@@ -84,12 +94,19 @@
84
94
  </template>
85
95
  <v-list-item-title> Load Saved Session </v-list-item-title>
86
96
  </v-list-item>
97
+ <v-list-item @click="executeOption('OnSendTo3rdParty')">
98
+ <template v-slot:prepend>
99
+ <v-icon> send </v-icon>
100
+ </template>
101
+ <v-list-item-title>Send to 3rd Party</v-list-item-title>
102
+ </v-list-item>
87
103
  <v-list-item @click="executeOption('OnShare')">
88
104
  <template v-slot:prepend>
89
105
  <v-icon> share </v-icon>
90
106
  </template>
91
- <v-list-item-title>Share</v-list-item-title>
107
+ <v-list-item-title>Share to Mobile / VR</v-list-item-title>
92
108
  </v-list-item>
109
+
93
110
  <v-list-item
94
111
  @click="
95
112
  executeOption('OnClosePopup');
@@ -122,18 +139,21 @@
122
139
  Settings
123
140
  </v-btn>
124
141
  </template>
125
- <v-card min-width="400" class="pa-4">
142
+ <v-card width="350" class="pa-4">
126
143
  <SliderSelector
127
144
  v-model:value="scanState.Display.Brightness"
128
145
  label="Adjust Brightness"
146
+ prepend="percent"
129
147
  />
130
148
  <SliderSelector
131
149
  v-model:value="scanState.Display.Contrast"
132
150
  label="Adjust Contrast"
151
+ prepend="percent"
133
152
  />
134
153
  <SliderSelector
135
154
  v-model:value="scanState.Display.Opacity"
136
155
  label="Adjust Opacity"
156
+ prepend="percent"
137
157
  />
138
158
  <v-divider class="my-4" />
139
159
  <SliderSelector
@@ -141,18 +161,21 @@
141
161
  :min="0"
142
162
  :max="100"
143
163
  label="Pan Sensitivity"
164
+ prepend="percent"
144
165
  />
145
166
  <SliderSelector
146
167
  v-model:value="scanState.InteractionSettings.ZoomSensitivity"
147
168
  :min="0"
148
169
  :max="100"
149
170
  label="Zoom Sensitivity"
171
+ prepend="percent"
150
172
  />
151
173
  <SliderSelector
152
174
  v-model:value="scanState.InteractionSettings.RotateSensitivity"
153
175
  :min="0"
154
176
  :max="100"
155
177
  label="Rotate Sensitivity"
178
+ prepend="percent"
156
179
  />
157
180
  <SliderSelector
158
181
  v-model:value="
@@ -161,6 +184,7 @@
161
184
  :min="0"
162
185
  :max="100"
163
186
  label="Camera Rotate Sensitivity"
187
+ prepend="percent"
164
188
  />
165
189
  </v-card>
166
190
  </v-menu>
@@ -178,19 +202,25 @@
178
202
  style="min-width: 36px !important"
179
203
  :color="isLayout2x2 ? 'secondary' : 'primary'"
180
204
  @click="payloadHandler.layouts(LayoutActions.lo02)"
181
- ><v-icon>grid_view</v-icon></v-btn
182
- >
205
+ ><v-icon>grid_view</v-icon>
206
+ <v-tooltip location="bottom" activator="parent">
207
+ Change Layout to 2:2
208
+ </v-tooltip>
209
+ </v-btn>
183
210
  <v-btn
184
- class="ma-1 mr-0 pa-1"
211
+ class="ma-1 mr-1 pa-1"
185
212
  height="36"
186
213
  style="min-width: 36px !important"
187
214
  :color="isLayout1x3 ? 'secondary' : 'primary'"
188
215
  @click="payloadHandler.layouts(LayoutActions.lo03)"
189
- ><v-icon style="rotate: -90deg">view_comfy</v-icon></v-btn
216
+ ><v-icon style="rotate: -90deg">view_comfy</v-icon>
217
+ <v-tooltip location="bottom" activator="parent">
218
+ Change Layout to 1:3
219
+ </v-tooltip></v-btn
190
220
  >
191
221
  <v-btn class="" variant="flat" color="red" @click="alterValue(false)"
192
- >Close Viewer</v-btn
193
- >
222
+ >Close Viewer
223
+ </v-btn>
194
224
  </v-toolbar>
195
225
  <v-navigation-drawer
196
226
  v-model="drawer"
@@ -235,7 +265,13 @@
235
265
  <template v-slot:append>
236
266
  <v-divider></v-divider>
237
267
  <v-list>
238
- <v-tooltip right v-for="(item, index) in footerItems" :key="index">
268
+ <v-tooltip
269
+ right
270
+ v-for="(item, index) in footerItems.filter((x) =>
271
+ x.conditional()
272
+ )"
273
+ :key="index"
274
+ >
239
275
  <template #activator="{ props }">
240
276
  <v-list-item
241
277
  class="px-2"
@@ -271,7 +307,7 @@
271
307
  </v-list-item-title>
272
308
  </v-list-item>
273
309
  </template>
274
- {{ item.text }}
310
+ {{ item.tooltip }}
275
311
  </v-tooltip>
276
312
  </v-list>
277
313
  </template>
@@ -317,6 +353,9 @@
317
353
  >&nbsp;&nbsp;{{ miniMenu[0].text }}</span
318
354
  >
319
355
  <v-spacer />
356
+ <v-tooltip location="right" activator="parent">
357
+ {{ miniMenu[0].tooltip }}
358
+ </v-tooltip>
320
359
  </v-expansion-panel-title>
321
360
  <v-expansion-panel-text class="px-0">
322
361
  <DoubleSliderSelector
@@ -493,9 +532,7 @@
493
532
  Exit Fullscreen View
494
533
  </v-tooltip>
495
534
  </div>
496
- <div
497
- v-if="getCurrentActiveView(layout) === ScanView.Volume"
498
- >
535
+ <div>
499
536
  <v-btn
500
537
  color="transparent"
501
538
  :icon="true"
@@ -696,7 +733,7 @@ import { defineEmits, nextTick, ref, unref, watch, WatchSource } from "vue";
696
733
  import {
697
734
  checkIsDemo,
698
735
  demoType,
699
- executeDemoOption,
736
+ getDemoOption,
700
737
  isDemo,
701
738
  m_demo,
702
739
  m_demoPatient,
@@ -732,6 +769,7 @@ import {
732
769
  windowSlider,
733
770
  } from "@/dataLayer/scanState";
734
771
  import { getIconForPreset } from "@/dataLayer/iconData";
772
+ import { ViewerAsyncCallback, ViewerCallback } from "@/models/Callbacks";
735
773
 
736
774
  export interface Props {
737
775
  payload?: LoadViewerPayload;
@@ -763,30 +801,39 @@ const openPanels = ref<number>(0);
763
801
  const footerItems = ref([
764
802
  {
765
803
  text: "Reset Scan",
804
+ tooltip: "Resets your scan to original position and settings in all views",
766
805
  icon: "refresh",
767
806
  color: "red",
768
807
  click: async () => {
769
808
  await payloadHandler.viewSelection(ViewSelectionActions.vs05);
770
809
  await payloadHandler.viewSelection(ViewSelectionActions.vs06);
771
810
  },
811
+ conditional: () => true,
772
812
  },
773
813
  {
774
814
  text: "Send to 3rd Party",
815
+ tooltip:
816
+ "Securely share your loaded scan with 3rd parties via email with option to anonymise",
775
817
  icon: "send",
776
818
  color: "blue",
777
819
  click: async () => executeOption("OnSendTo3rdParty"),
820
+ conditional: () => getOption("OnSendTo3rdParty") !== undefined,
778
821
  },
779
822
  {
780
823
  text: "Share to Mobile / VR",
824
+ tooltip:
825
+ "Share your loaded scan with the 3Dicom Mobile and VR applications to download within 7 days",
781
826
  icon: "share",
782
827
  color: "yellow",
783
828
  click: async () => executeOption("OnShareToMobile"),
829
+ conditional: () => getOption("OnShareToMobile") !== undefined,
784
830
  },
785
831
  {
786
832
  text: "Screenshot View",
787
833
  icon: "screenshot_region",
788
834
  color: "green",
789
835
  click: async () => executeOption("OnScreenshot"),
836
+ conditional: () => getOption("OnScreenshot") !== undefined,
790
837
  },
791
838
  ]);
792
839
  const miniMenu = ref([
@@ -794,22 +841,26 @@ const miniMenu = ref([
794
841
  icon: "display_settings",
795
842
  text: "Tissue Density",
796
843
  tooltip:
797
- "Tissue Density - Change the view of density within the scan, allowing you to see through a certain density of particles",
844
+ "Change the range of visible anatomy in the scan by only showing areas with certain density of tissue",
798
845
  },
799
846
  ]);
800
847
  const rotationDeg = ref<number>(0);
801
848
  const stateOverlay = ref<boolean>(false);
802
849
  const m_closeDialog = ref<boolean>(false);
803
850
 
804
- function executeOption(key: keyof LoadViewerOptions) {
851
+ function getOption(
852
+ key: keyof LoadViewerOptions
853
+ ): ViewerCallback | ViewerAsyncCallback | undefined {
805
854
  if (unref(isDemo)) {
806
- executeDemoOption(key);
855
+ return getDemoOption(key);
807
856
  } else {
808
- const functionToExecute = unref(props.options)[key];
809
- console.log("executeOption", key, functionToExecute);
810
- if (functionToExecute !== undefined) {
811
- functionToExecute();
812
- }
857
+ return unref(props.options)[key];
858
+ }
859
+ }
860
+ function executeOption(key: keyof LoadViewerOptions) {
861
+ const functionToExecute = getOption(key);
862
+ if (functionToExecute !== undefined) {
863
+ functionToExecute();
813
864
  }
814
865
  }
815
866
 
@@ -49,7 +49,7 @@ defineExpose({
49
49
  {{ label }}
50
50
  </span>
51
51
  </v-col>
52
- <v-col cols="6">
52
+ <v-col cols="4">
53
53
  <v-text-field
54
54
  :model-value="sliderValue"
55
55
  @update:modelValue="sliderValue = toNumber($event)"
@@ -60,7 +60,7 @@ defineExpose({
60
60
  variant="outlined"
61
61
  density="compact"
62
62
  type="number"
63
- :append-icon="prepend"
63
+ :append-inner-icon="prepend"
64
64
  ></v-text-field>
65
65
  </v-col>
66
66
  </v-row>
@@ -88,4 +88,8 @@ defineExpose({
88
88
  .single-slider-selector .v-slider__thumb-label {
89
89
  color: black;
90
90
  }
91
+ .single-slider-selector {
92
+ margin-top: 4px;
93
+ margin-bottom: 4px;
94
+ }
91
95
  </style>
@@ -1,6 +1,7 @@
1
1
  import { computed, ref, unref } from "vue";
2
2
  import { LoadViewerOptions } from "@/models/LoadViewerOptions";
3
3
  import { LoadViewerPayload } from "@/models/LoadViewerPayload";
4
+ import { ViewerAsyncCallback, ViewerCallback } from "@/models/Callbacks";
4
5
 
5
6
  export function checkIsDemo(payload: LoadViewerPayload) {
6
7
  isDemo.value =
@@ -37,9 +38,7 @@ export const demoLicenceOptions: LoadViewerOptions = {
37
38
  OnShare: () => {
38
39
  m_demo.value = true;
39
40
  },
40
- OnScreenshot: () => {
41
- m_demo.value = true;
42
- },
41
+ OnScreenshot: undefined,
43
42
  };
44
43
 
45
44
  export const demoPatientOptions: LoadViewerOptions = {
@@ -68,9 +67,7 @@ export const demoPatientOptions: LoadViewerOptions = {
68
67
  OnShare: () => {
69
68
  m_demoPatient.value = true;
70
69
  },
71
- OnScreenshot: () => {
72
- m_demoPatient.value = true;
73
- },
70
+ OnScreenshot: undefined,
74
71
  };
75
72
 
76
73
  export const demoType = computed(() => {
@@ -91,3 +88,12 @@ export function executeDemoOption(key: keyof LoadViewerOptions) {
91
88
  }
92
89
  }
93
90
  }
91
+ export function getDemoOption(
92
+ key: keyof LoadViewerOptions
93
+ ): ViewerCallback | ViewerAsyncCallback | undefined {
94
+ if (unref(demoType) === "licence") {
95
+ return demoLicenceOptions[key];
96
+ } else if (unref(demoType) === "patient") {
97
+ return demoPatientOptions[key];
98
+ }
99
+ }