Skip to content

Commit

Permalink
feat: New Basemap Switcher and Pin Selection State (#343)
Browse files Browse the repository at this point in the history
  • Loading branch information
popkinj authored Jan 15, 2025
1 parent b0e97c1 commit 1541de8
Show file tree
Hide file tree
Showing 24 changed files with 541 additions and 30 deletions.
2 changes: 1 addition & 1 deletion frontend/Caddyfile
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
script-src 'self' https://www2.gov.bc.ca https://*.openstreetmap.org;
style-src 'self' 'unsafe-inline' https://fonts.googleapis.com https://use.fontawesome.com https://*.openstreetmap.org;
font-src 'self' https://fonts.gstatic.com https://*.openstreetmap.org;
img-src 'self' data: https://fonts.googleapis.com http://www.w3.org https://*.gov.bc.ca https://*.openstreetmap.org;
img-src 'self' data: https://fonts.googleapis.com http://www.w3.org https://*.gov.bc.ca https://*.openstreetmap.org https://*.stadiamaps.com https://server.arcgisonline.com https://api.maptiler.com;
frame-ancestors 'none';
form-action 'self' {$BACKEND_URL};
frame-src 'none';
Expand Down
16 changes: 16 additions & 0 deletions frontend/e2e/pages/map.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,4 +106,20 @@ export const map_page = async (page: Page) => {
await showResultsBtn.click()

await page.getByTitle('Close').click({ force: true })

// Test basemap switcher
const basemapButton = page.locator('.basemap-toggle')
await expect(basemapButton).toBeVisible()
await basemapButton.click()

// Check all basemap options are available
await expect(
page.locator('.basemap-option span').filter({ hasText: 'Streets' }),
).toBeVisible()
await expect(
page.locator('.basemap-option span').filter({ hasText: 'Terrain' }),
).toBeVisible()
await expect(
page.locator('.basemap-option span').filter({ hasText: 'Imagery' }),
).toBeVisible()
}
Binary file added frontend/public/Streets.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added frontend/public/custom-1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added frontend/public/custom-2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added frontend/public/custom-3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added frontend/public/custom-4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added frontend/public/imagery.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added frontend/public/pale-osm.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added frontend/public/streets.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added frontend/public/terrain.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
35 changes: 35 additions & 0 deletions frontend/src/assets/svgs/pin-default-1.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
35 changes: 35 additions & 0 deletions frontend/src/assets/svgs/pin-hover-1.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
35 changes: 35 additions & 0 deletions frontend/src/assets/svgs/pin-selected-1.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion frontend/src/components/AuthorizationListItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export function AuthorizationListItem({
sx={sx}
>
<Typography component="div" fontSize={14} marginBottom="8px">
Authorization #: <u>{number}</u>
Authorization #: <b>{number}</b>
</Typography>
<Typography
component="div"
Expand Down
53 changes: 53 additions & 0 deletions frontend/src/constants/marker-icons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import shadowIcon1x from '@/assets/marker-shadow-1x.png'
import markerIcon2x from '@/assets/marker-icon-2x-blue.png'
import shadowIcon2x from '@/assets/marker-shadow-2x.png'
import crosshairsSvg from '@/assets/svgs/crosshairs.svg'
import pinDefault from '@/assets/svgs/pin-default-1.svg'
import pinSelected from '@/assets/svgs/pin-selected-1.svg'

export const blueIcon2x = new L.Icon({
iconUrl: markerIcon2x,
Expand All @@ -30,6 +32,57 @@ export const blueIcon1x = new L.Icon({
shadowAnchor: [8, 4],
})

export const pinDefaultIcon = new L.Icon({
iconUrl: pinDefault,
iconSize: [23, 30],
iconAnchor: [11.5, 30],
className: 'pin-default-icon',
// both relative to iconAnchor
popupAnchor: [0, -28],
tooltipAnchor: [0, -28],
shadowUrl: shadowIcon1x,
shadowSize: [16, 8],
shadowAnchor: [8, 4],
})

export const pinSelectedIcon = new L.Icon({
iconUrl: pinSelected,
iconSize: [23, 30],
iconAnchor: [11.5, 30],
className: 'pin-selected-icon',
// both relative to iconAnchor
popupAnchor: [0, -28],
tooltipAnchor: [0, -28],
shadowUrl: shadowIcon1x,
shadowSize: [16, 8],
shadowAnchor: [8, 4],
})
export const pinSelectedHoverIcon = new L.Icon({
iconUrl: pinSelected,
iconSize: [33, 33],
iconAnchor: [16.5, 33],
className: 'pin-selected-hover-icon',
// both relative to iconAnchor
popupAnchor: [0, -28],
tooltipAnchor: [0, -28],
shadowUrl: shadowIcon1x,
shadowSize: [16, 8],
shadowAnchor: [8, 4],
})

export const pinHoverIcon = new L.Icon({
iconUrl: pinDefault,
iconSize: [33, 33],
iconAnchor: [16.5, 33],
className: 'pin-hover-icon',
// both relative to iconAnchor
popupAnchor: [0, -28],
tooltipAnchor: [0, -28],
shadowUrl: shadowIcon1x,
shadowSize: [16, 8],
shadowAnchor: [8, 4],
})

// Used by Polygon and Point search tools
export const crosshairsIcon = new L.Icon({
iconUrl: crosshairsSvg,
Expand Down
6 changes: 6 additions & 0 deletions frontend/src/pages/authorizationDetails/DetailsGridItems.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,12 @@ function OrganicMatterGridItem({ item }: Readonly<Props>) {
<Typography className="organic-matter-title">
Organic Matter Used for Composting
</Typography>
<Typography className="organic-matter-note">
<i style={{ color: '#666666' }}>
The information presented was provided by the proponent at the time of
submission
</i>
</Typography>
<Grid
container
sx={{
Expand Down
5 changes: 2 additions & 3 deletions frontend/src/pages/map/MapView.css
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

.map-view {
width: 100%;
height: calc(100vh - var(--header-height));
Expand Down Expand Up @@ -46,7 +45,7 @@
height: 18px;
background-color: var(--surface-color-brand-blue-100);
border: 1px solid var(--surface-color-border-light);
box-shadow: var(--box-shadow-small)
box-shadow: var(--box-shadow-small);
}

.point-search-circle,
Expand Down Expand Up @@ -94,4 +93,4 @@

.wl-pod-sources img {
filter: brightness(0.5);
}
}
13 changes: 3 additions & 10 deletions frontend/src/pages/map/MapView.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
import { LatLngTuple } from 'leaflet'
import { MapContainer, TileLayer } from 'react-leaflet'
import { MapContainer } from 'react-leaflet'
import { useTheme } from '@mui/material/styles'
import useMediaQuery from '@mui/material/useMediaQuery'
import clsx from 'clsx'

import { env } from '@/env'
import { MapSearch } from './search/MapSearch'
import { MapDrawer } from './drawer/MapDrawer'
import { AuthorizationMarkers } from './layers/AuthorizationMarkers'
import { MyLocationMarker } from './layers/MyLocationMarker'
import { BasemapControl } from './layers/BasemapControl'
import { MapControls } from './layers/MapControls'
import { MapDataLayers } from './layers/MapDataLayers'
import { MapZoom } from './layers/MapZoom'
import { PointSearchLayer } from './layers/PointSearchLayer'
import { PolygonSearchLayer } from './layers/PolygonSearchLayer'

import 'leaflet/dist/leaflet.css'
import './MapView.css'

Expand All @@ -27,8 +26,6 @@ const CENTER_OF_BC: LatLngTuple = [53.7267, -127.6476]
function MapView() {
const theme = useTheme()
const isSmall = useMediaQuery(theme.breakpoints.down('md'))
// Feature flag for turning OpenStreetMap tiles gray
const osmGrayscale = env.VITE_OSM_GRAYSCALE_FLAG === 'true'

return (
<div
Expand All @@ -41,11 +38,7 @@ function MapView() {
zoomControl={false}
className="map-container"
>
<TileLayer
attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
className={clsx(osmGrayscale && 'osm--grayscale')}
/>
<BasemapControl />
<MapDataLayers />
<MapControls />
<AuthorizationMarkers />
Expand Down
16 changes: 14 additions & 2 deletions frontend/src/pages/map/layers/AuthorizationMarker.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
import { Tooltip } from 'react-leaflet'
import { useSelector } from 'react-redux'
import { RootState } from '@/app/store'

import OmrrData from '@/interfaces/omrr'
import { blueIcon1x, blueIcon2x } from '@/constants/marker-icons'
import {
pinDefaultIcon,
pinSelectedIcon,
pinHoverIcon,
pinSelectedHoverIcon,
} from '@/constants/marker-icons'
import { IconMarker } from './IconMarker'

interface Props {
Expand All @@ -15,11 +22,16 @@ export function AuthorizationMarker({
isSmall,
onClick,
}: Readonly<Props>) {
const selectedItem = useSelector((state: RootState) => state.map.selectedItem)
const isSelected =
selectedItem?.['Authorization Number'] === item['Authorization Number']

const title = item['Regulated Party']
return (
<IconMarker
position={[item.Latitude, item.Longitude]}
icon={isSmall ? blueIcon1x : blueIcon2x}
icon={isSelected ? pinSelectedIcon : pinDefaultIcon}
hoverIcon={isSelected ? pinSelectedHoverIcon : pinHoverIcon}
alt="Authorization marker"
title={title}
riseOnHover
Expand Down
Loading

0 comments on commit 1541de8

Please sign in to comment.