From 96396d9e4de2ea6c3f2a5915183ad18db8c6ee51 Mon Sep 17 00:00:00 2001 From: SrGooglo Date: Fri, 24 Feb 2023 14:38:26 +0000 Subject: [PATCH] improve router handlers --- packages/app/src/router.jsx | 124 +++++++++++++++++++++++++++++------- 1 file changed, 102 insertions(+), 22 deletions(-) diff --git a/packages/app/src/router.jsx b/packages/app/src/router.jsx index c9013d8e..6e767883 100755 --- a/packages/app/src/router.jsx +++ b/packages/app/src/router.jsx @@ -1,13 +1,16 @@ import React from "react" import { Route, Routes, useLocation, useNavigate, useParams } from "react-router-dom" -import { Skeleton } from "antd" +import { Skeleton, Button, Result } from "antd" +import config from "config" import loadable from "@loadable/component" -const NotFoundRender = () => { +import routesDeclaration from "schemas/routes" + +const DefaultNotFoundRender = () => { return
Not found
} -const LoadingRender = () => { +const DefaultLoadingRender = () => { return } @@ -21,22 +24,6 @@ const pathsMobile = { ...import.meta.glob("/src/pages/**/[a-z[]*.mobile.tsx"), } -function generateElementWrapper(route, element, bindProps) { - return React.createElement((props) => { - const params = useParams() - - return React.createElement( - loadable(element, { - fallback: React.createElement(LoadingRender), - }), - { - ...props, - ...bindProps, - params: params, - }) - }) -} - const routes = Object.keys(paths).map((route) => { const path = route .replace(/\/src\/pages|index|\.jsx$/g, "") @@ -63,6 +50,94 @@ const mobileRoutes = Object.keys(pathsMobile).map((route) => { } }) +function generatePageElementWrapper(route, element, bindProps) { + return React.createElement((props) => { + const params = useParams() + const url = new URL(window.location) + const query = new Proxy(url, { + get: (target, prop) => target.searchParams.get(prop), + }) + + const routeDeclaration = routesDeclaration.find((layout) => { + const routePath = layout.path.replace(/\*/g, ".*").replace(/!/g, "^") + + return new RegExp(routePath).test(route) + }) ?? { + path: route, + useLayout: "default", + } + + route = route.replace(/\?.+$/, "").replace(/\/{2,}/g, "/") + route = route.replace(/\/$/, "") + + if (routeDeclaration) { + if (!bindProps.user && (window.location.pathname !== config.app?.authPath)) { + if (!routeDeclaration.public) { + if (typeof window.app.setLocation === "function") { + window.app.setLocation(config.app?.authPath ?? "/login") + return
+ } + + window.location.href = config.app?.authPath ?? "/login" + + return
+ } + } + + if (typeof routeDeclaration.requiredRoles !== "undefined") { + const isAdmin = bindProps.user?.roles?.includes("admin") ?? false + + if (!isAdmin && !routeDeclaration.requiredRoles.some((role) => bindProps.user?.roles?.includes(role))) { + return window.app.setLocation("/")}>Back Home} + /> + } + } + + if (routeDeclaration.useLayout) { + app.layout.set(routeDeclaration.useLayout) + } + + // if (routeDeclaration.useHeader === true) { + // app.layout.header?.toggle(true) + // } else { + // app.layout.header?.toggle(false) + // } + + if (typeof routeDeclaration.useTitle !== "undefined") { + if (typeof routeDeclaration.useTitle === "function") { + routeDeclaration.useTitle = routeDeclaration.useTitle(route, params) + } + + document.title = `${routeDeclaration.useTitle} - ${config.app.siteName}` + } else { + document.title = config.app.siteName + } + + if (routeDeclaration.centeredContent) { + app.layout.toogleCenteredContent(true) + } else { + app.layout.toogleCenteredContent(false) + } + } + + return React.createElement( + loadable(element, { + fallback: React.createElement(bindProps.staticRenders?.PageLoad || DefaultLoadingRender), + }), + { + ...props, + ...bindProps, + url: url, + params: params, + query: query, + }) + }) +} + export const PageRender = React.memo((props) => { const navigate = useNavigate() app.location = useLocation() @@ -77,7 +152,9 @@ export const PageRender = React.memo((props) => { state = {} } - state.transitionDelay = Number((app.style.getValue("page-transition-duration") ?? "250ms").replace("ms", "")) + const transitionDuration = app.cores.style.getValue("page-transition-duration") ?? "250ms" + + state.transitionDelay = Number(transitionDuration.replace("ms", "")) app.eventBus.emit("router.navigate", to, { state, @@ -113,11 +190,14 @@ export const PageRender = React.memo((props) => { return }) } - } /> + }) \ No newline at end of file