Further conversions.

This commit is contained in:
mike12345567 2025-01-14 18:49:32 +00:00
parent 095eb0fe3a
commit 2fdf2289ed
6 changed files with 96 additions and 47 deletions

View File

@ -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>

View File

@ -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,

View File

@ -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,7 +153,8 @@
return options return options
} }
const debouncedEval = Utils.debounce((expression, context, snippets) => { const debouncedEval = Utils.debounce(
(expression: string | null, context: any, snippets: Snippet[]) => {
try { try {
expressionError = null expressionError = null
expressionResult = processStringSync( expressionResult = processStringSync(
@ -159,19 +167,25 @@
noThrow: false, noThrow: false,
} }
) )
} catch (err) { } catch (err: any) {
expressionResult = null expressionResult = null
expressionError = err expressionError = err
} }
evaluating = false evaluating = false
}, 260) },
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

View File

@ -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

View File

@ -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"> }

View File

@ -1 +1,2 @@
export * from "./sidepanel" export * from "./sidepanel"
export * from "./codeEditor"