diff --git a/src/components/layout/layout.js b/src/components/layout/layout.js
index 7d49b0c9..ec225295 100644
--- a/src/components/layout/layout.js
+++ b/src/components/layout/layout.js
@@ -31,14 +31,49 @@ export const Layout = ({ children }) => {
setLoggingOut(false)
}
const removeTrailingSlash = (url) => url.endsWith("/") ? url.slice(0, url.length - 1) : url
+ const getRouteAncestors = (route, ancestors=[]) => {
+ if (!route.parent) return ancestors
+ const parent = routes.find((r) => r.path === route.parent)
+ return getRouteAncestors(parent, [...ancestors, parent])
+ }
+ const makeMenuRoute = (route, props, children=undefined) => ({
+ key: route.path,
+ label: (
+ {route.text}
+ ),
+ children,
+ ...props
+ })
+ const generateMenuRoute = (route) => {
+ // We don't include any routes text as menu items
+ if (!route.text) return null
+ // If the route is not a submenu, include it as a top-level menu item
+ if (!route.subMenu) return makeMenuRoute(route)
+ // Route is a submenu, include children routes as well.
+ const childrenRoutes = routes.filter((r) => r.text && r.parent === route.path)
+ // The submenus looked really bad, removing for the time being.
+ return makeMenuRoute(route)
+ // return makeMenuRoute(route, {}, childrenRoutes.map((c) => generateMenuRoute(c)).filter((r) => r !== null))
+ }
+ const menuRoutes = [
+ // These 3 empty items are a legacy styling thing that affect spacing.
+ makeMenuRoute({}, { key: 0, style: { visibility: "hidden" } }),
+ makeMenuRoute({}, { key: 1, style: { visibility: "hidden" } }),
+ makeMenuRoute({}, { key: 2, style: { visibility: "hidden" } }),
+ ...routes.filter((r) => r.text && !r.parent).map((route) => generateMenuRoute(route)),
+ ]
+ /**
+ * 1) Find the routes whose paths exactly match the current URL path
+ * 2) Also include all parents of routes whose paths are matched in (1)
+ */
const activeRoutes = routes.filter((route) => (
// route.text !== "" &&
removeTrailingSlash(`${baseLinkPath}${route.path}`) === removeTrailingSlash(location.pathname)
)).flatMap((route) => ([
route,
- ...routes.filter((m) => m.path === route.parent)
+ ...getRouteAncestors(route)
])).map((route) => route.path)
-
+ console.log(menuRoutes, activeRoutes)
return (
@@ -50,13 +85,16 @@ export const Layout = ({ children }) => {
theme="light"
mode="horizontal"
selectedKeys={activeRoutes}
+ items={ menuRoutes }
style={{ display: "flex", flexGrow: 1, justifyContent: "flex-end" }}
>
{routes.map(m => m['text'] !== '' && (
- {m.text}
+
+ {m.text}
+
))}
{context.workspaces_enabled && !apiLoading && (
appstoreContext.links.map((link) => (
diff --git a/src/contexts/environment-context.js b/src/contexts/environment-context.js
index 96fe0863..09c67fc7 100644
--- a/src/contexts/environment-context.js
+++ b/src/contexts/environment-context.js
@@ -10,6 +10,7 @@ import {
SearchView,
SplashScreenView,
WorkspaceSignupView,
+ EduhelxAssignmentView
} from '../views'
// Setup global csrf token
@@ -43,7 +44,7 @@ export const EnvironmentProvider = ({ children }) => {
// If workspace module is enabled, all relevant paths will be added. (/workspaces/active, workspace/available, ...)
// Note: `parent` property refers to another equivalent or encapsulating route that occupies an entry in the site's header.
// It's important to include this if applicable so that the header entry stays active, e.g. on subroutes of workspaces.
- const generateRoutes = (searchEnabled, workspaceEnabled) => {
+ const generateRoutes = (searchEnabled, workspaceEnabled, isEduhelx) => {
const baseRoutes = [];
if (searchEnabled === 'true') {
// route homepage to search if search is enabled
@@ -55,13 +56,18 @@ export const EnvironmentProvider = ({ children }) => {
if (searchEnabled === 'false') {
baseRoutes.push({ path: '/', parent: '/workspaces', text: '', Component: AvailableView })
}
- baseRoutes.push({ path: '/workspaces', text: 'Workspaces', Component: AvailableView })
+ baseRoutes.push({ path: '/workspaces', text: 'Workspaces', subMenu: true, Component: AvailableView })
baseRoutes.push({ path: '/workspaces/login', parent: '/workspaces', text: '', Component: WorkspaceLoginView })
baseRoutes.push({ path: '/workspaces/login/success', parent: '/workspaces', text: '', Component: LoginSuccessRedirectView })
baseRoutes.push({ path: '/workspaces/signup/social', parent: '/workspaces', text: '', Component: WorkspaceSignupView })
baseRoutes.push({ path: '/workspaces/available', parent: '/workspaces', text: '', Component: AvailableView })
- baseRoutes.push({ path: '/workspaces/active', parent: '/workspaces', text: '', Component: ActiveView })
+ baseRoutes.push({ path: '/workspaces/active', parent: '/workspaces', text: 'Active', Component: ActiveView })
baseRoutes.push({ path: '/connect/:app_name/:app_url', parent: '/workspaces', text: '', Component: SplashScreenView })
+
+ if (isEduhelx) {
+ baseRoutes.push({ path: '/workspaces/edu', parent: '/workspaces', subMenu: true, text: 'Eduhelx', Component: () => null })
+ baseRoutes.push({ path: '/workspaces/edu/assignment', parent: '/workspaces/edu', text: 'Assignments', Component: EduhelxAssignmentView })
+ }
}
if (searchEnabled === 'false' && workspaceEnabled === 'false') {
// route homepage to support page if both search and workspaces are disabled
@@ -106,7 +112,7 @@ export const EnvironmentProvider = ({ children }) => {
// If workspace is enabled, all routes should have a '/helx' basePath as the ui is embedded in the appstore
useEffect(() => {
if (Object.keys(context).length !== 0) {
- const routes = generateRoutes(context.search_enabled, context.workspaces_enabled);
+ const routes = generateRoutes(context.search_enabled, context.workspaces_enabled, context.brand === "eduhelx");
setAvailableRoutes(routes);
if (context.workspaces_enabled === 'true') {
setBasePath('/helx/');