From b8d38159d09659b4b7d04077385e1cbb4832b1ce Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Fri, 24 Jan 2025 14:48:27 +0100 Subject: [PATCH] Extract binding utils --- .../DataSourceSelect/DataSourceSelect.svelte | 43 ++-------------- packages/builder/src/helpers/bindings.ts | 50 +++++++++++++++++++ packages/builder/src/helpers/index.ts | 1 + packages/types/src/ui/bindings/binding.ts | 13 +++++ 4 files changed, 67 insertions(+), 40 deletions(-) create mode 100644 packages/builder/src/helpers/bindings.ts diff --git a/packages/builder/src/components/design/settings/controls/DataSourceSelect/DataSourceSelect.svelte b/packages/builder/src/components/design/settings/controls/DataSourceSelect/DataSourceSelect.svelte index 1b9fdcdf10..6ccde7fede 100644 --- a/packages/builder/src/components/design/settings/controls/DataSourceSelect/DataSourceSelect.svelte +++ b/packages/builder/src/components/design/settings/controls/DataSourceSelect/DataSourceSelect.svelte @@ -31,6 +31,7 @@ import IntegrationQueryEditor from "@/components/integration/index.svelte" import { makePropSafe as safe } from "@budibase/string-templates" import { findAllComponents } from "@/helpers/components" + import { extractFields, extractRelationships } from "@/helpers/bindings" import ClientBindingPanel from "@/components/common/bindings/ClientBindingPanel.svelte" import DataSourceCategory from "@/components/design/settings/controls/DataSourceSelect/DataSourceCategory.svelte" import { API } from "@/api" @@ -81,46 +82,8 @@ value: `{{ literal ${safe(provider._id)} }}`, type: "provider", })) - $: links = bindings - // Get only link bindings - .filter(x => x.fieldSchema?.type === "link") - // Filter out bindings provided by forms - .filter(x => !x.component?.endsWith("/form")) - .map(binding => { - const { providerId, readableBinding, fieldSchema } = binding || {} - const { name, tableId } = fieldSchema || {} - const safeProviderId = safe(providerId) - return { - providerId, - label: readableBinding, - fieldName: name, - tableId, - type: "link", - // These properties will be enriched by the client library and provide - // details of the parent row of the relationship field, from context - rowId: `{{ ${safeProviderId}.${safe("_id")} }}`, - rowTableId: `{{ ${safeProviderId}.${safe("tableId")} }}`, - } - }) - $: fields = bindings - .filter( - x => - x.fieldSchema?.type === "attachment" || - (x.fieldSchema?.type === "array" && x.tableId) - ) - .map(binding => { - const { providerId, readableBinding, runtimeBinding } = binding - const { name, type, tableId } = binding.fieldSchema - return { - providerId, - label: readableBinding, - fieldName: name, - fieldType: type, - tableId, - type: "field", - value: `{{ literal ${runtimeBinding} }}`, - } - }) + $: links = extractRelationships(bindings) + $: fields = extractFields(bindings) $: jsonArrays = bindings .filter( x => diff --git a/packages/builder/src/helpers/bindings.ts b/packages/builder/src/helpers/bindings.ts new file mode 100644 index 0000000000..2d1410c76a --- /dev/null +++ b/packages/builder/src/helpers/bindings.ts @@ -0,0 +1,50 @@ +import { makePropSafe } from "@budibase/string-templates" +import { UIBinding } from "@budibase/types" + +export function extractRelationships(bindings: UIBinding[]) { + return ( + bindings + // Get only link bindings + .filter(x => x.fieldSchema?.type === "link") + // Filter out bindings provided by forms + .filter(x => !x.component?.endsWith("/form")) + .map(binding => { + const { providerId, readableBinding, fieldSchema } = binding || {} + const { name, tableId } = fieldSchema || {} + const safeProviderId = makePropSafe(providerId) + return { + providerId, + label: readableBinding, + fieldName: name, + tableId, + type: "link", + // These properties will be enriched by the client library and provide + // details of the parent row of the relationship field, from context + rowId: `{{ ${safeProviderId}.${makePropSafe("_id")} }}`, + rowTableId: `{{ ${safeProviderId}.${makePropSafe("tableId")} }}`, + } + }) + ) +} + +export function extractFields(bindings: UIBinding[]) { + return bindings + .filter( + x => + x.fieldSchema?.type === "attachment" || + (x.fieldSchema?.type === "array" && x.tableId) + ) + .map(binding => { + const { providerId, readableBinding, runtimeBinding } = binding + const { name, type, tableId } = binding.fieldSchema! + return { + providerId, + label: readableBinding, + fieldName: name, + fieldType: type, + tableId, + type: "field", + value: `{{ literal ${runtimeBinding} }}`, + } + }) +} diff --git a/packages/builder/src/helpers/index.ts b/packages/builder/src/helpers/index.ts index 81afc696a3..0e61eeb9c6 100644 --- a/packages/builder/src/helpers/index.ts +++ b/packages/builder/src/helpers/index.ts @@ -10,3 +10,4 @@ export { isBuilderInputFocused, } from "./helpers" export * as featureFlag from "./featureFlags" +export * as bindings from "./bindings" diff --git a/packages/types/src/ui/bindings/binding.ts b/packages/types/src/ui/bindings/binding.ts index 2cfb23ed2d..10e6968409 100644 --- a/packages/types/src/ui/bindings/binding.ts +++ b/packages/types/src/ui/bindings/binding.ts @@ -24,3 +24,16 @@ export type InsertAtPositionFn = (_: { value: string cursor?: { anchor: number } }) => void + +export interface UIBinding { + tableId?: string + fieldSchema?: { + name: string + tableId: string + type: string + } + component?: string + providerId: string + readableBinding?: string + runtimeBinding?: string +}