stop coercing values on the server - do on client instead
This commit is contained in:
parent
62db75eafb
commit
f975237417
|
@ -19,10 +19,13 @@
|
|||
const modelFields = modelId => {
|
||||
const model = $backendUiStore.models.find(m => m._id === modelId)
|
||||
|
||||
return Object.keys(model.schema)
|
||||
return Object.keys(model.schema).map(k => ({
|
||||
name: k,
|
||||
type: model.schema[k].type,
|
||||
}))
|
||||
}
|
||||
|
||||
$: fieldNames =
|
||||
$: schemaFields =
|
||||
parameters && parameters.modelId ? modelFields(parameters.modelId) : []
|
||||
|
||||
const onFieldsChanged = e => {
|
||||
|
@ -42,7 +45,7 @@
|
|||
{#if parameters.modelId}
|
||||
<SaveFields
|
||||
parameterFields={parameters.fields}
|
||||
schemaFields={fieldNames}
|
||||
{schemaFields}
|
||||
on:fieldschanged={onFieldsChanged} />
|
||||
{/if}
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
(parameterFields &&
|
||||
runtimeToReadableBinding(
|
||||
bindableProperties,
|
||||
parameterFields[name]
|
||||
parameterFields[name].value
|
||||
)) ||
|
||||
"",
|
||||
}))
|
||||
|
@ -56,10 +56,12 @@
|
|||
const newParameterFields = {}
|
||||
for (let field of fields) {
|
||||
if (field.name) {
|
||||
newParameterFields[field.name] = readableToRuntimeBinding(
|
||||
bindableProperties,
|
||||
field.value
|
||||
)
|
||||
// value and type is needed by the client, so it can parse
|
||||
// a string into a correct type
|
||||
newParameterFields[field.name] = {
|
||||
type: schemaFields.find(f => f.name === field.name).type,
|
||||
value: readableToRuntimeBinding(bindableProperties, field.value),
|
||||
}
|
||||
}
|
||||
}
|
||||
dispatch("fieldschanged", newParameterFields)
|
||||
|
@ -74,8 +76,8 @@
|
|||
<Label size="m" color="dark">Field</Label>
|
||||
<Select secondary bind:value={field.name} on:blur={rebuildParameters}>
|
||||
<option value="" />
|
||||
{#each schemaFields as fieldName}
|
||||
<option value={fieldName}>{fieldName}</option>
|
||||
{#each schemaFields as schemaField}
|
||||
<option value={schemaField.name}>{schemaField.name}</option>
|
||||
{/each}
|
||||
</Select>
|
||||
<Label size="m" color="dark">Value</Label>
|
||||
|
|
|
@ -39,15 +39,12 @@
|
|||
$: parameters._id = `{{ ${recordId} }}`
|
||||
|
||||
// just wraps binding in {{ ... }}
|
||||
const toBindingExpression = bindingPath => {
|
||||
console.log("yeo")
|
||||
return `{{ ${bindingPath} }}`
|
||||
}
|
||||
const toBindingExpression = bindingPath => `{{ ${bindingPath} }}`
|
||||
|
||||
// finds the selected idBinding, then reads the table/view
|
||||
// from the component instance that it belongs to.
|
||||
// then returns the field names for that schema
|
||||
const modelInfoFromIdBinding = recordId => {
|
||||
const schemaFromIdBinding = recordId => {
|
||||
if (!recordId) return []
|
||||
|
||||
const idBinding = bindableProperties.find(
|
||||
|
@ -66,15 +63,18 @@
|
|||
|
||||
const model = $backendUiStore.models.find(m => m._id === modelInfo.modelId)
|
||||
parameters.modelId = modelInfo.modelId
|
||||
return Object.keys(model.schema)
|
||||
return Object.keys(model.schema).map(k => ({
|
||||
name: k,
|
||||
type: model.schema[k].type,
|
||||
}))
|
||||
}
|
||||
|
||||
let fieldNames
|
||||
let schemaFields
|
||||
$: {
|
||||
if (parameters && recordId) {
|
||||
fieldNames = modelInfoFromIdBinding(recordId)
|
||||
schemaFields = schemaFromIdBinding(recordId)
|
||||
} else {
|
||||
fieldNames = []
|
||||
schemaFields = []
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -104,7 +104,7 @@
|
|||
{#if recordId}
|
||||
<SaveFields
|
||||
parameterFields={parameters.fields}
|
||||
schemaFields={fieldNames}
|
||||
{schemaFields}
|
||||
on:fieldschanged={onFieldsChanged} />
|
||||
{/if}
|
||||
|
||||
|
|
|
@ -54,10 +54,13 @@ const apiOpts = {
|
|||
}
|
||||
|
||||
const createRecord = async params =>
|
||||
await post({ url: `/api/${params.modelId}/records`, body: params.fields })
|
||||
await post({
|
||||
url: `/api/${params.modelId}/records`,
|
||||
body: makeRecordRequestBody(params),
|
||||
})
|
||||
|
||||
const updateRecord = async params => {
|
||||
const record = params.fields
|
||||
const record = makeRecordRequestBody(params)
|
||||
record._id = params._id
|
||||
await patch({
|
||||
url: `/api/${params.modelId}/records/${params._id}`,
|
||||
|
@ -65,6 +68,32 @@ const updateRecord = async params => {
|
|||
})
|
||||
}
|
||||
|
||||
const makeRecordRequestBody = parameters => {
|
||||
const body = {}
|
||||
for (let fieldName in parameters.fields) {
|
||||
const field = parameters.fields[fieldName]
|
||||
|
||||
// ensure fields sent are of the correct type
|
||||
if (field.type === "boolean") {
|
||||
if (field.value === "true") body[fieldName] = true
|
||||
if (field.value === "false") body[fieldName] = false
|
||||
} else if (field.type === "number") {
|
||||
const val = parseFloat(field.value)
|
||||
if (!isNaN(val)) {
|
||||
body[fieldName] = val
|
||||
}
|
||||
} else if (field.type === "datetime") {
|
||||
const date = new Date(field.value)
|
||||
if (!isNaN(date.getTime())) {
|
||||
body[fieldName] = date.toISOString()
|
||||
}
|
||||
} else {
|
||||
body[fieldName] = field.value
|
||||
}
|
||||
}
|
||||
return body
|
||||
}
|
||||
|
||||
export default {
|
||||
authenticate: authenticate(apiOpts),
|
||||
triggerWorkflow: triggerWorkflow(apiOpts),
|
||||
|
|
|
@ -22,7 +22,6 @@ exports.patch = async function(ctx) {
|
|||
if (!model.schema[key]) continue
|
||||
record[key] = patchfields[key]
|
||||
}
|
||||
coerceFieldsToCorrectType(record, model)
|
||||
|
||||
const validateResult = await validate({
|
||||
record,
|
||||
|
@ -58,8 +57,6 @@ exports.save = async function(ctx) {
|
|||
|
||||
const model = await db.get(record.modelId)
|
||||
|
||||
coerceFieldsToCorrectType(record, model)
|
||||
|
||||
const validateResult = await validate({
|
||||
record,
|
||||
model,
|
||||
|
@ -195,32 +192,6 @@ exports.validate = async function(ctx) {
|
|||
ctx.body = errors
|
||||
}
|
||||
|
||||
// this function modifies an incoming record, to allow for things like
|
||||
// "boolField": "true" (instead of mandating "boolField": true)
|
||||
// this allows us to use mustash templating to send non-string fields in a request
|
||||
const coerceFieldsToCorrectType = (record, model) => {
|
||||
for (let fieldName in record) {
|
||||
const fieldValue = record[fieldName]
|
||||
if (model.schema[fieldName]) {
|
||||
if (
|
||||
model.schema[fieldName].type === "boolean" &&
|
||||
typeof fieldValue !== "boolean"
|
||||
) {
|
||||
if (fieldValue === "true") record[fieldName] = true
|
||||
if (fieldValue === "false") record[fieldName] = false
|
||||
continue
|
||||
}
|
||||
|
||||
if (model.schema[fieldName].type === "number") {
|
||||
const val = parseFloat(fieldValue)
|
||||
if (!isNaN(val)) {
|
||||
record[fieldName] = val
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function validate({ instanceId, modelId, record, model }) {
|
||||
if (!model) {
|
||||
const db = new CouchDB(instanceId)
|
||||
|
|
Loading…
Reference in New Issue