Merge branch 'master' into feat/pick-relationship-fields
This commit is contained in:
commit
fc3684c73c
|
@ -22,6 +22,7 @@ jobs:
|
||||||
env:
|
env:
|
||||||
PAYLOAD_BRANCH: ${{ github.head_ref }}
|
PAYLOAD_BRANCH: ${{ github.head_ref }}
|
||||||
PAYLOAD_PR_NUMBER: ${{ github.event.pull_request.number }}
|
PAYLOAD_PR_NUMBER: ${{ github.event.pull_request.number }}
|
||||||
|
PAYLOAD_LICENSE_TYPE: "free"
|
||||||
with:
|
with:
|
||||||
repository: budibase/budibase-deploys
|
repository: budibase/budibase-deploys
|
||||||
event: featurebranch-qa-deploy
|
event: featurebranch-qa-deploy
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"$schema": "node_modules/lerna/schemas/lerna-schema.json",
|
"$schema": "node_modules/lerna/schemas/lerna-schema.json",
|
||||||
"version": "2.31.3",
|
"version": "2.31.4",
|
||||||
"npmClient": "yarn",
|
"npmClient": "yarn",
|
||||||
"packages": [
|
"packages": [
|
||||||
"packages/*",
|
"packages/*",
|
||||||
|
|
|
@ -266,7 +266,7 @@ export class FlagSet<V extends Flag<any>, T extends { [key: string]: V }> {
|
||||||
// All of the machinery in this file is to make sure that flags have their
|
// All of the machinery in this file is to make sure that flags have their
|
||||||
// default values set correctly and their types flow through the system.
|
// default values set correctly and their types flow through the system.
|
||||||
export const flags = new FlagSet({
|
export const flags = new FlagSet({
|
||||||
DEFAULT_VALUES: Flag.boolean(false),
|
DEFAULT_VALUES: Flag.boolean(env.isDev()),
|
||||||
SQS: Flag.boolean(env.isDev()),
|
SQS: Flag.boolean(env.isDev()),
|
||||||
[FeatureFlag.ENRICHED_RELATIONSHIPS]: Flag.boolean(false),
|
[FeatureFlag.ENRICHED_RELATIONSHIPS]: Flag.boolean(false),
|
||||||
})
|
})
|
||||||
|
|
|
@ -57,6 +57,7 @@ export const getBindableProperties = (asset, componentId) => {
|
||||||
const stateBindings = getStateBindings()
|
const stateBindings = getStateBindings()
|
||||||
const selectedRowsBindings = getSelectedRowsBindings(asset)
|
const selectedRowsBindings = getSelectedRowsBindings(asset)
|
||||||
const roleBindings = getRoleBindings()
|
const roleBindings = getRoleBindings()
|
||||||
|
const embedBindings = getEmbedBindings()
|
||||||
return [
|
return [
|
||||||
...contextBindings,
|
...contextBindings,
|
||||||
...urlBindings,
|
...urlBindings,
|
||||||
|
@ -65,6 +66,7 @@ export const getBindableProperties = (asset, componentId) => {
|
||||||
...deviceBindings,
|
...deviceBindings,
|
||||||
...selectedRowsBindings,
|
...selectedRowsBindings,
|
||||||
...roleBindings,
|
...roleBindings,
|
||||||
|
...embedBindings,
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -813,6 +815,25 @@ export const getActionBindings = (actions, actionId) => {
|
||||||
return bindings
|
return bindings
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets all device bindings for embeds.
|
||||||
|
*/
|
||||||
|
const getEmbedBindings = () => {
|
||||||
|
let bindings = []
|
||||||
|
const safeEmbed = makePropSafe("embed")
|
||||||
|
|
||||||
|
bindings = [
|
||||||
|
{
|
||||||
|
type: "context",
|
||||||
|
runtimeBinding: `${safeEmbed}`,
|
||||||
|
readableBinding: `ParentWindow`,
|
||||||
|
category: "Embed",
|
||||||
|
icon: "DistributeVertically",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
return bindings
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the schema for a certain datasource plus.
|
* Gets the schema for a certain datasource plus.
|
||||||
* The options which can be passed in are:
|
* The options which can be passed in are:
|
||||||
|
|
|
@ -7,10 +7,22 @@ import {
|
||||||
FIELDS,
|
FIELDS,
|
||||||
isAutoColumnUserRelationship,
|
isAutoColumnUserRelationship,
|
||||||
} from "constants/backend"
|
} from "constants/backend"
|
||||||
|
import { isEnabled } from "helpers/featureFlags"
|
||||||
|
|
||||||
export function getAutoColumnInformation(enabled = true) {
|
export function getAutoColumnInformation(enabled = true) {
|
||||||
let info = {}
|
let info = {}
|
||||||
for (let [key, subtype] of Object.entries(AUTO_COLUMN_SUB_TYPES)) {
|
for (const [key, subtype] of Object.entries(AUTO_COLUMN_SUB_TYPES)) {
|
||||||
|
// Because it's possible to replicate the functionality of CREATED_AT and
|
||||||
|
// CREATED_BY columns, we disable their creation when the DEFAULT_VALUES
|
||||||
|
// feature flag is enabled.
|
||||||
|
if (isEnabled("DEFAULT_VALUES")) {
|
||||||
|
if (
|
||||||
|
subtype === AUTO_COLUMN_SUB_TYPES.CREATED_AT ||
|
||||||
|
subtype === AUTO_COLUMN_SUB_TYPES.CREATED_BY
|
||||||
|
) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
info[subtype] = { enabled, name: AUTO_COLUMN_DISPLAY_NAMES[key] }
|
info[subtype] = { enabled, name: AUTO_COLUMN_DISPLAY_NAMES[key] }
|
||||||
}
|
}
|
||||||
return info
|
return info
|
||||||
|
|
|
@ -49,7 +49,7 @@
|
||||||
right: 0;
|
right: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
z-index: 999;
|
z-index: 9000;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
background: rgba(255, 255, 255, 0.1);
|
background: rgba(255, 255, 255, 0.1);
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
|
@ -42,6 +42,7 @@
|
||||||
import FreeFooter from "components/FreeFooter.svelte"
|
import FreeFooter from "components/FreeFooter.svelte"
|
||||||
import MaintenanceScreen from "components/MaintenanceScreen.svelte"
|
import MaintenanceScreen from "components/MaintenanceScreen.svelte"
|
||||||
import SnippetsProvider from "./context/SnippetsProvider.svelte"
|
import SnippetsProvider from "./context/SnippetsProvider.svelte"
|
||||||
|
import EmbedProvider from "./context/EmbedProvider.svelte"
|
||||||
|
|
||||||
// Provide contexts
|
// Provide contexts
|
||||||
setContext("sdk", SDK)
|
setContext("sdk", SDK)
|
||||||
|
@ -160,116 +161,119 @@
|
||||||
{#if $environmentStore.maintenance.length > 0}
|
{#if $environmentStore.maintenance.length > 0}
|
||||||
<MaintenanceScreen maintenanceList={$environmentStore.maintenance} />
|
<MaintenanceScreen maintenanceList={$environmentStore.maintenance} />
|
||||||
{:else}
|
{:else}
|
||||||
<DeviceBindingsProvider>
|
<EmbedProvider>
|
||||||
<UserBindingsProvider>
|
<DeviceBindingsProvider>
|
||||||
<StateBindingsProvider>
|
<UserBindingsProvider>
|
||||||
<RowSelectionProvider>
|
<StateBindingsProvider>
|
||||||
<QueryParamsProvider>
|
<RowSelectionProvider>
|
||||||
<SnippetsProvider>
|
<QueryParamsProvider>
|
||||||
<!-- Settings bar can be rendered outside of device preview -->
|
<SnippetsProvider>
|
||||||
<!-- Key block needs to be outside the if statement or it breaks -->
|
<!-- Settings bar can be rendered outside of device preview -->
|
||||||
{#key $builderStore.selectedComponentId}
|
<!-- Key block needs to be outside the if statement or it breaks -->
|
||||||
{#if $builderStore.inBuilder}
|
{#key $builderStore.selectedComponentId}
|
||||||
<SettingsBar />
|
{#if $builderStore.inBuilder}
|
||||||
{/if}
|
<SettingsBar />
|
||||||
{/key}
|
|
||||||
|
|
||||||
<!-- Clip boundary for selection indicators -->
|
|
||||||
<div
|
|
||||||
id="clip-root"
|
|
||||||
class:preview={$builderStore.inBuilder}
|
|
||||||
class:tablet-preview={$builderStore.previewDevice ===
|
|
||||||
"tablet"}
|
|
||||||
class:mobile-preview={$builderStore.previewDevice ===
|
|
||||||
"mobile"}
|
|
||||||
>
|
|
||||||
<!-- Actual app -->
|
|
||||||
<div id="app-root">
|
|
||||||
{#if showDevTools}
|
|
||||||
<DevToolsHeader />
|
|
||||||
{/if}
|
{/if}
|
||||||
|
{/key}
|
||||||
|
|
||||||
<div id="app-body">
|
<!-- Clip boundary for selection indicators -->
|
||||||
{#if permissionError}
|
<div
|
||||||
<div class="error">
|
id="clip-root"
|
||||||
<Layout justifyItems="center" gap="S">
|
class:preview={$builderStore.inBuilder}
|
||||||
<!-- eslint-disable-next-line svelte/no-at-html-tags -->
|
class:tablet-preview={$builderStore.previewDevice ===
|
||||||
{@html ErrorSVG}
|
"tablet"}
|
||||||
<Heading size="L">
|
class:mobile-preview={$builderStore.previewDevice ===
|
||||||
You don't have permission to use this app
|
"mobile"}
|
||||||
</Heading>
|
>
|
||||||
<Body size="S">
|
<!-- Actual app -->
|
||||||
Ask your administrator to grant you access
|
<div id="app-root">
|
||||||
</Body>
|
{#if showDevTools}
|
||||||
</Layout>
|
<DevToolsHeader />
|
||||||
</div>
|
|
||||||
{:else if !$screenStore.activeLayout}
|
|
||||||
<div class="error">
|
|
||||||
<Layout justifyItems="center" gap="S">
|
|
||||||
<!-- eslint-disable-next-line svelte/no-at-html-tags -->
|
|
||||||
{@html ErrorSVG}
|
|
||||||
<Heading size="L">
|
|
||||||
Something went wrong rendering your app
|
|
||||||
</Heading>
|
|
||||||
<Body size="S">
|
|
||||||
Get in touch with support if this issue persists
|
|
||||||
</Body>
|
|
||||||
</Layout>
|
|
||||||
</div>
|
|
||||||
{:else if embedNoScreens}
|
|
||||||
<div class="error">
|
|
||||||
<Layout justifyItems="center" gap="S">
|
|
||||||
<!-- eslint-disable-next-line svelte/no-at-html-tags -->
|
|
||||||
{@html ErrorSVG}
|
|
||||||
<Heading size="L">
|
|
||||||
This Budibase app is not publicly accessible
|
|
||||||
</Heading>
|
|
||||||
</Layout>
|
|
||||||
</div>
|
|
||||||
{:else}
|
|
||||||
<CustomThemeWrapper>
|
|
||||||
{#key $screenStore.activeLayout._id}
|
|
||||||
<Component
|
|
||||||
isLayout
|
|
||||||
instance={$screenStore.activeLayout.props}
|
|
||||||
/>
|
|
||||||
{/key}
|
|
||||||
|
|
||||||
<!-- Layers on top of app -->
|
|
||||||
<NotificationDisplay />
|
|
||||||
<ConfirmationDisplay />
|
|
||||||
<PeekScreenDisplay />
|
|
||||||
</CustomThemeWrapper>
|
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
{#if showDevTools}
|
<div id="app-body">
|
||||||
<DevTools />
|
{#if permissionError}
|
||||||
|
<div class="error">
|
||||||
|
<Layout justifyItems="center" gap="S">
|
||||||
|
<!-- eslint-disable-next-line svelte/no-at-html-tags -->
|
||||||
|
{@html ErrorSVG}
|
||||||
|
<Heading size="L">
|
||||||
|
You don't have permission to use this app
|
||||||
|
</Heading>
|
||||||
|
<Body size="S">
|
||||||
|
Ask your administrator to grant you access
|
||||||
|
</Body>
|
||||||
|
</Layout>
|
||||||
|
</div>
|
||||||
|
{:else if !$screenStore.activeLayout}
|
||||||
|
<div class="error">
|
||||||
|
<Layout justifyItems="center" gap="S">
|
||||||
|
<!-- eslint-disable-next-line svelte/no-at-html-tags -->
|
||||||
|
{@html ErrorSVG}
|
||||||
|
<Heading size="L">
|
||||||
|
Something went wrong rendering your app
|
||||||
|
</Heading>
|
||||||
|
<Body size="S">
|
||||||
|
Get in touch with support if this issue
|
||||||
|
persists
|
||||||
|
</Body>
|
||||||
|
</Layout>
|
||||||
|
</div>
|
||||||
|
{:else if embedNoScreens}
|
||||||
|
<div class="error">
|
||||||
|
<Layout justifyItems="center" gap="S">
|
||||||
|
<!-- eslint-disable-next-line svelte/no-at-html-tags -->
|
||||||
|
{@html ErrorSVG}
|
||||||
|
<Heading size="L">
|
||||||
|
This Budibase app is not publicly accessible
|
||||||
|
</Heading>
|
||||||
|
</Layout>
|
||||||
|
</div>
|
||||||
|
{:else}
|
||||||
|
<CustomThemeWrapper>
|
||||||
|
{#key $screenStore.activeLayout._id}
|
||||||
|
<Component
|
||||||
|
isLayout
|
||||||
|
instance={$screenStore.activeLayout.props}
|
||||||
|
/>
|
||||||
|
{/key}
|
||||||
|
|
||||||
|
<!-- Layers on top of app -->
|
||||||
|
<NotificationDisplay />
|
||||||
|
<ConfirmationDisplay />
|
||||||
|
<PeekScreenDisplay />
|
||||||
|
</CustomThemeWrapper>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
{#if showDevTools}
|
||||||
|
<DevTools />
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{#if !$builderStore.inBuilder && $featuresStore.logoEnabled}
|
||||||
|
<FreeFooter />
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{#if !$builderStore.inBuilder && $featuresStore.logoEnabled}
|
<!-- Preview and dev tools utilities -->
|
||||||
<FreeFooter />
|
{#if $appStore.isDevApp}
|
||||||
|
<SelectionIndicator />
|
||||||
|
{/if}
|
||||||
|
{#if $builderStore.inBuilder || $devToolsStore.allowSelection}
|
||||||
|
<HoverIndicator />
|
||||||
|
{/if}
|
||||||
|
{#if $builderStore.inBuilder}
|
||||||
|
<DNDHandler />
|
||||||
|
<GridDNDHandler />
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
</SnippetsProvider>
|
||||||
<!-- Preview and dev tools utilities -->
|
</QueryParamsProvider>
|
||||||
{#if $appStore.isDevApp}
|
</RowSelectionProvider>
|
||||||
<SelectionIndicator />
|
</StateBindingsProvider>
|
||||||
{/if}
|
</UserBindingsProvider>
|
||||||
{#if $builderStore.inBuilder || $devToolsStore.allowSelection}
|
</DeviceBindingsProvider>
|
||||||
<HoverIndicator />
|
</EmbedProvider>
|
||||||
{/if}
|
|
||||||
{#if $builderStore.inBuilder}
|
|
||||||
<DNDHandler />
|
|
||||||
<GridDNDHandler />
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
</SnippetsProvider>
|
|
||||||
</QueryParamsProvider>
|
|
||||||
</RowSelectionProvider>
|
|
||||||
</StateBindingsProvider>
|
|
||||||
</UserBindingsProvider>
|
|
||||||
</DeviceBindingsProvider>
|
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
<KeyboardManager />
|
<KeyboardManager />
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
<script>
|
||||||
|
import Provider from "./Provider.svelte"
|
||||||
|
import { onMount } from "svelte"
|
||||||
|
|
||||||
|
let data = {}
|
||||||
|
|
||||||
|
function extractDomainFromUrl(url) {
|
||||||
|
const { hostname } = new URL(url)
|
||||||
|
const parts = hostname.split(".")
|
||||||
|
const tld = parts.slice(-2).join(".")
|
||||||
|
return tld
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleMessage(event) {
|
||||||
|
if (event.data?.type !== "bb-parent-window-event") {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate the event origin to ensure it's coming from a trusted source
|
||||||
|
// Allow different subdomains but must match TLD
|
||||||
|
const appOrigin = extractDomainFromUrl(window.location.origin)
|
||||||
|
const eventOrigin = extractDomainFromUrl(event.origin)
|
||||||
|
|
||||||
|
if (appOrigin === eventOrigin) {
|
||||||
|
data = event.data
|
||||||
|
} else {
|
||||||
|
console.error(
|
||||||
|
`Embedded budibase app domain ${appOrigin} does not match origin of event ${eventOrigin}.
|
||||||
|
Top level domains must match`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
window.addEventListener("message", handleMessage)
|
||||||
|
|
||||||
|
return () => window.removeEventListener("message", handleMessage)
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Provider key="embed" {data}>
|
||||||
|
<slot />
|
||||||
|
</Provider>
|
Loading…
Reference in New Issue