diff --git a/lerna.json b/lerna.json
index 7205c201e6..694a22ccc9 100644
--- a/lerna.json
+++ b/lerna.json
@@ -1,5 +1,5 @@
{
- "version": "2.9.33-alpha.3",
+ "version": "2.9.33-alpha.6",
"npmClient": "yarn",
"packages": [
"packages/*"
diff --git a/packages/bbui/src/Modal/Modal.svelte b/packages/bbui/src/Modal/Modal.svelte
index 384cfe6cac..da97bf332e 100644
--- a/packages/bbui/src/Modal/Modal.svelte
+++ b/packages/bbui/src/Modal/Modal.svelte
@@ -9,6 +9,7 @@
export let fixed = false
export let inline = false
export let disableCancel = false
+ export let autoFocus = true
const dispatch = createEventDispatcher()
let visible = fixed || inline
@@ -53,6 +54,9 @@
}
async function focusModal(node) {
+ if (!autoFocus) {
+ return
+ }
await tick()
// Try to focus first input
diff --git a/packages/bbui/src/Tabs/Tabs.svelte b/packages/bbui/src/Tabs/Tabs.svelte
index 9c3d25a807..c94b396398 100644
--- a/packages/bbui/src/Tabs/Tabs.svelte
+++ b/packages/bbui/src/Tabs/Tabs.svelte
@@ -57,10 +57,8 @@
function calculateIndicatorLength() {
if (!vertical) {
width = $tab.info?.width + "px"
- height = $tab.info?.height
} else {
height = $tab.info?.height + 4 + "px"
- width = $tab.info?.width
}
}
diff --git a/packages/builder/src/builderStore/dataBinding.js b/packages/builder/src/builderStore/dataBinding.js
index 20172e4f9c..d2f354a361 100644
--- a/packages/builder/src/builderStore/dataBinding.js
+++ b/packages/builder/src/builderStore/dataBinding.js
@@ -351,12 +351,19 @@ const getProviderContextBindings = (asset, dataProviders) => {
schema = info.schema
table = info.table
- // For JSON arrays, use the array name as the readable prefix.
- // Otherwise use the table name
+ // Determine what to prefix bindings with
if (datasource.type === "jsonarray") {
+ // For JSON arrays, use the array name as the readable prefix
const split = datasource.label.split(".")
readablePrefix = split[split.length - 1]
+ } else if (datasource.type === "viewV2") {
+ // For views, use the view name
+ const view = Object.values(table?.views || {}).find(
+ view => view.id === datasource.id
+ )
+ readablePrefix = view?.name
} else {
+ // Otherwise use the table name
readablePrefix = info.table?.name
}
}
@@ -464,7 +471,7 @@ const getComponentBindingCategory = (component, context, def) => {
*/
export const getUserBindings = () => {
let bindings = []
- const { schema } = getSchemaForTable(TableNames.USERS)
+ const { schema } = getSchemaForDatasourcePlus(TableNames.USERS)
const keys = Object.keys(schema).sort()
const safeUser = makePropSafe("user")
@@ -714,17 +721,25 @@ export const getActionBindings = (actions, actionId) => {
}
/**
- * Gets the schema for a certain table ID.
+ * Gets the schema for a certain datasource plus.
* The options which can be passed in are:
* formSchema: whether the schema is for a form
* searchableSchema: whether to generate a searchable schema, which may have
* fewer fields than a readable schema
- * @param tableId the table ID to get the schema for
+ * @param resourceId the DS+ resource ID
* @param options options for generating the schema
* @return {{schema: Object, table: Object}}
*/
-export const getSchemaForTable = (tableId, options) => {
- return getSchemaForDatasource(null, { type: "table", tableId }, options)
+export const getSchemaForDatasourcePlus = (resourceId, options) => {
+ const isViewV2 = resourceId?.includes("view_")
+ const datasource = isViewV2
+ ? {
+ type: "viewV2",
+ id: resourceId,
+ tableId: resourceId.split("_").slice(1, 3).join("_"),
+ }
+ : { type: "table", tableId: resourceId }
+ return getSchemaForDatasource(null, datasource, options)
}
/**
@@ -801,9 +816,21 @@ export const getSchemaForDatasource = (asset, datasource, options) => {
// Determine the schema from the backing entity if not already determined
if (table && !schema) {
if (type === "view") {
- // For views, the schema is pulled from the `views` property of the
- // table
+ // Old views
schema = cloneDeep(table.views?.[datasource.name]?.schema)
+ } else if (type === "viewV2") {
+ // New views which are DS+
+ const view = Object.values(table.views || {}).find(
+ view => view.id === datasource.id
+ )
+ schema = cloneDeep(view?.schema)
+
+ // Strip hidden fields
+ Object.keys(schema || {}).forEach(field => {
+ if (!schema[field].visible) {
+ delete schema[field]
+ }
+ })
} else if (
type === "query" &&
(options.formSchema || options.searchableSchema)
@@ -849,12 +876,12 @@ export const getSchemaForDatasource = (asset, datasource, options) => {
// Determine if we should add ID and rev to the schema
const isInternal = table && !table.sql
- const isTable = ["table", "link"].includes(datasource.type)
+ const isDSPlus = ["table", "link", "viewV2"].includes(datasource.type)
// ID is part of the readable schema for all tables
// Rev is part of the readable schema for internal tables only
- let addId = isTable
- let addRev = isTable && isInternal
+ let addId = isDSPlus
+ let addRev = isDSPlus && isInternal
// Don't add ID or rev for form schemas
if (options.formSchema) {
@@ -864,7 +891,7 @@ export const getSchemaForDatasource = (asset, datasource, options) => {
// ID is only searchable for internal tables
else if (options.searchableSchema) {
- addId = isTable && isInternal
+ addId = isDSPlus && isInternal
}
// Add schema properties if required
diff --git a/packages/builder/src/builderStore/store/screenTemplates/index.js b/packages/builder/src/builderStore/store/screenTemplates/index.js
index 1bf0af6eeb..3ff42fdec6 100644
--- a/packages/builder/src/builderStore/store/screenTemplates/index.js
+++ b/packages/builder/src/builderStore/store/screenTemplates/index.js
@@ -1,10 +1,10 @@
import rowListScreen from "./rowListScreen"
import createFromScratchScreen from "./createFromScratchScreen"
-const allTemplates = tables => [...rowListScreen(tables)]
+const allTemplates = datasources => [...rowListScreen(datasources)]
// Allows us to apply common behaviour to all create() functions
-const createTemplateOverride = (frontendState, template) => () => {
+const createTemplateOverride = template => () => {
const screen = template.create()
screen.name = screen.props._id
screen.routing.route = screen.routing.route.toLowerCase()
@@ -12,14 +12,13 @@ const createTemplateOverride = (frontendState, template) => () => {
return screen
}
-export default (frontendState, tables) => {
+export default datasources => {
const enrichTemplate = template => ({
...template,
- create: createTemplateOverride(frontendState, template),
+ create: createTemplateOverride(template),
})
-
const fromScratch = enrichTemplate(createFromScratchScreen)
- const tableTemplates = allTemplates(tables).map(enrichTemplate)
+ const tableTemplates = allTemplates(datasources).map(enrichTemplate)
return [
fromScratch,
...tableTemplates.sort((templateA, templateB) => {
diff --git a/packages/builder/src/builderStore/store/screenTemplates/rowListScreen.js b/packages/builder/src/builderStore/store/screenTemplates/rowListScreen.js
index 06d9e5aa3e..968d6deb4a 100644
--- a/packages/builder/src/builderStore/store/screenTemplates/rowListScreen.js
+++ b/packages/builder/src/builderStore/store/screenTemplates/rowListScreen.js
@@ -2,31 +2,26 @@ import sanitizeUrl from "./utils/sanitizeUrl"
import { Screen } from "./utils/Screen"
import { Component } from "./utils/Component"
-export default function (tables) {
- return tables.map(table => {
+export default function (datasources) {
+ return datasources.map(datasource => {
return {
- name: `${table.name} - List`,
- create: () => createScreen(table),
+ name: `${datasource.name} - List`,
+ create: () => createScreen(datasource),
id: ROW_LIST_TEMPLATE,
- table: table._id,
+ resourceId: datasource.resourceId,
}
})
}
export const ROW_LIST_TEMPLATE = "ROW_LIST_TEMPLATE"
-export const rowListUrl = table => sanitizeUrl(`/${table.name}`)
+export const rowListUrl = datasource => sanitizeUrl(`/${datasource.name}`)
-const generateTableBlock = table => {
+const generateTableBlock = datasource => {
const tableBlock = new Component("@budibase/standard-components/tableblock")
tableBlock
.customProps({
- title: table.name,
- dataSource: {
- label: table.name,
- name: table._id,
- tableId: table._id,
- type: "table",
- },
+ title: datasource.name,
+ dataSource: datasource,
sortOrder: "Ascending",
size: "spectrum--medium",
paginate: true,
@@ -36,14 +31,14 @@ const generateTableBlock = table => {
titleButtonText: "Create row",
titleButtonClickBehaviour: "new",
})
- .instanceName(`${table.name} - Table block`)
+ .instanceName(`${datasource.name} - Table block`)
return tableBlock
}
-const createScreen = table => {
+const createScreen = datasource => {
return new Screen()
- .route(rowListUrl(table))
- .instanceName(`${table.name} - List`)
- .addChild(generateTableBlock(table))
+ .route(rowListUrl(datasource))
+ .instanceName(`${datasource.name} - List`)
+ .addChild(generateTableBlock(datasource))
.json()
}
diff --git a/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte b/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte
index 6b57fe3d18..02340ab2b7 100644
--- a/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte
+++ b/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte
@@ -39,7 +39,7 @@
import FilterDrawer from "components/design/settings/controls/FilterEditor/FilterDrawer.svelte"
import { LuceneUtils } from "@budibase/frontend-core"
import {
- getSchemaForTable,
+ getSchemaForDatasourcePlus,
getEnvironmentBindings,
} from "builderStore/dataBinding"
import { Utils } from "@budibase/frontend-core"
@@ -67,7 +67,9 @@
$: table = tableId
? $tables.list.find(table => table._id === inputData.tableId)
: { schema: {} }
- $: schema = getSchemaForTable(tableId, { searchableSchema: true }).schema
+ $: schema = getSchemaForDatasourcePlus(tableId, {
+ searchableSchema: true,
+ }).schema
$: schemaFields = Object.values(schema || {})
$: queryLimit = tableId?.includes("datasource") ? "∞" : "1000"
$: isTrigger = block?.type === "TRIGGER"
@@ -158,7 +160,7 @@
// instead fetch the schema in the backend at runtime.
let schema
if (e.detail?.tableId) {
- schema = getSchemaForTable(e.detail.tableId, {
+ schema = getSchemaForDatasourcePlus(e.detail.tableId, {
searchableSchema: true,
}).schema
}
diff --git a/packages/builder/src/components/backend/DataTable/DataTable.svelte b/packages/builder/src/components/backend/DataTable/TableDataTable.svelte
similarity index 90%
rename from packages/builder/src/components/backend/DataTable/DataTable.svelte
rename to packages/builder/src/components/backend/DataTable/TableDataTable.svelte
index 38eb87aa73..e0c653e9d7 100644
--- a/packages/builder/src/components/backend/DataTable/DataTable.svelte
+++ b/packages/builder/src/components/backend/DataTable/TableDataTable.svelte
@@ -26,12 +26,14 @@
$: id = $tables.selected?._id
$: isUsersTable = id === TableNames.USERS
$: isInternal = $tables.selected?.type !== "external"
-
- $: datasource = $datasources.list.find(datasource => {
+ $: gridDatasource = {
+ type: "table",
+ tableId: id,
+ }
+ $: tableDatasource = $datasources.list.find(datasource => {
return datasource._id === $tables.selected?.sourceId
})
-
- $: relationshipsEnabled = relationshipSupport(datasource)
+ $: relationshipsEnabled = relationshipSupport(tableDatasource)
const relationshipSupport = datasource => {
const integration = $integrations[datasource?.source]
@@ -54,12 +56,12 @@
@@ -72,9 +74,7 @@
- {#if isInternal}
-
- {/if}
+
{#if relationshipsEnabled}
diff --git a/packages/builder/src/components/backend/DataTable/ViewV2DataTable.svelte b/packages/builder/src/components/backend/DataTable/ViewV2DataTable.svelte
new file mode 100644
index 0000000000..0c6a0cca9a
--- /dev/null
+++ b/packages/builder/src/components/backend/DataTable/ViewV2DataTable.svelte
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/builder/src/components/backend/DataTable/buttons/ManageAccessButton.svelte b/packages/builder/src/components/backend/DataTable/buttons/ManageAccessButton.svelte
index bc8e0c5318..f6a74784fa 100644
--- a/packages/builder/src/components/backend/DataTable/buttons/ManageAccessButton.svelte
+++ b/packages/builder/src/components/backend/DataTable/buttons/ManageAccessButton.svelte
@@ -5,6 +5,7 @@
export let resourceId
export let disabled = false
+ export let requiresLicence
let modal
let resourcePermissions
@@ -21,6 +22,7 @@
diff --git a/packages/builder/src/components/backend/DataTable/buttons/TableFilterButton.svelte b/packages/builder/src/components/backend/DataTable/buttons/TableFilterButton.svelte
index b96738ab1a..23f6d1dea1 100644
--- a/packages/builder/src/components/backend/DataTable/buttons/TableFilterButton.svelte
+++ b/packages/builder/src/components/backend/DataTable/buttons/TableFilterButton.svelte
@@ -15,6 +15,7 @@
$: tempValue = filters || []
$: schemaFields = Object.values(schema || {})
$: text = getText(filters)
+ $: selected = tempValue.filter(x => !x.onEmptyFilter)?.length > 0
const getText = filters => {
const count = filters?.filter(filter => filter.field)?.length
@@ -22,13 +23,7 @@
}
- 0}
->
+
{text}
diff --git a/packages/builder/src/components/backend/DataTable/buttons/grid/GridCreateViewButton.svelte b/packages/builder/src/components/backend/DataTable/buttons/grid/GridCreateViewButton.svelte
index 33c416d7ef..3244ce3277 100644
--- a/packages/builder/src/components/backend/DataTable/buttons/grid/GridCreateViewButton.svelte
+++ b/packages/builder/src/components/backend/DataTable/buttons/grid/GridCreateViewButton.svelte
@@ -1,7 +1,7 @@
-{#key $tableId}
+{#key $datasource}
{/key}
diff --git a/packages/builder/src/components/backend/DataTable/buttons/grid/GridImportButton.svelte b/packages/builder/src/components/backend/DataTable/buttons/grid/GridImportButton.svelte
index a0881163b4..71d971891c 100644
--- a/packages/builder/src/components/backend/DataTable/buttons/grid/GridImportButton.svelte
+++ b/packages/builder/src/components/backend/DataTable/buttons/grid/GridImportButton.svelte
@@ -4,12 +4,12 @@
export let disabled = false
- const { rows, tableId, table } = getContext("grid")
+ const { rows, datasource, definition } = getContext("grid")
diff --git a/packages/builder/src/components/backend/DataTable/buttons/grid/GridManageAccessButton.svelte b/packages/builder/src/components/backend/DataTable/buttons/grid/GridManageAccessButton.svelte
index 154007950a..e4c48528f4 100644
--- a/packages/builder/src/components/backend/DataTable/buttons/grid/GridManageAccessButton.svelte
+++ b/packages/builder/src/components/backend/DataTable/buttons/grid/GridManageAccessButton.svelte
@@ -1,8 +1,29 @@
-
+
diff --git a/packages/builder/src/components/backend/DataTable/buttons/grid/GridRelationshipButton.svelte b/packages/builder/src/components/backend/DataTable/buttons/grid/GridRelationshipButton.svelte
index 460391366f..baa7dbed14 100644
--- a/packages/builder/src/components/backend/DataTable/buttons/grid/GridRelationshipButton.svelte
+++ b/packages/builder/src/components/backend/DataTable/buttons/grid/GridRelationshipButton.svelte
@@ -2,12 +2,12 @@
import ExistingRelationshipButton from "../ExistingRelationshipButton.svelte"
import { getContext } from "svelte"
- const { table, rows } = getContext("grid")
+ const { definition, rows } = getContext("grid")
-{#if $table}
+{#if $definition}
rows.actions.refreshData()}
/>
{/if}
diff --git a/packages/builder/src/components/backend/DataTable/modals/CreateViewModal.svelte b/packages/builder/src/components/backend/DataTable/modals/CreateViewModal.svelte
deleted file mode 100644
index 8f2679f874..0000000000
--- a/packages/builder/src/components/backend/DataTable/modals/CreateViewModal.svelte
+++ /dev/null
@@ -1,38 +0,0 @@
-
-
-
-
-
diff --git a/packages/builder/src/components/backend/DataTable/modals/ManageAccessModal.svelte b/packages/builder/src/components/backend/DataTable/modals/ManageAccessModal.svelte
index aa6dbc93e0..678fb3b1c5 100644
--- a/packages/builder/src/components/backend/DataTable/modals/ManageAccessModal.svelte
+++ b/packages/builder/src/components/backend/DataTable/modals/ManageAccessModal.svelte
@@ -7,11 +7,14 @@
notifications,
Body,
ModalContent,
+ Tags,
+ Tag,
} from "@budibase/bbui"
import { capitalise } from "helpers"
export let resourceId
export let permissions
+ export let requiresLicence
async function changePermission(level, role) {
try {
@@ -30,22 +33,36 @@
}
-
- Specify the minimum access level role for this data.
-
-
-
- {#each Object.keys(permissions) as level}
-
-
+
+
+ Manage Access
+ {#if requiresLicence}
+
+
+ {requiresLicence.tier}
+
+
+ {/if}
+
+ {#if requiresLicence}
+ {requiresLicence.message}
+ {:else}
+ Specify the minimum access level role for this data.
+
+
+
+ {#each Object.keys(permissions) as level}
+
+
+ {/if}
diff --git a/packages/builder/src/components/backend/DataTable/modals/grid/GridCreateColumnModal.svelte b/packages/builder/src/components/backend/DataTable/modals/grid/GridCreateColumnModal.svelte
index 12834e6c7f..2040f66706 100644
--- a/packages/builder/src/components/backend/DataTable/modals/grid/GridCreateColumnModal.svelte
+++ b/packages/builder/src/components/backend/DataTable/modals/grid/GridCreateColumnModal.svelte
@@ -2,7 +2,7 @@
import { getContext } from "svelte"
import CreateEditColumn from "components/backend/DataTable/modals/CreateEditColumn.svelte"
- const { rows } = getContext("grid")
+ const { datasource } = getContext("grid")
-
+
diff --git a/packages/builder/src/components/backend/DataTable/modals/grid/GridCreateViewModal.svelte b/packages/builder/src/components/backend/DataTable/modals/grid/GridCreateViewModal.svelte
new file mode 100644
index 0000000000..f698a8cb97
--- /dev/null
+++ b/packages/builder/src/components/backend/DataTable/modals/grid/GridCreateViewModal.svelte
@@ -0,0 +1,60 @@
+
+
+
+
+
diff --git a/packages/builder/src/components/backend/DatasourceNavigator/DatasourceNavigator.svelte b/packages/builder/src/components/backend/DatasourceNavigator/DatasourceNavigator.svelte
index f7b6f61a10..1c264a5aaf 100644
--- a/packages/builder/src/components/backend/DatasourceNavigator/DatasourceNavigator.svelte
+++ b/packages/builder/src/components/backend/DatasourceNavigator/DatasourceNavigator.svelte
@@ -1,7 +1,14 @@
diff --git a/packages/builder/src/components/backend/TableNavigator/TableNavigator.svelte b/packages/builder/src/components/backend/TableNavigator/TableNavigator.svelte
index d9def682dc..056a36c4a7 100644
--- a/packages/builder/src/components/backend/TableNavigator/TableNavigator.svelte
+++ b/packages/builder/src/components/backend/TableNavigator/TableNavigator.svelte
@@ -1,5 +1,5 @@
{#if $database?._id}
@@ -37,18 +45,23 @@
{/if}
- {#each [...Object.keys(table.views || {})].sort() as viewName, idx (idx)}
+ {#each [...Object.entries(table.views || {})].sort() as [name, view], idx (idx)}
$goto(`./view/${encodeURIComponent(viewName)}`)}
- selectedBy={$userSelectedResourceMap[viewName]}
+ text={name}
+ selected={isViewActive(view, $isActive, $views, $viewsV2)}
+ on:click={() => {
+ if (view.version === 2) {
+ $goto(`./view/v2/${view.id}`)
+ } else {
+ $goto(`./view/v1/${encodeURIComponent(name)}`)
+ }
+ }}
+ selectedBy={$userSelectedResourceMap[name] ||
+ $userSelectedResourceMap[view.id]}
>
-
+
{/each}
{/each}
diff --git a/packages/builder/src/components/backend/TableNavigator/popovers/EditTablePopover.svelte b/packages/builder/src/components/backend/TableNavigator/popovers/EditTablePopover.svelte
index 11ef60480b..1760938c53 100644
--- a/packages/builder/src/components/backend/TableNavigator/popovers/EditTablePopover.svelte
+++ b/packages/builder/src/components/backend/TableNavigator/popovers/EditTablePopover.svelte
@@ -35,7 +35,7 @@
screen => screen.autoTableId === table._id
)
willBeDeleted = ["All table data"].concat(
- templateScreens.map(screen => `Screen ${screen.props._instanceName}`)
+ templateScreens.map(screen => `Screen ${screen.routing?.route || ""}`)
)
confirmDeleteDialog.show()
}
@@ -44,7 +44,10 @@
const isSelected = $params.tableId === table._id
try {
await tables.delete(table)
- await store.actions.screens.delete(templateScreens)
+ // Screens need deleted one at a time because of undo/redo
+ for (let screen of templateScreens) {
+ await store.actions.screens.delete(screen)
+ }
if (table.type === "external") {
await datasources.fetch()
}
diff --git a/packages/builder/src/components/backend/TableNavigator/popovers/EditViewPopover.svelte b/packages/builder/src/components/backend/TableNavigator/popovers/EditViewPopover.svelte
index 99f19935a1..5e2b0102f8 100644
--- a/packages/builder/src/components/backend/TableNavigator/popovers/EditViewPopover.svelte
+++ b/packages/builder/src/components/backend/TableNavigator/popovers/EditViewPopover.svelte
@@ -1,6 +1,5 @@
@@ -15,9 +23,9 @@