diff --git a/e2e/map.spec.ts b/e2e/map.spec.ts index 000ba144..6976d2e9 100644 --- a/e2e/map.spec.ts +++ b/e2e/map.spec.ts @@ -2,7 +2,6 @@ import { test, expect } from '@playwright/test'; import { BERLIN_COORDINATES, setupHeightMock, - setupLocateMock, setupNominatimMock, setupRouteMock, setupSearchMock, @@ -481,6 +480,9 @@ test.describe('Map interactions with left context menu', () => { button: 'left', }); + // Wait for popup to appear (has 200ms delay) + await expect(page.getByTestId('map-info-popup')).toBeVisible(); + await expect(page.getByTestId('dd-button')).toContainText( '13.393707, 52.518310' ); @@ -496,14 +498,9 @@ test.describe('Map interactions with left context menu', () => { ); await expect(page.getByTestId('dms-copy-button')).toBeVisible(); - await expect( - page.getByRole('button', { name: 'Locate Point' }) - ).toBeVisible(); - await expect(page.getByTestId('locate-point-copy-button')).toBeVisible(); - - await expect( - page.getByRole('button', { name: 'Valhalla Location JSON' }) - ).toBeVisible(); + await expect(page.getByTestId('location-json-button')).toContainText( + 'Valhalla Location JSON' + ); await expect(page.getByTestId('location-json-copy-button')).toBeVisible(); await expect(page.getByTestId('elevation-button')).toContainText('34 m'); @@ -516,35 +513,10 @@ test.describe('Map interactions with left context menu', () => { button: 'left', }); - await expect(page.getByTestId('elevation-button')).toContainText('34 m'); - }); - - test('should call locate', async ({ page }) => { - await setupHeightMock(page); - const locateRequests = await setupLocateMock(page); + // Wait for popup to appear (has 200ms delay) + await expect(page.getByTestId('map-info-popup')).toBeVisible(); - await page.getByRole('region', { name: 'Map' }).click({ - button: 'left', - }); - - await expect( - page.getByRole('button', { name: 'Locate Point' }) - ).toBeVisible(); - - await page.getByRole('button', { name: 'Locate Point' }).click(); - - expect(locateRequests.length).toBeGreaterThan(0); - - const locateRequest = locateRequests[0] as RouteApiRequest; - expect(locateRequest.method).toBe('POST'); - expect(locateRequest.url).toMatch( - /https:\/\/valhalla1\.openstreetmap\.de\/locate/ - ); - expect(locateRequest.body).toBeDefined(); - expect(locateRequest.body?.costing).toBe('bicycle'); - expect(locateRequest.body?.locations).toStrictEqual([ - { lat: 52.51830999999976, lon: 13.393706999999239 }, - ]); + await expect(page.getByTestId('elevation-button')).toContainText('34 m'); }); test('should copy text to clipboard', async ({ page }) => { @@ -554,6 +526,9 @@ test.describe('Map interactions with left context menu', () => { button: 'left', }); + // Wait for popup to appear (has 200ms delay) + await expect(page.getByTestId('map-info-popup')).toBeVisible(); + await page.getByTestId('dd-copy-button').click(); const clipboardContent = await page.evaluate(() => diff --git a/src/components/map/index.tsx b/src/components/map/index.tsx index 2a310ae0..76b544be 100644 --- a/src/components/map/index.tsx +++ b/src/components/map/index.tsx @@ -16,11 +16,7 @@ import 'maplibre-gl/dist/maplibre-gl.css'; import axios from 'axios'; import { throttle } from 'throttle-debounce'; -import { - getValhallaUrl, - buildHeightRequest, - buildLocateRequest, -} from '@/utils/valhalla'; +import { getValhallaUrl, buildHeightRequest } from '@/utils/valhalla'; import { buildHeightgraphData } from '@/utils/heightgraph'; import HeightGraph from '@/components/heightgraph'; import { DrawControl } from './draw-control'; @@ -89,12 +85,10 @@ export const MapComponent = () => { ); const updateSettings = useCommonStore((state) => state.updateSettings); const setMapReady = useCommonStore((state) => state.setMapReady); - const { profile, style } = useSearch({ from: '/$activeTab' }); + const { style } = useSearch({ from: '/$activeTab' }); const [showInfoPopup, setShowInfoPopup] = useState(false); const [showContextPopup, setShowContextPopup] = useState(false); - const [isLocateLoading, setIsLocateLoading] = useState(false); const [isHeightLoading, setIsHeightLoading] = useState(false); - const [locate, setLocate] = useState([]); const [popupLngLat, setPopupLngLat] = useState<{ lng: number; lat: number; @@ -292,32 +286,6 @@ export const MapComponent = () => { }); }, []); - const getLocate = useCallback( - (lng: number, lat: number) => { - setIsLocateLoading(true); - axios - .post( - getValhallaUrl() + '/locate', - buildLocateRequest({ lng, lat }, profile || 'bicycle'), - { - headers: { - 'Content-Type': 'application/json', - }, - } - ) - .then(({ data }) => { - setLocate(data); - }) - .catch(({ response }) => { - console.log(response); - }) - .finally(() => { - setIsLocateLoading(false); - }); - }, - [profile] - ); - const handleAddWaypoint = useCallback( (index: number) => { if (!popupLngLat) return; @@ -876,12 +844,8 @@ export const MapComponent = () => { popupLngLat={popupLngLat} elevation={elevation} isHeightLoading={isHeightLoading} - isLocateLoading={isLocateLoading} - locate={locate} - onLocate={getLocate} onClose={() => { setShowInfoPopup(false); - setLocate([]); }} /> diff --git a/src/components/map/parts/map-info-popup.spec.tsx b/src/components/map/parts/map-info-popup.spec.tsx index f8d61ae6..679cdfff 100644 --- a/src/components/map/parts/map-info-popup.spec.tsx +++ b/src/components/map/parts/map-info-popup.spec.tsx @@ -11,9 +11,6 @@ const defaultProps = { popupLngLat: { lng: 10.123456, lat: 50.654321 }, elevation: '250 m', isHeightLoading: false, - isLocateLoading: false, - locate: [], - onLocate: vi.fn(), onClose: vi.fn(), }; @@ -68,15 +65,7 @@ describe('MapInfoPopup', () => { expect(screen.getByTestId('elevation-button')).toHaveTextContent('500 m'); }); - it('should display Locate Point button', () => { - render(); - - expect(screen.getByTestId('locate-point-button')).toHaveTextContent( - 'Locate Point' - ); - }); - - it('should display Valhalla Location JSON button', () => { + it('should display Valhalla Location JSON label', () => { render(); expect(screen.getByTestId('location-json-button')).toHaveTextContent( @@ -84,24 +73,6 @@ describe('MapInfoPopup', () => { ); }); - it('should call onLocate when Locate Point is clicked', async () => { - const user = userEvent.setup(); - const onLocate = vi.fn(); - const popupLngLat = { lng: 10.5, lat: 50.5 }; - - render( - - ); - - await user.click(screen.getByTestId('locate-point-button')); - - expect(onLocate).toHaveBeenCalledWith(10.5, 50.5); - }); - it('should format coordinates to 6 decimal places', () => { render( { ); }); - it('should have copy buttons for coordinate rows', () => { + it('should have copy buttons for coordinate rows with copyable values', () => { render(); expect(screen.getByTestId('dd-copy-button')).toBeInTheDocument(); @@ -123,4 +94,12 @@ describe('MapInfoPopup', () => { expect(screen.getByTestId('dms-copy-button')).toBeInTheDocument(); expect(screen.getByTestId('location-json-copy-button')).toBeInTheDocument(); }); + + it('should not have copy button for elevation (non-copyable value)', () => { + render(); + + expect( + screen.queryByTestId('elevation-copy-button') + ).not.toBeInTheDocument(); + }); }); diff --git a/src/components/map/parts/map-info-popup.tsx b/src/components/map/parts/map-info-popup.tsx index 437331b7..a974ec54 100644 --- a/src/components/map/parts/map-info-popup.tsx +++ b/src/components/map/parts/map-info-popup.tsx @@ -1,23 +1,12 @@ import { Button } from '@/components/ui/button'; import { CoordinateRow } from '@/components/ui/coordinate-row'; -import { - X, - Locate, - Globe, - Compass, - Cog, - MapPin, - ArrowUpDown, -} from 'lucide-react'; +import { X, Locate, Globe, Compass, MapPin, ArrowUpDown } from 'lucide-react'; import { convertDDToDMS } from '../utils'; interface MapInfoPopupProps { popupLngLat: { lng: number; lat: number }; elevation: string; isHeightLoading: boolean; - isLocateLoading: boolean; - locate: unknown[]; - onLocate: (lng: number, lat: number) => void; onClose: () => void; } @@ -25,9 +14,6 @@ export function MapInfoPopup({ popupLngLat, elevation, isHeightLoading, - isLocateLoading, - locate, - onLocate, onClose, }: MapInfoPopupProps) { const lngLatStr = `${popupLngLat.lng.toFixed(6)}, ${popupLngLat.lat.toFixed(6)}`; @@ -43,12 +29,13 @@ export function MapInfoPopup({ ); return ( -
+
@@ -78,18 +65,7 @@ export function MapInfoPopup({ /> } - onClick={() => onLocate(popupLngLat.lng, popupLngLat.lat)} - isLoading={isLocateLoading} - copyDisabled={locate.length === 0} - testId="locate-point" - /> - - } diff --git a/src/components/ui/coordinate-row.tsx b/src/components/ui/coordinate-row.tsx index cf7ed3e4..7bfce495 100644 --- a/src/components/ui/coordinate-row.tsx +++ b/src/components/ui/coordinate-row.tsx @@ -1,26 +1,23 @@ import { type ReactNode } from 'react'; import { Loader2 } from 'lucide-react'; -import { Button } from '@/components/ui/button'; -import { ButtonGroup } from '@/components/ui/button-group'; import { CopyButton } from '@/components/ui/copy-button'; import { Tooltip, TooltipContent, TooltipTrigger, } from '@/components/ui/tooltip'; +import { cn } from '@/lib/utils'; interface CoordinateRowProps { - /** Tooltip content describing the button */ + /** Tooltip content describing the label */ label: string; - /** Display value/label shown in the button */ + /** Display value/label shown */ value: string; /** Text to copy to clipboard. If omitted, no copy button is shown */ copyText?: string; /** Optional icon to show before the value */ icon?: ReactNode; - /** Click handler for the main button */ - onClick?: () => void; - /** Shows loading spinner and disables button */ + /** Shows loading spinner */ isLoading?: boolean; /** Disables the copy button */ copyDisabled?: boolean; @@ -33,37 +30,38 @@ function CoordinateRow({ value, copyText, icon, - onClick, isLoading, copyDisabled, testId, }: CoordinateRowProps) { return ( - +
- +
{label} {copyText && ( )} -
+
); }