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; }