Dedupe and improve logic around selecting available datasources for saving and duplicating rows
This commit is contained in:
parent
bad79618c1
commit
883ac0d008
|
@ -2,27 +2,20 @@
|
||||||
import { Select, Label, Body, Checkbox, Input } from "@budibase/bbui"
|
import { Select, Label, Body, Checkbox, Input } from "@budibase/bbui"
|
||||||
import { store, currentAsset } from "builderStore"
|
import { store, currentAsset } from "builderStore"
|
||||||
import { tables, viewsV2 } from "stores/backend"
|
import { tables, viewsV2 } from "stores/backend"
|
||||||
import {
|
import { getSchemaForDatasourcePlus } from "builderStore/dataBinding"
|
||||||
getContextProviderComponents,
|
|
||||||
getSchemaForDatasourcePlus,
|
|
||||||
} from "builderStore/dataBinding"
|
|
||||||
import SaveFields from "./SaveFields.svelte"
|
import SaveFields from "./SaveFields.svelte"
|
||||||
|
import { getDatasourceLikeProviders } from "components/design/settings/controls/ButtonActionEditor/actions/utils"
|
||||||
|
|
||||||
export let parameters
|
export let parameters
|
||||||
export let bindings = []
|
export let bindings = []
|
||||||
|
export let nested
|
||||||
|
|
||||||
$: formComponents = getContextProviderComponents(
|
$: providerOptions = getDatasourceLikeProviders({
|
||||||
$currentAsset,
|
asset: $currentAsset,
|
||||||
$store.selectedComponentId,
|
componentId: $store.selectedComponentId,
|
||||||
"form"
|
nested,
|
||||||
)
|
})
|
||||||
$: schemaComponents = getContextProviderComponents(
|
$: schemaFields = getSchemaFields(parameters?.tableId)
|
||||||
$currentAsset,
|
|
||||||
$store.selectedComponentId,
|
|
||||||
"schema"
|
|
||||||
)
|
|
||||||
$: providerOptions = getProviderOptions(formComponents, schemaComponents)
|
|
||||||
$: schemaFields = getSchemaFields($currentAsset, parameters?.tableId)
|
|
||||||
$: tableOptions = $tables.list.map(table => ({
|
$: tableOptions = $tables.list.map(table => ({
|
||||||
label: table.name,
|
label: table.name,
|
||||||
resourceId: table._id,
|
resourceId: table._id,
|
||||||
|
@ -33,44 +26,8 @@
|
||||||
}))
|
}))
|
||||||
$: options = [...(tableOptions || []), ...(viewOptions || [])]
|
$: options = [...(tableOptions || []), ...(viewOptions || [])]
|
||||||
|
|
||||||
// Gets a context definition of a certain type from a component definition
|
const getSchemaFields = resourceId => {
|
||||||
const extractComponentContext = (component, contextType) => {
|
const { schema } = getSchemaForDatasourcePlus(resourceId)
|
||||||
const def = store.actions.components.getDefinition(component?._component)
|
|
||||||
if (!def) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
const contexts = Array.isArray(def.context) ? def.context : [def.context]
|
|
||||||
return contexts.find(context => context?.type === contextType)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Gets options for valid context keys which provide valid data to submit
|
|
||||||
const getProviderOptions = (formComponents, schemaComponents) => {
|
|
||||||
const formContexts = formComponents.map(component => ({
|
|
||||||
component,
|
|
||||||
context: extractComponentContext(component, "form"),
|
|
||||||
}))
|
|
||||||
const schemaContexts = schemaComponents.map(component => ({
|
|
||||||
component,
|
|
||||||
context: extractComponentContext(component, "schema"),
|
|
||||||
}))
|
|
||||||
const allContexts = formContexts.concat(schemaContexts)
|
|
||||||
|
|
||||||
return allContexts.map(({ component, context }) => {
|
|
||||||
let runtimeBinding = component._id
|
|
||||||
if (context.suffix) {
|
|
||||||
runtimeBinding += `-${context.suffix}`
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
label: component._instanceName,
|
|
||||||
value: runtimeBinding,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const getSchemaFields = (asset, tableId) => {
|
|
||||||
const { schema } = getSchemaForDatasourcePlus(tableId)
|
|
||||||
delete schema._id
|
|
||||||
delete schema._rev
|
|
||||||
return Object.values(schema || {})
|
return Object.values(schema || {})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,29 +2,19 @@
|
||||||
import { Select, Label, Body, Checkbox, Input } from "@budibase/bbui"
|
import { Select, Label, Body, Checkbox, Input } from "@budibase/bbui"
|
||||||
import { store, currentAsset } from "builderStore"
|
import { store, currentAsset } from "builderStore"
|
||||||
import { tables, viewsV2 } from "stores/backend"
|
import { tables, viewsV2 } from "stores/backend"
|
||||||
import {
|
import { getSchemaForDatasourcePlus } from "builderStore/dataBinding"
|
||||||
getContextProviderComponents,
|
|
||||||
getSchemaForDatasourcePlus,
|
|
||||||
} from "builderStore/dataBinding"
|
|
||||||
import SaveFields from "./SaveFields.svelte"
|
import SaveFields from "./SaveFields.svelte"
|
||||||
|
import { getDatasourceLikeProviders } from "components/design/settings/controls/ButtonActionEditor/actions/utils"
|
||||||
|
|
||||||
export let parameters
|
export let parameters
|
||||||
export let bindings = []
|
export let bindings = []
|
||||||
export let nested
|
export let nested
|
||||||
|
|
||||||
$: formComponents = getContextProviderComponents(
|
$: providerOptions = getDatasourceLikeProviders({
|
||||||
$currentAsset,
|
asset: $currentAsset,
|
||||||
$store.selectedComponentId,
|
componentId: $store.selectedComponentId,
|
||||||
"form",
|
nested,
|
||||||
{ includeSelf: nested }
|
})
|
||||||
)
|
|
||||||
$: schemaComponents = getContextProviderComponents(
|
|
||||||
$currentAsset,
|
|
||||||
$store.selectedComponentId,
|
|
||||||
"schema",
|
|
||||||
{ includeSelf: nested }
|
|
||||||
)
|
|
||||||
$: providerOptions = getProviderOptions(formComponents, schemaComponents)
|
|
||||||
$: schemaFields = getSchemaFields(parameters?.tableId)
|
$: schemaFields = getSchemaFields(parameters?.tableId)
|
||||||
$: tableOptions = $tables.list.map(table => ({
|
$: tableOptions = $tables.list.map(table => ({
|
||||||
label: table.name,
|
label: table.name,
|
||||||
|
@ -36,40 +26,6 @@
|
||||||
}))
|
}))
|
||||||
$: options = [...(tableOptions || []), ...(viewOptions || [])]
|
$: options = [...(tableOptions || []), ...(viewOptions || [])]
|
||||||
|
|
||||||
// Gets a context definition of a certain type from a component definition
|
|
||||||
const extractComponentContext = (component, contextType) => {
|
|
||||||
const def = store.actions.components.getDefinition(component?._component)
|
|
||||||
if (!def) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
const contexts = Array.isArray(def.context) ? def.context : [def.context]
|
|
||||||
return contexts.find(context => context?.type === contextType)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Gets options for valid context keys which provide valid data to submit
|
|
||||||
const getProviderOptions = (formComponents, schemaComponents) => {
|
|
||||||
const formContexts = formComponents.map(component => ({
|
|
||||||
component,
|
|
||||||
context: extractComponentContext(component, "form"),
|
|
||||||
}))
|
|
||||||
const schemaContexts = schemaComponents.map(component => ({
|
|
||||||
component,
|
|
||||||
context: extractComponentContext(component, "schema"),
|
|
||||||
}))
|
|
||||||
const allContexts = formContexts.concat(schemaContexts)
|
|
||||||
|
|
||||||
return allContexts.map(({ component, context }) => {
|
|
||||||
let runtimeBinding = component._id
|
|
||||||
if (context.suffix) {
|
|
||||||
runtimeBinding += `-${context.suffix}`
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
label: component._instanceName,
|
|
||||||
value: runtimeBinding,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const getSchemaFields = resourceId => {
|
const getSchemaFields = resourceId => {
|
||||||
const { schema } = getSchemaForDatasourcePlus(resourceId)
|
const { schema } = getSchemaForDatasourcePlus(resourceId)
|
||||||
return Object.values(schema || {})
|
return Object.values(schema || {})
|
||||||
|
|
|
@ -0,0 +1,79 @@
|
||||||
|
import { getContextProviderComponents } from "builderStore/dataBinding"
|
||||||
|
import { store } from "builderStore"
|
||||||
|
|
||||||
|
// Generates bindings for all components that provider "datasource like"
|
||||||
|
// contexts. This includes "form" contexts and "schema" contexts. This is used
|
||||||
|
// by various button actions as candidates for whole "row" objects.
|
||||||
|
// Some examples are saving rows or duplicating rows.
|
||||||
|
export const getDatasourceLikeProviders = ({ asset, componentId, nested }) => {
|
||||||
|
// Get all form context providers
|
||||||
|
const formComponents = getContextProviderComponents(
|
||||||
|
asset,
|
||||||
|
componentId,
|
||||||
|
"form",
|
||||||
|
{ includeSelf: nested }
|
||||||
|
)
|
||||||
|
|
||||||
|
// Get all schema context providers
|
||||||
|
const schemaComponents = getContextProviderComponents(
|
||||||
|
asset,
|
||||||
|
componentId,
|
||||||
|
"schema",
|
||||||
|
{ includeSelf: nested }
|
||||||
|
)
|
||||||
|
|
||||||
|
// Generate contexts for all form providers
|
||||||
|
const formContexts = formComponents.map(component => ({
|
||||||
|
component,
|
||||||
|
context: extractComponentContext(component, "form"),
|
||||||
|
}))
|
||||||
|
|
||||||
|
// Generate contexts for all schema providers
|
||||||
|
const schemaContexts = schemaComponents.map(component => ({
|
||||||
|
component,
|
||||||
|
context: extractComponentContext(component, "schema"),
|
||||||
|
}))
|
||||||
|
|
||||||
|
// Check for duplicate contexts by the same component. In this case, attempt
|
||||||
|
// to label contexts with their suffixes
|
||||||
|
schemaContexts.forEach(schemaContext => {
|
||||||
|
// Check if we have a form context for this component
|
||||||
|
const id = schemaContext.component._id
|
||||||
|
const existing = formContexts.find(x => x.component._id === id)
|
||||||
|
if (existing) {
|
||||||
|
if (existing.context.suffix) {
|
||||||
|
existing.readableSuffix = ` (${existing.context.suffix})`
|
||||||
|
}
|
||||||
|
if (schemaContext.context.suffix) {
|
||||||
|
schemaContext.readableSuffix = ` (${schemaContext.context.suffix})`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// Generate bindings for all contexts
|
||||||
|
const allContexts = formContexts.concat(schemaContexts)
|
||||||
|
return allContexts.map(({ component, context, readableSuffix }) => {
|
||||||
|
let readableBinding = component._instanceName
|
||||||
|
let runtimeBinding = component._id
|
||||||
|
if (context.suffix) {
|
||||||
|
runtimeBinding += `-${context.suffix}`
|
||||||
|
}
|
||||||
|
if (readableSuffix) {
|
||||||
|
readableBinding += readableSuffix
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
label: readableBinding,
|
||||||
|
value: runtimeBinding,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gets a context definition of a certain type from a component definition
|
||||||
|
const extractComponentContext = (component, contextType) => {
|
||||||
|
const def = store.actions.components.getDefinition(component?._component)
|
||||||
|
if (!def) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
const contexts = Array.isArray(def.context) ? def.context : [def.context]
|
||||||
|
return contexts.find(context => context?.type === contextType)
|
||||||
|
}
|
Loading…
Reference in New Issue