@geode/opengeodeweb-front 10.34.0-rc.9 → 10.34.0
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/{server → .build/server}/utils/app_config.js +10 -9
- package/{server → .build/server}/utils/cleanup.js +31 -17
- package/{server → .build/server}/utils/cloud.js +1 -4
- package/{server → .build/server}/utils/microservices.js +21 -9
- package/{server → .build/server}/utils/path.js +4 -4
- package/{server → .build/server}/utils/scripts.js +9 -9
- package/.build/server/utils/server_config.js +51 -0
- package/.build/server/utils/stream.js +6 -0
- package/{server → .build/server}/utils/ws_client.js +18 -3
- package/{shared → .build/shared}/scripts.js +10 -10
- package/.build/shared/utils/call_raw.js +31 -0
- package/{shared → .build/shared}/utils/call_schema.js +2 -2
- package/.build/shared/utils/fetch_raw.js +52 -0
- package/{shared → .build/shared}/utils/fetch_schema.js +2 -2
- package/{shared → .build/shared}/utils/file.js +3 -1
- package/{shared → .build/shared}/utils/response_handlers/load.js +10 -7
- package/{shared → .build/shared}/utils/validate_schema.js +1 -1
- package/app/components/ActionButton.vue +6 -6
- package/app/components/CameraManager/List.vue +5 -5
- package/app/components/CameraManager/Saver.vue +3 -5
- package/app/components/CameraManager.vue +6 -4
- package/app/components/CameraOrientation.vue +12 -12
- package/app/components/ClippingPlaneCard.vue +4 -2
- package/app/components/ClippingPlanes.vue +8 -8
- package/app/components/CrsSelector.vue +9 -10
- package/app/components/DeleteDialog.vue +4 -2
- package/app/components/DragAndDrop.vue +10 -12
- package/app/components/DragAndDropInternal/DragAndDropInline.vue +4 -2
- package/app/components/ExtensionSelector.vue +4 -4
- package/app/components/FeedBack/ErrorBanner.vue +3 -1
- package/app/components/FeedBack/Snackers.vue +4 -3
- package/app/components/FileSelector.vue +10 -8
- package/app/components/FileUploader.vue +11 -11
- package/app/components/GlassCard.vue +1 -1
- package/app/components/HybridRenderingView.vue +7 -5
- package/app/components/HybridViewerTooltip.vue +7 -7
- package/app/components/Launcher.vue +1 -1
- package/app/components/Loading/EcoMessages.vue +9 -3
- package/app/components/Loading.vue +2 -2
- package/app/components/MissingFilesSelector.vue +12 -10
- package/app/components/ObjectSelector.vue +10 -9
- package/app/components/PackagesVersions.vue +6 -5
- package/app/components/Recaptcha.vue +3 -3
- package/app/components/RemoteRenderingView.vue +6 -7
- package/app/components/Ruler.vue +3 -3
- package/app/components/Screenshot.vue +6 -6
- package/app/components/SearchBar.vue +4 -2
- package/app/components/ShrinkFilter.vue +7 -7
- package/app/components/Step.vue +6 -5
- package/app/components/Stepper.vue +4 -3
- package/app/components/ToolPanel.vue +6 -3
- package/app/components/ViewToolbar.vue +25 -28
- package/app/components/Viewer/ContextMenu/CenterButton.vue +7 -5
- package/app/components/Viewer/ContextMenu/CircularItems.vue +3 -3
- package/app/components/Viewer/ContextMenu/ContextMenu.vue +22 -19
- package/app/components/Viewer/ContextMenu/ContextMenuItem.vue +10 -8
- package/app/components/Viewer/ContextMenu/InfoCard.vue +11 -12
- package/app/components/Viewer/EdgedCurve/SpecificEdgesOptions.vue +13 -17
- package/app/components/Viewer/Generic/Mesh/CellsOptions.vue +11 -15
- package/app/components/Viewer/Generic/Mesh/EdgesOptions.vue +12 -16
- package/app/components/Viewer/Generic/Mesh/PointsOptions.vue +8 -12
- package/app/components/Viewer/Generic/Mesh/PolygonsOptions.vue +11 -15
- package/app/components/Viewer/Generic/Mesh/PolyhedraOptions.vue +11 -15
- package/app/components/Viewer/Generic/Model/BlocksOptions.vue +67 -38
- package/app/components/Viewer/Generic/Model/CornersOptions.vue +53 -23
- package/app/components/Viewer/Generic/Model/EdgesOptions.vue +1 -3
- package/app/components/Viewer/Generic/Model/LinesOptions.vue +67 -38
- package/app/components/Viewer/Generic/Model/ModelStyleCard.vue +31 -15
- package/app/components/Viewer/Generic/Model/ModelStyleOptions.vue +2 -3
- package/app/components/Viewer/Generic/Model/PointsOptions.vue +6 -6
- package/app/components/Viewer/Generic/Model/SurfacesOptions.vue +69 -38
- package/app/components/Viewer/ObjectTree/Base/CommonTreeView.vue +64 -46
- package/app/components/Viewer/ObjectTree/Base/Controls.vue +5 -5
- package/app/components/Viewer/ObjectTree/Base/ItemLabel.vue +13 -9
- package/app/components/Viewer/ObjectTree/Base/StickyHeader.vue +5 -5
- package/app/components/Viewer/ObjectTree/Base/TreeRow.vue +10 -10
- package/app/components/Viewer/ObjectTree/Box.vue +6 -4
- package/app/components/Viewer/ObjectTree/Layout.vue +23 -21
- package/app/components/Viewer/ObjectTree/Views/GlobalObjects.vue +14 -14
- package/app/components/Viewer/ObjectTree/Views/{ModelCollections.vue → ModelTree.vue} +59 -24
- package/app/components/Viewer/Options/AttributeColorBar.vue +4 -2
- package/app/components/Viewer/Options/AttributeRangeSelector.vue +4 -2
- package/app/components/Viewer/Options/AttributeSelector.vue +7 -9
- package/app/components/Viewer/Options/ColorMapList.vue +15 -13
- package/app/components/Viewer/Options/ColorMapPicker.vue +4 -4
- package/app/components/Viewer/Options/ColorPicker.vue +223 -41
- package/app/components/Viewer/Options/ColoringTypeSelector.vue +16 -16
- package/app/components/Viewer/Options/ColormapQuickPicker.vue +7 -5
- package/app/components/Viewer/Options/OptionsSection.vue +1 -1
- package/app/components/Viewer/Options/TextureItem.vue +8 -6
- package/app/components/Viewer/Options/TexturesSelector.vue +1 -1
- package/app/components/Viewer/OverlappingObjectsPicker.vue +8 -9
- package/app/components/Viewer/PointSet/SpecificPointsOptions.vue +2 -6
- package/app/components/Viewer/Solid/SpecificPolyhedraOptions.vue +12 -16
- package/app/components/Viewer/Surface/PolygonsOptions.vue +12 -16
- package/app/components/Viewer/Ui.vue +2 -2
- package/app/components/Wrapper.vue +1 -4
- package/app/components/ZScaling.vue +5 -3
- package/app/components/csv-preview/CsvPreviewer.vue +38 -37
- package/app/components/csv-preview/CsvSettings.vue +6 -4
- package/app/components/csv-preview/CsvTable.vue +1 -1
- package/app/composables/batch_style.ts +5 -6
- package/app/composables/clipping_planes_widget.ts +73 -181
- package/app/composables/clipping_planes_widget_entries.ts +189 -0
- package/app/composables/copy_to_clipboard.ts +7 -0
- package/app/composables/global_attribute_style.ts +163 -83
- package/app/composables/hover_highlight.ts +46 -14
- package/app/composables/model_collections.ts +26 -13
- package/app/composables/model_components.ts +26 -13
- package/app/composables/project_manager.ts +76 -19
- package/app/composables/responsive_middle_truncate.ts +13 -13
- package/app/composables/stepper_tree.ts +34 -11
- package/app/composables/tree_filter.ts +66 -44
- package/app/composables/tree_keyboard_nav.ts +25 -11
- package/app/composables/tree_scroll.ts +44 -14
- package/app/composables/use_adaptive_styles.ts +66 -23
- package/app/composables/use_overlapping_picker.ts +66 -16
- package/app/composables/use_quick_colormap.ts +16 -5
- package/app/composables/virtual_tree.ts +75 -43
- package/app/composables/vtk_implicit_plane_widget.d.ts +2 -0
- package/app/plugins/auto_store_register.ts +2 -7
- package/app/plugins/click_outside_ignore_snackbars.client.ts +39 -0
- package/app/stores/app.ts +57 -192
- package/app/stores/app_helpers/extension.ts +179 -0
- package/app/stores/back.ts +37 -21
- package/app/stores/camera_manager.ts +22 -20
- package/app/stores/cloud.ts +17 -13
- package/app/stores/data.ts +88 -47
- package/app/stores/data_helpers/collections.ts +36 -38
- package/app/stores/data_helpers/mesh.ts +45 -36
- package/app/stores/data_style.ts +50 -28
- package/app/stores/feedback.ts +6 -6
- package/app/stores/hybrid_viewer.ts +41 -52
- package/app/stores/infra.ts +39 -37
- package/app/stores/menu.ts +23 -14
- package/app/stores/treeview.ts +72 -42
- package/app/stores/viewer.ts +39 -27
- package/app/utils/attributes.ts +3 -3
- package/app/utils/clipping_planes.ts +111 -14
- package/app/utils/color_picker.ts +57 -0
- package/app/utils/colormap.ts +58 -35
- package/app/utils/default_styles/index.ts +2 -2
- package/app/utils/default_styles/meshes.ts +107 -13
- package/app/utils/default_styles/models.ts +83 -14
- package/app/utils/extension.ts +47 -20
- package/app/utils/import_workflow.ts +21 -13
- package/app/utils/name_cleaner.ts +1 -1
- package/app/utils/string.ts +1 -1
- package/app/utils/treeview.ts +2 -2
- package/internal/database/base_database.ts +7 -3
- package/internal/database/database.ts +36 -26
- package/internal/database/extended_database.ts +1 -1
- package/internal/stores/data_style/mesh/cells/cell.ts +70 -34
- package/internal/stores/data_style/mesh/cells/color.ts +12 -6
- package/internal/stores/data_style/mesh/cells/common.ts +18 -8
- package/internal/stores/data_style/mesh/cells/index.ts +122 -42
- package/internal/stores/data_style/mesh/cells/textures.ts +12 -6
- package/internal/stores/data_style/mesh/cells/vertex.ts +75 -34
- package/internal/stores/data_style/mesh/cells/visibility.ts +15 -4
- package/internal/stores/data_style/mesh/edges/color.ts +12 -6
- package/internal/stores/data_style/mesh/edges/common.ts +14 -6
- package/internal/stores/data_style/mesh/edges/edge.ts +71 -39
- package/internal/stores/data_style/mesh/edges/index.ts +117 -42
- package/internal/stores/data_style/mesh/edges/vertex.ts +76 -39
- package/internal/stores/data_style/mesh/edges/visibility.ts +15 -4
- package/internal/stores/data_style/mesh/edges/width.ts +12 -4
- package/internal/stores/data_style/mesh/index.ts +30 -11
- package/internal/stores/data_style/mesh/points/color.ts +12 -6
- package/internal/stores/data_style/mesh/points/common.ts +21 -8
- package/internal/stores/data_style/mesh/points/index.ts +101 -50
- package/internal/stores/data_style/mesh/points/size.ts +12 -4
- package/internal/stores/data_style/mesh/points/vertex.ts +75 -34
- package/internal/stores/data_style/mesh/points/visibility.ts +17 -7
- package/internal/stores/data_style/mesh/polygons/color.ts +12 -6
- package/internal/stores/data_style/mesh/polygons/common.ts +23 -6
- package/internal/stores/data_style/mesh/polygons/index.ts +130 -70
- package/internal/stores/data_style/mesh/polygons/polygon.ts +77 -43
- package/internal/stores/data_style/mesh/polygons/textures.ts +12 -6
- package/internal/stores/data_style/mesh/polygons/vertex.ts +79 -39
- package/internal/stores/data_style/mesh/polygons/visibility.ts +16 -6
- package/internal/stores/data_style/mesh/polyhedra/color.ts +12 -6
- package/internal/stores/data_style/mesh/polyhedra/common.ts +14 -6
- package/internal/stores/data_style/mesh/polyhedra/index.ts +115 -56
- package/internal/stores/data_style/mesh/polyhedra/polyhedron.ts +80 -39
- package/internal/stores/data_style/mesh/polyhedra/vertex.ts +79 -39
- package/internal/stores/data_style/mesh/polyhedra/visibility.ts +16 -6
- package/internal/stores/data_style/model/blocks/color.ts +43 -13
- package/internal/stores/data_style/model/blocks/common.ts +21 -6
- package/internal/stores/data_style/model/blocks/index.ts +89 -59
- package/internal/stores/data_style/model/blocks/polyhedron.ts +101 -44
- package/internal/stores/data_style/model/blocks/vertex.ts +107 -42
- package/internal/stores/data_style/model/blocks/visibility.ts +17 -4
- package/internal/stores/data_style/model/color.ts +171 -83
- package/internal/stores/data_style/model/common.ts +70 -21
- package/internal/stores/data_style/model/corners/color.ts +43 -11
- package/internal/stores/data_style/model/corners/common.ts +25 -6
- package/internal/stores/data_style/model/corners/index.ts +66 -41
- package/internal/stores/data_style/model/corners/vertex.ts +105 -74
- package/internal/stores/data_style/model/corners/visibility.ts +19 -4
- package/internal/stores/data_style/model/edges/common.ts +12 -4
- package/internal/stores/data_style/model/edges/index.ts +2 -1
- package/internal/stores/data_style/model/edges/visibility.ts +24 -7
- package/internal/stores/data_style/model/index.ts +24 -11
- package/internal/stores/data_style/model/lines/color.ts +41 -11
- package/internal/stores/data_style/model/lines/common.ts +17 -6
- package/internal/stores/data_style/model/lines/edge.ts +105 -42
- package/internal/stores/data_style/model/lines/index.ts +86 -59
- package/internal/stores/data_style/model/lines/vertex.ts +105 -42
- package/internal/stores/data_style/model/lines/visibility.ts +17 -4
- package/internal/stores/data_style/model/points/common.ts +8 -4
- package/internal/stores/data_style/model/points/index.ts +10 -3
- package/internal/stores/data_style/model/points/size.ts +12 -4
- package/internal/stores/data_style/model/points/visibility.ts +16 -6
- package/internal/stores/data_style/model/selection.ts +80 -58
- package/internal/stores/data_style/model/surfaces/color.ts +41 -11
- package/internal/stores/data_style/model/surfaces/common.ts +23 -6
- package/internal/stores/data_style/model/surfaces/index.ts +89 -59
- package/internal/stores/data_style/model/surfaces/polygon.ts +107 -67
- package/internal/stores/data_style/model/surfaces/vertex.ts +111 -67
- package/internal/stores/data_style/model/surfaces/visibility.ts +18 -5
- package/internal/stores/data_style/model/visibility.ts +82 -20
- package/internal/stores/data_style/state.ts +77 -65
- package/internal/stores/hybrid_viewer/brightness.ts +49 -31
- package/internal/stores/hybrid_viewer/camera.ts +191 -177
- package/internal/stores/hybrid_viewer/camera_animation.ts +11 -10
- package/internal/stores/hybrid_viewer/core.ts +64 -0
- package/internal/stores/hybrid_viewer/filters.ts +10 -16
- package/internal/stores/hybrid_viewer/highlight.ts +91 -130
- package/internal/stores/hybrid_viewer/ruler.ts +24 -15
- package/internal/stores/hybrid_viewer/scene.ts +96 -117
- package/internal/stores/hybrid_viewer/viewport.ts +74 -65
- package/internal/stores/hybrid_viewer/vtk_types.ts +13 -29
- package/internal/utils/api_fetch.ts +54 -23
- package/internal/utils/upload_file.ts +74 -53
- package/internal/utils/viewer_call.ts +22 -13
- package/internal/utils/ws_client.ts +24 -13
- package/nuxt.config.ts +58 -1
- package/package.json +20 -8
- package/server/api/cloud/extensions/run.post.ts +6 -10
- package/server/api/local/app/project_folder_path.post.ts +4 -4
- package/server/api/local/app/run_back.post.ts +5 -7
- package/server/api/local/app/run_viewer.post.ts +5 -7
- package/server/api/local/extensions/kill.post.ts +4 -3
- package/server/api/local/extensions/run.post.ts +7 -10
- package/server/api/local/extensions/upload.put.ts +44 -54
- package/server/api/microservice/app/get_is_app_ready.get.ts +4 -5
- package/server/api/microservice/app/set_app_base_url.post.ts +5 -6
- package/server/api/microservice/app/set_back_base_url.post.ts +5 -6
- package/server/api/microservice/app/set_is_app_ready.post.ts +5 -6
- package/server/api/microservice/app/set_viewer_base_url.post.ts +5 -6
- package/server/api/microservice/extensions/download.post.ts +5 -4
- package/server/api/serverless/run_cloud.post.ts +53 -11
- package/server/utils/app_config.ts +29 -22
- package/server/utils/cleanup.ts +60 -30
- package/server/utils/cloud.ts +9 -8
- package/server/utils/extension.ts +23 -9
- package/server/utils/microservices.ts +33 -24
- package/server/utils/path.ts +4 -4
- package/server/utils/scripts.ts +26 -23
- package/server/utils/server.ts +2 -2
- package/server/utils/server_config.ts +41 -27
- package/server/utils/stream.ts +6 -0
- package/server/utils/ws_client.ts +42 -8
- package/shared/scripts.ts +15 -10
- package/shared/utils/call_raw.ts +23 -16
- package/shared/utils/call_schema.ts +5 -8
- package/shared/utils/fetch_raw.ts +87 -47
- package/shared/utils/fetch_schema.ts +6 -9
- package/shared/utils/file.ts +8 -2
- package/shared/utils/response_handlers/load.ts +26 -11
- package/shared/utils/types.ts +9 -9
- package/shared/utils/validate_schema.ts +1 -1
- package/app/components/Viewer/ObjectTree/Views/ModelComponents.vue +0 -276
- package/server/types/vendor.d.ts +0 -64
- package/server/utils/server_config.js +0 -43
- package/shared/utils/call_raw.js +0 -30
- package/shared/utils/fetch_raw.js +0 -40
- /package/{opengeodeweb_front_schemas.js → .build/opengeodeweb_front_schemas.js} +0 -0
- /package/{server → .build/server}/utils/server.js +0 -0
- /package/{shared → .build/shared}/app_mode.js +0 -0
- /package/{shared → .build/shared}/utils/parse_boolean.js +0 -0
- /package/{shared → .build/shared}/utils/types.js +0 -0
|
@@ -1,17 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
// oxlint-disable eslint/sort-imports
|
|
3
|
-
// Third party imports
|
|
4
|
-
import { liveQuery } from "dexie";
|
|
5
|
-
// oxlint-disable-next-line eslint/no-duplicate-imports
|
|
6
|
-
import type { Table } from "dexie";
|
|
7
|
-
import { useObservable } from "@vueuse/rxjs";
|
|
8
|
-
import viewer_schemas from "@geode/opengeodeweb-viewer/opengeodeweb_viewer_schemas.json";
|
|
1
|
+
import { type Table, liveQuery } from "dexie";
|
|
9
2
|
import type { Observable } from "rxjs";
|
|
3
|
+
import { useObservable } from "@vueuse/rxjs";
|
|
10
4
|
|
|
11
5
|
// Local imports
|
|
6
|
+
import type { CameraOptions } from "@ogw_internal/stores/hybrid_viewer/vtk_types.js";
|
|
12
7
|
import { database } from "@ogw_internal/database/database.js";
|
|
13
8
|
import { useViewerStore } from "@ogw_front/stores/viewer";
|
|
14
|
-
import
|
|
9
|
+
import viewer_schemas from "@geode/opengeodeweb-viewer/opengeodeweb_viewer_schemas.json";
|
|
15
10
|
|
|
16
11
|
interface CameraPositionRecord {
|
|
17
12
|
id?: number;
|
|
@@ -19,38 +14,45 @@ interface CameraPositionRecord {
|
|
|
19
14
|
camera_options: CameraOptions;
|
|
20
15
|
}
|
|
21
16
|
|
|
17
|
+
// oxlint-disable-next-line max-lines-per-function
|
|
22
18
|
export const useCameraManagerStore = defineStore("camera_manager", () => {
|
|
23
19
|
const viewerStore = useViewerStore();
|
|
20
|
+
// Database's table map is assembled dynamically at runtime (see internal/database/database.ts),
|
|
21
|
+
// So it's typed as `{}`; this store's table is registered before use, hence the cast.
|
|
22
|
+
// oxlint-disable-next-line no-unsafe-type-assertion -- trusted database table boundary.
|
|
24
23
|
const camera_positions_db = database.camera_positions as unknown as Table<
|
|
25
24
|
CameraPositionRecord,
|
|
26
25
|
number
|
|
27
26
|
>;
|
|
28
27
|
|
|
29
|
-
function refAllCameraPositions() {
|
|
28
|
+
function refAllCameraPositions(): Ref<CameraPositionRecord[]> {
|
|
30
29
|
// Dexie's liveQuery() returns Dexie's own minimal Observable shape, not an
|
|
31
30
|
// Actual rxjs Observable instance (useObservable's declared parameter type);
|
|
32
31
|
// The two are structurally close enough at runtime (vueuse only calls
|
|
33
32
|
// `.subscribe`) but not identical, hence the cast.
|
|
34
33
|
return useObservable(
|
|
35
|
-
liveQuery(() =>
|
|
36
|
-
|
|
37
|
-
|
|
34
|
+
liveQuery(async () => {
|
|
35
|
+
const positions = await camera_positions_db.toArray();
|
|
36
|
+
return positions;
|
|
37
|
+
// oxlint-disable-next-line no-unsafe-type-assertion -- trusted vueuse/Dexie Observable boundary; see comment above.
|
|
38
|
+
}) as unknown as Observable<CameraPositionRecord[]>,
|
|
38
39
|
{ initialValue: [] as CameraPositionRecord[] },
|
|
39
40
|
);
|
|
40
41
|
}
|
|
41
42
|
|
|
42
|
-
async function getCameraPosition(id: number) {
|
|
43
|
-
|
|
43
|
+
async function getCameraPosition(id: number): Promise<CameraPositionRecord | undefined> {
|
|
44
|
+
const position = await camera_positions_db.get(id);
|
|
45
|
+
return position;
|
|
44
46
|
}
|
|
45
47
|
|
|
46
|
-
async function saveCameraPosition(name: string, camera_options: CameraOptions) {
|
|
48
|
+
async function saveCameraPosition(name: string, camera_options: CameraOptions): Promise<void> {
|
|
47
49
|
await camera_positions_db.put({
|
|
48
50
|
name,
|
|
49
51
|
camera_options,
|
|
50
|
-
}
|
|
52
|
+
});
|
|
51
53
|
}
|
|
52
54
|
|
|
53
|
-
async function restoreCameraPosition(id: number) {
|
|
55
|
+
async function restoreCameraPosition(id: number): Promise<void> {
|
|
54
56
|
const position = await camera_positions_db.get(id);
|
|
55
57
|
if (position) {
|
|
56
58
|
const schema = viewer_schemas.opengeodeweb_viewer.viewer.update_camera;
|
|
@@ -59,11 +61,11 @@ export const useCameraManagerStore = defineStore("camera_manager", () => {
|
|
|
59
61
|
}
|
|
60
62
|
}
|
|
61
63
|
|
|
62
|
-
async function deleteCameraPosition(id: number) {
|
|
64
|
+
async function deleteCameraPosition(id: number): Promise<void> {
|
|
63
65
|
await camera_positions_db.delete(id);
|
|
64
66
|
}
|
|
65
67
|
|
|
66
|
-
async function renameCameraPosition(id: number, newName: string) {
|
|
68
|
+
async function renameCameraPosition(id: number, newName: string): Promise<void> {
|
|
67
69
|
await camera_positions_db.update(id, { name: newName });
|
|
68
70
|
}
|
|
69
71
|
|
package/app/stores/cloud.ts
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
import { Status } from "@ogw_front/utils/status";
|
|
2
2
|
import { fetchSchema } from "@ogw_shared/utils/fetch_schema";
|
|
3
3
|
import { setAppBaseUrl } from "@ogw_shared/scripts";
|
|
4
|
-
import { useAppStore } from "./app";
|
|
5
|
-
import { useFeedbackStore } from "./feedback";
|
|
6
|
-
import { useInfraStore } from "./infra";
|
|
7
4
|
|
|
8
5
|
import opengeodeweb_front_schemas from "@geode/opengeodeweb-front/opengeodeweb_front_schemas.json" with { type: "json" };
|
|
9
6
|
|
|
@@ -12,31 +9,39 @@ export const useCloudStore = defineStore("cloud", {
|
|
|
12
9
|
status: Status.NOT_CONNECTED,
|
|
13
10
|
}),
|
|
14
11
|
actions: {
|
|
15
|
-
launch(email: string) {
|
|
12
|
+
async launch(email: string) {
|
|
16
13
|
this.status = Status.CONNECTING;
|
|
17
|
-
console.log("[CLOUD] Launching cloud backend...");
|
|
18
14
|
const schema = opengeodeweb_front_schemas.api.serverless.run_cloud;
|
|
19
15
|
const params = { email };
|
|
20
|
-
|
|
16
|
+
const { useAppStore } = await import("./app");
|
|
17
|
+
const { useFeedbackStore } = await import("./feedback");
|
|
21
18
|
const appStore = useAppStore();
|
|
22
19
|
const feedbackStore = useFeedbackStore();
|
|
23
|
-
|
|
20
|
+
const result = await fetchSchema(
|
|
24
21
|
{ schema, params },
|
|
25
22
|
{
|
|
26
23
|
request_error_function: () => {
|
|
27
24
|
feedbackStore.$patch({ server_error: true });
|
|
28
25
|
this.status = Status.NOT_CONNECTED;
|
|
29
26
|
},
|
|
30
|
-
response_function: (response: unknown) => {
|
|
31
|
-
|
|
27
|
+
response_function: async (response: unknown) => {
|
|
28
|
+
if (
|
|
29
|
+
typeof response !== "object" ||
|
|
30
|
+
response === null ||
|
|
31
|
+
!("url" in response) ||
|
|
32
|
+
typeof response.url !== "string"
|
|
33
|
+
) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
const { url } = response;
|
|
32
37
|
feedbackStore.$patch({ server_error: false });
|
|
33
|
-
console.log(`[CLOUD] Cloud launched on ${url}`);
|
|
34
38
|
this.status = Status.CONNECTED;
|
|
39
|
+
const { useInfraStore } = await import("./infra");
|
|
35
40
|
const infraStore = useInfraStore();
|
|
36
41
|
infraStore.$patch({
|
|
37
42
|
domain_name: url,
|
|
38
43
|
});
|
|
39
|
-
setAppBaseUrl(appStore.base_url);
|
|
44
|
+
setAppBaseUrl(appStore.base_url).catch(() => undefined);
|
|
40
45
|
appStore.$patch({
|
|
41
46
|
projectFolderPath: "/project",
|
|
42
47
|
});
|
|
@@ -47,11 +52,10 @@ export const useCloudStore = defineStore("cloud", {
|
|
|
47
52
|
},
|
|
48
53
|
},
|
|
49
54
|
);
|
|
55
|
+
return result;
|
|
50
56
|
},
|
|
51
57
|
connect() {
|
|
52
|
-
console.log("[CLOUD] Cloud connected");
|
|
53
58
|
this.status = Status.CONNECTED;
|
|
54
|
-
return Promise.resolve();
|
|
55
59
|
},
|
|
56
60
|
},
|
|
57
61
|
share: {
|
package/app/stores/data.ts
CHANGED
|
@@ -1,19 +1,14 @@
|
|
|
1
|
-
//
|
|
2
|
-
// oxlint-disable eslint/sort-imports, eslint/max-lines
|
|
1
|
+
// oxlint-disable eslint/max-lines
|
|
3
2
|
// Third party imports
|
|
4
|
-
import { liveQuery } from "dexie";
|
|
5
|
-
|
|
6
|
-
import type { Table } from "dexie";
|
|
3
|
+
import { type Table, liveQuery } from "dexie";
|
|
4
|
+
import type { Observable } from "rxjs";
|
|
7
5
|
import { useObservable } from "@vueuse/rxjs";
|
|
8
6
|
import viewer_schemas from "@geode/opengeodeweb-viewer/opengeodeweb_viewer_schemas.json";
|
|
9
|
-
import type { Observable } from "rxjs";
|
|
10
7
|
|
|
11
8
|
// Local imports
|
|
9
|
+
import { type ModelComponentRecord, useDataMesh } from "./data_helpers/mesh.js";
|
|
12
10
|
import { database } from "@ogw_internal/database/database.js";
|
|
13
11
|
import { useDataCollections } from "./data_helpers/collections.js";
|
|
14
|
-
import { useDataMesh } from "./data_helpers/mesh.js";
|
|
15
|
-
// oxlint-disable-next-line eslint/no-duplicate-imports
|
|
16
|
-
import type { ModelComponentRecord } from "./data_helpers/mesh.js";
|
|
17
12
|
import { useViewerStore } from "@ogw_front/stores/viewer";
|
|
18
13
|
|
|
19
14
|
interface DataItem {
|
|
@@ -66,12 +61,16 @@ interface ViewableItemLike {
|
|
|
66
61
|
}
|
|
67
62
|
|
|
68
63
|
const viewer_generic_schemas = viewer_schemas.opengeodeweb_viewer.generic;
|
|
64
|
+
// 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.
|
|
65
|
+
type DatabaseTables = Record<string, unknown>;
|
|
66
|
+
// oxlint-disable-next-line no-unsafe-type-assertion -- see comment above.
|
|
67
|
+
const typedDatabase = database as unknown as DatabaseTables;
|
|
69
68
|
function checkItemViewable(item: ViewableItemLike | undefined | null): boolean {
|
|
70
69
|
if (!item || typeof item !== "object") {
|
|
71
70
|
return false;
|
|
72
71
|
}
|
|
73
72
|
if (item.is_viewable !== undefined) {
|
|
74
|
-
return
|
|
73
|
+
return item.is_viewable;
|
|
75
74
|
}
|
|
76
75
|
if (item.binary_light_viewable !== undefined) {
|
|
77
76
|
return item.binary_light_viewable !== "not_viewable";
|
|
@@ -87,9 +86,8 @@ function checkItemViewable(item: ViewableItemLike | undefined | null): boolean {
|
|
|
87
86
|
}
|
|
88
87
|
function isItemViewable(itemOrId: string | ViewableItemLike): boolean | Promise<boolean> {
|
|
89
88
|
if (typeof itemOrId === "string") {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
.then(checkItemViewable);
|
|
89
|
+
// oxlint-disable-next-line no-unsafe-type-assertion -- database's table map is dynamically typed at runtime; see comment above.
|
|
90
|
+
return (typedDatabase.data as Table<DataItem, string>).get(itemOrId).then(checkItemViewable);
|
|
93
91
|
}
|
|
94
92
|
return checkItemViewable(itemOrId);
|
|
95
93
|
}
|
|
@@ -97,12 +95,12 @@ function isItemViewable(itemOrId: string | ViewableItemLike): boolean | Promise<
|
|
|
97
95
|
// oxlint-disable-next-line max-lines-per-function, max-statements
|
|
98
96
|
export const useDataStore = defineStore("data", () => {
|
|
99
97
|
const viewerStore = useViewerStore();
|
|
100
|
-
|
|
101
|
-
const
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
const model_components_relation_db =
|
|
98
|
+
// oxlint-disable-next-line no-unsafe-type-assertion -- database's table map is dynamically typed at runtime; see comment above.
|
|
99
|
+
const data_db = typedDatabase.data as Table<DataItem, string>;
|
|
100
|
+
// oxlint-disable-next-line no-unsafe-type-assertion -- database's table map is dynamically typed at runtime; see comment above.
|
|
101
|
+
const model_components_db = typedDatabase.model_components as Table<ModelComponentRecord, string>;
|
|
102
|
+
// oxlint-disable-next-line no-unsafe-type-assertion -- database's table map is dynamically typed at runtime; see comment above.
|
|
103
|
+
const model_components_relation_db = typedDatabase.model_components_relation as Table<
|
|
106
104
|
ModelComponentRelationRecord,
|
|
107
105
|
string
|
|
108
106
|
>;
|
|
@@ -133,24 +131,37 @@ export const useDataStore = defineStore("data", () => {
|
|
|
133
131
|
return data_item;
|
|
134
132
|
}
|
|
135
133
|
async function allItems(): Promise<DataItem[]> {
|
|
136
|
-
|
|
134
|
+
const items = await data_db.toArray();
|
|
135
|
+
return items;
|
|
137
136
|
}
|
|
138
|
-
function refItem(id: string) {
|
|
137
|
+
function refItem(id: string): Ref<DataItem | undefined> {
|
|
139
138
|
// Dexie's liveQuery() returns Dexie's own minimal Observable shape, not an
|
|
140
139
|
// Actual rxjs Observable instance (useObservable's declared parameter type);
|
|
141
140
|
// The two are structurally close enough at runtime (vueuse only calls
|
|
142
141
|
// `.subscribe`) but not identical, hence the cast.
|
|
143
142
|
return useObservable(
|
|
144
|
-
liveQuery(() =>
|
|
143
|
+
liveQuery(async () => {
|
|
144
|
+
const data_item = await data_db.get(id);
|
|
145
|
+
return data_item;
|
|
146
|
+
// oxlint-disable-next-line no-unsafe-type-assertion -- trusted vueuse/Dexie Observable boundary; see comment above.
|
|
147
|
+
}) as unknown as Observable<DataItem | undefined>,
|
|
145
148
|
{
|
|
149
|
+
// oxlint-disable-next-line no-unsafe-type-assertion -- placeholder until the live query resolves; consumers must treat this as possibly incomplete.
|
|
146
150
|
initialValue: {} as DataItem,
|
|
147
151
|
},
|
|
148
152
|
);
|
|
149
153
|
}
|
|
150
|
-
function refAllItems() {
|
|
151
|
-
return useObservable(
|
|
152
|
-
|
|
153
|
-
|
|
154
|
+
function refAllItems(): Ref<DataItem[]> {
|
|
155
|
+
return useObservable(
|
|
156
|
+
liveQuery(async () => {
|
|
157
|
+
const items = await data_db.toArray();
|
|
158
|
+
return items;
|
|
159
|
+
// oxlint-disable-next-line no-unsafe-type-assertion -- trusted vueuse/Dexie Observable boundary; see comment above.
|
|
160
|
+
}) as unknown as Observable<DataItem[]>,
|
|
161
|
+
{
|
|
162
|
+
initialValue: [] as DataItem[],
|
|
163
|
+
},
|
|
164
|
+
);
|
|
154
165
|
}
|
|
155
166
|
async function meshComponentType(modelId: string, geode_id: string): Promise<string | undefined> {
|
|
156
167
|
const component = await model_components_db
|
|
@@ -159,32 +170,36 @@ export const useDataStore = defineStore("data", () => {
|
|
|
159
170
|
.first();
|
|
160
171
|
return component?.type;
|
|
161
172
|
}
|
|
162
|
-
async function registerObject(id: string, name: string) {
|
|
173
|
+
async function registerObject(id: string, name: string): Promise<unknown> {
|
|
163
174
|
const schema = viewer_generic_schemas.register;
|
|
164
175
|
const params = {
|
|
165
176
|
id,
|
|
166
177
|
name,
|
|
167
178
|
};
|
|
168
|
-
|
|
179
|
+
const result = await viewerStore.request({
|
|
169
180
|
schema,
|
|
170
181
|
params,
|
|
171
182
|
timeout: 0,
|
|
172
183
|
});
|
|
184
|
+
return result;
|
|
173
185
|
}
|
|
174
|
-
async function deregisterObject(id: string) {
|
|
186
|
+
async function deregisterObject(id: string): Promise<unknown> {
|
|
175
187
|
const schema = viewer_generic_schemas.deregister;
|
|
176
188
|
const params = {
|
|
177
189
|
id,
|
|
178
190
|
};
|
|
179
|
-
|
|
191
|
+
const result = await viewerStore.request({
|
|
180
192
|
schema,
|
|
181
193
|
params,
|
|
182
194
|
});
|
|
195
|
+
return result;
|
|
183
196
|
}
|
|
184
|
-
|
|
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> {
|
|
185
200
|
const itemData: DataItem = {
|
|
186
201
|
id: new_item.id,
|
|
187
|
-
name: new_item.name
|
|
202
|
+
name: new_item.name ?? new_item.id,
|
|
188
203
|
viewer_type: new_item.viewer_type,
|
|
189
204
|
geode_object_type: new_item.geode_object_type,
|
|
190
205
|
visible: true,
|
|
@@ -194,11 +209,16 @@ export const useDataStore = defineStore("data", () => {
|
|
|
194
209
|
if (new_item.binary_light_viewable !== undefined && new_item.binary_light_viewable !== null) {
|
|
195
210
|
itemData.binary_light_viewable = new_item.binary_light_viewable;
|
|
196
211
|
}
|
|
197
|
-
|
|
212
|
+
const id = await data_db.put(itemData);
|
|
213
|
+
return id;
|
|
198
214
|
}
|
|
199
|
-
|
|
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> {
|
|
200
218
|
const allComponents: ModelComponentRecord[] = [];
|
|
201
|
-
|
|
219
|
+
// ModelComponentInput has mutable array fields (boundaries, internals, items), so a readonly
|
|
220
|
+
// Array of it can't satisfy prefer-readonly-parameter-types deeply; same limitation as above.
|
|
221
|
+
function addModelComponents(components: readonly ModelComponentInput[]): void {
|
|
202
222
|
for (const component of components) {
|
|
203
223
|
allComponents.push({
|
|
204
224
|
id: new_item.id,
|
|
@@ -216,11 +236,18 @@ export const useDataStore = defineStore("data", () => {
|
|
|
216
236
|
if (new_item.collection_components) {
|
|
217
237
|
addModelComponents(new_item.collection_components);
|
|
218
238
|
}
|
|
219
|
-
|
|
239
|
+
const lastKey = await model_components_db.bulkPut(allComponents);
|
|
240
|
+
return lastKey;
|
|
220
241
|
}
|
|
221
|
-
|
|
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> {
|
|
222
245
|
const relations: ModelComponentRelationRecord[] = [];
|
|
223
|
-
function addModelComponentRelations(
|
|
246
|
+
function addModelComponentRelations(
|
|
247
|
+
components: readonly string[],
|
|
248
|
+
parent: string,
|
|
249
|
+
type: string,
|
|
250
|
+
): void {
|
|
224
251
|
for (const child of components) {
|
|
225
252
|
relations.push({
|
|
226
253
|
id: new_item.id,
|
|
@@ -247,13 +274,17 @@ export const useDataStore = defineStore("data", () => {
|
|
|
247
274
|
}
|
|
248
275
|
}
|
|
249
276
|
}
|
|
250
|
-
|
|
277
|
+
const lastKey = await model_components_relation_db.bulkPut(relations);
|
|
278
|
+
return lastKey;
|
|
251
279
|
}
|
|
252
|
-
async function getComponentByViewerId(
|
|
280
|
+
async function getComponentByViewerId(
|
|
281
|
+
modelId: string,
|
|
282
|
+
viewer_id: string | number,
|
|
283
|
+
): Promise<ModelComponentRecord | undefined> {
|
|
253
284
|
const component = await model_components_db
|
|
254
285
|
.where("viewer_id")
|
|
255
286
|
.equals(Number(viewer_id))
|
|
256
|
-
.and((model_component) => model_component.id === modelId)
|
|
287
|
+
.and((model_component: ModelComponentRecord) => model_component.id === modelId)
|
|
257
288
|
.first();
|
|
258
289
|
return component;
|
|
259
290
|
}
|
|
@@ -273,19 +304,27 @@ export const useDataStore = defineStore("data", () => {
|
|
|
273
304
|
|
|
274
305
|
async function getAllModelComponentsViewerIds(modelId: string): Promise<number[]> {
|
|
275
306
|
const components = await model_components_db.where("id").equals(modelId).toArray();
|
|
276
|
-
return components.map((component) =>
|
|
307
|
+
return components.map((component: ModelComponentRecord) =>
|
|
308
|
+
Math.trunc(Number(component.viewer_id)),
|
|
309
|
+
);
|
|
277
310
|
}
|
|
278
311
|
async function getMeshComponentsViewerIds(
|
|
279
312
|
modelId: string,
|
|
280
|
-
meshComponentGeodeIds: string[],
|
|
313
|
+
meshComponentGeodeIds: readonly string[],
|
|
281
314
|
): Promise<number[]> {
|
|
282
315
|
const components = await model_components_db
|
|
283
316
|
.where("[id+geode_id]")
|
|
284
317
|
.anyOf(meshComponentGeodeIds.map((geode_id) => [modelId, geode_id]))
|
|
285
318
|
.toArray();
|
|
286
|
-
return components.map((component) =>
|
|
319
|
+
return components.map((component: ModelComponentRecord) =>
|
|
320
|
+
Math.trunc(Number(component.viewer_id)),
|
|
321
|
+
);
|
|
287
322
|
}
|
|
288
|
-
async function exportStores() {
|
|
323
|
+
async function exportStores(): Promise<{
|
|
324
|
+
items: DataItem[];
|
|
325
|
+
modelComponents: ModelComponentRecord[];
|
|
326
|
+
modelComponentsRelations: ModelComponentRelationRecord[];
|
|
327
|
+
}> {
|
|
289
328
|
const items = await data_db.toArray();
|
|
290
329
|
const modelComponents = await model_components_db.toArray();
|
|
291
330
|
const modelComponentsRelations = await model_components_relation_db.toArray();
|
|
@@ -302,9 +341,11 @@ export const useDataStore = defineStore("data", () => {
|
|
|
302
341
|
await model_components_relation_db.clear();
|
|
303
342
|
}
|
|
304
343
|
|
|
344
|
+
// Dexie's bulkPut expects mutable arrays, so this snapshot parameter can't deeply satisfy
|
|
345
|
+
// The prefer-readonly-parameter-types rule; same pattern as app/utils/import_workflow.ts.
|
|
305
346
|
async function importStores(snapshot: {
|
|
306
|
-
modelComponents: ModelComponentRecord[];
|
|
307
|
-
modelComponentsRelations: ModelComponentRelationRecord[];
|
|
347
|
+
readonly modelComponents: readonly ModelComponentRecord[];
|
|
348
|
+
readonly modelComponentsRelations: readonly ModelComponentRelationRecord[];
|
|
308
349
|
}): Promise<void> {
|
|
309
350
|
await clear();
|
|
310
351
|
await model_components_db.bulkPut(snapshot.modelComponents);
|
|
@@ -1,15 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
// oxlint-disable eslint/sort-imports
|
|
3
|
-
import { liveQuery } from "dexie";
|
|
4
|
-
// oxlint-disable-next-line eslint/no-duplicate-imports
|
|
5
|
-
import type { Table } from "dexie";
|
|
1
|
+
import { type FormattedComponent, type ModelComponentRecord, useDataMesh } from "./mesh.js";
|
|
6
2
|
import { MESH_COMPONENT_TYPES } from "@ogw_front/utils/default_styles";
|
|
7
|
-
import { database } from "@ogw_internal/database/database.js";
|
|
8
|
-
import { useDataMesh } from "./mesh.js";
|
|
9
|
-
// oxlint-disable-next-line eslint/no-duplicate-imports
|
|
10
|
-
import type { FormattedComponent, ModelComponentRecord } from "./mesh.js";
|
|
11
|
-
import { useObservable } from "@vueuse/rxjs";
|
|
12
3
|
import type { Observable } from "rxjs";
|
|
4
|
+
import type { Ref } from "vue";
|
|
5
|
+
import { getTable } from "@ogw_internal/database/database.js";
|
|
6
|
+
import { liveQuery } from "dexie";
|
|
7
|
+
import { useObservable } from "@vueuse/rxjs";
|
|
13
8
|
|
|
14
9
|
interface ModelComponentRelationRecord {
|
|
15
10
|
id: string;
|
|
@@ -19,13 +14,13 @@ interface ModelComponentRelationRecord {
|
|
|
19
14
|
}
|
|
20
15
|
|
|
21
16
|
interface CollectionComponent extends FormattedComponent {
|
|
22
|
-
children: FormattedComponent[];
|
|
17
|
+
readonly children: readonly FormattedComponent[];
|
|
23
18
|
}
|
|
24
19
|
|
|
25
20
|
interface CollectionComponentGroup {
|
|
26
21
|
id: string;
|
|
27
22
|
title: string;
|
|
28
|
-
children: CollectionComponent[];
|
|
23
|
+
readonly children: readonly CollectionComponent[];
|
|
29
24
|
}
|
|
30
25
|
|
|
31
26
|
function pluralize(type: string): string {
|
|
@@ -35,22 +30,25 @@ function pluralize(type: string): string {
|
|
|
35
30
|
return `${type}s`;
|
|
36
31
|
}
|
|
37
32
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
33
|
+
// oxlint-disable-next-line eslint/max-lines-per-function
|
|
34
|
+
export function useDataCollections(): {
|
|
35
|
+
hasCollectionComponents: typeof hasCollectionComponents;
|
|
36
|
+
getAllCollectionComponents: typeof getAllCollectionComponents;
|
|
37
|
+
fetchAllCollectionComponents: typeof fetchAllCollectionComponents;
|
|
38
|
+
formatedCollectionComponents: typeof formatedCollectionComponents;
|
|
39
|
+
refFormatedCollectionComponents: typeof refFormatedCollectionComponents;
|
|
40
|
+
} {
|
|
41
|
+
const model_components_db = getTable<ModelComponentRecord>("model_components");
|
|
42
|
+
const model_components_relation_db = getTable<ModelComponentRelationRecord>(
|
|
43
|
+
"model_components_relation",
|
|
44
|
+
);
|
|
47
45
|
const { getAllMeshComponents } = useDataMesh();
|
|
48
46
|
|
|
49
47
|
async function hasCollectionComponents(modelId: string): Promise<boolean> {
|
|
50
48
|
const count = await model_components_db
|
|
51
49
|
.where("id")
|
|
52
50
|
.equals(modelId)
|
|
53
|
-
.and((component) => !MESH_COMPONENT_TYPES.includes(component.type))
|
|
51
|
+
.and((component: ModelComponentRecord) => !MESH_COMPONENT_TYPES.includes(component.type))
|
|
54
52
|
.count();
|
|
55
53
|
return count > 0;
|
|
56
54
|
}
|
|
@@ -58,8 +56,8 @@ export function useDataCollections() {
|
|
|
58
56
|
async function getAllCollectionComponents(modelId: string): Promise<FormattedComponent[]> {
|
|
59
57
|
const items = await model_components_db.where("id").equals(modelId).toArray();
|
|
60
58
|
return items
|
|
61
|
-
.filter((component) => !MESH_COMPONENT_TYPES.includes(component.type))
|
|
62
|
-
.map((component) => ({
|
|
59
|
+
.filter((component: ModelComponentRecord) => !MESH_COMPONENT_TYPES.includes(component.type))
|
|
60
|
+
.map((component: ModelComponentRecord) => ({
|
|
63
61
|
id: component.geode_id,
|
|
64
62
|
title: component.name,
|
|
65
63
|
category: component.type,
|
|
@@ -81,14 +79,13 @@ export function useDataCollections() {
|
|
|
81
79
|
|
|
82
80
|
const byType: Record<string, CollectionComponent[]> = {};
|
|
83
81
|
for (const component of components) {
|
|
84
|
-
|
|
85
|
-
byType[component.category] = [];
|
|
86
|
-
}
|
|
82
|
+
byType[component.category] ??= [];
|
|
87
83
|
const itemRelations = relations.filter(
|
|
88
|
-
(relation) =>
|
|
84
|
+
(relation: ModelComponentRelationRecord) =>
|
|
85
|
+
relation.parent === component.id && relation.type === "collection",
|
|
89
86
|
);
|
|
90
87
|
const children = itemRelations
|
|
91
|
-
.map((relation) => meshComponentsById[relation.child])
|
|
88
|
+
.map((relation: ModelComponentRelationRecord) => meshComponentsById[relation.child])
|
|
92
89
|
.filter((child): child is FormattedComponent => Boolean(child));
|
|
93
90
|
byType[component.category]?.push({
|
|
94
91
|
...component,
|
|
@@ -105,7 +102,7 @@ export function useDataCollections() {
|
|
|
105
102
|
const collectionTypes = Object.keys(byType);
|
|
106
103
|
|
|
107
104
|
return collectionTypes
|
|
108
|
-
.filter((type) =>
|
|
105
|
+
.filter((type) => (byType[type]?.length ?? 0) > 0)
|
|
109
106
|
.map((type) => ({
|
|
110
107
|
id: type,
|
|
111
108
|
title: pluralize(type),
|
|
@@ -113,15 +110,16 @@ export function useDataCollections() {
|
|
|
113
110
|
}));
|
|
114
111
|
}
|
|
115
112
|
|
|
116
|
-
function refFormatedCollectionComponents(
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
// The two are structurally close enough at runtime (vueuse only calls
|
|
120
|
-
// `.subscribe`) but not identical, hence the cast.
|
|
113
|
+
function refFormatedCollectionComponents(
|
|
114
|
+
modelId: string,
|
|
115
|
+
): Ref<CollectionComponentGroup[] | undefined> {
|
|
121
116
|
return useObservable(
|
|
122
|
-
liveQuery
|
|
123
|
-
|
|
124
|
-
|
|
117
|
+
// Dexie's liveQuery returns its own Observable-like type, not rxjs's Observable, so bridging needs a cast.
|
|
118
|
+
liveQuery(async () => {
|
|
119
|
+
const groups = await formatedCollectionComponents(modelId);
|
|
120
|
+
return groups;
|
|
121
|
+
// oxlint-disable-next-line no-unsafe-type-assertion
|
|
122
|
+
}) as unknown as Observable<CollectionComponentGroup[]>,
|
|
125
123
|
{
|
|
126
124
|
initialValue: undefined,
|
|
127
125
|
},
|