diff --git a/packages/builder/src/builderStore/store/frontend.js b/packages/builder/src/builderStore/store/frontend.js index 8f131ac0ff..fcb1224608 100644 --- a/packages/builder/src/builderStore/store/frontend.js +++ b/packages/builder/src/builderStore/store/frontend.js @@ -11,12 +11,13 @@ import { } from "builderStore" import { fetchComponentLibDefinitions } from "../loadComponentLibraries" import api from "../api" -import { FrontendTypes } from "../../constants" +import { FrontendTypes } from "constants" import analytics from "analytics" import { findComponentType, findComponentParent, findComponentPath, + findComponent, } from "../storeUtils" import { uuid } from "../uuid" @@ -44,21 +45,21 @@ export const getFrontendStore = () => { store.actions = { initialise: async pkg => { const { layouts, screens, application } = pkg - const components = await fetchComponentLibDefinitions(pkg.application._id) + const components = await fetchComponentLibDefinitions(application._id) store.update(state => ({ ...state, - libraries: pkg.application.componentLibraries, + libraries: application.componentLibraries, components, - name: pkg.application.name, - description: pkg.application.description, - appId: pkg.application._id, + name: application.name, + description: application.description, + appId: application._id, layouts, screens, hasAppPackage: true, - appInstance: pkg.application.instance, + appInstance: application.instance, })) await hostingStore.actions.fetch() - await backendUiStore.actions.database.select(pkg.application.instance) + await backendUiStore.actions.database.select(application.instance) }, routing: { fetch: async () => { @@ -226,6 +227,25 @@ export const getFrontendStore = () => { }, components: { select: component => { + if (!component) { + return + } + + // If this is the root component, select the asset instead + const asset = get(currentAsset) + const parent = findComponentParent(asset.props, component._id) + if (parent == null) { + const state = get(store) + const isLayout = state.currentFrontEndType === FrontendTypes.LAYOUT + if (isLayout) { + store.actions.layouts.select(asset._id) + } else { + store.actions.screens.select(asset._id) + } + return + } + + // Otherwise select the component store.update(state => { state.selectedComponentId = component._id state.currentView = "component" @@ -236,10 +256,10 @@ export const getFrontendStore = () => { if (!componentName) { return null } - const name = componentName.startsWith("@budibase") - ? componentName - : `@budibase/standard-components/${componentName}` - return get(store).components[name] + if (!componentName.startsWith("@budibase")) { + componentName = `@budibase/standard-components/${componentName}` + } + return get(store).components[componentName] }, createInstance: (componentName, presetProps) => { const definition = store.actions.components.getDefinition(componentName) @@ -273,6 +293,19 @@ export const getFrontendStore = () => { } }, create: (componentName, presetProps) => { + const selected = get(selectedComponent) + const asset = get(currentAsset) + const state = get(store) + + // Only allow one screen slot, and in the layout + if (componentName.endsWith("screenslot")) { + const isLayout = state.currentFrontEndType === FrontendTypes.LAYOUT + const slot = findComponentType(asset.props, componentName) + if (!isLayout || slot != null) { + return + } + } + // Create new component const componentInstance = store.actions.components.createInstance( componentName, @@ -284,8 +317,7 @@ export const getFrontendStore = () => { // Find parent node to attach this component to let parentComponent - const selected = get(selectedComponent) - const asset = get(currentAsset) + if (!asset) { return } diff --git a/packages/builder/src/components/userInterface/ComponentDropdownMenu.svelte b/packages/builder/src/components/userInterface/ComponentDropdownMenu.svelte index 0b97684d82..5ab3898c8d 100644 --- a/packages/builder/src/components/userInterface/ComponentDropdownMenu.svelte +++ b/packages/builder/src/components/userInterface/ComponentDropdownMenu.svelte @@ -32,43 +32,35 @@ } const moveUpComponent = () => { - store.update(state => { - const asset = get(currentAsset) - const parent = findComponentParent(asset.props, component) - - if (parent) { - const currentIndex = parent._children.indexOf(component) - if (currentIndex === 0) return state - - const newChildren = parent._children.filter(c => c !== component) - newChildren.splice(currentIndex - 1, 0, component) - parent._children = newChildren - } - state.selectedComponentId = component._id - store.actions.preview.saveSelected() - - return state - }) + const asset = get(currentAsset) + const parent = findComponentParent(asset.props, component._id) + if (!parent) { + return + } + const currentIndex = parent._children.indexOf(component) + if (currentIndex === 0) { + return + } + const newChildren = parent._children.filter(c => c !== component) + newChildren.splice(currentIndex - 1, 0, component) + parent._children = newChildren + store.actions.preview.saveSelected() } const moveDownComponent = () => { - store.update(state => { - const asset = get(currentAsset) - const parent = findComponentParent(asset.props, component) - - if (parent) { - const currentIndex = parent._children.indexOf(component) - if (currentIndex === parent._children.length - 1) return state - - const newChildren = parent._children.filter(c => c !== component) - newChildren.splice(currentIndex + 1, 0, component) - parent._children = newChildren - } - state.selectedComponentId = component._id - store.actions.preview.saveSelected() - - return state - }) + const asset = get(currentAsset) + const parent = findComponentParent(asset.props, component._id) + if (!parent) { + return + } + const currentIndex = parent._children.indexOf(component) + if (currentIndex === parent._children.length - 1) { + return + } + const newChildren = parent._children.filter(c => c !== component) + newChildren.splice(currentIndex + 1, 0, component) + parent._children = newChildren + store.actions.preview.saveSelected() } const duplicateComponent = () => { diff --git a/packages/builder/src/components/userInterface/ComponentPropertiesPanel.svelte b/packages/builder/src/components/userInterface/ComponentPropertiesPanel.svelte index cee504719a..6291917cd0 100644 --- a/packages/builder/src/components/userInterface/ComponentPropertiesPanel.svelte +++ b/packages/builder/src/components/userInterface/ComponentPropertiesPanel.svelte @@ -2,48 +2,30 @@ import { get } from "svelte/store" import { store, selectedComponent, currentAsset } from "builderStore" import { FrontendTypes } from "constants" - import panelStructure from "./temporaryPanelStructure.js" import CategoryTab from "./CategoryTab.svelte" import DesignView from "./DesignView.svelte" import SettingsView from "./SettingsView.svelte" import { setWith } from "lodash" - let flattenedPanel = flattenComponents(panelStructure.categories) - let categories = [ + const categories = [ { value: "settings", name: "Settings" }, { value: "design", name: "Design" }, ] let selectedCategory = categories[0] - $: componentInstance = - $store.currentView !== "component" - ? { ...$currentAsset, ...$selectedComponent } - : $selectedComponent - $: componentDefinition = store.actions.components.getDefinition( - componentInstance._component + $: definition = store.actions.components.getDefinition( + $selectedComponent._component ) - $: componentPropDefinition = - flattenedPanel.find( - // use for getting controls for each component property - c => c._component === componentInstance._component - ) || {} - - $: panelDefinition = - componentPropDefinition.properties && - componentPropDefinition.properties[selectedCategory.value] + $: isComponentOrScreen = + $store.currentView === "component" || + $store.currentFrontEndType === FrontendTypes.SCREEN + $: isNotScreenslot = !$selectedComponent._component.endsWith("screenslot") + $: showDisplayName = isComponentOrScreen && isNotScreenslot const onStyleChanged = store.actions.components.updateStyle const onCustomStyleChanged = store.actions.components.updateCustomStyle const onResetStyles = store.actions.components.resetStyles - $: isComponentOrScreen = - $store.currentView === "component" || - $store.currentFrontEndType === FrontendTypes.SCREEN - $: isNotScreenslot = !componentInstance._component.endsWith("screenslot") - - $: displayName = - isComponentOrScreen && componentInstance._instanceName && isNotScreenslot - function walkProps(component, action) { action(component) if (component.children) { @@ -91,24 +73,23 @@ {categories} {selectedCategory} /> -{#if displayName} -