spike - list that accepts children

This commit is contained in:
Michael Shanks 2020-06-02 23:26:06 +01:00
parent c7e8cc95e4
commit f6b98d987f
6 changed files with 125 additions and 10 deletions

View File

@ -318,6 +318,17 @@ export default {
}, },
children: [], children: [],
}, },
{
name: "Another List",
_component: "@budibase/standard-components/list",
description: "Shiny list",
icon: "ri-file-list-fill",
properties: {
design: { ...all },
settings: [{ label: "Model", key: "model", control: ModelSelect }],
},
children: [],
},
{ {
name: "Map", name: "Map",
_component: "@budibase/standard-components/datamap", _component: "@budibase/standard-components/datamap",

View File

@ -14,6 +14,7 @@ export const attachChildren = initialiseOpts => (htmlElement, options) => {
const anchor = options && options.anchor ? options.anchor : null const anchor = options && options.anchor ? options.anchor : null
const force = options ? options.force : false const force = options ? options.force : false
const hydrate = options ? options.hydrate : true const hydrate = options ? options.hydrate : true
const context = options && options.context
if (!force && treeNode.children.length > 0) return treeNode.children if (!force && treeNode.children.length > 0) return treeNode.children
@ -37,12 +38,14 @@ export const attachChildren = initialiseOpts => (htmlElement, options) => {
const ComponentConstructor = componentLibraries[libName][componentName] const ComponentConstructor = componentLibraries[libName][componentName]
const prepareNodes = ctx => {
const childNodesThisIteration = prepareRenderComponent({ const childNodesThisIteration = prepareRenderComponent({
props: childProps, props: childProps,
parentNode: treeNode, parentNode: treeNode,
ComponentConstructor, ComponentConstructor,
htmlElement, htmlElement,
anchor, anchor,
context: ctx,
}) })
for (let childNode of childNodesThisIteration) { for (let childNode of childNodesThisIteration) {
@ -50,6 +53,15 @@ export const attachChildren = initialiseOpts => (htmlElement, options) => {
} }
} }
if (Array.isArray(context)) {
for (let singleCtx of context) {
prepareNodes(singleCtx)
}
} else {
prepareNodes(context)
}
}
if (areTreeNodesEqual(treeNode.children, childNodes)) return treeNode.children if (areTreeNodesEqual(treeNode.children, childNodes)) return treeNode.children
for (let node of childNodes) { for (let node of childNodes) {

View File

@ -7,11 +7,12 @@ export const prepareRenderComponent = ({
anchor, anchor,
props, props,
parentNode, parentNode,
context,
}) => { }) => {
const parentContext = (parentNode && parentNode.context) || {} const parentContext = (parentNode && parentNode.context) || {}
let nodesToRender = [] let nodesToRender = []
const createNodeAndRender = context => { const createNodeAndRender = () => {
let componentContext = parentContext let componentContext = parentContext
if (context) { if (context) {
componentContext = { ...context } componentContext = { ...context }
@ -48,6 +49,7 @@ export const prepareRenderComponent = ({
if (typeof propValue === "string") { if (typeof propValue === "string") {
storeBoundProps[prop] = mustache.render(propValue, { storeBoundProps[prop] = mustache.render(propValue, {
state, state,
context: componentContext,
}) })
} }
} }

View File

@ -216,6 +216,21 @@
} }
} }
}, },
"list": {
"description": "A configurable data list that attaches to your backend models.",
"data": true,
"props": {
"model": "models",
"layout": {
"type": "options",
"default": "list",
"options": [
"list",
"grid"
]
}
}
},
"datamap": { "datamap": {
"description": "shiny chart", "description": "shiny chart",
"data": true, "data": true,

View File

@ -0,0 +1,74 @@
<script>
import { onMount } from "svelte"
export let _bb
export let _instanceId
export let model
export let layout = "list"
let headers = []
let store = _bb.store
let target
async function fetchData() {
if (!model || !model.length) return
const FETCH_RECORDS_URL = `/api/${_instanceId}/views/all_${model}`
const response = await _bb.api.get(FETCH_RECORDS_URL)
if (response.status === 200) {
const json = await response.json()
_bb.attachChildren(target, {
hydrate: false,
context: json,
})
} else {
throw new Error("Failed to fetch records.", response)
}
}
$: if (model) fetchData()
onMount(async () => {
await fetchData()
})
</script>
<section class:grid={layout === 'grid'} class:list={layout === 'list'}>
<div class="data-card" bind:this={target}>
</div>
</section>
<style>
.list {
display: flex;
flex-direction: column;
font-family: Roboto;
}
.grid {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
}
ul {
list-style-type: none;
}
li {
margin: 5px 0 5px 0;
}
.data-card {
border: 1px solid #ccc;
border-radius: 5px;
padding: 10px;
}
.data-key {
font-weight: bold;
font-size: 20px;
text-transform: capitalize;
}
</style>

View File

@ -18,5 +18,6 @@ export { default as datatable } from "./DataTable.svelte"
export { default as dataform } from "./DataForm.svelte" export { default as dataform } from "./DataForm.svelte"
export { default as datachart } from "./DataChart.svelte" export { default as datachart } from "./DataChart.svelte"
export { default as datalist } from "./DataList.svelte" export { default as datalist } from "./DataList.svelte"
export { default as list } from "./List.svelte"
export { default as datasearch } from "./DataSearch.svelte" export { default as datasearch } from "./DataSearch.svelte"
export { default as datamap } from "./DataMap.svelte" export { default as datamap } from "./DataMap.svelte"