create model & record - validation hooked up again
This commit is contained in:
parent
53ff560e42
commit
0d637260be
|
@ -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} />
|
||||
|
||||
<Checkbox label="Required" bind:checked={required} />
|
||||
|
||||
|
||||
{#if field.type === 'string'}
|
||||
<NumberBox label="Max Length" bind:value={draftField.maxLength} />
|
||||
<ValuesList label="Categories" bind:values={draftField.values} />
|
||||
{:else if field.type === 'boolean'}
|
||||
{#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>
|
||||
|
|
|
@ -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
|
||||
|
||||
|
@ -27,14 +23,25 @@
|
|||
function closed() {
|
||||
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>
|
||||
|
|
|
@ -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}
|
||||
|
|
Loading…
Reference in New Issue