Tracardi / tracardi-gui

Tracardi ReactJs Graphical User Interface
Other
21 stars 25 forks source link

Use route config file make autoload menu and route component #257

Open ryomahan opened 1 year ago

ryomahan commented 1 year ago

config file like this:

/**
 *
 * route includes:
 *        // menu use
 *        icon: ReactIcons | default null
 *        style: {str: str} | default null
 *
 *        // route use
 *        exact: boolean
 *        redirect: string | default ""
 *        *path: string
 *
 *        // route extra use
 *        private: boolean | default false
 *        errorBoundary: boolean | default false
 *        title: string | default ""
 *        roles: [str] | default []
 *        *component: React.Component | required if not children and not redirect
 *
 *        tabs: [tab] | default []
 *        children: [route] | default []
 */

const routes = [
  {
    title: "",
    path: "/",
    redirect: "/dashboard",
    component: null,

    menu: false,
    exact: true,
    private: true,
    errorBoundary: false,

    icon: null,
    style: null,
    roles: ["admin", "developer", "marketer", "maintainer"],
  },
  {
    title: "",
    path: "/flow/collection/edit/:id",
    redirect: "",
    component: React.lazy(() => import("@c/flow/FlowEditor")),

    menu: false,
    exact: true,
    private: true,
    errorBoundary: false,

    roles: ["admin", "developer"],
  },

  {
    title: "menu.dashboard",
    path: "/dashboard",
    redirect: "",
    component: React.lazy(() => import("@views/Dashboard")),

    menu: true,
    exact: true,
    private: false,
    errorBoundary: false,

    style: { marginBottom: 20 },
    icon: () => { return <VscDashboard size={20} /> },
    roles: ["admin", "developer", "marketer", "maintainer"],
  },
  ...
]

export routes

then make AppBox and MainMenu roughly like this:

const AppRoutesList = ({ routes }) => {
  const pathname = useLocation().pathname

  return routes.map((route, key) => {
    return (
      route?.private
        ?
        <Route path={route.path} exact={route.exact} key={`private-${route.title}-${key}`}>
          {
            isAuth()
              ?
              hasPermission(route.roles)
                ?
                <>
                  {
                    route.redirect
                      ? <Redirect to={route.redirect} />
                      :
                      route?.errorBoundary
                        ?
                        <ErrorBoundary>
                          <Suspense fallback={<CenteredCircularProgress/>}>
                            { route.title && <TopBar>{T(route.title)}</TopBar> }

                            {
                              route?.tabs && route?.tabs.length
                                ? <AppTabs tabs={route.tabs} />
                                : <route.component />
                            }
                          </Suspense>
                        </ErrorBoundary>
                        :
                        <Suspense fallback={<CenteredCircularProgress/>}>
                          { route?.title && <TopBar>{T(route.title)}</TopBar> }

                          {
                            route?.tabs && route?.tabs.length
                              ? <AppTabs tabs={route.tabs} />
                              : <route.component />
                          }
                        </Suspense>
                  }
                </>
                : <NotAllowed />
              : <Redirect to={{ pathname: "/login", state: { from: pathname } }} />
          }
        </Route>
        :
        <Route key={`${route.title}-${key}`} path={route.path} exact={route.exact}>
          {
            route?.redirect
              ? <Redirect to={route.path} />
              :
              <>
                {
                  route?.errorBoundary
                    ? <ErrorBoundary>
                      <Suspense fallback={<CenteredCircularProgress/>}>
                        { route?.title && <TopBar>{T(route.title)}</TopBar> }
                        {
                          route?.tabs && route?.tabs.length
                            ? <AppTabs tabs={route.tabs} />
                            : <route.component />
                        }
                      </Suspense>
                    </ErrorBoundary>
                    : <Suspense fallback={<CenteredCircularProgress/>}>
                      { route?.title && <TopBar>{T(route.title)}</TopBar> }
                      {
                        route?.tabs && route?.tabs.length
                          ? <AppTabs tabs={route.tabs} />
                          : <route.component />
                      }
                    </Suspense>
                }
              </>
          }
        </Route>
    )
  })
}

then we can just change routes.js to create new menu and route