- 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 5e27b591f8..fab905e8b7 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,18 @@
} 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
+ export let placeholder = "All columns"
const dispatch = createEventDispatcher()
@@ -28,13 +36,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(
@@ -44,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/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/builder/src/constants/index.ts b/packages/builder/src/constants/index.ts
index 3c3a6888ad..7068a1bb96 100644
--- a/packages/builder/src/constants/index.ts
+++ b/packages/builder/src/constants/index.ts
@@ -71,4 +71,5 @@ export const AutoScreenTypes = {
BLANK: "blank",
TABLE: "table",
FORM: "form",
+ PDF: "pdf",
}
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/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/_components/Screen/GeneralPanel.svelte b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/_components/Screen/GeneralPanel.svelte
index 31479bc820..1da03377b5 100644
--- a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/_components/Screen/GeneralPanel.svelte
+++ b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/_components/Screen/GeneralPanel.svelte
@@ -16,6 +16,7 @@
import { getBindableProperties } from "@/dataBinding"
import BarButtonList from "@/components/design/settings/controls/BarButtonList.svelte"
import URLVariableTestInput from "@/components/design/settings/controls/URLVariableTestInput.svelte"
+ import { DrawerBindableInput } from "@/components/common/bindings"
$: bindings = getBindableProperties($selectedScreen, null)
$: screenSettings = getScreenSettings($selectedScreen)
@@ -23,7 +24,59 @@
let errors = {}
const getScreenSettings = screen => {
- let settings = [
+ // Determine correct screen settings for the top level component
+ let screenComponentSettings = []
+ switch ($selectedScreen.props._component) {
+ case "@budibase/standard-components/pdf":
+ screenComponentSettings = [
+ {
+ key: "props.fileName",
+ label: "PDF title",
+ defaultValue: "Report",
+ control: DrawerBindableInput,
+ },
+ {
+ key: "props.buttonText",
+ label: "Button text",
+ defaultValue: "Download PDF",
+ control: DrawerBindableInput,
+ },
+ ]
+ break
+ default:
+ screenComponentSettings = [
+ {
+ key: "width",
+ label: "Width",
+ control: Select,
+ props: {
+ options: ["Extra small", "Small", "Medium", "Large", "Max"],
+ placeholder: "Default",
+ disabled: !!screen.layoutId,
+ },
+ },
+ {
+ key: "props.layout",
+ label: "Layout",
+ defaultValue: "flex",
+ control: BarButtonList,
+ props: {
+ options: [
+ {
+ barIcon: "ModernGridView",
+ value: "flex",
+ },
+ {
+ barIcon: "ViewGrid",
+ value: "grid",
+ },
+ ],
+ },
+ },
+ ]
+ }
+
+ return [
{
key: "routing.homeScreen",
control: Checkbox,
@@ -66,34 +119,7 @@
label: "On screen load",
control: ButtonActionEditor,
},
- {
- key: "width",
- label: "Width",
- control: Select,
- props: {
- options: ["Extra small", "Small", "Medium", "Large", "Max"],
- placeholder: "Default",
- disabled: !!screen.layoutId,
- },
- },
- {
- key: "props.layout",
- label: "Layout",
- defaultValue: "flex",
- control: BarButtonList,
- props: {
- options: [
- {
- barIcon: "ModernGridView",
- value: "flex",
- },
- {
- barIcon: "ViewGrid",
- value: "grid",
- },
- ],
- },
- },
+ ...screenComponentSettings,
{
key: "urlTest",
control: URLVariableTestInput,
@@ -102,8 +128,6 @@
},
},
]
-
- return settings
}
const routeTaken = url => {
diff --git a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/_components/Screen/ThemePanel.svelte b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/_components/Screen/ThemePanel.svelte
index af693a872f..c1e68010ad 100644
--- a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/_components/Screen/ThemePanel.svelte
+++ b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/_components/Screen/ThemePanel.svelte
@@ -26,7 +26,9 @@
- These settings apply to all screens
+
+ These settings apply to all screens. PDFs are always light theme.
+
diff --git a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/new/_components/NewComponentPanel.svelte b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/new/_components/NewComponentPanel.svelte
index 1654ff5e06..3dccd97701 100644
--- a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/new/_components/NewComponentPanel.svelte
+++ b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/new/_components/NewComponentPanel.svelte
@@ -58,7 +58,7 @@
// Get initial set of allowed components
let allowedComponents = []
const definition = componentStore.getDefinition(component?._component)
- if (definition.legalDirectChildren?.length) {
+ if (definition?.legalDirectChildren?.length) {
allowedComponents = definition.legalDirectChildren.map(x => {
return `@budibase/standard-components/${x}`
})
@@ -67,7 +67,7 @@
}
// Build up list of illegal children from ancestors
- let illegalChildren = definition.illegalChildren || []
+ let illegalChildren = definition?.illegalChildren || []
path.forEach(ancestor => {
// Sidepanels and modals can be nested anywhere in the component tree, but really they are always rendered at the top level.
// Because of this, it doesn't make sense to carry over any parent illegal children to them, so the array is reset here.
@@ -144,11 +144,6 @@
}
})
- // Swap blocks and plugins
- let tmp = enrichedStructure[1]
- enrichedStructure[1] = enrichedStructure[0]
- enrichedStructure[0] = tmp
-
return enrichedStructure
}
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..c4ee0c9dd4 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
@@ -20,9 +20,11 @@
"name": "Data",
"icon": "Data",
"children": [
+ "singlerowprovider",
"dataprovider",
"repeater",
"gridblock",
+ "pdftable",
"spreadsheet",
"dynamicfilter",
"daterangepicker"
diff --git a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/AppPanel.svelte b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/AppPanel.svelte
index 9dd7aab640..be409eff09 100644
--- a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/AppPanel.svelte
+++ b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/AppPanel.svelte
@@ -1,10 +1,13 @@
@@ -14,10 +17,12 @@
diff --git a/packages/builder/src/pages/builder/app/[application]/design/_components/NewScreen/CreateScreenModal.svelte b/packages/builder/src/pages/builder/app/[application]/design/_components/NewScreen/CreateScreenModal.svelte
index edc502bbb4..12186a7055 100644
--- a/packages/builder/src/pages/builder/app/[application]/design/_components/NewScreen/CreateScreenModal.svelte
+++ b/packages/builder/src/pages/builder/app/[application]/design/_components/NewScreen/CreateScreenModal.svelte
@@ -53,7 +53,7 @@
// Otherwise choose a datasource
datasourceModal.show()
}
- } else if (mode === AutoScreenTypes.BLANK) {
+ } else if (mode === AutoScreenTypes.BLANK || mode === AutoScreenTypes.PDF) {
screenDetailsModal.show()
} else {
throw new Error("Invalid mode provided")
@@ -101,8 +101,11 @@
}
}
- const createBlankScreen = async ({ route }) => {
- const screenTemplates = screenTemplating.blank({ route, screens })
+ const createBasicScreen = async ({ route }) => {
+ const screenTemplates =
+ mode === AutoScreenTypes.BLANK
+ ? screenTemplating.blank({ route, screens })
+ : screenTemplating.pdf({ route, screens })
const newScreens = await createScreens(screenTemplates)
loadNewScreen(newScreens[0])
}
@@ -243,7 +246,7 @@