UNPKG

3.52 kBTypeScriptView Raw
1import React, { ReactNode } from 'react';
2
3import { StaticRouter, matchPath } from 'react-router';
4import { Switch, Route, BrowserRouter, Link } from 'react-router-dom';
5
6//import {useContext} from "react"
7//import {__RouterContext} from "react-router"
8
9import RedirectWithStatus from './redirect-w-status';
10import AttachRequest from '../dist/components/attach-request';
11
12/**
13 * Implementation of the RoutingAbstractionLayer
14 *
15 */
16
17export interface IRoute {
18
19 /**
20 * the relative path of the route, e.g. "/" for the root, or "/something"
21 */
22 path: string,
23
24 /**
25 * The http method of the route, e.g. get, post, ...
26 */
27 method: string,
28
29 /**
30 * array of callbacks to be used of a route before handing over to the "*"-callback
31 */
32 middlewares: Array<any>,
33
34
35 /**
36 *
37 * @param props any props to be passed to the Component to be rendered
38 * @return rendered(!) ReactNode of the Route, e.g. (<TestPage {...props}/>)
39 */
40 render?: (props: any) => ReactNode,
41
42 component?: any,
43
44 /**
45 * The displayed name of the route (e.g. in Menu)
46 */
47 name: string,
48
49 /**
50 * exact route required?
51 */
52 exact: boolean,
53
54 /**
55 * a custom type to be used to distinguish different types of Routes
56 */
57 customType?: any
58
59}
60
61export interface IRedirect {
62 /**
63 * the path to be redirected , e.g. '/any'
64 */
65 from: string,
66
67 /**
68 * the path to be redirected to, e.g. "/"
69 */
70 to: string,
71
72 /**
73 * the http-status code to use when redirecting, e.g. 301
74 */
75 status: number
76}
77
78interface RoutedAppProps {
79 routes: Array<IRoute>,
80 redirects: Array<IRedirect>
81};
82
83
84const RoutedApp: React.SFC<RoutedAppProps> = (props) => {
85 //.filter(({ customType }) => customType !== Types.IFRAME)
86 // (p) => render(Object.assign({},p, props))
87 //console.log("RoutedApp: " , useContext(__RouterContext))
88
89 const routes = props.routes.map(({ path, exact, component, render }, i) => {
90 console.log("routepath: ", path)
91 // NOT using routeConfig.pathToRoute(path) for the Router includes a basename already!
92 return render !== undefined ? <Route key={'ROUTE_'+i} exact={exact} path={path} render={render} />:
93 <Route key={'ROUTE_'+i} exact={exact} path={path} component={component} />
94 });
95
96 const redirects = props.redirects.map(({ from, to, status }, i) =>
97 <RedirectWithStatus key={'REDIRECT_'+i} from={from} to={to} status={status} />
98 );
99
100
101 return <Switch>
102 {routes}
103 {redirects}
104 </Switch>;
105
106};
107
108/**
109 * TODO when we use an internal link that attaches a path-parameter, do we get this here? maybe we need to force a reload from the server
110 *
111 * @param routes
112 * @param redirects
113 * @param basename
114 * @returns {any}
115 */
116export const createClientApp = (routes: Array<IRoute>, redirects: Array<IRedirect>, basename: string) => {
117 return <BrowserRouter basename={basename}>
118 <AttachRequest>
119 <RoutedApp routes={routes} redirects={redirects}/>
120 </AttachRequest>
121 </BrowserRouter>;
122};
123
124export const createServerApp = (
125 routes: Array<IRoute>,
126 redirects: Array<IRedirect>,
127 basename: string,
128 url: string,
129 context: any,
130 request: any) => {
131
132 return <StaticRouter context={context} location={url} basename={basename}>
133 <AttachRequest request={request}>
134 <RoutedApp routes={routes} redirects={redirects}/>
135 </AttachRequest>
136 </StaticRouter>;
137};
\No newline at end of file