Update client library so that component placeholders are always shown when required settings are missing
This commit is contained in:
parent
937c5a82ba
commit
e097f82b5d
|
@ -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}
|
||||
|
||||
|
|
|
@ -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>
|
||||
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
|
||||
</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>
|
||||
|
|
Loading…
Reference in New Issue