From 284f7fe3cc4888f30428f9f41c7c3f2ba51751d7 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Thu, 28 Mar 2024 17:58:32 +0000 Subject: [PATCH] Add client support for nav item updates --- .../client/src/components/app/Layout.svelte | 106 +++++------ .../client/src/components/app/NavItem.svelte | 164 ++++++++++++++++++ 2 files changed, 217 insertions(+), 53 deletions(-) create mode 100644 packages/client/src/components/app/NavItem.svelte diff --git a/packages/client/src/components/app/Layout.svelte b/packages/client/src/components/app/Layout.svelte index 325b3cda1e..b7f92101b4 100644 --- a/packages/client/src/components/app/Layout.svelte +++ b/packages/client/src/components/app/Layout.svelte @@ -2,9 +2,8 @@ import { getContext, setContext } from "svelte" import { writable } from "svelte/store" import { Heading, Icon, clickOutside } from "@budibase/bbui" - import { FieldTypes } from "constants" import { Constants } from "@budibase/frontend-core" - import active from "svelte-spa-router/active" + import NavItem from "./NavItem.svelte" const sdk = getContext("sdk") const { @@ -18,6 +17,7 @@ } = sdk const component = getContext("component") const context = getContext("context") + const navStateStore = writable({}) // Legacy props which must remain unchanged for backwards compatibility export let title @@ -65,7 +65,7 @@ }) setContext("layout", store) - $: validLinks = getValidLinks(links, $roleStore) + $: enrichedNavItems = enrichNavItems(links, $roleStore) $: typeClass = NavigationClasses[navigation] || NavigationClasses.None $: navWidthClass = WidthClasses[navWidth || width] || WidthClasses.Large $: pageWidthClass = WidthClasses[pageWidth || width] || WidthClasses.Large @@ -103,28 +103,52 @@ } } - const getValidLinks = (allLinks, userRoleHierarchy) => { - // Strip links missing required info - let validLinks = (allLinks || []).filter(link => link.text) - // Filter to only links allowed by the current role - return validLinks.filter(link => { - const role = link.roleId || Constants.Roles.BASIC - return userRoleHierarchy?.find(roleId => roleId === role) - }) + const enrichNavItem = navItem => { + const internalLink = isInternal(navItem.url) + return { + ...navItem, + internalLink, + url: internalLink ? navItem.url : ensureExternal(navItem.url), + } + } + + const enrichNavItems = (navItems, userRoleHierarchy) => { + if (!navItems?.length) { + return [] + } + return navItems + .filter(navitem => { + // Strip nav items without text + if (!navitem.text) { + return false + } + + // Filter to only links allowed by the current role + const role = navitem.roleId || Constants.Roles.BASIC + return userRoleHierarchy?.find(roleId => roleId === role) + }) + .map(navItem => { + const enrichedNavItem = enrichNavItem(navItem) + if (navItem.type === "sublinks" && navItem.subLinks?.length) { + enrichedNavItem.subLinks = navItem.subLinks + .filter(subLink => subLink.text) + .map(enrichNavItem) + } + return enrichedNavItem + }) } const isInternal = url => { - return url.startsWith("/") + return url?.startsWith("/") } const ensureExternal = url => { + if (!url?.length) { + return url + } return !url.startsWith("http") ? `http://${url}` : url } - const close = () => { - mobileOpen = false - } - const navigateToPortal = () => { if ($builderStore.inBuilder) return window.location.href = "/builder/apps" @@ -197,7 +221,7 @@ >