Browse Source

Merge branch 'app-list' into admin/user-management-ui

pull/1491/head
Keviin Åberg Kultalahti 5 years ago
parent
commit
c2bae6da4f
  1. 13
      hosting/envoy.dev.yaml.hbs
  2. 1
      hosting/envoy.yaml
  3. 3
      packages/bbui/src/ActionMenu/ActionMenu.svelte
  4. 2
      packages/bbui/src/Form/Core/Picker.svelte
  5. 2
      packages/bbui/src/Form/Core/Select.svelte
  6. 2
      packages/bbui/src/Form/Select.svelte
  7. 60
      packages/bbui/src/Label/Label.svelte
  8. 3
      packages/bbui/src/Layout/Layout.svelte
  9. 8
      packages/bbui/src/Menu/Item.svelte
  10. 11
      packages/bbui/src/Typography/Body.svelte
  11. 64
      packages/builder/src/actions.js
  12. 2
      packages/builder/src/components/backend/DataTable/RowFieldControl.svelte
  13. 2
      packages/builder/src/components/backend/DataTable/Table.svelte
  14. 2
      packages/builder/src/components/backend/DataTable/modals/ManageAccessModal.svelte
  15. 2
      packages/builder/src/components/backend/DatasourceNavigator/TableIntegrationMenu/IntegrationConfigForm.svelte
  16. 2
      packages/builder/src/components/common/bindings/BindingPanel.svelte
  17. 2
      packages/builder/src/components/common/bindings/ServerBindingPanel.svelte
  18. 5
      packages/builder/src/components/design/AppPreview/CurrentItemPreview.svelte
  19. 2
      packages/builder/src/components/design/PropertiesPanel/PropertyControls/PropertyControl.svelte
  20. 18
      packages/builder/src/components/login/LoginForm.svelte
  21. 2
      packages/builder/src/components/settings/tabs/DangerZone.svelte
  22. 86
      packages/builder/src/components/start/AppCard.svelte
  23. 53
      packages/builder/src/components/start/AppList.svelte
  24. 15
      packages/builder/src/components/start/BuilderSettingsButton.svelte
  25. 2
      packages/builder/src/components/start/CreateAppModal.svelte
  26. 6
      packages/builder/src/components/start/LogoutButton.svelte
  27. 29
      packages/builder/src/pages/_layout.svelte
  28. 69
      packages/builder/src/pages/admin/index.svelte
  29. 131
      packages/builder/src/pages/builder/_layout.svelte
  30. 78
      packages/builder/src/pages/builder/admin/index.svelte
  31. 6
      packages/builder/src/pages/builder/app/[application]/_reset.svelte
  32. 0
      packages/builder/src/pages/builder/app/[application]/automate/[automation]/_layout.svelte
  33. 0
      packages/builder/src/pages/builder/app/[application]/automate/[automation]/index.svelte
  34. 0
      packages/builder/src/pages/builder/app/[application]/automate/_layout.svelte
  35. 0
      packages/builder/src/pages/builder/app/[application]/automate/index.svelte
  36. 0
      packages/builder/src/pages/builder/app/[application]/data/_layout.svelte
  37. 0
      packages/builder/src/pages/builder/app/[application]/data/datasource/[selectedDatasource]/[query]/_layout.svelte
  38. 0
      packages/builder/src/pages/builder/app/[application]/data/datasource/[selectedDatasource]/[query]/index.svelte
  39. 0
      packages/builder/src/pages/builder/app/[application]/data/datasource/[selectedDatasource]/_layout.svelte
  40. 2
      packages/builder/src/pages/builder/app/[application]/data/datasource/[selectedDatasource]/index.svelte
  41. 0
      packages/builder/src/pages/builder/app/[application]/data/datasource/_layout.svelte
  42. 0
      packages/builder/src/pages/builder/app/[application]/data/datasource/index.svelte
  43. 0
      packages/builder/src/pages/builder/app/[application]/data/index.svelte
  44. 0
      packages/builder/src/pages/builder/app/[application]/data/table/[selectedTable]/_layout.svelte
  45. 0
      packages/builder/src/pages/builder/app/[application]/data/table/[selectedTable]/index.svelte
  46. 0
      packages/builder/src/pages/builder/app/[application]/data/table/[selectedTable]/relationship/[selectedRow]/[selectedField]/index.svelte
  47. 0
      packages/builder/src/pages/builder/app/[application]/data/table/[selectedTable]/relationship/[selectedRow]/index.svelte
  48. 0
      packages/builder/src/pages/builder/app/[application]/data/table/[selectedTable]/relationship/index.svelte
  49. 0
      packages/builder/src/pages/builder/app/[application]/data/table/_layout.svelte
  50. 0
      packages/builder/src/pages/builder/app/[application]/data/table/index.svelte
  51. 0
      packages/builder/src/pages/builder/app/[application]/data/view/[selectedView]/_layout.svelte
  52. 0
      packages/builder/src/pages/builder/app/[application]/data/view/[selectedView]/index.svelte
  53. 0
      packages/builder/src/pages/builder/app/[application]/deploy/_layout.svelte
  54. 0
      packages/builder/src/pages/builder/app/[application]/deploy/index.svelte
  55. 0
      packages/builder/src/pages/builder/app/[application]/design/[assetType]/[asset]/_fallback.svelte
  56. 0
      packages/builder/src/pages/builder/app/[application]/design/[assetType]/_layout.svelte
  57. 0
      packages/builder/src/pages/builder/app/[application]/design/[assetType]/index.svelte
  58. 0
      packages/builder/src/pages/builder/app/[application]/design/_layout.svelte
  59. 0
      packages/builder/src/pages/builder/app/[application]/design/index.svelte
  60. 0
      packages/builder/src/pages/builder/app/[application]/index.svelte
  61. 0
      packages/builder/src/pages/builder/app/[application]/settings/_layout.svelte
  62. 0
      packages/builder/src/pages/builder/app/[application]/settings/index.svelte
  63. 4
      packages/builder/src/pages/builder/app/index.svelte
  64. 4
      packages/builder/src/pages/builder/auth/index.svelte
  65. 5
      packages/builder/src/pages/builder/auth/login.svelte
  66. 123
      packages/builder/src/pages/builder/index.svelte
  67. 73
      packages/builder/src/pages/builder/portal/_layout.svelte
  68. 0
      packages/builder/src/pages/builder/portal/apps/_layout.svelte
  69. 92
      packages/builder/src/pages/builder/portal/apps/index.svelte
  70. 0
      packages/builder/src/pages/builder/portal/index.svelte
  71. 70
      packages/builder/src/pages/builder/portal/oauth/index.svelte
  72. 0
      packages/builder/src/pages/builder/portal/settings/_layout.svelte
  73. 23
      packages/builder/src/pages/builder/portal/settings/general.svelte
  74. 0
      packages/builder/src/pages/builder/portal/settings/index.svelte
  75. 5
      packages/builder/src/pages/index.svelte
  76. 27
      packages/builder/src/pages/portal/apps/index.svelte
  77. 43
      packages/builder/src/pages/portal/manage/auth/logos/Google.svelte
  78. 36
      packages/builder/src/stores/backend/auth.js
  79. 27
      packages/builder/src/stores/portal/apps.js
  80. 1
      packages/builder/src/stores/portal/index.js
  81. 10
      packages/builder/vite.config.js
  82. 3
      packages/standard-components/src/CardHorizontal.svelte
  83. 4
      packages/standard-components/src/StackedList.svelte

13
hosting/envoy.dev.yaml.hbs

@ -16,6 +16,11 @@ static_resources:
- name: local_services
domains: ["*"]
routes:
# special case to redirect specifically the route path
# to the builder, if this were a prefix then it would break minio
- match: { path: "/" }
redirect: { path_redirect: "/builder/" }
- match: { prefix: "/db/" }
route:
cluster: couchdb-service
@ -33,7 +38,11 @@ static_resources:
route:
cluster: server-dev
- match: { prefix: "/" }
- match: { path: "/" }
route:
cluster: builder-dev
- match: { prefix: "/builder/" }
route:
cluster: builder-dev
@ -41,7 +50,7 @@ static_resources:
route:
cluster: builder-dev
prefix_rewrite: "/builder/"
# minio is on the default route because this works
# best, minio + AWS SDK doesn't handle path proxy
- match: { prefix: "/" }

1
hosting/envoy.yaml

@ -21,7 +21,6 @@ static_resources:
cluster: app-service
prefix_rewrite: "/"
# special case for presenting our static self hosting page
- match: { path: "/" }
route:
cluster: app-service

3
packages/bbui/src/ActionMenu/ActionMenu.svelte

@ -4,6 +4,7 @@
import Menu from "../Menu/Menu.svelte"
export let disabled = false
export let align = "left"
let anchor
let dropdown
@ -31,7 +32,7 @@
<div use:getAnchor on:click={openMenu}>
<slot name="control" />
</div>
<Popover bind:this={dropdown} {anchor} align="left">
<Popover bind:this={dropdown} {anchor} {align}>
<Menu>
<slot />
</Menu>

2
packages/bbui/src/Form/Core/Picker.svelte

@ -19,6 +19,7 @@
export let getOptionValue = option => option
export let open = false
export let readonly = false
export let quiet = false
const dispatch = createEventDispatcher()
const onClick = e => {
@ -33,6 +34,7 @@
<button
{id}
class="spectrum-Picker spectrum-Picker--sizeM"
class:spectrum-Picker--quiet={quiet}
{disabled}
class:is-invalid={!!error}
class:is-open={open}

2
packages/bbui/src/Form/Core/Select.svelte

@ -11,6 +11,7 @@
export let getOptionLabel = option => option
export let getOptionValue = option => option
export let readonly = false
export let quiet = false
const dispatch = createEventDispatcher()
let open = false
@ -43,6 +44,7 @@
<Picker
on:click
bind:open
{quiet}
{id}
{error}
{disabled}

2
packages/bbui/src/Form/Select.svelte

@ -13,6 +13,7 @@
export let options = []
export let getOptionLabel = option => extractProperty(option, "label")
export let getOptionValue = option => extractProperty(option, "value")
export let quiet = false
const dispatch = createEventDispatcher()
const onChange = e => {
@ -29,6 +30,7 @@
<Field {label} {labelPosition} {disabled} {error}>
<Select
{quiet}
{error}
{disabled}
{readonly}

60
packages/bbui/src/Label/Label.svelte

@ -1,62 +1,16 @@
<script>
export let forAttr = "",
extraSmall = false,
small = false,
medium = false,
large = false,
extraLarge = false,
white = false,
grey = false,
black = false
import "@spectrum-css/fieldlabel/dist/index-vars.css"
export let size = "M"
</script>
<label
class="bb-label"
class:extraSmall
class:small
class:medium
class:large
class:extraLarge
class:white
class:grey
class:black
for={forAttr}
>
<label class={`spectrum-FieldLabel spectrum-FieldLabel--size${size}`}>
<slot />
</label>
<style>
.bb-label {
font-family: var(--font-sans);
font-weight: 500;
text-rendering: var(--text-render);
color: var(--ink);
font-size: var(--font-size-s);
margin-bottom: var(--spacing-s);
display: block;
}
.extraSmall {
font-size: var(--font-size-xs);
}
.small {
font-size: var(--font-size-s);
}
.medium {
font-size: var(--font-size-m);
}
.large {
font-size: var(--font-size-l);
}
.extraLarge {
font-size: var(--font-size-xl);
}
.white {
color: white;
}
.grey {
color: var(--grey-6);
}
.black {
color: var(--ink);
label {
padding: 0;
white-space: nowrap;
}
</style>

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

@ -44,6 +44,9 @@
padding-top: var(--spacing-l);
padding-bottom: var(--spacing-l);
}
.gap-XS {
grid-gap: var(--spacing-s);
}
.gap-S {
grid-gap: var(--spectrum-alias-grid-gutter-xsmall);
}

8
packages/bbui/src/Menu/Item.svelte

@ -27,7 +27,7 @@
>
{#if icon}
<svg
class="spectrum-Icon spectrum-Icon--sizeM spectrum-Menu-itemIcon"
class="spectrum-Icon spectrum-Icon--sizeS spectrum-Menu-itemIcon"
focusable="false"
aria-hidden="true"
aria-label={icon}
@ -37,3 +37,9 @@
{/if}
<span class="spectrum-Menu-itemLabel"><slot /></span>
</li>
<style>
.spectrum-Menu-itemIcon {
align-self: center;
}
</style>

11
packages/bbui/src/Typography/Body.svelte

@ -3,11 +3,20 @@
export let size = "M"
export let serif = false
export let noPadding = false
</script>
<p
class="spectrum-Body class:spectrum-Body--size{size}"
class:noPadding
class="spectrum-Body spectrum-Body--size{size}"
class:spectrum-Body--serif={serif}
>
<slot />
</p>
<style>
.noPadding {
padding: 0;
margin: 0;
}
</style>

64
packages/builder/src/actions.js

@ -0,0 +1,64 @@
export const gradient = (node, config = {}) => {
const defaultConfig = {
points: 10,
saturation: 0.8,
lightness: 0.75,
softness: 0.8,
}
// Applies a gradient background
const createGradient = config => {
config = {
...defaultConfig,
...config,
}
const { saturation, lightness, softness, points } = config
// Generates a random number between min and max
const rand = (min, max) => {
return Math.round(min + Math.random() * (max - min))
}
// Generates a random HSL colour using the options specified
const randomHSL = () => {
const lowerSaturation = Math.min(100, saturation * 100)
const upperSaturation = Math.min(100, (saturation + 0.2) * 100)
const lowerLightness = Math.min(100, lightness * 100)
const upperLightness = Math.min(100, (lightness + 0.2) * 100)
const hue = rand(0, 360)
const sat = `${rand(lowerSaturation, upperSaturation)}%`
const light = `${rand(lowerLightness, upperLightness)}%`
return `hsl(${hue},${sat},${light})`
}
// Generates a radial gradient stop point
const randomGradientPoint = () => {
const lowerTransparency = Math.min(100, softness * 100)
const upperTransparency = Math.min(100, (softness + 0.2) * 100)
const transparency = rand(lowerTransparency, upperTransparency)
return (
`radial-gradient(` +
`at ${rand(10, 90)}% ${rand(10, 90)}%,` +
`${randomHSL()} 0,` +
`transparent ${transparency}%)`
)
}
let css = `opacity:0.9;background-color:${randomHSL()};background-image:`
for (let i = 0; i < points - 1; i++) {
css += `${randomGradientPoint()},`
}
css += `${randomGradientPoint()};`
node.style = css
}
// Apply the initial gradient
createGradient(config)
return {
// Apply a new gradient
update: config => {
createGradient(config)
},
}
}

2
packages/builder/src/components/backend/DataTable/RowFieldControl.svelte

@ -1,7 +1,7 @@
<script>
import { Input, Select, DatePicker, Toggle, TextArea } from "@budibase/bbui"
import Dropzone from "components/common/Dropzone.svelte"
import { capitalise } from "../../../helpers"
import { capitalise } from "helpers"
import LinkedRowSelector from "components/common/LinkedRowSelector.svelte"
export let defaultValue

2
packages/builder/src/components/backend/DataTable/Table.svelte

@ -59,7 +59,7 @@
const selectRelationship = ({ tableId, rowId, fieldName }) => {
$goto(
`/builder/${$params.application}/data/table/${tableId}/relationship/${rowId}/${fieldName}`
`/builder/app/${$params.application}/data/table/${tableId}/relationship/${rowId}/${fieldName}`
)
}

2
packages/builder/src/components/backend/DataTable/modals/ManageAccessModal.svelte

@ -8,7 +8,7 @@
Body,
ModalContent,
} from "@budibase/bbui"
import { capitalise } from "../../../../helpers"
import { capitalise } from "helpers"
export let resourceId
export let permissions

2
packages/builder/src/components/backend/DatasourceNavigator/TableIntegrationMenu/IntegrationConfigForm.svelte

@ -1,7 +1,7 @@
<script>
import { Label, Input, Layout } from "@budibase/bbui"
import KeyValueBuilder from "components/integration/KeyValueBuilder.svelte"
import { capitalise } from "../../../../helpers"
import { capitalise } from "helpers"
export let integration
export let schema

2
packages/builder/src/components/common/bindings/BindingPanel.svelte

@ -14,7 +14,7 @@
getBindableProperties,
readableToRuntimeBinding,
} from "builderStore/dataBinding"
import { currentAsset, store } from "../../../builderStore"
import { currentAsset, store } from "builderStore"
import { handlebarsCompletions } from "constants/completions"
import { addToText } from "./utils"

2
packages/builder/src/components/common/bindings/ServerBindingPanel.svelte

@ -10,7 +10,7 @@
import { createEventDispatcher } from "svelte"
import { isValid } from "@budibase/string-templates"
import { handlebarsCompletions } from "constants/completions"
import { readableToRuntimeBinding } from "../../../builderStore/dataBinding"
import { readableToRuntimeBinding } from "builderStore/dataBinding"
import { addToText } from "./utils"
const dispatch = createEventDispatcher()

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

@ -3,7 +3,7 @@
import { store, currentAsset, selectedComponent } from "builderStore"
import iframeTemplate from "./iframeTemplate"
import { Screen } from "builderStore/store/screenTemplates/utils/Screen"
import { FrontendTypes } from "../../../constants"
import { FrontendTypes } from "constants"
let iframe
let layout
@ -82,7 +82,8 @@
style="height: 100%; width: 100%"
title="componentPreview"
bind:this={iframe}
srcdoc={template} />
srcdoc={template}
/>
</div>
<style>

2
packages/builder/src/components/design/PropertiesPanel/PropertyControls/PropertyControl.svelte

@ -7,7 +7,7 @@
runtimeToReadableBinding,
} from "builderStore/dataBinding"
import BindingPanel from "components/common/bindings/BindingPanel.svelte"
import { capitalise } from "../../../../helpers"
import { capitalise } from "helpers"
export let label = ""
export let bindable = true

18
packages/builder/src/components/login/LoginForm.svelte

@ -1,7 +1,7 @@
<script>
import { goto } from "@roxi/routify"
import {
notifications,
Button,
Link,
Input,
Modal,
@ -18,27 +18,18 @@
username,
password,
})
notifications.success("Logged in successfully.")
notifications.success("Logged in successfully")
$goto("../portal")
} catch (err) {
console.error(err)
notifications.error("Invalid credentials")
}
}
async function createTestUser() {
try {
await auth.firstUser()
notifications.success("Test user created")
} catch (err) {
console.error(err)
notifications.error("Could not create test user")
}
}
</script>
<Modal fixed>
<ModalContent
size="L"
size="M"
title="Log In"
onConfirm={login}
confirmText="Log In"
@ -51,7 +42,6 @@
<Link target="_blank" href="/api/admin/auth/google">
Sign In With Google
</Link>
<Button secondary on:click={createTestUser}>Create Test User</Button>
</div>
</ModalContent>
</Modal>

2
packages/builder/src/components/settings/tabs/DangerZone.svelte

@ -11,7 +11,7 @@
const id = $params.application
await del(`/api/applications/${id}`)
loading = false
$goto("/builder/")
$goto("/builder")
}
</script>

86
packages/builder/src/components/start/AppCard.svelte

@ -1,11 +1,19 @@
<script>
import { goto } from "@roxi/routify"
import { ActionButton, Heading } from "@budibase/bbui"
import { notifications } from "@budibase/bbui"
import Spinner from "components/common/Spinner.svelte"
import {
Heading,
Icon,
Body,
Layout,
ActionMenu,
MenuItem,
Link,
notifications,
} from "@budibase/bbui"
import download from "downloadjs"
import { gradient } from "actions"
export let name, _id
export let name
export let _id
let appExportLoading = false
@ -15,58 +23,60 @@
download(
`/api/backups/export?appId=${_id}&appname=${encodeURIComponent(name)}`
)
notifications.success("App Export Complete.")
notifications.success("App export complete")
} catch (err) {
console.error(err)
notifications.error("App Export Failed.")
notifications.error("App export failed")
} finally {
appExportLoading = false
}
}
</script>
<div class="apps-card">
<Heading size="S">{name}</Heading>
<div class="card-footer" data-cy={`app-${name}`}>
<ActionButton on:click={() => $goto(`/builder/${_id}`)}>
Open
{name}
</ActionButton>
{#if appExportLoading}
<Spinner size="10" />
{:else}
<ActionButton icon="Download" quiet />
<Layout noPadding gap="XS">
<div class="preview" use:gradient />
<div class="title">
<Link href={`/builder/app/${_id}`}>
<Heading size="XS">
{name}
</Heading>
</Link>
<ActionMenu>
<Icon slot="control" name="More" hoverable />
<MenuItem on:click={exportApp} icon="Download">Export</MenuItem>
</ActionMenu>
</div>
<div class="status">
<Body noPadding size="S">
Edited {Math.floor(1 + Math.random() * 10)} months ago
</Body>
{#if Math.random() > 0.5}
<Icon name="LockClosed" />
{/if}
</div>
</div>
</Layout>
<style>
.apps-card {
background-color: var(--background);
padding: var(--spacing-xl) var(--spacing-xl) var(--spacing-xl)
var(--spacing-xl);
max-width: 300px;
max-height: 150px;
border-radius: var(--border-radius-m);
border: var(--border-dark);
.preview {
height: 135px;
border-radius: var(--border-radius-s);
margin-bottom: var(--spacing-s);
}
.card-footer {
.title,
.status {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
margin-top: var(--spacing-m);
align-items: center;
}
i {
font-size: var(--font-size-l);
cursor: pointer;
transition: 0.2s all;
.title :global(a) {
text-decoration: none;
}
i:hover {
color: var(--blue);
.title :global(h1:hover) {
color: var(--spectrum-global-color-blue-600);
cursor: pointer;
transition: color 130ms ease;
}
</style>

53
packages/builder/src/components/start/AppList.svelte

@ -1,50 +1,25 @@
<script>
import { onMount } from "svelte"
import AppCard from "./AppCard.svelte"
import { Heading, Divider } from "@budibase/bbui"
import Spinner from "components/common/Spinner.svelte"
import { get } from "builderStore/api"
import { apps } from "stores/portal"
let promise = getApps()
async function getApps() {
const res = await get("/api/applications")
const json = await res.json()
if (res.ok) {
return json
} else {
throw new Error(json)
}
}
onMount(apps.load)
</script>
<div class="root">
<Heading size="M">Your Apps</Heading>
<Divider size="M" />
{#await promise}
<div class="spinner-container">
<Spinner size="30" />
</div>
{:then apps}
<div class="apps">
{#each apps as app}
<AppCard {...app} />
{/each}
</div>
{:catch err}
<h1 style="color:red">{err}</h1>
{/await}
</div>
{#if $apps.length}
<div class="appList">
{#each $apps as app}
<AppCard {...app} />
{/each}
</div>
{:else}
<div>No apps found.</div>
{/if}
<style>
.root {
margin-top: 10px;
}
.apps {
margin-top: var(--layout-m);
.appList {
display: grid;
grid-gap: 50px;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
grid-gap: var(--layout-s);
justify-content: start;
}
</style>

15
packages/builder/src/components/start/BuilderSettingsButton.svelte

@ -1,15 +0,0 @@
<script>
import { Button, Modal } from "@budibase/bbui"
import BuilderSettingsModal from "./BuilderSettingsModal.svelte"
let modal
</script>
<div>
<Button primary quiet icon="Settings" text on:click={modal.show}>
Settings
</Button>
</div>
<Modal bind:this={modal} width="30%">
<BuilderSettingsModal />
</Modal>

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

@ -112,7 +112,7 @@
}
const userResp = await api.post(`/api/users/metadata/self`, user)
await userResp.json()
$goto(`./${appJson._id}`)
window.location = `/builder/app/${appJson._id}`
} catch (error) {
console.error(error)
notifications.error(error)

6
packages/builder/src/components/start/LogoutButton.svelte

@ -1,6 +0,0 @@
<script>
import { Button } from "@budibase/bbui"
import { auth } from "stores/backend"
</script>
<Button primary quiet text icon="LogOut" on:click={auth.logout}>Log Out</Button>

29
packages/builder/src/pages/_layout.svelte

@ -1,29 +0,0 @@
<script>
import { onMount } from "svelte"
import { goto } from "@roxi/routify"
import {
SideNavigation as Navigation,
SideNavigationItem as Item,
} from "@budibase/bbui"
import { admin } from "stores/portal"
import LoginForm from "components/login/LoginForm.svelte"
import BuilderSettingsButton from "components/start/BuilderSettingsButton.svelte"
import LogoutButton from "components/start/LogoutButton.svelte"
import Logo from "/assets/budibase-logo.svg"
import api from "builderStore/api"
let checklist
onMount(async () => {
await admin.init()
if (!$admin?.checklist?.adminUser) {
$goto("./admin")
} else {
$goto("./portal")
}
})
</script>
{#if $admin.checklist}
<slot />
{/if}

69
packages/builder/src/pages/admin/index.svelte

@ -1,69 +0,0 @@
<script>
import {
Button,
Heading,
Label,
notifications,
Layout,
Input,
Body,
} from "@budibase/bbui"
import { goto } from "@roxi/routify"
import { onMount } from "svelte"
import api from "builderStore/api"
let adminUser = {}
async function save() {
try {
// Save the admin user
const response = await api.post(`/api/admin/users/init`, adminUser)
const json = await response.json()
if (response.status !== 200) throw new Error(json.message)
notifications.success(`Admin user created.`)
$goto("../portal")
} catch (err) {
notifications.error(`Failed to create admin user.`)
}
}
</script>
<section>
<div class="container">
<header>
<Heading size="M">Create an admin user</Heading>
<Body size="S">The admin user has access to everything in budibase.</Body>
</header>
<div class="config-form">
<Layout gap="S">
<Input label="email" bind:value={adminUser.email} />
<Input
label="password"
type="password"
bind:value={adminUser.password}
/>
<Button cta on:click={save}>Create super admin user</Button>
</Layout>
</div>
</div>
</section>
<style>
section {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
}
header {
text-align: center;
width: 80%;
margin: 0 auto;
}
.config-form {
margin-bottom: 42px;
}
</style>

131
packages/builder/src/pages/builder/_layout.svelte

@ -1,116 +1,33 @@
<script>
import {
SideNavigation as Navigation,
SideNavigationItem as Item,
} from "@budibase/bbui"
import { onMount } from "svelte"
import { goto } from "@roxi/routify"
import { auth } from "stores/backend"
import LoginForm from "components/login/LoginForm.svelte"
import BuilderSettingsButton from "components/start/BuilderSettingsButton.svelte"
import LogoutButton from "components/start/LogoutButton.svelte"
import Logo from "/assets/budibase-logo.svg"
import { admin } from "stores/portal"
let modal
</script>
{#if $auth}
{#if $auth.user}
<div class="root">
<div class="ui-nav">
<div class="home-logo">
<img src={Logo} alt="Budibase icon" />
</div>
<div class="nav-section">
<div class="nav-top">
<Navigation>
<Item href="/builder/" icon="Apps" selected>Apps</Item>
<Item external href="https://portal.budi.live/" icon="Servers">
Hosting
</Item>
<Item external href="https://docs.budibase.com/" icon="Book">
Documentation
</Item>
<Item
external
href="https://github.com/Budibase/budibase/discussions"
icon="PeopleGroup"
>
Community
</Item>
<Item
external
href="https://github.com/Budibase/budibase/issues/new/choose"
icon="Bug"
>
Raise an issue
</Item>
</Navigation>
</div>
<div class="nav-bottom">
<BuilderSettingsButton />
<LogoutButton />
</div>
</div>
</div>
<div class="main">
<slot />
</div>
</div>
{:else}
<section class="login">
<LoginForm />
</section>
{/if}
{/if}
<style>
.root {
display: grid;
grid-template-columns: 260px 1fr;
height: 100%;
width: 100%;
}
.login {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
width: 100%;
}
let loaded = false
$: hasAdminUser = !!$admin?.checklist?.adminUser
.main {
grid-column: 2;
overflow: auto;
}
onMount(async () => {
await admin.init()
await auth.checkAuth()
loaded = true
})
.ui-nav {
grid-column: 1;
background-color: var(--background);
padding: 20px;
display: flex;
flex-direction: column;
border-right: var(--border-light);
// Force creation of an admin user if one doesn't exist
$: {
if (loaded && !hasAdminUser) {
$goto("./admin")
}
}
.home-logo {
cursor: pointer;
height: 40px;
margin-bottom: 20px;
}
.home-logo img {
height: 40px;
}
.nav-section {
margin: 20px 0 0 0;
display: flex;
flex-direction: column;
justify-content: space-between;
height: 100%;
// Redirect to log in at any time if the user isn't authenticated
$: {
if (loaded && hasAdminUser && !$auth.user) {
$goto("./auth/login")
}
}
</script>
.nav-bottom :global(> *) {
margin-top: 5px;
}
</style>
{#if loaded}
<slot />
{/if}

78
packages/builder/src/pages/builder/admin/index.svelte

@ -0,0 +1,78 @@
<script>
import {
Button,
Heading,
notifications,
Layout,
Input,
Body,
} from "@budibase/bbui"
import { goto } from "@roxi/routify"
import api from "builderStore/api"
import { admin } from "stores/portal"
let adminUser = {}
async function save() {
try {
// Save the admin user
const response = await api.post(`/api/admin/users/init`, adminUser)
const json = await response.json()
if (response.status !== 200) {
throw new Error(json.message)
}
notifications.success(`Admin user created`)
await admin.init()
$goto("../portal")
} catch (err) {
notifications.error(`Failed to create admin user`)
}
}
</script>
<section>
<div class="container">
<Layout gap="XS">
<img src="https://i.imgur.com/ZKyklgF.png" />
</Layout>
<div class="center">
<Layout gap="XS">
<Heading size="M">Create an admin user</Heading>
<Body size="M"
>The admin user has access to everything in Budibase.</Body
>
</Layout>
</div>
<Layout gap="XS">
<Input label="Email" bind:value={adminUser.email} />
<Input label="Password" type="password" bind:value={adminUser.password} />
</Layout>
<Layout gap="S">
<Button cta on:click={save}>Create super admin user</Button>
</Layout>
</div>
</section>
<style>
section {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
}
.container {
margin: 0 auto;
width: 260px;
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: stretch;
}
.center {
text-align: center;
}
img {
width: 40px;
margin: 0 auto;
}
</style>

6
packages/builder/src/pages/builder/[application]/_reset.svelte → packages/builder/src/pages/builder/app/[application]/_reset.svelte

@ -6,9 +6,9 @@
import ThemeEditorDropdown from "components/settings/ThemeEditorDropdown.svelte"
import FeedbackNavLink from "components/feedback/FeedbackNavLink.svelte"
import { get } from "builderStore/api"
import { isActive, goto, layout, params } from "@roxi/routify"
import { isActive, goto, layout } from "@roxi/routify"
import Logo from "/assets/bb-logo.svg"
import { capitalise } from "../../../helpers"
import { capitalise } from "helpers"
// Get Package and set store
export let application
@ -60,7 +60,7 @@
<img
src={Logo}
alt="budibase icon"
on:click={() => $goto(`/builder/`)}
on:click={() => $goto(`../../portal/`)}
/>
</button>

0
packages/builder/src/pages/builder/[application]/automate/[automation]/_layout.svelte → packages/builder/src/pages/builder/app/[application]/automate/[automation]/_layout.svelte

0
packages/builder/src/pages/builder/[application]/automate/[automation]/index.svelte → packages/builder/src/pages/builder/app/[application]/automate/[automation]/index.svelte

0
packages/builder/src/pages/builder/[application]/automate/_layout.svelte → packages/builder/src/pages/builder/app/[application]/automate/_layout.svelte

0
packages/builder/src/pages/builder/[application]/automate/index.svelte → packages/builder/src/pages/builder/app/[application]/automate/index.svelte

0
packages/builder/src/pages/builder/[application]/data/_layout.svelte → packages/builder/src/pages/builder/app/[application]/data/_layout.svelte

0
packages/builder/src/pages/builder/[application]/data/datasource/[selectedDatasource]/[query]/_layout.svelte → packages/builder/src/pages/builder/app/[application]/data/datasource/[selectedDatasource]/[query]/_layout.svelte

0
packages/builder/src/pages/builder/[application]/data/datasource/[selectedDatasource]/[query]/index.svelte → packages/builder/src/pages/builder/app/[application]/data/datasource/[selectedDatasource]/[query]/index.svelte

0
packages/builder/src/pages/builder/[application]/data/datasource/[selectedDatasource]/_layout.svelte → packages/builder/src/pages/builder/app/[application]/data/datasource/[selectedDatasource]/_layout.svelte

2
packages/builder/src/pages/builder/[application]/data/datasource/[selectedDatasource]/index.svelte → packages/builder/src/pages/builder/app/[application]/data/datasource/[selectedDatasource]/index.svelte

@ -5,7 +5,7 @@
import { notifications } from "@budibase/bbui"
import IntegrationConfigForm from "components/backend/DatasourceNavigator/TableIntegrationMenu/IntegrationConfigForm.svelte"
import ICONS from "components/backend/DatasourceNavigator/icons"
import { capitalise } from "../../../../../../helpers"
import { capitalise } from "helpers"
let unsaved = false

0
packages/builder/src/pages/builder/[application]/data/datasource/_layout.svelte → packages/builder/src/pages/builder/app/[application]/data/datasource/_layout.svelte

0
packages/builder/src/pages/builder/[application]/data/datasource/index.svelte → packages/builder/src/pages/builder/app/[application]/data/datasource/index.svelte

0
packages/builder/src/pages/builder/[application]/data/index.svelte → packages/builder/src/pages/builder/app/[application]/data/index.svelte

0
packages/builder/src/pages/builder/[application]/data/table/[selectedTable]/_layout.svelte → packages/builder/src/pages/builder/app/[application]/data/table/[selectedTable]/_layout.svelte

0
packages/builder/src/pages/builder/[application]/data/table/[selectedTable]/index.svelte → packages/builder/src/pages/builder/app/[application]/data/table/[selectedTable]/index.svelte

0
packages/builder/src/pages/builder/[application]/data/table/[selectedTable]/relationship/[selectedRow]/[selectedField]/index.svelte → packages/builder/src/pages/builder/app/[application]/data/table/[selectedTable]/relationship/[selectedRow]/[selectedField]/index.svelte

0
packages/builder/src/pages/builder/[application]/data/table/[selectedTable]/relationship/[selectedRow]/index.svelte → packages/builder/src/pages/builder/app/[application]/data/table/[selectedTable]/relationship/[selectedRow]/index.svelte

0
packages/builder/src/pages/builder/[application]/data/table/[selectedTable]/relationship/index.svelte → packages/builder/src/pages/builder/app/[application]/data/table/[selectedTable]/relationship/index.svelte

0
packages/builder/src/pages/builder/[application]/data/table/_layout.svelte → packages/builder/src/pages/builder/app/[application]/data/table/_layout.svelte

0
packages/builder/src/pages/builder/[application]/data/table/index.svelte → packages/builder/src/pages/builder/app/[application]/data/table/index.svelte

0
packages/builder/src/pages/builder/[application]/data/view/[selectedView]/_layout.svelte → packages/builder/src/pages/builder/app/[application]/data/view/[selectedView]/_layout.svelte

0
packages/builder/src/pages/builder/[application]/data/view/[selectedView]/index.svelte → packages/builder/src/pages/builder/app/[application]/data/view/[selectedView]/index.svelte

0
packages/builder/src/pages/builder/[application]/deploy/_layout.svelte → packages/builder/src/pages/builder/app/[application]/deploy/_layout.svelte

0
packages/builder/src/pages/builder/[application]/deploy/index.svelte → packages/builder/src/pages/builder/app/[application]/deploy/index.svelte

0
packages/builder/src/pages/builder/[application]/design/[assetType]/[asset]/_fallback.svelte → packages/builder/src/pages/builder/app/[application]/design/[assetType]/[asset]/_fallback.svelte

0
packages/builder/src/pages/builder/[application]/design/[assetType]/_layout.svelte → packages/builder/src/pages/builder/app/[application]/design/[assetType]/_layout.svelte

0
packages/builder/src/pages/builder/[application]/design/[assetType]/index.svelte → packages/builder/src/pages/builder/app/[application]/design/[assetType]/index.svelte

0
packages/builder/src/pages/builder/[application]/design/_layout.svelte → packages/builder/src/pages/builder/app/[application]/design/_layout.svelte

0
packages/builder/src/pages/builder/[application]/design/index.svelte → packages/builder/src/pages/builder/app/[application]/design/index.svelte

0
packages/builder/src/pages/builder/[application]/index.svelte → packages/builder/src/pages/builder/app/[application]/index.svelte

0
packages/builder/src/pages/builder/[application]/settings/_layout.svelte → packages/builder/src/pages/builder/app/[application]/settings/_layout.svelte

0
packages/builder/src/pages/builder/[application]/settings/index.svelte → packages/builder/src/pages/builder/app/[application]/settings/index.svelte

4
packages/builder/src/pages/builder/app/index.svelte

@ -0,0 +1,4 @@
<script>
import { goto } from "@roxi/routify"
$goto("../portal")
</script>

4
packages/builder/src/pages/builder/auth/index.svelte

@ -0,0 +1,4 @@
<script>
import { goto } from "@roxi/routify"
$goto("./login")
</script>

5
packages/builder/src/pages/builder/auth/login.svelte

@ -0,0 +1,5 @@
<script>
import LoginForm from "components/login/LoginForm.svelte"
</script>
<LoginForm />

123
packages/builder/src/pages/builder/index.svelte

@ -1,123 +1,4 @@
<script>
import api from "builderStore/api"
import AppList from "components/start/AppList.svelte"
import { get } from "builderStore/api"
import CreateAppModal from "components/start/CreateAppModal.svelte"
import { Button, Heading, Modal, ButtonGroup } from "@budibase/bbui"
import TemplateList from "components/start/TemplateList.svelte"
import analytics from "analytics"
import Banner from "/assets/orange-landscape.png"
let hasKey
let template
let modal
async function getApps() {
const res = await get("/api/applications")
const json = await res.json()
if (res.ok) {
return json
} else {
throw new Error(json)
}
}
async function fetchKeys() {
const response = await api.get(`/api/keys/`)
return await response.json()
}
async function checkIfKeysAndApps() {
const keys = await fetchKeys()
const apps = await getApps()
if (keys.userId) {
hasKey = true
analytics.identify(keys.userId)
}
}
function selectTemplate(newTemplate) {
template = newTemplate
modal.show()
}
function initiateAppImport() {
template = { fromFile: true }
modal.show()
}
function closeModal() {
template = null
modal.hide()
}
checkIfKeysAndApps()
import { goto } from "@roxi/routify"
$goto("./portal")
</script>
<div class="container">
<div class="header">
<Heading size="M">Welcome to the Budibase Beta</Heading>
<ButtonGroup>
<Button secondary on:click={initiateAppImport}>Import Web App</Button>
<Button cta on:click={modal.show}>Create New Web App</Button>
</ButtonGroup>
</div>
<div class="banner">
<img src={Banner} alt="rocket" />
<div class="banner-content">
Every accomplishment starts with a decision to try.
</div>
</div>
<!-- <TemplateList onSelect={selectTemplate} /> -->
<AppList />
</div>
<Modal bind:this={modal} padding={false} width="600px" on:hide={closeModal}>
<CreateAppModal {hasKey} {template} />
</Modal>
<style>
.container {
display: grid;
gap: var(--spacing-xl);
margin: 40px 80px;
}
.header {
display: flex;
justify-content: space-between;
align-items: center;
}
.banner {
display: flex;
align-items: center;
justify-content: center;
position: relative;
text-align: center;
color: white;
border-radius: 16px;
}
.banner img {
height: 250px;
width: 100%;
border-radius: 5px;
}
.banner-content {
position: absolute;
font-size: 24px;
color: white;
font-weight: 500;
}
.button-group {
display: flex;
flex-direction: row;
}
</style>

73
packages/builder/src/pages/portal/_layout.svelte → packages/builder/src/pages/builder/portal/_layout.svelte

@ -1,49 +1,53 @@
<script>
import { isActive, url, goto } from "@roxi/routify"
import { isActive, goto } from "@roxi/routify"
import { onMount } from "svelte"
import {
ActionMenu,
Checkbox,
MenuItem,
Icon,
Heading,
Avatar,
Search,
Layout,
ProgressCircle,
SideNavigation as Navigation,
SideNavigationItem as Item,
ActionMenu,
MenuItem,
Modal,
} from "@budibase/bbui"
import api from "builderStore/api"
import ConfigChecklist from "components/common/ConfigChecklist.svelte"
import { organisation, admin } from "stores/portal"
import { organisation, apps } from "stores/portal"
import { auth } from "stores/backend"
import BuilderSettingsModal from "components/start/BuilderSettingsModal.svelte"
organisation.init()
apps.load()
let orgName
let orgLogo
let user
let oldSettingsModal
async function getInfo() {
// fetch orgInfo
orgName = "ACME Inc."
orgLogo = "https://via.placeholder.com/150"
user = { name: "John Doe" }
}
onMount(getInfo)
let menu = [
{ title: "Apps", href: "/portal/apps" },
{ title: "Drafts", href: "/portal/drafts" },
{ title: "Users", href: "/portal/manage/users", heading: "Manage" },
{ title: "Groups", href: "/portal/manage/groups" },
{ title: "Auth", href: "/portal/manage/auth" },
{ title: "Email", href: "/portal/manage/email" },
{ title: "General", href: "/portal/settings/general", heading: "Settings" },
{ title: "Theming", href: "/portal/theming" },
{ title: "Account", href: "/portal/account" },
{ title: "Apps", href: "/builder/portal/apps" },
{ title: "Drafts", href: "/builder/portal/drafts" },
{ title: "Users", href: "/builder/portal/manage/users", heading: "Manage" },
{ title: "Groups", href: "/builder/portal/manage/groups" },
{ title: "Auth", href: "/builder/portal/manage/auth" },
{ title: "Email", href: "/builder/portal/manage/email" },
{
title: "General",
href: "/builder/portal/settings/general",
heading: "Settings",
},
{ title: "Theming", href: "/builder/portal/theming" },
{ title: "Account", href: "/builder/portal/account" },
]
</script>
@ -51,7 +55,7 @@
<div class="nav">
<Layout paddingX="L" paddingY="L">
<div class="branding">
<div class="name">
<div class="name" on:click={() => $goto("./apps")}>
<img
src={$organisation?.logoUrl || "https://i.imgur.com/ZKyklgF.png"}
alt="Logotype"
@ -74,30 +78,42 @@
<div class="main">
<div class="toolbar">
<Search placeholder="Global search" />
<div class="avatar">
<Avatar size="M" name="John Doe" />
<Icon size="XL" name="ChevronDown" />
</div>
<ActionMenu align="right">
<div slot="control" class="avatar">
<Avatar size="M" name="John Doe" />
<Icon size="XL" name="ChevronDown" />
</div>
<MenuItem icon="Settings" on:click={oldSettingsModal.show}>
Old settings
</MenuItem>
<MenuItem icon="LogOut" on:click={auth.logout}>Log out</MenuItem>
</ActionMenu>
</div>
<div>
<div class="content">
<slot />
</div>
</div>
</div>
<Modal bind:this={oldSettingsModal} width="30%">
<BuilderSettingsModal />
</Modal>
<style>
.container {
min-height: 100vh;
height: 100%;
display: grid;
grid-template-columns: 250px 1fr;
align-items: stretch;
}
.nav {
background: var(--background);
border-right: var(--border-light);
overflow: auto;
}
.main {
display: grid;
grid-template-rows: auto 1fr;
overflow: hidden;
}
.branding {
display: grid;
@ -112,6 +128,9 @@
grid-gap: var(--spacing-m);
align-items: center;
}
.name:hover {
cursor: pointer;
}
.avatar {
display: grid;
grid-template-columns: auto auto;
@ -129,6 +148,7 @@
grid-template-columns: 250px auto;
justify-content: space-between;
padding: var(--spacing-m) calc(var(--spacing-xl) * 2);
align-items: center;
}
img {
width: 28px;
@ -139,4 +159,7 @@
text-overflow: ellipsis;
font-weight: 500;
}
.content {
overflow: auto;
}
</style>

0
packages/builder/src/pages/portal/apps/_layout.svelte → packages/builder/src/pages/builder/portal/apps/_layout.svelte

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

@ -0,0 +1,92 @@
<script>
import {
Heading,
Layout,
Button,
ActionButton,
ActionGroup,
ButtonGroup,
Select,
Modal,
} from "@budibase/bbui"
import AppList from "components/start/AppList.svelte"
import CreateAppModal from "components/start/CreateAppModal.svelte"
import api from "builderStore/api"
import analytics from "analytics"
import { onMount } from "svelte"
let layout = "grid"
let modal
let template
async function checkKeys() {
const response = await api.get(`/api/keys/`)
const keys = await response.json()
if (keys.userId) {
analytics.identify(keys.userId)
}
}
function initiateAppImport() {
template = { fromFile: true }
modal.show()
}
onMount(checkKeys)
</script>
<Layout noPadding>
<div class="title">
<Heading>Apps</Heading>
<ButtonGroup>
<Button secondary on:click={initiateAppImport}>Import app</Button>
<Button cta on:click={modal.show}>Create new app</Button>
</ButtonGroup>
</div>
<div class="filter">
<div class="select">
<Select quiet placeholder="Filter by groups" />
</div>
<ActionGroup>
<ActionButton
on:click={() => (layout = "grid")}
selected={layout === "grid"}
quiet
icon="ClassicGridView"
/>
<ActionButton
on:click={() => (layout = "table")}
selected={layout === "table"}
quiet
icon="ViewRow"
/>
</ActionGroup>
</div>
{#if layout === "grid"}
<AppList />
{:else}
Table view.
{/if}
</Layout>
<Modal
bind:this={modal}
padding={false}
width="600px"
on:hide={() => (template = null)}
>
<CreateAppModal {template} />
</Modal>
<style>
.title,
.filter {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
}
.select {
width: 110px;
}
</style>

0
packages/builder/src/pages/portal/index.svelte → packages/builder/src/pages/builder/portal/index.svelte

70
packages/builder/src/pages/portal/manage/auth/index.svelte → packages/builder/src/pages/builder/portal/oauth/index.svelte

@ -1,7 +1,8 @@
<script>
import GoogleLogo from "./logos/Google.svelte"
import GoogleLogo from "./_logos/Google.svelte"
import {
Button,
Page,
Heading,
Divider,
Label,
@ -58,48 +59,51 @@
})
</script>
<section>
<header>
<Heading size="M">OAuth</Heading>
<Body size="S">
Every budibase app comes with basic authentication (email/password)
included. You can add additional authentication methods from the options
below.
</Body>
</header>
<Divider />
{#if google}
<div class="config-form">
<Layout gap="S">
<Page>
<Layout noPadding>
<div>
<Heading size="M">OAuth</Heading>
<Body>
Every budibase app comes with basic authentication (email/password)
included. You can add additional authentication methods from the options
below.
</Body>
</div>
<Divider />
{#if google}
<div>
<Heading size="S">
<span>
<GoogleLogo />
Google
</span>
</Heading>
{#each ConfigFields.Google as field}
<div class="form-row">
<Label>{field}</Label>
<Input bind:value={google.config[field]} />
</div>
{/each}
</Layout>
<Button primary on:click={() => save(google)}>Save</Button>
</div>
<Divider />
{/if}
</section>
<Body>
To allow users to authenticate using their Google accounts, fill out
the fields below.
</Body>
</div>
<style>
.config-form {
margin-top: 42px;
margin-bottom: 42px;
}
{#each ConfigFields.Google as field}
<div class="form-row">
<Label size="L">{field}</Label>
<Input bind:value={google.config[field]} />
</div>
{/each}
<div>
<Button primary on:click={() => save(google)}>Save</Button>
</div>
<Divider />
{/if}
</Layout>
</Page>
<style>
.form-row {
display: grid;
grid-template-columns: 20% 1fr;
grid-gap: var(--spacing-l);
align-items: center;
}
span {
@ -107,8 +111,4 @@
align-items: center;
gap: var(--spacing-s);
}
header {
margin-bottom: 42px;
}
</style>

0
packages/builder/src/pages/portal/settings/_layout.svelte → packages/builder/src/pages/builder/portal/settings/_layout.svelte

23
packages/builder/src/pages/portal/settings/general.svelte → packages/builder/src/pages/builder/portal/settings/general.svelte

@ -45,12 +45,12 @@
<Layout noPadding>
<div class="intro">
<Heading size="M">General</Heading>
<Body
>Lorem ipsum, dolor sit amet consectetur adipisicing elit. Hic vero, aut
<Body>
Lorem ipsum, dolor sit amet consectetur adipisicing elit. Hic vero, aut
culpa provident sunt ratione! Voluptas doloremque, dicta nisi velit
perspiciatis, ratione vel blanditiis totam, nam voluptate repellat
aperiam fuga!</Body
>
aperiam fuga!
</Body>
</div>
<Divider size="S" />
<div class="information">
@ -58,7 +58,7 @@
<Body>Here you can update your logo and organization name.</Body>
<div class="fields">
<div class="field">
<Label>Organization name</Label>
<Label size="L">Organization name</Label>
<Input thin bind:value={company} />
</div>
<!-- <div class="field">
@ -72,13 +72,13 @@
<Divider size="S" />
<div class="analytics">
<Heading size="S">Analytics</Heading>
<Body
>If you would like to send analytics that help us make Budibase better,
please let us know below.</Body
>
<Body>
If you would like to send analytics that help us make Budibase better,
please let us know below.
</Body>
<div class="fields">
<div class="field">
<Label>Send Analytics to Budibase</Label>
<Label size="L">Send Analytics to Budibase</Label>
<Toggle text="" value={!analyticsDisabled} />
</div>
</div>
@ -97,7 +97,8 @@
}
.field {
display: grid;
grid-template-columns: 30% 1fr;
grid-template-columns: 32% 1fr;
align-items: center;
}
.file {
max-width: 30ch;

0
packages/builder/src/pages/portal/settings/index.svelte → packages/builder/src/pages/builder/portal/settings/index.svelte

5
packages/builder/src/pages/index.svelte

@ -1 +1,4 @@
Index route
<script>
import { goto } from "@roxi/routify"
$goto("./builder")
</script>

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

@ -1,27 +0,0 @@
<script>
import { Heading, Layout } from "@budibase/bbui"
</script>
<Layout noPadding>
<div>
<Heading>Apps</Heading>
</div>
<div class="appList">
{#each new Array(10) as _}
<div class="app" />
{/each}
</div>
</Layout>
<style>
.appList {
display: grid;
grid-gap: 50px;
grid-template-columns: repeat(auto-fill, 300px);
}
.app {
height: 130px;
border-radius: 4px;
background-color: var(--spectrum-global-color-gray-200);
}
</style>

43
packages/builder/src/pages/portal/manage/auth/logos/Google.svelte

@ -1,43 +0,0 @@
<svg
width="18"
height="18"
viewBox="0 0 268 268"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<g clip-path="url(#clip0)">
<path
d="M58.8037 109.043C64.0284 93.2355 74.1116 79.4822 87.615 69.7447C101.118
60.0073 117.352 54.783 134 54.8172C152.872 54.8172 169.934 61.5172 183.334
72.4828L222.328 33.5C198.566 12.7858 168.114 0 134 0C81.1817 0 35.711
30.1277 13.8467 74.2583L58.8037 109.043Z"
fill="#EA4335"
/>
<path
d="M179.113 201.145C166.942 208.995 151.487 213.183 134 213.183C117.418
213.217 101.246 208.034 87.7727 198.369C74.2993 188.703 64.2077 175.044
58.9265 159.326L13.8132 193.574C24.8821 215.978 42.012 234.828 63.2572
247.984C84.5024 261.14 109.011 268.075 134 268C166.752 268 198.041 256.353
221.48 234.5L179.125 201.145H179.113Z"
fill="#34A853"
/>
<path
d="M221.48 234.5C245.991 211.631 261.903 177.595 261.903 134C261.903
126.072 260.686 117.552 258.866 109.634H134V161.414H205.869C202.329
178.823 192.804 192.301 179.125 201.145L221.48 234.5Z"
fill="#4A90E2"
/>
<path
d="M58.9265 159.326C56.1947 151.162 54.8068 142.609 54.8172 134C54.8172
125.268 56.213 116.882 58.8037 109.043L13.8467 74.2584C4.64957 92.825
-0.0915078 113.28 1.86708e-05 134C1.86708e-05 155.44 4.96919 175.652
13.8132 193.574L58.9265 159.326Z"
fill="#FBBC05"
/>
</g>
<defs>
<clipPath id="clip0">
<rect width="268" height="268" fill="white" />
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

36
packages/builder/src/stores/backend/auth.js

@ -1,28 +1,25 @@
import { writable } from "svelte/store"
import api from "../../builderStore/api"
async function checkAuth() {
const response = await api.get("/api/self")
const user = await response.json()
if (response.status === 200) return user
return null
}
export function createAuthStore() {
const { subscribe, set } = writable(null)
checkAuth()
.then(user => set({ user }))
.catch(() => set({ user: null }))
const store = writable({ user: null })
return {
subscribe,
subscribe: store.subscribe,
checkAuth: async () => {
const response = await api.get("/api/self")
const user = await response.json()
if (response.status === 200) {
store.update(state => ({ ...state, user }))
} else {
store.update(state => ({ ...state, user: null }))
}
},
login: async creds => {
const response = await api.post(`/api/admin/auth`, creds)
const json = await response.json()
if (response.status === 200) {
set({ user: json.user })
store.update(state => ({ ...state, user: json.user }))
} else {
throw "Invalid credentials"
}
@ -34,7 +31,7 @@ export function createAuthStore() {
throw "Unable to create logout"
}
await response.json()
set({ user: null })
store.update(state => ({ ...state, user: null }))
},
createUser: async user => {
const response = await api.post(`/api/admin/users`, user)
@ -43,13 +40,6 @@ export function createAuthStore() {
}
await response.json()
},
firstUser: async () => {
const response = await api.post(`/api/admin/users/first`)
if (response.status !== 200) {
throw "Unable to create test user"
}
await response.json()
},
}
}

27
packages/builder/src/stores/portal/apps.js

@ -0,0 +1,27 @@
import { writable } from "svelte/store"
import { get } from "builderStore/api"
export function createAppStore() {
const store = writable([])
async function load() {
try {
const res = await get("/api/applications")
const json = await res.json()
if (res.ok && Array.isArray(json)) {
store.set(json)
} else {
store.set([])
}
} catch (error) {
store.set([])
}
}
return {
subscribe: store.subscribe,
load,
}
}
export const apps = createAppStore()

1
packages/builder/src/stores/portal/index.js

@ -1,3 +1,4 @@
export { organisation } from "./organisation"
export { users } from "./users"
export { admin } from "./admin"
export { apps } from "./apps"

10
packages/builder/vite.config.js

@ -6,7 +6,7 @@ import path from "path"
export default ({ mode }) => {
const isProduction = mode === "production"
return {
base: "/",
base: "/builder/",
build: {
minify: isProduction,
outDir: "../server/builder",
@ -52,6 +52,14 @@ export default ({ mode }) => {
find: "analytics",
replacement: path.resolve("./src/analytics"),
},
{
find: "actions",
replacement: path.resolve("./src/actions"),
},
{
find: "helpers",
replacement: path.resolve("./src/helpers"),
},
],
},
}

3
packages/standard-components/src/CardHorizontal.svelte

@ -1,7 +1,7 @@
<script>
import { getContext } from "svelte"
const { styleable } = getContext("sdk")
const { styleable, linkable } = getContext("sdk")
const component = getContext("component")
export const className = ""
@ -41,6 +41,7 @@
<footer>
<p class="subtext">{subtext}</p>
<a
use:linkable
style="--linkColor: {linkColor}; --linkHoverColor: {linkHoverColor}"
href={linkUrl || "/"}>{linkText}</a
>

4
packages/standard-components/src/StackedList.svelte

@ -1,7 +1,7 @@
<script>
import { getContext } from "svelte"
const { styleable } = getContext("sdk")
const { styleable, linkable } = getContext("sdk")
const component = getContext("component")
export let imageUrl = ""
@ -13,7 +13,7 @@
</script>
<div class="container" use:styleable={$component.styles}>
<a href={destinationUrl}>
<a use:linkable href={destinationUrl}>
<div class="stackedlist">
{#if showImage}
<div class="image-block">

Loading…
Cancel
Save