budibase/packages/builder/src/userInterface/pagesParsing/createProps.js

151 lines
3.6 KiB
JavaScript
Raw Normal View History

2019-07-19 13:52:08 +02:00
import {
isString,
isUndefined,
find,
keys,
uniq,
some,
filter,
reduce,
cloneDeep,
includes,
last,
} from "lodash/fp"
import { types, expandComponentDefinition } from "./types"
import { assign } from "lodash"
import { pipe } from "../../common/core"
import { isRootComponent } from "./searchComponents"
import { ensureShardNameIsInShardMap } from "../../../../core/src/indexing/sharding"
2019-08-14 23:11:59 +02:00
2019-08-16 16:48:45 +02:00
export const getInstanceProps = (componentInfo, props) => {
const finalProps = cloneDeep(componentInfo.fullProps)
2019-08-14 23:11:59 +02:00
for (let p in props) {
finalProps[p] = props[p]
}
2019-08-14 23:11:59 +02:00
return finalProps
2019-08-14 23:11:59 +02:00
}
export const getNewComponentInfo = (components, rootComponent, name) => {
const component = {
name: name || "",
description: "",
props: {
_component: rootComponent,
},
}
return getComponentInfo(components, component)
2019-08-14 23:11:59 +02:00
}
export const getScreenInfo = (components, screen) => {
return getComponentInfo(components, screen)
2019-08-14 23:11:59 +02:00
}
export const getComponentInfo = (components, comp) => {
const targetComponent = isString(comp)
? find(c => c.name === comp)(components)
: comp
let component
let subComponent
if (isRootComponent(targetComponent)) {
component = targetComponent
} else {
subComponent = targetComponent
component = find(
c =>
c.name ===
(subComponent.props
? subComponent.props._component
: subComponent._component)
)(components)
}
const subComponentProps = subComponent ? subComponent.props : {}
const p = createProps(component, subComponentProps)
const rootProps = createProps(component)
const unsetProps = pipe(p.props, [
keys,
filter(k => !includes(k)(keys(subComponentProps)) && k !== "_component"),
])
const fullProps = cloneDeep(p.props)
fullProps._component = targetComponent.name
return {
propsDefinition: expandComponentDefinition(component),
rootDefaultProps: rootProps.props,
unsetProps,
fullProps: fullProps,
errors: p.errors,
component: targetComponent,
rootComponent: component,
}
}
export const createProps = (componentDefinition, derivedFromProps) => {
const error = (propName, error) => errors.push({ propName, error })
2019-07-20 22:41:06 +02:00
const props = {
_component: componentDefinition.name,
}
2019-07-19 13:52:08 +02:00
const errors = []
2019-07-19 13:52:08 +02:00
if (!componentDefinition.name)
error("_component", "Component name not supplied")
2019-07-20 22:41:06 +02:00
const propsDef = componentDefinition.props
for (let propDef in propsDef) {
const parsedPropDef = parsePropDef(propsDef[propDef])
if (parsedPropDef.error) error(propDef, parsedPropDef.error)
else props[propDef] = parsedPropDef
}
2019-07-19 13:52:08 +02:00
if (derivedFromProps) {
assign(props, derivedFromProps)
}
2019-07-19 13:52:08 +02:00
if (componentDefinition.children !== false && isUndefined(props._children)) {
props._children = []
}
return {
props,
errors,
}
2019-07-19 13:52:08 +02:00
}
const parsePropDef = propDef => {
const error = message => ({ error: message, propDef })
2019-07-19 13:52:08 +02:00
if (isString(propDef)) {
if (!types[propDef]) return error(`Do not recognise type ${propDef}`)
return types[propDef].default()
}
2019-07-19 13:52:08 +02:00
if (!propDef.type) return error("Property Definition must declare a type")
const type = types[propDef.type]
if (!type) return error(`Do not recognise type ${propDef.type}`)
2019-07-19 13:52:08 +02:00
if (isUndefined(propDef.default)) return type.default(propDef)
2019-07-19 13:52:08 +02:00
if (!type.isOfType(propDef.default))
return error(`${propDef.default} is not of type ${type}`)
2019-07-19 13:52:08 +02:00
return propDef.default
2019-07-19 13:52:08 +02:00
}
export const arrayElementComponentName = (parentComponentName, arrayPropName) =>
`${parentComponentName}:${arrayPropName}`
2019-09-03 11:42:19 +02:00
2019-07-19 19:03:58 +02:00
/*
Allowed propDefOptions
- type: string, bool, number, array
- default: default value, when undefined
- required: field is required
*/