Merge remote-tracking branch 'origin/cheeks-lab-day-portal-redesign' into feature/user-onboarding-overlays

This commit is contained in:
Dean 2023-01-12 09:16:09 +00:00
commit 8d35c81ac7
12 changed files with 419 additions and 257 deletions

View File

@ -42,6 +42,7 @@
justify-content: flex-start; justify-content: flex-start;
align-items: stretch; align-items: stretch;
flex: 1 1 auto; flex: 1 1 auto;
overflow-x: hidden;
} }
.main { .main {
overflow: auto; overflow: auto;
@ -57,10 +58,10 @@
padding: 50px; padding: 50px;
z-index: 1; z-index: 1;
} }
.wide { .content.wide {
max-width: none; max-width: none;
} }
.narrow { .content.narrow {
max-width: 840px; max-width: 840px;
} }
#side-panel { #side-panel {
@ -71,6 +72,7 @@
background: var(--background); background: var(--background);
border-left: var(--border-light); border-left: var(--border-light);
width: 320px; width: 320px;
max-width: calc(100vw - 48px - 48px);
overflow: auto; overflow: auto;
overflow-x: hidden; overflow-x: hidden;
transform: translateX(100%); transform: translateX(100%);
@ -81,4 +83,13 @@
#side-panel.visible { #side-panel.visible {
transform: translateX(0); transform: translateX(0);
} }
@media (max-width: 640px) {
.content {
padding: 24px;
max-width: calc(100vw - 48px) !important;
width: calc(100vw - 48px) !important;
overflow: auto;
}
}
</style> </style>

View File

@ -63,7 +63,8 @@
name="LockClosed" name="LockClosed"
hoverable hoverable
size={buttonSize} size={buttonSize}
on:click={() => { on:click={e => {
e.stopPropagation()
appLockModal.show() appLockModal.show()
}} }}
/> />

View File

@ -1,9 +1,10 @@
<script> <script>
export let narrow = false export let narrow = false
export let showMobileNav = false
</script> </script>
<div class="content"> <div class="content">
<div class="side-nav"> <div class="side-nav" class:show-mobile={showMobileNav}>
<slot name="side-nav" /> <slot name="side-nav" />
</div> </div>
<div class="main" class:narrow> <div class="main" class:narrow>
@ -28,4 +29,18 @@
.main.narrow { .main.narrow {
max-width: 600px; max-width: 600px;
} }
@media (max-width: 640px) {
.content {
flex-direction: column;
}
.side-nav:not(.show-mobile) {
display: none;
}
.side-nav.show-mobile :global(.side-nav) {
border-bottom: var(--border-light);
margin: 0 -24px;
padding: 0 24px 32px 24px;
}
}
</style> </style>

View File

@ -2,9 +2,10 @@
import { Heading } from "@budibase/bbui" import { Heading } from "@budibase/bbui"
export let title export let title
export let wrap = true
</script> </script>
<div class="header"> <div class="header" class:wrap>
<slot name="icon" /> <slot name="icon" />
<Heading size="L">{title}</Heading> <Heading size="L">{title}</Heading>
<div class="buttons"> <div class="buttons">
@ -20,10 +21,19 @@
align-items: center; align-items: center;
gap: var(--spacing-xl); gap: var(--spacing-xl);
} }
.header.wrap {
flex-wrap: wrap;
}
.header :global(.spectrum-Heading) { .header :global(.spectrum-Heading) {
flex: 1 1 auto; flex: 1 1 auto;
margin-top: -2px; margin-top: -2px;
} }
.header:not(.wrap) :global(.spectrum-Heading) {
overflow: hidden;
width: 0;
white-space: nowrap;
text-overflow: ellipsis;
}
.buttons { .buttons {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
@ -34,4 +44,9 @@
.buttons :global(> div) { .buttons :global(> div) {
display: contents; display: contents;
} }
@media (max-width: 640px) {
.wrap .buttons {
margin-bottom: var(--spacing-m);
}
}
</style> </style>

View File

@ -8,41 +8,39 @@
export let appOverview export let appOverview
</script> </script>
<div class="app-row"> <div class="app-row" on:click={() => editApp(app)}>
<div class="header"> <div class="title" data-cy={`${app.devId}`}>
<div class="title" data-cy={`${app.devId}`}> <div class="app-icon">
<div class="app-icon"> <Icon size="L" name={app.icon?.name || "Apps"} color={app.icon?.color} />
<Icon
size="L"
name={app.icon?.name || "Apps"}
color={app.icon?.color}
/>
</div>
<div class="name" data-cy="app-name-link" on:click={() => editApp(app)}>
<Heading size="S">
{app.name}
</Heading>
</div>
</div> </div>
<div class="name" data-cy="app-name-link">
<Heading size="S">
{app.name}
</Heading>
</div>
</div>
<div class="updated"> <div class="updated">
{#if app.updatedAt} {#if app.updatedAt}
{processStringSync("Updated {{ duration time 'millisecond' }} ago", { {processStringSync("Updated {{ duration time 'millisecond' }} ago", {
time: new Date().getTime() - new Date(app.updatedAt).getTime(), time: new Date().getTime() - new Date(app.updatedAt).getTime(),
})} })}
{:else} {:else}
Never updated Never updated
{/if} {/if}
</div>
</div> </div>
<div class="title app-status" class:deployed={app.deployed}> <div class="title app-status" class:deployed={app.deployed}>
<Icon size="L" name={app.deployed ? "GlobeCheck" : "GlobeStrike"} /> <Icon size="L" name={app.deployed ? "GlobeCheck" : "GlobeStrike"} />
<Body size="S">{`${window.origin}/app${app.url}`}</Body> <Body size="S">{app.deployed ? "Published" : "Unpublished"}</Body>
</div> </div>
<div data-cy={`row_actions_${app.appId}`}> <div data-cy={`row_actions_${app.appId}`}>
<div class="app-row-actions"> <div class="app-row-actions">
<AppLockModal {app} buttonSize="M" />
<Button size="S" secondary on:click={() => appOverview(app)}>
Manage
</Button>
<Button <Button
size="S" size="S"
primary primary
@ -51,10 +49,6 @@
> >
Edit Edit
</Button> </Button>
<Button size="S" secondary on:click={() => appOverview(app)}>
Manage
</Button>
<AppLockModal {app} buttonSize="M" />
</div> </div>
</div> </div>
</div> </div>
@ -64,24 +58,29 @@
background: var(--background); background: var(--background);
padding: 24px 32px; padding: 24px 32px;
border-radius: 8px; border-radius: 8px;
display: flex; display: grid;
flex-direction: column; grid-template-columns: 35% 25% 15% auto;
justify-content: flex-start;
align-items: stretch;
gap: var(--spacing-m);
}
.header {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center; align-items: center;
gap: var(--spacing-m);
transition: border 130ms ease-out;
border: 1px solid transparent;
}
.app-row:hover {
cursor: pointer;
border-color: var(--spectrum-global-color-gray-300);
} }
.updated { .updated {
color: var(--spectrum-global-color-gray-700); color: var(--spectrum-global-color-gray-700);
} }
.title,
.name {
flex: 1 1 auto;
}
.name {
width: 0;
}
.title, .title,
.app-status { .app-status {
display: flex; display: flex;
@ -106,9 +105,8 @@
gap: var(--spacing-m); gap: var(--spacing-m);
display: flex; display: flex;
flex-direction: row; flex-direction: row;
justify-content: flex-start; justify-content: flex-end;
align-items: center; align-items: center;
margin-top: var(--spacing-m);
} }
.name { .name {
@ -120,15 +118,26 @@
white-space: nowrap; white-space: nowrap;
text-overflow: ellipsis; text-overflow: ellipsis;
} }
.title :global(h1:hover) {
color: var(--spectrum-global-color-blue-600);
cursor: pointer;
transition: color 130ms ease;
}
@media (max-width: 1000px) {
.app-row {
grid-template-columns: 45% 30% auto;
}
.updated {
display: none;
}
}
@media (max-width: 800px) {
.app-row {
grid-template-columns: 1fr auto;
}
.app-status {
display: none;
}
}
@media (max-width: 640px) { @media (max-width: 640px) {
.desktop { .app-row {
display: none !important; padding: 20px;
} }
} }
</style> </style>

View File

@ -0,0 +1,13 @@
<script>
import Logo from "assets/bb-emblem.svg"
import { goto } from "@roxi/routify"
</script>
<img src={Logo} alt="Budibase Logo" on:click={() => $goto("./apps")} />
<style>
img {
width: 30px;
height: 30px;
}
</style>

View File

@ -0,0 +1,79 @@
<script>
import { Layout } from "@budibase/bbui"
import { SideNav, SideNavItem } from "components/portal/page"
import { createEventDispatcher } from "svelte"
import { isActive } from "@roxi/routify"
import UpgradeButton from "./UpgradeButton.svelte"
import { fade } from "svelte/transition"
import Logo from "./Logo.svelte"
export let visible = false
export let menu
const dispatch = createEventDispatcher()
const close = () => dispatch("close")
</script>
{#if visible}
<div
class="mobile-nav-underlay"
transition:fade={{ duration: 130 }}
on:click={close}
/>
{/if}
<div class="mobile-nav" class:visible>
<Layout noPadding gap="M">
<div on:click={close}>
<Logo />
</div>
<SideNav>
{#each menu as { title, href }}
<SideNavItem
text={title}
url={href}
active={$isActive(href)}
on:click={close}
/>
{/each}
</SideNav>
<div>
<UpgradeButton />
</div>
</Layout>
</div>
<style>
.mobile-nav {
display: none;
}
@media (max-width: 640px) {
.mobile-nav-underlay {
display: block;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1;
background: rgba(0, 0, 0, 0.5);
}
.mobile-nav {
transform: translateX(-100%);
display: block;
position: absolute;
top: 0;
left: 0;
padding: 16px 24px;
height: 100%;
width: 240px;
background: var(--background);
z-index: 2;
transition: transform 130ms ease-out;
}
.mobile-nav.visible {
transform: translateX(0);
}
}
</style>

View File

@ -0,0 +1,20 @@
<script>
import { Button } from "@budibase/bbui"
import { goto } from "@roxi/routify"
import { auth, admin } from "stores/portal"
</script>
{#if $admin.cloud && $auth?.user?.accountPortalAccess}
<Button
cta
on:click={() => {
$goto($admin.accountPortalUrl + "/portal/upgrade")
}}
>
Upgrade
</Button>
{:else if !$admin.cloud && $auth.isAdmin}
<Button cta on:click={() => $goto("/builder/portal/account/upgrade")}>
Upgrade
</Button>
{/if}

View File

@ -0,0 +1,78 @@
<script>
import { auth } from "stores/portal"
import { ActionMenu, Avatar, MenuItem, Icon, Modal } from "@budibase/bbui"
import { goto } from "@roxi/routify"
import ProfileModal from "components/settings/ProfileModal.svelte"
import ChangePasswordModal from "components/settings/ChangePasswordModal.svelte"
import ThemeModal from "components/settings/ThemeModal.svelte"
import APIKeyModal from "components/settings/APIKeyModal.svelte"
let themeModal
let profileModal
let updatePasswordModal
let apiKeyModal
const logout = async () => {
try {
await auth.logout()
} catch (error) {
// Swallow error and do nothing
}
}
</script>
<ActionMenu align="right" dataCy="user-menu">
<div slot="control" class="user-dropdown">
<Avatar size="L" initials={$auth.initials} url={$auth.user.pictureUrl} />
<Icon size="XL" name="ChevronDown" />
</div>
<MenuItem icon="Moon" on:click={() => themeModal.show()} dataCy="theme">
Theme
</MenuItem>
<MenuItem
icon="UserEdit"
on:click={() => profileModal.show()}
dataCy="user-info"
>
My profile
</MenuItem>
<MenuItem icon="LockClosed" on:click={() => updatePasswordModal.show()}>
Update password
</MenuItem>
<MenuItem icon="Key" on:click={() => apiKeyModal.show()} dataCy="api-key">
View API key
</MenuItem>
<MenuItem icon="UserDeveloper" on:click={() => $goto("../apps")}>
Close developer mode
</MenuItem>
<MenuItem dataCy="user-logout" icon="LogOut" on:click={logout}>
Log out
</MenuItem>
</ActionMenu>
<Modal bind:this={themeModal}>
<ThemeModal />
</Modal>
<Modal bind:this={profileModal}>
<ProfileModal />
</Modal>
<Modal bind:this={updatePasswordModal}>
<ChangePasswordModal />
</Modal>
<Modal bind:this={apiKeyModal}>
<APIKeyModal />
</Modal>
<style>
.user-dropdown {
display: flex;
flex-direction: row;
justify-content: flex-end;
align-items: center;
gap: var(--spacing-s);
}
.user-dropdown:hover {
cursor: pointer;
filter: brightness(110%);
}
</style>

View File

@ -1,30 +1,15 @@
<script> <script>
import { isActive, redirect, goto, url } from "@roxi/routify" import { isActive, redirect, goto, url } from "@roxi/routify"
import { import { Icon, notifications, Tabs, Tab } from "@budibase/bbui"
Icon,
Avatar,
ActionMenu,
MenuItem,
Modal,
notifications,
Tabs,
Tab,
Button,
} from "@budibase/bbui"
import { organisation, auth, admin as adminStore } from "stores/portal" import { organisation, auth, admin as adminStore } from "stores/portal"
import { onMount } from "svelte" import { onMount } from "svelte"
import ProfileModal from "components/settings/ProfileModal.svelte"
import ChangePasswordModal from "components/settings/ChangePasswordModal.svelte"
import ThemeModal from "components/settings/ThemeModal.svelte"
import APIKeyModal from "components/settings/APIKeyModal.svelte"
import Logo from "assets/bb-emblem.svg"
import { isEnabled, TENANT_FEATURE_FLAGS } from "helpers/featureFlags" import { isEnabled, TENANT_FEATURE_FLAGS } from "helpers/featureFlags"
import UpgradeButton from "./_components/UpgradeButton.svelte"
import MobileMenu from "./_components/MobileMenu.svelte"
import Logo from "./_components/Logo.svelte"
import UserDropdown from "./_components/UserDropdown.svelte"
let loaded = false let loaded = false
let themeModal
let profileModal
let updatePasswordModal
let apiKeyModal
let mobileMenuVisible = false let mobileMenuVisible = false
let activeTab = "Apps" let activeTab = "Apps"
@ -91,14 +76,6 @@
return menu return menu
} }
const logout = async () => {
try {
await auth.logout()
} catch (error) {
// Swallow error and do nothing
}
}
const showMobileMenu = () => (mobileMenuVisible = true) const showMobileMenu = () => (mobileMenuVisible = true)
const hideMobileMenu = () => (mobileMenuVisible = false) const hideMobileMenu = () => (mobileMenuVisible = false)
@ -122,92 +99,31 @@
{#if $auth.user && loaded} {#if $auth.user && loaded}
<div class="container"> <div class="container">
<div class="nav"> <div class="nav">
<div class="branding" on:click={() => $goto("./apps")}> <div class="branding">
<img src={Logo} alt="Logotype" /> <Logo />
</div> </div>
<Tabs selected={activeTab}> <div class="desktop">
{#each menu as { title, href }} <Tabs selected={activeTab}>
<Tab {title} on:click={() => $goto(href)} /> {#each menu as { title, href }}
{/each} <Tab {title} on:click={() => $goto(href)} />
</Tabs> {/each}
<div class="toolbar"> </Tabs>
<div class="mobile-toggle"> </div>
<Icon hoverable name="ShowMenu" on:click={showMobileMenu} /> <div class="mobile">
</div> <Icon hoverable name="ShowMenu" on:click={showMobileMenu} />
<div class="mobile-logo"> </div>
<img <div class="desktop">
src={$organisation?.logoUrl || Logo} <UpgradeButton />
alt={$organisation?.company || "Budibase"} </div>
/> <div class="dropdown">
</div> <UserDropdown />
{#if !$adminStore.cloud && $auth.isAdmin}
<Button cta on:click={() => $goto("/builder/portal/account/upgrade")}>
Upgrade
</Button>
{/if}
<div class="user-dropdown">
<ActionMenu align="right" dataCy="user-menu">
<div slot="control" class="avatar">
<Avatar
size="L"
initials={$auth.initials}
url={$auth.user.pictureUrl}
/>
<Icon size="XL" name="ChevronDown" />
</div>
<MenuItem
icon="Moon"
on:click={() => themeModal.show()}
dataCy="theme"
>
Theme
</MenuItem>
<MenuItem
icon="UserEdit"
on:click={() => profileModal.show()}
dataCy="user-info"
>
My profile
</MenuItem>
<MenuItem
icon="LockClosed"
on:click={() => updatePasswordModal.show()}
>
Update password
</MenuItem>
<MenuItem
icon="Key"
on:click={() => apiKeyModal.show()}
dataCy="api-key"
>
View API key
</MenuItem>
<MenuItem icon="UserDeveloper" on:click={() => $goto("../apps")}>
Close developer mode
</MenuItem>
<MenuItem dataCy="user-logout" icon="LogOut" on:click={logout}>
Log out
</MenuItem>
</ActionMenu>
</div>
</div> </div>
</div> </div>
<div class="main"> <div class="main">
<slot /> <slot />
</div> </div>
<MobileMenu visible={mobileMenuVisible} {menu} on:close={hideMobileMenu} />
</div> </div>
<Modal bind:this={themeModal}>
<ThemeModal />
</Modal>
<Modal bind:this={profileModal}>
<ProfileModal />
</Modal>
<Modal bind:this={updatePasswordModal}>
<ChangePasswordModal />
</Modal>
<Modal bind:this={apiKeyModal}>
<APIKeyModal />
</Modal>
{/if} {/if}
<style> <style>
@ -223,54 +139,30 @@
display: flex; display: flex;
flex-direction: row; flex-direction: row;
justify-content: flex-start; justify-content: flex-start;
align-items: stretch; align-items: center;
border-bottom: var(--border-light); border-bottom: var(--border-light);
padding: 0 20px; padding: 0 24px;
gap: 24px; gap: 24px;
position: relative;
} }
/* Customise tabs appearance*/
.nav :global(.spectrum-Tabs) { .nav :global(.spectrum-Tabs) {
margin-bottom: -2px; margin-bottom: -2px;
padding: 7px 0; padding: 7px 0;
flex: 1 1 auto;
}
.nav :global(.spectrum-Tabs-content) {
display: none;
} }
.nav :global(.spectrum-Tabs-itemLabel) { .nav :global(.spectrum-Tabs-itemLabel) {
font-weight: 600; font-weight: 600;
} }
.branding { .branding {
display: grid; display: grid;
place-items: center; place-items: center;
} }
.avatar {
display: grid;
grid-template-columns: auto auto;
place-items: center;
grid-gap: var(--spacing-s);
}
.avatar:hover {
cursor: pointer;
filter: brightness(110%);
}
.toolbar {
flex: 1 1 auto;
display: flex;
flex-direction: row;
justify-content: flex-end;
align-items: center;
gap: 24px;
}
.mobile-toggle,
.mobile-logo {
display: none;
}
.user-dropdown {
display: flex;
flex-direction: row;
justify-content: flex-end;
}
img {
width: 30px;
height: 30px;
}
.main { .main {
flex: 1 1 auto; flex: 1 1 auto;
display: flex; display: flex;
@ -279,38 +171,29 @@
align-items: stretch; align-items: stretch;
overflow: auto; overflow: auto;
} }
.mobile {
display: none;
}
.desktop {
display: contents;
}
@media (max-width: 640px) { @media (max-width: 640px) {
.toolbar { .mobile {
background: var(--background); display: contents;
border-bottom: var(--border-light); }
display: flex; .desktop {
flex-direction: row; display: none;
justify-content: space-between;
align-items: center;
padding: var(--spacing-m) calc(var(--spacing-xl) * 1.5);
} }
.nav { .nav {
flex: 0 0 52px;
justify-content: space-between;
}
.branding {
position: absolute; position: absolute;
left: -250px; left: 50%;
height: 100%; top: 50%;
transition: left ease-in-out 230ms; transform: translateX(-50%) translateY(-50%);
z-index: 100;
}
.nav.visible {
left: 0;
box-shadow: 0 0 80px 20px rgba(0, 0, 0, 0.3);
}
.mobile-toggle,
.mobile-logo {
display: block;
}
.mobile-toggle,
.user-dropdown {
flex: 0 1 0;
} }
} }
</style> </style>

View File

@ -49,8 +49,6 @@
) )
: true) : true)
) )
$: lockedApps = filteredApps.filter(app => app?.lockedYou || app?.lockedOther)
$: unlocked = lockedApps?.length === 0
$: automationErrors = getAutomationErrors(enrichedApps) $: automationErrors = getAutomationErrors(enrichedApps)
const enrichApps = (apps, user, sortBy) => { const enrichApps = (apps, user, sortBy) => {
@ -309,7 +307,7 @@
{/if} {/if}
</div> </div>
<div class="appTable" class:unlocked> <div class="app-table">
{#each filteredApps as app (app.appId)} {#each filteredApps as app (app.appId)}
<AppRow {app} {editApp} {appOverview} /> <AppRow {app} {editApp} {appOverview} />
{/each} {/each}
@ -356,11 +354,6 @@
gap: var(--spacing-xl); gap: var(--spacing-xl);
flex-wrap: wrap; flex-wrap: wrap;
} }
@media (max-width: 1000px) {
.img-logo {
display: none;
}
}
.app-actions { .app-actions {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
@ -369,19 +362,15 @@
gap: var(--spacing-xl); gap: var(--spacing-xl);
} }
.appTable { .app-table {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: flex-start; justify-content: flex-start;
align-items: stretch; align-items: stretch;
gap: 24px; gap: var(--spacing-xl);
overflow: hidden;
} }
@media (max-width: 640px) {
.appTable {
grid-template-columns: 1fr auto !important;
}
}
.empty-wrapper { .empty-wrapper {
flex: 1 1 auto; flex: 1 1 auto;
height: 100%; height: 100%;
@ -394,4 +383,23 @@
width: 160px; width: 160px;
height: 160px; height: 160px;
} }
@media (max-width: 1000px) {
.img-logo {
display: none;
}
}
@media (max-width: 640px) {
.app-actions {
margin-top: var(--spacing-xl);
margin-bottom: calc(-1 * var(--spacing-m));
}
/* Hide download apps icon */
.app-actions :global(> .spectrum-Icon) {
display: none;
}
.app-actions > :global(*) {
flex: 0 0 50%;
}
}
</style> </style>

View File

@ -120,7 +120,7 @@
<Breadcrumb url={$url("../")} text="Apps" /> <Breadcrumb url={$url("../")} text="Apps" />
<Breadcrumb text={app?.name} /> <Breadcrumb text={app?.name} />
</Breadcrumbs> </Breadcrumbs>
<Header title={app?.name}> <Header title={app?.name} wrap={false}>
<div slot="icon"> <div slot="icon">
<EditableIcon <EditableIcon
{app} {app}
@ -132,28 +132,46 @@
</div> </div>
<div slot="buttons"> <div slot="buttons">
<AppLockModal {app} /> <AppLockModal {app} />
<Button <span class="desktop">
size="M" <Button
quiet size="M"
secondary quiet
disabled={!isPublished} secondary
on:click={viewApp} disabled={!isPublished}
dataCy="view-app" on:click={viewApp}
> dataCy="view-app"
View >
</Button> View
<Button </Button>
size="M" </span>
cta <span class="desktop">
disabled={appLocked && !lockedByYou} <Button
on:click={editApp} size="M"
> cta
Edit disabled={appLocked && !lockedByYou}
</Button> on:click={editApp}
>
Edit
</Button>
</span>
<ActionMenu align="right" dataCy="app-overview-menu-popover"> <ActionMenu align="right" dataCy="app-overview-menu-popover">
<span slot="control" class="app-overview-actions-icon"> <span slot="control" class="app-overview-actions-icon">
<Icon hoverable name="More" /> <Icon hoverable name="More" />
</span> </span>
<span class="mobile">
<MenuItem icon="Globe" disabled={!isPublished} on:click={viewApp}>
View
</MenuItem>
</span>
<span class="mobile">
<MenuItem
icon="Edit"
disabled={appLocked && !lockedByYou}
on:click={editApp}
>
Edit
</MenuItem>
</span>
<MenuItem <MenuItem
on:click={() => exportApp({ published: false })} on:click={() => exportApp({ published: false })}
icon="DownloadFromCloud" icon="DownloadFromCloud"
@ -177,7 +195,7 @@
</ActionMenu> </ActionMenu>
</div> </div>
</Header> </Header>
<Content> <Content showMobileNav>
<SideNav slot="side-nav"> <SideNav slot="side-nav">
<SideNavItem <SideNavItem
text="Overview" text="Overview"
@ -237,3 +255,15 @@
/> />
</ConfirmDialog> </ConfirmDialog>
{/key} {/key}
<style>
.desktop {
display: contents;
}
@media (max-width: 640px) {
.desktop {
display: none;
}
}
</style>