Merge branch 'master' of github.com:Budibase/budibase
This commit is contained in:
commit
4809105fc3
|
@ -5,11 +5,13 @@
|
|||
"jest": true,
|
||||
"node": true
|
||||
},
|
||||
"parser": "babel-eslint",
|
||||
"parserOptions": {
|
||||
"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"],
|
||||
"extends": ["eslint:recommended"],
|
||||
"overrides": [
|
||||
|
|
|
@ -27,6 +27,7 @@ jobs:
|
|||
node-version: ${{ matrix.node-version }}
|
||||
- run: yarn
|
||||
- run: yarn lint
|
||||
- run: yarn bootstrap
|
||||
- run: yarn build
|
||||
- run: yarn test
|
||||
env:
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
packages/builder/src/userInterface/CurrentItemPreview.svelte
|
||||
public
|
||||
dist
|
||||
packages/server/builder
|
||||
**/*.spec.js
|
|
@ -2,6 +2,7 @@
|
|||
"name": "root",
|
||||
"private": true,
|
||||
"devDependencies": {
|
||||
"babel-eslint": "^10.0.3",
|
||||
"eslint": "^6.8.0",
|
||||
"eslint-plugin-prettier": "^3.1.2",
|
||||
"eslint-plugin-svelte3": "^2.7.3",
|
||||
|
|
|
@ -16,12 +16,7 @@ const _builderProxy = proxy("/_builder", {
|
|||
pathRewrite: { "^/_builder": "" },
|
||||
})
|
||||
|
||||
const apiProxy = proxy(
|
||||
[
|
||||
"/_builder/api/**",
|
||||
"/_builder/**/componentlibrary"
|
||||
],
|
||||
{
|
||||
const apiProxy = proxy(["/_builder/api/**", "/_builder/**/componentlibrary"], {
|
||||
target,
|
||||
logLevel: "debug",
|
||||
changeOrigin: true,
|
||||
|
@ -31,8 +26,7 @@ const apiProxy = proxy(
|
|||
proxyReq.setHeader("origin", target)
|
||||
}
|
||||
},
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
const production = !process.env.ROLLUP_WATCH
|
||||
|
||||
|
|
|
@ -61,5 +61,4 @@
|
|||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
|
|
@ -83,10 +83,9 @@
|
|||
{:else}(no actions added){/if}
|
||||
|
||||
<Modal
|
||||
onClosed={() => isEditing = false}
|
||||
onClosed={() => (isEditing = false)}
|
||||
bind:isOpen={isEditing}
|
||||
title={isEditing ? "Edit Access Level" : "Create Access Level"}
|
||||
>
|
||||
title={isEditing ? 'Edit Access Level' : 'Create Access Level'}>
|
||||
{#if isEditing}
|
||||
<AccessLevelView
|
||||
level={editingLevel}
|
||||
|
|
|
@ -16,10 +16,10 @@
|
|||
let optValue = ""
|
||||
|
||||
let clonedAction = cloneDeep(action)
|
||||
let initialOptions = pipe(
|
||||
action.initialOptions,
|
||||
[keys, map(k => ({ key: k, value: action.initialOptions[k] }))]
|
||||
)
|
||||
let initialOptions = pipe(action.initialOptions, [
|
||||
keys,
|
||||
map(k => ({ key: k, value: action.initialOptions[k] })),
|
||||
])
|
||||
let errors = []
|
||||
|
||||
const addNewOption = () => {
|
||||
|
@ -44,26 +44,17 @@
|
|||
const removeOption = opt => {
|
||||
if (opt) {
|
||||
delete clonedAction.initialOptions[opt.key]
|
||||
initialOptions = pipe(
|
||||
initialOptions,
|
||||
[filter(o => o.key !== opt.key)]
|
||||
)
|
||||
initialOptions = pipe(initialOptions, [filter(o => o.key !== opt.key)])
|
||||
}
|
||||
}
|
||||
|
||||
const save = () => {
|
||||
const newActionsList = [
|
||||
...pipe(
|
||||
allActions,
|
||||
[filter(a => a !== action)]
|
||||
),
|
||||
...pipe(allActions, [filter(a => a !== action)]),
|
||||
clonedAction,
|
||||
]
|
||||
|
||||
errors = pipe(
|
||||
newActionsList,
|
||||
[validateActions, map(e => e.error)]
|
||||
)
|
||||
errors = pipe(newActionsList, [validateActions, map(e => e.error)])
|
||||
|
||||
if (errors.length === 0) onFinished(clonedAction)
|
||||
}
|
||||
|
|
|
@ -19,16 +19,11 @@
|
|||
|
||||
let actionsArray = []
|
||||
store.subscribe(s => {
|
||||
actionsArray = pipe(
|
||||
s.actions,
|
||||
[keys, map(k => s.actions[k])]
|
||||
)
|
||||
actionsArray = pipe(s.actions, [keys, map(k => s.actions[k])])
|
||||
})
|
||||
|
||||
let getDefaultOptionsHtml = defaultOptions =>
|
||||
pipe(
|
||||
defaultOptions,
|
||||
[
|
||||
pipe(defaultOptions, [
|
||||
keys,
|
||||
map(
|
||||
k =>
|
||||
|
@ -37,8 +32,7 @@
|
|||
)}`
|
||||
),
|
||||
join("<br>"),
|
||||
]
|
||||
)
|
||||
])
|
||||
|
||||
let actionEditingFinished = action => {
|
||||
if (action) {
|
||||
|
|
|
@ -22,10 +22,7 @@
|
|||
let cancel = () => onFinished()
|
||||
let save = () => {
|
||||
const newTriggersList = [
|
||||
...pipe(
|
||||
allTriggers,
|
||||
[filter(t => t !== trigger)]
|
||||
),
|
||||
...pipe(allTriggers, [filter(t => t !== trigger)]),
|
||||
clonedTrigger,
|
||||
]
|
||||
|
||||
|
|
|
@ -7,21 +7,22 @@
|
|||
* @returns {Object} an object with the client state values and how they are managed.
|
||||
*/
|
||||
export const buildStateOrigins = screenDefinition => {
|
||||
const origins = {};
|
||||
const origins = {}
|
||||
|
||||
function traverse(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]) {
|
||||
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
|
||||
}
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
import { createPackage } from "./createPackage"
|
||||
import getStore from "./store"
|
||||
|
||||
export const store = getStore()
|
||||
|
||||
export const createNewPackage = () => createPackage(packageInfo, store)
|
||||
|
||||
export const initialise = async () => {
|
||||
try {
|
||||
setupRouter(store)
|
||||
|
@ -17,8 +14,7 @@ export const initialise = async () => {
|
|||
const setupRouter = writable => {
|
||||
const pushState = history.pushState
|
||||
history.pushState = () => {
|
||||
pushState.apply(history, arguments)
|
||||
//fireEvents('pushState', arguments);
|
||||
pushState.apply(history, [writable])
|
||||
writable.initialise()
|
||||
}
|
||||
window.addEventListener("hashchange", () => {
|
||||
|
|
|
@ -5,7 +5,6 @@ export const loadLibs = async (appName, appPackage) => {
|
|||
const allLibraries = {}
|
||||
|
||||
for (let lib of libsFromPages(appPackage.pages)) {
|
||||
|
||||
const libModule = await import(makeLibraryUrl(appName, lib))
|
||||
allLibraries[lib] = libModule
|
||||
}
|
||||
|
@ -31,10 +30,5 @@ export const loadLib = async (appName, lib, allLibs) => {
|
|||
export const makeLibraryUrl = (appName, lib) =>
|
||||
`/_builder/${appName}/componentlibrary?lib=${encodeURI(lib)}`
|
||||
|
||||
export const libsFromPages = pages => pipe(pages, [
|
||||
values,
|
||||
map(p => p.componentLibraries),
|
||||
flatten,
|
||||
uniq
|
||||
])
|
||||
|
||||
export const libsFromPages = pages =>
|
||||
pipe(pages, [values, map(p => p.componentLibraries), flatten, uniq])
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<script>
|
||||
import { createEventDispatcher } from "svelte"
|
||||
import Select from "../common/Select.svelte";
|
||||
import Select from "../common/Select.svelte"
|
||||
|
||||
export let selected
|
||||
export let label
|
||||
|
|
|
@ -17,7 +17,9 @@
|
|||
class="dropdown-content"
|
||||
style="display: {isDroppedDown ? 'inline-block' : 'none'}">
|
||||
{#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}
|
||||
</div>
|
||||
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
<button on:click>
|
||||
<slot>
|
||||
+
|
||||
</slot>
|
||||
<slot>+</slot>
|
||||
</button>
|
||||
|
||||
<style>
|
||||
|
|
|
@ -4,7 +4,7 @@ import {
|
|||
getTemplateApi,
|
||||
getAuthApi,
|
||||
} 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"
|
||||
|
||||
|
|
|
@ -39,9 +39,7 @@
|
|||
{/if}
|
||||
|
||||
<Modal onClosed={() => (confirmDelete = false)} bind:isOpen={confirmDelete}>
|
||||
<span>
|
||||
Are you sure you want to delete {$store.currentNode.name}?
|
||||
</span>
|
||||
<span>Are you sure you want to delete {$store.currentNode.name}?</span>
|
||||
<div class="uk-modal-footer uk-text-right">
|
||||
<ButtonGroup>
|
||||
<ActionButton alert on:click={deleteCurrentNode}>Yes</ActionButton>
|
||||
|
|
|
@ -14,9 +14,7 @@
|
|||
|
||||
store.subscribe($store => {
|
||||
index = $store.currentNode
|
||||
indexableRecords = pipe(
|
||||
$store.hierarchy,
|
||||
[
|
||||
indexableRecords = pipe($store.hierarchy, [
|
||||
hierarchyFunctions.getFlattenedHierarchy,
|
||||
filter(hierarchyFunctions.isDecendant(index.parent())),
|
||||
filter(hierarchyFunctions.isRecord),
|
||||
|
@ -24,8 +22,7 @@
|
|||
node: n,
|
||||
isallowed: some(id => n.nodeId === id)(index.allowedRecordNodeIds),
|
||||
})),
|
||||
]
|
||||
)
|
||||
])
|
||||
})
|
||||
|
||||
const toggleAllowedRecord = record => {
|
||||
|
|
|
@ -99,7 +99,9 @@
|
|||
<Textbox label="Name:" bind:text={record.name} on:change={nameChanged} />
|
||||
{#if !record.isSingle}
|
||||
<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}
|
||||
<div class="recordkey">{record.nodeKey()}</div>
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@ import "uikit/dist/js/uikit.min.js"
|
|||
import "codemirror/lib/codemirror.css"
|
||||
import "codemirror/theme/monokai.css"
|
||||
|
||||
/* eslint-disable */
|
||||
const app = new App({
|
||||
target: document.getElementById("app"),
|
||||
})
|
||||
|
|
|
@ -14,7 +14,12 @@
|
|||
const setActive = () => store.setActiveNav(name)
|
||||
</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>
|
||||
.backend-nav-item {
|
||||
|
|
|
@ -1,13 +1,26 @@
|
|||
<script>
|
||||
import { splitName } from "./pagesParsing/splitRootComponentName.js"
|
||||
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 Select from "../common/Select.svelte"
|
||||
import Button from "../common/PlusButton.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
|
||||
|
||||
|
@ -27,7 +40,7 @@
|
|||
flatten,
|
||||
filter(t => !$store.components.some(c => c.name === t.component)),
|
||||
map(t => ({ name: splitName(t.component).componentName, template: t })),
|
||||
uniqBy(t => t.name)
|
||||
uniqBy(t => t.name),
|
||||
])
|
||||
|
||||
const addRootComponent = (component, allComponents) => {
|
||||
|
@ -62,8 +75,8 @@
|
|||
records: getRecordNodes(hierarchy),
|
||||
indexes: getIndexNodes(hierarchy),
|
||||
helpers: {
|
||||
indexSchema: getIndexSchema(hierarchy)
|
||||
}
|
||||
indexSchema: getIndexSchema(hierarchy),
|
||||
},
|
||||
}
|
||||
templateInstances = libraryModules[libName][componentName](templateOptions)
|
||||
if (!templateInstances || templateInstances.length === 0) return
|
||||
|
@ -73,7 +86,9 @@
|
|||
|
||||
const onTemplateInstanceChosen = () => {
|
||||
selectedComponent = null
|
||||
const instance = templateInstances.find(i => i.name === selectedTemplateInstance)
|
||||
const instance = templateInstances.find(
|
||||
i => i.name === selectedTemplateInstance
|
||||
)
|
||||
store.addTemplatedComponent(instance.props)
|
||||
toggleTab()
|
||||
}
|
||||
|
@ -81,7 +96,8 @@
|
|||
function generate_components_list(components) {
|
||||
return ($store.currentFrontEndType === "page"
|
||||
? $store.builtins.concat(components)
|
||||
: components).concat(standaloneTemplates)
|
||||
: components
|
||||
).concat(standaloneTemplates)
|
||||
}
|
||||
|
||||
$: {
|
||||
|
@ -96,15 +112,12 @@
|
|||
}
|
||||
|
||||
$: componentLibrary = componentLibraries.find(l => l.libName === selectedLib)
|
||||
|
||||
</script>
|
||||
|
||||
<div class="root">
|
||||
<Select on:change={e => selectedLib = e.target.value}>
|
||||
<Select on:change={e => (selectedLib = e.target.value)}>
|
||||
{#each componentLibraries as lib}
|
||||
<option value={lib.libName}>
|
||||
{lib.libName}
|
||||
</option>
|
||||
<option value={lib.libName}>{lib.libName}</option>
|
||||
{/each}
|
||||
</Select>
|
||||
|
||||
|
@ -136,9 +149,7 @@
|
|||
{#if componentLibrary}
|
||||
{#each generate_components_list(componentLibrary.components) as component}
|
||||
<div class="component-container">
|
||||
<div
|
||||
class="component"
|
||||
on:click={() => onComponentChosen(component)}>
|
||||
<div class="component" on:click={() => onComponentChosen(component)}>
|
||||
<div class="name">{splitName(component.name).componentName}</div>
|
||||
{#if (component.presets || templatesByComponent[component.name]) && component.name === selectedComponent}
|
||||
<ul class="preset-menu">
|
||||
|
@ -152,7 +163,9 @@
|
|||
{/each}
|
||||
{/if}
|
||||
{#if templatesByComponent[component.name]}
|
||||
<span>{splitName(component.name).componentName} Templates</span>
|
||||
<span>
|
||||
{splitName(component.name).componentName} Templates
|
||||
</span>
|
||||
{#each templatesByComponent[component.name] as template}
|
||||
<li
|
||||
on:click|stopPropagation={() => onTemplateChosen(template)}>
|
||||
|
@ -180,18 +193,21 @@
|
|||
{/if}
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<ConfirmDialog
|
||||
bind:this={selectTemplateDialog}
|
||||
title="Choose Template"
|
||||
onCancel={() => selectedComponent = null}
|
||||
onCancel={() => (selectedComponent = null)}
|
||||
onOk={onTemplateInstanceChosen}>
|
||||
{#each templateInstances.map(i => i.name) as instance}
|
||||
<div class="uk-margin uk-grid-small uk-child-width-auto uk-grid">
|
||||
<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>
|
||||
</label>
|
||||
</div>
|
||||
|
@ -307,5 +323,4 @@
|
|||
.template-instance-label {
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
|
|
@ -15,15 +15,12 @@
|
|||
const joinPath = join("/")
|
||||
|
||||
const normalizedName = name =>
|
||||
pipe(
|
||||
name,
|
||||
[
|
||||
pipe(name, [
|
||||
trimCharsStart("./"),
|
||||
trimCharsStart("~/"),
|
||||
trimCharsStart("../"),
|
||||
trimChars(" "),
|
||||
]
|
||||
)
|
||||
])
|
||||
|
||||
const lastPartOfName = c => {
|
||||
if (!c) return ""
|
||||
|
@ -31,15 +28,14 @@
|
|||
return last(name.split("/"))
|
||||
}
|
||||
|
||||
|
||||
const isComponentSelected = (current, comp) => current === comp
|
||||
|
||||
const isFolderSelected = (current, folder) => isInSubfolder(current, folder)
|
||||
|
||||
$: _screens = pipe(
|
||||
screens,
|
||||
[map(c => ({ component: c, title: lastPartOfName(c) })), sortBy("title")]
|
||||
)
|
||||
$: _screens = pipe(screens, [
|
||||
map(c => ({ component: c, title: lastPartOfName(c) })),
|
||||
sortBy("title"),
|
||||
])
|
||||
|
||||
const isScreenSelected = component =>
|
||||
component.component &&
|
||||
|
|
|
@ -20,11 +20,7 @@
|
|||
const capitalise = s => s.substring(0, 1).toUpperCase() + s.substring(1)
|
||||
const get_name = s => (!s ? "" : last(s.split("/")))
|
||||
|
||||
const get_capitalised_name = name =>
|
||||
pipe(
|
||||
name,
|
||||
[get_name, capitalise]
|
||||
)
|
||||
const get_capitalised_name = name => pipe(name, [get_name, capitalise])
|
||||
|
||||
const moveDownComponent = component => {
|
||||
const c = component
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
import ComponentPropertiesPanel from "./ComponentPropertiesPanel.svelte"
|
||||
import ComponentSelectionList from "./ComponentSelectionList.svelte"
|
||||
|
||||
const PROPERTIES_TAB = "properties";
|
||||
const COMPONENT_SELECTION_TAB = "components";
|
||||
const PROPERTIES_TAB = "properties"
|
||||
const COMPONENT_SELECTION_TAB = "components"
|
||||
|
||||
let selected = PROPERTIES_TAB
|
||||
|
||||
|
@ -12,7 +12,9 @@
|
|||
|
||||
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>
|
||||
|
||||
<div class="root">
|
||||
|
|
|
@ -16,15 +16,12 @@
|
|||
const joinPath = join("/")
|
||||
|
||||
const normalizedName = name =>
|
||||
pipe(
|
||||
name,
|
||||
[
|
||||
pipe(name, [
|
||||
trimCharsStart("./"),
|
||||
trimCharsStart("~/"),
|
||||
trimCharsStart("../"),
|
||||
trimChars(" "),
|
||||
]
|
||||
)
|
||||
])
|
||||
|
||||
const lastPartOfName = c =>
|
||||
c && last(c.name ? c.name.split("/") : c._component.split("/"))
|
||||
|
@ -33,10 +30,7 @@
|
|||
|
||||
const isFolderSelected = (current, folder) => isInSubfolder(current, folder)
|
||||
|
||||
$: _layout = pipe(
|
||||
layout,
|
||||
[c => ({ component: c, title: lastPartOfName(c) })]
|
||||
)
|
||||
$: _layout = pipe(layout, [c => ({ component: c, title: lastPartOfName(c) })])
|
||||
|
||||
const isScreenSelected = component =>
|
||||
component.component &&
|
||||
|
|
|
@ -24,13 +24,10 @@
|
|||
|
||||
let saveAttempted = false
|
||||
|
||||
$: layoutComponents = pipe(
|
||||
$store.components,
|
||||
[
|
||||
$: layoutComponents = pipe($store.components, [
|
||||
filter(c => c.container),
|
||||
map(c => ({ name: c.name, ...splitName(c.name) })),
|
||||
]
|
||||
)
|
||||
])
|
||||
|
||||
$: layoutComponent = layoutComponent
|
||||
? find(c => c.name === layoutComponent.name)(layoutComponents)
|
||||
|
@ -43,9 +40,11 @@
|
|||
saveAttempted = true
|
||||
|
||||
const isValid =
|
||||
name.length > 0 && !screenNameExists(name)
|
||||
&& route.length > 0 && !routeNameExists(route)
|
||||
&& layoutComponent
|
||||
name.length > 0 &&
|
||||
!screenNameExists(name) &&
|
||||
route.length > 0 &&
|
||||
!routeNameExists(route) &&
|
||||
layoutComponent
|
||||
|
||||
if (!isValid) return
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
import { store } from "../../builderStore"
|
||||
import { buildStateOrigins } from "../../builderStore/buildStateOrigins"
|
||||
import { isBinding, getBinding, setBinding } from "../../common/binding"
|
||||
import StateBindingOptions from "./StateBindingOptions.svelte";
|
||||
import StateBindingOptions from "./StateBindingOptions.svelte"
|
||||
|
||||
export let onChanged = () => {}
|
||||
export let value = ""
|
||||
|
@ -28,7 +28,8 @@
|
|||
const setBindingPath = value =>
|
||||
bindValueToSource(value, bindingFallbackValue, bindingSource)
|
||||
|
||||
const setBindingFallback = value => bindValueToSource(bindingPath, value, bindingSource)
|
||||
const setBindingFallback = value =>
|
||||
bindValueToSource(bindingPath, value, bindingSource)
|
||||
|
||||
const setBindingSource = source =>
|
||||
bindValueToSource(bindingPath, bindingFallbackValue, source)
|
||||
|
@ -69,9 +70,10 @@
|
|||
</button>
|
||||
</div>
|
||||
{#if isOpen}
|
||||
<StateBindingOptions onSelect={option => {
|
||||
onChanged(option);
|
||||
isOpen = false;
|
||||
<StateBindingOptions
|
||||
onSelect={option => {
|
||||
onChanged(option)
|
||||
isOpen = false
|
||||
}} />
|
||||
{/if}
|
||||
</div>
|
||||
|
|
|
@ -13,15 +13,13 @@
|
|||
const props_to_ignore = ["_component", "_children", "_styles", "_code", "_id"]
|
||||
|
||||
$: componentDef =
|
||||
component && components &&
|
||||
component &&
|
||||
components &&
|
||||
components.find(({ name }) => name === component._component)
|
||||
|
||||
|
||||
|
||||
let setProp = (name, value) => {
|
||||
onPropChanged(name, value)
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<div class="root">
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
class="uk-select uk-form-small"
|
||||
{value}
|
||||
on:change={ev => onChanged(ev.target.value)}>
|
||||
{#each (options || []) as option}
|
||||
{#each options || [] as option}
|
||||
<option value={option}>{option}</option>
|
||||
{/each}
|
||||
</select>
|
||||
|
|
|
@ -5,7 +5,7 @@ import { isRootComponent } from "./searchComponents"
|
|||
export const libraryDependencies = (components, lib) => {
|
||||
const componentDependsOnLibrary = comp => {
|
||||
if (isRootComponent(comp)) {
|
||||
const { libName } = splitName(component.name)
|
||||
const { libName } = splitName(comp.name)
|
||||
return libName === lib
|
||||
}
|
||||
return componentDependsOnLibrary(
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
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()
|
||||
|
||||
|
|
|
@ -3,10 +3,8 @@ import {
|
|||
isBoolean,
|
||||
isNumber,
|
||||
isArray,
|
||||
isObjectLike,
|
||||
isPlainObject,
|
||||
every,
|
||||
isUndefined,
|
||||
} from "lodash/fp"
|
||||
|
||||
import { EVENT_TYPE_MEMBER_NAME } from "../../common/eventHandlers"
|
||||
|
@ -61,7 +59,6 @@ export const expandComponentDefinition = componentDefinition => {
|
|||
return expandedComponent
|
||||
}
|
||||
|
||||
const isComponent = isObjectLike
|
||||
const isEvent = e =>
|
||||
isPlainObject(e) &&
|
||||
isString(e[EVENT_TYPE_MEMBER_NAME]) &&
|
||||
|
|
|
@ -2,7 +2,7 @@ import { isString, keys, flatten, isArray, map, filter } from "lodash/fp"
|
|||
import { common } from "../../../../core/src"
|
||||
const pipe = common.$
|
||||
|
||||
export const validatePage = (page, getComponent) => {
|
||||
export const validatePage = page => {
|
||||
const errors = []
|
||||
const error = message => errors.push(message)
|
||||
|
||||
|
|
|
@ -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", () => {
|
||||
expect(buildStateOrigins({
|
||||
"name": "screen1",
|
||||
"description": "",
|
||||
"props": {
|
||||
"_component": "@budibase/standard-components/container",
|
||||
"className": "",
|
||||
"type": "div",
|
||||
"onClick": [
|
||||
expect(
|
||||
buildStateOrigins({
|
||||
name: "screen1",
|
||||
description: "",
|
||||
props: {
|
||||
_component: "@budibase/standard-components/container",
|
||||
className: "",
|
||||
type: "div",
|
||||
onClick: [
|
||||
{
|
||||
"##eventHandlerType": "Set State",
|
||||
"parameters": {
|
||||
"path": "testKey",
|
||||
"value": "value"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
})).toEqual({
|
||||
"testKey": {
|
||||
parameters: {
|
||||
path: "testKey",
|
||||
value: "value",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
})
|
||||
).toEqual({
|
||||
testKey: {
|
||||
"##eventHandlerType": "Set State",
|
||||
"parameters": {
|
||||
"path": "testKey",
|
||||
"value": "value"
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
parameters: {
|
||||
path: "testKey",
|
||||
value: "value",
|
||||
},
|
||||
},
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1 +1 @@
|
|||
module.exports = config => ({})
|
||||
module.exports = () => ({})
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
const { resolve, join } = require("path")
|
||||
const { resolve } = require("path")
|
||||
const { cwd } = require("process")
|
||||
const buildAppContext = require("@budibase/server/initialise/buildAppContext")
|
||||
|
||||
|
|
|
@ -2,7 +2,6 @@ import resolve from "rollup-plugin-node-resolve"
|
|||
import commonjs from "rollup-plugin-commonjs"
|
||||
import builtins from "rollup-plugin-node-builtins"
|
||||
import nodeglobals from "rollup-plugin-node-globals"
|
||||
import { terser } from "rollup-plugin-terser"
|
||||
|
||||
const lodash_fp_exports = [
|
||||
"find",
|
||||
|
|
|
@ -19,8 +19,6 @@ const appPackages = join(
|
|||
const publicMain = appName => join(appPackages, appName, "public", "main")
|
||||
const publicUnauth = appName =>
|
||||
join(appPackages, appName, "public", "unauthenticated")
|
||||
const nodeModules = appName =>
|
||||
join(appPackages, appName, "node_modules", "@budibase", "client", "dist")
|
||||
|
||||
;(async () => {
|
||||
const apps = await readdir(appPackages)
|
||||
|
|
|
@ -6,8 +6,7 @@ import { builtins, builtinLibName } from "./render/builtinComponents"
|
|||
* create a web application from static budibase definition files.
|
||||
* @param {object} opts - configuration options for budibase client libary
|
||||
*/
|
||||
export const loadBudibase = async (opts) => {
|
||||
|
||||
export const loadBudibase = async opts => {
|
||||
let componentLibraries = opts && opts.componentLibraries
|
||||
const _window = (opts && opts.window) || window
|
||||
const _localStorage = (opts && opts.localStorage) || localStorage
|
||||
|
@ -33,8 +32,8 @@ export const loadBudibase = async (opts) => {
|
|||
: "/" + trimSlash(frontendDefinition.appRootPath)
|
||||
|
||||
if (!componentLibraries) {
|
||||
|
||||
const componentLibraryUrl = lib => frontendDefinition.appRootPath + "/" + trimSlash(lib)
|
||||
const componentLibraryUrl = lib =>
|
||||
frontendDefinition.appRootPath + "/" + trimSlash(lib)
|
||||
componentLibraries = {}
|
||||
|
||||
for (let lib of frontendDefinition.componentLibraries) {
|
||||
|
@ -46,25 +45,33 @@ export const loadBudibase = async (opts) => {
|
|||
|
||||
componentLibraries[builtinLibName] = builtins(_window)
|
||||
|
||||
const { initialisePage, screenStore, pageStore, routeTo, rootNode } = createApp(
|
||||
const {
|
||||
initialisePage,
|
||||
screenStore,
|
||||
pageStore,
|
||||
routeTo,
|
||||
rootNode,
|
||||
} = createApp(
|
||||
componentLibraries,
|
||||
frontendDefinition,
|
||||
backendDefinition,
|
||||
user,
|
||||
uiFunctions || {},
|
||||
_window
|
||||
_window,
|
||||
rootNode
|
||||
)
|
||||
|
||||
const route = _window.location
|
||||
? _window.location.pathname.replace(frontendDefinition.appRootPath, "")
|
||||
: "";
|
||||
: ""
|
||||
|
||||
initialisePage(frontendDefinition.page, _window.document.body, route)
|
||||
|
||||
return {
|
||||
rootNode: initialisePage(frontendDefinition.page, _window.document.body, route),
|
||||
screenStore,
|
||||
pageStore,
|
||||
routeTo,
|
||||
rootNode
|
||||
rootNode,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@ export const attachChildren = initialiseOpts => (htmlElement, options) => {
|
|||
uiFunctions,
|
||||
htmlElement,
|
||||
anchor,
|
||||
getCurrentState
|
||||
getCurrentState,
|
||||
})
|
||||
|
||||
for (let childNode of childNodesThisIteration) {
|
||||
|
|
|
@ -34,7 +34,8 @@ export const parseBinding = prop => {
|
|||
}
|
||||
|
||||
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"
|
||||
|
||||
const hasBindingObject = prop =>
|
||||
|
@ -50,7 +51,7 @@ const isBindingExpression = prop =>
|
|||
prop.startsWith("route."))
|
||||
|
||||
const parseBindingExpression = prop => {
|
||||
let [source, ...rest] = prop.split(".");
|
||||
let [source, ...rest] = prop.split(".")
|
||||
let path = rest.join(".")
|
||||
|
||||
if (source === "route") {
|
||||
|
|
|
@ -160,7 +160,11 @@ const setNodeState = (storeState, node) => {
|
|||
* Bind a components event handler parameters to state, context or the event itself.
|
||||
* @param {Array} eventHandlerProp - event handler array from component definition
|
||||
*/
|
||||
function bindComponentEventHandlers(eventHandlerProp) {
|
||||
function bindComponentEventHandlers(
|
||||
eventHandlerProp,
|
||||
context,
|
||||
getCurrentState
|
||||
) {
|
||||
const boundEventHandlers = []
|
||||
for (let event of eventHandlerProp) {
|
||||
const boundEventHandler = {
|
||||
|
@ -177,23 +181,24 @@ function bindComponentEventHandlers(eventHandlerProp) {
|
|||
continue
|
||||
}
|
||||
|
||||
let paramValueSource;
|
||||
let paramValueSource
|
||||
|
||||
if (paramBinding.source === "context") paramValueSource = context;
|
||||
if (paramBinding.source === "state") paramValueSource = getCurrentState();
|
||||
if (paramBinding.source === "context") paramValueSource = context
|
||||
if (paramBinding.source === "state") paramValueSource = getCurrentState()
|
||||
|
||||
// The new dynamic event parameter bound to the relevant source
|
||||
boundParameters[paramName] = eventContext => getState(
|
||||
boundParameters[paramName] = eventContext =>
|
||||
getState(
|
||||
paramBinding.source === "event" ? eventContext : paramValueSource,
|
||||
paramBinding.path,
|
||||
paramBinding.fallback
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
boundEventHandler.parameters = boundParameters
|
||||
boundEventHandlers.push(boundEventHandlers)
|
||||
|
||||
return boundEventHandlers;
|
||||
return boundEventHandlers
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -239,13 +244,17 @@ const _setup = (
|
|||
}
|
||||
|
||||
if (isEventType(propValue)) {
|
||||
const boundEventHandlers = bindComponentEventHandlers(propValue);
|
||||
const boundEventHandlers = bindComponentEventHandlers(
|
||||
propValue,
|
||||
context,
|
||||
getCurrentState
|
||||
)
|
||||
|
||||
if (boundEventHandlers.length === 0) {
|
||||
initialProps[propName] = doNothing
|
||||
} else {
|
||||
initialProps[propName] = async context => {
|
||||
for (let handlerInfo of handlersInfos) {
|
||||
for (let handlerInfo of boundEventHandlers) {
|
||||
const handler = makeHandler(handlerTypes, handlerInfo)
|
||||
await handler(context)
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { flatten, orderBy, filter, isUndefined } from "lodash/fp"
|
||||
import hierarchy, {
|
||||
import {
|
||||
getFlattenedHierarchy,
|
||||
getCollectionNodeByKeyOrNodeKey,
|
||||
isCollectionRecord,
|
||||
|
|
|
@ -5,7 +5,6 @@ import {
|
|||
isGlobalIndex,
|
||||
getParentKey,
|
||||
isShardedIndex,
|
||||
getExactNodeForKey,
|
||||
} from "../templateApi/hierarchy"
|
||||
import { joinKey, isNonEmptyString, splitKey, $ } from "../common"
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
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 {
|
||||
$,
|
||||
|
|
|
@ -5,7 +5,7 @@ import {
|
|||
isSingleRecord,
|
||||
getNodeForCollectionPath,
|
||||
} 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 { folderStructureArray, allIdChars } from "../indexing/allIds"
|
||||
|
||||
|
|
|
@ -73,9 +73,7 @@ const _uploadFile = async (
|
|||
)
|
||||
if (!isExpectedFileSize) {
|
||||
throw new BadRequestError(
|
||||
`Fields for ${relativeFilePath} do not have expected size: ${join(
|
||||
","
|
||||
)(incorrectFields)}`
|
||||
`Fields for ${relativeFilePath} do not have expected size.`
|
||||
)
|
||||
}
|
||||
})
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
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 and reference type fields
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { apiWrapper, apiWrapperSync } from "../src/common/apiWrapper"
|
||||
import { filter } from "lodash/fp"
|
||||
import { event, onComplete, onBegin, onError, events } from "../src/common"
|
||||
import { events } from "../src/common"
|
||||
|
||||
const getApp = () => {
|
||||
var events = []
|
||||
|
@ -26,7 +26,7 @@ describe("apiWrapper", () => {
|
|||
const getErrorEvents = app => app.getEvents(testNamespace.onError)
|
||||
|
||||
const runThrowEx = (arg1, arg2) => {
|
||||
const throwEx = (x, y) => {
|
||||
const throwEx = () => {
|
||||
throw new Error("test error")
|
||||
}
|
||||
const app = getApp()
|
||||
|
@ -47,7 +47,7 @@ describe("apiWrapper", () => {
|
|||
}
|
||||
|
||||
const runThrowExAsync = async (arg1, arg2) => {
|
||||
const throwEx = async (x, y) => {
|
||||
const throwEx = async () => {
|
||||
throw new Error("test error")
|
||||
}
|
||||
const app = getApp()
|
||||
|
|
|
@ -33,7 +33,7 @@ describe("authApi > authenticate", () => {
|
|||
})
|
||||
|
||||
it("should return null when non existing user", async () => {
|
||||
const { authApi, app } = await setupApphierarchy(
|
||||
const { authApi } = await setupApphierarchy(
|
||||
basicAppHierarchyCreator_WithFields
|
||||
)
|
||||
const result = await authApi.authenticate("nobody", "password")
|
||||
|
|
|
@ -31,7 +31,7 @@ describe("recordApi > files", () => {
|
|||
const { recordApi } = await setupApphierarchy(
|
||||
basicAppHierarchyCreator_WithFields
|
||||
)
|
||||
const { file, stream, content } = getFile()
|
||||
const { file, stream } = getFile()
|
||||
file.size = file.size - 1
|
||||
const record = recordApi.getNew("/customers", "customer")
|
||||
record.surname = "Ledog"
|
||||
|
@ -46,7 +46,7 @@ describe("recordApi > files", () => {
|
|||
const { recordApi } = await setupApphierarchy(
|
||||
basicAppHierarchyCreator_WithFields
|
||||
)
|
||||
const { file, stream, content } = getFile()
|
||||
const { file, stream } = getFile()
|
||||
const record = recordApi.getNew("/customers", "customer")
|
||||
record.surname = "Ledog"
|
||||
record.profilepic = file
|
||||
|
@ -80,7 +80,7 @@ describe("recordApi > files", () => {
|
|||
const { recordApi } = await setupApphierarchy(
|
||||
basicAppHierarchyCreator_WithFields
|
||||
)
|
||||
const { file, stream, content } = getFile()
|
||||
const { file, stream } = getFile()
|
||||
const record = recordApi.getNew("/customers", "customer")
|
||||
record.surname = "Ledog"
|
||||
record.profilepic = file
|
||||
|
@ -98,7 +98,7 @@ describe("recordApi > files", () => {
|
|||
const { recordApi } = await setupApphierarchy(
|
||||
basicAppHierarchyCreator_WithFields
|
||||
)
|
||||
const { file, stream, content } = getFile()
|
||||
const { file, stream } = getFile()
|
||||
const record = recordApi.getNew("/customers", "customer")
|
||||
record.surname = "Ledog"
|
||||
record.profilepic = file
|
||||
|
|
|
@ -4,7 +4,6 @@ import { promisify } from "es6-promisify"
|
|||
import _rimraf from "rimraf"
|
||||
|
||||
const mkdir = promisify(fs.mkdir)
|
||||
const rmdir = promisify(fs.rmdir)
|
||||
const rimraf = promisify(_rimraf)
|
||||
|
||||
const getConfig = async () => {
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
import fs from "fs"
|
||||
import { mkdir } from "fs"
|
||||
import { join } from "path"
|
||||
import { promisify } from "es6-promisify"
|
||||
|
||||
mkdirp = promisify(mkdir)
|
||||
const mkdirp = promisify(mkdir)
|
||||
|
||||
const getConfig = async () => {
|
||||
const config = {
|
||||
|
@ -13,15 +12,13 @@ const getConfig = async () => {
|
|||
memory: {},
|
||||
}
|
||||
|
||||
try {
|
||||
await mkdir("./output")
|
||||
} catch (e) {}
|
||||
await mkdirp("./output")
|
||||
|
||||
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
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ import {
|
|||
} from "@azure/storage-blob"
|
||||
|
||||
export const createFile = ({ containerUrl }) => async (key, content) => {
|
||||
const blobURL = BlobURL.fromContainerURL(containerURL, key)
|
||||
const blobURL = BlobURL.fromContainerURL(containerUrl, key)
|
||||
const blockBlobURL = BlockBlobURL.fromBlobURL(blobURL)
|
||||
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) =>
|
||||
createFile(opts)(path, content)
|
||||
|
||||
export const loadFile = ({ containerUrl }) => async key => {
|
||||
export const loadFile = ({ containerUrl }) => async (key, content) => {
|
||||
const blobURL = BlobURL.fromContainerURL(containerUrl, key)
|
||||
|
||||
const downloadBlockBlobResponse = await blobURL.download(Aborter.none, 0)
|
||||
|
@ -27,8 +27,8 @@ export const loadFile = ({ containerUrl }) => async key => {
|
|||
.toString()
|
||||
}
|
||||
|
||||
export const exists = ({ containerURL }) => async key => {
|
||||
const blobURL = BlobURL.fromContainerURL(containerURL, key)
|
||||
export const exists = ({ containerUrl }) => async key => {
|
||||
const blobURL = BlobURL.fromContainerURL(containerUrl, key)
|
||||
const getPropsResponse = await blobURL.getProperties()
|
||||
return getPropsResponse._response.StatusCode === 200
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ const initialise = opts => {
|
|||
const pipeline = StorageURL.newPipeline(sharedKeyCredential)
|
||||
|
||||
const serviceURL = new ServiceURL(
|
||||
`https://${account}.blob.core.windows.net`,
|
||||
`https://${opts.account}.blob.core.windows.net`,
|
||||
pipeline
|
||||
)
|
||||
|
||||
|
@ -77,6 +77,5 @@ export default opts => {
|
|||
|
||||
datastoreType: "azure-blob-storage",
|
||||
datastoreDescription: "",
|
||||
data,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,5 +24,5 @@ initialise()
|
|||
.then(init => {
|
||||
return tests(init.datastore, init.config)
|
||||
})
|
||||
.then(_ => console.log("done"))
|
||||
.then(() => console.log("done"))
|
||||
.catch(e => console.log(e))
|
||||
|
|
|
@ -1,14 +1,8 @@
|
|||
import { eventsList } from "@budibase/core"
|
||||
import { filter, union, has, map } from "lodash/fp"
|
||||
import records from "./records"
|
||||
|
||||
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")
|
||||
|
||||
export const register = (app, logTimeElapsed, eventNamespaces = []) => {
|
||||
|
|
|
@ -16,7 +16,6 @@ const iterateActions = async (apis, getIterator) => {
|
|||
limit(() => result.action.run(i))
|
||||
)
|
||||
|
||||
let n = 1
|
||||
await Promise.all(runPromises)
|
||||
result = iterator()
|
||||
} catch (e) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { action, iterateActionTimes, iterateCollection } from "./helpers"
|
||||
import { isUndefined, union, takeRight } from "lodash"
|
||||
import { action, iterateActionTimes } from "./helpers"
|
||||
import { isUndefined, union } from "lodash"
|
||||
|
||||
const createClient = (apis, getState) => async i => {
|
||||
const client = apis.recordApi.getNew("/clients", "client")
|
||||
|
@ -20,16 +20,6 @@ const createClient = (apis, getState) => async i => {
|
|||
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 clients = await apis.viewApi.listItems("/clients/default")
|
||||
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 => {
|
||||
const state = {}
|
||||
const getState = () => state
|
||||
|
@ -64,9 +48,6 @@ export default apis => {
|
|||
iterateActionTimes(recordsPerIteration)
|
||||
),
|
||||
|
||||
/*action("Get client", getClient(apis, getState),
|
||||
iterateCollection(() => takeRight(getState().clientKeys, recordsPerIteration))),*/
|
||||
|
||||
action("List Clients", listClients(apis, getState)),
|
||||
]
|
||||
|
||||
|
@ -75,14 +56,6 @@ export default apis => {
|
|||
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
|
||||
|
||||
return () => {
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import { getAppApis, getTemplateApi, setupDatastore } from "@budibase/core"
|
||||
import { action } from "./helpers"
|
||||
|
||||
const addField = templateApi => type => (record, name) => {
|
||||
const field = templateApi.getNewField(type)
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import svelte from "rollup-plugin-svelte"
|
||||
import postcss from "rollup-plugin-postcss"
|
||||
import resolve from "rollup-plugin-node-resolve"
|
||||
import path from "path"
|
||||
|
||||
const postcssOptions = () => ({
|
||||
extensions: [".scss", ".sass"],
|
||||
|
|
|
@ -5,7 +5,7 @@ import livereload from "rollup-plugin-livereload"
|
|||
import { terser } from "rollup-plugin-terser"
|
||||
import json from "rollup-plugin-json"
|
||||
import alias from "rollup-plugin-alias"
|
||||
import postcss from "rollup-plugin-postcss";
|
||||
import postcss from "rollup-plugin-postcss"
|
||||
import path from "path"
|
||||
|
||||
const aliases = {
|
||||
|
|
|
@ -1,28 +1,48 @@
|
|||
<script>
|
||||
import Checkbox from "./Checkbox.svelte";
|
||||
import Label from "../Common/Label.svelte";
|
||||
import Checkbox from "./Checkbox.svelte"
|
||||
import Label from "../Common/Label.svelte"
|
||||
|
||||
export let label = "";
|
||||
export let orientation = "row";
|
||||
export let fullwidth = false;
|
||||
export let onChange = selectedItems => {};
|
||||
export let label = ""
|
||||
export let orientation = "row"
|
||||
export let fullwidth = false
|
||||
export let onChange = selectedItems => {}
|
||||
|
||||
export let items = [];
|
||||
export let items = []
|
||||
|
||||
export let disabled = false;
|
||||
export let alignEnd = false;
|
||||
let selectedItems = [];
|
||||
export let disabled = false
|
||||
export let alignEnd = false
|
||||
let selectedItems = []
|
||||
|
||||
function handleonChange(item) {
|
||||
if (!!item.checked) {
|
||||
item.checked = !item.checked;
|
||||
item.checked = !item.checked
|
||||
} else {
|
||||
item.checked = true;
|
||||
item.checked = true
|
||||
}
|
||||
onChange(items.filter(i => i.checked));
|
||||
onChange(items.filter(i => i.checked))
|
||||
}
|
||||
</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>
|
||||
.checkbox-group {
|
||||
display: flex;
|
||||
|
@ -55,23 +75,3 @@
|
|||
text-align: left;
|
||||
}
|
||||
</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>
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import "./_style.scss";
|
||||
export { default as Checkbox } from "./Checkbox.svelte";
|
||||
export { default as Checkboxgroup } from "./CheckboxGroup.svelte";
|
||||
|
||||
import "./_style.scss"
|
||||
export { default as Checkbox } from "./Checkbox.svelte"
|
||||
export { default as Checkboxgroup } from "./CheckboxGroup.svelte"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
export default class ClassBuilder {
|
||||
constructor(block, defaultIgnoreList) {
|
||||
this.block = `mdc-${block}`;
|
||||
this.defaultIgnoreList = defaultIgnoreList; //will be ignored when building custom classes
|
||||
this.block = `mdc-${block}`
|
||||
this.defaultIgnoreList = defaultIgnoreList //will be ignored when building custom classes
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -10,32 +10,32 @@ export default class ClassBuilder {
|
|||
All are optional
|
||||
*/
|
||||
build(params) {
|
||||
if (!params) return this.block; //return block if nothing passed
|
||||
const { props, elementName } = params;
|
||||
let base = !!elementName ? `${this.block}__${elementName}` : this.block;
|
||||
if (!props) return base;
|
||||
return this._handleProps(base, props);
|
||||
if (!params) return this.block //return block if nothing passed
|
||||
const { props, elementName } = params
|
||||
let base = elementName ? `${this.block}__${elementName}` : this.block
|
||||
if (!props) return base
|
||||
return this._handleProps(base, props)
|
||||
}
|
||||
|
||||
//Easily grab a simple element class
|
||||
elem(elementName) {
|
||||
return this.build({ elementName });
|
||||
return this.build({ elementName })
|
||||
}
|
||||
|
||||
//use if a different base is needed than whats defined by this.block
|
||||
debase(base, elementProps) {
|
||||
if (!elementProps) return base;
|
||||
return this._handleProps(base, elementProps);
|
||||
if (!elementProps) return base
|
||||
return this._handleProps(base, elementProps)
|
||||
}
|
||||
|
||||
//proxies bindProps and checks for which elementProps exist before binding
|
||||
_handleProps(base, elementProps) {
|
||||
let cls = base;
|
||||
const { modifiers, customs, extras } = elementProps;
|
||||
if (!!modifiers) cls += this._bindProps(modifiers, base);
|
||||
if (!!customs) cls += this._bindProps(customs, base, true);
|
||||
if (!!extras) cls += ` ${extras.join(" ")}`;
|
||||
return cls.trim();
|
||||
let cls = base
|
||||
const { modifiers, customs, extras } = elementProps
|
||||
if (modifiers) cls += this._bindProps(modifiers, base)
|
||||
if (customs) cls += this._bindProps(customs, base, true)
|
||||
if (extras) cls += ` ${extras.join(" ")}`
|
||||
return cls.trim()
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -53,22 +53,22 @@ export default class ClassBuilder {
|
|||
!!value &&
|
||||
(!this.defaultIgnoreList || !this.defaultIgnoreList.includes(value))
|
||||
) {
|
||||
let classBase = isCustom ? `bbmd-${base}` : `${base}`;
|
||||
let valueType = typeof value;
|
||||
let classBase = isCustom ? `bbmd-${base}` : `${base}`
|
||||
let valueType = typeof value
|
||||
|
||||
if (valueType == "string" || valueType == "number") {
|
||||
return isCustom
|
||||
? ` ${classBase}--${this._convertCamel(property)}-${value}`
|
||||
: ` ${classBase}--${value}`;
|
||||
: ` ${classBase}--${value}`
|
||||
} else if (valueType == "boolean") {
|
||||
return ` ${classBase}--${this._convertCamel(property)}`;
|
||||
return ` ${classBase}--${this._convertCamel(property)}`
|
||||
}
|
||||
}
|
||||
})
|
||||
.join("");
|
||||
.join("")
|
||||
}
|
||||
|
||||
_convertCamel(str) {
|
||||
return str.replace(/[A-Z]/g, match => `-${match.toLowerCase()}`);
|
||||
return str.replace(/[A-Z]/g, match => `-${match.toLowerCase()}`)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,32 +1,32 @@
|
|||
<script>
|
||||
import "@material/form-field/mdc-form-field.scss";
|
||||
import ClassBuilder from "../ClassBuilder.js";
|
||||
import { fieldStore } from "./FormfieldStore.js";
|
||||
import { MDCFormField } from "@material/form-field";
|
||||
import { onMount, onDestroy, setContext } from "svelte";
|
||||
import "@material/form-field/mdc-form-field.scss"
|
||||
import ClassBuilder from "../ClassBuilder.js"
|
||||
import { fieldStore } from "./FormfieldStore.js"
|
||||
import { MDCFormField } from "@material/form-field"
|
||||
import { onMount, onDestroy, setContext } from "svelte"
|
||||
|
||||
const cb = new ClassBuilder("form-field");
|
||||
const cb = new ClassBuilder("form-field")
|
||||
|
||||
let store;
|
||||
const unsubscribe = fieldStore.subscribe(s => (store = s));
|
||||
let store
|
||||
const unsubscribe = fieldStore.subscribe(s => (store = s))
|
||||
|
||||
export let id = "";
|
||||
export let label = "";
|
||||
export let alignEnd = false;
|
||||
export let id = ""
|
||||
export let label = ""
|
||||
export let alignEnd = false
|
||||
|
||||
let formField = null;
|
||||
let formField = null
|
||||
|
||||
let modifiers = { alignEnd };
|
||||
let props = { modifiers };
|
||||
let modifiers = { alignEnd }
|
||||
let props = { modifiers }
|
||||
|
||||
let blockClasses = cb.build({ props });
|
||||
let blockClasses = cb.build({ props })
|
||||
|
||||
onMount(() => {
|
||||
if (!!formField) fieldStore.set(new MDCFormField(formField));
|
||||
setContext("BBMD:field-element", fieldStore);
|
||||
});
|
||||
if (!!formField) fieldStore.set(new MDCFormField(formField))
|
||||
setContext("BBMD:field-element", fieldStore)
|
||||
})
|
||||
|
||||
onDestroy(unsubscribe);
|
||||
onDestroy(unsubscribe)
|
||||
</script>
|
||||
|
||||
<div bind:this={formField} class={blockClasses}>
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
import { writable } from "svelte/store";
|
||||
import { writable } from "svelte/store"
|
||||
|
||||
function store() {
|
||||
const { set, update, subscribe } = writable({});
|
||||
const { set, update, subscribe } = writable({})
|
||||
|
||||
function setInput(inp) {
|
||||
update(n => {
|
||||
n.input = inp;
|
||||
});
|
||||
n.input = inp
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
subscribe,
|
||||
set,
|
||||
setInput
|
||||
};
|
||||
setInput,
|
||||
}
|
||||
}
|
||||
|
||||
export const fieldStore = store();
|
||||
export const fieldStore = store()
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
<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
|
||||
? `material-icons mdc-${iconContext}__icon`
|
||||
: "material-icons";
|
||||
: "material-icons"
|
||||
</script>
|
||||
|
||||
<i class={cls}>{icon}</i>
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
<script>
|
||||
export let bold = false;
|
||||
export let text = "";
|
||||
export let bold = false
|
||||
export let text = ""
|
||||
</script>
|
||||
|
||||
<span class="mdc-typography" class:bold>{text}</span>
|
||||
|
||||
<style>
|
||||
.bold {
|
||||
font-weight: 500;
|
||||
}
|
||||
</style>
|
||||
|
||||
<span class="mdc-typography" class:bold>{text}</span>
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
let tableElement
|
||||
let initialied = false
|
||||
|
||||
|
||||
|
||||
$: {
|
||||
if (tableElement && datatable && !initialied) {
|
||||
const children = _bb.attachChildren(tableElement)
|
||||
|
@ -43,7 +41,8 @@
|
|||
</script>
|
||||
|
||||
<div bind:this={datatable} class={cb.build()}>
|
||||
<table class={cb.elem`table`} aria-label="Material Design Datatable" bind:this={tableElement}>
|
||||
|
||||
</table>
|
||||
<table
|
||||
class={cb.elem`table`}
|
||||
aria-label="Material Design Datatable"
|
||||
bind:this={tableElement} />
|
||||
</div>
|
||||
|
|
|
@ -8,7 +8,6 @@ const cb = _bb.getContext("BBMD:data-table:cb")
|
|||
let tbody
|
||||
|
||||
$: tbody && _bb.attachChildren(tbody)
|
||||
|
||||
</script>
|
||||
|
||||
<tbody bind:this={tbody} class={cb.elem`content`}></tbody>
|
||||
<tbody bind:this={tbody} class={cb.elem`content`} />
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
let element
|
||||
|
||||
$: element && _bb.attachChildren(element)
|
||||
|
||||
</script>
|
||||
|
||||
{#if isHeader}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
<script>
|
||||
|
||||
export let _bb
|
||||
|
||||
const cb = _bb.getContext("BBMD:data-table:cb")
|
||||
|
@ -7,7 +6,6 @@ const cb = _bb.getContext("BBMD:data-table:cb")
|
|||
let thead
|
||||
|
||||
$: thead && _bb.attachChildren(thead)
|
||||
|
||||
</script>
|
||||
|
||||
<thead bind:this={thead} class=className></thead>
|
||||
<thead bind:this={thead} class="className" />
|
||||
|
|
|
@ -1,27 +1,27 @@
|
|||
<script>
|
||||
import { getContext } from "svelte";
|
||||
import { getContext } from "svelte"
|
||||
|
||||
export let onSelect = () => {};
|
||||
export let isHeader = false;
|
||||
export let onSelect = () => {}
|
||||
export let isHeader = false
|
||||
|
||||
export let _bb
|
||||
|
||||
let row = null;
|
||||
let selected = false;
|
||||
let row = null
|
||||
let selected = false
|
||||
|
||||
const cb = _bb.getContext("BBMD:data-table:cb")
|
||||
|
||||
let elementName = isHeader ? "header-row" : "row";
|
||||
let modifiers = {};
|
||||
let elementName = isHeader ? "header-row" : "row"
|
||||
let modifiers = {}
|
||||
|
||||
$: modifiers = { selected };
|
||||
$: props = { modifiers };
|
||||
$: rowClass = cb.build({ elementName, props });
|
||||
$: modifiers = { selected }
|
||||
$: props = { modifiers }
|
||||
$: rowClass = cb.build({ elementName, props })
|
||||
$: row && _bb.attachChildren(row)
|
||||
|
||||
function rowSelected() {
|
||||
selected = !selected;
|
||||
onSelect();
|
||||
selected = !selected
|
||||
onSelect()
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
|
@ -1,79 +1,71 @@
|
|||
<script>
|
||||
import { onMount, getContext } from "svelte";
|
||||
import { MDCList } from "@material/list";
|
||||
import { MDCRipple } from "@material/ripple";
|
||||
import ListItem from "./ListItem.svelte";
|
||||
import ClassBuilder from "../ClassBuilder.js";
|
||||
import { onMount, getContext } from "svelte"
|
||||
import { MDCList } from "@material/list"
|
||||
import { MDCRipple } from "@material/ripple"
|
||||
import ListItem from "./ListItem.svelte"
|
||||
import ClassBuilder from "../ClassBuilder.js"
|
||||
|
||||
const cb = new ClassBuilder("list", ["one-line"]);
|
||||
export let _bb
|
||||
const cb = new ClassBuilder("list", ["one-line"])
|
||||
|
||||
let list = null;
|
||||
let instance = null;
|
||||
let list = null
|
||||
let instance = null
|
||||
|
||||
export let onSelect = selectedItems => {};
|
||||
export let onSelect = selectedItems => {}
|
||||
|
||||
export let variant = "one-line";
|
||||
export let variant = "one-line"
|
||||
//items: [{text: string | {primary: string, secondary: string}, value: any, selected: bool}...n]
|
||||
export let items = [];
|
||||
export let singleSelection = false;
|
||||
export let inputElement = null;
|
||||
export let items = []
|
||||
export let singleSelection = false
|
||||
export let inputElement = null
|
||||
|
||||
let role = "listbox";
|
||||
let role = "listbox"
|
||||
|
||||
onMount(() => {
|
||||
if (!!list) {
|
||||
instance = new MDCList(list);
|
||||
instance.singleSelection = singleSelection;
|
||||
instance.listElements.map(element => new MDCRipple(element));
|
||||
instance = new MDCList(list)
|
||||
instance.singleSelection = singleSelection
|
||||
instance.listElements.map(element => new MDCRipple(element))
|
||||
}
|
||||
|
||||
let context = getContext("BBMD:list:context");
|
||||
let context = getContext("BBMD:list:context")
|
||||
if (context === "menu") {
|
||||
role = "menu";
|
||||
role = "menu"
|
||||
}
|
||||
|
||||
return () => {
|
||||
instance && instance.destroy();
|
||||
instance = null;
|
||||
};
|
||||
});
|
||||
instance && instance.destroy()
|
||||
instance = null
|
||||
}
|
||||
})
|
||||
|
||||
function handleSelectedItem(item) {
|
||||
if (!item.disabled) {
|
||||
if (singleSelection || inputElement === "radiobutton") {
|
||||
items.forEach(i => {
|
||||
if (i.selected) i.selected = false;
|
||||
});
|
||||
if (i.selected) i.selected = false
|
||||
})
|
||||
}
|
||||
|
||||
let idx = items.indexOf(item);
|
||||
let idx = items.indexOf(item)
|
||||
if (!!item.selected) {
|
||||
items[idx].selected = !item.selected;
|
||||
items[idx].selected = !item.selected
|
||||
} else {
|
||||
items[idx].selected = true;
|
||||
items[idx].selected = true
|
||||
}
|
||||
onSelect(items.filter(item => item.selected));
|
||||
onSelect(items.filter(item => item.selected))
|
||||
}
|
||||
}
|
||||
|
||||
$: useDoubleLine =
|
||||
variant == "two-line" &&
|
||||
items.every(i => typeof i.text == "object" && "primary" in i.text);
|
||||
items.every(i => typeof i.text == "object" && "primary" in i.text)
|
||||
|
||||
$: modifiers = { variant };
|
||||
$: props = { modifiers };
|
||||
$: listClass = cb.build({ props });
|
||||
$: list && _bb.attachChildren(list)
|
||||
|
||||
$: modifiers = { variant }
|
||||
$: props = { modifiers }
|
||||
$: listClass = cb.build({ props })
|
||||
</script>
|
||||
|
||||
<ul class={listClass} {role}>
|
||||
{#each items as item, i}
|
||||
<ListItem
|
||||
{item}
|
||||
{useDoubleLine}
|
||||
{inputElement}
|
||||
onClick={() => handleSelectedItem(item)} />
|
||||
{#if item.divider}
|
||||
<li role="separator" class="mdc-list-divider" />
|
||||
{/if}
|
||||
{/each}
|
||||
</ul>
|
||||
<ul bind:this={list} class={listClass} {role} />
|
||||
|
|
|
@ -1,71 +1,73 @@
|
|||
<script>
|
||||
import { onMount, getContext } from "svelte";
|
||||
import { Radiobutton } from "../Radiobutton";
|
||||
import { Checkbox } from "../Checkbox";
|
||||
import ClassBuilder from "../ClassBuilder.js";
|
||||
import { onMount, getContext } from "svelte"
|
||||
import { Radiobutton } from "../Radiobutton"
|
||||
import { Checkbox } from "../Checkbox"
|
||||
import ClassBuilder from "../ClassBuilder.js"
|
||||
|
||||
const cb = new ClassBuilder("list-item");
|
||||
const cb = new ClassBuilder("list-item")
|
||||
|
||||
export let onClick = item => {};
|
||||
export let onClick = item => {}
|
||||
|
||||
export let item = null;
|
||||
export let useDoubleLine = false;
|
||||
export let inputElement = null; //radiobutton or checkbox
|
||||
export let text = ""
|
||||
export let secondaryText = ""
|
||||
export let variant = "two-line"
|
||||
export let inputElement = null
|
||||
export let leadingIcon = ""
|
||||
export let trailingIcon = ""
|
||||
export let selected = false
|
||||
export let disabled = false
|
||||
|
||||
let role = "option";
|
||||
let role = "option"
|
||||
|
||||
onMount(() => {
|
||||
let context = getContext("BBMD:list:context");
|
||||
let context = getContext("BBMD:list:context")
|
||||
if (context === "menu") {
|
||||
role = "menuitem";
|
||||
role = "menuitem"
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
$: if (!!inputElement) {
|
||||
setContext("BBMD:input:context", "list-item");
|
||||
setContext("BBMD:input:context", "list-item")
|
||||
}
|
||||
|
||||
$: modifiers = {
|
||||
selected: !inputElement ? item.selected : null,
|
||||
disabled: item.disabled
|
||||
};
|
||||
$: props = { modifiers };
|
||||
$: listItemClass = cb.build({ props });
|
||||
selected,
|
||||
disabled,
|
||||
}
|
||||
$: props = { modifiers }
|
||||
$: listItemClass = cb.build({ props })
|
||||
|
||||
$: useSecondaryText =
|
||||
typeof item.text === "object" && "secondary" in item.text;
|
||||
$: useTwoLine = variant === "two-line" && !!secondaryText
|
||||
</script>
|
||||
|
||||
<li
|
||||
class={listItemClass}
|
||||
role="option"
|
||||
aria-selected={item.selected}
|
||||
aria-selected={selected}
|
||||
tabindex="0"
|
||||
on:click={onClick}>
|
||||
{#if item.leadingIcon}
|
||||
{#if leadingIcon}
|
||||
<span class="mdc-list-item__graphic material-icons" aria-hidden="true">
|
||||
{item.leadingIcon}
|
||||
{leadingIcon}
|
||||
</span>
|
||||
{/if}
|
||||
<span class={cb.elem`text`}>
|
||||
{#if useDoubleLine}
|
||||
<span class={cb.elem`primary-text`}>{item.text.primary}</span>
|
||||
{#if useSecondaryText}
|
||||
<span class={cb.elem`secondary-text`}>{item.text.secondary}</span>
|
||||
{/if}
|
||||
{:else}{item.text}{/if}
|
||||
{#if useTwoLine}
|
||||
<span class={cb.elem`primary-text`}>{text}</span>
|
||||
<span class={cb.elem`secondary-text`}>{secondaryText}</span>
|
||||
{:else}{text}{/if}
|
||||
</span>
|
||||
|
||||
{#if inputElement}
|
||||
{#if inputElement === 'radiobutton'}
|
||||
<Radiobutton checked={item.selected} disabled={item.disabled} />
|
||||
<Radiobutton checked={selected} {disabled} />
|
||||
{:else if inputElement === 'checkbox'}
|
||||
<Checkbox checked={item.selected} disabled={item.disabled} />
|
||||
<Checkbox checked={selected} {disabled} />
|
||||
{/if}
|
||||
{:else if item.trailingIcon}
|
||||
{:else if trailingIcon}
|
||||
<!-- TODO: Adapt label to accept class prop to handle this. Context is insufficient -->
|
||||
<span class="mdc-list-item__meta material-icons" aria-hidden="true">
|
||||
{item.trailingIcon}
|
||||
{trailingIcon}
|
||||
</span>
|
||||
{/if}
|
||||
</li>
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
import "./_style.scss";
|
||||
export { default as List } from "./List.svelte";
|
||||
import "./_style.scss"
|
||||
export { default as List } from "./List.svelte"
|
||||
export { default as ListItem } from "./ListItem.svelte"
|
||||
|
|
|
@ -1,32 +1,32 @@
|
|||
<script>
|
||||
import { List } from "../List";
|
||||
import { MDCMenu } from "@material/menu";
|
||||
import { onMount, setContext } from "svelte";
|
||||
export let items = [];
|
||||
export let singleSelection = true;
|
||||
export let width = "400px";
|
||||
export let open = true;
|
||||
export let useFixedPosition = false;
|
||||
export let useAbsolutePosition = false;
|
||||
import { List } from "../List"
|
||||
import { MDCMenu } from "@material/menu"
|
||||
import { onMount, setContext } from "svelte"
|
||||
export let items = []
|
||||
export let singleSelection = true
|
||||
export let width = "400px"
|
||||
export let open = true
|
||||
export let useFixedPosition = false
|
||||
export let useAbsolutePosition = false
|
||||
//{x: number, y: number}
|
||||
export let absolutePositionCoords = null;
|
||||
export let absolutePositionCoords = null
|
||||
|
||||
let menu = null;
|
||||
let instance = null;
|
||||
let menu = null
|
||||
let instance = null
|
||||
|
||||
onMount(() => {
|
||||
if (!!menu) {
|
||||
instance = new MDCMenu(menu);
|
||||
instance.open = open;
|
||||
instance = new MDCMenu(menu)
|
||||
instance.open = open
|
||||
if (useFixedPosition) {
|
||||
instance.setFixedPosition(true);
|
||||
instance.setFixedPosition(true)
|
||||
} else if (useAbsolutePosition) {
|
||||
let { x, y } = absolutePositionCoords;
|
||||
instance.setAbsolutePosition(x | 0, y | 0);
|
||||
let { x, y } = absolutePositionCoords
|
||||
instance.setAbsolutePosition(x | 0, y | 0)
|
||||
}
|
||||
}
|
||||
setContext("BBMD:list:context", "menu");
|
||||
});
|
||||
setContext("BBMD:list:context", "menu")
|
||||
})
|
||||
</script>
|
||||
|
||||
{#if useFixedPosition || useAbsolutePosition}
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
import "./_styles.scss";
|
||||
export { default as Menu } from "./Menu.svelte";
|
||||
import "./_styles.scss"
|
||||
export { default as Menu } from "./Menu.svelte"
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
import "./_style.scss";
|
||||
export { default as Radiobutton } from "./Radiobutton.svelte";
|
||||
export { default as Radiobuttongroup } from "./RadiobuttonGroup.svelte";
|
||||
import "./_style.scss"
|
||||
export { default as Radiobutton } from "./Radiobutton.svelte"
|
||||
export { default as Radiobuttongroup } from "./RadiobuttonGroup.svelte"
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
Datatable,
|
||||
CustomersIndexTable,
|
||||
List,
|
||||
Icon,
|
||||
} = props
|
||||
|
||||
let currentComponent
|
||||
|
@ -35,6 +36,7 @@
|
|||
Checkboxgroup,
|
||||
Radiobutton,
|
||||
Radiobuttongroup,
|
||||
Icon,
|
||||
Datatable,
|
||||
CustomersIndexTable,
|
||||
List,
|
||||
|
|
|
@ -4,7 +4,7 @@ import packageJson from "../../package.json"
|
|||
import { rootComponent } from "./rootComponent"
|
||||
import * as standardcomponents from "@budibase/standard-components/src/index"
|
||||
|
||||
export default async props => {
|
||||
export default async () => {
|
||||
delete components._lib
|
||||
const componentLibraries = {}
|
||||
componentLibraries[packageJson.name] = components
|
||||
|
|
|
@ -117,22 +117,39 @@ export const props = {
|
|||
CustomersIndexTable: indexDatatable(templateOptions)[0].props,
|
||||
List: {
|
||||
_component: "@budibase/materialdesign-components/List",
|
||||
_children: [
|
||||
{
|
||||
_component: "@budibase/materialdesign-components/ListItem",
|
||||
_children: [],
|
||||
variant: "two-line",
|
||||
singleSelection: true,
|
||||
items: [
|
||||
{
|
||||
text: { primary: "Curry", secondary: "Chicken or Beef" },
|
||||
text: "Curry",
|
||||
secondaryText: "Chicken or Beef",
|
||||
value: 0,
|
||||
divider: true,
|
||||
},
|
||||
{
|
||||
text: { primary: "Pastie", secondary: "Bap with Mayo" },
|
||||
_component: "@budibase/materialdesign-components/ListItem",
|
||||
_children: [],
|
||||
variant: "two-line",
|
||||
singleSelection: true,
|
||||
text: "Pastie",
|
||||
secondaryText: "Bap with Mayo",
|
||||
value: 1,
|
||||
disabled: true,
|
||||
},
|
||||
{ text: { primary: "Fish", secondary: "Salmon or Cod" }, value: 2 },
|
||||
{
|
||||
_component: "@budibase/materialdesign-components/ListItem",
|
||||
_children: [],
|
||||
variant: "two-line",
|
||||
singleSelection: true,
|
||||
text: "Fish",
|
||||
secondaryText: "Salmon or Cod",
|
||||
value: 2,
|
||||
},
|
||||
],
|
||||
variant: "two-line",
|
||||
singleSelection: true,
|
||||
onSelect: selected => console.log(selected),
|
||||
},
|
||||
}
|
||||
|
|
|
@ -68,7 +68,7 @@
|
|||
}
|
||||
|
||||
let useLabel = !!label && (!fullwidth || (fullwidth && textarea))
|
||||
let useIcon = !!icon && (!textarea && !fullwidth)
|
||||
let useIcon = !!icon && !textarea && !fullwidth
|
||||
|
||||
if (useIcon) {
|
||||
setContext("BBMD:icon:context", "text-field")
|
||||
|
@ -120,7 +120,7 @@ TODO:Needs error handling - this will depend on how Budibase handles errors
|
|||
{placeholder}
|
||||
{minLength}
|
||||
maxLength={safeMaxLength}
|
||||
value={value}
|
||||
{value}
|
||||
on:change={changed} />
|
||||
{:else}
|
||||
{#if renderLeadingIcon}
|
||||
|
@ -135,7 +135,7 @@ TODO:Needs error handling - this will depend on how Budibase handles errors
|
|||
placeholder={!!label && fullwidth ? label : placeholder}
|
||||
{minLength}
|
||||
maxLength={safeMaxLength}
|
||||
value={value}
|
||||
{value}
|
||||
aria-label={`Textfield ${variant}`}
|
||||
on:focus={focus}
|
||||
on:input={changed} />
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
import "./_style.scss";
|
||||
export { default as Body1 } from "./Body1.svelte";
|
||||
export { default as Body2 } from "./Body2.svelte";
|
||||
export { default as Caption } from "./Caption.svelte";
|
||||
export { default as H1 } from "./H1.svelte";
|
||||
export { default as H2 } from "./H2.svelte";
|
||||
export { default as H3 } from "./H3.svelte";
|
||||
export { default as H4 } from "./H4.svelte";
|
||||
export { default as H5 } from "./H5.svelte";
|
||||
export { default as H6 } from "./H6.svelte";
|
||||
export { default as Overline } from "./Overline.svelte";
|
||||
export { default as Sub1 } from "./Sub1.svelte";
|
||||
export { default as Sub2 } from "./Sub2.svelte";
|
||||
import "./_style.scss"
|
||||
export { default as Body1 } from "./Body1.svelte"
|
||||
export { default as Body2 } from "./Body2.svelte"
|
||||
export { default as Caption } from "./Caption.svelte"
|
||||
export { default as H1 } from "./H1.svelte"
|
||||
export { default as H2 } from "./H2.svelte"
|
||||
export { default as H3 } from "./H3.svelte"
|
||||
export { default as H4 } from "./H4.svelte"
|
||||
export { default as H5 } from "./H5.svelte"
|
||||
export { default as H6 } from "./H6.svelte"
|
||||
export { default as Overline } from "./Overline.svelte"
|
||||
export { default as Sub1 } from "./Sub1.svelte"
|
||||
export { default as Sub2 } from "./Sub2.svelte"
|
||||
|
|
|
@ -16,4 +16,4 @@ export {
|
|||
} from "./Datatable"
|
||||
export { default as indexDatatable } from "./Templates/indexDatatable"
|
||||
export { default as recordForm } from "./Templates/recordForm"
|
||||
export { List } from "./List"
|
||||
export { List, ListItem } from "./List"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
const fs = require("fs")
|
||||
|
||||
module.exports = config => ({
|
||||
module.exports = () => ({
|
||||
main: {
|
||||
outputToFile: async ({ filename, content }) => {
|
||||
await new Promise((resolve, reject) => {
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
|
@ -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'}
|
|
@ -11,26 +11,21 @@
|
|||
html, body {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
<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='/_master/clientFrontendDefinition.js'></script>
|
||||
<script src='/_master/clientBackendDefinition.js'></script>
|
||||
<script src='/clientFrontendDefinition.js'></script>
|
||||
<script src='/clientBackendDefinition.js'></script>
|
||||
<script src='/budibase-client.js'></script>
|
||||
<script>
|
||||
loadBudibase();
|
||||
|
|
|
@ -1 +1 @@
|
|||
module.exports = config => ({})
|
||||
module.exports = () => ({})
|
||||
|
|
|
@ -4,7 +4,6 @@ const { applictionVersionPackage } = require("../utilities/createAppPackage")
|
|||
const { determineVersionId } = require("../utilities/runtimePackages")
|
||||
|
||||
module.exports = async (context, datastoreModule, app, instance) => {
|
||||
try {
|
||||
const databaseManager = getDatabaseManager(
|
||||
datastoreModule,
|
||||
context.config.datastoreConfig
|
||||
|
@ -35,7 +34,4 @@ module.exports = async (context, datastoreModule, app, instance) => {
|
|||
)
|
||||
|
||||
return dbConfig
|
||||
} catch (e) {
|
||||
throw e
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,6 @@ const masterDbAccessLevels = require("../appPackages/_master/access_levels.json"
|
|||
const { masterAppPackage } = require("../utilities/createAppPackage")
|
||||
|
||||
module.exports = async (context, datastoreModule, username, password) => {
|
||||
try {
|
||||
const { config } = context
|
||||
const databaseManager = getDatabaseManager(
|
||||
datastoreModule,
|
||||
|
@ -19,9 +18,7 @@ module.exports = async (context, datastoreModule, username, password) => {
|
|||
|
||||
await databaseManager.createEmptyMasterDb()
|
||||
const masterDbConfig = databaseManager.masterDatastoreConfig
|
||||
const datastore = setupDatastore(
|
||||
datastoreModule.getDatastore(masterDbConfig)
|
||||
)
|
||||
const datastore = setupDatastore(datastoreModule.getDatastore(masterDbConfig))
|
||||
|
||||
await initialiseData(datastore, constructHierarchy(masterDbAppDefinition))
|
||||
|
||||
|
@ -34,7 +31,4 @@ module.exports = async (context, datastoreModule, username, password) => {
|
|||
await bbMaster.authApi.createUser(user, password)
|
||||
|
||||
return await getApisForUser(datastore, masterPackage, username, password)
|
||||
} catch (e) {
|
||||
throw e
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,9 @@ const copyfolder = (source, destination) =>
|
|||
})
|
||||
})
|
||||
|
||||
module.exports = async (context, bbMaster, latestAppsFolder) => {
|
||||
exports.copyfolder = copyfolder
|
||||
|
||||
module.exports = async context => {
|
||||
// create runtime folder
|
||||
// copy master into /master/latest
|
||||
if (await pathExists(runtimePackagesDirectory)) {
|
||||
|
@ -26,16 +28,6 @@ module.exports = async (context, bbMaster, latestAppsFolder) => {
|
|||
|
||||
await mkdir(runtimePackagesDirectory)
|
||||
|
||||
/*
|
||||
const allApps = await bbMaster
|
||||
.indexApi
|
||||
.listItems("/all_applications");
|
||||
|
||||
for(let app of allApps) {
|
||||
app.
|
||||
}
|
||||
*/
|
||||
|
||||
const apps = {
|
||||
_master: masterAppPackage(context),
|
||||
}
|
||||
|
|
|
@ -141,7 +141,11 @@ module.exports = (config, app) => {
|
|||
})
|
||||
.get("/_builder/api/:appname/components", async ctx => {
|
||||
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
|
||||
} catch (e) {
|
||||
if (e.status) {
|
||||
|
|
|
@ -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) */,
|
||||
renew: false /** (boolean) renew session when session is nearly expired, so we can always keep user logged in. (default is false)*/,
|
||||
store: {
|
||||
get: async (key, maxAge, { rolling }) => ({ key }),
|
||||
set: async (key, sess, maxAge, { rolling, changed }) => ({ key }),
|
||||
destroy: async key => ({}),
|
||||
get: async key => ({ key }),
|
||||
set: async key => ({ key }),
|
||||
destroy: async () => ({}),
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@ beforeAll(async () => {
|
|||
|
||||
await app.start()
|
||||
})
|
||||
|
||||
afterAll(async () => await app.destroy())
|
||||
|
||||
it("/apppackage should get appDefinition", async () => {
|
||||
|
|
|
@ -1,14 +1,9 @@
|
|||
const statusCodes = require("../utilities/statusCodes")
|
||||
const constructHierarchy = require("../utilities/constructHierarchy")
|
||||
const { readFile } = require("fs-extra")
|
||||
const { hierarchy } = require("@budibase/core")
|
||||
const { take } = require("lodash/fp")
|
||||
const masterAppDefinition = constructHierarchy(
|
||||
require("../appPackages/_master/appDefinition.json")
|
||||
)
|
||||
constructHierarchy(require("../appPackages/_master/appDefinition.json"))
|
||||
const { getApisWithFullAccess } = require("../utilities/budibaseApi")
|
||||
const { createTarGzPackage } = require("../utilities/targzAppPackage")
|
||||
const { timeout } = require("./helpers")
|
||||
|
||||
module.exports = app => {
|
||||
let _master
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue