UNPKG

bananas-commerce-admin

Version:

What's this, an admin for apes?

92 lines 3.77 kB
import React, { useMemo, useState } from "react"; import { matchPath, useNavigate } from "react-router-dom"; import { useSnackbar } from "notistack"; import { getPage, getPath, getTitle, isNavigation, parseOperationId, stripPathPrefix, } from "../router/routes"; import { useApi } from "./ApiContext"; const RouterContext = React.createContext({ routes: [], getCurrent: () => void 0, getRoute: (reverse) => void reverse, setCustomRoutes: (routes) => void routes, navigate: (route, options) => void [route, options], }); export const useRouter = () => React.useContext(RouterContext); export const RouterContextProvider = ({ children, ...props }) => { const api = useApi(); const [customRoutes, setCustomRoutes] = useState([]); const apiRoutes = useMemo(() => { const routes = []; for (const operation of Object.values(api.operations)) { const parsedOperationId = parseOperationId(operation.id); if (!parsedOperationId) { throw new TypeError(`Could not parse operation id ${operation.id}`); } const { app, view, action } = parsedOperationId; const title = getTitle(view, operation.summary); const navigation = isNavigation(operation.tags); const path = stripPathPrefix(getPath(operation.endpoint, operation.method, action), props.stripPathPrefix); const page = getPage(path, action); routes.push({ id: operation.id, app, view, action, title, navigation, path, page, }); } return routes; }, [api]); const routes = useMemo(() => customRoutes.concat(apiRoutes), [customRoutes, apiRoutes]); const routerNavigate = useNavigate(); const { enqueueSnackbar } = useSnackbar(); const getCurrent = () => { let currentPath = stripPathPrefix(location.pathname, props.basename); if (!currentPath.startsWith("/")) { currentPath = `/${currentPath}`; } for (const route of routes) { const match = matchPath(route.path, currentPath); if (match !== null) { return { route, match }; } } return undefined; }; const getRoute = (reverse) => { return routes.find(({ id }) => reverse === id); }; const navigate = (route, options) => { // Relative history, e.g. go back or forward x steps if (typeof route === "number") { routerNavigate(route); return; } // Direct operation id routes, requires reversing the operation id if (typeof route === "string") { const routeInfo = getRoute(route); if (routeInfo == null) { enqueueSnackbar("Failed to navigate, view console for more info", { variant: "error", }); throw new Error(`Could not find route with reverse: ${route}`); } route = routeInfo; } let pathname = route?.path; if (pathname != null) { for (const [key, value] of Object.entries(options?.params ?? {})) { pathname = pathname.replace(`:${key}`, encodeURIComponent(value)); } } routerNavigate({ pathname, search: new URLSearchParams(options?.query).toString(), }, { replace: options?.replace }); }; return (React.createElement(RouterContext.Provider, { value: { routes, getCurrent, getRoute, setCustomRoutes, navigate } }, children)); }; export default RouterContext; //# sourceMappingURL=RouterContext.js.map