commit
b8bd724dbf
46 changed files with 363 additions and 1214 deletions
|
@ -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",
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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()],
|
|
||||||
}
|
|
|
@ -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"))
|
|
||||||
}
|
}
|
||||||
})()
|
})()
|
||||||
|
|
|
@ -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"
|
|
|
@ -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),
|
|
||||||
},
|
|
||||||
})
|
|
|
@ -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",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
]
|
|
|
@ -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,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
})
|
|
|
@ -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("/")
|
|
||||||
}
|
|
|
@ -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",
|
|
||||||
},
|
|
||||||
})
|
|
|
@ -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",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
})
|
|
|
@ -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),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
|
@ -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,
|
||||||
|
|
|
@ -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)}`
|
|
||||||
|
|
|
@ -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("##")
|
||||||
|
? getBuiltin(componentToAdd)
|
||||||
|
: state.components.find(({ name }) => name === componentToAdd)
|
||||||
|
const presetProps = presetName ? component.presets[presetName] : {};
|
||||||
|
const newComponent = createProps(component, presetProps);
|
||||||
|
|
||||||
s.currentComponentInfo._children = s.currentComponentInfo._children.concat(
|
state.currentComponentInfo._children = state.currentComponentInfo._children.concat(
|
||||||
newComponent.props
|
newComponent.props
|
||||||
)
|
)
|
||||||
|
|
||||||
_savePage(s)
|
_savePage(state)
|
||||||
return s
|
|
||||||
|
return state
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
218
packages/builder/src/userInterface/ComponentSelectionList.svelte
Normal file
218
packages/builder/src/userInterface/ComponentSelectionList.svelte
Normal file
|
@ -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>
|
|
@ -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>
|
|
|
@ -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,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,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"
|
||||||
|
|
|
@ -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 })
|
||||||
|
onChanged(binding)
|
||||||
}
|
}
|
||||||
const binding = setBinding({ path, fallback, source });
|
|
||||||
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,9 +55,10 @@
|
||||||
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)
|
||||||
}} />
|
}} />
|
||||||
|
{#if stateBindings.length}
|
||||||
<button on:click={() => (isOpen = !isOpen)}>
|
<button on:click={() => (isOpen = !isOpen)}>
|
||||||
<div
|
<div
|
||||||
class="icon"
|
class="icon"
|
||||||
|
@ -64,6 +67,7 @@
|
||||||
<ArrowDownIcon size={36} />
|
<ArrowDownIcon size={36} />
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</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>
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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,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",
|
||||||
|
|
|
@ -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,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"))
|
|
||||||
}
|
}
|
||||||
})()
|
})()
|
||||||
|
|
|
@ -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"))
|
|
||||||
}
|
}
|
||||||
})()
|
})()
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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,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"))
|
|
||||||
}
|
}
|
||||||
})()
|
})()
|
||||||
|
|
|
@ -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"
|
|
|
@ -1,6 +0,0 @@
|
||||||
import { forms } from "./formsGenerator"
|
|
||||||
import { nav } from "./navGenerator"
|
|
||||||
|
|
||||||
export const app = params => {
|
|
||||||
return [...nav(params), ...forms(params)]
|
|
||||||
}
|
|
|
@ -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",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
]
|
|
|
@ -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,
|
|
||||||
},
|
|
||||||
})
|
|
|
@ -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",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
]
|
|
|
@ -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",
|
|
||||||
},
|
|
||||||
})
|
|
|
@ -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…
Reference in a new issue