1
0
Fork 0
mirror of synced 2024-08-03 20:31:50 +12:00

Merge pull request #130 from shogunpurple/demo-prep

eslint errors fixed for CI
This commit is contained in:
Michael Shanks 2020-02-25 17:05:28 +00:00 committed by GitHub
commit 4da68f1aeb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
125 changed files with 32947 additions and 23402 deletions

View file

@ -5,11 +5,13 @@
"jest": true, "jest": true,
"node": true "node": true
}, },
"parser": "babel-eslint",
"parserOptions": { "parserOptions": {
"ecmaVersion": 2019, "ecmaVersion": 2019,
"sourceType": "module" "sourceType": "module",
"allowImportExportEverywhere": true
}, },
"ignorePatterns": ["node_modules", "dist", "public"], "ignorePatterns": ["node_modules", "dist", "public", "*.spec.js", "bundle.js"],
"plugins": ["prettier", "svelte3"], "plugins": ["prettier", "svelte3"],
"extends": ["eslint:recommended"], "extends": ["eslint:recommended"],
"overrides": [ "overrides": [

View file

@ -27,6 +27,7 @@ jobs:
node-version: ${{ matrix.node-version }} node-version: ${{ matrix.node-version }}
- run: yarn - run: yarn
- run: yarn lint - run: yarn lint
- run: yarn bootstrap
- run: yarn build - run: yarn build
- run: yarn test - run: yarn test
env: env:

5
.prettierignore Normal file
View file

@ -0,0 +1,5 @@
packages/builder/src/userInterface/CurrentItemPreview.svelte
public
dist
packages/server/builder
**/*.spec.js

View file

@ -2,6 +2,7 @@
"name": "root", "name": "root",
"private": true, "private": true,
"devDependencies": { "devDependencies": {
"babel-eslint": "^10.0.3",
"eslint": "^6.8.0", "eslint": "^6.8.0",
"eslint-plugin-prettier": "^3.1.2", "eslint-plugin-prettier": "^3.1.2",
"eslint-plugin-svelte3": "^2.7.3", "eslint-plugin-svelte3": "^2.7.3",

View file

@ -16,23 +16,17 @@ const _builderProxy = proxy("/_builder", {
pathRewrite: { "^/_builder": "" }, pathRewrite: { "^/_builder": "" },
}) })
const apiProxy = proxy( const apiProxy = proxy(["/_builder/api/**", "/_builder/**/componentlibrary"], {
[ target,
"/_builder/api/**", logLevel: "debug",
"/_builder/**/componentlibrary" changeOrigin: true,
], cookieDomainRewrite: true,
{ onProxyReq(proxyReq) {
target, if (proxyReq.getHeader("origin")) {
logLevel: "debug", proxyReq.setHeader("origin", target)
changeOrigin: true, }
cookieDomainRewrite: true, },
onProxyReq(proxyReq) { })
if (proxyReq.getHeader("origin")) {
proxyReq.setHeader("origin", target)
}
},
}
)
const production = !process.env.ROLLUP_WATCH const production = !process.env.ROLLUP_WATCH

View file

@ -61,5 +61,4 @@
align-items: center; align-items: center;
justify-content: center; justify-content: center;
} }
</style> </style>

View file

@ -82,11 +82,10 @@
</table> </table>
{:else}(no actions added){/if} {:else}(no actions added){/if}
<Modal <Modal
onClosed={() => isEditing = false} onClosed={() => (isEditing = false)}
bind:isOpen={isEditing} bind:isOpen={isEditing}
title={isEditing ? "Edit Access Level" : "Create Access Level"} title={isEditing ? 'Edit Access Level' : 'Create Access Level'}>
>
{#if isEditing} {#if isEditing}
<AccessLevelView <AccessLevelView
level={editingLevel} level={editingLevel}

View file

@ -16,10 +16,10 @@
let optValue = "" let optValue = ""
let clonedAction = cloneDeep(action) let clonedAction = cloneDeep(action)
let initialOptions = pipe( let initialOptions = pipe(action.initialOptions, [
action.initialOptions, keys,
[keys, map(k => ({ key: k, value: action.initialOptions[k] }))] map(k => ({ key: k, value: action.initialOptions[k] })),
) ])
let errors = [] let errors = []
const addNewOption = () => { const addNewOption = () => {
@ -44,26 +44,17 @@
const removeOption = opt => { const removeOption = opt => {
if (opt) { if (opt) {
delete clonedAction.initialOptions[opt.key] delete clonedAction.initialOptions[opt.key]
initialOptions = pipe( initialOptions = pipe(initialOptions, [filter(o => o.key !== opt.key)])
initialOptions,
[filter(o => o.key !== opt.key)]
)
} }
} }
const save = () => { const save = () => {
const newActionsList = [ const newActionsList = [
...pipe( ...pipe(allActions, [filter(a => a !== action)]),
allActions,
[filter(a => a !== action)]
),
clonedAction, clonedAction,
] ]
errors = pipe( errors = pipe(newActionsList, [validateActions, map(e => e.error)])
newActionsList,
[validateActions, map(e => e.error)]
)
if (errors.length === 0) onFinished(clonedAction) if (errors.length === 0) onFinished(clonedAction)
} }

View file

@ -19,26 +19,20 @@
let actionsArray = [] let actionsArray = []
store.subscribe(s => { store.subscribe(s => {
actionsArray = pipe( actionsArray = pipe(s.actions, [keys, map(k => s.actions[k])])
s.actions,
[keys, map(k => s.actions[k])]
)
}) })
let getDefaultOptionsHtml = defaultOptions => let getDefaultOptionsHtml = defaultOptions =>
pipe( pipe(defaultOptions, [
defaultOptions, keys,
[ map(
keys, k =>
map( `<span style="color:var(--slate)">${k}: </span>${JSON.stringify(
k => defaultOptions[k]
`<span style="color:var(--slate)">${k}: </span>${JSON.stringify( )}`
defaultOptions[k] ),
)}` join("<br>"),
), ])
join("<br>"),
]
)
let actionEditingFinished = action => { let actionEditingFinished = action => {
if (action) { if (action) {

View file

@ -22,10 +22,7 @@
let cancel = () => onFinished() let cancel = () => onFinished()
let save = () => { let save = () => {
const newTriggersList = [ const newTriggersList = [
...pipe( ...pipe(allTriggers, [filter(t => t !== trigger)]),
allTriggers,
[filter(t => t !== trigger)]
),
clonedTrigger, clonedTrigger,
] ]

View file

@ -1,27 +1,28 @@
/** /**
* buildStateOrigins * buildStateOrigins
* *
* Builds an object that details all the bound state in the application, and what updates it. * Builds an object that details all the bound state in the application, and what updates it.
* *
* @param screenDefinition - the screen definition metadata. * @param screenDefinition - the screen definition metadata.
* @returns {Object} an object with the client state values and how they are managed. * @returns {Object} an object with the client state values and how they are managed.
*/ */
export const buildStateOrigins = screenDefinition => { export const buildStateOrigins = screenDefinition => {
const origins = {}; const origins = {}
function traverse(propValue) { function traverse(propValue) {
for (let key in propValue) { for (let key in propValue) {
if (!Array.isArray(propValue[key])) continue; if (!Array.isArray(propValue[key])) continue
if (key === "_children") propValue[key].forEach(traverse); if (key === "_children") propValue[key].forEach(traverse)
for (let element of propValue[key]) { for (let element of propValue[key]) {
if (element["##eventHandlerType"] === "Set State") origins[element.parameters.path] = element; if (element["##eventHandlerType"] === "Set State")
} origins[element.parameters.path] = element
} }
} }
}
traverse(screenDefinition.props); traverse(screenDefinition.props)
return origins; return origins
}; }

View file

@ -1,10 +1,7 @@
import { createPackage } from "./createPackage"
import getStore from "./store" import getStore from "./store"
export const store = getStore() export const store = getStore()
export const createNewPackage = () => createPackage(packageInfo, store)
export const initialise = async () => { export const initialise = async () => {
try { try {
setupRouter(store) setupRouter(store)
@ -17,8 +14,7 @@ export const initialise = async () => {
const setupRouter = writable => { const setupRouter = writable => {
const pushState = history.pushState const pushState = history.pushState
history.pushState = () => { history.pushState = () => {
pushState.apply(history, arguments) pushState.apply(history, [writable])
//fireEvents('pushState', arguments);
writable.initialise() writable.initialise()
} }
window.addEventListener("hashchange", () => { window.addEventListener("hashchange", () => {

View file

@ -5,7 +5,6 @@ export const loadLibs = async (appName, appPackage) => {
const allLibraries = {} const allLibraries = {}
for (let lib of libsFromPages(appPackage.pages)) { for (let lib of libsFromPages(appPackage.pages)) {
const libModule = await import(makeLibraryUrl(appName, lib)) const libModule = await import(makeLibraryUrl(appName, lib))
allLibraries[lib] = libModule allLibraries[lib] = libModule
} }
@ -31,10 +30,5 @@ export const loadLib = async (appName, lib, allLibs) => {
export const makeLibraryUrl = (appName, lib) => export const makeLibraryUrl = (appName, lib) =>
`/_builder/${appName}/componentlibrary?lib=${encodeURI(lib)}` `/_builder/${appName}/componentlibrary?lib=${encodeURI(lib)}`
export const libsFromPages = pages => pipe(pages, [ export const libsFromPages = pages =>
values, pipe(pages, [values, map(p => p.componentLibraries), flatten, uniq])
map(p => p.componentLibraries),
flatten,
uniq
])

View file

@ -763,7 +763,7 @@ const addChildComponent = store => (componentToAdd, presetName) => {
state.currentFrontEndType === "page" state.currentFrontEndType === "page"
? _savePage(state) ? _savePage(state)
: _saveScreenApi(state.currentPreviewItem, state) : _saveScreenApi(state.currentPreviewItem, state)
state.currentComponentInfo = newComponent.props state.currentComponentInfo = newComponent.props
return state return state

View file

@ -1,6 +1,6 @@
<script> <script>
import { createEventDispatcher } from "svelte" import { createEventDispatcher } from "svelte"
import Select from "../common/Select.svelte"; import Select from "../common/Select.svelte"
export let selected export let selected
export let label export let label

View file

@ -17,7 +17,9 @@
class="dropdown-content" class="dropdown-content"
style="display: {isDroppedDown ? 'inline-block' : 'none'}"> style="display: {isDroppedDown ? 'inline-block' : 'none'}">
{#each actions as action} {#each actions as action}
<div class="budibase__nav-item" on:click={action.onclick}>{action.label}</div> <div class="budibase__nav-item" on:click={action.onclick}>
{action.label}
</div>
{/each} {/each}
</div> </div>

View file

@ -1,7 +1,5 @@
<button on:click> <button on:click>
<slot> <slot>+</slot>
+
</slot>
</button> </button>
<style> <style>

View file

@ -4,7 +4,7 @@ import {
getTemplateApi, getTemplateApi,
getAuthApi, getAuthApi,
} from "../../../core/src" } from "../../../core/src"
import { find, filter, includes, keyBy, some, flatten, map } from "lodash/fp" import { find, filter, keyBy, flatten, map } from "lodash/fp"
import { generateSchema } from "../../../core/src/indexing/indexSchemaCreator" import { generateSchema } from "../../../core/src/indexing/indexSchemaCreator"

View file

@ -39,9 +39,7 @@
{/if} {/if}
<Modal onClosed={() => (confirmDelete = false)} bind:isOpen={confirmDelete}> <Modal onClosed={() => (confirmDelete = false)} bind:isOpen={confirmDelete}>
<span> <span>Are you sure you want to delete {$store.currentNode.name}?</span>
Are you sure you want to delete {$store.currentNode.name}?
</span>
<div class="uk-modal-footer uk-text-right"> <div class="uk-modal-footer uk-text-right">
<ButtonGroup> <ButtonGroup>
<ActionButton alert on:click={deleteCurrentNode}>Yes</ActionButton> <ActionButton alert on:click={deleteCurrentNode}>Yes</ActionButton>

View file

@ -152,4 +152,4 @@
</ActionButton> </ActionButton>
</ButtonGroup> </ButtonGroup>
</div> </div>
</div> </div>

View file

@ -14,18 +14,15 @@
store.subscribe($store => { store.subscribe($store => {
index = $store.currentNode index = $store.currentNode
indexableRecords = pipe( indexableRecords = pipe($store.hierarchy, [
$store.hierarchy, hierarchyFunctions.getFlattenedHierarchy,
[ filter(hierarchyFunctions.isDecendant(index.parent())),
hierarchyFunctions.getFlattenedHierarchy, filter(hierarchyFunctions.isRecord),
filter(hierarchyFunctions.isDecendant(index.parent())), map(n => ({
filter(hierarchyFunctions.isRecord), node: n,
map(n => ({ isallowed: some(id => n.nodeId === id)(index.allowedRecordNodeIds),
node: n, })),
isallowed: some(id => n.nodeId === id)(index.allowedRecordNodeIds), ])
})),
]
)
}) })
const toggleAllowedRecord = record => { const toggleAllowedRecord = record => {

View file

@ -99,7 +99,9 @@
<Textbox label="Name:" bind:text={record.name} on:change={nameChanged} /> <Textbox label="Name:" bind:text={record.name} on:change={nameChanged} />
{#if !record.isSingle} {#if !record.isSingle}
<Textbox label="Collection Name:" bind:text={record.collectionName} /> <Textbox label="Collection Name:" bind:text={record.collectionName} />
<Textbox label="Estimated Record Count:" bind:text={record.estimatedRecordCount} /> <Textbox
label="Estimated Record Count:"
bind:text={record.estimatedRecordCount} />
{/if} {/if}
<div class="recordkey">{record.nodeKey()}</div> <div class="recordkey">{record.nodeKey()}</div>

View file

@ -13,6 +13,7 @@ import "uikit/dist/js/uikit.min.js"
import "codemirror/lib/codemirror.css" import "codemirror/lib/codemirror.css"
import "codemirror/theme/monokai.css" import "codemirror/theme/monokai.css"
/* eslint-disable */
const app = new App({ const app = new App({
target: document.getElementById("app"), target: document.getElementById("app"),
}) })

View file

@ -14,10 +14,15 @@
const setActive = () => store.setActiveNav(name) const setActive = () => store.setActiveNav(name)
</script> </script>
<div class="budibase__nav-item backend-nav-item" class:selected={navActive} on:click={setActive}>{label}</div> <div
class="budibase__nav-item backend-nav-item"
class:selected={navActive}
on:click={setActive}>
{label}
</div>
<style> <style>
.backend-nav-item { .backend-nav-item {
padding-left: 25px; padding-left: 25px;
} }
</style> </style>

View file

@ -1,13 +1,26 @@
<script> <script>
import { splitName } from "./pagesParsing/splitRootComponentName.js" import { splitName } from "./pagesParsing/splitRootComponentName.js"
import { store } from "../builderStore" import { store } from "../builderStore"
import { find, sortBy, groupBy, values, filter, map, uniqBy, flatten } from "lodash/fp" import {
find,
sortBy,
groupBy,
values,
filter,
map,
uniqBy,
flatten,
} from "lodash/fp"
import { ImageIcon, InputIcon, LayoutIcon } from "../common/Icons/" import { ImageIcon, InputIcon, LayoutIcon } from "../common/Icons/"
import Select from "../common/Select.svelte" import Select from "../common/Select.svelte"
import Button from "../common/PlusButton.svelte" import Button from "../common/PlusButton.svelte"
import ConfirmDialog from "../common/ConfirmDialog.svelte" import ConfirmDialog from "../common/ConfirmDialog.svelte"
import { getRecordNodes, getIndexNodes, getIndexSchema, pipe } from "../common/core" import {
getRecordNodes,
getIndexNodes,
getIndexSchema,
pipe,
} from "../common/core"
export let toggleTab export let toggleTab
@ -27,7 +40,7 @@
flatten, flatten,
filter(t => !$store.components.some(c => c.name === t.component)), filter(t => !$store.components.some(c => c.name === t.component)),
map(t => ({ name: splitName(t.component).componentName, template: t })), map(t => ({ name: splitName(t.component).componentName, template: t })),
uniqBy(t => t.name) uniqBy(t => t.name),
]) ])
const addRootComponent = (component, allComponents) => { const addRootComponent = (component, allComponents) => {
@ -62,18 +75,20 @@
records: getRecordNodes(hierarchy), records: getRecordNodes(hierarchy),
indexes: getIndexNodes(hierarchy), indexes: getIndexNodes(hierarchy),
helpers: { helpers: {
indexSchema: getIndexSchema(hierarchy) indexSchema: getIndexSchema(hierarchy),
} },
} }
templateInstances = libraryModules[libName][componentName](templateOptions) templateInstances = libraryModules[libName][componentName](templateOptions)
if(!templateInstances || templateInstances.length === 0) return if (!templateInstances || templateInstances.length === 0) return
selectedTemplateInstance = templateInstances[0].name selectedTemplateInstance = templateInstances[0].name
selectTemplateDialog.show() selectTemplateDialog.show()
} }
const onTemplateInstanceChosen = () => { const onTemplateInstanceChosen = () => {
selectedComponent = null selectedComponent = null
const instance = templateInstances.find(i => i.name === selectedTemplateInstance) const instance = templateInstances.find(
i => i.name === selectedTemplateInstance
)
store.addTemplatedComponent(instance.props) store.addTemplatedComponent(instance.props)
toggleTab() toggleTab()
} }
@ -81,7 +96,8 @@
function generate_components_list(components) { function generate_components_list(components) {
return ($store.currentFrontEndType === "page" return ($store.currentFrontEndType === "page"
? $store.builtins.concat(components) ? $store.builtins.concat(components)
: components).concat(standaloneTemplates) : components
).concat(standaloneTemplates)
} }
$: { $: {
@ -96,15 +112,12 @@
} }
$: componentLibrary = componentLibraries.find(l => l.libName === selectedLib) $: componentLibrary = componentLibraries.find(l => l.libName === selectedLib)
</script> </script>
<div class="root"> <div class="root">
<Select on:change={e => selectedLib = e.target.value}> <Select on:change={e => (selectedLib = e.target.value)}>
{#each componentLibraries as lib} {#each componentLibraries as lib}
<option value={lib.libName}> <option value={lib.libName}>{lib.libName}</option>
{lib.libName}
</option>
{/each} {/each}
</Select> </Select>
@ -136,9 +149,7 @@
{#if componentLibrary} {#if componentLibrary}
{#each generate_components_list(componentLibrary.components) as component} {#each generate_components_list(componentLibrary.components) as component}
<div class="component-container"> <div class="component-container">
<div <div class="component" on:click={() => onComponentChosen(component)}>
class="component"
on:click={() => onComponentChosen(component)}>
<div class="name">{splitName(component.name).componentName}</div> <div class="name">{splitName(component.name).componentName}</div>
{#if (component.presets || templatesByComponent[component.name]) && component.name === selectedComponent} {#if (component.presets || templatesByComponent[component.name]) && component.name === selectedComponent}
<ul class="preset-menu"> <ul class="preset-menu">
@ -152,7 +163,9 @@
{/each} {/each}
{/if} {/if}
{#if templatesByComponent[component.name]} {#if templatesByComponent[component.name]}
<span>{splitName(component.name).componentName} Templates</span> <span>
{splitName(component.name).componentName} Templates
</span>
{#each templatesByComponent[component.name] as template} {#each templatesByComponent[component.name] as template}
<li <li
on:click|stopPropagation={() => onTemplateChosen(template)}> on:click|stopPropagation={() => onTemplateChosen(template)}>
@ -180,18 +193,21 @@
{/if} {/if}
</div> </div>
</div> </div>
<ConfirmDialog <ConfirmDialog
bind:this={selectTemplateDialog} bind:this={selectTemplateDialog}
title="Choose Template" title="Choose Template"
onCancel={() => selectedComponent = null} onCancel={() => (selectedComponent = null)}
onOk={onTemplateInstanceChosen}> onOk={onTemplateInstanceChosen}>
{#each templateInstances.map(i => i.name) as instance} {#each templateInstances.map(i => i.name) as instance}
<div class="uk-margin uk-grid-small uk-child-width-auto uk-grid"> <div class="uk-margin uk-grid-small uk-child-width-auto uk-grid">
<label> <label>
<input class="uk-radio" type="radio" bind:group={selectedTemplateInstance} value={instance}> <input
class="uk-radio"
type="radio"
bind:group={selectedTemplateInstance}
value={instance} />
<span class="template-instance-label">{instance}</span> <span class="template-instance-label">{instance}</span>
</label> </label>
</div> </div>
@ -307,5 +323,4 @@
.template-instance-label { .template-instance-label {
margin-left: 20px; margin-left: 20px;
} }
</style> </style>

View file

@ -15,15 +15,12 @@
const joinPath = join("/") const joinPath = join("/")
const normalizedName = name => const normalizedName = name =>
pipe( pipe(name, [
name, trimCharsStart("./"),
[ trimCharsStart("~/"),
trimCharsStart("./"), trimCharsStart("../"),
trimCharsStart("~/"), trimChars(" "),
trimCharsStart("../"), ])
trimChars(" "),
]
)
const lastPartOfName = c => { const lastPartOfName = c => {
if (!c) return "" if (!c) return ""
@ -31,15 +28,14 @@
return last(name.split("/")) return last(name.split("/"))
} }
const isComponentSelected = (current, comp) => current === comp const isComponentSelected = (current, comp) => current === comp
const isFolderSelected = (current, folder) => isInSubfolder(current, folder) const isFolderSelected = (current, folder) => isInSubfolder(current, folder)
$: _screens = pipe( $: _screens = pipe(screens, [
screens, map(c => ({ component: c, title: lastPartOfName(c) })),
[map(c => ({ component: c, title: lastPartOfName(c) })), sortBy("title")] sortBy("title"),
) ])
const isScreenSelected = component => const isScreenSelected = component =>
component.component && component.component &&

View file

@ -20,11 +20,7 @@
const capitalise = s => s.substring(0, 1).toUpperCase() + s.substring(1) const capitalise = s => s.substring(0, 1).toUpperCase() + s.substring(1)
const get_name = s => (!s ? "" : last(s.split("/"))) const get_name = s => (!s ? "" : last(s.split("/")))
const get_capitalised_name = name => const get_capitalised_name = name => pipe(name, [get_name, capitalise])
pipe(
name,
[get_name, capitalise]
)
const moveDownComponent = component => { const moveDownComponent = component => {
const c = component const c = component

View file

@ -3,16 +3,18 @@
import ComponentPropertiesPanel from "./ComponentPropertiesPanel.svelte" import ComponentPropertiesPanel from "./ComponentPropertiesPanel.svelte"
import ComponentSelectionList from "./ComponentSelectionList.svelte" import ComponentSelectionList from "./ComponentSelectionList.svelte"
const PROPERTIES_TAB = "properties"; const PROPERTIES_TAB = "properties"
const COMPONENT_SELECTION_TAB = "components"; const COMPONENT_SELECTION_TAB = "components"
let selected = PROPERTIES_TAB let selected = PROPERTIES_TAB
const isSelected = tab => selected === tab const isSelected = tab => selected === tab
const selectTab = tab => (selected = tab) const selectTab = tab => (selected = tab)
const toggleTab = () => selected = selected === PROPERTIES_TAB ? COMPONENT_SELECTION_TAB : PROPERTIES_TAB; const toggleTab = () =>
(selected =
selected === PROPERTIES_TAB ? COMPONENT_SELECTION_TAB : PROPERTIES_TAB)
</script> </script>
<div class="root"> <div class="root">

View file

@ -20,8 +20,8 @@
let draftEventHandler = { parameters: [] } let draftEventHandler = { parameters: [] }
$: eventData = event || { handlers: [] } $: eventData = event || { handlers: [] }
$: if (!eventOptions.includes(eventType) && eventOptions.length > 0) $: if (!eventOptions.includes(eventType) && eventOptions.length > 0)
eventType = eventOptions[0].name eventType = eventOptions[0].name
const closeModal = () => { const closeModal = () => {
onClose() onClose()

View file

@ -61,7 +61,7 @@
display: flex; display: flex;
flex-direction: column; flex-direction: column;
} }
.handler-input { .handler-input {
position: relative; position: relative;
display: flex; display: flex;

View file

@ -16,15 +16,12 @@
const joinPath = join("/") const joinPath = join("/")
const normalizedName = name => const normalizedName = name =>
pipe( pipe(name, [
name, trimCharsStart("./"),
[ trimCharsStart("~/"),
trimCharsStart("./"), trimCharsStart("../"),
trimCharsStart("~/"), trimChars(" "),
trimCharsStart("../"), ])
trimChars(" "),
]
)
const lastPartOfName = c => const lastPartOfName = c =>
c && last(c.name ? c.name.split("/") : c._component.split("/")) c && last(c.name ? c.name.split("/") : c._component.split("/"))
@ -33,10 +30,7 @@
const isFolderSelected = (current, folder) => isInSubfolder(current, folder) const isFolderSelected = (current, folder) => isInSubfolder(current, folder)
$: _layout = pipe( $: _layout = pipe(layout, [c => ({ component: c, title: lastPartOfName(c) })])
layout,
[c => ({ component: c, title: lastPartOfName(c) })]
)
const isScreenSelected = component => const isScreenSelected = component =>
component.component && component.component &&

View file

@ -21,20 +21,17 @@
let layoutComponent let layoutComponent
let screens let screens
let name = "" let name = ""
let saveAttempted = false let saveAttempted = false
$: layoutComponents = pipe( $: layoutComponents = pipe($store.components, [
$store.components, filter(c => c.container),
[ map(c => ({ name: c.name, ...splitName(c.name) })),
filter(c => c.container), ])
map(c => ({ name: c.name, ...splitName(c.name) })),
]
)
$: layoutComponent = layoutComponent $: layoutComponent = layoutComponent
? find(c => c.name === layoutComponent.name)(layoutComponents) ? find(c => c.name === layoutComponent.name)(layoutComponents)
: layoutComponents[0] : layoutComponents[0]
$: screens = $store.screens $: screens = $store.screens
$: route = !route && screens.length === 0 ? "*" : route $: route = !route && screens.length === 0 ? "*" : route
@ -43,9 +40,11 @@
saveAttempted = true saveAttempted = true
const isValid = const isValid =
name.length > 0 && !screenNameExists(name) name.length > 0 &&
&& route.length > 0 && !routeNameExists(route) !screenNameExists(name) &&
&& layoutComponent route.length > 0 &&
!routeNameExists(route) &&
layoutComponent
if (!isValid) return if (!isValid) return
@ -101,8 +100,8 @@
<input <input
class="uk-input uk-form-small" class="uk-input uk-form-small"
class:uk-form-danger={saveAttempted && (route.length === 0 || routeNameExists(route))} class:uk-form-danger={saveAttempted && (route.length === 0 || routeNameExists(route))}
bind:value={route} bind:value={route}
on:change={routeChanged}/> on:change={routeChanged} />
</div> </div>
</div> </div>

View file

@ -3,7 +3,7 @@
import { store } from "../../builderStore" import { store } from "../../builderStore"
import { buildStateOrigins } from "../../builderStore/buildStateOrigins" import { buildStateOrigins } from "../../builderStore/buildStateOrigins"
import { isBinding, getBinding, setBinding } from "../../common/binding" import { isBinding, getBinding, setBinding } from "../../common/binding"
import StateBindingOptions from "./StateBindingOptions.svelte"; import StateBindingOptions from "./StateBindingOptions.svelte"
export let onChanged = () => {} export let onChanged = () => {}
export let value = "" export let value = ""
@ -28,7 +28,8 @@
const setBindingPath = value => const setBindingPath = value =>
bindValueToSource(value, bindingFallbackValue, bindingSource) bindValueToSource(value, bindingFallbackValue, bindingSource)
const setBindingFallback = value => bindValueToSource(bindingPath, value, bindingSource) const setBindingFallback = value =>
bindValueToSource(bindingPath, value, bindingSource)
const setBindingSource = source => const setBindingSource = source =>
bindValueToSource(bindingPath, bindingFallbackValue, source) bindValueToSource(bindingPath, bindingFallbackValue, source)
@ -69,10 +70,11 @@
</button> </button>
</div> </div>
{#if isOpen} {#if isOpen}
<StateBindingOptions onSelect={option => { <StateBindingOptions
onChanged(option); onSelect={option => {
isOpen = false; onChanged(option)
}} /> isOpen = false
}} />
{/if} {/if}
</div> </div>

View file

@ -1 +1 @@
export { default } from "./PropertyCascader.svelte" export { default } from "./PropertyCascader.svelte"

View file

@ -11,36 +11,34 @@
let errors = [] let errors = []
const props_to_ignore = ["_component", "_children", "_styles", "_code", "_id"] const props_to_ignore = ["_component", "_children", "_styles", "_code", "_id"]
$: componentDef =
component && components &&
components.find(({ name }) => name === component._component)
$: componentDef =
component &&
components &&
components.find(({ name }) => name === component._component)
let setProp = (name, value) => { let setProp = (name, value) => {
onPropChanged(name, value) onPropChanged(name, value)
} }
</script> </script>
<div class="root"> <div class="root">
<form class="uk-form-stacked form-root"> <form class="uk-form-stacked form-root">
{#if componentDef} {#if componentDef}
{#each Object.entries(componentDef.props) as [prop_name, prop_def], index} {#each Object.entries(componentDef.props) as [prop_name, prop_def], index}
<div class="prop-container"> <div class="prop-container">
<PropControl <PropControl
{setProp} {setProp}
{prop_name} {prop_name}
prop_value={component[prop_name]} prop_value={component[prop_name]}
prop_definition={prop_def} prop_definition={prop_def}
{index} {index}
disabled={false} /> disabled={false} />
</div> </div>
{/each} {/each}
{/if} {/if}
</form> </form>

View file

@ -23,7 +23,7 @@
class="uk-select uk-form-small" class="uk-select uk-form-small"
{value} {value}
on:change={ev => onChanged(ev.target.value)}> on:change={ev => onChanged(ev.target.value)}>
{#each (options || []) as option} {#each options || [] as option}
<option value={option}>{option}</option> <option value={option}>{option}</option>
{/each} {/each}
</select> </select>

View file

@ -5,7 +5,7 @@ import { isRootComponent } from "./searchComponents"
export const libraryDependencies = (components, lib) => { export const libraryDependencies = (components, lib) => {
const componentDependsOnLibrary = comp => { const componentDependsOnLibrary = comp => {
if (isRootComponent(comp)) { if (isRootComponent(comp)) {
const { libName } = splitName(component.name) const { libName } = splitName(comp.name)
return libName === lib return libName === lib
} }
return componentDependsOnLibrary( return componentDependsOnLibrary(

View file

@ -1,6 +1,6 @@
import { pipe } from "../../common/core" import { pipe } from "../../common/core"
import { find, isUndefined, filter, some, includes, has } from "lodash/fp" import { find, isUndefined, filter, some, includes } from "lodash/fp"
const normalString = s => (s || "").trim().toLowerCase() const normalString = s => (s || "").trim().toLowerCase()

View file

@ -3,10 +3,8 @@ import {
isBoolean, isBoolean,
isNumber, isNumber,
isArray, isArray,
isObjectLike,
isPlainObject, isPlainObject,
every, every,
isUndefined,
} from "lodash/fp" } from "lodash/fp"
import { EVENT_TYPE_MEMBER_NAME } from "../../common/eventHandlers" import { EVENT_TYPE_MEMBER_NAME } from "../../common/eventHandlers"
@ -61,7 +59,6 @@ export const expandComponentDefinition = componentDefinition => {
return expandedComponent return expandedComponent
} }
const isComponent = isObjectLike
const isEvent = e => const isEvent = e =>
isPlainObject(e) && isPlainObject(e) &&
isString(e[EVENT_TYPE_MEMBER_NAME]) && isString(e[EVENT_TYPE_MEMBER_NAME]) &&

View file

@ -2,7 +2,7 @@ import { isString, keys, flatten, isArray, map, filter } from "lodash/fp"
import { common } from "../../../../core/src" import { common } from "../../../../core/src"
const pipe = common.$ const pipe = common.$
export const validatePage = (page, getComponent) => { export const validatePage = page => {
const errors = [] const errors = []
const error = message => errors.push(message) const error = message => errors.push(message)

View file

@ -1,30 +1,32 @@
import { buildStateOrigins } from "../src/builderStore/buildStateOrigins"; import { buildStateOrigins } from "../src/builderStore/buildStateOrigins"
it("builds the correct stateOrigins object from a screen definition with handlers", () => { it("builds the correct stateOrigins object from a screen definition with handlers", () => {
expect(buildStateOrigins({ expect(
"name": "screen1", buildStateOrigins({
"description": "", name: "screen1",
"props": { description: "",
"_component": "@budibase/standard-components/container", props: {
"className": "", _component: "@budibase/standard-components/container",
"type": "div", className: "",
"onClick": [ type: "div",
{ onClick: [
"##eventHandlerType": "Set State", {
"parameters": { "##eventHandlerType": "Set State",
"path": "testKey", parameters: {
"value": "value" path: "testKey",
} value: "value",
} },
] },
} ],
})).toEqual({ },
"testKey": { })
).toEqual({
testKey: {
"##eventHandlerType": "Set State", "##eventHandlerType": "Set State",
"parameters": { parameters: {
"path": "testKey", path: "testKey",
"value": "value" value: "value",
} },
} },
}); })
}); })

View file

@ -206,7 +206,7 @@ describe("createDefaultProps", () => {
expect(props.fieldName).toBe("surname") expect(props.fieldName).toBe("surname")
expect(props.fieldLength).toBe(500) expect(props.fieldLength).toBe(500)
}) })
it("should create standard props", () => { it("should create standard props", () => {
const comp = getcomponent() const comp = getcomponent()
comp.props.fieldName = { type: "string", default: 1 } comp.props.fieldName = { type: "string", default: 1 }

View file

@ -1 +1 @@
module.exports = config => ({}) module.exports = () => ({})

View file

@ -1,4 +1,4 @@
const { resolve, join } = require("path") const { resolve } = require("path")
const { cwd } = require("process") const { cwd } = require("process")
const buildAppContext = require("@budibase/server/initialise/buildAppContext") const buildAppContext = require("@budibase/server/initialise/buildAppContext")

View file

@ -2,7 +2,6 @@ import resolve from "rollup-plugin-node-resolve"
import commonjs from "rollup-plugin-commonjs" import commonjs from "rollup-plugin-commonjs"
import builtins from "rollup-plugin-node-builtins" import builtins from "rollup-plugin-node-builtins"
import nodeglobals from "rollup-plugin-node-globals" import nodeglobals from "rollup-plugin-node-globals"
import { terser } from "rollup-plugin-terser"
const lodash_fp_exports = [ const lodash_fp_exports = [
"find", "find",

View file

@ -19,8 +19,6 @@ const appPackages = join(
const publicMain = appName => join(appPackages, appName, "public", "main") const publicMain = appName => join(appPackages, appName, "public", "main")
const publicUnauth = appName => const publicUnauth = appName =>
join(appPackages, appName, "public", "unauthenticated") join(appPackages, appName, "public", "unauthenticated")
const nodeModules = appName =>
join(appPackages, appName, "node_modules", "@budibase", "client", "dist")
;(async () => { ;(async () => {
const apps = await readdir(appPackages) const apps = await readdir(appPackages)

View file

@ -6,16 +6,15 @@ import { builtins, builtinLibName } from "./render/builtinComponents"
* create a web application from static budibase definition files. * create a web application from static budibase definition files.
* @param {object} opts - configuration options for budibase client libary * @param {object} opts - configuration options for budibase client libary
*/ */
export const loadBudibase = async (opts) => { export const loadBudibase = async opts => {
let componentLibraries = opts && opts.componentLibraries let componentLibraries = opts && opts.componentLibraries
const _window = (opts && opts.window) || window const _window = (opts && opts.window) || window
const _localStorage = (opts && opts.localStorage) || localStorage const _localStorage = (opts && opts.localStorage) || localStorage
const backendDefinition = _window["##BUDIBASE_BACKEND_DEFINITION##"] const backendDefinition = _window["##BUDIBASE_BACKEND_DEFINITION##"]
const frontendDefinition = _window["##BUDIBASE_FRONTEND_DEFINITION##"] const frontendDefinition = _window["##BUDIBASE_FRONTEND_DEFINITION##"]
const uiFunctions = _window["##BUDIBASE_FRONTEND_FUNCTIONS##"] const uiFunctions = _window["##BUDIBASE_FRONTEND_FUNCTIONS##"]
const userFromStorage = _localStorage.getItem("budibase:user") const userFromStorage = _localStorage.getItem("budibase:user")
const user = userFromStorage const user = userFromStorage
@ -33,8 +32,8 @@ export const loadBudibase = async (opts) => {
: "/" + trimSlash(frontendDefinition.appRootPath) : "/" + trimSlash(frontendDefinition.appRootPath)
if (!componentLibraries) { if (!componentLibraries) {
const componentLibraryUrl = lib =>
const componentLibraryUrl = lib => frontendDefinition.appRootPath + "/" + trimSlash(lib) frontendDefinition.appRootPath + "/" + trimSlash(lib)
componentLibraries = {} componentLibraries = {}
for (let lib of frontendDefinition.componentLibraries) { for (let lib of frontendDefinition.componentLibraries) {
@ -46,25 +45,33 @@ export const loadBudibase = async (opts) => {
componentLibraries[builtinLibName] = builtins(_window) componentLibraries[builtinLibName] = builtins(_window)
const { initialisePage, screenStore, pageStore, routeTo, rootNode } = createApp( const {
initialisePage,
screenStore,
pageStore,
routeTo,
rootNode,
} = createApp(
componentLibraries, componentLibraries,
frontendDefinition, frontendDefinition,
backendDefinition, backendDefinition,
user, user,
uiFunctions || {}, uiFunctions || {},
_window _window,
rootNode
) )
const route = _window.location const route = _window.location
? _window.location.pathname.replace(frontendDefinition.appRootPath, "") ? _window.location.pathname.replace(frontendDefinition.appRootPath, "")
: ""; : ""
initialisePage(frontendDefinition.page, _window.document.body, route)
return { return {
rootNode: initialisePage(frontendDefinition.page, _window.document.body, route),
screenStore, screenStore,
pageStore, pageStore,
routeTo, routeTo,
rootNode rootNode,
} }
} }

View file

@ -47,7 +47,7 @@ export const attachChildren = initialiseOpts => (htmlElement, options) => {
uiFunctions, uiFunctions,
htmlElement, htmlElement,
anchor, anchor,
getCurrentState getCurrentState,
}) })
for (let childNode of childNodesThisIteration) { for (let childNode of childNodesThisIteration) {

View file

@ -5,9 +5,9 @@ export const BB_STATE_FALLBACK = "##bbstatefallback"
export const isBound = prop => !!parseBinding(prop) export const isBound = prop => !!parseBinding(prop)
/** /**
* *
* @param {object|string|number} prop - component property to parse for a dynamic state binding * @param {object|string|number} prop - component property to parse for a dynamic state binding
* @returns {object|boolean} * @returns {object|boolean}
*/ */
export const parseBinding = prop => { export const parseBinding = prop => {
if (!prop) return false if (!prop) return false
@ -34,7 +34,8 @@ export const parseBinding = prop => {
} }
export const isStoreBinding = binding => binding && binding.source === "store" export const isStoreBinding = binding => binding && binding.source === "store"
export const isContextBinding = binding => binding && binding.source === "context" export const isContextBinding = binding =>
binding && binding.source === "context"
export const isEventBinding = binding => binding && binding.source === "event" export const isEventBinding = binding => binding && binding.source === "event"
const hasBindingObject = prop => const hasBindingObject = prop =>
@ -50,8 +51,8 @@ const isBindingExpression = prop =>
prop.startsWith("route.")) prop.startsWith("route."))
const parseBindingExpression = prop => { const parseBindingExpression = prop => {
let [source, ...rest] = prop.split("."); let [source, ...rest] = prop.split(".")
let path = rest.join(".") let path = rest.join(".")
if (source === "route") { if (source === "route") {
source = "state" source = "state"
@ -59,7 +60,7 @@ const parseBindingExpression = prop => {
} }
return { return {
fallback: "", // TODO: provide fallback support fallback: "", // TODO: provide fallback support
source, source,
path, path,
} }

View file

@ -160,41 +160,46 @@ const setNodeState = (storeState, node) => {
* Bind a components event handler parameters to state, context or the event itself. * Bind a components event handler parameters to state, context or the event itself.
* @param {Array} eventHandlerProp - event handler array from component definition * @param {Array} eventHandlerProp - event handler array from component definition
*/ */
function bindComponentEventHandlers(eventHandlerProp) { function bindComponentEventHandlers(
const boundEventHandlers = [] eventHandlerProp,
for (let event of eventHandlerProp) { context,
const boundEventHandler = { getCurrentState
handlerType: event[EVENT_TYPE_MEMBER_NAME], ) {
parameters: event.parameters, const boundEventHandlers = []
for (let event of eventHandlerProp) {
const boundEventHandler = {
handlerType: event[EVENT_TYPE_MEMBER_NAME],
parameters: event.parameters,
}
const boundParameters = {}
for (let paramName in boundEventHandler.parameters) {
const paramValue = boundEventHandler.parameters[paramName]
const paramBinding = parseBinding(paramValue)
if (!paramBinding) {
boundParameters[paramName] = () => paramValue
continue
} }
const boundParameters = {} let paramValueSource
for (let paramName in boundEventHandler.parameters) {
const paramValue = boundEventHandler.parameters[paramName]
const paramBinding = parseBinding(paramValue)
if (!paramBinding) {
boundParameters[paramName] = () => paramValue
continue
}
let paramValueSource; if (paramBinding.source === "context") paramValueSource = context
if (paramBinding.source === "state") paramValueSource = getCurrentState()
if (paramBinding.source === "context") paramValueSource = context; // The new dynamic event parameter bound to the relevant source
if (paramBinding.source === "state") paramValueSource = getCurrentState(); boundParameters[paramName] = eventContext =>
getState(
// The new dynamic event parameter bound to the relevant source
boundParameters[paramName] = eventContext => getState(
paramBinding.source === "event" ? eventContext : paramValueSource, paramBinding.source === "event" ? eventContext : paramValueSource,
paramBinding.path, paramBinding.path,
paramBinding.fallback paramBinding.fallback
); )
}
boundEventHandler.parameters = boundParameters
boundEventHandlers.push(boundEventHandlers)
return boundEventHandlers;
} }
boundEventHandler.parameters = boundParameters
boundEventHandlers.push(boundEventHandlers)
return boundEventHandlers
}
} }
const _setup = ( const _setup = (
@ -230,22 +235,26 @@ const _setup = (
binding.fallback, binding.fallback,
binding.source binding.source
) )
} }
if (isBound && binding.source === "context") { if (isBound && binding.source === "context") {
initialProps[propName] = !context initialProps[propName] = !context
? propValue ? propValue
: getState(context, binding.path, binding.fallback, binding.source) : getState(context, binding.path, binding.fallback, binding.source)
} }
if (isEventType(propValue)) {
const boundEventHandlers = bindComponentEventHandlers(propValue);
if (boundEventHandlers.length === 0) { if (isEventType(propValue)) {
const boundEventHandlers = bindComponentEventHandlers(
propValue,
context,
getCurrentState
)
if (boundEventHandlers.length === 0) {
initialProps[propName] = doNothing initialProps[propName] = doNothing
} else { } else {
initialProps[propName] = async context => { initialProps[propName] = async context => {
for (let handlerInfo of handlersInfos) { for (let handlerInfo of boundEventHandlers) {
const handler = makeHandler(handlerTypes, handlerInfo) const handler = makeHandler(handlerTypes, handlerInfo)
await handler(context) await handler(context)
} }
@ -271,4 +280,4 @@ const makeHandler = (handlerTypes, handlerInfo) => {
} }
handlerType.execute(parameters) handlerType.execute(parameters)
} }
} }

View file

@ -1,5 +1,5 @@
import { flatten, orderBy, filter, isUndefined } from "lodash/fp" import { flatten, orderBy, filter, isUndefined } from "lodash/fp"
import hierarchy, { import {
getFlattenedHierarchy, getFlattenedHierarchy,
getCollectionNodeByKeyOrNodeKey, getCollectionNodeByKeyOrNodeKey,
isCollectionRecord, isCollectionRecord,

View file

@ -5,7 +5,6 @@ import {
isGlobalIndex, isGlobalIndex,
getParentKey, getParentKey,
isShardedIndex, isShardedIndex,
getExactNodeForKey,
} from "../templateApi/hierarchy" } from "../templateApi/hierarchy"
import { joinKey, isNonEmptyString, splitKey, $ } from "../common" import { joinKey, isNonEmptyString, splitKey, $ } from "../common"

View file

@ -1,5 +1,5 @@
import { keyBy, mapValues, filter, map, includes, last } from "lodash/fp" import { keyBy, mapValues, filter, map, includes, last } from "lodash/fp"
import { getExactNodeForKey, getNode } from "../templateApi/hierarchy" import { getNode } from "../templateApi/hierarchy"
import { safeParseField } from "../types" import { safeParseField } from "../types"
import { import {
$, $,

View file

@ -5,7 +5,7 @@ import {
isSingleRecord, isSingleRecord,
getNodeForCollectionPath, getNodeForCollectionPath,
} from "../templateApi/hierarchy" } from "../templateApi/hierarchy"
import { reduce, find, filter, take } from "lodash/fp" import { reduce, find, filter } from "lodash/fp"
import { $, getFileFromKey, joinKey, safeKey, keySep } from "../common" import { $, getFileFromKey, joinKey, safeKey, keySep } from "../common"
import { folderStructureArray, allIdChars } from "../indexing/allIds" import { folderStructureArray, allIdChars } from "../indexing/allIds"

View file

@ -73,9 +73,7 @@ const _uploadFile = async (
) )
if (!isExpectedFileSize) { if (!isExpectedFileSize) {
throw new BadRequestError( throw new BadRequestError(
`Fields for ${relativeFilePath} do not have expected size: ${join( `Fields for ${relativeFilePath} do not have expected size.`
","
)(incorrectFields)}`
) )
} }
}) })

View file

@ -1,6 +1,6 @@
import {} from "../templateApi/heirarchy" import {} from "../templateApi/heirarchy"
export const canDelete = (app, node) => { export const canDelete = () => {
/* /*
it must not exist on any index.allowedRecordNodeIds it must not exist on any index.allowedRecordNodeIds
it must not exist on and reference type fields it must not exist on and reference type fields

View file

@ -1,6 +1,6 @@
import { apiWrapper, apiWrapperSync } from "../src/common/apiWrapper" import { apiWrapper, apiWrapperSync } from "../src/common/apiWrapper"
import { filter } from "lodash/fp" import { filter } from "lodash/fp"
import { event, onComplete, onBegin, onError, events } from "../src/common" import { events } from "../src/common"
const getApp = () => { const getApp = () => {
var events = [] var events = []
@ -26,7 +26,7 @@ describe("apiWrapper", () => {
const getErrorEvents = app => app.getEvents(testNamespace.onError) const getErrorEvents = app => app.getEvents(testNamespace.onError)
const runThrowEx = (arg1, arg2) => { const runThrowEx = (arg1, arg2) => {
const throwEx = (x, y) => { const throwEx = () => {
throw new Error("test error") throw new Error("test error")
} }
const app = getApp() const app = getApp()
@ -47,7 +47,7 @@ describe("apiWrapper", () => {
} }
const runThrowExAsync = async (arg1, arg2) => { const runThrowExAsync = async (arg1, arg2) => {
const throwEx = async (x, y) => { const throwEx = async () => {
throw new Error("test error") throw new Error("test error")
} }
const app = getApp() const app = getApp()

View file

@ -33,7 +33,7 @@ describe("authApi > authenticate", () => {
}) })
it("should return null when non existing user", async () => { it("should return null when non existing user", async () => {
const { authApi, app } = await setupApphierarchy( const { authApi } = await setupApphierarchy(
basicAppHierarchyCreator_WithFields basicAppHierarchyCreator_WithFields
) )
const result = await authApi.authenticate("nobody", "password") const result = await authApi.authenticate("nobody", "password")

View file

@ -31,7 +31,7 @@ describe("recordApi > files", () => {
const { recordApi } = await setupApphierarchy( const { recordApi } = await setupApphierarchy(
basicAppHierarchyCreator_WithFields basicAppHierarchyCreator_WithFields
) )
const { file, stream, content } = getFile() const { file, stream } = getFile()
file.size = file.size - 1 file.size = file.size - 1
const record = recordApi.getNew("/customers", "customer") const record = recordApi.getNew("/customers", "customer")
record.surname = "Ledog" record.surname = "Ledog"
@ -46,7 +46,7 @@ describe("recordApi > files", () => {
const { recordApi } = await setupApphierarchy( const { recordApi } = await setupApphierarchy(
basicAppHierarchyCreator_WithFields basicAppHierarchyCreator_WithFields
) )
const { file, stream, content } = getFile() const { file, stream } = getFile()
const record = recordApi.getNew("/customers", "customer") const record = recordApi.getNew("/customers", "customer")
record.surname = "Ledog" record.surname = "Ledog"
record.profilepic = file record.profilepic = file
@ -80,7 +80,7 @@ describe("recordApi > files", () => {
const { recordApi } = await setupApphierarchy( const { recordApi } = await setupApphierarchy(
basicAppHierarchyCreator_WithFields basicAppHierarchyCreator_WithFields
) )
const { file, stream, content } = getFile() const { file, stream } = getFile()
const record = recordApi.getNew("/customers", "customer") const record = recordApi.getNew("/customers", "customer")
record.surname = "Ledog" record.surname = "Ledog"
record.profilepic = file record.profilepic = file
@ -98,7 +98,7 @@ describe("recordApi > files", () => {
const { recordApi } = await setupApphierarchy( const { recordApi } = await setupApphierarchy(
basicAppHierarchyCreator_WithFields basicAppHierarchyCreator_WithFields
) )
const { file, stream, content } = getFile() const { file, stream } = getFile()
const record = recordApi.getNew("/customers", "customer") const record = recordApi.getNew("/customers", "customer")
record.surname = "Ledog" record.surname = "Ledog"
record.profilepic = file record.profilepic = file

View file

@ -4,7 +4,6 @@ import { promisify } from "es6-promisify"
import _rimraf from "rimraf" import _rimraf from "rimraf"
const mkdir = promisify(fs.mkdir) const mkdir = promisify(fs.mkdir)
const rmdir = promisify(fs.rmdir)
const rimraf = promisify(_rimraf) const rimraf = promisify(_rimraf)
const getConfig = async () => { const getConfig = async () => {

View file

@ -1,9 +1,8 @@
import fs from "fs"
import { mkdir } from "fs" import { mkdir } from "fs"
import { join } from "path" import { join } from "path"
import { promisify } from "es6-promisify" import { promisify } from "es6-promisify"
mkdirp = promisify(mkdir) const mkdirp = promisify(mkdir)
const getConfig = async () => { const getConfig = async () => {
const config = { const config = {
@ -13,15 +12,13 @@ const getConfig = async () => {
memory: {}, memory: {},
} }
try { await mkdirp("./output")
await mkdir("./output")
} catch (e) {}
for (let type in config) { for (let type in config) {
await mkdir(join("output", type)) await mkdirp(join("output", type))
} }
await mkdir("./output/local/files") await mkdirp("./output/local/files")
return config return config
} }

View file

@ -9,7 +9,7 @@ import {
} from "@azure/storage-blob" } from "@azure/storage-blob"
export const createFile = ({ containerUrl }) => async (key, content) => { export const createFile = ({ containerUrl }) => async (key, content) => {
const blobURL = BlobURL.fromContainerURL(containerURL, key) const blobURL = BlobURL.fromContainerURL(containerUrl, key)
const blockBlobURL = BlockBlobURL.fromBlobURL(blobURL) const blockBlobURL = BlockBlobURL.fromBlobURL(blobURL)
await blockBlobURL.upload(Aborter.none, content, content.length) await blockBlobURL.upload(Aborter.none, content, content.length)
} }
@ -17,7 +17,7 @@ export const createFile = ({ containerUrl }) => async (key, content) => {
export const updateFile = opts => async (path, content) => export const updateFile = opts => async (path, content) =>
createFile(opts)(path, content) createFile(opts)(path, content)
export const loadFile = ({ containerUrl }) => async key => { export const loadFile = ({ containerUrl }) => async (key, content) => {
const blobURL = BlobURL.fromContainerURL(containerUrl, key) const blobURL = BlobURL.fromContainerURL(containerUrl, key)
const downloadBlockBlobResponse = await blobURL.download(Aborter.none, 0) const downloadBlockBlobResponse = await blobURL.download(Aborter.none, 0)
@ -27,8 +27,8 @@ export const loadFile = ({ containerUrl }) => async key => {
.toString() .toString()
} }
export const exists = ({ containerURL }) => async key => { export const exists = ({ containerUrl }) => async key => {
const blobURL = BlobURL.fromContainerURL(containerURL, key) const blobURL = BlobURL.fromContainerURL(containerUrl, key)
const getPropsResponse = await blobURL.getProperties() const getPropsResponse = await blobURL.getProperties()
return getPropsResponse._response.StatusCode === 200 return getPropsResponse._response.StatusCode === 200
} }
@ -53,7 +53,7 @@ const initialise = opts => {
const pipeline = StorageURL.newPipeline(sharedKeyCredential) const pipeline = StorageURL.newPipeline(sharedKeyCredential)
const serviceURL = new ServiceURL( const serviceURL = new ServiceURL(
`https://${account}.blob.core.windows.net`, `https://${opts.account}.blob.core.windows.net`,
pipeline pipeline
) )
@ -77,6 +77,5 @@ export default opts => {
datastoreType: "azure-blob-storage", datastoreType: "azure-blob-storage",
datastoreDescription: "", datastoreDescription: "",
data,
} }
} }

View file

@ -24,5 +24,5 @@ initialise()
.then(init => { .then(init => {
return tests(init.datastore, init.config) return tests(init.datastore, init.config)
}) })
.then(_ => console.log("done")) .then(() => console.log("done"))
.catch(e => console.log(e)) .catch(e => console.log(e))

View file

@ -1,14 +1,8 @@
import { eventsList } from "@budibase/core" import { eventsList } from "@budibase/core"
import { filter, union, has, map } from "lodash/fp" import { filter, union, has, map } from "lodash/fp"
import records from "./records"
const allEventsOfType = type => filter(e => e.endsWith(`:${type}`))(eventsList) const allEventsOfType = type => filter(e => e.endsWith(`:${type}`))(eventsList)
const getEventNamespace = ev => {
const parts = ev.split(":")
return `${parts[0]}:${parts[1]}`
}
const hasRecord = has("record") const hasRecord = has("record")
export const register = (app, logTimeElapsed, eventNamespaces = []) => { export const register = (app, logTimeElapsed, eventNamespaces = []) => {

View file

@ -16,7 +16,6 @@ const iterateActions = async (apis, getIterator) => {
limit(() => result.action.run(i)) limit(() => result.action.run(i))
) )
let n = 1
await Promise.all(runPromises) await Promise.all(runPromises)
result = iterator() result = iterator()
} catch (e) { } catch (e) {

View file

@ -1,5 +1,5 @@
import { action, iterateActionTimes, iterateCollection } from "./helpers" import { action, iterateActionTimes } from "./helpers"
import { isUndefined, union, takeRight } from "lodash" import { isUndefined, union } from "lodash"
const createClient = (apis, getState) => async i => { const createClient = (apis, getState) => async i => {
const client = apis.recordApi.getNew("/clients", "client") const client = apis.recordApi.getNew("/clients", "client")
@ -20,16 +20,6 @@ const createClient = (apis, getState) => async i => {
return client.key() return client.key()
} }
const getClient = (apis, getState) => async k => {
const state = getState()
if (isUndefined(state.clients)) state.clients = []
const client = await apis.recordApi.load(k)
state.clients.push(client)
return `key: ${k} , add1: ${client.Address1} , count: ${state.clients.length}`
}
const listClients = (apis, getState) => async () => { const listClients = (apis, getState) => async () => {
const clients = await apis.viewApi.listItems("/clients/default") const clients = await apis.viewApi.listItems("/clients/default")
const state = getState() const state = getState()
@ -43,12 +33,6 @@ const listClients = (apis, getState) => async () => {
} }
} }
const deleteClient = (apis, getState) => async k => {
await apis.recordApi.delete(k)
const state = getState()
state.clientKeys = state.clientKeys.filter(key => key !== k)
}
export default apis => { export default apis => {
const state = {} const state = {}
const getState = () => state const getState = () => state
@ -64,9 +48,6 @@ export default apis => {
iterateActionTimes(recordsPerIteration) iterateActionTimes(recordsPerIteration)
), ),
/*action("Get client", getClient(apis, getState),
iterateCollection(() => takeRight(getState().clientKeys, recordsPerIteration))),*/
action("List Clients", listClients(apis, getState)), action("List Clients", listClients(apis, getState)),
] ]
@ -75,14 +56,6 @@ export default apis => {
actions = union(actions, actionsInOneIteration()) actions = union(actions, actionsInOneIteration())
} }
/*
for (let index = 0; index < noOfIterations; index++) {
actions.push(
action("Delete Clients", deleteClient(apis, getState),
iterateCollection(() => takeRight(getState().clientKeys, recordsPerIteration))),
action("List Clients", listClients(apis, getState))
);
}*/
let actionIndex = 0 let actionIndex = 0
return () => { return () => {

View file

@ -1,5 +1,4 @@
import { getAppApis, getTemplateApi, setupDatastore } from "@budibase/core" import { getAppApis, getTemplateApi, setupDatastore } from "@budibase/core"
import { action } from "./helpers"
const addField = templateApi => type => (record, name) => { const addField = templateApi => type => (record, name) => {
const field = templateApi.getNewField(type) const field = templateApi.getNewField(type)

View file

@ -1,7 +1,6 @@
import svelte from "rollup-plugin-svelte" import svelte from "rollup-plugin-svelte"
import postcss from "rollup-plugin-postcss" import postcss from "rollup-plugin-postcss"
import resolve from "rollup-plugin-node-resolve" import resolve from "rollup-plugin-node-resolve"
import path from "path"
const postcssOptions = () => ({ const postcssOptions = () => ({
extensions: [".scss", ".sass"], extensions: [".scss", ".sass"],

View file

@ -5,7 +5,7 @@ import livereload from "rollup-plugin-livereload"
import { terser } from "rollup-plugin-terser" import { terser } from "rollup-plugin-terser"
import json from "rollup-plugin-json" import json from "rollup-plugin-json"
import alias from "rollup-plugin-alias" import alias from "rollup-plugin-alias"
import postcss from "rollup-plugin-postcss"; import postcss from "rollup-plugin-postcss"
import path from "path" import path from "path"
const aliases = { const aliases = {

View file

@ -1,28 +1,48 @@
<script> <script>
import Checkbox from "./Checkbox.svelte"; import Checkbox from "./Checkbox.svelte"
import Label from "../Common/Label.svelte"; import Label from "../Common/Label.svelte"
export let label = ""; export let label = ""
export let orientation = "row"; export let orientation = "row"
export let fullwidth = false; export let fullwidth = false
export let onChange = selectedItems => {}; export let onChange = selectedItems => {}
export let items = []; export let items = []
export let disabled = false; export let disabled = false
export let alignEnd = false; export let alignEnd = false
let selectedItems = []; let selectedItems = []
function handleonChange(item) { function handleonChange(item) {
if (!!item.checked) { if (!!item.checked) {
item.checked = !item.checked; item.checked = !item.checked
} else { } else {
item.checked = true; item.checked = true
} }
onChange(items.filter(i => i.checked)); onChange(items.filter(i => i.checked))
} }
</script> </script>
<div class="checkbox-group">
<div class="checkbox-group__label">
<Label text={label} bold />
</div>
<div class={`checkbox-group__boxes ${orientation}`}>
{#each items as item, i}
<div class:fullwidth>
<Checkbox
id={`${item.label}-${i}`}
{disabled}
{alignEnd}
indeterminate={item.indeterminate || false}
label={item.label}
checked={item.checked || false}
onClick={() => handleonChange(item)} />
</div>
{/each}
</div>
</div>
<style> <style>
.checkbox-group { .checkbox-group {
display: flex; display: flex;
@ -55,23 +75,3 @@
text-align: left; text-align: left;
} }
</style> </style>
<div class="checkbox-group">
<div class="checkbox-group__label">
<Label text={label} bold />
</div>
<div class={`checkbox-group__boxes ${orientation}`}>
{#each items as item, i}
<div class:fullwidth>
<Checkbox
id={`${item.label}-${i}`}
{disabled}
{alignEnd}
indeterminate={item.indeterminate || false}
label={item.label}
checked={item.checked || false}
onClick={() => handleonChange(item)} />
</div>
{/each}
</div>
</div>

View file

@ -1,4 +1,3 @@
import "./_style.scss"; import "./_style.scss"
export { default as Checkbox } from "./Checkbox.svelte"; export { default as Checkbox } from "./Checkbox.svelte"
export { default as Checkboxgroup } from "./CheckboxGroup.svelte"; export { default as Checkboxgroup } from "./CheckboxGroup.svelte"

View file

@ -1,7 +1,7 @@
export default class ClassBuilder { export default class ClassBuilder {
constructor(block, defaultIgnoreList) { constructor(block, defaultIgnoreList) {
this.block = `mdc-${block}`; this.block = `mdc-${block}`
this.defaultIgnoreList = defaultIgnoreList; //will be ignored when building custom classes this.defaultIgnoreList = defaultIgnoreList //will be ignored when building custom classes
} }
/* /*
@ -10,32 +10,32 @@ export default class ClassBuilder {
All are optional All are optional
*/ */
build(params) { build(params) {
if (!params) return this.block; //return block if nothing passed if (!params) return this.block //return block if nothing passed
const { props, elementName } = params; const { props, elementName } = params
let base = !!elementName ? `${this.block}__${elementName}` : this.block; let base = elementName ? `${this.block}__${elementName}` : this.block
if (!props) return base; if (!props) return base
return this._handleProps(base, props); return this._handleProps(base, props)
} }
//Easily grab a simple element class //Easily grab a simple element class
elem(elementName) { elem(elementName) {
return this.build({ elementName }); return this.build({ elementName })
} }
//use if a different base is needed than whats defined by this.block //use if a different base is needed than whats defined by this.block
debase(base, elementProps) { debase(base, elementProps) {
if (!elementProps) return base; if (!elementProps) return base
return this._handleProps(base, elementProps); return this._handleProps(base, elementProps)
} }
//proxies bindProps and checks for which elementProps exist before binding //proxies bindProps and checks for which elementProps exist before binding
_handleProps(base, elementProps) { _handleProps(base, elementProps) {
let cls = base; let cls = base
const { modifiers, customs, extras } = elementProps; const { modifiers, customs, extras } = elementProps
if (!!modifiers) cls += this._bindProps(modifiers, base); if (modifiers) cls += this._bindProps(modifiers, base)
if (!!customs) cls += this._bindProps(customs, base, true); if (customs) cls += this._bindProps(customs, base, true)
if (!!extras) cls += ` ${extras.join(" ")}`; if (extras) cls += ` ${extras.join(" ")}`
return cls.trim(); return cls.trim()
} }
/* /*
@ -53,22 +53,22 @@ export default class ClassBuilder {
!!value && !!value &&
(!this.defaultIgnoreList || !this.defaultIgnoreList.includes(value)) (!this.defaultIgnoreList || !this.defaultIgnoreList.includes(value))
) { ) {
let classBase = isCustom ? `bbmd-${base}` : `${base}`; let classBase = isCustom ? `bbmd-${base}` : `${base}`
let valueType = typeof value; let valueType = typeof value
if (valueType == "string" || valueType == "number") { if (valueType == "string" || valueType == "number") {
return isCustom return isCustom
? ` ${classBase}--${this._convertCamel(property)}-${value}` ? ` ${classBase}--${this._convertCamel(property)}-${value}`
: ` ${classBase}--${value}`; : ` ${classBase}--${value}`
} else if (valueType == "boolean") { } else if (valueType == "boolean") {
return ` ${classBase}--${this._convertCamel(property)}`; return ` ${classBase}--${this._convertCamel(property)}`
} }
} }
}) })
.join(""); .join("")
} }
_convertCamel(str) { _convertCamel(str) {
return str.replace(/[A-Z]/g, match => `-${match.toLowerCase()}`); return str.replace(/[A-Z]/g, match => `-${match.toLowerCase()}`)
} }
} }

View file

@ -1,32 +1,32 @@
<script> <script>
import "@material/form-field/mdc-form-field.scss"; import "@material/form-field/mdc-form-field.scss"
import ClassBuilder from "../ClassBuilder.js"; import ClassBuilder from "../ClassBuilder.js"
import { fieldStore } from "./FormfieldStore.js"; import { fieldStore } from "./FormfieldStore.js"
import { MDCFormField } from "@material/form-field"; import { MDCFormField } from "@material/form-field"
import { onMount, onDestroy, setContext } from "svelte"; import { onMount, onDestroy, setContext } from "svelte"
const cb = new ClassBuilder("form-field"); const cb = new ClassBuilder("form-field")
let store; let store
const unsubscribe = fieldStore.subscribe(s => (store = s)); const unsubscribe = fieldStore.subscribe(s => (store = s))
export let id = ""; export let id = ""
export let label = ""; export let label = ""
export let alignEnd = false; export let alignEnd = false
let formField = null; let formField = null
let modifiers = { alignEnd }; let modifiers = { alignEnd }
let props = { modifiers }; let props = { modifiers }
let blockClasses = cb.build({ props }); let blockClasses = cb.build({ props })
onMount(() => { onMount(() => {
if (!!formField) fieldStore.set(new MDCFormField(formField)); if (!!formField) fieldStore.set(new MDCFormField(formField))
setContext("BBMD:field-element", fieldStore); setContext("BBMD:field-element", fieldStore)
}); })
onDestroy(unsubscribe); onDestroy(unsubscribe)
</script> </script>
<div bind:this={formField} class={blockClasses}> <div bind:this={formField} class={blockClasses}>

View file

@ -1,19 +1,19 @@
import { writable } from "svelte/store"; import { writable } from "svelte/store"
function store() { function store() {
const { set, update, subscribe } = writable({}); const { set, update, subscribe } = writable({})
function setInput(inp) { function setInput(inp) {
update(n => { update(n => {
n.input = inp; n.input = inp
}); })
} }
return { return {
subscribe, subscribe,
set, set,
setInput setInput,
}; }
} }
export const fieldStore = store(); export const fieldStore = store()

View file

@ -1,12 +1,12 @@
<script> <script>
import { getContext } from "svelte"; import { getContext } from "svelte"
export let icon = ""; export let icon = ""
let iconContext = getContext("BBMD:icon:context"); let iconContext = getContext("BBMD:icon:context")
let cls = iconContext let cls = iconContext
? `material-icons mdc-${iconContext}__icon` ? `material-icons mdc-${iconContext}__icon`
: "material-icons"; : "material-icons"
</script> </script>
<i class={cls}>{icon}</i> <i class={cls}>{icon}</i>

View file

@ -1,12 +1,12 @@
<script> <script>
export let bold = false; export let bold = false
export let text = ""; export let text = ""
</script> </script>
<span class="mdc-typography" class:bold>{text}</span>
<style> <style>
.bold { .bold {
font-weight: 500; font-weight: 500;
} }
</style> </style>
<span class="mdc-typography" class:bold>{text}</span>

View file

@ -17,12 +17,10 @@
let tableElement let tableElement
let initialied = false let initialied = false
$: { $: {
if(tableElement && datatable && !initialied) { if (tableElement && datatable && !initialied) {
const children = _bb.attachChildren(tableElement) const children = _bb.attachChildren(tableElement)
if(children.length > 0) { if (children.length > 0) {
instance = new MDCDataTable(datatable) instance = new MDCDataTable(datatable)
initialied = true initialied = true
} }
@ -34,7 +32,7 @@
return () => { return () => {
try { try {
!!instance && instance.destroy() !!instance && instance.destroy()
} catch(e) { } catch (e) {
console.log(e) console.log(e)
} }
instance = null instance = null
@ -43,7 +41,8 @@
</script> </script>
<div bind:this={datatable} class={cb.build()}> <div bind:this={datatable} class={cb.build()}>
<table class={cb.elem`table`} aria-label="Material Design Datatable" bind:this={tableElement}> <table
class={cb.elem`table`}
</table> aria-label="Material Design Datatable"
bind:this={tableElement} />
</div> </div>

View file

@ -1,14 +1,13 @@
<script> <script>
import { getContext } from "svelte" import { getContext } from "svelte"
export let _bb export let _bb
const cb = _bb.getContext("BBMD:data-table:cb") const cb = _bb.getContext("BBMD:data-table:cb")
let tbody let tbody
$: tbody && _bb.attachChildren(tbody)
$: tbody && _bb.attachChildren(tbody)
</script> </script>
<tbody bind:this={tbody} class={cb.elem`content`}></tbody> <tbody bind:this={tbody} class={cb.elem`content`} />

View file

@ -5,7 +5,7 @@
export let numeric = false export let numeric = false
export let _bb export let _bb
const cb = _bb.getContext("BBMD:data-table:cb") const cb = _bb.getContext("BBMD:data-table:cb")
let elementName = isHeader ? "header-cell" : "cell" let elementName = isHeader ? "header-cell" : "cell"
let modifiers = { numeric } let modifiers = { numeric }
@ -14,7 +14,6 @@
let element let element
$: element && _bb.attachChildren(element) $: element && _bb.attachChildren(element)
</script> </script>
{#if isHeader} {#if isHeader}

View file

@ -1,13 +1,11 @@
<script> <script>
export let _bb
export let _bb const cb = _bb.getContext("BBMD:data-table:cb")
const cb = _bb.getContext("BBMD:data-table:cb") let thead
let thead
$: thead && _bb.attachChildren(thead)
$: thead && _bb.attachChildren(thead)
</script> </script>
<thead bind:this={thead} class=className></thead> <thead bind:this={thead} class="className" />

View file

@ -1,27 +1,27 @@
<script> <script>
import { getContext } from "svelte"; import { getContext } from "svelte"
export let onSelect = () => {}; export let onSelect = () => {}
export let isHeader = false; export let isHeader = false
export let _bb export let _bb
let row = null; let row = null
let selected = false; let selected = false
const cb = _bb.getContext("BBMD:data-table:cb") const cb = _bb.getContext("BBMD:data-table:cb")
let elementName = isHeader ? "header-row" : "row"; let elementName = isHeader ? "header-row" : "row"
let modifiers = {}; let modifiers = {}
$: modifiers = { selected }; $: modifiers = { selected }
$: props = { modifiers }; $: props = { modifiers }
$: rowClass = cb.build({ elementName, props }); $: rowClass = cb.build({ elementName, props })
$: row && _bb.attachChildren(row) $: row && _bb.attachChildren(row)
function rowSelected() { function rowSelected() {
selected = !selected; selected = !selected
onSelect(); onSelect()
} }
</script> </script>

View file

@ -1,32 +1,32 @@
<script> <script>
import { List } from "../List"; import { List } from "../List"
import { MDCMenu } from "@material/menu"; import { MDCMenu } from "@material/menu"
import { onMount, setContext } from "svelte"; import { onMount, setContext } from "svelte"
export let items = []; export let items = []
export let singleSelection = true; export let singleSelection = true
export let width = "400px"; export let width = "400px"
export let open = true; export let open = true
export let useFixedPosition = false; export let useFixedPosition = false
export let useAbsolutePosition = false; export let useAbsolutePosition = false
//{x: number, y: number} //{x: number, y: number}
export let absolutePositionCoords = null; export let absolutePositionCoords = null
let menu = null; let menu = null
let instance = null; let instance = null
onMount(() => { onMount(() => {
if (!!menu) { if (!!menu) {
instance = new MDCMenu(menu); instance = new MDCMenu(menu)
instance.open = open; instance.open = open
if (useFixedPosition) { if (useFixedPosition) {
instance.setFixedPosition(true); instance.setFixedPosition(true)
} else if (useAbsolutePosition) { } else if (useAbsolutePosition) {
let { x, y } = absolutePositionCoords; let { x, y } = absolutePositionCoords
instance.setAbsolutePosition(x | 0, y | 0); instance.setAbsolutePosition(x | 0, y | 0)
} }
} }
setContext("BBMD:list:context", "menu"); setContext("BBMD:list:context", "menu")
}); })
</script> </script>
{#if useFixedPosition || useAbsolutePosition} {#if useFixedPosition || useAbsolutePosition}

View file

@ -1,2 +1,2 @@
import "./_styles.scss"; import "./_styles.scss"
export { default as Menu } from "./Menu.svelte"; export { default as Menu } from "./Menu.svelte"

View file

@ -1,3 +1,3 @@
import "./_style.scss"; import "./_style.scss"
export { default as Radiobutton } from "./Radiobutton.svelte"; export { default as Radiobutton } from "./Radiobutton.svelte"
export { default as Radiobuttongroup } from "./RadiobuttonGroup.svelte"; export { default as Radiobuttongroup } from "./RadiobuttonGroup.svelte"

View file

@ -4,7 +4,7 @@ import packageJson from "../../package.json"
import { rootComponent } from "./rootComponent" import { rootComponent } from "./rootComponent"
import * as standardcomponents from "@budibase/standard-components/src/index" import * as standardcomponents from "@budibase/standard-components/src/index"
export default async props => { export default async () => {
delete components._lib delete components._lib
const componentLibraries = {} const componentLibraries = {}
componentLibraries[packageJson.name] = components componentLibraries[packageJson.name] = components

View file

@ -68,7 +68,7 @@
} }
let useLabel = !!label && (!fullwidth || (fullwidth && textarea)) let useLabel = !!label && (!fullwidth || (fullwidth && textarea))
let useIcon = !!icon && (!textarea && !fullwidth) let useIcon = !!icon && !textarea && !fullwidth
if (useIcon) { if (useIcon) {
setContext("BBMD:icon:context", "text-field") setContext("BBMD:icon:context", "text-field")
@ -120,7 +120,7 @@ TODO:Needs error handling - this will depend on how Budibase handles errors
{placeholder} {placeholder}
{minLength} {minLength}
maxLength={safeMaxLength} maxLength={safeMaxLength}
value={value} {value}
on:change={changed} /> on:change={changed} />
{:else} {:else}
{#if renderLeadingIcon} {#if renderLeadingIcon}
@ -135,7 +135,7 @@ TODO:Needs error handling - this will depend on how Budibase handles errors
placeholder={!!label && fullwidth ? label : placeholder} placeholder={!!label && fullwidth ? label : placeholder}
{minLength} {minLength}
maxLength={safeMaxLength} maxLength={safeMaxLength}
value={value} {value}
aria-label={`Textfield ${variant}`} aria-label={`Textfield ${variant}`}
on:focus={focus} on:focus={focus}
on:input={changed} /> on:input={changed} />

View file

@ -1,2 +1,2 @@
import "./_index.scss" import "./_index.scss"
export { default as Textfield } from "./Textfield.svelte" export { default as Textfield } from "./Textfield.svelte"

View file

@ -1,13 +1,13 @@
import "./_style.scss"; import "./_style.scss"
export { default as Body1 } from "./Body1.svelte"; export { default as Body1 } from "./Body1.svelte"
export { default as Body2 } from "./Body2.svelte"; export { default as Body2 } from "./Body2.svelte"
export { default as Caption } from "./Caption.svelte"; export { default as Caption } from "./Caption.svelte"
export { default as H1 } from "./H1.svelte"; export { default as H1 } from "./H1.svelte"
export { default as H2 } from "./H2.svelte"; export { default as H2 } from "./H2.svelte"
export { default as H3 } from "./H3.svelte"; export { default as H3 } from "./H3.svelte"
export { default as H4 } from "./H4.svelte"; export { default as H4 } from "./H4.svelte"
export { default as H5 } from "./H5.svelte"; export { default as H5 } from "./H5.svelte"
export { default as H6 } from "./H6.svelte"; export { default as H6 } from "./H6.svelte"
export { default as Overline } from "./Overline.svelte"; export { default as Overline } from "./Overline.svelte"
export { default as Sub1 } from "./Sub1.svelte"; export { default as Sub1 } from "./Sub1.svelte"
export { default as Sub2 } from "./Sub2.svelte"; export { default as Sub2 } from "./Sub2.svelte"

View file

@ -1,6 +1,6 @@
const fs = require("fs") const fs = require("fs")
module.exports = config => ({ module.exports = () => ({
main: { main: {
outputToFile: async ({ filename, content }) => { outputToFile: async ({ filename, content }) => {
await new Promise((resolve, reject) => { await new Promise((resolve, reject) => {

File diff suppressed because one or more lines are too long

View file

@ -1,2 +1,2 @@
window['##BUDIBASE_FRONTEND_DEINITION##'] = {"componentLibraries":[{"importPath":"/lib/customComponents/index.js","libName":"./customComponents"},{"importPath":"/lib/moreCustomComponents/index.js","libName":"./moreCustomComponents"}],"appRootPath":"","page":{"title":"Test App","favicon":"./_shared/favicon.png","stylesheets":["my-styles.css"],"componentLibraries":["./customComponents","./moreCustomComponents"],"props":{"_component":"@budibase/standard-components/container"}},"screens":[{"name":"screen1","description":"","props":{"_component":"@budibase/standard-components/container","className":""},"_css":"/css/d121e1ecc6cf44f433213222e9ff5d40.css"},{"name":"screen2","description":"","props":{"_component":"@budibase/standard-components/container","className":""},"_css":"/css/7b7c05b78e05c06eb8d69475caadfea3.css"}]}; window['##BUDIBASE_FRONTEND_DEFINITION##'] = {"componentLibraries":[{"importPath":"/lib/customComponents/index.js","libName":"./customComponents"},{"importPath":"/lib/moreCustomComponents/index.js","libName":"./moreCustomComponents"}],"appRootPath":"","page":{"title":"Test App","favicon":"./_shared/favicon.png","stylesheets":["my-styles.css"],"componentLibraries":["./customComponents","./moreCustomComponents"],"props":{"_component":"@budibase/standard-components/container","type":"div"}},"screens":[{"name":"screen1","description":"","props":{"_component":"@budibase/standard-components/container","className":"","type":"div"},"_css":"/css/d121e1ecc6cf44f433213222e9ff5d40.css"},{"name":"screen2","description":"","props":{"_component":"@budibase/standard-components/container","className":"","type":"div"},"_css":"/css/7b7c05b78e05c06eb8d69475caadfea3.css"}]};
window['##BUDIBASE_FRONTEND_FUNCTIONS##'] = {'1234':() => 'test return'} window['##BUDIBASE_FRONTEND_FUNCTIONS##'] = {'1234':() => 'test return'}

View file

@ -11,26 +11,21 @@
html, body { html, body {
height: 100%; height: 100%;
width: 100%; width: 100%;
margin: 0px;
padding: 0px;
} }
</style> </style>
<link rel='stylesheet' href='//my-styles.css'>
<link rel='stylesheet' href='//my-styles.css'> <link rel='stylesheet' href='/css/d121e1ecc6cf44f433213222e9ff5d40.css'>
<link rel='stylesheet' href='/css/7b7c05b78e05c06eb8d69475caadfea3.css'>
<link rel='stylesheet' href='/css/f66fc2928f7d850c946e619c1a1f3096.css'>
<script src='/clientFrontendDefinition.js'></script>
<link rel='stylesheet' href='/css/d121e1ecc6cf44f433213222e9ff5d40.css'> <script src='/clientBackendDefinition.js'></script>
<link rel='stylesheet' href='/css/7b7c05b78e05c06eb8d69475caadfea3.css'>
<link rel='stylesheet' href='/css/f66fc2928f7d850c946e619c1a1f3096.css'>
<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();

View file

@ -1 +1 @@
module.exports = config => ({}) module.exports = () => ({})

View file

@ -4,38 +4,34 @@ const { applictionVersionPackage } = require("../utilities/createAppPackage")
const { determineVersionId } = require("../utilities/runtimePackages") const { determineVersionId } = require("../utilities/runtimePackages")
module.exports = async (context, datastoreModule, app, instance) => { module.exports = async (context, datastoreModule, app, instance) => {
try { const databaseManager = getDatabaseManager(
const databaseManager = getDatabaseManager( datastoreModule,
datastoreModule, context.config.datastoreConfig
context.config.datastoreConfig )
)
await databaseManager.createEmptyInstanceDb(app.id, instance.id) await databaseManager.createEmptyInstanceDb(app.id, instance.id)
const dbConfig = databaseManager.getInstanceDatastoreConfig( const dbConfig = databaseManager.getInstanceDatastoreConfig(
app.id, app.id,
instance.id instance.id
) )
const datastore = setupDatastore(datastoreModule.getDatastore(dbConfig)) const datastore = setupDatastore(datastoreModule.getDatastore(dbConfig))
const versionId = determineVersionId(instance.version) const versionId = determineVersionId(instance.version)
const appPackage = await applictionVersionPackage( const appPackage = await applictionVersionPackage(
context, context,
app.name, app.name,
versionId, versionId,
instance.key instance.key
) )
await initialiseData( await initialiseData(
datastore, datastore,
appPackage.appDefinition, appPackage.appDefinition,
appPackage.accessLevels appPackage.accessLevels
) )
return dbConfig return dbConfig
} catch (e) {
throw e
}
} }

View file

@ -10,31 +10,25 @@ const masterDbAccessLevels = require("../appPackages/_master/access_levels.json"
const { masterAppPackage } = require("../utilities/createAppPackage") const { masterAppPackage } = require("../utilities/createAppPackage")
module.exports = async (context, datastoreModule, username, password) => { module.exports = async (context, datastoreModule, username, password) => {
try { const { config } = context
const { config } = context const databaseManager = getDatabaseManager(
const databaseManager = getDatabaseManager( datastoreModule,
datastoreModule, config.datastoreConfig
config.datastoreConfig )
)
await databaseManager.createEmptyMasterDb() await databaseManager.createEmptyMasterDb()
const masterDbConfig = databaseManager.masterDatastoreConfig const masterDbConfig = databaseManager.masterDatastoreConfig
const datastore = setupDatastore( const datastore = setupDatastore(datastoreModule.getDatastore(masterDbConfig))
datastoreModule.getDatastore(masterDbConfig)
)
await initialiseData(datastore, constructHierarchy(masterDbAppDefinition)) await initialiseData(datastore, constructHierarchy(masterDbAppDefinition))
const masterPackage = masterAppPackage(context) const masterPackage = masterAppPackage(context)
const bbMaster = await getApisWithFullAccess(datastore, masterPackage) const bbMaster = await getApisWithFullAccess(datastore, masterPackage)
await bbMaster.authApi.saveAccessLevels(masterDbAccessLevels) await bbMaster.authApi.saveAccessLevels(masterDbAccessLevels)
const user = bbMaster.authApi.getNewUser() const user = bbMaster.authApi.getNewUser()
user.name = username user.name = username
user.accessLevels = ["owner"] user.accessLevels = ["owner"]
await bbMaster.authApi.createUser(user, password) await bbMaster.authApi.createUser(user, password)
return await getApisForUser(datastore, masterPackage, username, password) return await getApisForUser(datastore, masterPackage, username, password)
} catch (e) {
throw e
}
} }

View file

@ -13,7 +13,9 @@ const copyfolder = (source, destination) =>
}) })
}) })
module.exports = async (context, bbMaster, latestAppsFolder) => { exports.copyfolder = copyfolder
module.exports = async context => {
// create runtime folder // create runtime folder
// copy master into /master/latest // copy master into /master/latest
if (await pathExists(runtimePackagesDirectory)) { if (await pathExists(runtimePackagesDirectory)) {
@ -26,16 +28,6 @@ module.exports = async (context, bbMaster, latestAppsFolder) => {
await mkdir(runtimePackagesDirectory) await mkdir(runtimePackagesDirectory)
/*
const allApps = await bbMaster
.indexApi
.listItems("/all_applications");
for(let app of allApps) {
app.
}
*/
const apps = { const apps = {
_master: masterAppPackage(context), _master: masterAppPackage(context),
} }

View file

@ -141,7 +141,11 @@ module.exports = (config, app) => {
}) })
.get("/_builder/api/:appname/components", async ctx => { .get("/_builder/api/:appname/components", async ctx => {
try { try {
ctx.body = getComponentDefinitions(config, ctx.params.appname, ctx.query.lib) ctx.body = getComponentDefinitions(
config,
ctx.params.appname,
ctx.query.lib
)
ctx.response.status = StatusCodes.OK ctx.response.status = StatusCodes.OK
} catch (e) { } catch (e) {
if (e.status) { if (e.status) {

View file

@ -14,9 +14,9 @@ module.exports = (config, app) => {
rolling: false /** (boolean) Force a session identifier cookie to be set on every response. The expiration is reset to the original maxAge, resetting the expiration countdown. (default is false) */, rolling: false /** (boolean) Force a session identifier cookie to be set on every response. The expiration is reset to the original maxAge, resetting the expiration countdown. (default is false) */,
renew: false /** (boolean) renew session when session is nearly expired, so we can always keep user logged in. (default is false)*/, renew: false /** (boolean) renew session when session is nearly expired, so we can always keep user logged in. (default is false)*/,
store: { store: {
get: async (key, maxAge, { rolling }) => ({ key }), get: async key => ({ key }),
set: async (key, sess, maxAge, { rolling, changed }) => ({ key }), set: async key => ({ key }),
destroy: async key => ({}), destroy: async () => ({}),
}, },
} }

View file

@ -25,6 +25,7 @@ beforeAll(async () => {
await app.start() await app.start()
}) })
afterAll(async () => await app.destroy()) afterAll(async () => await app.destroy())
it("/apppackage should get appDefinition", async () => { it("/apppackage should get appDefinition", async () => {

Some files were not shown because too many files have changed in this diff Show more