Budibase is an open-source low-code platform for creating internal apps in minutes. Supports PostgreSQL, MySQL, MSSQL, MongoDB, Rest API, Docker, K8s 🚀
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

171 lines
4.8 KiB

<script>
import { isEmpty } from "lodash/fp"
import { Input, DetailSummary, notifications } from "@budibase/bbui"
import { store } from "builderStore"
import PropertyControl from "./PropertyControls/PropertyControl.svelte"
import ResetFieldsButton from "./PropertyControls/ResetFieldsButton.svelte"
import { getComponentForSettingType } from "./PropertyControls/componentSettings"
import { Utils } from "@budibase/frontend-core"
import { onMount } from "svelte"
export let componentDefinition
export let componentInstance
export let bindings
export let componentBindings
$: sections = getSections(componentDefinition)
const getSections = definition => {
const settings = definition?.settings ?? []
const generalSettings = settings.filter(setting => !setting.section)
const customSections = settings.filter(setting => setting.section)
return [
{
name: componentDefinition?.name || "General",
info: componentDefinition?.info,
settings: generalSettings,
},
...(customSections || []),
]
}
const updateProp = Utils.sequential(async (key, value) => {
try {
await store.actions.components.updateProp(key, value)
} catch (error) {
notifications.error("Error updating component prop")
}
})
const canRenderControl = setting => {
const control = getComponentForSettingType(setting?.type)
if (!control) {
return false
}
// Parse dependant settings
if (setting.dependsOn) {
let dependantSetting = setting.dependsOn
let dependantValue = null
if (typeof setting.dependsOn === "object") {
dependantSetting = setting.dependsOn.setting
dependantValue = setting.dependsOn.value
}
if (!dependantSetting) {
return false
}
// If no specific value is depended upon, check if a value exists at all
// for the dependent setting
if (dependantValue == null) {
const currentValue = componentInstance[dependantSetting]
if (currentValue === false) {
return false
}
if (currentValue === true) {
return true
}
return !isEmpty(currentValue)
}
// Otherwise check the value matches
return componentInstance[dependantSetting] === dependantValue
}
return true
}
const isFocused = setting => {
if (!$store.builderFocus) {
return false
}
return (
setting.required === true && $store.builderFocus[0].key === setting.key
)
}
onMount(() => {
const emptyFields = (definition, options) => {
if (!options) {
return []
}
return definition?.settings
? definition.settings.filter(setting => {
return (
setting.required &&
(!options[setting.key] || options[setting.key] == "")
)
})
: []
}
let target = emptyFields(componentDefinition, componentInstance)[0]
if (target) {
store.update(state => ({
...state,
builderFocus: [
{
location: "component_settings",
key: target.key,
target: componentInstance._id,
},
],
}))
}
})
</script>
{#each sections as section, idx (section.name)}
<DetailSummary name={section.name} collapsible={false}>
{#if idx === 0 && !componentInstance._component.endsWith("/layout")}
<PropertyControl
control={Input}
label="Name"
key="_instanceName"
value={componentInstance._instanceName}
onChange={val => updateProp("_instanceName", val)}
/>
{/if}
{#each section.settings as setting (setting.key)}
{#if canRenderControl(setting)}
<PropertyControl
type={setting.type}
control={getComponentForSettingType(setting.type)}
label={setting.label}
key={setting.key}
value={componentInstance[setting.key] ??
componentInstance[setting.key]?.defaultValue}
nested={setting.nested}
onChange={val => updateProp(setting.key, val)}
props={{
options: setting.options || [],
placeholder: setting.placeholder || null,
min: setting.min || null,
max: setting.max || null,
}}
{bindings}
{componentBindings}
{componentInstance}
{componentDefinition}
autofocus={isFocused(setting)}
/>
{/if}
{/each}
{#if idx === 0 && componentDefinition?.component?.endsWith("/fieldgroup")}
<ResetFieldsButton {componentInstance} />
{/if}
{#if section?.info}
<div class="text">
{@html section.info}
</div>
{/if}
</DetailSummary>
{/each}
<style>
.text {
font-size: var(--spectrum-global-dimension-font-size-75);
color: var(--grey-6);
}
</style>