From 2fdf2289ed416ac8dc3bd70d94d82f9e74dc9a0f Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Tue, 14 Jan 2025 18:49:32 +0000 Subject: [PATCH] Further conversions. --- packages/bbui/src/Icon/Icon.svelte | 8 +- .../src/components/common/CodeEditor/index.ts | 3 +- .../common/bindings/BindingPanel.svelte | 110 +++++++++++------- packages/frontend-core/src/utils/utils.js | 2 +- .../types/src/ui/components/codeEditor.ts | 19 +++ packages/types/src/ui/components/index.ts | 1 + 6 files changed, 96 insertions(+), 47 deletions(-) create mode 100644 packages/types/src/ui/components/codeEditor.ts diff --git a/packages/bbui/src/Icon/Icon.svelte b/packages/bbui/src/Icon/Icon.svelte index 73ad8edd10..c22bb3f918 100644 --- a/packages/bbui/src/Icon/Icon.svelte +++ b/packages/bbui/src/Icon/Icon.svelte @@ -10,12 +10,12 @@ export let size = "M" export let hoverable = false export let disabled = false - export let color - export let hoverColor - export let tooltip + export let color = undefined + export let hoverColor = undefined + export let tooltip = undefined export let tooltipPosition = TooltipPosition.Bottom export let tooltipType = TooltipType.Default - export let tooltipColor + export let tooltipColor = undefined export let tooltipWrap = true export let newStyles = false diff --git a/packages/builder/src/components/common/CodeEditor/index.ts b/packages/builder/src/components/common/CodeEditor/index.ts index 0063cfc789..d2cbe8a23e 100644 --- a/packages/builder/src/components/common/CodeEditor/index.ts +++ b/packages/builder/src/components/common/CodeEditor/index.ts @@ -4,12 +4,13 @@ import { groupBy } from "lodash" import { BindingCompletion, BindingMode, + EditorModesMap, Helper, Snippet, } from "@budibase/types" import { CompletionContext } from "@codemirror/autocomplete" -export const EditorModes = { +export const EditorModes: EditorModesMap = { JS: { name: "javascript", json: false, diff --git a/packages/builder/src/components/common/bindings/BindingPanel.svelte b/packages/builder/src/components/common/bindings/BindingPanel.svelte index 29ddb6a1d0..6b9119f433 100644 --- a/packages/builder/src/components/common/bindings/BindingPanel.svelte +++ b/packages/builder/src/components/common/bindings/BindingPanel.svelte @@ -37,7 +37,9 @@ SidePanel, BindingCompletion, Snippet, + Helper, } from "@budibase/types" + import { CompletionContext } from "@codemirror/autocomplete" const dispatch = createEventDispatcher() @@ -53,8 +55,8 @@ export let placeholder = null export let showTabBar = true - let mode: BindingMode - let sidePanel: SidePanel + let mode: BindingMode | null + let sidePanel: SidePanel | null let initialValueJS = value?.startsWith?.("{{ js ") let jsValue = initialValueJS ? value : null let hbsValue = initialValueJS ? null : value @@ -109,19 +111,19 @@ snippets: Snippet[] | null, useSnippets?: boolean ) => { - const completions = [ + const completions: ((_: CompletionContext) => any)[] = [ jsAutocomplete([ ...bindingCompletions, ...getHelperCompletions(EditorModes.JS), ]), ] - if (useSnippets) { + if (useSnippets && snippets) { completions.push(snippetAutoComplete(snippets)) } return completions } - const getModeOptions = (allowHBS, allowJS) => { + const getModeOptions = (allowHBS: boolean, allowJS: boolean) => { let options = [] if (allowHBS) { options.push(BindingMode.Text) @@ -132,7 +134,12 @@ return options } - const getSidePanelOptions = (bindings, context, useSnippets, mode) => { + const getSidePanelOptions = ( + bindings: EnrichedBinding[], + context: any, + useSnippets: boolean, + mode: BindingMode | null + ) => { let options = [] if (bindings?.length) { options.push(SidePanel.Bindings) @@ -146,32 +153,39 @@ return options } - const debouncedEval = Utils.debounce((expression, context, snippets) => { - try { - expressionError = null - expressionResult = processStringSync( - expression || "", - { - ...context, - snippets, - }, - { - noThrow: false, - } - ) - } catch (err) { - expressionResult = null - expressionError = err - } - evaluating = false - }, 260) + const debouncedEval = Utils.debounce( + (expression: string | null, context: any, snippets: Snippet[]) => { + try { + expressionError = null + expressionResult = processStringSync( + expression || "", + { + ...context, + snippets, + }, + { + noThrow: false, + } + ) + } catch (err: any) { + expressionResult = null + expressionError = err + } + evaluating = false + }, + 260 + ) - const requestEval = (expression, context, snippets) => { + const requestEval = ( + expression: string | null, + context: any, + snippets: Snippet[] | null + ) => { evaluating = true debouncedEval(expression, context, snippets) } - const highlightJSON = json => { + const highlightJSON = (json: object | string) => { return JsonFormatter.format(json, { keyColor: "#e06c75", 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 const bindingStrings = bindings.map(binding => { if (binding.runtimeBinding.startsWith('trim "')) { @@ -193,17 +211,18 @@ return `{{ literal ${binding.runtimeBinding} }}` } }) - const bindingEvauations = processObjectSync(bindingStrings, { + const bindingEvaluations = processObjectSync(bindingStrings, { ...context, snippets, }) // Enrich bindings with evaluations and highlighted HTML return bindings.map((binding, idx) => { - if (!context) { + if (!context || typeof bindingEvaluations !== "object") { return binding } - const value = JSON.stringify(bindingEvauations[idx], null, 2) + const evalObj: Record = bindingEvaluations + const value = JSON.stringify(evalObj[idx], null, 2) return { ...binding, value, @@ -212,29 +231,38 @@ }) } - const updateValue = val => { + const updateValue = (val: any) => { const runtimeExpression = readableToRuntimeBinding(enrichedBindings, val) dispatch("change", val) requestEval(runtimeExpression, context, snippets) } - const onSelectHelper = (helper, js) => { - bindingHelpers.onSelectHelper(js ? jsValue : hbsValue, helper, { js }) + const onSelectHelper = (helper: Helper, js?: boolean) => { + bindingHelpers.onSelectHelper(js ? jsValue : hbsValue, helper, { + js, + dontDecode: undefined, + }) } - const onSelectBinding = (binding, { forceJS } = {}) => { + const onSelectBinding = ( + binding: EnrichedBinding, + { forceJS }: { forceJS?: boolean } = {} + ) => { 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) { return } // Get the raw editor value to see if we are abandoning changes let rawValue = editorValue - if (mode === BindingMode.JavaScript) { + if (mode === BindingMode.JavaScript && rawValue) { rawValue = decodeJSBinding(rawValue) } @@ -253,16 +281,16 @@ targetMode = null } - const changeSidePanel = newSidePanel => { + const changeSidePanel = (newSidePanel: SidePanel) => { sidePanel = newSidePanel === sidePanel ? null : newSidePanel } - const onChangeHBSValue = e => { + const onChangeHBSValue = (e: { detail: string }) => { hbsValue = e.detail updateValue(hbsValue) } - const onChangeJSValue = e => { + const onChangeJSValue = (e: { detail: string }) => { jsValue = encodeJSBinding(e.detail) if (!e.detail?.trim()) { // Don't bother saving empty values as JS diff --git a/packages/frontend-core/src/utils/utils.js b/packages/frontend-core/src/utils/utils.js index 55603b0129..f0635fbeac 100644 --- a/packages/frontend-core/src/utils/utils.js +++ b/packages/frontend-core/src/utils/utils.js @@ -43,7 +43,7 @@ export const sequential = fn => { * invocations is enforced. * @param callback an async function to run * @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) => { let timeout diff --git a/packages/types/src/ui/components/codeEditor.ts b/packages/types/src/ui/components/codeEditor.ts new file mode 100644 index 0000000000..8ea885b667 --- /dev/null +++ b/packages/types/src/ui/components/codeEditor.ts @@ -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 } diff --git a/packages/types/src/ui/components/index.ts b/packages/types/src/ui/components/index.ts index 6638d36b32..8dc1638f8c 100644 --- a/packages/types/src/ui/components/index.ts +++ b/packages/types/src/ui/components/index.ts @@ -1 +1,2 @@ export * from "./sidepanel" +export * from "./codeEditor"