diff --git a/app/layout/loading/component.tsx b/app/layout/loading/component.tsx new file mode 100644 index 0000000000..1854627458 --- /dev/null +++ b/app/layout/loading/component.tsx @@ -0,0 +1,41 @@ +import React from 'react'; + +import { useNProgress } from '@tanem/react-nprogress'; +import cx from 'classnames'; +import { AnimatePresence, motion } from 'framer-motion'; + +export interface LoadingProps { + loading?: boolean; +} + +export const Loading: React.FC = ({ loading }: LoadingProps) => { + const { isFinished, progress } = useNProgress({ + isAnimating: loading, + }); + + return ( + + {!isFinished && ( + +
+ + )} + + ); +}; + +export default Loading; diff --git a/app/layout/loading/index.ts b/app/layout/loading/index.ts new file mode 100644 index 0000000000..b404d7fd44 --- /dev/null +++ b/app/layout/loading/index.ts @@ -0,0 +1 @@ +export { default } from './component'; diff --git a/app/layout/projects/show/map/component.tsx b/app/layout/projects/show/map/component.tsx index 7fa81c3abc..ba47b2d2e4 100644 --- a/app/layout/projects/show/map/component.tsx +++ b/app/layout/projects/show/map/component.tsx @@ -384,15 +384,14 @@ export const ProjectMap: React.FC = () => {
)} +
)} - -
); }; diff --git a/app/layout/projects/show/scenarios/component.tsx b/app/layout/projects/show/scenarios/component.tsx index 915caf93ae..0c214fe44b 100644 --- a/app/layout/projects/show/scenarios/component.tsx +++ b/app/layout/projects/show/scenarios/component.tsx @@ -213,7 +213,7 @@ export const ProjectScenarios: React.FC = () => { return ( -
+
= () => {
- {!hasScenarios && !search && !hasFilters && ( + {!hasScenarios && !search && !hasFilters && scenariosIsFetched && ( { + const [routeLoading, setRouteLoading] = useState({ + loading: false, + key: 0, + }); const queryClientRef = useRef(null); if (!queryClientRef.current) { queryClientRef.current = new QueryClient(); } + const router = useRouter(); + + const onRouteChangeStart = useCallback(() => { + setRouteLoading((prevState) => ({ + ...prevState, + loading: true, + key: prevState.key + 1, + })); + }, []); + + const onRouteChangeEnd = useCallback(() => { + setRouteLoading((prevState) => ({ + ...prevState, + loading: false, + })); + }, []); + + useEffect(() => { + router.events.on('routeChangeStart', onRouteChangeStart); + router.events.on('routeChangeComplete', onRouteChangeEnd); + router.events.on('routeChangeError', onRouteChangeEnd); + + // If the component is unmounted, unsubscribe + // from the event with the `off` method: + return () => { + router.events.off('routeChangeStart', onRouteChangeStart); + router.events.off('routeChangeComplete', onRouteChangeEnd); + router.events.off('routeChangeError', onRouteChangeEnd); + }; + }, []); // eslint-disable-line + return ( @@ -46,6 +85,7 @@ const MarxanApp: React.ReactNode = ({ Component, pageProps }: AppProps) => { > +
diff --git a/app/yarn.lock b/app/yarn.lock index 887664d7c6..2ed336ab40 100644 --- a/app/yarn.lock +++ b/app/yarn.lock @@ -1375,6 +1375,13 @@ dependencies: regenerator-runtime "^0.13.4" +"@babel/runtime@^7.17.2": + version "7.17.2" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.17.2.tgz#66f68591605e59da47523c631416b18508779941" + integrity sha512-hzeyJyMA1YGdJTuWU0e/j4wKXrU4OMFvY2MSlaI9B7VQb0r5cxTE3EAIS2Q7Tn2RIcDkRvTA/v2JsAEhxe99uw== + dependencies: + regenerator-runtime "^0.13.4" + "@babel/template@^7.10.4", "@babel/template@^7.12.7": version "7.12.7" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.12.7.tgz#c817233696018e39fbb6c491d2fb684e05ed43bc" @@ -3713,6 +3720,15 @@ mini-svg-data-uri "^1.0.3" traverse "^0.6.6" +"@tanem/react-nprogress@^4.0.8": + version "4.0.8" + resolved "https://registry.yarnpkg.com/@tanem/react-nprogress/-/react-nprogress-4.0.8.tgz#704f459bd79185be18558c7c468320b34180ac78" + integrity sha512-e15HalPIkweMulfNg2fX6GXLqXayW+6VWxK2k2DFooqoSnPQc9MvHj+qKWbL+MxlKPpqzE5Pu+PE9NtY+E22+Q== + dependencies: + "@babel/runtime" "^7.17.2" + hoist-non-react-statics "^3.3.2" + prop-types "^15.8.1" + "@tippyjs/react@^4.2.0": version "4.2.0" resolved "https://registry.yarnpkg.com/@tippyjs/react/-/react-4.2.0.tgz#a1cb369d0051099e8a7e4ceb59f809abd9955283" @@ -11987,6 +12003,11 @@ npmlog@^4.0.1, npmlog@^4.1.2: gauge "~2.7.3" set-blocking "~2.0.0" +nprogress@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/nprogress/-/nprogress-0.2.0.tgz#cb8f34c53213d895723fcbab907e9422adbcafb1" + integrity sha1-y480xTIT2JVyP8urkH6UIq28r7E= + nth-check@^1.0.2, nth-check@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.2.tgz#b2bd295c37e3dd58a3bf0700376663ba4d9cf05c" @@ -13104,6 +13125,15 @@ prop-types@15.7.2, prop-types@^15.0.0, prop-types@^15.5.10, prop-types@^15.6.0, object-assign "^4.1.1" react-is "^16.8.1" +prop-types@^15.8.1: + version "15.8.1" + resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" + integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== + dependencies: + loose-envify "^1.4.0" + object-assign "^4.1.1" + react-is "^16.13.1" + property-information@^5.0.0, property-information@^5.3.0: version "5.6.0" resolved "https://registry.yarnpkg.com/property-information/-/property-information-5.6.0.tgz#61675545fb23002f245c6540ec46077d4da3ed69"