1
0
Fork 0
mirror of synced 2024-07-04 22:11:23 +12:00

Getting downloading working correctly, some minor UI updates, adding a new middleware for converting a query string to a body (useful for when a GET has to be used).

This commit is contained in:
mike12345567 2023-02-22 18:50:27 +00:00
parent 34f03a5129
commit 01076bd35f
6 changed files with 60 additions and 34 deletions

View file

@ -0,0 +1,22 @@
import { Ctx } from "@budibase/types"
/**
* Expects a standard "query" query string property which is the JSON body
* of the request, which has to be sent via query string due to the requirement
* of making an endpoint a GET request e.g. downloading a file stream.
*/
export default function (ctx: Ctx, next: any) {
const queryString = ctx.request.query?.query as string | undefined
if (!queryString) {
return next()
}
const decoded = decodeURIComponent(queryString)
let json
try {
json = JSON.parse(decoded)
} catch (err) {
return next()
}
ctx.request.body = json
return next()
}

View file

@ -17,4 +17,5 @@ export { default as builderOrAdmin } from "./builderOrAdmin"
export { default as builderOnly } from "./builderOnly"
export { default as logging } from "./logging"
export { default as errorHandling } from "./errorHandling"
export { default as downloadBody } from "./downloadBody"
export * as joiValidator from "./joi-validator"

View file

@ -21,13 +21,13 @@
import UserRenderer from "./_components/UserRenderer.svelte"
import TimeRenderer from "./_components/TimeRenderer.svelte"
import AppColumnRenderer from "./_components/AppColumnRenderer.svelte"
import download from "downloadjs"
import { cloneDeep } from "lodash"
const schema = {
date: { width: "0.8fr" },
user: { width: "0.5fr" },
app: { width: "1fr", fieldName: "name" },
name: { width: "1fr" },
app: { width: "0.75fr", fieldName: "name" },
name: { width: "1.5fr" },
view: { width: "auto", borderLeft: true, displayName: "" },
}
@ -134,8 +134,7 @@
$auditLogs.logs.bookmark
)
} catch (error) {
console.log(error)
notifications.error("Error getting audit logs")
notifications.error(`Error getting audit logs - ${error}`)
}
}
@ -164,24 +163,13 @@
}
const viewDetails = detail => {
console.log(detail)
selectedLog = detail
sidePanelVisible = true
}
async function exportView() {
try {
const data = await API.exportView({
viewName: view,
format: exportFormat,
})
} catch (error) {
notifications.error(`Unable to export ${exportFormat.toUpperCase()} data`)
}
}
const downloadLogs = async () => {
try {
let response = await auditLogs.downloadLogs({
window.location = auditLogs.getDownloadUrl({
startDate,
endDate,
fullSearch: logSearchTerm,
@ -189,8 +177,6 @@
appIds: selectedApps,
events: selectedEvents,
})
// DO SOMETHING HERE???????????
} catch (error) {
notifications.error(`Error downloading logs: ` + error.message)
}
@ -205,6 +191,20 @@
notifications.success("Copied")
}
function cleanupMetadata(log) {
const cloned = cloneDeep(log)
cloned.userId = cloned.user._id
if (cloned.app) {
cloned.appId = cloned.app.appId
}
// remove props that are confused/not returned in download
delete cloned._id
delete cloned._rev
delete cloned.app
delete cloned.user
return cloned
}
onMount(async () => {
await auditLogs.getEventDefinitions()
await licensing.init()
@ -277,15 +277,15 @@
/>
</div>
</div>
<div style="max-width: 150px; ">
<Search placeholder="Search" bind:value={logSearchTerm} />
</div>
<div
on:click={() => downloadLogs()}
style="padding-bottom: var(--spacing-s)"
>
<Icon name="Download" />
</div>
<div style="max-width: 150px; ">
<Search placeholder="Search" bind:value={logSearchTerm} />
<Icon name="Download" hoverable />
</div>
</div>
<Layout noPadding>
@ -352,7 +352,7 @@
disabled
minHeight={"300px"}
height={"100%"}
value={JSON.stringify(selectedLog.metadata, null, 2)}
value={JSON.stringify(cleanupMetadata(selectedLog), null, 2)}
/>
</div>
</div>

View file

@ -28,15 +28,15 @@ export function createAuditLogsStore() {
})
}
async function downloadLogs(opts = {}) {
return await API.downloadLogs(opts)
function getDownloadUrl(opts = {}) {
return API.getDownloadUrl(opts)
}
return {
subscribe,
search,
getEventDefinitions,
downloadLogs,
getDownloadUrl,
}
}

View file

@ -8,7 +8,7 @@ const buildOpts = ({
events,
}) => {
const opts = {}
if (bookmark) {
opts.bookmark = bookmark
}
@ -56,10 +56,8 @@ export const buildAuditLogsEndpoints = API => ({
})
},
downloadLogs: async opts => {
return await API.post({
url: `/api/global/auditlogs/download`,
body: buildOpts(opts),
})
getDownloadUrl: opts => {
const query = encodeURIComponent(JSON.stringify(opts))
return `/api/global/auditlogs/download?query=${query}`
},
})

View file

@ -0,0 +1,5 @@
import { mocks } from "@budibase/backend-core/tests"
mocks.licenses.useEnvironmentVariables()
describe("/api/global/auditlogs", () => {})