1
0
Fork 0
mirror of synced 2024-06-28 19:10:33 +12:00

Fix dependency loop in client stores

This commit is contained in:
Andrew Kingston 2021-08-20 09:27:38 +01:00
parent a895771179
commit 10066bf3e0
5 changed files with 103 additions and 44 deletions

View file

@ -74,7 +74,6 @@
styles: { ...instance._styles, id, empty, interactive },
empty,
selected,
props: componentSettings,
name,
})

View file

@ -1,5 +1,6 @@
import { writable, derived } from "svelte/store"
import Manifest from "@budibase/standard-components/manifest.json"
import { findComponentById, findComponentPathById } from "../utils/components"
const dispatchEvent = (type, data = {}) => {
window.dispatchEvent(
@ -9,45 +10,6 @@ const dispatchEvent = (type, data = {}) => {
)
}
const findComponentById = (component, componentId) => {
if (!component || !componentId) {
return null
}
if (component._id === componentId) {
return component
}
if (!component._children?.length) {
return null
}
for (let child of component._children) {
const result = findComponentById(child, componentId)
if (result) {
return result
}
}
return null
}
const findComponentIdPath = (component, componentId, path = []) => {
if (!component || !componentId) {
return null
}
path = [...path, component._id]
if (component._id === componentId) {
return path
}
if (!component._children?.length) {
return null
}
for (let child of component._children) {
const result = findComponentIdPath(child, componentId, path)
if (result) {
return result
}
}
return null
}
const createBuilderStore = () => {
const initialState = {
inBuilder: false,
@ -75,13 +37,13 @@ const createBuilderStore = () => {
const definition = type ? Manifest[type] : null
// Derive the selected component path
const path = findComponentIdPath(asset.props, selectedComponentId) || []
const path = findComponentPathById(asset.props, selectedComponentId) || []
return {
...$state,
selectedComponent: component,
selectedComponentDefinition: definition,
selectedComponentPath: path,
selectedComponentPath: path?.map(component => component._id),
}
})

View file

@ -1,7 +1,12 @@
import { derived } from "svelte/store"
import { derived, get } from "svelte/store"
import { routeStore } from "./routes"
import { builderStore } from "./builder"
import { appStore } from "./app"
import {
findComponentPathById,
findChildrenByType,
findComponentById,
} from "../utils/components"
const createScreenStore = () => {
const store = derived(
@ -36,8 +41,39 @@ const createScreenStore = () => {
}
)
// Utils to parse component definitions
const actions = {
findComponentById: componentId => {
const { activeScreen, activeLayout } = get(store)
let result = findComponentById(activeScreen?.props, componentId)
if (result) {
return result
}
return findComponentById(activeLayout?.props)
},
findComponentPathById: componentId => {
const { activeScreen, activeLayout } = get(store)
let result = findComponentPathById(activeScreen?.props, componentId)
if (result) {
return result
}
return findComponentPathById(activeLayout?.props)
},
findChildrenByType: (componentId, type) => {
const component = actions.findComponentById(componentId)
if (!component || !component._children) {
return null
}
let children = []
findChildrenByType(component, type, children)
console.log(children)
return children
},
}
return {
subscribe: store.subscribe,
actions,
}
}

View file

@ -0,0 +1,62 @@
/**
* Finds a component instance by ID
*/
export const findComponentById = (component, componentId) => {
if (!component || !componentId) {
return null
}
if (component._id === componentId) {
return component
}
if (!component._children?.length) {
return null
}
for (let child of component._children) {
const result = findComponentById(child, componentId)
if (result) {
return result
}
}
return null
}
/**
* Finds the component path to a component
*/
export const findComponentPathById = (component, componentId, path = []) => {
if (!component || !componentId) {
return null
}
path = [...path, component]
if (component._id === componentId) {
return path
}
if (!component._children?.length) {
return null
}
for (let child of component._children) {
const result = findComponentPathById(child, componentId, path)
if (result) {
return result
}
}
return null
}
/**
* Finds all children instances of a certain component type of a given component
*/
export const findChildrenByType = (component, type, children = []) => {
if (!component) {
return
}
if (component._component.endsWith(`/${type}`)) {
children.push(component)
}
if (!component._children?.length) {
return
}
component._children.forEach(child => {
findChildrenByType(child, type, children)
})
}

View file

@ -27,7 +27,7 @@
$: errors = deriveFieldProperty(fields, f => f.fieldState.error)
$: valid = !Object.values($errors).some(error => error != null)
// Derive which fields belong in which steps
// Derive whether the current form step is valid
$: currentStepValid = derived(
[currentStep, ...fields],
([currentStepValue, ...fieldsValue]) => {