@geode/opengeodeweb-front 10.2.0 → 10.2.1-rc.2
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/DragAndDrop.vue +120 -0
- package/app/components/FileSelector.vue +11 -14
- package/app/components/FileUploader.vue +69 -48
- package/app/components/Launcher.vue +1 -1
- package/app/components/OptionCard.vue +55 -0
- package/app/components/Recaptcha.vue +6 -1
- package/app/components/Screenshot.vue +46 -70
- package/app/components/Step.vue +60 -59
- package/app/components/Stepper.vue +24 -14
- package/app/components/Viewer/ContextMenuItem.vue +41 -62
- package/app/components/ZScaling.vue +46 -73
- package/app/plugins/auto_store_register.js +14 -10
- package/app/stores/data.js +1 -1
- package/internal/database/tables/model_components.js +1 -1
- package/internal/stores/model/blocks.js +6 -0
- package/internal/stores/model/corners.js +6 -0
- package/internal/stores/model/lines.js +6 -0
- package/internal/stores/model/surfaces.js +6 -0
- package/package.json +3 -3
- package/tests/integration/microservices/back/requirements.txt +1 -1
- package/tests/integration/microservices/viewer/requirements.txt +1 -1
- package/tests/unit/components/FileSelector.nuxt.test.js +5 -3
- package/tests/unit/components/FileUploader.nuxt.test.js +5 -4
- package/tests/unit/components/MissingFilesSelector.nuxt.test.js +5 -3
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<v-hover v-slot="{ isHovering, props: hoverProps }">
|
|
3
|
+
<v-card
|
|
4
|
+
v-bind="hoverProps"
|
|
5
|
+
class="text-center cursor-pointer"
|
|
6
|
+
:class="{
|
|
7
|
+
'elevation-4': isHovering || isDragging,
|
|
8
|
+
'elevation-0': !(isHovering || isDragging),
|
|
9
|
+
}"
|
|
10
|
+
:style="{
|
|
11
|
+
position: 'relative',
|
|
12
|
+
overflow: 'hidden',
|
|
13
|
+
transition: 'all 0.3s ease',
|
|
14
|
+
background:
|
|
15
|
+
isHovering || isDragging
|
|
16
|
+
? 'rgba(var(--v-theme-primary), 0.05)'
|
|
17
|
+
: 'rgba(0, 0, 0, 0.02)',
|
|
18
|
+
border: `2px dashed ${
|
|
19
|
+
isHovering || isDragging ? 'rgb(var(--v-theme-primary))' : '#e0e0e0'
|
|
20
|
+
}`,
|
|
21
|
+
transform: isHovering || isDragging ? 'translateY(-2px)' : 'none',
|
|
22
|
+
pointerEvents: loading ? 'none' : 'auto',
|
|
23
|
+
opacity: loading ? 0.6 : 1,
|
|
24
|
+
}"
|
|
25
|
+
rounded="xl"
|
|
26
|
+
@click="triggerFileDialog"
|
|
27
|
+
@dragover.prevent="isDragging = true"
|
|
28
|
+
@dragleave.prevent="isDragging = false"
|
|
29
|
+
@drop.prevent="handleDrop"
|
|
30
|
+
>
|
|
31
|
+
<v-card-text class="pa-8">
|
|
32
|
+
<v-sheet
|
|
33
|
+
class="mx-auto mb-6 d-flex align-center justify-center"
|
|
34
|
+
:color="isHovering || isDragging ? 'primary' : 'grey-lighten-2'"
|
|
35
|
+
:elevation="isHovering || isDragging ? 4 : 0"
|
|
36
|
+
rounded="circle"
|
|
37
|
+
width="80"
|
|
38
|
+
height="80"
|
|
39
|
+
style="transition: all 0.3s ease"
|
|
40
|
+
>
|
|
41
|
+
<v-icon
|
|
42
|
+
:icon="loading ? 'mdi-loading' : 'mdi-cloud-upload'"
|
|
43
|
+
size="40"
|
|
44
|
+
:color="isHovering || isDragging ? 'white' : 'grey-darken-1'"
|
|
45
|
+
:class="{ rotating: loading }"
|
|
46
|
+
/>
|
|
47
|
+
</v-sheet>
|
|
48
|
+
|
|
49
|
+
<v-card-title
|
|
50
|
+
class="text-h6 font-weight-bold justify-center pa-0 mb-1"
|
|
51
|
+
:class="
|
|
52
|
+
isHovering || isDragging ? 'text-primary' : 'text-grey-darken-2'
|
|
53
|
+
"
|
|
54
|
+
style="transition: color 0.3s ease"
|
|
55
|
+
>
|
|
56
|
+
{{ loading ? loadingText : isDragging ? dropText : idleText }}
|
|
57
|
+
</v-card-title>
|
|
58
|
+
|
|
59
|
+
<v-card-subtitle v-if="showExtensions" class="text-body-2 pa-0">
|
|
60
|
+
{{ accept ? `(${accept} files)` : "All files allowed" }}
|
|
61
|
+
</v-card-subtitle>
|
|
62
|
+
</v-card-text>
|
|
63
|
+
|
|
64
|
+
<input
|
|
65
|
+
ref="fileInput"
|
|
66
|
+
type="file"
|
|
67
|
+
class="d-none"
|
|
68
|
+
:multiple="multiple"
|
|
69
|
+
:accept="accept"
|
|
70
|
+
@change="handleFileSelect"
|
|
71
|
+
/>
|
|
72
|
+
</v-card>
|
|
73
|
+
</v-hover>
|
|
74
|
+
</template>
|
|
75
|
+
|
|
76
|
+
<script setup>
|
|
77
|
+
const props = defineProps({
|
|
78
|
+
multiple: { type: Boolean, default: false },
|
|
79
|
+
accept: { type: String, default: "" },
|
|
80
|
+
loading: { type: Boolean, default: false },
|
|
81
|
+
showExtensions: { type: Boolean, default: true },
|
|
82
|
+
idleText: { type: String, default: "Click or Drag & Drop files" },
|
|
83
|
+
dropText: { type: String, default: "Drop to upload" },
|
|
84
|
+
loadingText: { type: String, default: "Uploading..." },
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
const emit = defineEmits(["files-selected"])
|
|
88
|
+
|
|
89
|
+
const isDragging = ref(false)
|
|
90
|
+
const fileInput = ref(null)
|
|
91
|
+
|
|
92
|
+
const triggerFileDialog = () => fileInput.value?.click()
|
|
93
|
+
|
|
94
|
+
function handleDrop(e) {
|
|
95
|
+
isDragging.value = false
|
|
96
|
+
const files = Array.from(e.dataTransfer.files)
|
|
97
|
+
emit("files-selected", files)
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function handleFileSelect(e) {
|
|
101
|
+
const files = Array.from(e.target.files)
|
|
102
|
+
emit("files-selected", files)
|
|
103
|
+
e.target.value = ""
|
|
104
|
+
}
|
|
105
|
+
</script>
|
|
106
|
+
|
|
107
|
+
<style scoped>
|
|
108
|
+
.rotating {
|
|
109
|
+
animation: rotate 1s linear infinite;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
@keyframes rotate {
|
|
113
|
+
from {
|
|
114
|
+
transform: rotate(0deg);
|
|
115
|
+
}
|
|
116
|
+
to {
|
|
117
|
+
transform: rotate(360deg);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
</style>
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
import { useGeodeStore } from "@ogw_front/stores/geode"
|
|
16
16
|
|
|
17
17
|
const schema = schemas.opengeodeweb_back.allowed_files
|
|
18
|
+
|
|
18
19
|
const emit = defineEmits([
|
|
19
20
|
"update_values",
|
|
20
21
|
"increment_step",
|
|
@@ -23,12 +24,10 @@
|
|
|
23
24
|
|
|
24
25
|
const props = defineProps({
|
|
25
26
|
multiple: { type: Boolean, required: true },
|
|
26
|
-
files: { type: Array,
|
|
27
|
-
auto_upload: { type: Boolean,
|
|
27
|
+
files: { type: Array, default: () => [] },
|
|
28
|
+
auto_upload: { type: Boolean, default: true },
|
|
28
29
|
})
|
|
29
30
|
|
|
30
|
-
const { multiple } = props
|
|
31
|
-
|
|
32
31
|
const internal_files = ref(props.files)
|
|
33
32
|
const auto_upload = ref(props.auto_upload)
|
|
34
33
|
const accept = ref("")
|
|
@@ -36,14 +35,13 @@
|
|
|
36
35
|
|
|
37
36
|
watch(
|
|
38
37
|
() => props.files,
|
|
39
|
-
(
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
38
|
+
(val) => (internal_files.value = val),
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
watch(
|
|
42
|
+
() => props.auto_upload,
|
|
43
|
+
(val) => (auto_upload.value = val),
|
|
43
44
|
)
|
|
44
|
-
watch(props.auto_upload, (newVal) => {
|
|
45
|
-
auto_upload.value = newVal
|
|
46
|
-
})
|
|
47
45
|
|
|
48
46
|
const toggle_loading = useToggle(loading)
|
|
49
47
|
|
|
@@ -58,10 +56,9 @@
|
|
|
58
56
|
toggle_loading()
|
|
59
57
|
const geodeStore = useGeodeStore()
|
|
60
58
|
const response = await geodeStore.request(schema, {})
|
|
61
|
-
accept.value = response.extensions
|
|
62
|
-
.map((extension) => "." + extension)
|
|
63
|
-
.join(",")
|
|
59
|
+
accept.value = response.extensions.map((e) => `.${e}`).join(",")
|
|
64
60
|
toggle_loading()
|
|
65
61
|
}
|
|
62
|
+
|
|
66
63
|
await get_allowed_files()
|
|
67
64
|
</script>
|
|
@@ -1,43 +1,65 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
2
|
+
<DragAndDrop
|
|
3
|
+
:multiple="props.multiple"
|
|
4
|
+
:accept="props.accept"
|
|
5
|
+
:loading="loading"
|
|
6
|
+
:show-extensions="false"
|
|
7
|
+
@files-selected="processSelectedFiles"
|
|
8
|
+
/>
|
|
9
|
+
|
|
10
|
+
<v-card-text v-if="internal_files.length" class="mt-4">
|
|
11
|
+
<v-sheet class="d-flex align-center mb-3" color="transparent">
|
|
12
|
+
<v-icon icon="mdi-file-check" class="mr-2" color="primary" />
|
|
13
|
+
<span class="text-subtitle-2 font-weight-bold"> Selected Files </span>
|
|
14
|
+
<v-chip size="x-small" class="ml-2" color="primary" variant="flat">
|
|
15
|
+
{{ internal_files.length }}
|
|
16
|
+
</v-chip>
|
|
17
|
+
</v-sheet>
|
|
18
|
+
|
|
19
|
+
<v-sheet class="d-flex flex-wrap gap-2" color="transparent">
|
|
20
|
+
<v-chip
|
|
21
|
+
v-for="(file, index) in internal_files"
|
|
22
|
+
:key="index"
|
|
23
|
+
closable
|
|
24
|
+
size="small"
|
|
23
25
|
color="primary"
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
variant="tonal"
|
|
27
|
+
class="font-weight-medium"
|
|
28
|
+
@click:close="removeFile(index)"
|
|
29
|
+
>
|
|
30
|
+
<v-icon start size="16">mdi-file-outline</v-icon>
|
|
31
|
+
{{ file.name }}
|
|
32
|
+
</v-chip>
|
|
33
|
+
</v-sheet>
|
|
34
|
+
</v-card-text>
|
|
35
|
+
|
|
36
|
+
<v-card-actions v-if="!props.auto_upload && internal_files.length">
|
|
37
|
+
<v-btn
|
|
38
|
+
color="primary"
|
|
39
|
+
variant="elevated"
|
|
40
|
+
size="large"
|
|
41
|
+
rounded="lg"
|
|
42
|
+
:loading="loading"
|
|
43
|
+
class="text-none px-3 font-weight-bold"
|
|
44
|
+
@click="upload_files"
|
|
45
|
+
>
|
|
46
|
+
<v-icon start size="20">mdi-cloud-upload-outline</v-icon>
|
|
47
|
+
Upload {{ internal_files.length }} file<span
|
|
48
|
+
v-if="internal_files.length > 1"
|
|
49
|
+
>s</span
|
|
28
50
|
>
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
</v-col>
|
|
32
|
-
</v-row>
|
|
51
|
+
</v-btn>
|
|
52
|
+
</v-card-actions>
|
|
33
53
|
</template>
|
|
34
54
|
|
|
35
55
|
<script setup>
|
|
36
56
|
import schemas from "@geode/opengeodeweb-back/opengeodeweb_back_schemas.json"
|
|
37
57
|
import { upload_file } from "@ogw_front/utils/upload_file"
|
|
58
|
+
import DragAndDrop from "@ogw_front/components/DragAndDrop"
|
|
59
|
+
|
|
38
60
|
const schema = schemas.opengeodeweb_back.upload_file
|
|
39
61
|
|
|
40
|
-
const emit = defineEmits(["files_uploaded", "decrement_step"])
|
|
62
|
+
const emit = defineEmits(["files_uploaded", "decrement_step", "reset_values"])
|
|
41
63
|
|
|
42
64
|
const props = defineProps({
|
|
43
65
|
multiple: { type: Boolean, required: true },
|
|
@@ -47,15 +69,28 @@
|
|
|
47
69
|
mini: { type: Boolean, required: false, default: false },
|
|
48
70
|
})
|
|
49
71
|
|
|
50
|
-
const label = props.multiple
|
|
51
|
-
? "Please select file(s) to import"
|
|
52
|
-
: "Please select a file to import"
|
|
53
72
|
const internal_files = ref(props.files)
|
|
54
73
|
const loading = ref(false)
|
|
55
74
|
const files_uploaded = ref(false)
|
|
56
75
|
|
|
57
76
|
const toggle_loading = useToggle(loading)
|
|
58
77
|
|
|
78
|
+
function processSelectedFiles(files) {
|
|
79
|
+
if (props.multiple) {
|
|
80
|
+
internal_files.value = [...internal_files.value, ...files]
|
|
81
|
+
} else {
|
|
82
|
+
internal_files.value = [files[0]]
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function removeFile(index) {
|
|
87
|
+
internal_files.value.splice(index, 1)
|
|
88
|
+
if (internal_files.value.length === 0) {
|
|
89
|
+
files_uploaded.value = false
|
|
90
|
+
emit("files_uploaded", [])
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
59
94
|
async function upload_files() {
|
|
60
95
|
toggle_loading()
|
|
61
96
|
var promise_array = []
|
|
@@ -92,11 +127,6 @@
|
|
|
92
127
|
}
|
|
93
128
|
}
|
|
94
129
|
|
|
95
|
-
function clear() {
|
|
96
|
-
internal_files.value = []
|
|
97
|
-
emit("files_uploaded", internal_files.value)
|
|
98
|
-
}
|
|
99
|
-
|
|
100
130
|
watch(
|
|
101
131
|
() => props.files,
|
|
102
132
|
(newVal) => {
|
|
@@ -107,17 +137,8 @@
|
|
|
107
137
|
|
|
108
138
|
watch(internal_files, (value) => {
|
|
109
139
|
files_uploaded.value = false
|
|
110
|
-
if (props.auto_upload) {
|
|
111
|
-
if (props.multiple.value == false) {
|
|
112
|
-
internal_files.value = [value]
|
|
113
|
-
}
|
|
140
|
+
if (props.auto_upload && value.length > 0) {
|
|
114
141
|
upload_files()
|
|
115
142
|
}
|
|
116
143
|
})
|
|
117
144
|
</script>
|
|
118
|
-
|
|
119
|
-
<style scoped>
|
|
120
|
-
.div.v-input__details {
|
|
121
|
-
display: none;
|
|
122
|
-
}
|
|
123
|
-
</style>
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { useTheme } from "vuetify"
|
|
3
|
+
|
|
4
|
+
const theme = useTheme()
|
|
5
|
+
const primaryColor = computed(() => theme.current.value.colors.primary)
|
|
6
|
+
|
|
7
|
+
defineProps({
|
|
8
|
+
title: { type: String, default: "" },
|
|
9
|
+
width: { type: [Number, String], default: 320 },
|
|
10
|
+
maxHeight: { type: [Number, String], default: 500 },
|
|
11
|
+
})
|
|
12
|
+
</script>
|
|
13
|
+
<template>
|
|
14
|
+
<v-card
|
|
15
|
+
@click.stop
|
|
16
|
+
:title="title"
|
|
17
|
+
class="option-card rounded-xl border-thin elevation-24"
|
|
18
|
+
:width="width"
|
|
19
|
+
:max-height="maxHeight"
|
|
20
|
+
:ripple="false"
|
|
21
|
+
theme="dark"
|
|
22
|
+
>
|
|
23
|
+
<v-card-text class="pa-5">
|
|
24
|
+
<slot />
|
|
25
|
+
</v-card-text>
|
|
26
|
+
<v-card-actions v-if="$slots.actions" class="justify-center pb-4">
|
|
27
|
+
<slot name="actions" />
|
|
28
|
+
</v-card-actions>
|
|
29
|
+
</v-card>
|
|
30
|
+
</template>
|
|
31
|
+
|
|
32
|
+
<style scoped>
|
|
33
|
+
.option-card {
|
|
34
|
+
background-color: rgba(30, 30, 30, 0.85) !important;
|
|
35
|
+
backdrop-filter: blur(20px);
|
|
36
|
+
-webkit-backdrop-filter: blur(20px);
|
|
37
|
+
border-color: rgba(255, 255, 255, 0.15) !important;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
::v-deep(.v-list-item:hover) {
|
|
41
|
+
background-color: rgba(255, 255, 255, 0.1);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
::v-deep(.v-slider-track__fill),
|
|
45
|
+
::v-deep(.v-selection-control--dirty .v-switch__track) {
|
|
46
|
+
background-color: v-bind(primaryColor) !important;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
::v-deep(.v-btn) {
|
|
50
|
+
border-radius: 8px;
|
|
51
|
+
text-transform: none;
|
|
52
|
+
font-weight: 500;
|
|
53
|
+
letter-spacing: normal;
|
|
54
|
+
}
|
|
55
|
+
</style>
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
<VCol cols="4" class="d-flex justify-center align-center">
|
|
32
32
|
<VBtn
|
|
33
33
|
:text="props.button_label"
|
|
34
|
-
:color="props.button_color"
|
|
34
|
+
:color="props.color || props.button_color"
|
|
35
35
|
@click="submit_recaptcha"
|
|
36
36
|
/>
|
|
37
37
|
</VCol>
|
|
@@ -53,11 +53,16 @@
|
|
|
53
53
|
required: false,
|
|
54
54
|
default: "white",
|
|
55
55
|
},
|
|
56
|
+
color: {
|
|
57
|
+
type: String,
|
|
58
|
+
required: false,
|
|
59
|
+
},
|
|
56
60
|
})
|
|
57
61
|
const infraStore = useInfraStore()
|
|
58
62
|
const name = ref("")
|
|
59
63
|
const email = ref("")
|
|
60
64
|
const launch = ref(false)
|
|
65
|
+
const valid = ref(false)
|
|
61
66
|
const emailRules = [
|
|
62
67
|
(value) => {
|
|
63
68
|
if (value) {
|
|
@@ -1,65 +1,3 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<v-sheet
|
|
3
|
-
v-if="props.show_dialog"
|
|
4
|
-
:width="props.width + 'px'"
|
|
5
|
-
class="screenshot_menu"
|
|
6
|
-
border="md"
|
|
7
|
-
>
|
|
8
|
-
<v-card class="bg-primary pa-0">
|
|
9
|
-
<v-card-title>
|
|
10
|
-
<h3 class="mt-4">Take a screenshot</h3>
|
|
11
|
-
</v-card-title>
|
|
12
|
-
<v-card-text class="pa-0">
|
|
13
|
-
<v-container>
|
|
14
|
-
<v-row>
|
|
15
|
-
<v-col cols="8" class="py-0">
|
|
16
|
-
<v-text-field v-model="filename" label="File name"></v-text-field>
|
|
17
|
-
</v-col>
|
|
18
|
-
<v-col cols="4" class="py-0">
|
|
19
|
-
<v-select
|
|
20
|
-
v-model="output_extension"
|
|
21
|
-
:items="output_extensions"
|
|
22
|
-
label="Extension"
|
|
23
|
-
required
|
|
24
|
-
/>
|
|
25
|
-
</v-col>
|
|
26
|
-
</v-row>
|
|
27
|
-
|
|
28
|
-
<v-row>
|
|
29
|
-
<v-col cols="12" class="py-0">
|
|
30
|
-
<v-switch
|
|
31
|
-
v-model="include_background"
|
|
32
|
-
:disabled="output_extension !== 'png'"
|
|
33
|
-
label="Include background"
|
|
34
|
-
inset
|
|
35
|
-
></v-switch>
|
|
36
|
-
</v-col>
|
|
37
|
-
</v-row>
|
|
38
|
-
</v-container>
|
|
39
|
-
</v-card-text>
|
|
40
|
-
<v-card-actions justify-center>
|
|
41
|
-
<v-btn
|
|
42
|
-
variant="outlined"
|
|
43
|
-
color="white"
|
|
44
|
-
text
|
|
45
|
-
@click="emit('close')"
|
|
46
|
-
class="ml-8 mb-4"
|
|
47
|
-
>Close</v-btn
|
|
48
|
-
>
|
|
49
|
-
<v-btn
|
|
50
|
-
variant="outlined"
|
|
51
|
-
class="mb-4"
|
|
52
|
-
:disabled="!filename || !output_extension"
|
|
53
|
-
color="white"
|
|
54
|
-
text
|
|
55
|
-
@click="takeScreenshot()"
|
|
56
|
-
>Screenshot</v-btn
|
|
57
|
-
>
|
|
58
|
-
</v-card-actions>
|
|
59
|
-
</v-card>
|
|
60
|
-
</v-sheet>
|
|
61
|
-
</template>
|
|
62
|
-
|
|
63
1
|
<script setup>
|
|
64
2
|
import fileDownload from "js-file-download"
|
|
65
3
|
import viewer_schemas from "@geode/opengeodeweb-viewer/opengeodeweb_viewer_schemas.json"
|
|
@@ -107,12 +45,50 @@
|
|
|
107
45
|
}
|
|
108
46
|
})
|
|
109
47
|
</script>
|
|
48
|
+
<template>
|
|
49
|
+
<OptionCard
|
|
50
|
+
v-if="props.show_dialog"
|
|
51
|
+
title="Take a screenshot"
|
|
52
|
+
:width="props.width"
|
|
53
|
+
class="position-absolute"
|
|
54
|
+
style="z-index: 2; top: 90px; right: 55px"
|
|
55
|
+
>
|
|
56
|
+
<v-container>
|
|
57
|
+
<v-row>
|
|
58
|
+
<v-col cols="8" class="py-0">
|
|
59
|
+
<v-text-field v-model="filename" label="File name"></v-text-field>
|
|
60
|
+
</v-col>
|
|
61
|
+
<v-col cols="4" class="py-0">
|
|
62
|
+
<v-select
|
|
63
|
+
v-model="output_extension"
|
|
64
|
+
:items="output_extensions"
|
|
65
|
+
label="Extension"
|
|
66
|
+
required
|
|
67
|
+
/>
|
|
68
|
+
</v-col>
|
|
69
|
+
</v-row>
|
|
110
70
|
|
|
111
|
-
<
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
71
|
+
<v-row>
|
|
72
|
+
<v-col cols="12" class="py-0">
|
|
73
|
+
<v-switch
|
|
74
|
+
v-model="include_background"
|
|
75
|
+
:disabled="output_extension !== 'png'"
|
|
76
|
+
label="Include background"
|
|
77
|
+
inset
|
|
78
|
+
></v-switch>
|
|
79
|
+
</v-col>
|
|
80
|
+
</v-row>
|
|
81
|
+
</v-container>
|
|
82
|
+
|
|
83
|
+
<template #actions>
|
|
84
|
+
<v-btn variant="text" color="white" @click="emit('close')">Close</v-btn>
|
|
85
|
+
<v-btn
|
|
86
|
+
variant="outlined"
|
|
87
|
+
:disabled="!filename || !output_extension"
|
|
88
|
+
color="white"
|
|
89
|
+
@click="takeScreenshot()"
|
|
90
|
+
>Screenshot</v-btn
|
|
91
|
+
>
|
|
92
|
+
</template>
|
|
93
|
+
</OptionCard>
|
|
94
|
+
</template>
|
package/app/components/Step.vue
CHANGED
|
@@ -1,62 +1,61 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<v-stepper-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
color="grey"
|
|
13
|
-
/>
|
|
14
|
-
<v-icon
|
|
15
|
-
v-else-if="current_step_index == step_index"
|
|
16
|
-
:icon="`mdi-numeric-${step_index + 1}-circle`"
|
|
17
|
-
color="primary"
|
|
18
|
-
/>
|
|
19
|
-
<v-icon
|
|
20
|
-
v-else
|
|
21
|
-
:icon="`mdi-numeric-${step_index + 1}-circle`"
|
|
22
|
-
color="grey"
|
|
23
|
-
/>
|
|
24
|
-
</v-col>
|
|
25
|
-
<v-col>
|
|
26
|
-
<p class="m-0 font-weight-bold">
|
|
27
|
-
{{ steps[step_index].step_title }}
|
|
28
|
-
</p>
|
|
29
|
-
</v-col>
|
|
30
|
-
<v-chip-group
|
|
31
|
-
v-if="
|
|
32
|
-
steps[step_index].chips.length && current_step_index >= step_index
|
|
33
|
-
"
|
|
34
|
-
column
|
|
35
|
-
class="d-flex flex-wrap ma-2 overflow-y-auto"
|
|
36
|
-
multiple
|
|
37
|
-
style="max-height: 150px"
|
|
2
|
+
<v-stepper-vertical-item
|
|
3
|
+
:value="step_index + 1"
|
|
4
|
+
:editable="step_index < current_step_index"
|
|
5
|
+
color="primary"
|
|
6
|
+
hide-actions
|
|
7
|
+
>
|
|
8
|
+
<template #title>
|
|
9
|
+
<v-sheet
|
|
10
|
+
color="transparent"
|
|
11
|
+
class="d-flex flex-column justify-center ps-2"
|
|
38
12
|
>
|
|
39
|
-
<v-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
class="
|
|
43
|
-
|
|
13
|
+
<v-text
|
|
14
|
+
tag="h3"
|
|
15
|
+
class="text-subtitle-1 font-weight-bold mb-0 transition-swing"
|
|
16
|
+
:class="
|
|
17
|
+
current_step_index === step_index
|
|
18
|
+
? 'text-primary'
|
|
19
|
+
: 'text-grey-darken-1'
|
|
20
|
+
"
|
|
44
21
|
>
|
|
45
|
-
{{
|
|
46
|
-
</v-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
22
|
+
{{ steps[step_index].step_title }}
|
|
23
|
+
</v-text>
|
|
24
|
+
|
|
25
|
+
<v-sheet
|
|
26
|
+
v-if="sortedChips.length && current_step_index >= step_index"
|
|
27
|
+
color="transparent"
|
|
28
|
+
class="d-flex flex-wrap mt-2"
|
|
29
|
+
>
|
|
30
|
+
<v-chip
|
|
31
|
+
v-for="(chip, chip_index) in sortedChips"
|
|
32
|
+
:key="chip_index"
|
|
33
|
+
size="small"
|
|
34
|
+
class="me-2 mb-1 font-weight-medium"
|
|
35
|
+
color="primary"
|
|
36
|
+
variant="tonal"
|
|
37
|
+
>
|
|
38
|
+
{{ truncate(chip, 30) }}
|
|
39
|
+
</v-chip>
|
|
40
|
+
</v-sheet>
|
|
41
|
+
</v-sheet>
|
|
42
|
+
</template>
|
|
43
|
+
|
|
44
|
+
<v-card-text class="pt-0">
|
|
45
|
+
<v-divider class="mb-6 opacity-10" />
|
|
46
|
+
|
|
47
|
+
<component
|
|
48
|
+
v-if="step_index === current_step_index"
|
|
49
|
+
:key="step_index"
|
|
50
|
+
:is="steps[step_index].component.component_name"
|
|
51
|
+
v-bind="steps[step_index].component.component_options"
|
|
52
|
+
@increment_step="increment_step"
|
|
53
|
+
@decrement_step="decrement_step"
|
|
54
|
+
@update_values="update_values_event"
|
|
55
|
+
@reset_values="$emit('reset_values')"
|
|
56
|
+
/>
|
|
57
|
+
</v-card-text>
|
|
58
|
+
</v-stepper-vertical-item>
|
|
60
59
|
</template>
|
|
61
60
|
|
|
62
61
|
<script setup>
|
|
@@ -74,9 +73,11 @@
|
|
|
74
73
|
const stepper_tree = inject("stepper_tree")
|
|
75
74
|
const { current_step_index, steps } = toRefs(stepper_tree)
|
|
76
75
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
76
|
+
watch(current_step_index, (newVal, oldVal) => {
|
|
77
|
+
if (newVal < oldVal) {
|
|
78
|
+
stepper_tree.navigating_back = true
|
|
79
|
+
}
|
|
80
|
+
})
|
|
80
81
|
|
|
81
82
|
function update_values_event(keys_values_object) {
|
|
82
83
|
for (const [key, value] of Object.entries(keys_values_object)) {
|
|
@@ -1,20 +1,30 @@
|
|
|
1
1
|
<template>
|
|
2
|
+
<v-card-item class="flex-shrink-0 pa-0">
|
|
3
|
+
<v-card-title
|
|
4
|
+
class="text-h4 text-primary px-8 pt-6 pb-4 font-weight-bold d-flex align-center"
|
|
5
|
+
>
|
|
6
|
+
<v-icon icon="mdi-file-upload-outline" class="mr-3" />
|
|
7
|
+
Import Data
|
|
8
|
+
</v-card-title>
|
|
9
|
+
|
|
10
|
+
<v-card-subtitle class="px-8 pb-4 text-medium">
|
|
11
|
+
Choose a file to import.
|
|
12
|
+
</v-card-subtitle>
|
|
13
|
+
</v-card-item>
|
|
14
|
+
|
|
2
15
|
<v-stepper-vertical
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
16
|
+
:model-value="current_step_index + 1"
|
|
17
|
+
@update:model-value="current_step_index = $event - 1"
|
|
18
|
+
flat
|
|
19
|
+
non-linear
|
|
20
|
+
class="pa-0 ma-0 bg-white rounded-xl overflow-hidden"
|
|
7
21
|
>
|
|
8
|
-
<
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
@reset_values="emit('reset_values')"
|
|
15
|
-
/>
|
|
16
|
-
</v-col>
|
|
17
|
-
</v-stepper-items>
|
|
22
|
+
<Step
|
|
23
|
+
v-for="(step, index) in steps"
|
|
24
|
+
:key="index"
|
|
25
|
+
:step_index="index"
|
|
26
|
+
@reset_values="emit('reset_values')"
|
|
27
|
+
/>
|
|
18
28
|
</v-stepper-vertical>
|
|
19
29
|
</template>
|
|
20
30
|
|
|
@@ -1,50 +1,3 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<v-sheet class="menu-item-container transition-swing" color="transparent">
|
|
3
|
-
<v-tooltip
|
|
4
|
-
:location="props.itemProps.tooltip_location"
|
|
5
|
-
:origin="props.itemProps.tooltip_origin"
|
|
6
|
-
>
|
|
7
|
-
<template v-slot:activator="{ props: tooltipProps }">
|
|
8
|
-
<v-btn
|
|
9
|
-
icon
|
|
10
|
-
:active="is_active"
|
|
11
|
-
@click.stop="toggleOptions"
|
|
12
|
-
v-bind="tooltipProps"
|
|
13
|
-
class="menu-btn bg-white border"
|
|
14
|
-
elevation="2"
|
|
15
|
-
>
|
|
16
|
-
<v-img :src="btn_image" height="28" width="28" />
|
|
17
|
-
</v-btn>
|
|
18
|
-
</template>
|
|
19
|
-
<span>{{ props.tooltip }}</span>
|
|
20
|
-
</v-tooltip>
|
|
21
|
-
|
|
22
|
-
<v-sheet
|
|
23
|
-
v-if="is_active"
|
|
24
|
-
ref="optionsRef"
|
|
25
|
-
class="menu-options d-flex align-center pa-0"
|
|
26
|
-
:class="optionsClass"
|
|
27
|
-
:style="optionsStyle"
|
|
28
|
-
color="transparent"
|
|
29
|
-
@click.stop
|
|
30
|
-
>
|
|
31
|
-
<v-card
|
|
32
|
-
@click.stop
|
|
33
|
-
:title="props.tooltip"
|
|
34
|
-
class="options-card rounded-xl border-thin elevation-24"
|
|
35
|
-
width="320"
|
|
36
|
-
:max-height="maxCardHeight"
|
|
37
|
-
:ripple="false"
|
|
38
|
-
theme="dark"
|
|
39
|
-
>
|
|
40
|
-
<v-card-text class="pa-5">
|
|
41
|
-
<slot name="options" />
|
|
42
|
-
</v-card-text>
|
|
43
|
-
</v-card>
|
|
44
|
-
</v-sheet>
|
|
45
|
-
</v-sheet>
|
|
46
|
-
</template>
|
|
47
|
-
|
|
48
1
|
<script setup>
|
|
49
2
|
import { useTheme } from "vuetify"
|
|
50
3
|
import { useMenuStore } from "@ogw_front/stores/menu"
|
|
@@ -103,6 +56,46 @@
|
|
|
103
56
|
|
|
104
57
|
const toggleOptions = () => menuStore.toggleItemOptions(props.index)
|
|
105
58
|
</script>
|
|
59
|
+
<template>
|
|
60
|
+
<v-sheet class="menu-item-container transition-swing" color="transparent">
|
|
61
|
+
<v-tooltip
|
|
62
|
+
:location="props.itemProps.tooltip_location"
|
|
63
|
+
:origin="props.itemProps.tooltip_origin"
|
|
64
|
+
>
|
|
65
|
+
<template v-slot:activator="{ props: tooltipProps }">
|
|
66
|
+
<v-btn
|
|
67
|
+
icon
|
|
68
|
+
:active="is_active"
|
|
69
|
+
@click.stop="toggleOptions"
|
|
70
|
+
v-bind="tooltipProps"
|
|
71
|
+
class="menu-btn bg-white border"
|
|
72
|
+
elevation="2"
|
|
73
|
+
>
|
|
74
|
+
<v-img :src="btn_image" height="28" width="28" />
|
|
75
|
+
</v-btn>
|
|
76
|
+
</template>
|
|
77
|
+
<span>{{ props.tooltip }}</span>
|
|
78
|
+
</v-tooltip>
|
|
79
|
+
|
|
80
|
+
<v-sheet
|
|
81
|
+
v-if="is_active"
|
|
82
|
+
ref="optionsRef"
|
|
83
|
+
class="menu-options d-flex align-center pa-0"
|
|
84
|
+
:class="optionsClass"
|
|
85
|
+
:style="optionsStyle"
|
|
86
|
+
color="transparent"
|
|
87
|
+
@click.stop
|
|
88
|
+
>
|
|
89
|
+
<OptionCard
|
|
90
|
+
:title="props.tooltip"
|
|
91
|
+
width="320"
|
|
92
|
+
:max-height="maxCardHeight"
|
|
93
|
+
>
|
|
94
|
+
<slot name="options" />
|
|
95
|
+
</OptionCard>
|
|
96
|
+
</v-sheet>
|
|
97
|
+
</v-sheet>
|
|
98
|
+
</template>
|
|
106
99
|
|
|
107
100
|
<style scoped>
|
|
108
101
|
.menu-item-container {
|
|
@@ -146,22 +139,8 @@
|
|
|
146
139
|
.options-right {
|
|
147
140
|
left: 60px;
|
|
148
141
|
}
|
|
142
|
+
|
|
149
143
|
.options-left {
|
|
150
144
|
right: 60px;
|
|
151
145
|
}
|
|
152
|
-
|
|
153
|
-
.options-card {
|
|
154
|
-
background-color: rgba(30, 30, 30, 0.85) !important;
|
|
155
|
-
backdrop-filter: blur(20px);
|
|
156
|
-
-webkit-backdrop-filter: blur(20px);
|
|
157
|
-
border-color: rgba(255, 255, 255, 0.15) !important;
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
::v-deep(.v-list-item:hover) {
|
|
161
|
-
background-color: rgba(255, 255, 255, 0.1);
|
|
162
|
-
}
|
|
163
|
-
::v-deep(.v-slider-track__fill),
|
|
164
|
-
::v-deep(.v-selection-control--dirty .v-switch__track) {
|
|
165
|
-
background-color: v-bind(primaryColor) !important;
|
|
166
|
-
}
|
|
167
146
|
</style>
|
|
@@ -1,75 +1,55 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<v-sheet
|
|
3
|
-
:width="width + 'px'"
|
|
4
|
-
class="z-scaling-menu"
|
|
5
|
-
elevation="10"
|
|
6
|
-
rounded="lg"
|
|
7
|
-
>
|
|
8
|
-
<v-card class="bg-primary pa-4" elevation="0">
|
|
9
|
-
<v-card-title class="d-flex justify-space-between align-center">
|
|
10
|
-
<h3 class="text-h5 font-weight-bold">Z Scaling Control</h3>
|
|
11
|
-
</v-card-title>
|
|
12
|
-
<v-card-text class="pt-4">
|
|
13
|
-
<v-container>
|
|
14
|
-
<v-row>
|
|
15
|
-
<v-col cols="12" class="py-2">
|
|
16
|
-
<v-slider
|
|
17
|
-
v-model="zScale"
|
|
18
|
-
:min="1"
|
|
19
|
-
:max="10"
|
|
20
|
-
:step="0.2"
|
|
21
|
-
label="Z Scale"
|
|
22
|
-
thumb-label
|
|
23
|
-
color="white"
|
|
24
|
-
track-color="white"
|
|
25
|
-
/>
|
|
26
|
-
</v-col>
|
|
27
|
-
</v-row>
|
|
28
|
-
<v-row>
|
|
29
|
-
<v-col cols="12" class="py-2">
|
|
30
|
-
<v-text-field
|
|
31
|
-
v-model.number="zScale"
|
|
32
|
-
type="number"
|
|
33
|
-
label="Z Scale Value"
|
|
34
|
-
outlined
|
|
35
|
-
dense
|
|
36
|
-
hide-details
|
|
37
|
-
step="0.1"
|
|
38
|
-
class="custom-number-input"
|
|
39
|
-
:min="1"
|
|
40
|
-
/>
|
|
41
|
-
</v-col>
|
|
42
|
-
</v-row>
|
|
43
|
-
</v-container>
|
|
44
|
-
</v-card-text>
|
|
45
|
-
<v-card-actions class="justify-center pb-4">
|
|
46
|
-
<v-btn
|
|
47
|
-
variant="text"
|
|
48
|
-
color="white"
|
|
49
|
-
@click="$emit('close')"
|
|
50
|
-
class="px-4"
|
|
51
|
-
>
|
|
52
|
-
Close
|
|
53
|
-
</v-btn>
|
|
54
|
-
<v-btn
|
|
55
|
-
variant="outlined"
|
|
56
|
-
color="white"
|
|
57
|
-
@click="$emit('close')"
|
|
58
|
-
class="px-4"
|
|
59
|
-
>
|
|
60
|
-
Apply
|
|
61
|
-
</v-btn>
|
|
62
|
-
</v-card-actions>
|
|
63
|
-
</v-card>
|
|
64
|
-
</v-sheet>
|
|
65
|
-
</template>
|
|
66
|
-
|
|
67
1
|
<script setup>
|
|
68
2
|
const zScale = defineModel({ type: Number, default: 1 })
|
|
69
3
|
const props = defineProps({
|
|
70
4
|
width: { type: Number, default: 400 },
|
|
71
5
|
})
|
|
72
6
|
</script>
|
|
7
|
+
<template>
|
|
8
|
+
<OptionCard
|
|
9
|
+
title="Z Scaling Control"
|
|
10
|
+
:width="width"
|
|
11
|
+
class="position-absolute rounded-xl"
|
|
12
|
+
style="z-index: 2; top: 90px; right: 55px"
|
|
13
|
+
>
|
|
14
|
+
<v-container>
|
|
15
|
+
<v-row>
|
|
16
|
+
<v-col cols="12" class="py-2">
|
|
17
|
+
<v-slider
|
|
18
|
+
v-model="zScale"
|
|
19
|
+
:min="1"
|
|
20
|
+
:max="10"
|
|
21
|
+
:step="0.2"
|
|
22
|
+
label="Z Scale"
|
|
23
|
+
thumb-label
|
|
24
|
+
color="white"
|
|
25
|
+
track-color="white"
|
|
26
|
+
/>
|
|
27
|
+
</v-col>
|
|
28
|
+
</v-row>
|
|
29
|
+
<v-row>
|
|
30
|
+
<v-col cols="12" class="py-2">
|
|
31
|
+
<v-text-field
|
|
32
|
+
v-model.number="zScale"
|
|
33
|
+
type="number"
|
|
34
|
+
label="Z Scale Value"
|
|
35
|
+
outlined
|
|
36
|
+
dense
|
|
37
|
+
hide-details
|
|
38
|
+
step="0.1"
|
|
39
|
+
:min="1"
|
|
40
|
+
/>
|
|
41
|
+
</v-col>
|
|
42
|
+
</v-row>
|
|
43
|
+
</v-container>
|
|
44
|
+
|
|
45
|
+
<template #actions>
|
|
46
|
+
<v-btn variant="text" color="white" @click="$emit('close')">Close</v-btn>
|
|
47
|
+
<v-btn variant="outlined" color="white" @click="$emit('close')"
|
|
48
|
+
>Apply</v-btn
|
|
49
|
+
>
|
|
50
|
+
</template>
|
|
51
|
+
</OptionCard>
|
|
52
|
+
</template>
|
|
73
53
|
|
|
74
54
|
<style scoped>
|
|
75
55
|
.z-scaling-menu {
|
|
@@ -83,11 +63,4 @@
|
|
|
83
63
|
.custom-number-input :deep(.v-input__control) {
|
|
84
64
|
min-height: 48px;
|
|
85
65
|
}
|
|
86
|
-
|
|
87
|
-
.v-btn {
|
|
88
|
-
border-radius: 8px;
|
|
89
|
-
text-transform: none;
|
|
90
|
-
font-weight: 500;
|
|
91
|
-
letter-spacing: normal;
|
|
92
|
-
}
|
|
93
66
|
</style>
|
|
@@ -10,15 +10,19 @@ const autoStoreRegister = ({ store }) => {
|
|
|
10
10
|
console.log(`[AutoRegister] Store "${store.$id}" processed`)
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
export default defineNuxtPlugin(
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
13
|
+
export default defineNuxtPlugin({
|
|
14
|
+
name: "auto-store-register",
|
|
15
|
+
dependsOn: ["pinia"],
|
|
16
|
+
setup(nuxtApp) {
|
|
17
|
+
const { $pinia } = nuxtApp
|
|
18
|
+
if (!$pinia) {
|
|
19
|
+
console.warn("Pinia instance not available.")
|
|
20
|
+
return
|
|
21
|
+
}
|
|
19
22
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
23
|
+
$pinia.use(autoStoreRegister)
|
|
24
|
+
console.log(
|
|
25
|
+
"[AUTOREGISTER PLUGIN] Loaded automatically from OpenGeodeWeb-Front",
|
|
26
|
+
)
|
|
27
|
+
},
|
|
24
28
|
})
|
package/app/stores/data.js
CHANGED
|
@@ -103,7 +103,7 @@ export const useDataStore = defineStore("data", () => {
|
|
|
103
103
|
|
|
104
104
|
async function addModelComponents(values) {
|
|
105
105
|
if (!values || values.length === 0) {
|
|
106
|
-
console.
|
|
106
|
+
console.debug("[addModelComponents] No mesh components to add")
|
|
107
107
|
return
|
|
108
108
|
}
|
|
109
109
|
values.map((value) => {
|
|
@@ -32,6 +32,9 @@ export function useModelBlocksStyle() {
|
|
|
32
32
|
modelBlockStyle(id, block_id).visibility = visibility
|
|
33
33
|
}
|
|
34
34
|
async function setModelBlocksVisibility(id, block_ids, visibility) {
|
|
35
|
+
if (!block_ids || block_ids.length === 0) {
|
|
36
|
+
return
|
|
37
|
+
}
|
|
35
38
|
const blocks_viewer_ids = await dataStore.getMeshComponentsViewerIds(
|
|
36
39
|
id,
|
|
37
40
|
block_ids,
|
|
@@ -70,6 +73,9 @@ export function useModelBlocksStyle() {
|
|
|
70
73
|
}
|
|
71
74
|
|
|
72
75
|
async function setModelBlocksColor(id, block_ids, color) {
|
|
76
|
+
if (!block_ids || block_ids.length === 0) {
|
|
77
|
+
return
|
|
78
|
+
}
|
|
73
79
|
const blocks_viewer_ids = await dataStore.getMeshComponentsViewerIds(
|
|
74
80
|
id,
|
|
75
81
|
block_ids,
|
|
@@ -32,6 +32,9 @@ export function useModelCornersStyle() {
|
|
|
32
32
|
modelCornerStyle(id, corner_id).visibility = visibility
|
|
33
33
|
}
|
|
34
34
|
async function setModelCornersVisibility(id, corner_ids, visibility) {
|
|
35
|
+
if (!corner_ids || corner_ids.length === 0) {
|
|
36
|
+
return
|
|
37
|
+
}
|
|
35
38
|
const corner_viewer_ids = await dataStore.getMeshComponentsViewerIds(
|
|
36
39
|
id,
|
|
37
40
|
corner_ids,
|
|
@@ -71,6 +74,9 @@ export function useModelCornersStyle() {
|
|
|
71
74
|
}
|
|
72
75
|
|
|
73
76
|
async function setModelCornersColor(id, corner_ids, color) {
|
|
77
|
+
if (!corner_ids || corner_ids.length === 0) {
|
|
78
|
+
return
|
|
79
|
+
}
|
|
74
80
|
const corner_viewer_ids = await dataStore.getMeshComponentsViewerIds(
|
|
75
81
|
id,
|
|
76
82
|
corner_ids,
|
|
@@ -32,6 +32,9 @@ export function useModelLinesStyle() {
|
|
|
32
32
|
modelLineStyle(id, line_id).visibility = visibility
|
|
33
33
|
}
|
|
34
34
|
async function setModelLinesVisibility(id, line_ids, visibility) {
|
|
35
|
+
if (!line_ids || line_ids.length === 0) {
|
|
36
|
+
return
|
|
37
|
+
}
|
|
35
38
|
const line_viewer_ids = await dataStore.getMeshComponentsViewerIds(
|
|
36
39
|
id,
|
|
37
40
|
line_ids,
|
|
@@ -69,6 +72,9 @@ export function useModelLinesStyle() {
|
|
|
69
72
|
modelLineStyle(id, line_id).color = color
|
|
70
73
|
}
|
|
71
74
|
async function setModelLinesColor(id, line_ids, color) {
|
|
75
|
+
if (!line_ids || line_ids.length === 0) {
|
|
76
|
+
return
|
|
77
|
+
}
|
|
72
78
|
const line_viewer_ids = await dataStore.getMeshComponentsViewerIds(
|
|
73
79
|
id,
|
|
74
80
|
line_ids,
|
|
@@ -31,6 +31,9 @@ export function useModelSurfacesStyle() {
|
|
|
31
31
|
modelSurfaceStyle(id, surface_id).visibility = visibility
|
|
32
32
|
}
|
|
33
33
|
async function setModelSurfacesVisibility(id, surface_ids, visibility) {
|
|
34
|
+
if (!surface_ids || surface_ids.length === 0) {
|
|
35
|
+
return
|
|
36
|
+
}
|
|
34
37
|
const surface_viewer_ids = await dataStore.getMeshComponentsViewerIds(
|
|
35
38
|
id,
|
|
36
39
|
surface_ids,
|
|
@@ -68,6 +71,9 @@ export function useModelSurfacesStyle() {
|
|
|
68
71
|
}
|
|
69
72
|
|
|
70
73
|
async function setModelSurfacesColor(id, surface_ids, color) {
|
|
74
|
+
if (!surface_ids || surface_ids.length === 0) {
|
|
75
|
+
return
|
|
76
|
+
}
|
|
71
77
|
const surface_viewer_ids = await dataStore.getMeshComponentsViewerIds(
|
|
72
78
|
id,
|
|
73
79
|
surface_ids,
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@geode/opengeodeweb-front",
|
|
3
3
|
"description": "OpenSource Vue/Nuxt/Pinia/Vuetify framework for web applications",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"version": "10.2.
|
|
5
|
+
"version": "10.2.1-rc.2",
|
|
6
6
|
"main": "./nuxt.config.js",
|
|
7
7
|
"scripts": {
|
|
8
8
|
"lint": "eslint --fix --ext .js,.vue --ignore-path .gitignore .",
|
|
@@ -14,8 +14,8 @@
|
|
|
14
14
|
"build": ""
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"@geode/opengeodeweb-back": "
|
|
18
|
-
"@geode/opengeodeweb-viewer": "
|
|
17
|
+
"@geode/opengeodeweb-back": "next",
|
|
18
|
+
"@geode/opengeodeweb-viewer": "next",
|
|
19
19
|
"@kitware/vtk.js": "33.3.0",
|
|
20
20
|
"@mdi/font": "7.4.47",
|
|
21
21
|
"@pinia/nuxt": "0.11.3",
|
|
@@ -46,11 +46,13 @@ describe("FileSelector", async () => {
|
|
|
46
46
|
handler: () => ({}),
|
|
47
47
|
})
|
|
48
48
|
|
|
49
|
-
const v_file_input = file_uploader.
|
|
50
|
-
await v_file_input.trigger("click")
|
|
49
|
+
const v_file_input = file_uploader.find('input[type="file"]')
|
|
51
50
|
const files = [new File(["fake_file"], "fake_file.txt")]
|
|
52
51
|
const auto_upload = false
|
|
53
|
-
|
|
52
|
+
Object.defineProperty(v_file_input.element, "files", {
|
|
53
|
+
value: files,
|
|
54
|
+
writable: true,
|
|
55
|
+
})
|
|
54
56
|
await v_file_input.trigger("change")
|
|
55
57
|
const v_btn = wrapper.findComponent(components.VBtn)
|
|
56
58
|
await v_btn.trigger("click")
|
|
@@ -43,10 +43,11 @@ describe("FileUploader", async () => {
|
|
|
43
43
|
props: { multiple: false, accept: "*.txt" },
|
|
44
44
|
})
|
|
45
45
|
|
|
46
|
-
const v_file_input = wrapper.
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
46
|
+
const v_file_input = wrapper.find('input[type="file"]')
|
|
47
|
+
Object.defineProperty(v_file_input.element, "files", {
|
|
48
|
+
value: files,
|
|
49
|
+
writable: true,
|
|
50
|
+
})
|
|
50
51
|
await v_file_input.trigger("change")
|
|
51
52
|
const v_btn = wrapper.findComponent(components.VBtn)
|
|
52
53
|
|
|
@@ -55,10 +55,12 @@ describe("MissingFilesSelector", async () => {
|
|
|
55
55
|
const file_uploader = wrapper.findComponent(FileUploader)
|
|
56
56
|
expect(file_uploader.exists()).toBe(true)
|
|
57
57
|
|
|
58
|
-
const v_file_input = file_uploader.
|
|
59
|
-
await v_file_input.trigger("click")
|
|
58
|
+
const v_file_input = file_uploader.find('input[type="file"]')
|
|
60
59
|
const files = [new File(["fake_file"], "fake_file.txt")]
|
|
61
|
-
|
|
60
|
+
Object.defineProperty(v_file_input.element, "files", {
|
|
61
|
+
value: files,
|
|
62
|
+
writable: true,
|
|
63
|
+
})
|
|
62
64
|
await v_file_input.trigger("change")
|
|
63
65
|
const v_btn = file_uploader.findComponent(components.VBtn)
|
|
64
66
|
|