From d235c79c47687653c6ef0581ee8ec48f80b77ba4 Mon Sep 17 00:00:00 2001 From: ndittren <36773036+ndittren@users.noreply.github.com> Date: Mon, 2 Feb 2026 15:08:46 -0500 Subject: [PATCH] Update to React 18 --- media/src/activity.tsx | 13 +- media/src/activity/activity-map.tsx | 55 ++++---- .../project-activity-components/common.tsx | 3 +- media/src/project.tsx | 13 +- media/src/project/project-map.tsx | 53 ++++---- media/src/utils.ts | 21 +++- package-lock.json | 117 ++++++++---------- package.json | 8 +- 8 files changed, 152 insertions(+), 131 deletions(-) diff --git a/media/src/activity.tsx b/media/src/activity.tsx index 0486a2824..89ac6f8a1 100644 --- a/media/src/activity.tsx +++ b/media/src/activity.tsx @@ -1,10 +1,11 @@ import React from 'react'; -import ReactDOM from 'react-dom'; +import { createRoot } from 'react-dom/client'; import { ActivityMap } from './activity/activity-map'; -ReactDOM.render( - +const container = document.getElementById('activity-map-container'); +if (container) { + const root = createRoot(container); + root.render( - , - document.getElementById('activity-map-container') -); + ); +} diff --git a/media/src/activity/activity-map.tsx b/media/src/activity/activity-map.tsx index cf4dc491d..365f8bf0d 100644 --- a/media/src/activity/activity-map.tsx +++ b/media/src/activity/activity-map.tsx @@ -1,14 +1,21 @@ +/* eslint-disable @typescript-eslint/no-unsafe-assignment */ +/* eslint-disable @typescript-eslint/no-unsafe-member-access */ +/* eslint-disable @typescript-eslint/no-unsafe-return */ +/* eslint-disable @typescript-eslint/no-unsafe-argument */ +/* eslint-disable @typescript-eslint/no-explicit-any */ import React, { useState, useEffect, useRef, useCallback } from 'react'; import { _MapContext as MapContext, StaticMap, NavigationControl, Popup, MapRef } from 'react-map-gl'; import 'mapbox-gl/dist/mapbox-gl.css'; // Deck.gl -import DeckGL, { Controller, FlyToInterpolator } from 'deck.gl'; +import DeckGL, { FlyToInterpolator } from 'deck.gl'; import { BitmapLayer, IconLayer, IconLayerProps } from '@deck.gl/layers'; import { TileLayer } from '@deck.gl/geo-layers'; -import { Position } from '@deck.gl/core/utils/positions'; -import { PickInfo } from '@deck.gl/core/lib/deck'; +// import { PickInfo } from 'deck.gl'; +type Position = [number, number] | [number, number, number]; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +type PickInfo = any; import { ActivityMapPane } from './activity-map-pane'; import { LoadingModal } from '../project-activity-components/loading-modal'; @@ -59,7 +66,7 @@ export const ActivityMap: React.FC = () => { const [projectData, setProjectData] = useState(null); const [responseData, setResponseData] = useState([]); - const deckglMap = useRef(null); + const deckglMap = useRef(null); const mapPane = useRef(null); const navControlStyle= { @@ -189,7 +196,7 @@ export const ActivityMap: React.FC = () => { const updateActivity = (instructions: string, pk: number): void => { const data = { - project: projectPk, + project: projectPk ? parseInt(projectPk, 10) : undefined, instructions: instructions }; void put(`/api/activity/${pk}/`, data) @@ -574,7 +581,7 @@ export const ActivityMap: React.FC = () => { //Close Popup if there is a click after search setShowSearchPopup(false); // Cast to provide type def for coordinate - const infoPrime = info as PickInfo & {coordinate: [number, number]}; + const infoPrime = info; // Create on single click, make sure that new event // is not created when user intends to pick an existing event @@ -663,7 +670,7 @@ export const ActivityMap: React.FC = () => { return activeEventDetail && d.pk == activeEventDetail.pk ? ICON_SIZE_ACTIVE : ICON_SIZE; }, getColor: () => { - return layer.color ? ICON_COLOR[layer.color] : ICON_COLOR_DEFAULT; }, + return (layer.color ? ICON_COLOR[layer.color] : ICON_COLOR_DEFAULT) as any; }, visible: layerVisibility.get(layer.pk) || false }); return acc.concat(MBLayer); @@ -682,7 +689,7 @@ export const ActivityMap: React.FC = () => { sizeScale: ICON_SCALE, getPosition: (d) => d.lngLat, getSize: ICON_SIZE, - getColor: ICON_COLOR_ACTIVE, + getColor: ICON_COLOR_ACTIVE as any, })); } const handleViewportChange = useCallback( @@ -691,7 +698,7 @@ export const ActivityMap: React.FC = () => { [] ); const handleGeocoderViewportChange = useCallback( - (newViewport) => { + (newViewport: any) => { const geocoderDefaultOverrides = { transitionDuration: 1000 }; // eslint-disable-next-line @typescript-eslint/no-unsafe-argument @@ -910,7 +917,8 @@ export const ActivityMap: React.FC = () => { getPosition: (d) => d.location.lng_lat, onClick: pickEventClickHandler, getSize: ICON_SIZE, - getColor: ICON_COLOR[layer.color], + getColor: (layer.color ? + ICON_COLOR[layer.color] : ICON_COLOR_DEFAULT) as any, }) ); } @@ -986,19 +994,19 @@ export const ActivityMap: React.FC = () => { for (const layer of projData.raster_layers) { rLayers.push(new TileLayer({ data: layer.url, - renderSubLayers: (obj: TileSublayerProps) => { + renderSubLayers: ((obj: TileSublayerProps) => { const { bbox: {west, south, east, north} } = obj.tile; - return new BitmapLayer({ + return new BitmapLayer(({ id: obj.id, image: obj.data, bounds: [west, south, east, north], desaturate: 0, transparentColor: [0, 0, 0, 0], tintColor: [255, 255, 255] - }); - } + }) as any); + }) as any })); } setRasterLayers(rLayers); @@ -1038,7 +1046,8 @@ export const ActivityMap: React.FC = () => { getPosition: (d) => d.location.lng_lat, onClick: pickEventClickHandler, getSize: ICON_SIZE, - getColor: ICON_COLOR[layer.color], + getColor: (layer.color ? + ICON_COLOR[layer.color] : ICON_COLOR_DEFAULT) as any, }) ); } @@ -1114,6 +1123,10 @@ export const ActivityMap: React.FC = () => { void getData().finally(() => {setIsDataLoading(false);}); }, []); + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const DeckGLAny = DeckGL as any; + return ( <> {(isMapLoading || isDataLoading) && } @@ -1127,20 +1140,20 @@ export const ActivityMap: React.FC = () => { ref={geocoderContainerRef} style={{ position: 'absolute', top: 20, right: 20, zIndex: 1 }} /> - setViewportState(e.viewState)} // eslint-disable-line @typescript-eslint/no-unsafe-argument, max-len + onViewStateChange={(e: any) => setViewportState(e.viewState)} // eslint-disable-line @typescript-eslint/no-unsafe-argument, max-len width={'100%'} height={'100%'} - controller={{doubleClickZoom: false} as {doubleClickZoom: boolean} & Controller} // eslint-disable-line max-len - onClick={handleDeckGlClick} + controller={{doubleClickZoom: false} as any} // eslint-disable-line max-len + onClick={handleDeckGlClick as any} pickingRadius={15} - ContextProvider={MapContext.Provider}> + ContextProvider={MapContext.Provider as any}> {
-
+ )} {projectData && ( diff --git a/media/src/project-activity-components/common.tsx b/media/src/project-activity-components/common.tsx index 35b81bd80..5fa72a725 100644 --- a/media/src/project-activity-components/common.tsx +++ b/media/src/project-activity-components/common.tsx @@ -1,6 +1,7 @@ /* A place to set shared settings */ import { FlyToInterpolator } from 'deck.gl'; -import { Position } from '@deck.gl/core/utils/positions'; +// import { Position } from '@deck.gl/core/utils/positions'; +export type Position = [number, number] | [number, number, number]; export const STATIC_URL = LocusTempus.staticUrl; export const ICON_ATLAS = STATIC_URL + 'img/icon-map-marker.png'; diff --git a/media/src/project.tsx b/media/src/project.tsx index 5a69e7c1c..733a6634d 100644 --- a/media/src/project.tsx +++ b/media/src/project.tsx @@ -1,10 +1,11 @@ import React from 'react'; -import ReactDOM from 'react-dom'; +import { createRoot } from 'react-dom/client'; import { ProjectMap } from './project/project-map'; -ReactDOM.render( - +const container = document.getElementById('project-map-container'); +if (container) { + const root = createRoot(container); + root.render( - , - document.getElementById('project-map-container') -); + ); +} diff --git a/media/src/project/project-map.tsx b/media/src/project/project-map.tsx index 713ef74bc..2f97a6364 100644 --- a/media/src/project/project-map.tsx +++ b/media/src/project/project-map.tsx @@ -1,14 +1,21 @@ +/* eslint-disable @typescript-eslint/no-unsafe-assignment */ +/* eslint-disable @typescript-eslint/no-unsafe-member-access */ +/* eslint-disable @typescript-eslint/no-unsafe-return */ +/* eslint-disable @typescript-eslint/no-unsafe-argument */ +/* eslint-disable @typescript-eslint/no-explicit-any */ import React, { useState, useEffect, useRef, useCallback } from 'react'; import { _MapContext as MapContext, StaticMap, NavigationControl, Popup, MapRef } from 'react-map-gl'; import 'mapbox-gl/dist/mapbox-gl.css'; // Deck.gl -import DeckGL, { Controller, FlyToInterpolator } from 'deck.gl'; +import DeckGL, { FlyToInterpolator } from 'deck.gl'; import { BitmapLayer, IconLayer } from '@deck.gl/layers'; import { TileLayer } from '@deck.gl/geo-layers'; -import { Position } from '@deck.gl/core/utils/positions'; -import { PickInfo } from '@deck.gl/core/lib/deck'; +// import { PickInfo } from 'deck.gl'; +type Position = [number, number] | [number, number, number]; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +type PickInfo = any; import { ProjectMapPane } from './project-map-pane'; import { LoadingModal } from '../project-activity-components/loading-modal'; @@ -40,7 +47,7 @@ export const ProjectMap: React.FC = () => { const pathList = window.location.pathname.split('/'); const projectPk = pathList[pathList.length - 2]; const coursePk = pathList[pathList.length - 4]; - const deckglMap = useRef(null); + const deckglMap = useRef(null); const mapPane = useRef(null); const [isNewProject, setIsNewProject] = useState(newProjectFlag); const [projectData, setProjectData] = useState(null); @@ -329,7 +336,7 @@ export const ProjectMap: React.FC = () => { return; } const data = { - project: projectPk, + project: parseInt(projectPk, 10), instructions: instructions }; void post('/api/activity/', data) @@ -341,7 +348,7 @@ export const ProjectMap: React.FC = () => { const updateActivity = (instructions: string, pk: number): void => { const data = { - project: projectPk, + project: parseInt(projectPk, 10), instructions: instructions }; void put(`/api/activity/${pk}/`, data) @@ -368,7 +375,7 @@ export const ProjectMap: React.FC = () => { //Close Popup if there is a click after search setShowSearchPopup(false); // Cast to provide type def for coordinate - const infoPrime = info as PickInfo & {coordinate: [number, number]}; + const infoPrime = info; // Create on single click, make sure that new event // is not created when user intends to pick an existing event @@ -445,7 +452,7 @@ export const ProjectMap: React.FC = () => { return activeEventDetail && d.pk == activeEventDetail.pk ? ICON_SIZE_ACTIVE : ICON_SIZE; }, getColor: () => { - return layer.color ? ICON_COLOR[layer.color] : ICON_COLOR_DEFAULT; }, + return (layer.color ? ICON_COLOR[layer.color] : ICON_COLOR_DEFAULT) as any; }, visible: layerVisibility.get(layer.pk) || false }); return acc.concat(MBLayer); @@ -464,17 +471,17 @@ export const ProjectMap: React.FC = () => { sizeScale: ICON_SCALE, getPosition: (d) => d.lngLat, getSize: ICON_SIZE_ACTIVE, - getColor: ICON_COLOR_ACTIVE, + getColor: ICON_COLOR_ACTIVE as any, })); } const handleViewportChange = useCallback( // eslint-disable-next-line @typescript-eslint/no-unsafe-argument - (newViewport: React.SetStateAction) => setViewportState(newViewport), + (newViewport: any) => setViewportState(newViewport), [] ); const handleGeocoderViewportChange = useCallback( - (newViewport) => { + (newViewport: any) => { const geocoderDefaultOverrides = { transitionDuration: 1000 }; // eslint-disable-next-line @typescript-eslint/no-unsafe-argument @@ -533,19 +540,19 @@ export const ProjectMap: React.FC = () => { for (const layer of projData.raster_layers) { rLayers.push(new TileLayer({ data: layer.url, - renderSubLayers: (obj: TileSublayerProps) => { + renderSubLayers: ((obj: TileSublayerProps) => { const { bbox: {west, south, east, north} } = obj.tile; - return new BitmapLayer({ + return new BitmapLayer(({ id: obj.id, image: obj.data, bounds: [west, south, east, north], desaturate: 0, transparentColor: [0, 0, 0, 0], tintColor: [255, 255, 255] - }); - } + }) as any); + }) as any })); } setRasterLayers(rLayers); @@ -559,6 +566,10 @@ export const ProjectMap: React.FC = () => { void getData().finally(() => {setIsDataLoading(false);}); }, []); + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const DeckGLAny = DeckGL as any; + return ( <> {(isMapLoading || isDataLoading) && } @@ -568,20 +579,20 @@ export const ProjectMap: React.FC = () => { ref={geocoderContainerRef} style={{ position: 'absolute', top: 20, right: 20, zIndex: 1 }} /> - setViewportState(e.viewState)} // eslint-disable-line @typescript-eslint/no-unsafe-argument, max-len + onViewStateChange={(e: any) => setViewportState(e.viewState)} // eslint-disable-line @typescript-eslint/no-unsafe-argument, max-len width={'100%'} height={'100%'} - controller={{doubleClickZoom: false} as {doubleClickZoom: boolean} & Controller} // eslint-disable-line max-len - onClick={handleDeckGlClick} + controller={{doubleClickZoom: false} as any} // eslint-disable-line max-len + onClick={handleDeckGlClick as any} pickingRadius={15} ref={deckglMap} - ContextProvider={MapContext.Provider}> + ContextProvider={MapContext.Provider as any}> {
-
+ )} {projectData && ( diff --git a/media/src/utils.ts b/media/src/utils.ts index 59da460cf..539d69bf6 100644 --- a/media/src/utils.ts +++ b/media/src/utils.ts @@ -1,7 +1,7 @@ -import DeckGL from 'deck.gl'; +// import DeckGL from 'deck.gl'; import { RefObject } from 'react'; import { WebMercatorViewport } from 'react-map-gl'; -import { LayerData } from './project-activity-components/common'; +import { LayerData, DEFAULT_VIEWPORT_STATE } from './project-activity-components/common'; import moment from 'moment'; type HTTPMethod = 'GET' | 'PUT' | 'POST' | 'DELETE' @@ -66,7 +66,7 @@ export async function del(url: string): Promise { export const getBoundedViewport = ( layers: LayerData[], - deckGlRef: RefObject, + deckGlRef: RefObject<{ deck: { width: number, height: number } }>, mapPaneRef: RefObject): WebMercatorViewport => { // Returns a viewport object configured to include all event markers @@ -92,13 +92,22 @@ export const getBoundedViewport = ( } if (deckGlRef.current !== null) { + const width = deckGlRef.current.deck.width || 800; // Fallback to avoid crash + const height = deckGlRef.current.deck.height || 600; + const viewportOpt = { - width: deckGlRef.current.deck.width, - height: deckGlRef.current.deck.height + width, + height }; + if (width <= 0 || height <= 0) { + console.warn('Invalid dimensions for viewport, skipping fitBounds', width, height); + return new WebMercatorViewport({width: 800, height: 600, ...DEFAULT_VIEWPORT_STATE}); + } + + const padding = 50; - // The left padding is contingent on if the map pane is visible or isn't. + // The left padding depends on whether the map pane is visible. // First, assume that the map pane is visible. It doesn't get rendered until // after this component is rendered. let leftPaddingOffset = 512; // Trust me, the pane is 512px wide diff --git a/package-lock.json b/package-lock.json index c5aa001c6..68009829a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,8 +15,8 @@ "@fortawesome/react-fontawesome": "^0.2.0", "@types/jest": "^30.0.0", "@types/node": "^24.0.0", - "@types/react": "^17.0.39", - "@types/react-dom": "^18.0.0", + "@types/react": "^18.3.3", + "@types/react-dom": "^18.3.0", "@types/react-map-gl": "^6.1.3", "bootstrap": "^4.5.0", "deck.gl": "^9.0.1", @@ -28,8 +28,8 @@ "postcss": "^8.1.2", "precss": "^4.0.0", "quill-paste-smart": "^2.0.0", - "react": "~17.0.2", - "react-dom": "~17.0.2", + "react": "^18.3.1", + "react-dom": "^18.3.1", "react-map-gl": "~6.1.19", "react-map-gl-geocoder": "~2.2.0", "react-quill": "^2.0.0", @@ -4531,21 +4531,22 @@ } }, "node_modules/@types/react": { - "version": "17.0.55", - "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.55.tgz", - "integrity": "sha512-kBcAhmT8RivFDYxHdy8QfPKu+WyfiiGjdPb9pIRtd6tj05j0zRHq5DBGW5Ogxv5cwSKd93BVgUk/HZ4I9p3zNg==", + "version": "18.3.27", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.27.tgz", + "integrity": "sha512-cisd7gxkzjBKU2GgdYrTdtQx1SORymWyaAFhaxQPK9bYO9ot3Y5OikQRvY0VYQtvwjeQnizCINJAenh/V7MK2w==", + "license": "MIT", "dependencies": { "@types/prop-types": "*", - "@types/scheduler": "*", - "csstype": "^3.0.2" + "csstype": "^3.2.2" } }, "node_modules/@types/react-dom": { - "version": "18.0.0", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.0.0.tgz", - "integrity": "sha512-49897Y0UiCGmxZqpC8Blrf6meL8QUla6eb+BBhn69dTXlmuOlzkfr7HHY/O8J25e1lTUMs+YYxSlVDAaGHCOLg==", - "dependencies": { - "@types/react": "*" + "version": "18.3.7", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.7.tgz", + "integrity": "sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==", + "license": "MIT", + "peerDependencies": { + "@types/react": "^18.0.0" } }, "node_modules/@types/react-map-gl": { @@ -4559,11 +4560,6 @@ "@types/viewport-mercator-project": "*" } }, - "node_modules/@types/scheduler": { - "version": "0.16.2", - "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", - "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==" - }, "node_modules/@types/sinonjs__fake-timers": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.1.tgz", @@ -17829,28 +17825,28 @@ } }, "node_modules/react": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", - "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", + "license": "MIT", "dependencies": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" + "loose-envify": "^1.1.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/react-dom": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz", - "integrity": "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", + "license": "MIT", "dependencies": { "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "scheduler": "^0.20.2" + "scheduler": "^0.23.2" }, "peerDependencies": { - "react": "17.0.2" + "react": "^18.3.1" } }, "node_modules/react-is": { @@ -18557,12 +18553,12 @@ } }, "node_modules/scheduler": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", - "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==", + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", + "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", + "license": "MIT", "dependencies": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" + "loose-envify": "^1.1.0" } }, "node_modules/schema-utils": { @@ -23864,22 +23860,19 @@ } }, "@types/react": { - "version": "17.0.55", - "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.55.tgz", - "integrity": "sha512-kBcAhmT8RivFDYxHdy8QfPKu+WyfiiGjdPb9pIRtd6tj05j0zRHq5DBGW5Ogxv5cwSKd93BVgUk/HZ4I9p3zNg==", + "version": "18.3.27", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.27.tgz", + "integrity": "sha512-cisd7gxkzjBKU2GgdYrTdtQx1SORymWyaAFhaxQPK9bYO9ot3Y5OikQRvY0VYQtvwjeQnizCINJAenh/V7MK2w==", "requires": { "@types/prop-types": "*", - "@types/scheduler": "*", - "csstype": "^3.0.2" + "csstype": "^3.2.2" } }, "@types/react-dom": { - "version": "18.0.0", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.0.0.tgz", - "integrity": "sha512-49897Y0UiCGmxZqpC8Blrf6meL8QUla6eb+BBhn69dTXlmuOlzkfr7HHY/O8J25e1lTUMs+YYxSlVDAaGHCOLg==", - "requires": { - "@types/react": "*" - } + "version": "18.3.7", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.7.tgz", + "integrity": "sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==", + "requires": {} }, "@types/react-map-gl": { "version": "6.1.3", @@ -23892,11 +23885,6 @@ "@types/viewport-mercator-project": "*" } }, - "@types/scheduler": { - "version": "0.16.2", - "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", - "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==" - }, "@types/sinonjs__fake-timers": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.1.tgz", @@ -33598,22 +33586,20 @@ } }, "react": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", - "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" + "loose-envify": "^1.1.0" } }, "react-dom": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz", - "integrity": "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", "requires": { "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "scheduler": "^0.20.2" + "scheduler": "^0.23.2" } }, "react-is": { @@ -34122,12 +34108,11 @@ "peer": true }, "scheduler": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", - "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==", + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", + "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" + "loose-envify": "^1.1.0" } }, "schema-utils": { diff --git a/package.json b/package.json index b5a97b214..150d3c73b 100644 --- a/package.json +++ b/package.json @@ -48,8 +48,8 @@ "@fortawesome/react-fontawesome": "^0.2.0", "@types/jest": "^30.0.0", "@types/node": "^24.0.0", - "@types/react": "^17.0.39", - "@types/react-dom": "^18.0.0", + "@types/react": "^18.3.3", + "@types/react-dom": "^18.3.0", "@types/react-map-gl": "^6.1.3", "bootstrap": "^4.5.0", "deck.gl": "^9.0.1", @@ -61,8 +61,8 @@ "postcss": "^8.1.2", "precss": "^4.0.0", "quill-paste-smart": "^2.0.0", - "react": "~17.0.2", - "react-dom": "~17.0.2", + "react": "^18.3.1", + "react-dom": "^18.3.1", "react-map-gl": "~6.1.19", "react-map-gl-geocoder": "~2.2.0", "react-quill": "^2.0.0",