Update client library so that component placeholders are always shown when required settings are missing

This commit is contained in:
Andrew Kingston 2022-06-13 12:09:29 +01:00
parent 937c5a82ba
commit e097f82b5d
3 changed files with 80 additions and 79 deletions

View File

@ -23,6 +23,7 @@
import Manifest from "manifest.json"
import { getActiveConditions, reduceConditionActions } from "utils/conditions"
import Placeholder from "components/app/Placeholder.svelte"
import ComponentPlaceholder from "components/app/ComponentPlaceholder.svelte"
export let instance = {}
export let isLayout = false
@ -81,6 +82,7 @@
let definition
let settingsDefinition
let settingsDefinitionMap
let missingRequiredSettings = false
// Set up initial state for each new component instance
$: initialise(instance)
@ -102,6 +104,7 @@
$: editable = !!definition?.editable
$: hasChildren = !!definition?.hasChildren
$: showEmptyState = definition?.showEmptyState !== false
$: hasMissingRequiredSettings = missingRequiredSettings?.length > 0
// Interactive components can be selected, dragged and highlighted inside
// the builder preview
@ -155,6 +158,7 @@
name,
editing,
type: instance._component,
missingRequiredSettings,
})
const initialise = instance => {
@ -201,6 +205,14 @@
staticSettings = instanceSettings.staticSettings
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
enrichComponentSettings(get(context), settingsDefinitionMap, {
force: true,
@ -414,17 +426,21 @@
data-id={id}
data-name={name}
>
<svelte:component this={constructor} bind:this={ref} {...initialSettings}>
{#if children.length}
{#each children as child (child._id)}
<svelte:self instance={child} />
{/each}
{:else if emptyState}
<Placeholder />
{:else if isBlock}
<slot />
{/if}
</svelte:component>
{#if hasMissingRequiredSettings}
<ComponentPlaceholder />
{:else}
<svelte:component this={constructor} bind:this={ref} {...initialSettings}>
{#if children.length}
{#each children as child (child._id)}
<svelte:self instance={child} />
{/each}
{:else if emptyState}
<Placeholder />
{:else if isBlock}
<slot />
{/if}
</svelte:component>
{/if}
</div>
{/if}

View File

@ -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
&nbsp;
</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>

View File

@ -1,67 +1,15 @@
<script>
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")
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>
{#if $builderStore.inBuilder}
<div class="placeholder_wrap">
{#if componentInstance && focus_setting}
<div>
<span>
Add the <mark>{focus_setting?.label}</mark> setting to start using your
component &nbsp;
</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>
{text || $component.name || "Placeholder"}
</div>
{/if}
@ -69,18 +17,5 @@
div {
color: var(--spectrum-global-color-gray-600);
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>