Integration of Backend and Data Components

This commit is contained in:
cmack 2020-08-26 17:03:30 +01:00
parent 6684b31305
commit 1e38350199
18 changed files with 107 additions and 97 deletions

View File

@ -57,7 +57,7 @@
] ]
}, },
"dependencies": { "dependencies": {
"@budibase/bbui": "^1.24.1", "@budibase/bbui": "^1.27.1",
"@budibase/client": "^0.1.19", "@budibase/client": "^0.1.19",
"@budibase/colorpicker": "^1.0.1", "@budibase/colorpicker": "^1.0.1",
"@sentry/browser": "5.19.1", "@sentry/browser": "5.19.1",

View File

@ -4,19 +4,22 @@
import { onMount } from "svelte" import { onMount } from "svelte"
export let componentInstance = {} export let componentInstance = {}
export let value = ""
export let onChange = (val = {})
let datasource = componentInstance.datasource
const models = $backendUiStore.models const models = $backendUiStore.models
let options = [] let options = []
$: model = datasource ? models.find(m => m._id === datasource.modelId) : null $: model = componentInstance.datasource
? models.find(m => m._id === componentInstance.datasource.modelId)
: null
$: if (model) { $: if (model) {
options = datasource.isModel options = componentInstance.datasource.isModel
? Object.keys(model.schema) ? Object.keys(model.schema)
: Object.keys(model.views[datasource.name].schema) : Object.keys(model.views[componentInstance.datasource.name].schema)
} }
</script> </script>
<OptionSelect {options} /> <OptionSelect {value} {onChange} {options} />

View File

@ -24,7 +24,7 @@
let viewsArr = Object.entries(cur.views).map(([key, value]) => ({ let viewsArr = Object.entries(cur.views).map(([key, value]) => ({
label: key, label: key,
name: key, name: key,
modelId: value.modelId, ...value,
})) }))
return [...acc, ...viewsArr] return [...acc, ...viewsArr]
}, []) }, [])
@ -44,6 +44,7 @@
align="right"> align="right">
<div class="model-view-container"> <div class="model-view-container">
<p>Tables</p> <p>Tables</p>
<ul> <ul>
{#each models as model} {#each models as model}
<li <li

View File

@ -2,6 +2,7 @@
import { onMount, getContext } from "svelte" import { onMount, getContext } from "svelte"
export let label = "" export let label = ""
export let componentInstance = {}
export let control = null export let control = null
export let key = "" export let key = ""
export let value export let value
@ -36,6 +37,7 @@
<div data-cy={`${key}-prop-control`} class="control"> <div data-cy={`${key}-prop-control`} class="control">
<svelte:component <svelte:component
this={control} this={control}
{componentInstance}
{...handlevalueKey(value)} {...handlevalueKey(value)}
on:change={val => handleChange(key, val)} on:change={val => handleChange(key, val)}
onChange={val => handleChange(key, val)} onChange={val => handleChange(key, val)}

View File

@ -1,4 +1,5 @@
<script> <script>
import { isEmpty } from "lodash/fp"
import PropertyControl from "./PropertyControl.svelte" import PropertyControl from "./PropertyControl.svelte"
import Input from "./PropertyPanelControls/Input.svelte" import Input from "./PropertyPanelControls/Input.svelte"
import { goto } from "@sveltech/routify" import { goto } from "@sveltech/routify"
@ -30,9 +31,14 @@
{ key: "favicon", label: "Favicon", control: Input }, { key: "favicon", label: "Favicon", control: Input },
] ]
const canRenderControl = (key, dependsOn) => const canRenderControl = (key, dependsOn) => {
propExistsOnComponentDef(key) && let test = !isEmpty(componentInstance[dependsOn])
(!dependsOn || componentInstance[dependsOn])
return (
propExistsOnComponentDef(key) &&
(!dependsOn || !isEmpty(componentInstance[dependsOn]))
)
}
$: isPage = screenOrPageInstance && screenOrPageInstance.favicon $: isPage = screenOrPageInstance && screenOrPageInstance.favicon
$: screenOrPageDefinition = isPage ? pageDefinition : screenDefinition $: screenOrPageDefinition = isPage ? pageDefinition : screenDefinition
@ -68,11 +74,9 @@
label={definition.label} label={definition.label}
key={definition.key} key={definition.key}
value={componentInstance[definition.key]} value={componentInstance[definition.key]}
{componentInstance}
{onChange} {onChange}
props={{ componentInstance, ...excludeProps(definition, [ props={{ ...excludeProps(definition, ['control', 'label']) }} />
'control',
'label',
]) }} />
{/if} {/if}
{/each} {/each}
{:else} {:else}

View File

@ -21,6 +21,6 @@ export const TYPE_MAP = {
}, },
}, },
models: { models: {
default: [], default: {},
}, },
} }

View File

@ -680,12 +680,14 @@ export default {
{ {
label: "Name Label", label: "Name Label",
key: "nameLabel", key: "nameLabel",
control: Input, dependsOn: "datasource",
control: ModelViewFieldSelect,
}, },
{ {
label: "Value Label", label: "Value Label",
key: "valueLabel", key: "valueLabel",
control: Input, dependsOn: "datasource",
control: ModelViewFieldSelect,
}, },
{ {
label: "Y Axis Label", label: "Y Axis Label",
@ -789,6 +791,24 @@ export default {
key: "datasource", key: "datasource",
control: ModelViewSelect, control: ModelViewSelect,
}, },
{
label: "Name Label",
key: "nameLabel",
dependsOn: "datasource",
control: ModelViewFieldSelect,
},
{
label: "Group Label",
key: "groupLabel",
dependsOn: "datasource",
control: ModelViewFieldSelect,
},
{
label: "Value Label",
key: "valueLabel",
dependsOn: "datasource",
control: ModelViewFieldSelect,
},
{ {
label: "Color", label: "Color",
key: "color", key: "color",
@ -827,16 +847,6 @@ export default {
control: OptionSelect, control: OptionSelect,
options: ["vertical", "horizontal", "full"], options: ["vertical", "horizontal", "full"],
}, },
{
label: "Group Label",
key: "groupLabel",
control: Input,
},
{
label: "Name Label",
key: "nameLabel",
control: Input,
},
{ {
label: "Value Label", label: "Value Label",
key: "valueLabel", key: "valueLabel",
@ -884,6 +894,24 @@ export default {
key: "datasource", key: "datasource",
control: ModelViewSelect, control: ModelViewSelect,
}, },
{
label: "Value Label",
key: "valueLabel",
dependsOn: "datasource",
control: ModelViewFieldSelect,
},
{
label: "Topic Label",
key: "topicLabel",
dependsOn: "datasource",
control: ModelViewFieldSelect,
},
{
label: "Date Label",
key: "dateLabel",
dependsOn: "datasource",
control: ModelViewFieldSelect,
},
{ {
label: "Colors", label: "Colors",
key: "color", key: "color",
@ -941,21 +969,6 @@ export default {
control: OptionSelect, control: OptionSelect,
options: ["vertical", "horizontal", "full"], options: ["vertical", "horizontal", "full"],
}, },
{
label: "Date Label",
key: "dateLabel",
control: Input,
},
{
label: "Topic Label",
key: "topicLabel",
control: Input,
},
{
label: "Value Label",
key: "valueLabel",
control: Input,
},
{ {
label: "X Axis Label", label: "X Axis Label",
key: "xAxisLabel", key: "xAxisLabel",

View File

@ -1,6 +1,5 @@
import { last } from "lodash/fp" import { last } from "lodash/fp"
import { pipe } from "components/common/core" import { pipe } from "components/common/core"
export const buildStyle = styles => { export const buildStyle = styles => {
let str = "" let str = ""
for (let s in styles) { for (let s in styles) {

View File

@ -688,15 +688,15 @@
lodash "^4.17.13" lodash "^4.17.13"
to-fast-properties "^2.0.0" to-fast-properties "^2.0.0"
"@budibase/bbui@^1.24.2": "@budibase/bbui@^1.27.1":
version "1.24.2" version "1.27.1"
resolved "https://registry.yarnpkg.com/@budibase/bbui/-/bbui-1.24.2.tgz#d3416062d6d17c4f346686984d4da3c595106c87" resolved "https://registry.yarnpkg.com/@budibase/bbui/-/bbui-1.27.1.tgz#79625cb4235a6f0dad07338a05f1525de7ccade3"
dependencies: dependencies:
sirv-cli "^0.4.6" sirv-cli "^0.4.6"
"@budibase/client@^0.1.17": "@budibase/client@^0.1.19":
version "0.1.18" version "0.1.19"
resolved "https://registry.yarnpkg.com/@budibase/client/-/client-0.1.18.tgz#10cf733ed3e912d7a93f06c0f152a1dd7cff50a2" resolved "https://registry.yarnpkg.com/@budibase/client/-/client-0.1.19.tgz#3906781423ab4626118c981657ecf7a4578c547c"
dependencies: dependencies:
"@nx-js/compiler-util" "^2.0.0" "@nx-js/compiler-util" "^2.0.0"
bcryptjs "^2.4.3" bcryptjs "^2.4.3"

View File

@ -500,6 +500,8 @@
"data": true, "data": true,
"props": { "props": {
"datasource": "models", "datasource": "models",
"nameLabel": "string",
"valueLabel": "string",
"betweenBarsPadding": "number", "betweenBarsPadding": "number",
"gradient": "string", "gradient": "string",
"color": "string", "color": "string",
@ -510,9 +512,6 @@
"isHorizontal": "bool", "isHorizontal": "bool",
"labelNumberFormat": "number", "labelNumberFormat": "number",
"locale": "string", "locale": "string",
"nameLabel": "string",
"valueLabel": "string",
"numberLabel": "string",
"xAxisLabel": "string", "xAxisLabel": "string",
"yAxisLabel": "string", "yAxisLabel": "string",
"useLegend": "bool", "useLegend": "bool",
@ -583,6 +582,8 @@
"data": true, "data": true,
"props": { "props": {
"datasource": "models", "datasource": "models",
"nameLabel": "string",
"valueLabel": "string",
"color": "string", "color": "string",
"height": "string", "height": "string",
"width": "string", "width": "string",
@ -591,8 +592,6 @@
"groupLabel": "string", "groupLabel": "string",
"isAnimated": "bool", "isAnimated": "bool",
"isHorizontal": "bool", "isHorizontal": "bool",
"nameLabel": "string",
"valueLabel":"string",
"yTicks": "string", "yTicks": "string",
"useLegend": "bool", "useLegend": "bool",
"tooltipTitle": "string" "tooltipTitle": "string"

File diff suppressed because one or more lines are too long

View File

@ -3,6 +3,8 @@ import resolve from "rollup-plugin-node-resolve"
import commonjs from "@rollup/plugin-commonjs" import commonjs from "@rollup/plugin-commonjs"
import postcss from "rollup-plugin-postcss" import postcss from "rollup-plugin-postcss"
const lodash_fp_exports = ["isEmpty"]
export default { export default {
input: "src/index.js", input: "src/index.js",
output: [ output: [
@ -23,6 +25,10 @@ export default {
resolve({ resolve({
browser: true, browser: true,
}), }),
commonjs(), commonjs({
namedExports: {
"lodash/fp": lodash_fp_exports,
},
}),
], ],
} }

View File

@ -8,6 +8,7 @@
import britecharts from "britecharts" import britecharts from "britecharts"
import fetchData from "../fetchData.js" import fetchData from "../fetchData.js"
import { onMount } from "svelte" import { onMount } from "svelte"
import { isEmpty } from "lodash/fp"
import { select } from "d3-selection" import { select } from "d3-selection"
import shortid from "shortid" import shortid from "shortid"
@ -28,6 +29,7 @@
export let customClick = null export let customClick = null
let data = [] let data = []
export let datasource = null
export let xAxisLabel = "" export let xAxisLabel = ""
export let yAxisLabel = "" export let yAxisLabel = ""
export let betweenBarsPadding = 0.1 //takes decimal values 0.1, 0.5 etc export let betweenBarsPadding = 0.1 //takes decimal values 0.1, 0.5 etc
@ -54,11 +56,11 @@
export let yTicks = null export let yTicks = null
export let percentageAxisToMaxRatio = null export let percentageAxisToMaxRatio = null
export let _bb
onMount(async () => { onMount(async () => {
if (datasource) { if (!isEmpty(datasource)) {
data = await fetchData(datasource) data = await fetchData(datasource)
console.log("DATA", data)
if (schemaIsValid()) { if (schemaIsValid()) {
chartContainer = select(`.${chartClass}`) chartContainer = select(`.${chartClass}`)
bindChartUIProps() bindChartUIProps()

View File

@ -4,6 +4,7 @@
import Legend from "./Legend.svelte" import Legend from "./Legend.svelte"
import britecharts from "britecharts" import britecharts from "britecharts"
import { onMount } from "svelte" import { onMount } from "svelte"
import { isEmpty } from "lodash/fp"
import { select } from "d3-selection" import { select } from "d3-selection"
import shortid from "shortid" import shortid from "shortid"
@ -22,7 +23,6 @@
let chartSvg = null let chartSvg = null
export let _bb export let _bb
export let model
let store = _bb.store let store = _bb.store
@ -59,7 +59,7 @@
onMount(async () => { onMount(async () => {
if (chart) { if (chart) {
if (datasource) { if (!isEmpty(datasource)) {
let _data = await fetchData(datasource) let _data = await fetchData(datasource)
data = checkAndReformatData(_data) data = checkAndReformatData(_data)
if (data.length === 0) { if (data.length === 0) {
@ -84,11 +84,11 @@
function checkAndReformatData(data) { function checkAndReformatData(data) {
let _data = [...data] let _data = [...data]
if (valueKey) { if (valueKey && valueKey !== "quantity") {
_data = reformatDataKey(_data, valueKey, "quantity") _data = reformatDataKey(_data, valueKey, "quantity")
} }
if (nameKey) { if (nameKey && nameKey !== "name") {
_data = reformatDataKey(_data, nameKey, "name") _data = reformatDataKey(_data, nameKey, "name")
} }

View File

@ -6,14 +6,10 @@
import { onMount } from "svelte" import { onMount } from "svelte"
import { select } from "d3-selection" import { select } from "d3-selection"
import shortid from "shortid" import shortid from "shortid"
import { isEmpty } from "lodash/fp"
const _id = shortid.generate() const _id = shortid.generate()
export let _bb
export let datasource = {}
let store = _bb.store
const chart = britecharts.groupedBar() const chart = britecharts.groupedBar()
const chartClass = `groupedbar-container-${_id}` const chartClass = `groupedbar-container-${_id}`
const legendClass = `legend-container-${_id}` const legendClass = `legend-container-${_id}`
@ -26,6 +22,7 @@
export let customClick = null export let customClick = null
let data = [] let data = []
export let datasource = {}
export let color = "britecharts" export let color = "britecharts"
export let height = 200 export let height = 200
export let width = 200 export let width = 200
@ -51,7 +48,7 @@
(hasProp(data, "value") || hasProp(data, valueLabel)) (hasProp(data, "value") || hasProp(data, valueLabel))
onMount(async () => { onMount(async () => {
if (model) { if (!isEmpty(datasource)) {
data = await fetchData(datasource) data = await fetchData(datasource)
if (schemaIsValid()) { if (schemaIsValid()) {
chartContainer = select(`.${chartClass}`) chartContainer = select(`.${chartClass}`)

View File

@ -3,17 +3,15 @@
import fetchData from "../fetchData.js" import fetchData from "../fetchData.js"
import britecharts from "britecharts" import britecharts from "britecharts"
import { onMount } from "svelte" import { onMount } from "svelte"
import { isEmpty } from "lodash/fp"
import { select } from "d3-selection" import { select } from "d3-selection"
import shortid from "shortid" import shortid from "shortid"
const _id = shortid.generate() const _id = shortid.generate()
export let _bb
export let datasource = {} export let datasource = {}
let store = _bb.store
const chart = britecharts.line() const chart = britecharts.line()
const chartClass = `line-container-${_id}` const chartClass = `line-container-${_id}`
@ -66,8 +64,9 @@
export let tooltipTitle = "" export let tooltipTitle = ""
onMount(async () => { onMount(async () => {
if (datasource) { if (!isEmpty(datasource)) {
data = await getAndPrepareData() data = await getAndPrepareData()
console.log("DATA", data)
if (data.dataByTopic.length > 0) { if (data.dataByTopic.length > 0) {
chartContainer = select(`.${chartClass}`) chartContainer = select(`.${chartClass}`)
bindChartUIProps() bindChartUIProps()

View File

@ -5,8 +5,7 @@
import ArrowDown from "./icons/ArrowDown.svelte" import ArrowDown from "./icons/ArrowDown.svelte"
import fsort from "fast-sort" import fsort from "fast-sort"
import fetchData from "./fetchData.js" import fetchData from "./fetchData.js"
import { isEmpty } from "lodash/fp"
export let _bb
export let backgroundColor export let backgroundColor
export let color export let color
@ -16,7 +15,6 @@
let data = [] let data = []
let headers = [] let headers = []
let store = _bb.store
let sort = {} let sort = {}
let sorted = [] let sorted = []
@ -30,7 +28,7 @@
$: sorted = sort.direction ? fsort(data)[sort.direction](sort.column) : data $: sorted = sort.direction ? fsort(data)[sort.direction](sort.column) : data
onMount(async () => { onMount(async () => {
if (datasource) { if (!isEmpty(datasource)) {
data = await fetchData(datasource) data = await fetchData(datasource)
if (data) { if (data) {
headers = Object.keys(data[0]).filter(shouldDisplayField) headers = Object.keys(data[0]).filter(shouldDisplayField)

View File

@ -1,34 +1,21 @@
<script> <script>
import { onMount } from "svelte" import { onMount } from "svelte"
import fetchData from "./fetchData.js"
import { isEmpty } from "lodash/fp"
export let _bb export let _bb
export let model export let datasource = []
let headers = []
let store = _bb.store
let target let target
async function fetchData() { onMount(async () => {
if (!model || !model.length) return if (!isEmpty(datasource)) {
const data = await fetchData(datasource)
const FETCH_RECORDS_URL = `/api/views/all_${model}`
const response = await _bb.api.get(FETCH_RECORDS_URL)
if (response.status === 200) {
const json = await response.json()
_bb.attachChildren(target, { _bb.attachChildren(target, {
hydrate: false, hydrate: false,
context: json, context: data,
}) })
} else {
throw new Error("Failed to fetch records.", response)
} }
}
$: if (model) fetchData()
onMount(async () => {
await fetchData()
}) })
</script> </script>