{@html section.info}
diff --git a/packages/builder/src/components/design/PropertiesPanel/PropertiesPanel.svelte b/packages/builder/src/components/design/PropertiesPanel/PropertiesPanel.svelte
index 27f6650cde..df91a87456 100644
--- a/packages/builder/src/components/design/PropertiesPanel/PropertiesPanel.svelte
+++ b/packages/builder/src/components/design/PropertiesPanel/PropertiesPanel.svelte
@@ -6,13 +6,20 @@
import DesignSection from "./DesignSection.svelte"
import CustomStylesSection from "./CustomStylesSection.svelte"
import ConditionalUISection from "./ConditionalUISection.svelte"
- import { getBindableProperties } from "builderStore/dataBinding"
+ import {
+ getBindableProperties,
+ getComponentBindableProperties,
+ } from "builderStore/dataBinding"
$: componentInstance = $selectedComponent
$: componentDefinition = store.actions.components.getDefinition(
$selectedComponent?._component
)
$: bindings = getBindableProperties($currentAsset, $store.selectedComponentId)
+ $: componentBindings = getComponentBindableProperties(
+ $currentAsset,
+ $store.selectedComponentId
+ )
@@ -28,6 +35,7 @@
{componentInstance}
{componentDefinition}
{bindings}
+ {componentBindings}
/>
{}
export let bindings = []
+ export let componentBindings = []
+ export let nested = false
let bindingDrawer
let anchor
let valid
- $: safeValue = getSafeValue(value, props.defaultValue, bindings)
+ $: allBindings = getAllBindings(bindings, componentBindings, nested)
+ $: safeValue = getSafeValue(value, props.defaultValue, allBindings)
$: tempValue = safeValue
- $: replaceBindings = val => readableToRuntimeBinding(bindings, val)
+ $: replaceBindings = val => readableToRuntimeBinding(allBindings, val)
+
+ const getAllBindings = (bindings, componentBindings, nested) => {
+ if (!nested) {
+ return bindings
+ }
+ return [...(bindings || []), ...(componentBindings || [])]
+ }
const handleClose = () => {
handleChange(tempValue)
@@ -78,7 +88,7 @@
updateOnChange={false}
on:change={handleChange}
onChange={handleChange}
- {bindings}
+ bindings={allBindings}
name={key}
text={label}
{type}
@@ -104,7 +114,7 @@
bind:valid
value={safeValue}
on:change={e => (tempValue = e.detail)}
- bindableProperties={bindings}
+ bindableProperties={allBindings}
allowJS
/>
diff --git a/packages/client/manifest.json b/packages/client/manifest.json
index 982f96ef90..f3ba71223c 100644
--- a/packages/client/manifest.json
+++ b/packages/client/manifest.json
@@ -2599,6 +2599,21 @@
"type": "boolean",
"key": "horizontal",
"label": "Horizontal"
+ },
+ {
+ "type": "boolean",
+ "label": "Show button",
+ "key": "showButton"
+ },
+ {
+ "type": "text",
+ "key": "buttonText",
+ "label": "Button text"
+ },
+ {
+ "type": "event",
+ "label": "Button action",
+ "key": "buttonOnClick"
}
]
},
@@ -2710,22 +2725,22 @@
},
{
"section": true,
- "name": "Button",
+ "name": "Title button",
"settings": [
{
"type": "boolean",
"key": "showTitleButton",
- "label": "Show title button",
+ "label": "Show button",
"defaultValue": false
},
{
"type": "text",
"key": "titleButtonText",
- "label": "Title button text"
+ "label": "Button text"
},
{
"type": "event",
- "label": "Title button action",
+ "label": "Button action",
"key": "titleButtonOnClick"
}
]
@@ -2742,9 +2757,139 @@
}
]
}
+ ]
+ },
+ "cardlistwithsearch": {
+ "block": true,
+ "name": "Card list with search",
+ "icon": "Table",
+ "styles": ["size"],
+ "info": "Only the first 3 search columns will be used.",
+ "settings": [
+ {
+ "type": "text",
+ "label": "Title",
+ "key": "title"
+ },
+ {
+ "type": "dataSource",
+ "label": "Data",
+ "key": "dataSource"
+ },
+ {
+ "type": "multifield",
+ "label": "Search Columns",
+ "key": "searchColumns",
+ "placeholder": "Choose search columns"
+ },
+ {
+ "type": "filter",
+ "label": "Filtering",
+ "key": "filter"
+ },
+ {
+ "type": "field",
+ "label": "Sort Column",
+ "key": "sortColumn"
+ },
+ {
+ "type": "select",
+ "label": "Sort Order",
+ "key": "sortOrder",
+ "options": ["Ascending", "Descending"],
+ "defaultValue": "Descending"
+ },
+ {
+ "type": "number",
+ "label": "Limit",
+ "key": "limit",
+ "defaultValue": 10
+ },
+ {
+ "type": "boolean",
+ "label": "Paginate",
+ "key": "paginate"
+ },
+ {
+ "section": true,
+ "name": "Cards",
+ "settings": [
+ {
+ "type": "text",
+ "key": "cardTitle",
+ "label": "Title",
+ "nested": true
+ },
+ {
+ "type": "text",
+ "key": "cardSubtitle",
+ "label": "Subtitle",
+ "nested": true
+ },
+ {
+ "type": "text",
+ "key": "cardDescription",
+ "label": "Description",
+ "nested": true
+
+ },
+ {
+ "type": "text",
+ "key": "cardImageURL",
+ "label": "Image URL",
+ "nested": true
+
+ },
+ {
+ "type": "boolean",
+ "key": "cardHorizontal",
+ "label": "Horizontal"
+ },
+ {
+ "type": "boolean",
+ "label": "Show button",
+ "key": "showCardButton"
+ },
+ {
+ "type": "text",
+ "key": "cardButtonText",
+ "label": "Button text",
+ "nested": true
+
+ },
+ {
+ "type": "event",
+ "label": "Button action",
+ "key": "cardButtonOnClick",
+ "nested": true
+ }
+ ]
+ },
+ {
+ "section": true,
+ "name": "Title button",
+ "settings": [
+ {
+ "type": "boolean",
+ "key": "showTitleButton",
+ "label": "Show button"
+ },
+ {
+ "type": "text",
+ "key": "titleButtonText",
+ "label": "Button text"
+ },
+ {
+ "type": "event",
+ "label": "Button action",
+ "key": "titleButtonOnClick"
+ }
+ ]
+ }
],
"context": {
- "type": "schema"
+ "type": "schema",
+ "suffix": "repeater"
}
}
}
diff --git a/packages/client/src/components/BlockComponent.svelte b/packages/client/src/components/BlockComponent.svelte
index 02456322da..589998994d 100644
--- a/packages/client/src/components/BlockComponent.svelte
+++ b/packages/client/src/components/BlockComponent.svelte
@@ -6,6 +6,7 @@
export let type
export let props
export let styles
+ export let context
// ID is only exposed as a prop so that it can be bound to from parent
// block components
@@ -16,7 +17,7 @@
// Create a fake component instance so that we can use the core Component
// to render this part of the block, taking advantage of binding enrichment
- $: id = block.id + rand
+ $: id = `${block.id}-${context ?? rand}`
$: instance = {
_component: `@budibase/standard-components/${type}`,
_id: id,
diff --git a/packages/client/src/components/Component.svelte b/packages/client/src/components/Component.svelte
index c13a50d52e..346de98f2f 100644
--- a/packages/client/src/components/Component.svelte
+++ b/packages/client/src/components/Component.svelte
@@ -1,3 +1,7 @@
+
+
{#key renderKey}
- {#if constructor && componentSettings && (visible || inSelectedPath)}
+ {#if constructor && settings && (visible || inSelectedPath)}
-
+
{#if children.length}
{#each children as child (child._id)}
diff --git a/packages/client/src/components/app/SpectrumCard.svelte b/packages/client/src/components/app/SpectrumCard.svelte
index bac0a81fb3..ba3e919cdd 100644
--- a/packages/client/src/components/app/SpectrumCard.svelte
+++ b/packages/client/src/components/app/SpectrumCard.svelte
@@ -1,6 +1,7 @@
+
+
+
+
+ {#if title || enrichedSearchColumns?.length || showTitleButton}
+
+ {/if}
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/client/src/components/app/blocks/index.js b/packages/client/src/components/app/blocks/index.js
index 16b123d17e..7d0d15080a 100644
--- a/packages/client/src/components/app/blocks/index.js
+++ b/packages/client/src/components/app/blocks/index.js
@@ -1 +1,2 @@
export { default as tablewithsearch } from "./TableWithSearch.svelte"
+export { default as cardlistwithsearch } from "./CardListWithSearch.svelte"
diff --git a/packages/client/src/stores/context.js b/packages/client/src/stores/context.js
index e372b837bd..fcbcf0f592 100644
--- a/packages/client/src/stores/context.js
+++ b/packages/client/src/stores/context.js
@@ -1,4 +1,5 @@
import { writable, derived } from "svelte/store"
+import { hashString } from "../utils/helpers"
export const createContextStore = oldContext => {
const newContext = writable({})
@@ -9,7 +10,7 @@ export const createContextStore = oldContext => {
for (let i = 0; i < $contexts.length - 1; i++) {
key += $contexts[i].key
}
- key += JSON.stringify($contexts[$contexts.length - 1])
+ key = hashString(key + JSON.stringify($contexts[$contexts.length - 1]))
// Reduce global state
const reducer = (total, context) => ({ ...total, ...context })