diff --git a/src/components/ConfigurationsDrawer/MapBuilderTab/MapBuilderTab.tsx b/src/components/ConfigurationsDrawer/MapBuilderTab/MapBuilderTab.tsx index e74887e..47b84a2 100644 --- a/src/components/ConfigurationsDrawer/MapBuilderTab/MapBuilderTab.tsx +++ b/src/components/ConfigurationsDrawer/MapBuilderTab/MapBuilderTab.tsx @@ -9,17 +9,19 @@ import { FormLabel, Switch, } from '@mui/material'; -import { useContext, useState } from 'react'; +import { useContext, useEffect, useState } from 'react'; import { CGPVContext } from '@/providers/cgpvContextProvider/CGPVContextProvider'; import _ from 'lodash'; import PillsAutoComplete from '../../PillsAutoComplete'; import { componentsOptions, footerTabslist, navBarOptions, appBarOptions, mapInteractionOptions, mapProjectionOptions, zoomOptions, themeOptions, CONFIG_FILES_LIST, corePackagesOptions } from '@/constants'; import SingleSelectComplete from '../../SingleSelectAutoComplete'; import { ConfigSaveUploadButtons } from '../../ConfigSaveUploadButtons'; +import { useSearchParams } from "react-router-dom"; export function MapBuilderTab() { const cgpvContext = useContext(CGPVContext); + const [searchParams, setSearchParams] = useSearchParams(); if (!cgpvContext) { throw new Error('CGPVContent must be used within a CGPVProvider'); @@ -30,6 +32,17 @@ export function MapBuilderTab() { const [modifiedConfigJson, setModifiedConfigJson] = useState(configJson); const [isModified, setIsModified] = useState(false); + useEffect(() => { + const config = searchParams.get('config'); + if (config) { + handleConfigFileChange(config); + } + }, [searchParams]); // eslint-disable-line react-hooks/exhaustive-deps + + const onConfigFileChanged = (value: string) => { + setSearchParams({ config: value }); + } + const _updateConfigProperty = (property: string, value: any) => { const newConfig = { ...modifiedConfigJson }; if (value === undefined) { @@ -100,7 +113,7 @@ export function MapBuilderTab() { options={CONFIG_FILES_LIST} value={configFilePath} applyGrouping={true} - onChange={(value) => handleConfigFileChange(value)} + onChange={(value) => onConfigFileChanged(value)} label="Select Configuration File" placeholder="" /> { if (!isInitialized) { - initializeMap('sandboxMap3', config, configIsFilePath); + console.log('iitializing*************************'); + initializeMap(config, configIsFilePath); } }, []); // eslint-disable-line react-hooks/exhaustive-deps diff --git a/src/components/MapRenderer.tsx b/src/components/MapRenderer.tsx index 604432e..e20c995 100644 --- a/src/components/MapRenderer.tsx +++ b/src/components/MapRenderer.tsx @@ -1,6 +1,6 @@ import { Box } from '@mui/material'; import { CGPVContext } from '../providers/cgpvContextProvider/CGPVContextProvider'; -import { useContext } from 'react'; +import { useContext, useEffect, useRef } from 'react'; //TODO Maybe update this to control its own rendering on some feature changes. Eg. height, width, etc. export function MapRenderer() { @@ -10,8 +10,26 @@ export function MapRenderer() { throw new Error('CGPVContent must be used within a CGPVProvider'); } + const { mapId } = cgpvContext; + const mapContainerRef = useRef(null); + + useEffect(() => { + renderMapElem(); + }, [mapId]); + + //removes all child elements from the map container and creates a new map element + const renderMapElem = () => { + if (mapContainerRef.current) { + mapContainerRef.current.innerHTML = ''; + const mapElem = document.createElement('div'); + mapElem.id = mapId; + mapElem.className = 'geoview-map'; + mapContainerRef.current.appendChild(mapElem); + } + } + return ( - + ); diff --git a/src/providers/cgpvContextProvider/cgpvHook.ts b/src/providers/cgpvContextProvider/cgpvHook.ts index 6e9a21e..75f078e 100644 --- a/src/providers/cgpvContextProvider/cgpvHook.ts +++ b/src/providers/cgpvContextProvider/cgpvHook.ts @@ -22,8 +22,7 @@ export interface ICgpvHook { eventsList: EventListItemType[]; legendLayerStatusList: LegendLayerStatus[]; - initializeMap: (mapId: string, config: string | object, configIsFilePath?: boolean) => void; - handleRemoveMap: () => string; + initializeMap: (config: string | object, configIsFilePath?: boolean) => void; handleConfigFileChange: (filePath: string | null) => void; handleConfigJsonChange: (data: any) => void; handleApplyWidthHeight: (val: boolean) => void; @@ -168,114 +167,79 @@ export function useCgpvHook(): ICgpvHook { return res.json(); } - const initializeMap = (mapId: string, config: string | object, configIsFilePath = false) => { + const initializeMap = (config: string | object, configIsFilePath = false) => { if (isInitialized) return; - setIsLoading(true); - if (configIsFilePath) { - readConfigFile(config as string).then((data) => { - console.log('i fetch a file ', data); - initializeMap(mapId, data); - }); - } else { - setIsInitialized(true); - const configJson = typeof config === 'string' ? JSON.parse(config) : config; - handleCreateMap(mapId, configJson); - cgpv.init(() => { - // write some code ... - registerEventListeners(mapId); - setIsLoading(false); - }); - } - }; - - - const handleConfigFileChange = async (filePath: string | null) => { - if (!filePath) return; - readConfigFile(filePath).then((data) => { - setEventsList([]); - setLegendLayerStatusList([]); - handleConfigJsonChange(data); - setConfigFilePath(filePath); - }); + setIsInitialized(true); + createNewMap(config, configIsFilePath); }; //removes map and creates a new map - const handleRemoveMap = (): string => { + const createNewMap = (config: string | object, configIsFilePath = false) => { + console.log('renderNewMap', mapId, config, configIsFilePath); cgpv.api.maps[mapId]?.remove(true); - const newMapId = 'sandboxMap_' + uuidv4(); - // replace div with id 'sandboxMap' with another div - const mapContainerDiv = document.getElementById('sandboxMapContainer'); - const newDiv = document.createElement('div'); - newDiv.id = newMapId; - newDiv.className = 'geoview-map2'; - mapContainerDiv?.appendChild(newDiv); setMapId(newMapId); - - return newMapId; + + setTimeout(() => { + renderNewMap(newMapId, config, configIsFilePath); + }, 500); }; + const renderNewMap = async (mapId: string, config: string | object, configIsFilePath = false) => { + setEventsList([]); + setLegendLayerStatusList([]); + + const mapElement = document.getElementById(mapId); + if (!mapElement) { + return; + //throw new Error(`Element with id ${mapId} not found`); + } - const handleCreateMap = (theMapId: string, data: any) => { - const mapDiv = document.getElementById(theMapId); if (applyWidthHeight) { - mapDiv?.setAttribute('style', `width: ${mapWidth}px; height: ${mapHeight}px;`); + mapElement?.setAttribute('style', `width: ${mapWidth}px; height: ${mapHeight}px;`); + } + + let configTxt = config; + if(typeof config !== 'string' && !configIsFilePath) { + configTxt = JSON.stringify(config); + } + + if(configIsFilePath) { + setConfigFilePath(config as string); + const res = await readConfigFile(config as string); + configTxt = JSON.stringify(res) } - cgpv.api.createMapFromConfig(theMapId, JSON.stringify(data)); + //we have json; now lets start + setIsLoading(true); + + cgpv.api.createMapFromConfig(mapId, configTxt); cgpv.init(() => { - // write some code ... - console.log('map created----------------------------------------'); - registerEventListeners(theMapId); + registerEventListeners(mapId); + const configJson = JSON.parse(configTxt as string); + setConfigJson({ ...configJson }); + setTimeout(() => { // just a delay for animation purposes + setIsLoading(false); + }, 1500); }); - setConfigJson({ ...data }); - setMapId(theMapId); - setTimeout(() => { - setIsLoading(false); - }, 1500); }; - //deletes old map and creates a new map - const reCreateMap = () => { - const newMapId = handleRemoveMap(); - setTimeout(() => { - //waiting for states that were prior to this function to update - const mapDiv = document.getElementById(newMapId); - if (applyWidthHeight) { - mapDiv?.setAttribute('style', `width: ${mapWidth}px; height: ${mapHeight}px;`); - } - cgpv.api.createMapFromConfig(newMapId, JSON.stringify(configJson)); - }, 500); - setMapId(newMapId); + const handleConfigFileChange = async (filePath: string | null) => { + if (!filePath) return; + createNewMap(filePath, true); }; const handleApplyWidthHeight = (val: boolean) => { setApplyWidthHeight(val); - reCreateMap(); + createNewMap(configJson); } - /* - const onHeightChange = (newHeight: number) => { - setMapHeight(newHeight); - reCreateMap(); - }; - - const onWidthChange = (newWidth: number) => { - setMapWidth(newWidth); - reCreateMap(); - };*/ //when config settings changes recreate map const handleConfigJsonChange = (data: any) => { // pre-select theme and projection from config file - setIsLoading(true); - - const newMapId = handleRemoveMap(); - setTimeout(() => { - // create map - handleCreateMap(newMapId, data); - }, 1500); + createNewMap(data); }; const validateConfigJson = (json: string): string | null => { @@ -291,7 +255,7 @@ export function useCgpvHook(): ICgpvHook { const createMapFromConfigText = (configText: string) => { const config = JSON.parse(configText); - handleConfigJsonChange(config); + createNewMap(config); }; const updateConfigProperty = (property: string, value: any) => { @@ -302,12 +266,12 @@ export function useCgpvHook(): ICgpvHook { } else { _.set(newConfig, property, value); } - handleConfigJsonChange(newConfig); + createNewMap(newConfig); }; const handleApplyStateToConfigFile = () => { const state = cgpv.api.maps[mapId].createMapConfigFromMapState(); - handleConfigJsonChange(state); + createNewMap(state); } return { @@ -325,7 +289,6 @@ export function useCgpvHook(): ICgpvHook { legendLayerStatusList, initializeMap, - handleRemoveMap, handleConfigFileChange, handleConfigJsonChange, validateConfigJson,