Enrich configuration only for views

This commit is contained in:
Adria Navarro 2024-08-28 17:58:19 +02:00
parent 4826a5fbbf
commit de29d31c35
9 changed files with 74 additions and 92 deletions

View File

@ -18,8 +18,6 @@
import GridEditColumnModal from "components/backend/DataTable/modals/grid/GridEditColumnModal.svelte" import GridEditColumnModal from "components/backend/DataTable/modals/grid/GridEditColumnModal.svelte"
import GridUsersTableButton from "components/backend/DataTable/modals/grid/GridUsersTableButton.svelte" import GridUsersTableButton from "components/backend/DataTable/modals/grid/GridUsersTableButton.svelte"
import { DB_TYPE_EXTERNAL } from "constants/backend" import { DB_TYPE_EXTERNAL } from "constants/backend"
import { isEnabled } from "helpers/featureFlags"
import { FeatureFlag } from "@budibase/types"
const userSchemaOverrides = { const userSchemaOverrides = {
firstName: { displayName: "First name", disabled: true }, firstName: { displayName: "First name", disabled: true },
@ -68,7 +66,6 @@
canDeleteRows={!isUsersTable} canDeleteRows={!isUsersTable}
canEditRows={!isUsersTable || !$appStore.features.disableUserMetadata} canEditRows={!isUsersTable || !$appStore.features.disableUserMetadata}
canEditColumns={!isUsersTable || !$appStore.features.disableUserMetadata} canEditColumns={!isUsersTable || !$appStore.features.disableUserMetadata}
canSetRelationshipSchemas={isEnabled(FeatureFlag.ENRICHED_RELATIONSHIPS)}
schemaOverrides={isUsersTable ? userSchemaOverrides : null} schemaOverrides={isUsersTable ? userSchemaOverrides : null}
showAvatars={false} showAvatars={false}
on:updatedatasource={handleGridTableUpdate} on:updatedatasource={handleGridTableUpdate}

View File

@ -123,7 +123,7 @@
const table = await cache.actions.getTable(relationshipField.tableId) const table = await cache.actions.getTable(relationshipField.tableId)
relationshipPanelColumns = Object.entries( relationshipPanelColumns = Object.entries(
relationshipField?.schema || {} relationshipField?.columns || {}
).map(([name, column]) => { ).map(([name, column]) => {
return { return {
name: name, name: name,

View File

@ -62,12 +62,12 @@ export const deriveStores = context => {
} }
if ($subSchemaMutations[field]) { if ($subSchemaMutations[field]) {
enrichedSchema[field].schema ??= {} enrichedSchema[field].columns ??= {}
for (const [fieldName, mutation] of Object.entries( for (const [fieldName, mutation] of Object.entries(
$subSchemaMutations[field] $subSchemaMutations[field]
)) { )) {
enrichedSchema[field].schema[fieldName] = { enrichedSchema[field].columns[fieldName] = {
...enrichedSchema[field].schema[fieldName], ...enrichedSchema[field].columns[fieldName],
...mutation, ...mutation,
} }
} }
@ -239,12 +239,12 @@ export const createActions = context => {
...$schemaMutations[column], ...$schemaMutations[column],
} }
if ($subSchemaMutations[column]) { if ($subSchemaMutations[column]) {
newSchema[column].schema ??= {} newSchema[column].columns ??= {}
for (const [fieldName, mutation] of Object.entries( for (const [fieldName, mutation] of Object.entries(
$subSchemaMutations[column] $subSchemaMutations[column]
)) { )) {
newSchema[column].schema[fieldName] = { newSchema[column].columns[fieldName] = {
...newSchema[column].schema[fieldName], ...newSchema[column].columns[fieldName],
...mutation, ...mutation,
} }
} }

View File

@ -95,10 +95,7 @@ export async function find(ctx: UserCtx<void, TableResponse>) {
const tableId = ctx.params.tableId const tableId = ctx.params.tableId
const table = await sdk.tables.getTable(tableId) const table = await sdk.tables.getTable(tableId)
const result = await sdk.tables.enrichViewSchemas({ const result = await sdk.tables.enrichViewSchemas(table)
...table,
schema: await sdk.tables.enrichRelationshipSchema(table.schema),
})
ctx.body = result ctx.body = result
} }

View File

@ -22,8 +22,8 @@ async function parseSchema(view: CreateViewRequest) {
let fieldRelatedSchema: let fieldRelatedSchema:
| Record<string, RequiredKeys<RelationSchemaField>> | Record<string, RequiredKeys<RelationSchemaField>>
| undefined | undefined
if (schemaValue.schema) { if (schemaValue.columns) {
fieldRelatedSchema = Object.entries(schemaValue.schema).reduce< fieldRelatedSchema = Object.entries(schemaValue.columns).reduce<
NonNullable<typeof fieldRelatedSchema> NonNullable<typeof fieldRelatedSchema>
>((acc, [key, fieldSchema]) => { >((acc, [key, fieldSchema]) => {
acc[key] = { acc[key] = {
@ -36,7 +36,7 @@ async function parseSchema(view: CreateViewRequest) {
const fieldSchema: RequiredKeys< const fieldSchema: RequiredKeys<
ViewFieldMetadata & { ViewFieldMetadata & {
schema: typeof fieldRelatedSchema columns: typeof fieldRelatedSchema
} }
> = { > = {
order: schemaValue.order, order: schemaValue.order,
@ -44,7 +44,7 @@ async function parseSchema(view: CreateViewRequest) {
visible: schemaValue.visible, visible: schemaValue.visible,
readonly: schemaValue.readonly, readonly: schemaValue.readonly,
icon: schemaValue.icon, icon: schemaValue.icon,
schema: fieldRelatedSchema, columns: fieldRelatedSchema,
} }
Object.entries(fieldSchema) Object.entries(fieldSchema)
.filter(([, val]) => val === undefined) .filter(([, val]) => val === undefined)

View File

@ -11,10 +11,9 @@ import { USER_METDATA_PREFIX } from "../utils"
import partition from "lodash/partition" import partition from "lodash/partition"
import { getGlobalUsersFromMetadata } from "../../utilities/global" import { getGlobalUsersFromMetadata } from "../../utilities/global"
import { processFormulas } from "../../utilities/rowProcessor" import { processFormulas } from "../../utilities/rowProcessor"
import { context, features } from "@budibase/backend-core" import { context } from "@budibase/backend-core"
import { import {
ContextUser, ContextUser,
FeatureFlag,
FieldType, FieldType,
LinkDocumentValue, LinkDocumentValue,
Row, Row,
@ -259,11 +258,7 @@ export async function squashLinksToPrimaryDisplay(
for (const row of enrichedArray) { for (const 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)
const safeSchema = for (let [column, schema] of Object.entries(rowTable.schema)) {
(rowTable?.schema &&
(await sdk.tables.enrichRelationshipSchema(rowTable.schema))) ||
{}
for (let [column, schema] of Object.entries(safeSchema)) {
if (schema.type !== FieldType.LINK || !Array.isArray(row[column])) { if (schema.type !== FieldType.LINK || !Array.isArray(row[column])) {
continue continue
} }
@ -275,16 +270,17 @@ export async function squashLinksToPrimaryDisplay(
const obj: any = { _id: link._id } const obj: any = { _id: link._id }
obj.primaryDisplay = getPrimaryDisplayValue(link, linkedTable) obj.primaryDisplay = getPrimaryDisplayValue(link, linkedTable)
const allowRelationshipSchemas = await features.flags.isEnabled( // TODO
FeatureFlag.ENRICHED_RELATIONSHIPS // const allowRelationshipSchemas = await features.flags.isEnabled(
) // FeatureFlag.ENRICHED_RELATIONSHIPS
if (schema.schema && allowRelationshipSchemas) { // )
for (const relField of Object.entries(schema.schema) // if (schema.schema && allowRelationshipSchemas) {
.filter(([_, field]) => field.visible !== false) // for (const relField of Object.entries(schema.schema)
.map(([fieldKey]) => fieldKey)) { // .filter(([_, field]) => field.visible !== false)
obj[relField] = link[relField] // .map(([fieldKey]) => fieldKey)) {
} // obj[relField] = link[relField]
} // }
// }
newLinks.push(obj) newLinks.push(obj)
} }

View File

@ -146,53 +146,6 @@ export async function getTables(tableIds: string[]): Promise<Table[]> {
return processTables(tables) return processTables(tables)
} }
export async function enrichRelationshipSchema(
schema: TableSchema
): Promise<TableSchema> {
const tableCache: Record<string, Table> = {}
async function populateRelTableSchema(field: RelationshipFieldMetadata) {
if (!tableCache[field.tableId]) {
tableCache[field.tableId] = await sdk.tables.getTable(field.tableId)
}
const relTable = tableCache[field.tableId]
const fieldSchema = field.schema || {}
const resultSchema: Record<string, RelationSchemaField> = {}
for (const relTableFieldName of Object.keys(relTable.schema)) {
const relTableField = relTable.schema[relTableFieldName]
if ([FieldType.LINK, FieldType.FORMULA].includes(relTableField.type)) {
continue
}
if (relTableField.visible === false) {
continue
}
const isVisible = !!fieldSchema[relTableFieldName]?.visible
const isReadonly = !!fieldSchema[relTableFieldName]?.readonly
resultSchema[relTableFieldName] = {
visible: isVisible,
readonly: isReadonly,
}
}
field.schema = resultSchema
}
const result: TableSchema = {}
for (const fieldName of Object.keys(schema)) {
const field = { ...schema[fieldName] }
if (field.type === FieldType.LINK) {
await populateRelTableSchema(field)
}
result[fieldName] = field
}
return result
}
export async function enrichViewSchemas(table: Table): Promise<TableResponse> { export async function enrichViewSchemas(table: Table): Promise<TableResponse> {
const views = [] const views = []
for (const view of Object.values(table.views ?? [])) { for (const view of Object.values(table.views ?? [])) {

View File

@ -1,5 +1,8 @@
import { import {
FieldType,
RelationSchemaField,
RenameColumn, RenameColumn,
Table,
TableSchema, TableSchema,
View, View,
ViewFieldMetadata, ViewFieldMetadata,
@ -162,23 +165,59 @@ export async function enrichSchema(
view: ViewV2, view: ViewV2,
tableSchema: TableSchema tableSchema: TableSchema
): Promise<ViewV2Enriched> { ): Promise<ViewV2Enriched> {
const tableCache: Record<string, Table> = {}
async function populateRelTableSchema(
tableId: string,
viewFields: Record<string, RelationSchemaField>
) {
if (!tableCache[tableId]) {
tableCache[tableId] = await sdk.tables.getTable(tableId)
}
const relTable = tableCache[tableId]
const result: Record<string, RelationSchemaField> = {}
for (const relTableFieldName of Object.keys(relTable.schema)) {
const relTableField = relTable.schema[relTableFieldName]
if ([FieldType.LINK, FieldType.FORMULA].includes(relTableField.type)) {
continue
}
if (relTableField.visible === false) {
continue
}
const isVisible = !!viewFields[relTableFieldName]?.visible
const isReadonly = !!viewFields[relTableFieldName]?.readonly
result[relTableFieldName] = {
visible: isVisible,
readonly: isReadonly,
}
}
return result
}
let schema: TableSchema = {} let schema: TableSchema = {}
const anyViewOrder = Object.values(view.schema || {}).some(
ui => ui.order != null const viewSchema = view.schema || {}
) const anyViewOrder = Object.values(viewSchema).some(ui => ui.order != null)
for (const key of Object.keys(tableSchema).filter( for (const key of Object.keys(schema)) {
key => tableSchema[key].visible !== false
)) {
// if nothing specified in view, then it is not visible // if nothing specified in view, then it is not visible
const ui = view.schema?.[key] || { visible: false } const ui = viewSchema[key] || { visible: false }
schema[key] = { schema[key] = {
...tableSchema[key], ...tableSchema[key],
...ui, ...ui,
order: anyViewOrder ? ui?.order ?? undefined : tableSchema[key].order, order: anyViewOrder ? ui?.order ?? undefined : tableSchema[key].order,
} }
}
schema = await sdk.tables.enrichRelationshipSchema(schema) if (schema[key].type === FieldType.LINK) {
schema[key].columns = await populateRelTableSchema(
schema[key].tableId,
viewSchema[key].columns || {}
)
}
}
return { return {
...view, ...view,

View File

@ -38,7 +38,7 @@ export type ViewFieldMetadata = UIFieldMetadata & {
columns?: Record<string, RelationSchemaField> columns?: Record<string, RelationSchemaField>
} }
type RelationSchemaField = { export type RelationSchemaField = {
visible?: boolean visible?: boolean
readonly?: boolean readonly?: boolean
} }