Migrated layouts to the class structure, number of fixes across the new stores and refactoring
This commit is contained in:
parent
15c030bcf6
commit
d5a67ad23b
|
@ -11,6 +11,7 @@ import {
|
||||||
componentStore,
|
componentStore,
|
||||||
screenStore,
|
screenStore,
|
||||||
appStore,
|
appStore,
|
||||||
|
layoutStore,
|
||||||
} from "stores/frontend"
|
} from "stores/frontend"
|
||||||
import {
|
import {
|
||||||
queries as queriesStores,
|
queries as queriesStores,
|
||||||
|
@ -1048,7 +1049,7 @@ export const getAllStateVariables = () => {
|
||||||
export const getAllAssets = () => {
|
export const getAllAssets = () => {
|
||||||
// Get all component containing assets
|
// Get all component containing assets
|
||||||
let allAssets = []
|
let allAssets = []
|
||||||
allAssets = allAssets.concat(get(appStore).layouts || [])
|
allAssets = allAssets.concat(get(layoutStore).layouts || [])
|
||||||
allAssets = allAssets.concat(get(screenStore).screens || [])
|
allAssets = allAssets.concat(get(screenStore).screens || [])
|
||||||
|
|
||||||
return allAssets
|
return allAssets
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
import DraggableList from "../DraggableList/DraggableList.svelte"
|
import DraggableList from "../DraggableList/DraggableList.svelte"
|
||||||
import ButtonSetting from "./ButtonSetting.svelte"
|
import ButtonSetting from "./ButtonSetting.svelte"
|
||||||
import { createEventDispatcher } from "svelte"
|
import { createEventDispatcher } from "svelte"
|
||||||
import { store } from "builderStore"
|
|
||||||
import { Helpers } from "@budibase/bbui"
|
import { Helpers } from "@budibase/bbui"
|
||||||
|
import { componentStore } from "stores/frontend"
|
||||||
|
|
||||||
export let componentBindings
|
export let componentBindings
|
||||||
export let bindings
|
export let bindings
|
||||||
|
@ -47,7 +47,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
const buildPseudoInstance = cfg => {
|
const buildPseudoInstance = cfg => {
|
||||||
return store.actions.components.createInstance(
|
return componentStore.createInstance(
|
||||||
`@budibase/standard-components/button`,
|
`@budibase/standard-components/button`,
|
||||||
{
|
{
|
||||||
_instanceName: Helpers.uuid(),
|
_instanceName: Helpers.uuid(),
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<script>
|
<script>
|
||||||
import EditComponentPopover from "../EditComponentPopover.svelte"
|
import EditComponentPopover from "../EditComponentPopover.svelte"
|
||||||
import { Icon } from "@budibase/bbui"
|
import { Icon } from "@budibase/bbui"
|
||||||
import { runtimeToReadableBinding } from "builderStore/dataBinding"
|
import { runtimeToReadableBinding } from "builder/dataBinding"
|
||||||
import { isJSBinding } from "@budibase/string-templates"
|
import { isJSBinding } from "@budibase/string-templates"
|
||||||
|
|
||||||
export let item
|
export let item
|
||||||
|
|
|
@ -30,9 +30,7 @@
|
||||||
open = true
|
open = true
|
||||||
}
|
}
|
||||||
|
|
||||||
$: componentDef = store.actions.components.getDefinition(
|
$: componentDef = componentStore.getDefinition(componentInstance._component)
|
||||||
componentInstance._component
|
|
||||||
)
|
|
||||||
$: parsedComponentDef = processComponentDefinitionSettings(componentDef)
|
$: parsedComponentDef = processComponentDefinitionSettings(componentDef)
|
||||||
|
|
||||||
const processComponentDefinitionSettings = componentDef => {
|
const processComponentDefinitionSettings = componentDef => {
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
getBindableProperties,
|
getBindableProperties,
|
||||||
getComponentBindableProperties,
|
getComponentBindableProperties,
|
||||||
} from "builder/dataBinding"
|
} from "builder/dataBinding"
|
||||||
import DraggableList from "../DraggableList.svelte"
|
import DraggableList from "../DraggableList/DraggableList.svelte"
|
||||||
import { createEventDispatcher } from "svelte"
|
import { createEventDispatcher } from "svelte"
|
||||||
import { selectedScreen, currentAsset, componentStore } from "stores/frontend"
|
import { selectedScreen, currentAsset, componentStore } from "stores/frontend"
|
||||||
import FieldSetting from "./FieldSetting.svelte"
|
import FieldSetting from "./FieldSetting.svelte"
|
||||||
|
|
|
@ -3,9 +3,9 @@
|
||||||
import { Toggle, Icon } from "@budibase/bbui"
|
import { Toggle, Icon } from "@budibase/bbui"
|
||||||
import { createEventDispatcher } from "svelte"
|
import { createEventDispatcher } from "svelte"
|
||||||
import { cloneDeep } from "lodash/fp"
|
import { cloneDeep } from "lodash/fp"
|
||||||
import { store } from "builderStore"
|
import { runtimeToReadableBinding } from "builder/dataBinding"
|
||||||
import { runtimeToReadableBinding } from "builderStore/dataBinding"
|
|
||||||
import { isJSBinding } from "@budibase/string-templates"
|
import { isJSBinding } from "@budibase/string-templates"
|
||||||
|
import { componentStore } from "stores/frontend"
|
||||||
|
|
||||||
export let item
|
export let item
|
||||||
export let componentBindings
|
export let componentBindings
|
||||||
|
@ -37,7 +37,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
$: readableText = getReadableText(item)
|
$: readableText = getReadableText(item)
|
||||||
$: componentDef = store.actions.components.getDefinition(item._component)
|
$: componentDef = componentStore.getDefinition(item._component)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="list-item-body">
|
<div class="list-item-body">
|
||||||
|
|
|
@ -11,16 +11,7 @@ const registerNode = async (node, tourStepKey) => {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
builderStore.update(state => {
|
builderStore.registerTourNode(tourStepKey, node)
|
||||||
const update = {
|
|
||||||
...state,
|
|
||||||
tourNodes: {
|
|
||||||
...state.tourNodes,
|
|
||||||
[tourStepKey]: node,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
return update
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function tourHandler(node, tourStepKey) {
|
export function tourHandler(node, tourStepKey) {
|
||||||
|
@ -29,19 +20,7 @@ export function tourHandler(node, tourStepKey) {
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
destroy: () => {
|
destroy: () => {
|
||||||
const updatedTourNodes = get(builderStore).tourNodes
|
builderStore.destroyTourNode(tourStepKey)
|
||||||
if (updatedTourNodes && updatedTourNodes[tourStepKey]) {
|
|
||||||
delete updatedTourNodes[tourStepKey]
|
|
||||||
builderStore.update(state => {
|
|
||||||
const update = {
|
|
||||||
...state,
|
|
||||||
tourNodes: {
|
|
||||||
...updatedTourNodes,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
return update
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,20 +91,13 @@
|
||||||
// Check if onboarding is enabled.
|
// Check if onboarding is enabled.
|
||||||
if (isEnabled(TENANT_FEATURE_FLAGS.ONBOARDING_TOUR)) {
|
if (isEnabled(TENANT_FEATURE_FLAGS.ONBOARDING_TOUR)) {
|
||||||
if (!$auth.user?.onboardedAt) {
|
if (!$auth.user?.onboardedAt) {
|
||||||
await builderStore.update(state => ({
|
builderStore.startBuilderOnboarding()
|
||||||
...state,
|
|
||||||
onboarding: true,
|
|
||||||
tourKey: TOUR_KEYS.TOUR_BUILDER_ONBOARDING,
|
|
||||||
}))
|
|
||||||
} else {
|
} else {
|
||||||
// Feature tour date
|
// Feature tour date
|
||||||
const release_date = new Date("2023-03-01T00:00:00.000Z")
|
const release_date = new Date("2023-03-01T00:00:00.000Z")
|
||||||
const onboarded = new Date($auth.user?.onboardedAt)
|
const onboarded = new Date($auth.user?.onboardedAt)
|
||||||
if (onboarded < release_date) {
|
if (onboarded < release_date) {
|
||||||
await builderStore.update(state => ({
|
builderStore.startTour(TOUR_KEYS.FEATURE_ONBOARDING)
|
||||||
...state,
|
|
||||||
tourKey: TOUR_KEYS.FEATURE_ONBOARDING,
|
|
||||||
}))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
|
|
||||||
const onUpdateName = async value => {
|
const onUpdateName = async value => {
|
||||||
try {
|
try {
|
||||||
await store.actions.components.updateSetting("_instanceName", value)
|
await componentStore.updateSetting("_instanceName", value)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
notifications.error("Error updating component name")
|
notifications.error("Error updating component name")
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ import { writable } from "svelte/store"
|
||||||
import { createBuilderWebsocket } from "./websocket.js"
|
import { createBuilderWebsocket } from "./websocket.js"
|
||||||
import { BuilderSocketEvent } from "@budibase/shared-core"
|
import { BuilderSocketEvent } from "@budibase/shared-core"
|
||||||
import BudiStore from "./BudiStore"
|
import BudiStore from "./BudiStore"
|
||||||
|
import { TOUR_KEYS } from "components/portal/onboarding/tours.js"
|
||||||
|
|
||||||
export const INITIAL_BUILDER_STATE = {
|
export const INITIAL_BUILDER_STATE = {
|
||||||
previousTopNavPath: {},
|
previousTopNavPath: {},
|
||||||
|
@ -69,11 +70,13 @@ export class BuilderStore extends BudiStore {
|
||||||
}
|
}
|
||||||
|
|
||||||
setPreviousTopNavPath(route, url) {
|
setPreviousTopNavPath(route, url) {
|
||||||
this.update(state => {
|
this.update(state => ({
|
||||||
if (!state.previousTopNavPath) state.previousTopNavPath = {}
|
...state,
|
||||||
state.previousTopNavPath[route] = url
|
previousTopNavPath: {
|
||||||
return state
|
...(state.previousTopNavPath || {}),
|
||||||
})
|
[route]: url,
|
||||||
|
},
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
selectResource(id) {
|
selectResource(id) {
|
||||||
|
@ -82,9 +85,8 @@ export class BuilderStore extends BudiStore {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
registerTourNode(tourStepKey, node) {
|
||||||
register
|
this.update(state => {
|
||||||
update(state => {
|
|
||||||
const update = {
|
const update = {
|
||||||
...state,
|
...state,
|
||||||
tourNodes: {
|
tourNodes: {
|
||||||
|
@ -94,7 +96,34 @@ export class BuilderStore extends BudiStore {
|
||||||
}
|
}
|
||||||
return update
|
return update
|
||||||
})
|
})
|
||||||
*/
|
}
|
||||||
|
|
||||||
|
destroyTourNode(tourStepKey) {
|
||||||
|
if (this.tourNodes[tourStepKey]) {
|
||||||
|
this.update(state => ({
|
||||||
|
...state,
|
||||||
|
tourNodes: {
|
||||||
|
[tourStepKey]: _,
|
||||||
|
...this.tourNodes,
|
||||||
|
},
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
startBuilderOnboarding() {
|
||||||
|
this.update(state => ({
|
||||||
|
...state,
|
||||||
|
onboarding: true,
|
||||||
|
tourKey: TOUR_KEYS.TOUR_BUILDER_ONBOARDING,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
startTour(tourKey) {
|
||||||
|
this.update(state => ({
|
||||||
|
...state,
|
||||||
|
tourKey: tourKey,
|
||||||
|
}))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const builderStore = new BuilderStore()
|
export const builderStore = new BuilderStore()
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { writable, get, derived } from "svelte/store"
|
import { get, derived } from "svelte/store"
|
||||||
import { cloneDeep } from "lodash/fp"
|
import { cloneDeep } from "lodash/fp"
|
||||||
import { API } from "api"
|
import { API } from "api"
|
||||||
import { Helpers } from "@budibase/bbui"
|
import { Helpers } from "@budibase/bbui"
|
||||||
|
@ -23,26 +23,93 @@ import {
|
||||||
DB_TYPE_INTERNAL,
|
DB_TYPE_INTERNAL,
|
||||||
DB_TYPE_EXTERNAL,
|
DB_TYPE_EXTERNAL,
|
||||||
} from "constants/backend"
|
} from "constants/backend"
|
||||||
|
import BudiStore from "../BudiStore"
|
||||||
|
|
||||||
const INITIAL_COMPONENTS_STATE = {
|
export const INITIAL_COMPONENTS_STATE = {
|
||||||
components: [],
|
components: [],
|
||||||
customComponents: [],
|
customComponents: [],
|
||||||
selectedComponentId: null,
|
selectedComponentId: null,
|
||||||
componentToPaste: null,
|
componentToPaste: null,
|
||||||
}
|
}
|
||||||
|
|
||||||
export const createComponentStore = () => {
|
export class ComponentStore extends BudiStore {
|
||||||
const store = writable({
|
constructor() {
|
||||||
...INITIAL_COMPONENTS_STATE,
|
super(INITIAL_COMPONENTS_STATE)
|
||||||
})
|
|
||||||
|
|
||||||
const reset = () => {
|
this.reset = this.reset.bind(this)
|
||||||
store.set({ ...INITIAL_COMPONENTS_STATE })
|
this.refreshDefinitions = this.refreshDefinitions.bind(this)
|
||||||
|
this.getDefinition = this.getDefinition.bind(this)
|
||||||
|
this.getDefaultDatasource = this.getDefaultDatasource.bind(this)
|
||||||
|
this.enrichEmptySettings = this.enrichEmptySettings.bind(this)
|
||||||
|
this.createInstance = this.createInstance.bind(this)
|
||||||
|
this.create = this.create.bind(this)
|
||||||
|
this.patch = this.patch.bind(this)
|
||||||
|
this.delete = this.delete.bind(this)
|
||||||
|
this.copy = this.copy.bind(this)
|
||||||
|
this.paste = this.paste.bind(this)
|
||||||
|
this.select = this.select.bind(this)
|
||||||
|
this.getPrevious = this.getPrevious.bind(this)
|
||||||
|
this.getNext = this.getNext.bind(this)
|
||||||
|
this.selectPrevious = this.selectPrevious.bind(this)
|
||||||
|
this.selectNext = this.selectNext.bind(this)
|
||||||
|
this.moveUp = this.moveUp.bind(this)
|
||||||
|
this.moveDown = this.moveDown.bind(this)
|
||||||
|
this.updateStyle = this.updateStyle.bind(this)
|
||||||
|
this.updateStyles = this.updateStyles.bind(this)
|
||||||
|
this.updateCustomStyle = this.updateCustomStyle.bind(this)
|
||||||
|
this.updateConditions = this.updateConditions.bind(this)
|
||||||
|
this.requestEjectBlock = this.requestEjectBlock.bind(this)
|
||||||
|
this.handleEjectBlock = this.handleEjectBlock.bind(this)
|
||||||
|
this.updateSetting = this.updateSetting.bind(this)
|
||||||
|
this.updateComponentSetting = this.updateComponentSetting.bind(this)
|
||||||
|
this.addParent = this.addParent.bind(this)
|
||||||
|
|
||||||
|
this.selected = derived(
|
||||||
|
[this.store, selectedScreen],
|
||||||
|
([$store, $selectedScreen]) => {
|
||||||
|
if (
|
||||||
|
$selectedScreen &&
|
||||||
|
$store.selectedComponentId?.startsWith(`${$selectedScreen._id}-`)
|
||||||
|
) {
|
||||||
|
return $selectedScreen?.props
|
||||||
|
}
|
||||||
|
if (!$selectedScreen || !$store.selectedComponentId) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
return findComponent($selectedScreen?.props, $store.selectedComponentId)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
this.selectedComponentPath = derived(
|
||||||
|
[this.store, selectedScreen],
|
||||||
|
([$store, $selectedScreen]) => {
|
||||||
|
return findComponentPath(
|
||||||
|
$selectedScreen?.props,
|
||||||
|
$store.selectedComponentId
|
||||||
|
).map(component => component._id)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
this.subscribe(state => {
|
||||||
|
console.log("debug ", state)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const refreshDefinitions = async appId => {
|
/**
|
||||||
|
* Reset the component store to default values
|
||||||
|
*/
|
||||||
|
reset() {
|
||||||
|
this.store.set({ ...INITIAL_COMPONENTS_STATE })
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {string} appId
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
async refreshDefinitions(appId) {
|
||||||
if (!appId) {
|
if (!appId) {
|
||||||
appId = get(store).appId
|
appId = get(this.store).appId
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fetch definitions and filter out custom component definitions so we
|
// Fetch definitions and filter out custom component definitions so we
|
||||||
|
@ -53,7 +120,7 @@ export const createComponentStore = () => {
|
||||||
)
|
)
|
||||||
|
|
||||||
// Update store
|
// Update store
|
||||||
store.update(state => ({
|
this.update(state => ({
|
||||||
...state,
|
...state,
|
||||||
components,
|
components,
|
||||||
customComponents,
|
customComponents,
|
||||||
|
@ -65,14 +132,25 @@ export const createComponentStore = () => {
|
||||||
return components
|
return components
|
||||||
}
|
}
|
||||||
|
|
||||||
const getDefinition = componentName => {
|
/**
|
||||||
|
*
|
||||||
|
* @param {string} componentName
|
||||||
|
* @example
|
||||||
|
* '@budibase/standard-components/container'
|
||||||
|
* @returns {object}
|
||||||
|
*/
|
||||||
|
getDefinition(componentName) {
|
||||||
if (!componentName) {
|
if (!componentName) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
return get(store).components[componentName]
|
return get(this.store).components[componentName]
|
||||||
}
|
}
|
||||||
|
|
||||||
const getDefaultDatasource = () => {
|
/**
|
||||||
|
*
|
||||||
|
* @returns {object}
|
||||||
|
*/
|
||||||
|
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")
|
||||||
|
|
||||||
|
@ -102,11 +180,17 @@ export const createComponentStore = () => {
|
||||||
return validTables.find(table => table.type === DB_TYPE_EXTERNAL)
|
return validTables.find(table => table.type === DB_TYPE_EXTERNAL)
|
||||||
}
|
}
|
||||||
|
|
||||||
const enrichEmptySettings = (component, opts) => {
|
/**
|
||||||
|
*
|
||||||
|
* @param {object} component
|
||||||
|
* @param {object} opts
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
enrichEmptySettings(component, opts) {
|
||||||
if (!component?._component) {
|
if (!component?._component) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const defaultDS = getDefaultDatasource()
|
const defaultDS = this.getDefaultDatasource()
|
||||||
const settings = getComponentSettings(component._component)
|
const settings = getComponentSettings(component._component)
|
||||||
const { parent, screen, useDefaultValues } = opts || {}
|
const { parent, screen, useDefaultValues } = opts || {}
|
||||||
const treeId = parent?._id || component._id
|
const treeId = parent?._id || component._id
|
||||||
|
@ -198,8 +282,15 @@ export const createComponentStore = () => {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const createInstance = (componentName, presetProps, parent) => {
|
/**
|
||||||
const definition = getDefinition(componentName)
|
*
|
||||||
|
* @param {string} componentName
|
||||||
|
* @param {object} presetProps
|
||||||
|
* @param {object} parent
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
createInstance(componentName, presetProps, parent) {
|
||||||
|
const definition = this.getDefinition(componentName)
|
||||||
if (!definition) {
|
if (!definition) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
@ -218,7 +309,7 @@ export const createComponentStore = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enrich empty settings
|
// Enrich empty settings
|
||||||
enrichEmptySettings(instance, {
|
this.enrichEmptySettings(instance, {
|
||||||
parent,
|
parent,
|
||||||
screen: get(selectedScreen),
|
screen: get(selectedScreen),
|
||||||
useDefaultValues: true,
|
useDefaultValues: true,
|
||||||
|
@ -247,9 +338,21 @@ export const createComponentStore = () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const create = async (componentName, presetProps, parent, index) => {
|
/**
|
||||||
const state = get(store)
|
*
|
||||||
const componentInstance = createInstance(componentName, presetProps, parent)
|
* @param {string} componentName
|
||||||
|
* @param {object} presetProps
|
||||||
|
* @param {object} parent
|
||||||
|
* @param {number} index
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
async create(componentName, presetProps, parent, index) {
|
||||||
|
const state = get(this.store)
|
||||||
|
const componentInstance = this.createInstance(
|
||||||
|
componentName,
|
||||||
|
presetProps,
|
||||||
|
parent
|
||||||
|
)
|
||||||
if (!componentInstance) {
|
if (!componentInstance) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -286,7 +389,7 @@ export const createComponentStore = () => {
|
||||||
let parentComponent
|
let parentComponent
|
||||||
if (currentComponent) {
|
if (currentComponent) {
|
||||||
// Use selected component as parent if one is selected
|
// Use selected component as parent if one is selected
|
||||||
const definition = getDefinition(currentComponent._component)
|
const definition = this.getDefinition(currentComponent._component)
|
||||||
if (definition?.hasChildren) {
|
if (definition?.hasChildren) {
|
||||||
// Use selected component if it allows children
|
// Use selected component if it allows children
|
||||||
parentComponent = currentComponent
|
parentComponent = currentComponent
|
||||||
|
@ -314,7 +417,7 @@ export const createComponentStore = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Select new component
|
// Select new component
|
||||||
store.update(state => {
|
this.update(state => {
|
||||||
state.selectedComponentId = componentInstance._id
|
state.selectedComponentId = componentInstance._id
|
||||||
return state
|
return state
|
||||||
})
|
})
|
||||||
|
@ -327,10 +430,17 @@ export const createComponentStore = () => {
|
||||||
return componentInstance
|
return componentInstance
|
||||||
}
|
}
|
||||||
|
|
||||||
const patch = async (patchFn, componentId, screenId) => {
|
/**
|
||||||
|
*
|
||||||
|
* @param {function} patchFn
|
||||||
|
* @param {string} componentId
|
||||||
|
* @param {string} screenId
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
async patch(patchFn, componentId, screenId) {
|
||||||
// Use selected component by default
|
// Use selected component by default
|
||||||
if (!componentId || !screenId) {
|
if (!componentId || !screenId) {
|
||||||
const state = get(store)
|
const state = get(this.store)
|
||||||
componentId = componentId || state.selectedComponentId
|
componentId = componentId || state.selectedComponentId
|
||||||
|
|
||||||
const screenState = get(screenStore)
|
const screenState = get(screenStore)
|
||||||
|
@ -350,18 +460,23 @@ export const createComponentStore = () => {
|
||||||
await screenStore.patch(patchScreen, screenId)
|
await screenStore.patch(patchScreen, screenId)
|
||||||
}
|
}
|
||||||
|
|
||||||
const deleteComponent = async component => {
|
/**
|
||||||
|
*
|
||||||
|
* @param {object} component
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
async delete(component) {
|
||||||
if (!component) {
|
if (!component) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine the next component to select after deletion
|
// Determine the next component to select after deletion
|
||||||
const state = get(store)
|
const state = get(this.store)
|
||||||
let nextSelectedComponentId
|
let nextSelectedComponentId
|
||||||
if (state.selectedComponentId === component._id) {
|
if (state.selectedComponentId === component._id) {
|
||||||
nextSelectedComponentId = getNext()
|
nextSelectedComponentId = this.getNext()
|
||||||
if (!nextSelectedComponentId) {
|
if (!nextSelectedComponentId) {
|
||||||
nextSelectedComponentId = getPrevious()
|
nextSelectedComponentId = this.getPrevious()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -385,16 +500,16 @@ export const createComponentStore = () => {
|
||||||
|
|
||||||
// Update selected component if required
|
// Update selected component if required
|
||||||
if (nextSelectedComponentId) {
|
if (nextSelectedComponentId) {
|
||||||
store.update(state => {
|
this.update(state => {
|
||||||
state.selectedComponentId = nextSelectedComponentId
|
state.selectedComponentId = nextSelectedComponentId
|
||||||
return state
|
return state
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const copy = (component, cut = false, selectParent = true) => {
|
copy(component, cut = false, selectParent = true) {
|
||||||
// Update store with copied component
|
// Update store with copied component
|
||||||
store.update(state => {
|
this.update(state => {
|
||||||
state.componentToPaste = cloneDeep(component)
|
state.componentToPaste = cloneDeep(component)
|
||||||
state.componentToPaste.isCut = cut
|
state.componentToPaste.isCut = cut
|
||||||
return state
|
return state
|
||||||
|
@ -405,7 +520,7 @@ export const createComponentStore = () => {
|
||||||
const screen = get(selectedScreen)
|
const screen = get(selectedScreen)
|
||||||
const parent = findComponentParent(screen?.props, component._id)
|
const parent = findComponentParent(screen?.props, component._id)
|
||||||
if (parent) {
|
if (parent) {
|
||||||
store.update(state => {
|
this.update(state => {
|
||||||
state.selectedComponentId = parent._id
|
state.selectedComponentId = parent._id
|
||||||
return state
|
return state
|
||||||
})
|
})
|
||||||
|
@ -413,15 +528,26 @@ export const createComponentStore = () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const select = componentId => {
|
/**
|
||||||
store.update(state => {
|
*
|
||||||
|
* @param {string} componentId
|
||||||
|
*/
|
||||||
|
select(componentId) {
|
||||||
|
this.update(state => {
|
||||||
state.selectedComponentId = componentId
|
state.selectedComponentId = componentId
|
||||||
return state
|
return state
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const paste = async (targetComponent, mode, targetScreen) => {
|
/**
|
||||||
const state = get(store)
|
*
|
||||||
|
* @param {object} targetComponent
|
||||||
|
* @param {string} mode
|
||||||
|
* @param {object} targetScreen
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
async paste(targetComponent, mode, targetScreen) {
|
||||||
|
const state = get(this.store)
|
||||||
if (!state.componentToPaste) {
|
if (!state.componentToPaste) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -430,7 +556,7 @@ export const createComponentStore = () => {
|
||||||
// Remove copied component if cutting, regardless if pasting works
|
// Remove copied component if cutting, regardless if pasting works
|
||||||
let componentToPaste = cloneDeep(state.componentToPaste)
|
let componentToPaste = cloneDeep(state.componentToPaste)
|
||||||
if (componentToPaste.isCut) {
|
if (componentToPaste.isCut) {
|
||||||
store.update(state => {
|
this.update(state => {
|
||||||
delete state.componentToPaste
|
delete state.componentToPaste
|
||||||
return state
|
return state
|
||||||
})
|
})
|
||||||
|
@ -465,7 +591,7 @@ export const createComponentStore = () => {
|
||||||
|
|
||||||
// Check inside is valid
|
// Check inside is valid
|
||||||
if (mode === "inside") {
|
if (mode === "inside") {
|
||||||
const definition = getDefinition(targetComponent._component)
|
const definition = this.getDefinition(targetComponent._component)
|
||||||
if (!definition.hasChildren) {
|
if (!definition.hasChildren) {
|
||||||
mode = "below"
|
mode = "below"
|
||||||
}
|
}
|
||||||
|
@ -495,15 +621,15 @@ export const createComponentStore = () => {
|
||||||
await screenStore.patch(patch, targetScreenId)
|
await screenStore.patch(patch, targetScreenId)
|
||||||
|
|
||||||
// Select the new component
|
// Select the new component
|
||||||
store.update(state => {
|
this.update(state => {
|
||||||
state.selectedScreenId = targetScreenId
|
state.selectedScreenId = targetScreenId
|
||||||
state.selectedComponentId = newComponentId
|
state.selectedComponentId = newComponentId
|
||||||
return state
|
return state
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const getPrevious = () => {
|
getPrevious() {
|
||||||
const state = get(store)
|
const state = get(this.store)
|
||||||
const componentId = state.selectedComponentId
|
const componentId = state.selectedComponentId
|
||||||
const screen = get(selectedScreen)
|
const screen = get(selectedScreen)
|
||||||
const parent = findComponentParent(screen.props, componentId)
|
const parent = findComponentParent(screen.props, componentId)
|
||||||
|
@ -542,8 +668,8 @@ export const createComponentStore = () => {
|
||||||
return parent._id
|
return parent._id
|
||||||
}
|
}
|
||||||
|
|
||||||
const getNext = () => {
|
getNext() {
|
||||||
const state = get(store)
|
const state = get(this.store)
|
||||||
const component = get(selectedComponent)
|
const component = get(selectedComponent)
|
||||||
const componentId = component?._id
|
const componentId = component?._id
|
||||||
const screen = get(selectedScreen)
|
const screen = get(selectedScreen)
|
||||||
|
@ -593,27 +719,27 @@ export const createComponentStore = () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const selectPrevious = () => {
|
selectPrevious() {
|
||||||
const previousId = getPrevious()
|
const previousId = this.getPrevious()
|
||||||
if (previousId) {
|
if (previousId) {
|
||||||
store.update(state => {
|
this.update(state => {
|
||||||
state.selectedComponentId = previousId
|
state.selectedComponentId = previousId
|
||||||
return state
|
return state
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const selectNext = () => {
|
selectNext() {
|
||||||
const nextId = getNext()
|
const nextId = this.getNext()
|
||||||
if (nextId) {
|
if (nextId) {
|
||||||
store.update(state => {
|
this.update(state => {
|
||||||
state.selectedComponentId = nextId
|
state.selectedComponentId = nextId
|
||||||
return state
|
return state
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const moveUp = async component => {
|
async moveUp(component) {
|
||||||
await screenStore.patch(screen => {
|
await screenStore.patch(screen => {
|
||||||
const componentId = component?._id
|
const componentId = component?._id
|
||||||
const parent = findComponentParent(screen.props, componentId)
|
const parent = findComponentParent(screen.props, componentId)
|
||||||
|
@ -635,7 +761,7 @@ export const createComponentStore = () => {
|
||||||
// If sibling before us accepts children, move to last child of
|
// If sibling before us accepts children, move to last child of
|
||||||
// sibling
|
// sibling
|
||||||
const previousSibling = parent._children[index - 1]
|
const previousSibling = parent._children[index - 1]
|
||||||
const definition = getDefinition(previousSibling._component)
|
const definition = this.getDefinition(previousSibling._component)
|
||||||
if (definition.hasChildren) {
|
if (definition.hasChildren) {
|
||||||
previousSibling._children.push(originalComponent)
|
previousSibling._children.push(originalComponent)
|
||||||
}
|
}
|
||||||
|
@ -658,7 +784,7 @@ export const createComponentStore = () => {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const moveDown = async component => {
|
async moveDown(component) {
|
||||||
await screenStore.patch(screen => {
|
await screenStore.patch(screen => {
|
||||||
const componentId = component?._id
|
const componentId = component?._id
|
||||||
const parent = findComponentParent(screen.props, componentId)
|
const parent = findComponentParent(screen.props, componentId)
|
||||||
|
@ -687,7 +813,7 @@ export const createComponentStore = () => {
|
||||||
if (index < parent._children.length) {
|
if (index < parent._children.length) {
|
||||||
// If the next sibling has children, become the first child
|
// If the next sibling has children, become the first child
|
||||||
const nextSibling = parent._children[index]
|
const nextSibling = parent._children[index]
|
||||||
const definition = getDefinition(nextSibling._component)
|
const definition = this.getDefinition(nextSibling._component)
|
||||||
if (definition.hasChildren) {
|
if (definition.hasChildren) {
|
||||||
nextSibling._children.splice(0, 0, originalComponent)
|
nextSibling._children.splice(0, 0, originalComponent)
|
||||||
}
|
}
|
||||||
|
@ -709,8 +835,8 @@ export const createComponentStore = () => {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const updateStyle = async (name, value) => {
|
async updateStyle(name, value) {
|
||||||
await patch(component => {
|
await this.patch(component => {
|
||||||
if (value == null || value === "") {
|
if (value == null || value === "") {
|
||||||
delete component._styles.normal[name]
|
delete component._styles.normal[name]
|
||||||
} else {
|
} else {
|
||||||
|
@ -719,33 +845,33 @@ export const createComponentStore = () => {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const updateStyles = async (styles, id) => {
|
async updateStyles(styles, id) {
|
||||||
const patchFn = component => {
|
const patchFn = component => {
|
||||||
component._styles.normal = {
|
component._styles.normal = {
|
||||||
...component._styles.normal,
|
...component._styles.normal,
|
||||||
...styles,
|
...styles,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
await patch(patchFn, id)
|
await this.patch(patchFn, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
const updateCustomStyle = async style => {
|
async updateCustomStyle(style) {
|
||||||
await patch(component => {
|
await this.patch(component => {
|
||||||
component._styles.custom = style
|
component._styles.custom = style
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const updateConditions = async conditions => {
|
async updateConditions(conditions) {
|
||||||
await patch(component => {
|
await this.patch(component => {
|
||||||
component._conditions = conditions
|
component._conditions = conditions
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const updateSetting = async (name, value) => {
|
async updateSetting(name, value) {
|
||||||
await patch(updateComponentSetting(name, value))
|
await this.patch(this.updateComponentSetting(name, value))
|
||||||
}
|
}
|
||||||
|
|
||||||
const updateComponentSetting = (name, value) => {
|
updateComponentSetting(name, value) {
|
||||||
return component => {
|
return component => {
|
||||||
if (!name || !component) {
|
if (!name || !component) {
|
||||||
return false
|
return false
|
||||||
|
@ -783,11 +909,11 @@ export const createComponentStore = () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const requestEjectBlock = componentId => {
|
requestEjectBlock(componentId) {
|
||||||
previewStore.sendEvent("eject-block", componentId)
|
previewStore.sendEvent("eject-block", componentId)
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleEjectBlock = async (componentId, ejectedDefinition) => {
|
async handleEjectBlock(componentId, ejectedDefinition) {
|
||||||
let nextSelectedComponentId
|
let nextSelectedComponentId
|
||||||
|
|
||||||
await screenStore.patch(screen => {
|
await screenStore.patch(screen => {
|
||||||
|
@ -827,20 +953,20 @@ export const createComponentStore = () => {
|
||||||
|
|
||||||
// Select new root component
|
// Select new root component
|
||||||
if (nextSelectedComponentId) {
|
if (nextSelectedComponentId) {
|
||||||
store.update(state => {
|
this.update(state => {
|
||||||
state.selectedComponentId = nextSelectedComponentId
|
state.selectedComponentId = nextSelectedComponentId
|
||||||
return state
|
return state
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const addParent = async (componentId, parentType) => {
|
async addParent(componentId, parentType) {
|
||||||
if (!componentId || !parentType) {
|
if (!componentId || !parentType) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create new parent instance
|
// Create new parent instance
|
||||||
const newParentDefinition = createInstance(parentType, null, parent)
|
const newParentDefinition = this.createInstance(parentType, null, parent)
|
||||||
if (!newParentDefinition) {
|
if (!newParentDefinition) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -868,71 +994,15 @@ export const createComponentStore = () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
// Select the new parent
|
// Select the new parent
|
||||||
store.update(state => {
|
this.update(state => {
|
||||||
state.selectedComponentId = newParentDefinition._id
|
state.selectedComponentId = newParentDefinition._id
|
||||||
return state
|
return state
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return {
|
|
||||||
subscribe: store.subscribe,
|
|
||||||
reset,
|
|
||||||
update: store.update,
|
|
||||||
refreshDefinitions,
|
|
||||||
getDefinition,
|
|
||||||
getDefaultDatasource,
|
|
||||||
enrichEmptySettings,
|
|
||||||
createInstance,
|
|
||||||
create,
|
|
||||||
patch,
|
|
||||||
delete: deleteComponent,
|
|
||||||
copy,
|
|
||||||
paste,
|
|
||||||
select,
|
|
||||||
getPrevious,
|
|
||||||
getNext,
|
|
||||||
selectPrevious,
|
|
||||||
selectNext,
|
|
||||||
moveUp,
|
|
||||||
moveDown,
|
|
||||||
updateStyle,
|
|
||||||
updateStyles,
|
|
||||||
updateCustomStyle,
|
|
||||||
updateConditions,
|
|
||||||
requestEjectBlock,
|
|
||||||
handleEjectBlock,
|
|
||||||
updateSetting,
|
|
||||||
updateComponentSetting,
|
|
||||||
addParent,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const componentStore = createComponentStore()
|
export const componentStore = new ComponentStore()
|
||||||
|
|
||||||
export const selectedComponent = derived(
|
export const selectedComponent = componentStore.selected
|
||||||
[componentStore, selectedScreen],
|
|
||||||
([$componentStore, $selectedScreen]) => {
|
|
||||||
if (
|
|
||||||
$selectedScreen &&
|
|
||||||
$componentStore.selectedComponentId?.startsWith(`${$selectedScreen._id}-`)
|
|
||||||
) {
|
|
||||||
return $selectedScreen?.props
|
|
||||||
}
|
|
||||||
if (!$selectedScreen || !$componentStore.selectedComponentId) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
return findComponent(
|
|
||||||
$selectedScreen?.props,
|
|
||||||
$componentStore.selectedComponentId
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
export const selectedComponentPath = derived(
|
export const selectedComponentPath = componentStore.selectedComponentPath
|
||||||
[componentStore, selectedScreen],
|
|
||||||
([$componentStore, $selectedScreen]) => {
|
|
||||||
return findComponentPath(
|
|
||||||
$selectedScreen?.props,
|
|
||||||
$componentStore.selectedComponentId
|
|
||||||
).map(component => component._id)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { layoutStore } from "./layouts.js"
|
||||||
import { appStore } from "./app.js"
|
import { appStore } from "./app.js"
|
||||||
import {
|
import {
|
||||||
componentStore,
|
componentStore,
|
||||||
|
@ -14,7 +15,6 @@ import {
|
||||||
} from "./screens.js"
|
} from "./screens.js"
|
||||||
import { builderStore, screensHeight } from "./builder.js"
|
import { builderStore, screensHeight } from "./builder.js"
|
||||||
import { previewStore } from "./preview.js"
|
import { previewStore } from "./preview.js"
|
||||||
import { layoutStore } from "./layouts.js"
|
|
||||||
import {
|
import {
|
||||||
automationStore,
|
automationStore,
|
||||||
selectedAutomation,
|
selectedAutomation,
|
||||||
|
@ -25,6 +25,7 @@ import { deploymentStore } from "./deployments.js"
|
||||||
import { database } from "./database.js"
|
import { database } from "./database.js"
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
layoutStore,
|
||||||
database,
|
database,
|
||||||
appStore,
|
appStore,
|
||||||
componentStore,
|
componentStore,
|
||||||
|
@ -40,7 +41,6 @@ export {
|
||||||
automationHistoryStore,
|
automationHistoryStore,
|
||||||
currentAsset,
|
currentAsset,
|
||||||
sortedScreens,
|
sortedScreens,
|
||||||
layoutStore,
|
|
||||||
userStore,
|
userStore,
|
||||||
isOnlyUser,
|
isOnlyUser,
|
||||||
screensHeight,
|
screensHeight,
|
||||||
|
|
|
@ -1,32 +1,43 @@
|
||||||
import { writable, derived, get } from "svelte/store"
|
import { derived, get } from "svelte/store"
|
||||||
import { componentStore } from "stores/frontend"
|
import { componentStore } from "stores/frontend"
|
||||||
|
import BudiStore from "./BudiStore"
|
||||||
import { API } from "api"
|
import { API } from "api"
|
||||||
|
|
||||||
// Review the purpose of these
|
export const INITIAL_LAYOUT_STATE = {
|
||||||
const INITIAL_LAYOUT_STATE = {
|
|
||||||
layouts: [],
|
layouts: [],
|
||||||
selectedLayoutId: null,
|
selectedLayoutId: null,
|
||||||
}
|
}
|
||||||
|
|
||||||
export const createLayoutStore = () => {
|
export class LayoutStore extends BudiStore {
|
||||||
const store = writable({
|
constructor() {
|
||||||
...INITIAL_LAYOUT_STATE,
|
super(INITIAL_LAYOUT_STATE)
|
||||||
})
|
|
||||||
|
|
||||||
const reset = () => {
|
this.reset = this.reset.bind(this)
|
||||||
store.set({ ...INITIAL_LAYOUT_STATE })
|
this.syncAppLayouts = this.syncAppLayouts.bind(this)
|
||||||
|
this.select = this.select.bind(this)
|
||||||
|
this.deleteLayout = this.deleteLayout.bind(this)
|
||||||
|
|
||||||
|
this.selectedLayout = derived(this.store, $store => {
|
||||||
|
return $store.layouts?.find(
|
||||||
|
layout => layout._id === $store.selectedLayoutId
|
||||||
|
)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const syncAppLayouts = pkg => {
|
reset() {
|
||||||
store.update(state => ({
|
this.store.set({ ...INITIAL_LAYOUT_STATE })
|
||||||
|
}
|
||||||
|
|
||||||
|
syncAppLayouts(pkg) {
|
||||||
|
this.update(state => ({
|
||||||
...state,
|
...state,
|
||||||
layouts: [...pkg.layouts],
|
layouts: [...pkg.layouts],
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
const select = layoutId => {
|
select(layoutId) {
|
||||||
// Check this layout exists
|
// Check this layout exists
|
||||||
const state = get(store)
|
const state = get(this.store)
|
||||||
const componentState = get(componentStore)
|
const componentState = get(componentStore)
|
||||||
const layout = state.layouts.find(layout => layout._id === layoutId)
|
const layout = state.layouts.find(layout => layout._id === layoutId)
|
||||||
if (!layout) {
|
if (!layout) {
|
||||||
|
@ -42,7 +53,7 @@ export const createLayoutStore = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Select new layout
|
// Select new layout
|
||||||
store.update(state => {
|
this.update(state => {
|
||||||
state.selectedLayoutId = layout._id
|
state.selectedLayoutId = layout._id
|
||||||
return state
|
return state
|
||||||
})
|
})
|
||||||
|
@ -50,7 +61,7 @@ export const createLayoutStore = () => {
|
||||||
componentStore.select(layout.props?._id)
|
componentStore.select(layout.props?._id)
|
||||||
}
|
}
|
||||||
|
|
||||||
const deleteLayout = async layout => {
|
async deleteLayout(layout) {
|
||||||
if (!layout?._id) {
|
if (!layout?._id) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -58,25 +69,13 @@ export const createLayoutStore = () => {
|
||||||
layoutId: layout._id,
|
layoutId: layout._id,
|
||||||
layoutRev: layout._rev,
|
layoutRev: layout._rev,
|
||||||
})
|
})
|
||||||
store.update(state => {
|
this.update(state => {
|
||||||
state.layouts = state.layouts.filter(x => x._id !== layout._id)
|
state.layouts = state.layouts.filter(x => x._id !== layout._id)
|
||||||
return state
|
return state
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
|
||||||
subscribe: store.subscribe,
|
|
||||||
syncAppLayouts,
|
|
||||||
select,
|
|
||||||
delete: deleteLayout,
|
|
||||||
reset,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const layoutStore = createLayoutStore()
|
export const layoutStore = new LayoutStore()
|
||||||
|
|
||||||
export const selectedLayout = derived(layoutStore, $layoutStore => {
|
export const selectedLayout = layoutStore.selectedLayout
|
||||||
return $layoutStore.layouts?.find(
|
|
||||||
layout => layout._id === $layoutStore.selectedLayoutId
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ import { Helpers } from "@budibase/bbui"
|
||||||
import { RoleUtils, Utils } from "@budibase/frontend-core"
|
import { RoleUtils, Utils } from "@budibase/frontend-core"
|
||||||
import { findAllMatchingComponents } from "stores/frontend/components/utils"
|
import { findAllMatchingComponents } from "stores/frontend/components/utils"
|
||||||
import {
|
import {
|
||||||
|
layoutStore,
|
||||||
appStore,
|
appStore,
|
||||||
componentStore,
|
componentStore,
|
||||||
navigationStore,
|
navigationStore,
|
||||||
|
@ -36,7 +37,7 @@ export class ScreenStore extends BudiStore {
|
||||||
this.syncScreenData = this.syncScreenData.bind(this)
|
this.syncScreenData = this.syncScreenData.bind(this)
|
||||||
this.updateSetting = this.updateSetting.bind(this)
|
this.updateSetting = this.updateSetting.bind(this)
|
||||||
this.sequentialScreenPatch = this.sequentialScreenPatch.bind(this)
|
this.sequentialScreenPatch = this.sequentialScreenPatch.bind(this)
|
||||||
// this.removeCustomLayout = this.removeCustomLayout(this)
|
this.removeCustomLayout = this.removeCustomLayout(this)
|
||||||
|
|
||||||
this.selected = derived(this.store, $store => {
|
this.selected = derived(this.store, $store => {
|
||||||
return get(this.store).screens.find(
|
return get(this.store).screens.find(
|
||||||
|
@ -452,16 +453,16 @@ export class ScreenStore extends BudiStore {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Move to layouts store
|
// Move to layouts store
|
||||||
// async removeCustomLayout(screen) {
|
async removeCustomLayout(screen) {
|
||||||
// // Pull relevant settings from old layout, if required
|
// Pull relevant settings from old layout, if required
|
||||||
// const layout = get(this.store).layouts.find(x => x._id === screen.layoutId)
|
const layout = get(layoutStore).layouts.find(x => x._id === screen.layoutId)
|
||||||
// const patchFn = screen => {
|
const patchFn = screen => {
|
||||||
// screen.layoutId = null
|
screen.layoutId = null
|
||||||
// screen.showNavigation = layout?.props.navigation !== "None"
|
screen.showNavigation = layout?.props.navigation !== "None"
|
||||||
// screen.width = layout?.props.width || "Large"
|
screen.width = layout?.props.width || "Large"
|
||||||
// }
|
}
|
||||||
// await this.patch(patchFn, screen._id)
|
await this.patch(patchFn, screen._id)
|
||||||
// }
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse the entire screen component tree and ensure settings are valid
|
* Parse the entire screen component tree and ensure settings are valid
|
||||||
|
|
|
@ -9,12 +9,13 @@ vi.mock("../websocket.js")
|
||||||
describe("Builder store", () => {
|
describe("Builder store", () => {
|
||||||
beforeEach(ctx => {
|
beforeEach(ctx => {
|
||||||
vi.clearAllMocks()
|
vi.clearAllMocks()
|
||||||
const builderStorex = new BuilderStore()
|
const builderStore = new BuilderStore()
|
||||||
|
ctx.test = {}
|
||||||
ctx.test = {
|
ctx.test = {
|
||||||
get store() {
|
get store() {
|
||||||
return get(builderStorex)
|
return get(builderStore)
|
||||||
},
|
},
|
||||||
builderStorex,
|
builderStore,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -147,13 +148,13 @@ describe("Builder store", () => {
|
||||||
const designURL =
|
const designURL =
|
||||||
"/builder/app/app_dev_123/design/screen_456/screen_456-screen"
|
"/builder/app/app_dev_123/design/screen_456/screen_456-screen"
|
||||||
|
|
||||||
ctx.test.builderStorex.setPreviousTopNavPath(dataRoute, dataURL)
|
ctx.test.builderStore.setPreviousTopNavPath(dataRoute, dataURL)
|
||||||
|
|
||||||
expect(ctx.test.store.previousTopNavPath).toStrictEqual({
|
expect(ctx.test.store.previousTopNavPath).toStrictEqual({
|
||||||
[dataRoute]: dataURL,
|
[dataRoute]: dataURL,
|
||||||
})
|
})
|
||||||
|
|
||||||
ctx.test.builderStorex.setPreviousTopNavPath(designRoute, designURL)
|
ctx.test.builderStore.setPreviousTopNavPath(designRoute, designURL)
|
||||||
|
|
||||||
expect(ctx.test.store.previousTopNavPath).toStrictEqual({
|
expect(ctx.test.store.previousTopNavPath).toStrictEqual({
|
||||||
[dataRoute]: dataURL,
|
[dataRoute]: dataURL,
|
||||||
|
@ -161,24 +162,47 @@ describe("Builder store", () => {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it("Overrite an existing route/path mapping with a new URL", () => {
|
it("Overrite an existing route/path mapping with a new URL", ctx => {
|
||||||
// expect(ctx.test.store.previousTopNavPath).toStrictEqual({})
|
expect(ctx.test.store.previousTopNavPath).toStrictEqual({})
|
||||||
// ctx.test.builderStore.refresh()
|
|
||||||
console.log(INITIAL_BUILDER_STATE)
|
console.log(INITIAL_BUILDER_STATE)
|
||||||
// const dataRoute = "/builder/app/:application/data"
|
const dataRoute = "/builder/app/:application/data"
|
||||||
// const dataURL = "/builder/app/app_dev_123/data/table/ta_users"
|
const dataURL = "/builder/app/app_dev_123/data/table/ta_users"
|
||||||
// const updatedURL = "/builder/app/app_dev_123/data/table/ta_employees"
|
const updatedURL = "/builder/app/app_dev_123/data/table/ta_employees"
|
||||||
|
|
||||||
// ctx.test.builderStore.setPreviousTopNavPath(dataRoute, dataURL)
|
ctx.test.builderStore.setPreviousTopNavPath(dataRoute, dataURL)
|
||||||
|
|
||||||
// expect(ctx.test.store.previousTopNavPath).toStrictEqual({
|
expect(ctx.test.store.previousTopNavPath).toStrictEqual({
|
||||||
// [dataRoute]: dataURL,
|
[dataRoute]: dataURL,
|
||||||
// })
|
})
|
||||||
|
|
||||||
// ctx.test.builderStore.setPreviousTopNavPath(dataRoute, updatedURL)
|
ctx.test.builderStore.setPreviousTopNavPath(dataRoute, updatedURL)
|
||||||
|
|
||||||
// expect(ctx.test.store.previousTopNavPath).toStrictEqual({
|
expect(ctx.test.store.previousTopNavPath).toStrictEqual({
|
||||||
// [dataRoute]: updatedURL,
|
[dataRoute]: updatedURL,
|
||||||
// })
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it("Register a builder tour node", ctx => {
|
||||||
|
const fakeNode = { name: "node" }
|
||||||
|
ctx.test.builderStore.registerTourNode("sampleKey", fakeNode)
|
||||||
|
|
||||||
|
const registeredNodes = ctx.test.store.tourNodes
|
||||||
|
|
||||||
|
expect(registeredNodes).not.toBeNull()
|
||||||
|
expect(Object.keys(registeredNodes).length).toBe(1)
|
||||||
|
expect(registeredNodes["sampleKey"]).toStrictEqual(fakeNode)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("Clear a destroyed tour node", ctx => {
|
||||||
|
const fakeNode = { name: "node" }
|
||||||
|
ctx.test.builderStore.registerTourNode("sampleKey", fakeNode)
|
||||||
|
|
||||||
|
const registeredNodes = ctx.test.store.tourNodes
|
||||||
|
|
||||||
|
expect(registeredNodes).not.toBeNull()
|
||||||
|
expect(Object.keys(registeredNodes).length).toBe(1)
|
||||||
|
|
||||||
|
ctx.test.builderStore.destroyTourNode("sampleKey")
|
||||||
|
expect(registeredNodes).toBe({})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in New Issue