diff --git a/webapp/package-lock.json b/webapp/package-lock.json index dd07e5d4..d434a1ec 100644 --- a/webapp/package-lock.json +++ b/webapp/package-lock.json @@ -24,7 +24,7 @@ "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "color2k": "^2.0.4", - "coordo": "github:dataforgoodfr/Coordonnees#0.7.0", + "coordo": "github:dataforgoodfr/Coordonnees#0.8.1", "i18next": "^25.8.0", "i18next-browser-languagedetector": "^8.2.0", "i18next-http-backend": "^3.0.2", @@ -4605,7 +4605,7 @@ }, "node_modules/coordo": { "version": "0.7.0", - "resolved": "git+ssh://git@github.com/dataforgoodfr/Coordonnees.git#6bd094ed42a1678d7ddd27de3c118aeeb457850e", + "resolved": "git+ssh://git@github.com/dataforgoodfr/Coordonnees.git#c6a65de3db142e9b1a7505224cce794c4d1ef7a2", "license": "ISC", "dependencies": { "maplibre-gl": "^5.16.0" diff --git a/webapp/package.json b/webapp/package.json index 066f3c2f..e4fb02a3 100644 --- a/webapp/package.json +++ b/webapp/package.json @@ -40,8 +40,8 @@ "chart.js": "^4.5.1", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", - "coordo": "github:dataforgoodfr/Coordonnees#0.7.0", "color2k": "^2.0.4", + "coordo": "github:dataforgoodfr/Coordonnees#0.8.1", "i18next": "^25.8.0", "i18next-browser-languagedetector": "^8.2.0", "i18next-http-backend": "^3.0.2", diff --git a/webapp/src/features/categories-filters/main.tsx b/webapp/src/features/categories-filters/main.tsx index bc40cd92..9112a478 100644 --- a/webapp/src/features/categories-filters/main.tsx +++ b/webapp/src/features/categories-filters/main.tsx @@ -12,6 +12,7 @@ import type { CheckedState } from "@ui/checkbox"; import { AllOrNoneSelector } from "./all-or-none-selector"; import { CategoriesCheckboxGroup } from "./categories-checkbox-group"; import { useCategoriesConfig } from "./use-categories-config"; +import { changeLayerVisibility } from "./use-categories-filters"; type CategoriesFiltersProps = { disabled?: boolean; @@ -37,11 +38,12 @@ export const CategoriesFilters: FC = ({ disabled }) => { } try { - if (checkedState) { - mapApiRef.current.showLayer(layerId); - } else { - mapApiRef.current.hideLayer(layerId); - } + changeLayerVisibility({ + hideLayer: mapApiRef.current.hideLayer, + isActive: Boolean(checkedState), + layerId, + showLayer: mapApiRef.current.showLayer, + }); } catch (error) { console.error(error); } diff --git a/webapp/src/features/categories-filters/use-categories-filters.ts b/webapp/src/features/categories-filters/use-categories-filters.ts index eb8782dc..f396f000 100644 --- a/webapp/src/features/categories-filters/use-categories-filters.ts +++ b/webapp/src/features/categories-filters/use-categories-filters.ts @@ -5,8 +5,34 @@ import { type CategoriesFiltersState, parseLayerId, } from "@shared/api/categories-filters"; +import { LAYERS_WITH_CLUSTERS } from "@shared/api/layers"; import { useLocalStorage } from "@shared/hooks/use-local-storage"; -import { EVENTS } from "@shared/lib/coordo"; +import { EVENTS, getClusterLayerIds } from "@shared/lib/coordo"; + +/** + * Trigger visibility update on the layer and its cluster related layers + */ +export const changeLayerVisibility = ({ + layerId, + isActive, + showLayer, + hideLayer, +}: { + layerId: string; + isActive: boolean; + showLayer?: (layerId: string) => void; + hideLayer?: (layerId: string) => void; +}) => { + const isClustered = LAYERS_WITH_CLUSTERS.includes(layerId); + + const action = isActive ? showLayer : hideLayer; + action?.(layerId); + if (isClustered) { + const { circle, count } = getClusterLayerIds(layerId); + action?.(circle); + action?.(count); + } +}; export const useCategoriesFilters = () => { const [categoriesFilters, setCategoriesFilters] = @@ -69,11 +95,7 @@ export const useCategoriesFilters = () => { const layerId = parseLayerId(identifier); if (!layerId) return; - if (isActive) { - showLayer?.(layerId); - } else { - hideLayer?.(layerId); - } + changeLayerVisibility({ hideLayer, isActive, layerId, showLayer }); }); }, [categoriesFilters], diff --git a/webapp/src/shared/api/categories-filters.ts b/webapp/src/shared/api/categories-filters.ts index bc231f5d..660533cf 100644 --- a/webapp/src/shared/api/categories-filters.ts +++ b/webapp/src/shared/api/categories-filters.ts @@ -1,15 +1,17 @@ import { LAYERS } from "./layers"; +const SEPARATOR = ":::"; + /** * Format of a layer: GROUP_BACKEND-NAME */ export const CATEGORY_IDENTIFIERS = { ACTION_DIVERSITY: "action-tree-diversity", - ACTION_INVENTARY: `action-forest_${LAYERS.INVENTARY}`, - ACTION_SOCIO: `action-socio-eco_${LAYERS.ENQUETE}`, + ACTION_INVENTARY: `action-forest${SEPARATOR}${LAYERS.INVENTARY}`, + ACTION_SOCIO: `action-socio-eco${SEPARATOR}${LAYERS.ENQUETE}`, DATA_GROUND: "data-ground", DATA_MODEL: "data-model", - DATA_SATELLITE: `data_${LAYERS.SATELLITE}`, + DATA_SATELLITE: `data${SEPARATOR}${LAYERS.SATELLITE}`, SYSTEM_FOREST_PRIMARY: "system-forest-primary", SYSTEM_FOREST_SECONDARY: "system-forest-secondary", SYSTEM_MANGROVE_HIGH: "system-mangrove-high", @@ -21,7 +23,7 @@ export const CATEGORY_IDENTIFIERS = { * Return null if it can't retrieve the layer id. */ export const parseLayerId = (name: string) => { - const parts = name.split("_"); + const parts = name.split(SEPARATOR); return parts.length > 1 ? parts[1] : null; }; diff --git a/webapp/src/shared/api/layers.ts b/webapp/src/shared/api/layers.ts index 468b83c4..5ed1eb49 100644 --- a/webapp/src/shared/api/layers.ts +++ b/webapp/src/shared/api/layers.ts @@ -8,3 +8,8 @@ export const LAYERS = { TOWNS: "towns", VILLAGES: "villages", } as const; + +export const LAYERS_WITH_CLUSTERS: string[] = [ + LAYERS.ENQUETE, + LAYERS.INVENTARY, +]; diff --git a/webapp/src/shared/lib/coordo.ts b/webapp/src/shared/lib/coordo.ts index d39ed9b8..a41fb3f6 100644 --- a/webapp/src/shared/lib/coordo.ts +++ b/webapp/src/shared/lib/coordo.ts @@ -3,6 +3,7 @@ export { createMap, EVENTS, + getClusterLayerIds, LAYER_CONTROL_ELEMENTS, type LayerControlRenderAnchor, type LayerControlRenderLayerRow,