Browse Source

Fix component navigation, fix settings editing, fix design editing

master
Andrew Kingston 6 years ago
parent
commit
6b9e61e7e6
  1. 60
      packages/builder/src/builderStore/store/frontend.js
  2. 60
      packages/builder/src/components/userInterface/ComponentDropdownMenu.svelte
  3. 49
      packages/builder/src/components/userInterface/ComponentPropertiesPanel.svelte
  4. 16
      packages/builder/src/components/userInterface/DesignView.svelte
  5. 3
      packages/builder/src/components/userInterface/IconSelect/index.js
  6. 2
      packages/builder/src/components/userInterface/MultiTableViewFieldSelect.svelte
  7. 5
      packages/builder/src/components/userInterface/PropertyGroup.svelte
  8. 0
      packages/builder/src/components/userInterface/PropertyPanelControls/EventsEditor/EventEditorModal.svelte
  9. 0
      packages/builder/src/components/userInterface/PropertyPanelControls/EventsEditor/EventPropertyControl.svelte
  10. 0
      packages/builder/src/components/userInterface/PropertyPanelControls/EventsEditor/actions/CreateRow.svelte
  11. 0
      packages/builder/src/components/userInterface/PropertyPanelControls/EventsEditor/actions/DeleteRow.svelte
  12. 0
      packages/builder/src/components/userInterface/PropertyPanelControls/EventsEditor/actions/NavigateTo.svelte
  13. 0
      packages/builder/src/components/userInterface/PropertyPanelControls/EventsEditor/actions/SaveFields.svelte
  14. 0
      packages/builder/src/components/userInterface/PropertyPanelControls/EventsEditor/actions/SaveRow.svelte
  15. 0
      packages/builder/src/components/userInterface/PropertyPanelControls/EventsEditor/actions/UpdateRow.svelte
  16. 0
      packages/builder/src/components/userInterface/PropertyPanelControls/EventsEditor/actions/index.js
  17. 2
      packages/builder/src/components/userInterface/PropertyPanelControls/EventsEditor/index.js
  18. 0
      packages/builder/src/components/userInterface/PropertyPanelControls/FlatButtonGroup/FlatButton.svelte
  19. 0
      packages/builder/src/components/userInterface/PropertyPanelControls/FlatButtonGroup/FlatButtonGroup.svelte
  20. 2
      packages/builder/src/components/userInterface/PropertyPanelControls/FlatButtonGroup/index.js
  21. 0
      packages/builder/src/components/userInterface/PropertyPanelControls/IconSelect/IconSelect.svelte
  22. 0
      packages/builder/src/components/userInterface/PropertyPanelControls/IconSelect/icons.js
  23. 4
      packages/builder/src/components/userInterface/PropertyPanelControls/IconSelect/index.js
  24. 2
      packages/builder/src/components/userInterface/PropertyPanelControls/LayoutSelect.svelte
  25. 0
      packages/builder/src/components/userInterface/PropertyPanelControls/MultiOptionSelect.svelte
  26. 2
      packages/builder/src/components/userInterface/PropertyPanelControls/OptionSelect.svelte
  27. 2
      packages/builder/src/components/userInterface/PropertyPanelControls/PropertyControl.svelte
  28. 0
      packages/builder/src/components/userInterface/PropertyPanelControls/RoleSelect.svelte
  29. 0
      packages/builder/src/components/userInterface/PropertyPanelControls/ScreenSelect.svelte
  30. 0
      packages/builder/src/components/userInterface/PropertyPanelControls/TableSelect.svelte
  31. 0
      packages/builder/src/components/userInterface/PropertyPanelControls/TableViewFieldSelect.svelte
  32. 4
      packages/builder/src/components/userInterface/PropertyPanelControls/TableViewSelect.svelte
  33. 91
      packages/builder/src/components/userInterface/SettingsView.svelte
  34. 10
      packages/builder/src/components/userInterface/assetParsing/getRootComponent.js
  35. 46
      packages/builder/src/components/userInterface/assetParsing/searchComponents.js
  36. 13
      packages/builder/src/components/userInterface/assetParsing/splitRootComponentName.js
  37. 25
      packages/builder/src/components/userInterface/assetParsing/types.js
  38. 29
      packages/builder/src/components/userInterface/componentStyles.js
  39. 14
      packages/builder/src/components/userInterface/temporaryPanelStructure.js
  40. 27
      packages/standard-components/src/ScreenSlot.svelte

60
packages/builder/src/builderStore/store/frontend.js

@ -11,12 +11,13 @@ import {
} from "builderStore" } from "builderStore"
import { fetchComponentLibDefinitions } from "../loadComponentLibraries" import { fetchComponentLibDefinitions } from "../loadComponentLibraries"
import api from "../api" import api from "../api"
import { FrontendTypes } from "../../constants" import { FrontendTypes } from "constants"
import analytics from "analytics" import analytics from "analytics"
import { import {
findComponentType, findComponentType,
findComponentParent, findComponentParent,
findComponentPath, findComponentPath,
findComponent,
} from "../storeUtils" } from "../storeUtils"
import { uuid } from "../uuid" import { uuid } from "../uuid"
@ -44,21 +45,21 @@ export const getFrontendStore = () => {
store.actions = { store.actions = {
initialise: async pkg => { initialise: async pkg => {
const { layouts, screens, application } = pkg const { layouts, screens, application } = pkg
const components = await fetchComponentLibDefinitions(pkg.application._id) const components = await fetchComponentLibDefinitions(application._id)
store.update(state => ({ store.update(state => ({
...state, ...state,
libraries: pkg.application.componentLibraries, libraries: application.componentLibraries,
components, components,
name: pkg.application.name, name: application.name,
description: pkg.application.description, description: application.description,
appId: pkg.application._id, appId: application._id,
layouts, layouts,
screens, screens,
hasAppPackage: true, hasAppPackage: true,
appInstance: pkg.application.instance, appInstance: application.instance,
})) }))
await hostingStore.actions.fetch() await hostingStore.actions.fetch()
await backendUiStore.actions.database.select(pkg.application.instance) await backendUiStore.actions.database.select(application.instance)
}, },
routing: { routing: {
fetch: async () => { fetch: async () => {
@ -226,6 +227,25 @@ export const getFrontendStore = () => {
}, },
components: { components: {
select: component => { 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 => { store.update(state => {
state.selectedComponentId = component._id state.selectedComponentId = component._id
state.currentView = "component" state.currentView = "component"
@ -236,10 +256,10 @@ export const getFrontendStore = () => {
if (!componentName) { if (!componentName) {
return null return null
} }
const name = componentName.startsWith("@budibase") if (!componentName.startsWith("@budibase")) {
? componentName componentName = `@budibase/standard-components/${componentName}`
: `@budibase/standard-components/${componentName}` }
return get(store).components[name] return get(store).components[componentName]
}, },
createInstance: (componentName, presetProps) => { createInstance: (componentName, presetProps) => {
const definition = store.actions.components.getDefinition(componentName) const definition = store.actions.components.getDefinition(componentName)
@ -273,6 +293,19 @@ export const getFrontendStore = () => {
} }
}, },
create: (componentName, presetProps) => { 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 // Create new component
const componentInstance = store.actions.components.createInstance( const componentInstance = store.actions.components.createInstance(
componentName, componentName,
@ -284,8 +317,7 @@ export const getFrontendStore = () => {
// Find parent node to attach this component to // Find parent node to attach this component to
let parentComponent let parentComponent
const selected = get(selectedComponent)
const asset = get(currentAsset)
if (!asset) { if (!asset) {
return return
} }

60
packages/builder/src/components/userInterface/ComponentDropdownMenu.svelte

@ -32,43 +32,35 @@
} }
const moveUpComponent = () => { const moveUpComponent = () => {
store.update(state => { const asset = get(currentAsset)
const asset = get(currentAsset) const parent = findComponentParent(asset.props, component._id)
const parent = findComponentParent(asset.props, component) if (!parent) {
return
if (parent) { }
const currentIndex = parent._children.indexOf(component) const currentIndex = parent._children.indexOf(component)
if (currentIndex === 0) return state if (currentIndex === 0) {
return
const newChildren = parent._children.filter(c => c !== component) }
newChildren.splice(currentIndex - 1, 0, component) const newChildren = parent._children.filter(c => c !== component)
parent._children = newChildren newChildren.splice(currentIndex - 1, 0, component)
} parent._children = newChildren
state.selectedComponentId = component._id store.actions.preview.saveSelected()
store.actions.preview.saveSelected()
return state
})
} }
const moveDownComponent = () => { const moveDownComponent = () => {
store.update(state => { const asset = get(currentAsset)
const asset = get(currentAsset) const parent = findComponentParent(asset.props, component._id)
const parent = findComponentParent(asset.props, component) if (!parent) {
return
if (parent) { }
const currentIndex = parent._children.indexOf(component) const currentIndex = parent._children.indexOf(component)
if (currentIndex === parent._children.length - 1) return state if (currentIndex === parent._children.length - 1) {
return
const newChildren = parent._children.filter(c => c !== component) }
newChildren.splice(currentIndex + 1, 0, component) const newChildren = parent._children.filter(c => c !== component)
parent._children = newChildren newChildren.splice(currentIndex + 1, 0, component)
} parent._children = newChildren
state.selectedComponentId = component._id store.actions.preview.saveSelected()
store.actions.preview.saveSelected()
return state
})
} }
const duplicateComponent = () => { const duplicateComponent = () => {

49
packages/builder/src/components/userInterface/ComponentPropertiesPanel.svelte

@ -2,47 +2,29 @@
import { get } from "svelte/store" import { get } from "svelte/store"
import { store, selectedComponent, currentAsset } from "builderStore" import { store, selectedComponent, currentAsset } from "builderStore"
import { FrontendTypes } from "constants" import { FrontendTypes } from "constants"
import panelStructure from "./temporaryPanelStructure.js"
import CategoryTab from "./CategoryTab.svelte" import CategoryTab from "./CategoryTab.svelte"
import DesignView from "./DesignView.svelte" import DesignView from "./DesignView.svelte"
import SettingsView from "./SettingsView.svelte" import SettingsView from "./SettingsView.svelte"
import { setWith } from "lodash" import { setWith } from "lodash"
let flattenedPanel = flattenComponents(panelStructure.categories) const categories = [
let categories = [
{ value: "settings", name: "Settings" }, { value: "settings", name: "Settings" },
{ value: "design", name: "Design" }, { value: "design", name: "Design" },
] ]
let selectedCategory = categories[0] let selectedCategory = categories[0]
$: componentInstance = $: definition = store.actions.components.getDefinition(
$store.currentView !== "component" $selectedComponent._component
? { ...$currentAsset, ...$selectedComponent }
: $selectedComponent
$: componentDefinition = store.actions.components.getDefinition(
componentInstance._component
) )
$: componentPropDefinition =
flattenedPanel.find(
// use for getting controls for each component property
c => c._component === componentInstance._component
) || {}
$: panelDefinition =
componentPropDefinition.properties &&
componentPropDefinition.properties[selectedCategory.value]
const onStyleChanged = store.actions.components.updateStyle
const onCustomStyleChanged = store.actions.components.updateCustomStyle
const onResetStyles = store.actions.components.resetStyles
$: isComponentOrScreen = $: isComponentOrScreen =
$store.currentView === "component" || $store.currentView === "component" ||
$store.currentFrontEndType === FrontendTypes.SCREEN $store.currentFrontEndType === FrontendTypes.SCREEN
$: isNotScreenslot = !componentInstance._component.endsWith("screenslot") $: isNotScreenslot = !$selectedComponent._component.endsWith("screenslot")
$: showDisplayName = isComponentOrScreen && isNotScreenslot
$: displayName = const onStyleChanged = store.actions.components.updateStyle
isComponentOrScreen && componentInstance._instanceName && isNotScreenslot const onCustomStyleChanged = store.actions.components.updateCustomStyle
const onResetStyles = store.actions.components.resetStyles
function walkProps(component, action) { function walkProps(component, action) {
action(component) action(component)
@ -91,24 +73,23 @@
{categories} {categories}
{selectedCategory} /> {selectedCategory} />
{#if displayName} {#if showDisplayName}
<div class="instance-name">{componentInstance._instanceName}</div> <div class="instance-name">{$selectedComponent._instanceName}</div>
{/if} {/if}
<div class="component-props-container"> <div class="component-props-container">
{#if selectedCategory.value === 'design'} {#if selectedCategory.value === 'design'}
<DesignView <DesignView
{panelDefinition} componentInstance={$selectedComponent}
{componentInstance} componentDefinition={definition}
{onStyleChanged} {onStyleChanged}
{onCustomStyleChanged} {onCustomStyleChanged}
{onResetStyles} /> {onResetStyles} />
{:else if selectedCategory.value === 'settings'} {:else if selectedCategory.value === 'settings'}
<SettingsView <SettingsView
{componentInstance} componentInstance={$selectedComponent}
{componentDefinition} componentDefinition={definition}
{panelDefinition} {showDisplayName}
displayNameField={displayName}
onChange={store.actions.components.updateProp} onChange={store.actions.components.updateProp}
onScreenPropChange={setAssetProps} onScreenPropChange={setAssetProps}
assetInstance={$store.currentView !== 'component' && $currentAsset} /> assetInstance={$store.currentView !== 'component' && $currentAsset} />

16
packages/builder/src/components/userInterface/DesignView.svelte

@ -1,16 +1,16 @@
<script> <script>
import { TextArea, DetailSummary, Button } from "@budibase/bbui" import { TextArea, DetailSummary, Button } from "@budibase/bbui"
import PropertyGroup from "./PropertyGroup.svelte" import PropertyGroup from "./PropertyGroup.svelte"
import FlatButtonGroup from "./FlatButtonGroup.svelte" import FlatButtonGroup from "./PropertyPanelControls/FlatButtonGroup"
import { allStyles } from "./componentStyles"
export let panelDefinition = {} export let componentDefinition = {}
export let componentInstance = {} export let componentInstance = {}
export let onStyleChanged = () => {} export let onStyleChanged = () => {}
export let onCustomStyleChanged = () => {} export let onCustomStyleChanged = () => {}
export let onResetStyles = () => {} export let onResetStyles = () => {}
let selectedCategory = "normal" let selectedCategory = "normal"
let propGroup = null
let currentGroup let currentGroup
function onChange(category) { function onChange(category) {
@ -23,7 +23,7 @@
{ value: "active", text: "Active" }, { value: "active", text: "Active" },
] ]
$: propertyGroupNames = panelDefinition ? Object.keys(panelDefinition) : [] $: groups = componentDefinition?.styleable ? Object.keys(allStyles) : []
</script> </script>
<div class="design-view-container"> <div class="design-view-container">
@ -32,12 +32,12 @@
</div> </div>
<div class="positioned-wrapper"> <div class="positioned-wrapper">
<div bind:this={propGroup} class="design-view-property-groups"> <div class="design-view-property-groups">
{#if propertyGroupNames.length > 0} {#if groups.length > 0}
{#each propertyGroupNames as groupName} {#each groups as groupName}
<PropertyGroup <PropertyGroup
name={groupName} name={groupName}
properties={panelDefinition[groupName]} properties={allStyles[groupName]}
styleCategory={selectedCategory} styleCategory={selectedCategory}
{onStyleChanged} {onStyleChanged}
{componentInstance} {componentInstance}

3
packages/builder/src/components/userInterface/IconSelect/index.js

@ -1,3 +0,0 @@
import "@fortawesome/fontawesome-free/js/all.js"
export { default as IconSelect } from "./IconSelect.svelte"

2
packages/builder/src/components/userInterface/MultiTableViewFieldSelect.svelte

@ -1,5 +1,5 @@
<script> <script>
import TableViewFieldSelect from "./TableViewFieldSelect.svelte" import TableViewFieldSelect from "./PropertyPanelControls/TableViewFieldSelect.svelte"
</script> </script>
<TableViewFieldSelect {...$$props} multiselect /> <TableViewFieldSelect {...$$props} multiselect />

5
packages/builder/src/components/userInterface/PropertyGroup.svelte

@ -1,6 +1,5 @@
<script> <script>
import { excludeProps } from "./propertyCategories.js" import PropertyControl from "./PropertyPanelControls/PropertyControl.svelte"
import PropertyControl from "./PropertyControl.svelte"
import { DetailSummary } from "@budibase/bbui" import { DetailSummary } from "@budibase/bbui"
export let name = "" export let name = ""
@ -36,7 +35,7 @@
key={prop.key} key={prop.key}
value={style[prop.key]} value={style[prop.key]}
onChange={(key, value) => onStyleChanged(styleCategory, key, value)} onChange={(key, value) => onStyleChanged(styleCategory, key, value)}
props={{ ...excludeProps(prop, ['control', 'label']) }} /> props={{ options: prop.options, placeholder: prop.placeholder }} />
{/each} {/each}
</div> </div>
{/if} {/if}

0
packages/builder/src/components/userInterface/EventsEditor/EventEditorModal.svelte → packages/builder/src/components/userInterface/PropertyPanelControls/EventsEditor/EventEditorModal.svelte

0
packages/builder/src/components/userInterface/EventsEditor/EventPropertyControl.svelte → packages/builder/src/components/userInterface/PropertyPanelControls/EventsEditor/EventPropertyControl.svelte

0
packages/builder/src/components/userInterface/EventsEditor/actions/CreateRow.svelte → packages/builder/src/components/userInterface/PropertyPanelControls/EventsEditor/actions/CreateRow.svelte

0
packages/builder/src/components/userInterface/EventsEditor/actions/DeleteRow.svelte → packages/builder/src/components/userInterface/PropertyPanelControls/EventsEditor/actions/DeleteRow.svelte

0
packages/builder/src/components/userInterface/EventsEditor/actions/NavigateTo.svelte → packages/builder/src/components/userInterface/PropertyPanelControls/EventsEditor/actions/NavigateTo.svelte

0
packages/builder/src/components/userInterface/EventsEditor/actions/SaveFields.svelte → packages/builder/src/components/userInterface/PropertyPanelControls/EventsEditor/actions/SaveFields.svelte

0
packages/builder/src/components/userInterface/EventsEditor/actions/SaveRow.svelte → packages/builder/src/components/userInterface/PropertyPanelControls/EventsEditor/actions/SaveRow.svelte

0
packages/builder/src/components/userInterface/EventsEditor/actions/UpdateRow.svelte → packages/builder/src/components/userInterface/PropertyPanelControls/EventsEditor/actions/UpdateRow.svelte

0
packages/builder/src/components/userInterface/EventsEditor/actions/index.js → packages/builder/src/components/userInterface/PropertyPanelControls/EventsEditor/actions/index.js

2
packages/builder/src/components/userInterface/PropertyPanelControls/EventsEditor/index.js

@ -0,0 +1,2 @@
import EventsEditor from "./EventPropertyControl.svelte"
export default EventsEditor

0
packages/builder/src/components/userInterface/FlatButton.svelte → packages/builder/src/components/userInterface/PropertyPanelControls/FlatButtonGroup/FlatButton.svelte

0
packages/builder/src/components/userInterface/FlatButtonGroup.svelte → packages/builder/src/components/userInterface/PropertyPanelControls/FlatButtonGroup/FlatButtonGroup.svelte

2
packages/builder/src/components/userInterface/PropertyPanelControls/FlatButtonGroup/index.js

@ -0,0 +1,2 @@
import FlatButtonGroup from "./FlatButtonGroup.svelte"
export default FlatButtonGroup

0
packages/builder/src/components/userInterface/IconSelect/IconSelect.svelte → packages/builder/src/components/userInterface/PropertyPanelControls/IconSelect/IconSelect.svelte

0
packages/builder/src/components/userInterface/IconSelect/icons.js → packages/builder/src/components/userInterface/PropertyPanelControls/IconSelect/icons.js

4
packages/builder/src/components/userInterface/PropertyPanelControls/IconSelect/index.js

@ -0,0 +1,4 @@
import "@fortawesome/fontawesome-free/js/all.js"
import IconSelect from "./IconSelect.svelte"
export default IconSelect

2
packages/builder/src/components/userInterface/LayoutSelect.svelte → packages/builder/src/components/userInterface/PropertyPanelControls/LayoutSelect.svelte

@ -1,5 +1,5 @@
<script> <script>
import { store, currentAsset } from "builderStore" import { store } from "builderStore"
import { Select } from "@budibase/bbui" import { Select } from "@budibase/bbui"
export let value export let value

0
packages/builder/src/components/userInterface/MultiOptionSelect.svelte → packages/builder/src/components/userInterface/PropertyPanelControls/MultiOptionSelect.svelte

2
packages/builder/src/components/userInterface/OptionSelect.svelte → packages/builder/src/components/userInterface/PropertyPanelControls/OptionSelect.svelte

@ -1,7 +1,7 @@
<script> <script>
import { onMount } from "svelte" import { onMount } from "svelte"
import Portal from "svelte-portal" import Portal from "svelte-portal"
import { buildStyle } from "../../helpers.js" import { buildStyle } from "../../../helpers.js"
export let options = [] export let options = []
export let value = "" export let value = ""

2
packages/builder/src/components/userInterface/PropertyControl.svelte → packages/builder/src/components/userInterface/PropertyPanelControls/PropertyControl.svelte

@ -1,6 +1,6 @@
<script> <script>
import { Icon } from "@budibase/bbui" import { Icon } from "@budibase/bbui"
import Input from "./PropertyPanelControls/Input.svelte" import Input from "./Input.svelte"
import { store, backendUiStore, currentAsset } from "builderStore" import { store, backendUiStore, currentAsset } from "builderStore"
import fetchBindableProperties from "builderStore/fetchBindableProperties" import fetchBindableProperties from "builderStore/fetchBindableProperties"
import { import {

0
packages/builder/src/components/userInterface/RoleSelect.svelte → packages/builder/src/components/userInterface/PropertyPanelControls/RoleSelect.svelte

0
packages/builder/src/components/userInterface/ScreenSelect.svelte → packages/builder/src/components/userInterface/PropertyPanelControls/ScreenSelect.svelte

0
packages/builder/src/components/userInterface/TableSelect.svelte → packages/builder/src/components/userInterface/PropertyPanelControls/TableSelect.svelte

0
packages/builder/src/components/userInterface/TableViewFieldSelect.svelte → packages/builder/src/components/userInterface/PropertyPanelControls/TableViewFieldSelect.svelte

4
packages/builder/src/components/userInterface/TableViewSelect.svelte → packages/builder/src/components/userInterface/PropertyPanelControls/TableViewSelect.svelte

@ -2,7 +2,7 @@
import { Button, Icon, DropdownMenu, Spacer, Heading } from "@budibase/bbui" import { Button, Icon, DropdownMenu, Spacer, Heading } from "@budibase/bbui"
import { createEventDispatcher } from "svelte" import { createEventDispatcher } from "svelte"
import { store, backendUiStore, currentAsset } from "builderStore" import { store, backendUiStore, currentAsset } from "builderStore"
import fetchBindableProperties from "../../builderStore/fetchBindableProperties" import fetchBindableProperties from "../../../builderStore/fetchBindableProperties"
const dispatch = createEventDispatcher() const dispatch = createEventDispatcher()
let anchorRight, dropdownRight let anchorRight, dropdownRight
@ -56,7 +56,7 @@
class="dropdownbutton" class="dropdownbutton"
bind:this={anchorRight} bind:this={anchorRight}
on:click={dropdownRight.show}> on:click={dropdownRight.show}>
<span>{value.label ? value.label : 'Table / View'}</span> <span>{value && value.label ? value.label : 'Table / View'}</span>
<Icon name="arrowdown" /> <Icon name="arrowdown" />
</div> </div>
<DropdownMenu bind:this={dropdownRight} anchor={anchorRight}> <DropdownMenu bind:this={dropdownRight} anchor={anchorRight}>

91
packages/builder/src/components/userInterface/SettingsView.svelte

@ -1,32 +1,57 @@
<script> <script>
import { get } from "lodash" import { get } from "lodash"
import { isEmpty } from "lodash/fp" import { isEmpty } from "lodash/fp"
import PropertyControl from "./PropertyControl.svelte" import PropertyControl from "./PropertyPanelControls/PropertyControl.svelte"
import LayoutSelect from "./LayoutSelect.svelte"
import RoleSelect from "./RoleSelect.svelte"
import Input from "./PropertyPanelControls/Input.svelte" import Input from "./PropertyPanelControls/Input.svelte"
import { excludeProps } from "./propertyCategories.js"
export let panelDefinition = [] import LayoutSelect from "./PropertyPanelControls/LayoutSelect.svelte"
import RoleSelect from "./PropertyPanelControls/RoleSelect.svelte"
import OptionSelect from "./PropertyPanelControls/OptionSelect.svelte"
import MultiTableViewFieldSelect from "./MultiTableViewFieldSelect.svelte"
import Checkbox from "../common/Checkbox.svelte"
import TableSelect from "components/userInterface/PropertyPanelControls/TableSelect.svelte"
import TableViewSelect from "components/userInterface/PropertyPanelControls/TableViewSelect.svelte"
import TableViewFieldSelect from "components/userInterface/PropertyPanelControls/TableViewFieldSelect.svelte"
import EventsEditor from "components/userInterface/PropertyPanelControls/EventsEditor"
import ScreenSelect from "components/userInterface/PropertyPanelControls/ScreenSelect.svelte"
import DetailScreenSelect from "components/userInterface/DetailScreenSelect.svelte"
import IconSelect from "components/userInterface/PropertyPanelControls/IconSelect"
import Colorpicker from "@budibase/colorpicker"
export let componentDefinition = {} export let componentDefinition = {}
export let componentInstance = {} export let componentInstance = {}
export let assetInstance
export let onChange = () => {} export let onChange = () => {}
export let onScreenPropChange = () => {} export let onScreenPropChange = () => {}
export let displayNameField = false export let showDisplayName = false
export let assetInstance
let assetProps = [ const assetProps = [
"title", "title",
"description", "description",
"routing.route", "routing.route",
"layoutId", "layoutId",
"routing.roleId", "routing.roleId",
] ]
let duplicateName = false
$: settings = componentDefinition?.settings ?? []
const controlMap = {
text: Input,
select: OptionSelect,
datasource: TableViewSelect,
detailURL: DetailScreenSelect,
boolean: Checkbox,
number: Input,
}
const getControl = type => {
return controlMap[type]
}
const propExistsOnComponentDef = prop => const propExistsOnComponentDef = prop =>
assetProps.includes(prop) || prop in (componentDefinition?.props ?? {}) assetProps.includes(prop) || prop in (componentDefinition?.props ?? {})
const layoutDefinition = []
const screenDefinition = [ const screenDefinition = [
{ key: "description", label: "Description", control: Input }, { key: "description", label: "Description", control: Input },
{ key: "routing.route", label: "Route", control: Input }, { key: "routing.route", label: "Route", control: Input },
@ -34,13 +59,15 @@
{ key: "layoutId", label: "Layout", control: LayoutSelect }, { key: "layoutId", label: "Layout", control: LayoutSelect },
] ]
const layoutDefinition = [] const canRenderControl = setting => {
const control = getControl(setting?.type)
const canRenderControl = (key, dependsOn) => { if (!control) {
return ( return false
propExistsOnComponentDef(key) && }
(!dependsOn || !isEmpty(componentInstance[dependsOn])) if (setting.dependsOn && isEmpty(componentInstance[setting.dependsOn])) {
) return false
}
return true
} }
$: isLayout = assetInstance && assetInstance.favicon $: isLayout = assetInstance && assetInstance.favicon
@ -60,34 +87,30 @@
label={def.label} label={def.label}
key={def.key} key={def.key}
value={get(assetInstance, def.key)} value={get(assetInstance, def.key)}
onChange={onScreenPropChange} onChange={onScreenPropChange} />
props={{ ...excludeProps(def, ['control', 'label']) }} />
{/each} {/each}
{/if} {/if}
{#if displayNameField} {#if showDisplayName}
<PropertyControl <PropertyControl
control={Input} control={Input}
label="Name" label="Name"
key="_instanceName" key="_instanceName"
value={componentInstance._instanceName} value={componentInstance._instanceName}
onChange={onInstanceNameChange} /> onChange={onInstanceNameChange} />
{#if duplicateName}
<span class="duplicate-name">Name must be unique</span>
{/if}
{/if} {/if}
{#if !isLayout && panelDefinition && panelDefinition.length > 0} {#if settings && settings.length > 0}
{#each panelDefinition as definition} {#each settings as setting}
{#if canRenderControl(definition.key, definition.dependsOn)} {#if canRenderControl(setting)}
<PropertyControl <PropertyControl
control={definition.control} control={getControl(setting.type)}
label={definition.label} label={setting.label}
key={definition.key} key={setting.key}
value={componentInstance[definition.key] ?? componentInstance[definition.key]?.defaultValue} value={componentInstance[setting.key] ?? componentInstance[setting.key]?.defaultValue}
{componentInstance} {componentInstance}
{onChange} {onChange}
props={{ ...excludeProps(definition, ['control', 'label']) }} /> props={{ options: setting.options }} />
{/if} {/if}
{/each} {/each}
{:else} {:else}
@ -105,17 +128,9 @@
height: 100%; height: 100%;
gap: var(--spacing-s); gap: var(--spacing-s);
} }
.empty { .empty {
font-size: var(--font-size-xs); font-size: var(--font-size-xs);
margin-top: var(--spacing-m); margin-top: var(--spacing-m);
color: var(--grey-5); color: var(--grey-5);
} }
.duplicate-name {
color: var(--red);
font-size: var(--font-size-xs);
position: relative;
top: -10px;
}
</style> </style>

10
packages/builder/src/components/userInterface/assetParsing/getRootComponent.js

@ -1,10 +0,0 @@
import { isRootComponent } from "./searchComponents"
import { find } from "lodash/fp"
export const getRootComponent = (componentName, components) => {
const component = find(c => c.name === componentName)(components)
if (isRootComponent(component)) return component
return getRootComponent(component.props._component, components)
}

46
packages/builder/src/components/userInterface/assetParsing/searchComponents.js

@ -1,46 +0,0 @@
import { isUndefined, filter, some, includes } from "lodash/fp"
import { pipe } from "../../../helpers"
const normalString = s => (s || "").trim().toLowerCase()
export const isRootComponent = c =>
isComponent(c) && isUndefined(c.props._component)
export const isComponent = c => {
const hasProp = n => !isUndefined(c[n])
return hasProp("name") && hasProp("props")
}
export const searchAllComponents = (components, phrase) => {
const hasPhrase = (...vals) =>
pipe(vals, [some(v => includes(normalString(phrase))(normalString(v)))])
const componentMatches = c => {
if (hasPhrase(c._instanceName, ...(c.tags || []))) return true
if (isRootComponent(c)) return false
const parent = getExactComponent(components, c.props._component)
return componentMatches(parent)
}
return filter(componentMatches)(components)
}
export const getExactComponent = (components, name, isScreen = false) => {
return components.find(comp =>
isScreen ? comp.props._instanceName === name : comp._instanceName === name
)
}
export const getAncestorProps = (components, name, found = []) => {
const thisComponent = getExactComponent(components, name)
if (isRootComponent(thisComponent)) return [thisComponent.props, ...found]
return getAncestorProps(components, thisComponent.props._component, [
{ ...thisComponent.props },
...found,
])
}

13
packages/builder/src/components/userInterface/assetParsing/splitRootComponentName.js

@ -1,13 +0,0 @@
import { split, last } from "lodash/fp"
import { pipe } from "../../../helpers"
export const splitName = fullname => {
const componentName = pipe(fullname, [split("/"), last])
const libName = fullname.substring(
0,
fullname.length - componentName.length - 1
)
return { libName, componentName }
}

25
packages/builder/src/components/userInterface/assetParsing/types.js

@ -1,25 +0,0 @@
export const TYPE_MAP = {
string: {
default: "",
},
bool: {
default: false,
},
number: {
default: 0,
},
options: {
default: [],
},
event: {
default: [],
},
state: {
default: {
"##bbstate": "",
},
},
tables: {
default: {},
},
}

29
packages/builder/src/components/userInterface/propertyCategories.js → packages/builder/src/components/userInterface/componentStyles.js

@ -1,6 +1,6 @@
import Input from "./PropertyPanelControls/Input.svelte" import Input from "./PropertyPanelControls/Input.svelte"
import OptionSelect from "./OptionSelect.svelte" import OptionSelect from "./PropertyPanelControls/OptionSelect.svelte"
import FlatButtonGroup from "./FlatButtonGroup.svelte" import FlatButtonGroup from "./PropertyPanelControls/FlatButtonGroup"
import Colorpicker from "@budibase/colorpicker" import Colorpicker from "@budibase/colorpicker"
export const layout = [ export const layout = [
@ -299,42 +299,36 @@ export const size = [
key: "width", key: "width",
control: Input, control: Input,
placeholder: "px", placeholder: "px",
textAlign: "center",
}, },
{ {
label: "Height", label: "Height",
key: "height", key: "height",
control: Input, control: Input,
placeholder: "px", placeholder: "px",
textAlign: "center",
}, },
{ {
label: "Min Width", label: "Min Width",
key: "min-width", key: "min-width",
control: Input, control: Input,
placeholder: "px", placeholder: "px",
textAlign: "center",
}, },
{ {
label: "Max Width", label: "Max Width",
key: "max-width", key: "max-width",
control: Input, control: Input,
placeholder: "px", placeholder: "px",
textAlign: "center",
}, },
{ {
label: "Min Height", label: "Min Height",
key: "min-height", key: "min-height",
control: Input, control: Input,
placeholder: "px", placeholder: "px",
textAlign: "center",
}, },
{ {
label: "Max Height", label: "Max Height",
key: "max-height", key: "max-height",
control: Input, control: Input,
placeholder: "px", placeholder: "px",
textAlign: "center",
}, },
] ]
@ -357,28 +351,24 @@ export const position = [
key: "top", key: "top",
control: Input, control: Input,
placeholder: "px", placeholder: "px",
textAlign: "center",
}, },
{ {
label: "Right", label: "Right",
key: "right", key: "right",
control: Input, control: Input,
placeholder: "px", placeholder: "px",
textAlign: "center",
}, },
{ {
label: "Bottom", label: "Bottom",
key: "bottom", key: "bottom",
control: Input, control: Input,
placeholder: "px", placeholder: "px",
textAlign: "center",
}, },
{ {
label: "Left", label: "Left",
key: "left", key: "left",
control: Input, control: Input,
placeholder: "px", placeholder: "px",
textAlign: "center",
}, },
{ {
label: "Z-index", label: "Z-index",
@ -458,7 +448,6 @@ export const typography = [
{ label: "60px", value: "60px" }, { label: "60px", value: "60px" },
{ label: "72px", value: "72px" }, { label: "72px", value: "72px" },
], ],
textAlign: "center",
}, },
{ {
label: "Line H", label: "Line H",
@ -672,7 +661,6 @@ export const effects = [
label: "Opacity", label: "Opacity",
key: "opacity", key: "opacity",
control: OptionSelect, control: OptionSelect,
textAlign: "center",
options: [ options: [
{ label: "Choose option", value: "" }, { label: "Choose option", value: "" },
{ label: "0", value: "0" }, { label: "0", value: "0" },
@ -758,7 +746,6 @@ export const transitions = [
label: "Duration", label: "Duration",
key: "transition-duration", key: "transition-duration",
control: OptionSelect, control: OptionSelect,
textAlign: "center",
placeholder: "sec", placeholder: "sec",
options: [ options: [
{ label: "Choose option", value: "" }, { label: "Choose option", value: "" },
@ -785,7 +772,7 @@ export const transitions = [
}, },
] ]
export const all = { export const allStyles = {
layout, layout,
margin, margin,
padding, padding,
@ -797,13 +784,3 @@ export const all = {
effects, effects,
transitions, transitions,
} }
export function excludeProps(props, propsToExclude) {
const modifiedProps = {}
for (const prop in props) {
if (!propsToExclude.includes(prop)) {
modifiedProps[prop] = props[prop]
}
}
return modifiedProps
}

14
packages/builder/src/components/userInterface/temporaryPanelStructure.js

@ -1,14 +1,14 @@
import Input from "./PropertyPanelControls/Input.svelte" import Input from "./PropertyPanelControls/Input.svelte"
import OptionSelect from "./OptionSelect.svelte" import OptionSelect from "./PropertyPanelControls/OptionSelect.svelte"
import MultiTableViewFieldSelect from "./MultiTableViewFieldSelect.svelte" import MultiTableViewFieldSelect from "./MultiTableViewFieldSelect.svelte"
import Checkbox from "../common/Checkbox.svelte" import Checkbox from "../common/Checkbox.svelte"
import TableSelect from "components/userInterface/TableSelect.svelte" import TableSelect from "components/userInterface/PropertyPanelControls/TableSelect.svelte"
import TableViewSelect from "components/userInterface/TableViewSelect.svelte" import TableViewSelect from "components/userInterface/PropertyPanelControls/TableViewSelect.svelte"
import TableViewFieldSelect from "components/userInterface/TableViewFieldSelect.svelte" import TableViewFieldSelect from "components/userInterface/PropertyPanelControls/TableViewFieldSelect.svelte"
import Event from "components/userInterface/EventsEditor/EventPropertyControl.svelte" import Event from "components/userInterface/PropertyPanelControls/EventsEditor/EventPropertyControl.svelte"
import ScreenSelect from "components/userInterface/ScreenSelect.svelte" import ScreenSelect from "components/userInterface/PropertyPanelControls/ScreenSelect.svelte"
import DetailScreenSelect from "components/userInterface/DetailScreenSelect.svelte" import DetailScreenSelect from "components/userInterface/DetailScreenSelect.svelte"
import { IconSelect } from "components/userInterface/IconSelect" import { IconSelect } from "components/userInterface/PropertyPanelControls/IconSelect"
import Colorpicker from "@budibase/colorpicker" import Colorpicker from "@budibase/colorpicker"
import { all } from "./propertyCategories.js" import { all } from "./propertyCategories.js"

27
packages/standard-components/src/ScreenSlot.svelte

@ -1,9 +1,13 @@
<script> <script>
// This component is overridden when running in a real app. // This component is overridden when running in a real app.
// This simply serves as a placeholder component for the real screen router. // This simply serves as a placeholder component for the real screen router
import { getContext } from "svelte"
const { styleable } = getContext("sdk")
const component = getContext("component")
</script> </script>
<div> <div use:styleable={$component.styles}>
<h1>Screen Slot</h1> <h1>Screen Slot</h1>
<span> <span>
The screens that you create will be displayed inside this box. The screens that you create will be displayed inside this box.
@ -14,16 +18,15 @@
<style> <style>
div { div {
display: flex; display: flex !important;
flex-direction: column; flex-direction: column !important;
align-items: center; align-items: center !important;
justify-content: center; justify-content: center !important;
padding: 20px; padding: 20px !important;
text-align: center; text-align: center !important;
border-style: dashed !important; border-style: dashed !important;
border-width: 1px; border-width: 1px !important;
color: #000000; color: #000000 !important;
background-color: rgba(0, 0, 0, 0.05); background-color: rgba(0, 0, 0, 0.05) !important;
flex: 1 1 auto;
} }
</style> </style>

Loading…
Cancel
Save