diff --git a/lerna.json b/lerna.json
index c893e4b402..afcb33918b 100644
--- a/lerna.json
+++ b/lerna.json
@@ -1,6 +1,6 @@
{
"$schema": "node_modules/lerna/schemas/lerna-schema.json",
- "version": "3.4.6",
+ "version": "3.4.9",
"npmClient": "yarn",
"concurrency": 20,
"command": {
diff --git a/packages/backend-core/src/utils/utils.ts b/packages/backend-core/src/utils/utils.ts
index 30cf55b149..7f2e25b6d4 100644
--- a/packages/backend-core/src/utils/utils.ts
+++ b/packages/backend-core/src/utils/utils.ts
@@ -247,3 +247,7 @@ export function hasCircularStructure(json: any) {
}
return false
}
+
+export function urlHasProtocol(url: string): boolean {
+ return !!url.match(/^.+:\/\/.+$/)
+}
diff --git a/packages/bbui/src/Typography/Body.svelte b/packages/bbui/src/Typography/Body.svelte
index 2123eeee95..06664c9033 100644
--- a/packages/bbui/src/Typography/Body.svelte
+++ b/packages/bbui/src/Typography/Body.svelte
@@ -1,11 +1,11 @@
-
{
+const buildHelperInfoNode = (helper: Helper) => {
const ele = document.createElement("div")
ele.classList.add("info-bubble")
@@ -65,7 +54,7 @@ const toSpectrumIcon = (name: string) => {
`
}
-export const buildSectionHeader = (
+const buildSectionHeader = (
type: string,
sectionName: string,
icon: string,
@@ -84,30 +73,27 @@ export const buildSectionHeader = (
}
}
-export const helpersToCompletion = (
+const helpersToCompletion = (
helpers: Record,
mode: { name: "javascript" | "handlebars" }
-) => {
- const { type, name: sectionName, icon } = SECTIONS.HB_HELPER
- const helperSection = buildSectionHeader(type, sectionName, icon, 99)
+): BindingCompletionOption[] => {
+ const helperSection = buildSectionHeader("helper", "Helpers", "Code", 99)
return Object.keys(helpers).flatMap(helperName => {
- let helper = helpers[helperName]
+ const helper = helpers[helperName]
return {
label: helperName,
- info: (completion: BindingCompletion) => {
- return buildHelperInfoNode(completion, helper)
- },
+ info: () => buildHelperInfoNode(helper),
type: "helper",
section: helperSection,
detail: "Function",
apply: (
- view: any,
- completion: BindingCompletion,
+ view: EditorView,
+ _completion: BindingCompletionOption,
from: number,
to: number
) => {
- insertBinding(view, from, to, helperName, mode)
+ insertBinding(view, from, to, helperName, mode, AutocompleteType.HELPER)
},
}
})
@@ -115,7 +101,7 @@ export const helpersToCompletion = (
export const getHelperCompletions = (mode: {
name: "javascript" | "handlebars"
-}) => {
+}): BindingCompletionOption[] => {
// TODO: manifest needs to be properly typed
const manifest: any = getManifest()
return Object.keys(manifest).flatMap(key => {
@@ -123,49 +109,33 @@ export const getHelperCompletions = (mode: {
})
}
-export const snippetAutoComplete = (snippets: Snippet[]) => {
- return function myCompletions(context: CompletionContext) {
- if (!snippets?.length) {
- return null
- }
- const word = context.matchBefore(/\w*/)
- if (!word || (word.from == word.to && !context.explicit)) {
- return null
- }
- return {
- from: word.from,
- options: snippets.map(snippet => ({
- label: `snippets.${snippet.name}`,
- type: "text",
- simple: true,
- apply: (
- view: any,
- completion: BindingCompletion,
- from: number,
- to: number
- ) => {
- insertSnippet(view, from, to, completion.label)
- },
- })),
- }
- }
+export const snippetAutoComplete = (snippets: Snippet[]): BindingCompletion => {
+ return setAutocomplete(
+ snippets.map(snippet => ({
+ section: buildSectionHeader("snippets", "Snippets", "Code", 100),
+ label: `snippets.${snippet.name}`,
+ displayLabel: snippet.name,
+ }))
+ )
}
-const bindingFilter = (options: BindingCompletion[], query: string) => {
+const bindingFilter = (options: BindingCompletionOption[], query: string) => {
return options.filter(completion => {
- const section_parsed = completion.section.name.toLowerCase()
+ const section_parsed = completion.section?.toString().toLowerCase()
const label_parsed = completion.label.toLowerCase()
const query_parsed = query.toLowerCase()
return (
- section_parsed.includes(query_parsed) ||
+ section_parsed?.includes(query_parsed) ||
label_parsed.includes(query_parsed)
)
})
}
-export const hbAutocomplete = (baseCompletions: BindingCompletion[]) => {
- async function coreCompletion(context: CompletionContext) {
+export const hbAutocomplete = (
+ baseCompletions: BindingCompletionOption[]
+): BindingCompletion => {
+ function coreCompletion(context: CompletionContext) {
let bindingStart = context.matchBefore(EditorModes.Handlebars.match)
let options = baseCompletions || []
@@ -191,9 +161,15 @@ export const hbAutocomplete = (baseCompletions: BindingCompletion[]) => {
return coreCompletion
}
-export const jsAutocomplete = (baseCompletions: BindingCompletion[]) => {
- async function coreCompletion(context: CompletionContext) {
- let jsBinding = context.matchBefore(/\$\("[\s\w]*/)
+function wrappedAutocompleteMatch(context: CompletionContext) {
+ return context.matchBefore(/\$\("[\s\w]*/)
+}
+
+export const jsAutocomplete = (
+ baseCompletions: BindingCompletionOption[]
+): BindingCompletion => {
+ function coreCompletion(context: CompletionContext) {
+ let jsBinding = wrappedAutocompleteMatch(context)
let options = baseCompletions || []
if (jsBinding) {
@@ -217,10 +193,42 @@ export const jsAutocomplete = (baseCompletions: BindingCompletion[]) => {
return coreCompletion
}
-export const buildBindingInfoNode = (
- completion: BindingCompletion,
- binding: any
-) => {
+export const jsHelperAutocomplete = (
+ baseCompletions: BindingCompletionOption[]
+): BindingCompletion => {
+ return setAutocomplete(
+ baseCompletions.map(helper => ({
+ ...helper,
+ displayLabel: helper.label,
+ label: `helpers.${helper.label}()`,
+ }))
+ )
+}
+
+function setAutocomplete(
+ options: BindingCompletionOption[]
+): BindingCompletion {
+ return function (context: CompletionContext) {
+ if (wrappedAutocompleteMatch(context)) {
+ return null
+ }
+
+ const word = context.matchBefore(/\b\w*(\.\w*)?/)
+ if (!word || (word.from == word.to && !context.explicit)) {
+ return null
+ }
+
+ return {
+ from: word.from,
+ options,
+ }
+ }
+}
+
+const buildBindingInfoNode = (binding: {
+ valueHTML: string
+ value: string | null
+}) => {
if (!binding.valueHTML || binding.value == null) {
return null
}
@@ -278,18 +286,28 @@ export function jsInsert(
return parsedInsert
}
+const enum AutocompleteType {
+ BINDING,
+ HELPER,
+ TEXT,
+}
+
// Autocomplete apply behaviour
-export const insertBinding = (
- view: any,
+const insertBinding = (
+ view: EditorView,
from: number,
to: number,
text: string,
- mode: { name: "javascript" | "handlebars" }
+ mode: { name: "javascript" | "handlebars" },
+ type: AutocompleteType
) => {
let parsedInsert
if (mode.name == "javascript") {
- parsedInsert = jsInsert(view.state.doc?.toString(), from, to, text)
+ parsedInsert = jsInsert(view.state.doc?.toString(), from, to, text, {
+ helper: type === AutocompleteType.HELPER,
+ disableWrapping: type === AutocompleteType.TEXT,
+ })
} else if (mode.name == "handlebars") {
parsedInsert = hbInsert(view.state.doc?.toString(), from, to, text)
} else {
@@ -319,30 +337,11 @@ export const insertBinding = (
})
}
-export const insertSnippet = (
- view: any,
- from: number,
- to: number,
- text: string
-) => {
- let cursorPos = from + text.length
- view.dispatch({
- changes: {
- from,
- to,
- insert: text,
- },
- selection: {
- anchor: cursorPos,
- },
- })
-}
-
// TODO: typing in this function isn't great
export const bindingsToCompletions = (
bindings: any,
mode: { name: "javascript" | "handlebars" }
-) => {
+): BindingCompletionOption[] => {
const bindingByCategory = groupBy(bindings, "category")
const categoryMeta = bindings?.reduce((acc: any, ele: any) => {
acc[ele.category] = acc[ele.category] || {}
@@ -356,46 +355,54 @@ export const bindingsToCompletions = (
return acc
}, {})
- const completions = Object.keys(bindingByCategory).reduce(
- (comps: any, catKey: string) => {
- const { icon, rank } = categoryMeta[catKey] || {}
+ const completions = Object.keys(bindingByCategory).reduce<
+ BindingCompletionOption[]
+ >((comps, catKey) => {
+ const { icon, rank } = categoryMeta[catKey] || {}
- const bindingSectionHeader = buildSectionHeader(
- // @ts-ignore something wrong with this - logically this should be dictionary
- bindingByCategory.type,
- catKey,
- icon || "",
- typeof rank == "number" ? rank : 1
- )
+ const bindingSectionHeader = buildSectionHeader(
+ // @ts-ignore something wrong with this - logically this should be dictionary
+ bindingByCategory.type,
+ catKey,
+ icon || "",
+ typeof rank == "number" ? rank : 1
+ )
- return [
- ...comps,
- ...bindingByCategory[catKey].reduce((acc, binding) => {
+ comps.push(
+ ...bindingByCategory[catKey].reduce(
+ (acc, binding) => {
let displayType = binding.fieldSchema?.type || binding.display?.type
acc.push({
label:
binding.display?.name || binding.readableBinding || "NO NAME",
- info: (completion: BindingCompletion) => {
- return buildBindingInfoNode(completion, binding)
- },
+ info: () => buildBindingInfoNode(binding),
type: "binding",
detail: displayType,
section: bindingSectionHeader,
apply: (
- view: any,
- completion: BindingCompletion,
+ view: EditorView,
+ _completion: BindingCompletionOption,
from: number,
to: number
) => {
- insertBinding(view, from, to, binding.readableBinding, mode)
+ insertBinding(
+ view,
+ from,
+ to,
+ binding.readableBinding,
+ mode,
+ AutocompleteType.BINDING
+ )
},
})
return acc
- }, []),
- ]
- },
- []
- )
+ },
+ []
+ )
+ )
+
+ return comps
+ }, [])
return completions
}
diff --git a/packages/builder/src/components/common/bindings/BindingPanel.svelte b/packages/builder/src/components/common/bindings/BindingPanel.svelte
index ffb477012c..4bd37bf72c 100644
--- a/packages/builder/src/components/common/bindings/BindingPanel.svelte
+++ b/packages/builder/src/components/common/bindings/BindingPanel.svelte
@@ -23,6 +23,7 @@
snippetAutoComplete,
EditorModes,
bindingsToCompletions,
+ jsHelperAutocomplete,
} from "../CodeEditor"
import BindingSidePanel from "./BindingSidePanel.svelte"
import EvaluationSidePanel from "./EvaluationSidePanel.svelte"
@@ -34,7 +35,6 @@
import { BindingMode, SidePanel } from "@budibase/types"
import type {
EnrichedBinding,
- BindingCompletion,
Snippet,
Helper,
CaretPositionFn,
@@ -42,7 +42,7 @@
JSONValue,
} from "@budibase/types"
import type { Log } from "@budibase/string-templates"
- import type { CompletionContext } from "@codemirror/autocomplete"
+ import type { BindingCompletion, BindingCompletionOption } from "@/types"
const dispatch = createEventDispatcher()
@@ -91,7 +91,10 @@
$: bindingCompletions = bindingsToCompletions(enrichedBindings, editorMode)
$: bindingHelpers = new BindingHelpers(getCaretPosition, insertAtPos)
$: hbsCompletions = getHBSCompletions(bindingCompletions)
- $: jsCompletions = getJSCompletions(bindingCompletions, snippets, useSnippets)
+ $: jsCompletions = getJSCompletions(bindingCompletions, snippets, {
+ useHelpers: allowHelpers,
+ useSnippets,
+ })
$: {
// Ensure a valid side panel option is always selected
if (sidePanel && !sidePanelOptions.includes(sidePanel)) {
@@ -99,7 +102,7 @@
}
}
- const getHBSCompletions = (bindingCompletions: BindingCompletion[]) => {
+ const getHBSCompletions = (bindingCompletions: BindingCompletionOption[]) => {
return [
hbAutocomplete([
...bindingCompletions,
@@ -109,17 +112,23 @@
}
const getJSCompletions = (
- bindingCompletions: BindingCompletion[],
+ bindingCompletions: BindingCompletionOption[],
snippets: Snippet[] | null,
- useSnippets?: boolean
+ config: {
+ useHelpers: boolean
+ useSnippets: boolean
+ }
) => {
- const completions: ((_: CompletionContext) => any)[] = [
- jsAutocomplete([
- ...bindingCompletions,
- ...getHelperCompletions(EditorModes.JS),
- ]),
- ]
- if (useSnippets && snippets) {
+ const completions: BindingCompletion[] = []
+ if (bindingCompletions.length) {
+ completions.push(jsAutocomplete([...bindingCompletions]))
+ }
+ if (config.useHelpers) {
+ completions.push(
+ jsHelperAutocomplete([...getHelperCompletions(EditorModes.JS)])
+ )
+ }
+ if (config.useSnippets && snippets) {
completions.push(snippetAutoComplete(snippets))
}
return completions
@@ -381,7 +390,7 @@
autofocus={autofocusEditor}
placeholder={placeholder ||
"Add bindings by typing $ or use the menu on the right"}
- jsBindingWrapping
+ jsBindingWrapping={bindingCompletions.length > 0}
/>
{/key}
{/if}
diff --git a/packages/builder/src/components/common/bindings/SnippetDrawer.svelte b/packages/builder/src/components/common/bindings/SnippetDrawer.svelte
index f10c44f81f..4862217b13 100644
--- a/packages/builder/src/components/common/bindings/SnippetDrawer.svelte
+++ b/packages/builder/src/components/common/bindings/SnippetDrawer.svelte
@@ -118,6 +118,7 @@
allowHBS={false}
allowJS
allowSnippets={false}
+ allowHelpers={false}
showTabBar={false}
placeholder="return function(input) ❴ ... ❵"
value={code}
diff --git a/packages/builder/src/components/design/settings/controls/URLVariableTestInput.svelte b/packages/builder/src/components/design/settings/controls/URLVariableTestInput.svelte
new file mode 100644
index 0000000000..a75d7e625d
--- /dev/null
+++ b/packages/builder/src/components/design/settings/controls/URLVariableTestInput.svelte
@@ -0,0 +1,126 @@
+
+
+{#if hasUrlParams}
+
+
+
+
+
+
+{/if}
+
+
diff --git a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/_components/Screen/GeneralPanel.svelte b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/_components/Screen/GeneralPanel.svelte
index 3a6e7a702c..31479bc820 100644
--- a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/_components/Screen/GeneralPanel.svelte
+++ b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/_components/Screen/GeneralPanel.svelte
@@ -15,6 +15,7 @@
import ButtonActionEditor from "@/components/design/settings/controls/ButtonActionEditor/ButtonActionEditor.svelte"
import { getBindableProperties } from "@/dataBinding"
import BarButtonList from "@/components/design/settings/controls/BarButtonList.svelte"
+ import URLVariableTestInput from "@/components/design/settings/controls/URLVariableTestInput.svelte"
$: bindings = getBindableProperties($selectedScreen, null)
$: screenSettings = getScreenSettings($selectedScreen)
@@ -93,6 +94,13 @@
],
},
},
+ {
+ key: "urlTest",
+ control: URLVariableTestInput,
+ props: {
+ baseRoute: screen.routing?.route,
+ },
+ },
]
return settings
diff --git a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/new/_components/NewComponentPanel.svelte b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/new/_components/NewComponentPanel.svelte
index aa0b26f6b7..d13d72b89f 100644
--- a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/new/_components/NewComponentPanel.svelte
+++ b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/new/_components/NewComponentPanel.svelte
@@ -13,6 +13,11 @@
import { fly } from "svelte/transition"
import { findComponentPath } from "@/helpers/components"
+ // Smallest possible 1x1 transparent GIF
+ const ghost = new Image(1, 1)
+ ghost.src =
+ "data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=="
+
let searchString
let searchRef
let selectedIndex
@@ -217,7 +222,8 @@
}
})
- const onDragStart = component => {
+ const onDragStart = (e, component) => {
+ e.dataTransfer.setDragImage(ghost, 0, 0)
previewStore.startDrag(component)
}
@@ -250,13 +256,12 @@
{#each category.children as component}
onDragStart(component.component)}
+ on:dragstart={e => onDragStart(e, component.component)}
on:dragend={onDragEnd}
class="component"
class:selected={selectedIndex === orderMap[component.component]}
on:click={() => addComponent(component.component)}
- on:mouseover={() => (selectedIndex = null)}
- on:focus
+ on:mouseenter={() => (selectedIndex = null)}
>
{component.name}
@@ -308,7 +313,6 @@
}
.component:hover {
background: var(--spectrum-global-color-gray-300);
- cursor: pointer;
}
.component :global(.spectrum-Body) {
line-height: 1.2 !important;
diff --git a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/AppPreview.svelte b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/AppPreview.svelte
index ba600c8eef..59548ada01 100644
--- a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/AppPreview.svelte
+++ b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/AppPreview.svelte
@@ -189,8 +189,8 @@
} else if (type === "reload-plugin") {
await componentStore.refreshDefinitions()
} else if (type === "drop-new-component") {
- const { component, parent, index } = data
- await componentStore.create(component, null, parent, index)
+ const { component, parent, index, props } = data
+ await componentStore.create(component, props, parent, index)
} else if (type === "add-parent-component") {
const { componentId, parentType } = data
await componentStore.addParent(componentId, parentType)
diff --git a/packages/builder/src/stores/builder/app.ts b/packages/builder/src/stores/builder/app.ts
index 3c8ed4afc1..abebb5d9f1 100644
--- a/packages/builder/src/stores/builder/app.ts
+++ b/packages/builder/src/stores/builder/app.ts
@@ -39,7 +39,7 @@ interface AppMetaState {
appInstance: { _id: string } | null
initialised: boolean
hasAppPackage: boolean
- usedPlugins: Plugin[] | null
+ usedPlugins: Plugin[]
automations: AutomationSettings
routes: { [key: string]: any }
version?: string
@@ -76,7 +76,7 @@ export const INITIAL_APP_META_STATE: AppMetaState = {
appInstance: null,
initialised: false,
hasAppPackage: false,
- usedPlugins: null,
+ usedPlugins: [],
automations: {},
routes: {},
}
@@ -109,7 +109,7 @@ export class AppMetaStore extends BudiStore
{
appInstance: app.instance,
revertableVersion: app.revertableVersion,
upgradableVersion: app.upgradableVersion,
- usedPlugins: app.usedPlugins || null,
+ usedPlugins: app.usedPlugins || [],
icon: app.icon,
features: {
...INITIAL_APP_META_STATE.features,
diff --git a/packages/builder/src/stores/builder/components.ts b/packages/builder/src/stores/builder/components.ts
index b1198ca7b4..38fa9a6a41 100644
--- a/packages/builder/src/stores/builder/components.ts
+++ b/packages/builder/src/stores/builder/components.ts
@@ -11,6 +11,7 @@ import {
findComponentParent,
findAllMatchingComponents,
makeComponentUnique,
+ findComponentType,
} from "@/helpers/components"
import { getComponentFieldOptions } from "@/helpers/formFields"
import { selectedScreen } from "./screens"
@@ -139,10 +140,6 @@ export class ComponentStore extends BudiStore {
/**
* Retrieve the component definition object
- * @param {string} componentType
- * @example
- * '@budibase/standard-components/container'
- * @returns {object}
*/
getDefinition(componentType: string) {
if (!componentType) {
@@ -151,10 +148,6 @@ export class ComponentStore extends BudiStore {
return get(this.store).components[componentType]
}
- /**
- *
- * @returns {object}
- */
getDefaultDatasource() {
// Ignore users table
const validTables = get(tables).list.filter(x => x._id !== "ta_users")
@@ -188,8 +181,6 @@ export class ComponentStore extends BudiStore {
/**
* Takes an enriched component instance and applies any required migration
* logic
- * @param {object} enrichedComponent
- * @returns {object} migrated Component
*/
migrateSettings(enrichedComponent: Component) {
const componentPrefix = "@budibase/standard-components"
@@ -230,22 +221,15 @@ export class ComponentStore extends BudiStore {
for (let setting of filterableTypes || []) {
const isLegacy = Array.isArray(enrichedComponent[setting.key])
if (isLegacy) {
- const processedSetting = utils.processSearchFilters(
+ enrichedComponent[setting.key] = utils.processSearchFilters(
enrichedComponent[setting.key]
)
- enrichedComponent[setting.key] = processedSetting
migrated = true
}
}
return migrated
}
- /**
- *
- * @param {object} component
- * @param {object} opts
- * @returns
- */
enrichEmptySettings(
component: Component,
opts: { screen?: Screen; parent?: Component; useDefaultValues?: boolean }
@@ -280,14 +264,25 @@ export class ComponentStore extends BudiStore {
type: "table",
}
} else if (setting.type === "dataProvider") {
- // Pick closest data provider where required
+ let providerId
+
+ // Pick closest parent data provider if one exists
const path = findComponentPath(screen.props, treeId)
const providers = path.filter((component: Component) =>
component._component?.endsWith("/dataprovider")
)
- if (providers.length) {
- const id = providers[providers.length - 1]?._id
- component[setting.key] = `{{ literal ${safe(id)} }}`
+ providerId = providers[providers.length - 1]?._id
+
+ // If none in our direct path, select the first one the screen
+ if (!providerId) {
+ providerId = findComponentType(
+ screen.props,
+ "@budibase/standard-components/dataprovider"
+ )?._id
+ }
+
+ if (providerId) {
+ component[setting.key] = `{{ literal ${safe(providerId)} }}`
}
} else if (setting.type.startsWith("field/")) {
// Autofill form field names
@@ -427,17 +422,10 @@ export class ComponentStore extends BudiStore {
}
}
- /**
- *
- * @param {string} componentName
- * @param {object} presetProps
- * @param {object} parent
- * @returns
- */
createInstance(
componentType: string,
- presetProps: any,
- parent: any
+ presetProps?: Record,
+ parent?: Component
): Component | null {
const screen = get(selectedScreen)
if (!screen) {
@@ -463,7 +451,7 @@ export class ComponentStore extends BudiStore {
_id: Helpers.uuid(),
_component: definition.component,
_styles: {
- normal: {},
+ normal: { ...presetProps?._styles?.normal },
hover: {},
active: {},
},
@@ -512,19 +500,11 @@ export class ComponentStore extends BudiStore {
}
}
- /**
- *
- * @param {string} componentName
- * @param {object} presetProps
- * @param {object} parent
- * @param {number} index
- * @returns
- */
async create(
componentType: string,
- presetProps: any,
- parent: Component,
- index: number
+ presetProps?: Record,
+ parent?: Component,
+ index?: number
) {
const state = get(this.store)
const componentInstance = this.createInstance(
@@ -611,13 +591,6 @@ export class ComponentStore extends BudiStore {
return componentInstance
}
- /**
- *
- * @param {function} patchFn
- * @param {string} componentId
- * @param {string} screenId
- * @returns
- */
async patch(
patchFn: (component: Component, screen: Screen) => any,
componentId?: string,
@@ -652,11 +625,6 @@ export class ComponentStore extends BudiStore {
await screenStore.patch(patchScreen, screenId)
}
- /**
- *
- * @param {object} component
- * @returns
- */
async delete(component: Component) {
if (!component) {
return
@@ -737,13 +705,6 @@ export class ComponentStore extends BudiStore {
})
}
- /**
- *
- * @param {object} targetComponent
- * @param {string} mode
- * @param {object} targetScreen
- * @returns
- */
async paste(
targetComponent: Component,
mode: string,
@@ -1101,6 +1062,7 @@ export class ComponentStore extends BudiStore {
async updateStyles(styles: Record, id: string) {
const patchFn = (component: Component) => {
+ delete component._placeholder
component._styles.normal = {
...component._styles.normal,
...styles,
@@ -1231,7 +1193,7 @@ export class ComponentStore extends BudiStore {
}
// Create new parent instance
- const newParentDefinition = this.createInstance(parentType, null, parent)
+ const newParentDefinition = this.createInstance(parentType)
if (!newParentDefinition) {
return
}
@@ -1267,10 +1229,6 @@ export class ComponentStore extends BudiStore {
/**
* Check if the components settings have been cached
- * @param {string} componentType
- * @example
- * '@budibase/standard-components/container'
- * @returns {boolean}
*/
isCached(componentType: string) {
const settings = get(this.store).settingsCache
@@ -1279,11 +1237,6 @@ export class ComponentStore extends BudiStore {
/**
* Cache component settings
- * @param {string} componentType
- * @param {object} definition
- * @example
- * '@budibase/standard-components/container'
- * @returns {array} the settings
*/
cacheSettings(componentType: string, definition: ComponentDefinition | null) {
let settings: ComponentSetting[] = []
@@ -1313,12 +1266,7 @@ export class ComponentStore extends BudiStore {
/**
* Retrieve an array of the component settings.
* These settings are cached because they cannot change at run time.
- *
* Searches a component's definition for a setting matching a certain predicate.
- * @param {string} componentType
- * @example
- * '@budibase/standard-components/container'
- * @returns {Array