backup before an f-up

This commit is contained in:
Michael Shanks 2019-10-18 17:32:03 +01:00
parent 6f83fd19a3
commit 92dcf4b2b8
90 changed files with 5983 additions and 2074 deletions

View File

@ -10,21 +10,13 @@
"name": "Forms",
"description": "Generate forms, based on your records"
},
"buttons": {
"name": "Buttons",
"description": "Generate some styled buttons"
},
"headers": {
"name": "Headers",
"description": "Generate some styled headings"
},
"nav": {
"name": "Nav bar",
"description": "Generate a nav bar, based n your root records"
},
"indexTables": {
"name": "Nav bar",
"name": "Index Tables",
"description": "Generate a table based on an index"
},
"recordHomepages": {
"name": "Record Homepage",
"description": "Generates a 'homepage' based on your record types, including a create/edit form. Selecting a nav item will display a root content"
}
},
"form" : {
@ -53,14 +45,6 @@
"name": "Nav",
"description": "A nav - a side bar of buttons that control the currently active component",
"props" : {
"navBarBackground": {"type" :"string", "default":"silver"},
"navBarBorder": "string",
"navBarColor": {"type" :"string", "default":"black"},
"selectedItemBackground": {"type" :"string", "default":"white"},
"selectedItemColor": {"type" :"string", "default":"black"},
"selectedItemBorder": "string",
"itemHoverBackground": {"type" :"string", "default":"gainsboro"},
"itemHoverColor": {"type" :"string", "default":"black"},
"items": {
"type": "array",
"elementDefinition" : {
@ -69,6 +53,10 @@
}
},
"selectedItem":"string",
"pills":"bool",
"orientation":{"type":"options", "options": ["horizontal", "vertical"]},
"alignment":{"type":"options", "options": ["start", "center", "end"]},
"fill":"bool",
"hideNavBar":"bool"
},

File diff suppressed because one or more lines are too long

View File

@ -4,7 +4,7 @@ export let items = [];
export let hideNavBar=false;
export let selectedItem="";
export let orientation="horizontal"; // horizontal, verical
export let alignment="left"; // start, center, end
export let alignment="start"; // start, center, end
export let pills=false;
export let fill=false;
export let _bb;
@ -12,13 +12,20 @@ export let _bb;
let selectedIndex = -1;
let styleVars={};
let components = {};
let componentElements = {}
let componentElement;
let orientationClass="";
let navClasses="";
let currentComponent;
let _selectedItem="";
const hasComponentElements = () =>
Object.getOwnPropertyNames(componentElements).length > 0;
const getSelectedItemByIndex = (index) =>
index >= 0
? items[index].title
: "";
$: {
let _navClasses = "";
@ -37,30 +44,54 @@ $: {
navClasses = _navClasses;
if(items && items.length > 0 && hasComponentElements()) {
const currentSelectedItem = selectedIndex > 0
? items[selectedIndex].title
: "";
if(items ) {
const currentSelectedItem = getSelectedItemByIndex(selectedIndex);
if(selectedItem && currentSelectedItem !== selectedItem) {
let i=0;
for(let item of items) {
if(item.title === selectedItem) {
onSelectItem(i)();
SelectItem(i);
}
i++;
}
} else if(!currentSelectedItem) {
onSelectItem(0);
} else if(!selectedItem) {
SelectItem(-1);
}
}
}
const onSelectItem = (index) => () => {
const SelectItem = (index) => {
selectedIndex = index;
if(!components[index]) {
const comp = _bb.hydrateComponent(
items[index].component, componentElements[index]);
components[index] = comp;
const newSelectedItem = getSelectedItemByIndex(index);
if(newSelectedItem !== selectedItem) {
selectedItem = newSelectedItem;
}
if(currentComponent) {
try {
currentComponent.$destroy();
} catch(_) {}
}
if(index >= 0)
currentComponent = _bb.hydrateComponent(
items[index].component, componentElement);
}
const onSelectItemClicked = index => () => {
if(_bb.bindings["selectedItem"]) {
// binding - call state, which should SelectItem(..)
const selectedItemBinding = _bb.bindings["selectedItem"];
_bb.setStateFromBinding(
selectedItemBinding, getSelectedItemByIndex(index))
} else {
// no binding - call this
SelectItem(index);
}
}
@ -69,21 +100,22 @@ const onSelectItem = (index) => () => {
<div class="root">
{#if !hideNavBar}
<nav class="nav {navClasses}">
<ul class="nav {navClasses}">
{#each items as navItem, index}
<div class="nav-item"
on:click={onSelectItem(index)}
class:disabled={navItem.disabled}
class:active={selectedIndex === index}>
{navItem.title}
</div>
<li class="nav-item">
<button class="nav-link btn btn-link"
on:click={onSelectItemClicked(index)}
class:disabled={navItem.disabled}
class:active={selectedIndex === index}>
{navItem.title}
</button>
</li>
{/each}
</nav>
</ul>
{/if}
{#each items as navItem, index}
<div class="content"
bind:this={componentElements[index]}>
<div bind:this={componentElement}>
</div>
{/each}
</div>
@ -93,36 +125,8 @@ const onSelectItem = (index) => () => {
.root {
height: 100%;
width:100%;
grid-template-columns: [navbar] auto [content] 1fr;
display: grid;
}
.navbar {
grid-column: navbar;
background: var(--navBarBackground);
border: var(--navBarBorder);
color: var(--navBarColor);
}
.navitem {
padding: 10px 17px;
cursor: pointer;
}
.navitem:hover {
background: var(--itemHoverBackground);
color: var(--itemHoverColor);
}
.navitem.selected {
background: var(--selectedItemBackground);
border: var(--selectedItemBorder);
color: var(--selectedItemColor);
}
.content {
grid-column: content;
}
</style>

View File

@ -1 +1,4 @@
/*export { app } from "./generators/appGenerator";*/
export { forms } from "./generators/formsGenerator";
export { indexTables } from "./generators/indexTablesGenerator";
export { app } from "./generators/appGenerator";
export { recordHomePageComponents as recordHomepages } from "./generators/recordHomePageGenerator";

View File

@ -0,0 +1,36 @@
import { navContentComponentName, selectNavContent } from "./selectedNavContentGenerator";
import { recordHomepages } from "./recordHomePageGenerator";
export const app = ({records, indexes, helpers}) => [
{
name: "Application Root",
inherits: "@budibase/bootstrap-components/nav",
props: {
items: recordHomepages({indexes, records})
.map(navItem),
orientation: "horizontal",
alignment: "start",
fill: false,
pills: true,
selectedItem: {
"##bbstate":"selectedNav",
"##bbstatefallback":`${records[0].name}`,
"##bbsource": "store"
}
}
},
{
name: "Login",
inherits: "@budibase/standard-components/login",
props: {}
},
...selectNavContent({records, indexes, helpers})
]
export const navItem = ({record}) => ({
title: record.collectionName,
component : {
_component: navContentComponentName(record)
}
})

View File

@ -12,7 +12,7 @@ export const buttons = () => [
description: "Bootstrap default button",
inherits: "@budibase/standard-components/button",
props: {
className: "btn"
className: "btn btn-light"
}
}
]

View File

@ -1,19 +1,23 @@
import {headers} from "./headersGenerator";
import {buttons} from "./buttonGenerators";
export const forms = ({records, indexes}) =>
[...headers({records, indexes}),
...records.map(root)];
export const forms = ({records, indexes, helpers}) =>
[
...records.map(root),
...buttons({records, indexes, helpers})
];
export const formName = record => `${record.name}/${record.name} Form`;
const root = record => ({
name: `${record.name} Form`,
name: formName(record),
description: `Control for creating/updating '${record.nodeKey()}' `,
inherits: "@budibase/standard-components/div",
props: {
direction: "vertical",
className:"p-1",
children: [
{
control: {
_component: "@budibase/standard-components/H3",
component: {
_component: "@budibase/standard-components/h3",
text: `Edit ${record.name}`,
}
},
@ -24,51 +28,48 @@ const root = record => ({
})
const form = record => ({
control: {
component: {
_component: "@budibase/standard-components/form",
formControls:
record.fields.map(f => ({
label: f.label,
control: {
_component: "@budibase/standard-components/input",
value: {
"##bbstate":`current${record.name}.${f.name}`,
"##bbsource":"store"
}
}
}))
record.fields.map(f => formControl(record, f))
}
})
const formControl = (record, field) => {
if(field.type === "string" && field.typeOptions.values && values.typeOptions.length > 0) {
if(field.type === "string" && field.typeOptions.values && field.typeOptions.values.length > 0) {
return ({
_component: "@budibase/standard-components/select",
options: field.typeOptions.values.map(v => ({id:v, value:v})),
value: {
"##bbstate":`current${record.name}.${f.name}`,
"##bbsource":"store"
control: {
_component: "@budibase/standard-components/select",
options: field.typeOptions.values.map(v => ({id:v, value:v})),
value: {
"##bbstate":`${record.name}.${field.name}`,
"##bbsource":"store"
},
className: "form-control"
},
className: "form-control"
label: field.label
});
} else {
return ({
_component: "@budibase/standard-components/input",
value: {
"##bbstate":`current${record.name}.${f.name}`,
"##bbsource":"store"
control: {
_component: "@budibase/standard-components/input",
value: {
"##bbstate":`${record.name}.${field.name}`,
"##bbsource":"store"
},
className: "form-control",
type: field.type === "string" ? "text"
: field.type === "datetime" ? "date"
: field.type === "number" ? "number"
: "text"
},
className: "form-control",
type: field.type === "string" ? "text"
: field.type === "datetime" ? "date"
: field.type === "number" ? "number"
: "text"
label: field.label
});
}
}
const saveCancelButtons = (record) => ({
control: {
component: {
_component: "@budibase/standard-components/stackpanel",
direction: "horizontal",
children: [
@ -79,7 +80,14 @@ const saveCancelButtons = (record) => ({
{
"##eventHandlerType": "Save Record",
parameters: {
statePath: `current${record.name}`,
statePath: `${record.name}`,
}
},
{
"##eventHandlerType": "Set State",
parameters: {
path: `isEditing${record.name}`,
value: ""
}
}
]
@ -89,9 +97,10 @@ const saveCancelButtons = (record) => ({
contentText: `Cancel`,
onClick: [
{
"##eventHandlerType": "Save Record",
"##eventHandlerType": "Set State",
parameters: {
statePath: `current${record.name}`,
path: `isEditing${record.name}`,
value: ""
}
}
]
@ -102,9 +111,13 @@ const saveCancelButtons = (record) => ({
const paddedPanelForButton = (button) => ({
control: {
_component: "@budibase/standard-components/panel",
padding: "20px",
component: button
_component: "@budibase/standard-components/div",
className: "btn-group",
children: [
{
component: button
}
]
}
});

View File

@ -3,6 +3,8 @@ import { getRecordPath } from "./getRecordPath";
export const indexTables = ({indexes, helpers}) =>
indexes.map(i => indexTable(i, helpers));
const excludedColumns = ["id", "isNew", "key", "type", "sortKey"];
export const indexTableProps = (index, helpers) => ({
data: {
"##bbstate":index.nodeKey(),
@ -10,7 +12,10 @@ export const indexTableProps = (index, helpers) => ({
},
tableClass: "table table-hover",
theadClass: "thead-dark",
columns: helpers.indexSchema(index).map(column),
columns: helpers
.indexSchema(index)
.filter(c => !excludedColumns.includes(c.name))
.map(column),
onRowClick: [
{
"##eventHandlerType": "Load Record",
@ -36,8 +41,14 @@ export const indexTableProps = (index, helpers) => ({
]
});
export const getIndexTableName = (index) =>
`${getRecordPath}/${index.name} Table`
export const getIndexTableName = (index, record) => {
record = record
|| index.parent().type === "record" ? index.parent() : null;
return (record
? `${getRecordPath(record)}/${index.name} Table`
: `${index.name} Table`);
}
const indexTable = (index, helpers) => ({
name: getIndexTableName(index),

View File

@ -1,27 +0,0 @@
import {indexTables, getIndexTableName} from "./indexTablesGenerator";
export const nav = ({records, indexes, helpers}) => [
{
name: "Application Root",
inherits: "@budibase/bootstrap-components/nav",
props: {
items: indexes
.filter(i => i.parent().type === "root")
.map(navItem),
orientation: "horizontal",
alignment: "center",
fill: true,
pills: false
}
},
...indexTables({records, indexes, helpers})
]
export const navItem = (index) => ({
title: index.name,
component : {
_component: getIndexTableName(index)
}
})

View File

@ -0,0 +1,133 @@
import {
getIndexTableName, indexTables
} from "./indexTablesGenerator";
import {
buttons
} from "./buttonGenerators";
export const recordHomePageComponents = ({indexes, records, helpers}) =>
[
...recordHomepages({indexes, records})
.map(component),
...recordHomepages({indexes, records})
.map(homePageButtons),
...indexTables({indexes, records, helpers}),
...buttons({indexes, buttons, helpers})
]
const findIndexForRecord = (indexes, record) => {
const forRecord = indexes.filter(i => i.allowedRecordNodeIds.includes(record.nodeId));
if(forRecord.length === 0) return;
if(forRecord.length === 1) return forRecord[0];
const noMap = forRecord.filter(i => !i.filter || !i.filter.trim());
if(noMap.length === 0) forRecord[0];
return noMap[0];
}
export const recordHomepages = ({indexes, records}) =>
records.filter(r => r.parent().type === "root")
.map(r =>({
record:r,
index:findIndexForRecord(indexes, r)
}))
.filter(r => r.index);
export const homepageComponentName = (record) =>
`${record.name}/${record.name} homepage`;
const component = ({record, index}) => ({
inherits: "@budibase/standard-components/div",
name: homepageComponentName(record),
props: {
className: "p-3",
children: [
{
component: {
_component: "@budibase/standard-components/h2",
text: record.collectionName
}
},
{
component: {
_component: `${record.name}/homepage buttons`,
}
},
{
component: {
_component: getIndexTableName(index)
}
}
],
onLoad: [
{
"##eventHandlerType": "Set State",
parameters: {
path: `isEditing${record.name}`,
value: ""
}
},
{
"##eventHandlerType": "List Records",
parameters: {
statePath: index.nodeKey(),
indexKey: index.nodeKey()
}
}
]
}
});
const homePageButtons = ({index, record}) => ({
inherits: "@budibase/standard-components/div",
name: `${record.name}/homepage buttons`,
props: {
className: "btn-group",
children: [
{
component: {
_component: "common/Default Button",
contentText: `Create ${record.name}`,
onClick: [
{
"##eventHandlerType": "Get New Record",
parameters: {
statePath: record.name,
collectionKey: `/${record.collectionName}`,
childRecordType: record.name
}
},
{
"##eventHandlerType": "Set State",
parameters: {
path: `isEditing${record.name}`,
value: "true"
}
}
]
}
},
{
component: {
_component: "common/Default Button",
contentText: `Refresh`,
onClick: [
{
"##eventHandlerType": "List Records",
parameters: {
statePath: index.nodeKey(),
indexKey: index.nodeKey()
}
}
]
}
}
]
}
})

View File

@ -1,39 +0,0 @@
import {getIndexTableName} from "./indexTablesGenerator";
export const rootContent = ({indexes, records, helpers}) =>
record.filter(r => r.parent().type === "root")
.map(r =>({
record,
index:findIndexForRecord(indexes, r)
}))
.filter(r => r.index)
.map(component)
const findIndexForRecord = (indexes, record) => {
const forRecord = indexes.filter(i => i.allowedRecordNodeIds.includes(record.nodeId));
if(forRecord.length === 0) return;
if(forRecord.length === 1) return forRecord[0];
const noMap = forRecord.filter(i => !i.filter || !i.filter.trim());
if(noMap.length === 0) forRecord[0];
return noMap[0];
}
const component = (recordAndIndex) => ({
_component: "@budibase/standard-components/div",
className: "p-3",
children: [
{
component: {
_component: "@budibase/standard-components/H2",
text: recordAndIndex.record.collectionName
}
},
{
component: {
_component: getIndexTableName(recordAndIndex.index)
}
}
]
})

View File

@ -0,0 +1,36 @@
import {
recordHomepages,
homepageComponentName,
recordHomePageComponents
} from "./recordHomePageGenerator";
import { formName, forms } from "./formsGenerator";
export const selectNavContent = ({indexes, records, helpers}) =>
[
...recordHomepages({indexes, records})
.map(component),
...recordHomePageComponents({indexes, records, helpers}),
...forms({indexes, records, helpers})
]
export const navContentComponentName = record =>
`${record.name}/${record.name} Nav Content`;
const component = ({record, index}) => ({
inherits: "@budibase/standard-components/if",
description: `the component that gets displayed when the ${record.collectionName} nav is selected`,
name: navContentComponentName(record),
props: {
condition: `$store.isEditing${record.name}`,
thenComponent: {
_component: formName(record)
},
elseComponent: {
_component: homepageComponentName(record)
}
}
});

View File

@ -1,2 +1,3 @@
/*export {default as button} from "./Button.svelte";*/
export {default as form} from "./Form.svelte";
export {default as nav} from "./Nav.svelte";

View File

@ -3,7 +3,7 @@ import {
} from "../../../core/src";
import {
filter, cloneDeep, sortBy,
map, last, keys, concat,
map, last, keys, concat, keyBy,
find, isEmpty, reduce, values
} from "lodash/fp";
import {
@ -124,10 +124,7 @@ const initialise = (store, initial) => async () => {
initial.generators = generatorsArray(pkg.rootComponents.generators);
initial.allComponents = combineComponents(
pkg.derivedComponents, pkg.rootComponents.components);
initial.actions = reduce((arr, action) => {
arr.push(action);
return arr;
})(pkg.appDefinition.actions, []);
initial.actions = values(pkg.appDefinition.actions);
initial.triggers = pkg.appDefinition.triggers;
if(!!initial.hierarchy && !isEmpty(initial.hierarchy)) {
@ -662,7 +659,7 @@ const savePackage = (store, s) => {
const appDefinition = {
hierarchy:s.hierarchy,
triggers:s.triggers,
actions: s.actions,
actions: keyBy("name")(s.actions),
props: {
main: buildPropsHierarchy(s.allComponents, s.pages.main.appBody),
unauthenticated: buildPropsHierarchy(s.allComponents, s.pages.unauthenticated.appBody)

View File

@ -7,6 +7,8 @@ import {
generateSchema
} from "../../../core/src/indexing/indexSchemaCreator";
export { userWithFullAccess } from "../../../core/src/index";
export const pipe = common.$;
export const events = common.eventsList;

View File

@ -1,13 +1,23 @@
import {
eventHandlers
} from "../../../client/src/state/eventHandlers";
import {writable} from "svelte/store";
export {
EVENT_TYPE_MEMBER_NAME
} from "../../../client/src/state/eventHandlers";
import {
createCoreApi
} from "../../../client/src/core";
export const allHandlers = () => {
const handlersObj = eventHandlers({}, {});
export const allHandlers = (appDefinition, user) => {
const coreApi = createCoreApi(appDefinition, user);
appDefinition.hierarchy = coreApi.templateApi.constructHierarchy(appDefinition.hierarchy);
const store = writable({
_bbuser: user
});
const handlersObj = eventHandlers(store, coreApi);
const handlersArray = [];
for(let key in handlersObj) {
handlersArray.push({name:key, ...handlersObj[key]});

View File

@ -24,7 +24,8 @@ store.subscribe(s => {
]);
appDefinition = {
componentLibraries: s.loadLibraryUrls(),
props: buildPropsHierarchy(s.allComponents, s.currentFrontEndItem)
props: buildPropsHierarchy(s.allComponents, s.currentFrontEndItem),
hierarchy: s.hierarchy
};
});

View File

@ -2,20 +2,30 @@
import IconButton from "../common/IconButton.svelte";
import StateBindingControl from "./StateBindingControl.svelte";
import {
find, map, keys, reduce
find, map, keys, reduce, keyBy
} from "lodash/fp";
import { pipe } from "../common/core";
import { pipe, userWithFullAccess } from "../common/core";
import { EVENT_TYPE_MEMBER_NAME, allHandlers } from "../common/eventHandlers";
import { store } from "../builderStore";
export let event;
export let onChanged;
export let onRemoved;
const events = allHandlers();
let events;
let eventType;
let parameters = [];
store.subscribe(s => {
events = allHandlers(
{hierarchy: s.hierarchy},
userWithFullAccess({
hierarchy: s.hierarchy,
actions: keyBy("name")(s.actions)
})
);
});
$: {
if(event) {
eventType = event[EVENT_TYPE_MEMBER_NAME];

View File

@ -117,14 +117,14 @@ const makeBinding = () => {
<div>
<IconButton icon={value == true ? "check-square" : "square"}
size="19"
on:click={() => value = !value}/>
on:click={() => onChanged(!value)}/>
</div>
{:else if type === "options"}
<select class="uk-select uk-form-small"
value={value}
on:change={ev => onChanged(ev.target.checked)}>
on:change={ev => onChanged(ev.target.value)}>
{#each options as option}
<option value={option}>{option}</option>
{/each}

View File

@ -14,6 +14,8 @@ module.exports = (opts) => {
const run = async (opts) => {
const appContext = await getAppContext({configName: opts.config, masterIsCreated:true});
opts.appContext = appContext;
opts.datapath = "./.data";
await fetchUserLevels(opts);
await prompts(opts);
@ -22,7 +24,10 @@ const run = async (opts) => {
const fetchUserLevels = async (opts) => {
const accessLevels = await readJSON(
join(opts.appname, "access_levels.json")
join(
opts.appContext.config.latestPackagesFolder || ".",
opts.appname,
"access_levels.json")
);
if(accessLevels.levels.length === 0)
@ -76,16 +81,21 @@ const prompts = async (opts) => {
const createInstance = async (opts) => {
const appContext = await getAppContext({configName: opts.config, masterIsCreated:true});
const bb = opts.appContext.master.bbMaster;
const bb = appContext.master.bbMaster;
const app = await appContext.master.getApplication(opts.appname);
const app = await opts.appContext.master.getApplication(opts.appname);
const instance = bb.recordApi.getNew(`${app.key}/instances`, "instance");
instance.name = "dev instance";
instance.active = true;
instance.version = {key:""};
const user = bb.authApi.getNewUser();
user.accessLevels.push(opts.userAccessLevel);
user.name = opts.username;
await bb.recordApi.save(instance);
const savedInstance = await bb.recordApi.load(instance.key);
await opts.appContext.master.createAppUser(
opts.appname, savedInstance, user, opts.password);
}

View File

@ -5,7 +5,7 @@ import nodeglobals from 'rollup-plugin-node-globals';
import { terser } from 'rollup-plugin-terser';
const lodash_fp_exports = [
"find", "isUndefined", "split",
"find", "isUndefined", "split", "max",
"last", "union", "reduce", "isObject",
"cloneDeep", "some", "isArray", "map",
"filter", "keys", "isFunction", "isEmpty",
@ -17,7 +17,7 @@ const lodash_fp_exports = [
"isInteger", "toNumber"];
const lodash_exports = [
"flow", "head",
"flow", "head", "find", "each",
"tail", "findIndex", "startsWith",
"dropRight", "takeRight",
"trim", "split", "replace",

View File

@ -20,5 +20,5 @@ export const authenticate = (api) => async ({username, password}) => {
// set user even if error - so it is defined at least
api.setState(USER_STATE_PATH, user);
localStorage.setItem("budibase:user", user);
localStorage.setItem("budibase:user", JSON.stringify(user));
}

View File

@ -2,11 +2,12 @@ import { ERROR } from "../state/standardState";
import {loadRecord} from "./loadRecord";
import {listRecords} from "./listRecords";
import {authenticate} from "./authenticate";
import {saveRecord} from "./saveRecord";
export const createApi = ({rootPath, setState, getState}) => {
const apiCall = (method) => ({url, body, notFound, badRequest, forbidden}) => {
fetch(`${rootPath}${url}`, {
return fetch(`${rootPath}${url}`, {
method: method,
headers: {
'Content-Type': 'application/json',
@ -46,7 +47,7 @@ export const createApi = ({rootPath, setState, getState}) => {
return e;
}
const isSuccess = obj => !!obj[ERROR_MEMBER];
const isSuccess = obj => !obj || !obj[ERROR_MEMBER];
const apiOpts = {
rootPath, setState, getState, isSuccess, error,
@ -56,7 +57,8 @@ export const createApi = ({rootPath, setState, getState}) => {
return {
loadRecord:loadRecord(apiOpts),
listRecords: listRecords(apiOpts),
authenticate: authenticate(apiOpts)
authenticate: authenticate(apiOpts),
saveRecord: saveRecord(apiOpts)
}
}

View File

@ -11,7 +11,7 @@ export const listRecords = api => async ({indexKey, statePath}) => {
return;
}
const records = api.get({
const records = await api.get({
url:`/api/listRecords/${trimSlash(indexKey)}`
});

View File

@ -24,6 +24,6 @@ import {trimSlash} from "../common/trimSlash";
body: recordtoSave
});
if(api.isSuccess(record))
if(api.isSuccess(savedRecord))
api.setState(statePath, savedRecord);
}

View File

@ -2,6 +2,9 @@ import { createCoreApp } from "./createCoreApp"
import {
getNew, getNewChild
} from "../../../core/src/recordApi/getNew";
import {
constructHierarchy
} from "../../../core/src/templateApi/createNodes";
export const createCoreApi = (appDefinition, user) => {
@ -11,6 +14,10 @@ export const createCoreApi = (appDefinition, user) => {
recordApi: {
getNew: getNew(app),
getNewChild: getNewChild(app)
},
templateApi: {
constructHierarchy
}
}

View File

@ -21,23 +21,19 @@ export const createApp = (componentLibraries, appDefinition, user) => {
if(!componentName || !libName) return;
const {initialProps, bind, boundProps} = setupBinding(
store, props, coreApi, context || parentContext, appDefinition.appRootPath);
const {
initialProps, bind,
boundProps, boundArrays,
contextBoundProps
} = setupBinding(
store, props, coreApi,
context || parentContext, appDefinition.appRootPath);
const bindings = {};
if(boundProps && boundProps.length > 0) {
for(let p of boundProps) {
bindings[p.propName] = {
path: p.path,
fallback: p.fallback,
source: p.source
}
}
}
const bindings = buildBindings(boundProps, boundArrays, contextBoundProps);
const componentProps = {
...initialProps,
_bb:bb(bindings, context || parentContext)
_bb:bb(bindings, context || parentContext, props)
};
const component = new (componentLibraries[libName][componentName])({
@ -53,6 +49,7 @@ export const createApp = (componentLibraries, appDefinition, user) => {
}
const coreApi = createCoreApi(appDefinition, user);
appDefinition.hierarchy = coreApi.templateApi.constructHierarchy(appDefinition.hierarchy);
const store = writable({
_bbuser: user
});
@ -93,7 +90,7 @@ export const createApp = (componentLibraries, appDefinition, user) => {
if(isFunction(event)) event(context);
}
const bb = (bindings, context) => ({
const bb = (bindings, context, props) => ({
hydrateComponent: _initialiseComponent(context, true),
appendComponent: _initialiseComponent(context, false),
insertComponent: (props, htmlElement, anchor, context) =>
@ -109,12 +106,55 @@ export const createApp = (componentLibraries, appDefinition, user) => {
getStateOrValue(globalState, prop, currentContext),
bindings,
context,
props
});
return bb();
}
const buildBindings = (boundProps, boundArrays, contextBoundProps) => {
const bindings = {};
if(boundProps && boundProps.length > 0) {
for(let p of boundProps) {
bindings[p.propName] = {
path: p.path,
fallback: p.fallback,
source: p.source
}
}
}
if(contextBoundProps && contextBoundProps.length > 0) {
for(let p of contextBoundProps) {
bindings[p.propName] = {
path: p.path,
fallback: p.fallback,
source: p.source
}
}
}
if(boundArrays && boundArrays.length > 0) {
for(let a of boundArrays) {
const arrayOfBindings = [];
for(let b of a.arrayOfBindings) {
arrayOfBindings.push(
buildBindings(
b.boundProps,
b.boundArrays,
b.contextBoundProps)
);
}
bindings[a.propName] = arrayOfBindings;
}
}
return bindings;
}
const splitName = fullname => {
const componentName = $(fullname, [

View File

@ -4,12 +4,15 @@ import { trimSlash } from "./common/trimSlash";
export const loadBudibase = async (componentLibraries, props) => {
const appDefinition = window["##BUDIBASE_APPDEFINITION##"];
const user = localStorage.getItem("budibase:user") || {
const userFromStorage = localStorage.getItem("budibase:user")
const user = userFromStorage ? JSON.parse(userFromStorage) : {
name: "annonymous",
permissions : [],
isUser:false,
temp:false
}
};
if(!componentLibraries) {

View File

@ -1,6 +1,6 @@
import { ERROR } from "./standardState";
export const getNewChildRecordToState = (store, coreApi, setState) =>
export const getNewChildRecordToState = (coreApi, setState) =>
({recordKey, collectionName,childRecordType,statePath}) => {
const error = errorHandler(setState);
try {
@ -25,7 +25,7 @@ export const getNewChildRecordToState = (store, coreApi, setState) =>
}
const rec = coreApi.recordApi.getNewChild(recordKey, collectionName, childRecordType);
setState(store, statePath, rec);
setState(statePath, rec);
}
catch(e) {
error(e.message);
@ -33,7 +33,7 @@ export const getNewChildRecordToState = (store, coreApi, setState) =>
}
export const getNewRecordToState = (store, coreApi, setState) =>
export const getNewRecordToState = (coreApi, setState) =>
({collectionKey,childRecordType,statePath}) => {
const error = errorHandler(setState);
try {
@ -53,7 +53,7 @@ export const getNewRecordToState = (store, coreApi, setState) =>
}
const rec = coreApi.recordApi.getNew(collectionKey, childRecordType);
setState(store, statePath, rec);
setState(statePath, rec);
}
catch(e) {
error(e.message);

View File

@ -19,10 +19,15 @@ export const eventHandlers = (store,coreApi,rootPath) => {
const setStateWithStore = (path, value) => setState(store, path, value);
let currentState;
store.subscribe(s => {
currentState = s;
});
const api = createApi({
rootPath:rootPath,
setState: (path, value) => setStateWithStore,
getState: (path, fallback) => getState(store, path, fallback)
setState: setStateWithStore,
getState: (path, fallback) => getState(currentState, path, fallback)
});
const setStateHandler = ({path, value}) => setState(store, path, value);
@ -35,11 +40,11 @@ export const eventHandlers = (store,coreApi,rootPath) => {
"Get New Child Record": handler(
["recordKey", "collectionName", "childRecordType", "statePath"],
getNewChildRecordToState(store, coreApi, setStateWithStore)),
getNewChildRecordToState(coreApi, setStateWithStore)),
"Get New Record": handler(
["collectionKey", "childRecordType", "statePath"],
getNewRecordToState(store, coreApi, setStateWithStore)),
getNewRecordToState(coreApi, setStateWithStore)),
"Authenticate": handler(["username", "password"], api.authenticate)
};

View File

@ -8,6 +8,7 @@ import {
export const getState = (s, path, fallback) => {
if(!s) return fallback;
if(!path || path.length === 0) return fallback;
if(path === "$") return s;
@ -41,11 +42,26 @@ export const getState = (s, path, fallback) => {
}
export const getStateOrValue = (globalState, prop, currentContext) => {
if(!isBound(prop)) return prop;
const stateToUse = takeStateFromStore(prop)
? globalState
: currentContext;
if(!prop) return prop;
if(isBound(prop)) {
const stateToUse = takeStateFromStore(prop)
? globalState
: currentContext;
return getState(stateToUse, prop[BB_STATE_BINDINGPATH], prop[BB_STATE_FALLBACK]);
}
if(prop.path && prop.source) {
const stateToUse = prop.source === "store"
? globalState
: currentContext;
return getState(stateToUse, prop.path, prop.fallback);
}
return prop;
return getState(stateToUse, prop[BB_STATE_BINDINGPATH], prop[BB_STATE_FALLBACK]);
}

View File

@ -19,7 +19,7 @@ export const setState = (store, path, value) => {
if(obj[currentKey] === null
|| obj[currentKey] === undefined
|| !isObject(obj.currentKey)) {
|| !isObject(obj[currentKey])) {
obj[currentKey] = {};
}
@ -35,4 +35,4 @@ export const setState = (store, path, value) => {
};
export const setStateFromBinding = (store, binding, value) =>
setState(store, binding[BB_STATE_BINDINGPATH], value);
setState(store, binding.path, value);

View File

@ -22,6 +22,7 @@ export const setupBinding = (store, rootProps, coreApi, context, rootPath) => {
const getBindings = (props, initialProps) => {
const boundProps = [];
const contextBoundProps = [];
const componentEventHandlers = [];
const boundArrays = [];
@ -49,6 +50,11 @@ export const setupBinding = (store, rootProps, coreApi, context, rootPath) => {
const fallback = BindingFallback(val);
const source = BindingSource(val);
contextBoundProps.push({
path:binding,
fallback, propName, source
});
initialProps[propName] = getState(
context || {},
binding,
@ -83,7 +89,7 @@ export const setupBinding = (store, rootProps, coreApi, context, rootPath) => {
}
return {boundProps, componentEventHandlers, boundArrays, initialProps};
return {contextBoundProps, boundProps, componentEventHandlers, boundArrays, initialProps};
}
@ -181,7 +187,9 @@ export const setupBinding = (store, rootProps, coreApi, context, rootPath) => {
return {
initialProps:rootInitialProps,
bind:bind(bindings),
boundProps:bindings.boundProps
boundProps:bindings.boundProps,
boundArrays: bindings.boundArrays,
contextBoundProps: bindings.contextBoundProps
};
}

View File

@ -58,21 +58,13 @@ export const getAppApis = async (store, behaviourSources = null,
app.user = await authApi.authenticate(username, password);
};
const withFullAccess = () => {
app.user = {
name: "app",
permissions : generateFullPermissions(app),
isUser:false,
temp:false
}
};
const withFullAccess = () =>
userWithFullAccess(app);
const asUser = (user) => {
app.user = user
};
let apis = {
recordApi,
templateApi,
@ -97,6 +89,16 @@ export const getAppApis = async (store, behaviourSources = null,
return apis;
};
export const userWithFullAccess = (app) => {
app.user = {
name: "app",
permissions : generateFullPermissions(app),
isUser:false,
temp:false
}
return app.user;
};
export {events, eventsList} from "./common/events";
export {getTemplateApi} from "./templateApi";
export {getRecordApi} from "./recordApi";

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -43,6 +43,41 @@
"allidsShardFactor": 64,
"collectionName": "customers",
"isSingle": false
},
{
"name": "Contact",
"type": "record",
"fields": [
{
"name": "name",
"type": "string",
"typeOptions": {
"maxLength": null,
"values": null,
"allowDeclaredValuesOnly": false
},
"label": "Name",
"getInitialValue": "default",
"getUndefinedValue": "default"
},
{
"name": "contacted",
"type": "bool",
"typeOptions": {
"allowNulls": false
},
"label": "Has Been Contacted",
"getInitialValue": "default",
"getUndefinedValue": "default"
}
],
"children": [],
"validationRules": [],
"nodeId": 3,
"indexes": [],
"allidsShardFactor": 64,
"collectionName": "contacts",
"isSingle": false
}
],
"pathMaps": [],
@ -60,6 +95,20 @@
1
],
"nodeId": 2
},
{
"name": "all_contacts",
"type": "index",
"map": "return {...record};",
"filter": "",
"indexType": "ancestor",
"getShardName": "",
"getSortKey": "record.id",
"aggregateGroups": [],
"allowedRecordNodeIds": [
3
],
"nodeId": 4
}
],
"nodeId": 0
@ -67,7 +116,724 @@
"triggers": [],
"actions": {},
"props": {
"main": {},
"unauthenticated": {}
"main": {
"_component": "@budibase/bootstrap-components/nav",
"items": [
{
"_component": "items#array_element#",
"title": "customers",
"component": {
"_component": "@budibase/standard-components/if",
"condition": "$store.isEditingcustomer",
"thenComponent": {
"_component": "@budibase/standard-components/div",
"children": [
{
"_component": "children#array_element#",
"component": {
"_component": "@budibase/standard-components/h3",
"text": "Edit customer",
"className": ""
}
},
{
"_component": "children#array_element#",
"component": {
"_component": "@budibase/standard-components/form",
"containerClass": "",
"formControls": [
{
"_component": "formControls#array_element#",
"label": "Name",
"control": {
"_component": "@budibase/standard-components/input",
"value": {
"##bbstate": "customer.name",
"##bbsource": "store"
},
"type": "text",
"className": "form-control"
}
},
{
"_component": "formControls#array_element#",
"label": "Enquiry Source",
"control": {
"_component": "@budibase/standard-components/select",
"value": {
"##bbstate": "customer.enquiry",
"##bbsource": "store"
},
"options": [
{
"_component": "options#array_element#",
"id": "Google",
"value": "Google"
},
{
"_component": "options#array_element#",
"id": "Facebook",
"value": "Facebook"
},
{
"_component": "options#array_element#",
"id": "Word of Mouth",
"value": "Word of Mouth"
}
],
"className": "form-control"
}
}
]
}
},
{
"_component": "children#array_element#",
"component": {
"_component": "@budibase/standard-components/stackpanel",
"direction": "horizontal",
"children": [
{
"_component": "children#array_element#",
"control": {
"_component": "@budibase/standard-components/div",
"children": [
{
"_component": "children#array_element#",
"component": {
"_component": "@budibase/standard-components/button",
"contentText": "Save customer",
"contentComponent": {
"_component": ""
},
"className": "btn btn-primary",
"disabled": false,
"onClick": [
{
"##eventHandlerType": "Save Record",
"parameters": {
"statePath": "customer"
}
},
{
"##eventHandlerType": "Set State",
"parameters": {
"path": "isEditingcustomer",
"value": ""
}
}
],
"background": "",
"color": "",
"border": "",
"padding": "",
"hoverColor": "",
"hoverBackground": "",
"hoverBorder": ""
}
}
],
"className": "btn-group",
"data": {
"##bbstate": ""
},
"dataItemComponent": {
"_component": ""
},
"onLoad": []
}
},
{
"_component": "children#array_element#",
"control": {
"_component": "@budibase/standard-components/div",
"children": [
{
"_component": "children#array_element#",
"component": {
"_component": "@budibase/standard-components/button",
"contentText": "Cancel",
"contentComponent": {
"_component": ""
},
"className": "btn btn-light",
"disabled": false,
"onClick": [
{
"##eventHandlerType": "Set State",
"parameters": {
"path": "isEditingcustomer",
"value": ""
}
}
],
"background": "",
"color": "",
"border": "",
"padding": "",
"hoverColor": "",
"hoverBackground": "",
"hoverBorder": ""
}
}
],
"className": "btn-group",
"data": {
"##bbstate": ""
},
"dataItemComponent": {
"_component": ""
},
"onLoad": []
}
}
],
"width": "auto",
"height": "auto",
"containerClass": "",
"itemContainerClass": "",
"data": {
"##bbstate": ""
},
"dataItemComponent": {
"_component": ""
},
"onLoad": []
}
}
],
"className": "p-1",
"data": {
"##bbstate": ""
},
"dataItemComponent": {
"_component": ""
},
"onLoad": []
},
"elseComponent": {
"_component": "@budibase/standard-components/div",
"children": [
{
"_component": "children#array_element#",
"component": {
"_component": "@budibase/standard-components/h2",
"text": "customers",
"className": ""
}
},
{
"_component": "children#array_element#",
"component": {
"_component": "@budibase/standard-components/div",
"children": [
{
"_component": "children#array_element#",
"component": {
"_component": "@budibase/standard-components/button",
"contentText": "Create customer",
"contentComponent": {
"_component": ""
},
"className": "btn btn-light",
"disabled": false,
"onClick": [
{
"##eventHandlerType": "Get New Record",
"parameters": {
"statePath": "customer",
"collectionKey": "/customers",
"childRecordType": "customer"
}
},
{
"##eventHandlerType": "Set State",
"parameters": {
"path": "isEditingcustomer",
"value": "true"
}
}
],
"background": "",
"color": "",
"border": "",
"padding": "",
"hoverColor": "",
"hoverBackground": "",
"hoverBorder": ""
}
},
{
"_component": "children#array_element#",
"component": {
"_component": "@budibase/standard-components/button",
"contentText": "Refresh",
"contentComponent": {
"_component": ""
},
"className": "btn btn-light",
"disabled": false,
"onClick": [
{
"##eventHandlerType": "List Records",
"parameters": {
"statePath": "/all_customers",
"indexKey": "/all_customers"
}
}
],
"background": "",
"color": "",
"border": "",
"padding": "",
"hoverColor": "",
"hoverBackground": "",
"hoverBorder": ""
}
}
],
"className": "btn-group",
"data": {
"##bbstate": ""
},
"dataItemComponent": {
"_component": ""
},
"onLoad": []
}
},
{
"_component": "children#array_element#",
"component": {
"_component": "@budibase/standard-components/table",
"data": {
"##bbstate": "/all_customers",
"##bbsource": "store"
},
"columns": [
{
"_component": "columns#array_element#",
"title": "enquiry",
"value": {
"##bbstate": "enquiry",
"##bbsource": "context"
}
},
{
"_component": "columns#array_element#",
"title": "name",
"value": {
"##bbstate": "name",
"##bbsource": "context"
}
}
],
"onRowClick": [
{
"##eventHandlerType": "Set State",
"parameters": {
"path": "currentView",
"value": {
"##bbstate": "type",
"##bbsource": "context"
}
}
}
],
"tableClass": "table table-hover",
"theadClass": "thead-dark",
"tbodyClass": "tbody-default",
"trClass": "tr-default",
"thClass": "th-default"
}
}
],
"className": "p-3",
"data": {
"##bbstate": ""
},
"dataItemComponent": {
"_component": ""
},
"onLoad": [
{
"##eventHandlerType": "Set State",
"parameters": {
"path": "isEditingcustomer",
"value": ""
}
},
{
"##eventHandlerType": "List Records",
"parameters": {
"statePath": "/all_customers",
"indexKey": "/all_customers"
}
}
]
}
}
},
{
"_component": "items#array_element#",
"title": "contacts",
"component": {
"_component": "@budibase/standard-components/if",
"condition": "$store.isEditingContact",
"thenComponent": {
"_component": "@budibase/standard-components/div",
"children": [
{
"_component": "children#array_element#",
"component": {
"_component": "@budibase/standard-components/h3",
"text": "Edit Contact",
"className": ""
}
},
{
"_component": "children#array_element#",
"component": {
"_component": "@budibase/standard-components/form",
"containerClass": "",
"formControls": [
{
"_component": "formControls#array_element#",
"label": "Name",
"control": {
"_component": "@budibase/standard-components/input",
"value": {
"##bbstate": "Contact.name",
"##bbsource": "store"
},
"type": "text",
"className": "form-control"
}
},
{
"_component": "formControls#array_element#",
"label": "Has Been Contacted",
"control": {
"_component": "@budibase/standard-components/input",
"value": {
"##bbstate": "Contact.contacted",
"##bbsource": "store"
},
"type": "text",
"className": "form-control"
}
}
]
}
},
{
"_component": "children#array_element#",
"component": {
"_component": "@budibase/standard-components/stackpanel",
"direction": "horizontal",
"children": [
{
"_component": "children#array_element#",
"control": {
"_component": "@budibase/standard-components/div",
"children": [
{
"_component": "children#array_element#",
"component": {
"_component": "@budibase/standard-components/button",
"contentText": "Save Contact",
"contentComponent": {
"_component": ""
},
"className": "btn btn-primary",
"disabled": false,
"onClick": [
{
"##eventHandlerType": "Save Record",
"parameters": {
"statePath": "Contact"
}
},
{
"##eventHandlerType": "Set State",
"parameters": {
"path": "isEditingContact",
"value": ""
}
}
],
"background": "",
"color": "",
"border": "",
"padding": "",
"hoverColor": "",
"hoverBackground": "",
"hoverBorder": ""
}
}
],
"className": "btn-group",
"data": {
"##bbstate": ""
},
"dataItemComponent": {
"_component": ""
},
"onLoad": []
}
},
{
"_component": "children#array_element#",
"control": {
"_component": "@budibase/standard-components/div",
"children": [
{
"_component": "children#array_element#",
"component": {
"_component": "@budibase/standard-components/button",
"contentText": "Cancel",
"contentComponent": {
"_component": ""
},
"className": "btn btn-light",
"disabled": false,
"onClick": [
{
"##eventHandlerType": "Set State",
"parameters": {
"path": "isEditingContact",
"value": ""
}
}
],
"background": "",
"color": "",
"border": "",
"padding": "",
"hoverColor": "",
"hoverBackground": "",
"hoverBorder": ""
}
}
],
"className": "btn-group",
"data": {
"##bbstate": ""
},
"dataItemComponent": {
"_component": ""
},
"onLoad": []
}
}
],
"width": "auto",
"height": "auto",
"containerClass": "",
"itemContainerClass": "",
"data": {
"##bbstate": ""
},
"dataItemComponent": {
"_component": ""
},
"onLoad": []
}
}
],
"className": "p-1",
"data": {
"##bbstate": ""
},
"dataItemComponent": {
"_component": ""
},
"onLoad": []
},
"elseComponent": {
"_component": "@budibase/standard-components/div",
"children": [
{
"_component": "children#array_element#",
"component": {
"_component": "@budibase/standard-components/h2",
"text": "contacts",
"className": ""
}
},
{
"_component": "children#array_element#",
"component": {
"_component": "@budibase/standard-components/div",
"children": [
{
"_component": "children#array_element#",
"component": {
"_component": "@budibase/standard-components/button",
"contentText": "Create Contact",
"contentComponent": {
"_component": ""
},
"className": "btn btn-light",
"disabled": false,
"onClick": [
{
"##eventHandlerType": "Get New Record",
"parameters": {
"statePath": "Contact",
"collectionKey": "/contacts",
"childRecordType": "Contact"
}
},
{
"##eventHandlerType": "Set State",
"parameters": {
"path": "isEditingContact",
"value": "true"
}
}
],
"background": "",
"color": "",
"border": "",
"padding": "",
"hoverColor": "",
"hoverBackground": "",
"hoverBorder": ""
}
},
{
"_component": "children#array_element#",
"component": {
"_component": "@budibase/standard-components/button",
"contentText": "Refresh",
"contentComponent": {
"_component": ""
},
"className": "btn btn-light",
"disabled": false,
"onClick": [
{
"##eventHandlerType": "List Records",
"parameters": {
"statePath": "/all_contacts",
"indexKey": "/all_contacts"
}
}
],
"background": "",
"color": "",
"border": "",
"padding": "",
"hoverColor": "",
"hoverBackground": "",
"hoverBorder": ""
}
}
],
"className": "btn-group",
"data": {
"##bbstate": ""
},
"dataItemComponent": {
"_component": ""
},
"onLoad": []
}
},
{
"_component": "children#array_element#",
"component": {
"_component": "@budibase/standard-components/table",
"data": {
"##bbstate": "/all_contacts",
"##bbsource": "store"
},
"columns": [
{
"_component": "columns#array_element#",
"title": "contacted",
"value": {
"##bbstate": "contacted",
"##bbsource": "context"
}
},
{
"_component": "columns#array_element#",
"title": "name",
"value": {
"##bbstate": "name",
"##bbsource": "context"
}
}
],
"onRowClick": [
{
"##eventHandlerType": "Set State",
"parameters": {
"path": "currentView",
"value": {
"##bbstate": "type",
"##bbsource": "context"
}
}
}
],
"tableClass": "table table-hover",
"theadClass": "thead-dark",
"tbodyClass": "tbody-default",
"trClass": "tr-default",
"thClass": "th-default"
}
}
],
"className": "p-3",
"data": {
"##bbstate": ""
},
"dataItemComponent": {
"_component": ""
},
"onLoad": [
{
"##eventHandlerType": "Set State",
"parameters": {
"path": "isEditingContact",
"value": ""
}
},
{
"##eventHandlerType": "List Records",
"parameters": {
"statePath": "/all_contacts",
"indexKey": "/all_contacts"
}
}
]
}
}
}
],
"selectedItem": {
"##bbstate": "selectedNav",
"##bbstatefallback": "customer",
"##bbsource": "store"
},
"pills": true,
"orientation": "horizontal",
"alignment": "start",
"fill": false,
"hideNavBar": false
},
"unauthenticated": {
"_component": "@budibase/standard-components/login",
"logo": "",
"loginRedirect": "",
"usernameLabel": "Username",
"passwordLabel": "Password",
"loginButtonLabel": "Login",
"buttonClass": "",
"inputClass": ""
}
}
}

View File

@ -0,0 +1,29 @@
{
"name": "Application Root",
"inherits": "@budibase/bootstrap-components/nav",
"props": {
"items": [
{
"title": "customers",
"component": {
"_component": "customer/customer Nav Content"
}
},
{
"title": "contacts",
"component": {
"_component": "Contact/Contact Nav Content"
}
}
],
"orientation": "horizontal",
"alignment": "start",
"fill": false,
"pills": true,
"selectedItem": {
"##bbstate": "selectedNav",
"##bbstatefallback": "customer",
"##bbsource": "store"
}
}
}

View File

@ -0,0 +1,107 @@
{
"name": "Contact/Contact Form",
"description": "Control for creating/updating '/contacts/3-{id}' ",
"inherits": "@budibase/standard-components/div",
"props": {
"className": "p-1",
"children": [
{
"component": {
"_component": "@budibase/standard-components/h3",
"text": "Edit Contact"
}
},
{
"component": {
"_component": "@budibase/standard-components/form",
"formControls": [
{
"control": {
"_component": "@budibase/standard-components/input",
"value": {
"##bbstate": "Contact.name",
"##bbsource": "store"
},
"className": "form-control",
"type": "text"
},
"label": "Name"
},
{
"control": {
"_component": "@budibase/standard-components/input",
"value": {
"##bbstate": "Contact.contacted",
"##bbsource": "store"
},
"className": "form-control",
"type": "text"
},
"label": "Has Been Contacted"
}
]
}
},
{
"component": {
"_component": "@budibase/standard-components/stackpanel",
"direction": "horizontal",
"children": [
{
"control": {
"_component": "@budibase/standard-components/div",
"className": "btn-group",
"children": [
{
"component": {
"_component": "common/Primary Button",
"contentText": "Save Contact",
"onClick": [
{
"##eventHandlerType": "Save Record",
"parameters": {
"statePath": "Contact"
}
},
{
"##eventHandlerType": "Set State",
"parameters": {
"path": "isEditingContact",
"value": ""
}
}
]
}
}
]
}
},
{
"control": {
"_component": "@budibase/standard-components/div",
"className": "btn-group",
"children": [
{
"component": {
"_component": "common/Default Button",
"contentText": "Cancel",
"onClick": [
{
"##eventHandlerType": "Set State",
"parameters": {
"path": "isEditingContact",
"value": ""
}
}
]
}
}
]
}
}
]
}
}
]
}
}

View File

@ -0,0 +1,14 @@
{
"inherits": "@budibase/standard-components/if",
"description": "the component that gets displayed when the contacts nav is selected",
"name": "Contact/Contact Nav Content",
"props": {
"condition": "$store.isEditingContact",
"thenComponent": {
"_component": "Contact/Contact Form"
},
"elseComponent": {
"_component": "Contact/Contact homepage"
}
}
}

View File

@ -0,0 +1,41 @@
{
"inherits": "@budibase/standard-components/div",
"name": "Contact/Contact homepage",
"props": {
"className": "p-3",
"children": [
{
"component": {
"_component": "@budibase/standard-components/h2",
"text": "contacts"
}
},
{
"component": {
"_component": "Contact/homepage buttons"
}
},
{
"component": {
"_component": "all_contacts Table"
}
}
],
"onLoad": [
{
"##eventHandlerType": "Set State",
"parameters": {
"path": "isEditingContact",
"value": ""
}
},
{
"##eventHandlerType": "List Records",
"parameters": {
"statePath": "/all_contacts",
"indexKey": "/all_contacts"
}
}
]
}
}

View File

@ -0,0 +1,47 @@
{
"inherits": "@budibase/standard-components/div",
"name": "Contact/homepage buttons",
"props": {
"className": "btn-group",
"children": [
{
"component": {
"_component": "common/Default Button",
"contentText": "Create Contact",
"onClick": [
{
"##eventHandlerType": "Get New Record",
"parameters": {
"statePath": "Contact",
"collectionKey": "/contacts",
"childRecordType": "Contact"
}
},
{
"##eventHandlerType": "Set State",
"parameters": {
"path": "isEditingContact",
"value": "true"
}
}
]
}
},
{
"component": {
"_component": "common/Default Button",
"contentText": "Refresh",
"onClick": [
{
"##eventHandlerType": "List Records",
"parameters": {
"statePath": "/all_contacts",
"indexKey": "/all_contacts"
}
}
]
}
}
]
}
}

View File

@ -0,0 +1,5 @@
{
"name": "Login",
"inherits": "@budibase/standard-components/login",
"props": {}
}

View File

@ -0,0 +1,40 @@
{
"name": "all_contacts Table",
"inherits": "@budibase/standard-components/table",
"props": {
"data": {
"##bbstate": "/all_contacts",
"##bbsource": "store"
},
"tableClass": "table table-hover",
"theadClass": "thead-dark",
"columns": [
{
"title": "contacted",
"value": {
"##bbstate": "contacted",
"##bbsource": "context"
}
},
{
"title": "name",
"value": {
"##bbstate": "name",
"##bbsource": "context"
}
}
],
"onRowClick": [
{
"##eventHandlerType": "Set State",
"parameters": {
"path": "currentView",
"value": {
"##bbstate": "type",
"##bbsource": "context"
}
}
}
]
}
}

View File

@ -0,0 +1,40 @@
{
"name": "all_customers Table",
"inherits": "@budibase/standard-components/table",
"props": {
"data": {
"##bbstate": "/all_customers",
"##bbsource": "store"
},
"tableClass": "table table-hover",
"theadClass": "thead-dark",
"columns": [
{
"title": "enquiry",
"value": {
"##bbstate": "enquiry",
"##bbsource": "context"
}
},
{
"title": "name",
"value": {
"##bbstate": "name",
"##bbsource": "context"
}
}
],
"onRowClick": [
{
"##eventHandlerType": "Set State",
"parameters": {
"path": "currentView",
"value": {
"##bbstate": "type",
"##bbsource": "context"
}
}
}
]
}
}

View File

@ -0,0 +1,8 @@
{
"name": "common/Default Button",
"description": "Bootstrap default button",
"inherits": "@budibase/standard-components/button",
"props": {
"className": "btn btn-light"
}
}

View File

@ -0,0 +1,8 @@
{
"name": "common/Primary Button",
"description": "Bootstrap primary button ",
"inherits": "@budibase/standard-components/button",
"props": {
"className": "btn btn-primary"
}
}

View File

@ -0,0 +1,120 @@
{
"name": "customer/customer Form",
"description": "Control for creating/updating '/customers/1-{id}' ",
"inherits": "@budibase/standard-components/div",
"props": {
"className": "p-1",
"children": [
{
"component": {
"_component": "@budibase/standard-components/h3",
"text": "Edit customer"
}
},
{
"component": {
"_component": "@budibase/standard-components/form",
"formControls": [
{
"control": {
"_component": "@budibase/standard-components/input",
"value": {
"##bbstate": "customer.name",
"##bbsource": "store"
},
"className": "form-control",
"type": "text"
},
"label": "Name"
},
{
"control": {
"_component": "@budibase/standard-components/select",
"options": [
{
"id": "Google",
"value": "Google"
},
{
"id": "Facebook",
"value": "Facebook"
},
{
"id": "Word of Mouth",
"value": "Word of Mouth"
}
],
"value": {
"##bbstate": "customer.enquiry",
"##bbsource": "store"
},
"className": "form-control"
},
"label": "Enquiry Source"
}
]
}
},
{
"component": {
"_component": "@budibase/standard-components/stackpanel",
"direction": "horizontal",
"children": [
{
"control": {
"_component": "@budibase/standard-components/div",
"className": "btn-group",
"children": [
{
"component": {
"_component": "common/Primary Button",
"contentText": "Save customer",
"onClick": [
{
"##eventHandlerType": "Save Record",
"parameters": {
"statePath": "customer"
}
},
{
"##eventHandlerType": "Set State",
"parameters": {
"path": "isEditingcustomer",
"value": ""
}
}
]
}
}
]
}
},
{
"control": {
"_component": "@budibase/standard-components/div",
"className": "btn-group",
"children": [
{
"component": {
"_component": "common/Default Button",
"contentText": "Cancel",
"onClick": [
{
"##eventHandlerType": "Set State",
"parameters": {
"path": "isEditingcustomer",
"value": ""
}
}
]
}
}
]
}
}
]
}
}
]
}
}

View File

@ -0,0 +1,14 @@
{
"inherits": "@budibase/standard-components/if",
"description": "the component that gets displayed when the customers nav is selected",
"name": "customer/customer Nav Content",
"props": {
"condition": "$store.isEditingcustomer",
"thenComponent": {
"_component": "customer/customer Form"
},
"elseComponent": {
"_component": "customer/customer homepage"
}
}
}

View File

@ -0,0 +1,41 @@
{
"inherits": "@budibase/standard-components/div",
"name": "customer/customer homepage",
"props": {
"className": "p-3",
"children": [
{
"component": {
"_component": "@budibase/standard-components/h2",
"text": "customers"
}
},
{
"component": {
"_component": "customer/homepage buttons"
}
},
{
"component": {
"_component": "all_customers Table"
}
}
],
"onLoad": [
{
"##eventHandlerType": "Set State",
"parameters": {
"path": "isEditingcustomer",
"value": ""
}
},
{
"##eventHandlerType": "List Records",
"parameters": {
"statePath": "/all_customers",
"indexKey": "/all_customers"
}
}
]
}
}

View File

@ -0,0 +1,47 @@
{
"inherits": "@budibase/standard-components/div",
"name": "customer/homepage buttons",
"props": {
"className": "btn-group",
"children": [
{
"component": {
"_component": "common/Default Button",
"contentText": "Create customer",
"onClick": [
{
"##eventHandlerType": "Get New Record",
"parameters": {
"statePath": "customer",
"collectionKey": "/customers",
"childRecordType": "customer"
}
},
{
"##eventHandlerType": "Set State",
"parameters": {
"path": "isEditingcustomer",
"value": "true"
}
}
]
}
},
{
"component": {
"_component": "common/Default Button",
"contentText": "Refresh",
"onClick": [
{
"##eventHandlerType": "List Records",
"parameters": {
"statePath": "/all_customers",
"indexKey": "/all_customers"
}
}
]
}
}
]
}
}

View File

@ -8,6 +8,7 @@
"author": "",
"license": "ISC",
"dependencies": {
"@budibase/standard-components": "^0.0.10"
"@budibase/bootstrap-components": "file:../../../bootstrap-components",
"@budibase/standard-components": "file:../../../standard-components"
}
}

View File

@ -1,14 +1,19 @@
{
"main": {
"index": {},
"appBody": ""
"index": {
"title": "My App"
},
"appBody": "Application Root"
},
"unauthenticated": {
"index": {},
"appBody": ""
"index": {
"title": "My App - Login"
},
"appBody": "Login"
},
"componentLibraries": [
"@budibase/standard-components"
"@budibase/standard-components",
"@budibase/bootstrap-components"
],
"stylesheets": [
"https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -4,7 +4,7 @@
<meta charset='utf8'>
<meta name='viewport' content='width=device-width'>
<title>Budibase App</title>
<title>My App</title>
<link rel='icon' type='image/png' href='/testApp2//_shared/favicon.png'>
<style>

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
window['##BUDIBASE_APPDEFINITION##'] = {"hierarchy":{"name":"root","type":"root","children":[{"name":"customer","type":"record","fields":[{"name":"name","type":"string","typeOptions":{"maxLength":null,"values":null,"allowDeclaredValuesOnly":false},"label":"Name","getInitialValue":"default","getUndefinedValue":"default"},{"name":"enquiry","type":"string","typeOptions":{"maxLength":null,"values":["Google","Facebook","Word of Mouth"],"allowDeclaredValuesOnly":true},"label":"Enquiry Source","getInitialValue":"default","getUndefinedValue":"default"}],"children":[],"validationRules":[],"nodeId":1,"indexes":[],"allidsShardFactor":64,"collectionName":"customers","isSingle":false}],"pathMaps":[],"indexes":[{"name":"all_customers","type":"index","map":"return {...record};","filter":"","indexType":"ancestor","getShardName":"","getSortKey":"record.id","aggregateGroups":[],"allowedRecordNodeIds":[1],"nodeId":2}],"nodeId":0},"componentLibraries":[{"importPath":"/lib/node_modules/@budibase/standard-components/dist/index.js","libName":"@budibase/standard-components"}],"appRootPath":"/testApp2","props":{}}
window['##BUDIBASE_APPDEFINITION##'] = {"hierarchy":{"name":"root","type":"root","children":[{"name":"customer","type":"record","fields":[{"name":"name","type":"string","typeOptions":{"maxLength":null,"values":null,"allowDeclaredValuesOnly":false},"label":"Name","getInitialValue":"default","getUndefinedValue":"default"},{"name":"enquiry","type":"string","typeOptions":{"maxLength":null,"values":["Google","Facebook","Word of Mouth"],"allowDeclaredValuesOnly":true},"label":"Enquiry Source","getInitialValue":"default","getUndefinedValue":"default"}],"children":[],"validationRules":[],"nodeId":1,"indexes":[],"allidsShardFactor":64,"collectionName":"customers","isSingle":false},{"name":"Contact","type":"record","fields":[{"name":"name","type":"string","typeOptions":{"maxLength":null,"values":null,"allowDeclaredValuesOnly":false},"label":"Name","getInitialValue":"default","getUndefinedValue":"default"},{"name":"contacted","type":"bool","typeOptions":{"allowNulls":false},"label":"Has Been Contacted","getInitialValue":"default","getUndefinedValue":"default"}],"children":[],"validationRules":[],"nodeId":3,"indexes":[],"allidsShardFactor":64,"collectionName":"contacts","isSingle":false}],"pathMaps":[],"indexes":[{"name":"all_customers","type":"index","map":"return {...record};","filter":"","indexType":"ancestor","getShardName":"","getSortKey":"record.id","aggregateGroups":[],"allowedRecordNodeIds":[1],"nodeId":2},{"name":"all_contacts","type":"index","map":"return {...record};","filter":"","indexType":"ancestor","getShardName":"","getSortKey":"record.id","aggregateGroups":[],"allowedRecordNodeIds":[3],"nodeId":4}],"nodeId":0},"componentLibraries":[{"importPath":"/lib/node_modules/@budibase/standard-components/dist/index.js","libName":"@budibase/standard-components"},{"importPath":"/lib/node_modules/@budibase/bootstrap-components/dist/index.js","libName":"@budibase/bootstrap-components"}],"appRootPath":"/testApp2","props":{"_component":"@budibase/standard-components/login","logo":"","loginRedirect":"","usernameLabel":"Username","passwordLabel":"Password","loginButtonLabel":"Login","buttonClass":"","inputClass":""}}

View File

@ -4,7 +4,7 @@
<meta charset='utf8'>
<meta name='viewport' content='width=device-width'>
<title>Budibase App</title>
<title>My App - Login</title>
<link rel='icon' type='image/png' href='/testApp2//_shared/favicon.png'>
<style>

View File

@ -0,0 +1,9 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
"@budibase/bootstrap-components@file:../../../bootstrap-components":
version "0.0.11"
"@budibase/standard-components@file:../../../standard-components":
version "0.0.11"

File diff suppressed because one or more lines are too long

View File

@ -7,37 +7,37 @@ button.svelte-bxuckr{border-style:none;background-color:rgba(0,0,0,0);cursor:poi
.root.svelte-rjo9m0{display:grid;grid-template-columns:[uiNav] 250px [preview] auto [properties] 300px;height:100%;width:100%;overflow-y:auto}.ui-nav.svelte-rjo9m0{grid-column-start:uiNav;background-color:var(--secondary5);height:100%}.properties-pane.svelte-rjo9m0{grid-column-start:properties;background-color:var(--secondary5);height:100%;overflow-y:hidden}.pages-list-container.svelte-rjo9m0{padding-top:2rem}.components-nav-header.svelte-rjo9m0{font-size:.9rem}.nav-group-header.svelte-rjo9m0{font-size:.9rem;padding-left:1rem}.nav-items-container.svelte-rjo9m0{padding:1rem 1rem 0rem 1rem}.nav-group-header.svelte-rjo9m0{display:grid;grid-template-columns:[icon] auto [title] 1fr [button] auto;padding:2rem 1rem 0rem 1rem;font-size:.9rem;font-weight:bold}.nav-group-header.svelte-rjo9m0>div.svelte-rjo9m0:nth-child(1){padding:0rem .5rem 0rem 0rem;vertical-align:bottom;grid-column-start:icon;margin-right:5px}.nav-group-header.svelte-rjo9m0>span.svelte-rjo9m0:nth-child(2){margin-left:5px;vertical-align:bottom;grid-column-start:title;margin-top:auto}.nav-group-header.svelte-rjo9m0>div.svelte-rjo9m0:nth-child(3){vertical-align:bottom;grid-column-start:button;cursor:pointer;color:var(--primary75)}.nav-group-header.svelte-rjo9m0>div.svelte-rjo9m0:nth-child(3):hover{color:var(--primary75)}
h4.svelte-sqtlby{margin-top:20px}
.root.svelte-apja7r{height:100%;position:relative}.actions-header.svelte-apja7r{flex:0 1 auto}.node-view.svelte-apja7r{overflow-y:auto;flex:1 1 auto}
.items-root.svelte-19lmivt{display:flex;flex-direction:column;max-height:100%;height:100%;background-color:var(--secondary5)}.nav-group-header.svelte-19lmivt{display:grid;grid-template-columns:[icon] auto [title] 1fr [button] auto;padding:2rem 1rem 0rem 1rem;font-size:.9rem;font-weight:bold}.nav-group-header.svelte-19lmivt>div.svelte-19lmivt:nth-child(1){padding:0rem .7rem 0rem 0rem;vertical-align:bottom;grid-column-start:icon;margin-right:5px}.nav-group-header.svelte-19lmivt>div.svelte-19lmivt:nth-child(2){margin-left:5px;vertical-align:bottom;grid-column-start:title;margin-top:auto}.nav-group-header.svelte-19lmivt>div.svelte-19lmivt:nth-child(3){vertical-align:bottom;grid-column-start:button;cursor:pointer;color:var(--primary75)}.nav-group-header.svelte-19lmivt>div.svelte-19lmivt:nth-child(3):hover{color:var(--primary75)}.hierarchy-title.svelte-19lmivt{flex:auto 1 1}.hierarchy.svelte-19lmivt{display:flex;flex-direction:column;flex:1 0 auto;height:100px}.hierarchy-items-container.svelte-19lmivt{flex:1 1 auto;overflow-y:auto}
.root.svelte-nd1yft{height:100%;position:relative;padding:1.5rem}
.root.svelte-wfv60d{height:100%;position:relative;padding:1.5rem}.actions-header.svelte-wfv60d{flex:0 1 auto}.node-view.svelte-wfv60d{overflow-y:auto;flex:1 1 auto}
.items-root.svelte-19lmivt{display:flex;flex-direction:column;max-height:100%;height:100%;background-color:var(--secondary5)}.nav-group-header.svelte-19lmivt{display:grid;grid-template-columns:[icon] auto [title] 1fr [button] auto;padding:2rem 1rem 0rem 1rem;font-size:.9rem;font-weight:bold}.nav-group-header.svelte-19lmivt>div.svelte-19lmivt:nth-child(1){padding:0rem .7rem 0rem 0rem;vertical-align:bottom;grid-column-start:icon;margin-right:5px}.nav-group-header.svelte-19lmivt>div.svelte-19lmivt:nth-child(2){margin-left:5px;vertical-align:bottom;grid-column-start:title;margin-top:auto}.nav-group-header.svelte-19lmivt>div.svelte-19lmivt:nth-child(3){vertical-align:bottom;grid-column-start:button;cursor:pointer;color:var(--primary75)}.nav-group-header.svelte-19lmivt>div.svelte-19lmivt:nth-child(3):hover{color:var(--primary75)}.hierarchy-title.svelte-19lmivt{flex:auto 1 1}.hierarchy.svelte-19lmivt{display:flex;flex-direction:column;flex:1 0 auto;height:100px}.hierarchy-items-container.svelte-19lmivt{flex:1 1 auto;overflow-y:auto}
.root.svelte-1r2dipt{color:var(--secondary50);font-size:.9rem;font-weight:bold}.hierarchy-item.svelte-1r2dipt{cursor:pointer;padding:5px 0px}.hierarchy-item.svelte-1r2dipt:hover{color:var(--secondary)}.component.svelte-1r2dipt{margin-left:5px}.currentfolder.svelte-1r2dipt{color:var(--secondary100)}.selected.svelte-1r2dipt{color:var(--primary100);font-weight:bold}.title.svelte-1r2dipt{margin-left:10px}
.uk-modal-dialog.svelte-vwwrf9{border-radius:.3rem}
.root.svelte-1ersoxu{padding:15px}.help-text.svelte-1ersoxu{color:var(--slate);font-size:10pt}
.root.svelte-1r2dipt{color:var(--secondary50);font-size:.9rem;font-weight:bold}.hierarchy-item.svelte-1r2dipt{cursor:pointer;padding:5px 0px}.hierarchy-item.svelte-1r2dipt:hover{color:var(--secondary)}.component.svelte-1r2dipt{margin-left:5px}.currentfolder.svelte-1r2dipt{color:var(--secondary100)}.selected.svelte-1r2dipt{color:var(--primary100);font-weight:bold}.title.svelte-1r2dipt{margin-left:10px}
.root.svelte-117bbrk{padding-bottom:10px;padding-left:10px;font-size:.9rem;color:var(--secondary50);font-weight:bold}.hierarchy-item.svelte-117bbrk{cursor:pointer;padding:5px 0px}.hierarchy-item.svelte-117bbrk:hover{color:var(--secondary100)}.component.svelte-117bbrk{margin-left:5px}.selected.svelte-117bbrk{color:var(--primary100);font-weight:bold}.title.svelte-117bbrk{margin-left:10px}
.component-container.svelte-teqoiq{grid-row-start:middle;grid-column-start:middle;position:relative;overflow:hidden;padding-top:56.25%;margin:auto}.component-container.svelte-teqoiq iframe.svelte-teqoiq{border:0;height:100%;left:0;position:absolute;top:0;width:100%}
.section-container.svelte-yk1mmr{padding:15px;border-style:dotted;border-width:1px;border-color:var(--lightslate);border-radius:2px}.section-container.svelte-yk1mmr:nth-child(1){margin-bottom:15px}.row-text.svelte-yk1mmr{margin-right:15px;color:var(--primary100)}input.svelte-yk1mmr{margin-right:15px}p.svelte-yk1mmr>span.svelte-yk1mmr{margin-left:30px}.header.svelte-yk1mmr{display:grid;grid-template-columns:[title] 1fr [icon] auto}.header.svelte-yk1mmr>div.svelte-yk1mmr:nth-child(1){grid-column-start:title}.header.svelte-yk1mmr>div.svelte-yk1mmr:nth-child(2){grid-column-start:icon}
h1.svelte-16jkjx9{font-size:1.2em}
.component-container.svelte-teqoiq{grid-row-start:middle;grid-column-start:middle;position:relative;overflow:hidden;padding-top:56.25%;margin:auto}.component-container.svelte-teqoiq iframe.svelte-teqoiq{border:0;height:100%;left:0;position:absolute;top:0;width:100%}
.root.svelte-1ersoxu{padding:15px}.help-text.svelte-1ersoxu{color:var(--slate);font-size:10pt}
.root.svelte-1abif7s{height:100%;display:flex;flex-direction:column}.padding.svelte-1abif7s{padding:1rem 1rem 0rem 1rem}.info-text.svelte-1abif7s{color:var(--secondary100);font-size:.8rem !important;font-weight:bold}.title.svelte-1abif7s{padding:2rem 1rem 1rem 1rem;display:grid;grid-template-columns:[name] 1fr [actions] auto;color:var(--secondary100);font-size:.9rem;font-weight:bold}.title.svelte-1abif7s>div.svelte-1abif7s:nth-child(1){grid-column-start:name;color:var(--secondary100)}.title.svelte-1abif7s>div.svelte-1abif7s:nth-child(2){grid-column-start:actions}.section-header.svelte-1abif7s{display:grid;grid-template-columns:[name] 1fr [actions] auto;color:var(--secondary50);font-size:.9rem;font-weight:bold;vertical-align:middle}.component-props-container.svelte-1abif7s{flex:1 1 auto;overflow-y:auto}
.root.svelte-ehsf0i{display:block;font-size:.9rem;width:100%;cursor:pointer;font-weight:bold}.title.svelte-ehsf0i{font:var(--fontblack);padding-top:10px;padding-right:5px;padding-bottom:10px;color:var(--secondary100)}.title.svelte-ehsf0i:hover{background-color:var(--secondary10)}
.root.svelte-18xd5y3{height:100%;padding:2rem}.settings-title.svelte-18xd5y3{font-weight:700}.title.svelte-18xd5y3{margin:3rem 0rem 0rem 0rem;font-weight:700}.recordkey.svelte-18xd5y3{font-size:14px;font-weight:600;color:var(--primary100)}.fields-table.svelte-18xd5y3{margin:1rem 1rem 0rem 0rem;border-collapse:collapse}.add-field-button.svelte-18xd5y3{cursor:pointer}.edit-button.svelte-18xd5y3{cursor:pointer;color:var(--secondary25)}.edit-button.svelte-18xd5y3:hover{cursor:pointer;color:var(--secondary75)}th.svelte-18xd5y3{text-align:left}td.svelte-18xd5y3{padding:1rem 5rem 1rem 0rem;margin:0;font-size:14px;font-weight:500}.field-label.svelte-18xd5y3{font-size:14px;font-weight:500}thead.svelte-18xd5y3>tr.svelte-18xd5y3{border-width:0px 0px 1px 0px;border-style:solid;border-color:var(--secondary75);margin-bottom:20px}tbody.svelte-18xd5y3>tr.svelte-18xd5y3{border-width:0px 0px 1px 0px;border-style:solid;border-color:var(--primary10)}tbody.svelte-18xd5y3>tr.svelte-18xd5y3:hover{background-color:var(--primary10)}tbody.svelte-18xd5y3>tr:hover .edit-button.svelte-18xd5y3{color:var(--secondary75)}.index-container.svelte-18xd5y3{border-style:solid;border-width:0 0 1px 0;border-color:var(--secondary25);padding:10px;margin-bottom:5px}.index-label.svelte-18xd5y3{color:var(--slate)}.index-name.svelte-18xd5y3{font-weight:bold;color:var(--primary100)}.index-container.svelte-18xd5y3 code.svelte-18xd5y3{margin:0;display:inline;background-color:var(--primary10);color:var(--secondary100);padding:3px}.index-field-row.svelte-18xd5y3{margin:1rem 0rem 0rem 0rem}.no-indexes.svelte-18xd5y3{margin:1rem 0rem 0rem 0rem;font-family:var(--fontnormal);font-size:14px}
.root.svelte-pq2tmv{height:100%;padding:15px}.allowed-records.svelte-pq2tmv{margin:20px 0px}.allowed-records.svelte-pq2tmv>span.svelte-pq2tmv{margin-right:30px}
.dropdown-background.svelte-11ifkop{position:fixed;top:0;left:0;width:100vw;height:100vh}.root.svelte-11ifkop{cursor:pointer;z-index:1}.dropdown-content.svelte-11ifkop{position:absolute;background-color:var(--white);min-width:160px;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);z-index:1;font-weight:normal;border-style:solid;border-width:1px;border-color:var(--secondary10)}.dropdown-content.svelte-11ifkop:not(:focus){display:none}.action-row.svelte-11ifkop{padding:7px 10px;cursor:pointer}.action-row.svelte-11ifkop:hover{background-color:var(--primary100);color:var(--white)}
.root.svelte-x3bf9z{display:flex}.root.svelte-x3bf9z:last-child{border-radius:0 var(--borderradius) var(--borderradius) 0}.root.svelte-x3bf9z:first-child{border-radius:var(--borderradius) 0 0 var(--borderradius)}.root.svelte-x3bf9z:not(:first-child):not(:last-child){border-radius:0}
.root.svelte-wgyofl{padding:1.5rem;width:100%;align-items:right}
.edit-button.svelte-lhfdtn{cursor:pointer;color:var(--secondary25)}tr.svelte-lhfdtn:hover .edit-button.svelte-lhfdtn{color:var(--secondary75)}.title.svelte-lhfdtn{margin:3rem 0rem 0rem 0rem;font-weight:700}.table-content.svelte-lhfdtn{font-weight:500;font-size:.9rem}
.edit-button.svelte-zm41av{cursor:pointer;color:var(--secondary25)}.title.svelte-zm41av{margin:3rem 0rem 0rem 0rem;font-weight:700}.table-content.svelte-zm41av{font-weight:500;font-size:.9rem}tr.svelte-zm41av:hover .edit-button.svelte-zm41av{color:var(--secondary75)}
.nav-item.svelte-1i5jqm7{padding:1.5rem 1rem 0rem 1rem;font-size:.9rem;font-weight:bold;cursor:pointer;flex:0 0 auto}.nav-item.svelte-1i5jqm7:hover{background-color:var(--primary10)}.active.svelte-1i5jqm7{background-color:var(--primary10)}
.dropdown-background.svelte-11ifkop{position:fixed;top:0;left:0;width:100vw;height:100vh}.root.svelte-11ifkop{cursor:pointer;z-index:1}.dropdown-content.svelte-11ifkop{position:absolute;background-color:var(--white);min-width:160px;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);z-index:1;font-weight:normal;border-style:solid;border-width:1px;border-color:var(--secondary10)}.dropdown-content.svelte-11ifkop:not(:focus){display:none}.action-row.svelte-11ifkop{padding:7px 10px;cursor:pointer}.action-row.svelte-11ifkop:hover{background-color:var(--primary100);color:var(--white)}
.root.svelte-pq2tmv{height:100%;padding:15px}.allowed-records.svelte-pq2tmv{margin:20px 0px}.allowed-records.svelte-pq2tmv>span.svelte-pq2tmv{margin-right:30px}
.root.svelte-17ju2r{display:block;font-size:.9rem;width:100%;cursor:pointer;color:var(--secondary50);font-weight:500}.title.svelte-17ju2r{padding-top:.5rem;padding-right:.5rem}.title.svelte-17ju2r:hover{background-color:var(--secondary10)}.active.svelte-17ju2r{background-color:var(--primary10)}
.nav-item.svelte-1i5jqm7{padding:1.5rem 1rem 0rem 1rem;font-size:.9rem;font-weight:bold;cursor:pointer;flex:0 0 auto}.nav-item.svelte-1i5jqm7:hover{background-color:var(--primary10)}.active.svelte-1i5jqm7{background-color:var(--primary10)}
.root.svelte-x3bf9z{display:flex}.root.svelte-x3bf9z:last-child{border-radius:0 var(--borderradius) var(--borderradius) 0}.root.svelte-x3bf9z:first-child{border-radius:var(--borderradius) 0 0 var(--borderradius)}.root.svelte-x3bf9z:not(:first-child):not(:last-child){border-radius:0}
.edit-button.svelte-zm41av{cursor:pointer;color:var(--secondary25)}.title.svelte-zm41av{margin:3rem 0rem 0rem 0rem;font-weight:700}.table-content.svelte-zm41av{font-weight:500;font-size:.9rem}tr.svelte-zm41av:hover .edit-button.svelte-zm41av{color:var(--secondary75)}
.edit-button.svelte-lhfdtn{cursor:pointer;color:var(--secondary25)}tr.svelte-lhfdtn:hover .edit-button.svelte-lhfdtn{color:var(--secondary75)}.title.svelte-lhfdtn{margin:3rem 0rem 0rem 0rem;font-weight:700}.table-content.svelte-lhfdtn{font-weight:500;font-size:.9rem}
.info-text.svelte-1gx0gkl{font-size:0.7rem;color:var(--secondary50)}
.library-header.svelte-chhyel{font-size:1.1em;border-color:var(--primary25);border-width:1px 0px;border-style:solid;background-color:var(--primary10);padding:5px 0}.library-container.svelte-chhyel{padding:0 0 10px 10px}.inner-header.svelte-chhyel{font-size:0.9em;font-weight:bold;margin-top:7px;margin-bottom:3px}.component.svelte-chhyel{padding:2px 0px;cursor:pointer}.component.svelte-chhyel:hover{background-color:var(--lightslate)}.component.svelte-chhyel>.name.svelte-chhyel{color:var(--secondary100);display:inline-block}.component.svelte-chhyel>.description.svelte-chhyel{font-size:0.8em;color:var(--secondary75);display:inline-block;margin-left:10px}
.root.svelte-47ohpz{font-size:10pt}.padding.svelte-47ohpz{padding:0 10px}.inherited-title.svelte-47ohpz{padding:1rem 1rem 1rem 1rem;display:grid;grid-template-columns:[name] 1fr [actions] auto;color:var(--secondary100);font-size:.9rem;font-weight:bold}.inherited-title.svelte-47ohpz>div.svelte-47ohpz:nth-child(1){grid-column-start:name;color:var(--secondary50)}.inherited-title.svelte-47ohpz>div.svelte-47ohpz:nth-child(2){grid-column-start:actions;color:var(--secondary100)}
.library-header.svelte-chhyel{font-size:1.1em;border-color:var(--primary25);border-width:1px 0px;border-style:solid;background-color:var(--primary10);padding:5px 0}.library-container.svelte-chhyel{padding:0 0 10px 10px}.inner-header.svelte-chhyel{font-size:0.9em;font-weight:bold;margin-top:7px;margin-bottom:3px}.component.svelte-chhyel{padding:2px 0px;cursor:pointer}.component.svelte-chhyel:hover{background-color:var(--lightslate)}.component.svelte-chhyel>.name.svelte-chhyel{color:var(--secondary100);display:inline-block}.component.svelte-chhyel>.description.svelte-chhyel{font-size:0.8em;color:var(--secondary75);display:inline-block;margin-left:10px}
.component.svelte-3sgo90{padding:5px 0}.component.svelte-3sgo90 .title.svelte-3sgo90{width:300px
}.component.svelte-3sgo90>.description.svelte-3sgo90{font-size:0.8em;color:var(--secondary75)}.button-container.svelte-3sgo90{text-align:right;margin-top:20px}.error.svelte-3sgo90{font-size:10pt;color:red}
.title.svelte-dhe1ge{padding:3px;background-color:white;color:var(--secondary100);border-style:solid;border-width:1px 0 0 0;border-color:var(--lightslate)}.title.svelte-dhe1ge>span.svelte-dhe1ge{margin-left:10px}
textarea.svelte-di7k4b{padding:3px;margin-top:5px;margin-bottom:10px;background:var(--lightslate);color:var(--white);font-family:'Courier New', Courier, monospace;width:95%;height:100px;border-radius:5px}
.error-container.svelte-ole1mk{padding:10px;border-style:solid;border-color:var(--deletion100);border-radius:var(--borderradiusall);background:var(--deletion75)}.error-row.svelte-ole1mk{padding:5px 0px}
.root.svelte-16sjty9{padding:2rem;border-radius:2rem}.uk-grid-small.svelte-16sjty9{padding:1rem}.option-container.svelte-16sjty9{border-style:dotted;border-width:1px;border-color:var(--primary75);padding:3px;margin-right:5px}
input.svelte-9fre0g{margin-right:7px}
.root.svelte-16sjty9{padding:2rem;border-radius:2rem}.uk-grid-small.svelte-16sjty9{padding:1rem}.option-container.svelte-16sjty9{border-style:dotted;border-width:1px;border-color:var(--primary75);padding:3px;margin-right:5px}
.root.svelte-1v0yya9{padding:1rem 1rem 0rem 1rem}.prop-label.svelte-1v0yya9{font-size:0.8rem;color:var(--secondary100);font-weight:bold}
.root.svelte-ogh8o0{display:grid;grid-template-columns:[name] 1fr [actions] auto}.root.svelte-ogh8o0>div.svelte-ogh8o0:nth-child(1){grid-column-start:name;color:var(--secondary50)}.root.svelte-ogh8o0>div.svelte-ogh8o0:nth-child(2){grid-column-start:actions}.selectedname.svelte-ogh8o0{font-weight:bold;color:var(--secondary)}
textarea.svelte-1kv2xk7{width:300px;height:200px}

File diff suppressed because one or more lines are too long

View File

@ -20394,6 +20394,12 @@
fp_13(n => new RegExp(`${n.pathRegx()}$`).test(key)),
]);
const getNodeForCollectionPath = appHierarchy => collectionKey => $(appHierarchy, [
getFlattenedHierarchy,
fp_13(n => (isCollectionRecord(n)
&& new RegExp(`${n.collectionPathRegx()}$`).test(collectionKey))),
]);
const hasMatchingAncestor = ancestorPredicate => decendantNode => switchCase(
[node => isNothing(node.parent()),
@ -21015,6 +21021,8 @@
const getSampleFieldValue = field => getType(field.type).sampleValue;
const getNewFieldValue = field => getType(field.type).getNew(field);
const getDefaultOptions$1 = type => getType(type).getDefaultOptions();
const detectType = (value) => {
@ -21194,6 +21202,28 @@
setUserAccessLevels,
};
const getNew = app => (collectionKey, recordTypeName) => {
const recordNode = getRecordNode(app, collectionKey);
collectionKey=safeKey(collectionKey);
return apiWrapperSync(
app,
events.recordApi.getNew,
permission.createRecord.isAuthorized(recordNode.nodeKey()),
{ collectionKey, recordTypeName },
_getNew, recordNode, collectionKey,
);
};
const _getNew = (recordNode, collectionKey) => constructRecord(recordNode, getNewFieldValue, collectionKey);
const getRecordNode = (app, collectionKey) => {
collectionKey = safeKey(collectionKey);
return getNodeForCollectionPath(app.hierarchy)(collectionKey);
};
const getNewChild = app => (recordKey, collectionName, recordTypeName) =>
getNew(app)(joinKey(recordKey, collectionName), recordTypeName);
const constructRecord = (recordNode, getFieldValue, collectionKey) => {
const record = $(recordNode.fields, [
fp_30('name'),
@ -28096,6 +28126,16 @@
setUserAccessLevels: setUserAccessLevels$1(app),
});
const userWithFullAccess = (app) => {
app.user = {
name: "app",
permissions : generateFullPermissions(app),
isUser:false,
temp:false
};
return app.user;
};
const pipe$1 = common$1.$;
const events$1 = common$1.eventsList;
@ -28272,7 +28312,7 @@
if(obj[currentKey] === null
|| obj[currentKey] === undefined
|| !fp_27(obj.currentKey)) {
|| !fp_27(obj[currentKey])) {
obj[currentKey] = {};
}
@ -28289,8 +28329,11 @@
const getState = (s, path, fallback) => {
if(!s) return fallback;
if(!path || path.length === 0) return fallback;
if(path === "$") return s;
const pathParts = path.split(".");
const safeGetPath = (obj, currentPartIndex=0) => {
@ -28354,7 +28397,7 @@
return;
}
const records = api.get({
const records = await api.get({
url:`/api/listRecords/${trimSlash(indexKey)}`
});
@ -28383,13 +28426,41 @@
// set user even if error - so it is defined at least
api.setState(USER_STATE_PATH, user);
localStorage.setItem("budibase:user", user);
localStorage.setItem("budibase:user", JSON.stringify(user));
};
const saveRecord = (api) => async ({statePath}) => {
if(!statePath) {
api.error("Load Record: state path not set");
return;
}
const recordtoSave = api.getState(statePath);
if(!recordtoSave) {
api.error(`there is no record in state: ${statePath}`);
return;
}
if(!recordtoSave.key) {
api.error(`item in state does not appear to be a record - it has no key (${statePath})`);
return;
}
const savedRecord = await api.post({
url:`/api/record/${trimSlash(recordtoSave.key)}`,
body: recordtoSave
});
if(api.isSuccess(savedRecord))
api.setState(statePath, savedRecord);
};
const createApi = ({rootPath, setState, getState}) => {
const apiCall = (method) => ({url, body, notFound, badRequest, forbidden}) => {
fetch(`${rootPath}${url}`, {
return fetch(`${rootPath}${url}`, {
method: method,
headers: {
'Content-Type': 'application/json',
@ -28429,7 +28500,7 @@
return e;
};
const isSuccess = obj => !!obj[ERROR_MEMBER];
const isSuccess = obj => !obj || !obj[ERROR_MEMBER];
const apiOpts = {
rootPath, setState, getState, isSuccess, error,
@ -28439,11 +28510,12 @@
return {
loadRecord:loadRecord(apiOpts),
listRecords: listRecords(apiOpts),
authenticate: authenticate$1(apiOpts)
authenticate: authenticate$1(apiOpts),
saveRecord: saveRecord(apiOpts)
}
};
const getNewChildRecordToState = (store, coreApi, setState) =>
const getNewChildRecordToState = (coreApi, setState) =>
({recordKey, collectionName,childRecordType,statePath}) => {
const error = errorHandler(setState);
try {
@ -28468,7 +28540,7 @@
}
const rec = coreApi.recordApi.getNewChild(recordKey, collectionName, childRecordType);
setState(store, statePath, rec);
setState(statePath, rec);
}
catch(e) {
error(e.message);
@ -28476,7 +28548,7 @@
};
const getNewRecordToState = (store, coreApi, setState) =>
const getNewRecordToState = (coreApi, setState) =>
({collectionKey,childRecordType,statePath}) => {
const error = errorHandler(setState);
try {
@ -28496,7 +28568,7 @@
}
const rec = coreApi.recordApi.getNew(collectionKey, childRecordType);
setState(store, statePath, rec);
setState(statePath, rec);
}
catch(e) {
error(e.message);
@ -28515,10 +28587,15 @@
const setStateWithStore = (path, value) => setState(store, path, value);
let currentState;
store.subscribe(s => {
currentState = s;
});
const api = createApi({
rootPath:rootPath,
setState: (path, value) => setStateWithStore,
getState: (path, fallback) => getState(store, path, fallback)
setState: setStateWithStore,
getState: (path, fallback) => getState(currentState, path, fallback)
});
const setStateHandler = ({path, value}) => setState(store, path, value);
@ -28531,18 +28608,55 @@
"Get New Child Record": handler(
["recordKey", "collectionName", "childRecordType", "statePath"],
getNewChildRecordToState(store, coreApi, setStateWithStore)),
getNewChildRecordToState(coreApi, setStateWithStore)),
"Get New Record": handler(
["collectionKey", "childRecordType", "statePath"],
getNewRecordToState(store, coreApi, setStateWithStore)),
getNewRecordToState(coreApi, setStateWithStore)),
"Authenticate": handler(["username", "password"], api.authenticate)
};
};
const allHandlers$1 = () => {
const handlersObj = eventHandlers({}, {});
const createCoreApp = (appDefinition, user) => {
const app = {
datastore: null,
crypto:null,
publish: () => {},
hierarchy: appDefinition.hierarchy,
actions: appDefinition.actions,
user
};
return app;
};
const createCoreApi = (appDefinition, user) => {
const app = createCoreApp(appDefinition, user);
return {
recordApi: {
getNew: getNew(app),
getNewChild: getNewChild(app)
},
templateApi: {
constructHierarchy
}
}
};
const allHandlers$1 = (appDefinition, user) => {
const coreApi = createCoreApi(appDefinition, user);
appDefinition.hierarchy = coreApi.templateApi.constructHierarchy(appDefinition.hierarchy);
const store = writable({
_bbuser: user
});
const handlersObj = eventHandlers(store, coreApi);
const handlersArray = [];
for(let key in handlersObj) {
handlersArray.push({name:key, ...handlersObj[key]});
@ -29067,10 +29181,7 @@
initial.generators = generatorsArray(pkg.rootComponents.generators);
initial.allComponents = combineComponents(
pkg.derivedComponents, pkg.rootComponents.components);
initial.actions = fp_2((arr, action) => {
arr.push(action);
return arr;
})(pkg.appDefinition.actions, []);
initial.actions = fp_29(pkg.appDefinition.actions);
initial.triggers = pkg.appDefinition.triggers;
if(!!initial.hierarchy && !fp_9(initial.hierarchy)) {
@ -29605,7 +29716,7 @@
const appDefinition = {
hierarchy:s.hierarchy,
triggers:s.triggers,
actions: s.actions,
actions: fp_30("name")(s.actions),
props: {
main: buildPropsHierarchy(s.allComponents, s.pages.main.appBody),
unauthenticated: buildPropsHierarchy(s.allComponents, s.pages.unauthenticated.appBody)
@ -48414,7 +48525,7 @@
input = element("input");
attr_dev(input, "class", "uk-input uk-form-small svelte-jubmd5");
set_style(input, "flex", "1 0 auto");
add_location(input, file$d, 134, 4, 3275);
add_location(input, file$d, 134, 4, 3276);
dispose = [
listen_dev(input, "input", ctx.input_input_handler),
@ -48467,7 +48578,7 @@
each_blocks[i_1].c();
}
attr_dev(select, "class", "uk-select uk-form-small svelte-jubmd5");
add_location(select, file$d, 124, 4, 3016);
add_location(select, file$d, 124, 4, 3019);
dispose = listen_dev(select, "change", ctx.change_handler);
},
@ -48605,7 +48716,7 @@
t = text(t_value);
option.__value = option_value_value = ctx.option;
option.value = option.__value;
add_location(option, file$d, 128, 8, 3186);
add_location(option, file$d, 128, 8, 3187);
},
m: function mount(target, anchor) {
@ -48921,9 +49032,9 @@
const click_handler = () => $$invalidate('isExpanded', isExpanded=!isExpanded);
const click_handler_1 = () => $$invalidate('value', value = !value);
const click_handler_1 = () => onChanged(!value);
const change_handler = (ev) => onChanged(ev.target.checked);
const change_handler = (ev) => onChanged(ev.target.value);
function input_input_handler() {
value = this.value;
@ -49059,17 +49170,17 @@
return child_ctx;
}
// (64:8) {#each events as ev}
// (74:8) {#each events as ev}
function create_each_block_1$4(ctx) {
var option, t_value = ctx.ev.name + "", t;
var option, t_value = ctx.ev.name + "", t, option_value_value;
const block = {
c: function create() {
option = element("option");
t = text(t_value);
option.__value = ctx.ev.name;
option.__value = option_value_value = ctx.ev.name;
option.value = option.__value;
add_location(option, file$e, 64, 8, 1689);
add_location(option, file$e, 74, 8, 1965);
},
m: function mount(target, anchor) {
@ -49077,7 +49188,17 @@
append_dev(option, t);
},
p: noop,
p: function update(changed, ctx) {
if ((changed.events) && t_value !== (t_value = ctx.ev.name + "")) {
set_data_dev(t, t_value);
}
if ((changed.events) && option_value_value !== (option_value_value = ctx.ev.name)) {
prop_dev(option, "__value", option_value_value);
}
option.value = option.__value;
},
d: function destroy(detaching) {
if (detaching) {
@ -49085,11 +49206,11 @@
}
}
};
dispatch_dev("SvelteRegisterBlock", { block, id: create_each_block_1$4.name, type: "each", source: "(64:8) {#each events as ev}", ctx });
dispatch_dev("SvelteRegisterBlock", { block, id: create_each_block_1$4.name, type: "each", source: "(74:8) {#each events as ev}", ctx });
return block;
}
// (75:0) {#if parameters}
// (85:0) {#if parameters}
function create_if_block$6(ctx) {
var each_1_anchor, current;
@ -49176,11 +49297,11 @@
}
}
};
dispatch_dev("SvelteRegisterBlock", { block, id: create_if_block$6.name, type: "if", source: "(75:0) {#if parameters}", ctx });
dispatch_dev("SvelteRegisterBlock", { block, id: create_if_block$6.name, type: "if", source: "(85:0) {#if parameters}", ctx });
return block;
}
// (76:0) {#each parameters as p, index}
// (86:0) {#each parameters as p, index}
function create_each_block$6(ctx) {
var div, t0_value = ctx.p.name + "", t0, t1, current;
@ -49198,7 +49319,7 @@
t0 = text(t0_value);
t1 = space();
statebindingcontrol.$$.fragment.c();
add_location(div, file$e, 77, 0, 1930);
add_location(div, file$e, 87, 0, 2206);
},
m: function mount(target, anchor) {
@ -49240,7 +49361,7 @@
destroy_component(statebindingcontrol, detaching);
}
};
dispatch_dev("SvelteRegisterBlock", { block, id: create_each_block$6.name, type: "each", source: "(76:0) {#each parameters as p, index}", ctx });
dispatch_dev("SvelteRegisterBlock", { block, id: create_each_block$6.name, type: "each", source: "(86:0) {#each parameters as p, index}", ctx });
return block;
}
@ -49278,9 +49399,9 @@
if (if_block) if_block.c();
if_block_anchor = empty();
attr_dev(select, "class", "type-selector uk-select uk-form-small svelte-1b6pj9u");
add_location(select, file$e, 62, 4, 1547);
add_location(select, file$e, 72, 4, 1823);
attr_dev(div, "class", "type-selector-container svelte-1b6pj9u");
add_location(div, file$e, 61, 0, 1504);
add_location(div, file$e, 71, 0, 1780);
dispose = listen_dev(select, "change", ctx.eventTypeChanged);
},
@ -49412,11 +49533,20 @@
let { event, onChanged, onRemoved } = $$props;
const events = allHandlers$1();
let events;
let eventType;
let parameters = [];
store.subscribe(s => {
$$invalidate('events', events = allHandlers$1(
{hierarchy: s.hierarchy},
userWithFullAccess({
hierarchy: s.hierarchy,
actions: fp_30("name")(s.actions)
})
));
});
const eventChanged = (type, parameters) => {
const paramsAsObject = fp_2(
(obj, p) => {
@ -49457,13 +49587,14 @@
};
$$self.$capture_state = () => {
return { event, onChanged, onRemoved, eventType, parameters };
return { event, onChanged, onRemoved, events, eventType, parameters };
};
$$self.$inject_state = $$props => {
if ('event' in $$props) $$invalidate('event', event = $$props.event);
if ('onChanged' in $$props) $$invalidate('onChanged', onChanged = $$props.onChanged);
if ('onRemoved' in $$props) $$invalidate('onRemoved', onRemoved = $$props.onRemoved);
if ('events' in $$props) $$invalidate('events', events = $$props.events);
if ('eventType' in $$props) $$invalidate('eventType', eventType = $$props.eventType);
if ('parameters' in $$props) $$invalidate('parameters', parameters = $$props.parameters);
};
@ -53289,7 +53420,7 @@
const file$n = "src\\userInterface\\CurrentItemPreview.svelte";
// (38:4) {#if hasComponent}
// (39:4) {#if hasComponent}
function create_if_block$d(ctx) {
var iframe, iframe_srcdoc_value;
@ -53322,7 +53453,7 @@
</body>
</html>`);
attr_dev(iframe, "class", "svelte-teqoiq");
add_location(iframe, file$n, 38, 4, 982);
add_location(iframe, file$n, 39, 4, 1014);
},
m: function mount(target, anchor) {
@ -53362,7 +53493,7 @@
}
}
};
dispatch_dev("SvelteRegisterBlock", { block, id: create_if_block$d.name, type: "if", source: "(38:4) {#if hasComponent}", ctx });
dispatch_dev("SvelteRegisterBlock", { block, id: create_if_block$d.name, type: "if", source: "(39:4) {#if hasComponent}", ctx });
return block;
}
@ -53376,7 +53507,7 @@
div = element("div");
if (if_block) if_block.c();
attr_dev(div, "class", "component-container svelte-teqoiq");
add_location(div, file$n, 36, 0, 921);
add_location(div, file$n, 37, 0, 953);
},
l: function claim(nodes) {
@ -53435,7 +53566,8 @@
]));
$$invalidate('appDefinition', appDefinition = {
componentLibraries: s.loadLibraryUrls(),
props: buildPropsHierarchy(s.allComponents, s.currentFrontEndItem)
props: buildPropsHierarchy(s.allComponents, s.currentFrontEndItem),
hierarchy: s.hierarchy
});
});

File diff suppressed because one or more lines are too long

View File

@ -106,7 +106,7 @@ module.exports = (config, app) => {
if(!user) {
ctx.throw(StatusCodes.UNAUTHORIZED, "invalid username or password");
}
ctx.body = user;
ctx.body = user.user_json;
ctx.response.status = StatusCodes.OK;
})
.post("/:appname/api/setPasswordFromTemporaryCode", async (ctx) => {

View File

@ -87,6 +87,24 @@ module.exports = async (context) => {
}
};
const createAppUser = async (appname, instance, user, password) => {
if(isMaster(appname)) {
throw new Exception("This method is for creating app users - not on master!");
}
const versionId = determineVersionId(instance.version);
const dsConfig = JSON.parse(instance.datastoreconfig);
const appPackage = await applictionVersionPackage(
context, appname, versionId, instance.key);
const bbInstance = await getApisWithFullAccess(
datastoreModule.getDatastore(dsConfig),
appPackage
);
await bbInstance.authApi.createUser(user, password);
}
const authenticate = async (sessionId, appname, username, password, instanceName="default") => {
if(isMaster(appname)) {
@ -299,6 +317,7 @@ module.exports = async (context) => {
disableUser,
enableUser,
getUser,
createAppUser,
bbMaster:bb,
listApplications
});

View File

@ -366,5 +366,16 @@
"className":"string"
},
"tags": []
},
"if": {
"importPath": "if",
"name": "If",
"description": "An if condition.. if (CONDITION) THEN [display component A] ELSE [display component B]",
"props" : {
"condition": "string",
"thenComponent":{"type":"component", "required":true},
"elseComponent":"component"
},
"tags": []
}
}

File diff suppressed because one or more lines are too long

View File

@ -3,11 +3,11 @@
.root.svelte-crnq0a{height:100%;display:grid;grid-template-columns:[left] 1fr [middle] auto [right] 1fr;grid-template-rows:[top] 1fr [center] auto [bottom] 1fr}.content.svelte-crnq0a{grid-column-start:middle;grid-row-start:center;width:400px}.logo-container.svelte-crnq0a{margin-bottom:20px
}.logo-container.svelte-crnq0a>img.svelte-crnq0a{max-width:100%}.login-button-container.svelte-crnq0a{text-align:right;margin-top:20px}.incorrect-details-panel.svelte-crnq0a{margin-top:30px;padding:10px;border-style:solid;border-width:1px;border-color:maroon;border-radius:1px;text-align:center;color:maroon;background-color:mistyrose}.form-root.svelte-crnq0a{display:grid;grid-template-columns:[label] auto [control] 1fr}.label.svelte-crnq0a{grid-column-start:label;padding:5px 10px;vertical-align:middle}.control.svelte-crnq0a{grid-column-start:control;padding:5px 10px}.default-input.svelte-crnq0a{font-family:inherit;font-size:inherit;padding:0.4em;margin:0 0 0.5em 0;box-sizing:border-box;border:1px solid #ccc;border-radius:2px;width:100%}.default-button.svelte-crnq0a{font-family:inherit;font-size:inherit;padding:0.4em;margin:0 0 0.5em 0;box-sizing:border-box;border:1px solid #ccc;border-radius:2px;color:#333;background-color:#f4f4f4;outline:none}.default-button.svelte-crnq0a:active{background-color:#ddd}.default-button.svelte-crnq0a:focus{border-color:#666}
.form-root.svelte-m9d6ue{display:grid;grid-template-columns:[label] auto [control] 1fr}.label.svelte-m9d6ue{grid-column-start:label;padding:5px 10px;vertical-align:middle}.control.svelte-m9d6ue{grid-column-start:control;padding:5px 10px}.overflow.svelte-m9d6ue{grid-column-start:overflow}.full-width.svelte-m9d6ue{width:100%}
.panel.svelte-1nuhpxd:hover{background:var(--hoverBackground);color:var(--hoverColor)}
.root.svelte-aihwli{height:100%;width:100%;grid-template-columns:[navbar] auto [content] 1fr;display:grid}.navbar.svelte-aihwli{grid-column:navbar;background:var(--navBarBackground);border:var(--navBarBorder);color:var(--navBarColor)}.navitem.svelte-aihwli{padding:10px 17px;cursor:pointer}.navitem.svelte-aihwli:hover{background:var(--itemHoverBackground);color:var(--itemHoverColor)}.navitem.selected.svelte-aihwli{background:var(--selectedItemBackground);border:var(--selectedItemBorder);color:var(--selectedItemColor)}.content.svelte-aihwli{grid-column:content}
.default.svelte-1ec4wqj{width:100%;font-family:inherit;font-size:inherit;padding:0.4em;margin:0 0 0.5em 0;box-sizing:border-box;border:1px solid #ccc;border-radius:2px;width:100%}.default.svelte-1ec4wqj:disabled{color:#ccc}
.panel.svelte-6yfcjx:hover{background:var(--hoverBackground);color:var(--hoverColor)}
.horizontal.svelte-osi0db{display:inline-block}.vertical.svelte-osi0db{display:block}
.default.svelte-181okpd{font-family:inherit;font-size:inherit;padding:0.4em;margin:0 0 0.5em 0;box-sizing:border-box;border:1px solid #ccc;border-radius:2px;color:#333;background-color:#f4f4f4;outline:none}.default.svelte-181okpd:active{background-color:#ddd}.default.svelte-181okpd:focus{border-color:#666}.border.svelte-181okpd{border:var(--border)}.color.svelte-181okpd{color:var(--color)}.background.svelte-181okpd{background:var(--background)}.hoverBorder.svelte-181okpd:hover{border:var(--hoverBorder)}.hoverColor.svelte-181okpd:hover{color:var(--hoverColor)}.hoverBack.svelte-181okpd:hover{background:var(--hoverBackground)}
.table-default.svelte-h8rqk6{width:100%;margin-bottom:1rem;color:#212529;border-collapse:collapse}.table-default.svelte-h8rqk6 .thead-default .th-default.svelte-h8rqk6{vertical-align:bottom;border-bottom:2px solid #dee2e6;font-weight:bold}.table-default.svelte-h8rqk6 .th-default.svelte-h8rqk6{padding:.75rem;vertical-align:top;border-top:1px solid #dee2e6;font-weight:normal}.th-default.svelte-h8rqk6{text-align:inherit}.table-default.svelte-h8rqk6 .tbody-default .tr-default.svelte-h8rqk6:hover{color:#212529;background-color:rgba(0,0,0,.075);cursor:pointer}
.default.svelte-1q8lga0{font-family:inherit;font-size:inherit;padding:0.4em;margin:0 0 0.5em 0;box-sizing:border-box;border:1px solid #ccc;border-radius:2px;color:#333;background-color:#f4f4f4;outline:none}.default.svelte-1q8lga0:active{background-color:#ddd}.default.svelte-1q8lga0:focus{border-color:#666}
/*# sourceMappingURL=bundle.css.map */

View File

@ -6,25 +6,25 @@
"..\\src\\Grid.svelte",
"..\\src\\Login.svelte",
"..\\src\\Form.svelte",
"..\\src\\Panel.svelte",
"..\\src\\Nav.svelte",
"..\\src\\Textbox.svelte",
"..\\src\\Panel.svelte",
"..\\src\\StackPanel.svelte",
"..\\src\\Table.svelte",
"..\\src\\Button.svelte"
"..\\src\\Button.svelte",
"..\\src\\Table.svelte"
],
"sourcesContent": [
"<script>\nimport createApp from \"./createApp\";\nimport { props } from \"./props\";\n\nlet _bb;\n\nconst _appPromise = createApp();\n_appPromise.then(a => _bb = a);\n\nconst testProps = props.hiddenNav;\n\nlet currentComponent;\n\n$: {\n if(_bb && currentComponent) {\n _bb.hydrateComponent(testProps, currentComponent);\n }\n}\n\n\n\n</script>\n\n{#await _appPromise}\nloading\n{:then _bb}\n\n<div id=\"current_component\" bind:this={currentComponent}>\n</div>\n\n{/await}\n\n\n<style>\n#current_component {\n height: 100%;\n width: 100%;\n}\n</style>\n\n",
"<script>\nimport createApp from \"./createApp\";\nimport { props } from \"./props\";\n\nlet _bb;\n\nconst _appPromise = createApp();\n_appPromise.then(a => _bb = a);\n\nconst testProps = props.table;\n\nlet currentComponent;\n\n$: {\n if(_bb && currentComponent) {\n _bb.hydrateComponent(testProps, currentComponent);\n }\n}\n\n\n\n</script>\n\n{#await _appPromise}\nloading\n{:then _bb}\n\n<div id=\"current_component\" bind:this={currentComponent}>\n</div>\n\n{/await}\n\n\n<style>\n#current_component {\n height: 100%;\n width: 100%;\n}\n</style>\n\n",
"<script>\r\nimport { onMount } from 'svelte'\r\nimport {buildStyle} from \"./buildStyle\";\r\n\r\nexport let gridTemplateRows =\"\";\r\nexport let gridTemplateColumns =\"\";\r\nexport let children = [];\r\nexport let width = \"auto\";\r\nexport let height = \"auto\";\r\nexport let containerClass=\"\";\r\nexport let itemContainerClass=\"\";\r\n\r\n/*\"gridColumnStart\":\"string\",\r\n\"gridColumnEnd\":\"string\",\r\n\"gridRowStart\":\"string\",\r\n\"gridRowEnd\":\"string\"*/\r\n\r\n\r\nexport let _bb;\r\n\r\nlet style=\"\";\r\nlet htmlElements = {};\r\n\r\n$ : {\r\n if(_bb && htmlElements) {\r\n for(let el in htmlElements) {\r\n _bb.hydrateComponent(\r\n children[el].control,\r\n htmlElements[el]\r\n );\r\n }\r\n }\r\n}\r\n\r\nconst childStyle = child => \r\n buildStyle({\r\n \"grid-column-start\": child.gridColumnStart,\r\n \"grid-column-end\": child.gridColumnEnd,\r\n \"grid-column\": child.gridColumn,\r\n \"grid-row-start\": child.gridRowStart,\r\n \"grid-row-end\": child.gridRowStart,\r\n \"grid-row\": child.gridRow,\r\n });\r\n\r\n</script>\r\n\r\n<div class=\"root {containerClass}\"\r\n style=\"width: {width}; height: {height}; grid-template-columns: {gridTemplateColumns}; grid-template-rows: {gridTemplateRows};\">\r\n {#each children as child, index}\r\n <div class=\"{itemContainerClass}\"\r\n style={childStyle(child)}\r\n bind:this={htmlElements[index]}>\r\n </div>\r\n {/each}\r\n</div>\r\n\r\n<style>\r\n\r\n.root {\r\n display: grid;\r\n}\r\n\r\n</style>",
"<script>\n\nimport Textbox from \"./Textbox.svelte\";\nimport Form from \"./Form.svelte\";\nimport Button from \"./Button.svelte\";\n\nexport let usernameLabel = \"Username\";\nexport let passwordLabel = \"Password\";\nexport let loginButtonLabel = \"Login\";\nexport let loginRedirect = \"\";\nexport let logo = \"\";\nexport let buttonClass = \"\";\nexport let inputClass=\"\"\n\nexport let _bb;\n\nlet username = \"\";\nlet password = \"\";\nlet busy = false;\nlet incorrect = false;\nlet _logo = \"\";\nlet _buttonClass = \"\";\nlet _inputClass = \"\";\n\n$: {\n _logo = _bb.relativeUrl(logo);\n _buttonClass = buttonClass || \"default-button\";\n _inputClass = inputClass || \"default-input\";\n}\n\nconst login = () => {\n busy = true;\n _bb.api.post(\"/api/authenticate\", {username, password})\n .then(r => {\n busy = false;\n if(r.status === 200) {\n return r.json();\n } else {\n incorrect = true;\n return;\n }\n })\n .then(user => {\n if(user) {\n localStorage.setItem(\"budibase:user\", user);\n location.reload();\n }\n })\n}\n\n</script>\n\n<div class=\"root\">\n\n <div class=\"content\">\n\n {#if _logo}\n <div class=\"logo-container\">\n <img src={_logo} alt=\"logo\"/>\n </div>\n {/if}\n\n <div class=\"form-root\">\n <div class=\"label\">\n {usernameLabel}\n </div>\n <div class=\"control\">\n <input bind:value={username} type=\"text\" class={_inputClass}/>\n </div>\n <div class=\"label\">\n {passwordLabel}\n </div>\n <div class=\"control\">\n <input bind:value={password} type=\"password\" class={_inputClass}/>\n </div>\n </div>\n\n <div class=\"login-button-container\">\n <button disabled={busy} \n on:click={login}\n class={_buttonClass}>\n {loginButtonLabel}\n </button>\n </div>\n\n {#if incorrect}\n <div class=\"incorrect-details-panel\">\n Incorrect username or password\n </div>\n {/if}\n\n </div>\n\n</div>\n\n<style>\n\n.root {\n height: 100%;\n display:grid;\n grid-template-columns: [left] 1fr [middle] auto [right] 1fr;\n grid-template-rows: [top] 1fr [center] auto [bottom] 1fr;\n}\n\n.content {\n grid-column-start: middle;\n grid-row-start: center;\n width: 400px;\n}\n\n.logo-container {\n margin-bottom: 20px\n}\n\n.logo-container > img {\n max-width: 100%;\n}\n\n.login-button-container {\n text-align: right;\n margin-top: 20px;\n}\n\n.incorrect-details-panel {\n margin-top: 30px;\n padding: 10px;\n border-style: solid;\n border-width: 1px;\n border-color: maroon;\n border-radius: 1px;\n text-align: center;\n color: maroon;\n background-color: mistyrose;\n}\n\n.form-root {\n display: grid;\n grid-template-columns: [label] auto [control] 1fr; /* [overflow] auto;*/\n}\n\n.label {\n grid-column-start: label;\n padding: 5px 10px;\n vertical-align: middle;\n}\n.control {\n grid-column-start: control;\n padding: 5px 10px;\n}\n\n.default-input {\n\tfont-family: inherit;\n\tfont-size: inherit;\n\tpadding: 0.4em;\n\tmargin: 0 0 0.5em 0;\n\tbox-sizing: border-box;\n\tborder: 1px solid #ccc;\n border-radius: 2px;\n width: 100%;\n}\n\n.default-button {\n\tfont-family: inherit;\n\tfont-size: inherit;\n\tpadding: 0.4em;\n\tmargin: 0 0 0.5em 0;\n\tbox-sizing: border-box;\n\tborder: 1px solid #ccc;\n\tborder-radius: 2px;\n\tcolor: #333;\n\tbackground-color: #f4f4f4;\n\toutline: none;\n}\n\n.default-button:active {\n\tbackground-color: #ddd;\n}\n\n.default-button:focus {\n\tborder-color: #666;\n}\n\n</style>",
"<script>\n\nimport Textbox from \"./Textbox.svelte\";\nimport Form from \"./Form.svelte\";\nimport Button from \"./Button.svelte\";\n\nexport let usernameLabel = \"Username\";\nexport let passwordLabel = \"Password\";\nexport let loginButtonLabel = \"Login\";\nexport let loginRedirect = \"\";\nexport let logo = \"\";\nexport let buttonClass = \"\";\nexport let inputClass=\"\"\n\nexport let _bb;\n\nlet username = \"\";\nlet password = \"\";\nlet busy = false;\nlet incorrect = false;\nlet _logo = \"\";\nlet _buttonClass = \"\";\nlet _inputClass = \"\";\n\n$: {\n _logo = _bb.relativeUrl(logo);\n _buttonClass = buttonClass || \"default-button\";\n _inputClass = inputClass || \"default-input\";\n}\n\nconst login = () => {\n busy = true;\n _bb.api.post(\"/api/authenticate\", {username, password})\n .then(r => {\n busy = false;\n if(r.status === 200) {\n return r.json();\n } else {\n incorrect = true;\n return;\n }\n })\n .then(user => {\n if(user) {\n localStorage.setItem(\"budibase:user\", JSON.stringify(user));\n location.reload();\n }\n })\n}\n\n</script>\n\n<div class=\"root\">\n\n <div class=\"content\">\n\n {#if _logo}\n <div class=\"logo-container\">\n <img src={_logo} alt=\"logo\"/>\n </div>\n {/if}\n\n <div class=\"form-root\">\n <div class=\"label\">\n {usernameLabel}\n </div>\n <div class=\"control\">\n <input bind:value={username} type=\"text\" class={_inputClass}/>\n </div>\n <div class=\"label\">\n {passwordLabel}\n </div>\n <div class=\"control\">\n <input bind:value={password} type=\"password\" class={_inputClass}/>\n </div>\n </div>\n\n <div class=\"login-button-container\">\n <button disabled={busy} \n on:click={login}\n class={_buttonClass}>\n {loginButtonLabel}\n </button>\n </div>\n\n {#if incorrect}\n <div class=\"incorrect-details-panel\">\n Incorrect username or password\n </div>\n {/if}\n\n </div>\n\n</div>\n\n<style>\n\n.root {\n height: 100%;\n display:grid;\n grid-template-columns: [left] 1fr [middle] auto [right] 1fr;\n grid-template-rows: [top] 1fr [center] auto [bottom] 1fr;\n}\n\n.content {\n grid-column-start: middle;\n grid-row-start: center;\n width: 400px;\n}\n\n.logo-container {\n margin-bottom: 20px\n}\n\n.logo-container > img {\n max-width: 100%;\n}\n\n.login-button-container {\n text-align: right;\n margin-top: 20px;\n}\n\n.incorrect-details-panel {\n margin-top: 30px;\n padding: 10px;\n border-style: solid;\n border-width: 1px;\n border-color: maroon;\n border-radius: 1px;\n text-align: center;\n color: maroon;\n background-color: mistyrose;\n}\n\n.form-root {\n display: grid;\n grid-template-columns: [label] auto [control] 1fr; /* [overflow] auto;*/\n}\n\n.label {\n grid-column-start: label;\n padding: 5px 10px;\n vertical-align: middle;\n}\n.control {\n grid-column-start: control;\n padding: 5px 10px;\n}\n\n.default-input {\n\tfont-family: inherit;\n\tfont-size: inherit;\n\tpadding: 0.4em;\n\tmargin: 0 0 0.5em 0;\n\tbox-sizing: border-box;\n\tborder: 1px solid #ccc;\n border-radius: 2px;\n width: 100%;\n}\n\n.default-button {\n\tfont-family: inherit;\n\tfont-size: inherit;\n\tpadding: 0.4em;\n\tmargin: 0 0 0.5em 0;\n\tbox-sizing: border-box;\n\tborder: 1px solid #ccc;\n\tborder-radius: 2px;\n\tcolor: #333;\n\tbackground-color: #f4f4f4;\n\toutline: none;\n}\n\n.default-button:active {\n\tbackground-color: #ddd;\n}\n\n.default-button:focus {\n\tborder-color: #666;\n}\n\n</style>",
"<script>\nexport let containerClass = \"\";\nexport let formControls = [];\n\nexport let _bb;\n\nlet htmlElements = {};\nlet labels = {};\n\n$ : {\n let cIndex = 0;\n for(let c of formControls) {\n labels[cIndex] = c.label;\n cIndex++;\n }\n\n if(_bb && htmlElements) {\n for(let el in htmlElements) {\n _bb.hydrateComponent(\n formControls[el].control,\n htmlElements[el]\n );\n }\n }\n}\n\n</script>\n\n<div class=\"form-root {containerClass}\">\n {#each formControls as child, index}\n <div class=\"label\">{labels[index]}</div>\n <div class=\"control\"\n bind:this={htmlElements[index]}>\n </div>\n {/each}\n</div>\n\n<style>\n.form-root {\n display: grid;\n grid-template-columns: [label] auto [control] 1fr; /* [overflow] auto;*/\n}\n\n.label {\n grid-column-start: label;\n padding: 5px 10px;\n vertical-align: middle;\n}\n.control {\n grid-column-start: control;\n padding: 5px 10px;\n}\n.overflow {\n grid-column-start: overflow;\n}\n.full-width {\n width: 100%;\n}\n</style>",
"<script>\nimport {buildStyle} from \"./buildStyle\";\nimport cssVars from \"./cssVars\";\n\nexport let component=\"\";\nexport let text=\"\";\nexport let containerClass=\"\";\nexport let background=\"\";\nexport let border=\"\";\nexport let borderRadius=\"\";\nexport let font=\"\";\nexport let display=\"\";\nexport let textAlign=\"\";\nexport let color=\"\";\nexport let padding=\"\";\nexport let margin=\"\";\nexport let hoverBackground=\"\";\nexport let hoverColor=\"\";\nexport let onClick;\nexport let height;\nexport let width;\n\nexport let _bb;\n\nlet styleVars;\nlet style=\"\";\nlet componentElement;\nlet componentInitialised=false;\n\n$: {\n style=buildStyle({\n border, background, font, margin,\n padding, display, color, height, width,\n \"text-align\": textAlign,\n \"border-radius\":borderRadius,\n cursor: onClick ? \"pointer\" : \"none\"\n });\n\n if(_bb && component && componentElement && !componentInitialised) {\n _bb.hydrateComponent(component, componentElement);\n componentInitialised = true;\n }\n\n styleVars = {\n hoverBackground:hoverBackground || background, \n hoverColor:hoverColor || color\n }\n}\n\nconst clickHandler = () => {\n if(onClick) {\n _bb.call(onClick);\n }\n}\n\n</script>\n\n<div class=\"{containerClass} panel\" \n style={style}\n use:cssVars={styleVars}\n bind:this={componentElement}\n on:click={clickHandler}>\n {component && component._component ? \"\" : text}\n</div>\n\n<style>\n\n.panel:hover {\n background: var(--hoverBackground);\n color: var(--hoverColor);\n\n}\n\n</style>\n",
"<script>\r\nimport cssVars from \"./cssVars\";\r\n\r\nexport let navBarBackground = \"\";\r\nexport let navBarBorder=\"\";\r\nexport let navBarColor=\"\";\r\nexport let selectedItemBackground=\"\";\r\nexport let selectedItemColor=\"\";\r\nexport let selectedItemBorder=\"\";\r\nexport let itemHoverBackground=\"\";\r\nexport let itemHoverColor=\"\";\r\nexport let items = [];\r\nexport let hideNavBar=false;\r\nexport let selectedItem=\"\";\r\n\r\nexport let _bb;\r\n\r\nlet selectedIndex = -1;\r\nlet styleVars={};\r\nlet components = {};\r\nlet componentElements = {}\r\n\r\n\r\nconst hasComponentElements = () => \r\n Object.getOwnPropertyNames(componentElements).length > 0;\r\n\r\n$: {\r\n styleVars = {\r\n navBarBackground, navBarBorder,\r\n navBarColor, selectedItemBackground,\r\n selectedItemColor, selectedItemBorder,\r\n itemHoverBackground, itemHoverColor\r\n };\r\n\r\n if(items && items.length > 0 && hasComponentElements()) {\r\n const currentSelectedItem = selectedIndex > 0\r\n ? items[selectedIndex].title\r\n : \"\";\r\n if(selectedItem && currentSelectedItem !== selectedItem) {\r\n let i=0;\r\n for(let item of items) {\r\n if(item.title === selectedItem) {\r\n onSelectItem(i)();\r\n }\r\n i++;\r\n }\r\n } else if(!currentSelectedItem) {\r\n onSelectItem(0);\r\n }\r\n }\r\n}\r\n\r\nconst onSelectItem = (index) => () => {\r\n selectedIndex = index;\r\n if(!components[index]) {\r\n const comp = _bb.hydrateComponent(\r\n items[index].component, componentElements[index]);\r\n components[index] = comp; \r\n }\r\n}\r\n\r\n\r\n</script>\r\n\r\n<div class=\"root\" use:cssVars={styleVars}>\r\n {#if !hideNavBar}\r\n <div class=\"navbar\">\r\n {#each items as navItem, index}\r\n <div class=\"navitem\"\r\n on:click={onSelectItem(index)}\r\n class:selected={selectedIndex === index}>\r\n {navItem.title}\r\n </div>\r\n {/each}\r\n </div>\r\n {/if}\r\n {#each items as navItem, index}\r\n\r\n <div class=\"content\"\r\n bind:this={componentElements[index]}>\r\n </div>\r\n {/each}\r\n</div>\r\n\r\n<style>\r\n\r\n.root {\r\n height: 100%;\r\n width:100%;\r\n grid-template-columns: [navbar] auto [content] 1fr;\r\n display: grid;\r\n}\r\n\r\n.navbar {\r\n grid-column: navbar;\r\n background: var(--navBarBackground);\r\n border: var(--navBarBorder);\r\n color: var(--navBarColor);\r\n}\r\n\r\n.navitem {\r\n padding: 10px 17px;\r\n cursor: pointer;\r\n}\r\n\r\n.navitem:hover {\r\n background: var(--itemHoverBackground);\r\n color: var(--itemHoverColor);\r\n}\r\n\r\n.navitem.selected {\r\n background: var(--selectedItemBackground);\r\n border: var(--selectedItemBorder);\r\n color: var(--selectedItemColor);\r\n}\r\n\r\n.content {\r\n grid-column: content;\r\n}\r\n\r\n</style>\r\n\r\n",
"<script>\n\nexport let value=\"\";\nexport let hideValue = false;\nexport let className = \"default\";\n\nexport let _bb;\n\nlet actualValue = \"\";\n$: {\n\tif(_bb && value._isstate) {\n\t\t_bb.store.subscribe(s => {\n\t\t\tactualValue = _bb.store.getValue(s, value);\n\t\t});\n\t}\n}\n\nconst onchange = (ev) => {\n\tif(_bb && value._isstate) {\n\t\t_bb.store.setValue(value, ev.target.value);\n\t} else if(!value._isstate) {\n\t\tactualValue = ev.target.value;\n\t}\n}\n\n</script>\n\n{#if hideValue}\n<input class={className} \n\t type=\"password\" \n\t value={actualValue} on:change/>\n{:else}\n<input class={className} type=\"text\" value={actualValue}/>\n{/if}\n\n<style>\n.default {\n width: 100%;\n\tfont-family: inherit;\n\tfont-size: inherit;\n\tpadding: 0.4em;\n\tmargin: 0 0 0.5em 0;\n\tbox-sizing: border-box;\n\tborder: 1px solid #ccc;\n border-radius: 2px;\n width: 100%;\n}\n\n.default:disabled {\n\tcolor: #ccc;\n}\n\n</style>",
"<script>\r\nimport {buildStyle} from \"./buildStyle\";\r\nimport cssVars from \"./cssVars\";\r\n\r\nexport let component=\"\";\r\nexport let text=\"\";\r\nexport let containerClass=\"\";\r\nexport let background=\"\";\r\nexport let border=\"\";\r\nexport let borderRadius=\"\";\r\nexport let font=\"\";\r\nexport let display=\"\";\r\nexport let textAlign=\"\";\r\nexport let color=\"\";\r\nexport let padding=\"\";\r\nexport let margin=\"\";\r\nexport let hoverBackground=\"\";\r\nexport let hoverColor=\"\";\r\nexport let onClick;\r\nexport let height;\r\nexport let width;\r\n\r\nexport let _bb;\r\n\r\nlet styleVars;\r\nlet style=\"\";\r\nlet componentElement;\r\n\r\n$: {\r\n style=buildStyle({\r\n border, background, font, margin,\r\n padding, display, color, height, width,\r\n \"text-align\": textAlign,\r\n \"border-radius\":borderRadius,\r\n cursor: onClick ? \"pointer\" : \"none\"\r\n });\r\n\r\n if(_bb && component) {\r\n _bb.hydrateComponent(component, componentElement);\r\n }\r\n\r\n styleVars = {\r\n hoverBackground:hoverBackground || background, \r\n hoverColor:hoverColor || color\r\n }\r\n}\r\n\r\nconst clickHandler = () => {\r\n if(onClick) onClick();\r\n}\r\n\r\n</script>\r\n\r\n<div class=\"{containerClass} panel\" \r\n style={style}\r\n use:cssVars={styleVars}\r\n this:bind={componentElement}\r\n on:click={clickHandler}>\r\n {component && component._component ? \"\" : text}\r\n</div>\r\n\r\n<style>\r\n\r\n.panel:hover {\r\n background: var(--hoverBackground);\r\n color: var(--hoverColor);\r\n\r\n}\r\n\r\n</style>\r\n",
"<script>\n\nimport { emptyProps } from \"./emptyProps\";\n\nexport let direction = \"horizontal\";\nexport let children = [];\nexport let width = \"auto\";\nexport let height = \"auto\";\nexport let containerClass=\"\";\nexport let itemContainerClass=\"\";\nexport let onLoad;\n\nexport let data=[];\nexport let dataItemComponent;\n\nexport let _bb;\n\nlet staticHtmlElements = {};\nlet staticComponents = {};\nlet dataBoundElements = {};\nlet dataBoundComponents = {};\n\nlet onLoadCalled = false;\n\nconst hasDataBoundComponents = () => \n Object.getOwnPropertyNames(dataBoundComponents).length > 0;\n\nconst hasData = () => \n Array.isArray(data) && data.length > 0;\n\nconst hasStaticComponents = () => {\n return Object.getOwnPropertyNames(staticComponents).length > 0;\n}\n\n$: {\n\n if(staticHtmlElements) {\n if(hasStaticComponents()) {\n for(let c in staticComponents) {\n staticComponents[c].$destroy();\n }\n staticComponents = {};\n }\n\n for(let el in staticHtmlElements) {\n staticComponents[el] = _bb.hydrateComponent(\n children[el].control,\n staticHtmlElements[el]\n );\n }\n }\n \n\n if(hasDataBoundComponents()) {\n for(let c in dataBoundComponents) {\n dataBoundComponents[c].$destroy();\n }\n dataBoundComponents = {};\n }\n\n if(hasData()) {\n let index = 0;\n for(let d in dataBoundElements) {\n _bb.hydrateComponent(\n dataItemComponent,\n dataBoundElements[d],\n data[parseInt(d)]\n );\n }\n }\n\n if(!onLoadCalled && onLoad && !onLoad.isPlaceholder) {\n onLoad();\n onLoadCalled = true;\n }\n}\n\n\n</script>\n\n<div class=\"root {containerClass}\"\n style=\"width: {width}; height: {height}\">\n\n {#if children}\n {#each children as child, index}\n <div class={direction}>\n <div class=\"{itemContainerClass}\"\n bind:this={staticHtmlElements[index]}>\n </div>\n </div>\n {/each}\n {/if}\n\n {#if data && data.length > 0}\n {#each data as child, index}\n <div class={direction}>\n <div class=\"{itemContainerClass}\"\n bind:this={dataBoundElements[index]}>\n </div>\n </div>\n {/each}\n {/if}\n</div>\n\n<style>\n\n.horizontal {\n display:inline-block;\n}\n\n.vertical {\n display: block;\n}\n\n</style>",
"<script>\r\n\r\nexport let columns=[];\r\nexport let data=\"\";\r\nexport let tableClass=\"\";\r\nexport let theadClass=\"\";\r\nexport let tbodyClass=\"\";\r\nexport let trClass=\"\";\r\nexport let thClass=\"\";\r\nexport let onRowClick;\r\n\r\nexport let _bb;\r\n\r\nconst rowClickHandler = (row) => () => {\r\n onRowClick(row);\r\n}\r\n\r\n</script>\r\n\r\n <table class={tableClass}>\r\n <thead class={theadClass}>\r\n <tr class={trClass}>\r\n {#each columns as col}\r\n <th class={thClass}>{col.title}</th>\r\n {/each}\r\n </tr>\r\n </thead>\r\n <tbody class={tbodyClass}>\r\n {#each data as row}\r\n <tr class={trClass}\r\n on:click={rowClickHandler(row)} >\r\n {#each columns as col}\r\n <th class={thClass}>{_bb.getStateOrValue(col.value, row)}</th>\r\n {/each}\r\n </tr>\r\n {/each}\r\n </tbody>\r\n</table> \r\n\r\n<style>\r\n\r\n.table-default {\r\n width: 100%;\r\n margin-bottom: 1rem;\r\n color: #212529;\r\n border-collapse: collapse;\r\n}\r\n\r\n.table-default .thead-default .th-default {\r\n vertical-align: bottom;\r\n border-bottom: 2px solid #dee2e6;\r\n font-weight: bold;\r\n}\r\n\r\n.table-default .th-default {\r\n padding: .75rem;\r\n vertical-align: top;\r\n border-top: 1px solid #dee2e6;\r\n font-weight: normal;\r\n}\r\n\r\n.th-default {\r\n text-align: inherit;\r\n}\r\n\r\n.table-default .tbody-default .tr-default:hover {\r\n color: #212529;\r\n background-color: rgba(0,0,0,.075);\r\n cursor: pointer;\r\n}\r\n\r\n</style>",
"<script>\nexport let className = \"default\";\nexport let disabled = false;\nexport let contentText;\nexport let contentComponent;\nexport let onClick = () => {};\n\nexport let _bb;\nlet contentComponentContainer;\n\n$:{\n\tif(_bb && contentComponentContainer && contentComponent._component)\n\t\t_bb.hydrateComponent(contentComponent, contentComponentContainer);\n}\n\n\nconst clickHandler = () => {\n\tif(onClick) onClick();\n}\n\n</script>\n\n\n<button class={className} {disabled} on:click={clickHandler}>\n {#if contentComponent && contentComponent._component}\n\t<div bind:this={contentComponentContainer}>\n\t</div>\n {:else if contentText}\n {contentText}\n {:else}\n <slot />\n {/if}\n</button>\n\n\n<style>\n\n.default {\n\tfont-family: inherit;\n\tfont-size: inherit;\n\tpadding: 0.4em;\n\tmargin: 0 0 0.5em 0;\n\tbox-sizing: border-box;\n\tborder: 1px solid #ccc;\n\tborder-radius: 2px;\n\tcolor: #333;\n\tbackground-color: #f4f4f4;\n\toutline: none;\n}\n\n.default:active {\n\tbackground-color: #ddd;\n}\n\n.default:focus {\n\tborder-color: #666;\n}\n\n</style>"
"<script>\n\nexport let value=\"\";\nexport let hideValue = false;\nexport let className = \"default\";\n\nexport let _bb;\n\nlet actualValue = \"\";\n\nconst onchange = (ev) => {\n\tif(_bb) {\n\t\t_bb.setStateFromBinding(_bb.bindings.value, ev.target.value);\n\t}\n}\n\n</script>\n\n{#if hideValue}\n<input class={className} \n\t type=\"password\" \n\t value={value} \n\t on:change={onchange}/>\n{:else}\n<input class={className} \n\t type=\"text\" \n\t value={value}\n\t on:change={onchange}/>\n{/if}\n\n<style>\n.default {\n width: 100%;\n\tfont-family: inherit;\n\tfont-size: inherit;\n\tpadding: 0.4em;\n\tmargin: 0 0 0.5em 0;\n\tbox-sizing: border-box;\n\tborder: 1px solid #ccc;\n border-radius: 2px;\n width: 100%;\n}\n\n.default:disabled {\n\tcolor: #ccc;\n}\n\n</style>",
"<script>\n\nimport { emptyProps } from \"./emptyProps\";\n\nexport let direction = \"horizontal\";\nexport let children = [];\nexport let width = \"auto\";\nexport let height = \"auto\";\nexport let containerClass=\"\";\nexport let itemContainerClass=\"\";\nexport let onLoad;\n\nexport let data=[];\nexport let dataItemComponent;\n\nexport let _bb;\n\nlet staticHtmlElements = {};\nlet staticComponents = {};\nlet dataBoundElements = {};\nlet dataBoundComponents = {};\n\nlet onLoadCalled = false;\n\nconst hasDataBoundComponents = () => \n Object.getOwnPropertyNames(dataBoundComponents).length > 0;\n\nconst hasData = () => \n Array.isArray(data) && data.length > 0;\n\nconst hasStaticComponents = () => {\n return Object.getOwnPropertyNames(staticComponents).length > 0;\n}\n\n$: {\n\n if(staticHtmlElements) {\n if(hasStaticComponents()) {\n for(let c in staticComponents) {\n staticComponents[c].$destroy();\n }\n staticComponents = {};\n }\n\n for(let el in staticHtmlElements) {\n staticComponents[el] = _bb.hydrateComponent(\n children[el].control,\n staticHtmlElements[el]\n );\n }\n }\n \n\n if(hasDataBoundComponents()) {\n for(let c in dataBoundComponents) {\n dataBoundComponents[c].$destroy();\n }\n dataBoundComponents = {};\n }\n\n if(hasData()) {\n let index = 0;\n for(let d in dataBoundElements) {\n _bb.hydrateComponent(\n dataItemComponent,\n dataBoundElements[d],\n data[parseInt(d)]\n );\n }\n }\n\n if(!onLoadCalled && onLoad && !onLoad.isPlaceholder) {\n _bb.call(onLoad);\n onLoadCalled = true;\n }\n}\n\n\n</script>\n\n<div class=\"root {containerClass}\"\n style=\"width: {width}; height: {height}\">\n\n {#if children}\n {#each children as child, index}\n <div class={direction}>\n <div class=\"{itemContainerClass}\"\n bind:this={staticHtmlElements[index]}>\n </div>\n </div>\n {/each}\n {/if}\n\n {#if data && data.length > 0}\n {#each data as child, index}\n <div class={direction}>\n <div class=\"{itemContainerClass}\"\n bind:this={dataBoundElements[index]}>\n </div>\n </div>\n {/each}\n {/if}\n</div>\n\n<style>\n\n.horizontal {\n display:inline-block;\n}\n\n.vertical {\n display: block;\n}\n\n</style>",
"<script>\nimport cssVars from \"./cssVars\";\nimport {buildStyle} from \"./buildStyle\";\nexport let className = \"default\";\nexport let disabled = false;\nexport let contentText;\nexport let contentComponent;\nexport let onClick;\nexport let background;\nexport let color;\nexport let border;\nexport let padding;\nexport let hoverColor;\nexport let hoverBackground;\nexport let hoverBorder;\n\nexport let _bb;\nlet contentComponentContainer;\nlet cssVariables;\nlet buttonStyles;\n\nlet customHoverColorClass;\nlet customHoverBorderClass;\nlet customHoverBackClass;\n\nlet customClasses = \"\";\n\nconst createClasses = (classes) => {\n\tlet all = \"\";\n\tfor(let cls in classes) {\n\t\tif(classes[cls]) {\n\t\t\tall = all + \" \" + cls;\n\t\t}\n\t}\n\treturn all;\n}\n\t\n\n$:{\n\tif(_bb && contentComponentContainer && contentComponent._component)\n\t\t_bb.hydrateComponent(contentComponent, contentComponentContainer);\n\n\tcssVariables = {\n\t\thoverColor, hoverBorder,\n\t\thoverBackground,\n\t\tbackground, color, border,\n\t};\n\n\tbuttonStyles = buildStyle({\n\t\tpadding\n\t});\t\n\t\n\tcustomClasses = createClasses({\n\t\thoverColor, hoverBorder, hoverBackground,\n\t\tbackground, border, color\n\t});\n\t\n}\n\n\n\n\nconst clickHandler = () => {\n\t_bb.call(onClick);\n}\n\n</script>\n\n\n<button use:cssVars={cssVariables} \n\t\tclass=\"{className} {customClasses}\" \n\t\tdisabled={disabled || false} \n\t\ton:click={clickHandler} \n\t\tstyle={buttonStyles}>\n {#if contentComponent && contentComponent._component}\n\t<div bind:this={contentComponentContainer}>\n\t</div>\n {:else if contentText}\n {contentText}\n {:else}\n <slot />\n {/if}\n</button>\n\n\n<style>\n\n.default {\n\tfont-family: inherit;\n\tfont-size: inherit;\n\tpadding: 0.4em;\n\tmargin: 0 0 0.5em 0;\n\tbox-sizing: border-box;\n\tborder: 1px solid #ccc;\n\tborder-radius: 2px;\n\tcolor: #333;\n\tbackground-color: #f4f4f4;\n\toutline: none;\n}\n\n.default:active {\n\tbackground-color: #ddd;\n}\n\n.default:focus {\n\tborder-color: #666;\n}\n\n.border {\n\tborder: var(--border);\n}\n\n.color {\n\tcolor: var(--color);\n}\n\n.background {\n\tbackground: var(--background);\n}\n\n.hoverBorder:hover {\n\tborder: var(--hoverBorder);\n}\n\n.hoverColor:hover {\n\tcolor: var(--hoverColor);\n}\n\n.hoverBack:hover {\n\tbackground: var(--hoverBackground);\n}\n\n\n</style>",
"<script>\r\n\r\nexport let columns=[];\r\nexport let data=\"\";\r\nexport let tableClass=\"\";\r\nexport let theadClass=\"\";\r\nexport let tbodyClass=\"\";\r\nexport let trClass=\"\";\r\nexport let thClass=\"\";\r\nexport let onRowClick;\r\n\r\nexport let _bb;\r\n\r\nconst rowClickHandler = (row) => () => {\r\n _bb.call(onRowClick, row);\r\n}\r\n\r\nconst cellValue = (colIndex, row) => \r\n _bb.getStateOrValue(\r\n _bb.bindings.columns[colIndex].value\r\n , row)\r\n\r\n\r\n</script>\r\n\r\n <table class={tableClass}>\r\n <thead class={theadClass}>\r\n <tr class={trClass}>\r\n {#each columns as col}\r\n <th class={thClass}>{col.title}</th>\r\n {/each}\r\n </tr>\r\n </thead>\r\n <tbody class={tbodyClass}>\r\n {#if data}\r\n {#each data as row}\r\n <tr class={trClass}\r\n on:click={rowClickHandler(row)} >\r\n {#each columns as col, index}\r\n <th class={thClass}>{cellValue(index, row)}</th>\r\n {/each}\r\n </tr>\r\n {/each}\r\n {/if}\r\n </tbody>\r\n</table> \r\n\r\n<style>\r\n\r\n.table-default {\r\n width: 100%;\r\n margin-bottom: 1rem;\r\n color: #212529;\r\n border-collapse: collapse;\r\n}\r\n\r\n.table-default .thead-default .th-default {\r\n vertical-align: bottom;\r\n border-bottom: 2px solid #dee2e6;\r\n font-weight: bold;\r\n}\r\n\r\n.table-default .th-default {\r\n padding: .75rem;\r\n vertical-align: top;\r\n border-top: 1px solid #dee2e6;\r\n font-weight: normal;\r\n}\r\n\r\n.th-default {\r\n text-align: inherit;\r\n}\r\n\r\n.table-default .tbody-default .tr-default:hover {\r\n color: #212529;\r\n background-color: rgba(0,0,0,.075);\r\n cursor: pointer;\r\n}\r\n\r\n</style>"
],
"names": [],
"mappings": "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"
"mappings": "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"
}

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -8,7 +8,7 @@ import json from 'rollup-plugin-json';
const production = !process.env.ROLLUP_WATCH;
const lodash_fp_exports = [
"find", "isUndefined", "split",
"find", "isUndefined", "split", "max",
"last", "union", "reduce", "isObject",
"cloneDeep", "some", "isArray", "map",
"filter", "keys", "isFunction", "isEmpty",
@ -20,7 +20,7 @@ const lodash_fp_exports = [
"isInteger", "toNumber"];
const lodash_exports = [
"flow", "head",
"flow", "head", "find","each",
"tail", "findIndex", "startsWith",
"dropRight", "takeRight",
"trim", "split", "replace",

View File

@ -19,38 +19,41 @@ const hasData = () =>
$: {
if(children && children.length > 0 && !staticComponentsApplied) {
for(let child of children) {
_bb.appendComponent(
child.control,
rootDiv);
}
}
if(previousData !== data) {
for(let c of dataBoundComponents) {
dataBoundComponents[c].$destroy();
}
dataBoundComponents = [];
if(hasData()) {
let index = 0;
for(let dataItem of data) {
if(rootDiv) {
if(children && children.length > 0 && !staticComponentsApplied) {
for(let child of children) {
_bb.appendComponent(
dataItemComponent,
rootDiv,
dataItem
);
child.component,
rootDiv);
}
staticComponentsApplied = true;
}
if(previousData !== data) {
for(let c of dataBoundComponents) {
dataBoundComponents[c].$destroy();
}
dataBoundComponents = [];
if(hasData()) {
let index = 0;
for(let dataItem of data) {
_bb.appendComponent(
dataItemComponent,
rootDiv,
dataItem
);
}
}
}
}
if(!onLoadCalled && onLoad && !onLoad.isPlaceholder) {
_bb.call(onLoad);
onLoadCalled = true;
if(!onLoadCalled && onLoad && !onLoad.isPlaceholder) {
_bb.call(onLoad);
onLoadCalled = true;
}
}
}

View File

@ -0,0 +1,49 @@
<script>
export let condition;
export let thenComponent;
export let elseComponent;
export let _bb;
let element;
let currentEvalResult=null;
let currentComponent;
let state;
_bb.store.subscribe(s => {
state = s;
})
$: {
if(_bb && element && state) {
let result;
try {
let $store = state;
let $context = _bb.context;
result = !!(Function(`"use strict";return (function($store, $context) { return (${condition}); });`)()($store, $context));
} catch(e) {
console.log("If condition eval error: " + e.message)
}
if(result !== currentEvalResult) {
currentEvalResult = result;
if(currentComponent) {
currentComponent.$destroy();
}
if(result) {
currentComponent = _bb.hydrateComponent(
thenComponent,element);
} else if(elseComponent && elseComponent._component) {
currentComponent = _bb.hydrateComponent(
elseComponent,element);
}
}
}
}
</script>
<div bind:this={element}></div>

View File

@ -42,7 +42,7 @@ const login = () => {
})
.then(user => {
if(user) {
localStorage.setItem("budibase:user", user);
localStorage.setItem("budibase:user", JSON.stringify(user));
location.reload();
}
})

View File

@ -48,7 +48,9 @@ $: {
}
const clickHandler = () => {
if(onClick) onClick();
if(onClick) {
_bb.call(onClick);
}
}
</script>

View File

@ -15,6 +15,14 @@ const rowClickHandler = (row) => () => {
_bb.call(onRowClick, row);
}
const cellValue = (colIndex, row) => {
const val = _bb.getStateOrValue(
_bb.bindings.columns[colIndex].value
, row)
return val;
}
</script>
<table class={tableClass}>
@ -26,14 +34,16 @@ const rowClickHandler = (row) => () => {
</tr>
</thead>
<tbody class={tbodyClass}>
{#if data}
{#each data as row}
<tr class={trClass}
on:click={rowClickHandler(row)} >
{#each columns as col}
<th class={thClass}>{_bb.getStateOrValue(col.value, row)}</th>
{#each columns as col, index}
<th class={thClass}>{cellValue(index, row)}</th>
{/each}
</tr>
{/each}
{/if}
</tbody>
</table>

View File

@ -7,7 +7,7 @@ let _bb;
const _appPromise = createApp();
_appPromise.then(a => _bb = a);
const testProps = props.hiddenNav;
const testProps = props.table;
let currentComponent;

View File

@ -7,8 +7,13 @@ export const nav = ({records, indexes, helpers}) => [
props: {
items: indexes
.filter(i => i.parent().type === "root")
.map(navItem)
}
.map(navItem),
selectedItem: {
"##bbstate": "selectedNav",
"##bbstatefallback": records[0].collectionName,
"##bbsource":"store"
}
},
},
...indexTables({records, indexes, helpers})
]

View File

@ -1,9 +1,20 @@
export {default as button} from "./Button.svelte";
export {default as login} from "./Login.svelte";
export {default as div} from "./Div.svelte";
export {default as form} from "./Form.svelte";
export {default as grid} from "./Grid.svelte";
export {default as textbox} from "./Textbox.svelte";
export {default as stackpanel} from "./StackPanel.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 if} from "./If.svelte";
export {default as input} from "./Input.svelte";
export {default as login} from "./Login.svelte";
export {default as nav} from "./Nav.svelte";
export {default as panel} from "./Panel.svelte";
export {default as select} from "./Select.svelte";
export {default as stackpanel} from "./StackPanel.svelte";
export {default as table} from "./Table.svelte";
export {default as text} from "./Text.svelte";
export {default as textbox} from "./Textbox.svelte";