Merge branch 'develop' of github.com:Budibase/budibase into feature/BUDI-7458
This commit is contained in:
commit
1808665bb3
|
@ -55,7 +55,7 @@ http {
|
||||||
set $csp_style "style-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net https://fonts.googleapis.com https://rsms.me https://maxcdn.bootstrapcdn.com";
|
set $csp_style "style-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net https://fonts.googleapis.com https://rsms.me https://maxcdn.bootstrapcdn.com";
|
||||||
set $csp_object "object-src 'none'";
|
set $csp_object "object-src 'none'";
|
||||||
set $csp_base_uri "base-uri 'self'";
|
set $csp_base_uri "base-uri 'self'";
|
||||||
set $csp_connect "connect-src 'self' https://*.budibase.net https://api-iam.intercom.io https://api-iam.intercom.io https://api-ping.intercom.io https://app.posthog.com wss://nexus-websocket-a.intercom.io wss://nexus-websocket-b.intercom.io https://nexus-websocket-a.intercom.io https://nexus-websocket-b.intercom.io https://uploads.intercomcdn.com https://uploads.intercomusercontent.com https://*.amazonaws.com https://*.s3.amazonaws.com https://*.s3.us-east-2.amazonaws.com https://*.s3.us-east-1.amazonaws.com https://*.s3.us-west-1.amazonaws.com https://*.s3.us-west-2.amazonaws.com https://*.s3.af-south-1.amazonaws.com https://*.s3.ap-east-1.amazonaws.com https://*.s3.ap-southeast-3.amazonaws.com https://*.s3.ap-south-1.amazonaws.com https://*.s3.ap-northeast-3.amazonaws.com https://*.s3.ap-northeast-2.amazonaws.com https://*.s3.ap-southeast-1.amazonaws.com https://*.s3.ap-southeast-2.amazonaws.com https://*.s3.ap-northeast-1.amazonaws.com https://*.s3.ca-central-1.amazonaws.com https://*.s3.cn-north-1.amazonaws.com https://*.s3.cn-northwest-1.amazonaws.com https://*.s3.eu-central-1.amazonaws.com https://*.s3.eu-west-1.amazonaws.com https://*.s3.eu-west-2.amazonaws.com https://*.s3.eu-south-1.amazonaws.com https://*.s3.eu-west-3.amazonaws.com https://*.s3.eu-north-1.amazonaws.com https://*.s3.sa-east-1.amazonaws.com https://*.s3.me-south-1.amazonaws.com https://*.s3.us-gov-east-1.amazonaws.com https://*.s3.us-gov-west-1.amazonaws.com https://api.github.com";
|
set $csp_connect "connect-src 'self' https://*.budibase.app https://*.budibase.qa https://*.budibase.net https://api-iam.intercom.io https://api-iam.intercom.io https://api-ping.intercom.io https://app.posthog.com wss://nexus-websocket-a.intercom.io wss://nexus-websocket-b.intercom.io https://nexus-websocket-a.intercom.io https://nexus-websocket-b.intercom.io https://uploads.intercomcdn.com https://uploads.intercomusercontent.com https://*.amazonaws.com https://*.s3.amazonaws.com https://*.s3.us-east-2.amazonaws.com https://*.s3.us-east-1.amazonaws.com https://*.s3.us-west-1.amazonaws.com https://*.s3.us-west-2.amazonaws.com https://*.s3.af-south-1.amazonaws.com https://*.s3.ap-east-1.amazonaws.com https://*.s3.ap-southeast-3.amazonaws.com https://*.s3.ap-south-1.amazonaws.com https://*.s3.ap-northeast-3.amazonaws.com https://*.s3.ap-northeast-2.amazonaws.com https://*.s3.ap-southeast-1.amazonaws.com https://*.s3.ap-southeast-2.amazonaws.com https://*.s3.ap-northeast-1.amazonaws.com https://*.s3.ca-central-1.amazonaws.com https://*.s3.cn-north-1.amazonaws.com https://*.s3.cn-northwest-1.amazonaws.com https://*.s3.eu-central-1.amazonaws.com https://*.s3.eu-west-1.amazonaws.com https://*.s3.eu-west-2.amazonaws.com https://*.s3.eu-south-1.amazonaws.com https://*.s3.eu-west-3.amazonaws.com https://*.s3.eu-north-1.amazonaws.com https://*.s3.sa-east-1.amazonaws.com https://*.s3.me-south-1.amazonaws.com https://*.s3.us-gov-east-1.amazonaws.com https://*.s3.us-gov-west-1.amazonaws.com https://api.github.com";
|
||||||
set $csp_font "font-src 'self' data: https://cdn.jsdelivr.net https://fonts.gstatic.com https://rsms.me https://maxcdn.bootstrapcdn.com https://js.intercomcdn.com https://fonts.intercomcdn.com";
|
set $csp_font "font-src 'self' data: https://cdn.jsdelivr.net https://fonts.gstatic.com https://rsms.me https://maxcdn.bootstrapcdn.com https://js.intercomcdn.com https://fonts.intercomcdn.com";
|
||||||
set $csp_frame "frame-src 'self' https:";
|
set $csp_frame "frame-src 'self' https:";
|
||||||
set $csp_img "img-src http: https: data: blob:";
|
set $csp_img "img-src http: https: data: blob:";
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"version": "2.10.12-alpha.1",
|
"version": "2.10.12-alpha.3",
|
||||||
"npmClient": "yarn",
|
"npmClient": "yarn",
|
||||||
"packages": [
|
"packages": [
|
||||||
"packages/*"
|
"packages/*"
|
||||||
|
|
|
@ -0,0 +1,102 @@
|
||||||
|
<script>
|
||||||
|
import { notifications, Button, Icon, Body } from "@budibase/bbui"
|
||||||
|
import { admin, auth } from "stores/portal"
|
||||||
|
|
||||||
|
$: user = $auth.user
|
||||||
|
let loading = false
|
||||||
|
let complete = false
|
||||||
|
|
||||||
|
const resetPassword = async () => {
|
||||||
|
if (loading || complete) return
|
||||||
|
loading = true
|
||||||
|
|
||||||
|
try {
|
||||||
|
await fetch(`${$admin.accountPortalUrl}/api/auth/reset`, {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
body: JSON.stringify({ email: user.email }),
|
||||||
|
})
|
||||||
|
|
||||||
|
complete = true
|
||||||
|
} catch (e) {
|
||||||
|
notifications.error("There was an issue sending your validation email.")
|
||||||
|
} finally {
|
||||||
|
loading = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#if user?.account?.verified === false}
|
||||||
|
<section class="banner">
|
||||||
|
<div class="icon">
|
||||||
|
<Icon name="Info" />
|
||||||
|
</div>
|
||||||
|
<div class="copy">
|
||||||
|
<Body size="S">
|
||||||
|
Please verify your account. We've sent the verification link to <span
|
||||||
|
class="email">{user.email}</span
|
||||||
|
></Body
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<div class="button" class:disabled={loading || complete}>
|
||||||
|
<Button on:click={resetPassword}
|
||||||
|
>{complete ? "Email sent" : "Resend email"}</Button
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.banner {
|
||||||
|
flex-shrink: 0;
|
||||||
|
display: flex;
|
||||||
|
background-color: var(--grey-2);
|
||||||
|
height: 48px;
|
||||||
|
align-items: center;
|
||||||
|
padding: 0 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
margin-right: 15px;
|
||||||
|
color: var(--ink);
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.copy {
|
||||||
|
flex-grow: 1;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.copy :global(p) {
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
.email {
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button {
|
||||||
|
margin-left: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button :global(button) {
|
||||||
|
color: var(--ink);
|
||||||
|
background-color: var(--grey-3);
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button :global(button):hover {
|
||||||
|
background-color: var(--grey-4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.disabled :global(button) {
|
||||||
|
pointer-events: none;
|
||||||
|
color: var(--ink);
|
||||||
|
background-color: var(--grey-4);
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -3,7 +3,6 @@
|
||||||
import { createEventDispatcher } from "svelte"
|
import { createEventDispatcher } from "svelte"
|
||||||
import { notifications } from "@budibase/bbui"
|
import { notifications } from "@budibase/bbui"
|
||||||
import ButtonActionDrawer from "./ButtonActionDrawer.svelte"
|
import ButtonActionDrawer from "./ButtonActionDrawer.svelte"
|
||||||
import { automationStore } from "builderStore"
|
|
||||||
import { cloneDeep } from "lodash/fp"
|
import { cloneDeep } from "lodash/fp"
|
||||||
|
|
||||||
const dispatch = createEventDispatcher()
|
const dispatch = createEventDispatcher()
|
||||||
|
@ -24,47 +23,11 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
const saveEventData = async () => {
|
const saveEventData = async () => {
|
||||||
// any automations that need created from event triggers
|
|
||||||
const automationsToCreate = tmpValue.filter(
|
|
||||||
action => action["##eventHandlerType"] === "Trigger Automation"
|
|
||||||
)
|
|
||||||
for (let action of automationsToCreate) {
|
|
||||||
await createAutomation(action.parameters)
|
|
||||||
}
|
|
||||||
|
|
||||||
dispatch("change", tmpValue)
|
dispatch("change", tmpValue)
|
||||||
notifications.success("Component actions saved.")
|
notifications.success("Component actions saved.")
|
||||||
drawer.hide()
|
drawer.hide()
|
||||||
}
|
}
|
||||||
|
|
||||||
// called by the parent modal when actions are saved
|
|
||||||
const createAutomation = async parameters => {
|
|
||||||
if (parameters.automationId || !parameters.newAutomationName) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
let trigger = automationStore.actions.constructBlock(
|
|
||||||
"TRIGGER",
|
|
||||||
"APP",
|
|
||||||
$automationStore.blockDefinitions.TRIGGER.APP
|
|
||||||
)
|
|
||||||
trigger.inputs = {
|
|
||||||
fields: Object.keys(parameters.fields ?? {}).reduce((fields, key) => {
|
|
||||||
fields[key] = "string"
|
|
||||||
return fields
|
|
||||||
}, {}),
|
|
||||||
}
|
|
||||||
const automation = await automationStore.actions.create(
|
|
||||||
parameters.newAutomationName,
|
|
||||||
trigger
|
|
||||||
)
|
|
||||||
parameters.automationId = automation._id
|
|
||||||
delete parameters.newAutomationName
|
|
||||||
} catch (error) {
|
|
||||||
notifications.error("Error creating automation")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$: actionCount = value?.length
|
$: actionCount = value?.length
|
||||||
$: actionText = `${actionCount || "No"} action${
|
$: actionText = `${actionCount || "No"} action${
|
||||||
actionCount !== 1 ? "s" : ""
|
actionCount !== 1 ? "s" : ""
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
<script>
|
<script>
|
||||||
import { currentAsset, store } from "builderStore"
|
import { currentAsset, store } from "builderStore"
|
||||||
import { onMount } from "svelte"
|
|
||||||
import { Label, Combobox, Select } from "@budibase/bbui"
|
import { Label, Combobox, Select } from "@budibase/bbui"
|
||||||
import {
|
import {
|
||||||
getActionProviderComponents,
|
getActionProviderComponents,
|
||||||
|
@ -10,12 +9,6 @@
|
||||||
|
|
||||||
export let parameters
|
export let parameters
|
||||||
|
|
||||||
onMount(() => {
|
|
||||||
if (!parameters.type) {
|
|
||||||
parameters.type = "top"
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
$: formComponent = findComponent($currentAsset.props, parameters.componentId)
|
$: formComponent = findComponent($currentAsset.props, parameters.componentId)
|
||||||
$: formSchema = buildFormSchema(formComponent)
|
$: formSchema = buildFormSchema(formComponent)
|
||||||
$: fieldOptions = Object.keys(formSchema || {})
|
$: fieldOptions = Object.keys(formSchema || {})
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
import { admin, auth, licensing } from "stores/portal"
|
import { admin, auth, licensing } from "stores/portal"
|
||||||
import { onMount } from "svelte"
|
import { onMount } from "svelte"
|
||||||
import { CookieUtils, Constants } from "@budibase/frontend-core"
|
import { CookieUtils, Constants } from "@budibase/frontend-core"
|
||||||
import { banner, BANNER_TYPES } from "@budibase/bbui"
|
|
||||||
import { API } from "api"
|
import { API } from "api"
|
||||||
import Branding from "./Branding.svelte"
|
import Branding from "./Branding.svelte"
|
||||||
|
|
||||||
|
@ -17,32 +16,6 @@
|
||||||
$: user = $auth.user
|
$: user = $auth.user
|
||||||
|
|
||||||
$: useAccountPortal = cloud && !$admin.disableAccountPortal
|
$: useAccountPortal = cloud && !$admin.disableAccountPortal
|
||||||
let showVerificationPrompt = false
|
|
||||||
|
|
||||||
const checkVerification = user => {
|
|
||||||
if (!showVerificationPrompt && user?.account?.verified === false) {
|
|
||||||
showVerificationPrompt = true
|
|
||||||
banner.queue([
|
|
||||||
{
|
|
||||||
message: `Please verify your account. We've sent the verification link to ${user.email}`,
|
|
||||||
type: BANNER_TYPES.NEUTRAL,
|
|
||||||
showCloseButton: false,
|
|
||||||
extraButtonAction: () => {
|
|
||||||
fetch(`${$admin.accountPortalUrl}/api/auth/reset`, {
|
|
||||||
method: "POST",
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
},
|
|
||||||
body: JSON.stringify({ email: user.email }),
|
|
||||||
})
|
|
||||||
},
|
|
||||||
extraButtonText: "Resend email",
|
|
||||||
},
|
|
||||||
])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$: checkVerification(user)
|
|
||||||
|
|
||||||
const validateTenantId = async () => {
|
const validateTenantId = async () => {
|
||||||
const host = window.location.host
|
const host = window.location.host
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
import { isActive, goto, layout, redirect } from "@roxi/routify"
|
import { isActive, goto, layout, redirect } from "@roxi/routify"
|
||||||
import { capitalise } from "helpers"
|
import { capitalise } from "helpers"
|
||||||
import { onMount, onDestroy } from "svelte"
|
import { onMount, onDestroy } from "svelte"
|
||||||
|
import VerificationPromptBanner from "components/common/VerificationPromptBanner.svelte"
|
||||||
import CommandPalette from "components/commandPalette/CommandPalette.svelte"
|
import CommandPalette from "components/commandPalette/CommandPalette.svelte"
|
||||||
import TourWrap from "components/portal/onboarding/TourWrap.svelte"
|
import TourWrap from "components/portal/onboarding/TourWrap.svelte"
|
||||||
import TourPopover from "components/portal/onboarding/TourPopover.svelte"
|
import TourPopover from "components/portal/onboarding/TourPopover.svelte"
|
||||||
|
@ -136,6 +137,7 @@
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<div class="root" class:blur={$store.showPreview}>
|
<div class="root" class:blur={$store.showPreview}>
|
||||||
|
<VerificationPromptBanner />
|
||||||
<div class="top-nav">
|
<div class="top-nav">
|
||||||
{#if $store.initialised}
|
{#if $store.initialised}
|
||||||
<div class="topleftnav">
|
<div class="topleftnav">
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
import Logo from "./_components/Logo.svelte"
|
import Logo from "./_components/Logo.svelte"
|
||||||
import UserDropdown from "./_components/UserDropdown.svelte"
|
import UserDropdown from "./_components/UserDropdown.svelte"
|
||||||
import HelpMenu from "components/common/HelpMenu.svelte"
|
import HelpMenu from "components/common/HelpMenu.svelte"
|
||||||
|
import VerificationPromptBanner from "components/common/VerificationPromptBanner.svelte"
|
||||||
import { sdk } from "@budibase/shared-core"
|
import { sdk } from "@budibase/shared-core"
|
||||||
|
|
||||||
let loaded = false
|
let loaded = false
|
||||||
|
@ -55,6 +56,7 @@
|
||||||
{:else}
|
{:else}
|
||||||
<HelpMenu />
|
<HelpMenu />
|
||||||
<div class="container">
|
<div class="container">
|
||||||
|
<VerificationPromptBanner />
|
||||||
<div class="nav">
|
<div class="nav">
|
||||||
<div class="branding">
|
<div class="branding">
|
||||||
<Logo />
|
<Logo />
|
||||||
|
|
|
@ -230,10 +230,16 @@
|
||||||
// We want to validate every field (even if validation fails early) to
|
// We want to validate every field (even if validation fails early) to
|
||||||
// ensure that all fields are populated with errors if invalid
|
// ensure that all fields are populated with errors if invalid
|
||||||
let valid = true
|
let valid = true
|
||||||
|
let hasScrolled = false
|
||||||
stepFields.forEach(field => {
|
stepFields.forEach(field => {
|
||||||
const fieldValid = get(field).fieldApi.validate()
|
const fieldValid = get(field).fieldApi.validate()
|
||||||
valid = valid && fieldValid
|
valid = valid && fieldValid
|
||||||
|
if (!valid && !hasScrolled) {
|
||||||
|
handleScrollToField({ field: get(field) })
|
||||||
|
hasScrolled = true
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
return valid
|
return valid
|
||||||
},
|
},
|
||||||
reset: () => {
|
reset: () => {
|
||||||
|
@ -409,10 +415,15 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleScrollToField = ({ field }) => {
|
const handleScrollToField = ({ field }) => {
|
||||||
const fieldId = get(getField(field)).fieldState.fieldId
|
if (!field.fieldState) {
|
||||||
|
field = get(getField(field))
|
||||||
|
}
|
||||||
|
const fieldId = field.fieldState.fieldId
|
||||||
|
const fieldElement = document.getElementById(fieldId)
|
||||||
|
fieldElement.focus({ preventScroll: true })
|
||||||
const label = document.querySelector(`label[for="${fieldId}"]`)
|
const label = document.querySelector(`label[for="${fieldId}"]`)
|
||||||
document.getElementById(fieldId).focus({ preventScroll: true })
|
label.style.scrollMargin = "100px"
|
||||||
label.scrollIntoView({ behavior: "smooth" })
|
label.scrollIntoView({ behavior: "smooth", block: "nearest" })
|
||||||
}
|
}
|
||||||
|
|
||||||
// Action context to pass to children
|
// Action context to pass to children
|
||||||
|
|
Loading…
Reference in New Issue