48 builder frontend 2 (#70)

* Implement collapsing component hierarchy.

* Save screen when adding new components.

* Allow creation of nested child components.

* Fix level-based indentation of hierarchy.

* Rename updateComponentProps to setComponentProps

* Save layout information to the disk.

* Cleanup: switch to autosubscriptions to prevent memory leaks, remove unused imports.

* Remove unused css.

* Fix incorrect subscription.
This commit is contained in:
pngwn 2020-01-28 21:17:04 +00:00 committed by Michael Shanks
parent 6cb523478d
commit 6aa6c4d433
24 changed files with 1022 additions and 1208 deletions

View File

@ -4,7 +4,7 @@ import {
import {
filter, cloneDeep, sortBy,
map, last, keys, concat, keyBy,
find, isEmpty, reduce, values
find, isEmpty, reduce, values, isEqual
} from "lodash/fp";
import {
pipe, getNode, validate,
@ -93,8 +93,8 @@ export const getStore = () => {
store.createGeneratedComponents = createGeneratedComponents(store);
store.addChildComponent = addChildComponent(store);
store.selectComponent = selectComponent(store);
store.updateComponentProp = updateComponentProp(store);
store.setComponentProp = setComponentProp(store);
store.setComponentStyle = setComponentStyle(store);
return store;
}
@ -456,6 +456,10 @@ const _saveScreen = (store, s, screen) => {
return s;
}
const _save = (appname, screen, store, s) =>
api.post(`/_builder/api/${appname}/screen`, screen)
.then(() => savePackage(store, s));
const createScreen = store => (screenName, layoutComponentName) => {
store.update(s => {
const newComponentInfo = getNewComponentInfo(
@ -597,8 +601,6 @@ const addComponentLibrary = store => async lib => {
return s;
})
}
const removeComponentLibrary = store => lib => {
@ -701,17 +703,31 @@ const addChildComponent = store => component => {
const newComponent = getNewComponentInfo(
s.components, component);
const children = s.currentFrontEndItem.props._children;
let children = s.currentComponentInfo.component ?
s.currentComponentInfo.component.props._children :
s.currentComponentInfo._children;
const component_definition = Object.assign(
cloneDeep(newComponent.fullProps), {
_component: component,
_layout: {}
})
s.currentFrontEndItem.props._children =
children ?
children.concat(component_definition) :
[component_definition];
if (children) {
if (s.currentComponentInfo.component) {
s.currentComponentInfo.component.props._children = children.concat(component_definition);
} else {
s.currentComponentInfo._children = children.concat(component_definition)
}
} else {
if (s.currentComponentInfo.component) {
s.currentComponentInfo.component.props._children = [component_definition];
} else {
s.currentComponentInfo._children = [component_definition]
}
}
_saveScreen(store, s, s.currentFrontEndItem);
return s;
})
@ -725,7 +741,7 @@ const selectComponent = store => component => {
}
const updateComponentProp = store => (name, value) => {
const setComponentProp = store => (name, value) => {
store.update(s => {
const current_component = s.currentComponentInfo;
s.currentComponentInfo[name] = value;
@ -733,5 +749,18 @@ const updateComponentProp = store => (name, value) => {
s.currentComponentInfo = current_component;
return s;
})
}
const setComponentStyle = store => (name, value) => {
store.update(s => {
if (!s.currentComponentInfo._layout) {
s.currentComponentInfo._layout = {};
}
s.currentComponentInfo._layout[name] = value;
// save without messing with the store
_save(s.appname, s.currentFrontEndItem, store, s)
return s;
})
}

View File

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24">
<path fill="none" d="M0 0h24v24H0z"/>
<path fill="currentColor" d="M12 13.172l4.95-4.95 1.414 1.414L12 16 5.636 9.636 7.05 8.222z"/>
</svg>

After

Width:  |  Height:  |  Size: 228 B

View File

@ -3,3 +3,4 @@ export { default as PaintIcon } from './Paint.svelte';
export { default as TerminalIcon } from './Terminal.svelte';
export { default as InputIcon } from './Input.svelte';
export { default as ImageIcon } from './Image.svelte';
export { default as ArrowDownIcon } from './ArrowDown.svelte';

View File

@ -2,11 +2,19 @@
export let meta = [];
export let size = '';
export let values = [];
export let onStyleChanged = () => {};
let _values = values.map(v => v);
$: onStyleChanged(_values);
</script>
<div class="inputs {size}">
{#each meta as { placeholder }, i}
<input type="number" placeholder="{placeholder}" bind:value={values[i]}/>
<input type="number"
placeholder="{placeholder}"
value={values[i]}
on:input={(e) => _values[i] = e.target.value} />
{/each}
</div>

View File

@ -1,58 +1,22 @@
<script>
import PropsView from "./PropsView.svelte";
import { store } from "../builderStore";
import { isRootComponent } from "./pagesParsing/searchComponents";
import IconButton from "../common/IconButton.svelte";
import Textbox from "../common/Textbox.svelte";
import { pipe } from "../common/core";
import {
getScreenInfo
} from "./pagesParsing/createProps";
import { LayoutIcon, PaintIcon, TerminalIcon } from '../common/Icons/';
import CodeEditor from './CodeEditor.svelte';
import LayoutEditor from './LayoutEditor.svelte';
import {
cloneDeep,
join,
split,
map,
keys,
isUndefined,
last
} from "lodash/fp";
import { assign } from "lodash";
let component;
let name = "";
let description = "";
let tagsString = "";
let nameInvalid = "";
let componentInfo = {};
let modalElement
let propsValidationErrors = [];
let originalName="";
let components;
let ignoreStore = false;
// $: shortName = last(name.split("/"));
store.subscribe(s => {
if(ignoreStore) return;
component = s.currentComponentInfo;
if(!component) return;
originalName = component.name;
name = component.name;
description = component.description;
tagsString = join(", ")(component.tags);
componentInfo = s.currentComponentInfo;
components = s.components;
});
const onPropsChanged = store.updateComponentProp;
let current_view = 'props';
$: component = $store.currentComponentInfo;
$: originalName = component.name;
$: name = component.name;
$: description = component.description;
$: componentInfo = $store.currentComponentInfo;
$: components = $store.components;
const onPropChanged = store.setComponentProp;
const onStyleChanged = store.setComponentStyle;
</script>
<div class="root">
@ -78,9 +42,9 @@ let current_view = 'props';
<div class="component-props-container">
{#if current_view === 'props'}
<PropsView {componentInfo} {components} {onPropsChanged} />
<PropsView {componentInfo} {components} {onPropChanged} />
{:else if current_view === 'layout'}
<LayoutEditor />
<LayoutEditor {onStyleChanged} {componentInfo}/>
{:else}
<CodeEditor />
{/if}

View File

@ -5,18 +5,14 @@ import { store } from "../builderStore";
export let onComponentChosen = () => {};
let components = [];
let phrase = "";
store.subscribe(s => {
components = s.components;
});
components = $store.components;
$: filteredComponents =
!phrase
? []
: searchAllComponents(components, phrase);
</script>
<div class="root">

View File

@ -4,10 +4,7 @@ import {
} from "./pagesParsing/searchComponents"
import { splitName } from "./pagesParsing/splitRootComponentName.js"
import { store } from "../builderStore";
import {
groupBy, keys, find, sortBy
} from "lodash/fp";
import { pipe } from "../common/core";
import { find, sortBy } from "lodash/fp";
export let onComponentChosen;
export let onGeneratorChosen;
@ -38,12 +35,12 @@ const addRootComponent = (c, all, isGenerator) => {
};
store.subscribe(s => {
$: {
const newComponentLibraries = [];
const newscreens = [];
for(let comp of sortBy(["name"])(s.components)) {
for(let comp of sortBy(["name"])($store.components)) {
if(isRootComponent(comp)) {
addRootComponent(
comp,
@ -54,7 +51,7 @@ store.subscribe(s => {
}
}
for(let generator of s.generators) {
for(let generator of $store.generators) {
addRootComponent(
generator,
newComponentLibraries,
@ -63,12 +60,7 @@ store.subscribe(s => {
screens = sortBy(["name"])(newscreens);
componentLibraries = newComponentLibraries;
});
};
</script>
{#each componentLibraries as lib}

View File

@ -4,19 +4,15 @@ import ComponentsHierarchyChildren from './ComponentsHierarchyChildren.svelte';
import {
last,
sortBy,
filter,
map,
uniqWith,
isEqual,
trimCharsStart,
trimChars,
join,
includes
} from "lodash/fp";
import { pipe } from "../common/core";
import getIcon from "../common/icon";
import { store } from "../builderStore";
import { ArrowDownIcon } from '../common/Icons/'
export let components = []
@ -32,34 +28,15 @@ const normalizedName = name => pipe(name, [
const lastPartOfName = (c) =>
last(c.name ? c.name.split("/") : c._component.split("/"))
const expandFolder = folder => {
const expandedFolder = {...folder};
if(expandedFolder.isExpanded) {
expandedFolder.isExpanded = false;
expandedFolders = filter(f => f.name !== folder.name)(expandedFolders);
} else {
expandedFolder.isExpanded = true;
expandedFolders.push(folder.name);
}
const newFolders = [...subfolders];
newFolders.splice(
newFolders.indexOf(folder),
1,
expandedFolder);
subfolders = newFolders;
}
const isComponentSelected = (type, current,c) =>
type==="screen"
&& current
&& current.name === c.name
const isComponentSelected = (current, comp) =>
current &&
current.component &&
comp.component &&
current.component.name === comp.component.name
const isFolderSelected = (current, folder) =>
isInSubfolder(current, folder)
$: _components =
pipe(components, [
map(c => ({component: c, title:lastPartOfName(c)})),
@ -71,20 +48,32 @@ function select_component(screen, component) {
store.selectComponent(component);
}
const isScreenSelected = component =>
component.component &&
$store.currentFrontEndItem &&
component.component.name === $store.currentFrontEndItem.name;
</script>
<div class="root">
{#each _components as component}
<div class="hierarchy-item component"
class:selected={isComponentSelected($store.currentFrontEndType, $store.currentFrontEndItem, component.component)}
class:selected={isComponentSelected($store.currentComponentInfo, component)}
on:click|stopPropagation={() => store.setCurrentScreen(component.component.name)}>
<span class="icon" style="transform: rotate({isScreenSelected(component) ? 0 : -90}deg);">
{#if component.component.props && component.component.props._children}
<ArrowDownIcon />
{/if}
</span>
<span class="title">{component.title}</span>
</div>
{#if component.component.props && component.component.props._children}
{#if isScreenSelected(component) && component.component.props && component.component.props._children}
<ComponentsHierarchyChildren components={component.component.props._children}
currentComponent={$store.currentComponentInfo}
onSelect={child => select_component(component.component.name, child)} />
{/if}
{/each}
@ -102,9 +91,10 @@ function select_component(screen, component) {
.hierarchy-item {
cursor: pointer;
padding: 11px 7px;
margin: 5px 0;
border-radius: 5px;
display: flex;
align-items: center;
}
.hierarchy-item:hover {
@ -112,12 +102,6 @@ function select_component(screen, component) {
background: #fafafa;
}
.currentfolder {
color: var(--secondary100);
}
.selected {
color: var(--button-text);
background: var(--background-button)!important;
@ -127,5 +111,10 @@ function select_component(screen, component) {
margin-left: 10px;
}
.icon {
display: inline-block;
transition: 0.2s;
width: 24px;
height: 24px;
}
</style>

View File

@ -3,22 +3,55 @@
import { pipe } from "../common/core";
export let components = [];
export let currentComponent;
export let onSelect = () => {};
export let level = 0;
const capitalise = s => s.substring(0,1).toUpperCase() + s.substring(1);
const get_name = s => last(s.split('/'));
const get_capitalised_name = name => pipe(name, [get_name,capitalise]);
</script>
{#each components as component}
<ul>
{#each components as component}
<li on:click|stopPropagation={() => onSelect(component)}>
<span class="item"
class:selected={currentComponent === component}
style="padding-left: {level * 20 + 67}px">
{get_capitalised_name(component._component)}
</span>
{#if component._children}
<svelte:self components={component._children}/>
<svelte:self components={component._children}
{currentComponent}
{onSelect}
level={level + 1}/>
{/if}
</li>
</ul>
{/each}
</ul>
<style>
ul {
list-style: none;
padding-left: 0;
margin: 0;
}
.item {
display: block;
padding: 11px 67px;
border-radius: 3px;
}
.item:hover {
background: #fafafa;
cursor: pointer;
}
.selected {
color: var(--button-text);
background: var(--background-button)!important;
}
</style>

View File

@ -1,16 +1,11 @@
<script>
import {
isRootComponent
} from "./pagesParsing/searchComponents"
import { splitName } from "./pagesParsing/splitRootComponentName.js"
import { store } from "../builderStore";
import {
groupBy, keys, find, sortBy
} from "lodash/fp";
import { pipe } from "../common/core";
import { find, sortBy } from "lodash/fp";
import { ImageIcon, InputIcon, LayoutIcon } from '../common/Icons/';
let componentLibraries = [];
let current_view = 'text';
const addRootComponent = (c, all) => {
const { libName } = splitName(c.name);
@ -32,21 +27,17 @@ const addRootComponent = (c, all) => {
const onComponentChosen = store.addChildComponent;
store.subscribe(s => {
$: {
const newComponentLibraries = [];
for(let comp of sortBy(["name"])(s.components)) {
for(let comp of sortBy(["name"])($store.components)) {
addRootComponent(
comp,
newComponentLibraries);
}
componentLibraries = newComponentLibraries;
});
let current_view = 'text';
}
</script>
<div class="root">
@ -115,13 +106,6 @@ let current_view = 'text';
min-height: 0px;
}
.inner-header {
font-size: 0.9em;
font-weight: bold;
margin-top: 7px;
margin-bottom: 3px;
}
.component {
padding: 0 15px;
cursor: pointer;
@ -147,13 +131,6 @@ let current_view = 'text';
opacity: 0.6;
}
.component > .description {
font-size: 0.8em;
color: var(--secondary75);
display: inline-block;
margin-left: 10px;
}
ul {
list-style: none;
display: flex;

View File

@ -9,8 +9,6 @@ const isSelected = tab =>
const selectTab = tab =>
selected = tab;
</script>
<div class="root">

View File

@ -1,41 +1,25 @@
<script>
import { store } from "../builderStore";
import { makeLibraryUrl } from "../builderStore/loadComponentLibraries";
import {
last, split, map, join
} from "lodash/fp";
import { map, join } from "lodash/fp";
import { pipe } from "../common/core";
import { splitName } from "./pagesParsing/splitRootComponentName"
import { afterUpdate } from 'svelte';
import { getRootComponent } from "./pagesParsing/getRootComponent";
import { buildPropsHierarchy } from "./pagesParsing/buildPropsHierarchy";
$: hasComponent = !!$store.currentFrontEndItem;
let hasComponent=false;
let stylesheetLinks = "";
let appDefinition = {};
store.subscribe(s => {
hasComponent = !!s.currentFrontEndItem;
stylesheetLinks = pipe(s.pages.stylesheets, [
$: stylesheetLinks = pipe($store.pages.stylesheets, [
map(s => `<link rel="stylesheet" href="${s}"/>`),
join("\n")
]);
appDefinition = {
componentLibraries: s.loadLibraryUrls(),
$: appDefinition = {
componentLibraries: $store.loadLibraryUrls(),
props: buildPropsHierarchy(
s.components,
s.screens,
s.currentFrontEndItem),
hierarchy: s.hierarchy,
$store.components,
$store.screens,
$store.currentFrontEndItem),
hierarchy: $store.hierarchy,
appRootPath: ""
};
});
</script>
@ -52,7 +36,6 @@ store.subscribe(s => {
window["##BUDIBASE_APPDEFINITION##"] = ${JSON.stringify(appDefinition)};
import('/_builder/budibase-client.esm.mjs')
.then(module => {
console.log(module, window);
module.loadBudibase({ window, localStorage });
})
</script>
@ -73,7 +56,6 @@ store.subscribe(s => {
<style>
.component-container {
grid-row-start: middle;
grid-column-start: middle;
@ -91,5 +73,4 @@ store.subscribe(s => {
top: 0;
width: 100%;
}
</style>

View File

@ -1,68 +1,31 @@
<script>
import PropsView from "./PropsView.svelte";
import { store } from "../builderStore";
import { isRootComponent } from "./pagesParsing/searchComponents";
import IconButton from "../common/IconButton.svelte";
import Textbox from "../common/Textbox.svelte";
import UIkit from "uikit";
import { pipe } from "../common/core";
import {
getScreenInfo
} from "./pagesParsing/createProps";
import Button from "../common/Button.svelte";
import ButtonGroup from "../common/ButtonGroup.svelte";
import { LayoutIcon, PaintIcon, TerminalIcon } from '../common/Icons/';
import {
cloneDeep,
join,
split,
map,
keys,
isUndefined,
last
} from "lodash/fp";
import { assign } from "lodash";
let component;
let name = "";
let description = "";
let tagsString = "";
let nameInvalid = "";
let componentInfo;
let modalElement
let propsValidationErrors = [];
let originalName="";
let components;
let ignoreStore = false;
$: component = $store.currentFrontEndItem;
$: componentInfo = $store.currentComponentInfo;
$: components = $store.components;
$: shortName = last(name.split("/"));
store.subscribe(s => {
if(ignoreStore) return;
component = s.currentFrontEndItem;
if(!component) return;
originalName = component.name;
name = component.name;
description = component.description;
tagsString = join(", ")(component.tags);
componentInfo = s.currentComponentInfo;
components = s.components;
});
const updateComponent = doChange => {
const newComponent = cloneDeep(component);
doChange(newComponent);
component = newComponent;
componentInfo = getScreenInfo(components, newComponent);
}
const updateComponent = doChange =>
doChange(cloneDeep(component));
const onPropsChanged = newProps => {
updateComponent(newComponent =>
assign(newComponent.props, newProps));
}
</script>
<div class="root">
@ -74,19 +37,13 @@ const onPropsChanged = newProps => {
</ul>
<div class="component-props-container">
<PropsView
{componentInfo}
{onPropsChanged} />
</div>
</div>
<style>
.root {
height: 100%;
display: flex;
@ -94,15 +51,6 @@ const onPropsChanged = newProps => {
}
.title {
padding: 1rem;
display: grid;
grid-template-columns: [name] 1fr [actions] auto;
color: var(--secondary100);
font-size: .9rem;
font-weight: bold;
}
.title > div:nth-child(1) {
grid-column-start: name;
color: var(--secondary100);
@ -139,9 +87,4 @@ li button {
border-radius: 5px;
padding: 12px;
}
.selected {
background: lightblue;
}
</style>

View File

@ -9,14 +9,8 @@ import {EVENT_TYPE_MEMBER_NAME} from "../common/eventHandlers";
export let parentProps;
export let propDef;
export let onValueChanged;
export let onValidate = () => {};
let events = [];
let elementErrors = {};
$: {
events = parentProps[propDef.____name];
}
$: events = parentProps[propDef.____name];
const addHandler = () => {
const newHandler = {parameters:{}};
@ -67,15 +61,12 @@ const removeHandler = (index) => () => {
<style>
.addelement-container {
cursor: pointer;
padding: 3px 0px;
text-align: center;
}
.addelement-container:hover {
background-color: var(--primary25);
margin-top: 5px;
@ -94,5 +85,4 @@ const removeHandler = (index) => () => {
border-width: 1px 0 0 0;
border-color: var(--primary25);
}
</style>

View File

@ -12,22 +12,19 @@ export let event;
export let onChanged;
export let onRemoved;
let events;
let eventType;
let parameters = [];
store.subscribe(s => {
events = allHandlers(
{hierarchy: s.hierarchy},
$: events = allHandlers(
{hierarchy: $store.hierarchy},
userWithFullAccess({
hierarchy: s.hierarchy,
actions: keyBy("name")(s.actions)
actions: keyBy("name")($store.actions)
})
);
});
$: {
if(event) {
$: if(event) {
eventType = event[EVENT_TYPE_MEMBER_NAME];
parameters = pipe(event.parameters, [
keys,
@ -37,7 +34,6 @@ $: {
eventType = "";
parameters = [];
}
}
const eventChanged = (type, parameters) => {
const paramsAsObject = reduce(
@ -96,7 +92,6 @@ const onParameterChanged = index => val => {
{/if}
<style>
.type-selector-container {
display: flex;
}
@ -107,5 +102,4 @@ const onParameterChanged = index => val => {
width: 50px;
flex: 1 0 auto;
}
</style>

View File

@ -1,13 +1,8 @@
<script>
import InputGroup from '../common/Inputs/InputGroup.svelte';
let grid_values = ['', '', '', ''];
let column_values = ['', ''];
let row_values = ['', ''];
let gap_values = [''];
let margin_values = ['', '', '', ''];
let padding_values = ['', '', '', ''];
let zindex_values = [''];
export let onStyleChanged = () => {};
export let componentInfo;
const tbrl = [
{ placeholder: 'T' },
@ -22,6 +17,27 @@
]
const single = [{ placeholder: '' }];
$: layout = componentInfo._layout;
$: positions = {
gridarea: ['Grid Area', tbrl, 'small'],
column: ['Column', se],
row: ['Row', se],
gap: ['Gap', single],
};
$: spacing = {
margin: ['Margin', tbrl, 'small'],
padding: ['Padding', tbrl, 'small']
};
$: zindex = {
zindex: ['Z-Index', single]
}
const newValue = n => Array(n).fill('');
</script>
@ -30,48 +46,41 @@
<h4>Positioning</h4>
<div class="layout-pos">
{#each Object.entries(positions) as [key, [name, meta, size]]}
<div class="grid">
<h5>Grid Area:</h5>
<InputGroup meta={tbrl} bind:values={grid_values} size="small"/>
</div>
<div class="grid">
<h5>Column:</h5>
<InputGroup meta={se} bind:values={column_values} />
</div>
<div class="grid">
<h5>Row:</h5>
<InputGroup meta={se} bind:values={row_values} />
</div>
<div class="grid">
<h5>Gap:</h5>
<InputGroup meta={single} bind:values={gap_values} />
<InputGroup onStyleChanged={_value => onStyleChanged(key, _value)}
values={layout[key] || newValue(meta.length)}
{meta}
{size} />
</div>
{/each}
</div>
<h4>Spacing</h4>
<div class="layout-spacing">
{#each Object.entries(spacing) as [key, [name, meta, size]]}
<div class="grid">
<h5>Margin:</h5>
<InputGroup meta={tbrl} bind:values={margin_values} size="small"/>
</div>
<div class="grid">
<h5>Padding:</h5>
<InputGroup meta={tbrl} bind:values={padding_values} size="small"/>
<h5>Grid Area:</h5>
<InputGroup onStyleChanged={_value => onStyleChanged(key, _value)}
values={layout[key] || newValue(meta.length)}
{meta}
{size} />
</div>
{/each}
</div>
<h4>Z-Index</h4>
<div class="layout-layer">
{#each Object.entries(zindex) as [key, [name, meta, size]]}
<div class="grid">
<h5>Z-Index:</h5>
<InputGroup meta={single} bind:values={zindex_values}/>
<h5>Grid Area:</h5>
<InputGroup onStyleChanged={_value => onStyleChanged(key, _value)}
values={layout[key] || newValue(meta.length)}
{meta}
{size} />
</div>
{/each}
</div>
<style>
@ -112,5 +121,4 @@
.grid {
grid-template-columns: 70px 1fr;
}
</style>

View File

@ -1,5 +1,4 @@
<script>
import ComponentSelector from "./ComponentSelector.svelte";
import { store } from "../builderStore";
import PropsView from "./PropsView.svelte";
@ -109,24 +108,4 @@ const screenNameExists = (name) =>
h1 {
font-size:1.2em;
}
.component-option {
border-style: solid;
border-color: var(--slate);
border-width: 0 0 1px 0;
padding: 3px;
}
.component-option:hover {
background-color: var(--lightslate);
}
.component-name {
font-size: 11pt;
}
.lib-name {
font-size: 9pt;
}
</style>

View File

@ -10,23 +10,16 @@ import {
filter, find, concat
} from "lodash/fp";
let entryComponent;
let title = "";
let components = [];
let page={};
const notSeletedComponent = {name:"(none selected)"};
store.subscribe(s => {
page = s.pages[s.currentPageName];
if(!page) return;
title = page.index.title;
components = pipe(s.components, [
filter(s => !isRootComponent(s)),
$: page = $store.pages[$store.currentPageName];
$: title = page.index.title;
$: components = pipe($store.components, [
filter(store => !isRootComponent($store)),
concat([notSeletedComponent])
]);
entryComponent = find(c => c.name === page.appBody)(components);
if(!entryComponent) entryComponent = notSeletedComponent;
});
$: entryComponent = find(c => c.name === page.appBody)(components) || notSeletedComponent;
const save = () => {
if(!title || !entryComponent || entryComponent === notSeletedComponent) return;
@ -38,7 +31,6 @@ const save = () => {
}
store.savePage(page);
}
</script>
<div class="root">

View File

@ -16,7 +16,6 @@ const pages = [{
}]
store.setCurrentPage('main')
</script>
<div class="root">
@ -31,7 +30,6 @@ store.setCurrentPage('main')
</div>
<style>
.root {
padding-bottom: 10px;
font-size: .9rem;
@ -72,5 +70,4 @@ select {
pointer-events: none;
color: var(--primary100);
}
</style>

View File

@ -1,13 +1,10 @@
<script>
import Checkbox from "../common/Checkbox.svelte";
import Textbox from "../common/Textbox.svelte";
import Dropdown from "../common/Dropdown.svelte";
import EventListSelector from "./EventListSelector.svelte";
import StateBindingControl from "./StateBindingControl.svelte";
export let setProp = () => {};
export let disabled;
export let index;
export let prop_name;
export let prop_value;
@ -18,20 +15,11 @@ $: isOdd = (index % 2 !== 0);
const setComponentProp = (props) => {
setProp(propDef.____name, props);
}
</script>
<div class="root" >
{#if prop_type === "event"}
<!-- <h5>{prop_name}</h5>
<EventListSelector parentProps={props}
{propDef}
onValueChanged={setComponentProp} /> -->
{:else }
{#if prop_type !== "event" }
<h5>{prop_name}</h5>
<StateBindingControl value={prop_value}
@ -40,11 +28,9 @@ const setComponentProp = (props) => {
onChanged={v => setProp(prop_name, v)}/>
{/if}
</div>
<style>
.root {
height: 40px;
margin-bottom: 15px;
@ -62,5 +48,4 @@ h5 {
padding-top: 12px;
margin-bottom: 0;
}
</style>

View File

@ -1,27 +1,16 @@
<script>
import {
keys, map, some, includes,
cloneDeep, isEqual, sortBy,
filter, difference
} from "lodash/fp";
import { pipe } from "../common/core";
import { getInstanceProps } from "./pagesParsing/createProps";
import Checkbox from "../common/Checkbox.svelte";
import { some, includes, filter } from "lodash/fp";
import Textbox from "../common/Textbox.svelte";
import Dropdown from "../common/Dropdown.svelte";
import PropControl from "./PropControl.svelte";
import IconButton from "../common/IconButton.svelte";
export let componentInfo;
export let instanceProps = null;
export let onPropsChanged = () => {};
export let onPropChanged = () => {};
export let components;
let errors = [];
let props = {};
let propsDefinitions = [];
let isInstance = false;
const props_to_ignore = ['_component','_children', '_layout'];
@ -33,12 +22,11 @@ function find_type(prop_name) {
}
let setProp = (name, value) => {
onPropsChanged(name, value);
onPropChanged(name, value);
}
const fieldHasError = (propName) =>
some(e => e.propName === propName)(errors);
</script>
<div class="root">
@ -65,7 +53,6 @@ const fieldHasError = (propName) =>
<style>
.root {
font-size:10pt;
width: 100%;
@ -80,5 +67,4 @@ const fieldHasError = (propName) =>
flex: 1 1 auto;
min-width: 250px;
}
</style>

View File

@ -1,5 +1,4 @@
<script>
import { store } from "../builderStore";
import Textbox from "../common/Textbox.svelte";
import Button from "../common/Button.svelte";
@ -9,13 +8,9 @@ import UIkit from "uikit";
let addNewLib = "";
let addNewStylesheet = "";
let addComponentError = "";
let modalElement;
let components;
store.subscribe(s => {
components = s.components;
})
$: components = $store.components;
const removeLibrary = lib => {
const dependencies = libraryDependencies(components, lib);
@ -46,7 +41,6 @@ export const close = () => {
export const show = () => {
UIkit.modal(modalElement).show();
}
</script>
<div bind:this={modalElement} id="new-component-modal" uk-modal>
@ -103,7 +97,6 @@ export const show = () => {
</div>
<style>
.section-container {
padding: 15px;
border-style: dotted;
@ -141,5 +134,4 @@ p > span {
.header > div:nth-child(2) {
grid-column-start: icon;
}
</style>

View File

@ -1,7 +1,4 @@
<script>
import {
isString
} from "lodash/fp";
import IconButton from "../common/IconButton.svelte";
import {
isBinding, getBinding, setBinding
@ -66,11 +63,6 @@ const setBindingSource = ev => {
bind(bindingPath, bindingFallbackValue, ev.target.value);
}
// const makeBinding = () => {
// forceIsBound=true;
// isExpanded=true;
// }
</script>
{#if isBound}
@ -113,15 +105,12 @@ const setBindingSource = ev => {
<div class="unbound-container">
{#if type === "bool"}
<div>
<IconButton icon={value == true ? "check-square" : "square"}
size="19"
on:click={() => onChanged(!value)} />
</div>
{:else if type === "options"}
<select class="uk-select uk-form-small"
value={value}
on:change={ev => onChanged(ev.target.value)}>
@ -129,14 +118,10 @@ const setBindingSource = ev => {
<option value={option}>{option}</option>
{/each}
</select>
{:else}
<input on:change={ev => onChanged(ev.target.value)}
bind:value={value}
style="flex: 1 0 auto;" />
{/if}
</div>

View File

@ -1,10 +1,7 @@
<script>
import ComponentsHierarchy from "./ComponentsHierarchy.svelte";
import PagesList from "./PagesList.svelte"
import { store } from "../builderStore";
import getIcon from "../common/icon";
import { isComponent } from "./pagesParsing/searchComponents";
import IconButton from "../common/IconButton.svelte";
import Modal from "../common/Modal.svelte";
import NewComponent from "./NewComponent.svelte";
@ -14,6 +11,7 @@ import PageView from "./PageView.svelte";
import ComponentsPaneSwitcher from "./ComponentsPaneSwitcher.svelte";
let newComponentPicker;
const newComponent = () => {
newComponentPicker.show();
}
@ -22,7 +20,6 @@ let settingsView;
const settings = () => {
settingsView.show();
}
</script>
<div class="root">
@ -44,11 +41,6 @@ const settings = () => {
<span class="components-nav-header">Screens</span>
<div>
<!-- <IconButton icon="settings"
size="14px"
on:click={settings}/> -->
<!-- <IconButton icon="plus"
on:click={newComponent}/> -->
<button on:click={newComponent}>+</button>
</div>
</div>
@ -185,5 +177,4 @@ button {
font-weight: 400;
color: #999;
}
</style>