Merge branch 'master' of github.com:Budibase/budibase into form-builder
This commit is contained in:
commit
de4b87a208
|
@ -64,7 +64,11 @@
|
|||
{:else if value.customType === 'password'}
|
||||
<Input type="password" extraThin bind:value={block.inputs[key]} />
|
||||
{:else if value.customType === 'email'}
|
||||
<Input type="email" extraThin bind:value={block.inputs[key]} />
|
||||
<BindableInput
|
||||
type={'email'}
|
||||
extraThin
|
||||
bind:value={block.inputs[key]}
|
||||
{bindings} />
|
||||
{:else if value.customType === 'table'}
|
||||
<TableSelector bind:value={block.inputs[key]} />
|
||||
{:else if value.customType === 'row'}
|
||||
|
@ -75,7 +79,7 @@
|
|||
<SchemaSetup bind:value={block.inputs[key]} />
|
||||
{:else if value.type === 'string' || value.type === 'number'}
|
||||
<BindableInput
|
||||
type="string"
|
||||
type={value.customType}
|
||||
extraThin
|
||||
bind:value={block.inputs[key]}
|
||||
{bindings} />
|
||||
|
|
|
@ -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
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<script>
|
||||
import { Popover } from "@budibase/bbui"
|
||||
import { store } from "builderStore"
|
||||
import { onMount } from "svelte"
|
||||
|
||||
import FeedbackIframe from "./FeedbackIframe.svelte"
|
||||
import analytics from "analytics"
|
||||
|
@ -10,9 +11,15 @@
|
|||
let iconContainer
|
||||
let popover
|
||||
|
||||
setInterval(() => {
|
||||
$store.highlightFeedbackIcon = analytics.highlightFeedbackIcon()
|
||||
onMount(() => {
|
||||
const interval = setInterval(() => {
|
||||
store.update(state => {
|
||||
state.highlightFeedbackIcon = analytics.highlightFeedbackIcon()
|
||||
return state
|
||||
})
|
||||
}, FIVE_MINUTES)
|
||||
return () => clearInterval(interval)
|
||||
})
|
||||
</script>
|
||||
|
||||
<div class="container" bind:this={iconContainer} on:click={popover.show}>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
// }
|
||||
|
|
|
@ -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
|
||||
|
||||
if (view) {
|
||||
ctx.params.viewName = viewName
|
||||
// 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
|
||||
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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
</style>
|
||||
|
|
Loading…
Reference in New Issue