bananas-commerce-admin
Version:
What's this, an admin for apes?
77 lines • 3.36 kB
JavaScript
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