From 32ad21de4f37704440d03f3e8b812872cd39d0c9 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Tue, 29 Oct 2024 11:38:00 +0000 Subject: [PATCH 1/3] Fix forms always requesting table schema and cache view definitions --- .../src/components/app/forms/Form.svelte | 17 ++++---- .../src/components/app/forms/InnerForm.svelte | 6 +-- .../src/components/app/forms/validation.js | 8 ++-- packages/client/src/utils/schema.js | 39 ++++++++++++++----- packages/frontend-core/src/api/viewsV2.js | 1 + 5 files changed, 45 insertions(+), 26 deletions(-) diff --git a/packages/client/src/components/app/forms/Form.svelte b/packages/client/src/components/app/forms/Form.svelte index fe02dc665db..88333f75656 100644 --- a/packages/client/src/components/app/forms/Form.svelte +++ b/packages/client/src/components/app/forms/Form.svelte @@ -3,6 +3,7 @@ import InnerForm from "./InnerForm.svelte" import { Helpers } from "@budibase/bbui" import { writable } from "svelte/store" + import { fetchDatasourceDefinition } from "utils/schema" export let dataSource export let theme @@ -32,9 +33,9 @@ return parsedFormStep } - let loaded = false + let definition let schema - let table + let loaded = false let currentStep = getContext("current-step") || writable(getInitialFormStep()) $: fetchSchema(dataSource) @@ -84,12 +85,10 @@ // Fetches the form schema from this form's dataSource const fetchSchema = async dataSource => { - if (dataSource?.tableId && !dataSource?.type?.startsWith("query")) { - try { - table = await API.fetchTableDefinition(dataSource.tableId) - } catch (error) { - table = null - } + try { + definition = await fetchDatasourceDefinition(dataSource) + } catch (error) { + definition = null } const res = await fetchDatasourceSchema(dataSource) schema = res || {} @@ -121,7 +120,7 @@ {readonly} {actionType} {schema} - {table} + {definition} {initialValues} {disableSchemaValidation} {editAutoColumns} diff --git a/packages/client/src/components/app/forms/InnerForm.svelte b/packages/client/src/components/app/forms/InnerForm.svelte index bb2f51fc955..91a444aa6a6 100644 --- a/packages/client/src/components/app/forms/InnerForm.svelte +++ b/packages/client/src/components/app/forms/InnerForm.svelte @@ -10,7 +10,7 @@ export let initialValues export let size export let schema - export let table + export let definition export let disableSchemaValidation = false export let editAutoColumns = false @@ -164,7 +164,7 @@ schemaConstraints, validationRules, field, - table + definition ) // Sanitise the default value to ensure it doesn't contain invalid data @@ -338,7 +338,7 @@ schemaConstraints, validationRules, field, - table + definition ) // Update validator diff --git a/packages/client/src/components/app/forms/validation.js b/packages/client/src/components/app/forms/validation.js index 46a5330cf3f..ad3e5ae6897 100644 --- a/packages/client/src/components/app/forms/validation.js +++ b/packages/client/src/components/app/forms/validation.js @@ -5,17 +5,17 @@ import { Helpers } from "@budibase/bbui" /** * Creates a validation function from a combination of schema-level constraints * and custom validation rules - * @param schemaConstraints any schema level constraints from the table + * @param schemaConstraints any schema level constraints from the datasource * @param customRules any custom validation rules * @param field the field name we are evaluating - * @param table the definition of the table we are evaluating + * @param definition the definition of the datasource we are evaluating * @returns {function} a validator function which accepts test values */ export const createValidatorFromConstraints = ( schemaConstraints, customRules, field, - table + definition ) => { let rules = [] @@ -23,7 +23,7 @@ export const createValidatorFromConstraints = ( if (schemaConstraints) { // Required constraint if ( - field === table?.primaryDisplay || + field === definition?.primaryDisplay || schemaConstraints.presence?.allowEmpty === false || schemaConstraints.presence === true ) { diff --git a/packages/client/src/utils/schema.js b/packages/client/src/utils/schema.js index e2399e87383..ec1cef53cee 100644 --- a/packages/client/src/utils/schema.js +++ b/packages/client/src/utils/schema.js @@ -10,16 +10,13 @@ import ViewV2Fetch from "@budibase/frontend-core/src/fetch/ViewV2Fetch.js" import QueryArrayFetch from "@budibase/frontend-core/src/fetch/QueryArrayFetch" /** - * Fetches the schema of any kind of datasource. + * Constructs a fetch instance for a given datasource. * All datasource fetch classes implement their own functionality to get the * schema of a datasource of their respective types. - * @param datasource the datasource to fetch the schema for - * @param options options for enriching the schema + * @param datasource the datasource + * @returns */ -export const fetchDatasourceSchema = async ( - datasource, - options = { enrichRelationships: false, formSchema: false } -) => { +const getDatasourceFetchInstance = datasource => { const handler = { table: TableFetch, view: ViewFetch, @@ -34,10 +31,23 @@ export const fetchDatasourceSchema = async ( if (!handler) { return null } - const instance = new handler({ API }) + return new handler({ API }) +} - // Get the datasource definition and then schema - const definition = await instance.getDefinition(datasource) +/** + * Fetches the schema of any kind of datasource. + * @param datasource the datasource to fetch the schema for + * @param options options for enriching the schema + */ +export const fetchDatasourceSchema = async ( + datasource, + options = { enrichRelationships: false, formSchema: false } +) => { + const instance = getDatasourceFetchInstance(datasource) + const definition = await instance?.getDefinition(datasource) + if (!definition) { + return null + } // Get the normal schema as long as we aren't wanting a form schema let schema @@ -75,6 +85,15 @@ export const fetchDatasourceSchema = async ( return instance.enrichSchema(schema) } +/** + * Fetches the definition of any kind of datasource. + * @param datasource the datasource to fetch the schema for + */ +export const fetchDatasourceDefinition = async datasource => { + const instance = getDatasourceFetchInstance(datasource) + return await instance?.getDefinition(datasource) +} + /** * Fetches the schema of relationship fields for a SQL table schema * @param schema the schema to enrich diff --git a/packages/frontend-core/src/api/viewsV2.js b/packages/frontend-core/src/api/viewsV2.js index a2072c2e1da..d1cb07c6b09 100644 --- a/packages/frontend-core/src/api/viewsV2.js +++ b/packages/frontend-core/src/api/viewsV2.js @@ -6,6 +6,7 @@ export const buildViewV2Endpoints = API => ({ fetchDefinition: async viewId => { return await API.get({ url: `/api/v2/views/${encodeURIComponent(viewId)}`, + cache: true, }) }, /** From 7cce68f126b4405a7f5276443d4f54e0f00558b3 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Tue, 29 Oct 2024 11:44:03 +0000 Subject: [PATCH 2/3] Provide fetchDatasourceDefinition via SDK --- packages/client/src/components/app/forms/Form.svelte | 4 ++-- packages/client/src/sdk.js | 6 +++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/client/src/components/app/forms/Form.svelte b/packages/client/src/components/app/forms/Form.svelte index 88333f75656..2071e85fccf 100644 --- a/packages/client/src/components/app/forms/Form.svelte +++ b/packages/client/src/components/app/forms/Form.svelte @@ -3,7 +3,6 @@ import InnerForm from "./InnerForm.svelte" import { Helpers } from "@budibase/bbui" import { writable } from "svelte/store" - import { fetchDatasourceDefinition } from "utils/schema" export let dataSource export let theme @@ -23,7 +22,8 @@ const context = getContext("context") const component = getContext("component") - const { API, fetchDatasourceSchema } = getContext("sdk") + const { API, fetchDatasourceSchema, detchDatasourceDefinition } = + getContext("sdk") const getInitialFormStep = () => { const parsedFormStep = parseInt(initialFormStep) diff --git a/packages/client/src/sdk.js b/packages/client/src/sdk.js index 50d3f857d5c..bd51924bf49 100644 --- a/packages/client/src/sdk.js +++ b/packages/client/src/sdk.js @@ -26,7 +26,10 @@ import Provider from "components/context/Provider.svelte" import Block from "components/Block.svelte" import BlockComponent from "components/BlockComponent.svelte" import { ActionTypes } from "./constants" -import { fetchDatasourceSchema } from "./utils/schema.js" +import { + fetchDatasourceSchema, + fetchDatasourceDefinition, +} from "./utils/schema.js" import { getAPIKey } from "./utils/api.js" import { enrichButtonActions } from "./utils/buttonActions.js" import { processStringSync, makePropSafe } from "@budibase/string-templates" @@ -66,6 +69,7 @@ export default { linkable, getAction, fetchDatasourceSchema, + fetchDatasourceDefinition, fetchData, QueryUtils, ContextScopes: Constants.ContextScopes, From fc3fcb5cbdc6c55bc64b744b42c28476925b528b Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Tue, 29 Oct 2024 11:48:16 +0000 Subject: [PATCH 3/3] Lint --- packages/client/src/components/app/forms/Form.svelte | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/client/src/components/app/forms/Form.svelte b/packages/client/src/components/app/forms/Form.svelte index 2071e85fccf..f470297d782 100644 --- a/packages/client/src/components/app/forms/Form.svelte +++ b/packages/client/src/components/app/forms/Form.svelte @@ -22,8 +22,7 @@ const context = getContext("context") const component = getContext("component") - const { API, fetchDatasourceSchema, detchDatasourceDefinition } = - getContext("sdk") + const { fetchDatasourceSchema, fetchDatasourceDefinition } = getContext("sdk") const getInitialFormStep = () => { const parsedFormStep = parseInt(initialFormStep)