diff --git a/package.json b/package.json index e00f6cc1..73d86337 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,6 @@ }, "dependencies": { "@luontola/react-cache": "^2.0.0-alpha.2019-05-02", - "@reach/router": "^1.3.3", "alphanum-sort": "^1.0.2", "auth0-js": "^9.13.2", "axios": "^0.19.0", @@ -26,11 +25,12 @@ "ol": "^6.3.0", "prop-types": "^15.7.2", "purecss": "^1.0.1", - "react": "^0.0.0-experimental-e5d06e34b", - "react-dom": "^0.0.0-experimental-e5d06e34b", + "react": "^18.2.0", + "react-dom": "^18.2.0", "react-error-boundary": "^1.2.5", "react-intl": "^4.3.1", "react-qr-svg": "^2.2.2", + "react-router-dom": "^6.14.2", "regenerator-runtime": "^0.13.5" }, "devDependencies": { @@ -47,6 +47,7 @@ "@storybook/react": "^5.3.18", "@types/auth0-js": "^9.12.4", "@types/lodash": "^4.14.149", + "@types/react-dom": "^18.2.7", "babel-loader": "^8.1.0", "babel-plugin-react-intl": "^7.1.0", "babel-preset-react-app": "^9.1.2", diff --git a/territory-bro.iml b/territory-bro.iml index 6d471d4f..cbb8d7db 100644 --- a/territory-bro.iml +++ b/territory-bro.iml @@ -16,6 +16,9 @@ + + + diff --git a/web/js/index.tsx b/web/js/index.tsx index a69919b7..a01e9851 100644 --- a/web/js/index.tsx +++ b/web/js/index.tsx @@ -2,9 +2,8 @@ // This software is released under the Apache License 2.0. // The license text is at http://www.apache.org/licenses/LICENSE-2.0 -import React from "react"; -import ReactDOM from "react-dom"; -import {globalHistory, Router} from "@reach/router"; +import React, {useEffect} from "react"; +import ReactDOM from "react-dom/client"; import {IntlProvider} from "react-intl"; import {language, messages} from "./intl"; import ErrorBoundary from "react-error-boundary"; @@ -25,18 +24,19 @@ import TerritoryListPage from "./pages/TerritoryListPage"; import TerritoryPage from "./pages/TerritoryPage"; import OpenSharePage from "./pages/OpenSharePage"; import {getPageState, setPageState} from "./util"; +import {BrowserRouter, Route, Routes, useLocation} from "react-router-dom"; -let previousLocation = globalHistory.location; -globalHistory.listen(({location, action}) => { - if (previousLocation.href === location.href) { - return; // only page state was updated, but the URL remains the same - } - previousLocation = location; - - console.info(`Current URL is now ${location.pathname}${location.search}${location.hash} (${action})`); - logPageView(); +function NavigationListener({children}) { + const location = useLocation() + useEffect(() => { + console.info(`Current URL is now ${location.pathname}${location.search}${location.hash}`); + logPageView(); + restoreScrollY(getPageState("scrollY")); + }, [location.pathname]) + return children; +} - const scrollY = getPageState("scrollY"); +function restoreScrollY(scrollY?: number) { if (typeof scrollY === 'number') { // XXX: scrolling immediately does not scroll far enough; maybe we must wait for React to render the whole page setTimeout(() => { @@ -45,7 +45,7 @@ globalHistory.listen(({location, action}) => { } else { document.querySelector('main')?.scrollIntoView({block: "start"}); } -}); +} function listenScrollY(onScroll) { let lastKnownScrollY = 0; @@ -75,27 +75,32 @@ ReactDOM.createRoot(document.getElementById('root')) - Loading....

}> - - - - - - - - + + + Loading....

}> + + + }/> + }/> + }/> + }/> + }/> + }/> - - - - - - + }/> + }/> + }/> + }/> + }/> + }/> - -
-
-
+ }/> + + + + +
-
); + + ); diff --git a/web/js/layout/Layout.tsx b/web/js/layout/Layout.tsx index 79a4dcb1..9bba0e12 100644 --- a/web/js/layout/Layout.tsx +++ b/web/js/layout/Layout.tsx @@ -1,4 +1,4 @@ -// Copyright © 2015-2020 Esko Luontola +// Copyright © 2015-2023 Esko Luontola // This software is released under the Apache License 2.0. // The license text is at http://www.apache.org/licenses/LICENSE-2.0 @@ -7,18 +7,11 @@ import styles from "./Layout.css"; import * as React from "react"; import {useEffect} from "react"; import AuthenticationPanel from "./AuthenticationPanel"; -import {Link, Router} from "@reach/router"; import {getCongregationById} from "../api"; +import {NavLink as RouterNavLink, Route, Routes, useParams} from "react-router-dom"; const NavLink = (props) => ( - { - // the object returned here is passed to the anchor element's props - const active = (href === '/') ? isCurrent : isPartiallyCurrent; - return { - className: active ? styles.active : undefined - }; - }}/> + isActive ? styles.active : ""} {...props}/> ); const HomeNav = ({}) => { @@ -34,7 +27,8 @@ const HomeNav = ({}) => { ); } -const CongregationNav = ({congregationId}) => { +const CongregationNav = () => { + const {congregationId} = useParams() const congregation = getCongregationById(congregationId); return (
    @@ -42,7 +36,7 @@ const CongregationNav = ({congregationId}) => {
  • {congregation.name}
  • Territories
  • {congregation.permissions.viewCongregation && -
  • Printouts
  • } +
  • Printouts
  • } {congregation.permissions.configureCongregation && <>
  • Users
  • Settings
  • @@ -52,12 +46,6 @@ const CongregationNav = ({congregationId}) => { ); } -function RouterComponent({children}) { - // Workaround for Reach Router to not render in a
    which messes up flexbox. - // See https://github.com/reach/router/issues/63#issuecomment-524297867 - return <>{children}; -} - type Props = { title?: string; children?: React.ReactNode; @@ -72,10 +60,10 @@ const Layout = ({title, children}: Props) => { return <>