diff --git a/server/src/graphql/resolvers.js b/server/src/graphql/resolvers.js
index 6c4751011..6e10fe204 100644
--- a/server/src/graphql/resolvers.js
+++ b/server/src/graphql/resolvers.js
@@ -214,10 +214,9 @@ module.exports = {
})
}
})
-
return filtered
}
- return scanAreas
+ return scanAreas.filter((parent) => parent.children.length)
}
return []
},
diff --git a/src/components/layout/drawer/AreaTile.jsx b/src/components/layout/drawer/AreaTile.jsx
new file mode 100644
index 000000000..ad8178ab2
--- /dev/null
+++ b/src/components/layout/drawer/AreaTile.jsx
@@ -0,0 +1,101 @@
+import React from 'react'
+import { Grid, MenuItem, Typography, Checkbox } from '@material-ui/core'
+import { useMap } from 'react-leaflet'
+
+import Utility from '@services/Utility'
+import { useStore } from '@hooks/useStore'
+
+export default function AreaTile({
+ name,
+ feature,
+ childAreas,
+ scanAreasZoom,
+ allAreas,
+ i,
+}) {
+ const { scanAreas } = useStore((s) => s.filters)
+ const setAreas = useStore((s) => s.setAreas)
+ const map = useMap()
+
+ if (!scanAreas) return null
+
+ const hasAll =
+ childAreas &&
+ childAreas.every((c) => scanAreas.filter.areas.includes(c.properties.name))
+ const hasSome =
+ childAreas &&
+ childAreas.some((c) => scanAreas.filter.areas.includes(c.properties.name))
+ const hasManual = childAreas
+ ? childAreas.some((c) => c.properties.manual)
+ : feature.properties.manual
+
+ return (
+
+
+
+ )
+}
diff --git a/src/components/layout/drawer/Areas.jsx b/src/components/layout/drawer/Areas.jsx
index 97d36b405..d9003acdf 100644
--- a/src/components/layout/drawer/Areas.jsx
+++ b/src/components/layout/drawer/Areas.jsx
@@ -1,136 +1,83 @@
import React from 'react'
import { useQuery } from '@apollo/client'
-import { Grid, Paper, MenuItem, Typography, Checkbox } from '@material-ui/core'
-import { useMap } from 'react-leaflet'
+import { Grid, Button, Paper } from '@material-ui/core'
+import { useTranslation } from 'react-i18next'
-import Utility from '@services/Utility'
import Query from '@services/Query'
import { useStore } from '@hooks/useStore'
+import AreaTile from './AreaTile'
export default function AreaDropDown({ scanAreaMenuHeight, scanAreasZoom }) {
const { data, loading, error } = useQuery(Query.scanAreasMenu())
- const map = useMap()
- const { scanAreas } = useStore((s) => s.filters)
+ const { t } = useTranslation()
const setAreas = useStore((s) => s.setAreas)
+ const allAreas = React.useMemo(() => {
+ if (data?.scanAreasMenu) {
+ return data.scanAreasMenu.flatMap((parent) =>
+ parent.children.map((child) => child.properties.name),
+ )
+ }
+ return []
+ }, [data])
+
if (loading || error) return null
return (
-
- {data?.scanAreasMenu?.map(({ name, details, children }) => (
-
+
+
- ))}
-
+ {t('reset')}
+
+
+
+ {data?.scanAreasMenu?.map(({ name, details, children }) => (
+
+ {name && (
+
+ )}
+ {children.map((feature, i) => (
+
+ ))}
+
+ ))}
+
+ >
)
}
diff --git a/src/hooks/useStore.js b/src/hooks/useStore.js
index 4f2e897f2..7e214920a 100644
--- a/src/hooks/useStore.js
+++ b/src/hooks/useStore.js
@@ -10,8 +10,19 @@ export const useStore = create(
setZoom: (zoom) => set({ zoom }),
filters: undefined,
setFilters: (filters) => set({ filters }),
- setAreas: (area) => {
+ setAreas: (areas = [], validAreas = [], unselectAll = false) => {
const { filters } = get()
+ const incoming = new Set(Array.isArray(areas) ? areas : [areas])
+ const existing = new Set(filters?.scanAreas?.filter?.areas || [])
+
+ incoming.forEach((area) => {
+ if (existing.has(area) || unselectAll) {
+ existing.delete(area)
+ } else {
+ existing.add(area)
+ }
+ })
+
if (filters?.scanAreas?.filter?.areas) {
set({
filters: {
@@ -20,9 +31,9 @@ export const useStore = create(
...filters.scanAreas,
filter: {
...filters.scanAreas.filter,
- areas: filters.scanAreas.filter.areas.includes(area)
- ? filters.scanAreas.filter.areas.filter((a) => a !== area)
- : [...filters.scanAreas.filter.areas, area],
+ areas: [...existing].filter((area) =>
+ validAreas.includes(area),
+ ),
},
},
},