mirror of https://github.com/Budibase/budibase.git
50 changed files with 1044 additions and 618 deletions
@ -0,0 +1 @@ |
|||
export const EVENT_TYPE_MEMBER_NAME = "##eventHandlerType"; |
|||
@ -1,25 +1,32 @@ |
|||
import { createApp } from "./createApp"; |
|||
|
|||
const appDefinition = window["##BUDIBASE_APPDEFINITION##"]; |
|||
|
|||
const componentLibraryUrl = (lib) => "./" + trimSlash(lib) |
|||
export const loadBudibase = async (componentLibraries, props) => { |
|||
|
|||
const trimSlash = (str) => str.replace(/^\/+|\/+$/g, ''); |
|||
const appDefinition = window["##BUDIBASE_APPDEFINITION##"]; |
|||
|
|||
(async () => { |
|||
|
|||
const componentLibraries = {}; |
|||
if(!componentLibraries) { |
|||
|
|||
const componentLibraryUrl = (lib) => "./" + trimSlash(lib) |
|||
const trimSlash = (str) => str.replace(/^\/+|\/+$/g, ''); |
|||
componentLibraries = {}; |
|||
|
|||
for(let lib of appDefinition.componentLibraries) { |
|||
componentLibraries[lib.libName] = await import( |
|||
componentLibraryUrl(lib.importPath)); |
|||
} |
|||
|
|||
for(let lib of appDefinition.componentLibraries) { |
|||
componentLibraries[lib.libName] = await import( |
|||
componentLibraryUrl(lib.importPath)); |
|||
} |
|||
|
|||
if(!props) { |
|||
props = appDefinition.props; |
|||
} |
|||
|
|||
const _app = createApp(componentLibraries); |
|||
|
|||
_app.initialiseComponent( |
|||
props, |
|||
document.body); |
|||
|
|||
})(); |
|||
}; |
|||
|
|||
window.loadBudibase = loadBudibase; |
|||
@ -0,0 +1,26 @@ |
|||
import { |
|||
setState |
|||
} from "./setState"; |
|||
import { |
|||
isArray, isUndefined |
|||
} from "lodash/fp"; |
|||
|
|||
export const EVENT_TYPE_MEMBER_NAME = "##eventHandlerType"; |
|||
|
|||
export const eventHandlers = store => { |
|||
|
|||
const handler = (parameters, execute) => ({ |
|||
execute, parameters |
|||
}); |
|||
|
|||
const setStateHandler = ({path, value}) => setState(store, path, value); |
|||
|
|||
return { |
|||
"Set State": handler(["path", "value"], setStateHandler) |
|||
}; |
|||
}; |
|||
|
|||
export const isEventType = prop => |
|||
isArray(prop) |
|||
&& prop.length > 0 |
|||
&& !isUndefined(prop[0][EVENT_TYPE_MEMBER_NAME]); |
|||
@ -0,0 +1,34 @@ |
|||
import { |
|||
isUndefined, |
|||
isObject |
|||
} from "lodash/fp"; |
|||
|
|||
export const getState = (s, path, fallback) => { |
|||
|
|||
const pathParts = path.split("."); |
|||
const safeGetPath = (obj, currentPartIndex=0) => { |
|||
|
|||
const currentKey = pathParts[currentPartIndex]; |
|||
|
|||
if(pathParts.length - 1 == currentPartIndex) { |
|||
const value = obj[currentKey]; |
|||
if(isUndefined(value)) |
|||
return fallback; |
|||
else |
|||
return value; |
|||
} |
|||
|
|||
if(obj[currentKey] === null |
|||
|| obj[currentKey] === undefined |
|||
|| !isObject(obj[currentKey])) { |
|||
|
|||
return fallback; |
|||
} |
|||
|
|||
return safeGetPath(obj[currentKey], currentPartIndex + 1); |
|||
|
|||
} |
|||
|
|||
|
|||
return safeGetPath(s); |
|||
} |
|||
@ -0,0 +1,33 @@ |
|||
import { |
|||
isObject |
|||
} from "lodash/fp"; |
|||
|
|||
|
|||
export const setState = (store, path, value) => { |
|||
|
|||
const pathParts = path.split("."); |
|||
const safeSetPath = (obj, currentPartIndex=0) => { |
|||
|
|||
const currentKey = pathParts[currentPartIndex]; |
|||
|
|||
if(pathParts.length - 1 == currentPartIndex) { |
|||
obj[currentKey] = value; |
|||
return; |
|||
} |
|||
|
|||
if(obj[currentKey] === null |
|||
|| obj[currentKey] === undefined |
|||
|| !isObject(obj.currentKey)) { |
|||
|
|||
obj[currentKey] = {}; |
|||
} |
|||
|
|||
safeSetPath(obj[currentKey], currentPartIndex + 1); |
|||
|
|||
} |
|||
|
|||
store.update(s => { |
|||
safeSetPath(s); |
|||
return s; |
|||
}); |
|||
} |
|||
@ -0,0 +1,118 @@ |
|||
import { |
|||
isEventType, eventHandlers, EVENT_TYPE_MEMBER_NAME |
|||
} from "./eventHandlers"; |
|||
|
|||
import { |
|||
getState |
|||
} from "./getState"; |
|||
|
|||
export const BB_STATE_BINDINGPATH = "##bbstate"; |
|||
export const BB_STATE_FALLBACK = "##bbstatefallback"; |
|||
const doNothing = () => {}; |
|||
export const setupBinding = (store, props) => { |
|||
|
|||
const initialProps = {...props}; |
|||
const boundProps = []; |
|||
const componentEventHandlers = []; |
|||
|
|||
for(let propName in props) { |
|||
const val = initialProps[propName]; |
|||
|
|||
if(isState(val)) { |
|||
|
|||
const binding = stateBinding(val); |
|||
const fallback = stateFallback(val); |
|||
|
|||
boundProps.push({ |
|||
stateBinding:binding, |
|||
fallback, propName |
|||
}); |
|||
|
|||
initialProps[propName] = fallback; |
|||
} else if(isEventType(val)) { |
|||
|
|||
const handlers = { propName, handlers:[] }; |
|||
componentEventHandlers.push(handlers); |
|||
|
|||
for(let e of val) { |
|||
handlers.handlers.push({ |
|||
handlerType: e[EVENT_TYPE_MEMBER_NAME], |
|||
parameters: e.parameters |
|||
}) |
|||
} |
|||
|
|||
initialProps[propName] = doNothing; |
|||
} |
|||
|
|||
} |
|||
|
|||
const bind = (component) => { |
|||
|
|||
if(boundProps.length === 0 && componentEventHandlers.length === 0) return; |
|||
|
|||
const handlerTypes = eventHandlers(store); |
|||
|
|||
const unsubscribe = store.subscribe(s => { |
|||
const newProps = {}; |
|||
|
|||
for(let boundProp of boundProps) { |
|||
const val = getState( |
|||
s, |
|||
boundProp.stateBinding, |
|||
boundProp.fallback); |
|||
|
|||
if(val === undefined && newProps[boundProp.propName] !== undefined) { |
|||
delete newProps[boundProp.propName]; |
|||
} |
|||
|
|||
if(val !== undefined) { |
|||
newProps[boundProp.propName] = val; |
|||
} |
|||
} |
|||
|
|||
for(let boundHandler of componentEventHandlers) { |
|||
|
|||
const closuredHandlers = []; |
|||
for(let h of boundHandler.handlers) { |
|||
const parameters = {}; |
|||
for(let pname in h.parameters) { |
|||
const p = h.parameters[pname]; |
|||
parameters[pname] = isState(p) |
|||
? getState( |
|||
s, p[BB_STATE_BINDINGPATH], p[BB_STATE_FALLBACK]) |
|||
: p; |
|||
|
|||
} |
|||
const handlerType = handlerTypes[h.handlerType]; |
|||
closuredHandlers.push(() => handlerType.execute(parameters)); |
|||
} |
|||
|
|||
newProps[boundHandler.propName] = () => { |
|||
for(let runHandler of closuredHandlers) { |
|||
runHandler(); |
|||
} |
|||
} |
|||
|
|||
} |
|||
|
|||
|
|||
component.$set(newProps); |
|||
}); |
|||
|
|||
return unsubscribe; |
|||
} |
|||
|
|||
return { |
|||
initialProps, bind |
|||
}; |
|||
|
|||
} |
|||
|
|||
|
|||
const isState = (prop) => prop[BB_STATE_BINDINGPATH] !== undefined; |
|||
const stateBinding = (prop) => prop[BB_STATE_BINDINGPATH]; |
|||
const stateFallback = (prop) => prop[BB_STATE_FALLBACK]; |
|||
|
|||
|
|||
|
|||
|
|||
@ -1,59 +0,0 @@ |
|||
|
|||
export const BB_STATE_BINDINGPATH = "##bbstate"; |
|||
export const BB_STATE_FALLBACK = "##bbstatefallback"; |
|||
|
|||
export const bindComponent = (store, component) => { |
|||
|
|||
const newProps = {...component.props}; |
|||
const boundProps = []; |
|||
|
|||
for(let propName in component.props) { |
|||
const val = newProps[propName]; |
|||
|
|||
if(!isState(val)) continue; |
|||
|
|||
const binding = stateBinding(val); |
|||
const fallback = stateFallback(val); |
|||
|
|||
boundProps.push({ |
|||
stateBinding:binding, |
|||
fallback, propName |
|||
}); |
|||
|
|||
} |
|||
|
|||
if(boundProps.length === 0) return; |
|||
|
|||
const unsubscribe = store.subscribe(s => { |
|||
const newProps = {...component.props}; |
|||
|
|||
for(let boundProp of boundProps) { |
|||
const val = boundValueFromStore( |
|||
s, |
|||
boundProp.stateBinding, |
|||
boundProp.fallback); |
|||
|
|||
if(val === undefined && newProps[boundProp.propName] !== undefined) { |
|||
delete newProps[boundProp.propName]; |
|||
} |
|||
|
|||
if(val !== undefined) { |
|||
newProps[boundProp.propName] = val; |
|||
} |
|||
} |
|||
|
|||
component.$set(newProps); |
|||
}); |
|||
|
|||
return unsubscribe; |
|||
|
|||
} |
|||
|
|||
const isState = (prop) => prop[BB_STATE_BINDINGPATH] !== undefined; |
|||
const stateBinding = (prop) => prop[BB_STATE_BINDINGPATH]; |
|||
const stateFallback = (prop) => prop[BB_STATE_FALLBACK]; |
|||
const boundValueFromStore = (s, binding, fallback) => { |
|||
const value = s[binding]; |
|||
if(value === undefined) return fallback; |
|||
return value; |
|||
} |
|||
@ -0,0 +1,146 @@ |
|||
import { |
|||
setupBinding, |
|||
BB_STATE_BINDINGPATH, |
|||
BB_STATE_FALLBACK |
|||
} from "../src/state/stateBinding"; |
|||
import { EVENT_TYPE_MEMBER_NAME } from "../src/state/eventHandlers"; |
|||
import {writable} from "svelte/store"; |
|||
import { isFunction } from "lodash/fp"; |
|||
|
|||
describe("setupBinding", () => { |
|||
|
|||
|
|||
it("should correctly create initials props, including fallback values", () => { |
|||
|
|||
const {store, props, component} = testSetup(); |
|||
|
|||
const {initialProps} = testSetupBinding(store, props, component); |
|||
|
|||
expect(initialProps.boundWithFallback).toBe("Bob"); |
|||
expect(initialProps.boundNoFallback).toBeUndefined(); |
|||
expect(initialProps.unbound).toBe("hello"); |
|||
|
|||
expect(isFunction(initialProps.eventBound)).toBeTruthy(); |
|||
initialProps.eventBound(); |
|||
|
|||
}); |
|||
|
|||
it("should update component bound props when store is updated", () => { |
|||
|
|||
const {component, store, props} = testSetup(); |
|||
|
|||
const {bind} = testSetupBinding(store, props, component); |
|||
bind(component); |
|||
|
|||
store.update(s => { |
|||
s.FirstName = "Bobby"; |
|||
s.LastName = "Thedog"; |
|||
s.Customer = { |
|||
Name: "ACME inc", |
|||
Address: "" |
|||
}; |
|||
s.addressToSet = "123 Main Street" |
|||
return s; |
|||
}); |
|||
|
|||
expect(component.props.boundWithFallback).toBe("Bobby"); |
|||
expect(component.props.boundNoFallback).toBe("Thedog"); |
|||
expect(component.props.multiPartBound).toBe("ACME inc"); |
|||
|
|||
}); |
|||
|
|||
it("should not update unbound props when store is updated", () => { |
|||
|
|||
const {component, store, props} = testSetup(); |
|||
|
|||
const {bind} = testSetupBinding(store, props, component); |
|||
bind(component); |
|||
|
|||
store.update(s => { |
|||
s.FirstName = "Bobby"; |
|||
s.LastName = "Thedog"; |
|||
s.Customer = { |
|||
Name: "ACME inc", |
|||
Address: "" |
|||
}; |
|||
s.addressToSet = "123 Main Street" |
|||
return s; |
|||
}); |
|||
|
|||
expect(component.props.unbound).toBe("hello"); |
|||
|
|||
}); |
|||
|
|||
it("should update event handlers on state change", () => { |
|||
|
|||
const {component, store, props} = testSetup(); |
|||
|
|||
const {bind} = testSetupBinding(store, props, component); |
|||
bind(component); |
|||
|
|||
expect(component.props.boundToEventOutput).toBe("initial address"); |
|||
component.props.eventBound(); |
|||
expect(component.props.boundToEventOutput).toBe("event fallback address"); |
|||
|
|||
store.update(s => { |
|||
s.addressToSet = "123 Main Street" |
|||
return s; |
|||
}); |
|||
|
|||
component.props.eventBound(); |
|||
expect(component.props.boundToEventOutput).toBe("123 Main Street"); |
|||
|
|||
}); |
|||
|
|||
}); |
|||
const testSetupBinding = (store, props, component) => { |
|||
const setup = setupBinding(store, props); |
|||
component.props = setup.initialProps; // svelte does this for us in real life
|
|||
return setup; |
|||
} |
|||
const testSetup = () => { |
|||
|
|||
const c = {}; |
|||
|
|||
c.props = {}; |
|||
c.$set = propsToSet => { |
|||
for(let pname in propsToSet) |
|||
c.props[pname] = propsToSet[pname]; |
|||
} |
|||
|
|||
|
|||
const binding = (path, fallback) => { |
|||
const b = {}; |
|||
b[BB_STATE_BINDINGPATH] = path; |
|||
b[BB_STATE_FALLBACK] = fallback; |
|||
return b; |
|||
}; |
|||
|
|||
const event = (handlerType, parameters) => { |
|||
const e = {}; |
|||
e[EVENT_TYPE_MEMBER_NAME] = handlerType; |
|||
e.parameters = parameters; |
|||
return e; |
|||
} |
|||
|
|||
const props = { |
|||
boundWithFallback : binding("FirstName", "Bob"), |
|||
boundNoFallback : binding("LastName"), |
|||
unbound: "hello", |
|||
multiPartBound: binding("Customer.Name", "ACME"), |
|||
boundToEventOutput: binding("Customer.Address", "initial address"), |
|||
eventBound: [ |
|||
event("Set State", { |
|||
path: "Customer.Address", |
|||
value: binding("addressToSet", "event fallback address") |
|||
}) |
|||
] |
|||
} |
|||
|
|||
return { |
|||
component:c, |
|||
store:writable({}), |
|||
props |
|||
}; |
|||
} |
|||
|
|||
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
@ -1,37 +0,0 @@ |
|||
{ |
|||
"name": "Button in the middle", |
|||
"description": "", |
|||
"inherits": "Centered Panel", |
|||
"props": { |
|||
"children": [ |
|||
{ |
|||
"_component": "undefined:children", |
|||
"control": { |
|||
"_component": "@budibase/standard-components/button", |
|||
"contentText": "Button", |
|||
"contentComponent": { |
|||
"_component": "" |
|||
}, |
|||
"className": "default", |
|||
"disabled": false, |
|||
"onClick": [] |
|||
}, |
|||
"gridColumn": "center", |
|||
"gridRow": "middle", |
|||
"gridColumnStart": "", |
|||
"gridColumnEnd": "", |
|||
"gridRowStart": "", |
|||
"gridRowEnd": "" |
|||
} |
|||
], |
|||
"height": "200px", |
|||
"width": "200px" |
|||
}, |
|||
"tags": [ |
|||
"div", |
|||
"container", |
|||
"layout", |
|||
"panel", |
|||
"grid" |
|||
] |
|||
} |
|||
@ -1,10 +1,9 @@ |
|||
{ |
|||
"name": "Centered Panel", |
|||
"name": "/containers/two_columns", |
|||
"description": "", |
|||
"inherits": "@budibase/standard-components/grid", |
|||
"props": { |
|||
"gridTemplateColumns": "[left] 30px [center] 1fr [right] 30px", |
|||
"gridTemplateRows": "[top] 30px [middle] 1fr [bottom] 30px" |
|||
"gridTemplateColumns": "[left] 1fr [right] 1fr" |
|||
}, |
|||
"tags": [ |
|||
"div", |
|||
@ -0,0 +1,65 @@ |
|||
{ |
|||
"name": "mike", |
|||
"description": "", |
|||
"inherits": "containers/two_columns", |
|||
"props": { |
|||
"children": [ |
|||
{ |
|||
"_component": "#children#array_element", |
|||
"control": { |
|||
"_component": "@budibase/standard-components/button", |
|||
"contentText": "Click Me", |
|||
"contentComponent": { |
|||
"_component": "" |
|||
}, |
|||
"className": "default", |
|||
"disabled": false, |
|||
"onClick": [ |
|||
{ |
|||
"##eventHandlerType": "Set State", |
|||
"parameters": { |
|||
"path": "SomeText", |
|||
"value": "hello !" |
|||
} |
|||
} |
|||
] |
|||
}, |
|||
"gridColumn": "left", |
|||
"gridRow": "", |
|||
"gridColumnStart": "", |
|||
"gridColumnEnd": "", |
|||
"gridRowStart": "", |
|||
"gridRowEnd": "" |
|||
}, |
|||
{ |
|||
"_component": "#children#array_element", |
|||
"control": { |
|||
"_component": "@budibase/standard-components/button", |
|||
"contentText": { |
|||
"##bbstate": "SomeText", |
|||
"##bbstatefallback": "(none)" |
|||
}, |
|||
"contentComponent": { |
|||
"_component": "" |
|||
}, |
|||
"className": "default", |
|||
"disabled": false, |
|||
"onClick": [] |
|||
}, |
|||
"gridColumn": "", |
|||
"gridRow": "", |
|||
"gridColumnStart": "", |
|||
"gridColumnEnd": "", |
|||
"gridRowStart": "", |
|||
"gridRowEnd": "" |
|||
} |
|||
] |
|||
}, |
|||
"tags": [ |
|||
"div", |
|||
"container", |
|||
"layout", |
|||
"panel", |
|||
"grid" |
|||
] |
|||
} |
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1 +1 @@ |
|||
window['##BUDIBASE_APPDEFINITION##'] = {"hierarchy":{"name":"root","type":"root","children":[{"name":"customer","type":"record","fields":[{"name":"name","type":"string","typeOptions":{"maxLength":1000,"values":null,"allowDeclaredValuesOnly":false},"label":"name","getInitialValue":"default","getUndefinedValue":"default"}],"children":[{"name":"invoiceyooo","type":"record","fields":[{"name":"amount","type":"number","typeOptions":{"minValue":99999999999,"maxValue":99999999999,"decimalPlaces":2},"label":"amount","getInitialValue":"default","getUndefinedValue":"default"}],"children":[],"validationRules":[],"nodeId":2,"indexes":[],"allidsShardFactor":1,"collectionName":"invoices","isSingle":false}],"validationRules":[],"nodeId":1,"indexes":[{"name":"customer_invoices","type":"index","map":"return {...record};","filter":"","indexType":"ancestor","getShardName":"","getSortKey":"record.id","aggregateGroups":[],"allowedRecordNodeIds":[2],"nodeId":5}],"allidsShardFactor":64,"collectionName":"customers","isSingle":false}],"pathMaps":[],"indexes":[{"name":"Yeo index","type":"index","map":"return {...record};","filter":"","indexType":"ancestor","getShardName":"","getSortKey":"record.id","aggregateGroups":[],"allowedRecordNodeIds":[1],"nodeId":4},{"name":"everyones_invoices","type":"index","map":"return {...record};","filter":"","indexType":"ancestor","getShardName":"","getSortKey":"record.id","aggregateGroups":[],"allowedRecordNodeIds":[2],"nodeId":6}],"nodeId":0},"componentLibraries":["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":1000,"values":null,"allowDeclaredValuesOnly":false},"label":"name","getInitialValue":"default","getUndefinedValue":"default"}],"children":[{"name":"invoiceyooo","type":"record","fields":[{"name":"amount","type":"number","typeOptions":{"minValue":99999999999,"maxValue":99999999999,"decimalPlaces":2},"label":"amount","getInitialValue":"default","getUndefinedValue":"default"}],"children":[],"validationRules":[],"nodeId":2,"indexes":[],"allidsShardFactor":1,"collectionName":"invoices","isSingle":false}],"validationRules":[],"nodeId":1,"indexes":[{"name":"customer_invoices","type":"index","map":"return {...record};","filter":"","indexType":"ancestor","getShardName":"","getSortKey":"record.id","aggregateGroups":[],"allowedRecordNodeIds":[2],"nodeId":5}],"allidsShardFactor":64,"collectionName":"customers","isSingle":false}],"pathMaps":[],"indexes":[{"name":"Yeo index","type":"index","map":"return {...record};","filter":"","indexType":"ancestor","getShardName":"","getSortKey":"record.id","aggregateGroups":[],"allowedRecordNodeIds":[1],"nodeId":4},{"name":"everyones_invoices","type":"index","map":"return {...record};","filter":"","indexType":"ancestor","getShardName":"","getSortKey":"record.id","aggregateGroups":[],"allowedRecordNodeIds":[2],"nodeId":6}],"nodeId":0},"componentLibraries":[{"importPath":"/lib/node_modules/@budibase/standard-components/dist/index.js","libName":"@budibase/standard-components"}],"appRootPath":"/testApp2","props":{"_component":"@budibase/standard-components/grid","gridTemplateRows":"","gridTemplateColumns":"[left] 1fr [right] 1fr","children":[{"_component":"children#array_element#","control":{"_component":"@budibase/standard-components/button","contentText":"Click Me","contentComponent":{"_component":""},"className":"default","disabled":false,"onClick":[{"##eventHandlerType":"Set State","parameters":{"path":"SomeText","value":"hello !"}}]},"gridColumn":"left","gridRow":"","gridColumnStart":"","gridColumnEnd":"","gridRowStart":"","gridRowEnd":""},{"_component":"children#array_element#","control":{"_component":"@budibase/standard-components/button","contentText":{"##bbstate":"SomeText","##bbstatefallback":"(none)"},"contentComponent":{"_component":""},"className":"default","disabled":false,"onClick":[]},"gridColumn":"","gridRow":"","gridColumnStart":"","gridColumnEnd":"","gridRowStart":"","gridRowEnd":""}],"width":"auto","height":"auto","containerClass":"","itemContainerClass":""}} |
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1 +1 @@ |
|||
window['##BUDIBASE_APPDEFINITION##'] = {"hierarchy":{"name":"root","type":"root","children":[{"name":"customer","type":"record","fields":[{"name":"name","type":"string","typeOptions":{"maxLength":1000,"values":null,"allowDeclaredValuesOnly":false},"label":"name","getInitialValue":"default","getUndefinedValue":"default"}],"children":[{"name":"invoiceyooo","type":"record","fields":[{"name":"amount","type":"number","typeOptions":{"minValue":99999999999,"maxValue":99999999999,"decimalPlaces":2},"label":"amount","getInitialValue":"default","getUndefinedValue":"default"}],"children":[],"validationRules":[],"nodeId":2,"indexes":[],"allidsShardFactor":1,"collectionName":"invoices","isSingle":false}],"validationRules":[],"nodeId":1,"indexes":[{"name":"customer_invoices","type":"index","map":"return {...record};","filter":"","indexType":"ancestor","getShardName":"","getSortKey":"record.id","aggregateGroups":[],"allowedRecordNodeIds":[2],"nodeId":5}],"allidsShardFactor":64,"collectionName":"customers","isSingle":false}],"pathMaps":[],"indexes":[{"name":"Yeo index","type":"index","map":"return {...record};","filter":"","indexType":"ancestor","getShardName":"","getSortKey":"record.id","aggregateGroups":[],"allowedRecordNodeIds":[1],"nodeId":4},{"name":"everyones_invoices","type":"index","map":"return {...record};","filter":"","indexType":"ancestor","getShardName":"","getSortKey":"record.id","aggregateGroups":[],"allowedRecordNodeIds":[2],"nodeId":6}],"nodeId":0},"componentLibraries":["budibase-standard-components"],"appRootPath":"/testApp2","props":{"_component":"budibase-standard-components/login","logo":"/_shared/budibase-logo.png","loginRedirect":"","usernameLabel":"Username","passwordLabel":"Password","loginButtonLabel":"Login"}} |
|||
window['##BUDIBASE_APPDEFINITION##'] = {"hierarchy":{"name":"root","type":"root","children":[{"name":"customer","type":"record","fields":[{"name":"name","type":"string","typeOptions":{"maxLength":1000,"values":null,"allowDeclaredValuesOnly":false},"label":"name","getInitialValue":"default","getUndefinedValue":"default"}],"children":[{"name":"invoiceyooo","type":"record","fields":[{"name":"amount","type":"number","typeOptions":{"minValue":99999999999,"maxValue":99999999999,"decimalPlaces":2},"label":"amount","getInitialValue":"default","getUndefinedValue":"default"}],"children":[],"validationRules":[],"nodeId":2,"indexes":[],"allidsShardFactor":1,"collectionName":"invoices","isSingle":false}],"validationRules":[],"nodeId":1,"indexes":[{"name":"customer_invoices","type":"index","map":"return {...record};","filter":"","indexType":"ancestor","getShardName":"","getSortKey":"record.id","aggregateGroups":[],"allowedRecordNodeIds":[2],"nodeId":5}],"allidsShardFactor":64,"collectionName":"customers","isSingle":false}],"pathMaps":[],"indexes":[{"name":"Yeo index","type":"index","map":"return {...record};","filter":"","indexType":"ancestor","getShardName":"","getSortKey":"record.id","aggregateGroups":[],"allowedRecordNodeIds":[1],"nodeId":4},{"name":"everyones_invoices","type":"index","map":"return {...record};","filter":"","indexType":"ancestor","getShardName":"","getSortKey":"record.id","aggregateGroups":[],"allowedRecordNodeIds":[2],"nodeId":6}],"nodeId":0},"componentLibraries":[{"importPath":"/lib/node_modules/@budibase/standard-components/dist/index.js","libName":"@budibase/standard-components"}],"appRootPath":"/testApp2","props":{"_component":"@budibase/standard-components/grid","gridTemplateRows":"","gridTemplateColumns":"[left] 1fr [right] 1fr","children":[],"width":"auto","height":"auto","containerClass":"","itemContainerClass":""}} |
|||
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 it is too large
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Loading…
Reference in new issue