diff --git a/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte b/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte
index 439687d0c2..ed89d4316d 100644
--- a/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte
+++ b/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte
@@ -64,7 +64,11 @@
{:else if value.customType === 'password'}
{:else if value.customType === 'email'}
-
+
{:else if value.customType === 'table'}
{:else if value.customType === 'row'}
@@ -75,7 +79,7 @@
{:else if value.type === 'string' || value.type === 'number'}
diff --git a/packages/builder/src/components/backend/DataTable/popovers/ExportPopover.svelte b/packages/builder/src/components/backend/DataTable/popovers/ExportPopover.svelte
index 3e7642982a..af561668ec 100644
--- a/packages/builder/src/components/backend/DataTable/popovers/ExportPopover.svelte
+++ b/packages/builder/src/components/backend/DataTable/popovers/ExportPopover.svelte
@@ -20,13 +20,12 @@
let exportFormat = FORMATS[0].key
async function exportView() {
- const response = await api.post(
- `/api/views/export?format=${exportFormat}`,
- view
+ download(
+ `/api/views/export?view=${encodeURIComponent(
+ view.name
+ )}&format=${exportFormat}`
)
- const downloadInfo = await response.json()
onClosed()
- window.location = downloadInfo.url
}
diff --git a/packages/builder/src/components/feedback/FeedbackNavLink.svelte b/packages/builder/src/components/feedback/FeedbackNavLink.svelte
index 6cba6417d4..5b7a2faf2a 100644
--- a/packages/builder/src/components/feedback/FeedbackNavLink.svelte
+++ b/packages/builder/src/components/feedback/FeedbackNavLink.svelte
@@ -1,6 +1,7 @@
diff --git a/packages/builder/src/components/start/AppCard.svelte b/packages/builder/src/components/start/AppCard.svelte
index a64b0527ff..f4dac1dc6c 100644
--- a/packages/builder/src/components/start/AppCard.svelte
+++ b/packages/builder/src/components/start/AppCard.svelte
@@ -14,9 +14,10 @@
async function exportApp() {
appExportLoading = true
try {
- download(`/api/backups/export?appId=${_id}`)
+ download(`/api/backups/export?appId=${_id}&appname=${name}`)
notifier.success("App Export Complete.")
} catch (err) {
+ console.error(err)
notifier.danger("App Export Failed.")
} finally {
appExportLoading = false
diff --git a/packages/server/src/api/controllers/backup.js b/packages/server/src/api/controllers/backup.js
index d021dca91f..c8bcafcb7c 100644
--- a/packages/server/src/api/controllers/backup.js
+++ b/packages/server/src/api/controllers/backup.js
@@ -4,12 +4,12 @@ const os = require("os")
const fs = require("fs-extra")
exports.exportAppDump = async function(ctx) {
- const { appId } = ctx.query
+ const { appId, appname } = ctx.query
const backupsDir = path.join(os.homedir(), ".budibase", "backups")
fs.ensureDirSync(backupsDir)
- const backupIdentifier = `${appId} Backup: ${new Date()}.txt`
+ const backupIdentifier = `${appname}Backup${new Date().getTime()}.txt`
await performDump({
dir: backupsDir,
@@ -23,19 +23,4 @@ exports.exportAppDump = async function(ctx) {
ctx.attachment(backupIdentifier)
ctx.body = fs.createReadStream(backupFile)
- // ctx.body = {
- // url: `/api/backups/download/${backupIdentifier}`,
- // }
}
-
-// exports.downloadAppDump = async function(ctx) {
-// const fileName = ctx.params.fileName
-
-// const backupsDir = path.join(os.homedir(), ".budibase", "backups")
-// fs.ensureDirSync(backupsDir)
-
-// const backupFile = path.join(backupsDir, fileName)
-
-// ctx.attachment(fileName)
-// ctx.body = fs.createReadStream(backupFile)
-// }
diff --git a/packages/server/src/api/controllers/view/index.js b/packages/server/src/api/controllers/view/index.js
index c4e8c1e372..05dc299754 100644
--- a/packages/server/src/api/controllers/view/index.js
+++ b/packages/server/src/api/controllers/view/index.js
@@ -83,23 +83,42 @@ const controller = {
ctx.message = `View ${ctx.params.viewName} saved successfully.`
},
exportView: async ctx => {
- const view = ctx.query.view
+ const db = new CouchDB(ctx.user.appId)
+ const designDoc = await db.get("_design/database")
+
+ const viewName = decodeURI(ctx.query.view)
+
+ const view = designDoc.views[viewName]
const format = ctx.query.format
- // Fetch view rows
- ctx.params.viewName = view.name
- ctx.query.group = view.groupBy
- if (view.field) {
- ctx.query.stats = true
- ctx.query.field = view.field
+ if (view) {
+ ctx.params.viewName = viewName
+ // Fetch view rows
+ ctx.query = {
+ group: view.meta.groupBy,
+ calculation: view.meta.calculation,
+ stats: !!view.meta.field,
+ field: view.meta.field,
+ }
+ } else {
+ // table all_ view
+ ctx.params.viewName = viewName
}
+
await fetchView(ctx)
+ let schema = view && view.meta && view.meta.schema
+ if (!schema) {
+ const tableId = ctx.params.tableId || view.meta.tableId
+ const table = await db.get(tableId)
+ schema = table.schema
+ }
+
// Export part
- let headers = Object.keys(view.schema)
+ let headers = Object.keys(schema)
const exporter = exporters[format]
const exportedFile = exporter(headers, ctx.body)
- const filename = `${view.name}.${format}`
+ const filename = `${viewName}.${format}`
fs.writeFileSync(join(os.tmpdir(), filename), exportedFile)
ctx.attachment(filename)
diff --git a/packages/server/src/api/routes/backup.js b/packages/server/src/api/routes/backup.js
index 283bec39a4..7f24a452e5 100644
--- a/packages/server/src/api/routes/backup.js
+++ b/packages/server/src/api/routes/backup.js
@@ -6,10 +6,5 @@ const { BUILDER } = require("../../utilities/security/permissions")
const router = Router()
router.get("/api/backups/export", authorized(BUILDER), controller.exportAppDump)
-// .get(
-// "/api/backups/download/:fileName",
-// authorized(BUILDER),
-// controller.downloadAppDump
-// )
module.exports = router
diff --git a/packages/server/src/api/routes/view.js b/packages/server/src/api/routes/view.js
index 4a32b4c592..0ae12f687c 100644
--- a/packages/server/src/api/routes/view.js
+++ b/packages/server/src/api/routes/view.js
@@ -12,6 +12,7 @@ const usage = require("../../middleware/usageQuota")
const router = Router()
router
+ .get("/api/views/export", authorized(BUILDER), viewController.exportView)
.get(
"/api/views/:viewName",
authorized(PermissionTypes.VIEW, PermissionLevels.READ),
@@ -25,6 +26,5 @@ router
viewController.destroy
)
.post("/api/views", authorized(BUILDER), usage, viewController.save)
- .post("/api/views/export", authorized(BUILDER), viewController.exportView)
module.exports = router
diff --git a/packages/standard-components/src/Navigation.svelte b/packages/standard-components/src/Navigation.svelte
index 9bfc30384d..2062a9d982 100644
--- a/packages/standard-components/src/Navigation.svelte
+++ b/packages/standard-components/src/Navigation.svelte
@@ -63,13 +63,18 @@
.nav__menu {
display: flex;
margin-top: 40px;
- gap: 16px;
flex-direction: row;
justify-content: flex-start;
align-items: center;
}
- .nav__menu > a {
+
+ .nav__menu > * {
+ margin-right: 16px;
+ }
+
+ :global(.nav__menu > a) {
font-size: 1.5em;
text-decoration: none;
+ margin-right: 16px;
}