From 009d04a0a5489c05b75f7c0948d60e632119310a Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Fri, 9 Oct 2020 12:24:18 +0100 Subject: [PATCH 01/30] 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] + } } From 339bb8b76c629563238ca619026e4dedf7b89247 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Mon, 12 Oct 2020 10:49:21 +0100 Subject: [PATCH 02/30] Fix images and lots of other string escaping not working --- packages/client/src/state/renderTemplateString.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/client/src/state/renderTemplateString.js b/packages/client/src/state/renderTemplateString.js index c872bffc63..e2d8eba859 100644 --- a/packages/client/src/state/renderTemplateString.js +++ b/packages/client/src/state/renderTemplateString.js @@ -11,7 +11,7 @@ const entityMap = { mustache.escape = text => String(text).replace(/[&<>"'`=/]/g, function fromEntityMap(s) { - return entityMap[s] + return entityMap[s] || s }) export default mustache.render From d5bf44bba1cc1969e83b25abfa3b53a0166720c9 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Mon, 12 Oct 2020 10:50:29 +0100 Subject: [PATCH 03/30] Remove console log --- packages/builder/src/builderStore/fetchBindableProperties.js | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/builder/src/builderStore/fetchBindableProperties.js b/packages/builder/src/builderStore/fetchBindableProperties.js index d8f66af316..9205a3cad3 100644 --- a/packages/builder/src/builderStore/fetchBindableProperties.js +++ b/packages/builder/src/builderStore/fetchBindableProperties.js @@ -85,7 +85,6 @@ const contextToBindables = (models, walkResult) => context => { 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 From 55573b7e325c81872caef6f40ed35e7523811da1 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Mon, 12 Oct 2020 10:51:57 +0100 Subject: [PATCH 04/30] Remove console log statement --- .../builder/src/components/userInterface/BindingDropdown.svelte | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/builder/src/components/userInterface/BindingDropdown.svelte b/packages/builder/src/components/userInterface/BindingDropdown.svelte index 842e480b8e..10ccbd4256 100644 --- a/packages/builder/src/components/userInterface/BindingDropdown.svelte +++ b/packages/builder/src/components/userInterface/BindingDropdown.svelte @@ -12,7 +12,6 @@ const dispatch = createEventDispatcher() export let bindableProperties - console.log("Bindable Props: ", bindableProperties) export let value = "" export let close From 0f80428a23955a2685e3ca35a5baf81e413de22d Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Mon, 12 Oct 2020 11:02:03 +0100 Subject: [PATCH 05/30] Fix falsey table values not being rendered --- packages/standard-components/src/DataTable.svelte | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/standard-components/src/DataTable.svelte b/packages/standard-components/src/DataTable.svelte index 5bbd0e42a0..7eca3ede3f 100644 --- a/packages/standard-components/src/DataTable.svelte +++ b/packages/standard-components/src/DataTable.svelte @@ -100,8 +100,8 @@ {:else if schema[header].type === 'link'} {row[header]} related row(s) - {:else if row[header]} - {row[header]} + {:else} + {row[header] == null ? '' : row[header]} {/if} {/if} {/each} From f82161517e55f141ad7c91704dc8859bdfa28eb9 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Mon, 12 Oct 2020 11:25:56 +0100 Subject: [PATCH 06/30] Remove buggy transition when displaying frontend blocks --- .../src/components/userInterface/ItemTab/Item.svelte | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/packages/builder/src/components/userInterface/ItemTab/Item.svelte b/packages/builder/src/components/userInterface/ItemTab/Item.svelte index 6a3170eea5..86044cb617 100644 --- a/packages/builder/src/components/userInterface/ItemTab/Item.svelte +++ b/packages/builder/src/components/userInterface/ItemTab/Item.svelte @@ -1,13 +1,8 @@ -
+
From f1f757054e229df4321e60876d483603762dd66c Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Mon, 12 Oct 2020 14:14:50 +0100 Subject: [PATCH 07/30] Replace bindings to link fields with new count runtime property --- .../builderStore/fetchBindableProperties.js | 26 ++++++++++++------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/packages/builder/src/builderStore/fetchBindableProperties.js b/packages/builder/src/builderStore/fetchBindableProperties.js index 9205a3cad3..5aa9e47f98 100644 --- a/packages/builder/src/builderStore/fetchBindableProperties.js +++ b/packages/builder/src/builderStore/fetchBindableProperties.js @@ -95,15 +95,23 @@ const contextToBindables = (models, walkResult) => context => { return [] } - 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}`, - // how the binding exressions looks to the user of the builder - readableBinding: `${context.instance._instanceName}.${model.name}.${key}`, - }) + const newBindable = ([key, fieldSchema]) => { + // Replace link bindings with a new property representing the count + let runtimeBoundKey = key + if (fieldSchema.type === "link") { + runtimeBoundKey = `${key}_count` + } + + return { + type: "context", + fieldSchema, + instance: context.instance, + // how the binding expression persists, and is used in the app at runtime + runtimeBinding: `${contextParentPath}data.${runtimeBoundKey}`, + // how the binding expressions looks to the user of the builder + readableBinding: `${context.instance._instanceName}.${model.name}.${key}`, + } + } return ( Object.entries(schema) From 959aa3ff606f42cb228e0361e9192bb971899c7a Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Mon, 12 Oct 2020 14:19:54 +0100 Subject: [PATCH 08/30] Fix linked record selector rendering in client apps --- .../src/LinkedRecordSelector.svelte | 28 +++++++++---------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/packages/standard-components/src/LinkedRecordSelector.svelte b/packages/standard-components/src/LinkedRecordSelector.svelte index b00b5d53f3..80373a510d 100644 --- a/packages/standard-components/src/LinkedRecordSelector.svelte +++ b/packages/standard-components/src/LinkedRecordSelector.svelte @@ -1,6 +1,5 @@ -