@geode/opengeodeweb-front 0.0.1 → 0.0.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/.github/workflows/CD.yml +7 -1
- package/components/CrsSelector.vue +78 -0
- package/components/Errors/Banner.vue +48 -0
- package/components/Errors/Snackers.vue +49 -0
- package/components/ExtensionSelector.vue +53 -0
- package/components/FileSelector.vue +46 -0
- package/components/ObjectSelector.vue +66 -0
- package/components/PackagesVersions.vue +55 -0
- package/components/RemoteRenderingView.vue +87 -0
- package/components/Step.vue +61 -0
- package/components/Stepper.vue +13 -0
- package/components/Wrapper.vue +32 -0
- package/package.json +11 -13
- package/plugins/vuetify.js +45 -0
- package/protocols/index.js +5 -0
- package/protocols/vtk.js +13 -0
- package/stores/cloud.js +71 -0
- package/stores/errors.js +20 -0
- package/README copy.md +0 -63
- package/nuxt.config.ts +0 -2
package/.github/workflows/CD.yml
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
name: Publish Package to npmjs
|
|
2
|
-
on:
|
|
2
|
+
on:
|
|
3
|
+
push:
|
|
4
|
+
branches: [ next, master ]
|
|
3
5
|
|
|
4
6
|
jobs:
|
|
5
7
|
build:
|
|
@@ -12,6 +14,10 @@ jobs:
|
|
|
12
14
|
node-version: '16.x'
|
|
13
15
|
registry-url: 'https://registry.npmjs.org'
|
|
14
16
|
- run: npm ci
|
|
17
|
+
- run: |
|
|
18
|
+
git config --global user.email "contact@geode-solutions.com"
|
|
19
|
+
git config --global user.name "Geode-solutions"
|
|
20
|
+
- run: npm version patch
|
|
15
21
|
- run: npm publish --access public
|
|
16
22
|
env:
|
|
17
23
|
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<v-text-field v-model="search" append-icon="mdi-magnify" label="Search" single-line hide-details></v-text-field>
|
|
3
|
+
<v-data-table v-model="selected_crs" :v-model:items-per-page="10" :headers="headers" :items="crs_list" item-value="code"
|
|
4
|
+
class="elevation-1" density='compact' fixed-header select-strategy='single' show-select :search="search"
|
|
5
|
+
:loading="data_table_loading" loading-text="Loading... Please wait"></v-data-table>
|
|
6
|
+
</template>
|
|
7
|
+
|
|
8
|
+
<script setup>
|
|
9
|
+
import { useToggle } from '@vueuse/core'
|
|
10
|
+
|
|
11
|
+
const stepper_tree = inject('stepper_tree')
|
|
12
|
+
const { geode_object, route_prefix } = stepper_tree
|
|
13
|
+
|
|
14
|
+
const props = defineProps({
|
|
15
|
+
variable_to_update: { type: String, required: true },
|
|
16
|
+
variable_to_increment: { type: String, required: true },
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
const { variable_to_update, variable_to_increment } = props
|
|
20
|
+
|
|
21
|
+
const search = ref('')
|
|
22
|
+
const data_table_loading = ref(false)
|
|
23
|
+
const crs_list = ref([])
|
|
24
|
+
const selected_crs = ref([])
|
|
25
|
+
const toggle_loading = useToggle(data_table_loading)
|
|
26
|
+
|
|
27
|
+
watch(selected_crs, (new_value) => {
|
|
28
|
+
const crs = get_selected_crs(new_value[0])
|
|
29
|
+
set_crs(crs)
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
function set_crs (crs_value) {
|
|
33
|
+
stepper_tree[variable_to_update] = crs_value
|
|
34
|
+
stepper_tree[variable_to_increment]++
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function get_selected_crs (crs_code) {
|
|
38
|
+
for (let i = 0; i <= crs_list.value.length; i++) {
|
|
39
|
+
if (crs_list.value[i]['code'] == crs_code) {
|
|
40
|
+
return crs_list.value[i]
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
async function get_crs_table () {
|
|
46
|
+
let params = new FormData()
|
|
47
|
+
params.append('geode_object', geode_object)
|
|
48
|
+
toggle_loading()
|
|
49
|
+
await api_fetch(`${route_prefix}/geographic_coordinate_systems`, { method: 'POST', body: params },
|
|
50
|
+
{
|
|
51
|
+
'request_error_function': () => { toggle_loading() },
|
|
52
|
+
'response_function': (response) => {
|
|
53
|
+
toggle_loading()
|
|
54
|
+
crs_list.value = response._data.crs_list
|
|
55
|
+
},
|
|
56
|
+
'response_error_function': () => { toggle_loading() }
|
|
57
|
+
}
|
|
58
|
+
)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const headers = [
|
|
62
|
+
{
|
|
63
|
+
title: 'Authority',
|
|
64
|
+
align: 'start',
|
|
65
|
+
sortable: true,
|
|
66
|
+
key: 'authority',
|
|
67
|
+
|
|
68
|
+
},
|
|
69
|
+
{ title: 'Code', align: 'end', key: 'code' },
|
|
70
|
+
{ title: 'Name', align: 'end', key: 'name' }
|
|
71
|
+
]
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
onMounted(() => {
|
|
75
|
+
get_crs_table()
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
</script>
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<v-banner v-if="server_error" elevation="2" style="background-color: grey; z-index:100;" position="fixed">
|
|
3
|
+
<v-row>
|
|
4
|
+
<v-col cols="auto" class="white--text text-center">
|
|
5
|
+
<v-tooltip location="end">
|
|
6
|
+
<span>
|
|
7
|
+
We turn off our server automatically after 5 minutes of inactivity
|
|
8
|
+
</span>
|
|
9
|
+
<template #activator="{ props }">
|
|
10
|
+
<v-icon v-bind="props" color="white" class="justify-right">
|
|
11
|
+
mdi-information-outline
|
|
12
|
+
</v-icon>
|
|
13
|
+
</template>
|
|
14
|
+
</v-tooltip>
|
|
15
|
+
</v-col>
|
|
16
|
+
<v-col cols="auto" class="text-white font-weight-bold">Server timed out due to inactivity,
|
|
17
|
+
please reload this page
|
|
18
|
+
or click here:
|
|
19
|
+
</v-col>
|
|
20
|
+
<v-col cols="auto" align-items="center">
|
|
21
|
+
<v-btn @click="reload()" color="grey" density='compact'>
|
|
22
|
+
Reload
|
|
23
|
+
</v-btn>
|
|
24
|
+
</v-col>
|
|
25
|
+
<v-spacer />
|
|
26
|
+
<v-col cols="auto">
|
|
27
|
+
<v-btn icon flat size="20" @click="errors_store.delete_server_error()" color="grey" class=".align-center">
|
|
28
|
+
<v-icon icon="mdi-close" size="20" color="white" />
|
|
29
|
+
</v-btn>
|
|
30
|
+
</v-col>
|
|
31
|
+
</v-row>
|
|
32
|
+
</v-banner>
|
|
33
|
+
</template>
|
|
34
|
+
|
|
35
|
+
<script setup>
|
|
36
|
+
const errors_store = use_errors_store()
|
|
37
|
+
const { server_error } = storeToRefs(errors_store)
|
|
38
|
+
|
|
39
|
+
function reload () {
|
|
40
|
+
window.location.reload()
|
|
41
|
+
}
|
|
42
|
+
</script>
|
|
43
|
+
|
|
44
|
+
<style scoped>
|
|
45
|
+
.v-btn {
|
|
46
|
+
text-transform: unset !important;
|
|
47
|
+
}
|
|
48
|
+
</style>
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<v-snackbar :style="{ 'margin-bottom': calc_margin(index) }" v-for="(error, index) in errors" :key="index"
|
|
3
|
+
v-model="show" color="error" location="bottom right" transition="slide-x-reverse-transition" max-width="30%"
|
|
4
|
+
height="20px">
|
|
5
|
+
<v-row dense class="flex-nowrap">
|
|
6
|
+
<v-col cols="auto">
|
|
7
|
+
<v-tooltip location="left">
|
|
8
|
+
<span>
|
|
9
|
+
{{ error.code }}<br />
|
|
10
|
+
{{ error.route }}<br />
|
|
11
|
+
{{ error.description }}
|
|
12
|
+
<br>
|
|
13
|
+
</span>
|
|
14
|
+
<template #activator="{ props }">
|
|
15
|
+
<v-icon v-bind="props" color="white" class="justify-right">
|
|
16
|
+
mdi-information-outline
|
|
17
|
+
</v-icon>
|
|
18
|
+
</template>
|
|
19
|
+
</v-tooltip>
|
|
20
|
+
</v-col>
|
|
21
|
+
<v-col cols="9" class="text-no-wrap overflow-hidden">
|
|
22
|
+
{{ error.name }}
|
|
23
|
+
</v-col>
|
|
24
|
+
<v-spacer />
|
|
25
|
+
<v-col cols="auto">
|
|
26
|
+
<v-btn icon flat size="20" @click="errors_store.delete_error(index)" color="error">
|
|
27
|
+
<v-icon icon="mdi-close" size="20" color="white" />
|
|
28
|
+
</v-btn>
|
|
29
|
+
</v-col>
|
|
30
|
+
</v-row>
|
|
31
|
+
</v-snackbar>
|
|
32
|
+
</template>
|
|
33
|
+
|
|
34
|
+
<script setup>
|
|
35
|
+
const errors_store = use_errors_store()
|
|
36
|
+
const { errors } = storeToRefs(errors_store)
|
|
37
|
+
|
|
38
|
+
const show = true
|
|
39
|
+
|
|
40
|
+
function calc_margin (index) {
|
|
41
|
+
return (index * 60) + 8 + 'px'
|
|
42
|
+
}
|
|
43
|
+
</script>
|
|
44
|
+
|
|
45
|
+
<style scoped>
|
|
46
|
+
.v-snackbar :deep(.v-snackbar__content) {
|
|
47
|
+
width: 100%;
|
|
48
|
+
}
|
|
49
|
+
</style>
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<v-row class="justify-left">
|
|
3
|
+
<v-col v-for="file_extension in file_extensions" :key="file_extension" cols="2">
|
|
4
|
+
<v-card class="card ma-2" hover elevation="5" @click="set_output_extension(file_extension)">
|
|
5
|
+
<v-card-title align="center">
|
|
6
|
+
{{ file_extension }}
|
|
7
|
+
</v-card-title>
|
|
8
|
+
</v-card>
|
|
9
|
+
</v-col>
|
|
10
|
+
</v-row>
|
|
11
|
+
</template>
|
|
12
|
+
|
|
13
|
+
<script setup>
|
|
14
|
+
const stepper_tree = inject('stepper_tree')
|
|
15
|
+
const { geode_object, route_prefix } = stepper_tree
|
|
16
|
+
|
|
17
|
+
const props = defineProps({
|
|
18
|
+
variable_to_update: { type: String, required: true },
|
|
19
|
+
variable_to_increment: { type: String, required: true },
|
|
20
|
+
})
|
|
21
|
+
const { variable_to_update, variable_to_increment } = props
|
|
22
|
+
|
|
23
|
+
const file_extensions = ref([])
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
async function get_output_file_extensions () {
|
|
27
|
+
const params = new FormData()
|
|
28
|
+
params.append('geode_object', geode_object)
|
|
29
|
+
await api_fetch(`${route_prefix}/output_file_extensions`, { method: 'POST', body: params },
|
|
30
|
+
{
|
|
31
|
+
'response_function': (response) => {
|
|
32
|
+
file_extensions.value = response._data.output_file_extensions
|
|
33
|
+
},
|
|
34
|
+
}
|
|
35
|
+
)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function set_output_extension (extension) {
|
|
39
|
+
stepper_tree[variable_to_update] = extension
|
|
40
|
+
stepper_tree[variable_to_increment]++
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
onMounted(() => {
|
|
44
|
+
get_output_file_extensions()
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
</script>
|
|
48
|
+
|
|
49
|
+
<style scoped>
|
|
50
|
+
.card {
|
|
51
|
+
border-radius: 15px;
|
|
52
|
+
}
|
|
53
|
+
</style>
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<v-file-input v-model="files" :multiple="multiple" :label="label" :accept="accept"
|
|
3
|
+
:rules="[(value) => !!value || 'The file is mandatory']" color="primary" chips counter show-size
|
|
4
|
+
@click:clear="stepper_tree.files = []" />
|
|
5
|
+
</template>
|
|
6
|
+
|
|
7
|
+
<script setup>
|
|
8
|
+
const stepper_tree = inject('stepper_tree')
|
|
9
|
+
const { route_prefix } = stepper_tree
|
|
10
|
+
|
|
11
|
+
const props = defineProps({
|
|
12
|
+
multiple: { type: Boolean, required: true },
|
|
13
|
+
label: { type: String, required: true },
|
|
14
|
+
variable_to_update: { type: String, required: true },
|
|
15
|
+
variable_to_increment: { type: String, required: true },
|
|
16
|
+
})
|
|
17
|
+
const { multiple, label, variable_to_update, variable_to_increment } = props
|
|
18
|
+
|
|
19
|
+
const accept = ref('')
|
|
20
|
+
const files = ref([])
|
|
21
|
+
|
|
22
|
+
watch(files, (value) => {
|
|
23
|
+
stepper_tree[variable_to_update] = value
|
|
24
|
+
stepper_tree[variable_to_increment]++
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
function fill_extensions (response) {
|
|
28
|
+
const extensions = response._data.extensions.map((extension) => '.' + extension).join(',')
|
|
29
|
+
accept.value = extensions
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async function get_allowed_files () {
|
|
33
|
+
const route = `${route_prefix}/allowed_files`
|
|
34
|
+
await api_fetch(route, { method: 'GET' },
|
|
35
|
+
{
|
|
36
|
+
'response_function': (response) => {
|
|
37
|
+
fill_extensions(response)
|
|
38
|
+
}
|
|
39
|
+
})
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
onMounted(async () => {
|
|
43
|
+
await get_allowed_files()
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
</script>
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<v-row v-if="allowed_objects.length" class="justify-left">
|
|
3
|
+
<v-col v-for="object in allowed_objects" :key="object" cols="2" md="2">
|
|
4
|
+
<v-card v-ripple class="card ma-2" hover elevation="5" rounded>
|
|
5
|
+
<v-img :src="geode_objects[object].image" cover @click="set_geode_object(object)" />
|
|
6
|
+
<v-tooltip activator="parent" location="bottom">
|
|
7
|
+
{{ geode_objects[object].tooltip }}
|
|
8
|
+
</v-tooltip>
|
|
9
|
+
</v-card>
|
|
10
|
+
</v-col>
|
|
11
|
+
</v-row>
|
|
12
|
+
<v-row v-else class="pa-5">
|
|
13
|
+
<v-card class="card" variant="tonal" elevation="5" rounded>
|
|
14
|
+
<v-card-text>
|
|
15
|
+
This file format isn't supported! Please check the <a href="https://docs.geode-solutions.com/formats/"
|
|
16
|
+
target="_blank">
|
|
17
|
+
supported file formats documentation</a> for more information
|
|
18
|
+
</v-card-text>
|
|
19
|
+
</v-card>
|
|
20
|
+
</v-row>
|
|
21
|
+
</template>
|
|
22
|
+
|
|
23
|
+
<script setup>
|
|
24
|
+
import geode_objects from '@/assets/geode_objects'
|
|
25
|
+
|
|
26
|
+
const stepper_tree = inject('stepper_tree')
|
|
27
|
+
const { files, route_prefix } = stepper_tree
|
|
28
|
+
|
|
29
|
+
const props = defineProps({
|
|
30
|
+
variable_to_update: { type: String, required: true },
|
|
31
|
+
variable_to_increment: { type: String, required: true },
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
const { variable_to_update, variable_to_increment } = props
|
|
35
|
+
|
|
36
|
+
const allowed_objects = ref([])
|
|
37
|
+
|
|
38
|
+
async function get_allowed_objects () {
|
|
39
|
+
|
|
40
|
+
const params = new FormData()
|
|
41
|
+
params.append('filename', files[0].name)
|
|
42
|
+
|
|
43
|
+
await api_fetch(`${route_prefix}/allowed_objects`,
|
|
44
|
+
{ method: 'POST', body: params },
|
|
45
|
+
{
|
|
46
|
+
'response_function': (response) => { allowed_objects.value = response._data.allowed_objects }
|
|
47
|
+
})
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function set_geode_object (geode_object) {
|
|
51
|
+
stepper_tree[variable_to_update] = geode_object
|
|
52
|
+
stepper_tree[variable_to_increment]++
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
onMounted(() => {
|
|
56
|
+
get_allowed_objects()
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
</script>
|
|
61
|
+
|
|
62
|
+
<style scoped>
|
|
63
|
+
.card {
|
|
64
|
+
border-radius: 15px;
|
|
65
|
+
}
|
|
66
|
+
</style>
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<v-container>
|
|
3
|
+
This tool uses our Open-Source codes
|
|
4
|
+
<v-tooltip location="end">
|
|
5
|
+
<span v-for="package_version in packages_versions" :key="package_version.package">
|
|
6
|
+
{{ package_version.package }} v{{ package_version.version }}
|
|
7
|
+
<br>
|
|
8
|
+
</span>
|
|
9
|
+
<template #activator="{ props }">
|
|
10
|
+
<v-icon v-bind="props" color="primary" class="justify-right">
|
|
11
|
+
mdi-information-outline
|
|
12
|
+
</v-icon>
|
|
13
|
+
</template>
|
|
14
|
+
</v-tooltip>
|
|
15
|
+
</v-container>
|
|
16
|
+
</template>
|
|
17
|
+
|
|
18
|
+
<script setup>
|
|
19
|
+
const props = defineProps({
|
|
20
|
+
route_prefix: { type: String, required: true }
|
|
21
|
+
})
|
|
22
|
+
const { tool_route } = props
|
|
23
|
+
|
|
24
|
+
const { is_cloud_running } = storeToRefs(cloud_store)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
const packages_versions = ref([])
|
|
28
|
+
|
|
29
|
+
async function get_packages_versions () {
|
|
30
|
+
const route = `${tool_route}/versions`
|
|
31
|
+
await api_fetch(route, { method: 'GET' }, {
|
|
32
|
+
'response_function': (response) => {
|
|
33
|
+
packages_versions.value = response._data.versions
|
|
34
|
+
}
|
|
35
|
+
})
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
watch(is_cloud_running, (value) => {
|
|
39
|
+
if (value === true) {
|
|
40
|
+
get_packages_versions()
|
|
41
|
+
}
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
onMounted(() => {
|
|
45
|
+
if (is_cloud_running.value === true) {
|
|
46
|
+
get_packages_versions()
|
|
47
|
+
}
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
onActivated(() => {
|
|
51
|
+
if (is_cloud_running.value === true) {
|
|
52
|
+
get_packages_versions()
|
|
53
|
+
}
|
|
54
|
+
})
|
|
55
|
+
</script>
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<v-col v-element-size="resize" style="overflow: hidden; position: relative; z-index: 1; height: 100%; width: 100%"
|
|
3
|
+
ref="viewer" class="viewer" @click="get_x_y" @keydown.esc="app_store.toggle_picking_mode(false)">
|
|
4
|
+
</v-col>
|
|
5
|
+
</template>
|
|
6
|
+
|
|
7
|
+
<script setup>
|
|
8
|
+
import vtkRemoteView from '@kitware/vtk.js/Rendering/Misc/RemoteView';
|
|
9
|
+
import { vElementSize } from '@vueuse/components'
|
|
10
|
+
|
|
11
|
+
const app_store = use_app_store()
|
|
12
|
+
const { picking_mode } = storeToRefs(app_store)
|
|
13
|
+
|
|
14
|
+
function get_x_y (event) {
|
|
15
|
+
if (picking_mode.value === true) {
|
|
16
|
+
const { offsetX, offsetY } = event
|
|
17
|
+
app_store.set_picked_point(offsetX, offsetY)
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const props = defineProps({
|
|
22
|
+
viewId: { type: String, default: '-1' },
|
|
23
|
+
client: { type: Object, required: true }
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
const viewer = ref(null)
|
|
27
|
+
const { width, height } = useElementSize(viewer)
|
|
28
|
+
|
|
29
|
+
function resize () {
|
|
30
|
+
view.getCanvasView().setSize(0, 0) // hack to fit full size
|
|
31
|
+
view.resize();
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
watch(picking_mode, value => {
|
|
35
|
+
const cursor = value == true ? 'crosshair' : 'pointer'
|
|
36
|
+
view.getCanvasView().setCursor(cursor)
|
|
37
|
+
})
|
|
38
|
+
watch(width, value => {
|
|
39
|
+
resize()
|
|
40
|
+
})
|
|
41
|
+
watch(height, value => {
|
|
42
|
+
resize()
|
|
43
|
+
})
|
|
44
|
+
const { client, viewId } = toRefs(props)
|
|
45
|
+
const connected = ref(false)
|
|
46
|
+
|
|
47
|
+
const view = vtkRemoteView.newInstance({ rpcWheelEvent: 'viewport.mouse.zoom.wheel' })
|
|
48
|
+
// default of 0.5 causes 2x size labels on high-DPI screens. 1 good for demo, not for production.
|
|
49
|
+
if (location.hostname.split('.')[0] === 'localhost') {
|
|
50
|
+
view.setInteractiveRatio(1)
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
watch(client, (new_client) => {
|
|
55
|
+
connect()
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
watch(viewId, (id) => {
|
|
59
|
+
if (connected.value) {
|
|
60
|
+
view.setViewId(id)
|
|
61
|
+
view.render()
|
|
62
|
+
}
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
onMounted(async () => {
|
|
66
|
+
if (process.client) {
|
|
67
|
+
window.addEventListener('resize', resize)
|
|
68
|
+
await nextTick()
|
|
69
|
+
view.setContainer(viewer.value.$el)
|
|
70
|
+
connect()
|
|
71
|
+
resize()
|
|
72
|
+
}
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
function connect () {
|
|
76
|
+
const session = client.value.getConnection().getSession()
|
|
77
|
+
view.setSession(session)
|
|
78
|
+
view.setViewId(viewId.value)
|
|
79
|
+
connected.value = true
|
|
80
|
+
view.render()
|
|
81
|
+
}
|
|
82
|
+
function handleClick (event) {
|
|
83
|
+
onClick(event)
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
</script>
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<v-card class="pa-5 card" elevation="5">
|
|
3
|
+
<v-row align="center" @click="set_current_step(step_index)">
|
|
4
|
+
<v-col cols="auto">
|
|
5
|
+
<v-icon v-if="current_step_index > step_index" icon="mdi-check-circle" color="grey" />
|
|
6
|
+
<v-icon v-else-if="current_step_index == step_index" :icon="`mdi-numeric-${step_index + 1}-circle`"
|
|
7
|
+
color="primary" />
|
|
8
|
+
<v-icon v-else :icon="`mdi-numeric-${step_index + 1}-circle`" color="grey" />
|
|
9
|
+
</v-col>
|
|
10
|
+
<v-col cols="auto">
|
|
11
|
+
<p class="font-weight-bold">
|
|
12
|
+
{{ steps[step_index].step_title }}
|
|
13
|
+
</p>
|
|
14
|
+
</v-col>
|
|
15
|
+
<v-col v-if="steps[step_index].chips.length && (current_step_index >= step_index)">
|
|
16
|
+
<v-chip v-for="(chip, chip_index) in steps[step_index].chips" :key="chip_index">
|
|
17
|
+
{{ chip }}
|
|
18
|
+
</v-chip>
|
|
19
|
+
</v-col>
|
|
20
|
+
</v-row>
|
|
21
|
+
<Transition name="slide-fade">
|
|
22
|
+
<v-row v-if="step_index == current_step_index">
|
|
23
|
+
<component :is="steps[step_index].component.component_name"
|
|
24
|
+
v-bind="steps[step_index].component.component_options" />
|
|
25
|
+
</v-row>
|
|
26
|
+
</Transition>
|
|
27
|
+
</v-card>
|
|
28
|
+
</template>
|
|
29
|
+
|
|
30
|
+
<script setup>
|
|
31
|
+
const props = defineProps({
|
|
32
|
+
step_index: { type: Number, required: true }
|
|
33
|
+
})
|
|
34
|
+
const { step_index } = props
|
|
35
|
+
const stepper_tree = inject('stepper_tree')
|
|
36
|
+
const { current_step_index, steps } = toRefs(stepper_tree)
|
|
37
|
+
|
|
38
|
+
function set_current_step (step_index) {
|
|
39
|
+
stepper_tree.current_step_index = step_index
|
|
40
|
+
}
|
|
41
|
+
</script>
|
|
42
|
+
|
|
43
|
+
<style>
|
|
44
|
+
.card {
|
|
45
|
+
border-radius: 15px;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.slide-fade-enter-active {
|
|
49
|
+
transition: all 0.5s ease-out;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.slide-fade-leave-active {
|
|
53
|
+
transition: all 0.5s ease-in;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.slide-fade-enter-from,
|
|
57
|
+
.slide-fade-leave-to {
|
|
58
|
+
transform: translateX(50px);
|
|
59
|
+
opacity: 0;
|
|
60
|
+
}
|
|
61
|
+
</style>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<v-card class="card">
|
|
3
|
+
<div v-for="(step, index) in steps" :key="index" class="pa-3">
|
|
4
|
+
<ToolsStep :step_index="index" />
|
|
5
|
+
</div>
|
|
6
|
+
</v-card>
|
|
7
|
+
</template>
|
|
8
|
+
|
|
9
|
+
<script setup>
|
|
10
|
+
const stepper_tree = inject('stepper_tree')
|
|
11
|
+
const { steps } = stepper_tree
|
|
12
|
+
|
|
13
|
+
</script>
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<v-container>
|
|
3
|
+
<v-row class="flex-column">
|
|
4
|
+
<v-col>
|
|
5
|
+
<ToolsHeader :tool_name="tool_name" :cards_list="cards_list" />
|
|
6
|
+
</v-col>
|
|
7
|
+
<v-col v-if="!is_cloud_running">
|
|
8
|
+
<ToolsLauncher />
|
|
9
|
+
</v-col>
|
|
10
|
+
<v-col v-if="is_cloud_running">
|
|
11
|
+
<ToolsStepper />
|
|
12
|
+
</v-col>
|
|
13
|
+
<v-col v-if="is_cloud_running">
|
|
14
|
+
<ToolsPackagesVersions :route_prefix="route_prefix" />
|
|
15
|
+
</v-col>
|
|
16
|
+
</v-row>
|
|
17
|
+
</v-container>
|
|
18
|
+
</template>
|
|
19
|
+
|
|
20
|
+
<script setup>
|
|
21
|
+
const cloud_store = use_cloud_store()
|
|
22
|
+
const { is_cloud_running } = storeToRefs(cloud_store)
|
|
23
|
+
|
|
24
|
+
const props = defineProps({
|
|
25
|
+
cards_list: { type: Array, required: true }
|
|
26
|
+
})
|
|
27
|
+
const { cards_list } = props
|
|
28
|
+
|
|
29
|
+
const stepper_tree = inject('stepper_tree')
|
|
30
|
+
const { tool_name, route_prefix } = stepper_tree
|
|
31
|
+
|
|
32
|
+
</script>
|
package/package.json
CHANGED
|
@@ -2,31 +2,29 @@
|
|
|
2
2
|
"name": "@geode/opengeodeweb-front",
|
|
3
3
|
"private": false,
|
|
4
4
|
"scripts": {
|
|
5
|
-
"
|
|
6
|
-
"
|
|
7
|
-
"
|
|
8
|
-
"
|
|
9
|
-
"postinstall": "nuxt prepare"
|
|
5
|
+
"release:major": "npm version $(semver $npm_package_version -i major) && npm publish --tag latest",
|
|
6
|
+
"release:minor": "npm version $(semver $npm_package_version -i minor) && npm publish --tag latest",
|
|
7
|
+
"release:patch": "npm version $(semver $npm_package_version -i patch) && npm publish --tag latest",
|
|
8
|
+
"release:beta": "npm version $(semver $npm_package_version -i prerelease --preid $(npm whoami) ) && npm publish --tag rc"
|
|
10
9
|
},
|
|
11
10
|
"devDependencies": {
|
|
12
|
-
"
|
|
13
|
-
"
|
|
14
|
-
"vuetify": "^3.3.
|
|
11
|
+
"semver": "^7.5.4",
|
|
12
|
+
"@types/node": "^20.4.9",
|
|
13
|
+
"vuetify": "^3.3.12"
|
|
15
14
|
},
|
|
16
15
|
"overrides": {
|
|
17
16
|
"vue": "latest"
|
|
18
17
|
},
|
|
19
18
|
"description": "OpenSource Vue/Vuetify framework for web applications",
|
|
20
|
-
"version": "0.0.
|
|
19
|
+
"version": "0.0.3",
|
|
21
20
|
"main": "index.js",
|
|
22
21
|
"dependencies": {
|
|
23
22
|
"@mdi/font": "^7.2.96",
|
|
24
23
|
"@pinia/nuxt": "^0.4.11",
|
|
25
24
|
"@vueuse/core": "^10.3.0",
|
|
26
|
-
"nuxt": "^3.6.5",
|
|
27
25
|
"pinia": "^2.1.6",
|
|
28
|
-
"sass": "^1.
|
|
29
|
-
"vuetify": "^3.3.
|
|
26
|
+
"sass": "^1.65.1",
|
|
27
|
+
"vuetify": "^3.3.12"
|
|
30
28
|
},
|
|
31
29
|
"repository": {
|
|
32
30
|
"type": "git",
|
|
@@ -42,4 +40,4 @@
|
|
|
42
40
|
"url": "https://github.com/Geode-solutions/OpenGeodeWeb-Front/issues"
|
|
43
41
|
},
|
|
44
42
|
"homepage": "https://github.com/Geode-solutions/OpenGeodeWeb-Front#readme"
|
|
45
|
-
}
|
|
43
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { createVuetify } from 'vuetify'
|
|
2
|
+
import * as components from 'vuetify/components'
|
|
3
|
+
import { VDataTable } from 'vuetify/labs/VDataTable'
|
|
4
|
+
import * as directives from 'vuetify/directives'
|
|
5
|
+
|
|
6
|
+
import '@mdi/font/css/materialdesignicons.css'
|
|
7
|
+
import colors from 'vuetify/lib/util/colors'
|
|
8
|
+
import 'vuetify/styles'
|
|
9
|
+
|
|
10
|
+
const light_theme = {
|
|
11
|
+
dark: false,
|
|
12
|
+
colors: {
|
|
13
|
+
background: '#FFFFFF',
|
|
14
|
+
primary: colors.teal.darken1,
|
|
15
|
+
secondary: colors.teal.lighten4,
|
|
16
|
+
accent: colors.amber.accent4,
|
|
17
|
+
error: colors.red.lighten2,
|
|
18
|
+
info: colors.yellow.accent4,
|
|
19
|
+
success: colors.green.accent4,
|
|
20
|
+
warning: colors.orange.accent4,
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export default defineNuxtPlugin(nuxtApp => {
|
|
25
|
+
const vuetify = createVuetify({
|
|
26
|
+
components: {
|
|
27
|
+
...components,
|
|
28
|
+
VDataTable,
|
|
29
|
+
},
|
|
30
|
+
directives,
|
|
31
|
+
theme: {
|
|
32
|
+
defaultTheme: 'light_theme',
|
|
33
|
+
themes: {
|
|
34
|
+
light_theme,
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
defaultAssets: false,
|
|
38
|
+
icons: {
|
|
39
|
+
defaultSet: 'mdi'
|
|
40
|
+
},
|
|
41
|
+
ssr: true
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
nuxtApp.vueApp.use(vuetify)
|
|
45
|
+
})
|
package/protocols/vtk.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/* eslint-disable arrow-body-style */
|
|
2
|
+
export default function createMethods (session) {
|
|
3
|
+
return {
|
|
4
|
+
create_object_pipeline: (params) => session.call('create_object_pipeline', [params]),
|
|
5
|
+
create_visualization: () => session.call('create_visualization', []),
|
|
6
|
+
reset: () => session.call('reset'),
|
|
7
|
+
reset_camera: () => session.call('reset_camera', []),
|
|
8
|
+
toggle_object_visibility: (params) => session.call('toggle_object_visibility', [params]),
|
|
9
|
+
apply_textures: (params) => session.call('apply_textures', [params]),
|
|
10
|
+
get_point_position: (params) => session.call('get_point_position', [params]),
|
|
11
|
+
update_data: (params) => session.call('update_data', [params])
|
|
12
|
+
};
|
|
13
|
+
}
|
package/stores/cloud.js
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { defineStore } from 'pinia'
|
|
2
|
+
import { use_errors_store } from './errors'
|
|
3
|
+
|
|
4
|
+
export const use_cloud_store = defineStore('cloud', {
|
|
5
|
+
state: () => ({
|
|
6
|
+
ID: '',
|
|
7
|
+
is_captcha_validated: false,
|
|
8
|
+
is_cloud_running: false,
|
|
9
|
+
is_connexion_launched: false,
|
|
10
|
+
request_counter: 0
|
|
11
|
+
}),
|
|
12
|
+
actions: {
|
|
13
|
+
async create_connexion () {
|
|
14
|
+
if (this.is_connexion_launched) { return }
|
|
15
|
+
this.is_connexion_launched = true
|
|
16
|
+
const ID = localStorage.getItem('ID')
|
|
17
|
+
if (ID === null || typeof ID === 'undefined') {
|
|
18
|
+
return this.create_backend()
|
|
19
|
+
} else {
|
|
20
|
+
const config = useRuntimeConfig()
|
|
21
|
+
const { data, error } = await useFetch(`${config.public.API_URL}/${ID}/ping`, { method: 'POST' })
|
|
22
|
+
console.log("error", error)
|
|
23
|
+
if (data.value !== null) {
|
|
24
|
+
this.ID = ID
|
|
25
|
+
this.is_cloud_running = true
|
|
26
|
+
return this.ping_task()
|
|
27
|
+
} else {
|
|
28
|
+
return this.create_backend()
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
async create_backend () {
|
|
33
|
+
const errors_store = use_errors_store()
|
|
34
|
+
const config = useRuntimeConfig()
|
|
35
|
+
const { data, error } = await useFetch(`${config.public.API_URL}${config.public.SITE_BRANCH}/tools/createbackend`, { method: 'POST' })
|
|
36
|
+
if (data.value !== null) {
|
|
37
|
+
this.ID = data.value.ID
|
|
38
|
+
localStorage.setItem('ID', data.value.ID)
|
|
39
|
+
this.is_cloud_running = true
|
|
40
|
+
return this.ping_task()
|
|
41
|
+
} else {
|
|
42
|
+
console.log("error : ", error)
|
|
43
|
+
errors_store.server_error = true
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
|
|
47
|
+
ping_task () {
|
|
48
|
+
setInterval(() => this.do_ping(), 10 * 1000)
|
|
49
|
+
},
|
|
50
|
+
async do_ping () {
|
|
51
|
+
const errors_store = use_errors_store()
|
|
52
|
+
const config = useRuntimeConfig()
|
|
53
|
+
const { data, error } = await useFetch(`${config.public.API_URL}/${this.ID}/ping`, { method: 'POST' })
|
|
54
|
+
if (data.value !== null) {
|
|
55
|
+
this.is_cloud_running = true
|
|
56
|
+
} else {
|
|
57
|
+
errors_store.server_error = true
|
|
58
|
+
console.log("error : ", error)
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
|
|
62
|
+
mutations: {
|
|
63
|
+
start_request (state) {
|
|
64
|
+
state.request_counter++
|
|
65
|
+
},
|
|
66
|
+
stop_request (state) {
|
|
67
|
+
state.request_counter--
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
})
|
package/stores/errors.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { defineStore } from 'pinia'
|
|
2
|
+
|
|
3
|
+
export const use_errors_store = defineStore('errors', {
|
|
4
|
+
state: () => ({
|
|
5
|
+
errors: [],
|
|
6
|
+
server_error: false,
|
|
7
|
+
}),
|
|
8
|
+
actions: {
|
|
9
|
+
add_error (error_object) {
|
|
10
|
+
this.errors.push(error_object)
|
|
11
|
+
console.log(this.errors)
|
|
12
|
+
},
|
|
13
|
+
delete_error (error_index) {
|
|
14
|
+
this.errors.splice(error_index, 1)
|
|
15
|
+
},
|
|
16
|
+
delete_server_error () {
|
|
17
|
+
this.server_error = false
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
})
|
package/README copy.md
DELETED
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
# Nuxt 3 Minimal Starter
|
|
2
|
-
|
|
3
|
-
Look at the [Nuxt 3 documentation](https://nuxt.com/docs/getting-started/introduction) to learn more.
|
|
4
|
-
|
|
5
|
-
## Setup
|
|
6
|
-
|
|
7
|
-
Make sure to install the dependencies:
|
|
8
|
-
|
|
9
|
-
```bash
|
|
10
|
-
# npm
|
|
11
|
-
npm install
|
|
12
|
-
|
|
13
|
-
# pnpm
|
|
14
|
-
pnpm install
|
|
15
|
-
|
|
16
|
-
# yarn
|
|
17
|
-
yarn install
|
|
18
|
-
```
|
|
19
|
-
|
|
20
|
-
## Development Server
|
|
21
|
-
|
|
22
|
-
Start the development server on `http://localhost:3000`:
|
|
23
|
-
|
|
24
|
-
```bash
|
|
25
|
-
# npm
|
|
26
|
-
npm run dev
|
|
27
|
-
|
|
28
|
-
# pnpm
|
|
29
|
-
pnpm run dev
|
|
30
|
-
|
|
31
|
-
# yarn
|
|
32
|
-
yarn dev
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
## Production
|
|
36
|
-
|
|
37
|
-
Build the application for production:
|
|
38
|
-
|
|
39
|
-
```bash
|
|
40
|
-
# npm
|
|
41
|
-
npm run build
|
|
42
|
-
|
|
43
|
-
# pnpm
|
|
44
|
-
pnpm run build
|
|
45
|
-
|
|
46
|
-
# yarn
|
|
47
|
-
yarn build
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
Locally preview production build:
|
|
51
|
-
|
|
52
|
-
```bash
|
|
53
|
-
# npm
|
|
54
|
-
npm run preview
|
|
55
|
-
|
|
56
|
-
# pnpm
|
|
57
|
-
pnpm run preview
|
|
58
|
-
|
|
59
|
-
# yarn
|
|
60
|
-
yarn preview
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
Check out the [deployment documentation](https://nuxt.com/docs/getting-started/deployment) for more information.
|
package/nuxt.config.ts
DELETED