budibase/packages/builder/src/userInterface/PropsView.svelte

183 lines
4.6 KiB
Svelte
Raw Normal View History

<script>
import {
keys,
map,
2019-08-14 23:11:59 +02:00
some,
includes,
cloneDeep,
2019-08-16 16:48:45 +02:00
isEqual,
sortBy,
2019-08-19 09:51:01 +02:00
filter,
difference
} from "lodash/fp";
2019-08-14 23:11:59 +02:00
import { pipe } from "../common/core";
2019-08-16 16:48:45 +02:00
import {
getComponentInfo ,
getInstanceProps
} from "./pagesParsing/createProps";
2019-08-14 23:11:59 +02:00
import { getExactComponent } from "./pagesParsing/searchComponents";
import Checkbox from "../common/Checkbox.svelte";
import Textbox from "../common/Textbox.svelte";
import Dropdown from "../common/Dropdown.svelte";
2019-08-14 23:11:59 +02:00
import { validateProps } from "./pagesParsing/validateProps";
2019-08-16 16:48:45 +02:00
import ComponentPropSelector from "./ComponentPropSelector.svelte";
import PropControl from "./PropControl.svelte";
import IconButton from "../common/IconButton.svelte";
2019-08-14 23:11:59 +02:00
export let shouldValidate = true;
export let onValidate = () => {};
export let componentInfo;
2019-08-16 16:48:45 +02:00
export let instanceProps = null;
2019-08-14 23:11:59 +02:00
export let onPropsChanged = () => {};
2019-08-19 09:51:01 +02:00
export let onEditComponentProp = () => {};
2019-08-14 23:11:59 +02:00
let errors = [];
let props = {};
2019-08-16 16:48:45 +02:00
let propsDefinitions = [];
let inheritedPropsDefinitions = [];
let inheritedExpanded = false;
2019-08-19 09:51:01 +02:00
let isInstance = false;
2019-08-16 16:48:45 +02:00
const isPropInherited = name =>
includes(name)(componentInfo.inheritedProps);
2019-08-14 23:11:59 +02:00
$: {
2019-08-16 16:48:45 +02:00
if(componentInfo)
2019-08-14 23:11:59 +02:00
{
2019-08-19 09:51:01 +02:00
isInstance = !!instanceProps;
props = isInstance
2019-08-16 16:48:45 +02:00
? getInstanceProps(componentInfo, instanceProps)
: cloneDeep(componentInfo.fullProps);
2019-08-14 23:11:59 +02:00
2019-08-16 16:48:45 +02:00
propsDefinitions = pipe(componentInfo.propsDefinition, [
2019-08-14 23:11:59 +02:00
keys,
2019-08-16 16:48:45 +02:00
filter(k => !isPropInherited(k)),
map(k => ({...componentInfo.propsDefinition[k], ____name:k})),
sortBy("____name")
2019-08-14 23:11:59 +02:00
]);
2019-08-16 16:48:45 +02:00
inheritedPropsDefinitions = pipe(componentInfo.propsDefinition, [
keys,
filter(k => isPropInherited(k)),
map(k => ({...componentInfo.propsDefinition[k], ____name:k})),
sortBy("____name")
]);
2019-08-14 23:11:59 +02:00
}
}
2019-08-04 23:21:16 +02:00
2019-08-16 16:48:45 +02:00
let setProp = (name, value) => {
2019-08-14 23:11:59 +02:00
const newProps = cloneDeep(props);
2019-08-19 09:51:01 +02:00
let finalProps = isInstance ? newProps : cloneDeep(componentInfo.component.props);
2019-08-14 23:11:59 +02:00
2019-08-19 09:51:01 +02:00
if(!isInstance) {
const nowSet = [];
for(let p of componentInfo.unsetProps) {
if(!isEqual(newProps[p])(componentInfo.rootDefaultProps[p])) {
finalProps[p] = newProps[p];
nowSet.push(p);
}
2019-08-14 23:11:59 +02:00
}
2019-08-19 09:51:01 +02:00
componentInfo.unsetProps = difference(nowSet)(componentInfo.unsetProps);
2019-08-14 23:11:59 +02:00
}
2019-08-19 09:51:01 +02:00
newProps[name] = value;
finalProps[name] = value;
2019-08-14 23:11:59 +02:00
props = newProps;
if(validate(finalProps))
onPropsChanged(finalProps);
}
const validate = (finalProps) => {
errors = validateProps(componentInfo.propsDefinition, finalProps, [], false);
onValidate(errors);
return errors.length === 0;
}
2019-08-04 23:21:16 +02:00
2019-08-14 23:11:59 +02:00
const fieldHasError = (propName) =>
some(e => e.propName === propName)(errors);
2019-09-03 11:42:19 +02:00
const onEditComponent = (propName) => (arrayIndex, arrayPropName) => {
onEditComponentProp(propName, arrayIndex, arrayPropName);
2019-08-19 09:51:01 +02:00
}
2019-08-16 16:48:45 +02:00
</script>
2019-08-04 23:21:16 +02:00
<div class="root">
2019-08-16 16:48:45 +02:00
<form class="uk-form-stacked">
2019-08-19 09:51:01 +02:00
{#each propsDefinitions as propDef, index}
2019-08-16 16:48:45 +02:00
2019-09-03 11:42:19 +02:00
<PropControl {setProp}
{fieldHasError}
{propDef}
{props}
{index}
onEditComponent={onEditComponent(propDef.____name)}
disabled={false} />
2019-08-16 16:48:45 +02:00
{/each}
{#if inheritedPropsDefinitions.length > 0}
2019-08-19 09:51:01 +02:00
<div class="inherited-title padding">
2019-08-16 16:48:45 +02:00
<div>Inherited</div>
<div>
<IconButton icon={inheritedExpanded ? "chevron-down" : "chevron-right"}
on:click={() => inheritedExpanded = !inheritedExpanded}/>
</div>
</div>
{/if}
{#if inheritedExpanded}
2019-08-19 09:51:01 +02:00
{#each inheritedPropsDefinitions as propDef, index}
2019-08-16 16:48:45 +02:00
2019-09-03 11:42:19 +02:00
<PropControl {setProp}
{fieldHasError}
{propDef}
{props}
{index}
disabled={true} />
2019-08-16 16:48:45 +02:00
{/each}
{/if}
</form>
2019-08-16 16:48:45 +02:00
2019-08-04 23:21:16 +02:00
</div>
<style>
2019-08-04 23:21:16 +02:00
.root {
font-size:10pt;
}
2019-08-19 09:51:01 +02:00
.padding {
padding: 0 10px;
}
2019-08-16 16:48:45 +02:00
.inherited-title {
padding: 1rem 1rem 1rem 1rem;
2019-08-16 16:48:45 +02:00
display: grid;
grid-template-columns: [name] 1fr [actions] auto;
color: var(--secondary100);
font-size: .9rem;
font-weight: bold;
}
2019-08-16 16:48:45 +02:00
.inherited-title > div:nth-child(1) {
grid-column-start: name;
color: var(--secondary50);
}
2019-08-16 16:48:45 +02:00
.inherited-title > div:nth-child(2) {
grid-column-start: actions;
color: var(--secondary100);
2019-08-04 23:21:16 +02:00
}
</style>