@geode/opengeodeweb-front 10.32.2-rc.2 → 10.32.2-rc.3
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/app/components/CameraManager.vue +41 -26
- package/app/components/CameraOrientation.vue +3 -1
- package/app/components/ClippingPlanes.vue +11 -1
- package/app/components/GlassCard.vue +9 -1
- package/app/components/Ruler.vue +5 -0
- package/app/components/Screenshot.vue +11 -2
- package/app/components/ShrinkFilter.vue +11 -1
- package/app/components/ToolPanel.vue +6 -1
- package/app/components/ViewToolbar.vue +23 -4
- package/app/components/Viewer/ContextMenu/ContextMenu.vue +6 -0
- package/app/components/Viewer/Options/ColormapQuickPicker.vue +1 -0
- package/app/components/Viewer/Ui.vue +14 -2
- package/app/components/ZScaling.vue +3 -1
- package/app/components/csv-preview/CsvPreviewer.vue +2 -1
- package/package.json +1 -1
- package/tests/unit/components/ToolPanel.nuxt.test.js +66 -0
|
@@ -1,49 +1,64 @@
|
|
|
1
1
|
<script setup>
|
|
2
|
-
import GlassCard from "@ogw_front/components/GlassCard";
|
|
3
2
|
import List from "@ogw_front/components/CameraManager/List";
|
|
4
3
|
import Saver from "@ogw_front/components/CameraManager/Saver";
|
|
4
|
+
import ToolPanel from "@ogw_front/components/ToolPanel";
|
|
5
5
|
|
|
6
6
|
const emit = defineEmits(["close"]);
|
|
7
7
|
|
|
8
|
-
const { showDialog, width } = defineProps({
|
|
8
|
+
const { showDialog, width, escapeFunction } = defineProps({
|
|
9
9
|
showDialog: { type: Boolean, required: true },
|
|
10
10
|
width: { type: Number, required: false, default: 260 },
|
|
11
|
+
escapeFunction: { type: Function, default: undefined },
|
|
11
12
|
});
|
|
13
|
+
|
|
14
|
+
const show = computed({
|
|
15
|
+
get: () => showDialog,
|
|
16
|
+
set: (val) => {
|
|
17
|
+
if (!val) {
|
|
18
|
+
handleClose();
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
function handleClose() {
|
|
24
|
+
if (escapeFunction) {
|
|
25
|
+
escapeFunction();
|
|
26
|
+
} else {
|
|
27
|
+
emit("close");
|
|
28
|
+
}
|
|
29
|
+
}
|
|
12
30
|
</script>
|
|
13
31
|
|
|
14
32
|
<template>
|
|
15
|
-
<
|
|
16
|
-
v-
|
|
17
|
-
@click.stop
|
|
33
|
+
<ToolPanel
|
|
34
|
+
v-model="show"
|
|
18
35
|
title="Camera Positions"
|
|
19
36
|
:width="width"
|
|
20
|
-
:
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
class="position-absolute elevation-24"
|
|
24
|
-
style="top: 90px; right: 55px; z-index: 1"
|
|
37
|
+
:escapeFunction="handleClose"
|
|
38
|
+
style="top: 90px; right: 55px"
|
|
39
|
+
z-index="1"
|
|
25
40
|
>
|
|
26
41
|
<v-card-text class="pa-0">
|
|
27
42
|
<Saver />
|
|
28
|
-
<v-divider
|
|
43
|
+
<v-divider />
|
|
29
44
|
<List />
|
|
30
45
|
</v-card-text>
|
|
31
46
|
|
|
32
|
-
<
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
>
|
|
45
|
-
</
|
|
46
|
-
</
|
|
47
|
+
<template #actions>
|
|
48
|
+
<v-card-actions class="justify-center pb-3 pt-0" style="gap: 8px">
|
|
49
|
+
<v-btn
|
|
50
|
+
variant="text"
|
|
51
|
+
size="small"
|
|
52
|
+
color="white"
|
|
53
|
+
class="text-caption text-none"
|
|
54
|
+
data-testid="closeCameraManagerButton"
|
|
55
|
+
@click="handleClose"
|
|
56
|
+
>
|
|
57
|
+
Close
|
|
58
|
+
</v-btn>
|
|
59
|
+
</v-card-actions>
|
|
60
|
+
</template>
|
|
61
|
+
</ToolPanel>
|
|
47
62
|
</template>
|
|
48
63
|
|
|
49
64
|
<style scoped>
|
|
@@ -5,9 +5,10 @@ import { useHybridViewerStore } from "@ogw_front/stores/hybrid_viewer";
|
|
|
5
5
|
import { newInstance as vtkAnnotatedCubeActor } from "@kitware/vtk.js/Rendering/Core/AnnotatedCubeActor";
|
|
6
6
|
import { newInstance as vtkGenericRenderWindow } from "@kitware/vtk.js/Rendering/Misc/GenericRenderWindow";
|
|
7
7
|
|
|
8
|
-
const { panel, width } = defineProps({
|
|
8
|
+
const { panel, width, escapeFunction } = defineProps({
|
|
9
9
|
panel: { type: Boolean, default: false },
|
|
10
10
|
width: { type: Number, default: 260 },
|
|
11
|
+
escapeFunction: { type: Function, default: undefined },
|
|
11
12
|
});
|
|
12
13
|
|
|
13
14
|
const show = defineModel("show", { type: Boolean, default: false });
|
|
@@ -172,6 +173,7 @@ watch(hoveredFace, (newFace, oldFace) => {
|
|
|
172
173
|
v-model="show"
|
|
173
174
|
title="Camera Orientations"
|
|
174
175
|
:width="width"
|
|
176
|
+
:escapeFunction="escapeFunction"
|
|
175
177
|
style="top: 90px; right: 55px"
|
|
176
178
|
z-index="1"
|
|
177
179
|
>
|
|
@@ -7,6 +7,10 @@ import { useDataStore } from "@ogw_front/stores/data";
|
|
|
7
7
|
import { useDebounceFn } from "@vueuse/core";
|
|
8
8
|
import { useHybridViewerStore } from "@ogw_front/stores/hybrid_viewer";
|
|
9
9
|
|
|
10
|
+
const { escapeFunction } = defineProps({
|
|
11
|
+
escapeFunction: { type: Function, default: undefined },
|
|
12
|
+
});
|
|
13
|
+
|
|
10
14
|
const show = defineModel("show", { type: Boolean, default: false });
|
|
11
15
|
const dataStore = useDataStore();
|
|
12
16
|
const hybridViewerStore = useHybridViewerStore();
|
|
@@ -145,7 +149,13 @@ onBeforeUnmount(cleanupLocalWidget);
|
|
|
145
149
|
</script>
|
|
146
150
|
|
|
147
151
|
<template>
|
|
148
|
-
<ToolPanel
|
|
152
|
+
<ToolPanel
|
|
153
|
+
v-model="show"
|
|
154
|
+
title="Clipping Planes"
|
|
155
|
+
:width="360"
|
|
156
|
+
:click-outside="false"
|
|
157
|
+
:escapeFunction="escapeFunction"
|
|
158
|
+
>
|
|
149
159
|
<v-card-text class="pa-3 max-panel-height overflow-y-auto">
|
|
150
160
|
<v-sheet
|
|
151
161
|
ref="widgetContainer"
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import { computed, useAttrs } from "vue";
|
|
3
|
+
import { onKeyStroke } from "@vueuse/core";
|
|
3
4
|
|
|
4
|
-
const { variant, rounded, padding, theme } = defineProps({
|
|
5
|
+
const { variant, rounded, padding, theme, escapeFunction } = defineProps({
|
|
5
6
|
variant: {
|
|
6
7
|
type: String,
|
|
7
8
|
default: "panel",
|
|
@@ -10,10 +11,17 @@ const { variant, rounded, padding, theme } = defineProps({
|
|
|
10
11
|
rounded: { type: String, default: "xl" },
|
|
11
12
|
padding: { type: String, default: "pa-6" },
|
|
12
13
|
theme: { type: String, default: undefined },
|
|
14
|
+
escapeFunction: { type: Function, default: undefined },
|
|
13
15
|
});
|
|
14
16
|
|
|
15
17
|
const attrs = useAttrs();
|
|
16
18
|
const isInteractive = computed(() => Boolean(attrs.onClick));
|
|
19
|
+
|
|
20
|
+
onKeyStroke("Escape", () => {
|
|
21
|
+
if (escapeFunction) {
|
|
22
|
+
escapeFunction();
|
|
23
|
+
}
|
|
24
|
+
});
|
|
17
25
|
</script>
|
|
18
26
|
|
|
19
27
|
<template>
|
package/app/components/Ruler.vue
CHANGED
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
import ToolPanel from "@ogw_front/components/ToolPanel";
|
|
3
3
|
import { useHybridViewerStore } from "@ogw_front/stores/hybrid_viewer";
|
|
4
4
|
|
|
5
|
+
const { escapeFunction } = defineProps({
|
|
6
|
+
escapeFunction: { type: Function, default: undefined },
|
|
7
|
+
});
|
|
8
|
+
|
|
5
9
|
const show = defineModel("show", { type: Boolean, default: false });
|
|
6
10
|
const hybridViewerStore = useHybridViewerStore();
|
|
7
11
|
|
|
@@ -57,6 +61,7 @@ async function applyManualCoords() {
|
|
|
57
61
|
:width="300"
|
|
58
62
|
close-label="Stop ruler"
|
|
59
63
|
:click-outside="false"
|
|
64
|
+
:escapeFunction="escapeFunction"
|
|
60
65
|
>
|
|
61
66
|
<v-card-text class="pa-3">
|
|
62
67
|
<v-switch
|
|
@@ -8,8 +8,9 @@ import viewer_schemas from "@geode/opengeodeweb-viewer/opengeodeweb_viewer_schem
|
|
|
8
8
|
|
|
9
9
|
const show = defineModel({ type: Boolean, default: false });
|
|
10
10
|
|
|
11
|
-
const { width } = defineProps({
|
|
11
|
+
const { width, escapeFunction } = defineProps({
|
|
12
12
|
width: { type: Number, default: 260 },
|
|
13
|
+
escapeFunction: { type: Function, default: undefined },
|
|
13
14
|
});
|
|
14
15
|
|
|
15
16
|
const output_extensions =
|
|
@@ -72,6 +73,13 @@ watch(screenshot_type, (value) => {
|
|
|
72
73
|
output_extension.value = "png";
|
|
73
74
|
}
|
|
74
75
|
});
|
|
76
|
+
|
|
77
|
+
function handleClose() {
|
|
78
|
+
if (escapeFunction) {
|
|
79
|
+
escapeFunction();
|
|
80
|
+
}
|
|
81
|
+
show.value = false;
|
|
82
|
+
}
|
|
75
83
|
</script>
|
|
76
84
|
|
|
77
85
|
<template>
|
|
@@ -81,6 +89,7 @@ watch(screenshot_type, (value) => {
|
|
|
81
89
|
:width="width"
|
|
82
90
|
close-label="Cancel"
|
|
83
91
|
action-label="Screenshot"
|
|
92
|
+
:escapeFunction="escapeFunction"
|
|
84
93
|
@action="takeScreenshot"
|
|
85
94
|
>
|
|
86
95
|
<v-container class="pa-3 py-1">
|
|
@@ -167,7 +176,7 @@ watch(screenshot_type, (value) => {
|
|
|
167
176
|
color="white"
|
|
168
177
|
data-testid="screenshotCancelButton"
|
|
169
178
|
class="text-caption text-none"
|
|
170
|
-
@click="
|
|
179
|
+
@click="handleClose"
|
|
171
180
|
>
|
|
172
181
|
Cancel
|
|
173
182
|
</v-btn>
|
|
@@ -8,6 +8,10 @@ const DEFAULT_SHRINK_VALUE = 0.8;
|
|
|
8
8
|
const MAX_SHRINK_VALUE = 1;
|
|
9
9
|
const DEBOUNCE_DELAY = 100;
|
|
10
10
|
|
|
11
|
+
const { escapeFunction } = defineProps({
|
|
12
|
+
escapeFunction: { type: Function, default: undefined },
|
|
13
|
+
});
|
|
14
|
+
|
|
11
15
|
const show = defineModel("show", { type: Boolean, default: false });
|
|
12
16
|
const dataStore = useDataStore();
|
|
13
17
|
const hybridViewerStore = useHybridViewerStore();
|
|
@@ -88,7 +92,13 @@ watch(
|
|
|
88
92
|
</script>
|
|
89
93
|
|
|
90
94
|
<template>
|
|
91
|
-
<ToolPanel
|
|
95
|
+
<ToolPanel
|
|
96
|
+
v-model="show"
|
|
97
|
+
title="Shrink Filter"
|
|
98
|
+
:width="340"
|
|
99
|
+
:click-outside="false"
|
|
100
|
+
:escapeFunction="escapeFunction"
|
|
101
|
+
>
|
|
92
102
|
<v-card-text class="pa-3 max-panel-height overflow-y-auto overflow-x-hidden">
|
|
93
103
|
<v-switch
|
|
94
104
|
v-model="targetAllVisible"
|
|
@@ -1,18 +1,22 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import GlassCard from "@ogw_front/components/GlassCard";
|
|
3
3
|
|
|
4
|
-
const { title, width, closeLabel, actionLabel, clickOutside } = defineProps({
|
|
4
|
+
const { title, width, closeLabel, actionLabel, clickOutside, escapeFunction } = defineProps({
|
|
5
5
|
title: { type: String, default: "" },
|
|
6
6
|
width: { type: Number, default: 260 },
|
|
7
7
|
closeLabel: { type: String, default: "Close" },
|
|
8
8
|
actionLabel: { type: String, default: undefined },
|
|
9
9
|
clickOutside: { type: Boolean, default: true },
|
|
10
|
+
escapeFunction: { type: Function, default: undefined },
|
|
10
11
|
});
|
|
11
12
|
|
|
12
13
|
const model = defineModel({ type: Boolean, default: false });
|
|
13
14
|
const emit = defineEmits(["action"]);
|
|
14
15
|
|
|
15
16
|
function close() {
|
|
17
|
+
if (escapeFunction) {
|
|
18
|
+
escapeFunction();
|
|
19
|
+
}
|
|
16
20
|
model.value = false;
|
|
17
21
|
}
|
|
18
22
|
</script>
|
|
@@ -27,6 +31,7 @@ function close() {
|
|
|
27
31
|
variant="panel"
|
|
28
32
|
padding="pa-0"
|
|
29
33
|
class="position-absolute rounded-xl elevation-24 tool-panel"
|
|
34
|
+
:escapeFunction="close"
|
|
30
35
|
v-bind="$attrs"
|
|
31
36
|
>
|
|
32
37
|
<v-card-text class="pa-0 overflow-hidden position-relative">
|
|
@@ -8,6 +8,7 @@ import Ruler from "@ogw_front/components/Ruler";
|
|
|
8
8
|
import Screenshot from "@ogw_front/components/Screenshot";
|
|
9
9
|
import ShrinkFilter from "@ogw_front/components/ShrinkFilter";
|
|
10
10
|
import ZScaling from "@ogw_front/components/ZScaling";
|
|
11
|
+
import { onKeyStroke } from "@vueuse/core";
|
|
11
12
|
import schemas from "@geode/opengeodeweb-viewer/opengeodeweb_viewer_schemas.json";
|
|
12
13
|
import { useHybridViewerStore } from "@ogw_front/stores/hybrid_viewer";
|
|
13
14
|
import { useViewerStore } from "@ogw_front/stores/viewer";
|
|
@@ -23,6 +24,7 @@ const showShrinkFilter = ref(false);
|
|
|
23
24
|
const showRuler = ref(false);
|
|
24
25
|
const grid_scale = ref(false);
|
|
25
26
|
const zScale = ref(hybridViewerStore.zScale);
|
|
27
|
+
const openSubMenus = ref({});
|
|
26
28
|
|
|
27
29
|
watch(
|
|
28
30
|
() => hybridViewerStore.zScale,
|
|
@@ -36,6 +38,15 @@ async function handleZScalingClose() {
|
|
|
36
38
|
showZScaling.value = false;
|
|
37
39
|
}
|
|
38
40
|
|
|
41
|
+
onKeyStroke("Escape", () => {
|
|
42
|
+
const openMenuKeys = Object.keys(openSubMenus.value).filter((key) => openSubMenus.value[key]);
|
|
43
|
+
if (openMenuKeys.length > 0) {
|
|
44
|
+
for (const key of openMenuKeys) {
|
|
45
|
+
openSubMenus.value[key] = false;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
|
|
39
50
|
const camera_options = computed(() => [
|
|
40
51
|
{
|
|
41
52
|
testId: "resetCameraButton",
|
|
@@ -193,6 +204,7 @@ const camera_options = computed(() => [
|
|
|
193
204
|
<v-col>
|
|
194
205
|
<v-menu
|
|
195
206
|
v-if="camera_option.menu && !camera_option.action"
|
|
207
|
+
v-model="openSubMenus[camera_option.testId]"
|
|
196
208
|
location="start"
|
|
197
209
|
:close-on-content-click="false"
|
|
198
210
|
>
|
|
@@ -248,17 +260,24 @@ const camera_options = computed(() => [
|
|
|
248
260
|
panel
|
|
249
261
|
@select="hybridViewerStore.setCameraOrientation"
|
|
250
262
|
/>
|
|
251
|
-
<Screenshot v-model="take_screenshot" />
|
|
263
|
+
<Screenshot v-model="take_screenshot" :escapeFunction="() => (take_screenshot = false)" />
|
|
252
264
|
<CameraManager :showDialog="show_camera_manager" @close="show_camera_manager = false" />
|
|
253
265
|
<ZScaling
|
|
254
266
|
v-model:show="showZScaling"
|
|
255
267
|
v-model="zScale"
|
|
256
268
|
:width="260"
|
|
269
|
+
:escapeFunction="handleZScalingClose"
|
|
257
270
|
@apply="handleZScalingClose"
|
|
258
271
|
/>
|
|
259
|
-
<ClippingPlanes
|
|
260
|
-
|
|
261
|
-
|
|
272
|
+
<ClippingPlanes
|
|
273
|
+
v-model:show="showClippingPlanes"
|
|
274
|
+
:escapeFunction="() => (showClippingPlanes = false)"
|
|
275
|
+
/>
|
|
276
|
+
<ShrinkFilter
|
|
277
|
+
v-model:show="showShrinkFilter"
|
|
278
|
+
:escapeFunction="() => (showShrinkFilter = false)"
|
|
279
|
+
/>
|
|
280
|
+
<Ruler v-model:show="showRuler" :escapeFunction="() => (showRuler = false)" />
|
|
262
281
|
</template>
|
|
263
282
|
|
|
264
283
|
<style module>
|
|
@@ -36,6 +36,12 @@ const dragStartY = ref(0);
|
|
|
36
36
|
const menuX = ref(x);
|
|
37
37
|
const menuY = ref(y);
|
|
38
38
|
|
|
39
|
+
watch(show_menu, (newVal) => {
|
|
40
|
+
if (!newVal) {
|
|
41
|
+
menuStore.closeMenu();
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
|
|
39
45
|
watch(
|
|
40
46
|
() => [x, y, containerWidth, containerHeight],
|
|
41
47
|
([newX, newY]) => {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import ColorMapList from "@ogw_front/components/Viewer/Options/ColorMapList.vue";
|
|
3
3
|
import { getPresetsWithCurrentAtTop } from "@ogw_front/utils/colormap";
|
|
4
|
+
|
|
4
5
|
import { useDataStyleStore } from "@ogw_front/stores/data_style";
|
|
5
6
|
import { useHybridViewerStore } from "@ogw_front/stores/hybrid_viewer";
|
|
6
7
|
|
|
@@ -24,11 +24,23 @@ function stopHoverHighlight() {
|
|
|
24
24
|
hybridViewerStore.clearHoverHighlight();
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
onKeyStroke("Escape", () => {
|
|
28
|
-
|
|
27
|
+
onKeyStroke("Escape", (event) => {
|
|
28
|
+
let consumed = false;
|
|
29
|
+
if (viewerStore.picking_mode) {
|
|
30
|
+
viewerStore.toggle_picking_mode(false);
|
|
31
|
+
consumed = true;
|
|
32
|
+
} else if (hybridViewerStore.is_picking) {
|
|
33
|
+
hybridViewerStore.is_picking = false;
|
|
34
|
+
consumed = true;
|
|
35
|
+
} else if (hybridViewerStore.is_ruler_active) {
|
|
29
36
|
hybridViewerStore.deactivateRuler();
|
|
37
|
+
consumed = true;
|
|
30
38
|
} else if (hybridViewerStore.is_hover_highlight) {
|
|
31
39
|
stopHoverHighlight();
|
|
40
|
+
consumed = true;
|
|
41
|
+
}
|
|
42
|
+
if (consumed && event) {
|
|
43
|
+
event.stopImmediatePropagation();
|
|
32
44
|
}
|
|
33
45
|
});
|
|
34
46
|
|
|
@@ -4,8 +4,9 @@ import ToolPanel from "@ogw_front/components/ToolPanel";
|
|
|
4
4
|
const zScale = defineModel({ type: Number, default: 1 });
|
|
5
5
|
const show = defineModel("show", { type: Boolean, default: false });
|
|
6
6
|
|
|
7
|
-
const { width } = defineProps({
|
|
7
|
+
const { width, escapeFunction } = defineProps({
|
|
8
8
|
width: { type: Number, default: 260 },
|
|
9
|
+
escapeFunction: { type: Function, default: undefined },
|
|
9
10
|
});
|
|
10
11
|
|
|
11
12
|
const emit = defineEmits(["apply"]);
|
|
@@ -22,6 +23,7 @@ function apply() {
|
|
|
22
23
|
title="Z Scaling Control"
|
|
23
24
|
:width="width"
|
|
24
25
|
action-label="Apply"
|
|
26
|
+
:escapeFunction="escapeFunction"
|
|
25
27
|
@action="apply"
|
|
26
28
|
>
|
|
27
29
|
<v-container class="pa-3 py-1">
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
<script setup>
|
|
2
|
+
import { useToggle } from "@vueuse/core";
|
|
3
|
+
|
|
2
4
|
import CsvSettings from "./CsvSettings.vue";
|
|
3
5
|
import CsvTable from "./CsvTable.vue";
|
|
4
|
-
import { useToggle } from "@vueuse/core";
|
|
5
6
|
|
|
6
7
|
const { file, modelValue } = defineProps({
|
|
7
8
|
file: { type: Object, required: true },
|
package/package.json
CHANGED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
// Third party imports
|
|
2
|
+
import { describe, expect, test, vi } from "vitest";
|
|
3
|
+
import { mountSuspended } from "@nuxt/test-utils/runtime";
|
|
4
|
+
|
|
5
|
+
// Local imports
|
|
6
|
+
import ToolPanel from "@ogw_front/components/ToolPanel";
|
|
7
|
+
import { vuetify } from "@ogw_tests/utils";
|
|
8
|
+
|
|
9
|
+
const FIRST_INDEX = 0;
|
|
10
|
+
|
|
11
|
+
describe("tool panel", () => {
|
|
12
|
+
test("renders title and slot content when open", async () => {
|
|
13
|
+
const wrapper = await mountSuspended(ToolPanel, {
|
|
14
|
+
global: {
|
|
15
|
+
plugins: [vuetify],
|
|
16
|
+
},
|
|
17
|
+
props: {
|
|
18
|
+
modelValue: true,
|
|
19
|
+
title: "Test Panel",
|
|
20
|
+
},
|
|
21
|
+
slots: {
|
|
22
|
+
default: () => "Panel Content",
|
|
23
|
+
},
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
expect(wrapper.text()).toContain("Test Panel");
|
|
27
|
+
expect(wrapper.text()).toContain("Panel Content");
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
test("triggers escape key binding to close panel", async () => {
|
|
31
|
+
const wrapper = await mountSuspended(ToolPanel, {
|
|
32
|
+
global: {
|
|
33
|
+
plugins: [vuetify],
|
|
34
|
+
},
|
|
35
|
+
props: {
|
|
36
|
+
modelValue: true,
|
|
37
|
+
title: "Test Panel",
|
|
38
|
+
},
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
globalThis.dispatchEvent(new KeyboardEvent("keydown", { key: "Escape" }));
|
|
42
|
+
await wrapper.vm.$nextTick();
|
|
43
|
+
|
|
44
|
+
expect(wrapper.emitted()).toHaveProperty("update:modelValue");
|
|
45
|
+
expect(wrapper.emitted("update:modelValue")[FIRST_INDEX]).toStrictEqual([false]);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
test("calls escapeFunction prop when Escape key is pressed", async () => {
|
|
49
|
+
const escapeFunction = vi.fn();
|
|
50
|
+
const wrapper = await mountSuspended(ToolPanel, {
|
|
51
|
+
global: {
|
|
52
|
+
plugins: [vuetify],
|
|
53
|
+
},
|
|
54
|
+
props: {
|
|
55
|
+
escapeFunction,
|
|
56
|
+
modelValue: true,
|
|
57
|
+
title: "Test Panel",
|
|
58
|
+
},
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
globalThis.dispatchEvent(new KeyboardEvent("keydown", { key: "Escape" }));
|
|
62
|
+
await wrapper.vm.$nextTick();
|
|
63
|
+
|
|
64
|
+
expect(escapeFunction).toHaveBeenCalledWith();
|
|
65
|
+
});
|
|
66
|
+
});
|