@geode/opengeodeweb-front 10.34.0-rc.12 → 10.34.0-rc.14
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 +20 -28
- 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 +17 -11
- 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/internal/utils/api_fetch.ts +19 -13
- 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
|
@@ -19,14 +19,14 @@ async function performFetch({ route, method, params, baseURL, headers, max_retry
|
|
|
19
19
|
headers,
|
|
20
20
|
...hasBody(params) ? { body: params } : {},
|
|
21
21
|
...max_retry === void 0 ? {} : { retry: max_retry },
|
|
22
|
-
onRequestError({ error }) {
|
|
23
|
-
if (request_error_function) request_error_function(error);
|
|
22
|
+
async onRequestError({ error }) {
|
|
23
|
+
if (request_error_function) await request_error_function(error);
|
|
24
24
|
},
|
|
25
|
-
onResponse({ response }) {
|
|
26
|
-
if (response.ok && response_function) response_function(response._data);
|
|
25
|
+
async onResponse({ response }) {
|
|
26
|
+
if (response.ok && response_function) await response_function(response._data);
|
|
27
27
|
},
|
|
28
|
-
onResponseError({ response }) {
|
|
29
|
-
if (response_error_function) response_error_function(response);
|
|
28
|
+
async onResponseError({ response }) {
|
|
29
|
+
if (response_error_function) await response_error_function(response);
|
|
30
30
|
}
|
|
31
31
|
});
|
|
32
32
|
}
|
|
@@ -40,7 +40,7 @@ function useClippingPlanesWidget({
|
|
|
40
40
|
allItems,
|
|
41
41
|
hybridViewerStore,
|
|
42
42
|
debouncedApply,
|
|
43
|
-
}:
|
|
43
|
+
}: ClippingPlanesWidgetParams): {
|
|
44
44
|
getSceneCenter: typeof getSceneCenter;
|
|
45
45
|
syncWidgets: typeof syncWidgets;
|
|
46
46
|
syncLocalCamera: typeof syncLocalCamera;
|
|
@@ -82,7 +82,7 @@ function useClippingPlanesWidget({
|
|
|
82
82
|
localRenderWindow.getRenderWindow().render();
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
-
function limitCameraZoomOut(camera:
|
|
85
|
+
function limitCameraZoomOut(camera: vtkCamera): void {
|
|
86
86
|
if (maxDistance <= 0 || isLimitingCameraZoom) {
|
|
87
87
|
return;
|
|
88
88
|
}
|
|
@@ -128,7 +128,7 @@ function useClippingPlanesWidget({
|
|
|
128
128
|
widgetManager = undefined;
|
|
129
129
|
}
|
|
130
130
|
}
|
|
131
|
-
function updateWidgetPlacement({ isReset = false }:
|
|
131
|
+
function updateWidgetPlacement({ isReset = false }: { isReset?: boolean } = {}): void {
|
|
132
132
|
if (!widgetManager || !localRenderWindow) {
|
|
133
133
|
return;
|
|
134
134
|
}
|
|
@@ -148,11 +148,11 @@ function useClippingPlanesWidget({
|
|
|
148
148
|
}
|
|
149
149
|
}
|
|
150
150
|
|
|
151
|
-
function initLocalWidget(container:
|
|
151
|
+
function initLocalWidget(container: HTMLElement): void {
|
|
152
152
|
cleanupLocalWidget();
|
|
153
153
|
container.addEventListener(
|
|
154
154
|
"wheel",
|
|
155
|
-
(event:
|
|
155
|
+
(event: WheelEvent) => {
|
|
156
156
|
event.stopPropagation();
|
|
157
157
|
},
|
|
158
158
|
{ passive: true },
|
|
@@ -41,9 +41,7 @@ interface WidgetEntry {
|
|
|
41
41
|
subscription: { unsubscribe: () => void };
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
function asWidgetFactory(
|
|
45
|
-
widget: Readonly<PlaneWidget>,
|
|
46
|
-
): vtkAbstractWidgetFactory<vtkAbstractWidget> {
|
|
44
|
+
function asWidgetFactory(widget: PlaneWidget): vtkAbstractWidgetFactory<vtkAbstractWidget> {
|
|
47
45
|
// oxlint-disable-next-line no-unsafe-type-assertion -- vtk.js's WidgetManager APIs (addWidget/removeWidget) are untyped for our custom PlaneWidget shape; narrowed once here.
|
|
48
46
|
return widget as unknown as vtkAbstractWidgetFactory<vtkAbstractWidget>;
|
|
49
47
|
}
|
|
@@ -54,11 +52,11 @@ interface WidgetEntryManagerParams {
|
|
|
54
52
|
}
|
|
55
53
|
|
|
56
54
|
// oxlint-disable-next-line max-lines-per-function typescript/prefer-readonly-parameter-types -- Ref-backed params are inherently mutable through .value.
|
|
57
|
-
function useWidgetEntryManager({ planes, debouncedApply }:
|
|
55
|
+
function useWidgetEntryManager({ planes, debouncedApply }: WidgetEntryManagerParams): {
|
|
58
56
|
removeExtraWidgets: (widgetManager: WidgetManagerInstance | undefined) => void;
|
|
59
57
|
updateWidgetEntry: (
|
|
60
58
|
idx: number,
|
|
61
|
-
plane:
|
|
59
|
+
plane: ClippingPlane,
|
|
62
60
|
cubicBounds: readonly number[],
|
|
63
61
|
widgetManager: WidgetManagerInstance,
|
|
64
62
|
) => void;
|
|
@@ -70,8 +68,8 @@ function useWidgetEntryManager({ planes, debouncedApply }: Readonly<WidgetEntryM
|
|
|
70
68
|
let fromWidget = false;
|
|
71
69
|
|
|
72
70
|
function createWidgetEntry(
|
|
73
|
-
planeWidget:
|
|
74
|
-
widgetHandle:
|
|
71
|
+
planeWidget: PlaneWidget,
|
|
72
|
+
widgetHandle: WidgetHandle,
|
|
75
73
|
planeIndex: number,
|
|
76
74
|
): WidgetEntry {
|
|
77
75
|
const widgetState = planeWidget.getWidgetState();
|
|
@@ -125,7 +123,7 @@ function useWidgetEntryManager({ planes, debouncedApply }: Readonly<WidgetEntryM
|
|
|
125
123
|
|
|
126
124
|
function updateWidgetEntry(
|
|
127
125
|
idx: number,
|
|
128
|
-
plane:
|
|
126
|
+
plane: ClippingPlane,
|
|
129
127
|
cubicBounds: readonly number[],
|
|
130
128
|
widgetManager: WidgetManagerInstance,
|
|
131
129
|
): void {
|
|
@@ -70,7 +70,7 @@ function isNumberOrUndefined(value: unknown): value is number | undefined {
|
|
|
70
70
|
return value === undefined || typeof value === "number";
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
-
export function useGlobalAttributeStyle(dataIdRef:
|
|
73
|
+
export function useGlobalAttributeStyle(dataIdRef: Ref<string | undefined>): {
|
|
74
74
|
currentColormap: typeof currentColormap;
|
|
75
75
|
currentRange: typeof currentRange;
|
|
76
76
|
applyGlobalColormap: typeof applyGlobalColormap;
|
|
@@ -86,11 +86,11 @@ export function useHoverhighlight(): {
|
|
|
86
86
|
async function unhighlightAction(
|
|
87
87
|
type: HighlightType,
|
|
88
88
|
id: string,
|
|
89
|
-
request:
|
|
89
|
+
request: {
|
|
90
90
|
schema: JsonRpcSchema;
|
|
91
|
-
params?:
|
|
91
|
+
params?: Record<string, unknown>;
|
|
92
92
|
timeout?: number;
|
|
93
|
-
}
|
|
93
|
+
},
|
|
94
94
|
): Promise<void> {
|
|
95
95
|
try {
|
|
96
96
|
await viewerStore.request(request);
|
|
@@ -93,7 +93,7 @@ async function importProjectToViewer(
|
|
|
93
93
|
}
|
|
94
94
|
}
|
|
95
95
|
|
|
96
|
-
async function importProject(file:
|
|
96
|
+
async function importProject(file: File): Promise<void> {
|
|
97
97
|
const backStore = useBackStore();
|
|
98
98
|
const dataStyleStore = useDataStyleStore();
|
|
99
99
|
const viewerStore = useViewerStore();
|
|
@@ -12,13 +12,13 @@ interface ResponsiveMiddleTruncateOptions {
|
|
|
12
12
|
readonly minStartChars?: number;
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
//
|
|
16
|
-
type ReadonlyMaybeRefOrGetter<Value> = Value |
|
|
15
|
+
// Same shape as Vue's MaybeRefOrGetter<T>, kept as a local alias for readability at call sites.
|
|
16
|
+
type ReadonlyMaybeRefOrGetter<Value> = Value | Ref<Value> | (() => Value);
|
|
17
17
|
|
|
18
18
|
export function useResponsiveMiddleTruncate(
|
|
19
19
|
textRef: ReadonlyMaybeRefOrGetter<string | undefined | null>,
|
|
20
20
|
containerWidthRef: ReadonlyMaybeRefOrGetter<number | undefined>,
|
|
21
|
-
options:
|
|
21
|
+
options: ResponsiveMiddleTruncateOptions = {},
|
|
22
22
|
): ComputedRef<string> {
|
|
23
23
|
const {
|
|
24
24
|
estimatedCharWidth = DEFAULT_ESTIMATED_CHAR_WIDTH,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
interface StepperTreeApi {
|
|
2
2
|
state: Record<string, unknown>;
|
|
3
|
-
update_values: (keys_values_object:
|
|
3
|
+
update_values: (keys_values_object: Record<string, unknown>) => void;
|
|
4
4
|
increment_step: () => void;
|
|
5
5
|
decrement_step: () => void;
|
|
6
6
|
reset_values: () => void;
|
|
@@ -10,13 +10,13 @@ function isUnknownArray(value: unknown): value is unknown[] {
|
|
|
10
10
|
return Array.isArray(value);
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
function get_current_step_index(state:
|
|
13
|
+
function get_current_step_index(state: Record<string, unknown>): number {
|
|
14
14
|
const value = state.current_step_index;
|
|
15
15
|
return typeof value === "number" ? value : 0;
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
function build_initial_state_unref(
|
|
19
|
-
initial_state:
|
|
19
|
+
initial_state: Record<string, unknown>,
|
|
20
20
|
): Record<string, unknown> {
|
|
21
21
|
const initial_state_unref: Record<string, unknown> = {};
|
|
22
22
|
for (const [key, value] of Object.entries(initial_state)) {
|
|
@@ -28,7 +28,7 @@ function build_initial_state_unref(
|
|
|
28
28
|
|
|
29
29
|
export function useStepperTree(
|
|
30
30
|
steps: readonly unknown[],
|
|
31
|
-
initial_state:
|
|
31
|
+
initial_state: Record<string, unknown> = {},
|
|
32
32
|
): StepperTreeApi {
|
|
33
33
|
const initial_state_unref = build_initial_state_unref(initial_state);
|
|
34
34
|
const state = reactive<Record<string, unknown>>({
|
|
@@ -47,7 +47,7 @@ export function useStepperTree(
|
|
|
47
47
|
},
|
|
48
48
|
);
|
|
49
49
|
|
|
50
|
-
function update_values(keys_values_object:
|
|
50
|
+
function update_values(keys_values_object: Record<string, unknown>): void {
|
|
51
51
|
for (const [key, value] of Object.entries(keys_values_object)) {
|
|
52
52
|
state[key] = value;
|
|
53
53
|
}
|
|
@@ -1,11 +1,7 @@
|
|
|
1
1
|
import type { Ref } from "vue";
|
|
2
2
|
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
// Deeply readonly T itself is, and wrapping the *whole* union in Readonly<> instead would collapse
|
|
6
|
-
// The getter-function branch to an uncallable `{}` (Readonly<Fn> has no keys). Callers passing an
|
|
7
|
-
// Ordinary Ref<T> still type-check fine here: a mutable Ref<T> is assignable to Readonly<Ref<T>>.
|
|
8
|
-
type ReadonlyMaybeRefOrGetter<Value> = Value | Readonly<Ref<Value>> | (() => Value);
|
|
3
|
+
// Same shape as Vue's MaybeRefOrGetter<T>, kept as a local alias for readability at call sites.
|
|
4
|
+
type ReadonlyMaybeRefOrGetter<Value> = Value | Ref<Value> | (() => Value);
|
|
9
5
|
|
|
10
6
|
// This composable filters/sorts different flavors of "category with children" trees (treeview groups, model component/collection groups, ...); this shape captures just the fields it reads/writes, generically, across all of them.
|
|
11
7
|
interface FilterableItem {
|
|
@@ -21,7 +17,7 @@ interface FilterContext {
|
|
|
21
17
|
interface TreeFilterOptions {
|
|
22
18
|
readonly recursiveSort?: boolean;
|
|
23
19
|
readonly defaultSort?: string;
|
|
24
|
-
readonly defaultFilters?:
|
|
20
|
+
readonly defaultFilters?: Record<string, boolean>;
|
|
25
21
|
}
|
|
26
22
|
|
|
27
23
|
interface UseTreeFilterReturn {
|
|
@@ -11,8 +11,8 @@ interface ScrollInfo {
|
|
|
11
11
|
itemHeight: number;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
type ReadonlyDisplayItem =
|
|
15
|
-
readonly raw:
|
|
14
|
+
type ReadonlyDisplayItem = Omit<DisplayItem, "raw"> & {
|
|
15
|
+
readonly raw: Record<string, unknown>;
|
|
16
16
|
};
|
|
17
17
|
|
|
18
18
|
interface KeyboardEventLike {
|
|
@@ -22,13 +22,13 @@ interface KeyboardEventLike {
|
|
|
22
22
|
|
|
23
23
|
interface UseTreeKeyboardNavReturn {
|
|
24
24
|
focusedIndex: Ref<number>;
|
|
25
|
-
handleKeyDown: (event:
|
|
25
|
+
handleKeyDown: (event: KeyboardEventLike) => void;
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
function getBaseIndex(
|
|
29
29
|
currentIndex: number,
|
|
30
30
|
lastIndex: number,
|
|
31
|
-
bounds:
|
|
31
|
+
bounds: VisibleBounds | undefined,
|
|
32
32
|
key: string,
|
|
33
33
|
): number {
|
|
34
34
|
if (currentIndex < 0 || currentIndex > lastIndex) {
|
|
@@ -49,13 +49,13 @@ function getBaseIndex(
|
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
export function useTreeKeyboardNav(
|
|
52
|
-
displayItems:
|
|
52
|
+
displayItems: Ref<readonly ReadonlyDisplayItem[]>,
|
|
53
53
|
emit: EmitFn,
|
|
54
54
|
scrollToIndex: (index: number) => void,
|
|
55
|
-
toggleOpen: (raw:
|
|
55
|
+
toggleOpen: (raw: Record<string, unknown>) => void,
|
|
56
56
|
handleItemClick: (item: ReadonlyDisplayItem, index: number) => void,
|
|
57
57
|
getScrollInfo: (() => ScrollInfo | undefined) | undefined,
|
|
58
|
-
externalFocusedIndex:
|
|
58
|
+
externalFocusedIndex: Ref<number> | undefined,
|
|
59
59
|
): UseTreeKeyboardNavReturn {
|
|
60
60
|
const focusedIndex = externalFocusedIndex ?? ref(-1);
|
|
61
61
|
|
|
@@ -143,7 +143,7 @@ export function useTreeKeyboardNav(
|
|
|
143
143
|
return currentIndex;
|
|
144
144
|
}
|
|
145
145
|
|
|
146
|
-
function handleKeyDown(event:
|
|
146
|
+
function handleKeyDown(event: KeyboardEventLike): void {
|
|
147
147
|
if (displayItems.value.length === 0) {
|
|
148
148
|
return;
|
|
149
149
|
}
|
|
@@ -14,34 +14,34 @@ interface ScrollInfo {
|
|
|
14
14
|
itemHeight: number;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
type ReadonlyMaybeRefOrGetter<Value> = Value |
|
|
17
|
+
type ReadonlyMaybeRefOrGetter<Value> = Value | Ref<Value> | (() => Value);
|
|
18
18
|
|
|
19
|
-
type ReadonlyDisplayItem =
|
|
20
|
-
readonly raw:
|
|
19
|
+
type ReadonlyDisplayItem = Omit<DisplayItem, "raw"> & {
|
|
20
|
+
readonly raw: Record<string, unknown>;
|
|
21
21
|
};
|
|
22
22
|
|
|
23
23
|
interface ScrollEventLike {
|
|
24
|
-
readonly target:
|
|
24
|
+
readonly target: EventTarget | null;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
interface UseTreeScrollReturn {
|
|
28
28
|
internalScrollTop: Ref<number>;
|
|
29
29
|
virtualScrollRef: Ref<ScrollableElement | undefined>;
|
|
30
30
|
stickyHeader: ComputedRef<ReadonlyDisplayItem | undefined>;
|
|
31
|
-
handleScroll: (event:
|
|
31
|
+
handleScroll: (event: ScrollEventLike) => void;
|
|
32
32
|
scrollToIndex: (index: number) => void;
|
|
33
33
|
getScrollInfo: () => ScrollInfo;
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
function isHtmlElement(value:
|
|
36
|
+
function isHtmlElement(value: EventTarget | null): value is HTMLElement {
|
|
37
37
|
return value instanceof HTMLElement;
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
export function useTreeScroll(
|
|
41
|
-
propsIn: ReadonlyMaybeRefOrGetter<
|
|
41
|
+
propsIn: ReadonlyMaybeRefOrGetter<TreeScrollProps>,
|
|
42
42
|
emit: EmitFn,
|
|
43
|
-
displayItems:
|
|
44
|
-
actualItemProps:
|
|
43
|
+
displayItems: Ref<readonly ReadonlyDisplayItem[]>,
|
|
44
|
+
actualItemProps: Ref<ItemPropsConfig>,
|
|
45
45
|
): UseTreeScrollReturn {
|
|
46
46
|
const SCROLL_STICKY_THRESHOLD = 10;
|
|
47
47
|
const DEFAULT_ITEM_HEIGHT = 28;
|
|
@@ -50,7 +50,7 @@ export function useTreeScroll(
|
|
|
50
50
|
const internalScrollTop = ref(props.value.scrollTop ?? 0);
|
|
51
51
|
const virtualScrollRef = ref<ScrollableElement | undefined>(undefined);
|
|
52
52
|
|
|
53
|
-
function handleScroll(event:
|
|
53
|
+
function handleScroll(event: ScrollEventLike): void {
|
|
54
54
|
const { target } = event;
|
|
55
55
|
if (!isHtmlElement(target)) {
|
|
56
56
|
return;
|
|
@@ -60,7 +60,7 @@ function getValue(val: unknown): number {
|
|
|
60
60
|
// oxlint-disable max-lines-per-function
|
|
61
61
|
export function useAdaptiveStyles(
|
|
62
62
|
target: AdaptiveStylesTarget,
|
|
63
|
-
options:
|
|
63
|
+
options: AdaptiveStylesOptions = {},
|
|
64
64
|
): {
|
|
65
65
|
adaptiveStyles: ComputedRef<{
|
|
66
66
|
"--adaptive-blur": string;
|
|
@@ -34,7 +34,7 @@ interface GetViewerIdParams {
|
|
|
34
34
|
y: number;
|
|
35
35
|
containerWidth: number;
|
|
36
36
|
containerHeight: number;
|
|
37
|
-
containerRect:
|
|
37
|
+
containerRect: { left: number; top: number };
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
interface UseOverlappingPickerReturn {
|
|
@@ -43,9 +43,9 @@ interface UseOverlappingPickerReturn {
|
|
|
43
43
|
intermediateMenuX: Ref<number>;
|
|
44
44
|
intermediateMenuY: Ref<number>;
|
|
45
45
|
getIntermediateMenuStyle: () => { position: string; left: string; top: string };
|
|
46
|
-
selectIntermediateItem: (item:
|
|
46
|
+
selectIntermediateItem: (item: ProposedItem | undefined) => void;
|
|
47
47
|
handleIntermediateMenuUpdate: (val: boolean) => void;
|
|
48
|
-
get_viewer_id: (params:
|
|
48
|
+
get_viewer_id: (params: GetViewerIdParams) => Promise<ViewerIdResult>;
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
function isPickedItem(entry: unknown): entry is PickedItem {
|
|
@@ -95,14 +95,11 @@ export function useOverlappingPicker(): UseOverlappingPickerReturn {
|
|
|
95
95
|
const intermediateItems = ref<ProposedItem[]>([]);
|
|
96
96
|
const intermediateMenuX = ref(0);
|
|
97
97
|
const intermediateMenuY = ref(0);
|
|
98
|
-
let resolveIntermediate: ((item:
|
|
99
|
-
undefined;
|
|
98
|
+
let resolveIntermediate: ((item: ProposedItem | undefined) => void) | undefined = undefined;
|
|
100
99
|
|
|
101
|
-
async function fetchProposedItems(
|
|
102
|
-
pickedList: readonly Readonly<PickedItem>[],
|
|
103
|
-
): Promise<ProposedItem[]> {
|
|
100
|
+
async function fetchProposedItems(pickedList: readonly PickedItem[]): Promise<ProposedItem[]> {
|
|
104
101
|
const proposedItems = await Promise.all(
|
|
105
|
-
pickedList.map(async (pick:
|
|
102
|
+
pickedList.map(async (pick: PickedItem) => {
|
|
106
103
|
try {
|
|
107
104
|
const item = await dataStore.item(pick.id);
|
|
108
105
|
return {
|
|
@@ -134,7 +131,7 @@ export function useOverlappingPicker(): UseOverlappingPickerReturn {
|
|
|
134
131
|
};
|
|
135
132
|
}
|
|
136
133
|
|
|
137
|
-
function selectIntermediateItem(item:
|
|
134
|
+
function selectIntermediateItem(item: ProposedItem | undefined): void {
|
|
138
135
|
if (resolveIntermediate) {
|
|
139
136
|
resolveIntermediate(item);
|
|
140
137
|
resolveIntermediate = undefined;
|
|
@@ -154,8 +151,8 @@ export function useOverlappingPicker(): UseOverlappingPickerReturn {
|
|
|
154
151
|
containerWidth,
|
|
155
152
|
containerHeight,
|
|
156
153
|
containerRect,
|
|
157
|
-
}:
|
|
158
|
-
const activeIds = new Set(dataItems.value.map((i:
|
|
154
|
+
}: GetViewerIdParams): Promise<ViewerIdResult> {
|
|
155
|
+
const activeIds = new Set(dataItems.value.map((i: DataItem) => i.id));
|
|
159
156
|
const visibleStyleIds = Object.keys(dataStyleStore.styles).filter(
|
|
160
157
|
(styleId) => activeIds.has(styleId) && dataStyleStore.objectVisibility(styleId) === true,
|
|
161
158
|
);
|
|
@@ -242,7 +239,7 @@ export function useOverlappingPicker(): UseOverlappingPickerReturn {
|
|
|
242
239
|
|
|
243
240
|
/* eslint-disable-next-line promise/avoid-new */
|
|
244
241
|
return new Promise<ViewerIdResult>((resolve) => {
|
|
245
|
-
resolveIntermediate = (chosenResult:
|
|
242
|
+
resolveIntermediate = (chosenResult: ProposedItem | undefined): void => {
|
|
246
243
|
displayIntermediate.value = false;
|
|
247
244
|
resolve(
|
|
248
245
|
chosenResult
|
|
@@ -1,13 +1,9 @@
|
|
|
1
1
|
import type { Ref } from "vue";
|
|
2
2
|
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
// Deeply readonly T itself is, and wrapping the *whole* union in Readonly<> instead would collapse
|
|
6
|
-
// The getter-function branch to an uncallable `{}` (Readonly<Fn> has no keys). Callers passing an
|
|
7
|
-
// Ordinary Ref<T> still type-check fine here: a mutable Ref<T> is assignable to Readonly<Ref<T>>.
|
|
8
|
-
type ReadonlyMaybeRefOrGetter<Value> = Value | Readonly<Ref<Value>> | (() => Value);
|
|
3
|
+
// Same shape as Vue's MaybeRefOrGetter<T>, kept as a local alias for readability at call sites.
|
|
4
|
+
type ReadonlyMaybeRefOrGetter<Value> = Value | Ref<Value> | (() => Value);
|
|
9
5
|
|
|
10
|
-
type TreeItem =
|
|
6
|
+
type TreeItem = Record<string, unknown>;
|
|
11
7
|
|
|
12
8
|
interface ItemPropsConfig {
|
|
13
9
|
value: string;
|
|
@@ -28,14 +24,10 @@ interface VirtualTreeProps {
|
|
|
28
24
|
readonly opened?: readonly unknown[];
|
|
29
25
|
readonly selected?: readonly unknown[];
|
|
30
26
|
readonly active?: readonly unknown[];
|
|
31
|
-
readonly itemProps?:
|
|
32
|
-
readonly selection?:
|
|
27
|
+
readonly itemProps?: Partial<ItemPropsConfig>;
|
|
28
|
+
readonly selection?: Partial<SelectionConfig>;
|
|
33
29
|
readonly search?: string;
|
|
34
|
-
readonly customFilter?: (
|
|
35
|
-
id: unknown,
|
|
36
|
-
search: string,
|
|
37
|
-
context: Readonly<{ raw: TreeItem }>,
|
|
38
|
-
) => boolean;
|
|
30
|
+
readonly customFilter?: (id: unknown, search: string, context: { raw: TreeItem }) => boolean;
|
|
39
31
|
}
|
|
40
32
|
|
|
41
33
|
interface DisplayItem {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { PiniaPluginContext } from "pinia";
|
|
2
2
|
import { useAppStore } from "@ogw_front/stores/app";
|
|
3
3
|
|
|
4
|
-
function autoStoreRegister({ store }:
|
|
4
|
+
function autoStoreRegister({ store }: PiniaPluginContext): void {
|
|
5
5
|
if (store.$id === "app") {
|
|
6
6
|
return;
|
|
7
7
|
}
|
package/app/stores/app.ts
CHANGED
|
@@ -22,8 +22,8 @@ declare module "pinia" {
|
|
|
22
22
|
|
|
23
23
|
interface RegisterableStore {
|
|
24
24
|
$id: string;
|
|
25
|
-
$patch?: (partial:
|
|
26
|
-
exportStores?: (params?:
|
|
25
|
+
$patch?: (partial: Record<string, unknown>) => void;
|
|
26
|
+
exportStores?: (params?: Record<string, unknown>) => Promise<unknown>;
|
|
27
27
|
importStores?: (snapshot: unknown) => Promise<void> | void;
|
|
28
28
|
connect?: () => Promise<void>;
|
|
29
29
|
kill?: () => Promise<void>;
|
|
@@ -65,9 +65,9 @@ export const useAppStore = defineStore("app", () => {
|
|
|
65
65
|
}
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
-
function registerStore(store:
|
|
68
|
+
function registerStore(store: RegisterableStore): void {
|
|
69
69
|
const isAlreadyRegistered = stores.some(
|
|
70
|
-
(registeredStore:
|
|
70
|
+
(registeredStore: RegisterableStore) => registeredStore.$id === store.$id,
|
|
71
71
|
);
|
|
72
72
|
if (isAlreadyRegistered) {
|
|
73
73
|
return;
|
|
@@ -76,12 +76,12 @@ export const useAppStore = defineStore("app", () => {
|
|
|
76
76
|
}
|
|
77
77
|
|
|
78
78
|
async function exportStores(
|
|
79
|
-
params:
|
|
79
|
+
params: Record<string, unknown> = {},
|
|
80
80
|
): Promise<Record<string, unknown>> {
|
|
81
81
|
const snapshot: Record<string, unknown> = {};
|
|
82
82
|
|
|
83
83
|
await Promise.all(
|
|
84
|
-
stores.map(async (store:
|
|
84
|
+
stores.map(async (store: RegisterableStore) => {
|
|
85
85
|
if (!store.exportStores) {
|
|
86
86
|
return;
|
|
87
87
|
}
|
|
@@ -96,9 +96,7 @@ export const useAppStore = defineStore("app", () => {
|
|
|
96
96
|
return snapshot;
|
|
97
97
|
}
|
|
98
98
|
|
|
99
|
-
async function importStores(
|
|
100
|
-
snapshot: Readonly<Record<string, unknown>> | undefined,
|
|
101
|
-
): Promise<void> {
|
|
99
|
+
async function importStores(snapshot: Record<string, unknown> | undefined): Promise<void> {
|
|
102
100
|
if (!snapshot) {
|
|
103
101
|
return;
|
|
104
102
|
}
|
|
@@ -106,7 +104,7 @@ export const useAppStore = defineStore("app", () => {
|
|
|
106
104
|
const missingStoreIds: string[] = [];
|
|
107
105
|
|
|
108
106
|
await Promise.all(
|
|
109
|
-
stores.map(async (store:
|
|
107
|
+
stores.map(async (store: RegisterableStore) => {
|
|
110
108
|
if (!store.importStores) {
|
|
111
109
|
return;
|
|
112
110
|
}
|
|
@@ -142,14 +140,21 @@ export const useAppStore = defineStore("app", () => {
|
|
|
142
140
|
getExtensionEnabled,
|
|
143
141
|
} = useAppExtensions();
|
|
144
142
|
|
|
145
|
-
|
|
143
|
+
const request_counter = ref(0);
|
|
144
|
+
function start_request(): void {
|
|
145
|
+
request_counter.value += 1;
|
|
146
|
+
}
|
|
147
|
+
function stop_request(): void {
|
|
148
|
+
request_counter.value -= 1;
|
|
149
|
+
}
|
|
150
|
+
const is_busy = computed(() => request_counter.value > 0);
|
|
151
|
+
|
|
146
152
|
async function upload(file: Readonly<File>, callbacks: RequestHandlers = {}): Promise<unknown> {
|
|
147
|
-
const store = useAppStore();
|
|
148
153
|
const schema = opengeodeweb_front_schemas.api.local.extensions.upload;
|
|
149
154
|
const { PROJECT: projectName } = useRuntimeConfig().public;
|
|
150
155
|
const params = { projectName };
|
|
151
156
|
const result = await upload_file(
|
|
152
|
-
|
|
157
|
+
{ $id: "app", base_url: base_url.value, start_request, stop_request },
|
|
153
158
|
{ schema, file, params },
|
|
154
159
|
{
|
|
155
160
|
...callbacks,
|
|
@@ -166,15 +171,11 @@ export const useAppStore = defineStore("app", () => {
|
|
|
166
171
|
// `TResult` is asserted, not verified, at the single `return result as TResult` boundary below: the backend response is only checked against `schema` at runtime, so callers' `TResult` is a contract with the schema, not something this function can prove.
|
|
167
172
|
// oxlint-disable-next-line unicorn/consistent-function-scoping
|
|
168
173
|
async function request<TResult = unknown>(
|
|
169
|
-
{
|
|
170
|
-
schema,
|
|
171
|
-
params,
|
|
172
|
-
}: Readonly<{ schema: JsonRpcSchema; params?: Readonly<Record<string, unknown>> }>,
|
|
174
|
+
{ schema, params }: { schema: JsonRpcSchema; params?: Record<string, unknown> },
|
|
173
175
|
callbacks: RequestHandlers = {},
|
|
174
176
|
): Promise<TResult> {
|
|
175
|
-
const store = useAppStore();
|
|
176
177
|
const result = await api_fetch(
|
|
177
|
-
|
|
178
|
+
{ $id: "app", base_url: base_url.value, start_request, stop_request },
|
|
178
179
|
// The app store is only ever used with HTTP ("front") schemas, which always carry `methods`; the wider JsonRpcSchema param above is kept as-is to match this action's public signature (e.g. relayed from get_version-style callers that only know about the shared, looser schema shape).
|
|
179
180
|
// oxlint-disable-next-line no-unsafe-type-assertion -- narrowing optional `methods` to required is safe here; see comment above.
|
|
180
181
|
{ schema: schema as JsonRpcSchema & { methods: string[] }, params },
|
|
@@ -191,15 +192,6 @@ export const useAppStore = defineStore("app", () => {
|
|
|
191
192
|
return result as TResult;
|
|
192
193
|
}
|
|
193
194
|
|
|
194
|
-
const request_counter = ref(0);
|
|
195
|
-
function start_request(): void {
|
|
196
|
-
request_counter.value += 1;
|
|
197
|
-
}
|
|
198
|
-
function stop_request(): void {
|
|
199
|
-
request_counter.value -= 1;
|
|
200
|
-
}
|
|
201
|
-
const is_busy = computed(() => request_counter.value > 0);
|
|
202
|
-
|
|
203
195
|
const projectFolderPath = ref("");
|
|
204
196
|
|
|
205
197
|
async function createProjectFolder(): Promise<unknown> {
|
package/app/stores/back.ts
CHANGED
|
@@ -77,7 +77,7 @@ export const useBackStore = defineStore("back", {
|
|
|
77
77
|
stop_request() {
|
|
78
78
|
this.request_counter -= 1;
|
|
79
79
|
},
|
|
80
|
-
async launch(args:
|
|
80
|
+
async launch(args: Record<string, unknown>) {
|
|
81
81
|
const appStore = useAppStore();
|
|
82
82
|
const { COMMAND_BACK, NUXT_ROOT_PATH } = useRuntimeConfig().public;
|
|
83
83
|
const schema = opengeodeweb_front_schemas.api.local.app.run_back;
|
|
@@ -105,10 +105,7 @@ export const useBackStore = defineStore("back", {
|
|
|
105
105
|
await Promise.resolve();
|
|
106
106
|
},
|
|
107
107
|
async request(
|
|
108
|
-
{
|
|
109
|
-
schema,
|
|
110
|
-
params = {},
|
|
111
|
-
}: Readonly<{ schema: JsonRpcSchema; params?: Record<string, unknown> }>,
|
|
108
|
+
{ schema, params = {} }: { schema: JsonRpcSchema; params?: Record<string, unknown> },
|
|
112
109
|
callbacks: RequestHandlers = {},
|
|
113
110
|
) {
|
|
114
111
|
const result = await api_fetch(
|
|
@@ -129,7 +126,7 @@ export const useBackStore = defineStore("back", {
|
|
|
129
126
|
);
|
|
130
127
|
return result;
|
|
131
128
|
},
|
|
132
|
-
async upload(file:
|
|
129
|
+
async upload(file: File, callbacks: RequestHandlers = {}) {
|
|
133
130
|
const schema = back_schemas.opengeodeweb_back.upload_file;
|
|
134
131
|
const result = await upload_file(
|
|
135
132
|
this,
|
|
@@ -25,7 +25,7 @@ export const useCameraManagerStore = defineStore("camera_manager", () => {
|
|
|
25
25
|
number
|
|
26
26
|
>;
|
|
27
27
|
|
|
28
|
-
function refAllCameraPositions():
|
|
28
|
+
function refAllCameraPositions(): Ref<CameraPositionRecord[]> {
|
|
29
29
|
// Dexie's liveQuery() returns Dexie's own minimal Observable shape, not an
|
|
30
30
|
// Actual rxjs Observable instance (useObservable's declared parameter type);
|
|
31
31
|
// The two are structurally close enough at runtime (vueuse only calls
|
|
@@ -45,10 +45,7 @@ export const useCameraManagerStore = defineStore("camera_manager", () => {
|
|
|
45
45
|
return position;
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
async function saveCameraPosition(
|
|
49
|
-
name: string,
|
|
50
|
-
camera_options: Readonly<CameraOptions>,
|
|
51
|
-
): Promise<void> {
|
|
48
|
+
async function saveCameraPosition(name: string, camera_options: CameraOptions): Promise<void> {
|
|
52
49
|
await camera_positions_db.put({
|
|
53
50
|
name,
|
|
54
51
|
camera_options,
|