diff --git a/cms/config/sync/core-store.plugin_content_manager_configuration_content_types##api##data-info.data-info.json b/cms/config/sync/core-store.plugin_content_manager_configuration_content_types##api##data-info.data-info.json index 3c6ae023..6f8569ab 100644 --- a/cms/config/sync/core-store.plugin_content_manager_configuration_content_types##api##data-info.data-info.json +++ b/cms/config/sync/core-store.plugin_content_manager_configuration_content_types##api##data-info.data-info.json @@ -123,6 +123,12 @@ } }, "layouts": { + "list": [ + "id", + "slug", + "content", + "createdAt" + ], "edit": [ [ { @@ -140,12 +146,6 @@ "size": 6 } ] - ], - "list": [ - "id", - "slug", - "content", - "data_sources" ] } }, diff --git a/cms/config/sync/core-store.plugin_content_manager_configuration_content_types##api##fishing-protection-level-stat.fishing-protection-level-stat.json b/cms/config/sync/core-store.plugin_content_manager_configuration_content_types##api##fishing-protection-level-stat.fishing-protection-level-stat.json index aba53dd4..374dfbc4 100644 --- a/cms/config/sync/core-store.plugin_content_manager_configuration_content_types##api##fishing-protection-level-stat.fishing-protection-level-stat.json +++ b/cms/config/sync/core-store.plugin_content_manager_configuration_content_types##api##fishing-protection-level-stat.fishing-protection-level-stat.json @@ -127,24 +127,24 @@ "list": [ "id", "location", - "area", - "fishing_protection_level" + "fishing_protection_level", + "area" ], "edit": [ [ { "name": "location", "size": 6 + }, + { + "name": "fishing_protection_level", + "size": 6 } ], [ { "name": "area", "size": 4 - }, - { - "name": "fishing_protection_level", - "size": 6 } ] ] diff --git a/cms/config/sync/core-store.plugin_content_manager_configuration_content_types##api##habitat-stat.habitat-stat.json b/cms/config/sync/core-store.plugin_content_manager_configuration_content_types##api##habitat-stat.habitat-stat.json index 05b82a7c..be24cdd4 100644 --- a/cms/config/sync/core-store.plugin_content_manager_configuration_content_types##api##habitat-stat.habitat-stat.json +++ b/cms/config/sync/core-store.plugin_content_manager_configuration_content_types##api##habitat-stat.habitat-stat.json @@ -152,6 +152,12 @@ } }, "layouts": { + "list": [ + "id", + "location", + "habitat", + "year" + ], "edit": [ [ { @@ -177,14 +183,6 @@ "size": 4 } ] - ], - "list": [ - "id", - "location", - "habitat", - "year", - "protectedArea", - "totalArea" ] } }, diff --git a/cms/config/sync/core-store.plugin_content_manager_configuration_content_types##api##location.location.json b/cms/config/sync/core-store.plugin_content_manager_configuration_content_types##api##location.location.json index 2a2b3e28..94cd9355 100644 --- a/cms/config/sync/core-store.plugin_content_manager_configuration_content_types##api##location.location.json +++ b/cms/config/sync/core-store.plugin_content_manager_configuration_content_types##api##location.location.json @@ -229,9 +229,7 @@ "id", "code", "name", - "type", - "totalMarineArea", - "groups" + "totalMarineArea" ], "edit": [ [ @@ -245,6 +243,10 @@ } ], [ + { + "name": "totalMarineArea", + "size": 4 + }, { "name": "type", "size": 6 @@ -252,29 +254,25 @@ ], [ { - "name": "totalMarineArea", - "size": 4 + "name": "groups", + "size": 6 }, { - "name": "groups", + "name": "members", "size": 6 } ], [ { - "name": "members", + "name": "fishing_protection_level_stats", "size": 6 }, { - "name": "fishing_protection_level_stats", + "name": "mpaa_protection_level_stats", "size": 6 } ], [ - { - "name": "mpaa_protection_level_stats", - "size": 6 - }, { "name": "protection_coverage_stats", "size": 6 diff --git a/cms/config/sync/core-store.plugin_content_manager_configuration_content_types##api##mpa-protection-coverage-stat.mpa-protection-coverage-stat.json b/cms/config/sync/core-store.plugin_content_manager_configuration_content_types##api##mpa-protection-coverage-stat.mpa-protection-coverage-stat.json index cb0f06ab..988a9767 100644 --- a/cms/config/sync/core-store.plugin_content_manager_configuration_content_types##api##mpa-protection-coverage-stat.mpa-protection-coverage-stat.json +++ b/cms/config/sync/core-store.plugin_content_manager_configuration_content_types##api##mpa-protection-coverage-stat.mpa-protection-coverage-stat.json @@ -154,6 +154,12 @@ } }, "layouts": { + "list": [ + "id", + "mpa", + "fishing_protection_level", + "mpaa_protection_level" + ], "edit": [ [ { @@ -181,13 +187,6 @@ "size": 4 } ] - ], - "list": [ - "id", - "mpa", - "fishing_protection_level", - "mpaa_protection_level", - "location" ] } }, diff --git a/cms/config/sync/core-store.plugin_content_manager_configuration_content_types##api##mpa.mpa.json b/cms/config/sync/core-store.plugin_content_manager_configuration_content_types##api##mpa.mpa.json index 4d265ea6..b860c5d6 100644 --- a/cms/config/sync/core-store.plugin_content_manager_configuration_content_types##api##mpa.mpa.json +++ b/cms/config/sync/core-store.plugin_content_manager_configuration_content_types##api##mpa.mpa.json @@ -181,6 +181,12 @@ } }, "layouts": { + "list": [ + "id", + "wdpaid", + "name", + "year" + ], "edit": [ [ { @@ -220,15 +226,6 @@ "size": 6 } ] - ], - "list": [ - "id", - "wdpaid", - "name", - "year", - "protection_status", - "mpaa_establishment_stage", - "area" ] } }, diff --git a/cms/config/sync/core-store.plugin_content_manager_configuration_content_types##api##mpaa-establishment-stage-stat.mpaa-establishment-stage-stat.json b/cms/config/sync/core-store.plugin_content_manager_configuration_content_types##api##mpaa-establishment-stage-stat.mpaa-establishment-stage-stat.json index 084cec3b..baa0618d 100644 --- a/cms/config/sync/core-store.plugin_content_manager_configuration_content_types##api##mpaa-establishment-stage-stat.mpaa-establishment-stage-stat.json +++ b/cms/config/sync/core-store.plugin_content_manager_configuration_content_types##api##mpaa-establishment-stage-stat.mpaa-establishment-stage-stat.json @@ -153,6 +153,12 @@ } }, "layouts": { + "list": [ + "id", + "location", + "mpaa_establishment_stage", + "protection_status" + ], "edit": [ [ { @@ -180,14 +186,6 @@ "size": 4 } ] - ], - "list": [ - "id", - "location", - "mpaa_establishment_stage", - "protection_status", - "year", - "area" ] } }, diff --git a/cms/config/sync/core-store.plugin_content_manager_configuration_content_types##api##protection-coverage-stat.protection-coverage-stat.json b/cms/config/sync/core-store.plugin_content_manager_configuration_content_types##api##protection-coverage-stat.protection-coverage-stat.json index 163b6b18..0dac0cba 100644 --- a/cms/config/sync/core-store.plugin_content_manager_configuration_content_types##api##protection-coverage-stat.protection-coverage-stat.json +++ b/cms/config/sync/core-store.plugin_content_manager_configuration_content_types##api##protection-coverage-stat.protection-coverage-stat.json @@ -166,6 +166,12 @@ } }, "layouts": { + "list": [ + "id", + "location", + "protection_status", + "year" + ], "edit": [ [ { @@ -197,14 +203,6 @@ "size": 4 } ] - ], - "list": [ - "id", - "location", - "protection_status", - "year", - "cumSumProtectedArea", - "protectedAreasCount" ] } }, diff --git a/cms/config/sync/user-role.public.json b/cms/config/sync/user-role.public.json index 066442e3..0d024b4a 100644 --- a/cms/config/sync/user-role.public.json +++ b/cms/config/sync/user-role.public.json @@ -9,36 +9,12 @@ { "action": "api::data-info.data-info.findOne" }, - { - "action": "api::data-source.data-source.find" - }, - { - "action": "api::data-source.data-source.findOne" - }, - { - "action": "api::fishing-protection-level-stat.fishing-protection-level-stat.find" - }, - { - "action": "api::fishing-protection-level-stat.fishing-protection-level-stat.findOne" - }, - { - "action": "api::fishing-protection-level.fishing-protection-level.find" - }, - { - "action": "api::fishing-protection-level.fishing-protection-level.findOne" - }, { "action": "api::habitat-stat.habitat-stat.find" }, { "action": "api::habitat-stat.habitat-stat.findOne" }, - { - "action": "api::habitat.habitat.find" - }, - { - "action": "api::habitat.habitat.findOne" - }, { "action": "api::layer.layer.find" }, @@ -57,48 +33,12 @@ { "action": "api::mpa-protection-coverage-stat.mpa-protection-coverage-stat.findOne" }, - { - "action": "api::mpa.mpa.find" - }, - { - "action": "api::mpa.mpa.findOne" - }, - { - "action": "api::mpaa-establishment-stage-stat.mpaa-establishment-stage-stat.find" - }, - { - "action": "api::mpaa-establishment-stage-stat.mpaa-establishment-stage-stat.findOne" - }, - { - "action": "api::mpaa-establishment-stage.mpaa-establishment-stage.find" - }, - { - "action": "api::mpaa-establishment-stage.mpaa-establishment-stage.findOne" - }, - { - "action": "api::mpaa-protection-level-stat.mpaa-protection-level-stat.find" - }, - { - "action": "api::mpaa-protection-level-stat.mpaa-protection-level-stat.findOne" - }, - { - "action": "api::mpaa-protection-level.mpaa-protection-level.find" - }, - { - "action": "api::mpaa-protection-level.mpaa-protection-level.findOne" - }, { "action": "api::protection-coverage-stat.protection-coverage-stat.find" }, { "action": "api::protection-coverage-stat.protection-coverage-stat.findOne" }, - { - "action": "api::protection-status.protection-status.find" - }, - { - "action": "api::protection-status.protection-status.findOne" - }, { "action": "plugin::users-permissions.auth.callback" }, diff --git a/frontend/package.json b/frontend/package.json index 0b770e54..a5c437c7 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -54,7 +54,7 @@ "lucide-react": "^0.274.0", "mapbox-gl": "2.15.0", "next": "13.5.6", - "next-usequerystate": "1.8.4", + "next-usequerystate": "1.9.2", "orval": "6.18.1", "postcss": "8.4.21", "react": "18.2.0", diff --git a/frontend/src/containers/data-tool/content/index.tsx b/frontend/src/containers/data-tool/content/index.tsx index ee08a3f0..c05e99ea 100644 --- a/frontend/src/containers/data-tool/content/index.tsx +++ b/frontend/src/containers/data-tool/content/index.tsx @@ -7,7 +7,7 @@ const DataToolContent: React.FC = () => { const [{ showDetails }] = useSyncDataToolContentSettings(); return ( -
+
{showDetails &&
}
diff --git a/frontend/src/containers/data-tool/content/map/index.tsx b/frontend/src/containers/data-tool/content/map/index.tsx index 017fb0f3..e22f5bf4 100644 --- a/frontend/src/containers/data-tool/content/map/index.tsx +++ b/frontend/src/containers/data-tool/content/map/index.tsx @@ -1,9 +1,12 @@ -import { ComponentProps, useCallback } from 'react'; +import { ComponentProps, useCallback, useEffect, useRef } from 'react'; import { useMap } from 'react-map-gl'; +import { LngLatBoundsLike } from 'react-map-gl'; import dynamic from 'next/dynamic'; +import { useParams } from 'next/navigation'; +import { useQueryClient } from '@tanstack/react-query'; import { useAtomValue, useSetAtom } from 'jotai'; import Map, { ZoomControls, Attributions, DrawControls, Drawing } from '@/components/map'; @@ -12,6 +15,7 @@ import SidebarContent from '@/components/sidebar-content'; import LayersToolbox from '@/containers/data-tool/content/map/layers-toolbox'; import { useSyncMapSettings } from '@/containers/data-tool/content/map/sync-settings'; import { cn } from '@/lib/classnames'; +import { sidebarAtom } from '@/store/data-tool'; import { drawStateAtom, layersInteractiveAtom, @@ -19,6 +23,8 @@ import { popupAtom, } from '@/store/map'; import { useGetLayers } from '@/types/generated/layer'; +import { getGetLocationsQueryOptions } from '@/types/generated/location'; +import { LocationListResponse, LocationResponseDataObject } from '@/types/generated/strapi.schemas'; import { LayerTyped } from '@/types/layers'; const LayerManager = dynamic(() => import('@/containers/data-tool/content/map/layer-manager'), { @@ -26,10 +32,19 @@ const LayerManager = dynamic(() => import('@/containers/data-tool/content/map/la }); const DataToolMap: React.FC = () => { - const [{ bbox }, setMapSettings] = useSyncMapSettings(); + const [{ bbox: customBbox }, setMapSettings] = useSyncMapSettings(); const { default: map } = useMap(); const drawState = useAtomValue(drawStateAtom); const setPopup = useSetAtom(popupAtom); + const queryClient = useQueryClient(); + const { locationCode } = useParams(); + const isSidebarOpen = useAtomValue(sidebarAtom); + const hoveredPolygonId = useRef(null); + + const locationData = queryClient.getQueryData([ + 'locations', + locationCode, + ]); const layersInteractive = useAtomValue(layersInteractiveAtom); const layersInteractiveIds = useAtomValue(layersInteractiveIdsAtom); @@ -57,7 +72,7 @@ const DataToolMap: React.FC = () => { .getBounds() .toArray() .flat() - .map((b) => parseFloat(b.toFixed(2))) as typeof bbox, + .map((b) => parseFloat(b.toFixed(2))) as typeof customBbox, })); }, [map, setMapSettings]); @@ -71,23 +86,101 @@ const DataToolMap: React.FC = () => { }) ) { const p = Object.assign({}, e, { features: e.features ?? [] }); - setPopup(p); } }, [layersInteractive, layersInteractiveData, setPopup] ); + const handleMouseMove = useCallback( + (e: Parameters['onMouseOver']>[0]) => { + if (e.features.length > 0) { + if (hoveredPolygonId.current !== null) { + map.setFeatureState( + { + source: e.features?.[0].source, + id: hoveredPolygonId.current, + sourceLayer: e.features?.[0].sourceLayer, + }, + { hover: false } + ); + } + map.setFeatureState( + { + source: e.features?.[0].source, + id: e.features[0].id, + sourceLayer: e.features?.[0].sourceLayer, + }, + { hover: true } + ); + + hoveredPolygonId.current = e.features[0].id; + } + }, + [map, hoveredPolygonId] + ); + + const handleMouseLeave = useCallback(() => { + if (hoveredPolygonId.current !== null) { + map.setFeatureState( + // ? not a fan of harcoding the sources here, but there is no other way to find out the source + { source: 'ezz-source', id: hoveredPolygonId.current, sourceLayer: 'eez_v11' }, + { hover: false } + ); + } + }, [map, hoveredPolygonId]); + + const bounds = customBbox ?? (locationData?.attributes?.bounds as LngLatBoundsLike); + + useEffect(() => { + map?.easeTo({ + padding: { + top: 0, + bottom: 0, + left: isSidebarOpen ? 430 : 0, + right: 0, + }, + duration: 500, + }); + }, [isSidebarOpen, map]); + + useEffect(() => { + const { queryKey } = getGetLocationsQueryOptions(); + const d = queryClient.getQueryData(queryKey); + if (d) { + const location = d.data.find(({ attributes }) => attributes.code === locationCode); + + map?.fitBounds(location.attributes.bounds as LngLatBoundsLike, { + padding: { + top: 0, + bottom: 0, + left: isSidebarOpen ? 430 : 0, + right: 0, + }, + }); + } + }, [queryClient, locationCode, isSidebarOpen, map]); + return ( -
+
diff --git a/frontend/src/containers/data-tool/content/map/layer-manager/item.tsx b/frontend/src/containers/data-tool/content/map/layer-manager/item.tsx index 18d72a5f..a069c387 100644 --- a/frontend/src/containers/data-tool/content/map/layer-manager/item.tsx +++ b/frontend/src/containers/data-tool/content/map/layer-manager/item.tsx @@ -1,5 +1,7 @@ import { useCallback } from 'react'; +import { useParams } from 'next/navigation'; + import { useAtom } from 'jotai'; import DeckJsonLayer from '@/components/map/layers/deck-json-layer'; @@ -21,6 +23,7 @@ const LayerManagerItem = ({ id, beforeId, settings }: LayerManagerItemProps) => }); const [, setLayersInteractive] = useAtom(layersInteractiveAtom); const [, setLayersInteractiveIds] = useAtom(layersInteractiveIdsAtom); + const { locationCode } = useParams(); const handleAddMapboxLayer = useCallback( ({ styles }: Config) => { @@ -64,7 +67,10 @@ const LayerManagerItem = ({ id, beforeId, settings }: LayerManagerItemProps) => const c = parseConfig({ config, params_config, - settings, + settings: { + ...settings, + location: locationCode, + }, }); if (!c) return null; diff --git a/frontend/src/containers/data-tool/content/map/sync-settings.ts b/frontend/src/containers/data-tool/content/map/sync-settings.ts index 6235ce66..e4f849c8 100644 --- a/frontend/src/containers/data-tool/content/map/sync-settings.ts +++ b/frontend/src/containers/data-tool/content/map/sync-settings.ts @@ -28,3 +28,26 @@ export const useSyncMapLayerSettings = () => { parseAsJson<{ [layerId: number]: Partial }>().withDefault({}) ); }; + +// ? there is an issue where NextJS's useSearchParams will not return the update searchParams +// ? updated via next-usequerystate, so we rely in next-usequerystate to retrieve those searchParams as well +// ? this might be an issue with next-usequerystate, but for now we can make it work this way. +// ! if you are using syncing a new state through next-usequerystate in the data-tool's map page, remember to register it here +export const useDataToolSearchParams = () => { + const [settings] = useSyncMapSettings(); + const [layers] = useSyncMapLayers(); + const [layerSettings] = useSyncMapLayerSettings(); + const currentSearchparams = new URLSearchParams(); + + currentSearchparams.set('layers', parseAsArrayOf(parseAsInteger).serialize(layers)); + currentSearchparams.set( + 'settings', + parseAsJson().serialize(settings) + ); + currentSearchparams.set( + 'layer-settings', + parseAsJson<{ [layerId: number]: Partial }>().serialize(layerSettings) + ); + + return currentSearchparams; +}; diff --git a/frontend/src/containers/data-tool/sidebar/index.tsx b/frontend/src/containers/data-tool/sidebar/index.tsx index 56f74f9c..6fea7682 100644 --- a/frontend/src/containers/data-tool/sidebar/index.tsx +++ b/frontend/src/containers/data-tool/sidebar/index.tsx @@ -1,11 +1,10 @@ -import { useState } from 'react'; - -import { useAtomValue } from 'jotai'; +import { useAtom, useAtomValue } from 'jotai'; import { ChevronLeft } from 'lucide-react'; import { Button } from '@/components/ui/button'; import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '@/components/ui/collapsible'; import { cn } from '@/lib/classnames'; +import { sidebarAtom } from '@/store/data-tool'; import { locationAtom } from '@/store/location'; import DetailsButton from './details-button'; @@ -15,12 +14,12 @@ import Widgets from './widgets'; const DataToolSidebar: React.FC = () => { const location = useAtomValue(locationAtom); - const [sidebarOpen, setSidebarOpen] = useState(true); + const [isSidebarOpen, setSidebarOpen] = useAtom(sidebarAtom); return ( @@ -29,11 +28,11 @@ const DataToolSidebar: React.FC = () => { variant="white" className={cn('absolute bottom-0 z-10 h-12 border-l-0 px-1', { 'hidden md:flex': true, - 'left-0': !sidebarOpen, - 'left-[430px] transition-[left] delay-500': sidebarOpen, + 'left-0': !isSidebarOpen, + 'left-[430px] transition-[left] delay-500': isSidebarOpen, })} > - + Toggle sidebar diff --git a/frontend/src/containers/data-tool/sidebar/location-selector/index.tsx b/frontend/src/containers/data-tool/sidebar/location-selector/index.tsx index 12591a3c..157eb3ff 100644 --- a/frontend/src/containers/data-tool/sidebar/location-selector/index.tsx +++ b/frontend/src/containers/data-tool/sidebar/location-selector/index.tsx @@ -1,4 +1,4 @@ -import { useState } from 'react'; +import { useCallback, useState } from 'react'; import { useRouter } from 'next/router'; @@ -18,23 +18,33 @@ import { cn } from '@/lib/classnames'; import { locationAtom } from '@/store/location'; import { useGetLocations } from '@/types/generated/location'; +import { useDataToolSearchParams } from '../../content/map/sync-settings'; + type LocationSelectorProps = { - className: string; + className: HTMLDivElement['className']; }; const LocationSelector: React.FC = ({ className }) => { const location = useAtomValue(locationAtom); - const router = useRouter(); + const { push } = useRouter(); + const searchParams = useDataToolSearchParams(); const [locationPopoverOpen, setLocationPopoverOpen] = useState(false); - const { data: locationsData } = useGetLocations(); + const { data: locationsData } = useGetLocations(null, { + query: { + placeholderData: { data: [] }, + select: ({ data }) => data, + }, + }); - const locations = locationsData?.data || []; + const handleLocationSelected = useCallback( + async (locationCode: string) => { + setLocationPopoverOpen(false); - const handleLocationSelected = (locationCode: string) => { - setLocationPopoverOpen(false); - void router.replace(`${PAGES.dataTool}/${locationCode.toUpperCase()}`); - }; + await push(`${PAGES.dataTool}/${locationCode.toUpperCase()}?${searchParams.toString()}`); + }, + [push, searchParams] + ); return (
@@ -47,7 +57,7 @@ const LocationSelector: React.FC = ({ className }) => { No result - {locations.map(({ attributes }) => { + {locationsData.map(({ attributes }) => { const { name, code, type } = attributes; return ( diff --git a/frontend/src/layouts/.gitkeep b/frontend/src/layouts/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/frontend/src/pages/data-tool/[locationCode].tsx b/frontend/src/pages/data-tool/[locationCode].tsx index ee487836..694b4974 100644 --- a/frontend/src/pages/data-tool/[locationCode].tsx +++ b/frontend/src/pages/data-tool/[locationCode].tsx @@ -1,3 +1,4 @@ +import { QueryClient, dehydrate } from '@tanstack/react-query'; import { useSetAtom } from 'jotai'; import type { GetServerSideProps } from 'next'; @@ -6,12 +7,14 @@ import Sidebar from '@/containers/data-tool/sidebar'; import Layout from '@/layouts/data-tool'; import { locationAtom } from '@/store/location'; import { getLocations } from '@/types/generated/location'; -import { Location } from '@/types/generated/strapi.schemas'; +import { Location, LocationGroupsDataItem } from '@/types/generated/strapi.schemas'; export const getServerSideProps: GetServerSideProps = async (context) => { const { query } = context; const { locationCode } = query; + const queryClient = new QueryClient(); + const { data: locationsData } = await getLocations({ filters: { code: locationCode, @@ -20,9 +23,16 @@ export const getServerSideProps: GetServerSideProps = async (context) => { const location = locationsData[0]; + queryClient.setQueryData(['locations', locationCode], location); + if (!location) return { notFound: true }; - return { props: { location: location?.attributes } }; + return { + props: { + location: location?.attributes, + dehydratedState: dehydrate(queryClient), + }, + }; }; export default function Page({ location }: { location: Location }) { diff --git a/frontend/src/store/data-tool.ts b/frontend/src/store/data-tool.ts new file mode 100644 index 00000000..483b0c45 --- /dev/null +++ b/frontend/src/store/data-tool.ts @@ -0,0 +1,3 @@ +import { atom } from 'jotai'; + +export const sidebarAtom = atom(true); diff --git a/frontend/src/styles/globals.css b/frontend/src/styles/globals.css index e2c47656..4e762d99 100644 --- a/frontend/src/styles/globals.css +++ b/frontend/src/styles/globals.css @@ -5,6 +5,9 @@ .mapboxgl-ctrl-bottom-right { @apply !right-[335px]; } +.mapboxgl-ctrl-bottom-left { + @apply !right-[345px] !bottom-5 !left-auto; +} .mapboxgl-ctrl-attrib-button { @apply !p-0; diff --git a/frontend/yarn.lock b/frontend/yarn.lock index eccec83b..c1e7daf1 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -9772,14 +9772,14 @@ __metadata: languageName: node linkType: hard -"next-usequerystate@npm:1.8.4": - version: 1.8.4 - resolution: "next-usequerystate@npm:1.8.4" +"next-usequerystate@npm:1.9.2": + version: 1.9.2 + resolution: "next-usequerystate@npm:1.9.2" dependencies: mitt: ^3.0.1 peerDependencies: - next: ^13.4 - checksum: 4ab19aa11fd32058246375bdcd7c76fdff357e15a460e80a30835b972b7458ab99e59e8ae38be26b32d27727b156b655c2a0105c200b994408fb26366133b496 + next: ^13.4 || ^14 + checksum: ffc858c49d9c814526c446330e0f2db085175fcf4ead032ce2401757a96ea2e206bda2b7252711af83548c4d6c7400b3a966a2ffc856cd8abb42d5eb5789f893 languageName: node linkType: hard @@ -11695,7 +11695,7 @@ __metadata: lucide-react: ^0.274.0 mapbox-gl: 2.15.0 next: 13.5.6 - next-usequerystate: 1.8.4 + next-usequerystate: 1.9.2 orval: 6.18.1 postcss: 8.4.21 prettier: 2.8.3