From f8cfc8e7d7f347defe38ec3e0b0094e2d6c5d82f Mon Sep 17 00:00:00 2001 From: Martin McKeaveney Date: Thu, 11 Jun 2020 14:35:45 +0100 Subject: [PATCH 1/6] 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 3900b216e999cc381e02d5b8941ed496848f0697 Mon Sep 17 00:00:00 2001 From: Martin McKeaveney Date: Thu, 11 Jun 2020 17:24:09 +0100 Subject: [PATCH 2/6] 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 2b312d4c1f8ca1dfb61341c5790c9c85f26a2e5d Mon Sep 17 00:00:00 2001 From: Martin McKeaveney Date: Thu, 11 Jun 2020 17:28:19 +0100 Subject: [PATCH 3/6] 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 4ed4866bca75c020108dab5cab200de7027d6340 Mon Sep 17 00:00:00 2001 From: Martin McKeaveney Date: Thu, 11 Jun 2020 18:11:56 +0100 Subject: [PATCH 4/6] 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 9830725ac1cf325dc112023a6c6f6e08b9ae0b71 Mon Sep 17 00:00:00 2001 From: Martin McKeaveney Date: Thu, 11 Jun 2020 20:18:59 +0100 Subject: [PATCH 5/6] 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 0c35f46b5f147a403f8a38034e9f4be01f62ba46 Mon Sep 17 00:00:00 2001 From: Michael Shanks Date: Fri, 12 Jun 2020 12:15:17 +0100 Subject: [PATCH 6/6] 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)}