Create record added

This commit is contained in:
Michael Shanks 2020-09-09 22:15:31 +01:00
parent cb9fd4d1cd
commit 71cc329178
4 changed files with 200 additions and 101 deletions

View File

@ -4,7 +4,7 @@
import { AddIcon, ArrowDownIcon } from "components/common/Icons/" import { AddIcon, ArrowDownIcon } from "components/common/Icons/"
import { EVENT_TYPE_MEMBER_NAME } from "../../common/eventHandlers" import { EVENT_TYPE_MEMBER_NAME } from "../../common/eventHandlers"
import actionTypes from "./actions" import actionTypes from "./actions"
import { createEventDispatcher, onMount } from "svelte" import { createEventDispatcher } from "svelte"
const dispatch = createEventDispatcher() const dispatch = createEventDispatcher()

View File

@ -1,5 +1,72 @@
<script> <script>
import { Select, Label } from "@budibase/bbui"
import { store, backendUiStore } from "builderStore"
import fetchBindableProperties from "builderStore/fetchBindableProperties"
import SaveFields from "./SaveFields.svelte"
export let parameters
$: bindableProperties = fetchBindableProperties({
componentInstanceId: $store.currentComponentInfo._id,
components: $store.components,
screen: $store.currentPreviewItem,
models: $backendUiStore.models,
})
// just wraps binding in {{ ... }}
const toBindingExpression = bindingPath => `{{ ${bindingPath} }}`
const modelFields = modelId => {
const model = $backendUiStore.models.find(m => m._id === modelId)
return Object.keys(model.schema)
}
$: fieldNames =
parameters && parameters.modelId ? modelFields(parameters.modelId) : []
const onFieldsChanged = e => {
parameters.fields = e.detail
}
</script> </script>
<div>Create Record</div> <div class="root">
<Label size="m" color="dark">Table</Label>
<Select secondary bind:value={parameters.modelId}>
<option value="" />
{#each $backendUiStore.models as model}
<option value={model._id}>{model.name}</option>
{/each}
</Select>
{#if parameters.modelId}
<SaveFields
parameterFields={parameters.fields}
schemaFields={fieldNames}
on:fieldschanged={onFieldsChanged} />
{/if}
</div>
<style>
.root {
display: grid;
column-gap: var(--spacing-s);
row-gap: var(--spacing-s);
grid-template-columns: auto 1fr auto 1fr auto;
align-items: baseline;
}
.root :global(.relative:nth-child(2)) {
grid-column-start: 2;
grid-column-end: 6;
}
.cannot-use {
color: var(--red);
font-size: var(--font-size-s);
text-align: center;
width: 70%;
margin: auto;
}
</style>

View File

@ -0,0 +1,115 @@
<script>
import { Select, Label, TextButton, Spacer } from "@budibase/bbui"
import { store, backendUiStore } from "builderStore"
import fetchBindableProperties from "builderStore/fetchBindableProperties"
import { CloseCircleIcon, AddIcon } from "components/common/icons"
import {
readableToRuntimeBinding,
runtimeToReadableBinding,
} from "builderStore/replaceBindings"
import { createEventDispatcher } from "svelte"
const dispatch = createEventDispatcher()
export let parameterFields
export let schemaFields
const emptyField = () => ({ name: "", value: "" })
// this statement initialises fields from parameters.fields
$: fields =
fields ||
Object.keys(parameterFields || { "": "" }).map(name => ({
name,
value:
(parameterFields &&
runtimeToReadableBinding(
bindableProperties,
parameterFields[name]
)) ||
"",
}))
$: bindableProperties = fetchBindableProperties({
componentInstanceId: $store.currentComponentInfo._id,
components: $store.components,
screen: $store.currentPreviewItem,
models: $backendUiStore.models,
})
const addField = () => {
const newFields = fields.filter(f => f.name)
newFields.push(emptyField())
fields = newFields
rebuildParameters()
}
const removeField = field => () => {
fields = fields.filter(f => f !== field)
rebuildParameters()
}
const rebuildParameters = () => {
// rebuilds paramters.fields every time a field name or value is added
const newParameterFields = {}
for (let field of fields) {
if (field.name) {
newParameterFields[field.name] = readableToRuntimeBinding(
bindableProperties,
field.value
)
}
}
dispatch("fieldschanged", newParameterFields)
}
// just wraps binding in {{ ... }}
const toBindingExpression = bindingPath => `{{ ${bindingPath} }}`
</script>
{#if fields}
{#each fields as field}
<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}
</Select>
<Label size="m" color="dark">Value</Label>
<Select
editable
secondary
bind:value={field.value}
on:blur={rebuildParameters}>
<option value="" />
{#each bindableProperties as bindableProp}
<option value={toBindingExpression(bindableProp.readableBinding)}>
{bindableProp.readableBinding}
</option>
{/each}
</Select>
<div class="remove-field-container">
<TextButton text small on:click={removeField(field)}>
<CloseCircleIcon />
</TextButton>
</div>
{/each}
<div>
<Spacer small />
<TextButton text small blue on:click={addField}>
Add Field
<div style="height: 20px; width: 20px;">
<AddIcon />
</div>
</TextButton>
</div>
{/if}
<style>
.remove-field-container :global(button) {
vertical-align: bottom;
}
</style>

View File

@ -1,32 +1,11 @@
<script> <script>
import { Select, Label, TextButton, Spacer } from "@budibase/bbui" import { Select, Label } from "@budibase/bbui"
import { store, backendUiStore } from "builderStore" import { store, backendUiStore } from "builderStore"
import fetchBindableProperties from "builderStore/fetchBindableProperties" import fetchBindableProperties from "builderStore/fetchBindableProperties"
import { CloseCircleIcon, AddIcon } from "components/common/icons" import SaveFields from "./SaveFields.svelte"
import {
readableToRuntimeBinding,
runtimeToReadableBinding,
} from "builderStore/replaceBindings"
export let parameters export let parameters
const emptyField = () => ({ name: "", value: "" })
// this statement initialises fields from parameters.fields
$: fields =
fields ||
(parameters &&
Object.keys(parameters.fields || { "": "" }).map(name => ({
name,
value:
(parameters.fields &&
runtimeToReadableBinding(
bindableProperties,
parameters.fields[name]
)) ||
"",
})))
$: bindableProperties = fetchBindableProperties({ $: bindableProperties = fetchBindableProperties({
componentInstanceId: $store.currentComponentInfo._id, componentInstanceId: $store.currentComponentInfo._id,
components: $store.components, components: $store.components,
@ -43,38 +22,7 @@
// ensure recordId is always defaulted - there is usually only one option // ensure recordId is always defaulted - there is usually only one option
if (idFields.length > 0 && !parameters.recordId) { if (idFields.length > 0 && !parameters.recordId) {
parameters.recordId = idFields[0].runtimeBinding parameters.recordId = idFields[0].runtimeBinding
} parameters = parameters
}
const addField = () => {
const newFields = fields.filter(f => f.name)
newFields.push(emptyField())
fields = newFields
}
const removeField = field => () => {
fields = fields.filter(f => f !== field)
}
const bindablePropertyName = prop => {
if (prop.type === "instance") return prop.instance._instanceName
return prop.readableBinding.split(".")[
prop.readableBinding.lastIndexOf(".")
]
}
const fieldNameChanged = e => {}
const rebuildParameters = () => {
// rebuilds paramters.fields every time a field name or value is added
parameters.fields = {}
for (let field of fields) {
if (field.name) {
parameters.fields[field.name] = readableToRuntimeBinding(
bindableProperties,
field.value
)
}
} }
} }
@ -108,7 +56,14 @@
return Object.keys(model.schema) return Object.keys(model.schema)
} }
$: fieldNames = parameters ? fieldNamesFromIdBinding(parameters.recordId) : [] $: fieldNames =
parameters && parameters.recordId
? fieldNamesFromIdBinding(parameters.recordId)
: []
const onFieldsChanged = e => {
parameters.fields = e.detail
}
</script> </script>
<div class="root"> <div class="root">
@ -128,45 +83,11 @@
</Select> </Select>
{/if} {/if}
{#if parameters.recordId && fields} {#if parameters.recordId}
{#each fields as field} <SaveFields
<Label size="m" color="dark">Field</Label> parameterFields={parameters.fields}
<Select secondary bind:value={field.name} on:blur={rebuildParameters}> schemaFields={fieldNames}
<option value="" /> on:fieldschanged={onFieldsChanged} />
{#each fieldNames as fieldName}
<option value={fieldName}>{fieldName}</option>
{/each}
</Select>
<Label size="m" color="dark">Value</Label>
<Select
editable
secondary
bind:value={field.value}
on:blur={rebuildParameters}>
<option value="" />
{#each bindableProperties as bindableProp}
<option value={toBindingExpression(bindableProp.readableBinding)}>
{bindableProp.readableBinding}
</option>
{/each}
</Select>
<div class="remove-field-container">
<TextButton text small on:click={removeField(field)}>
<CloseCircleIcon />
</TextButton>
</div>
{/each}
<div>
<Spacer small />
<TextButton text small blue on:click={addField}>
Add Field
<div style="height: 20px; width: 20px;">
<AddIcon />
</div>
</TextButton>
</div>
{/if} {/if}
</div> </div>
@ -185,10 +106,6 @@
grid-column-end: 6; grid-column-end: 6;
} }
.remove-field-container :global(button) {
vertical-align: bottom;
}
.cannot-use { .cannot-use {
color: var(--red); color: var(--red);
font-size: var(--font-size-s); font-size: var(--font-size-s);