From d03f96ceb8327d46245700c404831e8afd9c3bbc Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Fri, 28 Apr 2023 09:03:09 +0100 Subject: [PATCH 01/43] Make all blindings global and improve client component performance --- .../builder/src/builderStore/dataBinding.js | 34 ++++++--- .../src/builderStore/store/frontend.js | 7 +- .../controls/DataProviderSelect.svelte | 9 +-- packages/client/manifest.json | 11 --- .../client/src/components/Component.svelte | 71 ++++++++++++++----- .../src/components/context/Provider.svelte | 6 +- packages/client/src/stores/context.js | 61 +++++++--------- packages/client/src/utils/componentProps.js | 16 +---- .../client/src/utils/enrichDataBinding.js | 1 + yarn.lock | 12 ++-- 10 files changed, 127 insertions(+), 101 deletions(-) diff --git a/packages/builder/src/builderStore/dataBinding.js b/packages/builder/src/builderStore/dataBinding.js index 0d41931a55..9f253f9f75 100644 --- a/packages/builder/src/builderStore/dataBinding.js +++ b/packages/builder/src/builderStore/dataBinding.js @@ -199,15 +199,7 @@ export const getContextProviderComponents = ( return [] } - // Get the component tree leading up to this component, ignoring the component - // itself - const path = findComponentPath(asset.props, componentId) - if (!options?.includeSelf) { - path.pop() - } - - // Filter by only data provider components - return path.filter(component => { + return findAllMatchingComponents(asset.props, component => { const def = store.actions.components.getDefinition(component._component) if (!def?.context) { return false @@ -222,6 +214,30 @@ export const getContextProviderComponents = ( const contexts = Array.isArray(def.context) ? def.context : [def.context] return contexts.find(context => context.type === type) != null }) + // + // // Get the component tree leading up to this component, ignoring the component + // // itself + // const path = findComponentPath(asset.props, componentId) + // if (!options?.includeSelf) { + // path.pop() + // } + // + // // Filter by only data provider components + // return path.filter(component => { + // const def = store.actions.components.getDefinition(component._component) + // if (!def?.context) { + // return false + // } + // + // // If no type specified, return anything that exposes context + // if (!type) { + // return true + // } + // + // // Otherwise only match components with the specific context type + // const contexts = Array.isArray(def.context) ? def.context : [def.context] + // return contexts.find(context => context.type === type) != null + // }) } /** diff --git a/packages/builder/src/builderStore/store/frontend.js b/packages/builder/src/builderStore/store/frontend.js index e264dc099b..fb3eb8f1d9 100644 --- a/packages/builder/src/builderStore/store/frontend.js +++ b/packages/builder/src/builderStore/store/frontend.js @@ -621,10 +621,9 @@ export const getFrontendStore = () => { else { if (setting.type === "dataProvider") { // Validate data provider exists, or else clear it - const treeId = parent?._id || component._id - const path = findComponentPath(screen?.props, treeId) - const providers = path.filter(component => - component._component?.endsWith("/dataprovider") + const providers = findAllMatchingComponents( + screen?.props, + component => component._component?.endsWith("/dataprovider") ) // Validate non-empty values const valid = providers?.some(dp => value.includes?.(dp._id)) diff --git a/packages/builder/src/components/design/settings/controls/DataProviderSelect.svelte b/packages/builder/src/components/design/settings/controls/DataProviderSelect.svelte index 83255ec325..9fd220e798 100644 --- a/packages/builder/src/components/design/settings/controls/DataProviderSelect.svelte +++ b/packages/builder/src/components/design/settings/controls/DataProviderSelect.svelte @@ -1,15 +1,16 @@ import { + getContextProviderComponents, readableToRuntimeBinding, runtimeToReadableBinding, } from "builderStore/dataBinding" @@ -29,7 +30,6 @@ import BindingBuilder from "components/integration/QueryBindingBuilder.svelte" import IntegrationQueryEditor from "components/integration/index.svelte" import { makePropSafe as safe } from "@budibase/string-templates" - import { findAllComponents } from "builderStore/componentUtils" import ClientBindingPanel from "components/common/bindings/ClientBindingPanel.svelte" import DataSourceCategory from "components/design/settings/controls/DataSourceSelect/DataSourceCategory.svelte" import { API } from "api" @@ -75,13 +75,12 @@ ...query, type: "query", })) - $: dataProviders = findAllComponents($currentAsset.props) - .filter(component => { - return ( - component._component?.endsWith("/dataprovider") && - component._id !== $store.selectedComponentId - ) - }) + $: contextProviders = getContextProviderComponents( + $currentAsset, + $store.selectedComponentId + ) + $: dataProviders = contextProviders + .filter(component => component._component?.endsWith("/dataprovider")) .map(provider => ({ label: provider._instanceName, name: provider._instanceName, diff --git a/packages/client/manifest.json b/packages/client/manifest.json index fe95f5536c..2a9bc6f258 100644 --- a/packages/client/manifest.json +++ b/packages/client/manifest.json @@ -573,6 +573,7 @@ "description": "A configurable data list that attaches to your backend tables.", "icon": "JourneyData", "illegalChildren": ["section"], + "requiredAncestors": ["dataprovider"], "hasChildren": true, "size": { "width": 400, @@ -710,12 +711,10 @@ ], "context": [ { - "type": "schema", - "scope": "local" + "type": "schema" }, { "type": "static", - "scope": "local", "values": [ { "label": "Row index", @@ -1565,6 +1564,7 @@ "name": "Bar Chart", "description": "Bar chart", "icon": "GraphBarVertical", + "requiredAncestors": ["dataprovider"], "size": { "width": 600, "height": 400 @@ -1727,6 +1727,7 @@ "width": 600, "height": 400 }, + "requiredAncestors": ["dataprovider"], "settings": [ { "type": "text", @@ -1880,6 +1881,7 @@ "width": 600, "height": 400 }, + "requiredAncestors": ["dataprovider"], "settings": [ { "type": "text", @@ -2045,6 +2047,7 @@ "width": 600, "height": 400 }, + "requiredAncestors": ["dataprovider"], "settings": [ { "type": "text", @@ -2174,6 +2177,7 @@ "width": 600, "height": 400 }, + "requiredAncestors": ["dataprovider"], "settings": [ { "type": "text", @@ -2303,6 +2307,7 @@ "width": 600, "height": 400 }, + "requiredAncestors": ["dataprovider"], "settings": [ { "type": "text", @@ -4076,6 +4081,7 @@ "width": 400, "height": 320 }, + "requiredAncestors": ["dataprovider"], "settings": [ { "type": "dataProvider", @@ -4631,6 +4637,7 @@ "name": "Table", "icon": "Table", "illegalChildren": ["section"], + "requiredAncestors": ["dataprovider"], "hasChildren": true, "showEmptyState": false, "size": { @@ -4721,6 +4728,7 @@ "name": "Date Range", "icon": "Calendar", "styles": ["size"], + "requiredAncestors": ["dataprovider"], "hasChildren": false, "size": { "width": 200, @@ -4828,6 +4836,7 @@ "width": 100, "height": 35 }, + "requiredAncestors": ["dataprovider"], "settings": [ { "type": "dataProvider", @@ -5602,38 +5611,7 @@ } ] } - ], - "context": { - "type": "static", - "suffix": "provider", - "values": [ - { - "label": "Rows", - "key": "rows", - "type": "array" - }, - { - "label": "Extra Info", - "key": "info", - "type": "string" - }, - { - "label": "Rows Length", - "key": "rowsLength", - "type": "number" - }, - { - "label": "Schema", - "key": "schema", - "type": "object" - }, - { - "label": "Page Number", - "key": "pageNumber", - "type": "number" - } - ] - } + ] }, "cardsblock": { "block": true, @@ -6036,8 +6014,7 @@ }, { "type": "schema", - "suffix": "repeater", - "scope": "local" + "suffix": "repeater" } ] }, @@ -6183,10 +6160,6 @@ "type": "form", "suffix": "form" }, - { - "type": "schema", - "suffix": "repeater" - }, { "type": "static", "suffix": "form", @@ -6503,23 +6476,6 @@ "suffix": "repeater" } }, - "grid": { - "name": "Grid", - "icon": "ViewGrid", - "hasChildren": true, - "settings": [ - { - "type": "number", - "key": "cols", - "label": "Columns" - }, - { - "type": "number", - "key": "rows", - "label": "Rows" - } - ] - }, "gridblock": { "name": "Grid Block", "icon": "Table", diff --git a/packages/client/src/components/Component.svelte b/packages/client/src/components/Component.svelte index 6694022b98..63ce8dc152 100644 --- a/packages/client/src/components/Component.svelte +++ b/packages/client/src/components/Component.svelte @@ -9,7 +9,7 @@ {#if constructor && initialSettings && (visible || inSelectedPath) && !builderHidden} diff --git a/packages/client/src/components/app/DataProvider.svelte b/packages/client/src/components/app/DataProvider.svelte index 1c6dfb32b7..342194d5e2 100644 --- a/packages/client/src/components/app/DataProvider.svelte +++ b/packages/client/src/components/app/DataProvider.svelte @@ -71,7 +71,7 @@ datasource: dataSource || {}, schema, rowsLength: $fetch.rows.length, - pageNumber: $fetch.pageNumber + 1, + // Undocumented properties. These aren't supposed to be used in builder // bindings, but are used internally by other components id: $component?.id, diff --git a/packages/client/src/components/app/EmptyPlaceholder.svelte b/packages/client/src/components/app/EmptyPlaceholder.svelte index 2c3596aadf..7e9920510a 100644 --- a/packages/client/src/components/app/EmptyPlaceholder.svelte +++ b/packages/client/src/components/app/EmptyPlaceholder.svelte @@ -1,5 +1,6 @@