working components nav - not styled properly

This commit is contained in:
michael shanks 2019-08-02 14:54:10 +01:00
parent fc9c1a1fbe
commit d27ec9e0a5
35 changed files with 1771 additions and 566 deletions

View File

@ -34,7 +34,7 @@ const production = !process.env.ROLLUP_WATCH;
const lodash_fp_exports = ["union", "reduce", "isUndefined", "cloneDeep", "split", "some", "map", "filter", "isEmpty", "countBy", "includes", "last", "find", "constant",
"take", "first", "intersection", "mapValues", "isNull", "has", "isNumber", "isString", "isBoolean", "isDate", "isArray", "isObject", "clone", "values", "keyBy",
"keys", "orderBy", "concat", "reverse", "difference", "merge", "flatten", "each", "pull", "join", "defaultCase", "uniqBy", "every", "uniqWith", "isFunction", "groupBy",
"differenceBy", "intersectionBy", "isEqual", "max", "sortBy", "assign"];
"differenceBy", "intersectionBy", "isEqual", "max", "sortBy", "assign", "uniq", "trimChars", "trimCharsStart"];
const lodash_exports = ["toNumber", "flow", "isArray", "join", "replace", "trim", "dropRight", "takeRight", "head", "isUndefined", "isNull", "isNaN", "reduce", "isEmpty",
"constant", "tail", "includes", "startsWith", "findIndex", "isInteger", "isDate", "isString", "split", "clone", "keys", "isFunction", "merge", "has", "isBoolean", "isNumber",

View File

@ -6,7 +6,7 @@ import ButtonGroup from "../common/ButtonGroup.svelte";
import {cloneDeep, filter, keys,
map, isUndefined} from "lodash/fp";
import ErrorsBox from "../common/ErrorsBox.svelte";
import {validateActions, chain} from "../common/core";
import {validateActions, pipe} from "../common/core";
import getIcon from "../common/icon";
export let action;
@ -18,7 +18,7 @@ let optKey = "";
let optValue = "";
let clonedAction = cloneDeep(action);
let initialOptions = chain(action.initialOptions, [
let initialOptions = pipe(action.initialOptions, [
keys,
map(k => ({key:k, value:action.initialOptions[k]}))
]);
@ -39,7 +39,7 @@ const addNewOption = () => {
const removeOption = (opt) => {
if(opt) {
delete clonedAction.initialOptions[opt.key]
initialOptions = chain(initialOptions, [
initialOptions = pipe(initialOptions, [
filter(o => o.key !== opt.key)
]);
}
@ -48,10 +48,10 @@ const removeOption = (opt) => {
const save = () => {
const newActionsList = [
...chain(allActions ,[filter(a => a !== action)]),
...pipe(allActions ,[filter(a => a !== action)]),
clonedAction]
errors = chain(newActionsList ,[
errors = pipe(newActionsList ,[
validateActions,
map(e => e.error)
]);

View File

@ -6,7 +6,7 @@ import Button from "../common/Button.svelte";
import ButtonGroup from "../common/ButtonGroup.svelte";
import ActionView from "./ActionView.svelte";
import Modal from "../common/Modal.svelte";
import {chain} from "../common/core";
import {pipe} from "../common/core";
import {keys, map, join} from "lodash/fp";
export let editingActionIsNew = false;
@ -19,7 +19,7 @@ export let onActionCancel = () => {};
$: isEditing = (editingAction !== null);
let getDefaultOptionsHtml = defaultOptions =>
chain(defaultOptions, [
pipe(defaultOptions, [
keys,
map(k => `<span style="color:var(--slate)">${k}: </span>${JSON.stringify(defaultOptions[k])}`),
join("<br>")

View File

@ -14,7 +14,7 @@ let editingTrigger = null;
let editingTriggerIsNew = true;
let getDefaultOptionsHtml = defaultOptions =>
chain(defaultOptions, [
pipe(defaultOptions, [
keys,
map(k => `<span style="color:var(--slate)">${k}: </span>${JSON.parse(typeOptions[k])}`),
join("<br>")

View File

@ -8,7 +8,7 @@ import CodeArea from "../common/CodeArea.svelte";
import {cloneDeep, filter, keys, some,
map, isUndefined} from "lodash/fp";
import ErrorsBox from "../common/ErrorsBox.svelte";
import {validateTriggers, chain, events} from "../common/core";
import {validateTriggers, pipe, events} from "../common/core";
import getIcon from "../common/icon";
export let trigger;
@ -24,7 +24,7 @@ $: actionNames = map(a => a.name)(allActions);
let cancel = () => onFinished();
let save = () => {
const newTriggersList = [
...chain(allTriggers ,[filter(t => t !== trigger)]),
...pipe(allTriggers ,[filter(t => t !== trigger)]),
clonedTrigger]
errors = validateTriggers(newTriggersList, allActions);

View File

@ -16,7 +16,7 @@ import {
reduce
} from "lodash/fp";
import {
chain,
pipe,
getNode,
validate,
constructHierarchy,
@ -27,8 +27,6 @@ import { defaultPagesObject } from "../userInterface/pagesParsing/defaultPagesOb
import api from "./api";
import { isRootComponent } from "../userInterface/pagesParsing/searchComponents";
const pipe = common.$;
export const getStore = () => {
const initial = {
@ -41,6 +39,7 @@ export const getStore = () => {
mainUi:{},
unauthenticatedUi:{},
allComponents:[],
currentFrontEndItem:null,
currentNodeIsNew: false,
errors: [],
activeNav: "database",
@ -74,6 +73,8 @@ export const getStore = () => {
store.addComponentLibrary = addComponentLibrary(store);
store.renameDerivedComponent = renameDerivedComponent(store);
store.deleteDerivedComponent = deleteDerivedComponent(store);
store.setCurrentComponent = setCurrentComponent(store);
store.setCurrentPage = setCurrentPage(store);
return store;
}
@ -124,7 +125,7 @@ const combineComponents = (root, derived) => {
all.push(root[r]);
}
for(let d in derived) {
all.push(root[d]);
all.push(derived[d]);
}
return all;
}
@ -192,7 +193,7 @@ const saveCurrentNode = (store) => () => {
if(!!existingNode) {
// remove existing
index = existingNode.parent().children.indexOf(existingNode);
existingNode.parent().children = chain(existingNode.parent().children, [
existingNode.parent().children = pipe(existingNode.parent().children, [
filter(c => c.nodeId !== existingNode.nodeId)
]);
}
@ -210,7 +211,7 @@ const saveCurrentNode = (store) => () => {
return currentIndex >= index ? currentIndex + 1 : currentIndex;
}
parentNode.children = chain(parentNode.children, [
parentNode.children = pipe(parentNode.children, [
sortBy(newIndexOfchild)
]);
@ -284,7 +285,7 @@ const saveAction = store => (newAction, isNew, oldAction=null) => {
: find(a => a.name === oldAction.name)(s.actions);
if(existingAction) {
s.actions = chain(s.actions, [
s.actions = pipe(s.actions, [
map(a => a === existingAction ? newAction : a)
]);
} else {
@ -311,7 +312,7 @@ const saveTrigger = store => (newTrigger, isNew, oldTrigger=null) => {
: find(a => a.name === oldTrigger.name)(s.triggers);
if(existingTrigger) {
s.triggers = chain(s.triggers, [
s.triggers = pipe(s.triggers, [
map(a => a === existingTrigger ? newTrigger : a)
]);
} else {
@ -337,7 +338,7 @@ const saveLevel = store => (newLevel, isNew, oldLevel=null) => {
: find(a => a.name === oldLevel.name)(s.accessLevels);
if(existingLevel) {
s.accessLevels = chain(s.accessLevels, [
s.accessLevels = pipe(s.accessLevels, [
map(a => a === existingLevel ? newLevel : a)
]);
} else {
@ -371,7 +372,7 @@ const saveDerivedComponent = store => (derivedComponent) => {
store.update(s => {
const components = pipe(s.allComponents, [
filter(c => c._name !== derivedComponent._name),
filter(c => c.name !== derivedComponent.name),
concat([derivedComponent])
]);
@ -387,7 +388,7 @@ const deleteDerivedComponent = store => name => {
store.update(s => {
const allComponents = pipe(s.allComponents, [
filter(c => c._name !== name)
filter(c => c.name !== name)
]);
s.allComponents = allComponents;
@ -402,13 +403,13 @@ const renameDerivedComponent = store => (oldname, newname) => {
store.update(s => {
const component = pipe(s.allComponents, [
find(c => c._name === name)
find(c => c.name === name)
]);
component._name = newname;
component.name = newname;
const allComponents = pipe(s.allComponents, [
filter(c => c._name !== name),
filter(c => c.name !== name),
concat([component])
]);
@ -466,7 +467,7 @@ const refreshComponents = store => async () => {
const rootComponents = pipe(components, [
keys,
map(k => ({...components[k], _name:k}))
map(k => ({...components[k], name:k}))
]);
store.update(s => {
@ -496,3 +497,20 @@ const savePackage = (store, s) => {
api.post(`/_builder/api/${s.appname}/appPackage`, data);
}
const setCurrentComponent = store => component => {
store.update(s => {
s.currentFrontEndItem = component;
s.currentFrontEndIsComponent = true;
return s;
})
}
const setCurrentPage = store => pageName => {
store.update(s => {
const props = s.pages[pageName];
s.currentFrontEndItem = {props, name:pageName};
s.currentFrontEndIsComponent = false;
return s;
})
}

View File

@ -3,12 +3,12 @@ import {hierarchy as hierarchyFunctions,
import {find, filter, includes, keyBy, some,
flatten, map} from "lodash/fp";
export const chain = common.$;
export const pipe = common.$;
export const events = common.eventsList;
export const getNode = (hierarchy, nodeId) =>
chain(hierarchy, [
pipe(hierarchy, [
hierarchyFunctions.getFlattenedHierarchy,
find(n => n.nodeId === nodeId || n.nodeKey() === nodeId)
]);
@ -35,7 +35,7 @@ export const validate = {
};
export const getPotentialReverseReferenceIndexes = (hierarchy, refIndex) => {
const res = chain(hierarchy, [
const res = pipe(hierarchy, [
hierarchyFunctions.getFlattenedHierarchy,
filter(n => hierarchyFunctions.isAncestor(refIndex)(n)
|| hierarchyFunctions.isAncestor(refIndex)(n.parent())),
@ -48,7 +48,7 @@ export const getPotentialReverseReferenceIndexes = (hierarchy, refIndex) => {
}
export const getPotentialReferenceIndexes = (hierarchy, record) =>
chain(hierarchy, [
pipe(hierarchy, [
hierarchyFunctions.getFlattenedHierarchy,
filter(hierarchyFunctions.isAncestorIndex),
filter(i => hierarchyFunctions.isAncestor(record)(i.parent())

View File

@ -1,2 +1,3 @@
import feather from "feather-icons";
export default icon => feather.toSvg(icon);
const getIcon = (icon, size) => feather.icons[icon].toSvg({height:size||"24", width:size||"24"});
export default getIcon;

View File

@ -8,14 +8,14 @@ import {store} from "../builderStore";
import {filter, some, map} from "lodash/fp";
import {hierarchy as hierarchyFunctions, common} from "../../../core/src";
const chain = common.$;
const pipe = common.$;
let index;
let indexableRecords = [];
store.subscribe($store => {
index = $store.currentNode;
indexableRecords = chain($store.hierarchy,[
indexableRecords = pipe($store.hierarchy,[
hierarchyFunctions.getFlattenedHierarchy,
filter(hierarchyFunctions.isDecendant(index.parent())),
filter(hierarchyFunctions.isRecord),

View File

@ -9,7 +9,7 @@ import {map, join, filter, some,
find, keys, isDate} from "lodash/fp";
import { store } from "../builderStore";
import {common, hierarchy as h} from "../../../core/src";
import {templateApi, chain, validate} from "../common/core";
import {templateApi, pipe, validate} from "../common/core";
let record;
let getIndexAllowedRecords;
@ -26,7 +26,7 @@ store.subscribe($store => {
record = $store.currentNode;
const flattened = h.getFlattenedHierarchy($store.hierarchy);
getIndexAllowedRecords = index =>
chain(index.allowedRecordNodeIds, [
pipe(index.allowedRecordNodeIds, [
filter(id => some(n => n.nodeId === id)(flattened)),
map(id => find(n => n.nodeId === id)
(flattened).name),
@ -73,7 +73,7 @@ let getTypeOptionsValueText = value => {
}
let getTypeOptions = typeOptions =>
chain(typeOptions, [
pipe(typeOptions, [
keys,
map(k => `<span style="color:var(--slate)">${k}: </span>${getTypeOptionsValueText(typeOptions[k])}`),
join("<br>")

View File

@ -1,12 +1,14 @@
:root {
--primary100: #454CA0FF;
--primary75: #454CA0BF;
--primary50: #454CA080;
--primary25: #454CA040;
--primary10: #454CA01A;
--primarydark: #3F448A;
--secondary100: #162B4DFF;
--secondary75: #162B4DBF;
--secondary50: #162B4D80;
--secondary25: #162B4D40;
--secondary10: #162B4D1A;
--secondarydark: #3F448A;
@ -15,12 +17,14 @@
--success100: #49C39EFF;
--success75: #49C39EBF;
--success50: #49C39E80;
--success25: #49C39E40;
--success10: #49C39E1A;
--successdark: #44B492;
--deletion100: #F2545BFF;
--deletion75: #F2545BBF;
--deletion50: #F2545B80;
--deletion25: #F2545B40;
--deletion10: #F2545B1A;
--deletiondark: #CF4046;

View File

@ -0,0 +1,159 @@
<script>
import {
last,
sortBy,
filter,
map,
uniqWith,
isEqual,
trimCharsStart,
trimChars,
join
} from "lodash/fp";
import { pipe } from "../common/core";
import getIcon from "../common/icon";
import { store } from "../builderStore";
export let components = []
export let thisLevel = "";
const joinPath = join("/");
const normalizedName = name => pipe(name, [
trimCharsStart("./"),
trimCharsStart("~/"),
trimCharsStart("../"),
trimChars(" ")
]);
const isOnThisLevel = (c) =>
normalizedName(c.name).split("/").length === pathPartsThisLevel
&&
(!thisLevel || normalizedName(c.name).startsWith(normalizedName(thisLevel)));
const notOnThisLevel = (c) => !isOnThisLevel(c);
const isInSubfolder = (subfolder, c) =>
normalizedName(c.name).startsWith(
trimCharsStart("/")(
joinPath([thisLevel, subfolder])));
const isOnNextLevel = (c) =>
normalizedName(c.name).split("/").length === pathPartsThisLevel + 1
const lastPartOfName = (c) =>
last(c.name.split("/"))
const subFolder = (c) => {
const cname = normalizedName(c.name);
const folderName = cname.substring(thisLevel.length, cname.length).split("/")[0];
return ({
name: folderName,
isExpanded: false,
path: thisLevel + "/" + folderName
});
}
let pathPartsThisLevel = !thisLevel
? 1
: normalizedName(thisLevel).split("/").length + 1;
let componentsThisLevel =
pipe(components, [
filter(isOnThisLevel),
map(c => ({component:c, title:lastPartOfName(c)})),
sortBy("title")
]);
let subfolders =
pipe(components, [
filter(notOnThisLevel),
sortBy("name"),
map(subFolder),
uniqWith((f1,f2) => f1.path === f2.path)
]);
const subComponents = (subfolder) => pipe(components, [
filter(c => isInSubfolder(subfolder, c))
]);
const expandFolder = folder => {
const expandedFolder = {...folder};
expandedFolder.isExpanded = !expandedFolder.isExpanded;
const newFolders = [...subfolders];
newFolders.splice(
newFolders.indexOf(folder),
1,
expandedFolder);
subfolders = newFolders;
}
const isComponentSelected = (current,c) =>
current
&& current.name === c.name
const isFolderSelected = (current, folder) =>
isInSubfolder(current, folder)
</script>
<div class="root" style={`padding-left: calc(10px * ${pathPartsThisLevel})`}>
{#each subfolders as folder}
<div class="hierarchy-item folder"
on:click|stopPropagation={() => expandFolder(folder)}>
<span>{@html getIcon(folder.isExpanded ? "chevron-down" : "chevron-right", "16")}</span>
<span class="title" class:currentfolder={$store.currentFrontEndItem && isInSubfolder(folder.name, $store.currentFrontEndItem)}>{folder.name}</span>
{#if folder.isExpanded}
<svelte:self components={subComponents(folder.name)}
thisLevel={folder.path} />
{/if}
</div>
{/each}
{#each componentsThisLevel as component}
<div class="hierarchy-item component" class:selected={isComponentSelected($store.currentFrontEndItem, component.component)}
on:click|stopPropagation={() => store.setCurrentComponent(component.component)}>
<span>{@html getIcon("circle", "7")}</span>
<span class="title">{component.title}</span>
</div>
{/each}
</div>
<style>
.root {
color: var(--secondary50);
}
.hierarchy-item {
cursor: pointer;
}
.hierarchy-item:hover {
color: var(--secondary75);
}
.component {
margin-left: 5px;
}
.currentfolder {
color: var(--secondary100);
}
.selected {
color: var(--primary100);
}
.title {
margin-left: 10px;
}
</style>

View File

@ -0,0 +1,56 @@
<script>
import { store } from "../builderStore";
import getIcon from "../common/icon";
const getPage = (s, name) => {
const props = s.pages[name];
return ({name, props});
}
</script>
<div class="root">
<div class="hierarchy-item component" class:selected={$store.currentFrontEndItem && $store.currentFrontEndItem.name === "main"}
on:click|stopPropagation={() => store.setCurrentPage("main")}>
<span>{@html getIcon("circle", "7")}</span>
<span class="title">Main</span>
</div>
<div class="hierarchy-item component" class:selected={$store.currentFrontEndItem && $store.currentFrontEndItem.name === "unauthenticated"}
on:click|stopPropagation={() => store.setCurrentPage("unauthenticated")}>
<span>{@html getIcon("circle", "7")}</span>
<span class="title">Login</span>
</div>
</div>
<style>
.root {
padding-left: 20px;
padding-bottom: 20px;
color: var(--secondary50);
}
.hierarchy-item {
cursor: pointer;
}
.hierarchy-item:hover {
color: var(--secondary75);
}
.component {
margin-left: 5px;
}
.selected {
color: var(--primary100);
}
.title {
margin-left: 10px;
}
</style>

View File

@ -0,0 +1,25 @@
<script>
import {
keys,
map,
} from "lodash/fp";
import {
pipe
} from "../common/core";
export let propsDefinition;
export let props;
let fields = pipe(propsDefinition,[
keys,
map(k => propsDefinition[k])
]);
</script>
<style>
</style>

View File

@ -1,6 +1,7 @@
<script>
import ComingSoon from "../common/ComingSoon.svelte";
import ComponentsHierarchy from "./ComponentsHierarchy.svelte";
import PagesList from "./PagesList.svelte"
import { store } from "../builderStore";
</script>
@ -9,10 +10,24 @@ import { store } from "../builderStore";
<div class="ui-nav">
<div class="components-list-container">
<h3>Components</h3>
<ComponentsHierarchy components={$store.allComponents}/>
</div>
<div class="pages-list-container">
<h3>Pages</h3>
<PagesList />
</div>
</div>
<div class="component-preview">
{#if $store.currentFrontEndItem}
<div class="component-container">
<h1>{$store.currentFrontEndItem.name}</h1>
</div>
{/if}
</div>
</div>
@ -28,11 +43,33 @@ import { store } from "../builderStore";
.ui-nav {
grid-column-start: uiNav;
background-color: red;
background-color: var(--primary10);
display: grid;
grid-template-rows: [components] 1fr [pages] auto;
}
.component-preview {
display: grid;
grid-template-rows: [top] 1fr [middle] auto [bottom] 1fr;
grid-template-columns: [left] 1fr [middle] auto [right] 1fr;
grid-column-start: preview;
}
.component-container {
grid-row-start: middle;
grid-column-start: middle;
}
.pages-list-container {
grid-row-start: pages;
}
.components-list-container {
grid-row-start: components;
}
h3 {
padding: 10px;
}
</style>

View File

@ -1 +1,86 @@
{"hierarchy":{"name":"root","type":"root","children":[{"name":"customer","type":"record","fields":[{"name":"name","type":"string","typeOptions":{"maxLength":1000,"values":null,"allowDeclaredValuesOnly":false},"label":"name","getInitialValue":"default","getUndefinedValue":"default"}],"children":[{"name":"invoiceyooo","type":"record","fields":[{"name":"amount","type":"number","typeOptions":{"minValue":99999999999,"maxValue":99999999999,"decimalPlaces":2},"label":"amount","getInitialValue":"default","getUndefinedValue":"default"}],"children":[],"validationRules":[],"nodeId":2,"indexes":[],"allidsShardFactor":1,"collectionName":"invoices","isSingle":false}],"validationRules":[],"nodeId":1,"indexes":[],"allidsShardFactor":64,"collectionName":"customers","isSingle":false}],"pathMaps":[],"indexes":[],"nodeId":0},"triggers":[{"actionName":"output_to_file","eventName":"authApi:createUser:onComplete","optionsCreator":"return { filename:'tempaccess' + context.user.name, content:context.result.tempCode };","condition":"!context.password"},{"actionName":"output_to_file","eventName":"authApi:createTemporaryAccess:onComplete","optionsCreator":"return { filename:'tempaccess' + context.userName, content:context.result };","condition":""}],"actions":{"undefined":[[[{"name":"output_to_file","behaviourSource":"main","behaviourName":"outputToFile","initialOptions":{}}]]]}}
{
"hierarchy": {
"name": "root",
"type": "root",
"children": [
{
"name": "customer",
"type": "record",
"fields": [
{
"name": "name",
"type": "string",
"typeOptions": {
"maxLength": 1000,
"values": null,
"allowDeclaredValuesOnly": false
},
"label": "name",
"getInitialValue": "default",
"getUndefinedValue": "default"
}
],
"children": [
{
"name": "invoiceyooo",
"type": "record",
"fields": [
{
"name": "amount",
"type": "number",
"typeOptions": {
"minValue": 99999999999,
"maxValue": 99999999999,
"decimalPlaces": 2
},
"label": "amount",
"getInitialValue": "default",
"getUndefinedValue": "default"
}
],
"children": [],
"validationRules": [],
"nodeId": 2,
"indexes": [],
"allidsShardFactor": 1,
"collectionName": "invoices",
"isSingle": false
}
],
"validationRules": [],
"nodeId": 1,
"indexes": [],
"allidsShardFactor": 64,
"collectionName": "customers",
"isSingle": false
}
],
"pathMaps": [],
"indexes": [],
"nodeId": 0
},
"triggers": [
{
"actionName": "output_to_file",
"eventName": "authApi:createUser:onComplete",
"optionsCreator": "return { filename:'tempaccess' + context.user.name, content:context.result.tempCode };",
"condition": "!context.password"
},
{
"actionName": "output_to_file",
"eventName": "authApi:createTemporaryAccess:onComplete",
"optionsCreator": "return { filename:'tempaccess' + context.userName, content:context.result };",
"condition": ""
}
],
"actions": {
"output_to_file":
{
"name": "output_to_file",
"behaviourSource": "main",
"behaviourName": "outputToFile",
"initialOptions": {}
}
}
}

View File

@ -0,0 +1,9 @@
{
"inherits": "./customComponents/textbox",
"name": "myTextBox",
"tags": [],
"description": "A text input, with a label",
"props" : {
"label": "hello"
}
}

View File

@ -0,0 +1,9 @@
{
"inherits": "./moreCustomComponents/textbox",
"name":"subfolder/otherTextBox.json",
"tags": [],
"description": "A text input, with a label",
"props" : {
"label": "hello"
}
}

View File

@ -0,0 +1,11 @@
{
"textbox" : {
"path": "./textbox",
"name": "Textbox",
"description": "A text input, with a label",
"props": {
"label": "string"
},
"tags": ["textboxt", "input", "text"]
}
}

Binary file not shown.

View File

@ -0,0 +1,11 @@
{
"textbox" : {
"path": "./textbox",
"name": "Textbox",
"description": "A text input, with a label",
"props": {
"label": "string"
},
"tags": ["textboxt", "input", "text"]
}
}

View File

@ -0,0 +1,19 @@
{
"main" : {
"index" : {
},
"appBody" : "./main.app.json"
},
"unauthenticated" : {
"index" : {
"_component": "budibase-components/indexHtml",
"title": "Test App 1 - Login",
"customScripts": [
"MyCustomComponents.js"
]
},
"appBody" : "./unauthenticated.app.json"
},
"componentLibraries": ["./customComponents", "./moreCustomComponents"]
}

View File

@ -2,8 +2,13 @@ const fs = require("fs");
module.exports = (config) => ({
main: {
outputToFile : ({filename, content}) => {
fs.writeFile(`./tests/.data/${filename}`, content, {encoding:"utf8"});
outputToFile : async ({filename, content}) => {
await new Promise((resolve,reject) => {
fs.writeFile(`./tests/.data/${filename}`, content, {encoding:"utf8"}, err => {
if(err) reject();
else resolve(err);
});
});
}
}
})

View File

@ -0,0 +1 @@
console.log("test app 1 - main");

View File

@ -0,0 +1,3 @@
<html>
<body>MAIN - TEST APP 1</body>
</html>

View File

@ -0,0 +1 @@
console.log("test app 1 - unauthenticated");

View File

@ -0,0 +1,3 @@
<html>
<body>UNAUTHENTICATED - TEST APP 1</body>
</html>

View File

@ -1,30 +1,32 @@
main.svelte-j8mzr7{height:100%;width:100%;font-family:"Lato", Helvetica, Arial, sans-serif}
.root.svelte-1rxbdcd{height:100%}.content.svelte-1rxbdcd{position:fixed;height:100%;background-color:var(--white);margin:0}
.root.svelte-jymnqv{position:fixed;margin:0 auto;text-align:center;top:20%;width:100%}.inner.svelte-jymnqv{display:inline-block;margin:auto}.logo.svelte-jymnqv{width:300px;margin-bottom:40px}.root.svelte-jymnqv .option{width:250px}.app-link.svelte-jymnqv{margin-top:10px;display:block}
.root.svelte-1bhe8g7{display:grid;grid-template-columns:[uiNav] 200px [preview] auto;height:100%}.ui-nav.svelte-1bhe8g7{grid-column-start:uiNav}.component-preview.svelte-1bhe8g7{grid-column-start:preview}
.root.svelte-1y6dy5x{padding:10px}
h4.svelte-o0id5a{margin-top:20px}
.root.svelte-z7gm0t{display:flex;height:100%;position:relative}.hierarchy.svelte-z7gm0t{flex:0 1 auto;background-color:var(--primary10);overflow-y:auto;height:100%}.node-container.svelte-z7gm0t{flex:1 1 auto;display:flex;flex-direction:column}.actions-header.svelte-z7gm0t{flex:0 1 auto}.node-view.svelte-z7gm0t{overflow-y:auto;flex:1 1 auto}.hierarchy-title-row.svelte-z7gm0t{padding:15px 7px;font-size:11pt;display:flex;font-weight:bold}.hierarchy-title.svelte-z7gm0t{flex:auto 1 1}
.root.svelte-1rxbdcd{height:100%}.content.svelte-1rxbdcd{position:fixed;height:100%;background-color:var(--white);margin:0}
.border-normal.svelte-7rfkdx{border-radius:var(--borderradiusall)}.border-left.svelte-7rfkdx{border-radius:var(--borderradius) 0 0 var(--borderradius)}.border-right.svelte-7rfkdx{border-radius:0 var(--borderradius) var(--borderradius) 0}.border-middle.svelte-7rfkdx{border-radius:0}button.svelte-7rfkdx{border-style:solid;padding:7px 15px;cursor:pointer}.primary.svelte-7rfkdx{background-color:var(--primary100);border-color:var(--primary100);color:var(--white)}.primary.svelte-7rfkdx:hover{background-color:var(--primary75);border-color:var(--primary75)}.primary.svelte-7rfkdx:active{background-color:var(--primarydark);border-color:var(--primarydark)}.primary-outline.svelte-7rfkdx{background-color:var(--white);border-color:var(--primary100);color:var(--primary100)}.primary-outline.svelte-7rfkdx:hover{background-color:var(--primary10)}.primary-outline.svelte-7rfkdx:pressed{background-color:var(--primary25)}.secondary.svelte-7rfkdx{background-color:var(--secondary100);border-color:var(--secondary100);color:var(--white)}.secondary.svelte-7rfkdx:hover{background-color:var(--secondary75);border-color:var(--secondary75)}.secondary.svelte-7rfkdx:pressed{background-color:var(--secondarydark);border-color:var(--secondarydark)}.secondary-outline.svelte-7rfkdx{background-color:var(--white);border-color:var(--secondary100);color:var(--secondary100)}.secondary-outline.svelte-7rfkdx:hover{background-color:var(--secondary10)}.secondary-outline.svelte-7rfkdx:pressed{background-color:var(--secondary25)}.success.svelte-7rfkdx{background-color:var(--success100);border-color:var(--success100);color:var(--white)}.success.svelte-7rfkdx:hover{background-color:var(--success75);border-color:var(--success75)}.success.svelte-7rfkdx:pressed{background-color:var(--successdark);border-color:var(--successdark)}.success-outline.svelte-7rfkdx{background-color:var(--white);border-color:var(--success100);color:var(--success100)}.success-outline.svelte-7rfkdx:hover{background-color:var(--success10)}.success-outline.svelte-7rfkdx:pressed{background-color:var(--success25)}.deletion.svelte-7rfkdx{background-color:var(--deletion100);border-color:var(--deletion100);color:var(--white)}.deletion.svelte-7rfkdx:hover{background-color:var(--deletion75);border-color:var(--deletion75)}.deletion.svelte-7rfkdx:pressed{background-color:var(--deletiondark);border-color:var(--deletiondark)}.deletion-outline.svelte-7rfkdx{background-color:var(--white);border-color:var(--deletion100);color:var(--deletion100)}.deletion-outline.svelte-7rfkdx:hover{background-color:var(--deletion10)}.deletion-outline.svelte-7rfkdx:pressed{background-color:var(--deletion25)}
.nav.svelte-n1ql72{height:100%;position:fixed;left:0px;background-color:var(--secondary100);color:var(--darkslate)}.nav.svelte-n1ql72>img.svelte-n1ql72{width:100%;margin-bottom:30px;margin-top:5px;margin-left:0px}
h4.svelte-o0id5a{margin-top:20px}
.root.svelte-153wzef{display:grid;grid-template-columns:[uiNav] 300px [preview] auto;height:100%;width:100%}.ui-nav.svelte-153wzef{grid-column-start:uiNav;background-color:var(--primary10);display:grid;grid-template-rows:[components] 1fr [pages] auto}.component-preview.svelte-153wzef{display:grid;grid-template-rows:[top] 1fr [middle] auto [bottom] 1fr;grid-template-columns:[left] 1fr [middle] auto [right] 1fr;grid-column-start:preview}.component-container.svelte-153wzef{grid-row-start:middle;grid-column-start:middle}.pages-list-container.svelte-153wzef{grid-row-start:pages}.components-list-container.svelte-153wzef{grid-row-start:components}h3.svelte-153wzef{padding:10px}
.root.svelte-z7gm0t{display:flex;height:100%;position:relative}.hierarchy.svelte-z7gm0t{flex:0 1 auto;background-color:var(--primary10);overflow-y:auto;height:100%}.node-container.svelte-z7gm0t{flex:1 1 auto;display:flex;flex-direction:column}.actions-header.svelte-z7gm0t{flex:0 1 auto}.node-view.svelte-z7gm0t{overflow-y:auto;flex:1 1 auto}.hierarchy-title-row.svelte-z7gm0t{padding:15px 7px;font-size:11pt;display:flex;font-weight:bold}.hierarchy-title.svelte-z7gm0t{flex:auto 1 1}
.root.svelte-1y6dy5x{padding:10px}
.root.svelte-1be865r{padding:10px}.edit-button.svelte-1be865r{cursor:pointer;color:var(--white)}tr.svelte-1be865r:hover .edit-button.svelte-1be865r{color:var(--secondary75)}
.edit-button.svelte-1le5bpl{cursor:pointer;color:var(--white)}tr.svelte-1le5bpl:hover .edit-button.svelte-1le5bpl{color:var(--secondary75)}
.root.svelte-d6wwkb{display:flex}.root.svelte-d6wwkb:last-child{border-radius:0 var(--borderradius) var(--borderradius) 0}.root.svelte-d6wwkb:first-child{border-radius:var(--borderradius) 0 0 var(--borderradius)}.root.svelte-d6wwkb:not(:first-child):not(:last-child){border-radius:0}
.edit-button.svelte-12jzg4k{cursor:pointer;color:var(--white)}tr.svelte-12jzg4k:hover .edit-button.svelte-12jzg4k{color:var(--secondary75)}
.nav-item.svelte-td9xyr{padding:0px 5px;display:block;padding:10px;color:var(--slate);cursor:pointer}.inner.svelte-td9xyr{padding:0px 20px 10px 0px;display:inline-block;width:100%}.nav-item.svelte-td9xyr:hover{background-color:var(--primary25)}.icon.svelte-td9xyr{font-size:0.9em;display:inline-block;position:relative;top:5px;margin-right:5px;width:100%}.active.svelte-td9xyr>div.svelte-td9xyr{background-color:var(--primary10);color:var(--secondary100)}.active.svelte-td9xyr>div.svelte-td9xyr:hover{background-color:var(--slate);color:var(--secondary100)}.active.svelte-td9xyr{background-color:white}
.root.svelte-1sgefwa{color:var(--secondary50)}.hierarchy-item.svelte-1sgefwa{cursor:pointer}.hierarchy-item.svelte-1sgefwa:hover{color:var(--secondary75)}.component.svelte-1sgefwa{margin-left:5px}.currentfolder.svelte-1sgefwa{color:var(--secondary100)}.selected.svelte-1sgefwa{color:var(--primary100)}.title.svelte-1sgefwa{margin-left:10px}
.root.svelte-1rctf7f{display:block;font-size:13pt;width:100%;cursor:pointer}.title.svelte-1rctf7f{font:var(--bodytext);padding-top:10px;padding-right:5px;padding-bottom:10px;color:var(--secondary100)}.title.svelte-1rctf7f:hover{background-color:var(--secondary10)}
.root.svelte-160njkp{padding:5px;top:0;width:100%}
.root.svelte-gq7l8x{height:100%;padding:15px}.fields-table.svelte-gq7l8x{margin:10px;border-collapse:collapse}.add-field-button.svelte-gq7l8x{margin-left:15px;cursor:pointer}.edit-button.svelte-gq7l8x{cursor:pointer;color:var(--white)}.edit-button.svelte-gq7l8x:hover{color:var(--secondary75)}th.svelte-gq7l8x{text-align:left}td.svelte-gq7l8x{padding:5px 30px 5px 0px;margin:0}thead.svelte-gq7l8x>tr.svelte-gq7l8x{border-width:0px 0px 1px 0px;border-style:solid;border-color:var(--secondary75);margin-bottom:20px}tbody.svelte-gq7l8x>tr.svelte-gq7l8x{border-width:0px 0px 1px 0px;border-style:solid;border-color:var(--primary10)}tbody.svelte-gq7l8x>tr.svelte-gq7l8x:hover{background-color:var(--primary10)}tbody.svelte-gq7l8x>tr:hover .edit-button.svelte-gq7l8x{color:var(--secondary75)}.index-container.svelte-gq7l8x{border-style:solid;border-width:0 0 1px 0;border-color:var(--secondary25);padding:10px;margin-bottom:5px}.index-label.svelte-gq7l8x{color:var(--slate)}.index-name.svelte-gq7l8x{font-weight:bold;color:var(--primary100)}.index-container.svelte-gq7l8x code.svelte-gq7l8x{margin:0;display:inline;background-color:var(--primary10);color:var(--secondary100);padding:3px}.index-field-row.svelte-gq7l8x{margin-top:7px}
.root.svelte-1fkfoam{height:100%;padding:15px}.allowed-records.svelte-1fkfoam{margin:20px 0px}.allowed-records.svelte-1fkfoam>span.svelte-1fkfoam{margin-right:30px}
.root.svelte-6ej2ac{padding-left:20px;padding-bottom:20px;color:var(--secondary50)}.hierarchy-item.svelte-6ej2ac{cursor:pointer}.hierarchy-item.svelte-6ej2ac:hover{color:var(--secondary75)}.component.svelte-6ej2ac{margin-left:5px}.selected.svelte-6ej2ac{color:var(--primary100)}.title.svelte-6ej2ac{margin-left:10px}
.dropdown-background.svelte-179p8ge{position:fixed;top:0;left:0;width:100vw;height:100vh}.root.svelte-179p8ge{cursor:pointer;z-index:1}.dropdown-content.svelte-179p8ge{position:absolute;background-color:var(--white);min-width:160px;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);z-index:1;font-weight:normal;border-style:solid;border-width:1px;border-color:var(--secondary10)}.dropdown-content.svelte-179p8ge:not(:focus){display:none}.action-row.svelte-179p8ge{padding:7px 10px;cursor:pointer}.action-row.svelte-179p8ge:hover{background-color:var(--primary100);color:var(--white)}
.nav-item.svelte-td9xyr{padding:0px 5px;display:block;padding:10px;color:var(--slate);cursor:pointer}.inner.svelte-td9xyr{padding:0px 20px 10px 0px;display:inline-block;width:100%}.nav-item.svelte-td9xyr:hover{background-color:var(--primary25)}.icon.svelte-td9xyr{font-size:0.9em;display:inline-block;position:relative;top:5px;margin-right:5px;width:100%}.active.svelte-td9xyr>div.svelte-td9xyr{background-color:var(--primary10);color:var(--secondary100)}.active.svelte-td9xyr>div.svelte-td9xyr:hover{background-color:var(--slate);color:var(--secondary100)}.active.svelte-td9xyr{background-color:white}
.root.svelte-emcy8y{padding:10px}.option-container.svelte-emcy8y{border-style:dotted;border-width:1px;border-color:var(--primary75);padding:3px;margin-right:5px}
.root.svelte-160njkp{padding:5px;top:0;width:100%}
.edit-button.svelte-12jzg4k{cursor:pointer;color:var(--white)}tr.svelte-12jzg4k:hover .edit-button.svelte-12jzg4k{color:var(--secondary75)}
.root.svelte-d6wwkb{display:flex}.root.svelte-d6wwkb:last-child{border-radius:0 var(--borderradius) var(--borderradius) 0}.root.svelte-d6wwkb:first-child{border-radius:var(--borderradius) 0 0 var(--borderradius)}.root.svelte-d6wwkb:not(:first-child):not(:last-child){border-radius:0}
.edit-button.svelte-1le5bpl{cursor:pointer;color:var(--white)}tr.svelte-1le5bpl:hover .edit-button.svelte-1le5bpl{color:var(--secondary75)}
.container.svelte-umifqh{display:grid;grid-template-columns:[label] 100px [control] auto;margin:20px 0px}.label.svelte-umifqh{grid-column-start:label;align-self:center}.control.svelte-umifqh{grid-column-start:control;align-self:center;margin:0}input.svelte-umifqh{width:300px}
.error-container.svelte-jwy920{padding:10px;border-style:solid;border-color:var(--deletion100);border-radius:var(--borderradiusall);background:var(--deletion75)}.error-row.svelte-jwy920{padding:5px 0px}
textarea.svelte-1ooq0hh{padding:3px;background:var(--darkslate);color:var(--white);font-family:'Courier New', Courier, monospace;width:95%;height:100px}
.container.svelte-bm0783{display:grid;grid-template-columns:[label] 100px [control] auto;margin:20px 0px}.label.svelte-bm0783{grid-column-start:label;align-self:center}.control.svelte-bm0783{grid-column-start:control;align-self:center;margin:0}select.svelte-bm0783{width:300px}
.error-container.svelte-jwy920{padding:10px;border-style:solid;border-color:var(--deletion100);border-radius:var(--borderradiusall);background:var(--deletion75)}.error-row.svelte-jwy920{padding:5px 0px}
input.svelte-66516k{margin-right:7px}
.container.svelte-85b8gk{display:grid;grid-template-columns:[label] 100px [control] auto;margin:20px 0px}.label.svelte-85b8gk{grid-column-start:label;align-self:center}.control.svelte-85b8gk{grid-column-start:control;align-self:center;margin:0}textarea.svelte-85b8gk{width:300px;height:200px}
.container.svelte-1pf9x5k{display:grid;grid-template-columns:[label] 100px [control] auto;margin:20px 0px}.label.svelte-1pf9x5k{grid-column-start:label;align-self:center}.control.svelte-1pf9x5k{grid-column-start:control;align-self:center;margin:0}input.svelte-1pf9x5k{width:300px}
.root.svelte-emcy8y{padding:10px}.option-container.svelte-emcy8y{border-style:dotted;border-width:1px;border-color:var(--primary75);padding:3px;margin-right:5px}
.container.svelte-umifqh{display:grid;grid-template-columns:[label] 100px [control] auto;margin:20px 0px}.label.svelte-umifqh{grid-column-start:label;align-self:center}.control.svelte-umifqh{grid-column-start:control;align-self:center;margin:0}input.svelte-umifqh{width:300px}
.container.svelte-1pf9x5k{display:grid;grid-template-columns:[label] 100px [control] auto;margin:20px 0px}.label.svelte-1pf9x5k{grid-column-start:label;align-self:center}.control.svelte-1pf9x5k{grid-column-start:control;align-self:center;margin:0}input.svelte-1pf9x5k{width:300px}
.container.svelte-85b8gk{display:grid;grid-template-columns:[label] 100px [control] auto;margin:20px 0px}.label.svelte-85b8gk{grid-column-start:label;align-self:center}.control.svelte-85b8gk{grid-column-start:control;align-self:center;margin:0}textarea.svelte-85b8gk{width:300px;height:200px}
/*# sourceMappingURL=bundle.css.map */

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -1,12 +1,14 @@
:root {
--primary100: #454CA0FF;
--primary75: #454CA0BF;
--primary50: #454CA080;
--primary25: #454CA040;
--primary10: #454CA01A;
--primarydark: #3F448A;
--secondary100: #162B4DFF;
--secondary75: #162B4DBF;
--secondary50: #162B4D80;
--secondary25: #162B4D40;
--secondary10: #162B4D1A;
--secondarydark: #3F448A;
@ -15,12 +17,14 @@
--success100: #49C39EFF;
--success75: #49C39EBF;
--success50: #49C39E80;
--success25: #49C39E40;
--success10: #49C39E1A;
--successdark: #44B492;
--deletion100: #F2545BFF;
--deletion75: #F2545BBF;
--deletion50: #F2545B80;
--deletion25: #F2545B40;
--deletion10: #F2545B1A;
--deletiondark: #CF4046;

View File

@ -131,7 +131,9 @@ const getRootComponents = async (appPath, pages ,lib) => {
return $(components, [
keys,
reduce((obj, k) => {
obj[`${libname}/${k}`] = components[k]
const component = components[k];
component.name = `${libname}/${k}`;
obj[component.name] = component;
return obj;
}, {})
])