diff --git a/.env b/.env
new file mode 100644
index 00000000..87c01f4e
--- /dev/null
+++ b/.env
@@ -0,0 +1,5 @@
+REACT_APP_SECURED="false"
+REACT_APP_TENANT="TENANT_ID"
+REACT_APP_DEFAULT_SCOPE="DEFAULT_SCOPE"
+REACT_APP_CLIENTID="CLIENT_ID"
+REACT_APP_AUTHORITY="AUTHORITY"
\ No newline at end of file
diff --git a/Dockerfile b/Dockerfile
index 674242c7..ccb3f74c 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,7 +1,7 @@
#Stage 1
-FROM node:18-alpine
-# Create app directory
-WORKDIR /app
+# FROM node:18-alpine
+# # Create app directory
+# WORKDIR /app
FROM nginx:1.25.0-alpine
WORKDIR /usr/share/nginx/html
RUN rm -rf ./*
diff --git a/package-lock.json b/package-lock.json
index 1ef0c98f..d8d8b9b6 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -25,13 +25,13 @@
"rc-menu": "^9.11.1",
"rc-slider": "^9.7.5",
"re-resizable": "^6.9.1",
- "react": "^17.0.2",
+ "react": "^18.2.0",
"react-collapsible": "^2.10.0",
"react-color": "^2.19.3",
"react-copy-to-clipboard": "^5.0.4",
"react-datepicker": "^4.16.0",
"react-device-detect": "^2.2.3",
- "react-dom": "^17.0.2",
+ "react-dom": "^18.2.0",
"react-ga4": "^2.0.0",
"react-highlight-words": "^0.20.0",
"react-icons": "^4.8.0",
@@ -3903,9 +3903,9 @@
}
},
"node_modules/@rc-component/trigger": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/@rc-component/trigger/-/trigger-2.0.0.tgz",
- "integrity": "sha512-niwKADPdY5dhdIblV6uwSayVivwo2uUISfJqri+/ovYQcH/omxDYBJKo755QKeoIIsWptxnRpgr7reEnNEZGFg==",
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/@rc-component/trigger/-/trigger-2.1.1.tgz",
+ "integrity": "sha512-UjHkedkgtEcgQu87w1VuWug1idoDJV7VUt0swxHXRcmei2uu1AuUzGBPEUlmOmXGJ+YtTgZfVLi7kuAUKoZTMA==",
"dependencies": {
"@babel/runtime": "^7.23.2",
"@rc-component/portal": "^1.1.0",
@@ -15372,12 +15372,11 @@
}
},
"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.2.0",
+ "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz",
+ "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==",
"dependencies": {
- "loose-envify": "^1.1.0",
- "object-assign": "^4.1.1"
+ "loose-envify": "^1.1.0"
},
"engines": {
"node": ">=0.10.0"
@@ -15562,16 +15561,15 @@
}
},
"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.2.0",
+ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz",
+ "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==",
"dependencies": {
"loose-envify": "^1.1.0",
- "object-assign": "^4.1.1",
- "scheduler": "^0.20.2"
+ "scheduler": "^0.23.0"
},
"peerDependencies": {
- "react": "17.0.2"
+ "react": "^18.2.0"
}
},
"node_modules/react-error-overlay": {
@@ -16534,12 +16532,11 @@
}
},
"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.0",
+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz",
+ "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==",
"dependencies": {
- "loose-envify": "^1.1.0",
- "object-assign": "^4.1.1"
+ "loose-envify": "^1.1.0"
}
},
"node_modules/schema-utils": {
diff --git a/package.json b/package.json
index 3b204cfd..eceeef0c 100644
--- a/package.json
+++ b/package.json
@@ -21,13 +21,13 @@
"rc-menu": "^9.11.1",
"rc-slider": "^9.7.5",
"re-resizable": "^6.9.1",
- "react": "^17.0.2",
+ "react": "^18.2.0",
"react-collapsible": "^2.10.0",
"react-color": "^2.19.3",
"react-copy-to-clipboard": "^5.0.4",
"react-datepicker": "^4.16.0",
"react-device-detect": "^2.2.3",
- "react-dom": "^17.0.2",
+ "react-dom": "^18.2.0",
"react-ga4": "^2.0.0",
"react-highlight-words": "^0.20.0",
"react-icons": "^4.8.0",
diff --git a/src/App.test.js b/src/App.test.js
index 635a333f..0d5b554a 100644
--- a/src/App.test.js
+++ b/src/App.test.js
@@ -1,9 +1,10 @@
import React from "react";
-import ReactDOM from "react-dom";
+import { createRoot } from "react-dom/client";
import App from "./App";
it("renders without crashing", () => {
- const div = document.createElement("div");
- ReactDOM.render(, div);
- ReactDOM.unmountComponentAtNode(div);
+ const div = document.createElement("div");
+ const root = createRoot(div); // createRoot(container!) if you use TypeScript
+ root.render();
+ root.unmount();
});
diff --git a/src/header/Header.jsx b/src/header/Header.jsx
index 9875d130..375c3a6d 100644
--- a/src/header/Header.jsx
+++ b/src/header/Header.jsx
@@ -1,5 +1,4 @@
import React, { useState, useEffect } from "react";
-import ReactDOM from "react-dom";
import "./Header.css";
import Search from "./Search.jsx";
import * as helpers from "../helpers/helpers";
@@ -50,7 +49,7 @@ const Header = (props) => {
);
- ReactDOM.render(menu, document.getElementById("portal-root"));
+ window.portalRoot.render(menu);
helpers.addAppStat("Header Dot Menu", "Click");
};
diff --git a/src/helpers/AttributeTable.jsx b/src/helpers/AttributeTable.jsx
index 10723d42..e07dbdfb 100644
--- a/src/helpers/AttributeTable.jsx
+++ b/src/helpers/AttributeTable.jsx
@@ -1,4 +1,4 @@
-import React, { Component } from "react";
+import React, { Component, useEffect } from "react";
import * as helpers from "./helpers";
import "./AttributeTable.css";
import { Resizable } from "re-resizable";
@@ -6,12 +6,12 @@ import AttributeTableTabs from "./AttributeTableTabs.jsx";
import FloatingMenu, { FloatingMenuItem } from "../helpers/FloatingMenu.jsx";
import { Item as MenuItem } from "rc-menu";
import Portal from "../helpers/Portal.jsx";
-import ReactDOM from "react-dom";
+import { createRoot } from "react-dom/client";
class AttrbuteTable extends Component {
constructor(props) {
super(props);
-
+ this.resizable = {};
this.numRecordsToPull = 200;
this.state = {
visible: false,
@@ -44,6 +44,7 @@ class AttrbuteTable extends Component {
resizeFromMap = () => {
const mapWidth = document.getElementById("map").offsetWidth;
+ if (!this.resizable) return;
this.resizable.updateSize({
width: mapWidth,
height: this.resizable.resizable.offsetHeight,
@@ -195,7 +196,21 @@ class AttrbuteTable extends Component {
);
- ReactDOM.render(menu, document.getElementById("portal-root"));
+ const uniqueId = `portal-root-${"attribute-table-header"}}`;
+ const element = document.createElement("div");
+ element.setAttribute("id", uniqueId);
+ document.getElementById("portal-root").appendChild(element);
+ const root = createRoot(document.getElementById(uniqueId));
+ const MenuWithCallback = () => {
+ useEffect(() => {
+ return () => {
+ root.unmount();
+ document.getElementById(uniqueId).remove();
+ };
+ }, []);
+ return menu;
+ };
+ root.render();
};
onRowClick = (evt, item, rowIndex) => {
@@ -217,7 +232,22 @@ class AttrbuteTable extends Component {
);
- ReactDOM.render(menu, document.getElementById("portal-root"));
+ const uniqueId = `portal-root-${"attribute-table-row"}`;
+ const element = document.createElement("div");
+ element.setAttribute("id", uniqueId);
+ document.getElementById("portal-root").appendChild(element);
+ const root = createRoot(document.getElementById(uniqueId));
+ const MenuWithCallback = () => {
+ useEffect(() => {
+ return () => {
+ root.unmount();
+ document.getElementById(uniqueId).remove();
+ };
+ }, []);
+ return menu;
+ };
+
+ root.render();
};
onRowMenuItemClick = (key, item, rowIndex) => {
diff --git a/src/helpers/FloatingMenu.jsx b/src/helpers/FloatingMenu.jsx
index 752ea046..ae4c123d 100644
--- a/src/helpers/FloatingMenu.jsx
+++ b/src/helpers/FloatingMenu.jsx
@@ -7,13 +7,16 @@ import { waitForLoad } from "./helpers";
// PROPER USE OF THIS COMPONENT IS TO USE A PORTAL. HAVE A LOOK AT MyMapsItem FOR AN EXAMPLE.
const FloatingMenu = (props) => {
+ let { positionX, positionY } = props;
+ if (positionX === undefined) positionX = props.buttonEvent.pageX;
+ if (positionY === undefined) positionY = props.buttonEvent.pageY;
const isMounted = useRef(false);
const [isVisible, setIsVisible] = useState(true);
const [style, setStyle] = useState({
position: "absolute",
zIndex: 10000,
- top: props.buttonEvent.pageY,
- left: props.buttonEvent.pageX,
+ top: positionY,
+ left: positionX,
backgroundColor: "white",
width: "180px",
});
@@ -36,7 +39,7 @@ const FloatingMenu = (props) => {
getStyle((newStyle) => {
setStyle(newStyle);
});
- }, [props.autoX, props.autoY, props.buttonEvent.pageX, props.buttonEvent.pageY, props.styleMode]);
+ }, [props.autoX, props.autoY, props.buttonEvent.pageX, props.buttonEvent.pageY, props.styleMode, props.positionX, props.positionY, props.yOffset, props.xOffset, props.width]);
const cleanup = () => {
document.body.removeEventListener("click", handleClickAway, true);
container.current = null;
@@ -89,17 +92,17 @@ const FloatingMenu = (props) => {
}
if (props.styleMode === "right") {
- xOffset = props.buttonEvent.pageX;
+ xOffset = positionX;
} else if (props.styleMode === "left") {
- xOffset = props.buttonEvent.pageX - 180;
+ xOffset = positionX - 180;
} else if (props.autoX) {
- if (props.buttonEvent.pageX < 180) {
- xOffset = props.buttonEvent.pageX;
+ if (positionX < 180) {
+ xOffset = positionX;
} else {
- xOffset = props.buttonEvent.pageX - 180;
+ xOffset = positionX - 180;
}
} else {
- xOffset = props.buttonEvent.pageX;
+ xOffset = positionX;
}
if (props.yOffset !== undefined) yOffset = props.yOffset;
@@ -108,7 +111,7 @@ const FloatingMenu = (props) => {
style = {
position: "absolute",
zIndex: 1000,
- top: props.buttonEvent.pageY - yOffset,
+ top: positionY - yOffset,
//left: this.state.styleMode === "right" ? this.props.buttonEvent.pageX : this.props.buttonEvent.pageX - 180,
left: xOffset,
backgroundColor: "white",
diff --git a/src/helpers/ModalWindowR.jsx b/src/helpers/ModalWindowR.jsx
index c54dfc06..801aa436 100644
--- a/src/helpers/ModalWindowR.jsx
+++ b/src/helpers/ModalWindowR.jsx
@@ -1,28 +1,25 @@
import React from "react";
-import ReactDOM from "react-dom";
import Modal from "react-responsive-modal";
export default class ModalWindowR extends React.Component {
- state = {
- open: this.props.open ? true : false,
- };
+ state = {
+ open: this.props.open ? true : false,
+ };
- onOpenModal = () => {
- this.setState({ open: true });
- };
+ onOpenModal = () => {
+ this.setState({ open: true });
+ };
- onCloseModal = () => {
- this.setState({ open: false });
- };
+ onCloseModal = () => {
+ this.setState({ open: false });
+ };
- render() {
- const { open } = this.state;
- return (
-
- Simple centered modal
-
- );
- }
+ render() {
+ const { open } = this.state;
+ return (
+
+ Simple centered modal
+
+ );
+ }
}
-
-//ReactDOM.render(, document.getElementById('root'));
diff --git a/src/helpers/Popup.jsx b/src/helpers/Popup.jsx
index bc8729ee..01e52b8b 100644
--- a/src/helpers/Popup.jsx
+++ b/src/helpers/Popup.jsx
@@ -1,6 +1,7 @@
// THIS CODE WAS PULLED FROM https://github.com/walkermatt/ol-popup
import React from "react";
-import ReactDOM from "react-dom";
+import { createRoot } from "react-dom/client";
+
import Overlay from "ol/Overlay";
import "./Popup.css";
import { getWidth } from "ol/extent.js";
@@ -67,7 +68,6 @@ export default class Popup extends Overlay {
this.contentNextButton.href = "#";
this.contentNextButtonContainer.appendChild(this.contentNextButton);
this.contentPrevButtonContainer.appendChild(this.contentPrevButton);
-
this.contentNextButton.addEventListener("click", () => {
this.contentIndex++;
if (this.contentIndex >= this.contentArray.length) {
@@ -84,16 +84,14 @@ export default class Popup extends Overlay {
this.contentNextButtonContainer.className = "sc-popup-content-next-button";
this.contentPrevButtonContainer.className = "sc-popup-content-prev-button";
}
-
this.headerTitle.innerHTML = this.contentArray[this.contentIndex].title || "Info";
- //ReactDOM.render(html, this.content);
if (isDOMTypeElement(this.contentArray[this.contentIndex].html)) {
// REGULAR HTML
this.content.innerHTML = "";
this.content.appendChild(this.contentArray[this.contentIndex].html);
} else {
// REACT COMPONENT
- ReactDOM.render(this.contentArray[this.contentIndex].html, this.content);
+ this.root.render(this.contentArray[this.contentIndex].html);
}
});
this.contentPrevButton.addEventListener("click", () => {
@@ -113,14 +111,13 @@ export default class Popup extends Overlay {
}
// SET TITLE
this.headerTitle.innerHTML = this.contentArray[this.contentIndex].title;
- //ReactDOM.render(html, this.content);
if (isDOMTypeElement(this.contentArray[this.contentIndex].html)) {
// REGULAR HTML
this.content.innerHTML = "";
this.content.appendChild(this.contentArray[this.contentIndex].html);
} else {
// REACT COMPONENT
- ReactDOM.render(this.contentArray[this.contentIndex].html, this.content);
+ this.root.render(this.contentArray[this.contentIndex].html);
}
});
this.headerCloseContainer = document.createElement("div");
@@ -162,6 +159,9 @@ export default class Popup extends Overlay {
this.content = document.createElement("div");
this.content.className = "ol-popup-content";
+ this.uniqueId = `sc-popup-content-${helpers.getUID()}}`;
+ this.content.setAttribute("id", this.uniqueId);
+ this.root = createRoot(this.content);
this.container.appendChild(this.content);
// Apply workaround to enable scrolling of content div on touch devices
@@ -225,14 +225,13 @@ export default class Popup extends Overlay {
// SET TITLE
this.headerTitle.innerHTML = title;
- //ReactDOM.render(html, this.content);
if (isDOMTypeElement(html)) {
// REGULAR HTML
this.content.innerHTML = "";
this.content.appendChild(html);
} else {
// REACT COMPONENT
- ReactDOM.render(html, this.content);
+ this.root.render(html);
}
this.container.style.display = "block";
diff --git a/src/helpers/ShowMessage.jsx b/src/helpers/ShowMessage.jsx
index 39997a21..cafb725b 100644
--- a/src/helpers/ShowMessage.jsx
+++ b/src/helpers/ShowMessage.jsx
@@ -27,6 +27,7 @@ class ShowMessage extends Component {
this._isMounted = false;
}
onCloseClick = (value) => {
+ if (this.props.onClose) this.props.onClose(value);
if (this._isMounted) this.setState({ hide: true });
};
diff --git a/src/helpers/helpers.js b/src/helpers/helpers.js
index a90683c0..baa2e699 100644
--- a/src/helpers/helpers.js
+++ b/src/helpers/helpers.js
@@ -1,6 +1,6 @@
// REACT
-import React from "react";
-import ReactDOM from "react-dom";
+import React, { useEffect } from "react";
+import { createRoot } from "react-dom/client";
// OPEN LAYERS
import Feature from "ol/Feature";
@@ -123,22 +123,58 @@ export function isMobile() {
// SHOW CONTENT WINDOW
export function showWindow(contents, options = { title: "Information", showFooter: false, mode: "normal", hideScroll: false }) {
- ReactDOM.render(
- ,
- document.getElementById("map-modal-window")
- );
+ const uniqueId = `map-modal-window-${getUID()}}`;
+ const element = document.createElement("div");
+ element.setAttribute("id", uniqueId);
+ document.getElementById("map-modal-window").appendChild(element);
+ const root = createRoot(document.getElementById(uniqueId));
+
+ const ShowWindowWithCallback = (props) => {
+ useEffect(() => {
+ return () => {
+ try {
+ root.unmount();
+ document.getElementById(uniqueId).remove();
+ } catch (err) {
+ console.log(err);
+ }
+ };
+ }, []);
+ return ;
+ };
+ root.render();
}
// SHOW URL WINDOW
export function showURLWindow(url, showFooter = false, mode = "normal", honorDontShow = false, hideScroll = false) {
let isSameOrigin = true;
+ const uniqueId = `map-modal-window-${getUID()}}`;
+ const element = document.createElement("div");
+ element.setAttribute("id", uniqueId);
+ document.getElementById("map-modal-window").appendChild(element);
+ const root = createRoot(document.getElementById(uniqueId));
+
+ const URLWindowWithCallback = (props) => {
+ useEffect(() => {
+ return () => {
+ try {
+ root.unmount();
+ document.getElementById(uniqueId).remove();
+ } catch (err) {
+ console.log(err);
+ }
+ };
+ }, []);
+ return ;
+ };
+
waitForLoad("settings", Date.now(), 30, () => {
if (window.config.restrictOriginForUrlWindow) {
if (url !== undefined) isSameOrigin = url.toLowerCase().indexOf(window.location.origin.toLowerCase()) !== -1;
}
if (isSameOrigin) {
- ReactDOM.render(, document.getElementById("map-modal-window"));
+ root.render();
} else {
window.open(url, "_blank");
}
@@ -414,7 +450,7 @@ export function showTerms(title = "Terms and Condition", messageText = "Message"
const domId = "portal-root";
const termsDomId = "sc-show-terms-root";
- ReactDOM.render(
+ window.portalRoot.render(
{
try {
- ReactDOM.unmountComponentAtNode(ref.current.parentNode);
+ window.portalRoot.unmount();
} catch (err) {
console.log(err);
}
}}
- />,
- document.getElementById("portal-root")
+ />
);
}
@@ -442,24 +477,42 @@ export function showMessage(title = "Info", messageText = "Message", color = mes
const domId = "sc-show-message-content";
var existingMsg = document.getElementById(domId);
if (existingMsg !== undefined && existingMsg !== null) existingMsg.remove();
- try {
- ReactDOM.unmountComponentAtNode(document.getElementById("sc-sidebar-message-container"));
- } catch {}
- const message = ReactDOM.render(
- ,
- document.getElementById("sc-sidebar-message-container"),
- () => {
+ const uniqueId = `sc-sidebar-message-container-${getUID()}}`;
+ const messageElement = document.createElement("div");
+ messageElement.setAttribute("id", uniqueId);
+ document.getElementById("sc-sidebar-message-container").appendChild(messageElement);
+
+ const root = createRoot(document.getElementById(uniqueId), { identifierPrefix: getUID() });
+
+ const ShowMessageWithCallback = (props) => {
+ const handleOnClose = () => {
+ try {
+ root.unmount();
+ document.getElementById(uniqueId).remove();
+ } catch (err) {
+ console.log(err);
+ }
+ };
+ useEffect(() => {
setTimeout(() => {
try {
- ReactDOM.unmountComponentAtNode(document.getElementById("sc-sidebar-message-container"));
+ handleOnClose();
} catch (err) {
console.log(err);
}
- }, timeout);
- }
- );
+ }, props.timeout);
+ return () => {
+ try {
+ if (props.onClose) props.onClose();
+ } catch (err) {
+ console.log(err);
+ }
+ };
+ }, [props.timeout]);
+ return ;
+ };
+ root.render();
}
-
export function searchArrayByKey(nameKey, myArray) {
for (var i = 0; i < myArray.length; i++) {
if (myArray[i].name === nameKey) {
@@ -1184,7 +1237,7 @@ function _escapeRegExp(str) {
}
export function showFeaturePopup(coord, feature) {
- window.popup.show(coord, );
+ window.popup.show(coord, , feature.get("layerDisplayName") || "Feature Info");
}
export function removeURLParameter(url, parameter) {
@@ -1211,7 +1264,22 @@ export function FilterKeys(feature) {
//WILDCARD = .*
//LITERAL STRING = [] EG: [_][.]
//NOT STRING = (?!string) EG: geostasis[.](?!test).*
- const filterKeys = ["[_].*", "id", "geometry", "geom", "extent_geom", ".*gid.*", "globalid", "objectid.*", "shape.*", "displayfieldname", "displayfieldvalue", "geostasis[.].*", ".*fid.*"];
+ const filterKeys = [
+ "[_].*",
+ "id",
+ "geometry",
+ "geom",
+ "extent_geom",
+ ".*gid.*",
+ "globalid",
+ "objectid.*",
+ "shape.*",
+ "displayfieldname",
+ "displayfieldvalue",
+ "layerdisplayname",
+ "geostasis[.].*",
+ ".*fid.*",
+ ];
const featureProps = feature.getProperties();
let keys = Object.keys(featureProps);
@@ -1403,7 +1471,7 @@ export function getBase64FromImageUrl(url, callback) {
export function waitForLoad(items, startTime = Date.now(), timeout = 30, callback) {
if (startTime + timeout * 1000 <= Date.now()) {
showMessage("Timeout", "Items Failed to load in a timely manner. Please reload the page", messageColors.red);
- console.error("timeout loading", items);
+ console.error("timeout loading", items, window.loaded);
} else {
if (isLoaded(items)) {
callback();
diff --git a/src/index.js b/src/index.js
index df59ac05..76656eba 100644
--- a/src/index.js
+++ b/src/index.js
@@ -1,28 +1,36 @@
// import 'react-app-polyfill/ie11';
import React from "react";
-import ReactDOM from "react-dom";
+import { createRoot } from "react-dom/client";
+
import "./index.css";
import * as serviceWorker from "./serviceWorker";
import { MsalProvider } from "@azure/msal-react";
import { Configuration, PublicClientApplication } from "@azure/msal-browser";
import "alertifyjs/build/css/alertify.css";
import "alertifyjs/build/css/themes/default.min.css";
+
+const root = createRoot(document.getElementById("root"));
+let element = document.createElement("div");
+element.setAttribute("id", "portal-root");
+document.getElementById("root").appendChild(element);
+window.portalRoot = createRoot(document.getElementById("portal-root"));
+
if (process.env.REACT_APP_SECURED === "true") {
import(`./AppSecure.jsx`)
.then((module) => {
const AppSecure = module.default;
// MSAL configuration
- const configuration: Configuration = {
+ const configuration = Configuration({
auth: {
clientId: process.env.REACT_APP_CLIENTID,
},
- };
+ });
const pca = new PublicClientApplication(configuration);
- ReactDOM.render(
+
+ root.render(
- ,
- document.getElementById("root")
+
);
})
.catch((error) => {
@@ -32,7 +40,7 @@ if (process.env.REACT_APP_SECURED === "true") {
import(`./App.js`)
.then((module) => {
const App = module.default;
- ReactDOM.render(, document.getElementById("root"));
+ root.render();
})
.catch((error) => {
console.log(error);
diff --git a/src/layerInfo/App.test.js b/src/layerInfo/App.test.js
index 635a333f..bb0dc284 100644
--- a/src/layerInfo/App.test.js
+++ b/src/layerInfo/App.test.js
@@ -1,9 +1,11 @@
import React from "react";
-import ReactDOM from "react-dom";
+import { createRoot } from "react-dom/client";
import App from "./App";
it("renders without crashing", () => {
- const div = document.createElement("div");
- ReactDOM.render(, div);
- ReactDOM.unmountComponentAtNode(div);
+ const div = document.createElement("div");
+
+ const root = createRoot(div); // createRoot(container!) if you use TypeScript
+ root.render();
+ root.unmount();
});
diff --git a/src/layerInfo/index.js b/src/layerInfo/index.js
index 781cb802..cecbde2b 100644
--- a/src/layerInfo/index.js
+++ b/src/layerInfo/index.js
@@ -1,10 +1,15 @@
import React from "react";
-import ReactDOM from "react-dom";
+import { createRoot } from "react-dom/client";
import "./index.css";
import App from "./App";
import * as serviceWorker from "./serviceWorker";
-ReactDOM.render(, document.getElementById("root"));
+const uniqueId = `root-${"layerInfo"}}`;
+const element = document.createElement("div");
+element.setAttribute("id", uniqueId);
+document.getElementById("root").appendChild(element);
+const root = createRoot(document.getElementById(uniqueId));
+root.render();
// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
diff --git a/src/legend/App.test.js b/src/legend/App.test.js
index 635a333f..0d5b554a 100644
--- a/src/legend/App.test.js
+++ b/src/legend/App.test.js
@@ -1,9 +1,10 @@
import React from "react";
-import ReactDOM from "react-dom";
+import { createRoot } from "react-dom/client";
import App from "./App";
it("renders without crashing", () => {
- const div = document.createElement("div");
- ReactDOM.render(, div);
- ReactDOM.unmountComponentAtNode(div);
+ const div = document.createElement("div");
+ const root = createRoot(div); // createRoot(container!) if you use TypeScript
+ root.render();
+ root.unmount();
});
diff --git a/src/map/BasicBasemapSwitcher.jsx b/src/map/BasicBasemapSwitcher.jsx
index b42bbc5e..48d10e59 100644
--- a/src/map/BasicBasemapSwitcher.jsx
+++ b/src/map/BasicBasemapSwitcher.jsx
@@ -1,5 +1,4 @@
import React, { useState, useRef, useContext, useEffect } from "react";
-import ReactDOM from "react-dom";
import Slider from "rc-slider";
import "./BasicBasemapSwitcher.css";
import * as helpers from "../helpers/helpers";
@@ -186,7 +185,7 @@ const BasicBasemapSwitcher = (props) => {
);
- ReactDOM.render(menu, document.getElementById("portal-root"));
+ window.portalRoot.render(menu);
};
const controlStateChange = (control, state) => {
diff --git a/src/map/SCMap.jsx b/src/map/SCMap.jsx
index f0bddbd1..550d4dfa 100644
--- a/src/map/SCMap.jsx
+++ b/src/map/SCMap.jsx
@@ -1,5 +1,4 @@
import React, { useState, useRef, useEffect, Fragment } from "react";
-import ReactDOM from "react-dom";
// import GitHubButton from "react-github-btn";
import GitHubButton from "../components/sc-github-btn";
//OPENLAYERS
@@ -230,7 +229,8 @@ const SCMap = (props) => {
);
- ReactDOM.render(menu, document.getElementById("portal-root"));
+
+ window.portalRoot.render(menu);
});
// APP STAT
diff --git a/src/sidebar/Sidebar.jsx b/src/sidebar/Sidebar.jsx
index 599c4488..6d61cc50 100644
--- a/src/sidebar/Sidebar.jsx
+++ b/src/sidebar/Sidebar.jsx
@@ -1,4 +1,5 @@
-import React, { Component } from "react";
+import React, { useState, useRef, useEffect } from "react";
+import { flushSync } from "react-dom";
import "./Sidebar.css";
import * as helpers from "../helpers/helpers";
@@ -13,179 +14,165 @@ import SidebarComponent from "../components/sc-sidebar.jsx";
import SidebarSlim from "./SidebarSlim.jsx";
import MenuButton from "./MenuButton.jsx";
-class Sidebar extends Component {
- constructor(props) {
- super(props);
-
- // BIND THIS FUNCTIONS
- this.togglePanelVisibility = this.togglePanelVisibility.bind(this);
- this.activateSidebarItem = this.activateSidebarItem.bind(this);
- this.onPanelComponentClose = this.onPanelComponentClose.bind(this);
- this.onSetSidebarOpen = this.onSetSidebarOpen.bind(this);
-
- this.state = {
- // TOOLS AND THEMES ARE IN HERE
- toolComponents: [],
-
- // CLASSES
- tabClassName: "sidebar-advanced-tab",
- sidebarOpen: false,
- tocLoaded: false,
- // SELECTED TAB
- tabIndex: 0,
- isMyMapsEditing: false,
- //hide components
- hideTools: false,
- hideThemes: false,
- hideLayers: false,
- hideMyMaps: false,
- hideReports: false,
- //TAB CONFIG ITEMS
- layers: {
- title: "Layers",
- icon: "legend-32x32.png",
- },
- tools: {
- title: "Tools",
- icon: "tools-32x32.png",
- },
- myMaps: {
- title: "My Maps",
- icon: "map-32x32.png",
- },
- themes: {
- title: "Themes",
- icon: "theme-32x32.png",
- },
- reports: {
- title: "Reports",
- icon: "report-32x32.png",
- },
- // COMPONENTS
- activeTabComponents: {
- layers: ,
- mymaps: ,
- reports: {
- default: ,
- loadedComponent: null,
- },
- tools: {
- default: ,
- loadedComponent: null,
- },
- themes: {
- default: ,
- loadedComponent: null,
- },
- },
- };
- // LISTEN FOR TOC TO LOAD
- window.emitter.addListener("tocLoaded", () => this.setState({ tocLoaded: true }));
- }
-
- onMyMapsEditing = (isMyMapsEditing) => {
+const Sidebar = (props) => {
+ const toolComponentsRef = useRef([]);
+
+ const toolComponentsLoaded = useRef(false);
+ const mapLoadingRef = useRef(props.mapLoading);
+ const headerLoadingRef = useRef(props.headerLoading);
+
+ const tabClassName = "sidebar-advanced-tab";
+ const [sidebarOpen, setSidebarOpen] = useState(false);
+ const [tabIndex, setTabIndex] = useState(0);
+ const [isMyMapsEditing, setIsMyMapsEditing] = useState(false);
+ const [hideTools, setHideTools] = useState(false);
+ const [hideThemes, setHideThemes] = useState(false);
+ const [hideLayers, setHideLayers] = useState(false);
+ const [hideMyMaps, setHideMyMaps] = useState(false);
+ const [hideReports, setHideReports] = useState(false);
+
+ const layers = {
+ title: "Layers",
+ icon: "legend-32x32.png",
+ };
+ const [tools, setTools] = useState({
+ title: "Tools",
+ icon: "tools-32x32.png",
+ });
+ const myMaps = {
+ title: "My Maps",
+ icon: "map-32x32.png",
+ };
+ const [themes, setThemes] = useState({
+ title: "Themes",
+ icon: "theme-32x32.png",
+ });
+ const reports = {
+ title: "Reports",
+ icon: "report-32x32.png",
+ };
+ const onMyMapsEditing = (isMyMapsEditingLocal) => {
// DISABLE PARCEL CLICK
- window.disableParcelClick = isMyMapsEditing;
+ window.disableParcelClick = isMyMapsEditingLocal;
// DISABLE POPUPS
- window.isDrawingOrEditing = isMyMapsEditing;
-
- this.setState({ isMyMapsEditing });
+ window.isDrawingOrEditing = isMyMapsEditingLocal;
+ setIsMyMapsEditing(isMyMapsEditingLocal);
};
+ // TOOL AND THEME ITEMS CLICK
+ const activateSidebarItem = (name, type, options = undefined) => {
+ // THIS HANDLES WHAT TOOL/THEME IS LOADED IN THE SIDEBAR
+ if (type === "tools") {
+ toolComponentsRef.current.map((Component) => {
+ if (Component.props.name.toLowerCase() === name.toLowerCase()) {
+ // CREATE TOOL COMPONENT
+ var comp = (
+ togglePanelVisibility()}
+ config={Component.props.config}
+ options={options}
+ />
+ );
+ setToolTabComponent(comp);
+ return comp;
+ } else return null;
+ });
- onSetSidebarOpen(open) {
- this.setState({ sidebarOpen: open });
- }
-
- addComponent = (componentConfig, typeFolder, callback = undefined) => {
- // THIS IMPORTS THE COMPONENTS
- //console.log(`Loading ${componentConfig.name} component...`);
- const typeLowerCase = `${componentConfig.componentName}`.toLowerCase().replace(/\s/g, "");
- const path = `./components/${typeFolder}/${typeLowerCase}/${componentConfig.componentName}.jsx`;
-
- import(`${path}`)
- .then((component) => {
- // SET PROPS FROM CONFIG
- let comp = component.default;
- comp.props = [];
- comp.props.active = false;
- comp.props.id = helpers.getUID();
- comp.props.description = componentConfig.description;
- comp.props.name = componentConfig.name;
- comp.props.componentName = componentConfig.componentName;
- comp.props.helpLink = componentConfig.helpLink;
- comp.props.config = componentConfig.config;
- if (componentConfig.hideHeader !== undefined) comp.props.hideHeader = componentConfig.hideHeader;
-
- // ADD COMPONENT TO LIST
- this.setState(
- {
- toolComponents: this.state.toolComponents.concat(comp),
- },
- callback("success")
- );
- })
- .catch((error) => {
- console.log(error);
- console.error(`"${componentConfig.name}" not yet supported`);
- callback("failure");
- })
- .finally(() => {
- if (callback === undefined) return "Done";
+ helpers.addAppStat("Tool", name);
+ } else {
+ toolComponentsRef.current.map((Component) => {
+ if (Component.props.name.toLowerCase() === name.toLowerCase()) {
+ // CREATE THEME COMPONENT
+ var comp = (
+ togglePanelVisibility()}
+ config={Component.props.config}
+ options={options}
+ />
+ );
+ setThemeTabComponent(comp);
+ return comp;
+ } else return null;
});
- };
- componentDidMount() {
+ helpers.addAppStat("Theme", name);
+ }
+ };
+ const defaultLayersTabComponentGUID = helpers.getUID();
+ const defaultToolTabComponentGUID = helpers.getUID();
+ const defaultThemeTabComponentGUID = helpers.getUID();
+ const defaultMyMapTabComponentGUID = helpers.getUID();
+ const defaultReportTabComponentGUID = helpers.getUID();
+ const defaultLayersTabComponent = ;
+ const defaultToolTabComponent = ;
+ const defaultThemeTabComponent = ;
+ const defaultMyMapTabComponent = ;
+ const defaultReportTabComponent = ;
+
+ const [activeLayersTabComponent, setLayersTabComponent] = useState(defaultLayersTabComponent);
+ const [activeToolTabComponent, setToolTabComponent] = useState(null);
+ const [activeThemeTabComponent, setThemeTabComponent] = useState(null);
+ const [activeMyMapTabComponent, setMyMapTabComponent] = useState(defaultMyMapTabComponent);
+ const [activeReportTabComponent, setReportTabComponent] = useState(null);
+
+ useEffect(() => {
// LISTEN FOR ITEM ACTIVATION FROM OTHER COMPONENTS
- window.emitter.addListener("activateSidebarItem", (name, type, options = undefined) => {
- helpers.waitForLoad("sidebar", Date.now(), 30, () => {
- this.activateItemFromEmmiter(name, type, options);
- });
- });
+ window.emitter.addListener("activateSidebarItem", activateItemFromEmmiter);
+
// LISTEN FOR OPEN OR CLOSE FROM OTHER COMPONENTS (CLOSE OR OPEN)
- window.emitter.addListener("setSidebarVisiblity", (openOrClose) => {
- helpers.waitForLoad("sidebar", Date.now(), 30, () => {
- this.sidebarVisiblityEventHandler(openOrClose);
- });
- });
+ window.emitter.addListener("setSidebarVisiblity", sidebarVisiblityEventHandler);
// LISTEN FOR TAB ACTIVATION FROM OTHER COMPONENTS
- window.emitter.addListener("activateTab", (tabName) => {
- helpers.waitForLoad("sidebar", Date.now(), 30, () => {
- this.activateTab(tabName);
- });
- });
+ window.emitter.addListener("activateTab", activateTab);
// LISTEN FOR REPORT LOADING
- window.emitter.addListener("loadReport", (content) => {
- helpers.waitForLoad("sidebar", Date.now(), 30, () => {
- this.loadReport(content);
- });
- });
+ window.emitter.addListener("loadReport", loadReport);
+ initSidebar();
+
+ return () => {
+ window.emitter.removeListener("activateSidebarItem", activateItemFromEmmiter);
+ window.emitter.removeListener("setSidebarVisiblity", sidebarVisiblityEventHandler);
+ window.emitter.removeListener("activateTab", activateTab);
+ window.emitter.removeListener("loadReport", loadReport);
+ };
+ }, []);
+
+ const initSidebar = () => {
helpers.waitForLoad("settings", Date.now(), 30, () => {
// IMPORT TOOLS FROM CONFIG and CHECK VISIBILITY
let tools = window.config.sidebarToolComponents;
tools = tools.filter((item) => item.enabled === undefined || item.enabled);
if (tools.length === 1) {
- this.setState({ tools: { title: tools[0].name, icon: tools[0].imageName } });
+ setTools({ title: tools[0].name, icon: tools[0].imageName });
tools[0]["hideHeader"] = true;
}
- if (tools.length === 0 || (window.config.mainSidebarItems !== undefined && window.config.mainSidebarItems["hideTools"])) this.setState({ hideTools: true });
- let loadedTools = [];
- let toolsProcessed = 0;
- tools.map((component) =>
- this.addComponent(component, "tools", (result) => {
- if (result === "success") loadedTools.push(component);
- else {
- window.config.sidebarToolComponents = window.config.sidebarToolComponents.map((item) => {
- if (component.name === item.name) item["enabled"] = false;
- return item;
+ if (tools.length === 0 || (window.config.mainSidebarItems !== undefined && window.config.mainSidebarItems["hideTools"])) setHideTools(true);
+ let componentPromises = [];
+ componentPromises.push(
+ ...tools.map((component) => {
+ return new Promise((resolve, reject) => {
+ addComponent(component, "tools", (result) => {
+ if (result) {
+ resolve({ component: result, type: "tools", loadedComponent: component });
+ } else {
+ window.config.sidebarToolComponents = window.config.sidebarToolComponents.map((item) => {
+ if (component.name === item.name) item["enabled"] = false;
+ return item;
+ });
+ reject();
+ }
});
- }
- toolsProcessed++;
- if (toolsProcessed >= tools.length) {
- helpers.addIsLoaded("tools");
- }
+ });
})
);
@@ -193,68 +180,132 @@ class Sidebar extends Component {
let themes = window.config.sidebarThemeComponents;
themes = themes.filter((item) => item.enabled === undefined || item.enabled);
if (themes.length === 1) {
- this.setState({ themes: { title: themes[0].name, icon: themes[0].imageName } });
+ setThemes({ title: themes[0].name, icon: themes[0].imageName });
themes[0]["hideHeader"] = true;
}
- if (themes.length === 0 || (window.config.mainSidebarItems !== undefined && window.config.mainSidebarItems["hideThemes"])) this.setState({ hideThemes: true });
- let loadedThemes = [];
- let themesProcessed = 0;
- themes.map((component) =>
- this.addComponent(component, "themes", (result) => {
- if (result === "success") loadedThemes.push(component);
- else {
- window.config.sidebarThemeComponents = window.config.sidebarThemeComponents.map((item) => {
- if (component.name === item.name) item["enabled"] = false;
- return item;
+ if (themes.length === 0 || (window.config.mainSidebarItems !== undefined && window.config.mainSidebarItems["hideThemes"])) setHideThemes(true);
+ componentPromises.push(
+ ...themes.map((component) => {
+ return new Promise((resolve, reject) => {
+ addComponent(component, "themes", (result) => {
+ if (result) {
+ resolve({ component: result, type: "themes", loadedComponent: component });
+ } else {
+ window.config.sidebarThemeComponents = window.config.sidebarThemeComponents.map((item) => {
+ if (component.name === item.name) item["enabled"] = false;
+ return item;
+ });
+ reject();
+ }
});
- }
- themesProcessed++;
- if (themesProcessed >= themes.length) {
- helpers.addIsLoaded("themes");
- }
+ });
})
);
+ let loadedThemes = [];
+ let loadedTools = [];
+ Promise.allSettled(componentPromises).then((results) => {
+ let loadedComponents = [];
+ results
+ .filter((result) => result.status === "fulfilled")
+ .forEach((result) => {
+ const { value } = result;
+ if (value.type === "themes") loadedThemes.push(value.loadedComponent);
+ if (value.type === "tools") loadedTools.push(value.loadedComponent);
+ loadedComponents.push(value.component);
+ });
+
+ toolComponentsLoaded.current = true;
+ toolComponentsRef.current = loadedComponents;
+ });
+
// CHECK VISIBILITY OF LAYERS MENUE
- if (window.config.mainSidebarItems !== undefined && window.config.mainSidebarItems["hideLayers"]) this.setState({ hideLayers: true });
+ if (window.config.mainSidebarItems !== undefined && window.config.mainSidebarItems["hideLayers"]) setHideLayers(true);
// CHECK VISIBILITY OF MY MAPS
- if (window.config.mainSidebarItems !== undefined && window.config.mainSidebarItems["hideMyMaps"]) this.setState({ hideMyMaps: true });
+ if (window.config.mainSidebarItems !== undefined && window.config.mainSidebarItems["hideMyMaps"]) setHideMyMaps(true);
// CHECK VISIBILITY OF REPORTS
- if (window.config.mainSidebarItems !== undefined && window.config.mainSidebarItems["hideReports"]) this.setState({ hideReports: true });
+ if (window.config.mainSidebarItems !== undefined && window.config.mainSidebarItems["hideReports"]) setHideReports(true);
const shortcuts = window.config.sidebarShortcutParams;
// HANDLE ADVANCED MODE PARAMETER
window.sidebarOpen = false;
if (window.config.viewerMode !== undefined && window.config.viewerMode !== null) {
- if (window.config.viewerMode.toUpperCase() === "ADVANCED") this.sidebarVisiblityEventHandler("OPEN");
+ if (window.config.viewerMode.toUpperCase() === "ADVANCED") sidebarVisiblityEventHandler("OPEN");
}
- helpers.waitForLoad(["tools", "themes"], Date.now(), 30, () => {
- this.initToolAndThemeUrlParameter({ tools: loadedTools, themes: loadedThemes, shortcuts: shortcuts }, () => {
+
+ helpers.waitForLoad(["tools", "themes", "header", "map"], Date.now(), 30, () => {
+ initToolAndThemeUrlParameter({ tools: loadedTools, themes: loadedThemes, shortcuts: shortcuts }, () => {
// TAB PARAMETER
const tabNameParameter = helpers.getURLParameter("TAB");
if (tabNameParameter != null) {
- this.sidebarVisiblityEventHandler("OPEN", () => {
- this.activateTab(tabNameParameter.toLowerCase());
+ sidebarVisiblityEventHandler("OPEN", () => {
+ activateTab(tabNameParameter.toLowerCase());
});
}
-
window.emitter.emit("sidebarLoaded");
helpers.addIsLoaded("sidebar");
});
});
});
- }
+ };
+
+ useEffect(() => {
+ helpers.addIsLoaded("tools");
+ helpers.addIsLoaded("themes");
+ }, [toolComponentsRef]);
- initToolAndThemeUrlParameter = (components, callback) => {
- if (components.tools.length + components.themes.length === this.state.toolComponents.length && !this.props.mapLoading && !this.props.headerLoading) {
+ useEffect(() => {
+ mapLoadingRef.current = props.mapLoading;
+ }, [props.mapLoading]);
+
+ useEffect(() => {
+ headerLoadingRef.current = props.headerLoading;
+ }, [props.headerLoading]);
+ const onSetSidebarOpen = (open) => {
+ setSidebarOpen(open);
+ };
+
+ const addComponent = (componentConfig, typeFolder, callback = undefined) => {
+ // THIS IMPORTS THE COMPONENTS
+ const typeLowerCase = `${componentConfig.componentName}`.toLowerCase().replace(/\s/g, "");
+ const path = `./components/${typeFolder}/${typeLowerCase}/${componentConfig.componentName}.jsx`;
+
+ import(`${path}`)
+ .then((component) => {
+ // SET PROPS FROM CONFIG
+ let comp = component.default;
+ comp.props = [];
+ comp.props.active = false;
+ comp.props.id = helpers.getUID();
+ comp.props.description = componentConfig.description;
+ comp.props.name = componentConfig.name;
+ comp.props.componentName = componentConfig.componentName;
+ comp.props.helpLink = componentConfig.helpLink;
+ comp.props.config = componentConfig.config;
+ if (componentConfig.hideHeader !== undefined) comp.props.hideHeader = componentConfig.hideHeader;
+
+ // ADD COMPONENT TO LIST
+ callback(comp);
+ })
+ .catch((error) => {
+ console.log(error);
+ console.error(`"${componentConfig.name}" not yet supported`);
+ callback();
+ })
+ .finally(() => {
+ if (callback === undefined) return "Done";
+ });
+ };
+
+ const initToolAndThemeUrlParameter = (components, callback) => {
+ if (components.tools.length + components.themes.length === toolComponentsRef.current.length && !mapLoadingRef.current && !headerLoadingRef.current) {
// HANDLE ADVANCED MODE PARAMETER
callback();
const queryString = window.location.search;
if (queryString !== "") {
const urlParams = new URLSearchParams(queryString.toLowerCase());
- const item = undefined;
let shortcuts = [];
let params = [];
- components.tools.map((item) => {
+ components.tools.forEach((item) => {
shortcuts.push({
name: item.name.toLowerCase(),
component: item.name,
@@ -263,7 +314,7 @@ class Sidebar extends Component {
});
if (!params.includes("tool")) params.push("tool");
});
- components.themes.map((item) => {
+ components.themes.forEach((item) => {
shortcuts.push({
name: item.name.toLowerCase(),
component: item.name,
@@ -272,7 +323,7 @@ class Sidebar extends Component {
});
if (!params.includes("theme")) params.push("theme");
});
- components.shortcuts.map((item) => {
+ components.shortcuts.forEach((item) => {
shortcuts.push({
name: item.matchValue,
component: item.component,
@@ -283,7 +334,7 @@ class Sidebar extends Component {
});
if (!params.includes(item.url_param.toLowerCase())) params.push(item.url_param.toLowerCase());
});
- params.map((param) => {
+ params.forEach((param) => {
var shortcutParam = urlParams.get(param);
if (shortcutParam !== null) {
const shortcut = shortcuts.filter(
@@ -293,8 +344,8 @@ class Sidebar extends Component {
if (shortcut.type === "search") {
window.emitter.emit("searchItem", shortcut.component, shortcutParam, shortcut.hidden, shortcut.timeout);
} else {
- this.sidebarVisiblityEventHandler("OPEN", () => {
- this.activateItemFromEmmiter(shortcut.component, shortcut.type);
+ sidebarVisiblityEventHandler("OPEN", () => {
+ activateItemFromEmmiter(shortcut.component, shortcut.type);
});
}
}
@@ -303,273 +354,206 @@ class Sidebar extends Component {
}
} else {
setTimeout(() => {
- this.initToolAndThemeUrlParameter(components, callback);
- }, 50);
+ initToolAndThemeUrlParameter(components, callback);
+ }, 500);
}
};
- loadReport = (content) => {
- let activeTabComponents = this.state.activeTabComponents;
- activeTabComponents.reports.loadedComponent = {content};
- this.setState({ activeTabComponents: activeTabComponents });
- this.sidebarVisiblityEventHandler("OPEN");
- this.activateTab("reports");
+ const loadReport = (content) => {
+ helpers.waitForLoad("sidebar", Date.now(), 30, () => {
+ setReportTabComponent({content});
+ sidebarVisiblityEventHandler("OPEN");
+ activateTab("reports");
+ });
};
- activateItemFromEmmiter(name, type, options = undefined) {
- const active = this.state.activeTabComponents;
- if (type === "tools") {
- //SAME TOOL WAS SELECTED
- if (active.tools.loadedComponent != null && type === "tools" && active.tools.loadedComponent.props.name === name) {
- this.activateTab("tools");
- return;
- }
-
- this.setState({ tabIndex: 1 }, () => {
- //CLEAR LOADED TOOL
- let activeTabComponents = this.state.activeTabComponents;
- activeTabComponents.tools.loadedComponent = null;
- this.setState({ activeTabComponents: activeTabComponents }, () => {
- // ASK TOOLS TO CLOSE
- window.emitter.emit("closeToolsOrThemes", type);
-
- // ACTIVATE THE NEW ITEM
- this.activateSidebarItem(name, type, options);
+ const activateItemFromEmmiter = (name, type, options = undefined) => {
+ helpers.waitForLoad("sidebar", Date.now(), 30, () => {
+ if (type === "tools") {
+ //SAME TOOL WAS SELECTED
+ if (activeToolTabComponent != null && type === "tools" && activeToolTabComponent.props.name === name) {
+ activateTab("tools");
+ return;
+ }
+ flushSync(() => {
+ setTabIndex(1);
+ //CLEAR LOADED TOOL
+ setToolTabComponent(null);
});
- });
- } else if (type === "themes") {
- // SAME THEME WAS SELECTED
- if (active.themes.loadedComponent != null && type === "themes" && active.themes.loadedComponent.props.name === name) {
- this.activateTab("themes");
- return;
- }
-
- this.setState({ tabIndex: 3 }, () => {
- //CLEAR LOADED THEME
- let activeTabComponents = this.state.activeTabComponents;
- activeTabComponents.themes.loadedComponent = null;
- this.setState({ activeTabComponents: activeTabComponents });
+ // ASK TOOLS TO CLOSE
+ window.emitter.emit("closeToolsOrThemes", type);
+ // ACTIVATE THE NEW ITEM
+ activateSidebarItem(name, type, options);
+ } else if (type === "themes") {
+ // SAME THEME WAS SELECTED
+ if (activeThemeTabComponent != null && type === "themes" && activeThemeTabComponent.props.name === name) {
+ activateTab("themes");
+ return;
+ }
+ flushSync(() => {
+ setTabIndex(3);
+ //CLEAR LOADED THEME
+ setThemeTabComponent(null);
+ });
// ASK THEMES TO CLOSE
window.emitter.emit("closeToolsOrThemes", type);
// ACTIVATE THE NEW ITEM
- this.activateSidebarItem(name, type, options);
- });
- } else if (type === "mymaps") {
- this.activateTab("mymaps");
- } else if (type === "reports") {
- this.activateTab("reports");
- }
+ activateSidebarItem(name, type, options);
+ } else if (type === "mymaps") {
+ activateTab("mymaps");
+ } else if (type === "reports") {
+ activateTab("reports");
+ }
- // OPEN PANEL
- this.sidebarVisiblityEventHandler("OPEN");
- }
-
- activateTab(tabName) {
- // OPEN PANEL
- this.sidebarVisiblityEventHandler("OPEN");
-
- // SET SELECTED TAB
- if (tabName === "layers") this.setState({ tabIndex: 0 });
- else if (tabName === "tools") this.setState({ tabIndex: 1 });
- else if (tabName === "mymaps") this.setState({ tabIndex: 2 });
- else if (tabName === "themes") this.setState({ tabIndex: 3 });
- else if (tabName === "reports") this.setState({ tabIndex: 4 });
- else console.log("NO VALID TAB FOUND");
- }
-
- sidebarVisiblityEventHandler(openOrClose, callback = undefined) {
- // CHECK IF NEED TO DO ANYTHING
- if ((openOrClose === "CLOSE" && window.sidebarOpen === false) || (openOrClose === "OPEN" && window.sidebarOpen === true)) {
- if (callback === undefined) return;
- else callback();
- } else {
- // TOGGLE IT
- this.togglePanelVisibility(callback);
- }
- }
+ // OPEN PANEL
+ sidebarVisiblityEventHandler("OPEN");
+ });
+ };
- togglePanelVisibility(callback = undefined) {
- // PANEL IN AND OUT CLASSES
- window.sidebarOpen = !window.sidebarOpen;
- this.setState({ sidebarOpen: window.sidebarOpen }, () => {
- // EMIT A CHANGE IN THE SIDEBAR (IN OR OUT)
- window.emitter.emit("sidebarChanged", window.sidebarOpen);
- if (callback !== undefined && typeof callback === "function") callback();
+ const activateTab = (tabName) => {
+ helpers.waitForLoad("sidebar", Date.now(), 30, () => {
+ // OPEN PANEL
+ sidebarVisiblityEventHandler("OPEN");
+ flushSync(() => {
+ // SET SELECTED TAB
+ if (tabName === "layers") setTabIndex(0);
+ else if (tabName === "tools") setTabIndex(1);
+ else if (tabName === "mymaps") setTabIndex(2);
+ else if (tabName === "themes") setTabIndex(3);
+ else if (tabName === "reports") setTabIndex(4);
+ else console.log("NO VALID TAB FOUND");
+ });
});
- }
+ };
- // TOOL AND THEME ITEMS CLICK
- activateSidebarItem(name, type, options = undefined) {
- // THIS HANDLES WHAT TOOL/THEME IS LOADED IN THE SIDEBAR
- if (type === "tools") {
- var loadedTool = this.state.activeTabComponents.tools.loadedComponent;
- if (loadedTool != null) {
- this.setState({ activeComponent: loadedTool });
+ const sidebarVisiblityEventHandler = (openOrClose, callback = undefined) => {
+ helpers.waitForLoad("sidebar", Date.now(), 30, () => {
+ // CHECK IF NEED TO DO ANYTHING
+ if ((openOrClose === "CLOSE" && window.sidebarOpen === false) || (openOrClose === "OPEN" && window.sidebarOpen === true)) {
+ if (callback === undefined) return;
+ else callback();
} else {
- this.state.toolComponents.map((Component) => {
- if (Component.props.name.toLowerCase() === name.toLowerCase()) {
- // CREATE TOOL COMPONENT
- var comp = (
- this.togglePanelVisibility()}
- config={Component.props.config}
- options={options}
- />
- );
- let activeTabComponents = this.state.activeTabComponents;
- activeTabComponents.tools.loadedComponent = comp;
- this.setState({ activeTabComponents: activeTabComponents });
- return comp;
- } else return null;
- });
+ // TOGGLE IT
+ togglePanelVisibility(callback);
}
+ });
+ };
- helpers.addAppStat("Tool", name);
- } else {
- var loadedTheme = this.state.activeTabComponents.themes.loadedComponent;
- if (loadedTheme != null) this.setState({ activeComponent: loadedTheme });
- else {
- this.state.toolComponents.map((Component) => {
- if (Component.props.name.toLowerCase() === name.toLowerCase()) {
- // CREATE THEME COMPONENT
- var comp = (
- this.togglePanelVisibility()}
- config={Component.props.config}
- options={options}
- />
- );
- let activeTabComponents = this.state.activeTabComponents;
- activeTabComponents.themes.loadedComponent = comp;
- this.setState({ activeTabComponents: activeTabComponents });
- //helpers.showMessage("Property Report", "Property Report Click is disabled while theme is active.", "green" , 5000);
- return comp;
- } else return null;
- });
- }
- helpers.addAppStat("Theme", name);
- }
- }
+ const togglePanelVisibility = (callback = undefined) => {
+ // PANEL IN AND OUT CLASSES
+ window.sidebarOpen = !window.sidebarOpen;
+ setSidebarOpen(window.sidebarOpen);
+ // EMIT A CHANGE IN THE SIDEBAR (IN OR OUT)
+ window.emitter.emit("sidebarChanged", window.sidebarOpen);
+ if (callback !== undefined && typeof callback === "function") callback();
+ };
- onPanelComponentClose(evt) {
+ const onPanelComponentClose = (evt) => {
// HANDLES UNLOADING OF TOOL/THEME
- if (this.state.tabIndex === 1) {
+ if (tabIndex === 1) {
// SET TOOLS
- let activeTabComponents = this.state.activeTabComponents;
- activeTabComponents.tools.loadedComponent = null;
- this.setState({ activeTabComponents: activeTabComponents });
- } else if (this.state.tabIndex === 3) {
+ setToolTabComponent(null);
+ } else if (tabIndex === 3) {
// SET THEMES
- let activeTabComponents = this.state.activeTabComponents;
- activeTabComponents.themes.loadedComponent = null;
- this.setState({ activeTabComponents: activeTabComponents });
+ setThemeTabComponent(null);
}
- }
+ };
- slimSidebarButtonClick = (name) => {
- this.sidebarVisiblityEventHandler("OPEN", () => {
- this.activateTab(name);
+ const slimSidebarButtonClick = (name) => {
+ sidebarVisiblityEventHandler("OPEN", () => {
+ activateTab(name);
helpers.addAppStat("Sidebar Slim", name);
});
};
- onTabSelect = (tabIndex) => {
- this.setState({ tabIndex });
- if (tabIndex === 0) helpers.addAppStat("Tab", "Layers");
- else if (tabIndex === 1) helpers.addAppStat("Tab", "Tools");
- else if (tabIndex === 2) helpers.addAppStat("Tab", "MyMaps");
- else if (tabIndex === 3) helpers.addAppStat("Tab", "Themes");
- else if (tabIndex === 4) helpers.addAppStat("Tab", "Reports");
+ const onTabSelect = (tabIndexLocal) => {
+ setTabIndex(tabIndexLocal);
+ if (tabIndexLocal === 0) helpers.addAppStat("Tab", "Layers");
+ else if (tabIndexLocal === 1) helpers.addAppStat("Tab", "Tools");
+ else if (tabIndexLocal === 2) helpers.addAppStat("Tab", "MyMaps");
+ else if (tabIndexLocal === 3) helpers.addAppStat("Tab", "Themes");
+ else if (tabIndexLocal === 4) helpers.addAppStat("Tab", "Reports");
};
- // this.setState({ tabIndex })} selectedIndex={this.state.tabIndex}>
- render() {
- return (
-