create model & record - validation hooked up again

This commit is contained in:
Michael Shanks 2020-05-28 22:26:32 +01:00
parent 53ff560e42
commit 0d637260be
3 changed files with 69 additions and 34 deletions

View File

@ -13,17 +13,33 @@
const FIELD_TYPES = ["string", "number", "boolean"]
export let field = { type: "string" }
export let field = { type: "string", constraints: { type: "string", presence: false } }
export let schema
export let goBack
let errors = []
let draftField = cloneDeep(field)
let type = field.type
let constraints = field.constraints
let required = field.constraints.presence && !field.constraints.presence.allowEmpty
const save = () => {
constraints.presence = required ? { allowEmpty: false } : false
draftField.constraints = constraints
draftField.type = type
schema[field.name] = draftField
goBack()
}
$: constraints =
type === "string" ? { type: "string", length: {}, presence: false }
: type === "number" ? { type: "number", presence: false, numericality: {} }
: type === "boolean" ? { type: "boolean", presence: false }
: type === "datetime" ? { type: "date", datetime: {}, presence: false }
: type.startsWith('array') ? { type: "array", presence: false }
: { type: "string", presence: false }
</script>
<div class="root">
@ -34,30 +50,22 @@
<Textbox label="Name" bind:text={field.name} />
<Dropdown
label="Type"
bind:selected={draftField.type}
bind:selected={type}
options={FIELD_TYPES} />
{#if field.type === 'string'}
<NumberBox label="Max Length" bind:value={draftField.maxLength} />
<ValuesList label="Categories" bind:values={draftField.values} />
{:else if field.type === 'boolean'}
<Checkbox label="Required" bind:checked={required} />
{#if type === 'string'}
<NumberBox label="Max Length" bind:value={constraints.length.maximum} />
<ValuesList label="Categories" bind:values={constraints.inclusion} />
{:else if type === 'datetime'}
<!-- TODO: revisit and fix with JSON schema -->
<Checkbox label="Allow Null" bind:checked={draftField.allowNulls} />
{:else if field.format === 'datetime'}
<!-- TODO: revisit and fix with JSON schema -->
<DatePicker label="Min Value" bind:value={draftField.minValue} />
<DatePicker label="Max Value" bind:value={draftField.maxValue} />
{:else if field.type === 'number'}
<NumberBox label="Min Value" bind:value={draftField.minimum} />
<NumberBox label="Max Value" bind:value={draftField.maximum} />
{:else if draftField.type.startsWith('array')}
<!-- TODO: revisit and fix with JSON schema -->
<NumberBox
label="Min Length"
bind:value={draftField.typeOptions.minLength} />
<NumberBox
label="Max Length"
bind:value={draftField.typeOptions.maxLength} />
<DatePicker label="Min Value" bind:value={constraints.datetime.earliest} />
<DatePicker label="Max Value" bind:value={constraints.datetime.latest} />
{:else if type === 'number'}
<NumberBox label="Min Value" bind:value={constraints.numericality.greaterThanOrEqualTo} />
<NumberBox label="Max Value" bind:value={constraints.numericality.lessThanOrEqualTo} />
{/if}
</form>
</div>

View File

@ -8,10 +8,6 @@
import * as api from "../api"
import ErrorsBox from "components/common/ErrorsBox.svelte"
const CLASS_NAME_MAP = {
boolean: "uk-checkbox",
}
export let record = {}
export let onClosed
@ -28,14 +24,25 @@
onClosed()
}
const isSelect = meta =>
meta.type === "string"
&& meta.constraints
&& meta.constraints.inclusion
&& meta.constraints.inclusion.length > 0
function determineInputType(meta) {
if (meta.type === "datetime") return "date"
if (meta.type === "number") return "number"
if (meta.type === "boolean") return "checkbox"
if (isSelect(meta)) return "select"
return "text"
}
function determineOptions(meta) {
return isSelect(meta) ? meta.constraints.inclusion : []
}
async function saveRecord() {
const recordResponse = await api.saveRecord(
{
@ -46,7 +53,9 @@
$backendUiStore.selectedModel._id
)
if (recordResponse.errors) {
errors = recordResponse.errors
errors = Object.keys(recordResponse.errors)
.map(k => ({dataPath: k, message: recordResponse.errors[k]}))
.flat()
return
}
@ -65,8 +74,8 @@
{#each modelSchema as [key, meta]}
<div class="uk-margin">
<RecordFieldControl
className={CLASS_NAME_MAP[meta.type]}
type={determineInputType(meta)}
options={determineOptions(meta)}
label={key}
bind:value={record[key]} />
</div>

View File

@ -3,10 +3,16 @@
export let value = ""
export let label
export let errors = []
export let className = "uk-input"
export let options = []
let checked = type === "checkbox" ? value : false
const determineClassName = type => {
if (type === "checkbox") return "uk-checkbox"
if (type === "select") return "uk-select"
return "uk-input"
}
const handleInput = event => {
if (event.target.type === "checkbox") {
value = event.target.checked
@ -23,11 +29,23 @@
</script>
<label>{label}</label>
{#if type === "select"}
<select
class={determineClassName(type)}
bind:value={value}
class:uk-form-danger={errors.length > 0} >
{#each options as opt}
<option value={opt}>{ opt }</option>
{/each}
</select>
{:else}
<input
class={className}
class={determineClassName(type)}
class:uk-form-danger={errors.length > 0}
{checked}
{type}
{value}
on:input={handleInput}
on:change={handleInput} />
{/if}