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

151 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) {
2019-08-14 23:11:59 +02:00
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 ? 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) => {
2019-07-20 22:41:06 +02:00
const error = (propName, error) =>
errors.push({ propName, error });
2019-07-20 22:41:06 +02:00
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]);
if (parsedPropDef.error)
error(propDef, parsedPropDef.error);
else
2019-07-19 13:52:08 +02:00
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 => {
const error = message => ({ error: message, propDef });
2019-07-19 13:52:08 +02:00
if (isString(propDef)) {
if (!types[propDef])
2019-07-19 13:52:08 +02:00
return error(`Do not recognise type ${propDef}`);
2019-07-19 13:52:08 +02:00
return types[propDef].default();
}
if (!propDef.type)
2019-07-19 13:52:08 +02:00
return error("Property Definition must declare a type");
2019-07-19 13:52:08 +02:00
const type = types[propDef.type];
if (!type)
2019-07-19 13:52:08 +02:00
return error(`Do not recognise type ${propDef.type}`);
if (isUndefined(propDef.default))
2019-07-19 13:52:08 +02:00
return type.default(propDef);
if (!type.isOfType(propDef.default))
2019-07-19 13:52:08 +02:00
return error(`${propDef.default} is not of type ${type}`);
return propDef.default;
}
export const arrayElementComponentName = (parentComponentName, arrayPropName) =>
2019-09-03 11:42:19 +02:00
`${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
*/