Merge pull request #2830 from Budibase/fix/2796

Fix for formula fields in enrich call
This commit is contained in:
Michael Drury 2021-10-01 11:10:14 +01:00 committed by GitHub
commit e4c6b61346
3 changed files with 70 additions and 784 deletions

View File

@ -1,12 +1,12 @@
import { cloneDeep } from "lodash/fp"
import { get } from "svelte/store"
import {
findAllMatchingComponents,
findComponent,
findComponentPath,
findAllMatchingComponents,
} from "./storeUtils"
import { store } from "builderStore"
import { tables as tablesStore, queries as queriesStores } from "stores/backend"
import { queries as queriesStores, tables as tablesStore } from "stores/backend"
import { makePropSafe } from "@budibase/string-templates"
import { TableNames } from "../constants"
@ -422,6 +422,10 @@ function shouldReplaceBinding(currentValue, from, convertTo) {
return !invalids.find(invalid => noSpaces?.includes(invalid))
}
function replaceBetween(string, start, end, replacement) {
return string.substring(0, start) + replacement + string.substring(end)
}
/**
* utility function for the readableToRuntimeBinding and runtimeToReadableBinding.
*/
@ -431,6 +435,7 @@ function bindingReplacement(bindableProperties, textWithBindings, convertTo) {
if (typeof textWithBindings !== "string") {
return textWithBindings
}
// work from longest to shortest
const convertFromProps = bindableProperties
.map(el => el[convertFrom])
.sort((a, b) => {
@ -440,12 +445,29 @@ function bindingReplacement(bindableProperties, textWithBindings, convertTo) {
let result = textWithBindings
for (let boundValue of boundValues) {
let newBoundValue = boundValue
// we use a search string, where any time we replace something we blank it out
// in the search, working from longest to shortest so always use best match first
let searchString = newBoundValue
for (let from of convertFromProps) {
if (shouldReplaceBinding(newBoundValue, from, convertTo)) {
const binding = bindableProperties.find(el => el[convertFrom] === from)
while (newBoundValue.includes(from)) {
newBoundValue = newBoundValue.replace(from, binding[convertTo])
}
let idx
do {
// see if any instances of this binding exist in the search string
idx = searchString.indexOf(from)
if (idx !== -1) {
let end = idx + from.length,
searchReplace = Array(binding[convertTo].length).join("*")
// blank out parts of the search string
searchString = replaceBetween(searchString, idx, end, searchReplace)
newBoundValue = replaceBetween(
newBoundValue,
idx,
end,
binding[convertTo]
)
}
} while (idx !== -1)
}
}
result = result.replace(boundValue, newBoundValue)

View File

@ -403,16 +403,32 @@ exports.fetchEnrichedRow = async ctx => {
rowId,
})
// look up the actual rows based on the ids
const response = await db.allDocs({
include_docs: true,
keys: linkVals.map(linkVal => linkVal.id),
})
// need to include the IDs in these rows for any links they may have
let linkedRows = await outputProcessing(
ctx,
table,
response.rows.map(row => row.doc)
)
let response = (
await db.allDocs({
include_docs: true,
keys: linkVals.map(linkVal => linkVal.id),
})
).rows.map(row => row.doc)
// group responses by table
let groups = {},
tables = {}
for (let row of response) {
const linkedTableId = row.tableId
if (groups[linkedTableId] == null) {
groups[linkedTableId] = [row]
tables[linkedTableId] = await db.get(linkedTableId)
} else {
groups[linkedTableId].push(row)
}
}
let linkedRows = []
for (let [tableId, rows] of Object.entries(groups)) {
// need to include the IDs in these rows for any links they may have
linkedRows = linkedRows.concat(
await outputProcessing(ctx, tables[tableId], rows)
)
}
// insert the link rows in the correct place throughout the main row
for (let fieldName of Object.keys(table.schema)) {
let field = table.schema[fieldName]

File diff suppressed because it is too large Load Diff