Merge branch 'master' of https://github.com/Budibase/budibase into property-panel/screen-page-testing

This commit is contained in:
Conor_Mack 2020-06-10 10:19:58 +01:00
commit 8ec6d33a7d
11 changed files with 151 additions and 322 deletions

View File

@ -39,7 +39,7 @@
},
"dependencies": {
"@beyonk/svelte-notifications": "^2.0.3",
"@budibase/bbui": "^0.3.5",
"@budibase/bbui": "^1.1.1",
"@budibase/client": "^0.0.32",
"@nx-js/compiler-util": "^2.0.0",
"codemirror": "^5.51.0",

View File

@ -69,7 +69,6 @@ export const getStore = () => {
store.getPathToComponent = getPathToComponent(store)
store.addTemplatedComponent = addTemplatedComponent(store)
store.setMetadataProp = setMetadataProp(store)
store.editPageOrScreen = editPageOrScreen(store)
return store
}
@ -172,15 +171,6 @@ const createScreen = store => (screenName, route, layoutComponentName) => {
})
}
const editPageOrScreen = store => (key, value) => {
store.update(state => {
state.currentPreviewItem[key] = value
_saveCurrentPreviewItem(state)
return state
})
}
const setCurrentScreen = store => screenName => {
store.update(s => {
const screen = getExactComponent(s.screens, screenName)
@ -295,7 +285,6 @@ const setCurrentPage = store => pageName => {
state.currentFrontEndType = "page"
state.currentPageName = pageName
state.currentView = "detail"
state.screens = Array.isArray(current_screens)
? current_screens
: Object.values(current_screens)
@ -456,7 +445,6 @@ const setScreenType = store => type => {
state.currentComponentInfo = pageOrScreen ? pageOrScreen.props : null
state.currentPreviewItem = pageOrScreen
state.currentView = "detail"
return state
})
}

View File

@ -10,18 +10,18 @@
export let onChange = () => {}
function handleChange(val, idx) {
value.splice(idx, 1, val !== "auto" ? val + suffix : val)
value.splice(idx, 1, val !== "auto" && suffix ? val + suffix : val)
value = value
let _value = value.map(v =>
!v.endsWith(suffix) && v !== "auto" ? v + suffix : v
suffix && !v.endsWith(suffix) && v !== "auto" ? v + suffix : v
)
onChange(_value)
}
$: displayValues = value
$: displayValues = value && suffix
? value.map(v => v.replace(new RegExp(`${suffix}$`), ""))
: []
: value || []
</script>
<div class="input-container">

View File

@ -21,14 +21,48 @@
return componentName || "element"
}
$: iframe &&
console.log(
iframe.contentDocument.head.insertAdjacentHTML(
"beforeend",
`<\style></style>`
)
)
const screenPlaceholder = {
name: "Screen Placeholder",
route: "*",
props: {
_component: "@budibase/standard-components/container",
type: "div",
_children: [
{
_component: "@budibase/standard-components/container",
_styles: { normal: {}, hover: {}, active: {}, selected: {} },
_id: "__screenslot__text",
_code: "",
className: "",
onLoad: [],
type: "div",
_children: [
{
_component: "@budibase/standard-components/text",
_styles: {
normal: {},
hover: {},
active: {},
selected: {},
},
_id: "__screenslot__text_2",
_code: "",
text: "content",
font: "",
color: "",
textAlign: "inline",
verticalAlign: "inline",
formattingTag: "none",
},
],
},
],
},
}
$: hasComponent = !!$store.currentPreviewItem
$: {
styles = ""
// Apply the CSS from the currently selected page and its screens
@ -52,49 +86,12 @@
$: frontendDefinition = {
appId: $store.appId,
libraries: $store.libraries,
page: $store.currentPreviewItem,
screens: screensExist
? $store.currentPreviewItem._screens
: [
{
name: "Screen Placeholder",
route: "*",
props: {
_component: "@budibase/standard-components/container",
type: "div",
_children: [
{
_component: "@budibase/standard-components/container",
_styles: { normal: {}, hover: {}, active: {}, selected: {} },
_id: "__screenslot__text",
_code: "",
className: "",
onLoad: [],
type: "div",
_children: [
{
_component: "@budibase/standard-components/text",
_styles: {
normal: {},
hover: {},
active: {},
selected: {},
},
_id: "__screenslot__text_2",
_code: "",
text: "content",
font: "",
color: "",
textAlign: "inline",
verticalAlign: "inline",
formattingTag: "none",
},
],
},
],
},
},
],
page: $store.pages[$store.currentPageName],
screens: [
$store.currentFrontEndType === "page"
? screenPlaceholder
: $store.currentPreviewItem,
],
appRootPath: "",
}
@ -103,6 +100,22 @@
$: selectedComponentId = $store.currentComponentInfo
? $store.currentComponentInfo._id
: ""
const refreshContent = () => {
iframe.contentWindow.postMessage(JSON.stringify({
styles,
stylesheetLinks,
selectedComponentType,
selectedComponentId,
frontendDefinition,
}))
}
$: if(iframe) iframe.contentWindow.addEventListener("bb-ready", refreshContent, { once: true })
$: if(iframe && frontendDefinition) {
refreshContent()
}
</script>
<div class="component-container">
@ -111,13 +124,7 @@
style="height: 100%; width: 100%"
title="componentPreview"
bind:this={iframe}
srcdoc={iframeTemplate({
styles,
stylesheetLinks,
selectedComponentType,
selectedComponentId,
frontendDefinition: JSON.stringify(frontendDefinition),
})} />
srcdoc={iframeTemplate} />
{/if}
</div>

View File

@ -1,20 +1,6 @@
export default ({
styles,
stylesheetLinks,
selectedComponentType,
selectedComponentId,
frontendDefinition,
}) => `<html>
export default `<html>
<head>
${stylesheetLinks}
<style>
${styles || ""}
.${selectedComponentType}-${selectedComponentId} {
border: 2px solid #0055ff;
}
body, html {
height: 100%!important;
font-family: Roboto !important;
@ -35,12 +21,50 @@ export default ({
}
</style>
<script>
window["##BUDIBASE_FRONTEND_DEFINITION##"] = ${frontendDefinition};
function receiveMessage(event) {
import('/_builder/budibase-client.esm.mjs')
.then(module => {
module.loadBudibase({ window, localStorage });
})
if (!event.data) return
const data = JSON.parse(event.data)
try {
if (styles) document.head.removeChild(styles)
} catch(_) { }
try {
if (selectedComponentStyle) document.head.removeChild(selectedComponentStyle)
} catch(_) { }
selectedComponentStyle = document.createElement('style');
document.head.appendChild(selectedComponentStyle)
var selectedCss = '.' + data.selectedComponentType + '-' + data.selectedComponentId + '{ border: 2px solid #0055ff; }'
selectedComponentStyle.appendChild(document.createTextNode(selectedCss))
styles = document.createElement('style')
document.head.appendChild(styles)
styles.appendChild(document.createTextNode(data.styles))
window["##BUDIBASE_FRONTEND_DEFINITION##"] = data.frontendDefinition;
if (clientModule) {
clientModule.loadBudibase({ window, localStorage })
}
}
let clientModule
let styles
let selectedComponentStyle
document.addEventListener("click", function(e) {
e.preventDefault()
e.stopPropagation()
return false;
}, true)
import('/_builder/budibase-client.esm.mjs')
.then(module => {
clientModule = module
window.addEventListener('message', receiveMessage)
window.dispatchEvent(new Event('bb-ready'))
})
</script>
</head>
<body>

View File

@ -1,6 +1,5 @@
<script>
import { setContext, onMount } from "svelte"
import {screen, page} from "./propertyCategories.js"
import PropsView from "./PropsView.svelte"
import { store } from "builderStore"
import IconButton from "components/common/IconButton.svelte"
@ -31,6 +30,7 @@
let selectedCategory = categories[0]
$: components = $store.components
$: componentInstance = $store.currentComponentInfo
$: componentDefinition = $store.components[componentInstance._component]
$: componentPropDefinition =
flattenedPanel.find(
@ -38,7 +38,6 @@
c => c._component === componentInstance._component
) || {}
let panelDefinition = {}
$: {
@ -58,17 +57,9 @@
}
}
$: componentInstance = $store.currentView !== "component" ? {...$store.currentPreviewItem, ...$store.currentComponentInfo} : $store.currentComponentInfo
const onStyleChanged = store.setComponentStyle
function onPropChanged(key, value) {
if($store.currentView !== "component") {
store.editPageOrScreen(key, value)
return
}
store.setComponentProp(key, value)
}
const onPropChanged = store.setComponentProp
function walkProps(component, action) {
action(component)
@ -108,9 +99,9 @@
<DesignView {panelDefinition} {componentInstance} {onStyleChanged} />
{:else if selectedCategory.value === 'settings'}
<SettingsView
{panelDefinition}
{componentInstance}
{componentDefinition}
{panelDefinition}
onChange={onPropChanged} />
{:else if selectedCategory.value === 'events'}
<EventsEditor component={componentInstance} />

View File

@ -1,6 +1,7 @@
<script>
import { excludeProps } from "./propertyCategories.js"
import PropertyControl from "./PropertyControl.svelte"
import { DetailSummary } from "@budibase/bbui"
export let name = ""
export let styleCategory = "normal"
@ -8,79 +9,17 @@
export let componentInstance = {}
export let onStyleChanged = () => {}
export let show = false
const capitalize = name => name[0].toUpperCase() + name.slice(1)
$: icon = show ? "ri-arrow-down-s-fill" : "ri-arrow-right-s-fill"
$: style = componentInstance["_styles"][styleCategory] || {}
</script>
<div class="property-group-container">
<div class="property-group-name" on:click={() => (show = !show)}>
<div class="icon">
<i class={icon} />
</div>
<div class="name">{capitalize(name)}</div>
</div>
<div class="property-panel" class:show>
{#each properties as props}
<PropertyControl
label={props.label}
control={props.control}
key={props.key}
value={style[props.key]}
onChange={(key, value) => onStyleChanged(styleCategory, key, value)}
props={{ ...excludeProps(props, ['control', 'label']) }} />
{/each}
</div>
</div>
<style>
.property-group-container {
display: flex;
flex-direction: column;
height: auto;
background: var(--grey-light);
margin: 0px 0px 4px 0px;
padding: 8px 12px;
justify-content: center;
border-radius: 4px;
}
.property-group-name {
cursor: pointer;
display: flex;
flex-flow: row nowrap;
}
.name {
flex: 1;
text-align: left;
padding-top: 2px;
font-size: 14px;
font-weight: 500;
letter-spacing: 0.14px;
color: var(--ink);
}
.icon {
flex: 0 0 20px;
text-align: center;
}
.property-panel {
/* height: 0px;
overflow: hidden; */
display: none;
}
.show {
/* overflow: auto;
height: auto; */
display: flex;
flex-direction: column;
flex: 1;
}
</style>
<DetailSummary {name}>
{#each properties as props}
<PropertyControl
label={props.label}
control={props.control}
key={props.key}
value={style[props.key]}
onChange={(key, value) => onStyleChanged(styleCategory, key, value)}
props={{ ...excludeProps(props, ['control', 'label']) }} />
{/each}
</DetailSummary>

View File

@ -9,10 +9,7 @@
export let componentInstance = {}
export let onChange = () => {}
let pageScreenProps = ["title","favicon", "description", "route"]
const propExistsOnComponentDef = prop => pageScreenProps.includes(prop) || prop in componentDefinition.props
const propExistsOnComponentDef = prop => prop in componentDefinition.props
function handleChange(key, data) {
data.target ? onChange(key, data.target.value) : onChange(key, data)

View File

@ -2,16 +2,10 @@ import Input from "../common/Input.svelte"
import OptionSelect from "./OptionSelect.svelte"
import InputGroup from "../common/Inputs/InputGroup.svelte"
import FlatButtonGroup from "./FlatButtonGroup.svelte"
export const screen = [
{ label: "Description", key: "description", control: Input },
{ label: "Route", key: "route", control: Input },
]
export const page = [
{ label: "Title", key: "title", control: Input },
{ label: "Favicon", key: "favicon", control: Input },
]
// import Colorpicker from "../common/Colorpicker.svelte"
/*
TODO: Allow for default values for all properties
*/
export const layout = [
{
@ -90,7 +84,6 @@ export const spacing = [
key: "margin",
control: InputGroup,
meta: spacingMeta,
suffix: "px",
defaultValue: ["0", "0", "0", "0"],
},
{
@ -98,7 +91,6 @@ export const spacing = [
key: "padding",
control: InputGroup,
meta: spacingMeta,
suffix: "px",
defaultValue: ["0", "0", "0", "0"],
},
]
@ -109,7 +101,6 @@ export const size = [
key: "width",
control: Input,
placeholder: "px",
suffix: "px",
width: "48px",
textAlign: "center",
},
@ -118,7 +109,6 @@ export const size = [
key: "height",
control: Input,
placeholder: "px",
suffix: "px",
width: "48px",
textAlign: "center",
},
@ -127,7 +117,6 @@ export const size = [
key: "min-width",
control: Input,
placeholder: "px",
suffix: "px",
width: "48px",
textAlign: "center",
},
@ -135,7 +124,6 @@ export const size = [
label: "Min H",
key: "min-height",
control: Input,
suffix: "px",
placeholder: "px",
width: "48px",
textAlign: "center",
@ -145,7 +133,6 @@ export const size = [
key: "max-width",
control: Input,
placeholder: "px",
suffix: "px",
width: "48px",
textAlign: "center",
},
@ -154,7 +141,6 @@ export const size = [
key: "max-height",
control: Input,
placeholder: "px",
suffix: "px",
width: "48px",
textAlign: "center",
},

View File

@ -62,7 +62,7 @@
<span
class:active={false}
class="topnavitemright"
on:click={() => (location = `/${application}`)}>
on:click={() => window.open(`/${application}`)}>
<PreviewIcon />
</span>
</div>

View File

@ -1,5 +1,6 @@
<script>
import Modal from "svelte-simple-modal"
import { Home as Link } from "@budibase/bbui"
import {
SettingsIcon,
AppsIcon,
@ -24,89 +25,29 @@
<div class="nav-section">
<div class="nav-section-title">Build</div>
<div class="nav-item-home">
<span class="nav-item-icon">
<AppsIcon />
</span>
<div class="nav-item-title">Apps</div>
</div>
<div class="nav-item">
<span class="nav-item-icon">
<SettingsIcon />
</span>
<div class="nav-item-title">Settings</div>
</div>
<a href="https://budibase.con/login" target="_blank" class="nav-item">
<span class="nav-item-icon">
<UpdatesIcon />
</span>
<div class="nav-item-title">Updates</div>
</a>
<a href="https://budibase.con/login" target="_blank" class="nav-item">
<span class="nav-item-icon">
<HostingIcon />
</span>
<div class="nav-item-title">Hosting</div>
</a>
<Link icon={AppsIcon} title="Apps" href="/" active />
<Link icon={SettingsIcon} title="Settings" href="/" />
<Link icon={UpdatesIcon} title="Updates" href="/" />
<Link icon={HostingIcon} title="Hosting" href="/" />
</div>
<div class="nav-section">
<div class="nav-section-title">Learn</div>
<a href="https://docs.budibase.com/" target="_blank" class="nav-item">
<span class="nav-item-icon">
<DocumentationIcon />
</span>
<div class="nav-item-title">Documentation</div>
</a>
<a
href="https://docs.budibase.com/tutorial/quick-start"
target="_blank"
class="nav-item">
<span class="nav-item-icon">
<TutorialsIcon />
</span>
<div class="nav-item-title">Tutorials</div>
</a>
<a href="https://forum.budibase.com/" target="_blank" class="nav-item">
<span class="nav-item-icon">
<CommunityIcon />
</span>
<div class="nav-item-title">Community</div>
</a>
<Link icon={DocumentationIcon} title="Documentation" href="/" />
<Link icon={TutorialsIcon} title="Tutorials" href="/" />
<Link icon={CommunityIcon} title="Community" href="/" />
<Link icon={ContributionIcon} title="Contact" href="/" />
</div>
<div class="nav-section">
<div class="nav-section-title">Contact</div>
<a
href="https://github.com/Budibase/budibase/blob/master/CONTRIBUTING.md"
target="_blank"
class="nav-item">
<span class="nav-item-icon">
<ContributionIcon />
</span>
<div class="nav-item-title">Contribute to our product</div>
</a>
<a
href="https://github.com/Budibase/budibase/issues"
target="_blank"
class="nav-item">
<span class="nav-item-icon">
<BugIcon />
</span>
<div class="nav-item-title">Report bug</div>
</a>
<a href="mailto:support@budibase.com" target="_blank" class="nav-item">
<span class="nav-item-icon">
<EmailIcon />
</span>
<div class="nav-item-title">Email</div>
</a>
<a href="https://twitter.com/budibase" target="_blank" class="nav-item">
<span class="nav-item-icon">
<TwitterIcon />
</span>
<div class="nav-item-title">Twitter</div>
</a>
<Link
icon={ContributionIcon}
title="Contribute to our product"
href="/" />
<Link icon={BugIcon} title="Report bug" href="/" />
<Link icon={EmailIcon} title="Email" href="/" />
<Link icon={TwitterIcon} title="Twitter" href="/" />
</div>
</div>
@ -160,48 +101,4 @@
font-weight: 700;
margin-bottom: 12px;
}
.nav-item {
cursor: pointer;
margin: 0px 0px 4px 0px;
padding: 0px 0px 0px 12px;
height: 40px;
display: flex;
flex-direction: row;
align-items: center;
box-sizing: border-box;
}
.nav-item-home {
cursor: pointer;
margin: 0px 0px 4px 0px;
padding: 0px 0px 0px 12px;
height: 40px;
display: flex;
flex-direction: row;
align-items: center;
box-sizing: border-box;
background-color: var(--blue-light);
}
.nav-item:hover {
background-color: var(--grey-light);
border-radius: 3px;
}
.nav-item::selection {
background-color: var(--blue-light);
border-radius: 3px;
}
.nav-item-title {
font-size: 14px;
color: var(--ink);
font-weight: 400;
margin-left: 12px;
}
.nav-item-icon {
color: var(--ink-light);
}
</style>