Initial work on support dragging new components on to grid screens and typing improvements for client
This commit is contained in:
parent
7b13b54b52
commit
73d3ce2038
|
@ -13,6 +13,11 @@
|
||||||
import { fly } from "svelte/transition"
|
import { fly } from "svelte/transition"
|
||||||
import { findComponentPath } from "@/helpers/components"
|
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 searchString
|
||||||
let searchRef
|
let searchRef
|
||||||
let selectedIndex
|
let selectedIndex
|
||||||
|
@ -217,7 +222,8 @@
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const onDragStart = component => {
|
const onDragStart = (e, component) => {
|
||||||
|
e.dataTransfer.setDragImage(ghost, 0, 0)
|
||||||
previewStore.startDrag(component)
|
previewStore.startDrag(component)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -250,7 +256,7 @@
|
||||||
{#each category.children as component}
|
{#each category.children as component}
|
||||||
<div
|
<div
|
||||||
draggable="true"
|
draggable="true"
|
||||||
on:dragstart={() => onDragStart(component.component)}
|
on:dragstart={e => onDragStart(e, component.component)}
|
||||||
on:dragend={onDragEnd}
|
on:dragend={onDragEnd}
|
||||||
class="component"
|
class="component"
|
||||||
class:selected={selectedIndex === orderMap[component.component]}
|
class:selected={selectedIndex === orderMap[component.component]}
|
||||||
|
@ -308,7 +314,7 @@
|
||||||
}
|
}
|
||||||
.component:hover {
|
.component:hover {
|
||||||
background: var(--spectrum-global-color-gray-300);
|
background: var(--spectrum-global-color-gray-300);
|
||||||
cursor: pointer;
|
cursor: grab;
|
||||||
}
|
}
|
||||||
.component :global(.spectrum-Body) {
|
.component :global(.spectrum-Body) {
|
||||||
line-height: 1.2 !important;
|
line-height: 1.2 !important;
|
||||||
|
|
|
@ -39,7 +39,7 @@ interface AppMetaState {
|
||||||
appInstance: { _id: string } | null
|
appInstance: { _id: string } | null
|
||||||
initialised: boolean
|
initialised: boolean
|
||||||
hasAppPackage: boolean
|
hasAppPackage: boolean
|
||||||
usedPlugins: Plugin[] | null
|
usedPlugins: Plugin[]
|
||||||
automations: AutomationSettings
|
automations: AutomationSettings
|
||||||
routes: { [key: string]: any }
|
routes: { [key: string]: any }
|
||||||
version?: string
|
version?: string
|
||||||
|
@ -76,7 +76,7 @@ export const INITIAL_APP_META_STATE: AppMetaState = {
|
||||||
appInstance: null,
|
appInstance: null,
|
||||||
initialised: false,
|
initialised: false,
|
||||||
hasAppPackage: false,
|
hasAppPackage: false,
|
||||||
usedPlugins: null,
|
usedPlugins: [],
|
||||||
automations: {},
|
automations: {},
|
||||||
routes: {},
|
routes: {},
|
||||||
}
|
}
|
||||||
|
@ -109,7 +109,7 @@ export class AppMetaStore extends BudiStore<AppMetaState> {
|
||||||
appInstance: app.instance,
|
appInstance: app.instance,
|
||||||
revertableVersion: app.revertableVersion,
|
revertableVersion: app.revertableVersion,
|
||||||
upgradableVersion: app.upgradableVersion,
|
upgradableVersion: app.upgradableVersion,
|
||||||
usedPlugins: app.usedPlugins || null,
|
usedPlugins: app.usedPlugins || [],
|
||||||
icon: app.icon,
|
icon: app.icon,
|
||||||
features: {
|
features: {
|
||||||
...INITIAL_APP_META_STATE.features,
|
...INITIAL_APP_META_STATE.features,
|
||||||
|
|
|
@ -139,10 +139,6 @@ export class ComponentStore extends BudiStore<ComponentState> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the component definition object
|
* Retrieve the component definition object
|
||||||
* @param {string} componentType
|
|
||||||
* @example
|
|
||||||
* '@budibase/standard-components/container'
|
|
||||||
* @returns {object}
|
|
||||||
*/
|
*/
|
||||||
getDefinition(componentType: string) {
|
getDefinition(componentType: string) {
|
||||||
if (!componentType) {
|
if (!componentType) {
|
||||||
|
@ -151,10 +147,6 @@ export class ComponentStore extends BudiStore<ComponentState> {
|
||||||
return get(this.store).components[componentType]
|
return get(this.store).components[componentType]
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @returns {object}
|
|
||||||
*/
|
|
||||||
getDefaultDatasource() {
|
getDefaultDatasource() {
|
||||||
// Ignore users table
|
// Ignore users table
|
||||||
const validTables = get(tables).list.filter(x => x._id !== "ta_users")
|
const validTables = get(tables).list.filter(x => x._id !== "ta_users")
|
||||||
|
@ -188,8 +180,6 @@ export class ComponentStore extends BudiStore<ComponentState> {
|
||||||
/**
|
/**
|
||||||
* Takes an enriched component instance and applies any required migration
|
* Takes an enriched component instance and applies any required migration
|
||||||
* logic
|
* logic
|
||||||
* @param {object} enrichedComponent
|
|
||||||
* @returns {object} migrated Component
|
|
||||||
*/
|
*/
|
||||||
migrateSettings(enrichedComponent: Component) {
|
migrateSettings(enrichedComponent: Component) {
|
||||||
const componentPrefix = "@budibase/standard-components"
|
const componentPrefix = "@budibase/standard-components"
|
||||||
|
@ -230,22 +220,15 @@ export class ComponentStore extends BudiStore<ComponentState> {
|
||||||
for (let setting of filterableTypes || []) {
|
for (let setting of filterableTypes || []) {
|
||||||
const isLegacy = Array.isArray(enrichedComponent[setting.key])
|
const isLegacy = Array.isArray(enrichedComponent[setting.key])
|
||||||
if (isLegacy) {
|
if (isLegacy) {
|
||||||
const processedSetting = utils.processSearchFilters(
|
enrichedComponent[setting.key] = utils.processSearchFilters(
|
||||||
enrichedComponent[setting.key]
|
enrichedComponent[setting.key]
|
||||||
)
|
)
|
||||||
enrichedComponent[setting.key] = processedSetting
|
|
||||||
migrated = true
|
migrated = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return migrated
|
return migrated
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param {object} component
|
|
||||||
* @param {object} opts
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
enrichEmptySettings(
|
enrichEmptySettings(
|
||||||
component: Component,
|
component: Component,
|
||||||
opts: { screen?: Screen; parent?: Component; useDefaultValues?: boolean }
|
opts: { screen?: Screen; parent?: Component; useDefaultValues?: boolean }
|
||||||
|
@ -427,17 +410,10 @@ export class ComponentStore extends BudiStore<ComponentState> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param {string} componentName
|
|
||||||
* @param {object} presetProps
|
|
||||||
* @param {object} parent
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
createInstance(
|
createInstance(
|
||||||
componentType: string,
|
componentType: string,
|
||||||
presetProps: any,
|
presetProps?: Record<string, any>,
|
||||||
parent: any
|
parent?: Component
|
||||||
): Component | null {
|
): Component | null {
|
||||||
const screen = get(selectedScreen)
|
const screen = get(selectedScreen)
|
||||||
if (!screen) {
|
if (!screen) {
|
||||||
|
@ -463,7 +439,7 @@ export class ComponentStore extends BudiStore<ComponentState> {
|
||||||
_id: Helpers.uuid(),
|
_id: Helpers.uuid(),
|
||||||
_component: definition.component,
|
_component: definition.component,
|
||||||
_styles: {
|
_styles: {
|
||||||
normal: {},
|
normal: { ...presetProps?._styles?.normal },
|
||||||
hover: {},
|
hover: {},
|
||||||
active: {},
|
active: {},
|
||||||
},
|
},
|
||||||
|
@ -512,19 +488,11 @@ export class ComponentStore extends BudiStore<ComponentState> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param {string} componentName
|
|
||||||
* @param {object} presetProps
|
|
||||||
* @param {object} parent
|
|
||||||
* @param {number} index
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
async create(
|
async create(
|
||||||
componentType: string,
|
componentType: string,
|
||||||
presetProps: any,
|
presetProps?: Record<string, any>,
|
||||||
parent: Component,
|
parent?: Component,
|
||||||
index: number
|
index?: number
|
||||||
) {
|
) {
|
||||||
const state = get(this.store)
|
const state = get(this.store)
|
||||||
const componentInstance = this.createInstance(
|
const componentInstance = this.createInstance(
|
||||||
|
@ -611,13 +579,6 @@ export class ComponentStore extends BudiStore<ComponentState> {
|
||||||
return componentInstance
|
return componentInstance
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param {function} patchFn
|
|
||||||
* @param {string} componentId
|
|
||||||
* @param {string} screenId
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
async patch(
|
async patch(
|
||||||
patchFn: (component: Component, screen: Screen) => any,
|
patchFn: (component: Component, screen: Screen) => any,
|
||||||
componentId?: string,
|
componentId?: string,
|
||||||
|
@ -652,11 +613,6 @@ export class ComponentStore extends BudiStore<ComponentState> {
|
||||||
await screenStore.patch(patchScreen, screenId)
|
await screenStore.patch(patchScreen, screenId)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param {object} component
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
async delete(component: Component) {
|
async delete(component: Component) {
|
||||||
if (!component) {
|
if (!component) {
|
||||||
return
|
return
|
||||||
|
@ -737,13 +693,6 @@ export class ComponentStore extends BudiStore<ComponentState> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param {object} targetComponent
|
|
||||||
* @param {string} mode
|
|
||||||
* @param {object} targetScreen
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
async paste(
|
async paste(
|
||||||
targetComponent: Component,
|
targetComponent: Component,
|
||||||
mode: string,
|
mode: string,
|
||||||
|
@ -1101,6 +1050,7 @@ export class ComponentStore extends BudiStore<ComponentState> {
|
||||||
|
|
||||||
async updateStyles(styles: Record<string, string>, id: string) {
|
async updateStyles(styles: Record<string, string>, id: string) {
|
||||||
const patchFn = (component: Component) => {
|
const patchFn = (component: Component) => {
|
||||||
|
delete component._placeholder
|
||||||
component._styles.normal = {
|
component._styles.normal = {
|
||||||
...component._styles.normal,
|
...component._styles.normal,
|
||||||
...styles,
|
...styles,
|
||||||
|
@ -1231,7 +1181,7 @@ export class ComponentStore extends BudiStore<ComponentState> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create new parent instance
|
// Create new parent instance
|
||||||
const newParentDefinition = this.createInstance(parentType, null, parent)
|
const newParentDefinition = this.createInstance(parentType)
|
||||||
if (!newParentDefinition) {
|
if (!newParentDefinition) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -1267,10 +1217,6 @@ export class ComponentStore extends BudiStore<ComponentState> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the components settings have been cached
|
* Check if the components settings have been cached
|
||||||
* @param {string} componentType
|
|
||||||
* @example
|
|
||||||
* '@budibase/standard-components/container'
|
|
||||||
* @returns {boolean}
|
|
||||||
*/
|
*/
|
||||||
isCached(componentType: string) {
|
isCached(componentType: string) {
|
||||||
const settings = get(this.store).settingsCache
|
const settings = get(this.store).settingsCache
|
||||||
|
@ -1279,11 +1225,6 @@ export class ComponentStore extends BudiStore<ComponentState> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cache component settings
|
* Cache component settings
|
||||||
* @param {string} componentType
|
|
||||||
* @param {object} definition
|
|
||||||
* @example
|
|
||||||
* '@budibase/standard-components/container'
|
|
||||||
* @returns {array} the settings
|
|
||||||
*/
|
*/
|
||||||
cacheSettings(componentType: string, definition: ComponentDefinition | null) {
|
cacheSettings(componentType: string, definition: ComponentDefinition | null) {
|
||||||
let settings: ComponentSetting[] = []
|
let settings: ComponentSetting[] = []
|
||||||
|
@ -1313,12 +1254,7 @@ export class ComponentStore extends BudiStore<ComponentState> {
|
||||||
/**
|
/**
|
||||||
* Retrieve an array of the component settings.
|
* Retrieve an array of the component settings.
|
||||||
* These settings are cached because they cannot change at run time.
|
* These settings are cached because they cannot change at run time.
|
||||||
*
|
|
||||||
* Searches a component's definition for a setting matching a certain predicate.
|
* Searches a component's definition for a setting matching a certain predicate.
|
||||||
* @param {string} componentType
|
|
||||||
* @example
|
|
||||||
* '@budibase/standard-components/container'
|
|
||||||
* @returns {Array<object>}
|
|
||||||
*/
|
*/
|
||||||
getComponentSettings(componentType: string) {
|
getComponentSettings(componentType: string) {
|
||||||
if (!componentType) {
|
if (!componentType) {
|
||||||
|
|
|
@ -4,15 +4,13 @@ import { appStore } from "@/stores/builder"
|
||||||
import { BudiStore } from "../BudiStore"
|
import { BudiStore } from "../BudiStore"
|
||||||
import { AppNavigation, AppNavigationLink, UIObject } from "@budibase/types"
|
import { AppNavigation, AppNavigationLink, UIObject } from "@budibase/types"
|
||||||
|
|
||||||
interface BuilderNavigationStore extends AppNavigation {}
|
|
||||||
|
|
||||||
export const INITIAL_NAVIGATION_STATE = {
|
export const INITIAL_NAVIGATION_STATE = {
|
||||||
navigation: "Top",
|
navigation: "Top",
|
||||||
links: [],
|
links: [],
|
||||||
textAlign: "Left",
|
textAlign: "Left",
|
||||||
}
|
}
|
||||||
|
|
||||||
export class NavigationStore extends BudiStore<BuilderNavigationStore> {
|
export class NavigationStore extends BudiStore<AppNavigation> {
|
||||||
constructor() {
|
constructor() {
|
||||||
super(INITIAL_NAVIGATION_STATE)
|
super(INITIAL_NAVIGATION_STATE)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
import { get } from "svelte/store"
|
import { get } from "svelte/store"
|
||||||
import { BudiStore } from "../BudiStore"
|
import { BudiStore } from "../BudiStore"
|
||||||
|
import { componentStore } from "./components"
|
||||||
|
import { selectedScreen } from "./screens"
|
||||||
|
|
||||||
type PreviewDevice = "desktop" | "tablet" | "mobile"
|
type PreviewDevice = "desktop" | "tablet" | "mobile"
|
||||||
type PreviewEventHandler = (name: string, payload?: any) => void
|
type PreviewEventHandler = (name: string, payload?: any) => void
|
||||||
|
@ -54,10 +56,21 @@ export class PreviewStore extends BudiStore<PreviewState> {
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
startDrag(component: any) {
|
async startDrag(componentType: string) {
|
||||||
|
let componentId
|
||||||
|
const gridScreen = get(selectedScreen)?.props?.layout === "grid"
|
||||||
|
if (gridScreen) {
|
||||||
|
const component = await componentStore.create(componentType, {
|
||||||
|
_placeholder: true,
|
||||||
|
_styles: { normal: { opacity: 0 } },
|
||||||
|
})
|
||||||
|
componentId = component?._id
|
||||||
|
}
|
||||||
this.sendEvent("dragging-new-component", {
|
this.sendEvent("dragging-new-component", {
|
||||||
dragging: true,
|
dragging: true,
|
||||||
component,
|
componentType,
|
||||||
|
componentId,
|
||||||
|
gridScreen,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
"module": "dist/budibase-client.js",
|
"module": "dist/budibase-client.js",
|
||||||
"main": "dist/budibase-client.js",
|
"main": "dist/budibase-client.js",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"svelte": "src/index.js",
|
"svelte": "src/index.ts",
|
||||||
"exports": {
|
"exports": {
|
||||||
".": {
|
".": {
|
||||||
"import": "./dist/budibase-client.js",
|
"import": "./dist/budibase-client.js",
|
||||||
|
|
|
@ -44,6 +44,7 @@
|
||||||
import MaintenanceScreen from "components/MaintenanceScreen.svelte"
|
import MaintenanceScreen from "components/MaintenanceScreen.svelte"
|
||||||
import SnippetsProvider from "./context/SnippetsProvider.svelte"
|
import SnippetsProvider from "./context/SnippetsProvider.svelte"
|
||||||
import EmbedProvider from "./context/EmbedProvider.svelte"
|
import EmbedProvider from "./context/EmbedProvider.svelte"
|
||||||
|
import GridNewComponentDNDHandler from "components/preview/GridNewComponentDNDHandler.svelte"
|
||||||
|
|
||||||
// Provide contexts
|
// Provide contexts
|
||||||
setContext("sdk", SDK)
|
setContext("sdk", SDK)
|
||||||
|
@ -266,6 +267,7 @@
|
||||||
{#if $builderStore.inBuilder}
|
{#if $builderStore.inBuilder}
|
||||||
<DNDHandler />
|
<DNDHandler />
|
||||||
<GridDNDHandler />
|
<GridDNDHandler />
|
||||||
|
<GridNewComponentDNDHandler />
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</SnippetsProvider>
|
</SnippetsProvider>
|
||||||
|
|
|
@ -0,0 +1,166 @@
|
||||||
|
<script>
|
||||||
|
import { onDestroy, getContext } from "svelte"
|
||||||
|
import { builderStore, componentStore, screenStore } from "stores"
|
||||||
|
import { Utils, memo } from "@budibase/frontend-core"
|
||||||
|
import { GridRowHeight } from "constants"
|
||||||
|
import { GridParams, getGridVar, Devices } from "utils/grid"
|
||||||
|
|
||||||
|
const context = getContext("context")
|
||||||
|
|
||||||
|
// Smallest possible 1x1 transparent GIF
|
||||||
|
const ghost = new Image(1, 1)
|
||||||
|
ghost.src =
|
||||||
|
"data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=="
|
||||||
|
|
||||||
|
let dragInfo
|
||||||
|
let styles = memo()
|
||||||
|
|
||||||
|
$: placeholderID = findPlaceholderID($screenStore.activeScreen)
|
||||||
|
$: handleNewPlaceholderID(placeholderID)
|
||||||
|
|
||||||
|
// Grid CSS variables
|
||||||
|
$: device = $context.device.mobile ? Devices.Mobile : Devices.Desktop
|
||||||
|
$: vars = {
|
||||||
|
colStart: getGridVar(device, GridParams.ColStart),
|
||||||
|
colEnd: getGridVar(device, GridParams.ColEnd),
|
||||||
|
rowStart: getGridVar(device, GridParams.RowStart),
|
||||||
|
rowEnd: getGridVar(device, GridParams.RowEnd),
|
||||||
|
}
|
||||||
|
|
||||||
|
// Some memoisation of primitive types for performance
|
||||||
|
$: id = dragInfo?.id
|
||||||
|
|
||||||
|
// Set ephemeral styles
|
||||||
|
$: instance = componentStore.actions.getComponentInstance(id)
|
||||||
|
$: $instance?.setEphemeralStyles($styles)
|
||||||
|
|
||||||
|
const findPlaceholderID = screen => {
|
||||||
|
return screen?.props?._children?.find(c => c._placeholder)?._id
|
||||||
|
}
|
||||||
|
|
||||||
|
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms))
|
||||||
|
|
||||||
|
const handleNewPlaceholderID = async placeholderID => {
|
||||||
|
if (!placeholderID) {
|
||||||
|
stopDragging()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
await sleep(100)
|
||||||
|
onDragStart(placeholderID)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sugar for a combination of both min and max
|
||||||
|
const minMax = (value, min, max) => Math.min(max, Math.max(min, value))
|
||||||
|
|
||||||
|
const processEvent = Utils.domDebounce((mouseX, mouseY) => {
|
||||||
|
if (!dragInfo?.grid) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const { grid, domGrid } = dragInfo
|
||||||
|
const { startX, startY, rowStart, rowEnd, colStart, colEnd } = grid
|
||||||
|
if (!domGrid) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const cols = parseInt(domGrid.dataset.cols)
|
||||||
|
const colSize = parseInt(domGrid.dataset.colSize)
|
||||||
|
const diffX = mouseX - startX
|
||||||
|
let deltaX = Math.round(diffX / colSize)
|
||||||
|
const diffY = mouseY - startY
|
||||||
|
let deltaY = Math.round(diffY / GridRowHeight)
|
||||||
|
deltaX = minMax(deltaX, 1 - colStart, cols + 1 - colEnd)
|
||||||
|
deltaY = Math.max(deltaY, 1 - rowStart)
|
||||||
|
const newStyles = {
|
||||||
|
[vars.colStart]: colStart + deltaX,
|
||||||
|
[vars.colEnd]: colEnd + deltaX,
|
||||||
|
[vars.rowStart]: rowStart + deltaY,
|
||||||
|
[vars.rowEnd]: rowEnd + deltaY,
|
||||||
|
opacity: 1,
|
||||||
|
}
|
||||||
|
styles.set(newStyles)
|
||||||
|
})
|
||||||
|
|
||||||
|
const handleEvent = e => {
|
||||||
|
e.preventDefault()
|
||||||
|
e.stopPropagation()
|
||||||
|
processEvent(e.clientX, e.clientY)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Callback when initially starting a drag on a draggable component
|
||||||
|
const onDragStart = id => {
|
||||||
|
console.log("DRAG START", id)
|
||||||
|
// Find grid parent and read from DOM
|
||||||
|
const domComponent = document.getElementsByClassName(id)[0]
|
||||||
|
const domGrid = domComponent?.closest(".grid")
|
||||||
|
if (!domGrid) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const styles = getComputedStyle(domComponent)
|
||||||
|
const bounds = domComponent.getBoundingClientRect()
|
||||||
|
|
||||||
|
// Show as active
|
||||||
|
domComponent.classList.add("dragging")
|
||||||
|
domGrid.classList.add("highlight")
|
||||||
|
builderStore.actions.selectComponent(id)
|
||||||
|
|
||||||
|
// Update state
|
||||||
|
dragInfo = {
|
||||||
|
domComponent,
|
||||||
|
domGrid,
|
||||||
|
id,
|
||||||
|
gridId: domGrid.parentNode.dataset.id,
|
||||||
|
grid: {
|
||||||
|
startX: bounds.left + bounds.width / 2,
|
||||||
|
startY: bounds.top + bounds.height / 2,
|
||||||
|
rowStart: parseInt(styles["grid-row-start"]),
|
||||||
|
rowEnd: parseInt(styles["grid-row-end"]),
|
||||||
|
colStart: parseInt(styles["grid-column-start"]),
|
||||||
|
colEnd: parseInt(styles["grid-column-end"]),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add event handler to clear all drag state when dragging ends
|
||||||
|
document.addEventListener("dragover", onDrag, false)
|
||||||
|
|
||||||
|
// Add event handler to clear all drag state when dragging ends
|
||||||
|
document.addEventListener("dragEnd", stopDragging, false)
|
||||||
|
document.addEventListener("drop", stopDragging, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
const onDrag = e => {
|
||||||
|
if (!dragInfo) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
handleEvent(e)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Callback when drag stops (whether dropped or not)
|
||||||
|
const stopDragging = async () => {
|
||||||
|
if (!dragInfo) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
console.log("END")
|
||||||
|
const { id, domGrid, domComponent } = dragInfo
|
||||||
|
|
||||||
|
// Reset DOM
|
||||||
|
domComponent.classList.remove("dragging")
|
||||||
|
domGrid.classList.remove("highlight")
|
||||||
|
document.removeEventListener("dragover", onDrag, false)
|
||||||
|
document.removeEventListener("dragend", stopDragging, false)
|
||||||
|
document.removeEventListener("drop", stopDragging, false)
|
||||||
|
|
||||||
|
// Save changes
|
||||||
|
if ($styles) {
|
||||||
|
builderStore.actions.updateStyles($styles, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset state
|
||||||
|
dragInfo = null
|
||||||
|
styles.set(null)
|
||||||
|
}
|
||||||
|
|
||||||
|
onDestroy(() => {
|
||||||
|
document.removeEventListener("dragover", onDrag, false)
|
||||||
|
document.removeEventListener("dragend", stopDragging, false)
|
||||||
|
document.removeEventListener("drop", stopDragging, false)
|
||||||
|
})
|
||||||
|
</script>
|
|
@ -1,5 +0,0 @@
|
||||||
interface Window {
|
|
||||||
"##BUDIBASE_APP_ID##": string
|
|
||||||
"##BUDIBASE_IN_BUILDER##": string
|
|
||||||
MIGRATING_APP: boolean
|
|
||||||
}
|
|
|
@ -1,138 +0,0 @@
|
||||||
import ClientApp from "./components/ClientApp.svelte"
|
|
||||||
import UpdatingApp from "./components/UpdatingApp.svelte"
|
|
||||||
import {
|
|
||||||
builderStore,
|
|
||||||
appStore,
|
|
||||||
blockStore,
|
|
||||||
componentStore,
|
|
||||||
environmentStore,
|
|
||||||
dndStore,
|
|
||||||
eventStore,
|
|
||||||
hoverStore,
|
|
||||||
stateStore,
|
|
||||||
} from "./stores"
|
|
||||||
import loadSpectrumIcons from "@budibase/bbui/spectrum-icons-vite.js"
|
|
||||||
import { get } from "svelte/store"
|
|
||||||
import { initWebsocket } from "./websocket.js"
|
|
||||||
|
|
||||||
// Provide svelte and svelte/internal as globals for custom components
|
|
||||||
import * as svelte from "svelte"
|
|
||||||
import * as internal from "svelte/internal"
|
|
||||||
|
|
||||||
window.svelte_internal = internal
|
|
||||||
window.svelte = svelte
|
|
||||||
|
|
||||||
// Initialise spectrum icons
|
|
||||||
loadSpectrumIcons()
|
|
||||||
|
|
||||||
let app
|
|
||||||
|
|
||||||
const loadBudibase = async () => {
|
|
||||||
// Update builder store with any builder flags
|
|
||||||
builderStore.set({
|
|
||||||
...get(builderStore),
|
|
||||||
inBuilder: !!window["##BUDIBASE_IN_BUILDER##"],
|
|
||||||
layout: window["##BUDIBASE_PREVIEW_LAYOUT##"],
|
|
||||||
screen: window["##BUDIBASE_PREVIEW_SCREEN##"],
|
|
||||||
selectedComponentId: window["##BUDIBASE_SELECTED_COMPONENT_ID##"],
|
|
||||||
previewId: window["##BUDIBASE_PREVIEW_ID##"],
|
|
||||||
theme: window["##BUDIBASE_PREVIEW_THEME##"],
|
|
||||||
customTheme: window["##BUDIBASE_PREVIEW_CUSTOM_THEME##"],
|
|
||||||
previewDevice: window["##BUDIBASE_PREVIEW_DEVICE##"],
|
|
||||||
navigation: window["##BUDIBASE_PREVIEW_NAVIGATION##"],
|
|
||||||
hiddenComponentIds: window["##BUDIBASE_HIDDEN_COMPONENT_IDS##"],
|
|
||||||
usedPlugins: window["##BUDIBASE_USED_PLUGINS##"],
|
|
||||||
location: window["##BUDIBASE_LOCATION##"],
|
|
||||||
snippets: window["##BUDIBASE_SNIPPETS##"],
|
|
||||||
componentErrors: window["##BUDIBASE_COMPONENT_ERRORS##"],
|
|
||||||
})
|
|
||||||
|
|
||||||
// Set app ID - this window flag is set by both the preview and the real
|
|
||||||
// server rendered app HTML
|
|
||||||
appStore.actions.setAppId(window["##BUDIBASE_APP_ID##"])
|
|
||||||
|
|
||||||
// Set the flag used to determine if the app is being loaded via an iframe
|
|
||||||
appStore.actions.setAppEmbedded(
|
|
||||||
window["##BUDIBASE_APP_EMBEDDED##"] === "true"
|
|
||||||
)
|
|
||||||
|
|
||||||
if (window.MIGRATING_APP) {
|
|
||||||
new UpdatingApp({
|
|
||||||
target: window.document.body,
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fetch environment info
|
|
||||||
if (!get(environmentStore)?.loaded) {
|
|
||||||
await environmentStore.actions.fetchEnvironment()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Register handler for runtime events from the builder
|
|
||||||
window.handleBuilderRuntimeEvent = (type, data) => {
|
|
||||||
if (!window["##BUDIBASE_IN_BUILDER##"]) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (type === "event-completed") {
|
|
||||||
eventStore.actions.resolveEvent(data)
|
|
||||||
} else if (type === "eject-block") {
|
|
||||||
const block = blockStore.actions.getBlock(data)
|
|
||||||
block?.eject()
|
|
||||||
} else if (type === "dragging-new-component") {
|
|
||||||
const { dragging, component } = data
|
|
||||||
if (dragging) {
|
|
||||||
const definition =
|
|
||||||
componentStore.actions.getComponentDefinition(component)
|
|
||||||
dndStore.actions.startDraggingNewComponent({ component, definition })
|
|
||||||
} else {
|
|
||||||
dndStore.actions.reset()
|
|
||||||
}
|
|
||||||
} else if (type === "request-context") {
|
|
||||||
const { selectedComponentInstance, screenslotInstance } =
|
|
||||||
get(componentStore)
|
|
||||||
const instance = selectedComponentInstance || screenslotInstance
|
|
||||||
const context = instance?.getDataContext()
|
|
||||||
let stringifiedContext = null
|
|
||||||
try {
|
|
||||||
stringifiedContext = JSON.stringify(context)
|
|
||||||
} catch (error) {
|
|
||||||
// Ignore - invalid context
|
|
||||||
}
|
|
||||||
eventStore.actions.dispatchEvent("provide-context", {
|
|
||||||
context: stringifiedContext,
|
|
||||||
})
|
|
||||||
} else if (type === "hover-component") {
|
|
||||||
hoverStore.actions.hoverComponent(data, false)
|
|
||||||
} else if (type === "builder-meta") {
|
|
||||||
builderStore.actions.setMetadata(data)
|
|
||||||
} else if (type === "builder-state") {
|
|
||||||
const [[key, value]] = Object.entries(data)
|
|
||||||
stateStore.actions.setValue(key, value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Register any custom components
|
|
||||||
if (window["##BUDIBASE_CUSTOM_COMPONENTS##"]) {
|
|
||||||
window["##BUDIBASE_CUSTOM_COMPONENTS##"].forEach(component => {
|
|
||||||
componentStore.actions.registerCustomComponent(component)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make a callback available for custom component bundles to register
|
|
||||||
// themselves at runtime
|
|
||||||
window.registerCustomComponent =
|
|
||||||
componentStore.actions.registerCustomComponent
|
|
||||||
|
|
||||||
// Initialise websocket
|
|
||||||
initWebsocket()
|
|
||||||
|
|
||||||
// Create app if one hasn't been created yet
|
|
||||||
if (!app) {
|
|
||||||
app = new ClientApp({
|
|
||||||
target: window.document.body,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Attach to window so the HTML template can call this when it loads
|
|
||||||
window.loadBudibase = loadBudibase
|
|
|
@ -1,6 +1,83 @@
|
||||||
|
import ClientApp from "./components/ClientApp.svelte"
|
||||||
|
import UpdatingApp from "./components/UpdatingApp.svelte"
|
||||||
|
import {
|
||||||
|
builderStore,
|
||||||
|
appStore,
|
||||||
|
blockStore,
|
||||||
|
componentStore,
|
||||||
|
environmentStore,
|
||||||
|
dndStore,
|
||||||
|
eventStore,
|
||||||
|
hoverStore,
|
||||||
|
stateStore,
|
||||||
|
} from "@/stores"
|
||||||
|
import { get } from "svelte/store"
|
||||||
|
import { initWebsocket } from "@/websocket"
|
||||||
import { APIClient } from "@budibase/frontend-core"
|
import { APIClient } from "@budibase/frontend-core"
|
||||||
import type { ActionTypes } from "./constants"
|
import type { ActionTypes } from "@/constants"
|
||||||
import { Readable } from "svelte/store"
|
import { Readable } from "svelte/store"
|
||||||
|
import {
|
||||||
|
Screen,
|
||||||
|
Layout,
|
||||||
|
Theme,
|
||||||
|
AppCustomTheme,
|
||||||
|
PreviewDevice,
|
||||||
|
AppNavigation,
|
||||||
|
Plugin,
|
||||||
|
Snippet,
|
||||||
|
UIComponentError,
|
||||||
|
CustomComponent,
|
||||||
|
} from "@budibase/types"
|
||||||
|
|
||||||
|
// Provide svelte and svelte/internal as globals for custom components
|
||||||
|
import * as svelte from "svelte"
|
||||||
|
// @ts-ignore
|
||||||
|
import * as internal from "svelte/internal"
|
||||||
|
window.svelte_internal = internal
|
||||||
|
window.svelte = svelte
|
||||||
|
|
||||||
|
// Initialise spectrum icons
|
||||||
|
// eslint-disable-next-line local-rules/no-budibase-imports
|
||||||
|
import loadSpectrumIcons from "@budibase/bbui/spectrum-icons-vite.js"
|
||||||
|
loadSpectrumIcons()
|
||||||
|
|
||||||
|
// Extend global window scope
|
||||||
|
declare global {
|
||||||
|
interface Window {
|
||||||
|
// Data from builder
|
||||||
|
"##BUDIBASE_APP_ID##"?: string
|
||||||
|
"##BUDIBASE_IN_BUILDER##"?: true
|
||||||
|
"##BUDIBASE_PREVIEW_LAYOUT##"?: Layout
|
||||||
|
"##BUDIBASE_PREVIEW_SCREEN##"?: Screen
|
||||||
|
"##BUDIBASE_SELECTED_COMPONENT_ID##"?: string
|
||||||
|
"##BUDIBASE_PREVIEW_ID##"?: number
|
||||||
|
"##BUDIBASE_PREVIEW_THEME##"?: Theme
|
||||||
|
"##BUDIBASE_PREVIEW_CUSTOM_THEME##"?: AppCustomTheme
|
||||||
|
"##BUDIBASE_PREVIEW_DEVICE##"?: PreviewDevice
|
||||||
|
"##BUDIBASE_APP_EMBEDDED##"?: string // This is a bool wrapped in a string
|
||||||
|
"##BUDIBASE_PREVIEW_NAVIGATION##"?: AppNavigation
|
||||||
|
"##BUDIBASE_HIDDEN_COMPONENT_IDS##"?: string[]
|
||||||
|
"##BUDIBASE_USED_PLUGINS##"?: Plugin[]
|
||||||
|
"##BUDIBASE_LOCATION##"?: {
|
||||||
|
protocol: string
|
||||||
|
hostname: string
|
||||||
|
port: string
|
||||||
|
}
|
||||||
|
"##BUDIBASE_SNIPPETS##"?: Snippet[]
|
||||||
|
"##BUDIBASE_COMPONENT_ERRORS##"?: Record<string, UIComponentError>[]
|
||||||
|
"##BUDIBASE_CUSTOM_COMPONENTS##"?: CustomComponent[]
|
||||||
|
|
||||||
|
// Other flags
|
||||||
|
MIGRATING_APP: boolean
|
||||||
|
|
||||||
|
// Client additions
|
||||||
|
handleBuilderRuntimeEvent: (type: string, data: any) => void
|
||||||
|
registerCustomComponent: typeof componentStore.actions.registerCustomComponent
|
||||||
|
loadBudibase: typeof loadBudibase
|
||||||
|
svelte: typeof svelte
|
||||||
|
svelte_internal: typeof internal
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export interface SDK {
|
export interface SDK {
|
||||||
API: APIClient
|
API: APIClient
|
||||||
|
@ -29,3 +106,119 @@ export type Component = Readable<{
|
||||||
}>
|
}>
|
||||||
|
|
||||||
export type Context = Readable<{}>
|
export type Context = Readable<{}>
|
||||||
|
|
||||||
|
let app: ClientApp
|
||||||
|
|
||||||
|
const loadBudibase = async () => {
|
||||||
|
// Update builder store with any builder flags
|
||||||
|
builderStore.set({
|
||||||
|
...get(builderStore),
|
||||||
|
inBuilder: !!window["##BUDIBASE_IN_BUILDER##"],
|
||||||
|
layout: window["##BUDIBASE_PREVIEW_LAYOUT##"],
|
||||||
|
screen: window["##BUDIBASE_PREVIEW_SCREEN##"],
|
||||||
|
selectedComponentId: window["##BUDIBASE_SELECTED_COMPONENT_ID##"],
|
||||||
|
previewId: window["##BUDIBASE_PREVIEW_ID##"],
|
||||||
|
theme: window["##BUDIBASE_PREVIEW_THEME##"],
|
||||||
|
customTheme: window["##BUDIBASE_PREVIEW_CUSTOM_THEME##"],
|
||||||
|
previewDevice: window["##BUDIBASE_PREVIEW_DEVICE##"],
|
||||||
|
navigation: window["##BUDIBASE_PREVIEW_NAVIGATION##"],
|
||||||
|
hiddenComponentIds: window["##BUDIBASE_HIDDEN_COMPONENT_IDS##"],
|
||||||
|
usedPlugins: window["##BUDIBASE_USED_PLUGINS##"],
|
||||||
|
location: window["##BUDIBASE_LOCATION##"],
|
||||||
|
snippets: window["##BUDIBASE_SNIPPETS##"],
|
||||||
|
componentErrors: window["##BUDIBASE_COMPONENT_ERRORS##"],
|
||||||
|
})
|
||||||
|
|
||||||
|
// Set app ID - this window flag is set by both the preview and the real
|
||||||
|
// server rendered app HTML
|
||||||
|
appStore.actions.setAppId(window["##BUDIBASE_APP_ID##"])
|
||||||
|
|
||||||
|
// Set the flag used to determine if the app is being loaded via an iframe
|
||||||
|
appStore.actions.setAppEmbedded(
|
||||||
|
window["##BUDIBASE_APP_EMBEDDED##"] === "true"
|
||||||
|
)
|
||||||
|
|
||||||
|
if (window.MIGRATING_APP) {
|
||||||
|
new UpdatingApp({
|
||||||
|
target: window.document.body,
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fetch environment info
|
||||||
|
if (!get(environmentStore)?.loaded) {
|
||||||
|
await environmentStore.actions.fetchEnvironment()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Register handler for runtime events from the builder
|
||||||
|
window.handleBuilderRuntimeEvent = (type, data) => {
|
||||||
|
if (!window["##BUDIBASE_IN_BUILDER##"]) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (type === "event-completed") {
|
||||||
|
eventStore.actions.resolveEvent(data)
|
||||||
|
} else if (type === "eject-block") {
|
||||||
|
const block = blockStore.actions.getBlock(data)
|
||||||
|
block?.eject()
|
||||||
|
} else if (type === "dragging-new-component") {
|
||||||
|
const { dragging, component, componentId } = data
|
||||||
|
if (dragging) {
|
||||||
|
const definition =
|
||||||
|
componentStore.actions.getComponentDefinition(component)
|
||||||
|
dndStore.actions.startDraggingNewComponent({
|
||||||
|
component,
|
||||||
|
definition,
|
||||||
|
componentId,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
dndStore.actions.reset()
|
||||||
|
}
|
||||||
|
} else if (type === "request-context") {
|
||||||
|
const { selectedComponentInstance, screenslotInstance } =
|
||||||
|
get(componentStore)
|
||||||
|
const instance = selectedComponentInstance || screenslotInstance
|
||||||
|
const context = instance?.getDataContext()
|
||||||
|
let stringifiedContext = null
|
||||||
|
try {
|
||||||
|
stringifiedContext = JSON.stringify(context)
|
||||||
|
} catch (error) {
|
||||||
|
// Ignore - invalid context
|
||||||
|
}
|
||||||
|
eventStore.actions.dispatchEvent("provide-context", {
|
||||||
|
context: stringifiedContext,
|
||||||
|
})
|
||||||
|
} else if (type === "hover-component") {
|
||||||
|
hoverStore.actions.hoverComponent(data, false)
|
||||||
|
} else if (type === "builder-meta") {
|
||||||
|
builderStore.actions.setMetadata(data)
|
||||||
|
} else if (type === "builder-state") {
|
||||||
|
const [[key, value]] = Object.entries(data)
|
||||||
|
stateStore.actions.setValue(key, value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Register any custom components
|
||||||
|
if (window["##BUDIBASE_CUSTOM_COMPONENTS##"]) {
|
||||||
|
window["##BUDIBASE_CUSTOM_COMPONENTS##"].forEach(component => {
|
||||||
|
componentStore.actions.registerCustomComponent(component)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make a callback available for custom component bundles to register
|
||||||
|
// themselves at runtime
|
||||||
|
window.registerCustomComponent =
|
||||||
|
componentStore.actions.registerCustomComponent
|
||||||
|
|
||||||
|
// Initialise websocket
|
||||||
|
initWebsocket()
|
||||||
|
|
||||||
|
// Create app if one hasn't been created yet
|
||||||
|
if (!app) {
|
||||||
|
app = new ClientApp({
|
||||||
|
target: window.document.body,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attach to window so the HTML template can call this when it loads
|
||||||
|
window.loadBudibase = loadBudibase
|
||||||
|
|
|
@ -21,7 +21,11 @@ const createDndStore = () => {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const startDraggingNewComponent = ({ component, definition }) => {
|
const startDraggingNewComponent = ({
|
||||||
|
component,
|
||||||
|
definition,
|
||||||
|
componentId,
|
||||||
|
}) => {
|
||||||
if (!component) {
|
if (!component) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -38,6 +42,7 @@ const createDndStore = () => {
|
||||||
bounds: { height, width },
|
bounds: { height, width },
|
||||||
index: null,
|
index: null,
|
||||||
newComponentType: component,
|
newComponentType: component,
|
||||||
|
newComponentId: componentId,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -82,6 +87,10 @@ export const dndParent = derivedMemo(dndStore, x => x.drop?.parent)
|
||||||
export const dndIndex = derivedMemo(dndStore, x => x.drop?.index)
|
export const dndIndex = derivedMemo(dndStore, x => x.drop?.index)
|
||||||
export const dndBounds = derivedMemo(dndStore, x => x.source?.bounds)
|
export const dndBounds = derivedMemo(dndStore, x => x.source?.bounds)
|
||||||
export const dndIsDragging = derivedMemo(dndStore, x => !!x.source)
|
export const dndIsDragging = derivedMemo(dndStore, x => !!x.source)
|
||||||
|
export const dndNewComponentId = derivedMemo(
|
||||||
|
dndStore,
|
||||||
|
x => x.source?.newComponentId
|
||||||
|
)
|
||||||
export const dndIsNewComponent = derivedMemo(
|
export const dndIsNewComponent = derivedMemo(
|
||||||
dndStore,
|
dndStore,
|
||||||
x => x.source?.newComponentType != null
|
x => x.source?.newComponentType != null
|
||||||
|
|
|
@ -2,7 +2,7 @@ export { authStore } from "./auth"
|
||||||
export { appStore } from "./app"
|
export { appStore } from "./app"
|
||||||
export { notificationStore } from "./notification"
|
export { notificationStore } from "./notification"
|
||||||
export { routeStore } from "./routes"
|
export { routeStore } from "./routes"
|
||||||
export { screenStore } from "./screens"
|
export { screenStore, isGridScreen } from "./screens"
|
||||||
export { builderStore } from "./builder"
|
export { builderStore } from "./builder"
|
||||||
export { dataSourceStore } from "./dataSource"
|
export { dataSourceStore } from "./dataSource"
|
||||||
export { confirmationStore } from "./confirmation"
|
export { confirmationStore } from "./confirmation"
|
||||||
|
|
|
@ -198,3 +198,7 @@ const createScreenStore = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const screenStore = createScreenStore()
|
export const screenStore = createScreenStore()
|
||||||
|
|
||||||
|
export const isGridScreen = derived(screenStore, $screenStore => {
|
||||||
|
return $screenStore.activeScreen?.props?.layout === "grid"
|
||||||
|
})
|
||||||
|
|
|
@ -20,7 +20,7 @@ export default defineConfig(({ mode }) => {
|
||||||
},
|
},
|
||||||
build: {
|
build: {
|
||||||
lib: {
|
lib: {
|
||||||
entry: "src/index.js",
|
entry: "src/index.ts",
|
||||||
formats: ["iife"],
|
formats: ["iife"],
|
||||||
outDir: "dist",
|
outDir: "dist",
|
||||||
name: "budibase_client",
|
name: "budibase_client",
|
||||||
|
@ -67,10 +67,6 @@ export default defineConfig(({ mode }) => {
|
||||||
find: "constants",
|
find: "constants",
|
||||||
replacement: path.resolve("./src/constants"),
|
replacement: path.resolve("./src/constants"),
|
||||||
},
|
},
|
||||||
{
|
|
||||||
find: "@/constants",
|
|
||||||
replacement: path.resolve("./src/constants"),
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
find: "sdk",
|
find: "sdk",
|
||||||
replacement: path.resolve("./src/sdk"),
|
replacement: path.resolve("./src/sdk"),
|
||||||
|
@ -87,6 +83,10 @@ export default defineConfig(({ mode }) => {
|
||||||
find: "@budibase/bbui",
|
find: "@budibase/bbui",
|
||||||
replacement: path.resolve("../bbui/src"),
|
replacement: path.resolve("../bbui/src"),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
find: "@",
|
||||||
|
replacement: path.resolve(__dirname, "src"),
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,16 @@ export * from "./sidepanel"
|
||||||
export * from "./codeEditor"
|
export * from "./codeEditor"
|
||||||
export * from "./errors"
|
export * from "./errors"
|
||||||
|
|
||||||
|
export interface CustomComponent {
|
||||||
|
Component: any
|
||||||
|
schema: {
|
||||||
|
type: "component"
|
||||||
|
metadata: Record<string, any>
|
||||||
|
schema: ComponentDefinition
|
||||||
|
}
|
||||||
|
version: string
|
||||||
|
}
|
||||||
|
|
||||||
export interface ComponentDefinition {
|
export interface ComponentDefinition {
|
||||||
component: string
|
component: string
|
||||||
name: string
|
name: string
|
||||||
|
|
Loading…
Reference in New Issue