103 lines
3.0 KiB
JavaScript
103 lines
3.0 KiB
JavaScript
import { writable, derived, get } from "svelte/store"
|
|
import Manifest from "manifest.json"
|
|
import { findComponentById, findComponentPathById } from "../utils/components"
|
|
import { pingEndUser } from "../api"
|
|
|
|
const dispatchEvent = (type, data = {}) => {
|
|
window.parent.postMessage({ type, data })
|
|
}
|
|
|
|
const createBuilderStore = () => {
|
|
const initialState = {
|
|
inBuilder: false,
|
|
layout: null,
|
|
screen: null,
|
|
selectedComponentId: null,
|
|
editMode: false,
|
|
previewId: null,
|
|
previewType: null,
|
|
selectedPath: [],
|
|
theme: null,
|
|
customTheme: null,
|
|
previewDevice: "desktop",
|
|
isDragging: false,
|
|
}
|
|
const writableStore = writable(initialState)
|
|
const derivedStore = derived(writableStore, $state => {
|
|
// Avoid any of this logic if we aren't in the builder preview
|
|
if (!$state.inBuilder) {
|
|
return $state
|
|
}
|
|
|
|
// Derive the selected component instance and definition
|
|
const { layout, screen, previewType, selectedComponentId } = $state
|
|
const asset = previewType === "layout" ? layout : screen
|
|
const component = findComponentById(asset?.props, selectedComponentId)
|
|
const prefix = "@budibase/standard-components/"
|
|
const type = component?._component?.replace(prefix, "")
|
|
const definition = type ? Manifest[type] : null
|
|
|
|
// Derive the selected component path
|
|
const path = findComponentPathById(asset.props, selectedComponentId) || []
|
|
|
|
return {
|
|
...$state,
|
|
selectedComponent: component,
|
|
selectedComponentDefinition: definition,
|
|
selectedComponentPath: path?.map(component => component._id),
|
|
}
|
|
})
|
|
|
|
const actions = {
|
|
selectComponent: id => {
|
|
if (id === get(writableStore).selectedComponentId) {
|
|
return
|
|
}
|
|
writableStore.update(state => ({ ...state, editMode: false }))
|
|
dispatchEvent("select-component", { id })
|
|
},
|
|
updateProp: (prop, value) => {
|
|
dispatchEvent("update-prop", { prop, value })
|
|
},
|
|
deleteComponent: id => {
|
|
dispatchEvent("delete-component", { id })
|
|
},
|
|
notifyLoaded: () => {
|
|
dispatchEvent("preview-loaded")
|
|
},
|
|
pingEndUser: () => {
|
|
pingEndUser()
|
|
},
|
|
setSelectedPath: path => {
|
|
writableStore.update(state => ({ ...state, selectedPath: path }))
|
|
},
|
|
moveComponent: (componentId, destinationComponentId, mode) => {
|
|
dispatchEvent("move-component", {
|
|
componentId,
|
|
destinationComponentId,
|
|
mode,
|
|
})
|
|
},
|
|
setDragging: dragging => {
|
|
if (dragging === get(writableStore).isDragging) {
|
|
return
|
|
}
|
|
writableStore.update(state => ({ ...state, isDragging: dragging }))
|
|
},
|
|
setEditMode: enabled => {
|
|
if (enabled === get(writableStore).editMode) {
|
|
return
|
|
}
|
|
writableStore.update(state => ({ ...state, editMode: enabled }))
|
|
},
|
|
}
|
|
return {
|
|
...writableStore,
|
|
set: state => writableStore.set({ ...initialState, ...state }),
|
|
subscribe: derivedStore.subscribe,
|
|
actions,
|
|
}
|
|
}
|
|
|
|
export const builderStore = createBuilderStore()
|