Merge pull request #2606 from Budibase/responsive-portal

Responsive portal
This commit is contained in:
Andrew Kingston 2021-09-16 17:28:21 +01:00 committed by GitHub
commit 00b12463f6
21 changed files with 2118 additions and 262 deletions

View File

@ -21,8 +21,5 @@
.wide { .wide {
max-width: none; max-width: none;
margin: 0; margin: 0;
padding: var(--spacing-xl) calc(var(--spacing-xl) * 2)
calc(var(--spacing-xl) * 2) calc(var(--spacing-xl) * 2);
min-height: calc(100% - var(--spacing-xl) * 3);
} }
</style> </style>

View File

@ -13,7 +13,7 @@
} }
} }
export let value = false export let value = null
export let minValue = 0 export let minValue = 0
export let maxValue = 100 export let maxValue = 100

View File

@ -13,6 +13,7 @@
class="spectrum-SideNav-item" class="spectrum-SideNav-item"
class:is-selected={selected} class:is-selected={selected}
class:is-disabled={disabled} class:is-disabled={disabled}
on:click
> >
{#if heading} {#if heading}
<h2 class="spectrum-SideNav-heading" id="nav-heading-{heading}"> <h2 class="spectrum-SideNav-heading" id="nav-heading-{heading}">

View File

@ -34,7 +34,7 @@ Cypress.Commands.add("createApp", name => {
cy.get(".spectrum-Modal") cy.get(".spectrum-Modal")
.within(() => { .within(() => {
cy.get("input").eq(0).type(name).should("have.value", name).blur() cy.get("input").eq(0).type(name).should("have.value", name).blur()
cy.contains("Create app").click() cy.get(".spectrum-ButtonGroup").contains("Create app").click()
}) })
.then(() => { .then(() => {
cy.expandBudibaseConnection() cy.expandBudibaseConnection()

View File

@ -8,9 +8,28 @@
} from "@budibase/bbui" } from "@budibase/bbui"
import { admin } from "stores/portal" import { admin } from "stores/portal"
import { goto } from "@roxi/routify" import { goto } from "@roxi/routify"
import { onMount } from "svelte"
let width = window.innerWidth
$: side = width < 500 ? "right" : "left"
const resizeObserver = new ResizeObserver(entries => {
if (entries?.[0]) {
width = entries[0].contentRect?.width
}
})
onMount(() => {
const doc = document.documentElement
resizeObserver.observe(doc)
return () => {
resizeObserver.unobserve(doc)
}
})
</script> </script>
<ActionMenu> <ActionMenu align={side}>
<div slot="control" class="icon"> <div slot="control" class="icon">
<ProgressCircle size="S" value={$admin.onboardingProgress} /> <ProgressCircle size="S" value={$admin.onboardingProgress} />
</div> </div>
@ -37,7 +56,7 @@
.item { .item {
display: grid; display: grid;
align-items: center; align-items: center;
grid-template-columns: 200px 20px; grid-template-columns: 175px 20px;
} }
.icon { .icon {
cursor: pointer; cursor: pointer;

View File

@ -104,8 +104,10 @@
// remove all iframe event listeners on component destroy // remove all iframe event listeners on component destroy
onDestroy(() => { onDestroy(() => {
iframe.contentWindow.removeEventListener("bb-event", handleBudibaseEvent) if (iframe.contentWindow) {
iframe.contentWindow.removeEventListener("keydown", handleKeydownEvent) iframe.contentWindow.removeEventListener("bb-event", handleBudibaseEvent)
iframe.contentWindow.removeEventListener("keydown", handleKeydownEvent)
}
}) })
const handleBudibaseEvent = event => { const handleBudibaseEvent = event => {
@ -123,17 +125,21 @@
} else { } else {
console.warning(`Client sent unknown event type: ${type}`) console.warning(`Client sent unknown event type: ${type}`)
} }
}; }
const handleKeydownEvent = event => { const handleKeydownEvent = event => {
if ((event.key === "Delete" || event.key === "Backspace") && if (
(event.key === "Delete" || event.key === "Backspace") &&
selectedComponentId && selectedComponentId &&
['input', 'textarea'].indexOf(iframe.contentWindow.document.activeElement?.tagName.toLowerCase()) === -1) { ["input", "textarea"].indexOf(
confirmDeleteComponent(selectedComponentId); iframe.contentWindow.document.activeElement?.tagName.toLowerCase()
) === -1
) {
confirmDeleteComponent(selectedComponentId)
} }
} }
const confirmDeleteComponent = (componentId) => { const confirmDeleteComponent = componentId => {
idToDelete = componentId idToDelete = componentId
confirmDeleteDialog.show() confirmDeleteDialog.show()
} }

View File

@ -28,7 +28,7 @@
</Heading> </Heading>
</div> </div>
</div> </div>
<div> <div class="desktop">
{#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(),
@ -37,7 +37,7 @@
Never updated Never updated
{/if} {/if}
</div> </div>
<div> <div class="desktop">
<StatusLight <StatusLight
positive={!app.lockedYou && !app.lockedOther} positive={!app.lockedYou && !app.lockedOther}
notice={app.lockedYou} notice={app.lockedYou}
@ -52,7 +52,7 @@
{/if} {/if}
</StatusLight> </StatusLight>
</div> </div>
<div> <div class="desktop">
<StatusLight active={app.deployed} neutral={!app.deployed}> <StatusLight active={app.deployed} neutral={!app.deployed}>
{#if app.deployed}Published{:else}Unpublished{/if} {#if app.deployed}Published{:else}Unpublished{/if}
</StatusLight> </StatusLight>
@ -109,4 +109,10 @@
cursor: pointer; cursor: pointer;
transition: color 130ms ease; transition: color 130ms ease;
} }
@media (max-width: 640px) {
.desktop {
display: none !important;
}
}
</style> </style>

View File

@ -134,7 +134,7 @@
</script> </script>
<ModalContent <ModalContent
title={template ? "Import app" : "Create new app"} title={template ? "Import app" : "Create app"}
confirmText={template ? "Import app" : "Create app"} confirmText={template ? "Import app" : "Create app"}
onConfirm={createNewApp} onConfirm={createNewApp}
disabled={!valid} disabled={!valid}

View File

@ -41,17 +41,8 @@
<Page> <Page>
<div class="content"> <div class="content">
<Layout noPadding> <Layout noPadding>
<img alt="logo" src={$organisation.logoUrl || Logo} /> <div class="header">
<div class="info-title"> <img alt="logo" src={$organisation.logoUrl || Logo} />
<Layout noPadding gap="XS">
<Heading size="L">
Hey {$auth.user.firstName || $auth.user.email}
</Heading>
<Body>
Welcome to the {$organisation.company} portal. Below you'll find
the list of apps that you have access to.
</Body>
</Layout>
<ActionMenu align="right"> <ActionMenu align="right">
<div slot="control" class="avatar"> <div slot="control" class="avatar">
<Avatar <Avatar
@ -81,6 +72,15 @@
<MenuItem icon="LogOut" on:click={auth.logout}>Log out</MenuItem> <MenuItem icon="LogOut" on:click={auth.logout}>Log out</MenuItem>
</ActionMenu> </ActionMenu>
</div> </div>
<Layout noPadding gap="XS">
<Heading size="M">
Hey {$auth.user.firstName || $auth.user.email}
</Heading>
<Body>
Welcome to the {$organisation.company} portal. Below you'll find the
list of apps that you have access to.
</Body>
</Layout>
<Divider /> <Divider />
{#if publishedApps.length} {#if publishedApps.length}
<Heading>Apps</Heading> <Heading>Apps</Heading>
@ -137,18 +137,18 @@
overflow: auto; overflow: auto;
} }
.content { .content {
padding: 60px 0;
width: 100%; width: 100%;
} }
.header {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
}
img { img {
width: 40px; width: 40px;
margin-bottom: -12px; margin-bottom: -12px;
} }
.info-title {
display: grid;
grid-template-columns: 1fr auto;
grid-gap: var(--spacing-xl);
}
.avatar { .avatar {
display: grid; display: grid;
grid-template-columns: auto auto; grid-template-columns: auto auto;
@ -160,7 +160,6 @@
filter: brightness(110%); filter: brightness(110%);
} }
.group { .group {
margin-top: var(--spacing-s);
} }
.app { .app {
display: grid; display: grid;

View File

@ -9,6 +9,7 @@
ActionMenu, ActionMenu,
MenuItem, MenuItem,
Modal, Modal,
clickOutside,
} from "@budibase/bbui" } from "@budibase/bbui"
import ConfigChecklist from "components/common/ConfigChecklist.svelte" import ConfigChecklist from "components/common/ConfigChecklist.svelte"
import { organisation, auth } from "stores/portal" import { organisation, auth } from "stores/portal"
@ -21,6 +22,7 @@
let loaded = false let loaded = false
let userInfoModal let userInfoModal
let changePasswordModal let changePasswordModal
let mobileMenuVisible = false
$: menu = buildMenu($auth.isAdmin) $: menu = buildMenu($auth.isAdmin)
@ -71,6 +73,9 @@
return menu return menu
} }
const showMobileMenu = () => (mobileMenuVisible = true)
const hideMobileMenu = () => (mobileMenuVisible = false)
onMount(async () => { onMount(async () => {
// Prevent non-builders from accessing the portal // Prevent non-builders from accessing the portal
if ($auth.user) { if ($auth.user) {
@ -86,7 +91,11 @@
{#if $auth.user && loaded} {#if $auth.user && loaded}
<div class="container"> <div class="container">
<div class="nav"> <div
class="nav"
class:visible={mobileMenuVisible}
use:clickOutside={hideMobileMenu}
>
<Layout paddingX="L" paddingY="L"> <Layout paddingX="L" paddingY="L">
<div class="branding"> <div class="branding">
<div class="name" on:click={() => $goto("./apps")}> <div class="name" on:click={() => $goto("./apps")}>
@ -100,7 +109,12 @@
<div class="menu"> <div class="menu">
<Navigation> <Navigation>
{#each menu as { title, href, heading }} {#each menu as { title, href, heading }}
<Item selected={$isActive(href)} {href} {heading}>{title}</Item> <Item
on:click={hideMobileMenu}
selected={$isActive(href)}
{href}
{heading}>{title}</Item
>
{/each} {/each}
</Navigation> </Navigation>
</div> </div>
@ -108,30 +122,40 @@
</div> </div>
<div class="main"> <div class="main">
<div class="toolbar"> <div class="toolbar">
<div /> <div class="mobile-toggle">
<ActionMenu align="right"> <Icon hoverable name="ShowMenu" on:click={showMobileMenu} />
<div slot="control" class="avatar"> </div>
<Avatar <div class="mobile-logo">
size="M" <img
initials={$auth.initials} src={$organisation?.logoUrl || Logo}
url={$auth.user.pictureUrl} alt={$organisation?.company || "Budibase"}
/> />
<Icon size="XL" name="ChevronDown" /> </div>
</div> <div class="user-dropdown">
<MenuItem icon="UserEdit" on:click={() => userInfoModal.show()}> <ActionMenu align="right">
Update user information <div slot="control" class="avatar">
</MenuItem> <Avatar
<MenuItem size="M"
icon="LockClosed" initials={$auth.initials}
on:click={() => changePasswordModal.show()} url={$auth.user.pictureUrl}
> />
Update password <Icon size="XL" name="ChevronDown" />
</MenuItem> </div>
<MenuItem icon="UserDeveloper" on:click={() => $goto("../apps")}> <MenuItem icon="UserEdit" on:click={() => userInfoModal.show()}>
Close developer mode Update user information
</MenuItem> </MenuItem>
<MenuItem icon="LogOut" on:click={auth.logout}>Log out</MenuItem> <MenuItem
</ActionMenu> icon="LockClosed"
on:click={() => changePasswordModal.show()}
>
Update password
</MenuItem>
<MenuItem icon="UserDeveloper" on:click={() => $goto("../apps")}>
Close developer mode
</MenuItem>
<MenuItem icon="LogOut" on:click={auth.logout}>Log out</MenuItem>
</ActionMenu>
</div>
</div> </div>
<div class="content"> <div class="content">
<slot /> <slot />
@ -149,16 +173,20 @@
<style> <style>
.container { .container {
height: 100%; height: 100%;
display: grid; display: flex;
grid-template-columns: 250px 1fr; flex-direction: row;
justify-content: flex-start;
align-items: stretch; align-items: stretch;
} }
.nav { .nav {
background: var(--background); background: var(--background);
border-right: var(--border-light); border-right: var(--border-light);
overflow: auto; overflow: auto;
flex: 0 0 auto;
width: 250px;
} }
.main { .main {
flex: 1 1 auto;
display: grid; display: grid;
grid-template-rows: auto 1fr; grid-template-rows: auto 1fr;
overflow: hidden; overflow: hidden;
@ -192,11 +220,21 @@
.toolbar { .toolbar {
background: var(--background); background: var(--background);
border-bottom: var(--border-light); border-bottom: var(--border-light);
display: grid; display: flex;
grid-template-columns: 250px auto; flex-direction: row;
justify-content: space-between; justify-content: space-between;
padding: var(--spacing-m) calc(var(--spacing-xl) * 2);
align-items: center; align-items: center;
padding: var(--spacing-m) calc(var(--spacing-xl) * 2);
}
.mobile-toggle,
.mobile-logo {
display: none;
}
.user-dropdown {
flex: 1 1 auto;
display: flex;
flex-direction: row;
justify-content: flex-end;
} }
img { img {
width: 28px; width: 28px;
@ -210,4 +248,43 @@
.content { .content {
overflow: auto; overflow: auto;
} }
@media (max-width: 640px) {
.toolbar {
background: var(--background);
border-bottom: var(--border-light);
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
padding: var(--spacing-m) calc(var(--spacing-xl) * 1.5);
}
.nav {
position: absolute;
left: -250px;
height: 100%;
transition: left ease-in-out 230ms;
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: 1 1 0;
}
/* Reduce BBUI page padding */
.content :global(> *) {
padding: calc(var(--spacing-xl) * 1.5) !important;
}
}
</style> </style>

View File

@ -201,7 +201,7 @@
<Heading>Apps</Heading> <Heading>Apps</Heading>
<ButtonGroup> <ButtonGroup>
<Button secondary on:click={initiateAppImport}>Import app</Button> <Button secondary on:click={initiateAppImport}>Import app</Button>
<Button cta on:click={initiateAppCreation}>Create new app</Button> <Button cta on:click={initiateAppCreation}>Create app</Button>
</ButtonGroup> </ButtonGroup>
</div> </div>
<div class="filter"> <div class="filter">
@ -347,4 +347,10 @@
justify-content: center; justify-content: center;
align-items: center; align-items: center;
} }
@media (max-width: 640px) {
.appTable {
grid-template-columns: 1fr auto;
}
}
</style> </style>

View File

@ -272,7 +272,7 @@
}) })
</script> </script>
<Layout> <Layout noPadding>
<Layout gap="XS" noPadding> <Layout gap="XS" noPadding>
<Heading size="M">Authentication</Heading> <Heading size="M">Authentication</Heading>
<Body> <Body>
@ -285,19 +285,17 @@
<Divider /> <Divider />
<Layout gap="XS" noPadding> <Layout gap="XS" noPadding>
<Heading size="S"> <Heading size="S">
<div> <div class="provider-title">
<GoogleLogo /> <GoogleLogo />
Google <span>Google</span>
<div class="google-save-button"> <Button
<div> disabled={googleSaveButtonDisabled}
<Button size="s"
disabled={googleSaveButtonDisabled} cta
size="s" on:click={() => save([providers.google])}
cta >
on:click={() => save([providers.google])}>Save</Button Save
> </Button>
</div>
</div>
</div> </div>
</Heading> </Heading>
<Body size="S"> <Body size="S">
@ -317,12 +315,8 @@
</div> </div>
{/each} {/each}
<div class="form-row"> <div class="form-row">
<div class="field"> <Label size="L">Activated</Label>
<Label size="L">Activated</Label> <Toggle text="" bind:value={providers.google.config.activated} />
<span class="alignedToggle">
<Toggle text="" bind:value={providers.google.config.activated} />
</span>
</div>
</div> </div>
</Layout> </Layout>
{/if} {/if}
@ -330,21 +324,19 @@
<Divider /> <Divider />
<Layout gap="XS" noPadding> <Layout gap="XS" noPadding>
<Heading size="S"> <Heading size="S">
<div> <div class="provider-title">
<OidcLogo /> <OidcLogo />
OpenID Connect <span>OpenID Connect</span>
<div class="oidc-save-button"> <Button
<div> disabled={oidcSaveButtonDisabled}
<Button size="s"
disabled={oidcSaveButtonDisabled} cta
size="s" on:click={() => save([providers.oidc])}
cta >
on:click={() => save([providers.oidc])}>Save</Button Save
> </Button>
</div> </div>
</div> </Heading>
</div></Heading
>
<Body size="S"> <Body size="S">
To allow users to authenticate using OIDC, fill out the fields below. To allow users to authenticate using OIDC, fill out the fields below.
</Body> </Body>
@ -360,7 +352,8 @@
/> />
</div> </div>
{/each} {/each}
<br /> </Layout>
<Layout gap="XS" noPadding>
<Body size="S"> <Body size="S">
To customize your login button, fill out the fields below. To customize your login button, fill out the fields below.
</Body> </Body>
@ -383,54 +376,37 @@
on:change={e => onFileSelected(e)} on:change={e => onFileSelected(e)}
bind:this={fileinput} bind:this={fileinput}
/> />
</Layout> <div class="form-row">
<div class="form-row">
<div class="field">
<Label size="L">Activated</Label> <Label size="L">Activated</Label>
<span class="alignedToggle"> <Toggle
<Toggle text=""
text="" bind:value={providers.oidc.config.configs[0].activated}
bind:value={providers.oidc.config.configs[0].activated} />
/>
</span>
</div> </div>
</div> </Layout>
{/if} {/if}
</Layout> </Layout>
<style> <style>
.field {
display: flex;
align-items: center;
}
.alignedToggle {
margin-left: 63%;
}
.form-row { .form-row {
display: grid; display: grid;
grid-template-columns: 20% 1fr; grid-template-columns: 100px 1fr;
grid-gap: var(--spacing-l); grid-gap: var(--spacing-l);
align-items: center; align-items: center;
} }
span {
display: flex;
align-items: center;
gap: var(--spacing-s);
}
input { input[type="file"] {
display: none; display: none;
} }
.google-save-button { .provider-title {
display: inline-block; display: flex;
margin-left: 400px; flex-direction: row;
justify-content: space-between;
align-items: center;
gap: var(--spacing-m);
} }
.provider-title span {
.oidc-save-button { flex: 1 1 auto;
display: inline-block;
margin-left: 320px;
} }
</style> </style>

View File

@ -71,90 +71,109 @@
} }
</script> </script>
<Layout gap="XS" noPadding> <Layout noPadding>
<div class="back"> <Layout gap="XS" noPadding>
<ActionButton <div>
on:click={() => $goto("./")} <ActionButton
quiet on:click={() => $goto("./")}
size="S" quiet
icon="BackAndroid" size="S"
> icon="BackAndroid"
Back to email settings >
</ActionButton> Back to email settings
</ActionButton>
</div>
<header>
<Heading>
Email Template: {name}
</Heading>
<Button cta on:click={saveTemplate}>Save</Button>
</header>
<Body>
{description}
<br />
Change the email template here. Add dynamic content by using the bindings menu
on the right.
</Body>
</Layout>
<div>
<Tabs selected="Edit" on:select={fixMountBug}>
<Tab title="Edit">
<div class="template-editor">
<div class="template-text-editor">
<Editor
editorHeight={640}
bind:this={htmlEditor}
mode="handlebars"
on:change={e => {
selectedTemplate.contents = e.detail.value
}}
value={selectedTemplate?.contents}
/>
</div>
<div class="bindings-editor">
<Detail size="L">Bindings</Detail>
{#if mounted}
<Tabs selected="Template">
<Tab title="Template">
<TemplateBindings
title="Template Bindings"
bindings={templateBindings}
onBindingClick={setTemplateBinding}
/>
</Tab>
<Tab title="Common">
<TemplateBindings
title="Common Bindings"
bindings={$email?.definitions?.bindings?.common}
onBindingClick={setTemplateBinding}
/>
</Tab>
</Tabs>
{/if}
</div>
</div>
</Tab>
<Tab title="Preview">
<div class="preview">
<iframe title="preview" srcdoc={previewContent} />
</div>
</Tab>
</Tabs>
</div> </div>
<header>
<Heading>
Email Template: {name}
</Heading>
<Button cta on:click={saveTemplate}>Save</Button>
</header>
<Detail>Description</Detail>
<Body>{description}</Body>
<Body
>Change the email template here. Add dynamic content by using the bindings
menu on the right.</Body
>
</Layout> </Layout>
<Tabs selected="Edit" on:select={fixMountBug}>
<Tab title="Edit">
<div class="template-editor">
<Editor
editorHeight={800}
bind:this={htmlEditor}
mode="handlebars"
on:change={e => {
selectedTemplate.contents = e.detail.value
}}
value={selectedTemplate?.contents}
/>
<div class="bindings-editor">
<Detail size="L">Bindings</Detail>
{#if mounted}
<Tabs selected="Template">
<Tab title="Template">
<TemplateBindings
title="Template Bindings"
bindings={templateBindings}
onBindingClick={setTemplateBinding}
/>
</Tab>
<Tab title="Common">
<TemplateBindings
title="Common Bindings"
bindings={$email?.definitions?.bindings?.common}
onBindingClick={setTemplateBinding}
/>
</Tab>
</Tabs>
{/if}
</div>
</div>
</Tab>
<Tab title="Preview">
<div class="preview">
<iframe title="preview" srcdoc={previewContent} />
</div>
</Tab>
</Tabs>
<style> <style>
.template-editor { .template-editor {
display: grid; display: flex;
grid-template-columns: 1fr minmax(250px, 20%); flex-direction: row;
justify-content: flex-start;
align-items: stretch;
flex-wrap: wrap;
grid-gap: var(--spacing-xl); grid-gap: var(--spacing-xl);
margin-top: var(--spacing-xl); margin-top: var(--spacing-xl);
} }
.template-text-editor {
flex: 1 1 0;
min-width: 250px;
}
.bindings-editor {
margin-top: var(--spacing-s);
max-height: 640px;
overflow: auto;
flex: 0 0 300px;
}
header { header {
display: flex; display: flex;
width: 100%; width: 100%;
justify-content: space-between; justify-content: space-between;
margin-top: var(--spacing-l); align-items: flex-start;
} }
.preview { .preview {
height: 800px; height: 640px;
padding: var(--spacing-xl) 0; margin-top: calc(var(--spacing-xl) + var(--spacing-s));
position: relative; position: relative;
} }
iframe { iframe {

View File

@ -107,7 +107,7 @@
fetchSmtp() fetchSmtp()
</script> </script>
<Layout> <Layout noPadding>
<Layout noPadding gap="XS"> <Layout noPadding gap="XS">
<Heading size="M">Email</Heading> <Heading size="M">Email</Heading>
<Body> <Body>
@ -186,7 +186,7 @@
<style> <style>
.form-row { .form-row {
display: grid; display: grid;
grid-template-columns: 25% 1fr; grid-template-columns: 120px 1fr;
grid-gap: var(--spacing-l); grid-gap: var(--spacing-l);
align-items: center; align-items: center;
} }

View File

@ -95,7 +95,7 @@
<Layout noPadding> <Layout noPadding>
<Layout gap="XS" noPadding> <Layout gap="XS" noPadding>
<div class="back"> <div>
<ActionButton <ActionButton
on:click={() => $goto("./")} on:click={() => $goto("./")}
quiet quiet

View File

@ -49,7 +49,7 @@
} }
</script> </script>
<Layout> <Layout noPadding>
<Layout gap="XS" noPadding> <Layout gap="XS" noPadding>
<Heading>Users</Heading> <Heading>Users</Heading>
<Body> <Body>

View File

@ -83,7 +83,7 @@
</script> </script>
{#if $auth.isAdmin} {#if $auth.isAdmin}
<Layout> <Layout noPadding>
<Layout gap="XS" noPadding> <Layout gap="XS" noPadding>
<Heading size="M">Organisation</Heading> <Heading size="M">Organisation</Heading>
<Body> <Body>
@ -99,7 +99,7 @@
</Layout> </Layout>
<div class="fields"> <div class="fields">
<div class="field"> <div class="field">
<Label size="L">Organization name</Label> <Label size="L">Org. name</Label>
<Input thin bind:value={$values.company} /> <Input thin bind:value={$values.company} />
</div> </div>
<div class="field logo"> <div class="field logo">
@ -138,12 +138,10 @@
please let us know below. please let us know below.
</Body> </Body>
</Layout> </Layout>
<div class="fields"> <Toggle
<div class="field"> text="Send Analytics to Budibase"
<Label size="L">Send Analytics to Budibase</Label> bind:value={$values.analytics}
<Toggle text="" bind:value={$values.analytics} /> />
</div>
</div>
<div> <div>
<Button disabled={loading} on:click={saveConfig} cta>Save</Button> <Button disabled={loading} on:click={saveConfig} cta>Save</Button>
</div> </div>
@ -158,7 +156,7 @@
} }
.field { .field {
display: grid; display: grid;
grid-template-columns: 33% 1fr; grid-template-columns: 100px 1fr;
align-items: center; align-items: center;
} }
.file { .file {

View File

@ -4,7 +4,7 @@
import { capitalise } from "helpers" import { capitalise } from "helpers"
</script> </script>
<Layout> <Layout noPadding>
<Layout gap="XS" noPadding> <Layout gap="XS" noPadding>
<Heading size="M">Theming</Heading> <Heading size="M">Theming</Heading>
<Body>Customize how Budibase looks and feels.</Body> <Body>Customize how Budibase looks and feels.</Body>
@ -30,7 +30,7 @@
} }
.field { .field {
display: grid; display: grid;
grid-template-columns: 33% 1fr; grid-template-columns: 120px 1fr;
align-items: center; align-items: center;
} }
</style> </style>

View File

@ -7,6 +7,7 @@
Button, Button,
Divider, Divider,
notifications, notifications,
Label,
} from "@budibase/bbui" } from "@budibase/bbui"
import api from "builderStore/api" import api from "builderStore/api"
import { auth } from "stores/portal" import { auth } from "stores/portal"
@ -47,36 +48,25 @@
</script> </script>
{#if $auth.isAdmin} {#if $auth.isAdmin}
<Layout> <Layout noPadding>
<Layout gap="XS" noPadding> <Layout gap="XS" noPadding>
<Heading size="M">Update</Heading> <Heading size="M">Updates</Heading>
<Body> <Body>
Keep your budibase installation up to date to take advantage of the Keep your budibase installation up to date to take advantage of the
latest features, security updates and much more. latest features, security updates and much more.
</Body> </Body>
</Layout> </Layout>
<Divider size="S" /> <Divider size="S" />
<div class="fields"> {#if version}
<div class="field"> <div>
{#if version} <Label size="L">Current version</Label>
Current Version: {version} <Heading size="XS">
{/if} {version}
</div> </Heading>
<div class="field">
<Button cta on:click={updateBudibase}>Check For Updates</Button>
</div> </div>
{/if}
<div>
<Button cta on:click={updateBudibase}>Check for updates</Button>
</div> </div>
</Layout> </Layout>
{/if} {/if}
<style>
.fields {
display: grid;
grid-gap: var(--spacing-m);
}
.field {
display: grid;
grid-template-columns: 33% 1fr;
align-items: center;
}
</style>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff