Further conversions.
This commit is contained in:
parent
095eb0fe3a
commit
2fdf2289ed
|
@ -10,12 +10,12 @@
|
||||||
export let size = "M"
|
export let size = "M"
|
||||||
export let hoverable = false
|
export let hoverable = false
|
||||||
export let disabled = false
|
export let disabled = false
|
||||||
export let color
|
export let color = undefined
|
||||||
export let hoverColor
|
export let hoverColor = undefined
|
||||||
export let tooltip
|
export let tooltip = undefined
|
||||||
export let tooltipPosition = TooltipPosition.Bottom
|
export let tooltipPosition = TooltipPosition.Bottom
|
||||||
export let tooltipType = TooltipType.Default
|
export let tooltipType = TooltipType.Default
|
||||||
export let tooltipColor
|
export let tooltipColor = undefined
|
||||||
export let tooltipWrap = true
|
export let tooltipWrap = true
|
||||||
export let newStyles = false
|
export let newStyles = false
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -4,12 +4,13 @@ import { groupBy } from "lodash"
|
||||||
import {
|
import {
|
||||||
BindingCompletion,
|
BindingCompletion,
|
||||||
BindingMode,
|
BindingMode,
|
||||||
|
EditorModesMap,
|
||||||
Helper,
|
Helper,
|
||||||
Snippet,
|
Snippet,
|
||||||
} from "@budibase/types"
|
} from "@budibase/types"
|
||||||
import { CompletionContext } from "@codemirror/autocomplete"
|
import { CompletionContext } from "@codemirror/autocomplete"
|
||||||
|
|
||||||
export const EditorModes = {
|
export const EditorModes: EditorModesMap = {
|
||||||
JS: {
|
JS: {
|
||||||
name: "javascript",
|
name: "javascript",
|
||||||
json: false,
|
json: false,
|
||||||
|
|
|
@ -37,7 +37,9 @@
|
||||||
SidePanel,
|
SidePanel,
|
||||||
BindingCompletion,
|
BindingCompletion,
|
||||||
Snippet,
|
Snippet,
|
||||||
|
Helper,
|
||||||
} from "@budibase/types"
|
} from "@budibase/types"
|
||||||
|
import { CompletionContext } from "@codemirror/autocomplete"
|
||||||
|
|
||||||
const dispatch = createEventDispatcher()
|
const dispatch = createEventDispatcher()
|
||||||
|
|
||||||
|
@ -53,8 +55,8 @@
|
||||||
export let placeholder = null
|
export let placeholder = null
|
||||||
export let showTabBar = true
|
export let showTabBar = true
|
||||||
|
|
||||||
let mode: BindingMode
|
let mode: BindingMode | null
|
||||||
let sidePanel: SidePanel
|
let sidePanel: SidePanel | null
|
||||||
let initialValueJS = value?.startsWith?.("{{ js ")
|
let initialValueJS = value?.startsWith?.("{{ js ")
|
||||||
let jsValue = initialValueJS ? value : null
|
let jsValue = initialValueJS ? value : null
|
||||||
let hbsValue = initialValueJS ? null : value
|
let hbsValue = initialValueJS ? null : value
|
||||||
|
@ -109,19 +111,19 @@
|
||||||
snippets: Snippet[] | null,
|
snippets: Snippet[] | null,
|
||||||
useSnippets?: boolean
|
useSnippets?: boolean
|
||||||
) => {
|
) => {
|
||||||
const completions = [
|
const completions: ((_: CompletionContext) => any)[] = [
|
||||||
jsAutocomplete([
|
jsAutocomplete([
|
||||||
...bindingCompletions,
|
...bindingCompletions,
|
||||||
...getHelperCompletions(EditorModes.JS),
|
...getHelperCompletions(EditorModes.JS),
|
||||||
]),
|
]),
|
||||||
]
|
]
|
||||||
if (useSnippets) {
|
if (useSnippets && snippets) {
|
||||||
completions.push(snippetAutoComplete(snippets))
|
completions.push(snippetAutoComplete(snippets))
|
||||||
}
|
}
|
||||||
return completions
|
return completions
|
||||||
}
|
}
|
||||||
|
|
||||||
const getModeOptions = (allowHBS, allowJS) => {
|
const getModeOptions = (allowHBS: boolean, allowJS: boolean) => {
|
||||||
let options = []
|
let options = []
|
||||||
if (allowHBS) {
|
if (allowHBS) {
|
||||||
options.push(BindingMode.Text)
|
options.push(BindingMode.Text)
|
||||||
|
@ -132,7 +134,12 @@
|
||||||
return options
|
return options
|
||||||
}
|
}
|
||||||
|
|
||||||
const getSidePanelOptions = (bindings, context, useSnippets, mode) => {
|
const getSidePanelOptions = (
|
||||||
|
bindings: EnrichedBinding[],
|
||||||
|
context: any,
|
||||||
|
useSnippets: boolean,
|
||||||
|
mode: BindingMode | null
|
||||||
|
) => {
|
||||||
let options = []
|
let options = []
|
||||||
if (bindings?.length) {
|
if (bindings?.length) {
|
||||||
options.push(SidePanel.Bindings)
|
options.push(SidePanel.Bindings)
|
||||||
|
@ -146,32 +153,39 @@
|
||||||
return options
|
return options
|
||||||
}
|
}
|
||||||
|
|
||||||
const debouncedEval = Utils.debounce((expression, context, snippets) => {
|
const debouncedEval = Utils.debounce(
|
||||||
try {
|
(expression: string | null, context: any, snippets: Snippet[]) => {
|
||||||
expressionError = null
|
try {
|
||||||
expressionResult = processStringSync(
|
expressionError = null
|
||||||
expression || "",
|
expressionResult = processStringSync(
|
||||||
{
|
expression || "",
|
||||||
...context,
|
{
|
||||||
snippets,
|
...context,
|
||||||
},
|
snippets,
|
||||||
{
|
},
|
||||||
noThrow: false,
|
{
|
||||||
}
|
noThrow: false,
|
||||||
)
|
}
|
||||||
} catch (err) {
|
)
|
||||||
expressionResult = null
|
} catch (err: any) {
|
||||||
expressionError = err
|
expressionResult = null
|
||||||
}
|
expressionError = err
|
||||||
evaluating = false
|
}
|
||||||
}, 260)
|
evaluating = false
|
||||||
|
},
|
||||||
|
260
|
||||||
|
)
|
||||||
|
|
||||||
const requestEval = (expression, context, snippets) => {
|
const requestEval = (
|
||||||
|
expression: string | null,
|
||||||
|
context: any,
|
||||||
|
snippets: Snippet[] | null
|
||||||
|
) => {
|
||||||
evaluating = true
|
evaluating = true
|
||||||
debouncedEval(expression, context, snippets)
|
debouncedEval(expression, context, snippets)
|
||||||
}
|
}
|
||||||
|
|
||||||
const highlightJSON = json => {
|
const highlightJSON = (json: object | string) => {
|
||||||
return JsonFormatter.format(json, {
|
return JsonFormatter.format(json, {
|
||||||
keyColor: "#e06c75",
|
keyColor: "#e06c75",
|
||||||
numberColor: "#e5c07b",
|
numberColor: "#e5c07b",
|
||||||
|
@ -182,7 +196,11 @@
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const enrichBindings = (bindings, context, snippets) => {
|
const enrichBindings = (
|
||||||
|
bindings: EnrichedBinding[],
|
||||||
|
context: any,
|
||||||
|
snippets: Snippet[] | null
|
||||||
|
) => {
|
||||||
// Create a single big array to enrich in one go
|
// Create a single big array to enrich in one go
|
||||||
const bindingStrings = bindings.map(binding => {
|
const bindingStrings = bindings.map(binding => {
|
||||||
if (binding.runtimeBinding.startsWith('trim "')) {
|
if (binding.runtimeBinding.startsWith('trim "')) {
|
||||||
|
@ -193,17 +211,18 @@
|
||||||
return `{{ literal ${binding.runtimeBinding} }}`
|
return `{{ literal ${binding.runtimeBinding} }}`
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
const bindingEvauations = processObjectSync(bindingStrings, {
|
const bindingEvaluations = processObjectSync(bindingStrings, {
|
||||||
...context,
|
...context,
|
||||||
snippets,
|
snippets,
|
||||||
})
|
})
|
||||||
|
|
||||||
// Enrich bindings with evaluations and highlighted HTML
|
// Enrich bindings with evaluations and highlighted HTML
|
||||||
return bindings.map((binding, idx) => {
|
return bindings.map((binding, idx) => {
|
||||||
if (!context) {
|
if (!context || typeof bindingEvaluations !== "object") {
|
||||||
return binding
|
return binding
|
||||||
}
|
}
|
||||||
const value = JSON.stringify(bindingEvauations[idx], null, 2)
|
const evalObj: Record<any, any> = bindingEvaluations
|
||||||
|
const value = JSON.stringify(evalObj[idx], null, 2)
|
||||||
return {
|
return {
|
||||||
...binding,
|
...binding,
|
||||||
value,
|
value,
|
||||||
|
@ -212,29 +231,38 @@
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const updateValue = val => {
|
const updateValue = (val: any) => {
|
||||||
const runtimeExpression = readableToRuntimeBinding(enrichedBindings, val)
|
const runtimeExpression = readableToRuntimeBinding(enrichedBindings, val)
|
||||||
dispatch("change", val)
|
dispatch("change", val)
|
||||||
requestEval(runtimeExpression, context, snippets)
|
requestEval(runtimeExpression, context, snippets)
|
||||||
}
|
}
|
||||||
|
|
||||||
const onSelectHelper = (helper, js) => {
|
const onSelectHelper = (helper: Helper, js?: boolean) => {
|
||||||
bindingHelpers.onSelectHelper(js ? jsValue : hbsValue, helper, { js })
|
bindingHelpers.onSelectHelper(js ? jsValue : hbsValue, helper, {
|
||||||
|
js,
|
||||||
|
dontDecode: undefined,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const onSelectBinding = (binding, { forceJS } = {}) => {
|
const onSelectBinding = (
|
||||||
|
binding: EnrichedBinding,
|
||||||
|
{ forceJS }: { forceJS?: boolean } = {}
|
||||||
|
) => {
|
||||||
const js = usingJS || forceJS
|
const js = usingJS || forceJS
|
||||||
bindingHelpers.onSelectBinding(js ? jsValue : hbsValue, binding, { js })
|
bindingHelpers.onSelectBinding(js ? jsValue : hbsValue, binding, {
|
||||||
|
js,
|
||||||
|
dontDecode: undefined,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const changeMode = newMode => {
|
const changeMode = (newMode: BindingMode) => {
|
||||||
if (targetMode || newMode === mode) {
|
if (targetMode || newMode === mode) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the raw editor value to see if we are abandoning changes
|
// Get the raw editor value to see if we are abandoning changes
|
||||||
let rawValue = editorValue
|
let rawValue = editorValue
|
||||||
if (mode === BindingMode.JavaScript) {
|
if (mode === BindingMode.JavaScript && rawValue) {
|
||||||
rawValue = decodeJSBinding(rawValue)
|
rawValue = decodeJSBinding(rawValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -253,16 +281,16 @@
|
||||||
targetMode = null
|
targetMode = null
|
||||||
}
|
}
|
||||||
|
|
||||||
const changeSidePanel = newSidePanel => {
|
const changeSidePanel = (newSidePanel: SidePanel) => {
|
||||||
sidePanel = newSidePanel === sidePanel ? null : newSidePanel
|
sidePanel = newSidePanel === sidePanel ? null : newSidePanel
|
||||||
}
|
}
|
||||||
|
|
||||||
const onChangeHBSValue = e => {
|
const onChangeHBSValue = (e: { detail: string }) => {
|
||||||
hbsValue = e.detail
|
hbsValue = e.detail
|
||||||
updateValue(hbsValue)
|
updateValue(hbsValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
const onChangeJSValue = e => {
|
const onChangeJSValue = (e: { detail: string }) => {
|
||||||
jsValue = encodeJSBinding(e.detail)
|
jsValue = encodeJSBinding(e.detail)
|
||||||
if (!e.detail?.trim()) {
|
if (!e.detail?.trim()) {
|
||||||
// Don't bother saving empty values as JS
|
// Don't bother saving empty values as JS
|
||||||
|
|
|
@ -43,7 +43,7 @@ export const sequential = fn => {
|
||||||
* invocations is enforced.
|
* invocations is enforced.
|
||||||
* @param callback an async function to run
|
* @param callback an async function to run
|
||||||
* @param minDelay the minimum delay between invocations
|
* @param minDelay the minimum delay between invocations
|
||||||
* @returns {Promise} a debounced version of the callback
|
* @returns a debounced version of the callback
|
||||||
*/
|
*/
|
||||||
export const debounce = (callback, minDelay = 1000) => {
|
export const debounce = (callback, minDelay = 1000) => {
|
||||||
let timeout
|
let timeout
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
type EditorMode =
|
||||||
|
| {
|
||||||
|
key: "JS"
|
||||||
|
name: "javascript"
|
||||||
|
json: boolean
|
||||||
|
match: RegExp
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
key: "Handlebars"
|
||||||
|
name: "handlebars"
|
||||||
|
base: "text/html"
|
||||||
|
match: RegExp
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
key: "Text"
|
||||||
|
name: "text/html"
|
||||||
|
}
|
||||||
|
|
||||||
|
export type EditorModesMap = { [M in EditorMode as M["key"]]: Omit<M, "key"> }
|
|
@ -1 +1,2 @@
|
||||||
export * from "./sidepanel"
|
export * from "./sidepanel"
|
||||||
|
export * from "./codeEditor"
|
||||||
|
|
Loading…
Reference in New Issue