From d1f367ccffb6cbb30c88cfbc4b35e876220b27fe Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Fri, 9 Oct 2020 12:24:18 +0100 Subject: [PATCH] Add relationships as data source --- .../builderStore/fetchBindableProperties.js | 34 ++++++++++------ .../userInterface/ModelViewFieldSelect.svelte | 8 ++-- .../userInterface/ModelViewSelect.svelte | 40 +++++++++++++++++-- .../server/src/utilities/fileProcessor.js | 18 ++++----- .../standard-components/src/DataTable.svelte | 4 +- packages/standard-components/src/List.svelte | 2 +- .../src/RecordDetail.svelte | 4 ++ packages/standard-components/src/fetchData.js | 27 +++++++++++-- 8 files changed, 103 insertions(+), 34 deletions(-) diff --git a/packages/builder/src/builderStore/fetchBindableProperties.js b/packages/builder/src/builderStore/fetchBindableProperties.js index 92359ae630..d8f66af316 100644 --- a/packages/builder/src/builderStore/fetchBindableProperties.js +++ b/packages/builder/src/builderStore/fetchBindableProperties.js @@ -73,18 +73,32 @@ const componentInstanceToBindable = walkResult => i => { const contextToBindables = (models, walkResult) => context => { const contextParentPath = getParentPath(walkResult, context) - const isModel = context.model?.isModel || typeof context.model === "string" - const modelId = - typeof context.model === "string" ? context.model : context.model.modelId - const model = models.find(model => model._id === modelId) + + let model, schema + if (typeof context.model === "string" || context.model.type === "model") { + const modelId = + typeof context.model === "string" ? context.model : context.model.modelId + model = models.find(model => model._id === modelId) + schema = model?.schema + } else if (context.model.type === "view") { + const modelId = context.model.modelId + model = models.find(model => model._id === modelId) + schema = model?.views?.[context.model.name]?.schema + } else if (context.model.type === "link") { + console.log(context.model) + const modelId = context.model.modelId + model = models.find(model => model._id === modelId) + schema = model?.schema + } // Avoid crashing whenever no data source has been selected - if (model == null) { + if (!schema) { return [] } - const newBindable = key => ({ + const newBindable = ([key, fieldSchema]) => ({ type: "context", + fieldSchema, instance: context.instance, // how the binding expression persists, and is used in the app at runtime runtimeBinding: `${contextParentPath}data.${key}`, @@ -92,15 +106,11 @@ const contextToBindables = (models, walkResult) => context => { readableBinding: `${context.instance._instanceName}.${model.name}.${key}`, }) - // see ModelViewSelect.svelte for the format of context.model - // ... this allows us to bind to Model schemas, or View schemas - const schema = isModel ? model.schema : model.views[context.model.name].schema - return ( - Object.keys(schema) + Object.entries(schema) .map(newBindable) // add _id and _rev fields - not part of schema, but always valid - .concat([newBindable("_id"), newBindable("_rev")]) + .concat([newBindable(["_id", "string"]), newBindable(["_rev", "string"])]) ) } diff --git a/packages/builder/src/components/userInterface/ModelViewFieldSelect.svelte b/packages/builder/src/components/userInterface/ModelViewFieldSelect.svelte index a6b3ef2224..ddc24c9a59 100644 --- a/packages/builder/src/components/userInterface/ModelViewFieldSelect.svelte +++ b/packages/builder/src/components/userInterface/ModelViewFieldSelect.svelte @@ -15,10 +15,12 @@ ? models.find(m => m._id === componentInstance.datasource.modelId) : null + $: type = componentInstance.datasource.type $: if (model) { - options = componentInstance.datasource.isModel - ? Object.keys(model.schema) - : Object.keys(model.views[componentInstance.datasource.name].schema) + options = + type === "model" || type === "link" + ? Object.keys(model.schema) + : Object.keys(model.views[componentInstance.datasource.name].schema) } diff --git a/packages/builder/src/components/userInterface/ModelViewSelect.svelte b/packages/builder/src/components/userInterface/ModelViewSelect.svelte index 282c6c93f0..d0f0c37f3b 100644 --- a/packages/builder/src/components/userInterface/ModelViewSelect.svelte +++ b/packages/builder/src/components/userInterface/ModelViewSelect.svelte @@ -1,7 +1,8 @@ diff --git a/packages/server/src/utilities/fileProcessor.js b/packages/server/src/utilities/fileProcessor.js index 3e580e9e37..734209733d 100644 --- a/packages/server/src/utilities/fileProcessor.js +++ b/packages/server/src/utilities/fileProcessor.js @@ -1,5 +1,5 @@ const fs = require("fs") -const sharp = require("sharp") +// const sharp = require("sharp") const fsPromises = fs.promises const FORMATS = { @@ -7,14 +7,14 @@ const FORMATS = { } async function processImage(file) { - const imgMeta = await sharp(file.path) - .resize(300) - .toFile(file.outputPath) - - return { - ...file, - ...imgMeta, - } + // const imgMeta = await sharp(file.path) + // .resize(300) + // .toFile(file.outputPath) + // + // return { + // ...file, + // ...imgMeta, + // } } async function process(file) { diff --git a/packages/standard-components/src/DataTable.svelte b/packages/standard-components/src/DataTable.svelte index 5b950fec4b..5bbd0e42a0 100644 --- a/packages/standard-components/src/DataTable.svelte +++ b/packages/standard-components/src/DataTable.svelte @@ -39,7 +39,7 @@ onMount(async () => { if (!isEmpty(datasource)) { - data = await fetchData(datasource) + data = await fetchData(datasource, _bb) if (data && data.length) { await fetchModel(data[0].modelId) headers = Object.keys(schema).filter(shouldDisplayField) @@ -99,7 +99,7 @@ {#if schema[header].type === 'attachment'} {:else if schema[header].type === 'link'} - {row[header] ? row[header].length : 0} related row(s) + {row[header]} related row(s) {:else if row[header]} {row[header]} {/if} diff --git a/packages/standard-components/src/List.svelte b/packages/standard-components/src/List.svelte index 6b2fa2bfb7..e31d510fbf 100644 --- a/packages/standard-components/src/List.svelte +++ b/packages/standard-components/src/List.svelte @@ -10,7 +10,7 @@ onMount(async () => { if (!isEmpty(datasource)) { - const data = await fetchData(datasource) + const data = await fetchData(datasource, _bb) _bb.attachChildren(target, { hydrate: false, context: data, diff --git a/packages/standard-components/src/RecordDetail.svelte b/packages/standard-components/src/RecordDetail.svelte index aa9d39c0cc..61ac79f4e7 100644 --- a/packages/standard-components/src/RecordDetail.svelte +++ b/packages/standard-components/src/RecordDetail.svelte @@ -26,6 +26,10 @@ async function fetchData() { const pathParts = window.location.pathname.split("/") + if (!model) { + return + } + let record // if srcdoc, then we assume this is the builder preview if (pathParts.length === 0 || pathParts[0] === "srcdoc") { diff --git a/packages/standard-components/src/fetchData.js b/packages/standard-components/src/fetchData.js index a0c50c233a..2193010530 100644 --- a/packages/standard-components/src/fetchData.js +++ b/packages/standard-components/src/fetchData.js @@ -1,10 +1,17 @@ import api from "./api" -export default async function fetchData(datasource) { - const { isModel, name } = datasource +export default async function fetchData(datasource, _bb) { + const { type, name } = datasource if (name) { - const records = isModel ? await fetchModelData() : await fetchViewData() + let records + if (type === "model") { + records = await fetchModelData() + } else if (type === "view") { + records = await fetchViewData() + } else if (type === "link") { + records = await fetchLinkedRecordsData() + } // Fetch model schema so we can check for linked records if (records && records.length) { @@ -53,4 +60,18 @@ export default async function fetchData(datasource) { const response = await api.get(QUERY_VIEW_URL) return await response.json() } + + async function fetchLinkedRecordsData() { + if ( + !_bb.store.state || + !_bb.store.state.data || + !_bb.store.state.data._id + ) { + return [] + } + const QUERY_URL = `/api/${_bb.store.state.data.modelId}/${_bb.store.state.data._id}/enrich` + const response = await api.get(QUERY_URL) + const record = await response.json() + return record[datasource.fieldName] + } }