Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
38e8e12
treeobject temp
MaxNumerique Mar 24, 2026
6f5c017
Apply prepare changes
MaxNumerique Mar 24, 2026
b170d74
trigger
MaxNumerique Mar 24, 2026
71e33d4
Merge branch 'feat/treecomponent_utils' of https://github.com/Geode-s…
MaxNumerique Mar 24, 2026
a800ff5
Apply prepare changes
MaxNumerique Mar 24, 2026
3d3f786
Merge branch 'next' of https://github.com/Geode-solutions/OpenGeodeWe…
MaxNumerique Mar 25, 2026
7c68660
Merge branch 'feat/treecomponent_utils' of https://github.com/Geode-s…
MaxNumerique Mar 25, 2026
3d6f9d7
reapply changes that disapeared
MaxNumerique Mar 25, 2026
bfc98e2
revert some
MaxNumerique Mar 25, 2026
506e4d9
harmonize props declaration
MaxNumerique Mar 25, 2026
e9f53de
color and size undefined
MaxNumerique Mar 25, 2026
9a6b644
Merge branch 'next' of https://github.com/Geode-solutions/OpenGeodeWe…
MaxNumerique Mar 25, 2026
cf45c21
Merge branch 'next' of https://github.com/Geode-solutions/OpenGeodeWe…
MaxNumerique Mar 25, 2026
d67cc57
fix breadcrumbs
MaxNumerique Mar 25, 2026
13e4372
Apply prepare changes
MaxNumerique Mar 25, 2026
befc67c
fix treecomponents, and breadcrumbs
MaxNumerique Mar 25, 2026
f0a4835
Merge branch 'feat/treecomponent_utils' of https://github.com/Geode-s…
MaxNumerique Mar 25, 2026
93afec6
fix treeComponents & BreadCrumbs => setModelMeshComponentsVisibility
MaxNumerique Mar 25, 2026
3ebf575
Apply prepare changes
MaxNumerique Mar 25, 2026
86922f1
revert ids
MaxNumerique Mar 25, 2026
085caf9
Merge branch 'feat/treecomponent_utils' of https://github.com/Geode-s…
MaxNumerique Mar 25, 2026
04d0f00
no fallback
MaxNumerique Mar 25, 2026
ab35ae7
Apply prepare changes
MaxNumerique Mar 25, 2026
0b35bf8
Merge branch 'next' of https://github.com/Geode-solutions/OpenGeodeWe…
MaxNumerique Mar 26, 2026
a797da3
Merge branch 'feat/treecomponent_utils' of https://github.com/Geode-s…
MaxNumerique Mar 26, 2026
0a06bd7
delete useless function & refacto
MaxNumerique Mar 26, 2026
fd4128e
Apply prepare changes
MaxNumerique Mar 26, 2026
fb8d04a
refacto
MaxNumerique Mar 26, 2026
50d647e
Merge branch 'feat/treecomponent_utils' of https://github.com/Geode-s…
MaxNumerique Mar 26, 2026
05f2aca
unref(id)
MaxNumerique Mar 26, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions app/components/ActionButton.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<script setup>
const DEFAULT_ICON_SIZE = 28;
const { icon, tooltip, color, size, variant, density, tooltipLocation, iconSize } = defineProps({
icon: { type: String, required: true },
tooltip: { type: String, required: true },
color: { type: String, default: undefined },
size: { type: [String, Number], default: undefined },
variant: { type: String },
density: { type: String, default: "comfortable" },
tooltipLocation: { type: String, default: "left" },
iconSize: { type: [String, Number], default: DEFAULT_ICON_SIZE },
});

const emit = defineEmits(["click"]);
</script>

<template>
<v-btn
:color="color"
:size="size"
:variant="variant"
:density="density"
v-tooltip:[tooltipLocation]="tooltip"
v-bind="$attrs"
icon
@click="emit('click', $event)"
>
<v-icon :size="iconSize">{{ icon }}</v-icon>
</v-btn>
</template>
12 changes: 5 additions & 7 deletions app/components/VeaseViewToolbar.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<script setup>
import schemas from "@geode/opengeodeweb-viewer/opengeodeweb_viewer_schemas.json";

import ActionButton from "@ogw_front/components/ActionButton.vue";
import Screenshot from "@ogw_front/components/Screenshot";
import ZScaling from "@ogw_front/components/ZScaling";

Expand Down Expand Up @@ -71,14 +72,11 @@ const camera_options = [
<v-container :class="[$style.floatToolbar, 'pa-0']" width="auto">
<v-row v-for="camera_option in camera_options" :key="camera_option.icon" dense>
<v-col>
<v-btn
density="comfortable"
icon
<ActionButton
:icon="camera_option.icon"
:tooltip="camera_option.tooltip"
@click.stop="camera_option.action"
v-tooltip:left="camera_option.tooltip"
>
<v-icon :icon="camera_option.icon" size="32" />
</v-btn>
/>
</v-col>
</v-row>
</v-container>
Expand Down
15 changes: 7 additions & 8 deletions app/components/ViewToolbar.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<script setup>
import schemas from "@geode/opengeodeweb-viewer/opengeodeweb_viewer_schemas.json";

import ActionButton from "@ogw_front/components/ActionButton.vue";
import Screenshot from "@ogw_front/components/Screenshot";
import { useViewerStore } from "@ogw_front/stores/viewer";

Expand Down Expand Up @@ -45,14 +46,12 @@ const camera_options = [
<v-container :class="[$style.floatToolbar, 'pa-0']" width="auto">
<v-row v-for="camera_option in camera_options" :key="camera_option.icon" dense>
<v-col>
<v-btn
density="comfortable"
icon
@click.stop="camera_option.action"
v-tooltip:left="camera_option.tooltip"
>
<v-icon :icon="camera_option.icon" size="32" />
</v-btn>
<ActionButton
:tooltip="camera_option.tooltip"
:icon="camera_option.icon"
tooltip-location="left"
@click="camera_option.action"
/>
</v-col>
</v-row>
</v-container>
Expand Down
37 changes: 15 additions & 22 deletions app/components/Viewer/BreadCrumb.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,33 +11,24 @@ function goBackToFileTree() {
treeviewStore.displayFileTree();
}

const model_id = computed(() => treeviewStore.model_id);

const metaDatas = computed(() => {
if (!model_id.value) {
return {};
}
return dataStore.refItem(model_id.value).value || {};
});
const metaDatas = computed(() => dataStore.refItem(treeviewStore.model_id));
</script>

<template>
<v-breadcrumbs class="mb-n10 breadcrumb-container">
<div class="d-flex align-center gap-2 ml-2 mt-2 mb-1">
<v-menu v-if="treeviewStore.isAdditionnalTreeDisplayed" offset-y>
<template v-slot:activator="{ props }">
<v-btn icon variant="text" size="medium" v-bind="props" @click="goBackToFileTree">
<v-icon size="large">mdi-file-tree</v-icon>
</v-btn>
<span class="text-h5 font-weight-bold">/</span>
<v-icon size="x-large">
{{ selectedTree && selectedTree.icon ? selectedTree.icon : "mdi-shape-outline" }}
</v-icon>
<span class="text-subtitle-1 font-weight-regular align-center mt-1">
Model Explorer ({{ metaDatas.name }})
</span>
</template>
</v-menu>
<template v-if="treeviewStore.isAdditionnalTreeDisplayed">
<v-btn icon variant="text" size="medium" @click.stop="goBackToFileTree">
<v-icon size="large">mdi-file-tree</v-icon>
</v-btn>
<span class="text-h5 font-weight-bold">/</span>
<v-icon size="large">
{{ selectedTree && selectedTree.icon ? selectedTree.icon : "mdi-shape-outline" }}
</v-icon>
<span class="text-subtitle-1 font-weight-regular align-center mt-1">
Model Explorer ({{ metaDatas.name }})
</span>
</template>

<div v-else class="d-flex align-center gap-2">
<v-icon size="large">mdi-file-tree</v-icon>
Expand All @@ -49,6 +40,8 @@ const metaDatas = computed(() => {

<style scoped>
.breadcrumb-container {
position: relative;
z-index: 10;
max-width: 100%;
overflow: hidden;
white-space: nowrap;
Expand Down
128 changes: 100 additions & 28 deletions app/components/Viewer/TreeComponent.vue
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
<script setup>
import ActionButton from "@ogw_front/components/ActionButton.vue";
import SearchBar from "@ogw_front/components/SearchBar.vue";
import { compareSelections } from "@ogw_front/utils/treeview";
import { useDataStore } from "@ogw_front/stores/data";
import { useDataStyleStore } from "@ogw_front/stores/data_style";
Expand All @@ -11,50 +13,120 @@ const hybridViewerStore = useHybridViewerStore();
const { id } = defineProps({ id: { type: String, required: true } });
const emit = defineEmits(["show-menu"]);

const items = dataStore.refFormatedMeshComponents(id);
const mesh_components_selection = computed(() => dataStyleStore.visibleMeshComponents(id));
const items = dataStore.refFormatedMeshComponents(toRef(() => id));
const mesh_components_selection = dataStyleStore.visibleMeshComponents(toRef(() => id));

watch(
mesh_components_selection,
async (current, previous) => {
if (!previous) {
return;
}
const search = ref("");
const sortType = ref("name");
const filterOptions = ref({
Corner: true,
Line: true,
Surface: true,
Block: true,
});

const { added, removed } = compareSelections(current, previous);
console.log("TreeComponent selection change:", {
id: props.id,
added,
removed,
});

if (added.length > 0) {
await dataStyleStore.setModelMeshComponentsVisibility(id, added, true);
}
if (removed.length > 0) {
await dataStyleStore.setModelMeshComponentsVisibility(id, removed, false);
}
hybridViewerStore.remoteRender();
},
{ deep: true },
const processedItems = computed(() =>
items.value
.filter((category) => filterOptions.value[category.id])
.map((category) => {
const field = sortType.value === "name" ? "title" : "id";
const children = (category.children || []).toSorted((first, second) =>
first[field].localeCompare(second[field]),
);
return { id: category.id, title: category.title, children };
}),
);

const availableFilterOptions = computed(() => items.value.map((category) => category.id));

function toggleSort() {
sortType.value = sortType.value === "name" ? "id" : "name";
}

function customFilter(value, searchQuery, item) {
if (!searchQuery) {
return true;
}
const query = searchQuery.toLowerCase();
return (
item.raw.title.toLowerCase().includes(query) ||
(item.raw.id && item.raw.id.toLowerCase().includes(query))
);
}

async function onSelectionChange(current) {
const previous = mesh_components_selection.value;
const { added, removed } = compareSelections(current, previous);

if (added.length === 0 && removed.length === 0) {
return;
}

if (added.length > 0) {
await dataStyleStore.setComponentsVisibility(id, added, true);
}
if (removed.length > 0) {
await dataStyleStore.setComponentsVisibility(id, removed, false);
}
hybridViewerStore.remoteRender();
}
</script>

<template>
<v-row dense align="center" class="mr-1 ml-3 mt-2 pa-1">
<v-col>
<SearchBar v-model="search" label="Search" color="black" base-color="black" />
</v-col>
<v-col cols="auto" class="d-flex align-center">
<ActionButton
:tooltip="'Sort by ' + (sortType === 'name' ? 'ID' : 'Name')"
:icon="
sortType === 'name' ? 'mdi-sort-alphabetical-ascending' : 'mdi-sort-numeric-ascending'
"
tooltipLocation="bottom"
@click="toggleSort"
/>
<v-menu :close-on-content-click="false">
<template #activator="{ props }">
<ActionButton
tooltip="Filter options"
icon="mdi-filter-variant"
tooltipLocation="bottom"
class="ml-1"
v-bind="props"
/>
</template>
<v-list class="mt-1">
<v-list-item v-for="category_id in availableFilterOptions" :key="category_id">
<v-checkbox
v-model="filterOptions[category_id]"
:label="category_id"
hide-details
density="compact"
/>
</v-list-item>
</v-list>
</v-menu>
</v-col>
</v-row>
<v-treeview
v-model:selected="mesh_components_selection"
:items="items"
:selected="mesh_components_selection"
:items="processedItems"
:search="search"
:custom-filter="customFilter"
class="transparent-treeview"
item-value="id"
select-strategy="classic"
select-strategy="independent"
selectable
@update:selected="onSelectionChange"
>
<template #title="{ item }">
<span
class="treeview-item"
@contextmenu.prevent.stop="emit('show-menu', { event: $event, itemId: item })"
>{{ item.title }}</span
>
{{ item.title }}
</span>
</template>
</v-treeview>
</template>
Expand Down
Loading
Loading