binding panel options from helpers

This commit is contained in:
Martin McKeaveney 2021-02-01 11:51:53 +00:00
parent ff75f8e8a5
commit 16cce9c10c
8 changed files with 102 additions and 1643 deletions

View File

@ -6,7 +6,6 @@ import { makePropSafe } from "@budibase/string-templates"
// Regex to match all instances of template strings // Regex to match all instances of template strings
const CAPTURE_VAR_INSIDE_TEMPLATE = /{{([^}]+)}}/g const CAPTURE_VAR_INSIDE_TEMPLATE = /{{([^}]+)}}/g
const INVALID_BINDING = "{{ invalid binding }}"
/** /**
* Gets all bindable data context fields and instance fields. * Gets all bindable data context fields and instance fields.

View File

@ -11,6 +11,8 @@
} from "@budibase/bbui" } from "@budibase/bbui"
import { createEventDispatcher } from "svelte" import { createEventDispatcher } from "svelte"
import { isValid } from "@budibase/string-templates" import { isValid } from "@budibase/string-templates"
import { handlebarsCompletions } from "constants/completions"
const dispatch = createEventDispatcher() const dispatch = createEventDispatcher()
export let value = "" export let value = ""
@ -19,6 +21,7 @@
export let align export let align
export let popover = null export let popover = null
let helpers = handlebarsCompletions()
let getCaretPosition let getCaretPosition
let validity = true let validity = true
@ -63,6 +66,15 @@
</div> </div>
{/each} {/each}
{/each} {/each}
<Heading extraSmall>Helpers</Heading>
<Spacer extraSmall />
{#each helpers as helper}
<div class="binding" on:click={() => onClickBinding(helper)}>
<span class="binding__label">{helper.displayText}</span>
<br />
<div class="binding__description">{helper.description || ''}</div>
</div>
{/each}
</div> </div>
</div> </div>
</div> </div>

View File

@ -1,6 +1,6 @@
<script> <script>
import groupBy from "lodash/fp/groupBy" import groupBy from "lodash/fp/groupBy"
import { TextArea, Heading, Spacer } from "@budibase/bbui" import { TextArea, Heading, Spacer, Label } from "@budibase/bbui"
import { createEventDispatcher } from "svelte" import { createEventDispatcher } from "svelte"
import { isValid } from "@budibase/string-templates" import { isValid } from "@budibase/string-templates"
import { import {
@ -8,18 +8,26 @@
readableToRuntimeBinding, readableToRuntimeBinding,
} from "builderStore/dataBinding" } from "builderStore/dataBinding"
import { currentAsset, store } from "../../../builderStore" import { currentAsset, store } from "../../../builderStore"
import { handlebarsCompletions } from "constants/completions"
const dispatch = createEventDispatcher() const dispatch = createEventDispatcher()
export let bindableProperties export let bindableProperties
export let value = "" export let value = ""
export let bindingDrawer export let bindingDrawer
export let valid = true export let valid = true
let originalValue = value
let helpers = handlebarsCompletions()
let getCaretPosition
$: value && checkValid() $: value && checkValid()
$: bindableProperties = getBindableProperties( $: bindableProperties = getBindableProperties(
$currentAsset.props, $currentAsset.props,
$store.selectedComponentId $store.selectedComponentId
) )
$: dispatch("update", value)
$: ({ instance, context } = groupBy("type", bindableProperties))
function checkValid() { function checkValid() {
// TODO: need to convert the value to the runtime binding // TODO: need to convert the value to the runtime binding
@ -28,18 +36,26 @@
} }
function addToText(readableBinding) { function addToText(readableBinding) {
value = `${value || ""}{{ ${readableBinding} }}` const position = getCaretPosition()
const toAdd = `{{ ${readableBinding} }}`
if (position.start) {
value =
value.substring(0, position.start) +
toAdd +
value.substring(position.end, value.length)
} else {
value += toAdd
}
} }
let originalValue = value
$: dispatch("update", value)
export function cancel() { export function cancel() {
dispatch("update", originalValue) dispatch("update", originalValue)
bindingDrawer.close() bindingDrawer.close()
} }
$: ({ instance, context } = groupBy("type", bindableProperties)) function updateValue({ detail }) {
value = detail.value
}
</script> </script>
<div class="drawer-contents"> <div class="drawer-contents">
@ -56,8 +72,10 @@
{/each} {/each}
</ul> </ul>
{/if} {/if}
<Spacer small />
{#if instance} {#if instance}
<Heading extraSmall>Components</Heading> <Heading extraSmall>Components</Heading>
<Spacer small />
<ul> <ul>
{#each instance as { readableBinding }} {#each instance as { readableBinding }}
<li on:click={() => addToText(readableBinding)}> <li on:click={() => addToText(readableBinding)}>
@ -66,9 +84,23 @@
{/each} {/each}
</ul> </ul>
{/if} {/if}
<Spacer small />
<Heading extraSmall>Helpers</Heading>
<Spacer small />
<ul>
{#each helpers as helper}
<li on:click={() => addToText(helper.text)}>
<div>
<Label extraSmall>{helper.displayText}</Label>
{helper.description}
</div>
</li>
{/each}
</ul>
</div> </div>
<div class="text"> <div class="text">
<TextArea <TextArea
bind:getCaretPosition
thin thin
bind:value bind:value
placeholder="Add text, or click the objects on the left to add them to placeholder="Add text, or click the objects on the left to add them to

View File

@ -2,6 +2,7 @@
import CodeMirror from "./codemirror" import CodeMirror from "./codemirror"
import { onMount, createEventDispatcher } from "svelte" import { onMount, createEventDispatcher } from "svelte"
import { themeStore } from "builderStore" import { themeStore } from "builderStore"
import { handlebarsCompletions } from "constants/completions"
const dispatch = createEventDispatcher() const dispatch = createEventDispatcher()
@ -15,6 +16,14 @@
export let lineNumbers = true export let lineNumbers = true
export let tab = true export let tab = true
export let mode export let mode
// export let parameters = []
let completions = handlebarsCompletions()
// $: completions = parameters.map(param => ({
// text: `{{ ${param.name} }}`,
// displayText: param.name,
// }))
let width let width
let height let height
@ -109,6 +118,7 @@
mode: modes[mode] || { mode: modes[mode] || {
name: mode, name: mode,
}, },
readOnly, readOnly,
autoCloseBrackets: true, autoCloseBrackets: true,
autoCloseTags: true, autoCloseTags: true,
@ -136,6 +146,18 @@
} }
}) })
// editor.on("cursorActivity", function() {
// editor.showHint({
// hint: function() {
// return {
// from: editor.getDoc().getCursor(),
// to: editor.getDoc().getCursor(),
// list: completions,
// }
// },
// })
// })
if (first) await sleep(50) if (first) await sleep(50)
editor.refresh() editor.refresh()

View File

@ -1,10 +1,12 @@
import CodeMirror from "codemirror" import CodeMirror from "codemirror"
import "codemirror/lib/codemirror.css" import "codemirror/lib/codemirror.css"
import "codemirror/theme/tomorrow-night-eighties.css" import "codemirror/theme/tomorrow-night-eighties.css"
import "codemirror/addon/hint/show-hint.css"
import "codemirror/theme/neo.css" import "codemirror/theme/neo.css"
import "codemirror/mode/sql/sql" import "codemirror/mode/sql/sql"
import "codemirror/mode/css/css" import "codemirror/mode/css/css"
import "codemirror/mode/handlebars/handlebars" import "codemirror/mode/handlebars/handlebars"
import "codemirror/mode/javascript/javascript" import "codemirror/mode/javascript/javascript"
import "codemirror/addon/hint/show-hint"
export default CodeMirror export default CodeMirror

View File

@ -28,14 +28,16 @@
mode="sql" mode="sql"
on:change={updateQuery} on:change={updateQuery}
readOnly={!editable} readOnly={!editable}
value={query.fields.sql} /> value={query.fields.sql}
parameters={query.parameters} />
{:else if schema.type === QueryTypes.JSON} {:else if schema.type === QueryTypes.JSON}
<Editor <Editor
label="Query" label="Query"
mode="json" mode="json"
on:change={updateQuery} on:change={updateQuery}
readOnly={!editable} readOnly={!editable}
value={query.fields.json} /> value={query.fields.json}
parameters={query.parameters} />
{:else if schema.type === QueryTypes.FIELDS} {:else if schema.type === QueryTypes.FIELDS}
<FieldsBuilder bind:fields={query.fields} {schema} {editable} /> <FieldsBuilder bind:fields={query.fields} {schema} {editable} />
{/if} {/if}

View File

@ -0,0 +1,14 @@
import { getManifest } from "@budibase/string-templates"
export function handlebarsCompletions() {
const manifest = getManifest()
return Object.keys(manifest).flatMap(key =>
Object.entries(manifest[key]).map(([helperName, helperConfig]) => ({
text: helperName,
path: helperName,
displayText: helperName,
description: helperConfig.description,
}))
)
}

File diff suppressed because it is too large Load Diff