mirror of https://github.com/Budibase/budibase.git
committed by
GitHub
46 changed files with 364 additions and 1215 deletions
@ -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()], |
|||
} |
|||
@ -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), |
|||
}, |
|||
}, |
|||
}) |
|||
@ -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,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()], |
|||
} |
|||
@ -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()], |
|||
} |
|||
@ -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