diff --git a/packages/builder/rollup.config.js b/packages/builder/rollup.config.js
index 1f5bc04b23..6678a00962 100644
--- a/packages/builder/rollup.config.js
+++ b/packages/builder/rollup.config.js
@@ -16,7 +16,7 @@ const _builderProxy = proxy('/_builder', {
pathRewrite: {'^/_builder' : ''}
});
-const apiProxy = proxy(['/_builder/api/**', '/_builder/**/componentlibrary'] , {
+const apiProxy = proxy(['/_builder/api/**', '/_builder/**/componentlibrary', '/_builder/**/componentlibraryGenerators'] , {
target,
logLevel: "debug",
changeOrigin: true,
diff --git a/packages/builder/src/accessLevels/AccessLevelsRoot.svelte b/packages/builder/src/accessLevels/AccessLevelsRoot.svelte
index 5f9ec73db7..2f1d50fe3c 100644
--- a/packages/builder/src/accessLevels/AccessLevelsRoot.svelte
+++ b/packages/builder/src/accessLevels/AccessLevelsRoot.svelte
@@ -65,7 +65,7 @@ const getPermissionsString = perms => {
- {#each $store.accessLevels as level}
+ {#each $store.accessLevels.levels as level}
{level.name} |
{getPermissionsString(level.permissions)} |
@@ -88,7 +88,7 @@ const getPermissionsString = perms => {
allPermissions={allPermissions}
onFinished={onEditingFinished}
isNew={editingLevelIsNew}
- allLevels={$store.accessLevels}
+ allLevels={$store.accessLevels.levels}
hierarchy={$store.hierarchy}
actions={$store.actions} />
{/if}
diff --git a/packages/builder/src/builderStore/createPackage.js b/packages/builder/src/builderStore/createPackage.js
index ea4e7fb17f..5df88b7dfd 100644
--- a/packages/builder/src/builderStore/createPackage.js
+++ b/packages/builder/src/builderStore/createPackage.js
@@ -7,7 +7,6 @@ export const createPackage = (packageInfo, store) => {
hierarchy:root,
actions:[],
triggers:[],
- accessLevels: [],
- accessLevelsVersion: 0
+ accessLevels: {version:0, levels:[]}
});
};
diff --git a/packages/builder/src/builderStore/loadComponentLibraries.js b/packages/builder/src/builderStore/loadComponentLibraries.js
index 9e69711d8e..1dfa99025a 100644
--- a/packages/builder/src/builderStore/loadComponentLibraries.js
+++ b/packages/builder/src/builderStore/loadComponentLibraries.js
@@ -11,6 +11,17 @@ export const loadLibs = async (appName, appPackage) => {
return allLibraries;
}
+export const loadGeneratorLibs = async (appName, appPackage) => {
+
+ const allGeneratorLibs = {};
+ for(let lib of appPackage.pages.componentLibraries) {
+ const generatorModule = await import(makeGeneratorLibraryUrl(appName, lib));
+ allGeneratorLibs[lib] = generatorModule;
+ }
+
+ return allGeneratorLibs;
+}
+
export const loadLibUrls = (appName, appPackage) => {
const allLibraries = [];
@@ -27,5 +38,13 @@ export const loadLib = async (appName, lib, allLibs) => {
return allLibs;
}
+export const loadGeneratorLib = async (appName, lib, allGeneratorLibs) => {
+ allGeneratorLibs[lib] = await import(makeGeneratorLibraryUrl(appName, lib));
+ return allGeneratorLibs;
+}
+
export const makeLibraryUrl = (appName, lib) =>
- `/_builder/${appName}/componentlibrary?lib=${encodeURI(lib)}`
\ No newline at end of file
+ `/_builder/${appName}/componentlibrary?lib=${encodeURI(lib)}`
+
+export const makeGeneratorLibraryUrl = (appName, lib) =>
+ `/_builder/${appName}/componentlibraryGenerators?lib=${encodeURI(lib)}`
\ No newline at end of file
diff --git a/packages/builder/src/builderStore/store.js b/packages/builder/src/builderStore/store.js
index 0a6ecac2f2..1f5ab246f6 100644
--- a/packages/builder/src/builderStore/store.js
+++ b/packages/builder/src/builderStore/store.js
@@ -19,7 +19,9 @@ import { rename } from "../userInterface/pagesParsing/renameComponent";
import {
getComponentInfo, getNewComponentInfo
} from "../userInterface/pagesParsing/createProps";
-import { loadLibs, loadLibUrls } from "./loadComponentLibraries";
+import {
+ loadLibs, loadLibUrls, loadGeneratorLibs
+} from "./loadComponentLibraries";
let appname = "";
@@ -45,7 +47,7 @@ export const getStore = () => {
activeNav: "database",
isBackend:true,
hasAppPackage: false,
- accessLevels: [],
+ accessLevels: {version:0, levels:[]},
currentNode: null,
libraries:null,
showSettings:false,
@@ -88,6 +90,7 @@ export const getStore = () => {
store.showBackend = showBackend(store);
store.showSettings = showSettings(store);
store.useAnalytics = useAnalytics(store);
+ store.createGeneratedComponents = createGeneratedComponents(store);
return store;
}
@@ -110,15 +113,17 @@ const initialise = (store, initial) => async () => {
.then(r => r.json());
initial.libraries = await loadLibs(appname, pkg);
+ initial.generatorLibraries = await loadGeneratorLibs(appname, pkg);
initial.loadLibraryUrls = () => loadLibUrls(appname, pkg);
initial.appname = appname;
initial.pages = pkg.pages;
initial.hasAppPackage = true;
initial.hierarchy = pkg.appDefinition.hierarchy;
- initial.accessLevels = pkg.accessLevels.levels;
+ initial.accessLevels = pkg.accessLevels;
initial.derivedComponents = pkg.derivedComponents;
+ initial.generators = generatorsArray(pkg.rootComponents.generators);
initial.allComponents = combineComponents(
- pkg.derivedComponents, pkg.rootComponents);
+ pkg.derivedComponents, pkg.rootComponents.components);
initial.actions = reduce((arr, action) => {
arr.push(action);
return arr;
@@ -137,6 +142,14 @@ const initialise = (store, initial) => async () => {
return initial;
}
+const generatorsArray = generators =>
+ pipe(generators, [
+ keys,
+ filter(k => k !== "_lib"),
+ map(k => generators[k])
+ ]);
+
+
const showSettings = store => show => {
store.update(s => {
s.showSettings = !s.showSettings;
@@ -377,20 +390,28 @@ const deleteTrigger = store => trigger => {
});
}
+const incrementAccessLevelsVersion = (s) =>
+ s.accessLevels.version = (s.accessLevels.version || 0) + 1;
+
const saveLevel = store => (newLevel, isNew, oldLevel=null) => {
store.update(s => {
+ const levels = s.accessLevels.levels;
+
const existingLevel = isNew
? null
- : find(a => a.name === oldLevel.name)(s.accessLevels);
+ : find(a => a.name === oldLevel.name)(levels);
if(existingLevel) {
- s.accessLevels = pipe(s.accessLevels, [
+ s.accessLevels.levels = pipe(levels, [
map(a => a === existingLevel ? newLevel : a)
]);
} else {
- s.accessLevels.push(newLevel);
+ s.accessLevels.levels.push(newLevel);
}
+
+ incrementAccessLevelsVersion(s);
+
savePackage(store, s);
return s;
});
@@ -398,7 +419,8 @@ const saveLevel = store => (newLevel, isNew, oldLevel=null) => {
const deleteLevel = store => level => {
store.update(s => {
- s.accessLevels = filter(t => t.name !== level.name)(s.accessLevels);
+ s.accessLevels.levels = filter(t => t.name !== level.name)(s.accessLevels.levels);
+ incrementAccessLevelsVersion(s);
savePackage(store, s);
return s;
});
@@ -442,7 +464,7 @@ const saveDerivedComponent = store => (derivedComponent) => {
})
};
-const createDerivedComponent = store => (componentName) => {
+const createDerivedComponent = store => componentName => {
store.update(s => {
const newComponentInfo = getNewComponentInfo(
s.allComponents, componentName);
@@ -453,7 +475,25 @@ const createDerivedComponent = store => (componentName) => {
s.currentComponentIsNew = true;
return s;
});
-}
+};
+
+const createGeneratedComponents = store => components => {
+ store.update(s => {
+ s.allComponents = [...s.allComponents, ...components];
+
+ const doCreate = async () => {
+ for(let c of components) {
+ await api.post(`/_builder/api/${s.appname}/derivedcomponent`, c);
+ }
+
+ await savePackage(store, s);
+ }
+
+ doCreate();
+
+ return s;
+ });
+};
const deleteDerivedComponent = store => name => {
store.update(s => {
@@ -470,6 +510,7 @@ const deleteDerivedComponent = store => name => {
s.derivedComponents = derivedComponents;
if(s.currentFrontEndItem.name === name) {
s.currentFrontEndItem = null;
+ s.currentFrontEndType = "";
}
api.delete(`/_builder/api/${s.appname}/derivedcomponent/${name}`);
@@ -598,9 +639,9 @@ const removeStylesheet = store => stylesheet => {
const refreshComponents = store => async () => {
const components =
- await api.get(`/_builder/api/${db.appname}/components`).then(r => r.json());
+ await api.get(`/_builder/api/${db.appname}/rootcomponents`).then(r => r.json());
- const rootComponents = pipe(components, [
+ const rootComponents = pipe(components.components, [
keys,
map(k => ({...components[k], name:k}))
]);
@@ -610,6 +651,7 @@ const refreshComponents = store => async () => {
filter(c => !isRootComponent(c)),
concat(rootComponents)
]);
+ s.generators = components.generators;
return s;
});
};
@@ -632,7 +674,7 @@ const savePackage = (store, s) => {
pages:s.pages,
}
- api.post(`/_builder/api/${s.appname}/appPackage`, data);
+ return api.post(`/_builder/api/${s.appname}/appPackage`, data);
}
const setCurrentComponent = store => componentName => {
diff --git a/packages/builder/src/common/core.js b/packages/builder/src/common/core.js
index 0061b03d8d..46bd798b44 100644
--- a/packages/builder/src/common/core.js
+++ b/packages/builder/src/common/core.js
@@ -3,6 +3,10 @@ import {hierarchy as hierarchyFunctions,
import {find, filter, includes, keyBy, some,
flatten, map} from "lodash/fp";
+import {
+ generateSchema
+} from "../../../core/src/indexing/indexSchemaCreator";
+
export const pipe = common.$;
export const events = common.eventsList;
@@ -72,4 +76,19 @@ export const getNewAccessLevel = () =>
authApi().getNewAccessLevel();
export const validateAccessLevels = (hierarchy, actions, accessLevels) =>
- authApi(hierarchy, actions).validateAccessLevels(accessLevels);
\ No newline at end of file
+ authApi(hierarchy, actions).validateAccessLevels(accessLevels);
+
+export const getIndexNodes = (hierarchy) =>
+ pipe(hierarchy, [
+ hierarchyFunctions.getFlattenedHierarchy,
+ filter(hierarchyFunctions.isIndex)
+ ]);
+
+export const getRecordNodes = (hierarchy) =>
+ pipe(hierarchy, [
+ hierarchyFunctions.getFlattenedHierarchy,
+ filter(hierarchyFunctions.isIndex)
+ ]);
+
+export const getIndexSchema = hierarchy => index =>
+ generateSchema(hierarchy, index);
\ No newline at end of file
diff --git a/packages/builder/src/userInterface/ComponentSelector.svelte b/packages/builder/src/userInterface/ComponentSelector.svelte
new file mode 100644
index 0000000000..ff208bcde8
--- /dev/null
+++ b/packages/builder/src/userInterface/ComponentSelector.svelte
@@ -0,0 +1,189 @@
+
+
+{#each componentLibraries as lib}
+
+
+
+
+
+
+ {#each lib.generators as generator}
+
+
onGeneratorChosen(generator)}>
+
+ {splitName(generator.name).componentName}
+
+
+ {generator.description}
+
+
+
+ {/each}
+
+
+
+ {#each lib.components as component}
+
+
onComponentChosen(component)}>
+
+ {splitName(component.name).componentName}
+
+
+ {component.description}
+
+
+
+ {/each}
+
+
+
+{/each}
+
+
+
+
+
+
+ {#each derivedComponents as component}
+
+
onComponentChosen(component)}>
+
+ {component.name}
+
+
+ {component.description}
+
+
+
+ {/each}
+
+
+
+
+
diff --git a/packages/builder/src/userInterface/CurrentItemPreview.svelte b/packages/builder/src/userInterface/CurrentItemPreview.svelte
index 92b9800152..6cbda17b59 100644
--- a/packages/builder/src/userInterface/CurrentItemPreview.svelte
+++ b/packages/builder/src/userInterface/CurrentItemPreview.svelte
@@ -11,19 +11,13 @@ import { getRootComponent } from "./pagesParsing/getRootComponent";
import { buildPropsHierarchy } from "./pagesParsing/buildPropsHierarchy";
-let component;
+let hasComponent=false;
let stylesheetLinks = "";
-let rootComponentName = "";
-let libraries;
-let allComponents;
let appDefinition = {};
store.subscribe(s => {
- const {componentName, libName} = splitName(
- s.currentComponentInfo.rootComponent.name);
-
- rootComponentName = componentName;
- component = s.libraries[libName][componentName];
+ hasComponent = !!s.currentFrontEndItem;
+
stylesheetLinks = pipe(s.pages.stylesheets, [
map(s => ``),
join("\n")
@@ -32,8 +26,7 @@ store.subscribe(s => {
componentLibraries: s.loadLibraryUrls(),
props: buildPropsHierarchy(s.allComponents, s.currentFrontEndItem)
};
- libraries = s.libraries;
- allComponents = s.allComponents;
+
});
@@ -42,6 +35,7 @@ store.subscribe(s => {
+ {#if hasComponent}