Update client library so that component placeholders are always shown when required settings are missing
This commit is contained in:
parent
417bede430
commit
f6b55efbec
|
@ -23,6 +23,7 @@
|
||||||
import Manifest from "manifest.json"
|
import Manifest from "manifest.json"
|
||||||
import { getActiveConditions, reduceConditionActions } from "utils/conditions"
|
import { getActiveConditions, reduceConditionActions } from "utils/conditions"
|
||||||
import Placeholder from "components/app/Placeholder.svelte"
|
import Placeholder from "components/app/Placeholder.svelte"
|
||||||
|
import ComponentPlaceholder from "components/app/ComponentPlaceholder.svelte"
|
||||||
|
|
||||||
export let instance = {}
|
export let instance = {}
|
||||||
export let isLayout = false
|
export let isLayout = false
|
||||||
|
@ -81,6 +82,7 @@
|
||||||
let definition
|
let definition
|
||||||
let settingsDefinition
|
let settingsDefinition
|
||||||
let settingsDefinitionMap
|
let settingsDefinitionMap
|
||||||
|
let missingRequiredSettings = false
|
||||||
|
|
||||||
// Set up initial state for each new component instance
|
// Set up initial state for each new component instance
|
||||||
$: initialise(instance)
|
$: initialise(instance)
|
||||||
|
@ -102,6 +104,7 @@
|
||||||
$: editable = !!definition?.editable
|
$: editable = !!definition?.editable
|
||||||
$: hasChildren = !!definition?.hasChildren
|
$: hasChildren = !!definition?.hasChildren
|
||||||
$: showEmptyState = definition?.showEmptyState !== false
|
$: showEmptyState = definition?.showEmptyState !== false
|
||||||
|
$: hasMissingRequiredSettings = missingRequiredSettings?.length > 0
|
||||||
|
|
||||||
// Interactive components can be selected, dragged and highlighted inside
|
// Interactive components can be selected, dragged and highlighted inside
|
||||||
// the builder preview
|
// the builder preview
|
||||||
|
@ -155,6 +158,7 @@
|
||||||
name,
|
name,
|
||||||
editing,
|
editing,
|
||||||
type: instance._component,
|
type: instance._component,
|
||||||
|
missingRequiredSettings,
|
||||||
})
|
})
|
||||||
|
|
||||||
const initialise = instance => {
|
const initialise = instance => {
|
||||||
|
@ -201,6 +205,14 @@
|
||||||
staticSettings = instanceSettings.staticSettings
|
staticSettings = instanceSettings.staticSettings
|
||||||
dynamicSettings = instanceSettings.dynamicSettings
|
dynamicSettings = instanceSettings.dynamicSettings
|
||||||
|
|
||||||
|
// Check if we have any missing required settings
|
||||||
|
missingRequiredSettings = settingsDefinition.filter(setting => {
|
||||||
|
return (
|
||||||
|
setting.required &&
|
||||||
|
(instance[setting.key] == null || instance[setting.key] === "")
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
// Force an initial enrichment of the new settings
|
// Force an initial enrichment of the new settings
|
||||||
enrichComponentSettings(get(context), settingsDefinitionMap, {
|
enrichComponentSettings(get(context), settingsDefinitionMap, {
|
||||||
force: true,
|
force: true,
|
||||||
|
@ -414,17 +426,21 @@
|
||||||
data-id={id}
|
data-id={id}
|
||||||
data-name={name}
|
data-name={name}
|
||||||
>
|
>
|
||||||
<svelte:component this={constructor} bind:this={ref} {...initialSettings}>
|
{#if hasMissingRequiredSettings}
|
||||||
{#if children.length}
|
<ComponentPlaceholder />
|
||||||
{#each children as child (child._id)}
|
{:else}
|
||||||
<svelte:self instance={child} />
|
<svelte:component this={constructor} bind:this={ref} {...initialSettings}>
|
||||||
{/each}
|
{#if children.length}
|
||||||
{:else if emptyState}
|
{#each children as child (child._id)}
|
||||||
<Placeholder />
|
<svelte:self instance={child} />
|
||||||
{:else if isBlock}
|
{/each}
|
||||||
<slot />
|
{:else if emptyState}
|
||||||
{/if}
|
<Placeholder />
|
||||||
</svelte:component>
|
{:else if isBlock}
|
||||||
|
<slot />
|
||||||
|
{/if}
|
||||||
|
</svelte:component>
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
<script>
|
||||||
|
import { getContext } from "svelte"
|
||||||
|
import { builderStore } from "stores"
|
||||||
|
|
||||||
|
const { styleable } = getContext("sdk")
|
||||||
|
const component = getContext("component")
|
||||||
|
|
||||||
|
$: focusSetting = $component.missingRequiredSettings?.[0]
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#if $builderStore.inBuilder && focusSetting}
|
||||||
|
<div use:styleable={$component.styles}>
|
||||||
|
<div class="component-placeholder">
|
||||||
|
<span>
|
||||||
|
Add the <mark>{focusSetting?.label}</mark> setting to start using your component
|
||||||
|
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
class="spectrum-Link"
|
||||||
|
on:click={() => {
|
||||||
|
builderStore.actions.setFocus([
|
||||||
|
{
|
||||||
|
location: "component_settings",
|
||||||
|
key: focusSetting.key,
|
||||||
|
target: $component.id,
|
||||||
|
},
|
||||||
|
])
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Show me
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.component-placeholder {
|
||||||
|
color: var(--spectrum-global-color-gray-600);
|
||||||
|
font-size: var(--font-size-s);
|
||||||
|
padding: var(--spacing-xs);
|
||||||
|
}
|
||||||
|
.component-placeholder mark {
|
||||||
|
background-color: var(--spectrum-global-color-gray-400);
|
||||||
|
padding: 0 2px;
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
.component-placeholder .spectrum-Link {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -1,67 +1,15 @@
|
||||||
<script>
|
<script>
|
||||||
import { getContext } from "svelte"
|
import { getContext } from "svelte"
|
||||||
import Manifest from "manifest.json"
|
|
||||||
import { builderStore } from "stores"
|
|
||||||
|
|
||||||
const { componentStore } = getContext("sdk")
|
const { builderStore } = getContext("sdk")
|
||||||
const component = getContext("component")
|
const component = getContext("component")
|
||||||
|
|
||||||
export let text
|
export let text
|
||||||
|
|
||||||
$: componentInstance = componentStore.actions.getComponentById($component.id)
|
|
||||||
|
|
||||||
const getComponentKey = compId => {
|
|
||||||
if (!compId) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
const prefix = "@budibase/standard-components/"
|
|
||||||
let componentKey = compId.replace(prefix, "")
|
|
||||||
return componentKey
|
|
||||||
}
|
|
||||||
|
|
||||||
const emptyFields = (definition, options) => {
|
|
||||||
if (!options) {
|
|
||||||
return []
|
|
||||||
}
|
|
||||||
return definition?.settings
|
|
||||||
? definition.settings.filter(setting => {
|
|
||||||
return (
|
|
||||||
setting.required &&
|
|
||||||
(!options[setting.key] || options[setting.key] == "")
|
|
||||||
)
|
|
||||||
})
|
|
||||||
: []
|
|
||||||
}
|
|
||||||
const definition = Manifest[getComponentKey($component.type)]
|
|
||||||
$: focus_setting = emptyFields(definition, componentInstance)[0]
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if $builderStore.inBuilder}
|
{#if $builderStore.inBuilder}
|
||||||
<div class="placeholder_wrap">
|
<div>
|
||||||
{#if componentInstance && focus_setting}
|
{text || $component.name || "Placeholder"}
|
||||||
<div>
|
|
||||||
<span>
|
|
||||||
Add the <mark>{focus_setting?.label}</mark> setting to start using your
|
|
||||||
component
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
class="showMe spectrum-Link"
|
|
||||||
on:click={() => {
|
|
||||||
builderStore.actions.setFocus([
|
|
||||||
{
|
|
||||||
location: "component_settings",
|
|
||||||
key: focus_setting.key,
|
|
||||||
target: $component.id,
|
|
||||||
},
|
|
||||||
])
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Show me
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
{:else}
|
|
||||||
{text || $component.name || "Placeholder"}
|
|
||||||
{/if}
|
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
|
@ -69,18 +17,5 @@
|
||||||
div {
|
div {
|
||||||
color: var(--spectrum-global-color-gray-600);
|
color: var(--spectrum-global-color-gray-600);
|
||||||
font-size: var(--font-size-s);
|
font-size: var(--font-size-s);
|
||||||
padding: var(--spacing-xs);
|
|
||||||
}
|
|
||||||
:global(div.placeholder_wrap mark) {
|
|
||||||
background-color: var(--spectrum-global-color-gray-400);
|
|
||||||
padding: 0px 2px;
|
|
||||||
border-radius: 2px;
|
|
||||||
}
|
|
||||||
:global(div.placeholder_wrap .showMe) {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
:global(div.placeholder_wrap .showMe:hover) {
|
|
||||||
text-decoration: underline;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
Loading…
Reference in New Issue