From 3f77e0a0ba87e96d07bd8f6bf358cdaedc0ec79a Mon Sep 17 00:00:00 2001
From: Joe <49767913+joebudi@users.noreply.github.com>
Date: Thu, 11 Jun 2020 13:07:10 +0100
Subject: [PATCH 1/8] Props update, including flex, border, shadow, rotate
---
.../userInterface/propertyCategories.js | 66 ++++++++++++++-----
1 file changed, 49 insertions(+), 17 deletions(-)
diff --git a/packages/builder/src/components/userInterface/propertyCategories.js b/packages/builder/src/components/userInterface/propertyCategories.js
index 38ef0558e4..8ee38d3c35 100644
--- a/packages/builder/src/components/userInterface/propertyCategories.js
+++ b/packages/builder/src/components/userInterface/propertyCategories.js
@@ -12,8 +12,9 @@ export const layout = [
label: "Display",
key: "display",
control: OptionSelect,
- initialValue: "Flex",
+ initialValue: "",
options: [
+ { label: "", value: "" },
{ label: "Flex", value: "flex" },
{ label: "Inline Flex", value: "inline-flex" },
],
@@ -39,6 +40,7 @@ export const layout = [
control: OptionSelect,
initialValue: "Flex Start",
options: [
+ { label: "", value: "" },
{ label: "Flex Start", value: "flex-start" },
{ label: "Flex End", value: "flex-end" },
{ label: "Center", value: "center" },
@@ -317,19 +319,31 @@ export const border = [
{
label: "Radius",
key: "border-radius",
- control: Input,
- width: "48px",
- placeholder: "px",
- textAlign: "center",
+ control: OptionSelect,
+ defaultValue: "None",
+ options: [
+ { label: "None", value: "0" },
+ { label: "small", value: "0.125rem" },
+ { label: "Medium", value: "0.25rem;" },
+ { label: "Large", value: "0.375rem" },
+ { label: "Extra large", value: "0.5rem" },
+ { label: "Full", value: "5678px" },
+ ],
},
{
label: "Width",
key: "border-width",
- control: Input,
- width: "48px",
- placeholder: "px",
- textAlign: "center",
- }, //custom
+ control: OptionSelect,
+ defaultValue: "None",
+ options: [
+ { label: "None", value: "0" },
+ { label: "Extra small", value: "0.5px" },
+ { label: "Small", value: "1px" },
+ { label: "Medium", value: "2px" },
+ { label: "Large", value: "4px" },
+ { label: "Extra large", value: "8px" },
+ ],
+ },
{
label: "Color",
key: "border-color",
@@ -339,6 +353,7 @@ export const border = [
label: "Style",
key: "border-style",
control: OptionSelect,
+ defaultValue: "None",
options: [
"none",
"hidden",
@@ -365,17 +380,34 @@ export const effects = [
},
{
label: "Rotate",
- key: "transform",
- control: Input,
- width: "48px",
- textAlign: "center",
- placeholder: "deg",
+ key: "transform-rotate",
+ control: OptionSelect,
+ defaultValue: "0",
+ options: [
+ "0",
+ "45deg",
+ "90deg",
+ "90deg",
+ "135deg",
+ "180deg",
+ "225deg",
+ "270deg",
+ "315dev",
+ ],
}, //needs special control
{
label: "Shadow",
key: "box-shadow",
- control: InputGroup,
- meta: [{ placeholder: "X" }, { placeholder: "Y" }, { placeholder: "B" }],
+ control: OptionSelect,
+ defaultValue: "None",
+ options: [
+ { label: "None", value: "none" },
+ { label: "Extra small", value: "0 1px 2px 0 rgba(0, 0, 0, 0.05)" },
+ { label: "Small", value: "0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)" },
+ { label: "Medium", value: "0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)" },
+ { label: "Large", value: "0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)" },
+ { label: "Extra large", value: "0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)" },
+ ],
},
]
From b603e27bc49734c8055979a41846bd9eeae65abd Mon Sep 17 00:00:00 2001
From: Joe <49767913+joebudi@users.noreply.github.com>
Date: Thu, 11 Jun 2020 13:15:19 +0100
Subject: [PATCH 2/8] formatting and lint update
---
.../common/Inputs/InputGroup.svelte | 7 ++--
.../AppPreview/CurrentItemPreview.svelte | 38 ++++++++++---------
.../ComponentPropertiesPanel.svelte | 23 ++++++-----
.../userInterface/propertyCategories.js | 24 ++++++++++--
4 files changed, 59 insertions(+), 33 deletions(-)
diff --git a/packages/builder/src/components/common/Inputs/InputGroup.svelte b/packages/builder/src/components/common/Inputs/InputGroup.svelte
index e5fed68103..385623ca19 100644
--- a/packages/builder/src/components/common/Inputs/InputGroup.svelte
+++ b/packages/builder/src/components/common/Inputs/InputGroup.svelte
@@ -19,9 +19,10 @@
onChange(_value)
}
- $: displayValues = value && suffix
- ? value.map(v => v.replace(new RegExp(`${suffix}$`), ""))
- : value || []
+ $: displayValues =
+ value && suffix
+ ? value.map(v => v.replace(new RegExp(`${suffix}$`), ""))
+ : value || []
diff --git a/packages/builder/src/components/userInterface/AppPreview/CurrentItemPreview.svelte b/packages/builder/src/components/userInterface/AppPreview/CurrentItemPreview.svelte
index 53450c2200..00d7e6c171 100644
--- a/packages/builder/src/components/userInterface/AppPreview/CurrentItemPreview.svelte
+++ b/packages/builder/src/components/userInterface/AppPreview/CurrentItemPreview.svelte
@@ -21,7 +21,7 @@
return componentName || "element"
}
- const screenPlaceholder = {
+ const screenPlaceholder = {
name: "Screen Placeholder",
route: "*",
props: {
@@ -60,9 +60,8 @@
},
}
-
$: hasComponent = !!$store.currentPreviewItem
-
+
$: {
styles = ""
// Apply the CSS from the currently selected page and its screens
@@ -88,9 +87,9 @@
libraries: $store.libraries,
page: $store.pages[$store.currentPageName],
screens: [
- $store.currentFrontEndType === "page"
- ? screenPlaceholder
- : $store.currentPreviewItem,
+ $store.currentFrontEndType === "page"
+ ? screenPlaceholder
+ : $store.currentPreviewItem,
],
appRootPath: "",
}
@@ -102,20 +101,25 @@
: ""
const refreshContent = () => {
- iframe.contentWindow.postMessage(JSON.stringify({
- styles,
- stylesheetLinks,
- selectedComponentType,
- selectedComponentId,
- frontendDefinition,
- }))
+ iframe.contentWindow.postMessage(
+ JSON.stringify({
+ styles,
+ stylesheetLinks,
+ selectedComponentType,
+ selectedComponentId,
+ frontendDefinition,
+ })
+ )
}
- $: if(iframe) iframe.contentWindow.addEventListener("bb-ready", refreshContent, { once: true })
+ $: if (iframe)
+ iframe.contentWindow.addEventListener("bb-ready", refreshContent, {
+ once: true,
+ })
- $: if(iframe && frontendDefinition) {
- refreshContent()
- }
+ $: if (iframe && frontendDefinition) {
+ refreshContent()
+ }
diff --git a/packages/builder/src/components/userInterface/ComponentPropertiesPanel.svelte b/packages/builder/src/components/userInterface/ComponentPropertiesPanel.svelte
index bfe5507256..7d33b9c963 100644
--- a/packages/builder/src/components/userInterface/ComponentPropertiesPanel.svelte
+++ b/packages/builder/src/components/userInterface/ComponentPropertiesPanel.svelte
@@ -37,27 +37,32 @@
//use for getting controls for each component property
c => c._component === componentInstance._component
) || {}
-
+
let panelDefinition = {}
$: {
- if(componentPropDefinition.properties) {
- if(selectedCategory.value === "design") {
+ if (componentPropDefinition.properties) {
+ if (selectedCategory.value === "design") {
panelDefinition = componentPropDefinition.properties["design"]
- }else{
+ } else {
let panelDef = componentPropDefinition.properties["settings"]
- if($store.currentFrontEndType === "page" && $store.currentView !== "component") {
- panelDefinition = [...page,...panelDef]
- }else if($store.currentFrontEndType === "screen" && $store.currentView !== "component") {
+ if (
+ $store.currentFrontEndType === "page" &&
+ $store.currentView !== "component"
+ ) {
+ panelDefinition = [...page, ...panelDef]
+ } else if (
+ $store.currentFrontEndType === "screen" &&
+ $store.currentView !== "component"
+ ) {
panelDefinition = [...screen, ...panelDef]
- }else {
+ } else {
panelDefinition = panelDef
}
}
}
}
-
const onStyleChanged = store.setComponentStyle
const onPropChanged = store.setComponentProp
diff --git a/packages/builder/src/components/userInterface/propertyCategories.js b/packages/builder/src/components/userInterface/propertyCategories.js
index 8ee38d3c35..c0485304ce 100644
--- a/packages/builder/src/components/userInterface/propertyCategories.js
+++ b/packages/builder/src/components/userInterface/propertyCategories.js
@@ -403,10 +403,26 @@ export const effects = [
options: [
{ label: "None", value: "none" },
{ label: "Extra small", value: "0 1px 2px 0 rgba(0, 0, 0, 0.05)" },
- { label: "Small", value: "0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)" },
- { label: "Medium", value: "0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)" },
- { label: "Large", value: "0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)" },
- { label: "Extra large", value: "0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)" },
+ {
+ label: "Small",
+ value:
+ "0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)",
+ },
+ {
+ label: "Medium",
+ value:
+ "0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)",
+ },
+ {
+ label: "Large",
+ value:
+ "0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)",
+ },
+ {
+ label: "Extra large",
+ value:
+ "0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)",
+ },
],
},
]
From d2477e1b81b5fb372cfe5531352cba1be82da24b Mon Sep 17 00:00:00 2001
From: Martin McKeaveney
Date: Thu, 11 Jun 2020 14:35:45 +0100
Subject: [PATCH 3/8] adding record models for brevity
---
packages/server/package.json | 2 +-
packages/server/src/api/controllers/record.js | 11 +++++-
packages/server/src/api/index.js | 4 ++
packages/server/src/api/routes/index.js | 2 +
packages/server/src/api/routes/model.js | 38 +------------------
packages/server/src/api/routes/record.js | 36 ++++++++++++++++++
.../server/src/api/routes/tests/model.spec.js | 1 -
.../src/api/routes/tests/record.spec.js | 24 ++++++++++++
8 files changed, 78 insertions(+), 40 deletions(-)
create mode 100644 packages/server/src/api/routes/record.js
diff --git a/packages/server/package.json b/packages/server/package.json
index 0888ef2ae4..49a5626f6f 100644
--- a/packages/server/package.json
+++ b/packages/server/package.json
@@ -25,7 +25,7 @@
"scripts": {
"test": "jest routes --runInBand",
"test:integration": "jest workflow --runInBand",
- "test:watch": "jest -w",
+ "test:watch": "jest --watch",
"initialise": "node ../cli/bin/budi init -b local -q",
"budi": "node ../cli/bin/budi",
"dev:builder": "nodemon ../cli/bin/budi run",
diff --git a/packages/server/src/api/controllers/record.js b/packages/server/src/api/controllers/record.js
index 5fab413f04..cf8eb27606 100644
--- a/packages/server/src/api/controllers/record.js
+++ b/packages/server/src/api/controllers/record.js
@@ -61,7 +61,7 @@ exports.fetchView = async function(ctx) {
ctx.body = response.rows.map(row => row.doc)
}
-exports.fetchModel = async function(ctx) {
+exports.fetchModelRecords = async function(ctx) {
const db = new CouchDB(ctx.params.instanceId)
const response = await db.query(`database/all_${ctx.params.modelId}`, {
include_docs: true,
@@ -69,6 +69,15 @@ exports.fetchModel = async function(ctx) {
ctx.body = response.rows.map(row => row.doc)
}
+exports.search = async function(ctx) {
+ const db = new CouchDB(ctx.params.instanceId)
+ const response = await db.allDocs({
+ include_docs: true,
+ ...ctx.request.body,
+ })
+ ctx.body = response.rows.map(row => row.doc)
+}
+
exports.find = async function(ctx) {
const db = new CouchDB(ctx.params.instanceId)
const record = await db.get(ctx.params.recordId)
diff --git a/packages/server/src/api/index.js b/packages/server/src/api/index.js
index 990714fdc7..e6143d6725 100644
--- a/packages/server/src/api/index.js
+++ b/packages/server/src/api/index.js
@@ -10,6 +10,7 @@ const {
instanceRoutes,
clientRoutes,
applicationRoutes,
+ recordRoutes,
modelRoutes,
viewRoutes,
staticRoutes,
@@ -69,6 +70,9 @@ router.use(viewRoutes.allowedMethods())
router.use(modelRoutes.routes())
router.use(modelRoutes.allowedMethods())
+router.use(recordRoutes.routes())
+router.use(recordRoutes.allowedMethods())
+
router.use(userRoutes.routes())
router.use(userRoutes.allowedMethods())
diff --git a/packages/server/src/api/routes/index.js b/packages/server/src/api/routes/index.js
index c515d5f437..b50fee788a 100644
--- a/packages/server/src/api/routes/index.js
+++ b/packages/server/src/api/routes/index.js
@@ -5,6 +5,7 @@ const instanceRoutes = require("./instance")
const clientRoutes = require("./client")
const applicationRoutes = require("./application")
const modelRoutes = require("./model")
+const recordRoutes = require("./record")
const viewRoutes = require("./view")
const staticRoutes = require("./static")
const componentRoutes = require("./component")
@@ -18,6 +19,7 @@ module.exports = {
instanceRoutes,
clientRoutes,
applicationRoutes,
+ recordRoutes,
modelRoutes,
viewRoutes,
staticRoutes,
diff --git a/packages/server/src/api/routes/model.js b/packages/server/src/api/routes/model.js
index 388f4618bd..f1ec46dbe5 100644
--- a/packages/server/src/api/routes/model.js
+++ b/packages/server/src/api/routes/model.js
@@ -1,46 +1,10 @@
const Router = require("@koa/router")
const modelController = require("../controllers/model")
-const recordController = require("../controllers/record")
const authorized = require("../../middleware/authorized")
-const {
- READ_MODEL,
- WRITE_MODEL,
- BUILDER,
-} = require("../../utilities/accessLevels")
+const { BUILDER } = require("../../utilities/accessLevels")
const router = Router()
-// records
-
-router
- .get(
- "/api/:instanceId/:modelId/records",
- authorized(READ_MODEL, ctx => ctx.params.modelId),
- recordController.fetchModel
- )
- .get(
- "/api/:instanceId/:modelId/records/:recordId",
- authorized(READ_MODEL, ctx => ctx.params.modelId),
- recordController.find
- )
- .post(
- "/api/:instanceId/:modelId/records",
- authorized(WRITE_MODEL, ctx => ctx.params.modelId),
- recordController.save
- )
- .post(
- "/api/:instanceId/:modelId/records/validate",
- authorized(WRITE_MODEL, ctx => ctx.params.modelId),
- recordController.validate
- )
- .delete(
- "/api/:instanceId/:modelId/records/:recordId/:revId",
- authorized(WRITE_MODEL, ctx => ctx.params.modelId),
- recordController.destroy
- )
-
-// models
-
router
.get("/api/:instanceId/models", authorized(BUILDER), modelController.fetch)
.get("/api/:instanceId/models/:id", authorized(BUILDER), modelController.find)
diff --git a/packages/server/src/api/routes/record.js b/packages/server/src/api/routes/record.js
new file mode 100644
index 0000000000..d555d3d8c8
--- /dev/null
+++ b/packages/server/src/api/routes/record.js
@@ -0,0 +1,36 @@
+const Router = require("@koa/router")
+const recordController = require("../controllers/record")
+const authorized = require("../../middleware/authorized")
+const { READ_MODEL, WRITE_MODEL } = require("../../utilities/accessLevels")
+
+const router = Router()
+
+router
+ .get(
+ "/api/:instanceId/:modelId/records",
+ authorized(READ_MODEL, ctx => ctx.params.modelId),
+ recordController.fetchModelRecords
+ )
+ .get(
+ "/api/:instanceId/:modelId/records/:recordId",
+ authorized(READ_MODEL, ctx => ctx.params.modelId),
+ recordController.find
+ )
+ .post("/api/:instanceId/records/search", recordController.search)
+ .post(
+ "/api/:instanceId/:modelId/records",
+ authorized(WRITE_MODEL, ctx => ctx.params.modelId),
+ recordController.save
+ )
+ .post(
+ "/api/:instanceId/:modelId/records/validate",
+ authorized(WRITE_MODEL, ctx => ctx.params.modelId),
+ recordController.validate
+ )
+ .delete(
+ "/api/:instanceId/:modelId/records/:recordId/:revId",
+ authorized(WRITE_MODEL, ctx => ctx.params.modelId),
+ recordController.destroy
+ )
+
+module.exports = router
diff --git a/packages/server/src/api/routes/tests/model.spec.js b/packages/server/src/api/routes/tests/model.spec.js
index 65a44b677a..df3b7d8b52 100644
--- a/packages/server/src/api/routes/tests/model.spec.js
+++ b/packages/server/src/api/routes/tests/model.spec.js
@@ -97,7 +97,6 @@ describe("/models", () => {
instanceId: instance._id,
})
})
-
});
describe("destroy", () => {
diff --git a/packages/server/src/api/routes/tests/record.spec.js b/packages/server/src/api/routes/tests/record.spec.js
index 2c8c542715..22ac67ecdc 100644
--- a/packages/server/src/api/routes/tests/record.spec.js
+++ b/packages/server/src/api/routes/tests/record.spec.js
@@ -110,6 +110,30 @@ describe("/records", () => {
expect(res.body.find(r => r.name === record.name)).toBeDefined()
})
+ it("lists records when queried by their ID", async () => {
+ const newRecord = {
+ modelId: model._id,
+ name: "Second Contact",
+ status: "new"
+ }
+ const record = await createRecord()
+ const secondRecord = await createRecord(newRecord)
+
+ const recordIds = [record.body._id, secondRecord.body._id]
+
+ const res = await request
+ .post(`/api/${instance._id}/records/search`)
+ .set(defaultHeaders)
+ .send({
+ keys: recordIds
+ })
+ .expect('Content-Type', /json/)
+ .expect(200)
+
+ expect(res.body.length).toBe(2)
+ expect(res.body.map(response => response._id)).toEqual(expect.arrayContaining(recordIds))
+ })
+
it("load should return 404 when record does not exist", async () => {
await createRecord()
await request
From 1c1ac8f1a3a0b61e1316ac54fc167f484b085ec4 Mon Sep 17 00:00:00 2001
From: Martin McKeaveney
Date: Thu, 11 Jun 2020 17:24:09 +0100
Subject: [PATCH 4/8] remove other link fields when you delete a model
---
packages/server/src/api/controllers/model.js | 32 ++++++++++++++-
.../src/api/routes/tests/couchTestUtils.js | 4 ++
.../server/src/api/routes/tests/model.spec.js | 40 ++++++++++++++++++-
3 files changed, 73 insertions(+), 3 deletions(-)
diff --git a/packages/server/src/api/controllers/model.js b/packages/server/src/api/controllers/model.js
index 9d06c7a413..c35a0ddd49 100644
--- a/packages/server/src/api/controllers/model.js
+++ b/packages/server/src/api/controllers/model.js
@@ -27,6 +27,23 @@ exports.create = async function(ctx) {
const result = await db.post(newModel)
newModel._rev = result.rev
+ const { schema } = ctx.request.body
+ for (let key in schema) {
+ // model has a linked record
+ if (schema[key].type === "link") {
+ // create the link field in the other model
+ const linkedModel = await db.get(schema[key].modelId);
+ linkedModel.schema[newModel.name] = {
+ type: "link",
+ modelId: newModel._id,
+ constraints: {
+ type: "array"
+ }
+ }
+ await db.put(linkedModel);
+ }
+ }
+
const designDoc = await db.get("_design/database")
designDoc.views = {
...designDoc.views,
@@ -50,7 +67,9 @@ exports.update = async function() {}
exports.destroy = async function(ctx) {
const db = new CouchDB(ctx.params.instanceId)
- await db.remove(ctx.params.modelId, ctx.params.revId)
+ const modelToDelete = await db.get(ctx.params.modelId);
+
+ await db.remove(modelToDelete)
const modelViewId = `all_${ctx.params.modelId}`
// Delete all records for that model
@@ -59,6 +78,17 @@ exports.destroy = async function(ctx) {
records.rows.map(record => ({ id: record.id, _deleted: true }))
)
+ // Delete linked record fields in dependent models
+ for (let key in modelToDelete.schema) {
+ const { type, modelId } = modelToDelete.schema[key];
+ if (type === "link") {
+ const linkedModel = await db.get(modelId);
+ delete linkedModel.schema[modelToDelete.name]
+ await db.put(linkedModel)
+ }
+ }
+
+
// delete the "all" view
const designDoc = await db.get("_design/database")
delete designDoc.views[modelViewId]
diff --git a/packages/server/src/api/routes/tests/couchTestUtils.js b/packages/server/src/api/routes/tests/couchTestUtils.js
index 6029e080cc..495b841b10 100644
--- a/packages/server/src/api/routes/tests/couchTestUtils.js
+++ b/packages/server/src/api/routes/tests/couchTestUtils.js
@@ -253,3 +253,7 @@ exports.insertDocument = async (databaseId, document) => {
exports.destroyDocument = async (databaseId, documentId) => {
return await new CouchDB(databaseId).destroy(documentId)
}
+
+exports.getDocument = async (databaseId, documentId) => {
+ return await new CouchDB(databaseId).get(documentId)
+}
diff --git a/packages/server/src/api/routes/tests/model.spec.js b/packages/server/src/api/routes/tests/model.spec.js
index df3b7d8b52..1fb16beb8b 100644
--- a/packages/server/src/api/routes/tests/model.spec.js
+++ b/packages/server/src/api/routes/tests/model.spec.js
@@ -3,9 +3,10 @@ const {
createModel,
supertest,
createClientDatabase,
- createApplication ,
+ createApplication,
defaultHeaders,
- builderEndpointShouldBlockNormalUsers
+ builderEndpointShouldBlockNormalUsers,
+ getDocument
} = require("./couchTestUtils")
describe("/models", () => {
@@ -119,6 +120,41 @@ describe("/models", () => {
});
})
+ it("deletes linked references to the model after deletion", async done => {
+ const linkedModel = await createModel(request, instance._id, {
+ name: "LinkedModel",
+ type: "model",
+ key: "name",
+ schema: {
+ name: {
+ type: "text",
+ constraints: {
+ type: "string",
+ },
+ },
+ TestModel: {
+ type: "link",
+ modelId: testModel._id,
+ constraints: {
+ type: "array"
+ }
+ }
+ },
+ })
+
+ request
+ .delete(`/api/${instance._id}/models/${testModel._id}/${testModel._rev}`)
+ .set(defaultHeaders)
+ .expect('Content-Type', /json/)
+ .expect(200)
+ .end(async (_, res) => {
+ expect(res.res.statusMessage).toEqual(`Model ${testModel._id} deleted.`);
+ const dependentModel = await getDocument(instance._id, linkedModel._id)
+ expect(dependentModel.schema.TestModel).not.toBeDefined();
+ done();
+ });
+ })
+
it("should apply authorization to endpoint", async () => {
await builderEndpointShouldBlockNormalUsers({
request,
From 3f0465a892f50642171970104f4b87037ded1534 Mon Sep 17 00:00:00 2001
From: Martin McKeaveney
Date: Thu, 11 Jun 2020 17:28:19 +0100
Subject: [PATCH 5/8] lint :sparkles:
---
packages/server/src/api/controllers/model.js | 15 +++++++--------
1 file changed, 7 insertions(+), 8 deletions(-)
diff --git a/packages/server/src/api/controllers/model.js b/packages/server/src/api/controllers/model.js
index c35a0ddd49..f1e3f51747 100644
--- a/packages/server/src/api/controllers/model.js
+++ b/packages/server/src/api/controllers/model.js
@@ -32,15 +32,15 @@ exports.create = async function(ctx) {
// model has a linked record
if (schema[key].type === "link") {
// create the link field in the other model
- const linkedModel = await db.get(schema[key].modelId);
+ const linkedModel = await db.get(schema[key].modelId)
linkedModel.schema[newModel.name] = {
type: "link",
modelId: newModel._id,
constraints: {
- type: "array"
- }
+ type: "array",
+ },
}
- await db.put(linkedModel);
+ await db.put(linkedModel)
}
}
@@ -67,7 +67,7 @@ exports.update = async function() {}
exports.destroy = async function(ctx) {
const db = new CouchDB(ctx.params.instanceId)
- const modelToDelete = await db.get(ctx.params.modelId);
+ const modelToDelete = await db.get(ctx.params.modelId)
await db.remove(modelToDelete)
const modelViewId = `all_${ctx.params.modelId}`
@@ -80,15 +80,14 @@ exports.destroy = async function(ctx) {
// Delete linked record fields in dependent models
for (let key in modelToDelete.schema) {
- const { type, modelId } = modelToDelete.schema[key];
+ const { type, modelId } = modelToDelete.schema[key]
if (type === "link") {
- const linkedModel = await db.get(modelId);
+ const linkedModel = await db.get(modelId)
delete linkedModel.schema[modelToDelete.name]
await db.put(linkedModel)
}
}
-
// delete the "all" view
const designDoc = await db.get("_design/database")
delete designDoc.views[modelViewId]
From 8b3ce41ba7761dedca43c3d0881c20be381ba5c1 Mon Sep 17 00:00:00 2001
From: Martin McKeaveney
Date: Thu, 11 Jun 2020 18:11:56 +0100
Subject: [PATCH 6/8] update _rev for deleted test model
---
packages/server/src/api/controllers/model.js | 1 +
packages/server/src/api/routes/tests/model.spec.js | 6 +++++-
2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/packages/server/src/api/controllers/model.js b/packages/server/src/api/controllers/model.js
index f1e3f51747..650342b33c 100644
--- a/packages/server/src/api/controllers/model.js
+++ b/packages/server/src/api/controllers/model.js
@@ -70,6 +70,7 @@ exports.destroy = async function(ctx) {
const modelToDelete = await db.get(ctx.params.modelId)
await db.remove(modelToDelete)
+
const modelViewId = `all_${ctx.params.modelId}`
// Delete all records for that model
diff --git a/packages/server/src/api/routes/tests/model.spec.js b/packages/server/src/api/routes/tests/model.spec.js
index 1fb16beb8b..7134245fb3 100644
--- a/packages/server/src/api/routes/tests/model.spec.js
+++ b/packages/server/src/api/routes/tests/model.spec.js
@@ -108,7 +108,11 @@ describe("/models", () => {
testModel = await createModel(request, instance._id, testModel)
});
- it("returns a success response when a model is deleted.", done => {
+ afterEach(() => {
+ delete testModel._rev
+ })
+
+ it("returns a success response when a model is deleted.", async done => {
request
.delete(`/api/${instance._id}/models/${testModel._id}/${testModel._rev}`)
.set(defaultHeaders)
From 6f1ea30fe6249ddd884e031b857fd1eee70a9328 Mon Sep 17 00:00:00 2001
From: Martin McKeaveney
Date: Thu, 11 Jun 2020 20:18:59 +0100
Subject: [PATCH 7/8] embed component, rename main and login to public and
private
---
.../src/components/userInterface/PagesList.svelte | 4 ++--
.../userInterface/temporaryPanelStructure.js | 12 ++++++++++++
packages/standard-components/components.json | 7 +++++++
packages/standard-components/src/Embed.svelte | 5 +++++
packages/standard-components/src/index.js | 1 +
5 files changed, 27 insertions(+), 2 deletions(-)
create mode 100644 packages/standard-components/src/Embed.svelte
diff --git a/packages/builder/src/components/userInterface/PagesList.svelte b/packages/builder/src/components/userInterface/PagesList.svelte
index 4a87c4ac8a..5a78ef7121 100644
--- a/packages/builder/src/components/userInterface/PagesList.svelte
+++ b/packages/builder/src/components/userInterface/PagesList.svelte
@@ -9,11 +9,11 @@
const pages = [
{
- title: "Main",
+ title: "Private",
id: "main",
},
{
- title: "Login",
+ title: "Public",
id: "unauthenticated",
},
]
diff --git a/packages/builder/src/components/userInterface/temporaryPanelStructure.js b/packages/builder/src/components/userInterface/temporaryPanelStructure.js
index afd3a06694..7315e09736 100644
--- a/packages/builder/src/components/userInterface/temporaryPanelStructure.js
+++ b/packages/builder/src/components/userInterface/temporaryPanelStructure.js
@@ -11,6 +11,18 @@ export default {
name: "Basic",
isCategory: true,
children: [
+ {
+ _component: "@budibase/standard-components/embed",
+ icon: "ri-code-line",
+ name: "Embed",
+ description: "Embed content from 3rd party sources",
+ properties: {
+ design: {
+ ...all,
+ },
+ settings: [{ label: "Embed", key: "embed", control: Input }],
+ },
+ },
{
_component: "@budibase/standard-components/container",
name: "Container",
diff --git a/packages/standard-components/components.json b/packages/standard-components/components.json
index a562650b85..c4c0246672 100644
--- a/packages/standard-components/components.json
+++ b/packages/standard-components/components.json
@@ -6,6 +6,13 @@
"component": "button"
}
},
+ "embed": {
+ "name": "Embed",
+ "description": "Embed stuff",
+ "props": {
+ "embed": "string"
+ }
+ },
"Navigation": {
"name": "Navigation",
"description": "A basic header navigation component",
diff --git a/packages/standard-components/src/Embed.svelte b/packages/standard-components/src/Embed.svelte
new file mode 100644
index 0000000000..2640864681
--- /dev/null
+++ b/packages/standard-components/src/Embed.svelte
@@ -0,0 +1,5 @@
+
+
+{@html embed}
diff --git a/packages/standard-components/src/index.js b/packages/standard-components/src/index.js
index 2284ab1fcb..24342066e8 100644
--- a/packages/standard-components/src/index.js
+++ b/packages/standard-components/src/index.js
@@ -21,3 +21,4 @@ export { default as datalist } from "./DataList.svelte"
export { default as list } from "./List.svelte"
export { default as datasearch } from "./DataSearch.svelte"
export { default as datamap } from "./DataMap.svelte"
+export { default as embed } from "./Embed.svelte"
From c5c8309b09d7d5d6a1314e8e08e8c72558b7aa80 Mon Sep 17 00:00:00 2001
From: Michael Shanks
Date: Fri, 12 Jun 2020 12:15:17 +0100
Subject: [PATCH 8/8] bugfix - screen/page > settings throwing error
---
.../builder/src/builderStore/store/index.js | 56 +++++--------------
.../builder/src/builderStore/storeUtils.js | 13 +++++
.../ComponentPropertiesPanel.svelte | 29 ++--------
.../userInterface/SettingsView.svelte | 40 +++++++++++++
4 files changed, 72 insertions(+), 66 deletions(-)
diff --git a/packages/builder/src/builderStore/store/index.js b/packages/builder/src/builderStore/store/index.js
index 9f91550bca..1f3ea9c0ef 100644
--- a/packages/builder/src/builderStore/store/index.js
+++ b/packages/builder/src/builderStore/store/index.js
@@ -5,7 +5,6 @@ import { writable, get } from "svelte/store"
import api from "../api"
import { DEFAULT_PAGES_OBJECT } from "../../constants"
import { getExactComponent } from "components/userInterface/pagesParsing/searchComponents"
-import { rename } from "components/userInterface/pagesParsing/renameScreen"
import {
createProps,
makePropsSafe,
@@ -24,6 +23,7 @@ import {
saveCurrentPreviewItem as _saveCurrentPreviewItem,
saveScreenApi as _saveScreenApi,
regenerateCssForCurrentScreen,
+ renameCurrentScreen,
} from "../storeUtils"
export const getStore = () => {
@@ -52,7 +52,6 @@ export const getStore = () => {
store.createDatabaseForApp = backendStoreActions.createDatabaseForApp(store)
store.saveScreen = saveScreen(store)
- store.renameScreen = renameScreen(store)
store.deleteScreen = deleteScreen(store)
store.setCurrentScreen = setCurrentScreen(store)
store.setCurrentPage = setCurrentPage(store)
@@ -63,6 +62,7 @@ export const getStore = () => {
store.addChildComponent = addChildComponent(store)
store.selectComponent = selectComponent(store)
store.setComponentProp = setComponentProp(store)
+ store.setPageOrScreenProp = setPageOrScreenProp(store)
store.setComponentStyle = setComponentStyle(store)
store.setComponentCode = setComponentCode(store)
store.setScreenType = setScreenType(store)
@@ -207,46 +207,6 @@ const deleteScreen = store => name => {
})
}
-const renameScreen = store => (oldname, newname) => {
- store.update(s => {
- const { screens, pages, error, changedScreens } = rename(
- s.pages,
- s.screens,
- oldname,
- newname
- )
-
- if (error) {
- // should really do something with this
- return s
- }
-
- s.screens = screens
- s.pages = pages
- if (s.currentPreviewItem.name === oldname)
- s.currentPreviewItem.name = newname
-
- const saveAllChanged = async () => {
- for (let screenName of changedScreens) {
- const changedScreen = getExactComponent(screens, screenName)
- await api.post(`/_builder/api/${s.appId}/screen`, changedScreen)
- }
- }
-
- api
- .patch(`/_builder/api/${s.appId}/screen`, {
- oldname,
- newname,
- })
- .then(() => saveAllChanged())
- .then(() => {
- _savePage(s)
- })
-
- return s
- })
-}
-
const savePage = store => async page => {
store.update(state => {
if (state.currentFrontEndType !== "page" || !state.currentPageName) {
@@ -400,6 +360,18 @@ const setComponentProp = store => (name, value) => {
})
}
+const setPageOrScreenProp = store => (name, value) => {
+ store.update(state => {
+ if (name === "name" && state.currentFrontEndType === "screen") {
+ state = renameCurrentScreen(value, state)
+ } else {
+ state.currentPreviewItem[name] = value
+ _saveCurrentPreviewItem(state)
+ }
+ return state
+ })
+}
+
const setComponentStyle = store => (type, name, value) => {
store.update(state => {
if (!state.currentComponentInfo._styles) {
diff --git a/packages/builder/src/builderStore/storeUtils.js b/packages/builder/src/builderStore/storeUtils.js
index d6aa4d0308..ff951e6b6f 100644
--- a/packages/builder/src/builderStore/storeUtils.js
+++ b/packages/builder/src/builderStore/storeUtils.js
@@ -45,6 +45,19 @@ export const saveScreenApi = (screen, s) => {
.then(() => savePage(s))
}
+export const renameCurrentScreen = (newname, state) => {
+ const oldname = state.currentPreviewItem.name
+ state.currentPreviewItem.name = newname
+ api.patch(
+ `/_builder/api/${state.appId}/pages/${state.currentPageName}/screen`,
+ {
+ oldname,
+ newname,
+ }
+ )
+ return state
+}
+
export const walkProps = (props, action, cancelToken = null) => {
cancelToken = cancelToken || { cancelled: false }
action(props, () => {
diff --git a/packages/builder/src/components/userInterface/ComponentPropertiesPanel.svelte b/packages/builder/src/components/userInterface/ComponentPropertiesPanel.svelte
index 7d33b9c963..bcebb4d2d4 100644
--- a/packages/builder/src/components/userInterface/ComponentPropertiesPanel.svelte
+++ b/packages/builder/src/components/userInterface/ComponentPropertiesPanel.svelte
@@ -13,7 +13,6 @@
import CodeEditor from "./CodeEditor.svelte"
import LayoutEditor from "./LayoutEditor.svelte"
import EventsEditor from "./EventsEditor"
-
import panelStructure from "./temporaryPanelStructure.js"
import CategoryTab from "./CategoryTab.svelte"
import DesignView from "./DesignView.svelte"
@@ -40,28 +39,8 @@
let panelDefinition = {}
- $: {
- if (componentPropDefinition.properties) {
- if (selectedCategory.value === "design") {
- panelDefinition = componentPropDefinition.properties["design"]
- } else {
- let panelDef = componentPropDefinition.properties["settings"]
- if (
- $store.currentFrontEndType === "page" &&
- $store.currentView !== "component"
- ) {
- panelDefinition = [...page, ...panelDef]
- } else if (
- $store.currentFrontEndType === "screen" &&
- $store.currentView !== "component"
- ) {
- panelDefinition = [...screen, ...panelDef]
- } else {
- panelDefinition = panelDef
- }
- }
- }
- }
+ $: panelDefinition = componentPropDefinition.properties &&
+ componentPropDefinition.properties[selectedCategory.value]
const onStyleChanged = store.setComponentStyle
const onPropChanged = store.setComponentProp
@@ -107,7 +86,9 @@
{componentInstance}
{componentDefinition}
{panelDefinition}
- onChange={onPropChanged} />
+ onChange={onPropChanged}
+ onScreenPropChange={store.setPageOrScreenProp}
+ screenOrPageInstance={$store.currentView !== "component" && $store.currentPreviewItem} />
{:else if selectedCategory.value === 'events'}
{/if}
diff --git a/packages/builder/src/components/userInterface/SettingsView.svelte b/packages/builder/src/components/userInterface/SettingsView.svelte
index 99e704d1d9..17e4fe5e71 100644
--- a/packages/builder/src/components/userInterface/SettingsView.svelte
+++ b/packages/builder/src/components/userInterface/SettingsView.svelte
@@ -2,20 +2,60 @@
import PropertyControl from "./PropertyControl.svelte"
import InputGroup from "../common/Inputs/InputGroup.svelte"
import Colorpicker from "../common/Colorpicker.svelte"
+ import { goto } from "@sveltech/routify"
import { excludeProps } from "./propertyCategories.js"
+ import Input from "../common/Input.svelte"
export let panelDefinition = []
export let componentDefinition = {}
export let componentInstance = {}
export let onChange = () => {}
+ export let onScreenPropChange = () => {}
+ export let screenOrPageInstance
const propExistsOnComponentDef = prop => prop in componentDefinition.props
function handleChange(key, data) {
data.target ? onChange(key, data.target.value) : onChange(key, data)
}
+
+ function handleScreenPropChange (name, value) {
+ onScreenPropChange(name,value)
+ if(!isPage && name === "name") {
+ // screen name is changed... change URL
+ $goto(`./:page/${value}`)
+ }
+ }
+
+ const screenDefinition = [
+ { key: "name", label: "Name", control: Input },
+ { key: "description", label: "Description", control: Input },
+ { key: "route", label: "Route", control: Input },
+ ]
+
+ const pageDefinition = [
+ { key: "title", label: "Title", control: Input },
+ { key: "favicon", label: "Favicon", control: Input },
+ ]
+
+ $: isPage = screenOrPageInstance && screenOrPageInstance.favicon
+ $: screenOrPageDefinition = isPage ? pageDefinition : screenDefinition
+
+{#if screenOrPageInstance}
+ {#each screenOrPageDefinition as def}
+
+ {/each}
+
+{/if}
+
{#if panelDefinition && panelDefinition.length > 0}
{#each panelDefinition as definition}
{#if propExistsOnComponentDef(definition.key)}