Simplify and add new contextAccess manifest key to solve incompatibility with table format and condition settings

This commit is contained in:
Andrew Kingston 2025-02-11 16:14:24 +00:00
parent 83e23ef578
commit 917548bf84
No known key found for this signature in database
10 changed files with 82 additions and 27 deletions

View File

@ -43,7 +43,6 @@
<EditComponentPopover
{anchor}
componentInstance={item}
{componentBindings}
{bindings}
on:change
parseSettings={updatedNestedFlags}

View File

@ -1,13 +1,13 @@
<script>
import { Icon, Popover, Layout } from "@budibase/bbui"
import { componentStore } from "@/stores/builder"
import { componentStore, selectedScreen } from "@/stores/builder"
import { cloneDeep } from "lodash/fp"
import { createEventDispatcher, getContext } from "svelte"
import ComponentSettingsSection from "@/pages/builder/app/[application]/design/[screenId]/[componentId]/_components/Component/ComponentSettingsSection.svelte"
import { getComponentBindableProperties } from "@/dataBinding"
export let anchor
export let componentInstance
export let componentBindings
export let bindings
export let parseSettings
@ -28,6 +28,10 @@
}
$: componentDef = componentStore.getDefinition(componentInstance._component)
$: parsedComponentDef = processComponentDefinitionSettings(componentDef)
$: componentBindings = getComponentBindableProperties(
$selectedScreen,
$componentStore.selectedComponentId
)
const open = () => {
isOpen = true

View File

@ -45,7 +45,6 @@
<EditComponentPopover
{anchor}
componentInstance={item}
{componentBindings}
{bindings}
{parseSettings}
on:change

View File

@ -22,29 +22,59 @@
export let propertyFocus = false
export let info = null
export let disableBindings = false
export let wide
export let isolated = false
export let wide = false
export let contextAccess = null
let highlightType
$: highlightedProp = $builderStore.highlightedSetting
$: allBindings = getAllBindings(bindings, componentBindings, nested, isolated)
$: allBindings = getAllBindings(
bindings,
componentBindings,
nested,
contextAccess
)
$: safeValue = getSafeValue(value, defaultValue, allBindings)
$: replaceBindings = val => readableToRuntimeBinding(allBindings, val)
$: if (value) {
highlightType =
highlightedProp?.key === key ? `highlighted-${highlightedProp?.type}` : ""
}
const getAllBindings = (bindings, componentBindings, nested, isolated) => {
if (isolated) {
bindings = []
const getAllBindings = (
bindings,
componentBindings,
nested,
contextAccess
) => {
// contextAccess is a bit of an escape hatch to get around how we render
// certain settings types by using a pseudo component definition, leading
// to problems with the nested flag
if (contextAccess != null) {
// Optionally include global bindings
let allBindings = contextAccess.global ? bindings : []
// Optionally include or exclude self (component) bindings.
// If this is a nested setting then we will already have our own context
// bindings mixed in, so if we don't want self context we need to filter
// them out.
if (contextAccess.self) {
return [...allBindings, ...componentBindings]
} else {
return allBindings.filter(binding => {
return !componentBindings.some(componentBinding => {
return componentBinding.runtimeBinding === binding.runtimeBinding
})
})
}
if (!nested) {
}
// Otherwise just honour the normal nested flag
if (nested) {
return [...bindings, ...componentBindings]
} else {
return bindings
}
return [...(componentBindings || []), ...(bindings || [])]
}
// Handle a value change of any type

View File

@ -151,7 +151,7 @@
propertyFocus={$builderStore.propertyFocus === setting.key}
info={setting.info}
disableBindings={setting.disableBindings}
isolated={setting.isolated}
contextAccess={setting.contextAccess}
props={{
// Generic settings
placeholder: setting.placeholder || null,

View File

@ -3088,13 +3088,21 @@
{
"type": "tableConditions",
"label": "Conditions",
"key": "conditions"
"key": "conditions",
"contextAccess": {
"global": true,
"self": false
}
},
{
"type": "text",
"label": "Format",
"key": "format",
"info": "Changing format will display values as text"
"info": "Changing format will display values as text",
"contextAccess": {
"global": false,
"self": true
}
}
]
},
@ -7692,8 +7700,7 @@
"type": "columns/grid",
"key": "columns",
"resetOn": "table",
"nested": true,
"isolated": true
"nested": true
}
]
},

View File

@ -47,8 +47,8 @@
$: currentTheme = $context?.device?.theme
$: darkMode = !currentTheme?.includes("light")
$: parsedColumns = getParsedColumns(columns)
$: schemaOverrides = getSchemaOverrides(parsedColumns)
$: enrichedButtons = enrichButtons(buttons)
$: schemaOverrides = getSchemaOverrides(parsedColumns, $context)
$: selectedRows = deriveSelectedRows(gridContext)
$: styles = patchStyles($component.styles, minHeight)
$: data = { selectedRows: $selectedRows }
@ -97,18 +97,19 @@
}))
}
const getSchemaOverrides = columns => {
const getSchemaOverrides = (columns, context) => {
let overrides = {}
columns.forEach((column, idx) => {
overrides[column.field] = {
displayName: column.label,
order: idx,
conditions: column.conditions,
visible: !!column.active,
conditions: enrichConditions(column.conditions, context),
format: createFormatter(column),
// Small hack to ensure we react to all changes when inside the builder
rand: Math.random(),
// Small hack to ensure we react to all changes, as our
// memoization cannot compare differences in functions
rand: column.conditions?.length ? Math.random() : null,
}
if (column.width) {
overrides[column.field].width = column.width
@ -117,6 +118,15 @@
return overrides
}
const enrichConditions = (conditions, context) => {
return conditions?.map(condition => {
return {
...condition,
referenceValue: processStringSync(condition.referenceValue, context),
}
})
}
const createFormatter = column => {
if (typeof column.format !== "string" || !column.format.trim().length) {
return null

View File

@ -31,7 +31,7 @@ export const deriveStores = (context: StoreContext): ConditionDerivedStore => {
// Derive and memoize the cell conditions present in our columns so that we
// only recompute condition metadata when absolutely necessary
const conditions = derivedMemo(columns, $columns => {
let newConditions = []
let newConditions: UICondition[] = []
for (let column of $columns) {
for (let condition of column.conditions || []) {
newConditions.push({

View File

@ -1,9 +1,15 @@
import { CalculationType, FieldSchema, FieldType, UIRow } from "@budibase/types"
import {
CalculationType,
FieldSchema,
FieldType,
UICondition,
UIRow,
} from "@budibase/types"
export type UIColumn = FieldSchema & {
label: string
readonly: boolean
conditions: any
conditions?: UICondition[]
format?: (row: UIRow) => any
related?: {
field: string

View File

@ -3,7 +3,7 @@ import { FieldType, SearchFilter } from "@budibase/types"
export interface UICondition {
column: string
type: FieldType
referenceValue: string
referenceValue: any
operator: SearchFilter["operator"]
metadataKey: string
metadataValue: string