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