diff --git a/packages/builder/src/builderStore/dataBinding.js b/packages/builder/src/builderStore/dataBinding.js index b94d0d841a..22b2b02f37 100644 --- a/packages/builder/src/builderStore/dataBinding.js +++ b/packages/builder/src/builderStore/dataBinding.js @@ -11,21 +11,24 @@ const CAPTURE_VAR_INSIDE_TEMPLATE = /{{([^}]+)}}/g /** * Gets all bindable data context fields and instance fields. */ -export const getBindableProperties = (rootComponent, componentId) => { - return getContextBindings(rootComponent, componentId) +export const getBindableProperties = (asset, componentId) => { + const contextBindings = getContextBindings(asset, componentId) + const userBindings = getUserBindings() + const urlBindings = getUrlBindings(asset, componentId) + return [...contextBindings, ...userBindings, ...urlBindings] } /** * Gets all data provider components above a component. */ -export const getDataProviderComponents = (rootComponent, componentId) => { - if (!rootComponent || !componentId) { +export const getDataProviderComponents = (asset, componentId) => { + if (!asset || !componentId) { return [] } // Get the component tree leading up to this component, ignoring the component // itself - const path = findComponentPath(rootComponent, componentId) + const path = findComponentPath(asset.props, componentId) path.pop() // Filter by only data provider components @@ -38,18 +41,14 @@ export const getDataProviderComponents = (rootComponent, componentId) => { /** * Gets all data provider components above a component. */ -export const getActionProviderComponents = ( - rootComponent, - componentId, - actionType -) => { - if (!rootComponent || !componentId) { +export const getActionProviderComponents = (asset, componentId, actionType) => { + if (!asset || !componentId) { return [] } // Get the component tree leading up to this component, ignoring the component // itself - const path = findComponentPath(rootComponent, componentId) + const path = findComponentPath(asset.props, componentId) path.pop() // Filter by only data provider components @@ -92,13 +91,12 @@ export const getDatasourceForProvider = component => { } /** - * Gets all bindable data contexts. These are fields of schemas of data contexts - * provided by data provider components, such as lists or row detail components. + * Gets all bindable data properties from component data contexts. */ -export const getContextBindings = (rootComponent, componentId) => { +const getContextBindings = (asset, componentId) => { // Extract any components which provide data contexts - const dataProviders = getDataProviderComponents(rootComponent, componentId) - let contextBindings = [] + const dataProviders = getDataProviderComponents(asset, componentId) + let bindings = [] // Create bindings for each data provider dataProviders.forEach(component => { @@ -143,7 +141,7 @@ export const getContextBindings = (rootComponent, componentId) => { runtimeBoundKey = `${key}_first` } - contextBindings.push({ + bindings.push({ type: "context", runtimeBinding: `${makePropSafe(component._id)}.${makePropSafe( runtimeBoundKey @@ -157,7 +155,14 @@ export const getContextBindings = (rootComponent, componentId) => { }) }) - // Add logged in user bindings + return bindings +} + +/** + * Gets all bindable properties from the logged in user. + */ +const getUserBindings = () => { + let bindings = [] const tables = get(backendUiStore).tables const userTable = tables.find(table => table._id === TableNames.USERS) const schema = { @@ -176,7 +181,7 @@ export const getContextBindings = (rootComponent, componentId) => { runtimeBoundKey = `${key}_first` } - contextBindings.push({ + bindings.push({ type: "context", runtimeBinding: `user.${runtimeBoundKey}`, readableBinding: `Current User.${key}`, @@ -187,7 +192,26 @@ export const getContextBindings = (rootComponent, componentId) => { }) }) - return contextBindings + return bindings +} + +/** + * Gets all bindable properties from URL parameters. + */ +const getUrlBindings = asset => { + const url = asset?.routing?.route ?? "" + const split = url.split("/") + let params = [] + split.forEach(part => { + if (part.startsWith(":") && part.length > 1) { + params.push(part.replace(/:/g, "").replace(/\?/g, "")) + } + }) + return params.map(param => ({ + type: "context", + runtimeBinding: `url.${param}`, + readableBinding: `URL.${param}`, + })) } /** diff --git a/packages/builder/src/components/common/DrawerBindableInput.svelte b/packages/builder/src/components/common/DrawerBindableInput.svelte new file mode 100644 index 0000000000..af0da92463 --- /dev/null +++ b/packages/builder/src/components/common/DrawerBindableInput.svelte @@ -0,0 +1,84 @@ + + +
+ onChange(event.detail)} + placeholder="/screen" /> +
+ +
+
+ +
+ + Add the objects on the left to enrich your text. + +
+ + + +
+ (tempValue = event.detail)} + bindableProperties={bindings} /> +
+
+ + diff --git a/packages/builder/src/components/design/PropertiesPanel/BindingPanel.svelte b/packages/builder/src/components/design/PropertiesPanel/BindingPanel.svelte index 76dbdf229c..02a7a33bec 100644 --- a/packages/builder/src/components/design/PropertiesPanel/BindingPanel.svelte +++ b/packages/builder/src/components/design/PropertiesPanel/BindingPanel.svelte @@ -24,7 +24,7 @@ $: value && checkValid() $: bindableProperties = getBindableProperties( - $currentAsset.props, + $currentAsset, $store.selectedComponentId ) $: dispatch("update", value) diff --git a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/DatasourceSelect.svelte b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/DatasourceSelect.svelte index 75702b7cdb..5675774139 100644 --- a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/DatasourceSelect.svelte +++ b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/DatasourceSelect.svelte @@ -47,7 +47,7 @@ type: "query", })) $: bindableProperties = getBindableProperties( - $currentAsset.props, + $currentAsset, $store.selectedComponentId ) $: queryBindableProperties = bindableProperties.map(property => ({ diff --git a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/EventsEditor/actions/DeleteRow.svelte b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/EventsEditor/actions/DeleteRow.svelte index 287f76d9e3..79ee23acd7 100644 --- a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/EventsEditor/actions/DeleteRow.svelte +++ b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/EventsEditor/actions/DeleteRow.svelte @@ -10,7 +10,7 @@ export let parameters $: dataProviderComponents = getDataProviderComponents( - $currentAsset.props, + $currentAsset, $store.selectedComponentId ) $: { diff --git a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/EventsEditor/actions/ExecuteQuery.svelte b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/EventsEditor/actions/ExecuteQuery.svelte index 74d27df027..68ed77f1d2 100644 --- a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/EventsEditor/actions/ExecuteQuery.svelte +++ b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/EventsEditor/actions/ExecuteQuery.svelte @@ -10,7 +10,7 @@ ds => ds._id === parameters.datasourceId ) $: bindableProperties = getBindableProperties( - $currentAsset.props, + $currentAsset, $store.selectedComponentId ).map(property => ({ ...property, diff --git a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/EventsEditor/actions/NavigateTo.svelte b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/EventsEditor/actions/NavigateTo.svelte index 041237266e..9d814bf369 100644 --- a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/EventsEditor/actions/NavigateTo.svelte +++ b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/EventsEditor/actions/NavigateTo.svelte @@ -1,18 +1,23 @@
- - - {/each} - + (parameters.url = value.detail)} + {bindings} />
diff --git a/packages/builder/src/components/design/PropertiesPanel/SettingsView.svelte b/packages/builder/src/components/design/PropertiesPanel/SettingsView.svelte index 430e622c4f..889c7d5dcd 100644 --- a/packages/builder/src/components/design/PropertiesPanel/SettingsView.svelte +++ b/packages/builder/src/components/design/PropertiesPanel/SettingsView.svelte @@ -18,7 +18,6 @@ import MultiFieldSelect from "./PropertyControls/MultiFieldSelect.svelte" import SchemaSelect from "./PropertyControls/SchemaSelect.svelte" import EventsEditor from "./PropertyControls/EventsEditor" - import ScreenSelect from "./PropertyControls/ScreenSelect.svelte" import DetailScreenSelect from "./PropertyControls/DetailScreenSelect.svelte" import { IconSelect } from "./PropertyControls/IconSelect" import ColorPicker from "./PropertyControls/ColorPicker.svelte" @@ -62,7 +61,6 @@ text: Input, select: OptionSelect, datasource: DatasourceSelect, - screen: ScreenSelect, detailScreen: DetailScreenSelect, boolean: Checkbox, number: Input, diff --git a/packages/client/src/utils/componentProps.js b/packages/client/src/utils/componentProps.js index 18a894beaa..161565e789 100644 --- a/packages/client/src/utils/componentProps.js +++ b/packages/client/src/utils/componentProps.js @@ -44,7 +44,7 @@ export const enrichProps = async (props, context) => { let enrichedProps = await enrichDataBindings(validProps, totalContext) // Enrich button actions if they exist - if (props._component.endsWith("/button") && enrichedProps.onClick) { + if (props._component?.endsWith("/button") && enrichedProps.onClick) { enrichedProps.onClick = enrichButtonActions( enrichedProps.onClick, totalContext diff --git a/packages/standard-components/manifest.json b/packages/standard-components/manifest.json index cbebe1986c..fbf62c02d9 100644 --- a/packages/standard-components/manifest.json +++ b/packages/standard-components/manifest.json @@ -137,9 +137,10 @@ "key": "subheading" }, { - "type": "screen", + "type": "text", "label": "Link URL", - "key": "destinationUrl" + "key": "destinationUrl", + "placeholder": "/screen" } ] }, @@ -170,9 +171,10 @@ "key": "linkText" }, { - "type": "screen", - "label": "Link Url", - "key": "linkUrl" + "type": "text", + "label": "Link URL", + "key": "linkUrl", + "placeholder": "/screen" }, { "type": "color", @@ -339,9 +341,10 @@ "key": "text" }, { - "type": "screen", + "type": "text", "label": "URL", - "key": "url" + "key": "url", + "placeholder": "/screen" }, { "type": "boolean", @@ -412,9 +415,10 @@ "key": "linkText" }, { - "type": "screen", + "type": "text", "label": "Link URL", - "key": "linkUrl" + "key": "linkUrl", + "placeholder": "/screen" }, { "type": "color",