diff --git a/packages/builder/src/builderStore/fetchBindableProperties.js b/packages/builder/src/builderStore/fetchBindableProperties.js
index f36484fbdf..b2e67ad520 100644
--- a/packages/builder/src/builderStore/fetchBindableProperties.js
+++ b/packages/builder/src/builderStore/fetchBindableProperties.js
@@ -72,14 +72,21 @@ const componentInstanceToBindable = walkResult => i => {
const contextToBindables = walkResult => context => {
const contextParentPath = getParentPath(walkResult, context)
- return Object.keys(context.model.schema).map(k => ({
+ const newBindable = key => ({
type: "context",
instance: context.instance,
// how the binding expression persists, and is used in the app at runtime
- runtimeBinding: `${contextParentPath}data.${k}`,
+ runtimeBinding: `${contextParentPath}data.${key}`,
// how the binding exressions looks to the user of the builder
- readableBinding: `${context.instance._instanceName}.${context.model.name}.${k}`,
- }))
+ readableBinding: `${context.instance._instanceName}.${context.model.name}.${key}`,
+ })
+
+ return (
+ Object.keys(context.model.schema)
+ .map(newBindable)
+ // add _id and _rev fields - not part of schema, but always valid
+ .concat([newBindable("_id"), newBindable("_rev")])
+ )
}
const getParentPath = (walkResult, context) => {
diff --git a/packages/builder/src/components/userInterface/EventsEditor/EventEditorModal.svelte b/packages/builder/src/components/userInterface/EventsEditor/EventEditorModal.svelte
index 5a9af8de9d..6e804ae3fd 100644
--- a/packages/builder/src/components/userInterface/EventsEditor/EventEditorModal.svelte
+++ b/packages/builder/src/components/userInterface/EventsEditor/EventEditorModal.svelte
@@ -10,7 +10,7 @@
import { AddIcon, ArrowDownIcon } from "components/common/Icons/"
import { EVENT_TYPE_MEMBER_NAME } from "../../common/eventHandlers"
import actionTypes from "./actions"
- import { createEventDispatcher } from "svelte"
+ import { createEventDispatcher, onMount } from "svelte"
const dispatch = createEventDispatcher()
@@ -38,7 +38,7 @@
actions[index] = updatedHandler
}
- const deleteEventHandler = index => {
+ const deleteAction = index => {
actions.splice(index, 1)
actions = actions
}
@@ -107,7 +107,9 @@
this={selectedActionComponent}
parameters={selectedAction.parameters} />
- Delete
+ deleteAction(index)}>
+ Delete
+
{/if}
diff --git a/packages/builder/src/components/userInterface/EventsEditor/actions/UpdateRecord.svelte b/packages/builder/src/components/userInterface/EventsEditor/actions/UpdateRecord.svelte
index 22125ee7c3..ff1e824f6f 100644
--- a/packages/builder/src/components/userInterface/EventsEditor/actions/UpdateRecord.svelte
+++ b/packages/builder/src/components/userInterface/EventsEditor/actions/UpdateRecord.svelte
@@ -8,10 +8,14 @@
const emptyField = () => ({ name: "", value: "" })
- $: fields = Object.keys(parameters.fields || emptyField()).map(name => ({
- name,
- value: (parameters.fields && parameters.fields[name]) || "",
- }))
+ // this statement initialises fields from parameters.fields
+ $: fields =
+ fields ||
+ (parameters &&
+ Object.keys(parameters.fields || { "": "" }).map(name => ({
+ name,
+ value: (parameters.fields && parameters.fields[name]) || "",
+ })))
$: bindableProperties = fetchBindableProperties({
componentInstanceId: $store.currentComponentInfo._id,
@@ -20,6 +24,18 @@
models: $backendUiStore.models,
})
+ let idFields
+ $: {
+ idFields = bindableProperties.filter(
+ bindable =>
+ bindable.type === "context" && bindable.runtimeBinding.endsWith("._id")
+ )
+ // ensure recordId is always defaulted - there is usually only one option
+ if (idFields.length > 0 && !parameters.recordId) {
+ parameters.recordId = idFields[0].runtimeBinding
+ }
+ }
+
const addField = () => {
const newFields = fields.filter(f => f.name)
newFields.push(emptyField())
@@ -28,46 +44,92 @@
const bindablePropertyName = prop => {
if (prop.type === "instance") return prop.instance._instanceName
- return instance.readableBinding.split(".")[
- instance.readableBinding.lastIndexOf(".")
+ return prop.readableBinding.split(".")[
+ prop.readableBinding.lastIndexOf(".")
]
}
- let fieldNames
- $: {
- fieldNames =
- parameters.model &&
- Object.keys(
- $backendUiStore.models.find(model => model._id === parameters.model)
- .schema
- )
+ const fieldNameChanged = e => {}
+
+ const rebuildParameters = () => {
+ // rebuilds paramters.fields every time a field name or value is added
+ parameters.fields = {}
+ for (let field of fields) {
+ if (field.name) {
+ parameters.fields[field.name] = field.value
+ }
+ }
}
+
+ // just wraps binding in {{ ... }}
+ const toBindingExpression = bindingPath => `{{ ${bindingPath} }}`
+
+ // finds the selected idBinding, then reads the table/view
+ // from the component instance that it belongs to.
+ // then returns the field names for that schema
+ const fieldNamesFromIdBinding = recordId => {
+ if (!recordId) return []
+
+ const idBinding = bindableProperties.find(
+ prop => prop.runtimeBinding === recordId
+ )
+ if (!idBinding) return []
+
+ const { instance } = idBinding
+
+ const component = $store.components[instance._component]
+
+ // component.context is the name of the prop that holds the modelId
+ const modelId = instance[component.context]
+
+ if (!modelId) return []
+
+ const model = $backendUiStore.models.find(
+ m => m._id === instance[component.context]
+ )
+
+ return Object.keys(model.schema)
+ }
+
+ $: fieldNames = parameters ? fieldNamesFromIdBinding(parameters.recordId) : []
-
-
+ {#if idFields.length === 0}
+
+ Update record can only be used within a component that provides data, such
+ as a List
+
+ {:else}
+
+
+ {/if}
- {#if parameters.model && fields}
+ {#if parameters.recordId && fields}
{#each fields as field}
-