commit
b8bd724dbf
|
@ -1,24 +1,5 @@
|
|||
{
|
||||
"_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" : {
|
||||
"importPath": "Form",
|
||||
"name": "Form",
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
"main": "dist/index.js",
|
||||
"module": "dist/index.js",
|
||||
"scripts": {
|
||||
"build": "rollup -c && rollup -c rollup.generatorsconfig.js",
|
||||
"build": "rollup -c",
|
||||
"prepublishOnly": "npm run build",
|
||||
"testbuild": "rollup -w -c rollup.testconfig.js",
|
||||
"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 jsFile = dir => join(dir, "index.js")
|
||||
const generatorsFile = dir => join(dir, "generators.js")
|
||||
const jsMapFile = dir => join(dir, "index.js.map")
|
||||
const sourceJs = jsFile("dist")
|
||||
const sourceJsMap = jsMapFile("dist")
|
||||
const componentsFile = "components.json"
|
||||
const sourceGenerators = generatorsFile("dist")
|
||||
|
||||
const appPackages = join(packagesFolder, "server", "appPackages")
|
||||
|
||||
|
@ -69,7 +67,6 @@ const nodeModules = appName =>
|
|||
|
||||
const copySourceJs = copySource(sourceJs)
|
||||
const copySourceJsMap = copySource(sourceJsMap)
|
||||
const copyGenerators = copySource(sourceGenerators)
|
||||
const copyComponentsJson = copySource(componentsFile)
|
||||
|
||||
for (let app of apps) {
|
||||
|
@ -77,16 +74,13 @@ const nodeModules = appName =>
|
|||
|
||||
await copySourceJs(nodeModulesDist(app))
|
||||
await copySourceJsMap(nodeModulesDist(app))
|
||||
await copyGenerators(nodeModulesDist(app))
|
||||
|
||||
await copyComponentsJson(nodeModules(app))
|
||||
|
||||
await copySourceJs(join(publicMain(app), "dist"))
|
||||
await copySourceJsMap(join(publicMain(app), "dist"))
|
||||
await copyGenerators(join(publicMain(app), "dist"))
|
||||
|
||||
await copySourceJs(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(
|
||||
[
|
||||
"/_builder/api/**",
|
||||
"/_builder/**/componentlibrary",
|
||||
"/_builder/**/componentlibraryGenerators",
|
||||
"/_builder/**/componentlibrary"
|
||||
],
|
||||
{
|
||||
target,
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
import { map } from "lodash/fp"
|
||||
|
||||
export const loadLibs = async (appName, appPackage) => {
|
||||
const allLibraries = {}
|
||||
for (let lib of appPackage.pages.componentLibraries) {
|
||||
|
@ -10,16 +8,6 @@ export const loadLibs = async (appName, appPackage) => {
|
|||
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) => {
|
||||
const allLibraries = []
|
||||
for (let lib of appPackage.pages.componentLibraries) {
|
||||
|
@ -35,13 +23,5 @@ export const loadLib = async (appName, lib, allLibs) => {
|
|||
return allLibs
|
||||
}
|
||||
|
||||
export const loadGeneratorLib = async (appName, lib, allGeneratorLibs) => {
|
||||
allGeneratorLibs[lib] = await import(makeGeneratorLibraryUrl(appName, lib))
|
||||
return allGeneratorLibs
|
||||
}
|
||||
|
||||
export const makeLibraryUrl = (appName, 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 {
|
||||
loadLibs,
|
||||
loadLibUrls,
|
||||
loadGeneratorLibs,
|
||||
loadLibUrls
|
||||
} from "./loadComponentLibraries"
|
||||
import { buildCodeForScreens } from "./buildCodeForScreens"
|
||||
import { generate_screen_css } from "./generate_css"
|
||||
import { insertCodeMetadata } from "./insertCodeMetadata"
|
||||
// import { uuid } from "./uuid"
|
||||
|
||||
let appname = ""
|
||||
|
||||
|
@ -94,7 +91,6 @@ export const getStore = () => {
|
|||
store.deleteLevel = deleteLevel(store)
|
||||
store.setActiveNav = setActiveNav(store)
|
||||
store.saveScreen = saveScreen(store)
|
||||
store.refreshComponents = refreshComponents(store)
|
||||
store.addComponentLibrary = addComponentLibrary(store)
|
||||
store.renameScreen = renameScreen(store)
|
||||
store.deleteScreen = deleteScreen(store)
|
||||
|
@ -159,8 +155,6 @@ const initialise = (store, initial) => async () => {
|
|||
}
|
||||
|
||||
initial.libraries = await loadLibs(appname, pkg)
|
||||
|
||||
initial.generatorLibraries = await loadGeneratorLibs(appname, pkg)
|
||||
initial.loadLibraryUrls = () => loadLibUrls(appname, pkg)
|
||||
initial.appname = appname
|
||||
initial.pages = pkg.pages
|
||||
|
@ -168,7 +162,6 @@ const initialise = (store, initial) => async () => {
|
|||
initial.hierarchy = pkg.appDefinition.hierarchy
|
||||
initial.accessLevels = pkg.accessLevels
|
||||
initial.screens = values(pkg.screens)
|
||||
initial.generators = generatorsArray(pkg.components.generators)
|
||||
initial.components = values(pkg.components.components).map(
|
||||
expandComponentDefinition
|
||||
)
|
||||
|
@ -187,9 +180,6 @@ const initialise = (store, initial) => async () => {
|
|||
return initial
|
||||
}
|
||||
|
||||
const generatorsArray = generators =>
|
||||
pipe(generators, [keys, filter(k => k !== "_lib"), map(k => generators[k])])
|
||||
|
||||
const showSettings = store => () => {
|
||||
store.update(s => {
|
||||
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 page = s.pages[s.currentPageName]
|
||||
|
||||
|
@ -749,19 +718,25 @@ const setCurrentPage = store => pageName => {
|
|||
const getContainerComponent = components =>
|
||||
components.find(c => c.name === "@budibase/standard-components/container")
|
||||
|
||||
const addChildComponent = store => componentName => {
|
||||
store.update(s => {
|
||||
const component = componentName.startsWith("##")
|
||||
? getBuiltin(componentName)
|
||||
: s.components.find(c => c.name === componentName)
|
||||
const newComponent = createProps(component)
|
||||
/**
|
||||
* @param {string} componentToAdd - name of the component to add to the application
|
||||
* @param {string} presetName - name of the component preset if defined
|
||||
*/
|
||||
const addChildComponent = store => (componentToAdd, presetName) => {
|
||||
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
|
||||
)
|
||||
|
||||
_savePage(s)
|
||||
return s
|
||||
_savePage(state)
|
||||
|
||||
return state
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
<button on:click>+</button>
|
||||
<button on:click>
|
||||
<slot>
|
||||
+
|
||||
</slot>
|
||||
</button>
|
||||
|
||||
<style>
|
||||
button {
|
||||
|
@ -8,8 +12,8 @@
|
|||
border-radius: 5px;
|
||||
background: rgba(249, 249, 249, 1);
|
||||
|
||||
width: 1.8rem;
|
||||
height: 1.8rem;
|
||||
min-width: 1.8rem;
|
||||
min-height: 1.8rem;
|
||||
padding-bottom: 10px;
|
||||
|
||||
display: flex;
|
||||
|
|
|
@ -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>
|
||||
import { store } from "../builderStore/"
|
||||
import ComponentPanel from "./ComponentPanel.svelte"
|
||||
import ComponentsList from "./ComponentsList.svelte"
|
||||
import ComponentPropertiesPanel from "./ComponentPropertiesPanel.svelte"
|
||||
import ComponentSelectionList from "./ComponentSelectionList.svelte"
|
||||
|
||||
let selected = "properties"
|
||||
|
||||
|
@ -30,11 +30,11 @@
|
|||
|
||||
<div class="panel">
|
||||
{#if selected === 'properties'}
|
||||
<ComponentPanel />
|
||||
<ComponentPropertiesPanel />
|
||||
{/if}
|
||||
|
||||
{#if selected === 'components'}
|
||||
<ComponentsList />
|
||||
<ComponentSelectionList />
|
||||
{/if}
|
||||
|
||||
</div>
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
<script>
|
||||
import PropsView from "./PropsView.svelte"
|
||||
import { store } from "../builderStore"
|
||||
import IconButton from "../common/IconButton.svelte"
|
||||
import Textbox from "../common/Textbox.svelte"
|
||||
import Button from "../common/Button.svelte"
|
||||
import { LayoutIcon, PaintIcon, TerminalIcon } from "../common/Icons/"
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
<script>
|
||||
import ComponentSelector from "./ComponentSelector.svelte"
|
||||
import { store } from "../builderStore"
|
||||
import PropsView from "./PropsView.svelte"
|
||||
import Textbox from "../common/Textbox.svelte"
|
||||
|
|
|
@ -1,48 +1,50 @@
|
|||
<script>
|
||||
import { ArrowDownIcon } from "../common/Icons/";
|
||||
import { store } from "../builderStore";
|
||||
import { buildStateOrigins } from "../builderStore/buildStateOrigins";
|
||||
import { isBinding, getBinding, setBinding } from "../common/binding";
|
||||
import { ArrowDownIcon } from "../common/Icons/"
|
||||
import { store } from "../builderStore"
|
||||
import { buildStateOrigins } from "../builderStore/buildStateOrigins"
|
||||
import { isBinding, getBinding, setBinding } from "../common/binding"
|
||||
|
||||
export let onChanged = () => {};
|
||||
export let value = "";
|
||||
export let onChanged = () => {}
|
||||
export let value = ""
|
||||
|
||||
let isOpen = false;
|
||||
let stateBindings = [];
|
||||
let isOpen = false
|
||||
let stateBindings = []
|
||||
|
||||
let bindingPath = "";
|
||||
let bindingFallbackValue = "";
|
||||
let bindingSource = "store";
|
||||
let bindingValue = "";
|
||||
let bindingPath = ""
|
||||
let bindingFallbackValue = ""
|
||||
let bindingSource = "store"
|
||||
let bindingValue = ""
|
||||
|
||||
const bind = (path, fallback, source) => {
|
||||
if (!path) {
|
||||
onChanged(fallback);
|
||||
return;
|
||||
onChanged(fallback)
|
||||
return
|
||||
}
|
||||
const binding = setBinding({ path, fallback, source })
|
||||
onChanged(binding)
|
||||
}
|
||||
const binding = setBinding({ path, fallback, source });
|
||||
onChanged(binding);
|
||||
};
|
||||
|
||||
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 =>
|
||||
bind(bindingPath, bindingFallbackValue, value);
|
||||
bind(bindingPath, bindingFallbackValue, value)
|
||||
|
||||
$: {
|
||||
const binding = getBinding(value);
|
||||
if (bindingPath !== binding.path) isOpen = false;
|
||||
bindingPath = binding.path;
|
||||
bindingValue = typeof value === "object" ? "" : value;
|
||||
bindingFallbackValue = binding.fallback || bindingValue;
|
||||
const binding = getBinding(value)
|
||||
if (bindingPath !== binding.path) isOpen = false
|
||||
bindingPath = binding.path
|
||||
bindingValue = typeof value === "object" ? "" : value
|
||||
bindingFallbackValue = binding.fallback || bindingValue
|
||||
|
||||
const currentScreen = $store.screens.find(
|
||||
({ name }) => name === $store.currentPreviewItem.name
|
||||
);
|
||||
stateBindings = currentScreen ? Object.keys(buildStateOrigins(currentScreen)) : [];
|
||||
)
|
||||
stateBindings = currentScreen
|
||||
? Object.keys(buildStateOrigins(currentScreen))
|
||||
: []
|
||||
}
|
||||
</script>
|
||||
|
||||
|
@ -53,9 +55,10 @@
|
|||
class="uk-input uk-form-small"
|
||||
value={bindingFallbackValue || bindingPath}
|
||||
on:change={e => {
|
||||
setBindingFallback(e.target.value);
|
||||
onChanged(e.target.value);
|
||||
setBindingFallback(e.target.value)
|
||||
onChanged(e.target.value)
|
||||
}} />
|
||||
{#if stateBindings.length}
|
||||
<button on:click={() => (isOpen = !isOpen)}>
|
||||
<div
|
||||
class="icon"
|
||||
|
@ -64,6 +67,7 @@
|
|||
<ArrowDownIcon size={36} />
|
||||
</div>
|
||||
</button>
|
||||
{/if}
|
||||
</div>
|
||||
{#if isOpen}
|
||||
<ul class="options">
|
||||
|
@ -71,7 +75,7 @@
|
|||
<li
|
||||
class:bold={stateBinding === bindingPath}
|
||||
on:click={() => {
|
||||
setBindingPath(stateBinding === bindingPath ? null : stateBinding);
|
||||
setBindingPath(stateBinding === bindingPath ? null : stateBinding)
|
||||
}}>
|
||||
{stateBinding}
|
||||
</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) => {
|
||||
const error = (propName, error) => errors.push({ propName, error })
|
||||
const errorOccurred = (propName, error) => errors.push({ propName, error })
|
||||
|
||||
const props = {
|
||||
_component: componentDefinition.name,
|
||||
|
@ -37,12 +42,12 @@ export const createProps = (componentDefinition, derivedFromProps) => {
|
|||
const errors = []
|
||||
|
||||
if (!componentDefinition.name)
|
||||
error("_component", "Component name not supplied")
|
||||
errorOccurred("_component", "Component name not supplied")
|
||||
|
||||
const propsDef = componentDefinition.props
|
||||
for (let propDef in propsDef) {
|
||||
const parsedPropDef = parsePropDef(propsDef[propDef])
|
||||
if (parsedPropDef.error) error(propDef, parsedPropDef.error)
|
||||
if (parsedPropDef.error) errorOccurred(propDef, parsedPropDef.error)
|
||||
else props[propDef] = parsedPropDef
|
||||
}
|
||||
|
||||
|
|
|
@ -573,23 +573,6 @@
|
|||
lodash "^4.17.10"
|
||||
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@*":
|
||||
version "1.17.0"
|
||||
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"
|
||||
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:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
|
||||
|
@ -1438,11 +1416,6 @@ loose-envify@^1.0.0:
|
|||
dependencies:
|
||||
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:
|
||||
version "1.3.0"
|
||||
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"
|
||||
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:
|
||||
version "1.2.13"
|
||||
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"
|
||||
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:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d"
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
{
|
||||
"_lib": "./dist/index.js",
|
||||
"_generators": {},
|
||||
"Body1": {
|
||||
"name": "Body1",
|
||||
"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 jsFile = dir => join(dir, "index.js")
|
||||
const generatorsFile = dir => join(dir, "generators.js")
|
||||
const jsMapFile = dir => join(dir, "index.js.map")
|
||||
const sourceJs = jsFile("dist")
|
||||
const sourceJsMap = jsMapFile("dist")
|
||||
const componentsFile = "components.json"
|
||||
const sourceGenerators = generatorsFile("dist")
|
||||
|
||||
const appPackages = join(
|
||||
packagesFolder,
|
||||
|
@ -68,7 +66,6 @@ const nodeModules = appName =>
|
|||
|
||||
const copySourceJs = copySource(sourceJs)
|
||||
const copySourceJsMap = copySource(sourceJsMap)
|
||||
const copyGenerators = copySource(sourceGenerators)
|
||||
const copyComponentsJson = copySource(componentsFile)
|
||||
|
||||
for (let app of apps) {
|
||||
|
@ -77,16 +74,13 @@ const nodeModules = appName =>
|
|||
|
||||
await copySourceJs(nodeModulesDist(app))
|
||||
await copySourceJsMap(nodeModulesDist(app))
|
||||
await copyGenerators(nodeModulesDist(app))
|
||||
|
||||
await copyComponentsJson(nodeModules(app))
|
||||
|
||||
await copySourceJs(join(publicMain(app), "dist"))
|
||||
await copySourceJsMap(join(publicMain(app), "dist"))
|
||||
await copyGenerators(join(publicMain(app), "dist"))
|
||||
|
||||
await copySourceJs(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 jsFile = dir => join(dir, "index.js")
|
||||
const generatorsFile = dir => join(dir, "generators.js")
|
||||
const jsMapFile = dir => join(dir, "index.js.map")
|
||||
const sourceJs = jsFile("dist")
|
||||
const sourceJsMap = jsMapFile("dist")
|
||||
const componentsFile = "components.json"
|
||||
const sourceGenerators = generatorsFile("dist")
|
||||
|
||||
const appPackages = join(
|
||||
packagesFolder,
|
||||
|
@ -68,7 +66,6 @@ const nodeModules = appName =>
|
|||
|
||||
const copySourceJs = copySource(sourceJs)
|
||||
const copySourceJsMap = copySource(sourceJsMap)
|
||||
const copyGenerators = copySource(sourceGenerators)
|
||||
const copyComponentsJson = copySource(componentsFile)
|
||||
|
||||
for (let app of apps) {
|
||||
|
@ -77,16 +74,13 @@ const nodeModules = appName =>
|
|||
|
||||
await copySourceJs(nodeModulesDist(app))
|
||||
await copySourceJsMap(nodeModulesDist(app))
|
||||
await copyGenerators(nodeModulesDist(app))
|
||||
|
||||
await copyComponentsJson(nodeModules(app))
|
||||
|
||||
await copySourceJs(join(publicMain(app), "dist"))
|
||||
await copySourceJsMap(join(publicMain(app), "dist"))
|
||||
await copyGenerators(join(publicMain(app), "dist"))
|
||||
|
||||
await copySourceJs(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 {
|
||||
getPackageForBuilder,
|
||||
getComponents,
|
||||
getComponentDefinitions,
|
||||
getApps,
|
||||
saveScreen,
|
||||
renameScreen,
|
||||
|
@ -70,16 +70,6 @@ module.exports = (config, app) => {
|
|||
)
|
||||
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) => {
|
||||
if (!config.dev) {
|
||||
ctx.response.status = StatusCodes.FORBIDDEN
|
||||
|
@ -151,7 +141,7 @@ module.exports = (config, app) => {
|
|||
})
|
||||
.get("/_builder/api/:appname/components", async ctx => {
|
||||
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
|
||||
} catch (e) {
|
||||
if (e.status) {
|
||||
|
@ -171,15 +161,6 @@ module.exports = (config, app) => {
|
|||
ctx.body = info.components
|
||||
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 => {
|
||||
await saveBackend(
|
||||
config,
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
const { readJSON, exists } = require("fs-extra")
|
||||
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) => {
|
||||
try {
|
||||
const componentsFile = require.resolve(join(libname, "components.json"), {
|
||||
|
@ -17,11 +22,18 @@ const getComponentsFilepath = libPath => resolve(libPath, "components.json")
|
|||
module.exports.componentsFilepath = (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) => {
|
||||
const libDir = getLibDir(appPath, libname)
|
||||
const componentsPath = getComponentsFilepath(libDir)
|
||||
|
||||
if (!(await exists(componentsPath))) {
|
||||
const componentDefinitionExists = await exists(componentsPath);
|
||||
|
||||
if (!componentDefinitionExists) {
|
||||
const e = new Error(
|
||||
`could not find components definition file at ${componentsPath}`
|
||||
)
|
||||
|
@ -30,29 +42,17 @@ module.exports.componentLibraryInfo = async (appPath, libname) => {
|
|||
}
|
||||
|
||||
try {
|
||||
const components = await readJSON(componentsPath)
|
||||
const namespacedComponents = { _lib: components._lib }
|
||||
for (let cname in components) {
|
||||
if (cname === "_lib" || cname == "_generators") continue
|
||||
const namespacedName = `${libname}/${cname}`
|
||||
components[cname].name = namespacedName
|
||||
namespacedComponents[namespacedName] = components[cname]
|
||||
}
|
||||
|
||||
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]
|
||||
}
|
||||
const componentDefinitions = await readJSON(componentsPath)
|
||||
const namespacedComponents = { _lib: componentDefinitions._lib }
|
||||
for (let componentKey in componentDefinitions) {
|
||||
if (componentKey === "_lib") continue
|
||||
const namespacedName = `${libname}/${componentKey}`
|
||||
componentDefinitions[componentKey].name = namespacedName
|
||||
namespacedComponents[namespacedName] = componentDefinitions[componentKey]
|
||||
}
|
||||
|
||||
return {
|
||||
components: namespacedComponents,
|
||||
generators: namespacedGenerators,
|
||||
libDir,
|
||||
componentsPath,
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ module.exports.getPackageForBuilder = async (config, appname) => {
|
|||
|
||||
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)
|
||||
}
|
||||
|
||||
module.exports.componentLibraryInfo = async (config, appname, lib) => {
|
||||
module.exports.componentLibraryInfo = async (config, appname, componentLibrary) => {
|
||||
const appPath = appPackageFolder(config, appname)
|
||||
return await componentLibraryInfo(appPath, lib)
|
||||
return await componentLibraryInfo(appPath, componentLibrary)
|
||||
}
|
||||
|
||||
const getComponents = async (appPath, pages, lib) => {
|
||||
let libs
|
||||
if (!lib) {
|
||||
/**
|
||||
* @param {string} appPath - path to a budibase application
|
||||
* @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))
|
||||
|
||||
if (!pages) return []
|
||||
|
||||
libs = $(pages, [values, map(p => p.componentLibraries), flatten])
|
||||
componentLibraries = $(pages, [values, map(p => p.componentLibraries), flatten])
|
||||
} else {
|
||||
libs = [lib]
|
||||
componentLibraries = [componentLibrary]
|
||||
}
|
||||
|
||||
const components = {}
|
||||
const generators = {}
|
||||
|
||||
for (let l of libs) {
|
||||
const info = await componentLibraryInfo(appPath, l)
|
||||
for (let library of componentLibraries) {
|
||||
const info = await componentLibraryInfo(appPath, library)
|
||||
merge(components, info.components)
|
||||
merge(generators, info.generators)
|
||||
}
|
||||
|
||||
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"
|
||||
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":
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@cnakazawa/watch/-/watch-1.0.3.tgz#099139eaec7ebf07a27c1786a3ff64f39464d2ef"
|
||||
|
@ -322,11 +299,6 @@
|
|||
path-to-regexp "^1.1.1"
|
||||
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":
|
||||
version "7.1.2"
|
||||
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-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:
|
||||
version "2.6.9"
|
||||
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"
|
||||
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"
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548"
|
||||
integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==
|
||||
|
@ -2810,11 +2777,6 @@ lru-cache@^4.0.1:
|
|||
pseudomap "^1.0.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:
|
||||
version "1.3.0"
|
||||
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"
|
||||
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:
|
||||
version "1.2.13"
|
||||
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"
|
||||
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:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d"
|
||||
|
@ -4100,11 +4050,6 @@ supports-color@^6.1.0:
|
|||
dependencies:
|
||||
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:
|
||||
version "3.2.4"
|
||||
resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2"
|
||||
|
|
|
@ -1,32 +1,5 @@
|
|||
{
|
||||
"_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" : {
|
||||
"name": "Button",
|
||||
"description": "an html <button />",
|
||||
|
@ -43,7 +16,28 @@
|
|||
"hoverBackground": "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" : {
|
||||
"name": "Login Control",
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
"main": "dist/index.js",
|
||||
"module": "dist/index.js",
|
||||
"scripts": {
|
||||
"build": "rollup -c && rollup -c rollup.generatorsconfig.js",
|
||||
"build": "rollup -c",
|
||||
"prepublishOnly": "npm run build",
|
||||
"testbuild": "rollup -w -c rollup.testconfig.js",
|
||||
"dev": "run-p start:dev testbuild",
|
||||
|
|
|
@ -27513,7 +27513,7 @@ var app = (function (crypto$1) {
|
|||
var main = "dist/index.js";
|
||||
var module = "dist/index.js";
|
||||
var scripts = {
|
||||
build: "rollup -c && rollup -c rollup.generatorsconfig.js",
|
||||
build: "rollup -c",
|
||||
prepublishOnly: "npm run build",
|
||||
testbuild: "rollup -w -c rollup.testconfig.js",
|
||||
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 jsFile = dir => join(dir, "index.js")
|
||||
const generatorsFile = dir => join(dir, "generators.js")
|
||||
const jsMapFile = dir => join(dir, "index.js.map")
|
||||
const sourceJs = jsFile("dist")
|
||||
const sourceJsMap = jsMapFile("dist")
|
||||
const componentsFile = "components.json"
|
||||
const sourceGenerators = generatorsFile("dist")
|
||||
|
||||
const appPackages = join(
|
||||
packagesFolder,
|
||||
|
@ -50,6 +48,7 @@ const nodeModulesDist = appName =>
|
|||
"standard-components",
|
||||
"dist"
|
||||
)
|
||||
|
||||
const nodeModules = appName =>
|
||||
join(appPackages, appName, "node_modules", "@budibase", "standard-components")
|
||||
|
||||
|
@ -68,7 +67,6 @@ const nodeModules = appName =>
|
|||
|
||||
const copySourceJs = copySource(sourceJs)
|
||||
const copySourceJsMap = copySource(sourceJsMap)
|
||||
const copyGenerators = copySource(sourceGenerators)
|
||||
const copyComponentsJson = copySource(componentsFile)
|
||||
|
||||
for (let app of apps) {
|
||||
|
@ -77,16 +75,13 @@ const nodeModules = appName =>
|
|||
|
||||
await copySourceJs(nodeModulesDist(app))
|
||||
await copySourceJsMap(nodeModulesDist(app))
|
||||
await copyGenerators(nodeModulesDist(app))
|
||||
|
||||
await copyComponentsJson(nodeModules(app))
|
||||
|
||||
await copySourceJs(join(publicMain(app), "dist"))
|
||||
await copySourceJsMap(join(publicMain(app), "dist"))
|
||||
await copyGenerators(join(publicMain(app), "dist"))
|
||||
|
||||
await copySourceJs(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 New Issue