For some reason this component is giving me infinite reloads when one function is called:
I have put the locations in bold comments where the errors might be occurring.
import React, { useState, useRef, useContext, useEffect } from 'react';
import { useQuery } from 'react-query';
import { Loading } from '../Elements/LoadingComponent';
import { Row, Col } from 'react-bootstrap';
import AddDesks from '../Elements/Layout/AddDesks';
import Status from '../Elements/Layout/Status';
import { Desk } from '../Elements/Layout/Desks';
import { SiteMapContext } from '../../App';
import {
Layout_Get_Sites,
Layout_Get_Desk_Types,
Layout_Undo_Change,
Layout_Redo_Change,
Layout_Clear_Desk,
Layout_Delete_Desk,
Layout_Update_Desklist,
Layout_Restore_All,
Layout_Update_Desk_Data,
Layout_Create_Desk,
Layout_Set_UserImage,
Layout_Update_Desk_Sizes
} from '../../network/Layout_Creator';
import '../../shared/styles/layout.css';
const LayoutMap = (props) => {
//const dispatch = useDispatch();
const mapRef = useRef();
const mapContainer = useRef();
const siteMap = useContext(SiteMapContext);
let roles = siteMap.siteMapData.user.roles;
const isAdmin = roles.indexOf('admin') + roles.indexOf('system') > 0
let siteCount = 0;
let mapsLoaded = false;
let mapScale = 0;
let currentMap = -1;
const [desks, setDesks] = useState({ past: [], present: [], future: [] });
const [currentDesk, setDesk] = useState(-1);
const [deskTypes, setDeskTypes] = useState(-1);
const [maps, setMaps] = useState({ maps: [] });
const [editMode, setEditMode] = useState(false);
const [deskComponents, setDeskComponents] = useState(null);
const { isLoading: areMapsLoading, refetch } = useQuery('LayoutMaps', () => Layout_Get_Sites(siteCount),
{
staleTime: Infinity,
refetchInterval: false,
refetchOnMount: false,
refetchOnReconnect: false,
refetchOnWindowFocus: false,
onSuccess: (data) => {
let map = data.maps;
if (map) {
let newMaps = [...maps.maps, map];
setMaps({ maps: newMaps })
siteCount = newMaps.length;
mapsLoaded = data.done;
}
if (!data.done) refetch();
},
})
useEffect(() => {
const loadDeskTypes = async () => {
let dt = await Layout_Get_Desk_Types();
setDeskTypes(dt);
}
loadDeskTypes();
}, [])
//called when location Select is used
const changeMap = target => {
console.log("Layout.changeMap");
setDesk(null);
const site = parseInt(target.value);
//layout_Set_Current_Site(site);
currentMap = site;
setEditMode(false);
//THIS IS WHERE THE INFINITE RELOAD LOOP STARTS
const desks = buildDesks();
setDeskComponents(desks);
}
const getScale = () => {
const site = maps.maps[currentMap] //the id on the select
if (!site) return;
let newMap = document.getElementById("floorMap");
let map = mapRef.current;
let mapWidth = map?.getBoundingClientRect()?.width;
let newMapWidth = newMap?.getBoundingClientRect()?.width;
let scale = (mapWidth && site?.wMM) ? (mapWidth / site.wMM) : 1;
mapScale = scale;
return scale;
}
const clickMap = () => {
setDesk(null);
}
const createDesk = async (newDesk) => {
//TODO: Modify to update data before database update
Layout_Create_Desk(newDesk)
.then(data => {
let newDesks = data.desks;
setDesks({ past: desks.present, present: newDesks, future: [] });
});
}
const updateDesk = (desk) => {
//TODO write fn to update the data for a desk and update database
}
const setUserImage = (file) => {
Layout_Set_UserImage(file, currentDesk)
}
const AddDesksFns = {
Update_Desklist: setDesks,
Create_Desk: createDesk
}
const StatusFns = {
Update_Desklist: setDesks,
Update_Desk_Data: updateDesk,
Set_UserImage: setUserImage,
Set_Current: setDesk
}
const buildMapOption = (site, index) => {
var ret = <option value={index} key={site.id}>{site.SiteName}</option>
return ret;
}
const buildMapSelector = () => {
var ret =
<select onChange={(e) => changeMap(e.target)} value={maps.current ?? -1}>
<option id='-1'>Select Site...</option>
{
maps.maps.map((site, index) => buildMapOption(site, index))
}
</select>
return ret;
}
//THIS IS AN EXTERNAL COMPONENT WHICH MAY BE RESPONSIBLE FOR INFINITE RELOADS
const buildDesk = (desk, scale) => {
const res = <Desk key={desk.id} desk={desk} scale={scale} deskTypes={deskTypes} currentDesk={currentDesk} fns={StatusFns} />
return res;
}
const buildDesks = () => {
try {
let scale = getScale();
let res = maps.maps[currentMap]?.desks.map(desk => buildDesk(desk, scale));
//RES IS AN ARRAY OF 61 DESK COMPONENTS
return res
} catch (error) {
console.error('Error building desks:', error);
return null;
}
};
return (
<div>
<Row>
<Col sm={1}>
{(isAdmin && !areMapsLoading) ?
<span style={{ 'whiteSpace': 'nowrap', 'backgroundColor': '#ccc' }}>
<label htmlFor='layoutEditSelect'>Edit</label>
<input id='layoutEditSelect' type='checkbox'
onClick={async (e) => { setEditMode(e.target.checked); }}
/>
</span>
: <span></span>
}
</Col>
<Col sm={10}>
{(editMode && currentDesk != null) ?
<div style={{ position: 'absolute', top: '100px', left: '300px' }}>
<Row>
<Col>Left</Col><Col>{Math.round(currentDesk.x)}</Col>
<Col>Height</Col><Col>{currentDesk.height}</Col>
</Row>
<Row>
<Col>Top</Col><Col>{Math.round(currentDesk.y)}</Col>
<Col>Width</Col><Col>{currentDesk.width}</Col>
</Row>
<Row>
<Col>Rotation</Col>
<Col>{currentDesk.rotation}°</Col>
</Row>
</div>
: ''
}
</Col>
</Row>
<Row>
<Col sm={1}>
<Row>
<Col>
{!areMapsLoading ?
buildMapSelector()
:
<Loading title="Map Data" />
}
</Col>
<Col>
<AddDesks
maps={maps}
deskTypes={deskTypes}
editMode={editMode}
scale={mapScale}
fns={AddDesksFns}
/>
</Col>
</Row>
</Col>
<Col sm={10} id="Layout_Map_Container" ref={mapContainer} >
{/* <BuildMap map={maps.maps[props.maps.current]} fns={props.MapFunctions} scale={props.scale} /> */}
{/*onClick={clickDesk}*/}
<div ref={mapContainer}
style={{ width: '100%', height: `${window.height}px`, position: 'relative' }}
onClick={()=>clickMap()}
onLoad={() => { getScale(); clickMap(); } /*If map is reset, set current desk to null*/}
className='map'
id="Layout_SiteMap_Img"
>
<img src={`data:image/jpeg;base64,${maps.maps[currentMap]?.SiteBackground ?? 'R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=='}`}
style={{ width: '100%', position: 'absolute' }}
alt={`Layout plan for ${maps.maps[currentMap]?.currentSite?.SiteName}`}
ref={mapRef}
id="floorMap"
/>
<React.Fragment id="desks">
{deskComponents}
</React.Fragment>
</div>
</Col>
</Row >
<Status desk={currentDesk} currentDesk={currentDesk} moveData={desks} />
</div>
)
}
export default LayoutMap;
I have been troubleshooting this for long enough that it is getting irritating.
I will provide CSV of desks and desktypes but they contain large strings for the images so prefer not to if possible.