Update snippets to be an array
This commit is contained in:
parent
5b3280832c
commit
706f9b5d4a
|
@ -41,6 +41,7 @@
|
|||
export let allowHelpers = true
|
||||
export let allowSnippets = true
|
||||
export let context = null
|
||||
export let snippets = null
|
||||
export let autofocusEditor = false
|
||||
|
||||
const drawerContext = getContext("drawer")
|
||||
|
@ -69,14 +70,14 @@
|
|||
$: drawerContext?.modal.subscribe(val => (drawerIsModal = val))
|
||||
$: editorModeOptions = allowJS ? [Modes.Text, Modes.JavaScript] : [Modes.Text]
|
||||
$: sidePanelOptions = getSidePanelOptions(context, allowSnippets, mode)
|
||||
$: enrichedBindings = enrichBindings(bindings, context)
|
||||
$: enrichedBindings = enrichBindings(bindings, context, snippets)
|
||||
$: usingJS = mode === Modes.JavaScript
|
||||
$: editorMode =
|
||||
mode === Modes.JavaScript ? EditorModes.JS : EditorModes.Handlebars
|
||||
$: editorValue = editorMode === EditorModes.JS ? jsValue : hbsValue
|
||||
$: bindingCompletions = bindingsToCompletions(enrichedBindings, editorMode)
|
||||
$: runtimeExpression = readableToRuntimeBinding(enrichedBindings, value)
|
||||
$: requestUpdateEvaluation(runtimeExpression, context)
|
||||
$: requestEval(runtimeExpression, context, snippets)
|
||||
$: bindingHelpers = new BindingHelpers(getCaretPosition, insertAtPos)
|
||||
$: {
|
||||
if (!sidePanelOptions.includes(sidePanel)) {
|
||||
|
@ -95,20 +96,23 @@
|
|||
return options
|
||||
}
|
||||
|
||||
const debouncedUpdateEvaluation = Utils.debounce((expression, context) => {
|
||||
expressionResult = processStringSync(expression || "", context)
|
||||
const debouncedEval = Utils.debounce((expression, context, snippets) => {
|
||||
expressionResult = processStringSync(expression || "", {
|
||||
...context,
|
||||
snippets,
|
||||
})
|
||||
evaluating = false
|
||||
}, 260)
|
||||
|
||||
const requestUpdateEvaluation = (expression, context) => {
|
||||
const requestEval = (expression, context, snippets) => {
|
||||
evaluating = true
|
||||
debouncedUpdateEvaluation(expression, context)
|
||||
debouncedEval(expression, context, snippets)
|
||||
}
|
||||
|
||||
const getBindingValue = (binding, context) => {
|
||||
const getBindingValue = (binding, context, snippets) => {
|
||||
const js = `return $("${binding.runtimeBinding}")`
|
||||
const hbs = encodeJSBinding(js)
|
||||
const res = processStringSync(hbs, context)
|
||||
const res = processStringSync(hbs, { ...context, snippets })
|
||||
return JSON.stringify(res, null, 2)
|
||||
}
|
||||
|
||||
|
@ -123,9 +127,9 @@
|
|||
})
|
||||
}
|
||||
|
||||
const enrichBindings = (bindings, context) => {
|
||||
const enrichBindings = (bindings, context, snippets) => {
|
||||
return bindings.map(binding => {
|
||||
const value = getBindingValue(binding, context)
|
||||
const value = getBindingValue(binding, context, snippets)
|
||||
return {
|
||||
...binding,
|
||||
value,
|
||||
|
@ -139,7 +143,7 @@
|
|||
valid = isValid(runtimeExpression)
|
||||
if (valid) {
|
||||
dispatch("change", val)
|
||||
requestUpdateEvaluation(runtimeExpression, context)
|
||||
requestEval(runtimeExpression, context, snippets)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -152,10 +156,6 @@
|
|||
bindingHelpers.onSelectBinding(js ? jsValue : hbsValue, binding, { js })
|
||||
}
|
||||
|
||||
const onSelectSnippet = snippet => {
|
||||
bindingHelpers.onSelectSnippet(jsValue, snippet)
|
||||
}
|
||||
|
||||
const changeMode = newMode => {
|
||||
if (targetMode || newMode === mode) {
|
||||
return
|
||||
|
@ -316,7 +316,10 @@
|
|||
expression={editorValue}
|
||||
/>
|
||||
{:else if sidePanel === SidePanels.Snippets}
|
||||
<SnippetSidePanel addSnippet={onSelectSnippet} />
|
||||
<SnippetSidePanel
|
||||
addSnippet={snippet => bindingHelpers.onSelectSnippet(snippet)}
|
||||
{snippets}
|
||||
/>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<script>
|
||||
import BindingPanel from "./BindingPanel.svelte"
|
||||
import { previewStore } from "stores/builder"
|
||||
import { previewStore, snippetStore } from "stores/builder"
|
||||
import { onMount } from "svelte"
|
||||
|
||||
export let bindings = []
|
||||
|
@ -30,6 +30,7 @@
|
|||
bind:valid
|
||||
bindings={enrichedBindings}
|
||||
context={$previewStore.selectedComponentContext}
|
||||
snippets={$snippetStore}
|
||||
{value}
|
||||
{allowJS}
|
||||
{allowHelpers}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
<script>
|
||||
import BindingPanel from "./BindingPanel.svelte"
|
||||
import { snippetStore } from "stores/builder"
|
||||
|
||||
export let bindings = []
|
||||
export let valid
|
||||
|
@ -22,6 +23,7 @@
|
|||
<BindingPanel
|
||||
bind:valid
|
||||
bindings={enrichedBindings}
|
||||
snippets={$snippetStore}
|
||||
{value}
|
||||
{allowJS}
|
||||
{context}
|
||||
|
|
|
@ -13,43 +13,6 @@
|
|||
let hoveredSnippet
|
||||
let hideTimeout
|
||||
|
||||
snippets = [
|
||||
{
|
||||
name: "Square",
|
||||
code: `
|
||||
return function(num) {
|
||||
return num * num
|
||||
}
|
||||
`,
|
||||
},
|
||||
{
|
||||
name: "HelloWorld",
|
||||
code: `
|
||||
return "Hello, world!"
|
||||
`,
|
||||
},
|
||||
{
|
||||
name: "Colorful",
|
||||
code: `
|
||||
let a = null
|
||||
let b = "asdasd"
|
||||
let c = 123123
|
||||
let d = undefined
|
||||
let e = [1, 2, 3]
|
||||
let f = { foo: "bar" }
|
||||
let g = Math.round(1.234)
|
||||
if (a === b) {
|
||||
return c ?? e
|
||||
}
|
||||
return d || f
|
||||
// comment
|
||||
let h = 1 + 2 + 3 * 3
|
||||
let i = true
|
||||
let j = false
|
||||
`,
|
||||
},
|
||||
]
|
||||
|
||||
$: filteredSnippets = getFilteredSnippets(snippets, search)
|
||||
|
||||
const getFilteredSnippets = (snippets, search) => {
|
||||
|
|
|
@ -40,11 +40,9 @@ export class BindingHelpers {
|
|||
}
|
||||
|
||||
// Adds a JS/HBS helper to the expression
|
||||
onSelectSnippet(value, snippet) {
|
||||
onSelectSnippet(snippet) {
|
||||
const pos = this.getCaretPosition()
|
||||
const { start, end } = pos
|
||||
const jsVal = decodeJSBinding(value)
|
||||
const insertVal = jsInsert(jsVal, start, end, `snippets.${snippet.name}`)
|
||||
this.insertAtPos({ start, end, value: insertVal })
|
||||
this.insertAtPos({ start, end, value: `snippets.${snippet.name}` })
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ import {
|
|||
} from "./automations.js"
|
||||
import { userStore, userSelectedResourceMap, isOnlyUser } from "./users.js"
|
||||
import { deploymentStore } from "./deployments.js"
|
||||
import { snippetStore } from "./snippets"
|
||||
|
||||
// Backend
|
||||
import { tables } from "./tables"
|
||||
|
@ -62,6 +63,7 @@ export {
|
|||
queries,
|
||||
flags,
|
||||
hoverStore,
|
||||
snippetStore,
|
||||
}
|
||||
|
||||
export const reset = () => {
|
||||
|
@ -101,6 +103,7 @@ export const initialise = async pkg => {
|
|||
builderStore.init(application)
|
||||
navigationStore.syncAppNavigation(application?.navigation)
|
||||
themeStore.syncAppTheme(application)
|
||||
snippetStore.syncMetadata(application)
|
||||
screenStore.syncAppScreens(pkg)
|
||||
layoutStore.syncAppLayouts(pkg)
|
||||
resetBuilderHistory()
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
import { writable } from "svelte/store"
|
||||
|
||||
const EXAMPLE_SNIPPETS = [
|
||||
{
|
||||
name: "Square",
|
||||
code: `
|
||||
return function(num) {
|
||||
return num * num
|
||||
}
|
||||
`,
|
||||
},
|
||||
{
|
||||
name: "HelloWorld",
|
||||
code: `
|
||||
return "Hello, world!"
|
||||
`,
|
||||
},
|
||||
{
|
||||
name: "Colorful",
|
||||
code: `
|
||||
let a = null
|
||||
let b = "asdasd"
|
||||
let c = 123123
|
||||
let d = undefined
|
||||
let e = [1, 2, 3]
|
||||
let f = { foo: "bar" }
|
||||
let g = Math.round(1.234)
|
||||
if (a === b) {
|
||||
return c ?? e
|
||||
}
|
||||
return d || f
|
||||
// comment
|
||||
let h = 1 + 2 + 3 * 3
|
||||
let i = true
|
||||
let j = false
|
||||
`,
|
||||
},
|
||||
]
|
||||
|
||||
const createSnippetStore = () => {
|
||||
const store = writable(EXAMPLE_SNIPPETS)
|
||||
|
||||
const syncMetadata = metadata => {
|
||||
store.set(metadata?.snippets || EXAMPLE_SNIPPETS)
|
||||
}
|
||||
|
||||
const createSnippet = snippet => {
|
||||
store.update(state => [...state, snippet])
|
||||
}
|
||||
|
||||
const updateSnippet = updatedSnippet => {
|
||||
store.update(state => [
|
||||
...state.filter(snippet => snippet.name !== updatedSnippet.name),
|
||||
updatedSnippet,
|
||||
])
|
||||
}
|
||||
|
||||
const deleteSnippet = snippetName => {
|
||||
store.update(state => state.filter(snippet => snippet.name !== snippetName))
|
||||
}
|
||||
|
||||
return {
|
||||
...store,
|
||||
syncMetadata,
|
||||
createSnippet,
|
||||
updateSnippet,
|
||||
deleteSnippet,
|
||||
}
|
||||
}
|
||||
|
||||
export const snippetStore = createSnippetStore()
|
|
@ -6,6 +6,7 @@ import {
|
|||
themeStore,
|
||||
navigationStore,
|
||||
deploymentStore,
|
||||
snippetStore,
|
||||
datasources,
|
||||
tables,
|
||||
} from "stores/builder"
|
||||
|
@ -64,6 +65,7 @@ export const createBuilderWebsocket = appId => {
|
|||
appStore.syncMetadata(metadata)
|
||||
themeStore.syncMetadata(metadata)
|
||||
navigationStore.syncMetadata(metadata)
|
||||
snippetStore.syncMetadata(metadata)
|
||||
})
|
||||
socket.onOther(
|
||||
BuilderSocketEvent.AppPublishChange,
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
"use strict";var snippets=(()=>{var s=Object.create;var p=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var c=Object.getOwnPropertyNames;var l=Object.getPrototypeOf,m=Object.prototype.hasOwnProperty;var W=(e,r)=>()=>(r||e((r={exports:{}}).exports,r),r.exports),d=(e,r)=>{for(var n in r)p(e,n,{get:r[n],enumerable:!0})},o=(e,r,n,i)=>{if(r&&typeof r=="object"||typeof r=="function")for(let t of c(r))!m.call(e,t)&&t!==n&&p(e,t,{get:()=>r[t],enumerable:!(i=x(r,t))||i.enumerable});return e};var g=(e,r,n)=>(n=e!=null?s(l(e)):{},o(r||!e||!e.__esModule?p(n,"default",{value:e,enumerable:!0}):n,e)),v=e=>o(p({},"__esModule",{value:!0}),e);var u=W((_,f)=>{f.exports.iifeWrapper=e=>`(function(){
|
||||
"use strict";var snippets=(()=>{var u=Object.create;var i=Object.defineProperty;var c=Object.getOwnPropertyDescriptor;var d=Object.getOwnPropertyNames;var m=Object.getPrototypeOf,x=Object.prototype.hasOwnProperty;var l=(e,n)=>()=>(n||e((n={exports:{}}).exports,n),n.exports),W=(e,n)=>{for(var r in n)i(e,r,{get:n[r],enumerable:!0})},o=(e,n,r,p)=>{if(n&&typeof n=="object"||typeof n=="function")for(let t of d(n))!x.call(e,t)&&t!==r&&i(e,t,{get:()=>n[t],enumerable:!(p=c(n,t))||p.enumerable});return e};var g=(e,n,r)=>(r=e!=null?u(m(e)):{},o(n||!e||!e.__esModule?i(r,"default",{value:e,enumerable:!0}):r,e)),v=e=>o(i({},"__esModule",{value:!0}),e);var a=l((_,f)=>{f.exports.iifeWrapper=e=>`(function(){
|
||||
${e}
|
||||
})();`});var y={};d(y,{default:()=>w});var a=g(u()),w=new Proxy({},{get:function(e,r){return[eval][0]((0,a.iifeWrapper)($("snippets")[r]))}});return v(y);})();
|
||||
})();`});var y={};W(y,{default:()=>w});var s=g(a()),w=new Proxy({},{get:function(e,n){let r=($("snippets")||[]).find(p=>p.name===n);return[eval][0]((0,s.iifeWrapper)(r.code))}});return v(y);})();
|
||||
|
|
|
@ -7,12 +7,14 @@ export default new Proxy(
|
|||
{
|
||||
get: function (_, name) {
|
||||
// Get snippet definitions from global context, get the correct snippet
|
||||
// then eval the JS.
|
||||
// then eval the JS. This will error if the snippet doesn't exist, but
|
||||
// that's intended.
|
||||
// https://esbuild.github.io/content-types/#direct-eval for info on why
|
||||
// eval is being called this way.
|
||||
// @ts-ignore
|
||||
// eslint-disable-next-line no-undef
|
||||
return [eval][0](iifeWrapper($("snippets")[name]))
|
||||
const snippet = ($("snippets") || []).find(x => x.name === name)
|
||||
return [eval][0](iifeWrapper(snippet.code))
|
||||
},
|
||||
}
|
||||
)
|
||||
|
|
|
@ -63,7 +63,9 @@ module.exports.processJS = (handlebars, context) => {
|
|||
{},
|
||||
{
|
||||
get: function (_, name) {
|
||||
return eval(iifeWrapper(context.snippets[name]))
|
||||
// This will error if the snippet doesn't exist, but that's intended
|
||||
const snippet = (context.snippets || []).find(x => x.name === name)
|
||||
return eval(iifeWrapper(snippet.code))
|
||||
},
|
||||
}
|
||||
),
|
||||
|
|
Loading…
Reference in New Issue