Browse Source

Merge pull request #110 from shogunpurple/presets

Presets
gh-pages
Martin McKeaveney 7 years ago
committed by GitHub
parent
commit
0ea3c71195
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 19
      packages/bootstrap-components/components.json
  2. 2
      packages/bootstrap-components/package.json
  3. 14
      packages/bootstrap-components/rollup.generatorsconfig.js
  4. 6
      packages/bootstrap-components/scripts/publishDev.js
  5. 4
      packages/bootstrap-components/src/generators.js
  6. 37
      packages/bootstrap-components/src/generators/appGenerator.js
  7. 18
      packages/bootstrap-components/src/generators/buttonGenerators.js
  8. 128
      packages/bootstrap-components/src/generators/formsGenerator.js
  9. 14
      packages/bootstrap-components/src/generators/getRecordPath.js
  10. 53
      packages/bootstrap-components/src/generators/indexTablesGenerator.js
  11. 183
      packages/bootstrap-components/src/generators/recordHomePageGenerator.js
  12. 32
      packages/bootstrap-components/src/generators/selectedNavContentGenerator.js
  13. 3
      packages/builder/rollup.config.js
  14. 20
      packages/builder/src/builderStore/loadComponentLibraries.js
  15. 59
      packages/builder/src/builderStore/store.js
  16. 10
      packages/builder/src/common/PlusButton.svelte
  17. 0
      packages/builder/src/userInterface/ComponentPropertiesPanel.svelte
  18. 218
      packages/builder/src/userInterface/ComponentSelectionList.svelte
  19. 158
      packages/builder/src/userInterface/ComponentsList.svelte
  20. 8
      packages/builder/src/userInterface/ComponentsPaneSwitcher.svelte
  21. 1
      packages/builder/src/userInterface/EditComponentProps.svelte
  22. 1
      packages/builder/src/userInterface/NewComponent.svelte
  23. 80
      packages/builder/src/userInterface/PropertyCascader.svelte
  24. 11
      packages/builder/src/userInterface/pagesParsing/createProps.js
  25. 39
      packages/datastores/yarn.lock
  26. 1
      packages/materialdesign-components/components.json
  27. 14
      packages/materialdesign-components/rollup.generatorsconfig.js
  28. 6
      packages/materialdesign-components/scripts/publishDev.js
  29. 0
      packages/materialdesign-components/src/generators.js
  30. 6
      packages/materialdesign-components/src/scripts/publishDev.js
  31. 23
      packages/server/middleware/routers.js
  32. 40
      packages/server/utilities/builder/componentLibraryInfo.js
  33. 33
      packages/server/utilities/builder/index.js
  34. 57
      packages/server/yarn.lock
  35. 50
      packages/standard-components/components.json
  36. 2
      packages/standard-components/package.json
  37. 2
      packages/standard-components/public/bundle.js
  38. 14
      packages/standard-components/rollup.generatorsconfig.js
  39. 7
      packages/standard-components/scripts/publishDev.js
  40. 6
      packages/standard-components/src/generators.js
  41. 6
      packages/standard-components/src/generators/appGenerator.js
  42. 28
      packages/standard-components/src/generators/buttonsGenerator.js
  43. 82
      packages/standard-components/src/generators/formsGenerator.js
  44. 34
      packages/standard-components/src/generators/headersGenerator.js
  45. 26
      packages/standard-components/src/generators/indexTablesGenerator.js
  46. 24
      packages/standard-components/src/generators/navGenerator.js

19
packages/bootstrap-components/components.json

@ -1,24 +1,5 @@
{ {
"_lib": "./dist/index.js", "_lib": "./dist/index.js",
"_generators": {
"_lib": "./dist/generators.js",
"app": {
"name": "App",
"description": "Generate app based on your backend"
},
"forms": {
"name": "Forms",
"description": "Generate forms, based on your records"
},
"indexTables": {
"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" : { "form" : {
"importPath": "Form", "importPath": "Form",
"name": "Form", "name": "Form",

2
packages/bootstrap-components/package.json

@ -4,7 +4,7 @@
"main": "dist/index.js", "main": "dist/index.js",
"module": "dist/index.js", "module": "dist/index.js",
"scripts": { "scripts": {
"build": "rollup -c && rollup -c rollup.generatorsconfig.js", "build": "rollup -c",
"prepublishOnly": "npm run build", "prepublishOnly": "npm run build",
"testbuild": "rollup -w -c rollup.testconfig.js", "testbuild": "rollup -w -c rollup.testconfig.js",
"dev": "run-p start:dev testbuild", "dev": "run-p start:dev testbuild",

14
packages/bootstrap-components/rollup.generatorsconfig.js

@ -1,14 +0,0 @@
import resolve from "rollup-plugin-node-resolve"
export default {
input: "src/generators.js",
output: [
{
file: "dist/generators.js",
format: "esm",
name: "budibaseStandardComponents",
sourcemap: "inline",
},
],
plugins: [resolve()],
}

6
packages/bootstrap-components/scripts/publishDev.js

@ -5,12 +5,10 @@ const { join, basename } = require("path")
const packagesFolder = ".." const packagesFolder = ".."
const jsFile = dir => join(dir, "index.js") const jsFile = dir => join(dir, "index.js")
const generatorsFile = dir => join(dir, "generators.js")
const jsMapFile = dir => join(dir, "index.js.map") const jsMapFile = dir => join(dir, "index.js.map")
const sourceJs = jsFile("dist") const sourceJs = jsFile("dist")
const sourceJsMap = jsMapFile("dist") const sourceJsMap = jsMapFile("dist")
const componentsFile = "components.json" const componentsFile = "components.json"
const sourceGenerators = generatorsFile("dist")
const appPackages = join(packagesFolder, "server", "appPackages") const appPackages = join(packagesFolder, "server", "appPackages")
@ -69,7 +67,6 @@ const nodeModules = appName =>
const copySourceJs = copySource(sourceJs) const copySourceJs = copySource(sourceJs)
const copySourceJsMap = copySource(sourceJsMap) const copySourceJsMap = copySource(sourceJsMap)
const copyGenerators = copySource(sourceGenerators)
const copyComponentsJson = copySource(componentsFile) const copyComponentsJson = copySource(componentsFile)
for (let app of apps) { for (let app of apps) {
@ -77,16 +74,13 @@ const nodeModules = appName =>
await copySourceJs(nodeModulesDist(app)) await copySourceJs(nodeModulesDist(app))
await copySourceJsMap(nodeModulesDist(app)) await copySourceJsMap(nodeModulesDist(app))
await copyGenerators(nodeModulesDist(app))
await copyComponentsJson(nodeModules(app)) await copyComponentsJson(nodeModules(app))
await copySourceJs(join(publicMain(app), "dist")) await copySourceJs(join(publicMain(app), "dist"))
await copySourceJsMap(join(publicMain(app), "dist")) await copySourceJsMap(join(publicMain(app), "dist"))
await copyGenerators(join(publicMain(app), "dist"))
await copySourceJs(join(publicUnauth(app), "dist")) await copySourceJs(join(publicUnauth(app), "dist"))
await copySourceJsMap(join(publicUnauth(app), "dist")) await copySourceJsMap(join(publicUnauth(app), "dist"))
await copyGenerators(join(publicUnauth(app), "dist"))
} }
})() })()

4
packages/bootstrap-components/src/generators.js

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

37
packages/bootstrap-components/src/generators/appGenerator.js

@ -1,37 +0,0 @@
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",
},
className: "p-3",
},
},
{
name: "Login",
inherits: "@budibase/standard-components/login",
props: {},
},
...selectNavContent({ records, indexes, helpers }),
]
export const navItem = ({ record }) => ({
title: record.collectionName,
component: {
_component: navContentComponentName(record),
},
})

18
packages/bootstrap-components/src/generators/buttonGenerators.js

@ -1,18 +0,0 @@
export const buttons = () => [
{
name: "common/Primary Button",
description: "Bootstrap primary button ",
inherits: "@budibase/standard-components/button",
props: {
className: "btn btn-primary",
},
},
{
name: "common/Default Button",
description: "Bootstrap default button",
inherits: "@budibase/standard-components/button",
props: {
className: "btn btn-secondary",
},
},
]

128
packages/bootstrap-components/src/generators/formsGenerator.js

@ -1,128 +0,0 @@
import { buttons } from "./buttonGenerators"
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: formName(record),
description: `Control for creating/updating '${record.nodeKey()}' `,
inherits: "@budibase/standard-components/container",
props: {
className: "p-1",
children: [
{
component: {
_component: "@budibase/standard-components/h3",
text: `Edit ${record.name}`,
},
},
form(record),
saveCancelButtons(record),
],
},
})
const form = record => ({
component: {
_component: "@budibase/standard-components/form",
formControls: record.fields.map(f => formControl(record, f)),
},
})
const formControl = (record, field) => {
if (
field.type === "string" &&
field.typeOptions.values &&
field.typeOptions.values.length > 0
) {
return {
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",
},
label: field.label,
}
} else {
return {
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",
},
label: field.label,
}
}
}
const saveCancelButtons = record => ({
component: {
_component: "@budibase/standard-components/stackpanel",
direction: "horizontal",
children: [
paddedPanelForButton({
_component: "common/Primary Button",
contentText: `Save ${record.name}`,
onClick: [
{
"##eventHandlerType": "Save Record",
parameters: {
statePath: `${record.name}`,
},
},
{
"##eventHandlerType": "Set State",
parameters: {
path: `isEditing${record.name}`,
value: "",
},
},
],
}),
paddedPanelForButton({
_component: "common/Default Button",
contentText: `Cancel`,
onClick: [
{
"##eventHandlerType": "Set State",
parameters: {
path: `isEditing${record.name}`,
value: "",
},
},
],
}),
],
},
})
const paddedPanelForButton = button => ({
control: {
_component: "@budibase/standard-components/container",
className: "btn-group",
children: [
{
component: button,
},
],
},
})

14
packages/bootstrap-components/src/generators/getRecordPath.js

@ -1,14 +0,0 @@
export const getRecordPath = () => {
const parts = []
const add = current => {
parts.push(current.name)
if (current.parent().type === "root") {
return
}
add(current.parent())
}
return parts.reverse().join("/")
}

53
packages/bootstrap-components/src/generators/indexTablesGenerator.js

@ -1,53 +0,0 @@
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(),
"##bbsource": "store",
},
tableClass: "table table-hover",
theadClass: "thead-dark",
columns: helpers
.indexSchema(index)
.filter(c => !excludedColumns.includes(c.name))
.map(column),
onRowClick: [
{
"##eventHandlerType": "Set State",
parameters: {
path: `selectedrow_${index.name}`,
value: {
"##bbstate": "key",
"##bbsource": "event",
},
},
},
],
})
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),
inherits: "@budibase/standard-components/table",
props: indexTableProps(index, helpers),
})
const column = col => ({
title: col.name,
value: {
"##bbstate": col.name,
"##bbsource": "context",
},
})

183
packages/bootstrap-components/src/generators/recordHomePageGenerator.js

@ -1,183 +0,0 @@
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/container",
name: homepageComponentName(record),
props: {
className: "d-flex flex-column h-100",
children: [
{
component: {
_component: `${record.name}/homepage buttons`,
},
},
{
component: {
_component: getIndexTableName(index),
},
className: "flex-gow-1 overflow-auto",
},
],
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/container",
name: `${record.name}/homepage buttons`,
props: {
className: "btn-toolbar mt-4 mb-2",
children: [
{
component: {
_component: "@budibase/standard-components/container",
className: "btn-group mr-3",
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(),
},
},
],
},
},
],
},
},
{
component: {
_component: "@budibase/standard-components/if",
condition: `$store.selectedrow_${index.name} && $store.selectedrow_${index.name}.length > 0`,
thenComponent: {
_component: "@budibase/standard-components/container",
className: "btn-group",
children: [
{
component: {
_component: "common/Default Button",
contentText: `Edit ${record.name}`,
onClick: [
{
"##eventHandlerType": "Load Record",
parameters: {
statePath: record.name,
recordKey: {
"##bbstate": `selectedrow_${index.name}`,
"##source": "store",
},
},
},
{
"##eventHandlerType": "Set State",
parameters: {
path: `isEditing${record.name}`,
value: "true",
},
},
],
},
},
{
component: {
_component: "common/Default Button",
contentText: `Delete ${record.name}`,
onClick: [
{
"##eventHandlerType": "Delete Record",
parameters: {
recordKey: {
"##bbstate": `selectedrow_${index.name}`,
"##source": "store",
},
},
},
],
},
},
],
},
},
},
],
},
})

32
packages/bootstrap-components/src/generators/selectedNavContentGenerator.js

@ -1,32 +0,0 @@
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 }) => ({
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),
},
},
})

3
packages/builder/rollup.config.js

@ -19,8 +19,7 @@ const _builderProxy = proxy("/_builder", {
const apiProxy = proxy( const apiProxy = proxy(
[ [
"/_builder/api/**", "/_builder/api/**",
"/_builder/**/componentlibrary", "/_builder/**/componentlibrary"
"/_builder/**/componentlibraryGenerators",
], ],
{ {
target, target,

20
packages/builder/src/builderStore/loadComponentLibraries.js

@ -1,5 +1,3 @@
import { map } from "lodash/fp"
export const loadLibs = async (appName, appPackage) => { export const loadLibs = async (appName, appPackage) => {
const allLibraries = {} const allLibraries = {}
for (let lib of appPackage.pages.componentLibraries) { for (let lib of appPackage.pages.componentLibraries) {
@ -10,16 +8,6 @@ export const loadLibs = async (appName, appPackage) => {
return allLibraries return allLibraries
} }
export const loadGeneratorLibs = async (appName, appPackage) => {
const allGeneratorLibs = {}
for (let lib of appPackage.pages.componentLibraries) {
const generatorModule = await import(makeGeneratorLibraryUrl(appName, lib))
allGeneratorLibs[lib] = generatorModule
}
return allGeneratorLibs
}
export const loadLibUrls = (appName, appPackage) => { export const loadLibUrls = (appName, appPackage) => {
const allLibraries = [] const allLibraries = []
for (let lib of appPackage.pages.componentLibraries) { for (let lib of appPackage.pages.componentLibraries) {
@ -35,13 +23,5 @@ export const loadLib = async (appName, lib, allLibs) => {
return allLibs return allLibs
} }
export const loadGeneratorLib = async (appName, lib, allGeneratorLibs) => {
allGeneratorLibs[lib] = await import(makeGeneratorLibraryUrl(appName, lib))
return allGeneratorLibs
}
export const makeLibraryUrl = (appName, lib) => export const makeLibraryUrl = (appName, lib) =>
`/_builder/${appName}/componentlibrary?lib=${encodeURI(lib)}` `/_builder/${appName}/componentlibrary?lib=${encodeURI(lib)}`
export const makeGeneratorLibraryUrl = (appName, lib) =>
`/_builder/${appName}/componentlibraryGenerators?lib=${encodeURI(lib)}`

59
packages/builder/src/builderStore/store.js

@ -35,13 +35,10 @@ import {
import { expandComponentDefinition } from "../userInterface/pagesParsing/types" import { expandComponentDefinition } from "../userInterface/pagesParsing/types"
import { import {
loadLibs, loadLibs,
loadLibUrls, loadLibUrls
loadGeneratorLibs,
} from "./loadComponentLibraries" } from "./loadComponentLibraries"
import { buildCodeForScreens } from "./buildCodeForScreens" import { buildCodeForScreens } from "./buildCodeForScreens"
import { generate_screen_css } from "./generate_css" import { generate_screen_css } from "./generate_css"
import { insertCodeMetadata } from "./insertCodeMetadata"
// import { uuid } from "./uuid"
let appname = "" let appname = ""
@ -94,7 +91,6 @@ export const getStore = () => {
store.deleteLevel = deleteLevel(store) store.deleteLevel = deleteLevel(store)
store.setActiveNav = setActiveNav(store) store.setActiveNav = setActiveNav(store)
store.saveScreen = saveScreen(store) store.saveScreen = saveScreen(store)
store.refreshComponents = refreshComponents(store)
store.addComponentLibrary = addComponentLibrary(store) store.addComponentLibrary = addComponentLibrary(store)
store.renameScreen = renameScreen(store) store.renameScreen = renameScreen(store)
store.deleteScreen = deleteScreen(store) store.deleteScreen = deleteScreen(store)
@ -159,8 +155,6 @@ const initialise = (store, initial) => async () => {
} }
initial.libraries = await loadLibs(appname, pkg) initial.libraries = await loadLibs(appname, pkg)
initial.generatorLibraries = await loadGeneratorLibs(appname, pkg)
initial.loadLibraryUrls = () => loadLibUrls(appname, pkg) initial.loadLibraryUrls = () => loadLibUrls(appname, pkg)
initial.appname = appname initial.appname = appname
initial.pages = pkg.pages initial.pages = pkg.pages
@ -168,7 +162,6 @@ const initialise = (store, initial) => async () => {
initial.hierarchy = pkg.appDefinition.hierarchy initial.hierarchy = pkg.appDefinition.hierarchy
initial.accessLevels = pkg.accessLevels initial.accessLevels = pkg.accessLevels
initial.screens = values(pkg.screens) initial.screens = values(pkg.screens)
initial.generators = generatorsArray(pkg.components.generators)
initial.components = values(pkg.components.components).map( initial.components = values(pkg.components.components).map(
expandComponentDefinition expandComponentDefinition
) )
@ -187,9 +180,6 @@ const initialise = (store, initial) => async () => {
return initial return initial
} }
const generatorsArray = generators =>
pipe(generators, [keys, filter(k => k !== "_lib"), map(k => generators[k])])
const showSettings = store => () => { const showSettings = store => () => {
store.update(s => { store.update(s => {
s.showSettings = !s.showSettings s.showSettings = !s.showSettings
@ -683,27 +673,6 @@ const removeStylesheet = store => stylesheet => {
}) })
} }
const refreshComponents = store => async () => {
const componentsAndGenerators = await api
.get(`/_builder/api/${appname}/components`)
.then(r => r.json())
const components = pipe(componentsAndGenerators.components, [
keys,
map(k => ({ ...componentsAndGenerators[k], name: k })),
map(c => expandComponentDefinition(c)),
])
store.update(s => {
s.components = pipe(s.components, [
filter(c => !isRootComponent(c)),
concat(components),
])
s.generators = componentsAndGenerators.generators
return s
})
}
const _savePage = async s => { const _savePage = async s => {
const page = s.pages[s.currentPageName] const page = s.pages[s.currentPageName]
@ -749,19 +718,25 @@ const setCurrentPage = store => pageName => {
const getContainerComponent = components => const getContainerComponent = components =>
components.find(c => c.name === "@budibase/standard-components/container") components.find(c => c.name === "@budibase/standard-components/container")
const addChildComponent = store => componentName => { /**
store.update(s => { * @param {string} componentToAdd - name of the component to add to the application
const component = componentName.startsWith("##") * @param {string} presetName - name of the component preset if defined
? getBuiltin(componentName) */
: s.components.find(c => c.name === componentName) const addChildComponent = store => (componentToAdd, presetName) => {
const newComponent = createProps(component) store.update(state => {
const component = componentToAdd.startsWith("##")
s.currentComponentInfo._children = s.currentComponentInfo._children.concat( ? getBuiltin(componentToAdd)
: state.components.find(({ name }) => name === componentToAdd)
const presetProps = presetName ? component.presets[presetName] : {};
const newComponent = createProps(component, presetProps);
state.currentComponentInfo._children = state.currentComponentInfo._children.concat(
newComponent.props newComponent.props
) )
_savePage(s) _savePage(state)
return s
return state
}) })
} }

10
packages/builder/src/common/PlusButton.svelte

@ -1,4 +1,8 @@
<button on:click>+</button> <button on:click>
<slot>
+
</slot>
</button>
<style> <style>
button { button {
@ -8,8 +12,8 @@
border-radius: 5px; border-radius: 5px;
background: rgba(249, 249, 249, 1); background: rgba(249, 249, 249, 1);
width: 1.8rem; min-width: 1.8rem;
height: 1.8rem; min-height: 1.8rem;
padding-bottom: 10px; padding-bottom: 10px;
display: flex; display: flex;

0
packages/builder/src/userInterface/ComponentPanel.svelte → packages/builder/src/userInterface/ComponentPropertiesPanel.svelte

218
packages/builder/src/userInterface/ComponentSelectionList.svelte

@ -0,0 +1,218 @@
<script>
import { splitName } from "./pagesParsing/splitRootComponentName.js"
import { store } from "../builderStore"
import { find, sortBy } from "lodash/fp"
import { ImageIcon, InputIcon, LayoutIcon } from "../common/Icons/"
import Select from "../common/Select.svelte"
import Button from "../common/PlusButton.svelte"
let componentLibraries = []
let current_view = "text"
let selectedComponent = null
const addRootComponent = (component, allComponents) => {
const { libName } = splitName(component.name)
let group = find(r => r.libName === libName)(allComponents)
if (!group) {
group = {
libName,
components: [],
}
allComponents.push(group)
}
group.components.push(component)
}
const onComponentChosen = store.addChildComponent
$: {
const newComponentLibraries = []
for (let comp of sortBy(["name"])($store.components)) {
addRootComponent(comp, newComponentLibraries)
}
componentLibraries = newComponentLibraries
}
</script>
<div class="root">
<Select>
{#each componentLibraries as componentLibrary}
<option value={componentLibrary.libName}>
{componentLibrary.libName}
</option>
{/each}
</Select>
{#each componentLibraries as componentLibrary}
<div class="library-container">
<ul>
<li>
<button
class:selected={current_view === 'text'}
on:click={() => (current_view = 'text')}>
<InputIcon />
</button>
</li>
<li>
<button
class:selected={current_view === 'layout'}
on:click={() => (current_view = 'layout')}>
<LayoutIcon />
</button>
</li>
<li>
<button
class:selected={current_view === 'media'}
on:click={() => (current_view = 'media')}>
<ImageIcon />
</button>
</li>
</ul>
{#each $store.builtins.concat(componentLibrary.components) as component}
<div class="component-container">
<div
class="component"
on:click={() => onComponentChosen(component.name)}>
<div class="name">{splitName(component.name).componentName}</div>
{#if component.presets && component.name === selectedComponent}
<ul class="preset-menu">
<span>{splitName(component.name).componentName} Presets</span>
{#each Object.keys(component.presets) as preset}
<li
on:click|stopPropagation={() => onComponentChosen(component.name, preset)}>
{preset}
</li>
{/each}
</ul>
{/if}
</div>
{#if component.presets}
<Button
on:click={() => {
selectedComponent = selectedComponent ? null : component.name
}}>
<span
class="open-presets"
class:open={selectedComponent === component.name}>
...
</span>
</Button>
{/if}
</div>
{/each}
</div>
{/each}
</div>
<style>
.root {
display: flex;
flex-direction: column;
}
.library-container {
padding: 0 0 10px 10px;
flex: 1 1 auto;
min-height: 0px;
}
.component-container {
display: flex;
align-items: center;
}
.component {
position: relative;
padding: 0 15px;
cursor: pointer;
border: 1px solid #ebebeb;
border-radius: 2px;
margin: 10px 0;
height: 40px;
box-sizing: border-box;
color: #163057;
display: flex;
align-items: center;
flex: 1;
margin-right: 5px;
}
.component:hover {
background-color: var(--lightslate);
}
.component > .name {
color: #163057;
display: inline-block;
font-size: 12px;
font-weight: bold;
opacity: 0.6;
}
ul {
list-style: none;
display: flex;
padding: 0;
}
.preset-menu {
flex-direction: column;
position: absolute;
top: 25px;
left: 0;
right: 0;
z-index: 1;
background: #fafafa;
padding: 10px;
border-radius: 2px;
color: rgba(22, 48, 87, 0.6);
}
.preset-menu > span {
font-size: 12px;
font-weight: bold;
text-transform: uppercase;
}
.preset-menu li {
font-size: 14px;
margin-top: 13px;
}
.preset-menu li:hover {
font-weight: bold;
}
li {
margin-right: 20px;
background: none;
border-radius: 5px;
}
li button {
width: 100%;
height: 100%;
background: none;
border: none;
border-radius: 5px;
padding: 12px;
outline: none;
cursor: pointer;
}
.selected {
color: var(--button-text);
background: var(--background-button) !important;
}
.open {
color: rgba(0, 85, 255, 1);
}
</style>

158
packages/builder/src/userInterface/ComponentsList.svelte

@ -1,158 +0,0 @@
<script>
import { splitName } from "./pagesParsing/splitRootComponentName.js"
import { store } from "../builderStore"
import { find, sortBy } from "lodash/fp"
import { ImageIcon, InputIcon, LayoutIcon } from "../common/Icons/"
let componentLibraries = []
let current_view = "text"
const addRootComponent = (c, all) => {
const { libName } = splitName(c.name)
let group = find(r => r.libName === libName)(all)
if (!group) {
group = {
libName,
components: [],
generators: [],
}
all.push(group)
}
group.components.push(c)
}
const onComponentChosen = store.addChildComponent
$: {
const newComponentLibraries = []
for (let comp of sortBy(["name"])($store.components)) {
addRootComponent(comp, newComponentLibraries)
}
componentLibraries = newComponentLibraries
}
</script>
<div class="root">
{#each componentLibraries as lib}
<div class="library-header">{lib.libName}</div>
<div class="library-container">
<ul>
<li>
<button
class:selected={current_view === 'text'}
on:click={() => (current_view = 'text')}>
<InputIcon />
</button>
</li>
<li>
<button
class:selected={current_view === 'layout'}
on:click={() => (current_view = 'layout')}>
<LayoutIcon />
</button>
</li>
<li>
<button
class:selected={current_view === 'media'}
on:click={() => (current_view = 'media')}>
<ImageIcon />
</button>
</li>
</ul>
{#each $store.builtins.concat(lib.components.filter(_ => true)) as component}
<div
class="component"
on:click={() => onComponentChosen(component.name)}>
<div class="name">{splitName(component.name).componentName}</div>
</div>
{/each}
</div>
{/each}
</div>
<style>
.root {
display: flex;
flex-direction: column;
}
.library-header {
font-size: 1.1em;
border-color: var(--primary25);
border-width: 1px 0px;
border-style: solid;
background-color: var(--primary10);
padding: 5px 0;
flex: 0 0 auto;
}
.library-container {
padding: 0 0 10px 10px;
flex: 1 1 auto;
min-height: 0px;
}
.component {
padding: 0 15px;
cursor: pointer;
border: 1px solid #ccc;
border-radius: 2px;
margin: 10px 0;
height: 40px;
box-sizing: border-box;
color: #163057;
display: flex;
align-items: center;
}
.component:hover {
background-color: var(--lightslate);
}
.component > .name {
color: #163057;
display: inline-block;
font-size: 12px;
font-weight: bold;
opacity: 0.6;
}
ul {
list-style: none;
display: flex;
padding: 0;
}
li {
margin-right: 20px;
background: none;
border-radius: 5px;
width: 48px;
height: 48px;
}
li button {
width: 100%;
height: 100%;
background: none;
border: none;
border-radius: 5px;
padding: 12px;
outline: none;
cursor: pointer;
}
.selected {
color: var(--button-text);
background: var(--background-button) !important;
}
</style>

8
packages/builder/src/userInterface/ComponentsPaneSwitcher.svelte

@ -1,7 +1,7 @@
<script> <script>
import { store } from "../builderStore/" import { store } from "../builderStore/"
import ComponentPanel from "./ComponentPanel.svelte" import ComponentPropertiesPanel from "./ComponentPropertiesPanel.svelte"
import ComponentsList from "./ComponentsList.svelte" import ComponentSelectionList from "./ComponentSelectionList.svelte"
let selected = "properties" let selected = "properties"
@ -30,11 +30,11 @@
<div class="panel"> <div class="panel">
{#if selected === 'properties'} {#if selected === 'properties'}
<ComponentPanel /> <ComponentPropertiesPanel />
{/if} {/if}
{#if selected === 'components'} {#if selected === 'components'}
<ComponentsList /> <ComponentSelectionList />
{/if} {/if}
</div> </div>

1
packages/builder/src/userInterface/EditComponentProps.svelte

@ -1,7 +1,6 @@
<script> <script>
import PropsView from "./PropsView.svelte" import PropsView from "./PropsView.svelte"
import { store } from "../builderStore" import { store } from "../builderStore"
import IconButton from "../common/IconButton.svelte"
import Textbox from "../common/Textbox.svelte" import Textbox from "../common/Textbox.svelte"
import Button from "../common/Button.svelte" import Button from "../common/Button.svelte"
import { LayoutIcon, PaintIcon, TerminalIcon } from "../common/Icons/" import { LayoutIcon, PaintIcon, TerminalIcon } from "../common/Icons/"

1
packages/builder/src/userInterface/NewComponent.svelte

@ -1,5 +1,4 @@
<script> <script>
import ComponentSelector from "./ComponentSelector.svelte"
import { store } from "../builderStore" import { store } from "../builderStore"
import PropsView from "./PropsView.svelte" import PropsView from "./PropsView.svelte"
import Textbox from "../common/Textbox.svelte" import Textbox from "../common/Textbox.svelte"

80
packages/builder/src/userInterface/PropertyCascader.svelte

@ -1,48 +1,50 @@
<script> <script>
import { ArrowDownIcon } from "../common/Icons/"; import { ArrowDownIcon } from "../common/Icons/"
import { store } from "../builderStore"; import { store } from "../builderStore"
import { buildStateOrigins } from "../builderStore/buildStateOrigins"; import { buildStateOrigins } from "../builderStore/buildStateOrigins"
import { isBinding, getBinding, setBinding } from "../common/binding"; import { isBinding, getBinding, setBinding } from "../common/binding"
export let onChanged = () => {}; export let onChanged = () => {}
export let value = ""; export let value = ""
let isOpen = false; let isOpen = false
let stateBindings = []; let stateBindings = []
let bindingPath = ""; let bindingPath = ""
let bindingFallbackValue = ""; let bindingFallbackValue = ""
let bindingSource = "store"; let bindingSource = "store"
let bindingValue = ""; let bindingValue = ""
const bind = (path, fallback, source) => { const bind = (path, fallback, source) => {
if (!path) { if (!path) {
onChanged(fallback); onChanged(fallback)
return; return
} }
const binding = setBinding({ path, fallback, source }); const binding = setBinding({ path, fallback, source })
onChanged(binding); onChanged(binding)
}; }
const setBindingPath = value => const setBindingPath = value =>
bind(value, bindingFallbackValue, bindingSource); bind(value, bindingFallbackValue, bindingSource)
const setBindingFallback = value => bind(bindingPath, value, bindingSource); const setBindingFallback = value => bind(bindingPath, value, bindingSource)
const setBindingSource = value => const setBindingSource = value =>
bind(bindingPath, bindingFallbackValue, value); bind(bindingPath, bindingFallbackValue, value)
$: { $: {
const binding = getBinding(value); const binding = getBinding(value)
if (bindingPath !== binding.path) isOpen = false; if (bindingPath !== binding.path) isOpen = false
bindingPath = binding.path; bindingPath = binding.path
bindingValue = typeof value === "object" ? "" : value; bindingValue = typeof value === "object" ? "" : value
bindingFallbackValue = binding.fallback || bindingValue; bindingFallbackValue = binding.fallback || bindingValue
const currentScreen = $store.screens.find( const currentScreen = $store.screens.find(
({ name }) => name === $store.currentPreviewItem.name ({ name }) => name === $store.currentPreviewItem.name
); )
stateBindings = currentScreen ? Object.keys(buildStateOrigins(currentScreen)) : []; stateBindings = currentScreen
? Object.keys(buildStateOrigins(currentScreen))
: []
} }
</script> </script>
@ -53,17 +55,19 @@
class="uk-input uk-form-small" class="uk-input uk-form-small"
value={bindingFallbackValue || bindingPath} value={bindingFallbackValue || bindingPath}
on:change={e => { on:change={e => {
setBindingFallback(e.target.value); setBindingFallback(e.target.value)
onChanged(e.target.value); onChanged(e.target.value)
}} /> }} />
<button on:click={() => (isOpen = !isOpen)}> {#if stateBindings.length}
<div <button on:click={() => (isOpen = !isOpen)}>
class="icon" <div
class:highlighted={bindingPath} class="icon"
style={`transform: rotate(${isOpen ? 0 : 90}deg);`}> class:highlighted={bindingPath}
<ArrowDownIcon size={36} /> style={`transform: rotate(${isOpen ? 0 : 90}deg);`}>
</div> <ArrowDownIcon size={36} />
</button> </div>
</button>
{/if}
</div> </div>
{#if isOpen} {#if isOpen}
<ul class="options"> <ul class="options">
@ -71,7 +75,7 @@
<li <li
class:bold={stateBinding === bindingPath} class:bold={stateBinding === bindingPath}
on:click={() => { on:click={() => {
setBindingPath(stateBinding === bindingPath ? null : stateBinding); setBindingPath(stateBinding === bindingPath ? null : stateBinding)
}}> }}>
{stateBinding} {stateBinding}
</li> </li>

11
packages/builder/src/userInterface/pagesParsing/createProps.js

@ -24,8 +24,13 @@ export const getNewScreen = (components, rootComponentName, name) => {
} }
} }
/**
* @param {object} componentDefinition - component definition from a component library
* @param {object} derivedFromProps - extra props derived from a components given props.
* @return {object} the fully created properties for the component, and any property parsing errors
*/
export const createProps = (componentDefinition, derivedFromProps) => { export const createProps = (componentDefinition, derivedFromProps) => {
const error = (propName, error) => errors.push({ propName, error }) const errorOccurred = (propName, error) => errors.push({ propName, error })
const props = { const props = {
_component: componentDefinition.name, _component: componentDefinition.name,
@ -37,12 +42,12 @@ export const createProps = (componentDefinition, derivedFromProps) => {
const errors = [] const errors = []
if (!componentDefinition.name) if (!componentDefinition.name)
error("_component", "Component name not supplied") errorOccurred("_component", "Component name not supplied")
const propsDef = componentDefinition.props const propsDef = componentDefinition.props
for (let propDef in propsDef) { for (let propDef in propsDef) {
const parsedPropDef = parsePropDef(propsDef[propDef]) const parsedPropDef = parsePropDef(propsDef[propDef])
if (parsedPropDef.error) error(propDef, parsedPropDef.error) if (parsedPropDef.error) errorOccurred(propDef, parsedPropDef.error)
else props[propDef] = parsedPropDef else props[propDef] = parsedPropDef
} }

39
packages/datastores/yarn.lock

@ -573,23 +573,6 @@
lodash "^4.17.10" lodash "^4.17.10"
to-fast-properties "^2.0.0" to-fast-properties "^2.0.0"
"@budibase/core@^0.0.16":
version "0.0.16"
resolved "https://registry.yarnpkg.com/@budibase/core/-/core-0.0.16.tgz#efff16876f906b2aa59803c3312ec7593664b623"
integrity sha512-DvzfurHHp9KkSjkvbGbKsVczR5ne38bMLRA2hHEJxAmC0Tshld06cEq7HMy2BmPb6kaC1URYHlFs/gPhW2cSFQ==
dependencies:
"@nx-js/compiler-util" "^2.0.0"
date-fns "^1.29.0"
lodash "^4.17.13"
lunr "^2.3.5"
safe-buffer "^5.1.2"
shortid "^2.2.8"
"@nx-js/compiler-util@^2.0.0":
version "2.0.0"
resolved "https://registry.yarnpkg.com/@nx-js/compiler-util/-/compiler-util-2.0.0.tgz#c74c12165fa2f017a292bb79af007e8fce0af297"
integrity sha512-AxSQbwj9zqt8DYPZ6LwZdytqnwfiOEdcFdq4l8sdjkZmU2clTht7RDLCI8xvkp7KqgcNaOGlTeCM55TULWruyQ==
"@types/body-parser@*": "@types/body-parser@*":
version "1.17.0" version "1.17.0"
resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.17.0.tgz#9f5c9d9bd04bb54be32d5eb9fc0d8c974e6cf58c" resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.17.0.tgz#9f5c9d9bd04bb54be32d5eb9fc0d8c974e6cf58c"
@ -911,11 +894,6 @@ core-util-is@~1.0.0:
version "1.0.2" version "1.0.2"
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
date-fns@^1.29.0:
version "1.30.1"
resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-1.30.1.tgz#2e71bf0b119153dbb4cc4e88d9ea5acfb50dc05c"
integrity sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw==
debug@=3.1.0: debug@=3.1.0:
version "3.1.0" version "3.1.0"
resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
@ -1438,11 +1416,6 @@ loose-envify@^1.0.0:
dependencies: dependencies:
js-tokens "^3.0.0 || ^4.0.0" js-tokens "^3.0.0 || ^4.0.0"
lunr@^2.3.5:
version "2.3.8"
resolved "https://registry.yarnpkg.com/lunr/-/lunr-2.3.8.tgz#a8b89c31f30b5a044b97d2d28e2da191b6ba2072"
integrity sha512-oxMeX/Y35PNFuZoHp+jUj5OSEmLCaIH4KTFJh7a93cHBoFmpw2IoPs22VIz7vyO2YUnx2Tn9dzIwO2P/4quIRg==
make-dir@^1.0.0: make-dir@^1.0.0:
version "1.3.0" version "1.3.0"
resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c"
@ -1556,11 +1529,6 @@ nan@^2.9.2:
version "2.11.1" version "2.11.1"
resolved "https://registry.yarnpkg.com/nan/-/nan-2.11.1.tgz#90e22bccb8ca57ea4cd37cc83d3819b52eea6766" resolved "https://registry.yarnpkg.com/nan/-/nan-2.11.1.tgz#90e22bccb8ca57ea4cd37cc83d3819b52eea6766"
nanoid@^2.1.0:
version "2.1.11"
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-2.1.11.tgz#ec24b8a758d591561531b4176a01e3ab4f0f0280"
integrity sha512-s/snB+WGm6uwi0WjsZdaVcuf3KJXlfGl2LcxgwkEwJF0D/BWzVWAZW/XY4bFaiR7s0Jk3FPvlnepg1H1b1UwlA==
nanomatch@^1.2.9: nanomatch@^1.2.9:
version "1.2.13" version "1.2.13"
resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119"
@ -1946,13 +1914,6 @@ set-value@^2.0.0:
is-plain-object "^2.0.3" is-plain-object "^2.0.3"
split-string "^3.0.1" split-string "^3.0.1"
shortid@^2.2.8:
version "2.2.15"
resolved "https://registry.yarnpkg.com/shortid/-/shortid-2.2.15.tgz#2b902eaa93a69b11120373cd42a1f1fe4437c122"
integrity sha512-5EaCy2mx2Jgc/Fdn9uuDuNIIfWBpzY4XIlhoqtXF6qsf+/+SGZ+FxDdX/ZsMZiWupIWNqAEmiNY4RC+LSmCeOw==
dependencies:
nanoid "^2.1.0"
signal-exit@^3.0.0: signal-exit@^3.0.0:
version "3.0.2" version "3.0.2"
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d"

1
packages/materialdesign-components/components.json

@ -1,6 +1,5 @@
{ {
"_lib": "./dist/index.js", "_lib": "./dist/index.js",
"_generators": {},
"Body1": { "Body1": {
"name": "Body1", "name": "Body1",
"description": "Sets the font properties as Roboto Body 1", "description": "Sets the font properties as Roboto Body 1",

14
packages/materialdesign-components/rollup.generatorsconfig.js

@ -1,14 +0,0 @@
import resolve from "rollup-plugin-node-resolve"
export default {
input: "src/generators.js",
output: [
{
file: "dist/generators.js",
format: "esm",
name: "budibaseStandardComponents",
sourcemap: "inline",
},
],
plugins: [resolve()],
}

6
packages/materialdesign-components/scripts/publishDev.js

@ -6,12 +6,10 @@ const serverConfig = require("../../server/config")()
const packagesFolder = ".." const packagesFolder = ".."
const jsFile = dir => join(dir, "index.js") const jsFile = dir => join(dir, "index.js")
const generatorsFile = dir => join(dir, "generators.js")
const jsMapFile = dir => join(dir, "index.js.map") const jsMapFile = dir => join(dir, "index.js.map")
const sourceJs = jsFile("dist") const sourceJs = jsFile("dist")
const sourceJsMap = jsMapFile("dist") const sourceJsMap = jsMapFile("dist")
const componentsFile = "components.json" const componentsFile = "components.json"
const sourceGenerators = generatorsFile("dist")
const appPackages = join( const appPackages = join(
packagesFolder, packagesFolder,
@ -68,7 +66,6 @@ const nodeModules = appName =>
const copySourceJs = copySource(sourceJs) const copySourceJs = copySource(sourceJs)
const copySourceJsMap = copySource(sourceJsMap) const copySourceJsMap = copySource(sourceJsMap)
const copyGenerators = copySource(sourceGenerators)
const copyComponentsJson = copySource(componentsFile) const copyComponentsJson = copySource(componentsFile)
for (let app of apps) { for (let app of apps) {
@ -77,16 +74,13 @@ const nodeModules = appName =>
await copySourceJs(nodeModulesDist(app)) await copySourceJs(nodeModulesDist(app))
await copySourceJsMap(nodeModulesDist(app)) await copySourceJsMap(nodeModulesDist(app))
await copyGenerators(nodeModulesDist(app))
await copyComponentsJson(nodeModules(app)) await copyComponentsJson(nodeModules(app))
await copySourceJs(join(publicMain(app), "dist")) await copySourceJs(join(publicMain(app), "dist"))
await copySourceJsMap(join(publicMain(app), "dist")) await copySourceJsMap(join(publicMain(app), "dist"))
await copyGenerators(join(publicMain(app), "dist"))
await copySourceJs(join(publicUnauth(app), "dist")) await copySourceJs(join(publicUnauth(app), "dist"))
await copySourceJsMap(join(publicUnauth(app), "dist")) await copySourceJsMap(join(publicUnauth(app), "dist"))
await copyGenerators(join(publicUnauth(app), "dist"))
} }
})() })()

0
packages/materialdesign-components/src/generators.js

6
packages/materialdesign-components/src/scripts/publishDev.js

@ -6,12 +6,10 @@ const serverConfig = require("../../../server/config")()
const packagesFolder = ".." const packagesFolder = ".."
const jsFile = dir => join(dir, "index.js") const jsFile = dir => join(dir, "index.js")
const generatorsFile = dir => join(dir, "generators.js")
const jsMapFile = dir => join(dir, "index.js.map") const jsMapFile = dir => join(dir, "index.js.map")
const sourceJs = jsFile("dist") const sourceJs = jsFile("dist")
const sourceJsMap = jsMapFile("dist") const sourceJsMap = jsMapFile("dist")
const componentsFile = "components.json" const componentsFile = "components.json"
const sourceGenerators = generatorsFile("dist")
const appPackages = join( const appPackages = join(
packagesFolder, packagesFolder,
@ -68,7 +66,6 @@ const nodeModules = appName =>
const copySourceJs = copySource(sourceJs) const copySourceJs = copySource(sourceJs)
const copySourceJsMap = copySource(sourceJsMap) const copySourceJsMap = copySource(sourceJsMap)
const copyGenerators = copySource(sourceGenerators)
const copyComponentsJson = copySource(componentsFile) const copyComponentsJson = copySource(componentsFile)
for (let app of apps) { for (let app of apps) {
@ -77,16 +74,13 @@ const nodeModules = appName =>
await copySourceJs(nodeModulesDist(app)) await copySourceJs(nodeModulesDist(app))
await copySourceJsMap(nodeModulesDist(app)) await copySourceJsMap(nodeModulesDist(app))
await copyGenerators(nodeModulesDist(app))
await copyComponentsJson(nodeModules(app)) await copyComponentsJson(nodeModules(app))
await copySourceJs(join(publicMain(app), "dist")) await copySourceJs(join(publicMain(app), "dist"))
await copySourceJsMap(join(publicMain(app), "dist")) await copySourceJsMap(join(publicMain(app), "dist"))
await copyGenerators(join(publicMain(app), "dist"))
await copySourceJs(join(publicUnauth(app), "dist")) await copySourceJs(join(publicUnauth(app), "dist"))
await copySourceJsMap(join(publicUnauth(app), "dist")) await copySourceJsMap(join(publicUnauth(app), "dist"))
await copyGenerators(join(publicUnauth(app), "dist"))
} }
})() })()

23
packages/server/middleware/routers.js

@ -6,7 +6,7 @@ const { resolve } = require("path")
const send = require("koa-send") const send = require("koa-send")
const { const {
getPackageForBuilder, getPackageForBuilder,
getComponents, getComponentDefinitions,
getApps, getApps,
saveScreen, saveScreen,
renameScreen, renameScreen,
@ -70,16 +70,6 @@ module.exports = (config, app) => {
) )
await send(ctx, info.components._lib || "index.js", { root: info.libDir }) await send(ctx, info.components._lib || "index.js", { root: info.libDir })
}) })
.get("/_builder/:appname/componentLibraryGenerators", async ctx => {
const info = await componentLibraryInfo(
config,
ctx.params.appname,
ctx.query.lib
)
await send(ctx, info.generators._lib || "generators.js", {
root: info.libDir,
})
})
.get("/_builder/*", async (ctx, next) => { .get("/_builder/*", async (ctx, next) => {
if (!config.dev) { if (!config.dev) {
ctx.response.status = StatusCodes.FORBIDDEN ctx.response.status = StatusCodes.FORBIDDEN
@ -151,7 +141,7 @@ module.exports = (config, app) => {
}) })
.get("/_builder/api/:appname/components", async ctx => { .get("/_builder/api/:appname/components", async ctx => {
try { try {
ctx.body = getComponents(config, ctx.params.appname, ctx.query.lib) ctx.body = getComponentDefinitions(config, ctx.params.appname, ctx.query.lib)
ctx.response.status = StatusCodes.OK ctx.response.status = StatusCodes.OK
} catch (e) { } catch (e) {
if (e.status) { if (e.status) {
@ -171,15 +161,6 @@ module.exports = (config, app) => {
ctx.body = info.components ctx.body = info.components
ctx.response.status = StatusCodes.OK ctx.response.status = StatusCodes.OK
}) })
.get("/_builder/api/:appname/generators", async ctx => {
const info = await componentLibraryInfo(
config,
ctx.params.appname,
ctx.query.lib ? decodeURI(ctx.query.lib) : ""
)
ctx.body = info.generators
ctx.response.status = StatusCodes.OK
})
.post("/_builder/api/:appname/backend", async ctx => { .post("/_builder/api/:appname/backend", async ctx => {
await saveBackend( await saveBackend(
config, config,

40
packages/server/utilities/builder/componentLibraryInfo.js

@ -1,6 +1,11 @@
const { readJSON, exists } = require("fs-extra") const { readJSON, exists } = require("fs-extra")
const { resolve, join, dirname } = require("path") const { resolve, join, dirname } = require("path")
/**
* @param {string} appPath - budibase application name
* @param {string} libname - component library name
* @returns {string} directory name of component definitions for a specific budibase application.
*/
const getLibDir = (appPath, libname) => { const getLibDir = (appPath, libname) => {
try { try {
const componentsFile = require.resolve(join(libname, "components.json"), { const componentsFile = require.resolve(join(libname, "components.json"), {
@ -17,11 +22,18 @@ const getComponentsFilepath = libPath => resolve(libPath, "components.json")
module.exports.componentsFilepath = (appPath, libname) => module.exports.componentsFilepath = (appPath, libname) =>
getComponentsFilepath(getLibDir(appPath, libname)) getComponentsFilepath(getLibDir(appPath, libname))
/**
* @param {string} appPath - the path to a budibase application
* @param {string} libname - the name of the component libary to use for namespacing
* @returns {object} tree of components namespaced by their component library name.
*/
module.exports.componentLibraryInfo = async (appPath, libname) => { module.exports.componentLibraryInfo = async (appPath, libname) => {
const libDir = getLibDir(appPath, libname) const libDir = getLibDir(appPath, libname)
const componentsPath = getComponentsFilepath(libDir) const componentsPath = getComponentsFilepath(libDir)
if (!(await exists(componentsPath))) { const componentDefinitionExists = await exists(componentsPath);
if (!componentDefinitionExists) {
const e = new Error( const e = new Error(
`could not find components definition file at ${componentsPath}` `could not find components definition file at ${componentsPath}`
) )
@ -30,29 +42,17 @@ module.exports.componentLibraryInfo = async (appPath, libname) => {
} }
try { try {
const components = await readJSON(componentsPath) const componentDefinitions = await readJSON(componentsPath)
const namespacedComponents = { _lib: components._lib } const namespacedComponents = { _lib: componentDefinitions._lib }
for (let cname in components) { for (let componentKey in componentDefinitions) {
if (cname === "_lib" || cname == "_generators") continue if (componentKey === "_lib") continue
const namespacedName = `${libname}/${cname}` const namespacedName = `${libname}/${componentKey}`
components[cname].name = namespacedName componentDefinitions[componentKey].name = namespacedName
namespacedComponents[namespacedName] = components[cname] namespacedComponents[namespacedName] = componentDefinitions[componentKey]
}
const namespacedGenerators = {}
if (components._generators) {
namespacedGenerators._lib = components._generators._lib || "generators.js"
for (let gname in components._generators) {
if (gname === "_lib") continue
const namespacedName = `${libname}/${gname}`
components._generators[gname].name = namespacedName
namespacedGenerators[namespacedName] = components._generators[gname]
}
} }
return { return {
components: namespacedComponents, components: namespacedComponents,
generators: namespacedGenerators,
libDir, libDir,
componentsPath, componentsPath,
} }

33
packages/server/utilities/builder/index.js

@ -39,7 +39,7 @@ module.exports.getPackageForBuilder = async (config, appname) => {
pages, pages,
components: await getComponents(appPath, pages), components: await getComponentDefinitions(appPath, pages),
} }
} }
@ -112,36 +112,39 @@ module.exports.savePage = async (config, appname, pagename, page) => {
await buildPage(config, appname, appDefinition, pagename, page) await buildPage(config, appname, appDefinition, pagename, page)
} }
module.exports.componentLibraryInfo = async (config, appname, lib) => { module.exports.componentLibraryInfo = async (config, appname, componentLibrary) => {
const appPath = appPackageFolder(config, appname) const appPath = appPackageFolder(config, appname)
return await componentLibraryInfo(appPath, lib) return await componentLibraryInfo(appPath, componentLibrary)
} }
const getComponents = async (appPath, pages, lib) => { /**
let libs * @param {string} appPath - path to a budibase application
if (!lib) { * @param {Array} pages - a list of budibase application pages
* @param {string} componentLibrary - component library to fetch components for
* @returns {object} - an object containing component definitions namespaced by their component library
*/
const getComponentDefinitions = async (appPath, pages, componentLibrary) => {
let componentLibraries
if (!componentLibrary) {
pages = pages || (await getPages(appPath)) pages = pages || (await getPages(appPath))
if (!pages) return [] if (!pages) return []
libs = $(pages, [values, map(p => p.componentLibraries), flatten]) componentLibraries = $(pages, [values, map(p => p.componentLibraries), flatten])
} else { } else {
libs = [lib] componentLibraries = [componentLibrary]
} }
const components = {} const components = {}
const generators = {}
for (let l of libs) { for (let library of componentLibraries) {
const info = await componentLibraryInfo(appPath, l) const info = await componentLibraryInfo(appPath, library)
merge(components, info.components) merge(components, info.components)
merge(generators, info.generators)
} }
if (components._lib) delete components._lib if (components._lib) delete components._lib
if (components._generators) delete components._generators
return { components, generators } return { components }
} }
module.exports.getComponents = getComponents module.exports.getComponentDefinitions = getComponentDefinitions

57
packages/server/yarn.lock

@ -131,29 +131,6 @@
lodash "^4.17.13" lodash "^4.17.13"
to-fast-properties "^2.0.0" to-fast-properties "^2.0.0"
"@budibase/client@^0.0.16":
version "0.0.16"
resolved "https://registry.yarnpkg.com/@budibase/client/-/client-0.0.16.tgz#4eef9373816448e99cafd2714f417c6610af5e69"
integrity sha512-fx4ptePj7+IehM37xdNPHdu5jEUgAFmDx23jI0yb4sI6Z5U4gxH10FZYyoJ/A9KdzmShsIfgrmudV5ffvoehdg==
dependencies:
"@nx-js/compiler-util" "^2.0.0"
lodash "^4.17.15"
lunr "^2.3.5"
shortid "^2.2.8"
svelte "^3.9.2"
"@budibase/core@^0.0.16":
version "0.0.16"
resolved "https://registry.yarnpkg.com/@budibase/core/-/core-0.0.16.tgz#efff16876f906b2aa59803c3312ec7593664b623"
integrity sha512-DvzfurHHp9KkSjkvbGbKsVczR5ne38bMLRA2hHEJxAmC0Tshld06cEq7HMy2BmPb6kaC1URYHlFs/gPhW2cSFQ==
dependencies:
"@nx-js/compiler-util" "^2.0.0"
date-fns "^1.29.0"
lodash "^4.17.13"
lunr "^2.3.5"
safe-buffer "^5.1.2"
shortid "^2.2.8"
"@cnakazawa/watch@^1.0.3": "@cnakazawa/watch@^1.0.3":
version "1.0.3" version "1.0.3"
resolved "https://registry.yarnpkg.com/@cnakazawa/watch/-/watch-1.0.3.tgz#099139eaec7ebf07a27c1786a3ff64f39464d2ef" resolved "https://registry.yarnpkg.com/@cnakazawa/watch/-/watch-1.0.3.tgz#099139eaec7ebf07a27c1786a3ff64f39464d2ef"
@ -322,11 +299,6 @@
path-to-regexp "^1.1.1" path-to-regexp "^1.1.1"
urijs "^1.19.0" urijs "^1.19.0"
"@nx-js/compiler-util@^2.0.0":
version "2.0.0"
resolved "https://registry.yarnpkg.com/@nx-js/compiler-util/-/compiler-util-2.0.0.tgz#c74c12165fa2f017a292bb79af007e8fce0af297"
integrity sha512-AxSQbwj9zqt8DYPZ6LwZdytqnwfiOEdcFdq4l8sdjkZmU2clTht7RDLCI8xvkp7KqgcNaOGlTeCM55TULWruyQ==
"@types/babel__core@^7.1.0": "@types/babel__core@^7.1.0":
version "7.1.2" version "7.1.2"
resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.2.tgz#608c74f55928033fce18b99b213c16be4b3d114f" resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.2.tgz#608c74f55928033fce18b99b213c16be4b3d114f"
@ -1073,11 +1045,6 @@ data-urls@^1.0.0:
whatwg-mimetype "^2.2.0" whatwg-mimetype "^2.2.0"
whatwg-url "^7.0.0" whatwg-url "^7.0.0"
date-fns@^1.29.0:
version "1.30.1"
resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-1.30.1.tgz#2e71bf0b119153dbb4cc4e88d9ea5acfb50dc05c"
integrity sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw==
debug@^2.2.0, debug@^2.3.3: debug@^2.2.0, debug@^2.3.3:
version "2.6.9" version "2.6.9"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
@ -2785,7 +2752,7 @@ lodash.sortby@^4.7.0:
resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438"
integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg= integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=
lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.15: lodash@^4.17.11, lodash@^4.17.13:
version "4.17.15" version "4.17.15"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548"
integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==
@ -2810,11 +2777,6 @@ lru-cache@^4.0.1:
pseudomap "^1.0.2" pseudomap "^1.0.2"
yallist "^2.1.2" yallist "^2.1.2"
lunr@^2.3.5:
version "2.3.8"
resolved "https://registry.yarnpkg.com/lunr/-/lunr-2.3.8.tgz#a8b89c31f30b5a044b97d2d28e2da191b6ba2072"
integrity sha512-oxMeX/Y35PNFuZoHp+jUj5OSEmLCaIH4KTFJh7a93cHBoFmpw2IoPs22VIz7vyO2YUnx2Tn9dzIwO2P/4quIRg==
make-dir@^1.0.0: make-dir@^1.0.0:
version "1.3.0" version "1.3.0"
resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c"
@ -2976,11 +2938,6 @@ nan@^2.12.1:
resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c" resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c"
integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg== integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==
nanoid@^2.1.0:
version "2.1.11"
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-2.1.11.tgz#ec24b8a758d591561531b4176a01e3ab4f0f0280"
integrity sha512-s/snB+WGm6uwi0WjsZdaVcuf3KJXlfGl2LcxgwkEwJF0D/BWzVWAZW/XY4bFaiR7s0Jk3FPvlnepg1H1b1UwlA==
nanomatch@^1.2.9: nanomatch@^1.2.9:
version "1.2.13" version "1.2.13"
resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119"
@ -3816,13 +3773,6 @@ shellwords@^0.1.1:
resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b" resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b"
integrity sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww== integrity sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==
shortid@^2.2.8:
version "2.2.15"
resolved "https://registry.yarnpkg.com/shortid/-/shortid-2.2.15.tgz#2b902eaa93a69b11120373cd42a1f1fe4437c122"
integrity sha512-5EaCy2mx2Jgc/Fdn9uuDuNIIfWBpzY4XIlhoqtXF6qsf+/+SGZ+FxDdX/ZsMZiWupIWNqAEmiNY4RC+LSmCeOw==
dependencies:
nanoid "^2.1.0"
signal-exit@^3.0.0, signal-exit@^3.0.2: signal-exit@^3.0.0, signal-exit@^3.0.2:
version "3.0.2" version "3.0.2"
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d"
@ -4100,11 +4050,6 @@ supports-color@^6.1.0:
dependencies: dependencies:
has-flag "^3.0.0" has-flag "^3.0.0"
svelte@^3.9.2:
version "3.18.2"
resolved "https://registry.yarnpkg.com/svelte/-/svelte-3.18.2.tgz#f136b9e169049f8bb6a364bd8b8f3b619ed957d9"
integrity sha512-jRk7jdYULb9V4Z+0BKlfofombmdIIQph4leojrOSHzvZBRmCredz7fZsJBiUDLO6h83XYekuLbwfy5zx1i95GQ==
symbol-tree@^3.2.2: symbol-tree@^3.2.2:
version "3.2.4" version "3.2.4"
resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2"

50
packages/standard-components/components.json

@ -1,32 +1,5 @@
{ {
"_lib": "./dist/index.js", "_lib": "./dist/index.js",
"_generators": {
"_lib": "./dist/generators.js",
"app": {
"name": "App",
"description": "Generate app based on your backend"
},
"forms": {
"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",
"description": "Generate a table based on an index"
}
},
"button" : { "button" : {
"name": "Button", "name": "Button",
"description": "an html <button />", "description": "an html <button />",
@ -43,7 +16,28 @@
"hoverBackground": "string", "hoverBackground": "string",
"hoverBorder": "string" "hoverBorder": "string"
}, },
"tags": ["layout"] "tags": ["layout"],
"presets": {
"primary": {
"contentText": "Primary Button Preset",
"color": "papayawhip",
"padding": "20px",
"background": "blue"
},
"secondary": {
"contentText": "Secondary Button Preset",
"color": "rebeccapurple",
"padding": "10px",
"background": "#fff",
"border": "1px solid red"
},
"error": {
"contentText": "ERROR",
"color": "red",
"padding": "10px",
"border": "1px solid red"
}
}
}, },
"login" : { "login" : {
"name": "Login Control", "name": "Login Control",

2
packages/standard-components/package.json

@ -4,7 +4,7 @@
"main": "dist/index.js", "main": "dist/index.js",
"module": "dist/index.js", "module": "dist/index.js",
"scripts": { "scripts": {
"build": "rollup -c && rollup -c rollup.generatorsconfig.js", "build": "rollup -c",
"prepublishOnly": "npm run build", "prepublishOnly": "npm run build",
"testbuild": "rollup -w -c rollup.testconfig.js", "testbuild": "rollup -w -c rollup.testconfig.js",
"dev": "run-p start:dev testbuild", "dev": "run-p start:dev testbuild",

2
packages/standard-components/public/bundle.js

@ -27513,7 +27513,7 @@ var app = (function (crypto$1) {
var main = "dist/index.js"; var main = "dist/index.js";
var module = "dist/index.js"; var module = "dist/index.js";
var scripts = { var scripts = {
build: "rollup -c && rollup -c rollup.generatorsconfig.js", build: "rollup -c",
prepublishOnly: "npm run build", prepublishOnly: "npm run build",
testbuild: "rollup -w -c rollup.testconfig.js", testbuild: "rollup -w -c rollup.testconfig.js",
dev: "run-p start:dev testbuild", dev: "run-p start:dev testbuild",

14
packages/standard-components/rollup.generatorsconfig.js

@ -1,14 +0,0 @@
import resolve from "rollup-plugin-node-resolve"
export default {
input: "src/generators.js",
output: [
{
file: "dist/generators.js",
format: "esm",
name: "budibaseStandardComponents",
sourcemap: "inline",
},
],
plugins: [resolve()],
}

7
packages/standard-components/scripts/publishDev.js

@ -6,12 +6,10 @@ const serverConfig = require("../../server/config")()
const packagesFolder = ".." const packagesFolder = ".."
const jsFile = dir => join(dir, "index.js") const jsFile = dir => join(dir, "index.js")
const generatorsFile = dir => join(dir, "generators.js")
const jsMapFile = dir => join(dir, "index.js.map") const jsMapFile = dir => join(dir, "index.js.map")
const sourceJs = jsFile("dist") const sourceJs = jsFile("dist")
const sourceJsMap = jsMapFile("dist") const sourceJsMap = jsMapFile("dist")
const componentsFile = "components.json" const componentsFile = "components.json"
const sourceGenerators = generatorsFile("dist")
const appPackages = join( const appPackages = join(
packagesFolder, packagesFolder,
@ -50,6 +48,7 @@ const nodeModulesDist = appName =>
"standard-components", "standard-components",
"dist" "dist"
) )
const nodeModules = appName => const nodeModules = appName =>
join(appPackages, appName, "node_modules", "@budibase", "standard-components") join(appPackages, appName, "node_modules", "@budibase", "standard-components")
@ -68,7 +67,6 @@ const nodeModules = appName =>
const copySourceJs = copySource(sourceJs) const copySourceJs = copySource(sourceJs)
const copySourceJsMap = copySource(sourceJsMap) const copySourceJsMap = copySource(sourceJsMap)
const copyGenerators = copySource(sourceGenerators)
const copyComponentsJson = copySource(componentsFile) const copyComponentsJson = copySource(componentsFile)
for (let app of apps) { for (let app of apps) {
@ -77,16 +75,13 @@ const nodeModules = appName =>
await copySourceJs(nodeModulesDist(app)) await copySourceJs(nodeModulesDist(app))
await copySourceJsMap(nodeModulesDist(app)) await copySourceJsMap(nodeModulesDist(app))
await copyGenerators(nodeModulesDist(app))
await copyComponentsJson(nodeModules(app)) await copyComponentsJson(nodeModules(app))
await copySourceJs(join(publicMain(app), "dist")) await copySourceJs(join(publicMain(app), "dist"))
await copySourceJsMap(join(publicMain(app), "dist")) await copySourceJsMap(join(publicMain(app), "dist"))
await copyGenerators(join(publicMain(app), "dist"))
await copySourceJs(join(publicUnauth(app), "dist")) await copySourceJs(join(publicUnauth(app), "dist"))
await copySourceJsMap(join(publicUnauth(app), "dist")) await copySourceJsMap(join(publicUnauth(app), "dist"))
await copyGenerators(join(publicUnauth(app), "dist"))
} }
})() })()

6
packages/standard-components/src/generators.js

@ -1,6 +0,0 @@
export { app } from "./generators/appGenerator"
export { forms } from "./generators/formsGenerator"
export { buttons } from "./generators/buttonsGenerator"
export { headers } from "./generators/headersGenerator"
export { nav } from "./generators/navGenerator"
export { indexTables } from "./generators/indexTablesGenerator"

6
packages/standard-components/src/generators/appGenerator.js

@ -1,6 +0,0 @@
import { forms } from "./formsGenerator"
import { nav } from "./navGenerator"
export const app = params => {
return [...nav(params), ...forms(params)]
}

28
packages/standard-components/src/generators/buttonsGenerator.js

@ -1,28 +0,0 @@
export const buttons = () => [
{
name: "common/Primary Button",
description: "a styled button",
inherits: "@budibase/standard-components/button",
props: {
padding: "5px 7px",
border: "1px solid #EEE",
color: "#5F6368",
background: "##f2f2f2",
hoverColor: "black",
hoverBackground: "#cccccc",
},
},
{
name: "common/Secondary Button",
description: "a styled button",
inherits: "@budibase/standard-components/button",
props: {
padding: "5px 7px",
border: "1px solid #EEE",
color: "#5F6368",
background: "##f2f2f2",
hoverColor: "black",
hoverBackground: "#cccccc",
},
},
]

82
packages/standard-components/src/generators/formsGenerator.js

@ -1,82 +0,0 @@
import { headers } from "./headersGenerator"
export const forms = ({ records, indexes }) => [
...headers({ records, indexes }),
...records.map(root),
]
const root = record => ({
name: `${record.name} Form`,
description: `All fields on record '${record.nodeKey()}' `,
inherits: "@budibase/standard-components/stackpanel",
props: {
direction: "vertical",
children: [
{
control: {
_component: "common/H1",
value: `Edit ${record.name}`,
},
},
form(record),
saveCancelButtons(record),
],
},
})
const form = record => ({
control: {
_component: "@budibase/standard-components/form",
formControls: record.fields.map(f => ({
label: f.label,
control: {
_component: "@budibase/standard-components/textbox",
value: {
"##bbstate": `current${record.name}.${f.name}`,
"##bbsource": "store",
},
},
})),
},
})
const saveCancelButtons = record => ({
control: {
_component: "@budibase/standard-components/stackpanel",
direction: "horizontal",
children: [
paddedPanelForButton({
_component: "common/Primary Button",
contentText: `Save ${record.name}`,
onClick: [
{
"##eventHandlerType": "Save Record",
parameters: {
statePath: `current${record.name}`,
},
},
],
}),
paddedPanelForButton({
_component: "common/Secondary Button",
contentText: `Cancel`,
onClick: [
{
"##eventHandlerType": "Save Record",
parameters: {
statePath: `current${record.name}`,
},
},
],
}),
],
},
})
const paddedPanelForButton = button => ({
control: {
_component: "@budibase/standard-components/panel",
padding: "20px",
component: button,
},
})

34
packages/standard-components/src/generators/headersGenerator.js

@ -1,34 +0,0 @@
export const headers = () => [
{
name: "common/H1",
description: "Header 1",
inherits: "@budibase/standard-components/text",
props: {
font: "20pt",
},
},
{
name: "common/H2",
description: "Header 2",
inherits: "@budibase/standard-components/text",
props: {
font: "15pt",
},
},
{
name: "common/H3",
description: "Header 3",
inherits: "@budibase/standard-components/text",
props: {
font: "12pt bold",
},
},
{
name: "common/H4",
description: "Header 4",
inherits: "@budibase/standard-components/text",
props: {
font: "10pt bold",
},
},
]

26
packages/standard-components/src/generators/indexTablesGenerator.js

@ -1,26 +0,0 @@
export const indexTables = ({ indexes, helpers }) =>
indexes
.filter(i => i.parent().type === "root")
.map(i => indexTable(i, helpers))
export const indexTableProps = (index, helpers) => ({
data: {
"##bbstate": index.nodeKey(),
"##bbsource": "store",
},
columns: helpers.indexSchema(index).map(column),
})
const indexTable = (index, helpers) => ({
name: `tables/${index.name} Table`,
inherits: "@budibase/standard-components/table",
props: indexTableProps(index, helpers),
})
const column = col => ({
title: col.name,
value: {
"##bbstate": col.name,
"##bbsource": "context",
},
})

24
packages/standard-components/src/generators/navGenerator.js

@ -1,24 +0,0 @@
import { indexTables } from "./indexTablesGenerator"
export const nav = ({ records, indexes, helpers }) => [
{
name: "Application Root",
inherits: "@budibase/standard-components/nav",
props: {
items: indexes.filter(i => i.parent().type === "root").map(navItem),
selectedItem: {
"##bbstate": "selectedNav",
"##bbstatefallback": records[0].collectionName,
"##bbsource": "store",
},
},
},
...indexTables({ records, indexes, helpers }),
]
export const navItem = index => ({
title: index.name,
component: {
_component: `tables/${index.name} Table`,
},
})
Loading…
Cancel
Save