diff --git a/packages/builder/src/builderStore/store/screenTemplates/newRowScreen.js b/packages/builder/src/builderStore/store/screenTemplates/newRowScreen.js index be399b4bb8..980f71742b 100644 --- a/packages/builder/src/builderStore/store/screenTemplates/newRowScreen.js +++ b/packages/builder/src/builderStore/store/screenTemplates/newRowScreen.js @@ -35,6 +35,7 @@ const createScreen = table => { const form = makeMainForm() .instanceName("Form") .customProps({ + actionType: "Create", theme: "spectrum--lightest", size: "spectrum--medium", dataSource: { diff --git a/packages/builder/src/builderStore/store/screenTemplates/rowDetailScreen.js b/packages/builder/src/builderStore/store/screenTemplates/rowDetailScreen.js index b0cf694a5d..f15f1de5a4 100644 --- a/packages/builder/src/builderStore/store/screenTemplates/rowDetailScreen.js +++ b/packages/builder/src/builderStore/store/screenTemplates/rowDetailScreen.js @@ -110,6 +110,7 @@ const createScreen = table => { const form = makeMainForm() .instanceName("Form") .customProps({ + actionType: "Update", theme: "spectrum--lightest", size: "spectrum--medium", dataSource: { diff --git a/packages/standard-components/manifest.json b/packages/standard-components/manifest.json index 8f0f63f681..81aa63e1e3 100644 --- a/packages/standard-components/manifest.json +++ b/packages/standard-components/manifest.json @@ -1023,6 +1023,13 @@ "ValidateForm" ], "settings": [ + { + "type": "select", + "label": "Type", + "key": "actionType", + "options": ["Create", "Update"], + "defaultValue": "Create" + }, { "type": "schema", "label": "Schema", diff --git a/packages/standard-components/src/forms/Form.svelte b/packages/standard-components/src/forms/Form.svelte index d73af72a47..327cc70572 100644 --- a/packages/standard-components/src/forms/Form.svelte +++ b/packages/standard-components/src/forms/Form.svelte @@ -8,6 +8,7 @@ export let theme export let size export let disabled = false + export let actionType = "Create" const component = getContext("component") const context = getContext("context") @@ -19,15 +20,29 @@ let fieldMap = {} // 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)) { 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 - const initialValues = getInitialValues($context) + const initialValues = getInitialValues(actionType, dataSource, $context) // Form state contains observable data about the form const formState = writable({ values: initialValues, errors: {}, valid: true }) @@ -42,22 +57,11 @@ // Auto columns are always disabled 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 const constraints = schema?.[field]?.constraints const validate = createValidatorFromConstraints(constraints, field, table) + // Construct field object fieldMap[field] = { fieldState: makeFieldState( field, @@ -67,6 +71,17 @@ fieldApi: makeFieldApi(field, defaultValue, validate), 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] }, validate: () => { diff --git a/packages/string-templates/src/index.cjs b/packages/string-templates/src/index.cjs index a14a3efcda..0b4515b815 100644 --- a/packages/string-templates/src/index.cjs +++ b/packages/string-templates/src/index.cjs @@ -16,9 +16,6 @@ registerAll(hbsInstance) * utility function to check if the object is valid */ function testObject(object) { - if (object == null) { - throw "Unable to process null object" - } // JSON stringify will fail if there are any cycles, stops infinite recursion try { JSON.stringify(object) diff --git a/packages/string-templates/test/basic.spec.js b/packages/string-templates/test/basic.spec.js index f5c7c8be75..f9b994be99 100644 --- a/packages/string-templates/test/basic.spec.js +++ b/packages/string-templates/test/basic.spec.js @@ -81,14 +81,14 @@ describe("Test that the object processing works correctly", () => { 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 try { await processObject(null, null) } catch (err) { error = err } - expect(error).not.toBeNull() + expect(error).toBeNull() }) })