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

142 lines
3.6 KiB
Svelte
Raw Normal View History

<script>
import {
keys,
map,
2019-08-14 23:11:59 +02:00
some,
includes,
cloneDeep,
isEqual
} from "lodash/fp";
2019-08-14 23:11:59 +02:00
import { pipe } from "../common/core";
import { getComponentInfo } from "./pagesParsing/createProps";
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-04 23:21:16 +02:00
export let allComponents;
2019-08-14 23:11:59 +02:00
export let shouldValidate = true;
export let onValidate = () => {};
export let showTitle = true;
export let componentInfo;
export let component;
export let onPropsChanged = () => {};
let errors = [];
let fields = [];
let props = {};
let propsDefinitionArray = [];
$: {
if(componentInfo || component)
{
if(!componentInfo || (component &&
component.name !== componentInfo.component.name)) {
componentInfo = getComponentInfo(allComponents, component.name);
}
props = cloneDeep(componentInfo.fullProps);
propsDefinitionArray = pipe(componentInfo.propsDefinition, [
keys,
map(k => ({...componentInfo.propsDefinition[k], ____name:k}))
]);
fields = pipe(componentInfo.propsDefinition,[
keys,
map(k => componentInfo.propsDefinition[k])
]);
}
}
2019-08-04 23:21:16 +02:00
2019-08-14 23:11:59 +02:00
const isPropInherited = name =>
includes(name)(componentInfo.inheritedProps);
2019-08-14 23:11:59 +02:00
let setProp = (name) => (ev, targetValue="value") => {
const newProps = cloneDeep(props);
newProps[name] = ev.target[targetValue];
2019-08-15 09:49:15 +02:00
const finalProps = {};
2019-08-14 23:11:59 +02:00
for(let p of componentInfo.unsetProps) {
if(!isEqual(newProps[p])(componentInfo.rootDefaultProps[p])) {
finalProps[p] = newProps[p];
}
}
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);
</script>
2019-08-04 23:21:16 +02:00
<div class="root">
2019-08-14 23:11:59 +02:00
{#if showTitle=true}
<div class="title">{componentInfo.component.name}</div>
<div class="component-description">{componentInfo.component.description || ""}</div>
{/if}
{#each propsDefinitionArray as propDef}
<form class="uk-form-stacked prop-row ">
2019-08-04 23:21:16 +02:00
{#if propDef.type === "bool"}
2019-08-14 23:11:59 +02:00
<Checkbox label={propDef.____name}
checked={props[propDef.____name]}
on:change={setProp(propDef.____name, "checked")}
hasError={fieldHasError(propDef.____name)} />
{:else if propDef.type === "options"}
2019-08-14 23:11:59 +02:00
<Dropdown label={propDef.____name}
selected={props[propDef.____name]}
options={propDef.options}
on:change={setProp(propDef.____name)}
hasError={fieldHasError(propDef.____name)}/>
2019-08-04 23:21:16 +02:00
{:else}
2019-08-14 23:11:59 +02:00
<Textbox label={propDef.____name}
text={props[propDef.____name]}
on:change={setProp(propDef.____name)}
margin={false}
hasError={fieldHasError(propDef.____name)}
disabled={isPropInherited(propDef.____name)} />
2019-08-04 23:21:16 +02:00
{/if}
</form>
2019-08-04 23:21:16 +02:00
{/each}
</div>
<style>
2019-08-04 23:21:16 +02:00
.root {
font-size:10pt;
}
.title {
2019-08-14 23:11:59 +02:00
font-size: 1.2em;
font-weight: bold;
}
.prop-row {
padding: 7px 3px;
}
.component-description {
2019-08-14 23:11:59 +02:00
font-size: 0.9em;
color: var(--slate);
margin-bottom: 10px;
2019-08-04 23:21:16 +02:00
}
</style>