Rewrite navigation settings panel

This commit is contained in:
Andrew Kingston 2024-03-26 16:05:01 +00:00
parent df52b6937a
commit cdac78899a
1 changed files with 136 additions and 210 deletions

View File

@ -3,60 +3,59 @@
import { get } from "svelte/store"
import Panel from "components/design/Panel.svelte"
import {
Detail,
Toggle,
Body,
Icon,
ColorPicker,
Input,
Label,
ActionGroup,
ActionButton,
DetailSummary,
Checkbox,
notifications,
Select,
Combobox,
} from "@budibase/bbui"
import {
themeStore,
selectedScreen,
screenStore,
navigationStore,
componentStore,
navigationStore as nav,
} from "stores/builder"
import { DefaultAppTheme } from "constants"
import BarButtonList from "/src/components/design/settings/controls/BarButtonList.svelte"
import PropertyControl from "components/design/settings/controls/PropertyControl.svelte"
import BarButtonList from "components/design/settings/controls/BarButtonList.svelte"
import ColorPicker from "components/design/settings/controls/ColorPicker.svelte"
import DrawerBindableInput from "components/common/bindings/DrawerBindableInput.svelte"
import DrawerBindableCombobox from "components/common/bindings/DrawerBindableCombobox.svelte"
import { getBindableProperties } from "dataBinding"
$: alignmentOptions = [
const positionOptions = [
{ value: "Top", barIcon: "PaddingTop" },
{ value: "Left", barIcon: "PaddingLeft" },
]
const alignmentOptions = [
{ value: "Left", barIcon: "TextAlignLeft" },
{ value: "Center", barIcon: "TextAlignCenter" },
{ value: "Right", barIcon: "TextAlignRight" },
]
const widthOptions = ["Max", "Large", "Medium", "Small"]
$: bindings = getBindableProperties(
$selectedScreen,
$componentStore.selectedComponentId
)
$: screenRouteOptions = $screenStore.screens
.map(screen => screen.routing?.route)
.filter(x => x != null)
const updateShowNavigation = async e => {
await screenStore.updateSetting(
get(selectedScreen),
"showNavigation",
e.detail
)
const updateShowNavigation = async show => {
await screenStore.updateSetting(get(selectedScreen), "showNavigation", show)
}
const update = async (key, value) => {
try {
let navigation = $navigationStore
let navigation = $nav
navigation[key] = value
await navigationStore.save(navigation)
await nav.save(navigation)
} catch (error) {
notifications.error("Error updating navigation settings")
}
}
const updateTextAlign = textAlignValue => {
navigationStore.syncAppNavigation({ textAlign: textAlignValue })
}
</script>
<Panel
@ -65,215 +64,142 @@
borderLeft
wide
>
<div class="generalSection">
<div class="subheading">
<Detail>General</Detail>
</div>
<div class="toggle">
<Toggle
on:change={updateShowNavigation}
<DetailSummary name="General" initiallyShow collapsible={false}>
<PropertyControl
control={Toggle}
props={{ text: "Show nav on this screen" }}
onChange={updateShowNavigation}
value={$selectedScreen?.showNavigation}
/>
<Body size="S">Show nav on this screen</Body>
</div>
</div>
</DetailSummary>
{#if $selectedScreen?.showNavigation}
<div class="divider" />
<div class="customizeSection">
<div class="subheading">
<Detail>Customize</Detail>
</div>
<div class="info">
<Icon name="InfoOutline" size="S" />
<Body size="S">These settings apply to all screens</Body>
</div>
<div class="configureLinks">
<DetailSummary name="Customize" initiallyShow collapsible={false}>
<LinksEditor />
</div>
<div class="controls">
<div class="label">
<Label size="M">Position</Label>
</div>
<ActionGroup quiet>
<ActionButton
selected={$navigationStore.navigation === "Top"}
quiet={$navigationStore.navigation !== "Top"}
icon="PaddingTop"
on:click={() => update("navigation", "Top")}
<div class="settings">
<PropertyControl
label="Position"
control={BarButtonList}
onChange={position => update("navigation", position)}
value={$nav.navigation}
props={{
options: positionOptions,
}}
/>
<ActionButton
selected={$navigationStore.navigation === "Left"}
quiet={$navigationStore.navigation !== "Left"}
icon="PaddingLeft"
on:click={() => update("navigation", "Left")}
{#if $nav.navigation === "Top"}
<PropertyControl
label="Sticky header"
control={Checkbox}
value={$nav.sticky}
onChange={width => update("navWidth", width)}
/>
</ActionGroup>
{#if $navigationStore.navigation === "Top"}
<div class="label">
<Label size="M">Sticky header</Label>
</div>
<Checkbox
value={$navigationStore.sticky}
on:change={e => update("sticky", e.detail)}
/>
<div class="label">
<Label size="M">Width</Label>
</div>
<Select
options={["Max", "Large", "Medium", "Small"]}
plaveholder={null}
value={$navigationStore.navWidth}
on:change={e => update("navWidth", e.detail)}
<PropertyControl
label="Width"
control={Select}
onChange={position => update("navigation", position)}
value={$nav.navWidth}
props={{
placeholder: null,
options: widthOptions,
}}
/>
{/if}
<div class="label">
<Label size="M">Show title</Label>
</div>
<Checkbox
value={!$navigationStore.hideTitle}
on:change={e => update("hideTitle", !e.detail)}
<PropertyControl
label="Show title"
control={Checkbox}
value={!$nav.hideTitle}
onChange={show => update("hideTitle", !show)}
/>
{#if !$navigationStore.hideTitle}
<div class="label">
<Label size="M">Title</Label>
</div>
<Input
value={$navigationStore.title}
on:change={e => update("title", e.detail)}
updateOnChange={false}
{#if !$nav.hideTitle}
<PropertyControl
label="Title"
control={DrawerBindableInput}
value={$nav.title}
onChange={title => update("title", title)}
{bindings}
props={{
updateOnChange: false,
}}
/>
<div class="label">
<Label size="M">Text align</Label>
</div>
<BarButtonList
options={alignmentOptions}
value={$navigationStore.textAlign}
onChange={updateTextAlign}
<PropertyControl
label="Text align"
control={BarButtonList}
onChange={align => nav.syncAppNavigation({ textAlign: align })}
value={$nav.textAlign}
props={{
options: alignmentOptions,
}}
/>
{/if}
<div class="label">
<Label>Background</Label>
</div>
<ColorPicker
spectrumTheme={$themeStore.theme}
value={$navigationStore.navBackground ||
DefaultAppTheme.navBackground}
on:change={e => update("navBackground", e.detail)}
<PropertyControl
label="Background"
control={ColorPicker}
onChange={color => update("navBackground", color)}
value={$nav.navBackground || DefaultAppTheme.navBackground}
props={{
spectrumTheme: $themeStore.theme,
}}
/>
<div class="label">
<Label>Text</Label>
</div>
<ColorPicker
spectrumTheme={$themeStore.theme}
value={$navigationStore.navTextColor || DefaultAppTheme.navTextColor}
on:change={e => update("navTextColor", e.detail)}
<PropertyControl
label="Text"
control={ColorPicker}
onChange={color => update("navTextColor", color)}
value={$nav.navTextColor || DefaultAppTheme.navTextColor}
props={{
spectrumTheme: $themeStore.theme,
}}
/>
</div>
</div>
</DetailSummary>
<div class="divider" />
<div class="customizeSection">
<div class="subheading">
<Detail>Logo</Detail>
</div>
<div class="controls">
<div class="label">
<Label size="M">Show logo</Label>
</div>
<Checkbox
value={!$navigationStore.hideLogo}
on:change={e => update("hideLogo", !e.detail)}
<DetailSummary name="Logo" initiallyShow collapsible={false}>
<div class="settings">
<PropertyControl
label="Show logo"
control={Checkbox}
value={!$nav.hideLogo}
onChange={show => update("hideLogo", !show)}
/>
{#if !$navigationStore.hideLogo}
<div class="label">
<Label size="M">Logo image URL</Label>
</div>
<Input
value={$navigationStore.logoUrl}
on:change={e => update("logoUrl", e.detail)}
updateOnChange={false}
{#if !$nav.hideLogo}
<PropertyControl
label="Logo image URL"
control={DrawerBindableInput}
value={$nav.logoUrl}
onChange={url => update("logoUrl", url)}
{bindings}
props={{
updateOnChange: false,
}}
/>
<div class="label">
<Label size="M">Logo link URL</Label>
</div>
<Combobox
value={$navigationStore.logoLinkUrl}
on:change={e => update("logoLinkUrl", e.detail)}
options={screenRouteOptions}
<PropertyControl
label="Logo link URL"
control={DrawerBindableCombobox}
value={$nav.logoLinkUrl}
onChange={url => update("logoLinkUrl", url)}
{bindings}
props={{
appendBindingsAsOptions: false,
options: screenRouteOptions,
}}
/>
<div class="label">
<Label size="M">New tab</Label>
</div>
<Checkbox
value={!!$navigationStore.openLogoLinkInNewTab}
on:change={e => update("openLogoLinkInNewTab", !!e.detail)}
<PropertyControl
label="New tab"
control={Checkbox}
value={$nav.openLogoLinkInNewTab}
onChange={show => update("openLogoLinkInNewTab", show)}
/>
{/if}
</div>
</div>
</DetailSummary>
{/if}
</Panel>
<style>
.generalSection {
padding: 13px 13px 25px;
}
.customizeSection {
padding: 13px 13px 25px;
}
.subheading {
margin-bottom: 10px;
}
.subheading :global(p) {
color: var(--grey-6);
}
.toggle {
.settings {
display: flex;
align-items: center;
}
.divider {
border-top: 1px solid var(--grey-3);
}
.controls {
position: relative;
display: grid;
grid-template-columns: 90px 1fr;
align-items: start;
transition: background 130ms ease-out, border-color 130ms ease-out;
border-left: 4px solid transparent;
margin: 0 calc(-1 * var(--spacing-xl));
padding: 0 var(--spacing-xl) 0 calc(var(--spacing-xl) - 4px);
gap: 12px;
}
.label {
margin-top: 16px;
transform: translateY(-50%);
}
.info {
background-color: var(--background-alt);
padding: 12px;
display: flex;
border-radius: 4px;
gap: 4px;
margin-bottom: 16px;
}
.info :global(svg) {
margin-right: 5px;
color: var(--spectrum-global-color-gray-600);
}
.configureLinks :global(button) {
margin-bottom: 20px;
width: 100%;
flex-direction: column;
justify-content: flex-start;
align-items: stretch;
gap: 8px;
}
</style>