From 7b20aa31d1a8165b642b5d3bf390f29b1a9e0669 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Mon, 6 Dec 2021 12:37:50 +0000 Subject: [PATCH] Flatten JSON schema in apps to allow filtering and display of nested values --- packages/bbui/src/Table/Table.svelte | 3 ++- packages/bbui/src/index.js | 3 +++ packages/bbui/src/utils/helpers.js | 24 ++++++++++++++++++++++++ packages/builder/src/helpers/lucene.js | 19 +------------------ packages/client/src/api/datasources.js | 2 +- 5 files changed, 31 insertions(+), 20 deletions(-) diff --git a/packages/bbui/src/Table/Table.svelte b/packages/bbui/src/Table/Table.svelte index bcd84e7112..09ade22627 100644 --- a/packages/bbui/src/Table/Table.svelte +++ b/packages/bbui/src/Table/Table.svelte @@ -4,6 +4,7 @@ import CellRenderer from "./CellRenderer.svelte" import SelectEditRenderer from "./SelectEditRenderer.svelte" import { cloneDeep } from "lodash" + import { deepGet } from "../utils/helpers" /** * The expected schema is our normal couch schemas for our tables. @@ -318,7 +319,7 @@ {customRenderers} {row} schema={schema[field]} - value={row[field]} + value={deepGet(row, field)} on:clickrelationship > diff --git a/packages/bbui/src/index.js b/packages/bbui/src/index.js index 377d451604..ea866ee20c 100644 --- a/packages/bbui/src/index.js +++ b/packages/bbui/src/index.js @@ -76,3 +76,6 @@ export { default as clickOutside } from "./Actions/click_outside" // Stores export { notifications, createNotificationStore } from "./Stores/notifications" + +// Utils +export * from "./utils/helpers" diff --git a/packages/bbui/src/utils/helpers.js b/packages/bbui/src/utils/helpers.js index 83d305d573..cbb720f9a4 100644 --- a/packages/bbui/src/utils/helpers.js +++ b/packages/bbui/src/utils/helpers.js @@ -6,3 +6,27 @@ export const generateID = () => { } export const capitalise = s => s.substring(0, 1).toUpperCase() + s.substring(1) + +/** + * Gets a key within an object. The key supports dot syntax for retrieving deep + * fields - e.g. "a.b.c". + * Exact matches of keys with dots in them take precedence over nested keys of + * the same path - e.g. getting "a.b" from { "a.b": "foo", a: { b: "bar" } } + * will return "foo" over "bar". + * @param obj the object + * @param key the key + */ +export const deepGet = (obj, key) => { + if (!obj || !key) { + return null + } + if (obj[key] != null) { + return obj[key] + } + const split = key.split(".") + let value = obj + for (let i = 0; i < split.length; i++) { + value = value?.[split[i]] + } + return value +} diff --git a/packages/builder/src/helpers/lucene.js b/packages/builder/src/helpers/lucene.js index 9f4269b046..5b8e1b805e 100644 --- a/packages/builder/src/helpers/lucene.js +++ b/packages/builder/src/helpers/lucene.js @@ -1,4 +1,5 @@ import { NoEmptyFilterStrings } from "../constants/lucene" +import { deepGet } from "@budibase/bbui" /** * Removes any fields that contain empty strings that would cause inconsistent @@ -205,21 +206,3 @@ export const luceneLimit = (docs, limit) => { } return docs.slice(0, numLimit) } - -/** - * Gets a key within an object. The key supports dot syntax for retrieving deep - * fields - e.g. "a.b.c". - * @param obj the object - * @param key the key - */ -const deepGet = (obj, key) => { - if (!obj || !key) { - return null - } - const split = key.split(".") - let value = obj - for (let i = 0; i < split.length; i++) { - value = value?.[split[i]] - } - return value -} diff --git a/packages/client/src/api/datasources.js b/packages/client/src/api/datasources.js index d2941f3be9..87570fe29a 100644 --- a/packages/client/src/api/datasources.js +++ b/packages/client/src/api/datasources.js @@ -85,7 +85,7 @@ export const fetchDatasourceSchema = async dataSource => { for (let i = 0; i < keysToSchema.length; i++) { schema = schema[keysToSchema[i]].schema } - return convertJSONSchemaToTableSchema(schema) + return convertJSONSchemaToTableSchema(schema, true) } // Tables, views and links can be fetched by table ID