2020-02-10 16:51:09 +01:00
|
|
|
import { isString, isUndefined } from "lodash/fp"
|
|
|
|
import { types } from "./types"
|
2020-02-03 10:24:25 +01:00
|
|
|
import { assign } from "lodash"
|
2020-02-10 16:51:09 +01:00
|
|
|
import { uuid } from "../../builderStore/uuid"
|
2019-08-14 23:11:59 +02:00
|
|
|
|
2020-02-18 11:32:00 +01:00
|
|
|
export const getBuiltin = name => {
|
|
|
|
const { props } = createProps({ name })
|
|
|
|
|
|
|
|
return {
|
|
|
|
name,
|
|
|
|
props,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-02-10 16:51:09 +01:00
|
|
|
export const getNewScreen = (components, rootComponentName, name) => {
|
|
|
|
const rootComponent = components.find(c => c.name === rootComponentName)
|
|
|
|
return {
|
2020-02-03 10:24:25 +01:00
|
|
|
name: name || "",
|
|
|
|
description: "",
|
2020-02-10 16:51:09 +01:00
|
|
|
url: "",
|
|
|
|
_css: "",
|
|
|
|
uiFunctions: "",
|
|
|
|
props: createProps(rootComponent).props,
|
2020-02-03 10:24:25 +01:00
|
|
|
}
|
2020-01-18 00:06:42 +01:00
|
|
|
}
|
|
|
|
|
2020-02-18 16:41:44 +01:00
|
|
|
/**
|
|
|
|
* @param {object} componentDefinition - component definition from a component library
|
|
|
|
* @param {object} derivedFromProps - extra props derived from a components given props.
|
|
|
|
* @return {object} the fully created properties for the component, and any property parsing errors
|
|
|
|
*/
|
2020-01-18 00:06:42 +01:00
|
|
|
export const createProps = (componentDefinition, derivedFromProps) => {
|
2020-02-18 16:41:44 +01:00
|
|
|
const errorOccurred = (propName, error) => errors.push({ propName, error })
|
2019-07-20 22:41:06 +02:00
|
|
|
|
2020-02-03 10:24:25 +01:00
|
|
|
const props = {
|
|
|
|
_component: componentDefinition.name,
|
2020-02-10 16:51:09 +01:00
|
|
|
_styles: { position: {}, layout: {} },
|
|
|
|
_id: uuid(),
|
|
|
|
_code: "",
|
2020-02-03 10:24:25 +01:00
|
|
|
}
|
2019-07-19 13:52:08 +02:00
|
|
|
|
2020-02-03 10:24:25 +01:00
|
|
|
const errors = []
|
2019-07-19 13:52:08 +02:00
|
|
|
|
2020-02-03 10:24:25 +01:00
|
|
|
if (!componentDefinition.name)
|
2020-02-18 16:41:44 +01:00
|
|
|
errorOccurred("_component", "Component name not supplied")
|
2019-07-20 22:41:06 +02:00
|
|
|
|
2020-02-03 10:24:25 +01:00
|
|
|
const propsDef = componentDefinition.props
|
|
|
|
for (let propDef in propsDef) {
|
|
|
|
const parsedPropDef = parsePropDef(propsDef[propDef])
|
2020-02-18 16:41:44 +01:00
|
|
|
if (parsedPropDef.error) errorOccurred(propDef, parsedPropDef.error)
|
2020-02-03 10:24:25 +01:00
|
|
|
else props[propDef] = parsedPropDef
|
|
|
|
}
|
2019-07-19 13:52:08 +02:00
|
|
|
|
2020-02-03 10:24:25 +01:00
|
|
|
if (derivedFromProps) {
|
|
|
|
assign(props, derivedFromProps)
|
|
|
|
}
|
2019-07-19 13:52:08 +02:00
|
|
|
|
2020-02-03 10:24:25 +01:00
|
|
|
if (componentDefinition.children !== false && isUndefined(props._children)) {
|
|
|
|
props._children = []
|
|
|
|
}
|
2020-01-18 00:06:42 +01:00
|
|
|
|
2020-02-03 10:24:25 +01:00
|
|
|
return {
|
|
|
|
props,
|
|
|
|
errors,
|
|
|
|
}
|
2019-07-19 13:52:08 +02:00
|
|
|
}
|
|
|
|
|
2020-02-14 12:51:45 +01:00
|
|
|
export const makePropsSafe = (componentDefinition, props) => {
|
|
|
|
const safeProps = createProps(componentDefinition, props).props
|
|
|
|
for (let propName in safeProps) {
|
|
|
|
props[propName] = safeProps[propName]
|
|
|
|
}
|
|
|
|
|
|
|
|
for (let propName in props) {
|
|
|
|
if (safeProps[propName] === undefined) {
|
|
|
|
delete props[propName]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return props
|
|
|
|
}
|
|
|
|
|
2019-07-19 13:52:08 +02:00
|
|
|
const parsePropDef = propDef => {
|
2020-02-03 10:24:25 +01:00
|
|
|
const error = message => ({ error: message, propDef })
|
2019-07-19 13:52:08 +02:00
|
|
|
|
2020-02-03 10:24:25 +01:00
|
|
|
if (isString(propDef)) {
|
|
|
|
if (!types[propDef]) return error(`Do not recognise type ${propDef}`)
|
2020-01-24 12:32:13 +01:00
|
|
|
|
2020-02-03 10:24:25 +01:00
|
|
|
return types[propDef].default()
|
|
|
|
}
|
2019-07-19 13:52:08 +02:00
|
|
|
|
2020-02-03 10:24:25 +01:00
|
|
|
if (!propDef.type) return error("Property Definition must declare a type")
|
2020-01-24 12:32:13 +01:00
|
|
|
|
2020-02-03 10:24:25 +01:00
|
|
|
const type = types[propDef.type]
|
|
|
|
if (!type) return error(`Do not recognise type ${propDef.type}`)
|
2019-07-19 13:52:08 +02:00
|
|
|
|
2020-02-03 10:24:25 +01:00
|
|
|
if (isUndefined(propDef.default)) return type.default(propDef)
|
2019-07-19 13:52:08 +02:00
|
|
|
|
2020-02-03 10:24:25 +01:00
|
|
|
if (!type.isOfType(propDef.default))
|
|
|
|
return error(`${propDef.default} is not of type ${type}`)
|
2019-07-19 13:52:08 +02:00
|
|
|
|
2020-02-03 10:24:25 +01:00
|
|
|
return propDef.default
|
2019-07-19 13:52:08 +02:00
|
|
|
}
|
|
|
|
|
2020-01-24 12:32:13 +01:00
|
|
|
export const arrayElementComponentName = (parentComponentName, arrayPropName) =>
|
2020-02-03 10:24:25 +01:00
|
|
|
`${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
|
2020-01-24 12:32:13 +01:00
|
|
|
- required: field is required
|
|
|
|
*/
|