Centralise menu logic and show full menu on mobile
This commit is contained in:
parent
abd84118d9
commit
5d24fe0a13
|
@ -6,9 +6,9 @@
|
||||||
import UpgradeButton from "./UpgradeButton.svelte"
|
import UpgradeButton from "./UpgradeButton.svelte"
|
||||||
import { fade } from "svelte/transition"
|
import { fade } from "svelte/transition"
|
||||||
import Logo from "./Logo.svelte"
|
import Logo from "./Logo.svelte"
|
||||||
|
import { menu } from "stores/portal"
|
||||||
|
|
||||||
export let visible = false
|
export let visible = false
|
||||||
export let menu
|
|
||||||
|
|
||||||
const dispatch = createEventDispatcher()
|
const dispatch = createEventDispatcher()
|
||||||
|
|
||||||
|
@ -28,13 +28,28 @@
|
||||||
<Logo />
|
<Logo />
|
||||||
</div>
|
</div>
|
||||||
<SideNav>
|
<SideNav>
|
||||||
{#each menu as { title, href }}
|
{#each $menu as { title, href, subPages }}
|
||||||
<SideNavItem
|
{#if !subPages?.length}
|
||||||
text={title}
|
<SideNavItem
|
||||||
url={href}
|
text={title}
|
||||||
active={$isActive(href)}
|
url={href}
|
||||||
on:click={close}
|
active={$isActive(href)}
|
||||||
/>
|
on:click={close}
|
||||||
|
/>
|
||||||
|
{/if}
|
||||||
|
{/each}
|
||||||
|
{#each $menu as { title, href, subPages }}
|
||||||
|
{#if subPages?.length}
|
||||||
|
<div class="category">{title}</div>
|
||||||
|
{#each subPages as { title, href }}
|
||||||
|
<SideNavItem
|
||||||
|
text={title}
|
||||||
|
url={href}
|
||||||
|
active={$isActive(href)}
|
||||||
|
on:click={close}
|
||||||
|
/>
|
||||||
|
{/each}
|
||||||
|
{/if}
|
||||||
{/each}
|
{/each}
|
||||||
</SideNav>
|
</SideNav>
|
||||||
<div>
|
<div>
|
||||||
|
@ -47,6 +62,13 @@
|
||||||
.mobile-nav {
|
.mobile-nav {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
.category {
|
||||||
|
color: var(--spectrum-global-color-gray-600);
|
||||||
|
font-size: var(--font-size-s);
|
||||||
|
margin-left: var(--spacing-m);
|
||||||
|
margin-top: 24px;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
@media (max-width: 640px) {
|
@media (max-width: 640px) {
|
||||||
.mobile-nav-underlay {
|
.mobile-nav-underlay {
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
<script>
|
<script>
|
||||||
import { isActive, redirect, goto, url } from "@roxi/routify"
|
import { isActive, redirect, goto, url } from "@roxi/routify"
|
||||||
import { Icon, notifications, Tabs, Tab } from "@budibase/bbui"
|
import { Icon, notifications, Tabs, Tab } from "@budibase/bbui"
|
||||||
import { organisation, auth, admin as adminStore } from "stores/portal"
|
import { organisation, auth, menu } from "stores/portal"
|
||||||
import { onMount } from "svelte"
|
import { onMount } from "svelte"
|
||||||
import { isEnabled, TENANT_FEATURE_FLAGS } from "helpers/featureFlags"
|
|
||||||
import UpgradeButton from "./_components/UpgradeButton.svelte"
|
import UpgradeButton from "./_components/UpgradeButton.svelte"
|
||||||
import MobileMenu from "./_components/MobileMenu.svelte"
|
import MobileMenu from "./_components/MobileMenu.svelte"
|
||||||
import Logo from "./_components/Logo.svelte"
|
import Logo from "./_components/Logo.svelte"
|
||||||
|
@ -13,10 +12,9 @@
|
||||||
let mobileMenuVisible = false
|
let mobileMenuVisible = false
|
||||||
let activeTab = "Apps"
|
let activeTab = "Apps"
|
||||||
|
|
||||||
$: menu = buildMenu($auth.isAdmin)
|
$: $url(), updateActiveTab($menu)
|
||||||
$: $url(), updateActiveTab()
|
|
||||||
|
|
||||||
const updateActiveTab = () => {
|
const updateActiveTab = menu => {
|
||||||
for (let entry of menu) {
|
for (let entry of menu) {
|
||||||
if ($isActive(entry.href)) {
|
if ($isActive(entry.href)) {
|
||||||
if (activeTab !== entry.title) {
|
if (activeTab !== entry.title) {
|
||||||
|
@ -27,55 +25,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const buildMenu = admin => {
|
|
||||||
// Standard user and developer pages
|
|
||||||
let menu = [
|
|
||||||
{
|
|
||||||
title: "Apps",
|
|
||||||
href: "/builder/portal/apps",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "Plugins",
|
|
||||||
href: "/builder/portal/plugins",
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
// Admin only pages
|
|
||||||
if (admin) {
|
|
||||||
menu = [
|
|
||||||
{
|
|
||||||
title: "Apps",
|
|
||||||
href: "/builder/portal/apps",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "Users",
|
|
||||||
href: "/builder/portal/users/users",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "Plugins",
|
|
||||||
href: "/builder/portal/plugins",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "Settings",
|
|
||||||
href: "/builder/portal/settings",
|
|
||||||
},
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if allowed access to account section
|
|
||||||
if (
|
|
||||||
isEnabled(TENANT_FEATURE_FLAGS.LICENSING) &&
|
|
||||||
($auth?.user?.accountPortalAccess || (!$adminStore.cloud && admin))
|
|
||||||
) {
|
|
||||||
menu.push({
|
|
||||||
title: "Account",
|
|
||||||
href: "/builder/portal/account",
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return menu
|
|
||||||
}
|
|
||||||
|
|
||||||
const showMobileMenu = () => (mobileMenuVisible = true)
|
const showMobileMenu = () => (mobileMenuVisible = true)
|
||||||
const hideMobileMenu = () => (mobileMenuVisible = false)
|
const hideMobileMenu = () => (mobileMenuVisible = false)
|
||||||
|
|
||||||
|
@ -104,7 +53,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="desktop">
|
<div class="desktop">
|
||||||
<Tabs selected={activeTab}>
|
<Tabs selected={activeTab}>
|
||||||
{#each menu as { title, href }}
|
{#each $menu as { title, href }}
|
||||||
<Tab {title} on:click={() => $goto(href)} />
|
<Tab {title} on:click={() => $goto(href)} />
|
||||||
{/each}
|
{/each}
|
||||||
</Tabs>
|
</Tabs>
|
||||||
|
@ -122,7 +71,7 @@
|
||||||
<div class="main">
|
<div class="main">
|
||||||
<slot />
|
<slot />
|
||||||
</div>
|
</div>
|
||||||
<MobileMenu visible={mobileMenuVisible} {menu} on:close={hideMobileMenu} />
|
<MobileMenu visible={mobileMenuVisible} on:close={hideMobileMenu} />
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
|
|
|
@ -1,40 +1,19 @@
|
||||||
<script>
|
<script>
|
||||||
import { url, isActive } from "@roxi/routify"
|
import { isActive } from "@roxi/routify"
|
||||||
import { Page } from "@budibase/bbui"
|
import { Page } from "@budibase/bbui"
|
||||||
import { Content, SideNav, SideNavItem } from "components/portal/page"
|
import { Content, SideNav, SideNavItem } from "components/portal/page"
|
||||||
import { admin, auth } from "stores/portal"
|
import { menu } from "stores/portal"
|
||||||
|
|
||||||
|
$: pages = $menu.find(x => x.title === "Account").subPages
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Page narrow>
|
<Page narrow>
|
||||||
<Content>
|
<Content>
|
||||||
<div slot="side-nav">
|
<div slot="side-nav">
|
||||||
<SideNav>
|
<SideNav>
|
||||||
<!-- Always show usage in self-host or cloud if licensing enabled-->
|
{#each pages as { title, href }}
|
||||||
<SideNavItem
|
<SideNavItem text={title} url={href} active={$isActive(href)} />
|
||||||
text="Usage"
|
{/each}
|
||||||
url={$url("./usage")}
|
|
||||||
active={$isActive("./usage")}
|
|
||||||
/>
|
|
||||||
<!-- Show the relevant hosting upgrade page-->
|
|
||||||
{#if $admin.cloud && $auth?.user?.accountPortalAccess}
|
|
||||||
<SideNavItem
|
|
||||||
text="Upgrade"
|
|
||||||
url={$admin.accountPortalUrl + "/portal/upgrade"}
|
|
||||||
/>
|
|
||||||
{:else if !$admin.cloud && admin}
|
|
||||||
<SideNavItem
|
|
||||||
text="Upgrade"
|
|
||||||
url={$url("./upgrade")}
|
|
||||||
active={$isActive("./upgrade")}
|
|
||||||
/>
|
|
||||||
{/if}
|
|
||||||
<!-- Show the billing page to licensed account holders in cloud -->
|
|
||||||
{#if $auth?.user?.accountPortalAccess && $auth.user.account.stripeCustomerId}
|
|
||||||
<SideNavItem
|
|
||||||
text="Billing"
|
|
||||||
url={$admin.accountPortalUrl + "/portal/billing"}
|
|
||||||
/>
|
|
||||||
{/if}
|
|
||||||
</SideNav>
|
</SideNav>
|
||||||
</div>
|
</div>
|
||||||
<slot />
|
<slot />
|
||||||
|
|
|
@ -1,38 +1,20 @@
|
||||||
<script>
|
<script>
|
||||||
import { url, isActive } from "@roxi/routify"
|
import { isActive } from "@roxi/routify"
|
||||||
import { Page } from "@budibase/bbui"
|
import { Page } from "@budibase/bbui"
|
||||||
import { Content, SideNav, SideNavItem } from "components/portal/page"
|
import { Content, SideNav, SideNavItem } from "components/portal/page"
|
||||||
import { admin } from "stores/portal"
|
import { menu } from "stores/portal"
|
||||||
|
|
||||||
$: wide = $isActive("./email/:template")
|
$: wide = $isActive("./email/:template")
|
||||||
|
$: pages = $menu.find(x => x.title === "Settings").subPages
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Page>
|
<Page>
|
||||||
<Content narrow={!wide}>
|
<Content narrow={!wide}>
|
||||||
<div slot="side-nav">
|
<div slot="side-nav">
|
||||||
<SideNav>
|
<SideNav>
|
||||||
<SideNavItem
|
{#each pages as { title, href }}
|
||||||
text="Auth"
|
<SideNavItem text={title} url={href} active={$isActive(href)} />
|
||||||
url={$url("./auth")}
|
{/each}
|
||||||
active={$isActive("./auth")}
|
|
||||||
/>
|
|
||||||
<SideNavItem
|
|
||||||
text="Email"
|
|
||||||
url={$url("./email")}
|
|
||||||
active={$isActive("./email")}
|
|
||||||
/>
|
|
||||||
<SideNavItem
|
|
||||||
text="Organisation"
|
|
||||||
url={$url("./organisation")}
|
|
||||||
active={$isActive("./organisation")}
|
|
||||||
/>
|
|
||||||
{#if !$admin.cloud}
|
|
||||||
<SideNavItem
|
|
||||||
text="Version"
|
|
||||||
url={$url("./version")}
|
|
||||||
active={$isActive("./version")}
|
|
||||||
/>
|
|
||||||
{/if}
|
|
||||||
</SideNav>
|
</SideNav>
|
||||||
</div>
|
</div>
|
||||||
<slot />
|
<slot />
|
||||||
|
|
|
@ -1,28 +1,20 @@
|
||||||
<script>
|
<script>
|
||||||
import { Page } from "@budibase/bbui"
|
import { Page } from "@budibase/bbui"
|
||||||
import { SideNav, SideNavItem, Content } from "components/portal/page"
|
import { SideNav, SideNavItem, Content } from "components/portal/page"
|
||||||
import { isActive, url } from "@roxi/routify"
|
import { isActive } from "@roxi/routify"
|
||||||
import { isEnabled, TENANT_FEATURE_FLAGS } from "helpers/featureFlags"
|
import { menu } from "stores/portal"
|
||||||
|
|
||||||
$: wide = $isActive("./users/index") || $isActive("./groups/index")
|
$: wide = $isActive("./users/index") || $isActive("./groups/index")
|
||||||
|
$: pages = $menu.find(x => x.title === "Users").subPages
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Page>
|
<Page>
|
||||||
<Content narrow={!wide}>
|
<Content narrow={!wide}>
|
||||||
<div slot="side-nav">
|
<div slot="side-nav">
|
||||||
<SideNav>
|
<SideNav>
|
||||||
<SideNavItem
|
{#each pages as { title, href }}
|
||||||
text="Users"
|
<SideNavItem text={title} url={href} active={$isActive(href)} />
|
||||||
url={$url("./users")}
|
{/each}
|
||||||
active={$isActive("./users")}
|
|
||||||
/>
|
|
||||||
{#if isEnabled(TENANT_FEATURE_FLAGS.USER_GROUPS)}
|
|
||||||
<SideNavItem
|
|
||||||
text="Groups"
|
|
||||||
url={$url("./groups")}
|
|
||||||
active={$isActive("./groups")}
|
|
||||||
/>
|
|
||||||
{/if}
|
|
||||||
</SideNav>
|
</SideNav>
|
||||||
</div>
|
</div>
|
||||||
<slot />
|
<slot />
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
<script>
|
||||||
|
import { redirect } from "@roxi/routify"
|
||||||
|
$redirect("./users")
|
||||||
|
</script>
|
|
@ -11,3 +11,4 @@ export { groups } from "./groups"
|
||||||
export { plugins } from "./plugins"
|
export { plugins } from "./plugins"
|
||||||
export { backups } from "./backups"
|
export { backups } from "./backups"
|
||||||
export { overview } from "./overview"
|
export { overview } from "./overview"
|
||||||
|
export { menu } from "./menu"
|
||||||
|
|
|
@ -0,0 +1,120 @@
|
||||||
|
import { derived } from "svelte/store"
|
||||||
|
import { isEnabled, TENANT_FEATURE_FLAGS } from "helpers/featureFlags"
|
||||||
|
import { admin } from "./admin"
|
||||||
|
import { auth } from "./auth"
|
||||||
|
|
||||||
|
export const menu = derived([admin, auth], ([$admin, $auth]) => {
|
||||||
|
// Standard user and developer pages
|
||||||
|
let menu = [
|
||||||
|
{
|
||||||
|
title: "Apps",
|
||||||
|
href: "/builder/portal/apps",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Plugins",
|
||||||
|
href: "/builder/portal/plugins",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
// Admin only pages
|
||||||
|
if ($auth.isAdmin) {
|
||||||
|
// Determine user sub pages
|
||||||
|
let userSubPages = [
|
||||||
|
{
|
||||||
|
title: "Users",
|
||||||
|
href: "/builder/portal/users/users",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
if (isEnabled(TENANT_FEATURE_FLAGS.USER_GROUPS)) {
|
||||||
|
userSubPages.push({
|
||||||
|
title: "Groups",
|
||||||
|
href: "/builder/portal/users/groups",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine settings sub pages
|
||||||
|
let settingsSubPages = [
|
||||||
|
{
|
||||||
|
title: "Auth",
|
||||||
|
href: "/builder/portal/settings/auth",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Email",
|
||||||
|
href: "/builder/portal/settings/email",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Organisation",
|
||||||
|
href: "/builder/portal/settings/organisation",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
if (!$admin.cloud) {
|
||||||
|
settingsSubPages.push({
|
||||||
|
title: "Version",
|
||||||
|
href: "/builder/portal/settings/version",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
menu = [
|
||||||
|
{
|
||||||
|
title: "Apps",
|
||||||
|
href: "/builder/portal/apps",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Users",
|
||||||
|
href: "/builder/portal/users",
|
||||||
|
subPages: userSubPages,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Plugins",
|
||||||
|
href: "/builder/portal/plugins",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Settings",
|
||||||
|
href: "/builder/portal/settings",
|
||||||
|
subPages: settingsSubPages,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if allowed access to account section
|
||||||
|
if (
|
||||||
|
isEnabled(TENANT_FEATURE_FLAGS.LICENSING) &&
|
||||||
|
($auth?.user?.accountPortalAccess || (!$admin.cloud && $auth.isAdmin))
|
||||||
|
) {
|
||||||
|
// Determine account sub pages
|
||||||
|
let accountSubPages = [
|
||||||
|
{
|
||||||
|
title: "Usage",
|
||||||
|
href: "/builder/portal/account/usage",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
if ($admin.cloud && $auth?.user?.accountPortalAccess) {
|
||||||
|
accountSubPages.push({
|
||||||
|
title: "Upgrade",
|
||||||
|
href: $admin.accountPortalUrl + "/portal/upgrade",
|
||||||
|
})
|
||||||
|
} else if (!$admin.cloud && admin) {
|
||||||
|
accountSubPages.push({
|
||||||
|
title: "Upgrade",
|
||||||
|
href: "/builder/portal/account/upgrade",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
$auth?.user?.accountPortalAccess &&
|
||||||
|
$auth.user.account.stripeCustomerId
|
||||||
|
) {
|
||||||
|
accountSubPages.push({
|
||||||
|
title: "Billing",
|
||||||
|
href: $admin.accountPortalUrl + "/portal/billing",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
menu.push({
|
||||||
|
title: "Account",
|
||||||
|
href: "/builder/portal/account",
|
||||||
|
subPages: accountSubPages,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return menu
|
||||||
|
})
|
Loading…
Reference in New Issue