1
0
Fork 0
mirror of synced 2024-07-03 05:20:32 +12:00

Merge pull request #1678 from Budibase/form-fixes

Form fixes
This commit is contained in:
Andrew Kingston 2021-06-09 14:42:59 +01:00 committed by GitHub
commit 18a78c979d
6 changed files with 41 additions and 20 deletions

View file

@ -35,6 +35,7 @@ const createScreen = table => {
const form = makeMainForm() const form = makeMainForm()
.instanceName("Form") .instanceName("Form")
.customProps({ .customProps({
actionType: "Create",
theme: "spectrum--lightest", theme: "spectrum--lightest",
size: "spectrum--medium", size: "spectrum--medium",
dataSource: { dataSource: {

View file

@ -110,6 +110,7 @@ const createScreen = table => {
const form = makeMainForm() const form = makeMainForm()
.instanceName("Form") .instanceName("Form")
.customProps({ .customProps({
actionType: "Update",
theme: "spectrum--lightest", theme: "spectrum--lightest",
size: "spectrum--medium", size: "spectrum--medium",
dataSource: { dataSource: {

View file

@ -1023,6 +1023,13 @@
"ValidateForm" "ValidateForm"
], ],
"settings": [ "settings": [
{
"type": "select",
"label": "Type",
"key": "actionType",
"options": ["Create", "Update"],
"defaultValue": "Create"
},
{ {
"type": "schema", "type": "schema",
"label": "Schema", "label": "Schema",

View file

@ -8,6 +8,7 @@
export let theme export let theme
export let size export let size
export let disabled = false export let disabled = false
export let actionType = "Create"
const component = getContext("component") const component = getContext("component")
const context = getContext("context") const context = getContext("context")
@ -19,15 +20,29 @@
let fieldMap = {} let fieldMap = {}
// Returns the closes data context which isn't a built in context // Returns the closes data context which isn't a built in context
const getInitialValues = context => { const getInitialValues = (type, dataSource, context) => {
// Only inherit values for update forms
if (type !== "Update") {
return {}
}
// Only inherit values for forms targetting internal tables
if (!dataSource?.tableId) {
return {}
}
// Don't inherit values representing built in contexts
if (["user", "url"].includes(context.closestComponentId)) { if (["user", "url"].includes(context.closestComponentId)) {
return {} return {}
} }
return context[`${context.closestComponentId}`] || {} // Only inherit values if the table ID matches
const closestContext = context[`${context.closestComponentId}`] || {}
if (dataSource.tableId !== closestContext?.tableId) {
return {}
}
return closestContext
} }
// Use the closest data context as the initial form values // Use the closest data context as the initial form values
const initialValues = getInitialValues($context) const initialValues = getInitialValues(actionType, dataSource, $context)
// Form state contains observable data about the form // Form state contains observable data about the form
const formState = writable({ values: initialValues, errors: {}, valid: true }) const formState = writable({ values: initialValues, errors: {}, valid: true })
@ -42,22 +57,11 @@
// Auto columns are always disabled // Auto columns are always disabled
const isAutoColumn = !!schema?.[field]?.autocolumn const isAutoColumn = !!schema?.[field]?.autocolumn
if (fieldMap[field] != null) {
// Update disabled property just so that toggling the disabled field
// state in the builder makes updates in real time.
// We only need this because of optimisations which prevent fully
// remounting when settings change.
fieldMap[field].fieldState.update(state => {
state.disabled = disabled || fieldDisabled || isAutoColumn
return state
})
return fieldMap[field]
}
// Create validation function based on field schema // Create validation function based on field schema
const constraints = schema?.[field]?.constraints const constraints = schema?.[field]?.constraints
const validate = createValidatorFromConstraints(constraints, field, table) const validate = createValidatorFromConstraints(constraints, field, table)
// Construct field object
fieldMap[field] = { fieldMap[field] = {
fieldState: makeFieldState( fieldState: makeFieldState(
field, field,
@ -67,6 +71,17 @@
fieldApi: makeFieldApi(field, defaultValue, validate), fieldApi: makeFieldApi(field, defaultValue, validate),
fieldSchema: schema?.[field] ?? {}, fieldSchema: schema?.[field] ?? {},
} }
// Set initial value
const initialValue = get(fieldMap[field].fieldState).value
formState.update(state => ({
...state,
values: {
...state.values,
[field]: initialValue,
},
}))
return fieldMap[field] return fieldMap[field]
}, },
validate: () => { validate: () => {

View file

@ -16,9 +16,6 @@ registerAll(hbsInstance)
* utility function to check if the object is valid * utility function to check if the object is valid
*/ */
function testObject(object) { function testObject(object) {
if (object == null) {
throw "Unable to process null object"
}
// JSON stringify will fail if there are any cycles, stops infinite recursion // JSON stringify will fail if there are any cycles, stops infinite recursion
try { try {
JSON.stringify(object) JSON.stringify(object)

View file

@ -81,14 +81,14 @@ describe("Test that the object processing works correctly", () => {
expect(error).not.toBeNull() expect(error).not.toBeNull()
}) })
it("should fail gracefully when wrong type is passed in", async () => { it("should be able to handle null objects", async () => {
let error = null let error = null
try { try {
await processObject(null, null) await processObject(null, null)
} catch (err) { } catch (err) {
error = err error = err
} }
expect(error).not.toBeNull() expect(error).toBeNull()
}) })
}) })