diff --git a/packages/builder/src/builderStore/api.js b/packages/builder/src/builderStore/api.js index 3a918ac8a5..3196f4e9e4 100644 --- a/packages/builder/src/builderStore/api.js +++ b/packages/builder/src/builderStore/api.js @@ -1,17 +1,19 @@ -const apiCall = (method) => (url, body, returnResponse=false) => +const apiCall = (method, returnResponse) => (url, body) => fetch(url, { method: method, headers: { 'Content-Type': 'application/json', }, body: body && JSON.stringify(body), - }).then(r => returnResponse ? r : r.json()); + }).then(r => + returnResponse ? r.json() : r + ); -const post = apiCall("POST"); -const get = apiCall("GET"); -const patch = apiCall("PATCH"); -const del = apiCall("DELETE"); +const post = apiCall("POST", true); +const get = apiCall("GET", true); +const patch = apiCall("PATCH", true); +const del = apiCall("DELETE", false); export default { post, get, patch, delete:del diff --git a/packages/builder/src/builderStore/store.js b/packages/builder/src/builderStore/store.js index a810f36afb..46c27a8a85 100644 --- a/packages/builder/src/builderStore/store.js +++ b/packages/builder/src/builderStore/store.js @@ -384,7 +384,11 @@ const saveDerivedComponent = store => (derivedComponent) => { ]); s.allComponents = components; - + s.currentFrontEndItem = derivedComponent; + s.currentComponentInfo = getNewComponentInfo( + s.allComponents, componentName); + s.currentComponentIsNew = false; + api.post(`/_builder/api/${s.appname}/derivedcomponent`, derivedComponent); return s; diff --git a/packages/builder/src/userInterface/ComponentInstanceEditor.svelte b/packages/builder/src/userInterface/ComponentInstanceEditor.svelte new file mode 100644 index 0000000000..7c59d20c6f --- /dev/null +++ b/packages/builder/src/userInterface/ComponentInstanceEditor.svelte @@ -0,0 +1,94 @@ + + +
+ +
+ + {propertyName} +
+ + {#if editingSubComponentName} +
+ +
+ {:else} + + {/if} + + + + +
+ + \ No newline at end of file diff --git a/packages/builder/src/userInterface/ComponentPropSelector.svelte b/packages/builder/src/userInterface/ComponentPropSelector.svelte index 8d0b5d86ea..86b1e645e5 100644 --- a/packages/builder/src/userInterface/ComponentPropSelector.svelte +++ b/packages/builder/src/userInterface/ComponentPropSelector.svelte @@ -16,6 +16,8 @@ const emptyProps = () => ({_component:""}) export let props = emptyProps(); export let onValueChanged = () => {}; +export let onComponentChosen = () => {}; +export let onEdit = () => {}; export let label = "" export let disabled = false; @@ -43,10 +45,11 @@ const clearComponent = () => { showDialog(); } -const onComponentChosen = (component) => { +const componentChosen = (component) => { const componentInfo = getComponentInfo(allComponents, component.name); props = componentInfo.fullProps; onValueChanged(props); + onComponentChosen(); hideDialog(); } @@ -74,7 +77,8 @@ const confirmClearComponent = () => {
{#if !disabled && componentSelected} - + @@ -91,7 +95,7 @@ const confirmClearComponent = () => { {#if modalAction === CHOOSE_COMPONENT}
- +
{:else if modalAction === CLEAR_COMPONENT}
diff --git a/packages/builder/src/userInterface/EditComponent.svelte b/packages/builder/src/userInterface/EditComponent.svelte index 5c99e38e27..e46ba461bc 100644 --- a/packages/builder/src/userInterface/EditComponent.svelte +++ b/packages/builder/src/userInterface/EditComponent.svelte @@ -12,6 +12,7 @@ import { } from "./pagesParsing/createProps"; import Button from "../common/Button.svelte"; import ButtonGroup from "../common/ButtonGroup.svelte"; +import ComponentInstanceEditor from "./ComponentInstanceEditor.svelte"; import { cloneDeep, @@ -33,6 +34,10 @@ let componentDetailsExpanded = false; let componentInfo; let modalElement let propsValidationErrors = []; +let editingComponentInstance; +let editingComponentInstancePropName=""; +let allComponents; + $: shortName = last(name.split("/")); store.subscribe(s => { @@ -43,6 +48,7 @@ store.subscribe(s => { tagsString = join(", ")(component.tags); componentInfo = s.currentComponentInfo; componentDetailsExpanded = s.currentComponentIsNew; + allComponents = s.allComponents; }); const save = () => { @@ -72,8 +78,17 @@ const onPropsValidate = result => { propsValidationErrors = result; } -const onPropsChanged = props => { - assign(component.props, props); +const updateComponent = doChange => { + const newComponent = cloneDeep(component); + doChange(newComponent); + component = newComponent; + componentInfo = getComponentInfo(allComponents, newComponent); +} + +const onPropsChanged = newProps => { + updateComponent(newComponent => + assign(newComponent.props, newProps)); + } const validate = () => { @@ -96,6 +111,21 @@ const showDialog = () => { UIkit.modal(modalElement).show(); } +const onEditComponentProp = (propName) => { + editingComponentInstance = component.props[propName]; + editingComponentInstancePropName = propName; +} + +const componentInstanceCancelEdit = () => { + editingComponentInstance = null; + editingComponentInstancePropName = ""; +} + +const componentInstancePropsChanged = (instanceProps) => { + updateComponent(newComponent => + newComponent.props[editingComponentInstancePropName] = instanceProps); +} +
@@ -114,15 +144,21 @@ const showDialog = () => {
-
+ {#if editingComponentInstance} + + {:else} +
-
componentDetailsExpanded = !componentDetailsExpanded}> +
componentDetailsExpanded = !componentDetailsExpanded}> Component Details
{#if componentDetailsExpanded} -
+
{
{/if} -

Properties

+
+ Properties +
+ {onPropsChanged} + {onEditComponentProp}/>
+ {/if}
@@ -188,8 +228,8 @@ const showDialog = () => { border-width: 0px 0px 0px 1px; } -.body { - padding: 10px; +.padding { + padding: 0px 5px 0px 10px; } .title { @@ -218,6 +258,7 @@ const showDialog = () => { .section-header { vertical-align: middle; + margin-top: 20px; } \ No newline at end of file diff --git a/packages/builder/src/userInterface/PropControl.svelte b/packages/builder/src/userInterface/PropControl.svelte index 009fd9d780..6f6e238cf0 100644 --- a/packages/builder/src/userInterface/PropControl.svelte +++ b/packages/builder/src/userInterface/PropControl.svelte @@ -11,11 +11,19 @@ export let fieldHasError =() => {}; export let propDef = {}; export let props = {}; export let disabled; +export let index; +export let onEditComponent = () => {}; + +$: isOdd = (index % 2 !== 0); + +const setComponentProp = (props) => { + setProp(propDef.____name, props); +} -
+
{#if propDef.type === "bool"} @@ -33,7 +41,9 @@ export let disabled; setProp(propDef.____name, props)}/> + onEdit={onEditComponent} + onComponentChosen={onEditComponent} + onValueChanged={setComponentProp}/> {:else} .root { - margin-top: 7px; + padding: 3px 5px 7px 10px; + border-style: dotted; + border-width: 0 0 1px 0; + border-color: var(--primary25); } \ No newline at end of file diff --git a/packages/builder/src/userInterface/PropsView.svelte b/packages/builder/src/userInterface/PropsView.svelte index e0d191bbd9..16ee43e264 100644 --- a/packages/builder/src/userInterface/PropsView.svelte +++ b/packages/builder/src/userInterface/PropsView.svelte @@ -8,7 +8,8 @@ import { cloneDeep, isEqual, sortBy, - filter + filter, + difference } from "lodash/fp"; import { pipe } from "../common/core"; import { @@ -29,12 +30,14 @@ export let onValidate = () => {}; export let componentInfo; export let instanceProps = null; export let onPropsChanged = () => {}; +export let onEditComponentProp = () => {}; let errors = []; let props = {}; let propsDefinitions = []; let inheritedPropsDefinitions = []; let inheritedExpanded = false; +let isInstance = false; const isPropInherited = name => includes(name)(componentInfo.inheritedProps); @@ -42,7 +45,8 @@ const isPropInherited = name => $: { if(componentInfo) { - props = instanceProps + isInstance = !!instanceProps; + props = isInstance ? getInstanceProps(componentInfo, instanceProps) : cloneDeep(componentInfo.fullProps); @@ -65,16 +69,22 @@ $: { let setProp = (name, value) => { const newProps = cloneDeep(props); - newProps[name] = value; - const finalProps = {}; + let finalProps = isInstance ? newProps : cloneDeep(componentInfo.component.props); - for(let p of componentInfo.unsetProps) { - if(!isEqual(newProps[p])(componentInfo.rootDefaultProps[p])) { - finalProps[p] = newProps[p]; + if(!isInstance) { + const nowSet = []; + for(let p of componentInfo.unsetProps) { + if(!isEqual(newProps[p])(componentInfo.rootDefaultProps[p])) { + finalProps[p] = newProps[p]; + nowSet.push(p); + } } + componentInfo.unsetProps = difference(nowSet)(componentInfo.unsetProps); } + newProps[name] = value; + finalProps[name] = value; props = newProps; if(validate(finalProps)) onPropsChanged(finalProps); @@ -90,25 +100,30 @@ const validate = (finalProps) => { const fieldHasError = (propName) => some(e => e.propName === propName)(errors); +const onEditComponent = (propName) => () => { + onEditComponentProp(propName); +}
- {#each propsDefinitions as propDef} + {#each propsDefinitions as propDef, index} {/each} {#if inheritedPropsDefinitions.length > 0} -
+
Inherited
{/if} {#if inheritedExpanded} - {#each inheritedPropsDefinitions as propDef} + {#each inheritedPropsDefinitions as propDef, index} {/each} @@ -143,6 +159,10 @@ const fieldHasError = (propName) => font-size:10pt; } +.padding { + padding: 0 10px; +} + .inherited-title { margin-top: 40px; display: grid; diff --git a/packages/builder/src/userInterface/UserInterfaceRoot.svelte b/packages/builder/src/userInterface/UserInterfaceRoot.svelte index 04d7e1e1d6..b4d043ac81 100644 --- a/packages/builder/src/userInterface/UserInterfaceRoot.svelte +++ b/packages/builder/src/userInterface/UserInterfaceRoot.svelte @@ -71,7 +71,7 @@ const newComponent = () => { .root { display: grid; - grid-template-columns: [uiNav] 250px [preview] auto [properties] 250px; + grid-template-columns: [uiNav] 250px [preview] auto [properties] 300px; height: 100%; width: 100%; } diff --git a/packages/builder/src/userInterface/pagesParsing/createProps.js b/packages/builder/src/userInterface/pagesParsing/createProps.js index a8f50c9819..63be9739b8 100644 --- a/packages/builder/src/userInterface/pagesParsing/createProps.js +++ b/packages/builder/src/userInterface/pagesParsing/createProps.js @@ -66,8 +66,11 @@ export const getNewComponentInfo = (allComponents, inherits) => { } -export const getComponentInfo = (allComponents, cname, stack=[], subComponentProps=null) => { - const component = find(c => c.name === cname)(allComponents); +export const getComponentInfo = (allComponents, comp, stack=[], subComponentProps=null) => { + const component = isString(comp) + ? find(c => c.name === comp)(allComponents) + : comp; + const cname = isString(comp) ? comp : comp.name; if(isRootComponent(component)) { subComponentProps = subComponentProps||{}; const p = createProps(cname, component.props, subComponentProps);