merging with master
This commit is contained in:
parent
8be69162f7
commit
0b3f75aaff
|
@ -462,14 +462,13 @@ const saveScreen = store => screen => {
|
|||
}
|
||||
|
||||
const _saveScreen = (store, s, screen) => {
|
||||
s.currentFrontEndItem = screen
|
||||
s.currentComponentInfo = getScreenInfo(s.components, screen)
|
||||
const currentPageScreens = s.pages[s.currentPageName]._screens
|
||||
|
||||
api
|
||||
.post(`/_builder/api/${s.appname}/screen`, screen)
|
||||
.post(`/_builder/api/${s.appname}/pages/${s.currentPageName}/screen`, screen)
|
||||
.then(async savedScreen => {
|
||||
const updatedScreen = await savedScreen.json();
|
||||
const screens = [...s.screens.filter(storeScreen => storeScreen.name !== updatedScreen.name), updatedScreen];
|
||||
const screens = [...currentPageScreens.filter(storeScreen => storeScreen.name !== updatedScreen.name), updatedScreen];
|
||||
s.pages[s.currentPageName]._screens = screens
|
||||
s.screens = screens
|
||||
_savePage(s);
|
||||
|
|
|
@ -1,69 +1,79 @@
|
|||
<script>
|
||||
import { store } from "../builderStore";
|
||||
import { map, join } from "lodash/fp";
|
||||
import { pipe } from "../common/core";
|
||||
import { buildPropsHierarchy } from "./pagesParsing/buildPropsHierarchy";
|
||||
import { store } from "../builderStore"
|
||||
import { map, join } from "lodash/fp"
|
||||
import { pipe } from "../common/core"
|
||||
|
||||
let iframe;
|
||||
let iframe
|
||||
|
||||
$: iframe && console.log(iframe.contentDocument.head.insertAdjacentHTML('beforeend', '<style></style>'))
|
||||
$: hasComponent = !!$store.currentFrontEndItem;
|
||||
$: styles = hasComponent ? $store.currentFrontEndItem._css : '';
|
||||
function transform_component(comp) {
|
||||
const props = comp.props || comp
|
||||
if (props && props._children && props._children.length) {
|
||||
props._children = props._children.map(transform_component)
|
||||
}
|
||||
|
||||
$: stylesheetLinks = pipe($store.pages.stylesheets, [
|
||||
map(s => `<link rel="stylesheet" href="${s}"/>`),
|
||||
join("\n")
|
||||
]);
|
||||
return props
|
||||
}
|
||||
|
||||
$: appDefinition = {
|
||||
$: iframe &&
|
||||
console.log(
|
||||
iframe.contentDocument.head.insertAdjacentHTML(
|
||||
"beforeend",
|
||||
`<\style></style>`
|
||||
)
|
||||
)
|
||||
$: hasComponent = !!$store.currentPreviewItem
|
||||
$: styles = hasComponent ? $store.currentPreviewItem._css : ""
|
||||
|
||||
$: stylesheetLinks = pipe(
|
||||
$store.pages.stylesheets,
|
||||
[map(s => `<link rel="stylesheet" href="${s}"/>`), join("\n")]
|
||||
)
|
||||
|
||||
$: frontendDefinition = {
|
||||
componentLibraries: $store.loadLibraryUrls(),
|
||||
props: buildPropsHierarchy(
|
||||
$store.components,
|
||||
$store.screens,
|
||||
$store.currentFrontEndItem),
|
||||
page: $store.currentPreviewItem,
|
||||
screens: [],
|
||||
appRootPath: "",
|
||||
}
|
||||
|
||||
$: backendDefinition = {
|
||||
hierarchy: $store.hierarchy,
|
||||
appRootPath: ""
|
||||
};
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
<div class="component-container">
|
||||
{#if hasComponent}
|
||||
<iframe style="height: 100%; width: 100%"
|
||||
{#if hasComponent && $store.currentPreviewItem}
|
||||
<iframe
|
||||
style="height: 100%; width: 100%"
|
||||
title="componentPreview"
|
||||
bind:this={iframe}
|
||||
srcdoc={
|
||||
`<html>
|
||||
|
||||
srcdoc={`<html>
|
||||
<head>
|
||||
${stylesheetLinks}
|
||||
<script>
|
||||
window["##BUDIBASE_APPDEFINITION##"] = ${JSON.stringify(appDefinition)};
|
||||
window["##BUDIBASE_UIFUNCTIONS"] = ${$store.currentScreenFunctions};
|
||||
<style>
|
||||
${styles || ''}
|
||||
body, html {
|
||||
height: 100%!important;
|
||||
}
|
||||
<\/style>
|
||||
<\script>
|
||||
window["##BUDIBASE_FRONTEND_DEFINITION##"] = ${JSON.stringify(frontendDefinition)};
|
||||
window["##BUDIBASE_BACKEND_DEFINITION##"] = ${JSON.stringify(backendDefinition)};
|
||||
window["##BUDIBASE_FRONTEND_FUNCTIONS##"] = ${$store.currentScreenFunctions};
|
||||
|
||||
import('/_builder/budibase-client.esm.mjs')
|
||||
.then(module => {
|
||||
module.loadBudibase({ window, localStorage });
|
||||
})
|
||||
</script>
|
||||
<style>
|
||||
|
||||
body {
|
||||
box-sizing: border-box;
|
||||
padding: 20px;
|
||||
}
|
||||
${styles}
|
||||
</style>
|
||||
<\/script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>`}>
|
||||
</iframe>
|
||||
</html>`} />
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
|
||||
<style>
|
||||
.component-container {
|
||||
grid-row-start: middle;
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
export const EVENT_TYPE = "event"
|
||||
|
||||
export let componentInfo
|
||||
export let component
|
||||
export let onPropChanged = () => {}
|
||||
export let components
|
||||
|
||||
|
@ -33,15 +33,16 @@
|
|||
let events = []
|
||||
let selectedEvent = null
|
||||
|
||||
|
||||
$: {
|
||||
events = Object.keys(componentInfo)
|
||||
events = Object.keys(component)
|
||||
.filter(key => findType(key) === EVENT_TYPE)
|
||||
.map(key => ({ name: key, handlers: componentInfo[key] }))
|
||||
.map(key => ({ name: key, handlers: component[key] }))
|
||||
}
|
||||
|
||||
function findType(propName) {
|
||||
if (!componentInfo._component) return
|
||||
return components.find(({ name }) => name === componentInfo._component)
|
||||
if (!component._component) return
|
||||
return components.find(({ name }) => name === component._component)
|
||||
.props[propName]
|
||||
}
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
: value;
|
||||
|
||||
const currentScreen = $store.screens.find(
|
||||
({ name }) => name === $store.currentFrontEndItem.name
|
||||
({ name }) => name === $store.currentPreviewItem.name
|
||||
);
|
||||
stateBindings = currentScreen ? currentScreen.stateOrigins : [];
|
||||
}
|
||||
|
|
|
@ -207,7 +207,7 @@ module.exports = (config, app) => {
|
|||
ctx.response.status = StatusCodes.OK
|
||||
})
|
||||
.post("/_builder/api/:appname/pages/:pagename/screen", async ctx => {
|
||||
await saveScreen(
|
||||
ctx.body = await saveScreen(
|
||||
config,
|
||||
ctx.params.appname,
|
||||
ctx.params.pagename,
|
||||
|
|
|
@ -18,6 +18,8 @@ const publicPath = require("./publicPath")
|
|||
module.exports = async (config, appname, pageName, pkg) => {
|
||||
const appPath = appPackageFolder(config, appname)
|
||||
|
||||
pkg.screens = pkg.screens || []
|
||||
|
||||
await convertCssToFiles(publicPath(appPath, pageName), pkg)
|
||||
|
||||
await buildIndexHtml(config, appname, pageName, appPath, pkg)
|
||||
|
|
|
@ -63,8 +63,8 @@ module.exports.saveScreen = async (config, appname, pagename, screen) => {
|
|||
flag: "w",
|
||||
spaces: 2,
|
||||
})
|
||||
component.stateOrigins = buildStateOrigins(component);
|
||||
return component;
|
||||
screen.stateOrigins = listScreens.buildStateOrigins(screen);
|
||||
return screen;
|
||||
}
|
||||
|
||||
module.exports.renameScreen = async (
|
||||
|
@ -141,75 +141,4 @@ const getComponents = async (appPath, pages, lib) => {
|
|||
return { components, generators }
|
||||
}
|
||||
|
||||
/**
|
||||
* buildStateOrigins
|
||||
*
|
||||
* Builds an object that details all the bound state in the application, and what updates it.
|
||||
*
|
||||
* @param screenDefinition - the screen definition metadata.
|
||||
* @returns {Object} an object with the client state values and how they are managed.
|
||||
*/
|
||||
const buildStateOrigins = screenDefinition => {
|
||||
const origins = {};
|
||||
|
||||
function traverse(propValue) {
|
||||
for (let key in propValue) {
|
||||
if (!Array.isArray(propValue[key])) continue;
|
||||
|
||||
if (key === "_children") propValue[key].forEach(traverse);
|
||||
|
||||
for (let element of propValue[key]) {
|
||||
if (element["##eventHandlerType"] === "Set State") origins[element.parameters.path] = element;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
traverse(screenDefinition.props);
|
||||
|
||||
return origins;
|
||||
};
|
||||
|
||||
module.exports.buildStateOrigins = buildStateOrigins;
|
||||
|
||||
const fetchscreens = async (appPath, relativePath = "") => {
|
||||
const currentDir = join(appPath, "components", relativePath)
|
||||
|
||||
const contents = await readdir(currentDir)
|
||||
|
||||
const components = []
|
||||
|
||||
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 || {}
|
||||
|
||||
component.stateOrigins = buildStateOrigins(component);
|
||||
|
||||
components.push(component)
|
||||
} else {
|
||||
const childComponents = await fetchscreens(
|
||||
appPath,
|
||||
join(relativePath, item)
|
||||
)
|
||||
|
||||
for (let c of childComponents) {
|
||||
components.push(c)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return components
|
||||
}
|
||||
|
||||
module.exports.getComponents = getComponents
|
||||
|
|
|
@ -31,6 +31,8 @@ const fetchscreens = async (appPath, pagename, relativePath = "") => {
|
|||
|
||||
component.props = component.props || {}
|
||||
|
||||
component.stateOrigins = buildStateOrigins(component);
|
||||
|
||||
screens.push(component)
|
||||
} else {
|
||||
const childComponents = await fetchscreens(
|
||||
|
@ -46,3 +48,33 @@ const fetchscreens = async (appPath, pagename, relativePath = "") => {
|
|||
|
||||
return screens
|
||||
}
|
||||
|
||||
/**
|
||||
* buildStateOrigins
|
||||
*
|
||||
* Builds an object that details all the bound state in the application, and what updates it.
|
||||
*
|
||||
* @param screenDefinition - the screen definition metadata.
|
||||
* @returns {Object} an object with the client state values and how they are managed.
|
||||
*/
|
||||
const buildStateOrigins = screenDefinition => {
|
||||
const origins = {};
|
||||
|
||||
function traverse(propValue) {
|
||||
for (let key in propValue) {
|
||||
if (!Array.isArray(propValue[key])) continue;
|
||||
|
||||
if (key === "_children") propValue[key].forEach(traverse);
|
||||
|
||||
for (let element of propValue[key]) {
|
||||
if (element["##eventHandlerType"] === "Set State") origins[element.parameters.path] = element;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
traverse(screenDefinition.props);
|
||||
|
||||
return origins;
|
||||
};
|
||||
|
||||
module.exports.buildStateOrigins = buildStateOrigins;
|
|
@ -131,6 +131,29 @@
|
|||
lodash "^4.17.13"
|
||||
to-fast-properties "^2.0.0"
|
||||
|
||||
"@budibase/client@^0.0.16":
|
||||
version "0.0.16"
|
||||
resolved "https://registry.yarnpkg.com/@budibase/client/-/client-0.0.16.tgz#4eef9373816448e99cafd2714f417c6610af5e69"
|
||||
integrity sha512-fx4ptePj7+IehM37xdNPHdu5jEUgAFmDx23jI0yb4sI6Z5U4gxH10FZYyoJ/A9KdzmShsIfgrmudV5ffvoehdg==
|
||||
dependencies:
|
||||
"@nx-js/compiler-util" "^2.0.0"
|
||||
lodash "^4.17.15"
|
||||
lunr "^2.3.5"
|
||||
shortid "^2.2.8"
|
||||
svelte "^3.9.2"
|
||||
|
||||
"@budibase/core@^0.0.16":
|
||||
version "0.0.16"
|
||||
resolved "https://registry.yarnpkg.com/@budibase/core/-/core-0.0.16.tgz#efff16876f906b2aa59803c3312ec7593664b623"
|
||||
integrity sha512-DvzfurHHp9KkSjkvbGbKsVczR5ne38bMLRA2hHEJxAmC0Tshld06cEq7HMy2BmPb6kaC1URYHlFs/gPhW2cSFQ==
|
||||
dependencies:
|
||||
"@nx-js/compiler-util" "^2.0.0"
|
||||
date-fns "^1.29.0"
|
||||
lodash "^4.17.13"
|
||||
lunr "^2.3.5"
|
||||
safe-buffer "^5.1.2"
|
||||
shortid "^2.2.8"
|
||||
|
||||
"@cnakazawa/watch@^1.0.3":
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@cnakazawa/watch/-/watch-1.0.3.tgz#099139eaec7ebf07a27c1786a3ff64f39464d2ef"
|
||||
|
@ -299,6 +322,11 @@
|
|||
path-to-regexp "^1.1.1"
|
||||
urijs "^1.19.0"
|
||||
|
||||
"@nx-js/compiler-util@^2.0.0":
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@nx-js/compiler-util/-/compiler-util-2.0.0.tgz#c74c12165fa2f017a292bb79af007e8fce0af297"
|
||||
integrity sha512-AxSQbwj9zqt8DYPZ6LwZdytqnwfiOEdcFdq4l8sdjkZmU2clTht7RDLCI8xvkp7KqgcNaOGlTeCM55TULWruyQ==
|
||||
|
||||
"@types/babel__core@^7.1.0":
|
||||
version "7.1.2"
|
||||
resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.2.tgz#608c74f55928033fce18b99b213c16be4b3d114f"
|
||||
|
@ -1045,6 +1073,11 @@ data-urls@^1.0.0:
|
|||
whatwg-mimetype "^2.2.0"
|
||||
whatwg-url "^7.0.0"
|
||||
|
||||
date-fns@^1.29.0:
|
||||
version "1.30.1"
|
||||
resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-1.30.1.tgz#2e71bf0b119153dbb4cc4e88d9ea5acfb50dc05c"
|
||||
integrity sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw==
|
||||
|
||||
debug@^2.2.0, debug@^2.3.3:
|
||||
version "2.6.9"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
|
||||
|
@ -2752,7 +2785,7 @@ lodash.sortby@^4.7.0:
|
|||
resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438"
|
||||
integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=
|
||||
|
||||
lodash@^4.17.11, lodash@^4.17.13:
|
||||
lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.15:
|
||||
version "4.17.15"
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548"
|
||||
integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==
|
||||
|
@ -2777,6 +2810,11 @@ lru-cache@^4.0.1:
|
|||
pseudomap "^1.0.2"
|
||||
yallist "^2.1.2"
|
||||
|
||||
lunr@^2.3.5:
|
||||
version "2.3.8"
|
||||
resolved "https://registry.yarnpkg.com/lunr/-/lunr-2.3.8.tgz#a8b89c31f30b5a044b97d2d28e2da191b6ba2072"
|
||||
integrity sha512-oxMeX/Y35PNFuZoHp+jUj5OSEmLCaIH4KTFJh7a93cHBoFmpw2IoPs22VIz7vyO2YUnx2Tn9dzIwO2P/4quIRg==
|
||||
|
||||
make-dir@^1.0.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c"
|
||||
|
@ -2938,6 +2976,11 @@ nan@^2.12.1:
|
|||
resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c"
|
||||
integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==
|
||||
|
||||
nanoid@^2.1.0:
|
||||
version "2.1.11"
|
||||
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-2.1.11.tgz#ec24b8a758d591561531b4176a01e3ab4f0f0280"
|
||||
integrity sha512-s/snB+WGm6uwi0WjsZdaVcuf3KJXlfGl2LcxgwkEwJF0D/BWzVWAZW/XY4bFaiR7s0Jk3FPvlnepg1H1b1UwlA==
|
||||
|
||||
nanomatch@^1.2.9:
|
||||
version "1.2.13"
|
||||
resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119"
|
||||
|
@ -3773,6 +3816,13 @@ shellwords@^0.1.1:
|
|||
resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b"
|
||||
integrity sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==
|
||||
|
||||
shortid@^2.2.8:
|
||||
version "2.2.15"
|
||||
resolved "https://registry.yarnpkg.com/shortid/-/shortid-2.2.15.tgz#2b902eaa93a69b11120373cd42a1f1fe4437c122"
|
||||
integrity sha512-5EaCy2mx2Jgc/Fdn9uuDuNIIfWBpzY4XIlhoqtXF6qsf+/+SGZ+FxDdX/ZsMZiWupIWNqAEmiNY4RC+LSmCeOw==
|
||||
dependencies:
|
||||
nanoid "^2.1.0"
|
||||
|
||||
signal-exit@^3.0.0, signal-exit@^3.0.2:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d"
|
||||
|
@ -4050,6 +4100,11 @@ supports-color@^6.1.0:
|
|||
dependencies:
|
||||
has-flag "^3.0.0"
|
||||
|
||||
svelte@^3.9.2:
|
||||
version "3.18.2"
|
||||
resolved "https://registry.yarnpkg.com/svelte/-/svelte-3.18.2.tgz#f136b9e169049f8bb6a364bd8b8f3b619ed957d9"
|
||||
integrity sha512-jRk7jdYULb9V4Z+0BKlfofombmdIIQph4leojrOSHzvZBRmCredz7fZsJBiUDLO6h83XYekuLbwfy5zx1i95GQ==
|
||||
|
||||
symbol-tree@^3.2.2:
|
||||
version "3.2.4"
|
||||
resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2"
|
||||
|
|
Loading…
Reference in New Issue