2023-08-03 10:29:12 +02:00
< script >
import { Icon , Popover , Layout } from "@budibase/bbui"
import { store } from "builderStore"
import { cloneDeep } from "lodash/fp"
2023-10-27 16:09:17 +02:00
import { createEventDispatcher } from "svelte"
2023-10-13 15:53:39 +02:00
import ComponentSettingsSection from "../../../../pages/builder/app/[application]/design/[screenId]/[componentId]/_components/Component/ComponentSettingsSection.svelte"
2023-08-25 12:19:28 +02:00
import { getContext } from "svelte"
2023-08-03 10:29:12 +02:00
export let anchor
2023-10-13 15:53:39 +02:00
export let componentInstance
2023-08-03 10:29:12 +02:00
export let componentBindings
export let bindings
2023-10-13 15:53:39 +02:00
export let parseSettings
2023-11-08 17:59:00 +01:00
export let disabled
2023-08-03 10:29:12 +02:00
2023-08-25 12:19:28 +02:00
const draggable = getContext("draggable")
2023-08-24 15:39:53 +02:00
const dispatch = createEventDispatcher()
2023-08-03 10:29:12 +02:00
2023-08-24 15:39:53 +02:00
let popover
let drawers = []
2023-08-25 12:19:28 +02:00
let open = false
2023-10-13 15:53:39 +02:00
// Auto hide the component when another item is selected
2023-10-27 16:09:17 +02:00
$: if (open && $draggable.selected !== componentInstance._id) {
2023-08-25 12:19:28 +02:00
popover.hide()
}
2023-08-03 10:29:12 +02:00
2023-10-13 15:53:39 +02:00
// Open automatically if the component is marked as selected
$: if (!open && $draggable.selected === componentInstance._id && popover) {
popover.show()
open = true
2023-08-03 10:29:12 +02:00
}
2023-10-13 15:53:39 +02:00
2023-08-24 15:39:53 +02:00
$: componentDef = store.actions.components.getDefinition(
2023-10-13 15:53:39 +02:00
componentInstance._component
2023-08-24 15:39:53 +02:00
)
$: parsedComponentDef = processComponentDefinitionSettings(componentDef)
2023-08-03 10:29:12 +02:00
const processComponentDefinitionSettings = componentDef => {
2023-08-24 15:39:53 +02:00
if (!componentDef) {
return {}
}
2023-08-03 10:29:12 +02:00
const clone = cloneDeep(componentDef)
2023-10-13 15:53:39 +02:00
if (typeof parseSettings === "function") {
clone.settings = parseSettings(clone.settings)
}
2023-08-03 10:29:12 +02:00
return clone
}
const updateSetting = async (setting, value) => {
2023-10-13 15:53:39 +02:00
const nestedComponentInstance = cloneDeep(componentInstance)
2023-08-03 10:29:12 +02:00
2023-08-24 15:39:53 +02:00
const patchFn = store.actions.components.updateComponentSetting(
setting.key,
value
2023-08-03 10:29:12 +02:00
)
2023-08-24 15:39:53 +02:00
patchFn(nestedComponentInstance)
2023-08-03 10:29:12 +02:00
2023-10-13 15:53:39 +02:00
dispatch("change", nestedComponentInstance)
2023-08-03 10:29:12 +02:00
}
2023-10-11 11:09:14 +02:00
const customPositionHandler = (anchorBounds, eleBounds, cfg) => {
let { left , top } = cfg
let percentageOffset = 30
// left-outside
left = anchorBounds.left - eleBounds.width - 18
// shift up from the anchor, if space allows
let offsetPos = Math.floor(eleBounds.height / 100) * percentageOffset
let defaultTop = anchorBounds.top - offsetPos
if (window.innerHeight - defaultTop < eleBounds.height ) {
top = window.innerHeight - eleBounds.height - 5
} else {
top = anchorBounds.top - offsetPos
2023-08-24 15:39:53 +02:00
}
2023-08-03 10:29:12 +02:00
2023-10-11 11:09:14 +02:00
return { ... cfg , left , top }
2023-08-03 10:29:12 +02:00
}
< / script >
< Icon
name="Settings"
hoverable
size="S"
on:click={() => {
2023-08-25 12:19:28 +02:00
if (!open) {
popover.show()
open = true
}
2023-08-03 10:29:12 +02:00
}}
/>
2023-08-24 15:39:53 +02:00
< Popover
bind:this={ popover }
on:open={() => {
drawers = []
2023-10-13 15:53:39 +02:00
$draggable.actions.select(componentInstance._id)
2023-08-25 12:19:28 +02:00
}}
on:close={() => {
open = false
2023-10-27 16:09:17 +02:00
if ($draggable.selected === componentInstance._id) {
2023-08-25 12:19:28 +02:00
$draggable.actions.select()
}
2023-08-24 15:39:53 +02:00
}}
{ anchor }
align="left-outside"
2023-10-27 16:09:17 +02:00
showPopover={ drawers . length === 0 }
2023-08-24 15:39:53 +02:00
clickOutsideOverride={ drawers . length > 0 }
2023-08-25 12:19:28 +02:00
maxHeight={ 600 }
2023-10-11 11:09:14 +02:00
handlePostionUpdate={ customPositionHandler }
2023-08-24 15:39:53 +02:00
>
< span class = "popover-wrap" >
< Layout noPadding noGap >
2023-10-13 15:53:39 +02:00
< slot name = "header" / >
2023-08-24 15:39:53 +02:00
< ComponentSettingsSection
2023-10-27 12:42:01 +02:00
includeHidden
2023-10-13 15:53:39 +02:00
{ componentInstance }
2023-08-24 15:39:53 +02:00
componentDefinition={ parsedComponentDef }
isScreen={ false }
onUpdateSetting={ updateSetting }
showSectionTitle={ false }
showInstanceName={ false }
{ bindings }
2023-08-03 10:29:12 +02:00
{ componentBindings }
2023-08-24 15:39:53 +02:00
on:drawerShow={ e => {
drawers = [...drawers, e.detail]
}}
2023-08-25 16:14:49 +02:00
on:drawerHide={() => {
2023-08-24 15:39:53 +02:00
drawers = drawers.slice(0, -1)
}}
/>
< / Layout >
< / span >
2023-08-03 10:29:12 +02:00
< / Popover >
2023-08-24 15:39:53 +02:00
< style >
.popover-wrap {
2023-08-29 18:11:25 +02:00
background-color: var(--spectrum-alias-background-color-primary);
2023-08-24 15:39:53 +02:00
}
< / style >