Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 2 additions & 0 deletions src/app/map/[id]/components/AreaPopup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ function WrappedAreaPopup({
}) {
const { viewConfig } = useMapViews();
const choroplethDataSource = useChoroplethDataSource();
const [, setHoverArea] = useHoverArea();
Copy link

Copilot AI Dec 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change adds a setHoverArea handler that wasn't previously imported. While the onClose handler at line 108 is a reasonable addition, this change appears unrelated to the PR's stated purpose of fixing area stats queries with empty strings. Consider moving this to a separate PR focused on popup behavior improvements.

Copilot uses AI. Check for mistakes.

const areaStatsQuery = useAreaStats();
const areaStats = areaStatsQuery.data;
Expand Down Expand Up @@ -104,6 +105,7 @@ function WrappedAreaPopup({
longitude={coordinates[0]}
latitude={coordinates[1]}
closeButton={false}
onClose={() => setHoverArea(null)}
Copy link

Copilot AI Dec 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change adds an onClose handler that appears unrelated to the PR's stated purpose of fixing area stats queries with empty strings. Consider moving this to a separate PR focused on popup behavior improvements.

Suggested change
onClose={() => setHoverArea(null)}

Copilot uses AI. Check for mistakes.
>
<div className="font-sans text-sm flex flex-col gap-2">
<p className="font-semibold">{name}</p>
Expand Down
2 changes: 1 addition & 1 deletion src/app/map/[id]/components/Choropleth/index.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { Layer, Source } from "react-map-gl/mapbox";
import { getMapStyle } from "@/app/map/[id]/context/MapContext";
import { useChoropleth } from "@/app/map/[id]/hooks/useChoropleth";
import { useMapViews } from "@/app/map/[id]/hooks/useMapViews";
import { MapType } from "@/server/models/MapView";
import { getMapStyle } from "../../utils/map";
import { useChoroplethAreaStats } from "./useChoroplethAreaStats";

export default function Choropleth() {
Expand Down
5 changes: 1 addition & 4 deletions src/app/map/[id]/components/Map.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@ import * as turf from "@turf/turf";
import { useCallback, useEffect, useMemo, useState } from "react";
import MapGL from "react-map-gl/mapbox";
import { v4 as uuidv4 } from "uuid";
import {
getDataSourceIds,
getMapStyle,
} from "@/app/map/[id]/context/MapContext";
import { useMapBounds } from "@/app/map/[id]/hooks/useMapBounds";
import { useMapConfig } from "@/app/map/[id]/hooks/useMapConfig";
import { useMapViews } from "@/app/map/[id]/hooks/useMapViews";
Expand All @@ -26,6 +22,7 @@ import { useMapRef } from "../hooks/useMapCore";
import { useMapHoverEffect } from "../hooks/useMapHover";
import { useTurfMutations, useTurfState } from "../hooks/useTurfs";
import { CONTROL_PANEL_WIDTH, mapColors } from "../styles";
import { getDataSourceIds, getMapStyle } from "../utils/map";
import AreaPopup from "./AreaPopup";
import Choropleth from "./Choropleth";
import { MAPBOX_SOURCE_IDS } from "./Choropleth/configs";
Expand Down
4 changes: 2 additions & 2 deletions src/app/map/[id]/components/MapViews.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import { CSS } from "@dnd-kit/utilities";
import { Check, Layers, Plus, X } from "lucide-react";
import React, { useEffect, useMemo, useRef, useState } from "react";
import { v4 as uuidv4 } from "uuid";
import { createNewViewConfig } from "@/app/map/[id]/context/MapContext";
import { useMapViews } from "@/app/map/[id]/hooks/useMapViews";
import ContextMenuContentWithFocus from "@/components/ContextMenuContentWithFocus";
import { Button } from "@/shadcn/ui/button";
Expand All @@ -35,12 +34,13 @@ import { Tooltip, TooltipContent, TooltipTrigger } from "@/shadcn/ui/tooltip";
import { cn } from "@/shadcn/utils";
import { useMapId } from "../hooks/useMapCore";
import { useDirtyViewIds, useSetViewId } from "../hooks/useMapViews";
import { createNewViewConfig } from "../utils/mapView";
import {
compareByPositionAndId,
getNewPositionAfter,
getNewPositionBefore,
sortByPositionAndId,
} from "../utils";
} from "../utils/position";
import type { View } from "../types";
import type { DragEndEvent } from "@dnd-kit/core";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ import {
getNewPositionAfter,
getNewPositionBefore,
sortByPositionAndId,
} from "@/app/map/[id]/utils";
} from "@/app/map/[id]/utils/position";
import { useTRPC } from "@/services/trpc/react";
import { LayerType } from "@/types";
import { useMapId } from "../../../hooks/useMapCore";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
} from "lucide-react";
import { useMemo, useState } from "react";

import { sortByPositionAndId } from "@/app/map/[id]/utils";
import { sortByPositionAndId } from "@/app/map/[id]/utils/position";
import { ContextMenu } from "@/shadcn/ui/context-menu";
import { cn } from "@/shadcn/utils";
import { LayerType } from "@/types";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {
verticalListSortingStrategy,
} from "@dnd-kit/sortable";
import { useMemo } from "react";
import { sortByPositionAndId } from "@/app/map/[id]/utils";
import { sortByPositionAndId } from "@/app/map/[id]/utils/position";
import SortableMarkerItem from "./SortableMarkerItem";
import type { Folder } from "@/server/models/Folder";
import type { PlacedMarker } from "@/server/models/PlacedMarker";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,26 @@ export default function VisualisationPanel({
</Select>
</>
)}

{viewConfig.calculationType !== CalculationType.Count &&
columnOneIsNumber && (
Copy link

Copilot AI Dec 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The visibility condition for this switch differs from the "Aggregation" select above (lines 300-305). The aggregation select checks for dataRecordsWillAggregate and areaSetGroupCode, but this switch doesn't. This inconsistency could cause the switch to appear in scenarios where it's not applicable or meaningful. Consider adding the same conditions to ensure the switch is only shown when it will actually affect the behavior.

Suggested change
columnOneIsNumber && (
columnOneIsNumber &&
dataRecordsWillAggregate(
dataSource?.geocodingConfig,
viewConfig.areaSetGroupCode,
) && (

Copilot uses AI. Check for mistakes.
<>
<Label
htmlFor="choropleth-empty-zero-switch"
className="text-sm text-muted-foreground font-normal"
>
Treat empty values as zero
</Label>

<Switch
id="choropleth-empty-zero-switch"
checked={Boolean(viewConfig.areaDataNullIsZero)}
onCheckedChange={(v) =>
updateViewConfig({ areaDataNullIsZero: v })
}
/>
</>
)}
</div>
{!viewConfig.areaDataSourceId && (
<div className="flex items-center gap-2">
Expand Down
2 changes: 1 addition & 1 deletion src/app/map/[id]/components/inspector/TurfMarkersList.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { useQueries } from "@tanstack/react-query";
import { useMemo } from "react";

import { getDataSourceIds } from "@/app/map/[id]/context/MapContext";
import { useDataSources } from "@/app/map/[id]/hooks/useDataSources";
import { useFoldersQuery } from "@/app/map/[id]/hooks/useFolders";
import { useInspector } from "@/app/map/[id]/hooks/useInspector";
Expand All @@ -11,6 +10,7 @@ import { DataSourceRecordType } from "@/server/models/DataSource";
import { FilterType } from "@/server/models/MapView";
import { useTRPC } from "@/services/trpc/react";
import { buildName } from "@/utils/dataRecord";
import { getDataSourceIds } from "../../utils/map";
import {
getMarkersInsidePolygon,
groupPlacedMarkersByFolder,
Expand Down
3 changes: 3 additions & 0 deletions src/app/map/[id]/data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ export const useAreaStats = () => {
areaDataColumn: column,
areaDataSecondaryColumn: secondaryColumn,
areaDataSourceId: dataSourceId,
areaDataNullIsZero: nullIsZero,
areaSetGroupCode,
} = viewConfig;

Expand Down Expand Up @@ -106,6 +107,7 @@ export const useAreaStats = () => {
dataSourceId,
column: columnOrCount,
secondaryColumn: secondaryColumn,
nullIsZero,
excludeColumns,
boundingBox: requiresBoundingBox ? boundingBox : null,
},
Expand All @@ -121,6 +123,7 @@ export const useAreaStats = () => {
dataSourceId,
column,
secondaryColumn,
nullIsZero,
excludeColumns,
]);

Expand Down
2 changes: 1 addition & 1 deletion src/app/map/[id]/hooks/useFolders.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { useIsMutating } from "@tanstack/react-query";
import { useCallback } from "react";
import { toast } from "sonner";
import { useTRPC } from "@/services/trpc/react";
import { getNewLastPosition } from "../utils";
import { getNewLastPosition } from "../utils/position";
import { useMapId } from "./useMapCore";
import { useMapQuery } from "./useMapQuery";
import type { Folder } from "@/server/models/Folder";
Expand Down
4 changes: 2 additions & 2 deletions src/app/map/[id]/hooks/useInitialMapView.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { useEffect, useRef } from "react";
import { v4 as uuidv4 } from "uuid";
import { createNewViewConfig } from "@/app/map/[id]/context/MapContext";
import { useTRPC } from "@/services/trpc/react";
import { getNewLastPosition } from "../utils";
import { createNewViewConfig } from "../utils/mapView";
import { getNewLastPosition } from "../utils/position";
import { useMapId } from "./useMapCore";
import { useMapQuery } from "./useMapQuery";
import { useViewIdAtom } from "./useMapViews";
Expand Down
4 changes: 2 additions & 2 deletions src/app/map/[id]/hooks/useMapViews.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ import { useMutation, useQueryClient } from "@tanstack/react-query";
import { useAtom, useAtomValue, useSetAtom } from "jotai";
import { useCallback, useContext, useMemo } from "react";
import { toast } from "sonner";
import { createNewViewConfig } from "@/app/map/[id]/context/MapContext";
import { AreaSetGroupCode } from "@/server/models/AreaSet";
import { MapType, type MapViewConfig } from "@/server/models/MapView";
import { useTRPC } from "@/services/trpc/react";
import { dirtyViewIdsAtom, viewIdAtom } from "../atoms/mapStateAtoms";
import { getNewLastPosition } from "../utils";
import { createNewViewConfig } from "../utils/mapView";
import { getNewLastPosition } from "../utils/position";
import { PublicMapContext } from "../view/[viewIdOrHost]/publish/context/PublicMapContext";
import { useMapId } from "./useMapCore";
import { useMapQuery } from "./useMapQuery";
Expand Down
2 changes: 1 addition & 1 deletion src/app/map/[id]/hooks/useMarkerQueries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

import { useQueries } from "@tanstack/react-query";
import { useContext, useMemo } from "react";
import { getDataSourceIds } from "@/app/map/[id]/context/MapContext";
import { useMapConfig } from "@/app/map/[id]/hooks/useMapConfig";
import { useMapViews } from "@/app/map/[id]/hooks/useMapViews";
import { getDataSourceIds } from "../utils/map";
import { PublicMapContext } from "../view/[viewIdOrHost]/publish/context/PublicMapContext";
import type { MarkerFeatureWithoutDataSourceId } from "@/types";

Expand Down
2 changes: 1 addition & 1 deletion src/app/map/[id]/hooks/usePlacedMarkers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {
searchMarkerAtom,
selectedPlacedMarkerIdAtom,
} from "../atoms/markerAtoms";
import { getNewLastPosition } from "../utils";
import { getNewLastPosition } from "../utils/position";
import { useSetPinDropMode } from "./useMapControls";
import { useMapId, useMapRef } from "./useMapCore";
import { useMapQuery } from "./useMapQuery";
Expand Down
21 changes: 21 additions & 0 deletions src/app/map/[id]/utils/map.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { MapType } from "@/server/models/MapView";
import mapStyles, { hexMapStyle } from "../styles";
import type { MapConfig } from "@/server/models/Map";
import type { MapViewConfig } from "@/server/models/MapView";

export const getDataSourceIds = (mapConfig: MapConfig) => {
return new Set(
[mapConfig.membersDataSourceId]
.concat(mapConfig.markerDataSourceIds)
.filter(Boolean),
)
.values()
.toArray();
};

export const getMapStyle = (viewConfig: MapViewConfig) => {
if (viewConfig.mapType === MapType.Hex) {
return hexMapStyle;
}
return mapStyles[viewConfig.mapStyleName] || Object.values(mapStyles)[0];
};
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,14 @@ import {
CalculationType,
ColorScheme,
MapStyleName,
MapType,
} from "@/server/models/MapView";
import mapStyles, { hexMapStyle } from "../styles";
import type { MapConfig } from "@/server/models/Map";
import type { MapViewConfig } from "@/server/models/MapView";

export const createNewViewConfig = (): MapViewConfig => {
return {
areaDataSourceId: "",
areaDataColumn: "",
areaDataNullIsZero: true,
areaSetGroupCode: null,
excludeColumnsString: "",
mapStyleName: MapStyleName.Light,
Expand All @@ -25,20 +23,3 @@ export const createNewViewConfig = (): MapViewConfig => {
reverseColorScheme: false,
};
};

export const getDataSourceIds = (mapConfig: MapConfig) => {
return new Set(
[mapConfig.membersDataSourceId]
.concat(mapConfig.markerDataSourceIds)
.filter(Boolean),
)
.values()
.toArray();
};

export const getMapStyle = (viewConfig: MapViewConfig) => {
if (viewConfig.mapType === MapType.Hex) {
return hexMapStyle;
}
return mapStyles[viewConfig.mapStyleName] || Object.values(mapStyles)[0];
};
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { Database } from "lucide-react";
import { useContext } from "react";
import { getDataSourceIds } from "@/app/map/[id]/context/MapContext";
import { useDataSources } from "@/app/map/[id]/hooks/useDataSources";
import { useMapConfig } from "@/app/map/[id]/hooks/useMapConfig";
import { getDataSourceIds } from "@/app/map/[id]/utils/map";
import { Button } from "@/shadcn/ui/button";
import {
DropdownMenu,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
"use client";

import { useEffect, useState } from "react";
import { getDataSourceIds } from "@/app/map/[id]/context/MapContext";
import { useDataSources } from "@/app/map/[id]/hooks/useDataSources";
import { useMapConfig } from "@/app/map/[id]/hooks/useMapConfig";
import { getDataSourceIds } from "@/app/map/[id]/utils/map";
import { createDataSourceConfig } from "../components/DataSourcesSelect";
import { PublicMapContext } from "../context/PublicMapContext";
import type {
Expand Down
1 change: 1 addition & 0 deletions src/server/models/MapView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ export const mapViewConfigSchema = z.object({
areaDataSourceId: z.string(),
areaDataColumn: z.string(),
areaDataSecondaryColumn: z.string().optional(),
areaDataNullIsZero: z.boolean().optional(),
areaSetGroupCode: areaSetGroupCode.nullish(),
choroplethOpacityPct: z.number().optional(),
excludeColumnsString: z.string(),
Expand Down
Loading