From 588ad5f907eed88d2a8fd628be67aaf4670ca86a Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Thu, 27 Mar 2025 09:36:31 +0000 Subject: [PATCH 01/12] Add PDF specific table component --- .../new/_components/componentStructure.json | 1 + packages/client/manifest.json | 56 ++++++++ packages/client/src/components/app/index.js | 2 +- .../src/components/app/pdf/PDFTable.svelte | 133 ++++++++++++++++++ .../client/src/components/app/pdf/index.ts | 2 + 5 files changed, 193 insertions(+), 1 deletion(-) create mode 100644 packages/client/src/components/app/pdf/PDFTable.svelte create mode 100644 packages/client/src/components/app/pdf/index.ts diff --git a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/new/_components/componentStructure.json b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/new/_components/componentStructure.json index d809095dc0..21cb25f74f 100644 --- a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/new/_components/componentStructure.json +++ b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/new/_components/componentStructure.json @@ -23,6 +23,7 @@ "dataprovider", "repeater", "gridblock", + "pdftable", "spreadsheet", "dynamicfilter", "daterangepicker" diff --git a/packages/client/manifest.json b/packages/client/manifest.json index efd392f54d..17e25347ad 100644 --- a/packages/client/manifest.json +++ b/packages/client/manifest.json @@ -8088,5 +8088,61 @@ "defaultValue": "Download PDF" } ] + }, + "pdftable": { + "name": "Plain Table", + "icon": "Table", + "styles": ["size"], + "size": { + "width": 600, + "height": 400 + }, + "grid": { + "hAlign": "stretch", + "vAlign": "stretch" + }, + "settings": [ + { + "type": "dataSource", + "label": "Data", + "key": "datasource", + "required": true + }, + { + "type": "filter", + "label": "Filtering", + "key": "filter", + "dependsOn": { + "setting": "datasource.type", + "value": "custom", + "invert": true + } + }, + { + "type": "field/sortable", + "label": "Sort column", + "key": "sortColumn", + "placeholder": "Default", + "dependsOn": { + "setting": "datasource.type", + "value": "custom", + "invert": true + } + }, + { + "type": "select", + "label": "Sort order", + "key": "sortOrder", + "options": ["Ascending", "Descending"], + "defaultValue": "Ascending", + "dependsOn": "sortColumn" + }, + { + "type": "columns/basic", + "label": "Columns", + "key": "columns", + "resetOn": "datasource" + } + ] } } diff --git a/packages/client/src/components/app/index.js b/packages/client/src/components/app/index.js index 547cb50230..1cad2019fb 100644 --- a/packages/client/src/components/app/index.js +++ b/packages/client/src/components/app/index.js @@ -36,11 +36,11 @@ export { default as sidepanel } from "./SidePanel.svelte" export { default as modal } from "./Modal.svelte" export { default as gridblock } from "./GridBlock.svelte" export { default as textv2 } from "./Text.svelte" -export { default as pdf } from "./pdf/PDF.svelte" export * from "./charts" export * from "./forms" export * from "./blocks" export * from "./dynamic-filter" +export * from "./pdf" // Deprecated component left for compatibility in old apps export * from "./deprecated/table" diff --git a/packages/client/src/components/app/pdf/PDFTable.svelte b/packages/client/src/components/app/pdf/PDFTable.svelte new file mode 100644 index 0000000000..7335a548fe --- /dev/null +++ b/packages/client/src/components/app/pdf/PDFTable.svelte @@ -0,0 +1,133 @@ + + +
+
+ {#if schema} + {#each Object.keys(schema) as col} +
{schema[col].displayName}
+ {/each} + {#each $fetch.rows as row} + {#each Object.keys(schema) as col} +
{row[col]}
+ {/each} + {/each} + {/if} +
+
+ + diff --git a/packages/client/src/components/app/pdf/index.ts b/packages/client/src/components/app/pdf/index.ts new file mode 100644 index 0000000000..ae100c894b --- /dev/null +++ b/packages/client/src/components/app/pdf/index.ts @@ -0,0 +1,2 @@ +export { default as pdf } from "./PDF.svelte" +export { default as pdftable } from "./PDFTable.svelte" From 7a5b311a7ee6a27c57e4d24dcb2c8499360a8764 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Thu, 27 Mar 2025 16:25:38 +0000 Subject: [PATCH 02/12] Support string values when formatting dates --- packages/bbui/src/helpers.ts | 5 +- .../frontend-core/src/utils/formatting.ts | 120 ++++++++++++++++++ 2 files changed, 124 insertions(+), 1 deletion(-) create mode 100644 packages/frontend-core/src/utils/formatting.ts diff --git a/packages/bbui/src/helpers.ts b/packages/bbui/src/helpers.ts index 330f381d53..10ccf4683d 100644 --- a/packages/bbui/src/helpers.ts +++ b/packages/bbui/src/helpers.ts @@ -211,9 +211,12 @@ const localeDateFormat = new Intl.DateTimeFormat() // Formats a dayjs date according to schema flags export const getDateDisplayValue = ( - value: dayjs.Dayjs | null, + value: dayjs.Dayjs | string | null, { enableTime = true, timeOnly = false } = {} ): string => { + if (typeof value === "string") { + value = dayjs(value) + } if (!value?.isValid()) { return "" } diff --git a/packages/frontend-core/src/utils/formatting.ts b/packages/frontend-core/src/utils/formatting.ts new file mode 100644 index 0000000000..2fa1a59adf --- /dev/null +++ b/packages/frontend-core/src/utils/formatting.ts @@ -0,0 +1,120 @@ +import { + BBReferenceFieldMetadata, + BBReferenceFieldSubType, + BBReferenceSingleFieldMetadata, + DateFieldMetadata, + FieldSchema, + FieldType, + Row, + TableSchema, +} from "@budibase/types" +import { Helpers } from "@budibase/bbui" + +// Singleton formatter to save us creating one every time +const NumberFormatter = Intl.NumberFormat() + +export type StringifiedRow = { [key: string]: string } + +// Formats a number according to the locale +export const formatNumber = (value: any): string => { + const type = typeof value + if (type !== "string" && type !== "number") { + return "" + } + if (type === "string" && !value.trim().length) { + return "" + } + const res = NumberFormatter.format(value) + return res === "NaN" ? stringifyValue(value) : res +} + +// Attempts to stringify any type of value +const stringifyValue = (value: any): string => { + if (value == null) { + return "" + } + if (typeof value === "string") { + return value + } + if (typeof value.toString === "function") { + return stringifyValue(value.toString()) + } + try { + return JSON.stringify(value) + } catch (e) { + return "" + } +} + +const stringifyField = (value: any, schema: FieldSchema): string => { + switch (schema.type) { + // TODO + case FieldType.ATTACHMENT_SINGLE: + case FieldType.ATTACHMENTS: + case FieldType.AUTO: + case FieldType.JSON: + case FieldType.LINK: + case FieldType.SIGNATURE_SINGLE: + return "" + + // User is the only BB reference subtype right now + case FieldType.BB_REFERENCE: + case FieldType.BB_REFERENCE_SINGLE: { + if ( + schema.subtype !== BBReferenceFieldSubType.USERS && + schema.subtype !== BBReferenceFieldSubType.USER + ) { + return "" + } + if (!value) { + return "" + } + const arrayVal = Array.isArray(value) ? value : [value] + return arrayVal?.map((user: any) => user.primaryDisplay).join(", ") || "" + } + + // Join arrays with commas + case FieldType.ARRAY: + return value?.join(", ") || "" + + // Just capitalise booleans + case FieldType.BOOLEAN: + return Helpers.capitalise(value?.toString() || "false") + + // Format dates into something readable + case FieldType.DATETIME: { + return Helpers.getDateDisplayValue(value, { + enableTime: !schema.dateOnly, + timeOnly: schema.timeOnly, + }) + } + + // Format numbers using a locale string + case FieldType.NUMBER: + return formatNumber(value) + + // Simple string types + case FieldType.STRING: + case FieldType.LONGFORM: + case FieldType.BIGINT: + case FieldType.OPTIONS: + case FieldType.AI: + case FieldType.BARCODEQR: + return value || "" + + // Fallback for unknown types or future column types that we forget to add + case FieldType.FORMULA: + default: + return stringifyValue(value) + } +} + +// Stringifies every property of a row, ensuring they are all human-readable +// strings for display +export const stringifyRow = (row: Row, schema: TableSchema): StringifiedRow => { + let stringified: StringifiedRow = {} + Object.entries(schema).forEach(([field, fieldSchema]) => { + stringified[field] = stringifyField(row[field], fieldSchema) + }) + return stringified +} From 776f1cf61f60db5e5c92c14a3c98b162cd2883d6 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Thu, 27 Mar 2025 16:26:00 +0000 Subject: [PATCH 03/12] Add WIP on core formatting utils for row values --- .../src/components/app/pdf/PDFTable.svelte | 7 +++++-- .../src/components/grid/cells/NumberCell.svelte | 17 +---------------- packages/frontend-core/src/utils/index.ts | 1 + 3 files changed, 7 insertions(+), 18 deletions(-) diff --git a/packages/client/src/components/app/pdf/PDFTable.svelte b/packages/client/src/components/app/pdf/PDFTable.svelte index 7335a548fe..3c65e6f707 100644 --- a/packages/client/src/components/app/pdf/PDFTable.svelte +++ b/packages/client/src/components/app/pdf/PDFTable.svelte @@ -8,7 +8,7 @@ UISearchFilter, UserDatasource, } from "@budibase/types" - import { fetchData, QueryUtils } from "@budibase/frontend-core/src" + import { fetchData, QueryUtils, stringifyRow } from "@budibase/frontend-core" import { getContext } from "svelte" type ProviderDatasource = Exclude< @@ -39,6 +39,9 @@ $: schema = sanitizeSchema($fetch.schema, columns) $: columnCount = Object.keys(schema).length $: rowCount = $fetch.rows?.length || 0 + $: stringifiedRows = ($fetch?.rows || []).map(row => + stringifyRow(row, schema) + ) const createFetch = (datasource: ProviderDatasource) => { return fetchData({ @@ -95,7 +98,7 @@ {#each Object.keys(schema) as col}
{schema[col].displayName}
{/each} - {#each $fetch.rows as row} + {#each stringifiedRows as row} {#each Object.keys(schema) as col}
{row[col]}
{/each} diff --git a/packages/frontend-core/src/components/grid/cells/NumberCell.svelte b/packages/frontend-core/src/components/grid/cells/NumberCell.svelte index c8ae96ef21..5ac6e14b6e 100644 --- a/packages/frontend-core/src/components/grid/cells/NumberCell.svelte +++ b/packages/frontend-core/src/components/grid/cells/NumberCell.svelte @@ -1,8 +1,5 @@ - - Date: Fri, 28 Mar 2025 10:58:54 +0000 Subject: [PATCH 04/12] Add nested JSON fields to plain table and create core util for nested JSON fields --- packages/builder/src/dataBinding.js | 22 ++---------------- .../src/components/app/pdf/PDFTable.svelte | 12 +++++++--- .../frontend-core/src/utils/formatting.ts | 10 ++++++-- packages/frontend-core/src/utils/schema.js | 23 +++++++++++++++++++ 4 files changed, 42 insertions(+), 25 deletions(-) diff --git a/packages/builder/src/dataBinding.js b/packages/builder/src/dataBinding.js index 1011774ac5..ada1ee274d 100644 --- a/packages/builder/src/dataBinding.js +++ b/packages/builder/src/dataBinding.js @@ -26,7 +26,7 @@ import { getJsHelperList, } from "@budibase/string-templates" import { TableNames } from "./constants" -import { JSONUtils, Constants } from "@budibase/frontend-core" +import { JSONUtils, Constants, SchemaUtils } from "@budibase/frontend-core" import ActionDefinitions from "@/components/design/settings/controls/ButtonActionEditor/manifest.json" import { environment, licensing } from "@/stores/portal" import { convertOldFieldFormat } from "@/components/design/settings/controls/FieldConfiguration/utils" @@ -1026,25 +1026,7 @@ export const getSchemaForDatasource = (asset, datasource, options) => { // Check for any JSON fields so we can add any top level properties if (schema) { - let jsonAdditions = {} - Object.keys(schema).forEach(fieldKey => { - const fieldSchema = schema[fieldKey] - if (fieldSchema?.type === "json") { - const jsonSchema = JSONUtils.convertJSONSchemaToTableSchema( - fieldSchema, - { - squashObjects: true, - } - ) - Object.keys(jsonSchema).forEach(jsonKey => { - jsonAdditions[`${fieldKey}.${jsonKey}`] = { - type: jsonSchema[jsonKey].type, - nestedJSON: true, - } - }) - } - }) - schema = { ...schema, ...jsonAdditions } + schema = SchemaUtils.addNestedJSONSchemaFields(schema) } // Determine if we should add ID and rev to the schema diff --git a/packages/client/src/components/app/pdf/PDFTable.svelte b/packages/client/src/components/app/pdf/PDFTable.svelte index 3c65e6f707..a9376460df 100644 --- a/packages/client/src/components/app/pdf/PDFTable.svelte +++ b/packages/client/src/components/app/pdf/PDFTable.svelte @@ -8,7 +8,12 @@ UISearchFilter, UserDatasource, } from "@budibase/types" - import { fetchData, QueryUtils, stringifyRow } from "@budibase/frontend-core" + import { + fetchData, + QueryUtils, + stringifyRow, + SchemaUtils, + } from "@budibase/frontend-core" import { getContext } from "svelte" type ProviderDatasource = Exclude< @@ -88,7 +93,8 @@ sanitized = pruned } - return sanitized + // Add nested JSON fields + return SchemaUtils.addNestedJSONSchemaFields(sanitized) } @@ -114,7 +120,7 @@ } .table { display: grid; - grid-template-columns: repeat(var(--cols), minmax(20px, auto)); + grid-template-columns: repeat(var(--cols), minmax(40px, auto)); grid-template-rows: repeat(var(--rows), max-content); overflow: hidden; background: white; diff --git a/packages/frontend-core/src/utils/formatting.ts b/packages/frontend-core/src/utils/formatting.ts index 2fa1a59adf..66c10de0d8 100644 --- a/packages/frontend-core/src/utils/formatting.ts +++ b/packages/frontend-core/src/utils/formatting.ts @@ -52,11 +52,14 @@ const stringifyField = (value: any, schema: FieldSchema): string => { case FieldType.ATTACHMENT_SINGLE: case FieldType.ATTACHMENTS: case FieldType.AUTO: - case FieldType.JSON: case FieldType.LINK: case FieldType.SIGNATURE_SINGLE: return "" + // Stringify JSON blobs + case FieldType.JSON: + return value ? JSON.stringify(value) : "" + // User is the only BB reference subtype right now case FieldType.BB_REFERENCE: case FieldType.BB_REFERENCE_SINGLE: { @@ -114,7 +117,10 @@ const stringifyField = (value: any, schema: FieldSchema): string => { export const stringifyRow = (row: Row, schema: TableSchema): StringifiedRow => { let stringified: StringifiedRow = {} Object.entries(schema).forEach(([field, fieldSchema]) => { - stringified[field] = stringifyField(row[field], fieldSchema) + stringified[field] = stringifyField( + Helpers.deepGet(row, field), + fieldSchema + ) }) return stringified } diff --git a/packages/frontend-core/src/utils/schema.js b/packages/frontend-core/src/utils/schema.js index cd55d4983d..135dbd3e35 100644 --- a/packages/frontend-core/src/utils/schema.js +++ b/packages/frontend-core/src/utils/schema.js @@ -1,5 +1,6 @@ import { helpers } from "@budibase/shared-core" import { TypeIconMap } from "../constants" +import { convertJSONSchemaToTableSchema } from "./json" export const getColumnIcon = column => { // For some reason we have remix icons saved under this property sometimes, @@ -24,3 +25,25 @@ export const getColumnIcon = column => { return result || "Text" } + +export const addNestedJSONSchemaFields = schema => { + if (!schema) { + return schema + } + let jsonAdditions = {} + Object.keys(schema).forEach(fieldKey => { + const fieldSchema = schema[fieldKey] + if (fieldSchema?.type === "json") { + const jsonSchema = convertJSONSchemaToTableSchema(fieldSchema, { + squashObjects: true, + }) + Object.keys(jsonSchema).forEach(jsonKey => { + jsonAdditions[`${fieldKey}.${jsonKey}`] = { + type: jsonSchema[jsonKey].type, + nestedJSON: true, + } + }) + } + }) + return { ...schema, ...jsonAdditions } +} From 4dfe10a5ad63675376fefa07de79f7888668b656 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Fri, 28 Mar 2025 11:30:09 +0000 Subject: [PATCH 05/12] Add new top level column editor and ensure all types can be stringified in PDF tables --- .../design/settings/componentSettings.js | 4 ++ .../controls/ColumnEditor/ColumnEditor.svelte | 17 ++++---- .../ColumnEditor/TopLevelColumnEditor.svelte | 15 +++++++ packages/client/manifest.json | 2 +- .../src/components/app/pdf/PDFTable.svelte | 3 +- .../frontend-core/src/utils/formatting.ts | 39 +++++++++++++++---- .../types/src/documents/app/table/schema.ts | 2 + 7 files changed, 63 insertions(+), 19 deletions(-) create mode 100644 packages/builder/src/components/design/settings/controls/ColumnEditor/TopLevelColumnEditor.svelte diff --git a/packages/builder/src/components/design/settings/componentSettings.js b/packages/builder/src/components/design/settings/componentSettings.js index 1cf4b0211c..86014f152c 100644 --- a/packages/builder/src/components/design/settings/componentSettings.js +++ b/packages/builder/src/components/design/settings/componentSettings.js @@ -22,6 +22,7 @@ import ValidationEditor from "./controls/ValidationEditor/ValidationEditor.svelt import DrawerBindableInput from "@/components/common/bindings/DrawerBindableInput.svelte" import ColumnEditor from "./controls/ColumnEditor/ColumnEditor.svelte" import BasicColumnEditor from "./controls/ColumnEditor/BasicColumnEditor.svelte" +import TopLevelColumnEditor from "./controls/ColumnEditor/TopLevelColumnEditor.svelte" import GridColumnEditor from "./controls/GridColumnConfiguration/GridColumnConfiguration.svelte" import BarButtonList from "./controls/BarButtonList.svelte" import FieldConfiguration from "./controls/FieldConfiguration/FieldConfiguration.svelte" @@ -62,7 +63,10 @@ const componentMap = { stepConfiguration: FormStepConfiguration, formStepControls: FormStepControls, columns: ColumnEditor, + // "Basic" actually includes nested JSON and relationship fields "columns/basic": BasicColumnEditor, + // "Top level" is only the top level schema fields + "columns/toplevel": TopLevelColumnEditor, "columns/grid": GridColumnEditor, tableConditions: TableConditionEditor, "field/sortable": SortableFieldSelect, diff --git a/packages/builder/src/components/design/settings/controls/ColumnEditor/ColumnEditor.svelte b/packages/builder/src/components/design/settings/controls/ColumnEditor/ColumnEditor.svelte index 5e27b591f8..d4190068c1 100644 --- a/packages/builder/src/components/design/settings/controls/ColumnEditor/ColumnEditor.svelte +++ b/packages/builder/src/components/design/settings/controls/ColumnEditor/ColumnEditor.svelte @@ -10,10 +10,17 @@ } from "@/dataBinding" import { selectedScreen, tables } from "@/stores/builder" - export let componentInstance + const getSearchableFields = (schema, tableList) => { + return search.getFields(tableList, Object.values(schema || {}), { + allowLinks: true, + }) + } + + export let componentInstance = undefined export let value = [] export let allowCellEditing = true export let allowReorder = true + export let getSchemaFields = getSearchableFields const dispatch = createEventDispatcher() @@ -28,13 +35,7 @@ : enrichedSchemaFields?.map(field => field.name) $: sanitisedValue = getValidColumns(value, options) $: updateBoundValue(sanitisedValue) - $: enrichedSchemaFields = search.getFields( - $tables.list, - Object.values(schema || {}), - { - allowLinks: true, - } - ) + $: enrichedSchemaFields = getSchemaFields(schema, $tables.list) $: { value = (value || []).filter( diff --git a/packages/builder/src/components/design/settings/controls/ColumnEditor/TopLevelColumnEditor.svelte b/packages/builder/src/components/design/settings/controls/ColumnEditor/TopLevelColumnEditor.svelte new file mode 100644 index 0000000000..69a80a85da --- /dev/null +++ b/packages/builder/src/components/design/settings/controls/ColumnEditor/TopLevelColumnEditor.svelte @@ -0,0 +1,15 @@ + + + diff --git a/packages/client/manifest.json b/packages/client/manifest.json index 17e25347ad..055086baf7 100644 --- a/packages/client/manifest.json +++ b/packages/client/manifest.json @@ -8138,7 +8138,7 @@ "dependsOn": "sortColumn" }, { - "type": "columns/basic", + "type": "columns/toplevel", "label": "Columns", "key": "columns", "resetOn": "datasource" diff --git a/packages/client/src/components/app/pdf/PDFTable.svelte b/packages/client/src/components/app/pdf/PDFTable.svelte index a9376460df..793134984c 100644 --- a/packages/client/src/components/app/pdf/PDFTable.svelte +++ b/packages/client/src/components/app/pdf/PDFTable.svelte @@ -93,8 +93,7 @@ sanitized = pruned } - // Add nested JSON fields - return SchemaUtils.addNestedJSONSchemaFields(sanitized) + return sanitized } diff --git a/packages/frontend-core/src/utils/formatting.ts b/packages/frontend-core/src/utils/formatting.ts index 66c10de0d8..af0fe5ebd2 100644 --- a/packages/frontend-core/src/utils/formatting.ts +++ b/packages/frontend-core/src/utils/formatting.ts @@ -1,8 +1,5 @@ import { - BBReferenceFieldMetadata, BBReferenceFieldSubType, - BBReferenceSingleFieldMetadata, - DateFieldMetadata, FieldSchema, FieldType, Row, @@ -48,14 +45,40 @@ const stringifyValue = (value: any): string => { const stringifyField = (value: any, schema: FieldSchema): string => { switch (schema.type) { - // TODO - case FieldType.ATTACHMENT_SINGLE: - case FieldType.ATTACHMENTS: + // Auto should not exist as it should always be typed by its underlying + // real type, like date or user case FieldType.AUTO: - case FieldType.LINK: - case FieldType.SIGNATURE_SINGLE: return "" + // Just state whether signatures exist or not + case FieldType.SIGNATURE_SINGLE: + return value ? "Yes" : "No" + + // Extract attachment names + case FieldType.ATTACHMENT_SINGLE: + case FieldType.ATTACHMENTS: { + if (!value) { + return "" + } + const arrayValue = Array.isArray(value) ? value : [value] + return arrayValue + .map(x => x.name) + .filter(x => !!x) + .join(", ") + } + + // Extract primary displays from relationships + case FieldType.LINK: { + if (!value) { + return "" + } + const arrayValue = Array.isArray(value) ? value : [value] + return arrayValue + .map(x => x.primaryDisplay) + .filter(x => !!x) + .join(", ") + } + // Stringify JSON blobs case FieldType.JSON: return value ? JSON.stringify(value) : "" diff --git a/packages/types/src/documents/app/table/schema.ts b/packages/types/src/documents/app/table/schema.ts index 86e15e4974..e3f9d3af3f 100644 --- a/packages/types/src/documents/app/table/schema.ts +++ b/packages/types/src/documents/app/table/schema.ts @@ -207,6 +207,8 @@ export interface BaseFieldSchema extends UIFieldMetadata { autocolumn?: boolean autoReason?: AutoReason.FOREIGN_KEY subtype?: never + // added when enriching nested JSON fields into schema + nestedJSON?: boolean } interface OtherFieldMetadata extends BaseFieldSchema { From b8b8828b13d5cfd087ec4c3a6f2bb59f7f164401 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Fri, 28 Mar 2025 12:38:24 +0000 Subject: [PATCH 06/12] Add limit setting to PDF tables --- packages/client/manifest.json | 6 ++++++ .../client/src/components/app/pdf/PDFTable.svelte | 13 +++++-------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/packages/client/manifest.json b/packages/client/manifest.json index 055086baf7..b7d68264f7 100644 --- a/packages/client/manifest.json +++ b/packages/client/manifest.json @@ -8142,6 +8142,12 @@ "label": "Columns", "key": "columns", "resetOn": "datasource" + }, + { + "type": "number", + "label": "Limit", + "key": "limit", + "defaultValue": 20 } ] } diff --git a/packages/client/src/components/app/pdf/PDFTable.svelte b/packages/client/src/components/app/pdf/PDFTable.svelte index 793134984c..306756f00b 100644 --- a/packages/client/src/components/app/pdf/PDFTable.svelte +++ b/packages/client/src/components/app/pdf/PDFTable.svelte @@ -8,12 +8,7 @@ UISearchFilter, UserDatasource, } from "@budibase/types" - import { - fetchData, - QueryUtils, - stringifyRow, - SchemaUtils, - } from "@budibase/frontend-core" + import { fetchData, QueryUtils, stringifyRow } from "@budibase/frontend-core" import { getContext } from "svelte" type ProviderDatasource = Exclude< @@ -28,6 +23,7 @@ export let sortColumn: string | undefined = undefined export let sortOrder: SortOrder | undefined = undefined export let columns: ChosenColumns = undefined + export let limit: number = 20 const component = getContext("component") const { styleable, API } = getContext("sdk") @@ -38,8 +34,7 @@ query, sortColumn, sortOrder, - limit: 100, - paginate: false, + limit, }) $: schema = sanitizeSchema($fetch.schema, columns) $: columnCount = Object.keys(schema).length @@ -56,6 +51,8 @@ query, sortColumn, sortOrder, + limit, + paginate: false, }, }) } From 4b8a5a7f7977bf4838716f638f34b0d6630f8d08 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Fri, 28 Mar 2025 14:32:12 +0000 Subject: [PATCH 07/12] Add size setting to text component --- packages/client/manifest.json | 26 +++++++++++++++++++ .../client/src/components/app/Text.svelte | 7 +++-- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/packages/client/manifest.json b/packages/client/manifest.json index b7d68264f7..f360a837d4 100644 --- a/packages/client/manifest.json +++ b/packages/client/manifest.json @@ -8017,6 +8017,32 @@ "key": "text", "wide": true }, + { + "type": "select", + "label": "Size", + "key": "size", + "defaultValue": "14px", + "showInBar": true, + "placeholder": "Default", + "options": [ + { + "label": "Small", + "value": "12px" + }, + { + "label": "Medium", + "value": "14px" + }, + { + "label": "Large", + "value": "18px" + }, + { + "label": "Extra Large", + "value": "24px" + } + ] + }, { "type": "select", "label": "Alignment", diff --git a/packages/client/src/components/app/Text.svelte b/packages/client/src/components/app/Text.svelte index 1880669c15..086c0c66e3 100644 --- a/packages/client/src/components/app/Text.svelte +++ b/packages/client/src/components/app/Text.svelte @@ -5,20 +5,23 @@ export let text: string = "" export let color: string | undefined = undefined export let align: "left" | "center" | "right" | "justify" = "left" + export let size: string | undefined = "14px" const component = getContext("component") const { styleable } = getContext("sdk") // Add in certain settings to styles - $: styles = enrichStyles($component.styles, color, align) + $: styles = enrichStyles($component.styles, color, align, size) const enrichStyles = ( styles: any, colorStyle: typeof color, - alignStyle: typeof align + alignStyle: typeof align, + size: string | undefined ) => { let additions: Record = { "text-align": alignStyle, + "font-size": size || "14px", } if (colorStyle) { additions.color = colorStyle From 3cade98428d97e7627f83d54a0142eaf14e8a0c3 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Fri, 28 Mar 2025 15:57:15 +0000 Subject: [PATCH 08/12] Only show first 3 columns by default in PDF table, and line clamp all cells to 3 lines --- .../controls/ColumnEditor/ColumnDrawer.svelte | 2 +- .../controls/ColumnEditor/ColumnEditor.svelte | 3 ++- packages/client/manifest.json | 5 ++-- .../src/components/app/pdf/PDFTable.svelte | 25 +++++++++++-------- 4 files changed, 21 insertions(+), 14 deletions(-) diff --git a/packages/builder/src/components/design/settings/controls/ColumnEditor/ColumnDrawer.svelte b/packages/builder/src/components/design/settings/controls/ColumnEditor/ColumnDrawer.svelte index 09734c2ca4..df7932c74d 100644 --- a/packages/builder/src/components/design/settings/controls/ColumnEditor/ColumnDrawer.svelte +++ b/packages/builder/src/components/design/settings/controls/ColumnEditor/ColumnDrawer.svelte @@ -145,7 +145,7 @@
- By default, all columns will automatically be shown. + The default column configuration will automatically be shown.
You can manually control which columns are included by adding them below. diff --git a/packages/builder/src/components/design/settings/controls/ColumnEditor/ColumnEditor.svelte b/packages/builder/src/components/design/settings/controls/ColumnEditor/ColumnEditor.svelte index d4190068c1..fab905e8b7 100644 --- a/packages/builder/src/components/design/settings/controls/ColumnEditor/ColumnEditor.svelte +++ b/packages/builder/src/components/design/settings/controls/ColumnEditor/ColumnEditor.svelte @@ -21,6 +21,7 @@ export let allowCellEditing = true export let allowReorder = true export let getSchemaFields = getSearchableFields + export let placeholder = "All columns" const dispatch = createEventDispatcher() @@ -45,7 +46,7 @@ const getText = value => { if (!value?.length) { - return "All columns" + return placeholder } let text = `${value.length} column` if (value.length !== 1) { diff --git a/packages/client/manifest.json b/packages/client/manifest.json index f360a837d4..b47c4a63ab 100644 --- a/packages/client/manifest.json +++ b/packages/client/manifest.json @@ -8038,7 +8038,7 @@ "value": "18px" }, { - "label": "Extra Large", + "label": "Extra large", "value": "24px" } ] @@ -8167,7 +8167,8 @@ "type": "columns/toplevel", "label": "Columns", "key": "columns", - "resetOn": "datasource" + "resetOn": "datasource", + "placeholder": "First 3 columns" }, { "type": "number", diff --git a/packages/client/src/components/app/pdf/PDFTable.svelte b/packages/client/src/components/app/pdf/PDFTable.svelte index 306756f00b..c5d92aa59a 100644 --- a/packages/client/src/components/app/pdf/PDFTable.svelte +++ b/packages/client/src/components/app/pdf/PDFTable.svelte @@ -76,19 +76,21 @@ } }) - // Clean out unselected columns - if (columns?.length) { - let pruned: Schema = {} - for (let col of columns) { - if (sanitized[col.name]) { - pruned[col.name] = { - ...sanitized[col.name], - displayName: col.displayName || sanitized[col.name].displayName, - } + // Clean out unselected columns. + // Default to first 3 columns if none specified, as we are width contrained. + if (!columns?.length) { + columns = Object.values(sanitized).slice(0, 3) + } + let pruned: Schema = {} + for (let col of columns) { + if (sanitized[col.name]) { + pruned[col.name] = { + ...sanitized[col.name], + displayName: col.displayName || sanitized[col.name].displayName, } } - sanitized = pruned } + sanitized = pruned return sanitized } @@ -131,6 +133,9 @@ padding: var(--spacing-xs) var(--spacing-s); overflow: hidden; word-break: break-word; + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 3; } .cell.header { font-weight: 600; From 7590534bb71d8cdcfd4af5c7ab9ae69f6c126f2f Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Mon, 31 Mar 2025 09:04:47 +0100 Subject: [PATCH 09/12] Update default sizing and props of PDF table --- packages/client/manifest.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/client/manifest.json b/packages/client/manifest.json index b47c4a63ab..a5557be5fb 100644 --- a/packages/client/manifest.json +++ b/packages/client/manifest.json @@ -8121,7 +8121,7 @@ "styles": ["size"], "size": { "width": 600, - "height": 400 + "height": 304 }, "grid": { "hAlign": "stretch", @@ -8174,7 +8174,7 @@ "type": "number", "label": "Limit", "key": "limit", - "defaultValue": 20 + "defaultValue": 10 } ] } From 959d49e32858d92fb2687e2e599007653cc492be Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Mon, 31 Mar 2025 09:05:06 +0100 Subject: [PATCH 10/12] Update name to PDF Table --- packages/client/manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/client/manifest.json b/packages/client/manifest.json index a5557be5fb..0afdbbc6de 100644 --- a/packages/client/manifest.json +++ b/packages/client/manifest.json @@ -8116,7 +8116,7 @@ ] }, "pdftable": { - "name": "Plain Table", + "name": "PDF Table", "icon": "Table", "styles": ["size"], "size": { From 3896a60428c01e26d2003136c259f9af16273291 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Tue, 1 Apr 2025 11:04:23 +0100 Subject: [PATCH 11/12] Reset filter and sort settings when datasource changes --- packages/client/manifest.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/client/manifest.json b/packages/client/manifest.json index 0afdbbc6de..de13a15fd5 100644 --- a/packages/client/manifest.json +++ b/packages/client/manifest.json @@ -8138,6 +8138,7 @@ "type": "filter", "label": "Filtering", "key": "filter", + "resetOn": "datasource", "dependsOn": { "setting": "datasource.type", "value": "custom", @@ -8149,6 +8150,7 @@ "label": "Sort column", "key": "sortColumn", "placeholder": "Default", + "resetOn": "datasource", "dependsOn": { "setting": "datasource.type", "value": "custom", @@ -8159,6 +8161,7 @@ "type": "select", "label": "Sort order", "key": "sortOrder", + "resetOn": "datasource", "options": ["Ascending", "Descending"], "defaultValue": "Ascending", "dependsOn": "sortColumn" From 400db88e2d0c41e93f46d5744f0491a8880274c0 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Tue, 1 Apr 2025 11:07:04 +0100 Subject: [PATCH 12/12] Don't use static white background color as we allow this component to be used anywhere --- packages/client/src/components/app/pdf/PDFTable.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/client/src/components/app/pdf/PDFTable.svelte b/packages/client/src/components/app/pdf/PDFTable.svelte index c5d92aa59a..e4d415fa01 100644 --- a/packages/client/src/components/app/pdf/PDFTable.svelte +++ b/packages/client/src/components/app/pdf/PDFTable.svelte @@ -121,7 +121,7 @@ grid-template-columns: repeat(var(--cols), minmax(40px, auto)); grid-template-rows: repeat(var(--rows), max-content); overflow: hidden; - background: white; + background: var(--spectrum-global-color-gray-50); } .table.valid { border-left: 1px solid var(--border-color);