routeReducer.js 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. import {promiseWorker,actionPromise} from "./promiseReducer";
  2. import {gql} from "../actions";
  3. import {takeEvery, call} from 'redux-saga/effects';
  4. import {queries} from "../actions";
  5. import {connect} from 'react-redux';
  6. import {Route, Redirect} from 'react-router-dom';
  7. import {useEffect} from "react";
  8. export function routeReducer(state={}, {type, match}) {
  9. if (type === 'ROUTE') {
  10. return match
  11. }
  12. return state
  13. }
  14. function* routeWorker({match}) {
  15. console.log(match)
  16. if (match.path in queries) {
  17. const {name, query, variables} = queries[match.path](match)
  18. yield call(promiseWorker, actionPromise(name, gql(query, variables)))
  19. }
  20. }
  21. export function* routeWatcher() {
  22. yield takeEvery('ROUTE', routeWorker)
  23. }
  24. const RRoute = ({ action, component:Component, ...routeProps}) => {
  25. const WrapperComponent = (componentProps) => {
  26. useEffect(() =>{
  27. action(componentProps.match)
  28. })
  29. return <Component {...componentProps} />
  30. }
  31. return <Route {...routeProps} component={WrapperComponent} />
  32. }
  33. export const CRRoute = connect(null, {action: match => ({type: 'ROUTE', match})})(RRoute)
  34. const ProtectedRoute = ({ fallback='/',
  35. roles=["admin"],
  36. auth,
  37. component:Component,
  38. ...routeProps}) => {
  39. const WrapperComponent = (componentProps) => {
  40. let aclArr = auth?.payload?.sub?.acl
  41. if (!aclArr) {
  42. aclArr = ['anon']
  43. }
  44. let crossArr = [];
  45. for (const role of roles) {
  46. crossArr = [...crossArr, ...aclArr.filter(aclItem => aclItem === role)]
  47. }
  48. if (crossArr.length === 0) {
  49. return <Redirect to={fallback} />
  50. } else {
  51. return <Component {...componentProps} />
  52. }
  53. }
  54. return <CRRoute {...routeProps} component={WrapperComponent} />
  55. }
  56. export const CProtectedRoute = connect(state => ({auth: state.auth}))(ProtectedRoute)