Browse Source

working components nav - not styled properly

gh-pages
michael shanks 7 years ago
parent
commit
d27ec9e0a5
  1. 2
      packages/builder/rollup.config.js
  2. 10
      packages/builder/src/actionsAndTriggers/ActionView.svelte
  3. 4
      packages/builder/src/actionsAndTriggers/Actions.svelte
  4. 2
      packages/builder/src/actionsAndTriggers/ActionsAndTriggersRoot.svelte
  5. 4
      packages/builder/src/actionsAndTriggers/TriggerView.svelte
  6. 48
      packages/builder/src/builderStore/store.js
  7. 8
      packages/builder/src/common/core.js
  8. 3
      packages/builder/src/common/icon.js
  9. 4
      packages/builder/src/database/IndexView.svelte
  10. 6
      packages/builder/src/database/RecordView.svelte
  11. 4
      packages/builder/src/global.css
  12. 159
      packages/builder/src/userInterface/ComponentsHierarchy.svelte
  13. 56
      packages/builder/src/userInterface/PagesList.svelte
  14. 25
      packages/builder/src/userInterface/PropsView.svelte
  15. 43
      packages/builder/src/userInterface/UserInterfaceRoot.svelte
  16. 87
      packages/server/appPackages/testApp2/appDefinition.json
  17. 9
      packages/server/appPackages/testApp2/components/myTextBox.json
  18. 9
      packages/server/appPackages/testApp2/components/subfolder/otherTextBox.json
  19. 11
      packages/server/appPackages/testApp2/customComponents/components.json
  20. 0
      packages/server/appPackages/testApp2/customComponents/textbox/index.js
  21. BIN
      packages/server/appPackages/testApp2/dist/package.tar.gz
  22. 11
      packages/server/appPackages/testApp2/moreCustomComponents/components.json
  23. 0
      packages/server/appPackages/testApp2/moreCustomComponents/textbox/index.js
  24. 19
      packages/server/appPackages/testApp2/pages.json
  25. 9
      packages/server/appPackages/testApp2/plugins.js
  26. 1
      packages/server/appPackages/testApp2/public/main/app.js
  27. 3
      packages/server/appPackages/testApp2/public/main/index.html
  28. 1
      packages/server/appPackages/testApp2/public/unauthenticated/app.js
  29. 3
      packages/server/appPackages/testApp2/public/unauthenticated/index.html
  30. 30
      packages/server/builder/bundle.css
  31. 76
      packages/server/builder/bundle.css.map
  32. 1680
      packages/server/builder/bundle.js
  33. 2
      packages/server/builder/bundle.js.map
  34. 4
      packages/server/builder/global.css
  35. 4
      packages/server/utilities/builder.js

2
packages/builder/rollup.config.js

@ -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",

10
packages/builder/src/actionsAndTriggers/ActionView.svelte

@ -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)
]);

4
packages/builder/src/actionsAndTriggers/Actions.svelte

@ -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>")

2
packages/builder/src/actionsAndTriggers/ActionsAndTriggersRoot.svelte

@ -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>")

4
packages/builder/src/actionsAndTriggers/TriggerView.svelte

@ -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);

48
packages/builder/src/builderStore/store.js

@ -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;
})
}

8
packages/builder/src/common/core.js

@ -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())

3
packages/builder/src/common/icon.js

@ -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;

4
packages/builder/src/database/IndexView.svelte

@ -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),

6
packages/builder/src/database/RecordView.svelte

@ -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>")

4
packages/builder/src/global.css

@ -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;

159
packages/builder/src/userInterface/ComponentsHierarchy.svelte

@ -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>

56
packages/builder/src/userInterface/PagesList.svelte

@ -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>

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

@ -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>

43
packages/builder/src/userInterface/UserInterfaceRoot.svelte

@ -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>

87
packages/server/appPackages/testApp2/appDefinition.json

@ -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": {}
}
}
}

9
packages/server/appPackages/testApp2/components/myTextBox.json

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

9
packages/server/appPackages/testApp2/components/subfolder/otherTextBox.json

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

11
packages/server/appPackages/testApp2/customComponents/components.json

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

0
packages/server/appPackages/testApp2/customComponents/textbox/index.js

BIN
packages/server/appPackages/testApp2/dist/package.tar.gz

Binary file not shown.

11
packages/server/appPackages/testApp2/moreCustomComponents/components.json

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

0
packages/server/appPackages/testApp2/moreCustomComponents/textbox/index.js

19
packages/server/appPackages/testApp2/pages.json

@ -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"]
}

9
packages/server/appPackages/testApp2/plugins.js

@ -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);
});
});
}
}
})

1
packages/server/appPackages/testApp2/public/main/app.js

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

3
packages/server/appPackages/testApp2/public/main/index.html

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

1
packages/server/appPackages/testApp2/public/unauthenticated/app.js

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

3
packages/server/appPackages/testApp2/public/unauthenticated/index.html

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

30
packages/server/builder/bundle.css

@ -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 */

76
packages/server/builder/bundle.css.map

File diff suppressed because one or more lines are too long

1680
packages/server/builder/bundle.js

File diff suppressed because it is too large

2
packages/server/builder/bundle.js.map

File diff suppressed because one or more lines are too long

4
packages/server/builder/global.css

@ -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;

4
packages/server/utilities/builder.js

@ -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;
}, {})
])

Loading…
Cancel
Save