create/edit record - supports field types

This commit is contained in:
Michael Shanks 2020-03-27 11:28:30 +00:00
parent 5c7e603a5e
commit 51caa55f4b
5 changed files with 103 additions and 19 deletions

View File

@ -8,6 +8,7 @@
import DropdownButton from "../common/DropdownButton.svelte" import DropdownButton from "../common/DropdownButton.svelte"
import ActionButton from "../common/ActionButton.svelte" import ActionButton from "../common/ActionButton.svelte"
import Modal from "../common/Modal.svelte" import Modal from "../common/Modal.svelte"
import * as api from "./ModelDataTable/api"
import { import {
CreateEditRecordModal, CreateEditRecordModal,
CreateEditModelModal, CreateEditModelModal,
@ -19,8 +20,11 @@
let selectedRecord let selectedRecord
function selectRecord(record) { async function selectRecord(record) {
selectedRecord = record selectedRecord = await api.loadRecord(record.key, {
appname: $store.appname,
instanceId: $backendUiStore.selectedDatabase.id,
})
} }
function onClosed() { function onClosed() {

View File

@ -20,6 +20,12 @@ export async function deleteRecord(record, { appname, instanceId }) {
return response return response
} }
export async function loadRecord(key, { appname, instanceId }) {
const LOAD_RECORDS_URL = `/_builder/instance/${appname}/${instanceId}/api/record${key}`
const response = await api.get(LOAD_RECORDS_URL)
return await response.json()
}
export async function saveRecord(record, { appname, instanceId }) { export async function saveRecord(record, { appname, instanceId }) {
let recordBase = { ...record } let recordBase = { ...record }

View File

@ -5,12 +5,16 @@
import Modal from "../../../common/Modal.svelte" import Modal from "../../../common/Modal.svelte"
import ActionButton from "../../../common/ActionButton.svelte" import ActionButton from "../../../common/ActionButton.svelte"
import Select from "../../../common/Select.svelte" import Select from "../../../common/Select.svelte"
import { getNewRecord, joinKey } from "../../../common/core" import { getNewRecord, joinKey, getExactNodeForKey } from "../../../common/core"
import RecordFieldControl from "./RecordFieldControl.svelte"
import * as api from "../api" import * as api from "../api"
import ErrorsBox from "../../../common/ErrorsBox.svelte"
export let record export let record
export let onClosed export let onClosed
let errors = []
const childModelsForModel = compose( const childModelsForModel = compose(
flatten, flatten,
map("children"), map("children"),
@ -25,20 +29,26 @@
? childModelsForModel($store.hierarchy) ? childModelsForModel($store.hierarchy)
: $store.hierarchy.children : $store.hierarchy.children
$: selectedModel = selectedModel || models[0] let selectedModel
$: {
if (record) {
selectedModel = getExactNodeForKey($store.hierarchy)(record.key)
} else {
selectedModel = selectedModel || models[0]
}
}
$: modelFields = selectedModel $: modelFields = selectedModel
? selectedModel.fields.map(({ name }) => name) ? selectedModel.fields
: [] : []
function getCurrentCollectionKey(selectedRecord) { function getCurrentCollectionKey(selectedRecord) {
return selectedRecord return selectedRecord
? joinKey(selectedRecord.key, selectedModel.collectionName) ? joinKey(selectedRecord.key, selectedModel.collectionName)
: joinKey(selectedModel.collectionName) : joinKey(selectedModel.collectionName)
} }
$: editingRecord = editingRecord || record || getNewRecord(selectedModel, getCurrentCollectionKey($backendUiStore.selectedRecord)) $: editingRecord = record || editingRecord || getNewRecord(selectedModel, getCurrentCollectionKey($backendUiStore.selectedRecord))
function closed() { function closed() {
editingRecord = null editingRecord = null
@ -60,6 +70,7 @@
<div> <div>
<h4 class="budibase__title--4">Create / Edit Record</h4> <h4 class="budibase__title--4">Create / Edit Record</h4>
<ErrorsBox {errors} />
<div class="actions"> <div class="actions">
<form class="uk-form-stacked"> <form class="uk-form-stacked">
{#if !record} {#if !record}
@ -72,17 +83,11 @@
</Select> </Select>
</div> </div>
{/if} {/if}
{#each modelFields as field} {#each (modelFields || []) as field}
<div class="uk-margin"> <RecordFieldControl
<label class="uk-form-label" for="form-stacked-text">{field}</label> record={editingRecord}
<div class="uk-form-controls"> {field}
<input {errors} />
class="uk-input"
id="form-stacked-text"
type="text"
bind:value={editingRecord[field]} />
</div>
</div>
{/each} {/each}
</form> </form>
<footer> <footer>

View File

@ -0,0 +1,69 @@
<script>
import Select from "../../../common/Select.svelte"
export let record
export let field
export let errors
$: isDropdown =
field.type === "string"
&& field.typeOptions.values
&& field.typeOptions.values.length > 0
$: isNumber = field.type === "number"
$: isText =
field.type === "string"
&& !isDropdown
$: isCheckbox = field.type === "bool"
$: isError = errors && errors.some(e => e.field && e.field === field.name)
$: isDatetime = field.type === "datetime"
</script>
<div class="uk-margin">
{#if !isCheckbox}
<label class="uk-form-label" for={field.name}>{field.label}</label>
{/if}
<div class="uk-form-controls">
{#if isDropdown}
<Select bind:value={record[field.name]}>
<option value=""></option>
{#each field.typeOptions.values as val}
<option value={val}>{val}</option>
{/each}
</Select>
{:else if isText}
<input
class="uk-input"
class:uk-form-danger={isError}
id={field.name}
type="text"
bind:value={record[field.name]} />
{:else if isNumber}
<input
class="uk-input"
class:uk-form-danger={isError}
type="number"
bind:value={record[field.name]} />
{:else if isDatetime}
<input
class="uk-input"
class:uk-form-danger={isError}
type="date"
bind:value={record[field.name]} />
{:else if isCheckbox}
<label>
<input
class="uk-checkbox"
class:uk-form-danger={isError}
type="checkbox"
bind:checked={record[field.name]} >
{field.label}
</label>
{/if}
</div>
</div>

View File

@ -37,7 +37,7 @@ const options = {
isValid: v => isValid: v =>
v === null || (isArrayOfString(v) && v.length > 0 && v.length < 10000), v === null || (isArrayOfString(v) && v.length > 0 && v.length < 10000),
requirementDescription: requirementDescription:
"'values' must be null (no values) or an arry of at least one string", "'values' must be null (no values) or an array of at least one string",
parse: s => s, parse: s => s,
}, },
allowDeclaredValuesOnly: { allowDeclaredValuesOnly: {