Add loading indicator and debounce evaluations to fix performance issues with large JSON payloads
This commit is contained in:
parent
a27529eca5
commit
d666d03328
|
@ -1,5 +1,5 @@
|
||||||
<script>
|
<script>
|
||||||
import { DrawerContent, ActionButton, Icon } from "@budibase/bbui"
|
import { DrawerContent, ActionButton, Icon, Helpers } from "@budibase/bbui"
|
||||||
import { createEventDispatcher, getContext, onMount } from "svelte"
|
import { createEventDispatcher, getContext, onMount } from "svelte"
|
||||||
import {
|
import {
|
||||||
isValid,
|
isValid,
|
||||||
|
@ -26,6 +26,7 @@
|
||||||
import formatHighlight from "json-format-highlight"
|
import formatHighlight from "json-format-highlight"
|
||||||
import { capitalise } from "helpers"
|
import { capitalise } from "helpers"
|
||||||
import DrawerBindableInput from "components/common/bindings/DrawerBindableInput.svelte"
|
import DrawerBindableInput from "components/common/bindings/DrawerBindableInput.svelte"
|
||||||
|
import { Utils } from "@budibase/frontend-core"
|
||||||
|
|
||||||
const dispatch = createEventDispatcher()
|
const dispatch = createEventDispatcher()
|
||||||
|
|
||||||
|
@ -57,6 +58,7 @@
|
||||||
let targetMode = null
|
let targetMode = null
|
||||||
let expressionResult
|
let expressionResult
|
||||||
let drawerIsModal
|
let drawerIsModal
|
||||||
|
let evaluating = false
|
||||||
|
|
||||||
$: drawerContext?.modal.subscribe(val => (drawerIsModal = val))
|
$: drawerContext?.modal.subscribe(val => (drawerIsModal = val))
|
||||||
$: editorTabs = allowJS ? [Modes.Text, Modes.JavaScript] : [Modes.Text]
|
$: editorTabs = allowJS ? [Modes.Text, Modes.JavaScript] : [Modes.Text]
|
||||||
|
@ -67,9 +69,21 @@
|
||||||
mode === Modes.JavaScript ? EditorModes.JS : EditorModes.Handlebars
|
mode === Modes.JavaScript ? EditorModes.JS : EditorModes.Handlebars
|
||||||
$: bindingCompletions = bindingsToCompletions(enrichedBindings, editorMode)
|
$: bindingCompletions = bindingsToCompletions(enrichedBindings, editorMode)
|
||||||
$: runtimeExpression = readableToRuntimeBinding(enrichedBindings, value)
|
$: runtimeExpression = readableToRuntimeBinding(enrichedBindings, value)
|
||||||
$: expressionResult = processStringSync(runtimeExpression || "", context)
|
$: requestUpdateEvaluation(runtimeExpression, context)
|
||||||
$: bindingHelpers = new BindingHelpers(getCaretPosition, insertAtPos)
|
$: bindingHelpers = new BindingHelpers(getCaretPosition, insertAtPos)
|
||||||
|
|
||||||
|
const updateEvaluation = (expression, context) => {
|
||||||
|
expressionResult = processStringSync(expression || "", context)
|
||||||
|
evaluating = false
|
||||||
|
}
|
||||||
|
|
||||||
|
const debouncedUpdateEvaluation = Utils.debounce(updateEvaluation, 260)
|
||||||
|
|
||||||
|
const requestUpdateEvaluation = (expression, context) => {
|
||||||
|
evaluating = true
|
||||||
|
debouncedUpdateEvaluation(expression, context)
|
||||||
|
}
|
||||||
|
|
||||||
const getBindingValue = (binding, context) => {
|
const getBindingValue = (binding, context) => {
|
||||||
const hbs = `{{ literal ${binding.runtimeBinding} }}`
|
const hbs = `{{ literal ${binding.runtimeBinding} }}`
|
||||||
const res = processStringSync(hbs, context)
|
const res = processStringSync(hbs, context)
|
||||||
|
@ -103,7 +117,7 @@
|
||||||
valid = isValid(runtimeExpression)
|
valid = isValid(runtimeExpression)
|
||||||
if (valid) {
|
if (valid) {
|
||||||
dispatch("change", val)
|
dispatch("change", val)
|
||||||
expressionResult = processStringSync(runtimeExpression || "", context)
|
requestUpdateEvaluation(runtimeExpression, context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -249,7 +263,7 @@
|
||||||
mode={editorMode}
|
mode={editorMode}
|
||||||
/>
|
/>
|
||||||
{:else if sidePanel === SidePanels.Evaluation}
|
{:else if sidePanel === SidePanels.Evaluation}
|
||||||
<EvaluationSidePanel {expressionResult} />
|
<EvaluationSidePanel {expressionResult} {evaluating} />
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,13 +1,16 @@
|
||||||
<script>
|
<script>
|
||||||
import formatHighlight from "json-format-highlight"
|
import formatHighlight from "json-format-highlight"
|
||||||
import { Icon, notifications } from "@budibase/bbui"
|
import { Icon, ProgressCircle, notifications } from "@budibase/bbui"
|
||||||
import { copyToClipboard } from "@budibase/bbui/helpers"
|
import { copyToClipboard } from "@budibase/bbui/helpers"
|
||||||
|
import { fade } from "svelte/transition"
|
||||||
|
|
||||||
export let expressionResult
|
export let expressionResult
|
||||||
|
export let evaluating = false
|
||||||
|
|
||||||
$: error = expressionResult === "Error while executing JS"
|
$: error = expressionResult === "Error while executing JS"
|
||||||
$: empty = expressionResult == null || expressionResult === ""
|
$: empty = expressionResult == null || expressionResult === ""
|
||||||
$: success = !error && !empty
|
$: success = !error && !empty
|
||||||
|
$: highlightedResult = highlight(expressionResult)
|
||||||
|
|
||||||
const highlight = json => {
|
const highlight = json => {
|
||||||
// Attempt to parse and then stringify, in case this is valid JSON
|
// Attempt to parse and then stringify, in case this is valid JSON
|
||||||
|
@ -16,7 +19,6 @@
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// Ignore
|
// Ignore
|
||||||
}
|
}
|
||||||
|
|
||||||
return formatHighlight(json, {
|
return formatHighlight(json, {
|
||||||
keyColor: "#e06c75",
|
keyColor: "#e06c75",
|
||||||
numberColor: "#e5c07b",
|
numberColor: "#e5c07b",
|
||||||
|
@ -42,10 +44,22 @@
|
||||||
<div class="header-content">
|
<div class="header-content">
|
||||||
{#if error}
|
{#if error}
|
||||||
<Icon name="Alert" color="var(--spectrum-global-color-red-600)" />
|
<Icon name="Alert" color="var(--spectrum-global-color-red-600)" />
|
||||||
<span> Error </span>
|
<div>Error</div>
|
||||||
|
{#if evaluating}
|
||||||
|
<div transition:fade|local={{ duration: 130 }}>
|
||||||
|
<ProgressCircle size="S" />
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
<span />
|
||||||
<Icon name="Copy" hoverable on:click={copy} />
|
<Icon name="Copy" hoverable on:click={copy} />
|
||||||
{:else}
|
{:else}
|
||||||
<span>Preview</span>
|
<div>Preview</div>
|
||||||
|
{#if evaluating}
|
||||||
|
<div transition:fade|local={{ duration: 130 }}>
|
||||||
|
<ProgressCircle size="S" />
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
<span />
|
||||||
{#if !empty}
|
{#if !empty}
|
||||||
<Icon name="Copy" hoverable on:click={copy} />
|
<Icon name="Copy" hoverable on:click={copy} />
|
||||||
{/if}
|
{/if}
|
||||||
|
@ -54,7 +68,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="body">
|
<div class="body">
|
||||||
{#if expressionResult}
|
{#if expressionResult}
|
||||||
{@html highlight(expressionResult)}
|
{@html highlightedResult}
|
||||||
{:else}
|
{:else}
|
||||||
Your expression will be evaluated here
|
Your expression will be evaluated here
|
||||||
{/if}
|
{/if}
|
||||||
|
|
Loading…
Reference in New Issue