diff --git a/hosting/nginx.dev.conf.hbs b/hosting/nginx.dev.conf.hbs
index 9398b7e719..e08516c9d3 100644
--- a/hosting/nginx.dev.conf.hbs
+++ b/hosting/nginx.dev.conf.hbs
@@ -62,6 +62,10 @@ http {
proxy_pass http://{{ address }}:4001;
}
+ location /preview {
+ proxy_pass http://{{ address }}:4001;
+ }
+
location /builder {
proxy_pass http://{{ address }}:3000;
rewrite ^/builder(.*)$ /builder/$1 break;
diff --git a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/AppPreview.svelte b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/AppPreview.svelte
index 8e4e172a0d..9f81effd1d 100644
--- a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/AppPreview.svelte
+++ b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/AppPreview.svelte
@@ -8,7 +8,6 @@
selectedLayout,
currentAsset,
} from "builderStore"
- import iframeTemplate from "./iframeTemplate"
import ConfirmDialog from "components/common/ConfirmDialog.svelte"
import {
ProgressCircle,
@@ -40,12 +39,6 @@
BUDIBASE: "type",
}
- // Construct iframe template
- $: template = iframeTemplate.replace(
- /\{\{ CLIENT_LIB_PATH }}/,
- $store.clientLibPath
- )
-
const placeholderScreen = new Screen()
.name("Screen Placeholder")
.route("/")
@@ -298,7 +291,7 @@
-
-`
diff --git a/packages/server/src/api/controllers/static/index.ts b/packages/server/src/api/controllers/static/index.ts
index c4d51293b5..3b748a6591 100644
--- a/packages/server/src/api/controllers/static/index.ts
+++ b/packages/server/src/api/controllers/static/index.ts
@@ -128,6 +128,22 @@ export const serveApp = async function (ctx: any) {
}
}
+export const serveBuilderPreview = async function (ctx: any) {
+ const db = getAppDB({ skip_setup: true })
+ const appInfo = await db.get(DocumentType.APP_METADATA)
+
+ if (!env.isJest()) {
+ let appId = getAppId()
+ const previewHbs = loadHandlebarsFile(`${__dirname}/templates/preview.hbs`)
+ ctx.body = await processString(previewHbs, {
+ clientLibPath: clientLibraryPath(appId, appInfo.version, ctx),
+ })
+ } else {
+ // just return the app info for jest to assert on
+ ctx.body = { ...appInfo, builderPreview: true }
+ }
+}
+
export const serveClientLibrary = async function (ctx: any) {
return send(ctx, "budibase-client.js", {
root: join(NODE_MODULES_PATH, "@budibase", "client", "dist"),
diff --git a/packages/server/src/api/controllers/static/templates/preview.hbs b/packages/server/src/api/controllers/static/templates/preview.hbs
new file mode 100644
index 0000000000..28908df507
--- /dev/null
+++ b/packages/server/src/api/controllers/static/templates/preview.hbs
@@ -0,0 +1,103 @@
+
+
+ Budibase Builder Preview
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/packages/server/src/api/routes/static.ts b/packages/server/src/api/routes/static.ts
index c94ff54708..9a53486689 100644
--- a/packages/server/src/api/routes/static.ts
+++ b/packages/server/src/api/routes/static.ts
@@ -56,6 +56,7 @@ router
authorized(PermissionTypes.TABLE, PermissionLevels.WRITE),
controller.deleteObjects
)
+ .get("/preview", authorized(BUILDER), controller.serveBuilderPreview)
.get("/:appId/:path*", controller.serveApp)
.get("/app/:appUrl/:path*", controller.serveApp)
.post(
diff --git a/packages/server/src/api/routes/tests/static.spec.js b/packages/server/src/api/routes/tests/static.spec.js
index 37176f5cf5..812b88329b 100644
--- a/packages/server/src/api/routes/tests/static.spec.js
+++ b/packages/server/src/api/routes/tests/static.spec.js
@@ -40,7 +40,6 @@ describe("/static", () => {
})
describe("/app", () => {
-
beforeEach(() => {
jest.clearAllMocks()
})
@@ -60,7 +59,7 @@ describe("/static", () => {
it("should serve the app by url", async () => {
const headers = config.defaultHeaders()
delete headers[constants.Headers.APP_ID]
-
+
const res = await request
.get(`/app${config.prodApp.url}`)
.set(headers)
@@ -82,7 +81,7 @@ describe("/static", () => {
describe("/attachments", () => {
describe("generateSignedUrls", () => {
let datasource
-
+
beforeEach(async () => {
datasource = await config.createDatasource({
datasource: {
@@ -93,7 +92,7 @@ describe("/static", () => {
},
})
})
-
+
it("should be able to generate a signed upload URL", async () => {
const bucket = "foo"
const key = "bar"
@@ -108,7 +107,7 @@ describe("/static", () => {
`https://${bucket}.s3.eu-west-1.amazonaws.com/${key}`
)
})
-
+
it("should handle an invalid datasource ID", async () => {
const res = await request
.post(`/api/attachments/foo/url`)
@@ -123,7 +122,7 @@ describe("/static", () => {
"The specified datasource could not be found"
)
})
-
+
it("should require a bucket parameter", async () => {
const res = await request
.post(`/api/attachments/${datasource._id}/url`)
@@ -136,7 +135,7 @@ describe("/static", () => {
.expect(400)
expect(res.body.message).toEqual("bucket and key values are required")
})
-
+
it("should require a key parameter", async () => {
const res = await request
.post(`/api/attachments/${datasource._id}/url`)
@@ -151,4 +150,17 @@ describe("/static", () => {
})
})
+ describe("/preview", () => {
+ beforeEach(() => {
+ jest.clearAllMocks()
+ })
+
+ it("should serve the builder preview", async () => {
+ const headers = config.defaultHeaders()
+ const res = await request.get(`/preview`).set(headers).expect(200)
+
+ expect(res.body.appId).toBe(config.appId)
+ expect(res.body.builderPreview).toBe(true)
+ })
+ })
})