@geode/opengeodeweb-front 10.34.0-rc.12 → 10.34.0-rc.13
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/.build/shared/utils/fetch_raw.js +6 -6
- package/app/composables/clipping_planes_widget.ts +5 -5
- package/app/composables/clipping_planes_widget_entries.ts +6 -8
- package/app/composables/global_attribute_style.ts +1 -1
- package/app/composables/hover_highlight.ts +3 -3
- package/app/composables/project_manager.ts +1 -1
- package/app/composables/responsive_middle_truncate.ts +3 -3
- package/app/composables/stepper_tree.ts +5 -5
- package/app/composables/tree_filter.ts +3 -7
- package/app/composables/tree_keyboard_nav.ts +8 -8
- package/app/composables/tree_scroll.ts +10 -10
- package/app/composables/use_adaptive_styles.ts +1 -1
- package/app/composables/use_overlapping_picker.ts +10 -13
- package/app/composables/virtual_tree.ts +6 -14
- package/app/plugins/auto_store_register.ts +1 -1
- package/app/stores/app.ts +10 -15
- package/app/stores/back.ts +3 -6
- package/app/stores/camera_manager.ts +2 -5
- package/app/stores/data.ts +16 -16
- package/app/stores/data_helpers/collections.ts +6 -14
- package/app/stores/data_helpers/mesh.ts +6 -8
- package/app/stores/data_style.ts +7 -7
- package/app/stores/hybrid_viewer.ts +1 -1
- package/app/stores/infra.ts +15 -21
- package/app/stores/menu.ts +1 -1
- package/app/stores/treeview.ts +7 -7
- package/app/stores/viewer.ts +4 -4
- package/app/utils/attributes.ts +1 -1
- package/app/utils/clipping_planes.ts +12 -17
- package/app/utils/colormap.ts +1 -1
- package/app/utils/default_styles/meshes.ts +5 -5
- package/app/utils/default_styles/models.ts +4 -4
- package/app/utils/extension.ts +6 -10
- package/app/utils/import_workflow.ts +3 -3
- package/app/utils/log.ts +4 -4
- package/internal/stores/data_style/mesh/cells/index.ts +10 -10
- package/internal/stores/data_style/mesh/edges/index.ts +10 -10
- package/internal/stores/data_style/mesh/points/common.ts +5 -6
- package/internal/stores/data_style/mesh/points/index.ts +8 -8
- package/internal/stores/data_style/mesh/polygons/index.ts +10 -10
- package/internal/stores/data_style/mesh/polyhedra/index.ts +9 -11
- package/internal/stores/data_style/state.ts +12 -15
- package/internal/stores/hybrid_viewer/brightness.ts +6 -13
- package/internal/stores/hybrid_viewer/core.ts +1 -1
- package/package.json +1 -1
- package/server/api/microservice/extensions/download.post.ts +1 -1
- package/server/utils/app_config.ts +1 -1
- package/server/utils/cleanup.ts +6 -8
- package/server/utils/microservices.ts +6 -9
- package/server/utils/scripts.ts +2 -2
- package/server/utils/ws_client.ts +5 -9
- package/shared/utils/call_raw.ts +7 -18
- package/shared/utils/call_schema.ts +5 -5
- package/shared/utils/fetch_raw.ts +18 -18
- package/shared/utils/fetch_schema.ts +4 -11
- package/shared/utils/response_handlers/load.ts +1 -1
- package/shared/utils/types.ts +3 -3
- package/shared/utils/validate_schema.ts +1 -4
package/app/stores/data.ts
CHANGED
|
@@ -65,7 +65,7 @@ const viewer_generic_schemas = viewer_schemas.opengeodeweb_viewer.generic;
|
|
|
65
65
|
type DatabaseTables = Record<string, unknown>;
|
|
66
66
|
// oxlint-disable-next-line no-unsafe-type-assertion -- see comment above.
|
|
67
67
|
const typedDatabase = database as unknown as DatabaseTables;
|
|
68
|
-
function checkItemViewable(item:
|
|
68
|
+
function checkItemViewable(item: ViewableItemLike | undefined | null): boolean {
|
|
69
69
|
if (!item || typeof item !== "object") {
|
|
70
70
|
return false;
|
|
71
71
|
}
|
|
@@ -84,7 +84,7 @@ function checkItemViewable(item: Readonly<ViewableItemLike> | undefined | null):
|
|
|
84
84
|
}
|
|
85
85
|
return true;
|
|
86
86
|
}
|
|
87
|
-
function isItemViewable(itemOrId: string |
|
|
87
|
+
function isItemViewable(itemOrId: string | ViewableItemLike): boolean | Promise<boolean> {
|
|
88
88
|
if (typeof itemOrId === "string") {
|
|
89
89
|
// oxlint-disable-next-line no-unsafe-type-assertion -- database's table map is dynamically typed at runtime; see comment above.
|
|
90
90
|
return (typedDatabase.data as Table<DataItem, string>).get(itemOrId).then(checkItemViewable);
|
|
@@ -134,7 +134,7 @@ export const useDataStore = defineStore("data", () => {
|
|
|
134
134
|
const items = await data_db.toArray();
|
|
135
135
|
return items;
|
|
136
136
|
}
|
|
137
|
-
function refItem(id: string):
|
|
137
|
+
function refItem(id: string): Ref<DataItem | undefined> {
|
|
138
138
|
// Dexie's liveQuery() returns Dexie's own minimal Observable shape, not an
|
|
139
139
|
// Actual rxjs Observable instance (useObservable's declared parameter type);
|
|
140
140
|
// The two are structurally close enough at runtime (vueuse only calls
|
|
@@ -151,7 +151,7 @@ export const useDataStore = defineStore("data", () => {
|
|
|
151
151
|
},
|
|
152
152
|
);
|
|
153
153
|
}
|
|
154
|
-
function refAllItems():
|
|
154
|
+
function refAllItems(): Ref<DataItem[]> {
|
|
155
155
|
return useObservable(
|
|
156
156
|
liveQuery(async () => {
|
|
157
157
|
const items = await data_db.toArray();
|
|
@@ -194,9 +194,9 @@ export const useDataStore = defineStore("data", () => {
|
|
|
194
194
|
});
|
|
195
195
|
return result;
|
|
196
196
|
}
|
|
197
|
-
// NewDataItem has mutable array fields (mesh_components, collection_components), so
|
|
198
|
-
//
|
|
199
|
-
async function addItem(new_item:
|
|
197
|
+
// NewDataItem has mutable array fields (mesh_components, collection_components), so it can't
|
|
198
|
+
// Satisfy prefer-readonly-parameter-types deeply; same pattern as app/utils/import_workflow.ts.
|
|
199
|
+
async function addItem(new_item: NewDataItem): Promise<string> {
|
|
200
200
|
const itemData: DataItem = {
|
|
201
201
|
id: new_item.id,
|
|
202
202
|
name: new_item.name ?? new_item.id,
|
|
@@ -212,9 +212,9 @@ export const useDataStore = defineStore("data", () => {
|
|
|
212
212
|
const id = await data_db.put(itemData);
|
|
213
213
|
return id;
|
|
214
214
|
}
|
|
215
|
-
// NewDataItem has mutable array fields (mesh_components, collection_components), so
|
|
216
|
-
//
|
|
217
|
-
async function addComponents(new_item:
|
|
215
|
+
// NewDataItem has mutable array fields (mesh_components, collection_components), so it can't
|
|
216
|
+
// Satisfy prefer-readonly-parameter-types deeply; same pattern as app/utils/import_workflow.ts.
|
|
217
|
+
async function addComponents(new_item: NewDataItem): Promise<string> {
|
|
218
218
|
const allComponents: ModelComponentRecord[] = [];
|
|
219
219
|
// ModelComponentInput has mutable array fields (boundaries, internals, items), so a readonly
|
|
220
220
|
// Array of it can't satisfy prefer-readonly-parameter-types deeply; same limitation as above.
|
|
@@ -239,9 +239,9 @@ export const useDataStore = defineStore("data", () => {
|
|
|
239
239
|
const lastKey = await model_components_db.bulkPut(allComponents);
|
|
240
240
|
return lastKey;
|
|
241
241
|
}
|
|
242
|
-
// NewDataItem has mutable array fields (mesh_components, collection_components), so
|
|
243
|
-
//
|
|
244
|
-
async function addComponentRelations(new_item:
|
|
242
|
+
// NewDataItem has mutable array fields (mesh_components, collection_components), so it can't
|
|
243
|
+
// Satisfy prefer-readonly-parameter-types deeply; same pattern as app/utils/import_workflow.ts.
|
|
244
|
+
async function addComponentRelations(new_item: NewDataItem): Promise<string> {
|
|
245
245
|
const relations: ModelComponentRelationRecord[] = [];
|
|
246
246
|
function addModelComponentRelations(
|
|
247
247
|
components: readonly string[],
|
|
@@ -284,7 +284,7 @@ export const useDataStore = defineStore("data", () => {
|
|
|
284
284
|
const component = await model_components_db
|
|
285
285
|
.where("viewer_id")
|
|
286
286
|
.equals(Number(viewer_id))
|
|
287
|
-
.and((model_component:
|
|
287
|
+
.and((model_component: ModelComponentRecord) => model_component.id === modelId)
|
|
288
288
|
.first();
|
|
289
289
|
return component;
|
|
290
290
|
}
|
|
@@ -304,7 +304,7 @@ export const useDataStore = defineStore("data", () => {
|
|
|
304
304
|
|
|
305
305
|
async function getAllModelComponentsViewerIds(modelId: string): Promise<number[]> {
|
|
306
306
|
const components = await model_components_db.where("id").equals(modelId).toArray();
|
|
307
|
-
return components.map((component:
|
|
307
|
+
return components.map((component: ModelComponentRecord) =>
|
|
308
308
|
Math.trunc(Number(component.viewer_id)),
|
|
309
309
|
);
|
|
310
310
|
}
|
|
@@ -316,7 +316,7 @@ export const useDataStore = defineStore("data", () => {
|
|
|
316
316
|
.where("[id+geode_id]")
|
|
317
317
|
.anyOf(meshComponentGeodeIds.map((geode_id) => [modelId, geode_id]))
|
|
318
318
|
.toArray();
|
|
319
|
-
return components.map((component:
|
|
319
|
+
return components.map((component: ModelComponentRecord) =>
|
|
320
320
|
Math.trunc(Number(component.viewer_id)),
|
|
321
321
|
);
|
|
322
322
|
}
|
|
@@ -48,10 +48,7 @@ export function useDataCollections(): {
|
|
|
48
48
|
const count = await model_components_db
|
|
49
49
|
.where("id")
|
|
50
50
|
.equals(modelId)
|
|
51
|
-
.and(
|
|
52
|
-
(component: Readonly<ModelComponentRecord>) =>
|
|
53
|
-
!MESH_COMPONENT_TYPES.includes(component.type),
|
|
54
|
-
)
|
|
51
|
+
.and((component: ModelComponentRecord) => !MESH_COMPONENT_TYPES.includes(component.type))
|
|
55
52
|
.count();
|
|
56
53
|
return count > 0;
|
|
57
54
|
}
|
|
@@ -59,11 +56,8 @@ export function useDataCollections(): {
|
|
|
59
56
|
async function getAllCollectionComponents(modelId: string): Promise<FormattedComponent[]> {
|
|
60
57
|
const items = await model_components_db.where("id").equals(modelId).toArray();
|
|
61
58
|
return items
|
|
62
|
-
.filter(
|
|
63
|
-
|
|
64
|
-
!MESH_COMPONENT_TYPES.includes(component.type),
|
|
65
|
-
)
|
|
66
|
-
.map((component: Readonly<ModelComponentRecord>) => ({
|
|
59
|
+
.filter((component: ModelComponentRecord) => !MESH_COMPONENT_TYPES.includes(component.type))
|
|
60
|
+
.map((component: ModelComponentRecord) => ({
|
|
67
61
|
id: component.geode_id,
|
|
68
62
|
title: component.name,
|
|
69
63
|
category: component.type,
|
|
@@ -87,13 +81,11 @@ export function useDataCollections(): {
|
|
|
87
81
|
for (const component of components) {
|
|
88
82
|
byType[component.category] ??= [];
|
|
89
83
|
const itemRelations = relations.filter(
|
|
90
|
-
(relation:
|
|
84
|
+
(relation: ModelComponentRelationRecord) =>
|
|
91
85
|
relation.parent === component.id && relation.type === "collection",
|
|
92
86
|
);
|
|
93
87
|
const children = itemRelations
|
|
94
|
-
.map(
|
|
95
|
-
(relation: Readonly<ModelComponentRelationRecord>) => meshComponentsById[relation.child],
|
|
96
|
-
)
|
|
88
|
+
.map((relation: ModelComponentRelationRecord) => meshComponentsById[relation.child])
|
|
97
89
|
.filter((child): child is FormattedComponent => Boolean(child));
|
|
98
90
|
byType[component.category]?.push({
|
|
99
91
|
...component,
|
|
@@ -120,7 +112,7 @@ export function useDataCollections(): {
|
|
|
120
112
|
|
|
121
113
|
function refFormatedCollectionComponents(
|
|
122
114
|
modelId: string,
|
|
123
|
-
):
|
|
115
|
+
): Ref<CollectionComponentGroup[] | undefined> {
|
|
124
116
|
return useObservable(
|
|
125
117
|
// Dexie's liveQuery returns its own Observable-like type, not rxjs's Observable, so bridging needs a cast.
|
|
126
118
|
liveQuery(async () => {
|
|
@@ -26,7 +26,7 @@ interface FormattedComponentGroup {
|
|
|
26
26
|
readonly children: readonly FormattedComponent[];
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
function toFormattedComponent(meshComponent:
|
|
29
|
+
function toFormattedComponent(meshComponent: ModelComponentRecord): FormattedComponent {
|
|
30
30
|
return {
|
|
31
31
|
id: meshComponent.geode_id,
|
|
32
32
|
title: meshComponent.name,
|
|
@@ -77,15 +77,13 @@ export function useDataMesh(): {
|
|
|
77
77
|
.map((type) => ({
|
|
78
78
|
id: type,
|
|
79
79
|
title: componentTitles[type] ?? type,
|
|
80
|
-
children: (componentsByType[type] ?? []).map((item:
|
|
80
|
+
children: (componentsByType[type] ?? []).map((item: ModelComponentRecord) =>
|
|
81
81
|
toFormattedComponent(item),
|
|
82
82
|
),
|
|
83
83
|
}));
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
-
function refFormatedMeshComponents(
|
|
87
|
-
modelId: string,
|
|
88
|
-
): Readonly<Ref<FormattedComponentGroup[] | undefined>> {
|
|
86
|
+
function refFormatedMeshComponents(modelId: string): Ref<FormattedComponentGroup[] | undefined> {
|
|
89
87
|
return useObservable(
|
|
90
88
|
liveQuery(async () => {
|
|
91
89
|
const components = await formatedMeshComponents(modelId);
|
|
@@ -106,12 +104,12 @@ export function useDataMesh(): {
|
|
|
106
104
|
.where("[id+type]")
|
|
107
105
|
.equals([modelId, type])
|
|
108
106
|
.toArray();
|
|
109
|
-
return components.map((item:
|
|
107
|
+
return components.map((item: ModelComponentRecord) => toFormattedComponent(item));
|
|
110
108
|
}
|
|
111
109
|
|
|
112
110
|
async function getAllMeshComponents(modelId: string): Promise<FormattedComponent[]> {
|
|
113
111
|
const items = await model_components_db.where("id").equals(modelId).toArray();
|
|
114
|
-
return items.map((item:
|
|
112
|
+
return items.map((item: ModelComponentRecord) => toFormattedComponent(item));
|
|
115
113
|
}
|
|
116
114
|
|
|
117
115
|
async function fetchAllMeshComponents(
|
|
@@ -131,7 +129,7 @@ export function useDataMesh(): {
|
|
|
131
129
|
.where("[id+type]")
|
|
132
130
|
.equals([modelId, type])
|
|
133
131
|
.toArray();
|
|
134
|
-
return components.map((component:
|
|
132
|
+
return components.map((component: ModelComponentRecord) => component.geode_id);
|
|
135
133
|
}
|
|
136
134
|
|
|
137
135
|
async function getCornersGeodeIds(modelId: string): Promise<string[]> {
|
package/app/stores/data_style.ts
CHANGED
|
@@ -12,9 +12,9 @@ import { useMeshStyle } from "@ogw_internal/stores/data_style/mesh/index";
|
|
|
12
12
|
import { useModelStyle } from "@ogw_internal/stores/data_style/model/index";
|
|
13
13
|
|
|
14
14
|
interface DataStyleSnapshot {
|
|
15
|
-
readonly styles:
|
|
16
|
-
readonly componentStyles:
|
|
17
|
-
readonly modelComponentTypeStyles:
|
|
15
|
+
readonly styles: Record<string, ObjectStyle>;
|
|
16
|
+
readonly componentStyles: Record<string, ModelComponentStyle>;
|
|
17
|
+
readonly modelComponentTypeStyles: Record<string, ModelComponentTypeStyle>;
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
// The database's table map is dynamically assembled at runtime (see internal/database/database.ts), so its exported type is a loose `{}`; cast it to the shape it actually has at runtime rather than widening every call site.
|
|
@@ -100,7 +100,7 @@ export const useDataStyleStore = defineStore("dataStyle", () => {
|
|
|
100
100
|
}
|
|
101
101
|
|
|
102
102
|
// oxlint-disable-next-line prefer-readonly-parameter-types -- ObjectStyle (external type) has a mutable index signature and mutable nested StyleValues fields that can't be marked readonly from here.
|
|
103
|
-
async function importStores(snapshot:
|
|
103
|
+
async function importStores(snapshot: DataStyleSnapshot): Promise<void> {
|
|
104
104
|
const stylesSnapshot = snapshot.styles;
|
|
105
105
|
const componentStylesSnapshot = snapshot.componentStyles;
|
|
106
106
|
const modelComponentTypeStylesSnapshot = snapshot.modelComponentTypeStyles;
|
|
@@ -109,19 +109,19 @@ export const useDataStyleStore = defineStore("dataStyle", () => {
|
|
|
109
109
|
|
|
110
110
|
const style_promises = Object.entries(stylesSnapshot).map(
|
|
111
111
|
// oxlint-disable-next-line prefer-readonly-parameter-types -- same external ObjectStyle limitation as above.
|
|
112
|
-
async ([id, style]: readonly [string,
|
|
112
|
+
async ([id, style]: readonly [string, ObjectStyle]) => {
|
|
113
113
|
const key = await data_style_db.put(structuredClone({ ...style, id }));
|
|
114
114
|
return key;
|
|
115
115
|
},
|
|
116
116
|
);
|
|
117
117
|
const component_style_promises = Object.values(componentStylesSnapshot).map(
|
|
118
|
-
async (style:
|
|
118
|
+
async (style: ModelComponentStyle) => {
|
|
119
119
|
const key = await component_datastyle_db.put(structuredClone(style));
|
|
120
120
|
return key;
|
|
121
121
|
},
|
|
122
122
|
);
|
|
123
123
|
const model_component_type_style_promises = Object.values(modelComponentTypeStylesSnapshot).map(
|
|
124
|
-
async (style:
|
|
124
|
+
async (style: ModelComponentTypeStyle) => {
|
|
125
125
|
const key = await model_component_type_datastyle_db.put(structuredClone(style));
|
|
126
126
|
return key;
|
|
127
127
|
},
|
|
@@ -82,7 +82,7 @@ export const useHybridViewerStore = defineStore("hybridViewer", () => {
|
|
|
82
82
|
};
|
|
83
83
|
const imageStream = clientApi.getImageStream();
|
|
84
84
|
viewportStore.viewStream.value = imageStream.createViewStream("-1");
|
|
85
|
-
viewportStore.viewStream.value?.onImageReady((event:
|
|
85
|
+
viewportStore.viewStream.value?.onImageReady((event: { image: unknown }) => {
|
|
86
86
|
if (is_moving.value) {
|
|
87
87
|
return;
|
|
88
88
|
}
|
package/app/stores/infra.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { useCloudStore } from "@ogw_front/stores/cloud";
|
|
|
5
5
|
|
|
6
6
|
interface ElectronApi {
|
|
7
7
|
electronAPI: {
|
|
8
|
-
project_folder_path: (args:
|
|
8
|
+
project_folder_path: (args: { projectFolderPath: string }) => void;
|
|
9
9
|
};
|
|
10
10
|
}
|
|
11
11
|
|
|
@@ -23,29 +23,25 @@ export const useInfraStore = defineStore("infra", {
|
|
|
23
23
|
}),
|
|
24
24
|
getters: {
|
|
25
25
|
microservices_connected(): boolean {
|
|
26
|
-
return this.microservices.every(
|
|
27
|
-
(store: Readonly<Microservice>) => store.status === Status.CONNECTED,
|
|
28
|
-
);
|
|
26
|
+
return this.microservices.every((store: Microservice) => store.status === Status.CONNECTED);
|
|
29
27
|
},
|
|
30
28
|
microservices_busy(): boolean {
|
|
31
|
-
return this.microservices.some((store:
|
|
29
|
+
return this.microservices.some((store: Microservice) => store.is_busy === true);
|
|
32
30
|
},
|
|
33
31
|
},
|
|
34
32
|
actions: {
|
|
35
|
-
register_microservice(store:
|
|
33
|
+
register_microservice(store: Microservice) {
|
|
36
34
|
const store_name = store.$id;
|
|
37
35
|
|
|
38
36
|
if (
|
|
39
|
-
!this.microservices.some(
|
|
40
|
-
(microservice: Readonly<Microservice>) => microservice.$id === store_name,
|
|
41
|
-
)
|
|
37
|
+
!this.microservices.some((microservice: Microservice) => microservice.$id === store_name)
|
|
42
38
|
) {
|
|
43
39
|
this.microservices.push(store);
|
|
44
40
|
}
|
|
45
41
|
},
|
|
46
42
|
unregister_microservice(microserviceId: string) {
|
|
47
43
|
this.microservices = this.microservices.filter(
|
|
48
|
-
(microservice:
|
|
44
|
+
(microservice: Microservice) => microservice.$id !== microserviceId,
|
|
49
45
|
);
|
|
50
46
|
},
|
|
51
47
|
async create_backend(email?: string) {
|
|
@@ -71,16 +67,14 @@ export const useInfraStore = defineStore("infra", {
|
|
|
71
67
|
}
|
|
72
68
|
await setAppBaseUrl(appStore.base_url);
|
|
73
69
|
const microservices_with_launch = this.microservices.filter(
|
|
74
|
-
(store:
|
|
75
|
-
);
|
|
76
|
-
const launch_promises = microservices_with_launch.map(
|
|
77
|
-
async (store: Readonly<Microservice>) => {
|
|
78
|
-
const result = await store.launch?.({
|
|
79
|
-
projectFolderPath: appStore.projectFolderPath,
|
|
80
|
-
});
|
|
81
|
-
return result;
|
|
82
|
-
},
|
|
70
|
+
(store: Microservice) => store.launch,
|
|
83
71
|
);
|
|
72
|
+
const launch_promises = microservices_with_launch.map(async (store: Microservice) => {
|
|
73
|
+
const result = await store.launch?.({
|
|
74
|
+
projectFolderPath: appStore.projectFolderPath,
|
|
75
|
+
});
|
|
76
|
+
return result;
|
|
77
|
+
});
|
|
84
78
|
const { registerRunningExtensions } = await import("@ogw_front/utils/extension");
|
|
85
79
|
launch_promises.push(registerRunningExtensions());
|
|
86
80
|
await Promise.all(launch_promises);
|
|
@@ -92,7 +86,7 @@ export const useInfraStore = defineStore("infra", {
|
|
|
92
86
|
},
|
|
93
87
|
async create_connection() {
|
|
94
88
|
await Promise.all(
|
|
95
|
-
this.microservices.map(async (store:
|
|
89
|
+
this.microservices.map(async (store: Microservice) => {
|
|
96
90
|
await store.connect();
|
|
97
91
|
}),
|
|
98
92
|
);
|
|
@@ -107,6 +101,6 @@ export interface Microservice {
|
|
|
107
101
|
$id: string;
|
|
108
102
|
status?: string;
|
|
109
103
|
is_busy?: boolean;
|
|
110
|
-
launch?: (params:
|
|
104
|
+
launch?: (params: Record<string, unknown>) => Promise<unknown>;
|
|
111
105
|
connect: () => Promise<void>;
|
|
112
106
|
}
|
package/app/stores/menu.ts
CHANGED
|
@@ -56,7 +56,7 @@ interface OpenMenuOptions {
|
|
|
56
56
|
readonly height: number;
|
|
57
57
|
readonly top: number;
|
|
58
58
|
readonly left: number;
|
|
59
|
-
readonly meta_data:
|
|
59
|
+
readonly meta_data: MenuMetaData | undefined;
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
const PointSet_menu = [PointSetPointsOptions];
|
package/app/stores/treeview.ts
CHANGED
|
@@ -55,20 +55,20 @@ function defaultOpenedViews(): OpenedView[] {
|
|
|
55
55
|
return [{ type: "object", id: "main", title: "Objects", scrollTop: 0, opened: [] }];
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
type ReadonlyOpenedView =
|
|
58
|
+
type ReadonlyOpenedView = Omit<OpenedView, "opened"> & {
|
|
59
59
|
readonly opened: readonly string[];
|
|
60
60
|
};
|
|
61
|
-
type ReadonlyTreeviewGroup =
|
|
62
|
-
readonly children: readonly
|
|
61
|
+
type ReadonlyTreeviewGroup = Omit<TreeviewGroup, "children"> & {
|
|
62
|
+
readonly children: readonly TreeviewChild[];
|
|
63
63
|
};
|
|
64
|
-
type ReadonlyTreeviewSnapshot =
|
|
64
|
+
type ReadonlyTreeviewSnapshot = {
|
|
65
65
|
opened_views?: readonly ReadonlyOpenedView[];
|
|
66
66
|
panelWidth?: number;
|
|
67
67
|
additionalPanelWidth?: number;
|
|
68
68
|
rowHeights?: readonly number[];
|
|
69
69
|
selectionIds?: readonly string[];
|
|
70
|
-
selection?: readonly (string |
|
|
71
|
-
}
|
|
70
|
+
selection?: readonly (string | { id: string })[];
|
|
71
|
+
};
|
|
72
72
|
|
|
73
73
|
// oxlint-disable-next-line max-lines-per-function, max-statements
|
|
74
74
|
export const useTreeviewStore = defineStore("treeview", () => {
|
|
@@ -260,7 +260,7 @@ export const useTreeviewStore = defineStore("treeview", () => {
|
|
|
260
260
|
rowHeights.value = snapshot?.rowHeights ? [...snapshot.rowHeights] : [];
|
|
261
261
|
pendingSelectionIds.value = snapshot?.selectionIds
|
|
262
262
|
? [...snapshot.selectionIds]
|
|
263
|
-
: (snapshot?.selection ?? []).map((selectionItem:
|
|
263
|
+
: (snapshot?.selection ?? []).map((selectionItem: string | { id: string }) =>
|
|
264
264
|
typeof selectionItem === "string" ? selectionItem : selectionItem.id,
|
|
265
265
|
);
|
|
266
266
|
}
|
package/app/stores/viewer.ts
CHANGED
|
@@ -68,11 +68,11 @@ export const useViewerStore = defineStore(
|
|
|
68
68
|
schema,
|
|
69
69
|
params = {},
|
|
70
70
|
timeout = request_timeout,
|
|
71
|
-
}:
|
|
71
|
+
}: {
|
|
72
72
|
schema: JsonRpcSchema;
|
|
73
|
-
params?:
|
|
73
|
+
params?: Record<string, unknown>;
|
|
74
74
|
timeout?: number;
|
|
75
|
-
}
|
|
75
|
+
},
|
|
76
76
|
callbacks: RequestHandlers = {},
|
|
77
77
|
): Promise<unknown> {
|
|
78
78
|
const store = useViewerStore();
|
|
@@ -154,7 +154,7 @@ export const useViewerStore = defineStore(
|
|
|
154
154
|
function stop_request(): void {
|
|
155
155
|
request_counter.value -= 1;
|
|
156
156
|
}
|
|
157
|
-
async function launch(args:
|
|
157
|
+
async function launch(args: { projectFolderPath?: string } = {}): Promise<unknown> {
|
|
158
158
|
const appStore = useAppStore();
|
|
159
159
|
const { COMMAND_VIEWER, NUXT_ROOT_PATH } = useRuntimeConfig().public;
|
|
160
160
|
const schema = opengeodeweb_front_schemas.api.local.app.run_viewer;
|
package/app/utils/attributes.ts
CHANGED
|
@@ -11,7 +11,7 @@ interface AttributeRange {
|
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
export function getAttributeRange(
|
|
14
|
-
currentAttribute:
|
|
14
|
+
currentAttribute: AttributeRangeSource | undefined | null,
|
|
15
15
|
compIndex = 0,
|
|
16
16
|
): AttributeRange {
|
|
17
17
|
if (!currentAttribute) {
|
|
@@ -79,7 +79,7 @@ function getPlaneStyle(rgb: readonly number[]): PlaneStyle {
|
|
|
79
79
|
};
|
|
80
80
|
}
|
|
81
81
|
|
|
82
|
-
function computeSceneBounds(actors: readonly
|
|
82
|
+
function computeSceneBounds(actors: readonly vtkActor[]): Bounds {
|
|
83
83
|
let bounds: Bounds = [Infinity, -Infinity, Infinity, -Infinity, Infinity, -Infinity];
|
|
84
84
|
for (const actor of actors) {
|
|
85
85
|
const boundsOfActor = actor.getBounds();
|
|
@@ -100,7 +100,7 @@ interface SceneBoundsInfo {
|
|
|
100
100
|
readonly cubicBounds: readonly number[];
|
|
101
101
|
}
|
|
102
102
|
|
|
103
|
-
function computeSceneBoundsInfo(actors: readonly
|
|
103
|
+
function computeSceneBoundsInfo(actors: readonly vtkActor[]): SceneBoundsInfo {
|
|
104
104
|
if (actors.length === 0) {
|
|
105
105
|
return { center: [0, 0, 0], cubicBounds: [-1, 1, -1, 1, -1, 1] };
|
|
106
106
|
}
|
|
@@ -112,7 +112,7 @@ function computeSceneBoundsInfo(actors: readonly Readonly<vtkActor>[]): SceneBou
|
|
|
112
112
|
];
|
|
113
113
|
|
|
114
114
|
const maxActorExtent = Math.max(
|
|
115
|
-
...actors.map((actor:
|
|
115
|
+
...actors.map((actor: vtkActor) => {
|
|
116
116
|
const bounds = actor.getBounds();
|
|
117
117
|
return Math.max(bounds[1] - bounds[0], bounds[3] - bounds[2], bounds[5] - bounds[4]);
|
|
118
118
|
}),
|
|
@@ -131,7 +131,7 @@ function computeSceneBoundsInfo(actors: readonly Readonly<vtkActor>[]): SceneBou
|
|
|
131
131
|
}
|
|
132
132
|
|
|
133
133
|
interface ActorEntry {
|
|
134
|
-
readonly actor:
|
|
134
|
+
readonly actor: vtkActor;
|
|
135
135
|
}
|
|
136
136
|
|
|
137
137
|
interface MainCameraOptions {
|
|
@@ -144,25 +144,20 @@ function resolveActiveActors(
|
|
|
144
144
|
targetAllVisible: boolean,
|
|
145
145
|
allItems: readonly { readonly id: string }[],
|
|
146
146
|
selectedDatasetIds: readonly string[],
|
|
147
|
-
hybridDb:
|
|
148
|
-
):
|
|
147
|
+
hybridDb: Record<string, ActorEntry | undefined>,
|
|
148
|
+
): vtkActor[] {
|
|
149
149
|
const targetIds = targetAllVisible
|
|
150
|
-
? allItems.map((item:
|
|
150
|
+
? allItems.map((item: { id: string }) => item.id)
|
|
151
151
|
: selectedDatasetIds;
|
|
152
152
|
const targeted = targetIds
|
|
153
153
|
.map((id) => hybridDb[id]?.actor)
|
|
154
|
-
.filter(
|
|
155
|
-
(actor: Readonly<vtkActor> | undefined): actor is Readonly<vtkActor> => actor !== undefined,
|
|
156
|
-
);
|
|
154
|
+
.filter((actor: vtkActor | undefined): actor is vtkActor => actor !== undefined);
|
|
157
155
|
if (targeted.length > 0) {
|
|
158
156
|
return targeted;
|
|
159
157
|
}
|
|
160
158
|
return Object.values(hybridDb)
|
|
161
|
-
.filter(
|
|
162
|
-
|
|
163
|
-
entry !== undefined,
|
|
164
|
-
)
|
|
165
|
-
.map((entry: Readonly<ActorEntry>) => entry.actor);
|
|
159
|
+
.filter((entry: ActorEntry | undefined): entry is ActorEntry => entry !== undefined)
|
|
160
|
+
.map((entry: ActorEntry) => entry.actor);
|
|
166
161
|
}
|
|
167
162
|
|
|
168
163
|
function computeNormalizedViewDirection(
|
|
@@ -184,8 +179,8 @@ function computeNormalizedViewDirection(
|
|
|
184
179
|
// Aligns the local clipping-plane preview camera onto the same viewing direction as the
|
|
185
180
|
// Main viewer camera, re-centered on the clipped scene's bounds.
|
|
186
181
|
function alignCameraToMainCamera(
|
|
187
|
-
camera:
|
|
188
|
-
mainCam:
|
|
182
|
+
camera: vtkCamera,
|
|
183
|
+
mainCam: MainCameraOptions,
|
|
189
184
|
center: readonly number[],
|
|
190
185
|
): void {
|
|
191
186
|
if (!mainCam.focal_point || !mainCam.position) {
|
package/app/utils/colormap.ts
CHANGED
|
@@ -55,7 +55,7 @@ function fillImageDataFromTable(
|
|
|
55
55
|
// ImageData can't satisfy prefer-readonly-parameter-types since lib.dom.d.ts types are inherently mutable, so this finding is left unfixed (same pattern as app/plugins/auto_store_register.ts).
|
|
56
56
|
imageData: ImageData,
|
|
57
57
|
// Float32Array's numeric index signature is inherently mutable and can't satisfy prefer-readonly-parameter-types, so this finding is left unfixed (same pattern as app/plugins/auto_store_register.ts).
|
|
58
|
-
table:
|
|
58
|
+
table: Float32Array,
|
|
59
59
|
width: number,
|
|
60
60
|
height: number,
|
|
61
61
|
): void {
|
|
@@ -117,7 +117,7 @@ interface SolidStyle {
|
|
|
117
117
|
function meshPointsDefaultStyle(
|
|
118
118
|
visibility: boolean = POINTS_DEFAULT_VISIBILITY,
|
|
119
119
|
size: number = POINTS_DEFAULT_SIZE,
|
|
120
|
-
constant:
|
|
120
|
+
constant: RGBAColor = POINTS_DEFAULT_COLOR,
|
|
121
121
|
): MeshPointsStyle {
|
|
122
122
|
return {
|
|
123
123
|
visibility,
|
|
@@ -133,7 +133,7 @@ function meshPointsDefaultStyle(
|
|
|
133
133
|
function meshEdgesDefaultStyle(
|
|
134
134
|
visibility: boolean = EDGES_DEFAULT_VISIBILITY,
|
|
135
135
|
width: number = EDGES_DEFAULT_WIDTH,
|
|
136
|
-
constant:
|
|
136
|
+
constant: RGBAColor = EDGES_DEFAULT_COLOR,
|
|
137
137
|
): MeshEdgesStyle {
|
|
138
138
|
return {
|
|
139
139
|
visibility,
|
|
@@ -149,7 +149,7 @@ function meshEdgesDefaultStyle(
|
|
|
149
149
|
|
|
150
150
|
function meshCellsDefaultStyle(
|
|
151
151
|
visibility: boolean = CELLS_DEFAULT_VISIBILITY,
|
|
152
|
-
constant:
|
|
152
|
+
constant: RGBAColor = CELLS_DEFAULT_COLOR,
|
|
153
153
|
): MeshCellsStyle {
|
|
154
154
|
return {
|
|
155
155
|
visibility,
|
|
@@ -166,7 +166,7 @@ function meshCellsDefaultStyle(
|
|
|
166
166
|
|
|
167
167
|
function meshPolygonsDefaultStyle(
|
|
168
168
|
visibility: boolean = POLYGONS_DEFAULT_VISIBILITY,
|
|
169
|
-
constant:
|
|
169
|
+
constant: RGBAColor = POLYGONS_DEFAULT_COLOR,
|
|
170
170
|
): MeshPolygonsStyle {
|
|
171
171
|
return {
|
|
172
172
|
visibility,
|
|
@@ -183,7 +183,7 @@ function meshPolygonsDefaultStyle(
|
|
|
183
183
|
|
|
184
184
|
function meshPolyhedraDefaultStyle(
|
|
185
185
|
visibility: boolean = POLYHEDRA_DEFAULT_VISIBILITY,
|
|
186
|
-
constant:
|
|
186
|
+
constant: RGBAColor = POLYHEDRA_DEFAULT_COLOR,
|
|
187
187
|
): MeshPolyhedraStyle {
|
|
188
188
|
return {
|
|
189
189
|
visibility,
|
|
@@ -96,7 +96,7 @@ interface ModelWithoutBlocksStyle {
|
|
|
96
96
|
|
|
97
97
|
function modelCornersDefaultStyle(
|
|
98
98
|
visibility: boolean = CORNERS_DEFAULT_VISIBILITY,
|
|
99
|
-
constant:
|
|
99
|
+
constant: RGBAColor = CORNERS_DEFAULT_COLOR,
|
|
100
100
|
): ModelCornersStyle {
|
|
101
101
|
return {
|
|
102
102
|
visibility,
|
|
@@ -110,7 +110,7 @@ function modelCornersDefaultStyle(
|
|
|
110
110
|
|
|
111
111
|
function modelLinesDefaultStyle(
|
|
112
112
|
visibility: boolean = LINES_DEFAULT_VISIBILITY,
|
|
113
|
-
constant:
|
|
113
|
+
constant: RGBAColor = LINES_DEFAULT_COLOR,
|
|
114
114
|
): ModelLinesStyle {
|
|
115
115
|
return {
|
|
116
116
|
visibility,
|
|
@@ -125,7 +125,7 @@ function modelLinesDefaultStyle(
|
|
|
125
125
|
|
|
126
126
|
function modelSurfacesDefaultStyle(
|
|
127
127
|
visibility: boolean = SURFACES_DEFAULT_VISIBILITY,
|
|
128
|
-
constant:
|
|
128
|
+
constant: RGBAColor = SURFACES_DEFAULT_COLOR,
|
|
129
129
|
): ModelSurfacesStyle {
|
|
130
130
|
return {
|
|
131
131
|
visibility,
|
|
@@ -140,7 +140,7 @@ function modelSurfacesDefaultStyle(
|
|
|
140
140
|
|
|
141
141
|
function modelBlocksDefaultStyle(
|
|
142
142
|
visibility: boolean = BLOCKS_DEFAULT_VISIBILITY,
|
|
143
|
-
constant:
|
|
143
|
+
constant: RGBAColor = BLOCKS_DEFAULT_COLOR,
|
|
144
144
|
): ModelBlocksStyle {
|
|
145
145
|
return {
|
|
146
146
|
visibility,
|
package/app/utils/extension.ts
CHANGED
|
@@ -29,7 +29,7 @@ interface RegisteredExtension {
|
|
|
29
29
|
extensionModule: ExtensionModuleType;
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
async function uploadExtension(file:
|
|
32
|
+
async function uploadExtension(file: File): Promise<void> {
|
|
33
33
|
const { useAppStore } = await import("@ogw_front/stores/app");
|
|
34
34
|
const appStore = useAppStore();
|
|
35
35
|
await appStore.upload(file);
|
|
@@ -57,7 +57,7 @@ async function runExtensions(): Promise<{ extensionsArray: ExtensionDescriptor[]
|
|
|
57
57
|
async function downloadExtension({
|
|
58
58
|
url,
|
|
59
59
|
extensionFileName,
|
|
60
|
-
}:
|
|
60
|
+
}: DownloadExtensionParams): Promise<unknown> {
|
|
61
61
|
const { useAppStore } = await import("@ogw_front/stores/app");
|
|
62
62
|
const appStore = useAppStore();
|
|
63
63
|
const { PROJECT: projectName } = useRuntimeConfig().public;
|
|
@@ -74,9 +74,7 @@ async function downloadExtension({
|
|
|
74
74
|
return result;
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
-
function isMicroservice(
|
|
78
|
-
store: Readonly<RegisterableStore>,
|
|
79
|
-
): store is RegisterableStore & Microservice {
|
|
77
|
+
function isMicroservice(store: RegisterableStore): store is RegisterableStore & Microservice {
|
|
80
78
|
return typeof store.connect === "function";
|
|
81
79
|
}
|
|
82
80
|
|
|
@@ -87,7 +85,7 @@ async function registerRunningExtensions(): Promise<RegisteredExtension[]> {
|
|
|
87
85
|
const infraStore = useInfraStore();
|
|
88
86
|
const { extensionsArray } = await runExtensions();
|
|
89
87
|
return Promise.all(
|
|
90
|
-
extensionsArray.map(async (extension:
|
|
88
|
+
extensionsArray.map(async (extension: ExtensionDescriptor) => {
|
|
91
89
|
const { id, name, version, frontendContent, port } = extension;
|
|
92
90
|
const blob = new Blob([frontendContent], {
|
|
93
91
|
type: "application/javascript",
|
|
@@ -116,14 +114,12 @@ async function registerRunningExtensions(): Promise<RegisteredExtension[]> {
|
|
|
116
114
|
);
|
|
117
115
|
}
|
|
118
116
|
|
|
119
|
-
async function importExtensionFile(file:
|
|
117
|
+
async function importExtensionFile(file: File): Promise<RegisteredExtension[]> {
|
|
120
118
|
await uploadExtension(file);
|
|
121
119
|
return registerRunningExtensions();
|
|
122
120
|
}
|
|
123
121
|
|
|
124
|
-
async function importExtensionURL(
|
|
125
|
-
url: Readonly<DownloadExtensionParams>,
|
|
126
|
-
): Promise<RegisteredExtension[]> {
|
|
122
|
+
async function importExtensionURL(url: DownloadExtensionParams): Promise<RegisteredExtension[]> {
|
|
127
123
|
await downloadExtension(url);
|
|
128
124
|
return registerRunningExtensions();
|
|
129
125
|
}
|
|
@@ -15,9 +15,9 @@ interface FileToImport {
|
|
|
15
15
|
readonly geode_object_type: string;
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
// NewDataItem has mutable array fields (mesh_components, collection_components), so
|
|
19
|
-
//
|
|
20
|
-
async function importItem(item:
|
|
18
|
+
// NewDataItem has mutable array fields (mesh_components, collection_components), so it can't
|
|
19
|
+
// Satisfy prefer-readonly-parameter-types deeply; left unfixed (same pattern as app/plugins/auto_store_register.ts).
|
|
20
|
+
async function importItem(item: NewDataItem): Promise<string> {
|
|
21
21
|
const dataStore = useDataStore();
|
|
22
22
|
const dataStyleStore = useDataStyleStore();
|
|
23
23
|
const hybridViewerStore = useHybridViewerStore();
|