create/edit record - supports field types
This commit is contained in:
parent
5c7e603a5e
commit
51caa55f4b
|
@ -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() {
|
||||||
|
|
|
@ -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 }
|
||||||
|
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
|
@ -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: {
|
||||||
|
|
Loading…
Reference in New Issue