From a22fd8a0a1b0ba0d15e7a8ef78489c4a9720aff5 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Tue, 1 Jun 2021 14:59:42 +0100 Subject: [PATCH] Improve client performance and add action to control data provider queries --- .../design/AppPreview/componentStructure.json | 3 +- .../client/src/components/Component.svelte | 4 +- packages/client/src/constants.js | 1 + packages/client/src/utils/componentProps.js | 4 +- .../client/src/utils/enrichDataBinding.js | 6 +- packages/standard-components/manifest.json | 18 ++ packages/standard-components/package.json | 1 + .../src/DataProvider.svelte | 25 +- .../src/DateRangePicker.svelte | 81 ++++++ packages/standard-components/src/index.js | 1 + packages/standard-components/src/lucene.js | 14 +- packages/standard-components/yarn.lock | 255 ++++++++++++++++++ packages/string-templates/src/index.cjs | 4 +- 13 files changed, 400 insertions(+), 17 deletions(-) create mode 100644 packages/standard-components/src/DateRangePicker.svelte diff --git a/packages/builder/src/components/design/AppPreview/componentStructure.json b/packages/builder/src/components/design/AppPreview/componentStructure.json index 5bd2e01d25..53b6699fb4 100644 --- a/packages/builder/src/components/design/AppPreview/componentStructure.json +++ b/packages/builder/src/components/design/AppPreview/componentStructure.json @@ -18,7 +18,8 @@ "longformfield", "datetimefield", "attachmentfield", - "relationshipfield" + "relationshipfield", + "daterangepicker" ] }, { diff --git a/packages/client/src/components/Component.svelte b/packages/client/src/components/Component.svelte index b32222ce2f..4d2dddffcc 100644 --- a/packages/client/src/components/Component.svelte +++ b/packages/client/src/components/Component.svelte @@ -55,13 +55,13 @@ } // Enriches any string component props using handlebars - const updateComponentProps = async (definition, context) => { + const updateComponentProps = (definition, context) => { // Record the timestamp so we can reference it after enrichment latestUpdateTime = Date.now() const enrichmentTime = latestUpdateTime // Enrich props with context - const enrichedProps = await enrichProps(definition, context) + const enrichedProps = enrichProps(definition, context) // Abandon this update if a newer update has started if (enrichmentTime !== latestUpdateTime) { diff --git a/packages/client/src/constants.js b/packages/client/src/constants.js index 3aa302bec9..31ac4b285e 100644 --- a/packages/client/src/constants.js +++ b/packages/client/src/constants.js @@ -5,4 +5,5 @@ export const TableNames = { export const ActionTypes = { ValidateForm: "ValidateForm", RefreshDatasource: "RefreshDatasource", + SetDataProviderQuery: "SetDataProviderQuery", } diff --git a/packages/client/src/utils/componentProps.js b/packages/client/src/utils/componentProps.js index 559fc54486..14516fdb4c 100644 --- a/packages/client/src/utils/componentProps.js +++ b/packages/client/src/utils/componentProps.js @@ -21,7 +21,7 @@ export const propsAreSame = (a, b) => { * Enriches component props. * Data bindings are enriched, and button actions are enriched. */ -export const enrichProps = async (props, context) => { +export const enrichProps = (props, context) => { // Exclude all private props that start with an underscore let validProps = {} Object.entries(props) @@ -41,7 +41,7 @@ export const enrichProps = async (props, context) => { } // Enrich all data bindings in top level props - let enrichedProps = await enrichDataBindings(validProps, totalContext) + let enrichedProps = enrichDataBindings(validProps, totalContext) // Enrich click actions if they exist if (enrichedProps.onClick) { diff --git a/packages/client/src/utils/enrichDataBinding.js b/packages/client/src/utils/enrichDataBinding.js index b8c5020c74..34bfb78539 100644 --- a/packages/client/src/utils/enrichDataBinding.js +++ b/packages/client/src/utils/enrichDataBinding.js @@ -1,5 +1,5 @@ import { cloneDeep } from "lodash/fp" -import { processString, processObject } from "@budibase/string-templates" +import { processString, processObjectSync } from "@budibase/string-templates" // Regex to test inputs with to see if they are likely candidates for template strings const looksLikeTemplate = /{{.*}}/ @@ -23,6 +23,6 @@ export const enrichDataBinding = async (input, context) => { * Recursively enriches all props in a props object and returns the new props. * Props are deeply cloned so that no mutation is done to the source object. */ -export const enrichDataBindings = async (props, context) => { - return await processObject(cloneDeep(props), context) +export const enrichDataBindings = (props, context) => { + return processObjectSync(cloneDeep(props), context) } diff --git a/packages/standard-components/manifest.json b/packages/standard-components/manifest.json index 9f67af6489..71a64cb2b1 100644 --- a/packages/standard-components/manifest.json +++ b/packages/standard-components/manifest.json @@ -1505,5 +1505,23 @@ "context": { "type": "schema" } + }, + "daterangepicker": { + "name": "Date Range", + "icon": "Date", + "styleable": true, + "hasChildren": false, + "settings": [ + { + "type": "dataProvider", + "label": "Provider", + "key": "dataProvider" + }, + { + "type": "field", + "label": "Date field", + "key": "field" + } + ] } } diff --git a/packages/standard-components/package.json b/packages/standard-components/package.json index 610535d5b2..ba05de829f 100644 --- a/packages/standard-components/package.json +++ b/packages/standard-components/package.json @@ -37,6 +37,7 @@ "@spectrum-css/page": "^3.0.1", "@spectrum-css/vars": "^3.0.1", "apexcharts": "^3.22.1", + "dayjs": "^1.10.5", "svelte-apexcharts": "^1.0.2", "svelte-flatpickr": "^3.1.0" } diff --git a/packages/standard-components/src/DataProvider.svelte b/packages/standard-components/src/DataProvider.svelte index ece8dfad81..cb1ae1c12c 100644 --- a/packages/standard-components/src/DataProvider.svelte +++ b/packages/standard-components/src/DataProvider.svelte @@ -17,6 +17,10 @@ const { API, styleable, Provider, ActionTypes } = getContext("sdk") const component = getContext("component") + const dataProviderApi = { + setLuceneQuery: newQuery => (query = newQuery), + foo: "bar", + } // Loading flag every time data is being fetched let loading = false @@ -31,9 +35,11 @@ let schema = {} let bookmarks = [null] let pageNumber = 0 + let query = null - $: internalTable = dataSource?.type === "table" $: query = buildLuceneQuery(filter) + $: internalTable = dataSource?.type === "table" + $: nestedProvider = dataSource?.type === "provider" $: hasNextPage = bookmarks[pageNumber + 1] != null $: hasPrevPage = pageNumber > 0 $: getSchema(dataSource) @@ -71,8 +77,21 @@ callback: () => refresh(), metadata: { dataSource }, }, + { + type: ActionTypes.SetDataProviderQuery, + callback: newQuery => (query = newQuery), + }, ] - $: dataContext = { rows, schema, rowsLength: rows.length } + $: dataContext = { + rows, + schema, + rowsLength: rows.length, + + // Undocumented properties. These aren't supposed to be used in builder + // bindings, but are used internally by other components + id: $component?.id, + state: { query }, + } const getSortType = (schema, sortColumn) => { if (!schema || !sortColumn || !schema[sortColumn]) { @@ -83,7 +102,7 @@ } const refresh = async () => { - if (schemaLoaded) { + if (schemaLoaded && !nestedProvider) { fetchData( dataSource, query, diff --git a/packages/standard-components/src/DateRangePicker.svelte b/packages/standard-components/src/DateRangePicker.svelte new file mode 100644 index 0000000000..ef5b4d1029 --- /dev/null +++ b/packages/standard-components/src/DateRangePicker.svelte @@ -0,0 +1,81 @@ + + +
+