UNPKG

bananas-commerce-admin

Version:

What's this, an admin for apes?

77 lines 3.36 kB
import React, { lazy, Suspense, useCallback, useEffect, useMemo, useRef, useState } from "react"; import { useParams, useSearchParams } from "react-router-dom"; import { useApi } from "../contexts/ApiContext"; import { useUser } from "../contexts/UserContext"; import useAsyncError from "../hooks/useAsyncError"; import { hasAccess } from "../util/has_access"; import LoadingScreen from "./LoadingScreen"; export class PageLoadFailedError extends Error { response; constructor(response, message) { super(message); this.response = response; } } const PageLoader = ({ route, page, offline = false, request, defaultRequest, }) => { const api = useApi(); const params = useParams(); const [searchParams] = useSearchParams(); const { user } = useUser(); const hasFetchedInitialData = useRef(false); const [data, setData] = useState(null); const throwError = useAsyncError(); const operation = useMemo(() => api.operations[route.id], [api.operations, route.id]); const getData = useCallback(async () => { if (offline) return; if (operation == null) { throwError(new Error(`Operation ${route.id} not found`)); return; } const getQueryEntries = (request) => { if (!request?.query) return []; if (request.query instanceof URLSearchParams) return request.query.entries(); return Object.entries(request.query) ?? []; }; const query = Array.from(searchParams.entries()).length === 0 && defaultRequest != null ? getQueryEntries(defaultRequest) : searchParams.entries(); try { const requestParams = { ...params, ...request?.params }; const requestQuery = new URLSearchParams([ ...Array.from(query), ...Array.from(request ? getQueryEntries(request) : []), ]); const response = await operation.call({ params: requestParams, query: requestQuery, }); if (response.ok) { setData(await response.json()); } else { throwError(new PageLoadFailedError(response, `Page data load failed with ${response.status} ${response.statusText}`)); } } catch (error) { // TODO Handle error with sentry console.error("[PAGE_LOADER]Error loading page data", error); } }, [api, route.id, params, searchParams, request, defaultRequest, offline, setData, throwError]); // TODO: Set search params on initial load useEffect(() => { if (!hasFetchedInitialData.current) { getData(); hasFetchedInitialData.current = true; } }, [hasFetchedInitialData, getData]); const Page = useMemo(() => lazy(async () => ({ default: await Promise.resolve(page) })), [page]); if (!hasAccess(user, operation?.component?.permission, operation?.component?.group)) { return null; } return (React.createElement(Suspense, { fallback: React.createElement(LoadingScreen, null) }, Boolean(data != null || offline) && React.createElement(Page, { data: data, refresh: getData }))); }; export default PageLoader; //# sourceMappingURL=PageLoader.js.map