@geode/opengeodeweb-front 10.3.3-rc.1 → 10.4.0-rc.1
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/DeleteDialog.vue +122 -0
- package/app/components/GlassCard.vue +1 -2
- package/app/components/SearchBar.vue +34 -0
- package/app/components/Stepper.vue +2 -2
- package/app/stores/data.js +4 -15
- package/app/stores/data_style.js +3 -2
- package/app/stores/hybrid_viewer.js +2 -2
- package/internal/database/database.js +38 -15
- package/internal/database/extended_database.js +2 -2
- package/package.json +1 -1
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import GlassCard from "./GlassCard.vue"
|
|
3
|
+
|
|
4
|
+
const { show, item, selectedCount } = defineProps({
|
|
5
|
+
show: {
|
|
6
|
+
type: Boolean,
|
|
7
|
+
default: false,
|
|
8
|
+
},
|
|
9
|
+
item: {
|
|
10
|
+
type: Object,
|
|
11
|
+
default: null,
|
|
12
|
+
},
|
|
13
|
+
selectedCount: {
|
|
14
|
+
type: Number,
|
|
15
|
+
default: 0,
|
|
16
|
+
},
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
const emit = defineEmits(["update:show", "confirm"])
|
|
20
|
+
</script>
|
|
21
|
+
|
|
22
|
+
<template>
|
|
23
|
+
<v-dialog
|
|
24
|
+
:model-value="show"
|
|
25
|
+
@update:model-value="emit('update:show', $event)"
|
|
26
|
+
max-width="400"
|
|
27
|
+
>
|
|
28
|
+
<GlassCard v-if="item" variant="panel" padding="pa-8">
|
|
29
|
+
<v-card-title
|
|
30
|
+
class="pb-2 text-h5 font-weight-bold d-flex align-center text-white"
|
|
31
|
+
>
|
|
32
|
+
<v-icon
|
|
33
|
+
icon="mdi-trash-can-outline"
|
|
34
|
+
class="mr-3 text-h4"
|
|
35
|
+
color="error"
|
|
36
|
+
></v-icon>
|
|
37
|
+
Delete Item
|
|
38
|
+
</v-card-title>
|
|
39
|
+
|
|
40
|
+
<v-card-text class="pa-0 mt-4 text-white opacity-80">
|
|
41
|
+
Are you sure you want to delete this item?
|
|
42
|
+
<div
|
|
43
|
+
class="bg-white-opacity-5 rounded-lg pa-4 my-6 font-weight-bold border-thin text-center"
|
|
44
|
+
>
|
|
45
|
+
{{ item.name }}
|
|
46
|
+
</div>
|
|
47
|
+
</v-card-text>
|
|
48
|
+
|
|
49
|
+
<v-card-actions class="px-0 pb-0">
|
|
50
|
+
<v-btn
|
|
51
|
+
variant="text"
|
|
52
|
+
color="white"
|
|
53
|
+
size="large"
|
|
54
|
+
@click="emit('update:show', false)"
|
|
55
|
+
class="text-none rounded-lg"
|
|
56
|
+
>
|
|
57
|
+
<v-icon start>mdi-close-circle-outline</v-icon>
|
|
58
|
+
Cancel
|
|
59
|
+
</v-btn>
|
|
60
|
+
|
|
61
|
+
<v-spacer />
|
|
62
|
+
|
|
63
|
+
<v-btn
|
|
64
|
+
color="error"
|
|
65
|
+
size="large"
|
|
66
|
+
variant="flat"
|
|
67
|
+
@click="emit('confirm')"
|
|
68
|
+
class="text-none rounded-lg font-weight-bold"
|
|
69
|
+
elevation="4"
|
|
70
|
+
>
|
|
71
|
+
<v-icon start>mdi-trash-can-outline</v-icon>
|
|
72
|
+
Delete
|
|
73
|
+
</v-btn>
|
|
74
|
+
</v-card-actions>
|
|
75
|
+
</GlassCard>
|
|
76
|
+
|
|
77
|
+
<GlassCard v-else variant="panel" padding="pa-8">
|
|
78
|
+
<v-card-title
|
|
79
|
+
class="pb-2 text-h5 font-weight-bold d-flex align-center text-white"
|
|
80
|
+
>
|
|
81
|
+
<v-icon
|
|
82
|
+
icon="mdi-alert-circle-outline"
|
|
83
|
+
class="mr-3 text-h4"
|
|
84
|
+
color="error"
|
|
85
|
+
></v-icon>
|
|
86
|
+
Delete Items
|
|
87
|
+
</v-card-title>
|
|
88
|
+
|
|
89
|
+
<v-card-text class="pa-0 mt-4 text-white opacity-80">
|
|
90
|
+
Are you sure you want to delete
|
|
91
|
+
<strong class="text-white">{{ selectedCount }}</strong> items?
|
|
92
|
+
</v-card-text>
|
|
93
|
+
|
|
94
|
+
<v-card-actions class="px-0 pb-0 mt-8">
|
|
95
|
+
<v-btn
|
|
96
|
+
variant="text"
|
|
97
|
+
color="white"
|
|
98
|
+
size="large"
|
|
99
|
+
@click="emit('update:show', false)"
|
|
100
|
+
class="text-none rounded-lg"
|
|
101
|
+
>
|
|
102
|
+
<v-icon start>mdi-close-circle-outline</v-icon>
|
|
103
|
+
Cancel
|
|
104
|
+
</v-btn>
|
|
105
|
+
|
|
106
|
+
<v-spacer />
|
|
107
|
+
|
|
108
|
+
<v-btn
|
|
109
|
+
color="error"
|
|
110
|
+
size="large"
|
|
111
|
+
variant="flat"
|
|
112
|
+
@click="emit('confirm')"
|
|
113
|
+
class="text-none rounded-lg font-weight-bold"
|
|
114
|
+
elevation="4"
|
|
115
|
+
>
|
|
116
|
+
<v-icon start>mdi-trash-can-outline</v-icon>
|
|
117
|
+
Delete All
|
|
118
|
+
</v-btn>
|
|
119
|
+
</v-card-actions>
|
|
120
|
+
</GlassCard>
|
|
121
|
+
</v-dialog>
|
|
122
|
+
</template>
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
<script setup>
|
|
2
|
+
import { computed, useAttrs } from "vue"
|
|
2
3
|
defineProps({
|
|
3
4
|
variant: {
|
|
4
5
|
type: String,
|
|
@@ -16,11 +17,9 @@
|
|
|
16
17
|
|
|
17
18
|
<template>
|
|
18
19
|
<v-card
|
|
19
|
-
v-bind="$attrs"
|
|
20
20
|
@mousedown.stop
|
|
21
21
|
@click.stop
|
|
22
22
|
@dblclick.stop
|
|
23
|
-
@wheel.stop
|
|
24
23
|
@contextmenu.stop
|
|
25
24
|
flat
|
|
26
25
|
:ripple="isInteractive"
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<v-text-field
|
|
3
|
+
:model-value="modelValue"
|
|
4
|
+
@update:model-value="$emit('update:modelValue', $event)"
|
|
5
|
+
prepend-inner-icon="mdi-magnify"
|
|
6
|
+
:label="label"
|
|
7
|
+
variant="outlined"
|
|
8
|
+
density="compact"
|
|
9
|
+
hide-details
|
|
10
|
+
bg-color="transparent"
|
|
11
|
+
color="white"
|
|
12
|
+
base-color="white"
|
|
13
|
+
v-bind="$attrs"
|
|
14
|
+
>
|
|
15
|
+
<template v-for="(_, slot) in $slots" v-slot:[slot]="scope">
|
|
16
|
+
<slot :name="slot" v-bind="scope || {}"></slot>
|
|
17
|
+
</template>
|
|
18
|
+
</v-text-field>
|
|
19
|
+
</template>
|
|
20
|
+
|
|
21
|
+
<script setup>
|
|
22
|
+
defineProps({
|
|
23
|
+
modelValue: {
|
|
24
|
+
type: String,
|
|
25
|
+
default: "",
|
|
26
|
+
},
|
|
27
|
+
label: {
|
|
28
|
+
type: String,
|
|
29
|
+
default: "Search...",
|
|
30
|
+
},
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
defineEmits(["update:modelValue"])
|
|
34
|
+
</script>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import Step from "@ogw_front/components/Step"
|
|
3
3
|
|
|
4
|
-
const emit = defineEmits(["reset_values"])
|
|
4
|
+
const emit = defineEmits(["reset_values", "close"])
|
|
5
5
|
const stepper_tree = inject("stepper_tree")
|
|
6
6
|
const { steps, current_step_index } = toRefs(stepper_tree)
|
|
7
7
|
</script>
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
@update:model-value="current_step_index = $event - 1"
|
|
29
29
|
flat
|
|
30
30
|
non-linear
|
|
31
|
-
class="pa-0 ma-0 bg-transparent rounded-xl overflow-hidden custom-stepper"
|
|
31
|
+
class="pa-0 ma-0 bg-transparent rounded-xl overflow-hidden custom-stepper flex-grow-1"
|
|
32
32
|
>
|
|
33
33
|
<Step
|
|
34
34
|
v-for="(step, index) in steps"
|
package/app/stores/data.js
CHANGED
|
@@ -15,32 +15,21 @@ const viewer_generic_schemas = viewer_schemas.opengeodeweb_viewer.generic
|
|
|
15
15
|
export const useDataStore = defineStore("data", () => {
|
|
16
16
|
const viewerStore = useViewerStore()
|
|
17
17
|
|
|
18
|
-
const itemCache = new Map()
|
|
19
18
|
function getItem(id) {
|
|
20
19
|
if (!id) {
|
|
21
|
-
|
|
22
|
-
emptyRef.fetch = async () => ({})
|
|
23
|
-
return emptyRef
|
|
20
|
+
return ref({})
|
|
24
21
|
}
|
|
25
|
-
|
|
26
|
-
return itemCache.get(id)
|
|
27
|
-
}
|
|
28
|
-
const observable = useObservable(
|
|
22
|
+
return useObservable(
|
|
29
23
|
liveQuery(() => database.data.get(id)),
|
|
30
24
|
{ initialValue: {} },
|
|
31
25
|
)
|
|
32
|
-
observable.fetch = () => database.data.get(id)
|
|
33
|
-
itemCache.set(id, observable)
|
|
34
|
-
return observable
|
|
35
26
|
}
|
|
36
27
|
|
|
37
28
|
function getAllItems() {
|
|
38
|
-
|
|
29
|
+
return useObservable(
|
|
39
30
|
liveQuery(() => database.data.toArray()),
|
|
40
31
|
{ initialValue: [] },
|
|
41
32
|
)
|
|
42
|
-
observable.fetch = () => database.data.toArray()
|
|
43
|
-
return observable
|
|
44
33
|
}
|
|
45
34
|
|
|
46
35
|
async function formatedMeshComponents(id) {
|
|
@@ -167,7 +156,7 @@ export const useDataStore = defineStore("data", () => {
|
|
|
167
156
|
}
|
|
168
157
|
|
|
169
158
|
async function exportStores() {
|
|
170
|
-
const items = await
|
|
159
|
+
const items = await database.data.toArray()
|
|
171
160
|
return { items }
|
|
172
161
|
}
|
|
173
162
|
|
package/app/stores/data_style.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { getDefaultStyle } from "@ogw_front/utils/default_styles"
|
|
2
|
+
import { database } from "../../internal/database/database.js"
|
|
2
3
|
import { useDataStore } from "@ogw_front/stores/data"
|
|
3
4
|
import { useDataStyleStateStore } from "../../internal/stores/data_style/state"
|
|
4
5
|
import useMeshStyle from "../../internal/stores/data_style/mesh/index"
|
|
@@ -15,7 +16,7 @@ export const useDataStyleStore = defineStore("dataStyle", () => {
|
|
|
15
16
|
}
|
|
16
17
|
|
|
17
18
|
async function setVisibility(id, visibility) {
|
|
18
|
-
const item = await
|
|
19
|
+
const item = await database.data.get(id)
|
|
19
20
|
const viewer_type = item?.viewer_type
|
|
20
21
|
if (!viewer_type) {
|
|
21
22
|
throw new Error(`Item not found or not loaded: ${id}`)
|
|
@@ -31,7 +32,7 @@ export const useDataStyleStore = defineStore("dataStyle", () => {
|
|
|
31
32
|
}
|
|
32
33
|
|
|
33
34
|
async function applyDefaultStyle(id) {
|
|
34
|
-
const item = await
|
|
35
|
+
const item = await database.data.get(id)
|
|
35
36
|
const viewer_type = item?.viewer_type
|
|
36
37
|
if (!viewer_type) {
|
|
37
38
|
throw new Error(`Item not found or not loaded: ${id}`)
|
|
@@ -6,6 +6,7 @@ import { newInstance as vtkMapper } from "@kitware/vtk.js/Rendering/Core/Mapper"
|
|
|
6
6
|
import { newInstance as vtkXMLPolyDataReader } from "@kitware/vtk.js/IO/XML/XMLPolyDataReader"
|
|
7
7
|
|
|
8
8
|
import Status from "@ogw_front/utils/status"
|
|
9
|
+
import { database } from "../../internal/database/database.js"
|
|
9
10
|
import { useDataStore } from "@ogw_front/stores/data"
|
|
10
11
|
import { useViewerStore } from "@ogw_front/stores/viewer"
|
|
11
12
|
import viewer_schemas from "@geode/opengeodeweb-viewer/opengeodeweb_viewer_schemas.json"
|
|
@@ -73,8 +74,7 @@ export const useHybridViewerStore = defineStore("hybridViewer", () => {
|
|
|
73
74
|
if (!genericRenderWindow.value) {
|
|
74
75
|
return
|
|
75
76
|
}
|
|
76
|
-
const
|
|
77
|
-
const value = await item.fetch()
|
|
77
|
+
const value = await database.data.get(id)
|
|
78
78
|
console.log("hybridViewerStore.addItem", { value })
|
|
79
79
|
const reader = vtkXMLPolyDataReader()
|
|
80
80
|
const textEncoder = new TextEncoder()
|
|
@@ -14,37 +14,60 @@ class Database extends Dexie {
|
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
static async addTable(tableName, schemaDefinition) {
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
await this.addTables({ [tableName]: schemaDefinition })
|
|
18
|
+
}
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
}
|
|
20
|
+
static async addTables(newTables) {
|
|
21
|
+
const tempDb = new Dexie("Database")
|
|
22
|
+
await tempDb.open()
|
|
24
23
|
|
|
25
24
|
const currentVersion = tempDb.verno
|
|
26
25
|
const currentStores = {}
|
|
27
26
|
|
|
27
|
+
currentStores[dataTable.name] = dataTable.schema
|
|
28
|
+
currentStores[modelComponentsTable.name] = modelComponentsTable.schema
|
|
29
|
+
|
|
28
30
|
for (const table of tempDb.tables) {
|
|
29
31
|
const keyPath = table.schema.primKey.src
|
|
30
32
|
const indexes = table.schema.indexes.map((index) => index.src)
|
|
31
|
-
|
|
33
|
+
const parts = keyPath ? [keyPath, ...indexes] : indexes
|
|
34
|
+
currentStores[table.name] = parts.join(",")
|
|
32
35
|
}
|
|
33
36
|
|
|
34
37
|
tempDb.close()
|
|
35
38
|
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
currentStores,
|
|
39
|
-
tableName,
|
|
40
|
-
schemaDefinition,
|
|
39
|
+
const allExisting = Object.keys(newTables).every(
|
|
40
|
+
(tableName) => currentStores[tableName],
|
|
41
41
|
)
|
|
42
|
-
await newDb.open()
|
|
43
42
|
|
|
44
|
-
|
|
43
|
+
database.close()
|
|
44
|
+
|
|
45
|
+
if (allExisting) {
|
|
46
|
+
const existingDb = new Dexie("Database")
|
|
47
|
+
for (let version = 1; version <= currentVersion; version += 1) {
|
|
48
|
+
if (version === 1) {
|
|
49
|
+
existingDb.version(1).stores({
|
|
50
|
+
[dataTable.name]: dataTable.schema,
|
|
51
|
+
[modelComponentsTable.name]: modelComponentsTable.schema,
|
|
52
|
+
})
|
|
53
|
+
} else {
|
|
54
|
+
existingDb.version(version).stores(currentStores)
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
await existingDb.open()
|
|
58
|
+
database = existingDb
|
|
59
|
+
} else {
|
|
60
|
+
const newDb = new ExtendedDatabase(
|
|
61
|
+
currentVersion,
|
|
62
|
+
currentStores,
|
|
63
|
+
newTables,
|
|
64
|
+
)
|
|
65
|
+
await newDb.open()
|
|
66
|
+
database = newDb
|
|
67
|
+
}
|
|
45
68
|
}
|
|
46
69
|
}
|
|
47
70
|
|
|
48
|
-
|
|
71
|
+
let database = new Database()
|
|
49
72
|
|
|
50
73
|
export { Database, database }
|
|
@@ -3,7 +3,7 @@ import { dataTable } from "./tables/data_table"
|
|
|
3
3
|
import { modelComponentsTable } from "./tables/model_components"
|
|
4
4
|
|
|
5
5
|
export class ExtendedDatabase extends Dexie {
|
|
6
|
-
constructor(currentVersion, currentStores,
|
|
6
|
+
constructor(currentVersion, currentStores, newTables) {
|
|
7
7
|
super("Database")
|
|
8
8
|
|
|
9
9
|
for (let version = 1; version <= currentVersion; version += 1) {
|
|
@@ -19,7 +19,7 @@ export class ExtendedDatabase extends Dexie {
|
|
|
19
19
|
|
|
20
20
|
this.version(currentVersion + 1).stores({
|
|
21
21
|
...currentStores,
|
|
22
|
-
|
|
22
|
+
...newTables,
|
|
23
23
|
})
|
|
24
24
|
}
|
|
25
25
|
}
|
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.
|
|
5
|
+
"version": "10.4.0-rc.1",
|
|
6
6
|
"main": "./nuxt.config.js",
|
|
7
7
|
"scripts": {
|
|
8
8
|
"lint": "eslint --fix --ext .js,.vue --ignore-path .gitignore .",
|