diff --git a/packages/builder/src/components/common/bindings/DrawerBindableInput.svelte b/packages/builder/src/components/common/bindings/DrawerBindableInput.svelte
index 5c4f90606d..09732ce4f2 100644
--- a/packages/builder/src/components/common/bindings/DrawerBindableInput.svelte
+++ b/packages/builder/src/components/common/bindings/DrawerBindableInput.svelte
@@ -21,6 +21,7 @@
export let allowHelpers = true
export let updateOnChange = true
export let drawerLeft
+ export let disableBindings = false
const dispatch = createEventDispatcher()
let bindingDrawer
@@ -62,7 +63,7 @@
{placeholder}
{updateOnChange}
/>
- {#if !disabled}
+ {#if !disabled && !disableBindings}
{
diff --git a/packages/builder/src/components/design/settings/controls/ButtonActionEditor/actions/SaveRow.svelte b/packages/builder/src/components/design/settings/controls/ButtonActionEditor/actions/SaveRow.svelte
index c1917ad90f..27b6463ffa 100644
--- a/packages/builder/src/components/design/settings/controls/ButtonActionEditor/actions/SaveRow.svelte
+++ b/packages/builder/src/components/design/settings/controls/ButtonActionEditor/actions/SaveRow.svelte
@@ -21,7 +21,8 @@
$: schemaComponents = getContextProviderComponents(
$currentAsset,
$store.selectedComponentId,
- "schema"
+ "schema",
+ { includeSelf: nested }
)
$: providerOptions = getProviderOptions(formComponents, schemaComponents)
$: schemaFields = getSchemaFields(parameters?.tableId)
diff --git a/packages/builder/src/components/design/settings/controls/ButtonConfiguration/ButtonConfiguration.svelte b/packages/builder/src/components/design/settings/controls/ButtonConfiguration/ButtonConfiguration.svelte
index 324418511b..ce91c8f7b5 100644
--- a/packages/builder/src/components/design/settings/controls/ButtonConfiguration/ButtonConfiguration.svelte
+++ b/packages/builder/src/components/design/settings/controls/ButtonConfiguration/ButtonConfiguration.svelte
@@ -4,10 +4,15 @@
import { createEventDispatcher } from "svelte"
import { store } from "builderStore"
import { Helpers } from "@budibase/bbui"
+ import { getEventContextBindings } from "builderStore/dataBinding"
+ export let componentInstance
export let componentBindings
export let bindings
export let value
+ export let key
+ export let nested
+ export let max
const dispatch = createEventDispatcher()
@@ -15,12 +20,18 @@
$: buttonList = sanitizeValue(value) || []
$: buttonCount = buttonList.length
+ $: eventContextBindings = getEventContextBindings({
+ componentInstance,
+ settingKey: key,
+ })
+ $: allBindings = [...bindings, ...eventContextBindings]
$: itemProps = {
componentBindings: componentBindings || [],
- bindings,
+ bindings: allBindings,
removeButton,
- canRemove: buttonCount > 1,
+ nested,
}
+ $: canAddButtons = max == null || buttonList.length < max
const sanitizeValue = val => {
return val?.map(button => {
@@ -86,11 +97,16 @@
focus={focusItem}
draggable={buttonCount > 1}
/>
-
-
{/if}
+
+
diff --git a/packages/builder/src/components/design/settings/controls/ButtonConfiguration/ButtonSetting.svelte b/packages/builder/src/components/design/settings/controls/ButtonConfiguration/ButtonSetting.svelte
index a05fd9a39b..56b5deace4 100644
--- a/packages/builder/src/components/design/settings/controls/ButtonConfiguration/ButtonSetting.svelte
+++ b/packages/builder/src/components/design/settings/controls/ButtonConfiguration/ButtonSetting.svelte
@@ -9,11 +9,33 @@
export let bindings
export let anchor
export let removeButton
- export let canRemove
+ export let nested
$: readableText = isJSBinding(item.text)
? "(JavaScript function)"
: runtimeToReadableBinding([...bindings, componentBindings], item.text)
+
+ // If this is a nested setting (for example inside a grid or form block) then
+ // we need to mark all the settings of the actual buttons as nested too, to
+ // allow us to reference context provided by the block.
+ // We will need to update this in future if the normal button component
+ // gets broken into multiple settings sections, as we assume a flat array.
+ const updatedNestedFlags = settings => {
+ if (!nested || !settings?.length) {
+ return settings
+ }
+ let newSettings = settings.map(setting => ({
+ ...setting,
+ nested: true,
+ }))
+ // We need to prevent bindings for the button names because of how grid
+ // blocks work. This is an edge case but unavoidable.
+ let name = newSettings.find(x => x.key === "text")
+ if (name) {
+ name.disableBindings = true
+ }
+ return newSettings
+ }
@@ -24,12 +46,12 @@
{componentBindings}
{bindings}
on:change
+ parseSettings={updatedNestedFlags}
/>
{readableText || "Button"}
col.name)
$: schemaOverrides = getSchemaOverrides(columns)
+ $: enrichedButtons = enrichButtons(buttons)
const getSchemaOverrides = columns => {
let overrides = {}
@@ -33,6 +43,25 @@
})
return overrides
}
+
+ const enrichButtons = buttons => {
+ if (!buttons?.length) {
+ return null
+ }
+ return buttons.map(settings => ({
+ size: "M",
+ text: settings.text,
+ type: settings.type,
+ onClick: async row => {
+ // We add a fake context binding in here, which allows us to pretend
+ // that the grid provides a "schema" binding - that lets us use the
+ // clicked row in things like save row actions
+ const enrichedContext = { ...get(context), [get(component).id]: row }
+ const fn = enrichButtonActions(settings.onClick, enrichedContext)
+ return await fn?.({ row })
+ },
+ }))
+ }
onRowClick?.({ row: e.detail })}
/>
diff --git a/packages/client/src/sdk.js b/packages/client/src/sdk.js
index 1d77f3e2da..69c2cc9fd4 100644
--- a/packages/client/src/sdk.js
+++ b/packages/client/src/sdk.js
@@ -14,6 +14,7 @@ import {
dndIsDragging,
confirmationStore,
roleStore,
+ stateStore,
} from "stores"
import { styleable } from "utils/styleable"
import { linkable } from "utils/linkable"
@@ -24,9 +25,13 @@ import BlockComponent from "components/BlockComponent.svelte"
import { ActionTypes } from "./constants"
import { fetchDatasourceSchema } from "./utils/schema.js"
import { getAPIKey } from "./utils/api.js"
+import { enrichButtonActions } from "./utils/buttonActions.js"
+import { processStringSync, makePropSafe } from "@budibase/string-templates"
export default {
API,
+
+ // Stores
authStore,
notificationStore,
routeStore,
@@ -41,13 +46,23 @@ export default {
currentRole,
confirmationStore,
roleStore,
+ stateStore,
+
+ // Utils
styleable,
linkable,
getAction,
fetchDatasourceSchema,
- Provider,
- ActionTypes,
getAPIKey,
+ enrichButtonActions,
+ processStringSync,
+ makePropSafe,
+
+ // Components
+ Provider,
Block,
BlockComponent,
+
+ // Constants
+ ActionTypes,
}
diff --git a/packages/frontend-core/src/components/grid/cells/GridCell.svelte b/packages/frontend-core/src/components/grid/cells/GridCell.svelte
index dcc76b9c75..d10eb25528 100644
--- a/packages/frontend-core/src/components/grid/cells/GridCell.svelte
+++ b/packages/frontend-core/src/components/grid/cells/GridCell.svelte
@@ -15,7 +15,7 @@
$: style = getStyle(width, selectedUser)
const getStyle = (width, selectedUser) => {
- let style = `flex: 0 0 ${width}px;`
+ let style = width === "auto" ? "width: auto;" : `flex: 0 0 ${width}px;`
if (selectedUser) {
style += `--user-color:${selectedUser.color};`
}
diff --git a/packages/frontend-core/src/components/grid/layout/ButtonColumn.svelte b/packages/frontend-core/src/components/grid/layout/ButtonColumn.svelte
new file mode 100644
index 0000000000..d484f9408d
--- /dev/null
+++ b/packages/frontend-core/src/components/grid/layout/ButtonColumn.svelte
@@ -0,0 +1,144 @@
+
+
+
+
+
+
+ {#each buttons as button}
+
+ {button.text || "Button"}
+
+ {/each}
+
+
+
+
+
+
+
diff --git a/packages/frontend-core/src/components/grid/layout/Grid.svelte b/packages/frontend-core/src/components/grid/layout/Grid.svelte
index e2ecd0f968..285282ddf7 100644
--- a/packages/frontend-core/src/components/grid/layout/Grid.svelte
+++ b/packages/frontend-core/src/components/grid/layout/Grid.svelte
@@ -48,6 +48,7 @@
export let fixedRowHeight = null
export let notifySuccess = null
export let notifyError = null
+ export let buttons = null
// Unique identifier for DOM nodes inside this instance
const rand = Math.random()
@@ -99,6 +100,7 @@
fixedRowHeight,
notifySuccess,
notifyError,
+ buttons,
})
// Set context for children to consume
diff --git a/packages/frontend-core/src/components/grid/layout/GridBody.svelte b/packages/frontend-core/src/components/grid/layout/GridBody.svelte
index 0bb2a51fb4..559c465b86 100644
--- a/packages/frontend-core/src/components/grid/layout/GridBody.svelte
+++ b/packages/frontend-core/src/components/grid/layout/GridBody.svelte
@@ -3,6 +3,7 @@
import GridScrollWrapper from "./GridScrollWrapper.svelte"
import GridRow from "./GridRow.svelte"
import { BlankRowID } from "../lib/constants"
+ import ButtonColumn from "./ButtonColumn.svelte"
const {
bounds,
@@ -13,6 +14,7 @@
dispatch,
isDragging,
config,
+ props,
} = getContext("grid")
let body
@@ -54,6 +56,9 @@
/>
{/if}
+ {#if $props.buttons?.length}
+
+ {/if}