diff --git a/packages/builder/src/helpers/components.js b/packages/builder/src/helpers/components.js index 872a9441a4..ca1be3c736 100644 --- a/packages/builder/src/helpers/components.js +++ b/packages/builder/src/helpers/components.js @@ -213,7 +213,7 @@ export const getComponentText = component => { return component._instanceName } const type = - component._component.replace("@budibase/standard-components/", "") || + component._component?.replace("@budibase/standard-components/", "") || "component" return capitalise(type) } 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 39026af6d0..47d7c765d6 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 @@ -103,21 +103,23 @@ const createBlankScreen = async ({ route }) => { const screenTemplates = screenTemplating.blank({ route, screens }) - const newScreens = await createScreens(screenTemplates) loadNewScreen(newScreens[0]) } const createTableScreen = async type => { - const screenTemplates = selectedTablesAndViews.flatMap(tableOrView => - screenTemplating.table({ - screens, - tableOrView, - type, - permissions: permissions[tableOrView.id], - }) - ) - + const screenTemplates = ( + await Promise.all( + selectedTablesAndViews.map(tableOrView => + screenTemplating.table({ + screens, + tableOrView, + type, + permissions: permissions[tableOrView.id], + }) + ) + ) + ).flat() const newScreens = await createScreens(screenTemplates) loadNewScreen(newScreens[0]) } diff --git a/packages/builder/src/templates/screenTemplating/table/index.js b/packages/builder/src/templates/screenTemplating/table/index.js index 40cfde6f15..a94c7745bc 100644 --- a/packages/builder/src/templates/screenTemplating/table/index.js +++ b/packages/builder/src/templates/screenTemplating/table/index.js @@ -2,21 +2,22 @@ import inline from "./inline" import modal from "./modal" import sidePanel from "./sidePanel" import newScreen from "./newScreen" +import { getRowActionButtonTemplates } from "templates/rowActions" -const createScreen = ({ tableOrView, type, permissions, screens }) => { +const createScreen = async ({ tableOrView, type, permissions, screens }) => { if (type === "inline") { - return inline({ tableOrView, permissions, screens }) + return await inline({ tableOrView, permissions, screens }) } if (type === "modal") { - return modal({ tableOrView, permissions, screens }) + return await modal({ tableOrView, permissions, screens }) } if (type === "sidePanel") { - return sidePanel({ tableOrView, permissions, screens }) + return await sidePanel({ tableOrView, permissions, screens }) } if (type === "newScreen") { - return newScreen({ tableOrView, permissions, screens }) + return await newScreen({ tableOrView, permissions, screens }) } throw new Error(`Unrecognized table type ${type}`) diff --git a/packages/builder/src/templates/screenTemplating/table/inline.js b/packages/builder/src/templates/screenTemplating/table/inline.js index d218aa998a..b7e0dd58b8 100644 --- a/packages/builder/src/templates/screenTemplating/table/inline.js +++ b/packages/builder/src/templates/screenTemplating/table/inline.js @@ -2,8 +2,9 @@ import { Screen } from "../Screen" import { Component } from "../../Component" import { capitalise } from "helpers" import getValidRoute from "../getValidRoute" +import { getRowActionButtonTemplates } from "templates/rowActions" -const inline = ({ tableOrView, permissions, screens }) => { +const inline = async ({ tableOrView, permissions, screens }) => { const heading = new Component("@budibase/standard-components/heading") .instanceName("Table heading") .customProps({ @@ -12,7 +13,7 @@ const inline = ({ tableOrView, permissions, screens }) => { .gridDesktopColSpan(1, 13) .gridDesktopRowSpan(1, 3) - const tableBlock = new Component("@budibase/standard-components/gridblock") + let tableBlock = new Component("@budibase/standard-components/gridblock") .instanceName(`${tableOrView.name} - Table`) .customProps({ table: tableOrView.datasourceSelectFormat, @@ -20,6 +21,17 @@ const inline = ({ tableOrView, permissions, screens }) => { .gridDesktopColSpan(1, 13) .gridDesktopRowSpan(3, 21) + // Add row actions to table + const rowActionButtons = await getRowActionButtonTemplates({ + instance: tableBlock.json(), + }) + if (rowActionButtons.length) { + tableBlock = tableBlock.customProps({ + buttons: rowActionButtons, + buttonsCollapsed: rowActionButtons.length > 1, + }) + } + const screenTemplate = new Screen() .route(getValidRoute(screens, tableOrView.name, permissions.write)) .instanceName(`${tableOrView.name} - List`) diff --git a/packages/builder/src/templates/screenTemplating/table/modal.js b/packages/builder/src/templates/screenTemplating/table/modal.js index caf1582fbb..6a97979b31 100644 --- a/packages/builder/src/templates/screenTemplating/table/modal.js +++ b/packages/builder/src/templates/screenTemplating/table/modal.js @@ -5,8 +5,9 @@ import { makePropSafe as safe } from "@budibase/string-templates" import { Utils } from "@budibase/frontend-core" import { capitalise } from "helpers" import getValidRoute from "../getValidRoute" +import { getRowActionButtonTemplates } from "templates/rowActions" -const modal = ({ tableOrView, permissions, screens }) => { +const modal = async ({ tableOrView, permissions, screens }) => { /* Create Row */ @@ -56,7 +57,7 @@ const modal = ({ tableOrView, permissions, screens }) => { createFormBlock.instanceName("Create row form block").customProps({ dataSource: tableOrView.tableSelectFormat, labelPosition: "left", - buttonPosition: "top", + buttonPosition: "bottom", actionType: "Create", title: "Create row", buttons: Utils.buildFormBlockButtonConfig({ @@ -81,23 +82,34 @@ const modal = ({ tableOrView, permissions, screens }) => { size: "large", }) - const editFormBlock = new Component("@budibase/standard-components/formblock") - editFormBlock.instanceName("Edit row form block").customProps({ - dataSource: tableOrView.tableSelectFormat, - labelPosition: "left", - buttonPosition: "top", - actionType: "Update", - title: "Edit", - rowId: `{{ ${safe("state")}.${safe(stateKey)} }}`, - buttons: Utils.buildFormBlockButtonConfig({ - _id: editFormBlock._json._id, - showDeleteButton: true, - showSaveButton: true, - saveButtonLabel: "Save", - deleteButtonLabel: "Delete", - actionType: "Update", + let editFormBlock = new Component("@budibase/standard-components/formblock") + .instanceName("Edit row form block") + .customProps({ dataSource: tableOrView.tableSelectFormat, - }), + labelPosition: "left", + buttonPosition: "bottom", + actionType: "Update", + title: "Edit", + rowId: `{{ ${safe("state")}.${safe(stateKey)} }}`, + }) + + // Generate button config including row actions + let buttons = Utils.buildFormBlockButtonConfig({ + _id: editFormBlock._json._id, + showDeleteButton: true, + showSaveButton: true, + saveButtonLabel: "Save", + deleteButtonLabel: "Delete", + actionType: "Update", + dataSource: tableOrView.tableSelectFormat, + }) + const rowActionButtons = await getRowActionButtonTemplates({ + instance: editFormBlock.json(), + }) + buttons = [...(buttons || []), ...rowActionButtons] + editFormBlock = editFormBlock.customProps({ + buttons, + buttonsCollapsed: buttons.length > 5, }) detailsModal.addChild(editFormBlock) diff --git a/packages/builder/src/templates/screenTemplating/table/newScreen.js b/packages/builder/src/templates/screenTemplating/table/newScreen.js index 34026bca7f..b8b06d3d44 100644 --- a/packages/builder/src/templates/screenTemplating/table/newScreen.js +++ b/packages/builder/src/templates/screenTemplating/table/newScreen.js @@ -4,6 +4,7 @@ import { capitalise } from "helpers" import { makePropSafe as safe } from "@budibase/string-templates" import getValidRoute from "../getValidRoute" import { Helpers } from "@budibase/bbui" +import { getRowActionButtonTemplates } from "templates/rowActions" const getTableScreenTemplate = ({ route, @@ -92,7 +93,7 @@ const getTableScreenTemplate = ({ } } -const getUpdateScreenTemplate = ({ +const getUpdateScreenTemplate = async ({ route, tableScreenRoute, tableOrView, @@ -102,27 +103,11 @@ const getUpdateScreenTemplate = ({ const formId = `${formBlockId}-form` const repeaterId = `${formBlockId}-repeater` - const backButton = new Component("@budibase/standard-components/button") - .instanceName("Back button") - .customProps({ - type: "primary", - icon: "ri-arrow-go-back-fill", - text: "Back", - onClick: [ - { - "##eventHandlerType": "Navigate To", - parameters: { - type: "url", - url: tableScreenRoute, - }, - }, - ], - }) - const deleteButton = new Component("@budibase/standard-components/button") .instanceName("Delete button") .customProps({ - type: "secondary", + type: "warning", + quiet: true, text: "Delete", onClick: [ { @@ -173,7 +158,7 @@ const getUpdateScreenTemplate = ({ ], }) - const updateFormBlock = new Component( + let updateFormBlock = new Component( "@budibase/standard-components/formblock", formBlockId ) @@ -181,12 +166,22 @@ const getUpdateScreenTemplate = ({ .customProps({ dataSource: tableOrView.tableSelectFormat, labelPosition: "left", - buttonPosition: "top", + buttonPosition: "bottom", actionType: "Update", title: `Update ${tableOrView.name} row`, - buttons: [backButton.json(), saveButton.json(), deleteButton.json()], }) + // Generate button config including row actions + let buttons = [saveButton.json(), deleteButton.json()] + const rowActionButtons = await getRowActionButtonTemplates({ + instance: updateFormBlock.json(), + }) + buttons = [...(buttons || []), ...rowActionButtons] + updateFormBlock = updateFormBlock.customProps({ + buttons, + buttonsCollapsed: buttons.length > 5, + }) + const template = new Screen() .route(route) .instanceName(`Update row`) @@ -210,23 +205,6 @@ const getCreateScreenTemplate = ({ const formBlockId = Helpers.uuid() const formId = `${formBlockId}-form` - const backButton = new Component("@budibase/standard-components/button") - .instanceName("Back button") - .customProps({ - type: "primary", - icon: "ri-arrow-go-back-fill", - text: "Back", - onClick: [ - { - "##eventHandlerType": "Navigate To", - parameters: { - type: "url", - url: tableScreenRoute, - }, - }, - ], - }) - const saveButton = new Component("@budibase/standard-components/button") .instanceName("Save button") .customProps({ @@ -264,10 +242,10 @@ const getCreateScreenTemplate = ({ .customProps({ dataSource: tableOrView.tableSelectFormat, labelPosition: "left", - buttonPosition: "top", + buttonPosition: "bottom", actionType: "Create", title: `Create ${tableOrView.name} row`, - buttons: [backButton.json(), saveButton.json()], + buttons: [saveButton.json()], }) const template = new Screen() @@ -284,7 +262,7 @@ const getCreateScreenTemplate = ({ } } -const newScreen = ({ tableOrView, permissions, screens }) => { +const newScreen = async ({ tableOrView, permissions, screens }) => { const tableScreenRoute = getValidRoute( screens, tableOrView.name, @@ -312,7 +290,7 @@ const newScreen = ({ tableOrView, permissions, screens }) => { gridLayout: true, }) - const updateScreenTemplate = getUpdateScreenTemplate({ + const updateScreenTemplate = await getUpdateScreenTemplate({ route: updateScreenRoute, tableScreenRoute, tableOrView, diff --git a/packages/builder/src/templates/screenTemplating/table/sidePanel.js b/packages/builder/src/templates/screenTemplating/table/sidePanel.js index ef88597733..139b117d1b 100644 --- a/packages/builder/src/templates/screenTemplating/table/sidePanel.js +++ b/packages/builder/src/templates/screenTemplating/table/sidePanel.js @@ -5,8 +5,9 @@ import { makePropSafe as safe } from "@budibase/string-templates" import { Utils } from "@budibase/frontend-core" import { capitalise } from "helpers" import getValidRoute from "../getValidRoute" +import { getRowActionButtonTemplates } from "templates/rowActions" -const sidePanel = ({ tableOrView, permissions, screens }) => { +const sidePanel = async ({ tableOrView, permissions, screens }) => { /* Create Row */ @@ -54,7 +55,7 @@ const sidePanel = ({ tableOrView, permissions, screens }) => { createFormBlock.instanceName("Create row form block").customProps({ dataSource: tableOrView.tableSelectFormat, labelPosition: "left", - buttonPosition: "top", + buttonPosition: "bottom", actionType: "Create", title: "Create row", buttons: Utils.buildFormBlockButtonConfig({ @@ -77,23 +78,33 @@ const sidePanel = ({ tableOrView, permissions, screens }) => { "@budibase/standard-components/sidepanel" ).instanceName("Edit row side panel") - const editFormBlock = new Component("@budibase/standard-components/formblock") + let editFormBlock = new Component("@budibase/standard-components/formblock") editFormBlock.instanceName("Edit row form block").customProps({ dataSource: tableOrView.tableSelectFormat, labelPosition: "left", - buttonPosition: "top", + buttonPosition: "bottom", actionType: "Update", title: "Edit", rowId: `{{ ${safe("state")}.${safe(stateKey)} }}`, - buttons: Utils.buildFormBlockButtonConfig({ - _id: editFormBlock._json._id, - showDeleteButton: true, - showSaveButton: true, - saveButtonLabel: "Save", - deleteButtonLabel: "Delete", - actionType: "Update", - dataSource: tableOrView.tableSelectFormat, - }), + }) + + // Generate button config including row actions + let buttons = Utils.buildFormBlockButtonConfig({ + _id: editFormBlock._json._id, + showDeleteButton: true, + showSaveButton: true, + saveButtonLabel: "Save", + deleteButtonLabel: "Delete", + actionType: "Update", + dataSource: tableOrView.tableSelectFormat, + }) + const rowActionButtons = await getRowActionButtonTemplates({ + instance: editFormBlock.json(), + }) + buttons = [...(buttons || []), ...rowActionButtons] + editFormBlock = editFormBlock.customProps({ + buttons, + buttonsCollapsed: buttons.length > 5, }) detailsSidePanel.addChild(editFormBlock)