From efe1cca74bbbb70c7035863cdf406b5e621d7dd1 Mon Sep 17 00:00:00 2001 From: Martin McKeaveney Date: Wed, 3 Feb 2021 13:28:11 +0000 Subject: [PATCH 1/7] change backup to be appname --- .../src/components/start/AppCard.svelte | 11 ++++++----- packages/server/src/api/controllers/backup.js | 19 ++----------------- packages/server/src/api/routes/backup.js | 5 ----- 3 files changed, 8 insertions(+), 27 deletions(-) diff --git a/packages/builder/src/components/start/AppCard.svelte b/packages/builder/src/components/start/AppCard.svelte index a64b0527ff..aaee055c5e 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 @@ -29,13 +30,13 @@ 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/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 From 909ccac598d624cfddf2629fbbf07541f2c5cb79 Mon Sep 17 00:00:00 2001 From: Martin McKeaveney Date: Wed, 3 Feb 2021 13:50:19 +0000 Subject: [PATCH 2/7] make email field bindable in automations --- .../SetupPanel/AutomationBlockSetup.svelte | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte b/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte index 439687d0c2..61a0824363 100644 --- a/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte +++ b/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte @@ -62,9 +62,13 @@ {/each} {:else if value.customType === 'password'} - + {:else if value.customType === 'email'} - + {:else if value.customType === 'table'} {:else if value.customType === 'row'} @@ -75,10 +79,10 @@ {:else if value.type === 'string' || value.type === 'number'} + {bindings} /> {/if} {/each} From 1f6a755cb6f5a6a3162573f0a5b94a0668e440c2 Mon Sep 17 00:00:00 2001 From: Martin McKeaveney Date: Thu, 4 Feb 2021 08:18:33 +0000 Subject: [PATCH 3/7] fixing JSON and CSV import/export --- .../SetupPanel/AutomationBlockSetup.svelte | 8 +- .../DataTable/popovers/ExportPopover.svelte | 9 +- .../src/components/start/AppCard.svelte | 8 +- .../server/src/api/controllers/view/index.js | 37 +++++-- packages/server/src/api/routes/view.js | 2 +- .../standard-components/src/Navigation.svelte | 9 +- .../standard-components/src/Search.svelte | 103 ++++++++++++++++++ 7 files changed, 151 insertions(+), 25 deletions(-) create mode 100644 packages/standard-components/src/Search.svelte diff --git a/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte b/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte index 61a0824363..ed89d4316d 100644 --- a/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte +++ b/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte @@ -62,13 +62,13 @@ {/each} {:else if value.customType === 'password'} - + {:else if value.customType === 'email'} + {bindings} /> {:else if value.customType === 'table'} {:else if value.customType === 'row'} @@ -82,7 +82,7 @@ type={value.customType} extraThin bind:value={block.inputs[key]} - {bindings} /> + {bindings} /> {/if} {/each} 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/start/AppCard.svelte b/packages/builder/src/components/start/AppCard.svelte index aaee055c5e..f4dac1dc6c 100644 --- a/packages/builder/src/components/start/AppCard.svelte +++ b/packages/builder/src/components/start/AppCard.svelte @@ -30,13 +30,13 @@ 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/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 4a4ec8dccc..192beaf74e 100644 --- a/packages/standard-components/src/Navigation.svelte +++ b/packages/standard-components/src/Navigation.svelte @@ -60,13 +60,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; } diff --git a/packages/standard-components/src/Search.svelte b/packages/standard-components/src/Search.svelte new file mode 100644 index 0000000000..2896861289 --- /dev/null +++ b/packages/standard-components/src/Search.svelte @@ -0,0 +1,103 @@ + + +
+
+ {#each searchableFields as field} +
+ + {#if schema[field].type === 'options'} + + {:else if schema[field].type === 'boolean'} + + {:else if schema[field].type === 'number'} + + {:else if schema[field].type === 'string'} + + {/if} +
+ {/each} + + +
+ {#if rows.length > 0} + {#if $component.children === 0 && $builderStore.inBuilder} +

Add some components too

+ {:else} + {#each rows as row} + + + + {/each} + {/if} + {:else if loaded && $builderStore.inBuilder} +

Feed me some data

+ {/if} +
+ + From ef97ca3e8a8525ff853f7d294f07f5dcb7f16542 Mon Sep 17 00:00:00 2001 From: Martin McKeaveney Date: Thu, 4 Feb 2021 08:21:39 +0000 Subject: [PATCH 4/7] remove search carried over from other branch --- .../standard-components/src/Search.svelte | 103 ------------------ 1 file changed, 103 deletions(-) delete mode 100644 packages/standard-components/src/Search.svelte diff --git a/packages/standard-components/src/Search.svelte b/packages/standard-components/src/Search.svelte deleted file mode 100644 index 2896861289..0000000000 --- a/packages/standard-components/src/Search.svelte +++ /dev/null @@ -1,103 +0,0 @@ - - -
-
- {#each searchableFields as field} -
- - {#if schema[field].type === 'options'} - - {:else if schema[field].type === 'boolean'} - - {:else if schema[field].type === 'number'} - - {:else if schema[field].type === 'string'} - - {/if} -
- {/each} - - -
- {#if rows.length > 0} - {#if $component.children === 0 && $builderStore.inBuilder} -

Add some components too

- {:else} - {#each rows as row} - - - - {/each} - {/if} - {:else if loaded && $builderStore.inBuilder} -

Feed me some data

- {/if} -
- - From 1e2627cdfbc946c046bedd26eae10180b0527b23 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Thu, 4 Feb 2021 11:26:04 +0000 Subject: [PATCH 5/7] Fix bug making apps swap to different apps randomly --- .../src/components/feedback/FeedbackNavLink.svelte | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/packages/builder/src/components/feedback/FeedbackNavLink.svelte b/packages/builder/src/components/feedback/FeedbackNavLink.svelte index 6cba6417d4..7800ee0dea 100644 --- a/packages/builder/src/components/feedback/FeedbackNavLink.svelte +++ b/packages/builder/src/components/feedback/FeedbackNavLink.svelte @@ -1,18 +1,22 @@
From af5a95557af465213f8a00de12596109f6eb4986 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Thu, 4 Feb 2021 11:27:12 +0000 Subject: [PATCH 6/7] Reset back to 5 minute intervals --- packages/builder/src/components/feedback/FeedbackNavLink.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/builder/src/components/feedback/FeedbackNavLink.svelte b/packages/builder/src/components/feedback/FeedbackNavLink.svelte index 7800ee0dea..4801ef51a6 100644 --- a/packages/builder/src/components/feedback/FeedbackNavLink.svelte +++ b/packages/builder/src/components/feedback/FeedbackNavLink.svelte @@ -6,7 +6,7 @@ import FeedbackIframe from "./FeedbackIframe.svelte" import analytics from "analytics" - const FIVE_MINUTES = 30000 + const FIVE_MINUTES = 300000 let iconContainer let popover From 5a89c640bd7200eadb955e38b5af34b6013ce5cd Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Thu, 4 Feb 2021 11:29:35 +0000 Subject: [PATCH 7/7] Be even more explicit with notification icon store update to avoid any magic --- .../builder/src/components/feedback/FeedbackNavLink.svelte | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/builder/src/components/feedback/FeedbackNavLink.svelte b/packages/builder/src/components/feedback/FeedbackNavLink.svelte index 4801ef51a6..5b7a2faf2a 100644 --- a/packages/builder/src/components/feedback/FeedbackNavLink.svelte +++ b/packages/builder/src/components/feedback/FeedbackNavLink.svelte @@ -13,7 +13,10 @@ onMount(() => { const interval = setInterval(() => { - $store.highlightFeedbackIcon = analytics.highlightFeedbackIcon() + store.update(state => { + state.highlightFeedbackIcon = analytics.highlightFeedbackIcon() + return state + }) }, FIVE_MINUTES) return () => clearInterval(interval) })