Merge branch 'master' into BUDI-9016/extract-componenterrors-from-client
This commit is contained in:
commit
a3e69b752d
|
@ -31,6 +31,11 @@
|
||||||
import IntegrationQueryEditor from "@/components/integration/index.svelte"
|
import IntegrationQueryEditor from "@/components/integration/index.svelte"
|
||||||
import { makePropSafe as safe } from "@budibase/string-templates"
|
import { makePropSafe as safe } from "@budibase/string-templates"
|
||||||
import { findAllComponents } from "@/helpers/components"
|
import { findAllComponents } from "@/helpers/components"
|
||||||
|
import {
|
||||||
|
extractFields,
|
||||||
|
extractJSONArrayFields,
|
||||||
|
extractRelationships,
|
||||||
|
} from "@/helpers/bindings"
|
||||||
import ClientBindingPanel from "@/components/common/bindings/ClientBindingPanel.svelte"
|
import ClientBindingPanel from "@/components/common/bindings/ClientBindingPanel.svelte"
|
||||||
import DataSourceCategory from "@/components/design/settings/controls/DataSourceSelect/DataSourceCategory.svelte"
|
import DataSourceCategory from "@/components/design/settings/controls/DataSourceSelect/DataSourceCategory.svelte"
|
||||||
import { API } from "@/api"
|
import { API } from "@/api"
|
||||||
|
@ -81,67 +86,9 @@
|
||||||
value: `{{ literal ${safe(provider._id)} }}`,
|
value: `{{ literal ${safe(provider._id)} }}`,
|
||||||
type: "provider",
|
type: "provider",
|
||||||
}))
|
}))
|
||||||
$: links = bindings
|
$: links = extractRelationships(bindings)
|
||||||
// Get only link bindings
|
$: fields = extractFields(bindings)
|
||||||
.filter(x => x.fieldSchema?.type === "link")
|
$: jsonArrays = extractJSONArrayFields(bindings)
|
||||||
// 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} }}`,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
$: jsonArrays = bindings
|
|
||||||
.filter(
|
|
||||||
x =>
|
|
||||||
x.fieldSchema?.type === "jsonarray" ||
|
|
||||||
(x.fieldSchema?.type === "json" && x.fieldSchema?.subtype === "array")
|
|
||||||
)
|
|
||||||
.map(binding => {
|
|
||||||
const { providerId, readableBinding, runtimeBinding, tableId } = binding
|
|
||||||
const { name, type, prefixKeys, subtype } = binding.fieldSchema
|
|
||||||
return {
|
|
||||||
providerId,
|
|
||||||
label: readableBinding,
|
|
||||||
fieldName: name,
|
|
||||||
fieldType: type,
|
|
||||||
tableId,
|
|
||||||
prefixKeys,
|
|
||||||
type: type === "jsonarray" ? "jsonarray" : "queryarray",
|
|
||||||
subtype,
|
|
||||||
value: `{{ literal ${runtimeBinding} }}`,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
$: custom = {
|
$: custom = {
|
||||||
type: "custom",
|
type: "custom",
|
||||||
label: "JSON / CSV",
|
label: "JSON / CSV",
|
||||||
|
|
|
@ -0,0 +1,74 @@
|
||||||
|
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} }}`,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function extractJSONArrayFields(bindings: UIBinding[]) {
|
||||||
|
return bindings
|
||||||
|
.filter(
|
||||||
|
x =>
|
||||||
|
x.fieldSchema?.type === "jsonarray" ||
|
||||||
|
(x.fieldSchema?.type === "json" && x.fieldSchema?.subtype === "array")
|
||||||
|
)
|
||||||
|
.map(binding => {
|
||||||
|
const { providerId, readableBinding, runtimeBinding, tableId } = binding
|
||||||
|
const { name, type, prefixKeys, subtype } = binding.fieldSchema!
|
||||||
|
return {
|
||||||
|
providerId,
|
||||||
|
label: readableBinding,
|
||||||
|
fieldName: name,
|
||||||
|
fieldType: type,
|
||||||
|
tableId,
|
||||||
|
prefixKeys,
|
||||||
|
type: type === "jsonarray" ? "jsonarray" : "queryarray",
|
||||||
|
subtype,
|
||||||
|
value: `{{ literal ${runtimeBinding} }}`,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
|
@ -10,3 +10,4 @@ export {
|
||||||
isBuilderInputFocused,
|
isBuilderInputFocused,
|
||||||
} from "./helpers"
|
} from "./helpers"
|
||||||
export * as featureFlag from "./featureFlags"
|
export * as featureFlag from "./featureFlags"
|
||||||
|
export * as bindings from "./bindings"
|
||||||
|
|
|
@ -14,13 +14,14 @@ import {
|
||||||
} from "@budibase/types"
|
} from "@budibase/types"
|
||||||
import { queries } from "./queries"
|
import { queries } from "./queries"
|
||||||
import { views } from "./views"
|
import { views } from "./views"
|
||||||
import { featureFlag } from "@/helpers"
|
|
||||||
import { findAllComponents } from "@/helpers/components"
|
import { findAllComponents } from "@/helpers/components"
|
||||||
|
import { bindings, featureFlag } from "@/helpers"
|
||||||
|
import { getBindableProperties } from "@/dataBinding"
|
||||||
|
|
||||||
function reduceBy<TItem extends {}, TKey extends keyof TItem>(
|
function reduceBy<TItem extends {}, TKey extends keyof TItem>(
|
||||||
key: TKey,
|
key: TKey,
|
||||||
list: TItem[]
|
list: TItem[]
|
||||||
) {
|
): Record<string, any> {
|
||||||
return list.reduce(
|
return list.reduce(
|
||||||
(result, item) => ({
|
(result, item) => ({
|
||||||
...result,
|
...result,
|
||||||
|
@ -40,6 +41,9 @@ const validationKeyByType: Record<UIDatasourceType, string | null> = {
|
||||||
viewV2: "id",
|
viewV2: "id",
|
||||||
query: "_id",
|
query: "_id",
|
||||||
custom: null,
|
custom: null,
|
||||||
|
link: "rowId",
|
||||||
|
field: "value",
|
||||||
|
jsonarray: "value",
|
||||||
}
|
}
|
||||||
|
|
||||||
export const screenComponentErrors = derived(
|
export const screenComponentErrors = derived(
|
||||||
|
@ -77,10 +81,6 @@ function getInvalidDatasources(
|
||||||
"dataSource",
|
"dataSource",
|
||||||
])) {
|
])) {
|
||||||
const componentSettings = component[setting.key]
|
const componentSettings = component[setting.key]
|
||||||
if (!componentSettings) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
const { label } = componentSettings
|
const { label } = componentSettings
|
||||||
const type = componentSettings.type as UIDatasourceType
|
const type = componentSettings.type as UIDatasourceType
|
||||||
|
|
||||||
|
@ -88,8 +88,17 @@ function getInvalidDatasources(
|
||||||
if (!validationKey) {
|
if (!validationKey) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const componentBindings = getBindableProperties(screen, component._id)
|
||||||
|
|
||||||
|
const componentDatasources = {
|
||||||
|
...reduceBy("rowId", bindings.extractRelationships(componentBindings)),
|
||||||
|
...reduceBy("value", bindings.extractFields(componentBindings)),
|
||||||
|
...reduceBy("value", bindings.extractJSONArrayFields(componentBindings)),
|
||||||
|
}
|
||||||
|
|
||||||
const resourceId = componentSettings[validationKey]
|
const resourceId = componentSettings[validationKey]
|
||||||
if (!datasources[resourceId]) {
|
if (!{ ...datasources, ...componentDatasources }[resourceId]) {
|
||||||
const friendlyTypeName = friendlyNameByType[type] ?? type
|
const friendlyTypeName = friendlyNameByType[type] ?? type
|
||||||
result[component._id!] = [
|
result[component._id!] = [
|
||||||
{
|
{
|
||||||
|
|
|
@ -24,3 +24,18 @@ export type InsertAtPositionFn = (_: {
|
||||||
value: string
|
value: string
|
||||||
cursor?: { anchor: number }
|
cursor?: { anchor: number }
|
||||||
}) => void
|
}) => void
|
||||||
|
|
||||||
|
export interface UIBinding {
|
||||||
|
tableId?: string
|
||||||
|
fieldSchema?: {
|
||||||
|
name: string
|
||||||
|
tableId: string
|
||||||
|
type: string
|
||||||
|
subtype?: string
|
||||||
|
prefixKeys?: string
|
||||||
|
}
|
||||||
|
component?: string
|
||||||
|
providerId: string
|
||||||
|
readableBinding?: string
|
||||||
|
runtimeBinding?: string
|
||||||
|
}
|
||||||
|
|
|
@ -1 +1,9 @@
|
||||||
export type UIDatasourceType = "table" | "view" | "viewV2" | "query" | "custom"
|
export type UIDatasourceType =
|
||||||
|
| "table"
|
||||||
|
| "view"
|
||||||
|
| "viewV2"
|
||||||
|
| "query"
|
||||||
|
| "custom"
|
||||||
|
| "link"
|
||||||
|
| "field"
|
||||||
|
| "jsonarray"
|
||||||
|
|
Loading…
Reference in New Issue