forked from tsai/budibase
committed by
GitHub
38 changed files with 728 additions and 258 deletions
|
After Width: | Height: | Size: 213 B |
|
Before Width: | Height: | Size: 246 B After Width: | Height: | Size: 254 B |
|
After Width: | Height: | Size: 254 B |
|
After Width: | Height: | Size: 388 B |
|
After Width: | Height: | Size: 387 B |
@ -0,0 +1,146 @@ |
|||||
|
<script> |
||||
|
// import { tick } from "svelte" |
||||
|
import ComponentsHierarchyChildren from "./ComponentsHierarchyChildren.svelte" |
||||
|
|
||||
|
import { last, sortBy, map, trimCharsStart, trimChars, join } from "lodash/fp" |
||||
|
import ConfirmDialog from "../common/ConfirmDialog.svelte" |
||||
|
import { pipe } from "../common/core" |
||||
|
import { store } from "../builderStore" |
||||
|
import { ArrowDownIcon, GridIcon } from "../common/Icons/" |
||||
|
|
||||
|
export let layout |
||||
|
|
||||
|
let confirmDeleteDialog |
||||
|
let componentToDelete = "" |
||||
|
|
||||
|
const joinPath = join("/") |
||||
|
|
||||
|
const normalizedName = name => |
||||
|
pipe( |
||||
|
name, |
||||
|
[ |
||||
|
trimCharsStart("./"), |
||||
|
trimCharsStart("~/"), |
||||
|
trimCharsStart("../"), |
||||
|
trimChars(" "), |
||||
|
] |
||||
|
) |
||||
|
|
||||
|
const lastPartOfName = c => |
||||
|
c && last(c.name ? c.name.split("/") : c._component.split("/")) |
||||
|
|
||||
|
const isComponentSelected = (current, comp) => current === comp |
||||
|
|
||||
|
const isFolderSelected = (current, folder) => isInSubfolder(current, folder) |
||||
|
|
||||
|
$: _layout = pipe( |
||||
|
layout, |
||||
|
[c => ({ component: c, title: lastPartOfName(c) })] |
||||
|
) |
||||
|
|
||||
|
const isScreenSelected = component => |
||||
|
component.component && |
||||
|
$store.currentPreviewItem && |
||||
|
component.component.name === $store.currentPreviewItem.name |
||||
|
|
||||
|
const confirmDeleteComponent = async component => { |
||||
|
console.log(component) |
||||
|
componentToDelete = component |
||||
|
// await tick() |
||||
|
confirmDeleteDialog.show() |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<div class="root"> |
||||
|
<div |
||||
|
class="hierarchy-item component" |
||||
|
class:selected={$store.currentComponentInfo._id === _layout.component.props._id} |
||||
|
on:click|stopPropagation={() => store.setScreenType('page')}> |
||||
|
|
||||
|
<span |
||||
|
class="icon" |
||||
|
class:rotate={$store.currentPreviewItem.name !== _layout.title}> |
||||
|
{#if _layout.component.props._children.length} |
||||
|
<ArrowDownIcon /> |
||||
|
{/if} |
||||
|
</span> |
||||
|
|
||||
|
<span class="icon"> |
||||
|
<GridIcon /> |
||||
|
</span> |
||||
|
|
||||
|
<span class="title">Master Layout</span> |
||||
|
</div> |
||||
|
|
||||
|
{#if $store.currentPreviewItem.name === _layout.title && _layout.component.props._children} |
||||
|
<ComponentsHierarchyChildren |
||||
|
components={_layout.component.props._children} |
||||
|
currentComponent={$store.currentComponentInfo} |
||||
|
onSelect={store.selectComponent} |
||||
|
onDeleteComponent={confirmDeleteComponent} |
||||
|
onMoveUpComponent={store.moveUpComponent} |
||||
|
onMoveDownComponent={store.moveDownComponent} |
||||
|
onCopyComponent={store.copyComponent} /> |
||||
|
{/if} |
||||
|
</div> |
||||
|
|
||||
|
<ConfirmDialog |
||||
|
bind:this={confirmDeleteDialog} |
||||
|
title="Confirm Delete" |
||||
|
body={`Are you sure you wish to delete this '${lastPartOfName(componentToDelete)}' component`} |
||||
|
okText="Delete Component" |
||||
|
onOk={() => store.deleteComponent(componentToDelete)} /> |
||||
|
|
||||
|
<style> |
||||
|
.root { |
||||
|
font-weight: 400; |
||||
|
font-size: 0.8rem; |
||||
|
color: #333; |
||||
|
} |
||||
|
|
||||
|
.hierarchy-item { |
||||
|
cursor: pointer; |
||||
|
padding: 0 7px 0 3px; |
||||
|
height: 35px; |
||||
|
margin: 5px 0; |
||||
|
border-radius: 0 5px 5px 0; |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
font-weight: 500; |
||||
|
} |
||||
|
|
||||
|
.hierarchy-item:hover { |
||||
|
background: #fafafa; |
||||
|
} |
||||
|
|
||||
|
.selected { |
||||
|
color: var(--button-text); |
||||
|
background: var(--background-button) !important; |
||||
|
} |
||||
|
|
||||
|
.title { |
||||
|
margin-left: 10px; |
||||
|
margin-top: 2px; |
||||
|
} |
||||
|
|
||||
|
.icon { |
||||
|
display: inline-block; |
||||
|
transition: 0.2s; |
||||
|
width: 20px; |
||||
|
margin-top: 2px; |
||||
|
color: #333; |
||||
|
} |
||||
|
|
||||
|
.icon:nth-of-type(2) { |
||||
|
width: 14px; |
||||
|
margin: 0 0 0 5px; |
||||
|
} |
||||
|
|
||||
|
:global(svg) { |
||||
|
transition: 0.2s; |
||||
|
} |
||||
|
|
||||
|
.rotate :global(svg) { |
||||
|
transform: rotate(-90deg); |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,15 @@ |
|||||
|
<script> |
||||
|
import { getContext } from "svelte" |
||||
|
import ClassBuilder from "../ClassBuilder.js" |
||||
|
|
||||
|
export let _bb |
||||
|
|
||||
|
const cb = getContext("BBMD:data-table:cb") |
||||
|
|
||||
|
let tbody |
||||
|
|
||||
|
$: tbody && _bb.attachChildren(tbody) |
||||
|
|
||||
|
</script> |
||||
|
|
||||
|
<tbody bind:this={tbody} class={cb.elem`content`}></tbody> |
||||
@ -0,0 +1,11 @@ |
|||||
|
<script> |
||||
|
|
||||
|
export let _bb |
||||
|
|
||||
|
let thead |
||||
|
|
||||
|
$: thead && _bb.attachChildren(thead) |
||||
|
|
||||
|
</script> |
||||
|
|
||||
|
<thead bind:this={thead} class=className></thead> |
||||
@ -1,2 +1,6 @@ |
|||||
import "./_style.scss"; |
import "./_style.scss" |
||||
export { default as Datatable } from "./Datatable.svelte"; |
export { default as Datatable } from "./Datatable.svelte" |
||||
|
export { default as DatatableCell } from "./DatatableCell.svelte" |
||||
|
export { default as DatatableHead } from "./DatatableHead.svelte" |
||||
|
export { default as DatatableBody } from "./DatatableBody.svelte" |
||||
|
export { default as DatatableRow } from "./DatatableRow.svelte" |
||||
|
|||||
@ -0,0 +1,69 @@ |
|||||
|
export default ({ indexes, helpers }) => |
||||
|
indexes.map(i => ({ |
||||
|
name: `Table based on index: ${i.name} `, |
||||
|
props: tableProps(i, helpers.indexSchema(i)), |
||||
|
})) |
||||
|
|
||||
|
const tableProps = (index, indexSchema) => ({ |
||||
|
_component: "@budibase/materialdesign-components/Datatable", |
||||
|
_children: [ |
||||
|
{ |
||||
|
_component: "@budibase/materialdesign-components/DatatableHead", |
||||
|
_children: [ |
||||
|
{ |
||||
|
_component: "@budibase/materialdesign-components/DatatableRow", |
||||
|
isHeader: true, |
||||
|
_children: columnHeaders(indexSchema), |
||||
|
}, |
||||
|
], |
||||
|
}, |
||||
|
{ |
||||
|
_component: "@budibase/materialdesign-components/DatatableBody", |
||||
|
_children: [ |
||||
|
{ |
||||
|
_code: rowCode(index), |
||||
|
_component: "@budibase/materialdesign-components/DatatableRow", |
||||
|
_children: dataCells(index, indexSchema), |
||||
|
}, |
||||
|
], |
||||
|
}, |
||||
|
], |
||||
|
}) |
||||
|
|
||||
|
const columnHeaders = indexSchema => |
||||
|
indexSchema.map(col => ({ |
||||
|
_component: "@budibase/materialdesign-components/DatatableCell", |
||||
|
isHeader: true, |
||||
|
_children: [ |
||||
|
{ |
||||
|
_component: "@budibase/standard-components/text", |
||||
|
type: "none", |
||||
|
text: col.name, |
||||
|
}, |
||||
|
], |
||||
|
})) |
||||
|
|
||||
|
const dataCells = (index, indexSchema) => |
||||
|
indexSchema.map(col => ({ |
||||
|
_component: "@budibase/materialdesign-components/DatatableCell", |
||||
|
_children: [ |
||||
|
{ |
||||
|
_component: "@budibase/standard-components/text", |
||||
|
type: "none", |
||||
|
text: { |
||||
|
"##bbstate": `${dataItem(index)}.${col.name}`, |
||||
|
"##bbstatefallback": "", |
||||
|
"##bbsource": "context", |
||||
|
}, |
||||
|
}, |
||||
|
], |
||||
|
})) |
||||
|
|
||||
|
const dataItem = index => `${index.name}_item` |
||||
|
const dataCollection = index => `store.${index.name}` |
||||
|
const rowCode = index => |
||||
|
` |
||||
|
if (!${dataCollection(index)}) return |
||||
|
|
||||
|
for (let ${dataItem(index)} of ${dataCollection(index)}) |
||||
|
render( { ${dataItem(index)}) }` |
||||
@ -1,25 +1,3 @@ |
|||||
import { |
import * as components from "@BBMD" |
||||
H1, |
|
||||
Overline, |
|
||||
Button, |
|
||||
Icon, |
|
||||
Textfield, |
|
||||
Checkbox, |
|
||||
Checkboxgroup, |
|
||||
Radiobutton, |
|
||||
Radiobuttongroup, |
|
||||
Datatable, |
|
||||
} from "@BBMD" |
|
||||
|
|
||||
export default { |
export default components |
||||
H1, |
|
||||
Overline, |
|
||||
Button, |
|
||||
Icon, |
|
||||
Textfield, |
|
||||
Checkbox, |
|
||||
Checkboxgroup, |
|
||||
Radiobutton, |
|
||||
Radiobuttongroup, |
|
||||
Datatable, |
|
||||
} |
|
||||
|
|||||
@ -0,0 +1,19 @@ |
|||||
|
<script> |
||||
|
|
||||
|
import { buildStyle } from "./buildStyle" |
||||
|
|
||||
|
export let className = ""; |
||||
|
export let url = ""; |
||||
|
export let description = "" |
||||
|
export let height |
||||
|
export let width |
||||
|
|
||||
|
$: style = buildStyle({height, width}) |
||||
|
|
||||
|
</script> |
||||
|
|
||||
|
|
||||
|
<img class={className} |
||||
|
style={style} |
||||
|
src={url} |
||||
|
alt={description} > |
||||
@ -0,0 +1,18 @@ |
|||||
|
<script> |
||||
|
|
||||
|
export let url = "" |
||||
|
export let text = "" |
||||
|
export let openInNewTab = false |
||||
|
|
||||
|
export let _bb |
||||
|
|
||||
|
let anchorElement |
||||
|
|
||||
|
$: anchorElement && !text && _bb.attachChildren(anchorElement) |
||||
|
$: target = openInNewTab ? "_blank" : "_self" |
||||
|
|
||||
|
</script> |
||||
|
|
||||
|
<a href={url} bind:this={anchorElement} target={target}>{text}</a> |
||||
|
|
||||
|
|
||||
@ -0,0 +1,12 @@ |
|||||
|
<script> |
||||
|
|
||||
|
export let className="" |
||||
|
export let _bb |
||||
|
|
||||
|
let thead |
||||
|
|
||||
|
$: _bb.attachChildren(thead) |
||||
|
|
||||
|
</script> |
||||
|
|
||||
|
<tbody bind:this={thead} class=className></tbody> |
||||
@ -0,0 +1,12 @@ |
|||||
|
<script> |
||||
|
|
||||
|
export let className="" |
||||
|
export let _bb |
||||
|
|
||||
|
let thead |
||||
|
|
||||
|
$: _bb.attachChildren(thead) |
||||
|
|
||||
|
</script> |
||||
|
|
||||
|
<thead bind:this={thead} class=className></thead> |
||||
Loading…
Reference in new issue