Skip to content

Commit

Permalink
feat(core): 更新router
Browse files Browse the repository at this point in the history
  • Loading branch information
stbui committed Jan 1, 2020
1 parent b9a4e94 commit 67ac87f
Show file tree
Hide file tree
Showing 4 changed files with 115 additions and 42 deletions.
128 changes: 93 additions & 35 deletions packages/core/src/core/CoreRouter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,12 @@ import React, {
createElement,
FunctionComponent,
ComponentType,
useState,
useEffect,
} from 'react';
import { Switch, Route, Redirect } from 'react-router-dom';
import CoreRoutesWithLayout from './CoreRoutesWithLayout';
import { useGetPermissions, useAuthState } from '../auth';

export interface CoreRouterProps {
children: any;
Expand All @@ -20,7 +24,7 @@ export interface CoreRouterProps {
menu?: ComponentType;
brand?: ComponentType;
catchAll: ComponentType;
Layout: ComponentType;
layout: ComponentType;
customRoutes: any[];
}

Expand All @@ -29,64 +33,118 @@ const CoreRouter: FunctionComponent<CoreRouterProps> = ({
dashboard,
customRoutes = [],
catchAll,
Layout,
layout,
menu,
brand,
title,
...other
}) => {
if (typeof children !== 'function' && !children) {
return <div>缺失组件 &lt;Resource&gt;</div>;
}
const getPermissions = useGetPermissions();
const { authenticated } = useAuthState();
const [computedChildren, setComputedChildren] = useState([]);

const childrenArray = Children.toArray(children);
const firstChild: any = childrenArray.length > 0 ? childrenArray[0] : null;
useEffect(() => {
if (typeof children === 'function') {
initializeResources();
}
}, [authenticated]);

const initializeResources = async () => {
try {
const permissions = await getPermissions();
const resolveChildren = children;
const childrenFuncResult = resolveChildren(permissions);
if (childrenFuncResult.then) {
childrenFuncResult.then(resolvedChildren =>
setComputedChildren(
resolvedChildren
.filter(child => child)
.map(child => ({
...child,
props: {
...child.props,
key: child.props.name,
},
}))
)
);
} else {
setComputedChildren(childrenFuncResult.filter(child => child));
}
} catch (error) {
console.error(error);
}
};

const renderCustomRoutesWithoutLayout = (route, props) => {
const renderCustomRoutesWithoutLayout = (route, routeProps) => {
if (route.props.render) {
return route.props.render({ ...props });
return route.props.render({ ...routeProps, title });
}

if (route.props.component) {
return createElement(route.props.component, { ...props });
return createElement(route.props.component, {
...routeProps,
title,
});
}
};

if (typeof children !== 'function' && !children) {
return <div>缺失组件 &lt;Resource&gt;</div>;
}

const childrenToRender =
typeof children === 'function' ? computedChildren : children;

return (
<Layout {...other}>
{Children.map(children, (child: any) =>
<div>
{Children.map(childrenToRender, (child: any) =>
cloneElement(child, {
key: child.props.name,
context: 'registration',
})
)}
<Switch>
{customRoutes.map((route: any, key: any) =>
cloneElement(route, {
key,
render: props =>
renderCustomRoutesWithoutLayout(route, props),
})
)}
{Children.map(children, (child: any) => (
<Route
key={child.props.name}
path={`/${child.props.name}`}
render={props => cloneElement(child, { ...props })}
/>
))}
{dashboard ? (
<Route exact path="/" component={dashboard} />
) : firstChild ? (
<Redirect to={`/${firstChild.props.name}`} />
) : null}
{customRoutes
.filter(route => route.props.noLayout)
.map((route, key) =>
cloneElement(route, {
key,
render: routeProps =>
renderCustomRoutesWithoutLayout(
route,
routeProps
),
})
)}
<Route
render={(props: any) =>
createElement(catchAll, { ...props })
render={() =>
createElement<any>(
layout,
{
dashboard,
menu,
title,
},
<CoreRoutesWithLayout
catchAll={catchAll}
customRoutes={customRoutes.filter(
route => !route.props.noLayout
)}
dashboard={dashboard}
title={title}
>
{Children.map(childrenToRender, child =>
cloneElement(child, {
key: child.props.name,
intent: 'route',
})
)}
</CoreRoutesWithLayout>
)
}
/>
</Switch>
</Layout>
</div>
);
};

Expand Down
6 changes: 5 additions & 1 deletion packages/core/src/core/CoreRoutesWithLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,15 @@ const CoreRoutesWithLayout: FunctionComponent<CoreRoutesWithLayoutProps> = ({

return (
<Switch>
{customRoutes &&
customRoutes.map((route, key) => cloneElement(route, { key }))}
{Children.map(children, (child: any) => (
<Route
key={child.props.name}
path={`/${child.props.name}`}
render={props => cloneElement(child, { ...props })}
render={props =>
cloneElement(child, { intent: 'route', ...props })
}
/>
))}
{dashboard ? (
Expand Down
17 changes: 14 additions & 3 deletions packages/core/src/core/CoreUI.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export interface CoreUIProps {
title?: string;
dashboard?: ComponentType;
layout: ComponentType;
loginPage?: ComponentType;
loginPage?: ComponentType<any>;
catchAll: any;
menu?: ComponentType;
brand?: ComponentType;
Expand All @@ -32,12 +32,23 @@ const CoreUI: FunctionComponent<CoreUIProps> = ({
customRoutes = [],
}) => (
<Switch>
<Route exact path="/login" component={loginPage} />
{loginPage ? (
<Route
exact
path="/login"
render={props =>
React.createElement(loginPage, {
...props,
title,
})
}
/>
) : null}
<Route
path="/"
render={props => (
<CoreRouter
Layout={layout}
layout={layout}
dashboard={dashboard}
customRoutes={customRoutes}
catchAll={catchAll}
Expand Down
6 changes: 3 additions & 3 deletions packages/core/src/core/Resource.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -147,10 +147,10 @@ const ResourceRoutes: any = ({
]);
};

export default ({ context, ...other }) => {
export default ({ context = 'route', ...props }) => {
return context === 'registration' ? (
<ResourceRegister {...other} />
<ResourceRegister {...props} />
) : (
<ResourceRoutes {...other} />
<ResourceRoutes {...props} />
);
};

0 comments on commit 67ac87f

Please sign in to comment.