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

150 lines
4.0 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
2019-07-19 13:52:08 +02:00
} from "lodash/fp";
import { types, expandComponentDefinition } from "./types";
2019-07-19 13:52:08 +02:00
import { assign } from "lodash";
2019-08-04 23:21:16 +02:00
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) => {
2019-08-14 23:11:59 +02:00
const finalProps = cloneDeep(componentInfo.fullProps);
for(let p in props) {
finalProps[p] = props[p];
}
return finalProps;
}
export const getNewComponentInfo = (components, rootComponent, name) => {
2019-08-14 23:11:59 +02:00
const component = {
name: name || "",
description:"",
props:{
_component: rootComponent
}
2019-08-14 23:11:59 +02:00
};
return getComponentInfo(
components,
component);
2019-08-14 23:11:59 +02:00
}
export const getScreenInfo = (components, screen) => {
2019-08-14 23:11:59 +02:00
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._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) => {
2019-07-20 22:41:06 +02:00
const error = (propName, error) =>
errors.push({propName, error});
const props = {
_component: componentDefinition.name
2019-07-20 22:41:06 +02:00
};
2019-07-19 13:52:08 +02:00
const errors = [];
if(!componentDefinition.name)
2019-07-20 22:41:06 +02:00
error("_component", "Component name not supplied");
const propsDef = componentDefinition.props;
for(let propDef in propsDef) {
const parsedPropDef = parsePropDef(propsDef[propDef]);
2019-07-19 13:52:08 +02:00
if(parsedPropDef.error)
2019-07-20 22:41:06 +02:00
error(propDef, parsedPropDef.error);
2019-07-19 13:52:08 +02:00
else
props[propDef] = parsedPropDef;
}
if(derivedFromProps) {
2019-08-14 23:11:59 +02:00
assign(props, derivedFromProps);
2019-07-19 13:52:08 +02:00
}
if(componentDefinition.children !== false
&& isUndefined(props._children)) {
props._children = [];
}
2019-07-19 13:52:08 +02:00
return ({
props, errors
});
}
2019-09-03 11:42:19 +02:00
2019-07-19 13:52:08 +02:00
const parsePropDef = propDef => {
2019-07-19 19:03:58 +02:00
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();
}
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}`);
if(isUndefined(propDef.default))
return type.default(propDef);
if(!type.isOfType(propDef.default))
return error(`${propDef.default} is not of type ${type}`);
return propDef.default;
}
2019-09-03 11:42:19 +02:00
export const arrayElementComponentName = (parentComponentName, arrayPropName) =>
`${parentComponentName}:${arrayPropName}`;
2019-07-19 19:03:58 +02:00
/*
Allowed propDefOptions
- type: string, bool, number, array
- default: default value, when undefined
- required: field is required
*/