Browse Source

Merge pull request #2606 from Budibase/responsive-portal

Responsive portal
gh-pages
Andrew Kingston 5 years ago
committed by GitHub
parent
commit
3f249ab10b
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      packages/bbui/src/Layout/Page.svelte
  2. 2
      packages/bbui/src/ProgressCircle/ProgressCircle.svelte
  3. 1
      packages/bbui/src/SideNavigation/Item.svelte
  4. 2
      packages/builder/cypress/support/commands.js
  5. 23
      packages/builder/src/components/common/ConfigChecklist.svelte
  6. 20
      packages/builder/src/components/design/AppPreview/CurrentItemPreview.svelte
  7. 12
      packages/builder/src/components/start/AppRow.svelte
  8. 2
      packages/builder/src/components/start/CreateAppModal.svelte
  9. 35
      packages/builder/src/pages/builder/apps/index.svelte
  10. 139
      packages/builder/src/pages/builder/portal/_layout.svelte
  11. 8
      packages/builder/src/pages/builder/portal/apps/index.svelte
  12. 110
      packages/builder/src/pages/builder/portal/manage/auth/index.svelte
  13. 155
      packages/builder/src/pages/builder/portal/manage/email/[template].svelte
  14. 4
      packages/builder/src/pages/builder/portal/manage/email/index.svelte
  15. 2
      packages/builder/src/pages/builder/portal/manage/users/[userId].svelte
  16. 2
      packages/builder/src/pages/builder/portal/manage/users/index.svelte
  17. 16
      packages/builder/src/pages/builder/portal/settings/organisation.svelte
  18. 4
      packages/builder/src/pages/builder/portal/settings/theming.svelte
  19. 34
      packages/builder/src/pages/builder/portal/settings/update.svelte
  20. 1002
      packages/client/yarn.lock
  21. 804
      packages/server/yarn.lock

3
packages/bbui/src/Layout/Page.svelte

@ -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>

2
packages/bbui/src/ProgressCircle/ProgressCircle.svelte

@ -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

1
packages/bbui/src/SideNavigation/Item.svelte

@ -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}">

2
packages/builder/cypress/support/commands.js

@ -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()

23
packages/builder/src/components/common/ConfigChecklist.svelte

@ -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;

20
packages/builder/src/components/design/AppPreview/CurrentItemPreview.svelte

@ -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()
} }

12
packages/builder/src/components/start/AppRow.svelte

@ -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>

2
packages/builder/src/components/start/CreateAppModal.svelte

@ -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}

35
packages/builder/src/pages/builder/apps/index.svelte

@ -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;

139
packages/builder/src/pages/builder/portal/_layout.svelte

@ -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>

8
packages/builder/src/pages/builder/portal/apps/index.svelte

@ -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>

110
packages/builder/src/pages/builder/portal/manage/auth/index.svelte

@ -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>

155
packages/builder/src/pages/builder/portal/manage/email/[template].svelte

@ -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 {

4
packages/builder/src/pages/builder/portal/manage/email/index.svelte

@ -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;
} }

2
packages/builder/src/pages/builder/portal/manage/users/[userId].svelte

@ -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

2
packages/builder/src/pages/builder/portal/manage/users/index.svelte

@ -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>

16
packages/builder/src/pages/builder/portal/settings/organisation.svelte

@ -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 {

4
packages/builder/src/pages/builder/portal/settings/theming.svelte

@ -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>

34
packages/builder/src/pages/builder/portal/settings/update.svelte

@ -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>

1002
packages/client/yarn.lock

File diff suppressed because it is too large

804
packages/server/yarn.lock

File diff suppressed because it is too large
Loading…
Cancel
Save