Builder saves backend and front end seperately (#88)
* refactoring server for screens & page layout restructure * Disable API calls, UI placeholders. * buildPropsHierarchy is gone & screen has url * Recent changes. * router * router * updated git-ignore to reinclude server/utilities/builder * modified cli - budi new create new file structure * Fix uuid import. * prettier fixes * prettier fixes * prettier fixes * page/screen restructure.. broken tests * all tests passing at last * screen routing tests * Working screen editor and preview. * Render page previews to the screen. * Key input lists to ensure new array references when updating styles. * Ensure the iframe html and body fills the container. * Save screens via the API. * Get all save APIs almost working. * Write pages.json to disk. * Use correct API endpoint for saving styles. * Differentiate between saving properties of screens and pages. * Add required fields to default pages layouts. * Add _css default property to newly created screens. * Add default code property. * page layout / screens - app output * backend and fronend save seperately Co-authored-by: pngwn <pnda007@gmail.com>
This commit is contained in:
parent
f7bea46f01
commit
da7339035f
|
@ -295,7 +295,7 @@ const saveCurrentNode = store => () => {
|
||||||
|
|
||||||
s.currentNodeIsNew = false
|
s.currentNodeIsNew = false
|
||||||
|
|
||||||
savePackage(store, s)
|
saveBackend(s)
|
||||||
|
|
||||||
return s
|
return s
|
||||||
})
|
})
|
||||||
|
@ -331,7 +331,7 @@ const deleteCurrentNode = store => () => {
|
||||||
)(nodeToDelete.parent().indexes)
|
)(nodeToDelete.parent().indexes)
|
||||||
}
|
}
|
||||||
s.errors = []
|
s.errors = []
|
||||||
savePackage(store, s)
|
saveBackend(s)
|
||||||
return s
|
return s
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -370,7 +370,7 @@ const saveAction = store => (newAction, isNew, oldAction = null) => {
|
||||||
} else {
|
} else {
|
||||||
s.actions.push(newAction)
|
s.actions.push(newAction)
|
||||||
}
|
}
|
||||||
savePackage(store, s)
|
saveBackend(s)
|
||||||
return s
|
return s
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -378,7 +378,7 @@ const saveAction = store => (newAction, isNew, oldAction = null) => {
|
||||||
const deleteAction = store => action => {
|
const deleteAction = store => action => {
|
||||||
store.update(s => {
|
store.update(s => {
|
||||||
s.actions = filter(a => a.name !== action.name)(s.actions)
|
s.actions = filter(a => a.name !== action.name)(s.actions)
|
||||||
savePackage(store, s)
|
saveBackend(s)
|
||||||
return s
|
return s
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -396,7 +396,7 @@ const saveTrigger = store => (newTrigger, isNew, oldTrigger = null) => {
|
||||||
} else {
|
} else {
|
||||||
s.triggers.push(newTrigger)
|
s.triggers.push(newTrigger)
|
||||||
}
|
}
|
||||||
savePackage(store, s)
|
saveBackend(s)
|
||||||
return s
|
return s
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -429,7 +429,7 @@ const saveLevel = store => (newLevel, isNew, oldLevel = null) => {
|
||||||
|
|
||||||
incrementAccessLevelsVersion(s)
|
incrementAccessLevelsVersion(s)
|
||||||
|
|
||||||
savePackage(store, s)
|
saveBackend(s)
|
||||||
return s
|
return s
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -440,7 +440,7 @@ const deleteLevel = store => level => {
|
||||||
s.accessLevels.levels
|
s.accessLevels.levels
|
||||||
)
|
)
|
||||||
incrementAccessLevelsVersion(s)
|
incrementAccessLevelsVersion(s)
|
||||||
savePackage(store, s)
|
saveBackend(s)
|
||||||
return s
|
return s
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -477,18 +477,18 @@ const _saveScreen = (store, s, screen) => {
|
||||||
`/_builder/api/${s.appname}/pages/${s.currentPageName}/screen`,
|
`/_builder/api/${s.appname}/pages/${s.currentPageName}/screen`,
|
||||||
screen
|
screen
|
||||||
)
|
)
|
||||||
.then(() => savePackage(store, s))
|
.then(() => _savePage(s))
|
||||||
|
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
const _save = (appname, screen, store, s) =>
|
const _saveScreenApi = (screen, s) =>
|
||||||
api
|
api
|
||||||
.post(
|
.post(
|
||||||
`/_builder/api/${s.appname}/pages/${s.currentPageName}/screen`,
|
`/_builder/api/${s.appname}/pages/${s.currentPageName}/screen`,
|
||||||
screen
|
screen
|
||||||
)
|
)
|
||||||
.then(() => savePackage(store, s))
|
.then(() => _savePage(s))
|
||||||
|
|
||||||
const createScreen = store => (screenName, route, layoutComponentName) => {
|
const createScreen = store => (screenName, route, layoutComponentName) => {
|
||||||
store.update(s => {
|
store.update(s => {
|
||||||
|
@ -530,7 +530,7 @@ const createGeneratedComponents = store => components => {
|
||||||
await api.post(`/_builder/api/${s.appname}/screen`, c)
|
await api.post(`/_builder/api/${s.appname}/screen`, c)
|
||||||
}
|
}
|
||||||
|
|
||||||
await savePackage(store, s)
|
await _savePage(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
doCreate()
|
doCreate()
|
||||||
|
@ -591,7 +591,7 @@ const renameScreen = store => (oldname, newname) => {
|
||||||
})
|
})
|
||||||
.then(() => saveAllChanged())
|
.then(() => saveAllChanged())
|
||||||
.then(() => {
|
.then(() => {
|
||||||
savePackage(store, s)
|
_savePage(s)
|
||||||
})
|
})
|
||||||
|
|
||||||
return s
|
return s
|
||||||
|
@ -605,7 +605,7 @@ const savePage = store => async page => {
|
||||||
}
|
}
|
||||||
|
|
||||||
s.pages[s.currentPageName] = page
|
s.pages[s.currentPageName] = page
|
||||||
savePackage(store, s)
|
_savePage(s)
|
||||||
return s
|
return s
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -634,7 +634,7 @@ const addComponentLibrary = store => async lib => {
|
||||||
])
|
])
|
||||||
|
|
||||||
s.pages.componentLibraries.push(lib)
|
s.pages.componentLibraries.push(lib)
|
||||||
savePackage(store, s)
|
_savePage(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
return s
|
return s
|
||||||
|
@ -646,7 +646,7 @@ const removeComponentLibrary = store => lib => {
|
||||||
s.pages.componentLibraries = filter(l => l !== lib)(
|
s.pages.componentLibraries = filter(l => l !== lib)(
|
||||||
s.pages.componentLibraries
|
s.pages.componentLibraries
|
||||||
)
|
)
|
||||||
savePackage(store, s)
|
_savePage(s)
|
||||||
|
|
||||||
return s
|
return s
|
||||||
})
|
})
|
||||||
|
@ -655,7 +655,7 @@ const removeComponentLibrary = store => lib => {
|
||||||
const addStylesheet = store => stylesheet => {
|
const addStylesheet = store => stylesheet => {
|
||||||
store.update(s => {
|
store.update(s => {
|
||||||
s.pages.stylesheets.push(stylesheet)
|
s.pages.stylesheets.push(stylesheet)
|
||||||
savePackage(store, s)
|
_savePage(s)
|
||||||
return s
|
return s
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -663,14 +663,14 @@ const addStylesheet = store => stylesheet => {
|
||||||
const removeStylesheet = store => stylesheet => {
|
const removeStylesheet = store => stylesheet => {
|
||||||
store.update(s => {
|
store.update(s => {
|
||||||
s.pages.stylesheets = filter(s => s !== stylesheet)(s.pages.stylesheets)
|
s.pages.stylesheets = filter(s => s !== stylesheet)(s.pages.stylesheets)
|
||||||
savePackage(store, s)
|
_savePage(s)
|
||||||
return s
|
return s
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const refreshComponents = store => async () => {
|
const refreshComponents = store => async () => {
|
||||||
const componentsAndGenerators = await api
|
const componentsAndGenerators = await api
|
||||||
.get(`/_builder/api/${db.appname}/components`)
|
.get(`/_builder/api/${appname}/components`)
|
||||||
.then(r => r.json())
|
.then(r => r.json())
|
||||||
|
|
||||||
const components = pipe(componentsAndGenerators.components, [
|
const components = pipe(componentsAndGenerators.components, [
|
||||||
|
@ -688,20 +688,24 @@ const refreshComponents = store => async () => {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const savePackage = async (store, s) => {
|
const _savePage = async s => {
|
||||||
const page = s.pages[s.currentPageName]
|
const page = s.pages[s.currentPageName]
|
||||||
|
|
||||||
await api.post(`/_builder/api/${appname}/pages/${s.currentPageName}`, {
|
await api.post(`/_builder/api/${appname}/pages/${s.currentPageName}`, {
|
||||||
|
page: { componentLibraries: s.pages.componentLibraries, ...page },
|
||||||
|
uiFunctions: "{'1234':() => 'test return'}",
|
||||||
|
screens: page.screens,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const saveBackend = async s => {
|
||||||
|
await api.post(`/_builder/api/${appname}/backend`, {
|
||||||
appDefinition: {
|
appDefinition: {
|
||||||
hierarchy: s.hierarchy,
|
hierarchy: s.hierarchy,
|
||||||
actions: s.actions,
|
actions: s.actions,
|
||||||
triggers: s.triggers,
|
triggers: s.triggers,
|
||||||
},
|
},
|
||||||
accessLevels: s.accessLevels,
|
accessLevels: s.accessLevels,
|
||||||
page: { componentLibraries: s.pages.componentLibraries, ...page },
|
|
||||||
uiFunctions: "{'1234':() => 'test return'}",
|
|
||||||
props: page.props,
|
|
||||||
screens: page.screens,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -731,7 +735,7 @@ const addChildComponent = store => componentName => {
|
||||||
newComponent.props
|
newComponent.props
|
||||||
)
|
)
|
||||||
|
|
||||||
savePackage(store, s)
|
_savePage(s)
|
||||||
|
|
||||||
return s
|
return s
|
||||||
})
|
})
|
||||||
|
@ -750,7 +754,7 @@ const setComponentProp = store => (name, value) => {
|
||||||
s.currentComponentInfo[name] = value
|
s.currentComponentInfo[name] = value
|
||||||
|
|
||||||
s.currentFrontEndType === "page"
|
s.currentFrontEndType === "page"
|
||||||
? savePackage(store, s, s.currentPreviewItem)
|
? _savePage(s, s.currentPreviewItem)
|
||||||
: _saveScreen(store, s, s.currentPreviewItem)
|
: _saveScreen(store, s, s.currentPreviewItem)
|
||||||
|
|
||||||
s.currentComponentInfo = current_component
|
s.currentComponentInfo = current_component
|
||||||
|
@ -770,8 +774,8 @@ const setComponentStyle = store => (type, name, value) => {
|
||||||
|
|
||||||
// save without messing with the store
|
// save without messing with the store
|
||||||
s.currentFrontEndType === "page"
|
s.currentFrontEndType === "page"
|
||||||
? savePackage(store, s, s.currentPreviewItem)
|
? _savePage(s)
|
||||||
: _save(s.appname, s.currentPreviewItem, store, s)
|
: _saveScreenApi(s.currentPreviewItem, s)
|
||||||
return s
|
return s
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -782,7 +786,7 @@ const setComponentCode = store => code => {
|
||||||
|
|
||||||
setCurrentScreenFunctions(s)
|
setCurrentScreenFunctions(s)
|
||||||
// save without messing with the store
|
// save without messing with the store
|
||||||
_save(s.appname, s.currentPreviewItem, store, s)
|
_saveScreenApi(s.currentPreviewItem, s)
|
||||||
|
|
||||||
return s
|
return s
|
||||||
})
|
})
|
||||||
|
|
|
@ -29,14 +29,17 @@
|
||||||
[map(s => `<link rel="stylesheet" href="${s}"/>`), join("\n")]
|
[map(s => `<link rel="stylesheet" href="${s}"/>`), join("\n")]
|
||||||
)
|
)
|
||||||
|
|
||||||
$: appDefinition = {
|
$: frontendDefinition = {
|
||||||
componentLibraries: $store.loadLibraryUrls(),
|
componentLibraries: $store.loadLibraryUrls(),
|
||||||
props:
|
page: $store.currentPreviewItem,
|
||||||
$store.currentPreviewItem &&
|
screens: [],
|
||||||
transform_component($store.currentPreviewItem, true),
|
|
||||||
hierarchy: $store.hierarchy,
|
|
||||||
appRootPath: "",
|
appRootPath: "",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$: backendDefinition = {
|
||||||
|
hierarchy: $store.hierarchy,
|
||||||
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="component-container">
|
<div class="component-container">
|
||||||
|
@ -55,8 +58,9 @@
|
||||||
}
|
}
|
||||||
<\/style>
|
<\/style>
|
||||||
<\script>
|
<\script>
|
||||||
window["##BUDIBASE_APPDEFINITION##"] = ${JSON.stringify(appDefinition)};
|
window["##BUDIBASE_FRONTEND_DEFINITION##"] = ${JSON.stringify(frontendDefinition)};
|
||||||
window["##BUDIBASE_UIFUNCTIONS"] = ${$store.currentScreenFunctions};
|
window["##BUDIBASE_BACKEND_DEFINITION##"] = ${JSON.stringify(backendDefinition)};
|
||||||
|
window["##BUDIBASE_FRONTEND_FUNCTIONS##"] = ${$store.currentScreenFunctions};
|
||||||
|
|
||||||
import('/_builder/budibase-client.esm.mjs')
|
import('/_builder/budibase-client.esm.mjs')
|
||||||
.then(module => {
|
.then(module => {
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
export const createCoreApp = (appDefinition, user) => {
|
export const createCoreApp = (backendDefinition, user) => {
|
||||||
const app = {
|
const app = {
|
||||||
datastore: null,
|
datastore: null,
|
||||||
crypto: null,
|
crypto: null,
|
||||||
publish: () => {},
|
publish: () => {},
|
||||||
hierarchy: appDefinition.hierarchy,
|
hierarchy: backendDefinition.hierarchy,
|
||||||
actions: appDefinition.actions,
|
actions: backendDefinition.actions,
|
||||||
user,
|
user,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,8 @@ import { createCoreApp } from "./createCoreApp"
|
||||||
import { getNew, getNewChild } from "../../../core/src/recordApi/getNew"
|
import { getNew, getNewChild } from "../../../core/src/recordApi/getNew"
|
||||||
import { constructHierarchy } from "../../../core/src/templateApi/createNodes"
|
import { constructHierarchy } from "../../../core/src/templateApi/createNodes"
|
||||||
|
|
||||||
export const createCoreApi = (appDefinition, user) => {
|
export const createCoreApi = (backendDefinition, user) => {
|
||||||
const app = createCoreApp(appDefinition, user)
|
const app = createCoreApp(backendDefinition, user)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
recordApi: {
|
recordApi: {
|
||||||
|
|
|
@ -11,22 +11,23 @@ import { screenRouter } from "./render/screenRouter"
|
||||||
export const createApp = (
|
export const createApp = (
|
||||||
document,
|
document,
|
||||||
componentLibraries,
|
componentLibraries,
|
||||||
appDefinition,
|
frontendDefinition,
|
||||||
|
backendDefinition,
|
||||||
user,
|
user,
|
||||||
uiFunctions,
|
uiFunctions,
|
||||||
screens
|
screens
|
||||||
) => {
|
) => {
|
||||||
const coreApi = createCoreApi(appDefinition, user)
|
const coreApi = createCoreApi(backendDefinition, user)
|
||||||
appDefinition.hierarchy = coreApi.templateApi.constructHierarchy(
|
backendDefinition.hierarchy = coreApi.templateApi.constructHierarchy(
|
||||||
appDefinition.hierarchy
|
backendDefinition.hierarchy
|
||||||
)
|
)
|
||||||
const pageStore = writable({
|
const pageStore = writable({
|
||||||
_bbuser: user,
|
_bbuser: user,
|
||||||
})
|
})
|
||||||
|
|
||||||
const relativeUrl = url =>
|
const relativeUrl = url =>
|
||||||
appDefinition.appRootPath
|
frontendDefinition.appRootPath
|
||||||
? appDefinition.appRootPath + "/" + trimSlash(url)
|
? frontendDefinition.appRootPath + "/" + trimSlash(url)
|
||||||
: url
|
: url
|
||||||
|
|
||||||
const apiCall = method => (url, body) =>
|
const apiCall = method => (url, body) =>
|
||||||
|
@ -89,7 +90,7 @@ export const createApp = (
|
||||||
store,
|
store,
|
||||||
document,
|
document,
|
||||||
componentLibraries,
|
componentLibraries,
|
||||||
appDefinition,
|
frontendDefinition,
|
||||||
hydrate,
|
hydrate,
|
||||||
uiFunctions,
|
uiFunctions,
|
||||||
treeNode,
|
treeNode,
|
||||||
|
|
|
@ -10,8 +10,9 @@ export const loadBudibase = async ({
|
||||||
localStorage,
|
localStorage,
|
||||||
uiFunctions,
|
uiFunctions,
|
||||||
}) => {
|
}) => {
|
||||||
const appDefinition = window["##BUDIBASE_APPDEFINITION##"]
|
const backendDefinition = window["##BUDIBASE_BACKEND_DEFINITION##"]
|
||||||
const uiFunctionsFromWindow = window["##BUDIBASE_UIFUNCTIONS##"]
|
const frontendDefinition = window["##BUDIBASE_FRONTEND_DEFINITION##"]
|
||||||
|
const uiFunctionsFromWindow = window["##BUDIBASE_FRONTEND_FUNCTIONS##"]
|
||||||
uiFunctions = uiFunctionsFromWindow || uiFunctions
|
uiFunctions = uiFunctionsFromWindow || uiFunctions
|
||||||
|
|
||||||
const userFromStorage = localStorage.getItem("budibase:user")
|
const userFromStorage = localStorage.getItem("budibase:user")
|
||||||
|
@ -26,16 +27,16 @@ export const loadBudibase = async ({
|
||||||
}
|
}
|
||||||
|
|
||||||
const rootPath =
|
const rootPath =
|
||||||
appDefinition.appRootPath === ""
|
frontendDefinition.appRootPath === ""
|
||||||
? ""
|
? ""
|
||||||
: "/" + trimSlash(appDefinition.appRootPath)
|
: "/" + trimSlash(frontendDefinition.appRootPath)
|
||||||
|
|
||||||
if (!componentLibraries) {
|
if (!componentLibraries) {
|
||||||
|
|
||||||
const componentLibraryUrl = lib => rootPath + "/" + trimSlash(lib)
|
const componentLibraryUrl = lib => rootPath + "/" + trimSlash(lib)
|
||||||
componentLibraries = {}
|
componentLibraries = {}
|
||||||
|
|
||||||
for (let lib of appDefinition.componentLibraries) {
|
for (let lib of frontendDefinition.componentLibraries) {
|
||||||
componentLibraries[lib.libName] = await import(
|
componentLibraries[lib.libName] = await import(
|
||||||
componentLibraryUrl(lib.importPath)
|
componentLibraryUrl(lib.importPath)
|
||||||
)
|
)
|
||||||
|
@ -45,17 +46,18 @@ export const loadBudibase = async ({
|
||||||
componentLibraries[builtinLibName] = builtins(window)
|
componentLibraries[builtinLibName] = builtins(window)
|
||||||
|
|
||||||
if (!page) {
|
if (!page) {
|
||||||
page = appDefinition.page
|
page = frontendDefinition.page
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!screens) {
|
if (!screens) {
|
||||||
screens = appDefinition.screens
|
screens = frontendDefinition.screens
|
||||||
}
|
}
|
||||||
|
|
||||||
const { initialisePage, screenStore, pageStore, routeTo, rootNode } = createApp(
|
const { initialisePage, screenStore, pageStore, routeTo, rootNode } = createApp(
|
||||||
window.document,
|
window.document,
|
||||||
componentLibraries,
|
componentLibraries,
|
||||||
appDefinition,
|
frontendDefinition,
|
||||||
|
backendDefinition,
|
||||||
user,
|
user,
|
||||||
uiFunctions || {},
|
uiFunctions || {},
|
||||||
screens
|
screens
|
||||||
|
|
|
@ -16,7 +16,7 @@ export const initialiseChildren = initialiseOpts => (
|
||||||
store,
|
store,
|
||||||
componentLibraries,
|
componentLibraries,
|
||||||
treeNode,
|
treeNode,
|
||||||
appDefinition,
|
frontendDefinition,
|
||||||
hydrate,
|
hydrate,
|
||||||
onScreenSlotRendered,
|
onScreenSlotRendered,
|
||||||
} = initialiseOpts
|
} = initialiseOpts
|
||||||
|
@ -43,7 +43,7 @@ export const initialiseChildren = initialiseOpts => (
|
||||||
store,
|
store,
|
||||||
childProps,
|
childProps,
|
||||||
coreApi,
|
coreApi,
|
||||||
appDefinition.appRootPath
|
frontendDefinition.appRootPath
|
||||||
)
|
)
|
||||||
|
|
||||||
const componentConstructor = componentLibraries[libName][componentName]
|
const componentConstructor = componentLibraries[libName][componentName]
|
||||||
|
|
|
@ -51,13 +51,16 @@ const autoAssignIds = (props, count = 0) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const setAppDef = (window, page, screens) => {
|
const setAppDef = (window, page, screens) => {
|
||||||
window["##BUDIBASE_APPDEFINITION##"] = {
|
window["##BUDIBASE_FRONTEND_DEFINITION##"] = {
|
||||||
componentLibraries: [],
|
componentLibraries: [],
|
||||||
page,
|
page,
|
||||||
screens,
|
screens,
|
||||||
hierarchy: {},
|
|
||||||
appRootPath: "",
|
appRootPath: "",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
window["##BUDIBASE_BACKEND_DEFINITION##"] = {
|
||||||
|
hierarchy: {},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const allLibs = window => ({
|
const allLibs = window => ({
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
|
@ -15,7 +15,8 @@
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|
||||||
<script src='/_master/clientAppDefinition.js'></script>
|
<script src='/_master/clientFrontendDefinition.js'></script>
|
||||||
|
<script src='/_master/clientBackendDefinition.js'></script>
|
||||||
<script src='/_master/budibase-client.js'></script>
|
<script src='/_master/budibase-client.js'></script>
|
||||||
<script>
|
<script>
|
||||||
loadBudibase();
|
loadBudibase();
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
|
@ -15,7 +15,8 @@
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|
||||||
<script src='/_master/clientAppDefinition.js'></script>
|
<script src='/_master/clientFrontendDefinition.js'></script>
|
||||||
|
<script src='/_master/clientBackendDefinition.js'></script>
|
||||||
<script src='/_master/budibase-client.js'></script>
|
<script src='/_master/budibase-client.js'></script>
|
||||||
<script>
|
<script>
|
||||||
loadBudibase();
|
loadBudibase();
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
|
@ -29,7 +29,8 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<script src='/clientAppDefinition.js'></script>
|
<script src='/_master/clientFrontendDefinition.js'></script>
|
||||||
|
<script src='/_master/clientBackendDefinition.js'></script>
|
||||||
<script src='/budibase-client.js'></script>
|
<script src='/budibase-client.js'></script>
|
||||||
<script>
|
<script>
|
||||||
loadBudibase();
|
loadBudibase();
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
|
@ -17,7 +17,8 @@
|
||||||
<link rel='stylesheet' href='https://css-r-us.com/myawesomestyles.css'>
|
<link rel='stylesheet' href='https://css-r-us.com/myawesomestyles.css'>
|
||||||
<link rel='stylesheet' href='///local.css'>
|
<link rel='stylesheet' href='///local.css'>
|
||||||
|
|
||||||
<script src='/clientAppDefinition.js'></script>
|
<script src='/_master/clientFrontendDefinition.js'></script>
|
||||||
|
<script src='/_master/clientBackendDefinition.js'></script>
|
||||||
<script src='/budibase-client.js'></script>
|
<script src='/budibase-client.js'></script>
|
||||||
<script>
|
<script>
|
||||||
loadBudibase();
|
loadBudibase();
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
|
@ -16,7 +16,8 @@
|
||||||
|
|
||||||
<link rel='stylesheet' href='https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css'>
|
<link rel='stylesheet' href='https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css'>
|
||||||
|
|
||||||
<script src='/testApp2/clientAppDefinition.js'></script>
|
<script src='/_master/clientFrontendDefinition.js'></script>
|
||||||
|
<script src='/_master/clientBackendDefinition.js'></script>
|
||||||
<script src='/testApp2/budibase-client.js'></script>
|
<script src='/testApp2/budibase-client.js'></script>
|
||||||
<script>
|
<script>
|
||||||
loadBudibase();
|
loadBudibase();
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
|
@ -16,7 +16,8 @@
|
||||||
|
|
||||||
<link rel='stylesheet' href='https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css'>
|
<link rel='stylesheet' href='https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css'>
|
||||||
|
|
||||||
<script src='/testApp2/clientAppDefinition.js'></script>
|
<script src='/_master/clientFrontendDefinition.js'></script>
|
||||||
|
<script src='/_master/clientBackendDefinition.js'></script>
|
||||||
<script src='/testApp2/budibase-client.js'></script>
|
<script src='/testApp2/budibase-client.js'></script>
|
||||||
<script>
|
<script>
|
||||||
loadBudibase();
|
loadBudibase();
|
||||||
|
|
|
@ -11,9 +11,10 @@ const {
|
||||||
saveScreen,
|
saveScreen,
|
||||||
renameScreen,
|
renameScreen,
|
||||||
deleteScreen,
|
deleteScreen,
|
||||||
savePagePackage,
|
buildPage,
|
||||||
componentLibraryInfo,
|
componentLibraryInfo,
|
||||||
listScreens,
|
listScreens,
|
||||||
|
saveBackend,
|
||||||
} = require("../utilities/builder")
|
} = require("../utilities/builder")
|
||||||
|
|
||||||
const builderPath = resolve(__dirname, "../builder")
|
const builderPath = resolve(__dirname, "../builder")
|
||||||
|
@ -179,8 +180,17 @@ module.exports = (config, app) => {
|
||||||
ctx.body = info.generators
|
ctx.body = info.generators
|
||||||
ctx.response.status = StatusCodes.OK
|
ctx.response.status = StatusCodes.OK
|
||||||
})
|
})
|
||||||
|
.post("/_builder/api/:appname/backend", async ctx => {
|
||||||
|
await saveBackend(
|
||||||
|
config,
|
||||||
|
ctx.params.appname,
|
||||||
|
ctx.request.body.appDefinition,
|
||||||
|
ctx.request.body.accessLevels
|
||||||
|
)
|
||||||
|
ctx.response.status = StatusCodes.OK
|
||||||
|
})
|
||||||
.post("/_builder/api/:appname/pages/:pageName", async ctx => {
|
.post("/_builder/api/:appname/pages/:pageName", async ctx => {
|
||||||
await savePagePackage(
|
await buildPage(
|
||||||
config,
|
config,
|
||||||
ctx.params.appname,
|
ctx.params.appname,
|
||||||
ctx.params.pageName,
|
ctx.params.pageName,
|
||||||
|
|
|
@ -8,24 +8,27 @@ const {
|
||||||
copyFile,
|
copyFile,
|
||||||
writeFile,
|
writeFile,
|
||||||
readFile,
|
readFile,
|
||||||
|
writeJSON,
|
||||||
} = require("fs-extra")
|
} = require("fs-extra")
|
||||||
const { join, resolve, dirname } = require("path")
|
const { join, resolve, dirname } = require("path")
|
||||||
const sqrl = require("squirrelly")
|
const sqrl = require("squirrelly")
|
||||||
const { convertCssToFiles } = require("./convertCssToFiles")
|
const { convertCssToFiles } = require("./convertCssToFiles")
|
||||||
|
const publicPath = require("./publicPath")
|
||||||
|
|
||||||
module.exports = async (config, appname, pkg) => {
|
module.exports = async (config, appname, pageName, pkg) => {
|
||||||
const appPath = appPackageFolder(config, appname)
|
const appPath = appPackageFolder(config, appname)
|
||||||
|
|
||||||
await convertCssToFiles(publicPath(appPath, pkg.pageName), pkg)
|
await convertCssToFiles(publicPath(appPath, pageName), pkg)
|
||||||
|
|
||||||
await buildIndexHtml(config, appname, appPath, pkg)
|
await buildIndexHtml(config, appname, pageName, appPath, pkg)
|
||||||
|
|
||||||
await buildClientAppDefinition(config, appname, pkg, appPath)
|
await buildFrontendAppDefinition(config, appname, pageName, pkg, appPath)
|
||||||
|
|
||||||
await copyClientLib(appPath, pkg.pageName)
|
await copyClientLib(appPath, pageName)
|
||||||
|
|
||||||
|
await savePageJson(appPath, pageName, pkg)
|
||||||
}
|
}
|
||||||
|
|
||||||
const publicPath = (appPath, pageName) => join(appPath, "public", pageName)
|
|
||||||
const rootPath = (config, appname) =>
|
const rootPath = (config, appname) =>
|
||||||
config.useAppRootPath ? `/${appname}` : ""
|
config.useAppRootPath ? `/${appname}` : ""
|
||||||
|
|
||||||
|
@ -42,8 +45,8 @@ const copyClientLib = async (appPath, pageName) => {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const buildIndexHtml = async (config, appname, appPath, pkg) => {
|
const buildIndexHtml = async (config, appname, pageName, appPath, pkg) => {
|
||||||
const appPublicPath = publicPath(appPath, pkg.pageName)
|
const appPublicPath = publicPath(appPath, pageName)
|
||||||
const appRootPath = rootPath(config, appname)
|
const appRootPath = rootPath(config, appname)
|
||||||
|
|
||||||
const stylesheetUrl = s =>
|
const stylesheetUrl = s =>
|
||||||
|
@ -72,9 +75,9 @@ const buildIndexHtml = async (config, appname, appPath, pkg) => {
|
||||||
await writeFile(indexHtmlPath, indexHtml, { flag: "w+" })
|
await writeFile(indexHtmlPath, indexHtml, { flag: "w+" })
|
||||||
}
|
}
|
||||||
|
|
||||||
const buildClientAppDefinition = async (config, appname, pkg) => {
|
const buildFrontendAppDefinition = async (config, appname, pageName, pkg) => {
|
||||||
const appPath = appPackageFolder(config, appname)
|
const appPath = appPackageFolder(config, appname)
|
||||||
const appPublicPath = publicPath(appPath, pkg.pageName)
|
const appPublicPath = publicPath(appPath, pageName)
|
||||||
const appRootPath = rootPath(config, appname)
|
const appRootPath = rootPath(config, appname)
|
||||||
|
|
||||||
const componentLibraries = []
|
const componentLibraries = []
|
||||||
|
@ -109,7 +112,7 @@ const buildClientAppDefinition = async (config, appname, pkg) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const filename = join(appPublicPath, "clientAppDefinition.js")
|
const filename = join(appPublicPath, "clientFrontendDefinition.js")
|
||||||
|
|
||||||
if (pkg.page._css) {
|
if (pkg.page._css) {
|
||||||
delete pkg.page._css
|
delete pkg.page._css
|
||||||
|
@ -121,17 +124,32 @@ const buildClientAppDefinition = async (config, appname, pkg) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const clientAppDefObj = {
|
const clientUiDefinition = JSON.stringify({
|
||||||
hierarchy: pkg.appDefinition.hierarchy,
|
|
||||||
componentLibraries: componentLibraries,
|
componentLibraries: componentLibraries,
|
||||||
appRootPath: appRootPath,
|
appRootPath: appRootPath,
|
||||||
page: pkg.page,
|
page: pkg.page,
|
||||||
screens: pkg.screens,
|
screens: pkg.screens,
|
||||||
}
|
})
|
||||||
|
|
||||||
await writeFile(
|
await writeFile(
|
||||||
filename,
|
filename,
|
||||||
`window['##BUDIBASE_APPDEFINITION##'] = ${JSON.stringify(clientAppDefObj)};
|
`window['##BUDIBASE_FRONTEND_DEINITION##'] = ${clientUiDefinition};
|
||||||
window['##BUDIBASE_UIFUNCTIONS##'] = ${pkg.uiFunctions}`
|
window['##BUDIBASE_FRONTEND_FUNCTIONS##'] = ${pkg.uiFunctions}`
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const savePageJson = async (appPath, pageName, pkg) => {
|
||||||
|
const pageFile = join(appPath, "pages", pageName, "page.json")
|
||||||
|
|
||||||
|
if (pkg.page._css) {
|
||||||
|
delete pkg.page._css
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pkg.page.name) {
|
||||||
|
delete pkg.page.name
|
||||||
|
}
|
||||||
|
|
||||||
|
await writeJSON(pageFile, pkg.page, {
|
||||||
|
spaces: 2,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
const { readJSON, readdir } = require("fs-extra")
|
||||||
|
const { join } = require("path")
|
||||||
|
|
||||||
|
module.exports = async appPath => {
|
||||||
|
const pages = {}
|
||||||
|
|
||||||
|
const pageFolders = await readdir(join(appPath, "pages"))
|
||||||
|
for (let pageFolder of pageFolders) {
|
||||||
|
try {
|
||||||
|
pages[pageFolder] = await readJSON(
|
||||||
|
join(appPath, "pages", pageFolder, "page.json")
|
||||||
|
)
|
||||||
|
pages[pageFolder].name = pageFolder
|
||||||
|
} catch (_) {
|
||||||
|
// ignore error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return pages
|
||||||
|
}
|
|
@ -3,7 +3,6 @@ const {
|
||||||
readJSON,
|
readJSON,
|
||||||
writeJSON,
|
writeJSON,
|
||||||
readdir,
|
readdir,
|
||||||
stat,
|
|
||||||
ensureDir,
|
ensureDir,
|
||||||
rename,
|
rename,
|
||||||
unlink,
|
unlink,
|
||||||
|
@ -11,14 +10,18 @@ const {
|
||||||
} = require("fs-extra")
|
} = require("fs-extra")
|
||||||
const { join, dirname } = require("path")
|
const { join, dirname } = require("path")
|
||||||
const { $ } = require("@budibase/core").common
|
const { $ } = require("@budibase/core").common
|
||||||
const { keyBy, intersection, map, values, flatten } = require("lodash/fp")
|
const { intersection, map, values, flatten } = require("lodash/fp")
|
||||||
const { merge } = require("lodash")
|
const { merge } = require("lodash")
|
||||||
|
|
||||||
const { componentLibraryInfo } = require("./componentLibraryInfo")
|
const { componentLibraryInfo } = require("./componentLibraryInfo")
|
||||||
const savePagePackage = require("./savePagePackage")
|
|
||||||
const buildPage = require("./buildPage")
|
const buildPage = require("./buildPage")
|
||||||
|
const getPages = require("./getPages")
|
||||||
|
const listScreens = require("./listScreens")
|
||||||
|
const saveBackend = require("./saveBackend")
|
||||||
|
|
||||||
module.exports.savePagePackage = savePagePackage
|
module.exports.buildPage = buildPage
|
||||||
|
module.exports.listScreens = listScreens
|
||||||
|
module.exports.saveBackend = saveBackend
|
||||||
|
|
||||||
const getAppDefinition = async appPath =>
|
const getAppDefinition = async appPath =>
|
||||||
await readJSON(`${appPath}/appDefinition.json`)
|
await readJSON(`${appPath}/appDefinition.json`)
|
||||||
|
@ -45,31 +48,9 @@ module.exports.getApps = async (config, master) => {
|
||||||
return $(master.listApplications(), [map(a => a.name), intersection(dirs)])
|
return $(master.listApplications(), [map(a => a.name), intersection(dirs)])
|
||||||
}
|
}
|
||||||
|
|
||||||
const getPages = async appPath => {
|
|
||||||
const pages = {}
|
|
||||||
|
|
||||||
const pageFolders = await readdir(join(appPath, "pages"))
|
|
||||||
for (let pageFolder of pageFolders) {
|
|
||||||
try {
|
|
||||||
pages[pageFolder] = await readJSON(
|
|
||||||
join(appPath, "pages", pageFolder, "page.json")
|
|
||||||
)
|
|
||||||
} catch (_) {
|
|
||||||
// ignore error
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return pages
|
|
||||||
}
|
|
||||||
|
|
||||||
const screenPath = (appPath, pageName, name) =>
|
const screenPath = (appPath, pageName, name) =>
|
||||||
join(appPath, "pages", pageName, "screens", name + ".json")
|
join(appPath, "pages", pageName, "screens", name + ".json")
|
||||||
|
|
||||||
module.exports.listScreens = async (config, appname, pagename) => {
|
|
||||||
const appPath = appPackageFolder(config, appname)
|
|
||||||
return keyBy("name")(await fetchscreens(appPath, pagename))
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports.saveScreen = async (config, appname, pagename, screen) => {
|
module.exports.saveScreen = async (config, appname, pagename, screen) => {
|
||||||
const appPath = appPackageFolder(config, appname)
|
const appPath = appPackageFolder(config, appname)
|
||||||
const compPath = screenPath(appPath, pagename, screen.name)
|
const compPath = screenPath(appPath, pagename, screen.name)
|
||||||
|
@ -158,43 +139,4 @@ const getComponents = async (appPath, pages, lib) => {
|
||||||
return { components, generators }
|
return { components, generators }
|
||||||
}
|
}
|
||||||
|
|
||||||
const fetchscreens = async (appPath, pagename, relativePath = "") => {
|
|
||||||
const currentDir = join(appPath, "pages", pagename, "screens", relativePath)
|
|
||||||
|
|
||||||
const contents = await readdir(currentDir)
|
|
||||||
|
|
||||||
const screens = []
|
|
||||||
|
|
||||||
for (let item of contents) {
|
|
||||||
const itemRelativePath = join(relativePath, item)
|
|
||||||
const itemFullPath = join(currentDir, item)
|
|
||||||
const stats = await stat(itemFullPath)
|
|
||||||
|
|
||||||
if (stats.isFile()) {
|
|
||||||
if (!item.endsWith(".json")) continue
|
|
||||||
|
|
||||||
const component = await readJSON(itemFullPath)
|
|
||||||
|
|
||||||
component.name = itemRelativePath
|
|
||||||
.substring(0, itemRelativePath.length - 5)
|
|
||||||
.replace(/\\/g, "/")
|
|
||||||
|
|
||||||
component.props = component.props || {}
|
|
||||||
|
|
||||||
screens.push(component)
|
|
||||||
} else {
|
|
||||||
const childComponents = await fetchscreens(
|
|
||||||
appPath,
|
|
||||||
join(relativePath, item)
|
|
||||||
)
|
|
||||||
|
|
||||||
for (let c of childComponents) {
|
|
||||||
screens.push(c)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return screens
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports.getComponents = getComponents
|
module.exports.getComponents = getComponents
|
||||||
|
|
|
@ -27,7 +27,8 @@
|
||||||
{{ /if }}
|
{{ /if }}
|
||||||
|
|
||||||
|
|
||||||
<script src='{{ appRootPath }}/clientAppDefinition.js'></script>
|
<script src='{{ appRootPath }}/clientFrontendDefinition.js'></script>
|
||||||
|
<script src='{{ appRootPath }}/clientBackendDefinition.js'></script>
|
||||||
<script src='{{ appRootPath }}/budibase-client.js'></script>
|
<script src='{{ appRootPath }}/budibase-client.js'></script>
|
||||||
<script>
|
<script>
|
||||||
loadBudibase();
|
loadBudibase();
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
const { appPackageFolder } = require("../createAppPackage")
|
||||||
|
const { readJSON, readdir, stat } = require("fs-extra")
|
||||||
|
const { join } = require("path")
|
||||||
|
const { keyBy } = require("lodash/fp")
|
||||||
|
|
||||||
|
module.exports = async (config, appname, pagename) => {
|
||||||
|
const appPath = appPackageFolder(config, appname)
|
||||||
|
return keyBy("name")(await fetchscreens(appPath, pagename))
|
||||||
|
}
|
||||||
|
|
||||||
|
const fetchscreens = async (appPath, pagename, relativePath = "") => {
|
||||||
|
const currentDir = join(appPath, "pages", pagename, "screens", relativePath)
|
||||||
|
|
||||||
|
const contents = await readdir(currentDir)
|
||||||
|
|
||||||
|
const screens = []
|
||||||
|
|
||||||
|
for (let item of contents) {
|
||||||
|
const itemRelativePath = join(relativePath, item)
|
||||||
|
const itemFullPath = join(currentDir, item)
|
||||||
|
const stats = await stat(itemFullPath)
|
||||||
|
|
||||||
|
if (stats.isFile()) {
|
||||||
|
if (!item.endsWith(".json")) continue
|
||||||
|
|
||||||
|
const component = await readJSON(itemFullPath)
|
||||||
|
|
||||||
|
component.name = itemRelativePath
|
||||||
|
.substring(0, itemRelativePath.length - 5)
|
||||||
|
.replace(/\\/g, "/")
|
||||||
|
|
||||||
|
component.props = component.props || {}
|
||||||
|
|
||||||
|
screens.push(component)
|
||||||
|
} else {
|
||||||
|
const childComponents = await fetchscreens(
|
||||||
|
appPath,
|
||||||
|
join(relativePath, item)
|
||||||
|
)
|
||||||
|
|
||||||
|
for (let c of childComponents) {
|
||||||
|
screens.push(c)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return screens
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
const { join } = require("path")
|
||||||
|
|
||||||
|
module.exports = (appPath, pageName) => join(appPath, "public", pageName)
|
|
@ -0,0 +1,28 @@
|
||||||
|
const getPages = require("./getPages")
|
||||||
|
const { appPackageFolder } = require("../createAppPackage")
|
||||||
|
const { writeJSON, writeFile } = require("fs-extra")
|
||||||
|
const { join } = require("path")
|
||||||
|
const publicPath = require("./publicPath")
|
||||||
|
|
||||||
|
module.exports = async (config, appname, appDefinition, accessLevels) => {
|
||||||
|
const appPath = appPackageFolder(config, appname)
|
||||||
|
|
||||||
|
await writeJSON(`${appPath}/appDefinition.json`, appDefinition, {
|
||||||
|
spaces: 2,
|
||||||
|
})
|
||||||
|
|
||||||
|
await writeJSON(`${appPath}/access_levels.json`, accessLevels, {
|
||||||
|
spaces: 2,
|
||||||
|
})
|
||||||
|
|
||||||
|
const pages = await getPages(appPath)
|
||||||
|
for (let pageName in pages) {
|
||||||
|
const pagePublicPath = publicPath(appPath, pageName)
|
||||||
|
const filename = join(pagePublicPath, "clientBackendDefinition.js")
|
||||||
|
const appDefString = JSON.stringify(appDefinition)
|
||||||
|
await writeFile(
|
||||||
|
filename,
|
||||||
|
`window['##BUDIBASE_FRONTEND_DEINITION##'] = ${appDefString};`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,30 +0,0 @@
|
||||||
const { appPackageFolder } = require("../createAppPackage")
|
|
||||||
const { writeJSON } = require("fs-extra")
|
|
||||||
const { join } = require("path")
|
|
||||||
|
|
||||||
const buildPage = require("./buildPage")
|
|
||||||
|
|
||||||
module.exports = async (config, appname, pageName, pkg) => {
|
|
||||||
const appPath = appPackageFolder(config, appname)
|
|
||||||
pkg.pageName = pageName
|
|
||||||
|
|
||||||
await writeJSON(`${appPath}/appDefinition.json`, pkg.appDefinition, {
|
|
||||||
spaces: 2,
|
|
||||||
})
|
|
||||||
|
|
||||||
await writeJSON(`${appPath}/access_levels.json`, pkg.accessLevels, {
|
|
||||||
spaces: 2,
|
|
||||||
})
|
|
||||||
|
|
||||||
await buildPage(config, appname, pkg)
|
|
||||||
|
|
||||||
const pageFile = join(appPath, "pages", pageName, "page.json")
|
|
||||||
|
|
||||||
if (pkg.page._css) {
|
|
||||||
delete pkg.page._css
|
|
||||||
}
|
|
||||||
|
|
||||||
await writeJSON(pageFile, pkg.page, {
|
|
||||||
spaces: 2,
|
|
||||||
})
|
|
||||||
}
|
|
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue