Validate required settings messages from builder
This commit is contained in:
parent
c90296d552
commit
2537ee6980
|
@ -38,7 +38,7 @@ export function findComponentsBySettingsType(
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
function getManifestDefinition(component: Component) {
|
export function getManifestDefinition(component: Component) {
|
||||||
const componentType = component._component.split("/").slice(-1)[0]
|
const componentType = component._component.split("/").slice(-1)[0]
|
||||||
const definition =
|
const definition =
|
||||||
clientManifest[componentType as keyof typeof clientManifest]
|
clientManifest[componentType as keyof typeof clientManifest]
|
||||||
|
|
|
@ -2,11 +2,15 @@ import { derived } from "svelte/store"
|
||||||
import { tables } from "./tables"
|
import { tables } from "./tables"
|
||||||
import { selectedScreen } from "./screens"
|
import { selectedScreen } from "./screens"
|
||||||
import { viewsV2 } from "./viewsV2"
|
import { viewsV2 } from "./viewsV2"
|
||||||
import { findComponentsBySettingsType } from "@/helpers/screen"
|
import {
|
||||||
import { UIDatasourceType, Screen } from "@budibase/types"
|
findComponentsBySettingsType,
|
||||||
|
getManifestDefinition,
|
||||||
|
} from "@/helpers/screen"
|
||||||
|
import { UIDatasourceType, Screen, Component } from "@budibase/types"
|
||||||
import { queries } from "./queries"
|
import { queries } from "./queries"
|
||||||
import { views } from "./views"
|
import { views } from "./views"
|
||||||
import { featureFlag } from "@/helpers"
|
import { featureFlag } from "@/helpers"
|
||||||
|
import { findAllComponents } from "@/helpers/components"
|
||||||
|
|
||||||
function reduceBy<TItem extends {}, TKey extends keyof TItem>(
|
function reduceBy<TItem extends {}, TKey extends keyof TItem>(
|
||||||
key: TKey,
|
key: TKey,
|
||||||
|
@ -42,16 +46,36 @@ export const screenComponentErrors = derived(
|
||||||
if (!featureFlag.isEnabled("CHECK_SCREEN_COMPONENT_SETTINGS_ERRORS")) {
|
if (!featureFlag.isEnabled("CHECK_SCREEN_COMPONENT_SETTINGS_ERRORS")) {
|
||||||
return {}
|
return {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const datasources = {
|
||||||
|
...reduceBy("_id", $tables.list),
|
||||||
|
...reduceBy("name", $views.list),
|
||||||
|
...reduceBy("id", $viewsV2.list),
|
||||||
|
...reduceBy("_id", $queries.list),
|
||||||
|
}
|
||||||
|
|
||||||
|
const errors = {
|
||||||
|
...getInvalidDatasources($selectedScreen, datasources),
|
||||||
|
...getMissingRequiredSettings($selectedScreen),
|
||||||
|
}
|
||||||
|
return errors
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
function getInvalidDatasources(
|
function getInvalidDatasources(
|
||||||
screen: Screen,
|
screen: Screen,
|
||||||
datasources: Record<string, any>
|
datasources: Record<string, any>
|
||||||
) {
|
) {
|
||||||
const result: Record<string, string[]> = {}
|
const result: Record<string, string[]> = {}
|
||||||
for (const { component, setting } of findComponentsBySettingsType(
|
for (const { component, setting } of findComponentsBySettingsType(screen, [
|
||||||
screen,
|
"table",
|
||||||
["table", "dataSource"]
|
"dataSource",
|
||||||
)) {
|
])) {
|
||||||
const componentSettings = component[setting.key]
|
const componentSettings = component[setting.key]
|
||||||
|
if (!componentSettings) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
const { label } = componentSettings
|
const { label } = componentSettings
|
||||||
const type = componentSettings.type as UIDatasourceType
|
const type = componentSettings.type as UIDatasourceType
|
||||||
|
|
||||||
|
@ -71,13 +95,69 @@ export const screenComponentErrors = derived(
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
const datasources = {
|
function getAllComponentsInScreen(screen: Screen) {
|
||||||
...reduceBy("_id", $tables.list),
|
const result: Component[] = []
|
||||||
...reduceBy("name", $views.list),
|
function recursiveCheck(component: Component) {
|
||||||
...reduceBy("id", $viewsV2.list),
|
result.push(...findAllComponents(component))
|
||||||
...reduceBy("_id", $queries.list),
|
component._children?.forEach(recursiveCheck)
|
||||||
|
}
|
||||||
|
recursiveCheck(screen.props)
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
return getInvalidDatasources($selectedScreen, datasources)
|
function getMissingRequiredSettings(screen: Screen) {
|
||||||
|
const allComponents = getAllComponentsInScreen(screen)
|
||||||
|
|
||||||
|
const result: Record<string, string[]> = {}
|
||||||
|
for (const component of allComponents) {
|
||||||
|
const definition = getManifestDefinition(component)
|
||||||
|
if (!("settings" in definition)) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
const missingRequiredSettings = definition.settings.filter(
|
||||||
|
(setting: any) => {
|
||||||
|
let empty =
|
||||||
|
component[setting.key] == null || component[setting.key] === ""
|
||||||
|
let missing = setting.required && empty
|
||||||
|
|
||||||
|
// Check if this setting depends on another, as it may not be required
|
||||||
|
if (setting.dependsOn) {
|
||||||
|
const dependsOnKey = setting.dependsOn.setting || setting.dependsOn
|
||||||
|
const dependsOnValue = setting.dependsOn.value
|
||||||
|
const realDependentValue = component[dependsOnKey]
|
||||||
|
|
||||||
|
const sectionDependsOnKey =
|
||||||
|
setting.sectionDependsOn?.setting || setting.sectionDependsOn
|
||||||
|
const sectionDependsOnValue = setting.sectionDependsOn?.value
|
||||||
|
const sectionRealDependentValue = component[sectionDependsOnKey]
|
||||||
|
|
||||||
|
if (dependsOnValue == null && realDependentValue == null) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if (dependsOnValue != null && dependsOnValue !== realDependentValue) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
sectionDependsOnValue != null &&
|
||||||
|
sectionDependsOnValue !== sectionRealDependentValue
|
||||||
|
) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return missing
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (missingRequiredSettings.length) {
|
||||||
|
result[component._id!] = missingRequiredSettings.map(
|
||||||
|
(s: any) =>
|
||||||
|
`Add the <mark>${s.label}</mark> setting to start using your component`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
|
@ -695,11 +695,7 @@
|
||||||
use:gridLayout={gridMetadata}
|
use:gridLayout={gridMetadata}
|
||||||
>
|
>
|
||||||
{#if errorState}
|
{#if errorState}
|
||||||
<ComponentErrorState
|
<ComponentErrorState {componentErrors} />
|
||||||
{missingRequiredSettings}
|
|
||||||
{missingRequiredAncestors}
|
|
||||||
{componentErrors}
|
|
||||||
/>
|
|
||||||
{:else}
|
{:else}
|
||||||
<svelte:component this={constructor} bind:this={ref} {...initialSettings}>
|
<svelte:component this={constructor} bind:this={ref} {...initialSettings}>
|
||||||
{#if children.length}
|
{#if children.length}
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
{#if requiredAncestor}
|
{#if requiredAncestor}
|
||||||
<MissingRequiredAncestor {requiredAncestor} />
|
<MissingRequiredAncestor {requiredAncestor} />
|
||||||
{:else if errorMessage}
|
{:else if errorMessage}
|
||||||
{errorMessage}
|
{@html errorMessage}
|
||||||
{:else if requiredSetting}
|
{:else if requiredSetting}
|
||||||
<MissingRequiredSetting {requiredSetting} />
|
<MissingRequiredSetting {requiredSetting} />
|
||||||
{/if}
|
{/if}
|
||||||
|
|
Loading…
Reference in New Issue