From acd405ddd9f2d09d2eabe8d71b7af84049984f9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mar=C3=ADa?= Date: Thu, 19 Dec 2024 17:54:33 +0100 Subject: [PATCH] fix layers filter --- .../datasets/layers/projects/hooks.tsx | 43 +++++++++++-------- .../datasets/layers/tree-cover/settings.tsx | 1 - client/src/containers/map/index.tsx | 14 +++--- client/src/containers/map/popup/index.tsx | 8 +++- .../src/containers/projects/detail/header.tsx | 12 +++--- .../src/containers/projects/detail/panel.tsx | 8 ++-- client/src/containers/projects/list.tsx | 3 -- client/src/hooks/datasets/index.ts | 2 +- client/src/hooks/datasets/query-parsers.ts | 2 - 9 files changed, 50 insertions(+), 43 deletions(-) diff --git a/client/src/containers/datasets/layers/projects/hooks.tsx b/client/src/containers/datasets/layers/projects/hooks.tsx index e848402f..89dcec20 100644 --- a/client/src/containers/datasets/layers/projects/hooks.tsx +++ b/client/src/containers/datasets/layers/projects/hooks.tsx @@ -143,11 +143,18 @@ export function useLayers({ // Reactivity to Hover Events in the Sidebar: // Similarly, When a user hovers over the a project in the sidebar, both point and geometry representations within the layer are programmed to change in color and/or size. + const sanitizedProjects = filteredProjects.filter((project) => project !== null); + + const filter = + sanitizedProjects.length > 0 + ? ['in', ['get', 'project_code'], ['literal', sanitizedProjects]] + : ['!=', ['get', 'project_code'], null]; + return [ { id: 'projects_points_shadow', type: 'circle', - filter: ['in', ['get', 'project_code'], ['literal', filteredProjects]], + filter, source: 'projects', 'source-layer': 'areas_centroids_c_v202410', paint: { @@ -164,7 +171,7 @@ export function useLayers({ { id: 'projects_circle', type: 'circle', - filter: ['in', ['get', 'project_code'], ['literal', filteredProjects]], + filter, source: 'projects', 'source-layer': 'areas_centroids_c_v202410', paint: { @@ -173,9 +180,9 @@ export function useLayers({ 'case', ['boolean', ['feature-state', 'hover'], false], 3, - ['==', ['get', 'project_code'], hoveredProject?.[0]], + ['==', ['get', 'project_code'], hoveredProject?.[0] || null], 7, - ['!=', ['get', 'project_code'], hoveredProject?.[0]], + ['!=', ['get', 'project_code'], hoveredProject?.[0] || null], 3, 7, ], @@ -196,14 +203,14 @@ export function useLayers({ 1, [ 'all', - ['to-boolean', hoveredProject?.[0]], - ['!=', ['get', 'project_code'], hoveredProject?.[0]], + ['to-boolean', hoveredProject?.[0] || null], + ['!=', ['get', 'project_code'], hoveredProject?.[0] || null], ], 0.2, [ 'all', - ['to-boolean', hoveredProject?.[0]], - ['==', ['get', 'project_code'], hoveredProject?.[0]], + ['to-boolean', hoveredProject?.[0] || null], + ['==', ['get', 'project_code'], hoveredProject?.[0] || null], ], 1, opacity, @@ -214,14 +221,14 @@ export function useLayers({ 1, [ 'all', - ['to-boolean', hoveredProject?.[0]], - ['!=', ['get', 'project_code'], hoveredProject?.[0]], + ['to-boolean', hoveredProject?.[0] || null], + ['!=', ['get', 'project_code'], hoveredProject?.[0] || null], ], 0.2, [ 'all', - ['to-boolean', hoveredProject?.[0]], - ['==', ['get', 'project_code'], hoveredProject?.[0]], + ['to-boolean', hoveredProject?.[0] || null], + ['==', ['get', 'project_code'], hoveredProject?.[0] || null], ], 1, opacity, @@ -235,7 +242,7 @@ export function useLayers({ { id: 'projects_fill', type: 'fill', - filter: ['in', ['get', 'project_code'], ['literal', filteredProjects]], + filter, source: 'projects', 'source-layer': 'areas_centroids_l_v202410', paint: { @@ -246,14 +253,14 @@ export function useLayers({ 0.7, [ 'all', - ['to-boolean', hoveredProject?.[0]], - ['!=', ['get', 'project_code'], hoveredProject?.[0]], + ['to-boolean', hoveredProject?.[0] || null], + ['!=', ['get', 'project_code'], hoveredProject?.[0] || null], ], 0.2, [ 'all', - ['to-boolean', hoveredProject?.[0]], - ['==', ['get', 'project_code'], hoveredProject?.[0]], + ['to-boolean', hoveredProject?.[0] || null], + ['==', ['get', 'project_code'], hoveredProject?.[0] || null], ], 0.7, opacity * 0.7, @@ -267,7 +274,7 @@ export function useLayers({ { id: 'projects_line', type: 'line', - filter: ['in', ['get', 'project_code'], ['literal', filteredProjects]], + filter, source: 'projects', 'source-layer': 'areas_centroids_l_v202410', paint: { diff --git a/client/src/containers/datasets/layers/tree-cover/settings.tsx b/client/src/containers/datasets/layers/tree-cover/settings.tsx index c571100a..4ca56d41 100644 --- a/client/src/containers/datasets/layers/tree-cover/settings.tsx +++ b/client/src/containers/datasets/layers/tree-cover/settings.tsx @@ -13,7 +13,6 @@ const TreeCoverLossSettings: React.FC = ({ description, startYear: startYearValue, endYear: endYearValue, - paramsConfig, onChangeSettings, }) => { // const startYear = useMemo( diff --git a/client/src/containers/map/index.tsx b/client/src/containers/map/index.tsx index d020c9e7..f8a74a37 100644 --- a/client/src/containers/map/index.tsx +++ b/client/src/containers/map/index.tsx @@ -103,12 +103,15 @@ export default function MapContainer() { select: (response) => response?.data ?.map((project) => project.attributes) - .filter((project) => { - return project?.project_code && locationPopUp.info?.includes(project.project_code); - }) + .filter( + (project): project is { project_code: string; name: string } => + !!project?.project_code && + !!project?.name && + !!locationPopUp.info?.includes(project.project_code ?? '') + ) ?.map((p) => ({ - id: p?.project_code, - name: p?.name, + id: p.project_code, + name: p.name, })), }, } @@ -151,7 +154,6 @@ export default function MapContainer() { [map, push, queryParams, setTmpBbox] ); - const [ho] = useAtom(hoveredProjectMapAtom); const handleMouseMove = useCallback( (e: MapLayerMouseEvent) => { // Track hovered features as arrays diff --git a/client/src/containers/map/popup/index.tsx b/client/src/containers/map/popup/index.tsx index 031d408e..88fd2ed5 100644 --- a/client/src/containers/map/popup/index.tsx +++ b/client/src/containers/map/popup/index.tsx @@ -1,6 +1,9 @@ import { useEffect, useState, MouseEvent, useCallback } from 'react'; + import { useAtomValue } from 'jotai'; -import { hoveredProjectMapAtom, openAtom } from '@/store'; + +import { hoveredProjectMapAtom } from '@/store'; + import { Popup } from 'react-map-gl'; const PopupContainer = ({ @@ -11,7 +14,7 @@ const PopupContainer = ({ }: { longitude: number; latitude: number; - info?: + info: | ( | { id: string; @@ -63,6 +66,7 @@ const PopupContainer = ({
{info?.map((i) => (

{ if (h2Ref.current) { const h2Height = h2Ref.current.offsetHeight; const calculatedHeight = h2Height + 48 + 64; setDynamicHeight(Math.max(calculatedHeight, 208)); } - }, [data?.name]); + }, [data?.name, setDynamicHeight]); + + if (!params.id) { + return notFound(); + } return (

diff --git a/client/src/containers/projects/detail/panel.tsx b/client/src/containers/projects/detail/panel.tsx index fe17b187..0a9138f9 100644 --- a/client/src/containers/projects/detail/panel.tsx +++ b/client/src/containers/projects/detail/panel.tsx @@ -81,10 +81,6 @@ export default function ProjectDetailPanel() { } ); - if (!params.id) { - return notFound(); - } - const headerRef = useRef(null); // Ref to measure the height of the Header const [headerHeight, setHeaderHeight] = useState(0); // State to store the height of the Header @@ -99,6 +95,10 @@ export default function ProjectDetailPanel() { } }, []); // Run once after initial render + if (!params.id) { + return notFound(); + } + return (
diff --git a/client/src/containers/projects/list.tsx b/client/src/containers/projects/list.tsx index 437af4a9..56dbaceb 100644 --- a/client/src/containers/projects/list.tsx +++ b/client/src/containers/projects/list.tsx @@ -8,10 +8,8 @@ import { useSetAtom } from 'jotai'; import { Search, X } from 'lucide-react'; import { hoveredProjectMapAtom } from '@/store'; -import { tmpBboxAtom } from '@/store'; import { useGetProjects } from '@/types/generated/project'; -import { Bbox } from '@/types/map'; import { useSyncQueryParams } from '@/hooks/datasets'; import { useSyncFilters } from '@/hooks/datasets/sync-query'; @@ -27,7 +25,6 @@ import FiltersSelected from '../filters/selected'; export default function ProjectsList() { const [searchValue, setSearchValue] = useState(null); - const setTempBbox = useSetAtom(tmpBboxAtom); const [filtersSettings] = useSyncFilters(); const setHoveredProjectList = useSetAtom(hoveredProjectMapAtom); const queryParams = useSyncQueryParams({ bbox: true }); diff --git a/client/src/hooks/datasets/index.ts b/client/src/hooks/datasets/index.ts index e7d8c5db..72225692 100644 --- a/client/src/hooks/datasets/index.ts +++ b/client/src/hooks/datasets/index.ts @@ -1,5 +1,5 @@ 'use client'; -import { useCallback, useMemo } from 'react'; +import { useMemo } from 'react'; import { serialize } from './query-parsers'; import { diff --git a/client/src/hooks/datasets/query-parsers.ts b/client/src/hooks/datasets/query-parsers.ts index f77b4033..aee4f906 100644 --- a/client/src/hooks/datasets/query-parsers.ts +++ b/client/src/hooks/datasets/query-parsers.ts @@ -5,8 +5,6 @@ import type { MapSettings } from '@/types/map'; import type { FilterSettings } from '@/containers/filters/types'; -import { DEFAULT_BBOX } from '@/components/map/constants'; - export type ProjectsTab = 'statistics' | 'list'; export const filtersParser = parseAsJson().withDefault({});