Skip to content

Commit e89db42

Browse files
committed
Merge branch 'next' of https://github.com/Geode-solutions/OpenGeodeWeb-Front into feat/tooltip-copy
2 parents d190120 + b5f07e4 commit e89db42

16 files changed

Lines changed: 286 additions & 94 deletions

File tree

app/components/DeleteDialog.vue

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ const emit = defineEmits(["update:show", "confirm"]);
5454
color="error"
5555
size="large"
5656
variant="flat"
57+
data-testid="deleteConfirmButton"
5758
@click="emit('confirm')"
5859
class="text-none rounded-lg font-weight-bold"
5960
elevation="4"
@@ -93,6 +94,7 @@ const emit = defineEmits(["update:show", "confirm"]);
9394
color="error"
9495
size="large"
9596
variant="flat"
97+
data-testid="deleteConfirmButton"
9698
@click="emit('confirm')"
9799
class="text-none rounded-lg font-weight-bold"
98100
elevation="4"

app/components/FeedBack/Snackers.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ function calc_margin(index) {
2323
transition="slide-x-reverse-transition"
2424
max-width="200px"
2525
height="20px"
26-
timeout="10000"
26+
timeout="-1"
2727
z-index="4"
2828
>
2929
<v-row dense class="flex-nowrap">

app/components/Viewer/ObjectTree/Base/Controls.vue

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ watch(
3232
:class="{ 'is-expanded': showSearch }"
3333
>
3434
<ActionButton
35+
data-testid="searchObjectsButton"
3536
:tooltip="showSearch ? 'Hide search' : 'Show search'"
3637
icon="mdi-magnify"
3738
tooltipLocation="bottom"
@@ -43,6 +44,7 @@ watch(
4344
<v-expand-x-transition>
4445
<div v-if="showSearch" class="flex-grow-1 ms-1 text-no-wrap overflow-hidden">
4546
<SearchBar
47+
data-testid="searchObjectsInput"
4648
:model-value="search"
4749
placeholder="Search objects..."
4850
color="black"
@@ -67,6 +69,7 @@ watch(
6769
/>
6870
</v-fade-transition>
6971
<ActionButton
72+
data-testid="sortObjectsButton"
7073
:tooltip="'Sort by ' + (sortType === 'name' ? 'ID' : 'Name')"
7174
:icon="
7275
sortType === 'name' ? 'mdi-sort-alphabetical-ascending' : 'mdi-sort-numeric-ascending'
@@ -79,6 +82,7 @@ watch(
7982
<v-menu :close-on-content-click="false">
8083
<template #activator="{ props: menuProps }">
8184
<ActionButton
85+
data-testid="filterObjectsButton"
8286
tooltip="Filter options"
8387
icon="mdi-filter-variant"
8488
variant="text"
@@ -94,27 +98,19 @@ watch(
9498
:label="category_id"
9599
hide-details
96100
density="compact"
101+
:data-testid="'filterCheckbox-' + category_id"
97102
/>
98103
</v-list-item>
99104
</v-list>
100105
</v-menu>
101106
<ActionButton
102-
v-if="!isCollapsed"
103-
tooltip="Collapse All"
104-
icon="mdi-collapse-all-outline"
107+
data-testid="CollapseOrExpandAll"
108+
:tooltip="isCollapsed ? 'Expand All' : 'Collapse All'"
109+
:icon="isCollapsed ? 'mdi-expand-all-outline' : 'mdi-collapse-all-outline'"
105110
variant="text"
106111
color="black"
107112
tooltipLocation="bottom"
108-
@click="emit('collapse-all')"
109-
/>
110-
<ActionButton
111-
v-else
112-
tooltip="Expand All"
113-
icon="mdi-expand-all-outline"
114-
variant="text"
115-
color="black"
116-
tooltipLocation="bottom"
117-
@click="emit('expand-all')"
113+
@click="isCollapsed ? emit('expand-all') : emit('collapse-all')"
118114
/>
119115
</div>
120116
</div>

app/components/Viewer/ObjectTree/Base/ItemLabel.vue

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,11 @@ async function copyToClipboard(text, label) {
5858
</script>
5959

6060
<template>
61-
<div ref="label-container" class="tree-item-label-container w-100">
61+
<div
62+
ref="label-container"
63+
:data-testid="'treeRow-' + actualItem.id"
64+
class="tree-item-label-container w-100"
65+
>
6266
<v-tooltip
6367
:disabled="tooltipDisabled"
6468
location="right"

app/components/Viewer/Options/ColorPicker.vue

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ watch(pressed, (value) => {
5252
flat
5353
canvas-height="75"
5454
hide-inputs
55+
hide-eye-dropper
5556
width="220"
5657
mode="rgba"
5758
class="mx-auto"

app/composables/project_manager.js

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { useAppStore } from "@ogw_front/stores/app";
88
import { useBackStore } from "@ogw_front/stores/back";
99
import { useDataStore } from "@ogw_front/stores/data";
1010
import { useDataStyleStore } from "@ogw_front/stores/data_style";
11+
import { useFeedbackStore } from "@ogw_front/stores/feedback";
1112
import { useHybridViewerStore } from "@ogw_front/stores/hybrid_viewer";
1213
import { useTreeviewStore } from "@ogw_front/stores/treeview";
1314
import { useViewerStore } from "@ogw_front/stores/viewer";
@@ -16,6 +17,7 @@ async function exportProject() {
1617
console.log("[export triggered]");
1718
const appStore = useAppStore();
1819
const backStore = useBackStore();
20+
const feedbackStore = useFeedbackStore();
1921
const snapshot = await appStore.exportStores();
2022
const schema = back_schemas.opengeodeweb_back.export_project;
2123
const defaultName = "project.vease";
@@ -26,6 +28,7 @@ async function exportProject() {
2628
body: { snapshot, filename: defaultName },
2729
});
2830
fileDownload(result, defaultName);
31+
feedbackStore.add_success("Project exported successfully");
2932
return { result };
3033
}
3134

@@ -73,23 +76,20 @@ async function importProject(file) {
7376
await client2.getConnection().getSession().call("opengeodeweb_viewer.import_project", [{}]);
7477
}
7578

76-
await treeviewStore.importStores(snapshot.treeview || {});
79+
await treeviewStore.importStores(snapshot.treeview);
80+
await dataStore.importStores(snapshot.data);
7781
await hybridViewerStore.initHybridViewer();
78-
await hybridViewerStore.importStores(snapshot.hybridViewer || {});
7982

8083
const items = snapshot?.data?.items || [];
81-
8284
await importWorkflowFromSnapshot(items);
83-
await hybridViewerStore.importStores(snapshot.hybridViewer || {});
84-
{
85-
await dataStyleStore.importStores(snapshot.dataStyle || {});
86-
}
87-
{
88-
await dataStyleStore.applyAllStylesFromState();
89-
}
85+
await hybridViewerStore.importStores(snapshot.hybridViewer);
86+
await dataStyleStore.importStores(snapshot.dataStyle);
87+
await dataStyleStore.applyAllStylesFromState();
9088

9189
treeviewStore.finalizeImportSelection();
9290
treeviewStore.isImporting = false;
91+
const feedbackStore = useFeedbackStore();
92+
feedbackStore.add_success("Project imported successfully");
9393
}
9494

9595
export { exportProject, importProject };

app/stores/data.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -191,15 +191,21 @@ export const useDataStore = defineStore("data", () => {
191191

192192
async function exportStores() {
193193
const items = await data_db.toArray();
194-
return { items };
194+
const modelComponents = await model_components_db.toArray();
195+
const modelComponentsRelations = await model_components_relation_db.toArray();
196+
return { items, modelComponents, modelComponentsRelations };
195197
}
196198

197-
async function importStores(_snapshot) {
199+
async function importStores(snapshot) {
198200
await clear();
201+
await model_components_db.bulkPut(snapshot.modelComponents);
202+
await model_components_relation_db.bulkPut(snapshot.modelComponentsRelations);
199203
}
200204

201205
async function clear() {
202206
await data_db.clear();
207+
await model_components_db.clear();
208+
await model_components_relation_db.clear();
203209
}
204210

205211
return {

app/stores/data_style.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ export const useDataStyleStore = defineStore("dataStyle", () => {
1313
const dataStore = useDataStore();
1414
const data_style_db = database.data_style;
1515
const model_component_type_datastyle_db = database.model_component_type_datastyle;
16-
const component_datastyle_db = database.component_datastyle;
16+
const component_datastyle_db = database.model_component_datastyle;
1717

1818
async function addDataStyle(id, geode_object) {
1919
await data_style_db.put(structuredClone({ id, ...getDefaultStyle(geode_object) }));
@@ -47,9 +47,9 @@ export const useDataStyleStore = defineStore("dataStyle", () => {
4747

4848
function exportStores() {
4949
return {
50-
styles: dataStyleState.styles,
51-
componentStyles: dataStyleState.componentStyles,
52-
modelComponentTypeStyles: dataStyleState.modelComponentTypeStyles,
50+
styles: dataStyleState.styles.value,
51+
componentStyles: dataStyleState.componentStyles.value,
52+
modelComponentTypeStyles: dataStyleState.modelComponentTypeStyles.value,
5353
};
5454
}
5555

app/utils/local/microservices.js

Lines changed: 39 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,18 @@ import path from "node:path";
55

66
// Third party imports
77
import back_schemas from "@geode/opengeodeweb-back/opengeodeweb_back_schemas.json" with { type: "json" };
8-
import { getPort } from "get-port-please";
9-
import pTimeout from "p-timeout";
108

119
// Local imports
12-
import { commandExistsSync, waitForReady } from "./scripts.js";
10+
import { commandExistsSync, getAvailablePort, waitForReady } from "./scripts.js";
1311
import { microservicesMetadatasPath, projectMicroservices } from "./cleanup.js";
1412
import { executablePath } from "./path.js";
1513

16-
const DEFAULT_TIMEOUT_SECONDS = 120;
1714
const MILLISECONDS_PER_SECOND = 1000;
15+
const DEFAULT_TIMEOUT_SECONDS = 30;
1816

19-
function getAvailablePort() {
20-
return getPort({
21-
host: "localhost",
22-
random: true,
23-
});
17+
function resolveCommand(execPath, execName) {
18+
const command = commandExistsSync(execName) ? execName : executablePath(execPath, execName);
19+
return command;
2420
}
2521

2622
async function runScript(
@@ -30,33 +26,31 @@ async function runScript(
3026
expectedResponse,
3127
timeoutSeconds = DEFAULT_TIMEOUT_SECONDS,
3228
) {
33-
let command = "";
34-
if (commandExistsSync(execName)) {
35-
command = execName;
36-
} else {
37-
command = path.join(executablePath(execPath, execName));
38-
}
29+
const command = resolveCommand(execPath, execName);
3930
console.log("runScript", command, args);
4031

41-
const child = child_process.spawn(process.platform === "win32" ? command : `"${command}"`, args, {
42-
encoding: "utf8",
43-
shell: true,
32+
const child = child_process.spawn(command, args, {
33+
stdio: ["ignore", "pipe", "pipe"],
4434
});
45-
child.stdout.on("data", (data) => console.log(`[${execName}] ${data.toString()}`));
46-
child.stderr.on("data", (data) => console.log(`[${execName}] ${data.toString()}`));
4735

48-
child.on("close", (code) => console.log(`[${execName}] exited with code ${code}`));
49-
child.on("kill", () => {
50-
console.log(`[${execName}] process killed`);
51-
});
5236
child.name = command.replace(/^.*[\\/]/u, "");
5337

38+
child.on("spawn", () => {
39+
console.log(`[${child.name}] spawned, pid=${child.pid}`);
40+
});
41+
42+
const controller = new AbortController();
43+
const timer = setTimeout(() => controller.abort(), timeoutSeconds * MILLISECONDS_PER_SECOND);
44+
if (typeof timer.unref === "function") {
45+
timer.unref();
46+
}
47+
5448
try {
55-
return await pTimeout(waitForReady(child, expectedResponse), {
56-
milliseconds: timeoutSeconds * MILLISECONDS_PER_SECOND,
57-
message: `Timed out after ${timeoutSeconds} seconds`,
58-
});
49+
const result = await waitForReady(child, expectedResponse, controller.signal);
50+
clearTimeout(timer);
51+
return result;
5952
} catch (error) {
53+
clearTimeout(timer);
6054
child.kill();
6155
throw error;
6256
}
@@ -73,11 +67,16 @@ async function runBack(execName, execPath, args = {}) {
7367
}
7468
const port = await getAvailablePort();
7569
const backArgs = [
76-
`--port ${port}`,
77-
`--data_folder_path ${projectFolderPath}`,
78-
`--upload_folder_path ${uploadFolderPath}`,
79-
`--allowed_origin http://localhost:*`,
80-
`--timeout ${0}`,
70+
"--port",
71+
String(port),
72+
"--data_folder_path",
73+
projectFolderPath,
74+
"--upload_folder_path",
75+
uploadFolderPath,
76+
"--allowed_origin",
77+
"http://localhost:*",
78+
"--timeout",
79+
"0",
8180
];
8281
if (process.env.NODE_ENV === "development" || !process.env.NODE_ENV) {
8382
backArgs.push("--debug");
@@ -94,9 +93,12 @@ async function runViewer(execName, execPath, args = {}) {
9493
}
9594
const port = await getAvailablePort();
9695
const viewerArgs = [
97-
`--port ${port}`,
98-
`--data_folder_path ${projectFolderPath}`,
99-
`--timeout ${0}`,
96+
"--port",
97+
String(port),
98+
"--data_folder_path",
99+
projectFolderPath,
100+
"--timeout",
101+
"0",
100102
];
101103
console.log("runViewer", execPath, execName, viewerArgs);
102104
await runScript(execPath, execName, viewerArgs, "Starting factory");
@@ -121,4 +123,4 @@ function addMicroserviceMetadatas(projectFolderPath, serviceObj) {
121123
);
122124
}
123125

124-
export { addMicroserviceMetadatas, getAvailablePort, runBack, runViewer };
126+
export { addMicroserviceMetadatas, runBack, runViewer };

0 commit comments

Comments
 (0)