Expose refresh datasource action from form blocks and add row action button templates

This commit is contained in:
Andrew Kingston 2024-09-06 11:16:27 +01:00
parent 61b82b8817
commit 5de81c624f
No known key found for this signature in database
4 changed files with 127 additions and 4 deletions

View File

@ -6,6 +6,7 @@
import { componentStore } from "stores/builder"
import { getEventContextBindings } from "dataBinding"
import { cloneDeep, isEqual } from "lodash/fp"
import { getRowActionButtonTemplates } from "templates/rowActions"
export let componentInstance
export let componentBindings
@ -19,11 +20,14 @@
let focusItem
let cachedValue
let rowActionTemplates = []
$: console.log(rowActionTemplates)
$: getRowActionTemplates(componentInstance)
$: if (!isEqual(value, cachedValue)) {
cachedValue = cloneDeep(value)
}
$: buttonList = sanitizeValue(cachedValue) || []
$: buttonCount = buttonList.length
$: eventContextBindings = getEventContextBindings({
@ -39,6 +43,11 @@
}
$: canAddButtons = max == null || buttonList.length < max
const getRowActionTemplates = async instance => {
const templates = await getRowActionButtonTemplates({ component: instance })
rowActionTemplates = templates
}
const sanitizeValue = val => {
if (!Array.isArray(val)) {
return null
@ -79,9 +88,13 @@
}
const addButton = () => {
const newButton = buildPseudoInstance({
text: `Button ${buttonCount + 1}`,
})
// const newButton = buildPseudoInstance({
// text: `Button ${buttonCount + 1}`,
// })
const newButton = rowActionTemplates[0]
if (!newButton) {
return
}
dispatch("change", [...buttonList, newButton])
focusItem = newButton._id
}

View File

@ -8,6 +8,7 @@
import InfoDisplay from "./InfoDisplay.svelte"
import analytics, { Events } from "analytics"
import { shouldDisplaySetting } from "@budibase/frontend-core"
import { getContext, setContext } from "svelte"
export let componentDefinition
export let componentInstance
@ -19,6 +20,16 @@
export let includeHidden = false
export let tag
// Sometimes we render component settings using a complicated nested
// component instance technique. This results in instances with IDs that
// don't exist anywhere in the tree. Therefore we need to keep track of
// what the real component tree ID is so we can always find it.
const rootId = getContext("rootId")
if (!rootId) {
setContext("rootId", componentInstance._id)
}
componentInstance._rootId = rootId || componentInstance._id
$: sections = getSections(
componentInstance,
componentDefinition,

View File

@ -0,0 +1,91 @@
import { get } from "svelte/store"
import { getDatasourceForProvider } from "dataBinding"
import { rowActions, selectedScreen, componentStore } from "stores/builder"
import { Helpers } from "@budibase/bbui"
import { findComponent } from "helpers/components"
export const getRowActionButtonTemplates = async ({ screen, component }) => {
if (!component) {
return []
}
if (!screen) {
screen = get(selectedScreen)
}
const id = component._rootId
const instance = findComponent(screen?.props, id)
if (!instance) {
return []
}
// The row ID binding depends on what component this is.
// Therefore we need to whitelist this to only function for certain components.
const type = instance?._component
const isGridBlock = type?.endsWith("/gridblock")
const isFormBlock =
type?.endsWith("/formblock") || type?.endsWith("/multistepformblock")
if (!isGridBlock && !isFormBlock) {
return []
}
// Check we have a valid datasource that can contain row actions
const ds = getDatasourceForProvider(get(selectedScreen), instance)
if (ds?.type !== "table" && ds?.type !== "viewV2") {
return []
}
const resourceId = ds.id || ds.tableId
if (!resourceId) {
return []
}
await rowActions.refreshRowActions(resourceId)
const enabledActions = get(rowActions)[resourceId] || []
// Generate the row ID binding depending on the component
let rowIdBinding
if (isGridBlock) {
rowIdBinding = `{{ [${instance._id}].[_id] }}`
} else if (isFormBlock) {
rowIdBinding = `{{ [${instance._id}-repeater].[_id] }}`
}
// Create templates
return enabledActions.map(action => {
// Create a button instance
const button = componentStore.createInstance(
`@budibase/standard-components/button`,
{
_instanceName: Helpers.uuid(),
text: action.name,
type: "primary",
}
)
// Row action button action
const onClick = [
{
parameters: {
rowActionId: action.id,
resourceId,
rowId: rowIdBinding,
},
"##eventHandlerType": "Row Action",
id: Helpers.uuid(),
},
]
// For form blocks we need to manually refresh the form after running the action
if (isFormBlock) {
onClick.push({
parameters: {
componentId: `${instance._id}-provider`,
},
"##eventHandlerType": "Refresh Data Provider",
id: Helpers.uuid(),
})
}
return {
...button,
onClick,
}
})
}

View File

@ -6998,6 +6998,10 @@
{
"type": "ChangeFormStep",
"suffix": "form"
},
{
"type": "RefreshDatasource",
"suffix": "provider"
}
],
"context": [
@ -7241,6 +7245,10 @@
{
"type": "ScrollTo",
"suffix": "form"
},
{
"type": "RefreshDatasource",
"suffix": "provider"
}
],
"context": [