Merge branch 'develop' into api-tests-generate-tenants
This commit is contained in:
commit
cbc1901e1b
|
@ -139,6 +139,8 @@ spec:
|
|||
value: {{ .Values.globals.automationMaxIterations | quote }}
|
||||
- name: TENANT_FEATURE_FLAGS
|
||||
value: {{ .Values.globals.tenantFeatureFlags | quote }}
|
||||
- name: ENCRYPTION_KEY
|
||||
value: {{ .Values.globals.bbEncryptionKey | quote }}
|
||||
{{ if .Values.globals.bbAdminUserEmail }}
|
||||
- name: BB_ADMIN_USER_EMAIL
|
||||
value: {{ .Values.globals.bbAdminUserEmail | quote }}
|
||||
|
|
|
@ -146,6 +146,8 @@ spec:
|
|||
value: {{ .Values.globals.google.secret | quote }}
|
||||
- name: TENANT_FEATURE_FLAGS
|
||||
value: {{ .Values.globals.tenantFeatureFlags | quote }}
|
||||
- name: ENCRYPTION_KEY
|
||||
value: {{ .Values.globals.bbEncryptionKey | quote }}
|
||||
{{ if .Values.globals.elasticApmEnabled }}
|
||||
- name: ELASTIC_APM_ENABLED
|
||||
value: {{ .Values.globals.elasticApmEnabled | quote }}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"version": "2.2.12-alpha.50",
|
||||
"version": "2.2.12-alpha.54",
|
||||
"npmClient": "yarn",
|
||||
"packages": [
|
||||
"packages/*"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@budibase/backend-core",
|
||||
"version": "2.2.12-alpha.50",
|
||||
"version": "2.2.12-alpha.54",
|
||||
"description": "Budibase backend core libraries used in server and worker",
|
||||
"main": "dist/src/index.js",
|
||||
"types": "dist/src/index.d.ts",
|
||||
|
@ -23,7 +23,7 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@budibase/nano": "10.1.1",
|
||||
"@budibase/types": "2.2.12-alpha.50",
|
||||
"@budibase/types": "2.2.12-alpha.54",
|
||||
"@shopify/jest-koa-mocks": "5.0.1",
|
||||
"@techpass/passport-openidconnect": "0.3.2",
|
||||
"aws-cloudfront-sign": "2.2.0",
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "@budibase/bbui",
|
||||
"description": "A UI solution used in the different Budibase projects.",
|
||||
"version": "2.2.12-alpha.50",
|
||||
"version": "2.2.12-alpha.54",
|
||||
"license": "MPL-2.0",
|
||||
"svelte": "src/index.js",
|
||||
"module": "dist/bbui.es.js",
|
||||
|
@ -38,7 +38,7 @@
|
|||
],
|
||||
"dependencies": {
|
||||
"@adobe/spectrum-css-workflow-icons": "1.2.1",
|
||||
"@budibase/string-templates": "2.2.12-alpha.50",
|
||||
"@budibase/string-templates": "2.2.12-alpha.54",
|
||||
"@spectrum-css/accordion": "3.0.24",
|
||||
"@spectrum-css/actionbutton": "1.0.1",
|
||||
"@spectrum-css/actiongroup": "1.0.1",
|
||||
|
|
|
@ -86,7 +86,7 @@
|
|||
margin-left: 0;
|
||||
transition: color ease-out 130ms;
|
||||
}
|
||||
.is-selected:not(.spectrum-ActionButton--emphasized) {
|
||||
.is-selected:not(.spectrum-ActionButton--emphasized):not(.spectrum-ActionButton--quiet) {
|
||||
background: var(--spectrum-global-color-gray-300);
|
||||
border-color: var(--spectrum-global-color-gray-700);
|
||||
}
|
||||
|
|
|
@ -16,10 +16,10 @@ export default function positionDropdown(
|
|||
top: null,
|
||||
}
|
||||
|
||||
let popoverLeftPad = 20
|
||||
|
||||
// Determine vertical styles
|
||||
if (window.innerHeight - anchorBounds.bottom < 100) {
|
||||
if (align === "right-outside") {
|
||||
styles.top = anchorBounds.top
|
||||
} else if (window.innerHeight - anchorBounds.bottom < 100) {
|
||||
styles.top = anchorBounds.top - elementBounds.height - 5
|
||||
} else {
|
||||
styles.top = anchorBounds.bottom + 5
|
||||
|
@ -34,15 +34,9 @@ export default function positionDropdown(
|
|||
styles.minWidth = anchorBounds.width
|
||||
}
|
||||
if (align === "right") {
|
||||
let left =
|
||||
anchorBounds.left + anchorBounds.width / 2 - elementBounds.width
|
||||
// Accommodate margin on popover: 1.25rem; ~20px
|
||||
if (left + elementBounds.width + popoverLeftPad > window.innerWidth) {
|
||||
left -= 20
|
||||
}
|
||||
styles.left = left
|
||||
} else if (align === "right-side") {
|
||||
styles.left = anchorBounds.left + anchorBounds.width
|
||||
styles.left = anchorBounds.left + anchorBounds.width - elementBounds.width
|
||||
} else if (align === "right-outside") {
|
||||
styles.left = anchorBounds.right + 10
|
||||
} else {
|
||||
styles.left = anchorBounds.left
|
||||
}
|
||||
|
|
|
@ -247,10 +247,6 @@
|
|||
width: 100%;
|
||||
}
|
||||
|
||||
.no-variables-height {
|
||||
height: 100px;
|
||||
}
|
||||
|
||||
.no-variables-text {
|
||||
padding: var(--spacing-m);
|
||||
color: var(--spectrum-global-color-gray-600);
|
||||
|
|
|
@ -15,15 +15,10 @@
|
|||
export let portalTarget
|
||||
export let dataCy
|
||||
export let maxWidth
|
||||
export let direction = "bottom"
|
||||
export let showTip = false
|
||||
export let open = false
|
||||
export let useAnchorWidth = false
|
||||
export let dismissible = true
|
||||
|
||||
$: tooltipClasses = showTip
|
||||
? `spectrum-Popover--withTip spectrum-Popover--${direction}`
|
||||
: ""
|
||||
$: target = portalTarget || getContext(Context.PopoverRoot) || ".spectrum"
|
||||
|
||||
export const show = () => {
|
||||
|
@ -62,29 +57,31 @@
|
|||
</script>
|
||||
|
||||
{#if open}
|
||||
<Portal {target}>
|
||||
<div
|
||||
tabindex="0"
|
||||
use:positionDropdown={{
|
||||
anchor,
|
||||
align,
|
||||
maxWidth,
|
||||
useAnchorWidth,
|
||||
showTip: false,
|
||||
}}
|
||||
use:clickOutside={{
|
||||
callback: dismissible ? handleOutsideClick : () => {},
|
||||
anchor,
|
||||
}}
|
||||
on:keydown={handleEscape}
|
||||
class={"spectrum-Popover is-open " + (tooltipClasses || "")}
|
||||
role="presentation"
|
||||
data-cy={dataCy}
|
||||
transition:fly|local={{ y: -20, duration: 200 }}
|
||||
>
|
||||
<slot />
|
||||
</div>
|
||||
</Portal>
|
||||
{#key anchor}
|
||||
<Portal {target}>
|
||||
<div
|
||||
tabindex="0"
|
||||
use:positionDropdown={{
|
||||
anchor,
|
||||
align,
|
||||
maxWidth,
|
||||
useAnchorWidth,
|
||||
showTip: false,
|
||||
}}
|
||||
use:clickOutside={{
|
||||
callback: dismissible ? handleOutsideClick : () => {},
|
||||
anchor,
|
||||
}}
|
||||
on:keydown={handleEscape}
|
||||
class="spectrum-Popover is-open"
|
||||
role="presentation"
|
||||
data-cy={dataCy}
|
||||
transition:fly|local={{ y: -20, duration: 200 }}
|
||||
>
|
||||
<slot />
|
||||
</div>
|
||||
</Portal>
|
||||
{/key}
|
||||
{/if}
|
||||
|
||||
<style>
|
||||
|
@ -93,13 +90,4 @@
|
|||
border-color: var(--spectrum-global-color-gray-300);
|
||||
overflow: auto;
|
||||
}
|
||||
.spectrum-Popover.is-open.spectrum-Popover--withTip {
|
||||
margin-top: var(--spacing-xs);
|
||||
margin-left: var(--spacing-xl);
|
||||
}
|
||||
:global(.spectrum-Popover--bottom .spectrum-Popover-tip),
|
||||
:global(.spectrum-Popover--top .spectrum-Popover-tip) {
|
||||
left: 90%;
|
||||
margin-left: calc(var(--spectrum-global-dimension-size-150) * -1);
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@budibase/builder",
|
||||
"version": "2.2.12-alpha.50",
|
||||
"version": "2.2.12-alpha.54",
|
||||
"license": "GPL-3.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
|
@ -71,10 +71,13 @@
|
|||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@budibase/bbui": "2.2.12-alpha.50",
|
||||
"@budibase/client": "2.2.12-alpha.50",
|
||||
"@budibase/frontend-core": "2.2.12-alpha.50",
|
||||
"@budibase/string-templates": "2.2.12-alpha.50",
|
||||
"@budibase/bbui": "2.2.12-alpha.54",
|
||||
"@budibase/client": "2.2.12-alpha.54",
|
||||
"@budibase/frontend-core": "2.2.12-alpha.54",
|
||||
"@budibase/string-templates": "2.2.12-alpha.54",
|
||||
"@fortawesome/fontawesome-svg-core": "^6.2.1",
|
||||
"@fortawesome/free-brands-svg-icons": "^6.2.1",
|
||||
"@fortawesome/free-solid-svg-icons": "^6.2.1",
|
||||
"@sentry/browser": "5.19.1",
|
||||
"@spectrum-css/accordion": "^3.0.24",
|
||||
"@spectrum-css/page": "^3.0.1",
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
import { routes } from "../.routify/routes"
|
||||
import { NotificationDisplay, BannerDisplay } from "@budibase/bbui"
|
||||
import { parse, stringify } from "qs"
|
||||
import HelpIcon from "components/common/HelpIcon.svelte"
|
||||
import LicensingOverlays from "components/portal/licensing/LicensingOverlays.svelte"
|
||||
|
||||
const queryHandler = { parse, stringify }
|
||||
|
@ -15,7 +14,6 @@
|
|||
<LicensingOverlays />
|
||||
<Router {routes} config={{ queryHandler }} />
|
||||
<div class="modal-container" />
|
||||
<HelpIcon />
|
||||
|
||||
<style>
|
||||
.modal-container {
|
||||
|
|
|
@ -182,3 +182,9 @@
|
|||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
<style>
|
||||
svg {
|
||||
padding-top: 3px;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -11,6 +11,6 @@
|
|||
|
||||
<style>
|
||||
img {
|
||||
padding-top: 1px;
|
||||
padding-top: 5px;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -29,6 +29,18 @@
|
|||
: BUDIBASE_INTERNAL_DB_ID
|
||||
|
||||
export let name
|
||||
export let beforeSave = async () => {}
|
||||
export let afterSave = async table => {
|
||||
notifications.success(`Table ${name} created successfully.`)
|
||||
|
||||
// Navigate to new table
|
||||
const currentUrl = $url()
|
||||
const path = currentUrl.endsWith("data")
|
||||
? `./table/${table._id}`
|
||||
: `../../table/${table._id}`
|
||||
$goto(path)
|
||||
}
|
||||
|
||||
let error = ""
|
||||
let autoColumns = getAutoColumnInformation()
|
||||
let schema = {}
|
||||
|
@ -78,15 +90,9 @@
|
|||
// Create table
|
||||
let table
|
||||
try {
|
||||
await beforeSave()
|
||||
table = await tables.save(newTable)
|
||||
notifications.success(`Table ${name} created successfully.`)
|
||||
|
||||
// Navigate to new table
|
||||
const currentUrl = $url()
|
||||
const path = currentUrl.endsWith("data")
|
||||
? `./table/${table._id}`
|
||||
: `../../table/${table._id}`
|
||||
$goto(path)
|
||||
await afterSave(table)
|
||||
} catch (e) {
|
||||
notifications.error(e)
|
||||
// reload in case the table was created
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
<script context="module">
|
||||
import { dom, library } from "@fortawesome/fontawesome-svg-core"
|
||||
import {
|
||||
faEnvelope,
|
||||
faXmark,
|
||||
faBook,
|
||||
faPlay,
|
||||
faLock,
|
||||
faFileArrowUp,
|
||||
faChevronLeft,
|
||||
} from "@fortawesome/free-solid-svg-icons"
|
||||
import { faGithub, faDiscord } from "@fortawesome/free-brands-svg-icons"
|
||||
|
||||
library.add(
|
||||
faXmark,
|
||||
faBook,
|
||||
faPlay,
|
||||
faLock,
|
||||
faGithub,
|
||||
faDiscord,
|
||||
faEnvelope,
|
||||
faFileArrowUp,
|
||||
faChevronLeft
|
||||
)
|
||||
dom.watch()
|
||||
</script>
|
||||
|
||||
<script>
|
||||
export let name
|
||||
</script>
|
||||
|
||||
<span>
|
||||
<i class={name} />
|
||||
</span>
|
||||
|
||||
<style>
|
||||
span {
|
||||
display: contents;
|
||||
color: var(--spectrum-global-color-gray-900);
|
||||
}
|
||||
</style>
|
|
@ -1,42 +0,0 @@
|
|||
<script>
|
||||
import { Icon, Body } from "@budibase/bbui"
|
||||
</script>
|
||||
|
||||
<a target="_blank" href="https://github.com/Budibase/budibase/discussions">
|
||||
<div class="inner hoverable">
|
||||
<div class="hidden hoverable">
|
||||
<Body size="S">Need help? Go to our forums</Body>
|
||||
</div>
|
||||
<Icon name="Help" size="XXL" />
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<style>
|
||||
.inner {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--spacing-s);
|
||||
}
|
||||
.inner :global(*) {
|
||||
pointer-events: all;
|
||||
transition: color var(--spectrum-global-animation-duration-100, 130ms);
|
||||
}
|
||||
.inner:hover :global(*) {
|
||||
color: var(--spectrum-alias-icon-color-selected-hover);
|
||||
cursor: pointer;
|
||||
}
|
||||
a {
|
||||
color: inherit;
|
||||
position: absolute;
|
||||
bottom: var(--spacing-m);
|
||||
right: var(--spacing-m);
|
||||
border-radius: 55%;
|
||||
z-index: 99999;
|
||||
}
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
.inner:hover .hidden {
|
||||
display: block;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,182 @@
|
|||
<script>
|
||||
import FontAwesomeIcon from "./FontAwesomeIcon.svelte"
|
||||
import { Popover, Heading, Body } from "@budibase/bbui"
|
||||
import { licensing } from "stores/portal"
|
||||
import { isEnabled, TENANT_FEATURE_FLAGS } from "helpers/featureFlags"
|
||||
|
||||
$: isPremiumUser = $licensing.license && !$licensing.isFreePlan
|
||||
|
||||
let show
|
||||
let hide
|
||||
let popoverAnchor
|
||||
</script>
|
||||
|
||||
<div bind:this={popoverAnchor} class="help">
|
||||
<button class="openMenu" on:click={show}>Help</button>
|
||||
<Popover
|
||||
class="helpMenuPopoverOverride"
|
||||
bind:show
|
||||
bind:hide
|
||||
anchor={popoverAnchor}
|
||||
>
|
||||
<nav class="helpMenu">
|
||||
<div class="header">
|
||||
<Heading size="XS">Help resources</Heading>
|
||||
<button on:click={hide} class="closeButton">
|
||||
<FontAwesomeIcon name="fa-solid fa-xmark" />
|
||||
</button>
|
||||
</div>
|
||||
<div class="divider" />
|
||||
<a target="_blank" href="https://docs.budibase.com/docs">
|
||||
<div class="icon">
|
||||
<FontAwesomeIcon name="fa-solid fa-book" />
|
||||
</div>
|
||||
<Body size="S">Help docs</Body>
|
||||
</a>
|
||||
<div class="divider" />
|
||||
<a
|
||||
target="_blank"
|
||||
href="https://github.com/Budibase/budibase/discussions"
|
||||
>
|
||||
<div class="icon">
|
||||
<FontAwesomeIcon name="fa-brands fa-github" />
|
||||
</div>
|
||||
<Body size="S">Discussions</Body>
|
||||
</a>
|
||||
<div class="divider" />
|
||||
<a target="_blank" href="https://discord.com/invite/ZepTmGbtfF">
|
||||
<div class="icon">
|
||||
<FontAwesomeIcon name="fa-brands fa-discord" />
|
||||
</div>
|
||||
<Body size="S">Discord</Body>
|
||||
</a>
|
||||
<div class="divider" />
|
||||
<a target="_blank" href="https://vimeo.com/showcase/budibase-university">
|
||||
<div class="icon">
|
||||
<FontAwesomeIcon name="fa-solid fa-play" />
|
||||
</div>
|
||||
<Body size="S">Budibase University</Body>
|
||||
</a>
|
||||
<div class="divider" />
|
||||
{#if isEnabled(TENANT_FEATURE_FLAGS.LICENSING)}
|
||||
<a
|
||||
href={isPremiumUser
|
||||
? "mailto:support@budibase.com"
|
||||
: "/builder/portal/account/usage"}
|
||||
>
|
||||
<div class="premiumLinkContent" class:disabled={!isPremiumUser}>
|
||||
<div class="icon">
|
||||
<FontAwesomeIcon name="fa-solid fa-envelope" />
|
||||
</div>
|
||||
<Body size="S">Email support</Body>
|
||||
</div>
|
||||
{#if !isPremiumUser}
|
||||
<div class="premiumBadge">
|
||||
<div class="icon">
|
||||
<FontAwesomeIcon name="fa-solid fa-lock" />
|
||||
</div>
|
||||
<Body size="XS">Premium</Body>
|
||||
</div>
|
||||
{/if}
|
||||
</a>
|
||||
{/if}
|
||||
</nav>
|
||||
</Popover>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.help {
|
||||
z-index: 2;
|
||||
position: absolute;
|
||||
bottom: var(--spacing-xl);
|
||||
right: 24px;
|
||||
}
|
||||
|
||||
.openMenu {
|
||||
cursor: pointer;
|
||||
background-color: #6a1dc8;
|
||||
border-radius: 100px;
|
||||
color: white;
|
||||
border: none;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
padding: 10px 18px;
|
||||
}
|
||||
|
||||
.helpMenu {
|
||||
background-color: var(--background-alt);
|
||||
overflow: hidden;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
nav {
|
||||
min-width: 280px;
|
||||
}
|
||||
|
||||
.divider {
|
||||
border-bottom: 1px solid var(--spectrum-global-color-gray-300);
|
||||
}
|
||||
|
||||
.header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 0 0 16px;
|
||||
}
|
||||
|
||||
.closeButton {
|
||||
cursor: pointer;
|
||||
font-size: 13px;
|
||||
color: var(--grey-6);
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
padding: 18px 16px;
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.closeButton:hover {
|
||||
color: var(--grey-8);
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
color: white;
|
||||
display: flex;
|
||||
padding: 12px;
|
||||
align-items: center;
|
||||
transition: filter 0.5s, background 0.13s ease-out;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
background-color: var(--spectrum-global-color-gray-200);
|
||||
}
|
||||
|
||||
a:last-child {
|
||||
padding: 8px 12px;
|
||||
}
|
||||
|
||||
.icon {
|
||||
font-size: 13px;
|
||||
margin-right: 7px;
|
||||
min-width: 18px;
|
||||
justify-content: center;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.premiumLinkContent {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.disabled {
|
||||
opacity: 60%;
|
||||
}
|
||||
|
||||
.premiumBadge {
|
||||
align-items: center;
|
||||
margin-left: auto;
|
||||
display: flex;
|
||||
border: 1px solid var(--spectrum-global-color-gray-400);
|
||||
border-radius: 4px;
|
||||
padding: 4px 7px 5px 8px;
|
||||
}
|
||||
</style>
|
|
@ -179,7 +179,7 @@
|
|||
|
||||
<span class="detailPopover">
|
||||
<Popover
|
||||
align="right-side"
|
||||
align="right-outside"
|
||||
bind:this={popover}
|
||||
anchor={popoverAnchor}
|
||||
maxWidth={300}
|
||||
|
|
|
@ -125,7 +125,6 @@
|
|||
align="right"
|
||||
disabled={!isPublished}
|
||||
dataCy="publish-popover-menu"
|
||||
showTip={true}
|
||||
anchor={publishPopoverAnchor}
|
||||
>
|
||||
<Layout gap="M">
|
||||
|
|
|
@ -2,26 +2,29 @@
|
|||
import { Button } from "@budibase/bbui"
|
||||
import { goto } from "@roxi/routify"
|
||||
import { auth, admin } from "stores/portal"
|
||||
import { isEnabled, TENANT_FEATURE_FLAGS } from "helpers/featureFlags"
|
||||
</script>
|
||||
|
||||
{#if $admin.cloud && $auth?.user?.accountPortalAccess}
|
||||
<Button
|
||||
cta
|
||||
size="S"
|
||||
on:click
|
||||
on:click={() => {
|
||||
window.open($admin.accountPortalUrl + "/portal/upgrade", "_blank")
|
||||
}}
|
||||
>
|
||||
Upgrade
|
||||
</Button>
|
||||
{:else if !$admin.cloud && $auth.isAdmin}
|
||||
<Button
|
||||
cta
|
||||
size="S"
|
||||
on:click={() => $goto("/builder/portal/account/upgrade")}
|
||||
on:click
|
||||
>
|
||||
Upgrade
|
||||
</Button>
|
||||
{#if isEnabled(TENANT_FEATURE_FLAGS.LICENSING)}
|
||||
{#if $admin.cloud && $auth?.user?.accountPortalAccess}
|
||||
<Button
|
||||
cta
|
||||
size="S"
|
||||
on:click
|
||||
on:click={() => {
|
||||
window.open($admin.accountPortalUrl + "/portal/upgrade", "_blank")
|
||||
}}
|
||||
>
|
||||
Upgrade
|
||||
</Button>
|
||||
{:else if !$admin.cloud && $auth.isAdmin}
|
||||
<Button
|
||||
cta
|
||||
size="S"
|
||||
on:click={() => $goto("/builder/portal/account/upgrade")}
|
||||
on:click
|
||||
>
|
||||
Upgrade
|
||||
</Button>
|
||||
{/if}
|
||||
{/if}
|
||||
|
|
|
@ -1,18 +1,20 @@
|
|||
<script>
|
||||
import { isActive, redirect, goto, url } from "@roxi/routify"
|
||||
import { Icon, notifications, Tabs, Tab } from "@budibase/bbui"
|
||||
import { organisation, auth, menu } from "stores/portal"
|
||||
import { organisation, auth, menu, apps } from "stores/portal"
|
||||
import { onMount } from "svelte"
|
||||
import UpgradeButton from "./_components/UpgradeButton.svelte"
|
||||
import MobileMenu from "./_components/MobileMenu.svelte"
|
||||
import Logo from "./_components/Logo.svelte"
|
||||
import UserDropdown from "./_components/UserDropdown.svelte"
|
||||
import HelpMenu from "components/common/HelpMenu.svelte"
|
||||
|
||||
let loaded = false
|
||||
let mobileMenuVisible = false
|
||||
let activeTab = "Apps"
|
||||
|
||||
$: $url(), updateActiveTab($menu)
|
||||
$: fullScreen = !$apps?.length
|
||||
|
||||
const updateActiveTab = menu => {
|
||||
for (let entry of menu) {
|
||||
|
@ -45,7 +47,10 @@
|
|||
})
|
||||
</script>
|
||||
|
||||
{#if $auth.user && loaded}
|
||||
{#if fullScreen}
|
||||
<slot />
|
||||
{:else if $auth.user && loaded}
|
||||
<HelpMenu />
|
||||
<div class="container">
|
||||
<div class="nav">
|
||||
<div class="branding">
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
import { notifications } from "@budibase/bbui"
|
||||
import { apps, templates, licensing, groups } from "stores/portal"
|
||||
import { onMount } from "svelte"
|
||||
import { goto } from "@roxi/routify"
|
||||
import { redirect } from "@roxi/routify"
|
||||
|
||||
// Don't block loading if we've already hydrated state
|
||||
let loaded = $apps.length > 0
|
||||
|
@ -24,7 +24,7 @@
|
|||
|
||||
// Go to new app page if no apps exists
|
||||
if (!$apps.length) {
|
||||
$goto("./create")
|
||||
$redirect("./onboarding")
|
||||
}
|
||||
} catch (error) {
|
||||
notifications.error("Error loading apps and templates")
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
<script>
|
||||
import { url } from "@roxi/routify"
|
||||
import FirstAppOnboarding from "./onboarding/index.svelte"
|
||||
import { Layout, Page, Button, Modal } from "@budibase/bbui"
|
||||
import CreateAppModal from "components/start/CreateAppModal.svelte"
|
||||
import TemplateDisplay from "components/common/TemplateDisplay.svelte"
|
||||
|
@ -38,42 +39,45 @@
|
|||
}
|
||||
</script>
|
||||
|
||||
<Page>
|
||||
<Layout noPadding gap="L">
|
||||
<Breadcrumbs>
|
||||
<Breadcrumb url={$url("./")} text="Apps" />
|
||||
<Breadcrumb text="Create new app" />
|
||||
</Breadcrumbs>
|
||||
<Header title={$apps.length ? "Create new app" : "Create your first app"}>
|
||||
<div slot="buttons">
|
||||
<Button
|
||||
dataCy="import-app-btn"
|
||||
size="M"
|
||||
secondary
|
||||
on:click={initiateAppImport}
|
||||
>
|
||||
Import app
|
||||
</Button>
|
||||
<Button
|
||||
dataCy="create-app-btn"
|
||||
size="M"
|
||||
cta
|
||||
on:click={initiateAppCreation}
|
||||
>
|
||||
Start from scratch
|
||||
</Button>
|
||||
</div>
|
||||
</Header>
|
||||
<TemplateDisplay templates={$templates} />
|
||||
</Layout>
|
||||
</Page>
|
||||
|
||||
<Modal
|
||||
bind:this={creationModal}
|
||||
padding={false}
|
||||
width="600px"
|
||||
on:hide={stopAppCreation}
|
||||
>
|
||||
<CreateAppModal {template} />
|
||||
</Modal>
|
||||
<AppLimitModal bind:this={appLimitModal} />
|
||||
{#if !$apps.length}
|
||||
<FirstAppOnboarding />
|
||||
{:else}
|
||||
<Page>
|
||||
<Layout noPadding gap="L">
|
||||
<Breadcrumbs>
|
||||
<Breadcrumb url={$url("./")} text="Apps" />
|
||||
<Breadcrumb text="Create new app" />
|
||||
</Breadcrumbs>
|
||||
<Header title={"Create new app"}>
|
||||
<div slot="buttons">
|
||||
<Button
|
||||
dataCy="import-app-btn"
|
||||
size="M"
|
||||
secondary
|
||||
on:click={initiateAppImport}
|
||||
>
|
||||
Import app
|
||||
</Button>
|
||||
<Button
|
||||
dataCy="create-app-btn"
|
||||
size="M"
|
||||
cta
|
||||
on:click={initiateAppCreation}
|
||||
>
|
||||
Start from scratch
|
||||
</Button>
|
||||
</div>
|
||||
</Header>
|
||||
<TemplateDisplay templates={$templates} />
|
||||
</Layout>
|
||||
</Page>
|
||||
<Modal
|
||||
bind:this={creationModal}
|
||||
padding={false}
|
||||
width="600px"
|
||||
on:hide={stopAppCreation}
|
||||
>
|
||||
<CreateAppModal {template} />
|
||||
</Modal>
|
||||
<AppLimitModal bind:this={appLimitModal} />
|
||||
{/if}
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
<script>
|
||||
import PanelHeader from "./PanelHeader.svelte"
|
||||
export let onBack = () => {}
|
||||
</script>
|
||||
|
||||
<div>
|
||||
<PanelHeader
|
||||
title="Give it some data"
|
||||
subtitle="Not ready to add yours? Get started with sample data!"
|
||||
{onBack}
|
||||
/>
|
||||
<slot />
|
||||
</div>
|
|
@ -0,0 +1,109 @@
|
|||
<script>
|
||||
import { Button, FancyForm, FancyInput, FancyCheckbox } from "@budibase/bbui"
|
||||
import { capitalise } from "helpers/helpers"
|
||||
import PanelHeader from "./PanelHeader.svelte"
|
||||
|
||||
export let title = ""
|
||||
export let onBack = null
|
||||
export let onNext = () => {}
|
||||
export let fields = {}
|
||||
|
||||
let errors = {}
|
||||
|
||||
const formatName = name => {
|
||||
if (name === "ca") {
|
||||
return "CA"
|
||||
}
|
||||
|
||||
if (name === "ssl") {
|
||||
return "SSL"
|
||||
}
|
||||
|
||||
if (name === "rejectUnauthorized") {
|
||||
return "Reject Unauthorized"
|
||||
}
|
||||
|
||||
return capitalise(name)
|
||||
}
|
||||
|
||||
const getDefaultValues = fields => {
|
||||
const newValues = {}
|
||||
|
||||
Object.entries(fields).forEach(([name, { default: defaultValue }]) => {
|
||||
if (defaultValue) {
|
||||
newValues[name] = defaultValue
|
||||
}
|
||||
})
|
||||
|
||||
return newValues
|
||||
}
|
||||
|
||||
const values = getDefaultValues(fields)
|
||||
|
||||
const validateRequired = value => {
|
||||
if (value.length < 1) {
|
||||
return "Required field"
|
||||
}
|
||||
}
|
||||
|
||||
const getIsValid = (fields, errors, values) => {
|
||||
for (const [name, { required }] of Object.entries(fields)) {
|
||||
if (required && !values[name]) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return Object.values(errors).every(error => !error)
|
||||
}
|
||||
|
||||
$: isValid = getIsValid(fields, errors, values)
|
||||
|
||||
const handleNext = () => {
|
||||
const parsedValues = {}
|
||||
|
||||
Object.entries(values).forEach(([name, value]) => {
|
||||
if (fields[name].type === "number") {
|
||||
parsedValues[name] = parseInt(value, 10)
|
||||
} else {
|
||||
parsedValues[name] = value
|
||||
}
|
||||
})
|
||||
|
||||
return onNext(parsedValues)
|
||||
}
|
||||
</script>
|
||||
|
||||
<div>
|
||||
<PanelHeader
|
||||
{title}
|
||||
subtitle="Fill in the required fields to fetch your tables"
|
||||
{onBack}
|
||||
/>
|
||||
<div class="form">
|
||||
<FancyForm>
|
||||
{#each Object.entries(fields) as [name, { type, default: defaultValue, required }]}
|
||||
{#if type !== "boolean"}
|
||||
<FancyInput
|
||||
bind:value={values[name]}
|
||||
bind:error={errors[name]}
|
||||
validate={required ? validateRequired : () => {}}
|
||||
label={formatName(name)}
|
||||
{type}
|
||||
/>
|
||||
{/if}
|
||||
{/each}
|
||||
{#each Object.entries(fields) as [name, { type, default: defaultValue, required }]}
|
||||
{#if type === "boolean"}
|
||||
<FancyCheckbox bind:value={values[name]} text={formatName(name)} />
|
||||
{/if}
|
||||
{/each}
|
||||
</FancyForm>
|
||||
</div>
|
||||
<Button cta disabled={!isValid} on:click={handleNext}>Connect</Button>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.form {
|
||||
margin-bottom: 36px;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,254 @@
|
|||
<script>
|
||||
export let name = ""
|
||||
export let showData = false
|
||||
|
||||
const rows = [
|
||||
{
|
||||
firstName: "Julie",
|
||||
lastName: "Jimenez",
|
||||
email: "julie.jimenez@example.com",
|
||||
address: "4250 New Street",
|
||||
city: "Stevenage",
|
||||
postcode: "EE32 3SE",
|
||||
phone: "01754 13523",
|
||||
},
|
||||
{
|
||||
firstName: "Mandy",
|
||||
lastName: "Clark",
|
||||
email: "mandy.clark@example.com",
|
||||
address: "8632 North Street",
|
||||
city: "Hereford",
|
||||
postcode: "GT81 7DG",
|
||||
phone: "016973 32814",
|
||||
},
|
||||
{
|
||||
firstName: "Holly",
|
||||
lastName: "Carroll",
|
||||
email: "holly.carroll@example.com",
|
||||
address: "5976 Springfield Road",
|
||||
city: "Edinburgh",
|
||||
postcode: "Y4 2LH",
|
||||
phone: "016977 73053",
|
||||
},
|
||||
{
|
||||
firstName: "Francis",
|
||||
lastName: "Castro",
|
||||
email: "francis.castro@example.com",
|
||||
address: "3970 High Street",
|
||||
city: "Wells",
|
||||
postcode: "X12 6QA",
|
||||
phone: "017684 23551",
|
||||
},
|
||||
]
|
||||
</script>
|
||||
|
||||
<div tabindex="-1" class="exampleApp">
|
||||
<div class="page">
|
||||
<div class="header">
|
||||
<img alt="Budibase Logo" src={"https://i.imgur.com/Xhdt1YP.png"} />
|
||||
<h1>{name}</h1>
|
||||
</div>
|
||||
<div class="nav">Home</div>
|
||||
<table class={`table ${showData ? "tableVisible" : ""}`}>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>FIRST NAME</th>
|
||||
<th>LAST NAME</th>
|
||||
<th>EMAIL</th>
|
||||
<th>ADDRESS</th>
|
||||
<th>CITY</th>
|
||||
<th>POSTCODE</th>
|
||||
<th>PHONE</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each rows as row}
|
||||
<tr>
|
||||
{#each Object.values(row) as value}
|
||||
<td>{value}</td>
|
||||
{/each}
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
</table>
|
||||
<div class={`sidePanel ${showData ? "sidePanelVisible" : ""}`}>
|
||||
<h2>{rows[0].firstName}</h2>
|
||||
<div class="field">
|
||||
<label for="exampleLastName">lastName</label>
|
||||
<input
|
||||
id="exampleLastName"
|
||||
tabIndex="-1"
|
||||
readonly
|
||||
value={rows[0].lastName}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label for="exampleEmail">Email</label>
|
||||
<input id="exampleEmail" tabIndex="-1" readonly value={rows[0].email} />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label for="exampleAddress">Address</label>
|
||||
<input
|
||||
id="exampleAddress"
|
||||
tabIndex="-1"
|
||||
readonly
|
||||
value={rows[0].address}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label for="exampleCity">City</label>
|
||||
<input id="exampleCity" tabIndex="-1" readonly value={rows[0].city} />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label for="examplePostcode">Postcode</label>
|
||||
<input
|
||||
id="examplePostcode"
|
||||
tabIndex="-1"
|
||||
readonly
|
||||
value={rows[0].postcode}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label for="examplePhone">Phone</label>
|
||||
<input id="examplePhone" tabIndex="-1" readonly value={rows[0].phone} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.exampleApp {
|
||||
box-sizing: border-box;
|
||||
height: 100vh;
|
||||
padding: 100px 0 100px 100px;
|
||||
--text: #191919;
|
||||
--lightText: #303030;
|
||||
--extraLightText: #646464;
|
||||
--backgroundLight: #ffffff;
|
||||
--background: #f5f5f5;
|
||||
--tableBorder: 1px solid #e6e6e6;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.page {
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
height: 100%;
|
||||
background-color: var(--background);
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.header {
|
||||
background-color: var(--backgroundLight);
|
||||
display: flex;
|
||||
padding: 32px 0 20px 32px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.header img {
|
||||
height: 36px;
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
.header h1 {
|
||||
margin: 0;
|
||||
font-weight: 600;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.nav {
|
||||
background-color: var(--backgroundLight);
|
||||
padding: 20px 0 20px 32px;
|
||||
font-weight: 600;
|
||||
font-size: 16px;
|
||||
border-bottom: 1px solid #d0d0d0;
|
||||
}
|
||||
|
||||
table {
|
||||
margin: 32px;
|
||||
border: var(--tableBorder);
|
||||
border-collapse: collapse;
|
||||
min-width: 100%;
|
||||
}
|
||||
|
||||
thead {
|
||||
border-bottom: var(--tableBorder);
|
||||
}
|
||||
|
||||
thead th {
|
||||
font-family: "Source Sans Pro";
|
||||
color: var(--lightText);
|
||||
white-space: nowrap;
|
||||
padding: 12px;
|
||||
font-weight: 600;
|
||||
font-size: 12px;
|
||||
text-align: left;
|
||||
min-width: 70px;
|
||||
}
|
||||
|
||||
tbody td {
|
||||
border-bottom: 1px solid #e6e6e6;
|
||||
background-color: var(--backgroundLight);
|
||||
padding: 12px;
|
||||
color: var(--extraLightText);
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.table {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.tableVisible {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.sidePanel {
|
||||
position: absolute;
|
||||
width: 300px;
|
||||
background-color: var(--backgroundLight);
|
||||
box-shadow: 0px 4px 25px 0px #00000040;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
right: -364px;
|
||||
padding: 42px 32px;
|
||||
}
|
||||
|
||||
.sidePanelVisible {
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.sidePanel h2 {
|
||||
margin: 0;
|
||||
font-weight: 600;
|
||||
font-size: 22px;
|
||||
margin-bottom: 35px;
|
||||
}
|
||||
|
||||
.field {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
align-items: center;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.field label {
|
||||
font-weight: 500;
|
||||
font-size: 12px;
|
||||
color: #b0b0b0;
|
||||
width: 65px;
|
||||
}
|
||||
|
||||
.field input {
|
||||
border: 1px solid #d0d0d0;
|
||||
border-radius: 4px;
|
||||
color: var(--lightText);
|
||||
padding: 7.5px 12px;
|
||||
font-size: 13px;
|
||||
flex-grow: 1;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,60 @@
|
|||
<script>
|
||||
import { Button, FancyForm, FancyInput } from "@budibase/bbui"
|
||||
import PanelHeader from "./PanelHeader.svelte"
|
||||
|
||||
export let name = ""
|
||||
export let url = ""
|
||||
export let onNext = () => {}
|
||||
let nameError = null
|
||||
let urlError = null
|
||||
|
||||
$: isValid = name.length && url.length && !nameError && !urlError
|
||||
|
||||
const validateName = name => {
|
||||
if (name.length < 1) {
|
||||
return "Name must be provided"
|
||||
}
|
||||
}
|
||||
|
||||
const validateUrl = url => {
|
||||
if (url.length < 1) {
|
||||
return "URL must be provided"
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div>
|
||||
<PanelHeader
|
||||
title="Build your first app"
|
||||
subtitle="Name your app and set the URL"
|
||||
/>
|
||||
<FancyForm>
|
||||
<FancyInput
|
||||
bind:value={name}
|
||||
bind:error={nameError}
|
||||
validate={validateName}
|
||||
label="Name"
|
||||
/>
|
||||
<FancyInput
|
||||
bind:value={url}
|
||||
bind:error={urlError}
|
||||
validate={validateUrl}
|
||||
label="URL"
|
||||
/>
|
||||
</FancyForm>
|
||||
{#if url}
|
||||
<p><span class="host">{window.location.origin}/app/</span>{url}</p>
|
||||
{:else}
|
||||
<p></p>
|
||||
{/if}
|
||||
<Button size="L" cta disabled={!isValid} on:click={onNext}>Lets go!</Button>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
p {
|
||||
color: white;
|
||||
}
|
||||
.host {
|
||||
color: #b0b0b0;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,49 @@
|
|||
<script>
|
||||
import FontAwesomeIcon from "components/common/FontAwesomeIcon.svelte"
|
||||
import { Heading, Body } from "@budibase/bbui"
|
||||
|
||||
export let onBack = null
|
||||
export let title = ""
|
||||
export let subtitle = ""
|
||||
</script>
|
||||
|
||||
<div class="header">
|
||||
<img
|
||||
alt="Budibase Logo"
|
||||
class="budibaseLogo"
|
||||
src={"https://i.imgur.com/Xhdt1YP.png"}
|
||||
/>
|
||||
<div class="headingAndBack">
|
||||
{#if onBack}
|
||||
<button on:click={onBack}>
|
||||
<FontAwesomeIcon name="fa-solid fa-chevron-left" />
|
||||
</button>
|
||||
{/if}
|
||||
<Heading>{title}</Heading>
|
||||
</div>
|
||||
<Body>{subtitle}</Body>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.header {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.budibaseLogo {
|
||||
width: 42px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.headingAndBack {
|
||||
display: flex;
|
||||
margin-bottom: 13px;
|
||||
}
|
||||
|
||||
button {
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
color: white;
|
||||
padding-right: 18px;
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,202 @@
|
|||
<script>
|
||||
import { goto } from "@roxi/routify"
|
||||
import NamePanel from "./_components/NamePanel.svelte"
|
||||
import DataPanel from "./_components/DataPanel.svelte"
|
||||
import DatasourceConfigPanel from "./_components/DatasourceConfigPanel.svelte"
|
||||
import ExampleApp from "./_components/ExampleApp.svelte"
|
||||
import { FancyButton, notifications, Modal } from "@budibase/bbui"
|
||||
import IntegrationIcon from "components/backend/DatasourceNavigator/IntegrationIcon.svelte"
|
||||
import { SplitPage } from "@budibase/frontend-core"
|
||||
import { API } from "api"
|
||||
import { store, automationStore } from "builderStore"
|
||||
import { saveDatasource } from "builderStore/datasource"
|
||||
import { integrations } from "stores/backend"
|
||||
import { auth, admin } from "stores/portal"
|
||||
import FontAwesomeIcon from "components/common/FontAwesomeIcon.svelte"
|
||||
import CreateTableModal from "components/backend/TableNavigator/modals/CreateTableModal.svelte"
|
||||
import createFromScratchScreen from "builderStore/store/screenTemplates/createFromScratchScreen"
|
||||
import { Roles } from "constants/backend"
|
||||
|
||||
let name = ""
|
||||
let url = ""
|
||||
let stage = "name"
|
||||
let appId = null
|
||||
|
||||
let plusIntegrations = {}
|
||||
let integrationsLoading = true
|
||||
$: getIntegrations()
|
||||
|
||||
let uploadModal
|
||||
|
||||
const createApp = async useSampleData => {
|
||||
// Create form data to create app
|
||||
// This is form based and not JSON
|
||||
let data = new FormData()
|
||||
data.append("name", name.trim())
|
||||
data.append("url", url.trim())
|
||||
data.append("useTemplate", false)
|
||||
|
||||
if (useSampleData) {
|
||||
data.append("sampleData", true)
|
||||
}
|
||||
|
||||
const createdApp = await API.createApp(data)
|
||||
|
||||
// Select Correct Application/DB in prep for creating user
|
||||
const pkg = await API.fetchAppPackage(createdApp.instance._id)
|
||||
await store.actions.initialise(pkg)
|
||||
await automationStore.actions.fetch()
|
||||
// Update checklist - in case first app
|
||||
await admin.init()
|
||||
|
||||
// Create user
|
||||
await auth.setInitInfo({})
|
||||
|
||||
let defaultScreenTemplate = createFromScratchScreen.create()
|
||||
defaultScreenTemplate.routing.route = "/home"
|
||||
defaultScreenTemplate.routing.roldId = Roles.BASIC
|
||||
await store.actions.screens.save(defaultScreenTemplate)
|
||||
|
||||
return createdApp.instance._id
|
||||
}
|
||||
|
||||
const getIntegrations = async () => {
|
||||
try {
|
||||
await integrations.init()
|
||||
const newPlusIntegrations = {}
|
||||
|
||||
Object.entries($integrations).forEach(([integrationType, schema]) => {
|
||||
if (schema?.plus) {
|
||||
newPlusIntegrations[integrationType] = schema
|
||||
}
|
||||
})
|
||||
|
||||
plusIntegrations = newPlusIntegrations
|
||||
} catch (e) {
|
||||
notifications.error("There was a problem communicating with the server.")
|
||||
} finally {
|
||||
integrationsLoading = false
|
||||
}
|
||||
}
|
||||
|
||||
const goToApp = appId => {
|
||||
$goto(`/builder/app/${appId}`)
|
||||
notifications.success(`App created successfully`)
|
||||
}
|
||||
|
||||
const handleCreateApp = async ({ datasourceConfig, useSampleData }) => {
|
||||
try {
|
||||
appId = await createApp(useSampleData)
|
||||
|
||||
if (datasourceConfig) {
|
||||
await saveDatasource({
|
||||
plus: true,
|
||||
auth: undefined,
|
||||
name: plusIntegrations[stage].friendlyName,
|
||||
schema: plusIntegrations[stage].datasource,
|
||||
config: datasourceConfig,
|
||||
type: stage,
|
||||
})
|
||||
}
|
||||
|
||||
goToApp(appId)
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
notifications.error("There was a problem creating your app")
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<Modal bind:this={uploadModal}>
|
||||
<CreateTableModal
|
||||
name="Your Data"
|
||||
beforeSave={createApp}
|
||||
afterSave={() => goToApp(appId)}
|
||||
/>
|
||||
</Modal>
|
||||
|
||||
<SplitPage>
|
||||
{#if stage === "name"}
|
||||
<NamePanel bind:name bind:url onNext={() => (stage = "data")} />
|
||||
{:else if integrationsLoading}
|
||||
<p>loading...</p>
|
||||
{:else if stage === "data"}
|
||||
<DataPanel onBack={() => (stage = "name")}>
|
||||
<div class="dataButton">
|
||||
<FancyButton on:click={() => handleCreateApp({ useSampleData: true })}>
|
||||
<div class="dataButtonContent">
|
||||
<div class="dataButtonIcon">
|
||||
<img
|
||||
alt="Budibase Logo"
|
||||
class="budibaseLogo"
|
||||
src={"https://i.imgur.com/Xhdt1YP.png"}
|
||||
/>
|
||||
</div>
|
||||
Budibase Sample data
|
||||
</div>
|
||||
</FancyButton>
|
||||
</div>
|
||||
<div class="dataButton">
|
||||
<FancyButton on:click={uploadModal.show}>
|
||||
<div class="dataButtonContent">
|
||||
<div class="dataButtonIcon">
|
||||
<FontAwesomeIcon name="fa-solid fa-file-arrow-up" />
|
||||
</div>
|
||||
Upload file
|
||||
</div>
|
||||
</FancyButton>
|
||||
</div>
|
||||
{#each Object.entries(plusIntegrations) as [integrationType, schema]}
|
||||
<div class="dataButton">
|
||||
<FancyButton on:click={() => (stage = integrationType)}>
|
||||
<div class="dataButtonContent">
|
||||
<div class="dataButtonIcon">
|
||||
<IntegrationIcon {integrationType} {schema} />
|
||||
</div>
|
||||
{schema.friendlyName}
|
||||
</div>
|
||||
</FancyButton>
|
||||
</div>
|
||||
{/each}
|
||||
</DataPanel>
|
||||
{:else if stage in plusIntegrations}
|
||||
<DatasourceConfigPanel
|
||||
title={plusIntegrations[stage].friendlyName}
|
||||
fields={plusIntegrations[stage].datasource}
|
||||
onBack={() => (stage = "data")}
|
||||
onNext={data => handleCreateApp({ datasourceConfig: data })}
|
||||
/>
|
||||
{:else}
|
||||
<p>There was an problem. Please refresh the page and try again.</p>
|
||||
{/if}
|
||||
<div slot="right">
|
||||
<ExampleApp {name} showData={stage !== "name"} />
|
||||
</div>
|
||||
</SplitPage>
|
||||
|
||||
<style>
|
||||
.dataButton {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.dataButtonContent {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.budibaseLogo {
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
.dataButtonIcon {
|
||||
width: 22px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-right: 16px;
|
||||
}
|
||||
|
||||
.dataButtonContent :global(svg) {
|
||||
font-size: 18px;
|
||||
color: white;
|
||||
}
|
||||
</style>
|
|
@ -1,9 +1,16 @@
|
|||
import { svelte } from "@sveltejs/vite-plugin-svelte"
|
||||
import replace from "@rollup/plugin-replace"
|
||||
import { defineConfig, loadEnv } from "vite"
|
||||
|
||||
import path from "path"
|
||||
|
||||
const ignoredWarnings = [
|
||||
"unused-export-let",
|
||||
"css-unused-selector",
|
||||
"module-script-reactive-declaration",
|
||||
"a11y-no-onchange",
|
||||
"a11y-click-events-have-key-events",
|
||||
]
|
||||
|
||||
export default defineConfig(({ mode }) => {
|
||||
const isProduction = mode === "production"
|
||||
const env = loadEnv(mode, process.cwd())
|
||||
|
@ -29,6 +36,12 @@ export default defineConfig(({ mode }) => {
|
|||
svelte({
|
||||
hot: !isProduction,
|
||||
emitCss: true,
|
||||
onwarn: (warning, handler) => {
|
||||
// Ignore some warnings
|
||||
if (!ignoredWarnings.includes(warning.code)) {
|
||||
handler(warning)
|
||||
}
|
||||
},
|
||||
}),
|
||||
replace({
|
||||
preventAssignment: true,
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@budibase/cli",
|
||||
"version": "2.2.12-alpha.50",
|
||||
"version": "2.2.12-alpha.54",
|
||||
"description": "Budibase CLI, for developers, self hosting and migrations.",
|
||||
"main": "src/index.js",
|
||||
"bin": {
|
||||
|
@ -26,9 +26,9 @@
|
|||
"outputPath": "build"
|
||||
},
|
||||
"dependencies": {
|
||||
"@budibase/backend-core": "2.2.12-alpha.50",
|
||||
"@budibase/string-templates": "2.2.12-alpha.50",
|
||||
"@budibase/types": "2.2.12-alpha.50",
|
||||
"@budibase/backend-core": "2.2.12-alpha.54",
|
||||
"@budibase/string-templates": "2.2.12-alpha.54",
|
||||
"@budibase/types": "2.2.12-alpha.54",
|
||||
"axios": "0.21.2",
|
||||
"chalk": "4.1.0",
|
||||
"cli-progress": "3.11.2",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@budibase/client",
|
||||
"version": "2.2.12-alpha.50",
|
||||
"version": "2.2.12-alpha.54",
|
||||
"license": "MPL-2.0",
|
||||
"module": "dist/budibase-client.js",
|
||||
"main": "dist/budibase-client.js",
|
||||
|
@ -19,9 +19,9 @@
|
|||
"dev:builder": "rollup -cw"
|
||||
},
|
||||
"dependencies": {
|
||||
"@budibase/bbui": "2.2.12-alpha.50",
|
||||
"@budibase/frontend-core": "2.2.12-alpha.50",
|
||||
"@budibase/string-templates": "2.2.12-alpha.50",
|
||||
"@budibase/bbui": "2.2.12-alpha.54",
|
||||
"@budibase/frontend-core": "2.2.12-alpha.54",
|
||||
"@budibase/string-templates": "2.2.12-alpha.54",
|
||||
"@spectrum-css/button": "^3.0.3",
|
||||
"@spectrum-css/card": "^3.0.3",
|
||||
"@spectrum-css/divider": "^1.0.3",
|
||||
|
|
|
@ -17,6 +17,7 @@ const ignoredWarnings = [
|
|||
"css-unused-selector",
|
||||
"module-script-reactive-declaration",
|
||||
"a11y-no-onchange",
|
||||
"a11y-click-events-have-key-events",
|
||||
]
|
||||
|
||||
export default {
|
||||
|
@ -88,7 +89,9 @@ export default {
|
|||
dedupe: ["svelte", "svelte/internal"],
|
||||
}),
|
||||
svg(),
|
||||
image(),
|
||||
image({
|
||||
exclude: "**/*.svg",
|
||||
}),
|
||||
json(),
|
||||
production && terser(),
|
||||
!production && visualizer(),
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"name": "@budibase/frontend-core",
|
||||
"version": "2.2.12-alpha.50",
|
||||
"version": "2.2.12-alpha.54",
|
||||
"description": "Budibase frontend core libraries used in builder and client",
|
||||
"author": "Budibase",
|
||||
"license": "MPL-2.0",
|
||||
"svelte": "src/index.js",
|
||||
"dependencies": {
|
||||
"@budibase/bbui": "2.2.12-alpha.50",
|
||||
"@budibase/bbui": "2.2.12-alpha.54",
|
||||
"lodash": "^4.17.21",
|
||||
"svelte": "^3.46.2"
|
||||
}
|
||||
|
|
|
@ -9,7 +9,8 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="right spectrum spectrum--darkest">
|
||||
<img src={BG} alt="background" />
|
||||
<!-- No alt attribute to avoid flash -->
|
||||
<img src={BG} alt=" " />
|
||||
<slot name="right" />
|
||||
</div>
|
||||
</div>
|
||||
|
@ -30,6 +31,7 @@
|
|||
overflow-y: auto;
|
||||
}
|
||||
.right {
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
.right img {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@budibase/sdk",
|
||||
"version": "2.2.12-alpha.50",
|
||||
"version": "2.2.12-alpha.54",
|
||||
"description": "Budibase Public API SDK",
|
||||
"author": "Budibase",
|
||||
"license": "MPL-2.0",
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "@budibase/server",
|
||||
"email": "hi@budibase.com",
|
||||
"version": "2.2.12-alpha.50",
|
||||
"version": "2.2.12-alpha.54",
|
||||
"description": "Budibase Web Server",
|
||||
"main": "src/index.ts",
|
||||
"repository": {
|
||||
|
@ -43,11 +43,11 @@
|
|||
"license": "GPL-3.0",
|
||||
"dependencies": {
|
||||
"@apidevtools/swagger-parser": "10.0.3",
|
||||
"@budibase/backend-core": "2.2.12-alpha.50",
|
||||
"@budibase/client": "2.2.12-alpha.50",
|
||||
"@budibase/pro": "2.2.12-alpha.50",
|
||||
"@budibase/string-templates": "2.2.12-alpha.50",
|
||||
"@budibase/types": "2.2.12-alpha.50",
|
||||
"@budibase/backend-core": "2.2.12-alpha.54",
|
||||
"@budibase/client": "2.2.12-alpha.54",
|
||||
"@budibase/pro": "2.2.12-alpha.54",
|
||||
"@budibase/string-templates": "2.2.12-alpha.54",
|
||||
"@budibase/types": "2.2.12-alpha.54",
|
||||
"@bull-board/api": "3.7.0",
|
||||
"@bull-board/koa": "3.9.4",
|
||||
"@elastic/elasticsearch": "7.10.0",
|
||||
|
|
|
@ -1273,13 +1273,13 @@
|
|||
resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39"
|
||||
integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==
|
||||
|
||||
"@budibase/backend-core@2.2.12-alpha.50":
|
||||
version "2.2.12-alpha.50"
|
||||
resolved "https://registry.yarnpkg.com/@budibase/backend-core/-/backend-core-2.2.12-alpha.50.tgz#39f228904cf39de2dbb51900df4494267ac72381"
|
||||
integrity sha512-ysVJ6Eul7o+LZRoilFr7bk1/gkoxSqM30yBbRhKxIhH2IOk0qd9LAaNQiTnwn4ZzU+tJWSkyAsJAQdTnX8/i9g==
|
||||
"@budibase/backend-core@2.2.12-alpha.54":
|
||||
version "2.2.12-alpha.54"
|
||||
resolved "https://registry.yarnpkg.com/@budibase/backend-core/-/backend-core-2.2.12-alpha.54.tgz#c03c63c3d58cf401928104bf52cfd288f93f0fb8"
|
||||
integrity sha512-BfO9UlbnbRzSPXpjqAOx2qNU0atsQejCJTyB2n8nkdJqTgy6XGobQBn7iNiEWBO/zmIbqS4sz0/8NkDj7MxXDg==
|
||||
dependencies:
|
||||
"@budibase/nano" "10.1.1"
|
||||
"@budibase/types" "2.2.12-alpha.50"
|
||||
"@budibase/types" "2.2.12-alpha.54"
|
||||
"@shopify/jest-koa-mocks" "5.0.1"
|
||||
"@techpass/passport-openidconnect" "0.3.2"
|
||||
aws-cloudfront-sign "2.2.0"
|
||||
|
@ -1374,13 +1374,13 @@
|
|||
qs "^6.11.0"
|
||||
tough-cookie "^4.1.2"
|
||||
|
||||
"@budibase/pro@2.2.12-alpha.50":
|
||||
version "2.2.12-alpha.50"
|
||||
resolved "https://registry.yarnpkg.com/@budibase/pro/-/pro-2.2.12-alpha.50.tgz#599edc75363b323f613a0d56e5173150582b13bb"
|
||||
integrity sha512-eeKY9P4Zi81AlU6vYWVcffMwkyUrNv6PcNjdKZZNBuIgNfOVejy9vmpIukx43LpHUOsk6FKxHFNVDN1txnYRkg==
|
||||
"@budibase/pro@2.2.12-alpha.54":
|
||||
version "2.2.12-alpha.54"
|
||||
resolved "https://registry.yarnpkg.com/@budibase/pro/-/pro-2.2.12-alpha.54.tgz#e8c259ff88326f34eaca7ef2f5a15461a104f976"
|
||||
integrity sha512-gBIbbcR1fNNhs0D6+XrWP+nn9lJAHqjP8yQh3pPQ7srVSarohvdE3UgLEguMGtmGckJkna4UgzQd8ftOzd16sQ==
|
||||
dependencies:
|
||||
"@budibase/backend-core" "2.2.12-alpha.50"
|
||||
"@budibase/types" "2.2.12-alpha.50"
|
||||
"@budibase/backend-core" "2.2.12-alpha.54"
|
||||
"@budibase/types" "2.2.12-alpha.54"
|
||||
"@koa/router" "8.0.8"
|
||||
bull "4.10.1"
|
||||
joi "17.6.0"
|
||||
|
@ -1406,10 +1406,10 @@
|
|||
svelte-apexcharts "^1.0.2"
|
||||
svelte-flatpickr "^3.1.0"
|
||||
|
||||
"@budibase/types@2.2.12-alpha.50":
|
||||
version "2.2.12-alpha.50"
|
||||
resolved "https://registry.yarnpkg.com/@budibase/types/-/types-2.2.12-alpha.50.tgz#ef07d4593c1ea0da6a6b75004d1319d7621cd910"
|
||||
integrity sha512-LU+G7gQffBvnLvWfzpxUNcrCZFP/ZNQqAjB2KJxgq9pfeynU3MWAwut1tjKpp8eduuu7GnfBT1uvet9jM87FKA==
|
||||
"@budibase/types@2.2.12-alpha.54":
|
||||
version "2.2.12-alpha.54"
|
||||
resolved "https://registry.yarnpkg.com/@budibase/types/-/types-2.2.12-alpha.54.tgz#3d7676a92c42cbe131bc98ddc84a1d7ce9518efd"
|
||||
integrity sha512-t9GuvH8BIfHt4YoXM6Ztk9wmGipk9SwEdwCjcJfF2qhusgR4mJjl8LWQgzzKoCAryDgEmME3ajkaE6iw7g130A==
|
||||
|
||||
"@bull-board/api@3.7.0":
|
||||
version "3.7.0"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@budibase/string-templates",
|
||||
"version": "2.2.12-alpha.50",
|
||||
"version": "2.2.12-alpha.54",
|
||||
"description": "Handlebars wrapper for Budibase templating.",
|
||||
"main": "src/index.cjs",
|
||||
"module": "dist/bundle.mjs",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@budibase/types",
|
||||
"version": "2.2.12-alpha.50",
|
||||
"version": "2.2.12-alpha.54",
|
||||
"description": "Budibase types",
|
||||
"main": "dist/index.js",
|
||||
"types": "dist/index.d.ts",
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "@budibase/worker",
|
||||
"email": "hi@budibase.com",
|
||||
"version": "2.2.12-alpha.50",
|
||||
"version": "2.2.12-alpha.54",
|
||||
"description": "Budibase background service",
|
||||
"main": "src/index.ts",
|
||||
"repository": {
|
||||
|
@ -36,10 +36,10 @@
|
|||
"author": "Budibase",
|
||||
"license": "GPL-3.0",
|
||||
"dependencies": {
|
||||
"@budibase/backend-core": "2.2.12-alpha.50",
|
||||
"@budibase/pro": "2.2.12-alpha.50",
|
||||
"@budibase/string-templates": "2.2.12-alpha.50",
|
||||
"@budibase/types": "2.2.12-alpha.50",
|
||||
"@budibase/backend-core": "2.2.12-alpha.54",
|
||||
"@budibase/pro": "2.2.12-alpha.54",
|
||||
"@budibase/string-templates": "2.2.12-alpha.54",
|
||||
"@budibase/types": "2.2.12-alpha.54",
|
||||
"@koa/router": "8.0.8",
|
||||
"@sentry/node": "6.17.7",
|
||||
"@techpass/passport-openidconnect": "0.3.2",
|
||||
|
|
|
@ -470,13 +470,13 @@
|
|||
resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39"
|
||||
integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==
|
||||
|
||||
"@budibase/backend-core@2.2.12-alpha.50":
|
||||
version "2.2.12-alpha.50"
|
||||
resolved "https://registry.yarnpkg.com/@budibase/backend-core/-/backend-core-2.2.12-alpha.50.tgz#39f228904cf39de2dbb51900df4494267ac72381"
|
||||
integrity sha512-ysVJ6Eul7o+LZRoilFr7bk1/gkoxSqM30yBbRhKxIhH2IOk0qd9LAaNQiTnwn4ZzU+tJWSkyAsJAQdTnX8/i9g==
|
||||
"@budibase/backend-core@2.2.12-alpha.54":
|
||||
version "2.2.12-alpha.54"
|
||||
resolved "https://registry.yarnpkg.com/@budibase/backend-core/-/backend-core-2.2.12-alpha.54.tgz#c03c63c3d58cf401928104bf52cfd288f93f0fb8"
|
||||
integrity sha512-BfO9UlbnbRzSPXpjqAOx2qNU0atsQejCJTyB2n8nkdJqTgy6XGobQBn7iNiEWBO/zmIbqS4sz0/8NkDj7MxXDg==
|
||||
dependencies:
|
||||
"@budibase/nano" "10.1.1"
|
||||
"@budibase/types" "2.2.12-alpha.50"
|
||||
"@budibase/types" "2.2.12-alpha.54"
|
||||
"@shopify/jest-koa-mocks" "5.0.1"
|
||||
"@techpass/passport-openidconnect" "0.3.2"
|
||||
aws-cloudfront-sign "2.2.0"
|
||||
|
@ -521,13 +521,13 @@
|
|||
qs "^6.11.0"
|
||||
tough-cookie "^4.1.2"
|
||||
|
||||
"@budibase/pro@2.2.12-alpha.50":
|
||||
version "2.2.12-alpha.50"
|
||||
resolved "https://registry.yarnpkg.com/@budibase/pro/-/pro-2.2.12-alpha.50.tgz#599edc75363b323f613a0d56e5173150582b13bb"
|
||||
integrity sha512-eeKY9P4Zi81AlU6vYWVcffMwkyUrNv6PcNjdKZZNBuIgNfOVejy9vmpIukx43LpHUOsk6FKxHFNVDN1txnYRkg==
|
||||
"@budibase/pro@2.2.12-alpha.54":
|
||||
version "2.2.12-alpha.54"
|
||||
resolved "https://registry.yarnpkg.com/@budibase/pro/-/pro-2.2.12-alpha.54.tgz#e8c259ff88326f34eaca7ef2f5a15461a104f976"
|
||||
integrity sha512-gBIbbcR1fNNhs0D6+XrWP+nn9lJAHqjP8yQh3pPQ7srVSarohvdE3UgLEguMGtmGckJkna4UgzQd8ftOzd16sQ==
|
||||
dependencies:
|
||||
"@budibase/backend-core" "2.2.12-alpha.50"
|
||||
"@budibase/types" "2.2.12-alpha.50"
|
||||
"@budibase/backend-core" "2.2.12-alpha.54"
|
||||
"@budibase/types" "2.2.12-alpha.54"
|
||||
"@koa/router" "8.0.8"
|
||||
bull "4.10.1"
|
||||
joi "17.6.0"
|
||||
|
@ -535,10 +535,10 @@
|
|||
lru-cache "^7.14.1"
|
||||
node-fetch "^2.6.1"
|
||||
|
||||
"@budibase/types@2.2.12-alpha.50":
|
||||
version "2.2.12-alpha.50"
|
||||
resolved "https://registry.yarnpkg.com/@budibase/types/-/types-2.2.12-alpha.50.tgz#ef07d4593c1ea0da6a6b75004d1319d7621cd910"
|
||||
integrity sha512-LU+G7gQffBvnLvWfzpxUNcrCZFP/ZNQqAjB2KJxgq9pfeynU3MWAwut1tjKpp8eduuu7GnfBT1uvet9jM87FKA==
|
||||
"@budibase/types@2.2.12-alpha.54":
|
||||
version "2.2.12-alpha.54"
|
||||
resolved "https://registry.yarnpkg.com/@budibase/types/-/types-2.2.12-alpha.54.tgz#3d7676a92c42cbe131bc98ddc84a1d7ce9518efd"
|
||||
integrity sha512-t9GuvH8BIfHt4YoXM6Ztk9wmGipk9SwEdwCjcJfF2qhusgR4mJjl8LWQgzzKoCAryDgEmME3ajkaE6iw7g130A==
|
||||
|
||||
"@cspotcode/source-map-support@^0.8.0":
|
||||
version "0.8.1"
|
||||
|
|
Loading…
Reference in New Issue