Small update to make sure that save/patch calls to the rows API (all DS+) return the squashed relationships, not the whole structure.

This commit is contained in:
Michael Drury 2023-06-01 18:18:12 +01:00
parent d8d3d71523
commit adbdaf394a
5 changed files with 54 additions and 23 deletions

View File

@ -1,7 +1,7 @@
import { import {
SortDirection,
FieldTypes, FieldTypes,
NoEmptyFilterStrings, NoEmptyFilterStrings,
SortDirection,
} from "../../../constants" } from "../../../constants"
import { import {
breakExternalTableId, breakExternalTableId,
@ -11,20 +11,34 @@ import { ExternalRequest, RunConfig } from "./ExternalRequest"
import * as exporters from "../view/exporters" import * as exporters from "../view/exporters"
import { apiFileReturn } from "../../../utilities/fileSystem" import { apiFileReturn } from "../../../utilities/fileSystem"
import { import {
Operation,
UserCtx,
Row,
PaginationJson,
Table,
Datasource, Datasource,
IncludeRelationship, IncludeRelationship,
Operation,
PaginationJson,
Row,
SortJson, SortJson,
Table,
UserCtx,
} from "@budibase/types" } from "@budibase/types"
import sdk from "../../../sdk" import sdk from "../../../sdk"
import * as utils from "./utils" import * as utils from "./utils"
const { cleanExportRows } = require("./utils") const { cleanExportRows } = require("./utils")
async function getRow(
tableId: string,
rowId: string,
opts?: { relationships?: boolean }
) {
const response = (await handleRequest(Operation.READ, tableId, {
id: breakRowIdField(rowId),
includeSqlRelationships: opts?.relationships
? IncludeRelationship.INCLUDE
: IncludeRelationship.EXCLUDE,
})) as Row[]
return response ? response[0] : response
}
export async function handleRequest( export async function handleRequest(
operation: Operation, operation: Operation,
tableId: string, tableId: string,
@ -63,11 +77,15 @@ export async function patch(ctx: UserCtx) {
if (!validateResult.valid) { if (!validateResult.valid) {
throw { validation: validateResult.errors } throw { validation: validateResult.errors }
} }
return handleRequest(Operation.UPDATE, tableId, { const response = await handleRequest(Operation.UPDATE, tableId, {
id: breakRowIdField(id), id: breakRowIdField(id),
row: inputs, row: inputs,
includeSqlRelationships: IncludeRelationship.INCLUDE,
}) })
const row = await getRow(tableId, id, { relationships: true })
return {
...response,
row,
}
} }
export async function save(ctx: UserCtx) { export async function save(ctx: UserCtx) {
@ -80,10 +98,20 @@ export async function save(ctx: UserCtx) {
if (!validateResult.valid) { if (!validateResult.valid) {
throw { validation: validateResult.errors } throw { validation: validateResult.errors }
} }
return handleRequest(Operation.CREATE, tableId, { const response = await handleRequest(Operation.CREATE, tableId, {
row: inputs, row: inputs,
includeSqlRelationships: IncludeRelationship.EXCLUDE,
}) })
const responseRow = response as { row: Row }
const rowId = responseRow.row._id
if (rowId) {
const row = await getRow(tableId, rowId, { relationships: true })
return {
...response,
row,
}
} else {
return response
}
} }
export async function fetchView(ctx: UserCtx) { export async function fetchView(ctx: UserCtx) {
@ -104,11 +132,7 @@ export async function fetch(ctx: UserCtx) {
export async function find(ctx: UserCtx) { export async function find(ctx: UserCtx) {
const id = ctx.params.rowId const id = ctx.params.rowId
const tableId = ctx.params.tableId const tableId = ctx.params.tableId
const response = (await handleRequest(Operation.READ, tableId, { return getRow(tableId, id)
id: breakRowIdField(id),
includeSqlRelationships: IncludeRelationship.EXCLUDE,
})) as Row[]
return response ? response[0] : response
} }
export async function destroy(ctx: UserCtx) { export async function destroy(ctx: UserCtx) {

View File

@ -50,7 +50,7 @@ export const save = async (ctx: any) => {
if (body && body._id) { if (body && body._id) {
return patch(ctx) return patch(ctx)
} }
const { row, table } = await quotas.addRow(() => const { row, table, squashed } = await quotas.addRow(() =>
quotas.addQuery(() => pickApi(tableId).save(ctx), { quotas.addQuery(() => pickApi(tableId).save(ctx), {
datasourceId: tableId, datasourceId: tableId,
}) })
@ -58,8 +58,9 @@ export const save = async (ctx: any) => {
ctx.status = 200 ctx.status = 200
ctx.eventEmitter && ctx.eventEmitter.emitRow(`row:save`, appId, row, table) ctx.eventEmitter && ctx.eventEmitter.emitRow(`row:save`, appId, row, table)
ctx.message = `${table.name} saved successfully` ctx.message = `${table.name} saved successfully`
ctx.body = row // prefer squashed for response
gridSocket?.emitRowUpdate(ctx, row) ctx.body = row || squashed
gridSocket?.emitRowUpdate(ctx, row || squashed)
} }
export async function fetchView(ctx: any) { export async function fetchView(ctx: any) {
const tableId = utils.getTableId(ctx) const tableId = utils.getTableId(ctx)

View File

@ -7,6 +7,7 @@ import {
import { FieldTypes, FormulaTypes } from "../../../constants" import { FieldTypes, FormulaTypes } from "../../../constants"
import { context } from "@budibase/backend-core" import { context } from "@budibase/backend-core"
import { Table, Row } from "@budibase/types" import { Table, Row } from "@budibase/types"
import * as linkRows from "../../../db/linkedRows"
const { isEqual } = require("lodash") const { isEqual } = require("lodash")
const { cloneDeep } = require("lodash/fp") const { cloneDeep } = require("lodash/fp")
@ -166,5 +167,9 @@ export async function finaliseRow(
if (updateFormula) { if (updateFormula) {
await updateRelatedFormula(table, enrichedRow) await updateRelatedFormula(table, enrichedRow)
} }
return { row: enrichedRow, table } const squashed = await linkRows.squashLinksToPrimaryDisplay(
table,
enrichedRow
)
return { row: enrichedRow, squashed, table }
} }

View File

@ -189,11 +189,13 @@ export async function attachFullLinkedDocs(table: Table, rows: Row[]) {
*/ */
export async function squashLinksToPrimaryDisplay( export async function squashLinksToPrimaryDisplay(
table: Table, table: Table,
enriched: Row[] enriched: Row[] | Row
) { ) {
// will populate this as we find them // will populate this as we find them
const linkedTables = [table] const linkedTables = [table]
for (let row of enriched) { const isArray = Array.isArray(enriched)
let enrichedArray = !isArray ? [enriched] : enriched
for (let row of enrichedArray) {
// this only fetches the table if its not already in array // this only fetches the table if its not already in array
const rowTable = await getLinkedTable(row.tableId!, linkedTables) const rowTable = await getLinkedTable(row.tableId!, linkedTables)
for (let [column, schema] of Object.entries(rowTable?.schema || {})) { for (let [column, schema] of Object.entries(rowTable?.schema || {})) {
@ -213,5 +215,5 @@ export async function squashLinksToPrimaryDisplay(
row[column] = newLinks row[column] = newLinks
} }
} }
return enriched return isArray ? enrichedArray : enrichedArray[0]
} }

View File

@ -11,7 +11,6 @@ import {
tenancy, tenancy,
} from "@budibase/backend-core" } from "@budibase/backend-core"
import { checkAnyUserExists } from "../../../utilities/users" import { checkAnyUserExists } from "../../../utilities/users"
import { getLicensedConfig } from "../../../utilities/configs"
import { import {
Config, Config,
ConfigType, ConfigType,