Merge pull request #8219 from Budibase/feature/blocks-in-auto-screens
Component Blocks in CRUD Auto-screens
This commit is contained in:
commit
bebeccef12
|
@ -1,13 +1,8 @@
|
|||
import sanitizeUrl from "./utils/sanitizeUrl"
|
||||
import { Screen } from "./utils/Screen"
|
||||
import { Component } from "./utils/Component"
|
||||
import {
|
||||
makeBreadcrumbContainer,
|
||||
makeMainForm,
|
||||
makeTitleContainer,
|
||||
makeSaveButton,
|
||||
makeDatasourceFormComponents,
|
||||
} from "./utils/commonComponents"
|
||||
import { makeBreadcrumbContainer } from "./utils/commonComponents"
|
||||
import { getSchemaForDatasource } from "../../dataBinding"
|
||||
|
||||
export default function (tables) {
|
||||
return tables.map(table => {
|
||||
|
@ -23,48 +18,55 @@ export default function (tables) {
|
|||
export const newRowUrl = table => sanitizeUrl(`/${table.name}/new/row`)
|
||||
export const NEW_ROW_TEMPLATE = "NEW_ROW_TEMPLATE"
|
||||
|
||||
function generateTitleContainer(table, formId) {
|
||||
return makeTitleContainer("New Row").addChild(makeSaveButton(table, formId))
|
||||
const rowListUrl = table => sanitizeUrl(`/${table.name}`)
|
||||
|
||||
const getFields = schema => {
|
||||
let columns = []
|
||||
Object.entries(schema || {}).forEach(([field, fieldSchema]) => {
|
||||
if (!field || !fieldSchema) {
|
||||
return
|
||||
}
|
||||
if (!fieldSchema?.autocolumn) {
|
||||
columns.push(field)
|
||||
}
|
||||
})
|
||||
return columns
|
||||
}
|
||||
|
||||
const createScreen = table => {
|
||||
const screen = new Screen()
|
||||
.instanceName(`${table.name} - New`)
|
||||
.customProps({
|
||||
hAlign: "center",
|
||||
})
|
||||
.route(newRowUrl(table))
|
||||
|
||||
const form = makeMainForm()
|
||||
.instanceName("Form")
|
||||
const generateFormBlock = table => {
|
||||
const datasource = { type: "table", tableId: table._id }
|
||||
const { schema } = getSchemaForDatasource(null, datasource, {
|
||||
formSchema: true,
|
||||
})
|
||||
const formBlock = new Component("@budibase/standard-components/formblock")
|
||||
formBlock
|
||||
.customProps({
|
||||
title: "New row",
|
||||
actionType: "Create",
|
||||
actionUrl: rowListUrl(table),
|
||||
showDeleteButton: false,
|
||||
showSaveButton: true,
|
||||
fields: getFields(schema),
|
||||
dataSource: {
|
||||
label: table.name,
|
||||
tableId: table._id,
|
||||
type: "table",
|
||||
},
|
||||
labelPosition: "left",
|
||||
size: "spectrum--medium",
|
||||
})
|
||||
|
||||
const fieldGroup = new Component("@budibase/standard-components/fieldgroup")
|
||||
.instanceName("Field Group")
|
||||
.customProps({
|
||||
labelPosition: "left",
|
||||
})
|
||||
|
||||
// Add all form fields from this schema to the field group
|
||||
const datasource = { type: "table", tableId: table._id }
|
||||
makeDatasourceFormComponents(datasource).forEach(component => {
|
||||
fieldGroup.addChild(component)
|
||||
})
|
||||
|
||||
// Add all children to the form
|
||||
const formId = form._json._id
|
||||
form
|
||||
.addChild(makeBreadcrumbContainer(table.name, "New"))
|
||||
.addChild(generateTitleContainer(table, formId))
|
||||
.addChild(fieldGroup)
|
||||
|
||||
return screen.addChild(form).json()
|
||||
.instanceName(`${table.name} - Form block`)
|
||||
return formBlock
|
||||
}
|
||||
|
||||
const createScreen = table => {
|
||||
const formBlock = generateFormBlock(table)
|
||||
const screen = new Screen()
|
||||
.instanceName(`${table.name} - New`)
|
||||
.route(newRowUrl(table))
|
||||
|
||||
return screen
|
||||
.addChild(makeBreadcrumbContainer(table.name, "New row"))
|
||||
.addChild(formBlock)
|
||||
.json()
|
||||
}
|
||||
|
|
|
@ -1,15 +1,8 @@
|
|||
import sanitizeUrl from "./utils/sanitizeUrl"
|
||||
import { rowListUrl } from "./rowListScreen"
|
||||
import { Screen } from "./utils/Screen"
|
||||
import { Component } from "./utils/Component"
|
||||
import { makePropSafe } from "@budibase/string-templates"
|
||||
import {
|
||||
makeBreadcrumbContainer,
|
||||
makeTitleContainer,
|
||||
makeSaveButton,
|
||||
makeMainForm,
|
||||
makeDatasourceFormComponents,
|
||||
} from "./utils/commonComponents"
|
||||
import { makeBreadcrumbContainer } from "./utils/commonComponents"
|
||||
import { getSchemaForDatasource } from "../../dataBinding"
|
||||
|
||||
export default function (tables) {
|
||||
return tables.map(table => {
|
||||
|
@ -25,125 +18,53 @@ export default function (tables) {
|
|||
export const ROW_DETAIL_TEMPLATE = "ROW_DETAIL_TEMPLATE"
|
||||
export const rowDetailUrl = table => sanitizeUrl(`/${table.name}/:id`)
|
||||
|
||||
function generateTitleContainer(table, title, formId, repeaterId) {
|
||||
const saveButton = makeSaveButton(table, formId)
|
||||
const deleteButton = new Component("@budibase/standard-components/button")
|
||||
.text("Delete")
|
||||
.customProps({
|
||||
type: "secondary",
|
||||
quiet: true,
|
||||
size: "M",
|
||||
onClick: [
|
||||
{
|
||||
parameters: {
|
||||
tableId: table._id,
|
||||
rowId: `{{ ${makePropSafe(repeaterId)}.${makePropSafe("_id")} }}`,
|
||||
revId: `{{ ${makePropSafe(repeaterId)}.${makePropSafe("_rev")} }}`,
|
||||
confirm: true,
|
||||
},
|
||||
"##eventHandlerType": "Delete Row",
|
||||
},
|
||||
{
|
||||
parameters: {
|
||||
url: rowListUrl(table),
|
||||
},
|
||||
"##eventHandlerType": "Navigate To",
|
||||
},
|
||||
],
|
||||
})
|
||||
.instanceName("Delete Button")
|
||||
const rowListUrl = table => sanitizeUrl(`/${table.name}`)
|
||||
|
||||
const buttons = new Component("@budibase/standard-components/container")
|
||||
.instanceName("Button Container")
|
||||
.customProps({
|
||||
direction: "row",
|
||||
hAlign: "right",
|
||||
vAlign: "middle",
|
||||
size: "shrink",
|
||||
gap: "M",
|
||||
})
|
||||
.addChild(deleteButton)
|
||||
.addChild(saveButton)
|
||||
const getFields = schema => {
|
||||
let columns = []
|
||||
Object.entries(schema || {}).forEach(([field, fieldSchema]) => {
|
||||
if (!field || !fieldSchema) {
|
||||
return
|
||||
}
|
||||
if (!fieldSchema?.autocolumn) {
|
||||
columns.push(field)
|
||||
}
|
||||
})
|
||||
return columns
|
||||
}
|
||||
|
||||
return makeTitleContainer(title).addChild(buttons)
|
||||
const generateFormBlock = table => {
|
||||
const datasource = { type: "table", tableId: table._id }
|
||||
const { schema } = getSchemaForDatasource(null, datasource, {
|
||||
formSchema: true,
|
||||
})
|
||||
|
||||
const formBlock = new Component("@budibase/standard-components/formblock")
|
||||
formBlock
|
||||
.customProps({
|
||||
title: "Edit row",
|
||||
actionType: "Update",
|
||||
actionUrl: rowListUrl(table),
|
||||
showDeleteButton: true,
|
||||
showSaveButton: true,
|
||||
fields: getFields(schema),
|
||||
dataSource: {
|
||||
label: table.name,
|
||||
tableId: table._id,
|
||||
type: "table",
|
||||
},
|
||||
labelPosition: "left",
|
||||
size: "spectrum--medium",
|
||||
})
|
||||
.instanceName(`${table.name} - Form block`)
|
||||
return formBlock
|
||||
}
|
||||
|
||||
const createScreen = table => {
|
||||
const provider = new Component("@budibase/standard-components/dataprovider")
|
||||
.instanceName(`Data Provider`)
|
||||
.customProps({
|
||||
dataSource: {
|
||||
label: table.name,
|
||||
name: table._id,
|
||||
tableId: table._id,
|
||||
type: "table",
|
||||
},
|
||||
filter: [
|
||||
{
|
||||
field: "_id",
|
||||
operator: "equal",
|
||||
type: "string",
|
||||
value: `{{ ${makePropSafe("url")}.${makePropSafe("id")} }}`,
|
||||
valueType: "Binding",
|
||||
},
|
||||
],
|
||||
limit: 1,
|
||||
paginate: false,
|
||||
})
|
||||
|
||||
const repeater = new Component("@budibase/standard-components/repeater")
|
||||
.instanceName("Repeater")
|
||||
.customProps({
|
||||
dataProvider: `{{ literal ${makePropSafe(provider._json._id)} }}`,
|
||||
noRowsMessage: "We couldn't find a row to display",
|
||||
})
|
||||
|
||||
const form = makeMainForm()
|
||||
.instanceName("Form")
|
||||
.customProps({
|
||||
actionType: "Update",
|
||||
size: "spectrum--medium",
|
||||
dataSource: {
|
||||
label: table.name,
|
||||
tableId: table._id,
|
||||
type: "table",
|
||||
},
|
||||
})
|
||||
|
||||
const fieldGroup = new Component("@budibase/standard-components/fieldgroup")
|
||||
.instanceName("Field Group")
|
||||
.customProps({
|
||||
labelPosition: "left",
|
||||
})
|
||||
|
||||
// Add all form fields from this schema to the field group
|
||||
const datasource = { type: "table", tableId: table._id }
|
||||
makeDatasourceFormComponents(datasource).forEach(component => {
|
||||
fieldGroup.addChild(component)
|
||||
})
|
||||
|
||||
// Add all children to the form
|
||||
const formId = form._json._id
|
||||
const repeaterId = repeater._json._id
|
||||
const heading = table.primaryDisplay
|
||||
? `{{ ${makePropSafe(repeaterId)}.${makePropSafe(table.primaryDisplay)} }}`
|
||||
: null
|
||||
form
|
||||
.addChild(makeBreadcrumbContainer(table.name, heading || "Edit"))
|
||||
.addChild(
|
||||
generateTitleContainer(table, heading || "Edit Row", formId, repeaterId)
|
||||
)
|
||||
.addChild(fieldGroup)
|
||||
|
||||
repeater.addChild(form)
|
||||
provider.addChild(repeater)
|
||||
|
||||
return new Screen()
|
||||
.instanceName(`${table.name} - Detail`)
|
||||
.route(rowDetailUrl(table))
|
||||
.customProps({
|
||||
hAlign: "center",
|
||||
})
|
||||
.addChild(provider)
|
||||
.addChild(makeBreadcrumbContainer(table.name, "Edit row"))
|
||||
.addChild(generateFormBlock(table))
|
||||
.json()
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@ import sanitizeUrl from "./utils/sanitizeUrl"
|
|||
import { newRowUrl } from "./newRowScreen"
|
||||
import { Screen } from "./utils/Screen"
|
||||
import { Component } from "./utils/Component"
|
||||
import { makePropSafe } from "@budibase/string-templates"
|
||||
|
||||
export default function (tables) {
|
||||
return tables.map(table => {
|
||||
|
@ -18,48 +17,17 @@ export default function (tables) {
|
|||
export const ROW_LIST_TEMPLATE = "ROW_LIST_TEMPLATE"
|
||||
export const rowListUrl = table => sanitizeUrl(`/${table.name}`)
|
||||
|
||||
function generateTitleContainer(table) {
|
||||
const newButton = new Component("@budibase/standard-components/button")
|
||||
.text("Create New")
|
||||
.customProps({
|
||||
size: "M",
|
||||
type: "primary",
|
||||
onClick: [
|
||||
{
|
||||
parameters: {
|
||||
url: newRowUrl(table),
|
||||
},
|
||||
"##eventHandlerType": "Navigate To",
|
||||
},
|
||||
],
|
||||
})
|
||||
.instanceName("New Button")
|
||||
|
||||
const heading = new Component("@budibase/standard-components/heading")
|
||||
.instanceName("Title")
|
||||
.text(table.name)
|
||||
.customProps({
|
||||
size: "M",
|
||||
align: "left",
|
||||
})
|
||||
|
||||
return new Component("@budibase/standard-components/container")
|
||||
.customProps({
|
||||
direction: "row",
|
||||
hAlign: "stretch",
|
||||
vAlign: "middle",
|
||||
size: "shrink",
|
||||
gap: "M",
|
||||
})
|
||||
.instanceName("Title Container")
|
||||
.addChild(heading)
|
||||
.addChild(newButton)
|
||||
}
|
||||
|
||||
const createScreen = table => {
|
||||
const provider = new Component("@budibase/standard-components/dataprovider")
|
||||
.instanceName(`Data Provider`)
|
||||
const generateTableBlock = table => {
|
||||
const tableBlock = new Component("@budibase/standard-components/tableblock")
|
||||
tableBlock
|
||||
.customProps({
|
||||
linkRows: true,
|
||||
linkURL: `${rowListUrl(table)}/:id`,
|
||||
showAutoColumns: false,
|
||||
showTitleButton: true,
|
||||
titleButtonText: "Create new",
|
||||
titleButtonURL: newRowUrl(table),
|
||||
title: table.name,
|
||||
dataSource: {
|
||||
label: table.name,
|
||||
name: table._id,
|
||||
|
@ -68,41 +36,16 @@ const createScreen = table => {
|
|||
},
|
||||
size: "spectrum--medium",
|
||||
paginate: true,
|
||||
limit: 8,
|
||||
})
|
||||
|
||||
const spectrumTable = new Component("@budibase/standard-components/table")
|
||||
.customProps({
|
||||
dataProvider: `{{ literal ${makePropSafe(provider._json._id)} }}`,
|
||||
showAutoColumns: false,
|
||||
quiet: false,
|
||||
rowCount: 8,
|
||||
})
|
||||
.instanceName(`${table.name} Table`)
|
||||
|
||||
const safeTableId = makePropSafe(spectrumTable._json._id)
|
||||
const safeRowId = makePropSafe("_id")
|
||||
const viewLink = new Component("@budibase/standard-components/link")
|
||||
.customProps({
|
||||
text: "View",
|
||||
url: `${rowListUrl(table)}/{{ ${safeTableId}.${safeRowId} }}`,
|
||||
size: "S",
|
||||
color: "var(--spectrum-global-color-gray-600)",
|
||||
align: "left",
|
||||
})
|
||||
.normalStyle({
|
||||
["margin-left"]: "16px",
|
||||
["margin-right"]: "16px",
|
||||
})
|
||||
.instanceName("View Link")
|
||||
|
||||
spectrumTable.addChild(viewLink)
|
||||
provider.addChild(spectrumTable)
|
||||
.instanceName(`${table.name} - Table block`)
|
||||
return tableBlock
|
||||
}
|
||||
|
||||
const createScreen = table => {
|
||||
return new Screen()
|
||||
.route(rowListUrl(table))
|
||||
.instanceName(`${table.name} - List`)
|
||||
.addChild(generateTitleContainer(table))
|
||||
.addChild(provider)
|
||||
.addChild(generateTableBlock(table))
|
||||
.json()
|
||||
}
|
||||
|
|
|
@ -65,6 +65,11 @@ export function makeBreadcrumbContainer(tableName, text) {
|
|||
vAlign: "middle",
|
||||
size: "shrink",
|
||||
})
|
||||
.normalStyle({
|
||||
width: "600px",
|
||||
"margin-right": "auto",
|
||||
"margin-left": "auto",
|
||||
})
|
||||
.instanceName("Breadcrumbs")
|
||||
.addChild(link)
|
||||
.addChild(arrowText)
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
export let rowId
|
||||
export let actionUrl
|
||||
|
||||
const { fetchDatasourceSchema, builderStore } = getContext("sdk")
|
||||
const { fetchDatasourceSchema } = getContext("sdk")
|
||||
const FieldTypeToComponentMap = {
|
||||
string: "stringfield",
|
||||
number: "numberfield",
|
||||
|
@ -29,6 +29,7 @@
|
|||
attachment: "attachmentfield",
|
||||
link: "relationshipfield",
|
||||
json: "jsonfield",
|
||||
barcodeqr: "codescanner",
|
||||
}
|
||||
|
||||
let schema
|
||||
|
@ -80,7 +81,7 @@
|
|||
field: "_id",
|
||||
operator: "equal",
|
||||
type: "string",
|
||||
value: rowId,
|
||||
value: !rowId ? `{{ ${safe("url")}.${safe("id")} }}` : rowId,
|
||||
valueType: "Binding",
|
||||
},
|
||||
]
|
||||
|
@ -118,7 +119,7 @@
|
|||
props={{
|
||||
dataSource,
|
||||
filter,
|
||||
limit: rowId ? 1 : $builderStore.inBuilder ? 1 : 0,
|
||||
limit: 1,
|
||||
paginate: false,
|
||||
}}
|
||||
>
|
||||
|
@ -129,6 +130,8 @@
|
|||
props={{
|
||||
dataProvider,
|
||||
noRowsMessage: "We couldn't find a row to display",
|
||||
direction: "column",
|
||||
hAlign: "center",
|
||||
}}
|
||||
>
|
||||
<BlockComponent
|
||||
|
@ -139,6 +142,11 @@
|
|||
size,
|
||||
disabled: disabled || actionType === "View",
|
||||
}}
|
||||
styles={{
|
||||
normal: {
|
||||
width: "600px",
|
||||
},
|
||||
}}
|
||||
context="form"
|
||||
bind:id={formId}
|
||||
>
|
||||
|
|
Loading…
Reference in New Issue