fix(frontend): Fix csv generation (#3439)

* feat(frontend): properly convert JSON to CSV

* feat(frontend): properly convert JSON to CSV
This commit is contained in:
Faton Ramadani
2024-03-19 09:01:16 +01:00
committed by GitHub
parent 4557e7beb4
commit 21b4719949
3 changed files with 57 additions and 33 deletions
+20
View File
@@ -10,6 +10,7 @@
"license": "AGPL-3.0",
"dependencies": {
"@aws-crypto/sha256-js": "^4.0.0",
"@json2csv/plainjs": "^7.0.6",
"@leeoniya/ufuzzy": "^1.0.8",
"@popperjs/core": "^2.11.6",
"@redocly/json-to-json-schema": "^0.0.1",
@@ -1044,6 +1045,20 @@
"integrity": "sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==",
"dev": true
},
"node_modules/@json2csv/formatters": {
"version": "7.0.6",
"resolved": "https://registry.npmjs.org/@json2csv/formatters/-/formatters-7.0.6.tgz",
"integrity": "sha512-hjIk1H1TR4ydU5ntIENEPgoMGW+Q7mJ+537sDFDbsk+Y3EPl2i4NfFVjw0NJRgT+ihm8X30M67mA8AS6jPidSA=="
},
"node_modules/@json2csv/plainjs": {
"version": "7.0.6",
"resolved": "https://registry.npmjs.org/@json2csv/plainjs/-/plainjs-7.0.6.tgz",
"integrity": "sha512-4Md7RPDCSYpmW1HWIpWBOqCd4vWfIqm53S3e/uzQ62iGi7L3r34fK/8nhOMEe+/eVfCx8+gdSCt1d74SlacQHw==",
"dependencies": {
"@json2csv/formatters": "^7.0.6",
"@streamparser/json": "^0.0.20"
}
},
"node_modules/@kurkle/color": {
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/@kurkle/color/-/color-0.3.2.tgz",
@@ -1411,6 +1426,11 @@
"node": ">=14.0.0"
}
},
"node_modules/@streamparser/json": {
"version": "0.0.20",
"resolved": "https://registry.npmjs.org/@streamparser/json/-/json-0.0.20.tgz",
"integrity": "sha512-VqAAkydywPpkw63WQhPVKCD3SdwXuihCUVZbbiY3SfSTGQyHmwRoq27y4dmJdZuJwd5JIlQoMPyGvMbUPY0RKQ=="
},
"node_modules/@sveltejs/adapter-static": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/@sveltejs/adapter-static/-/adapter-static-3.0.1.tgz",
+1
View File
@@ -92,6 +92,7 @@
"type": "module",
"dependencies": {
"@aws-crypto/sha256-js": "^4.0.0",
"@json2csv/plainjs": "^7.0.6",
"@leeoniya/ufuzzy": "^1.0.8",
"@popperjs/core": "^2.11.6",
"@redocly/json-to-json-schema": "^0.0.1",
@@ -14,14 +14,14 @@
import DataTable from './DataTable.svelte'
import Head from './Head.svelte'
import Row from './Row.svelte'
import { pluralize } from '$lib/utils'
import { pluralize, sendUserToast } from '$lib/utils'
import Badge from '$lib/components/common/badge/Badge.svelte'
import { isEmail, isLink } from './tableUtils'
import type { BadgeColor } from '../common'
import Popover from '../Popover.svelte'
import DarkModeObserver from '../DarkModeObserver.svelte'
import Button from '../common/button/Button.svelte'
import { Parser } from '@json2csv/plainjs'
export let objects: Array<Record<string, any>> = []
let currentPage = 1
@@ -118,6 +118,16 @@
typeof objects[0][key] === 'boolean'
)
}
function convertJsonToCsv(arr: Array<Record<string, any>>): string {
try {
const parser = new Parser({})
const csv = parser.parse(arr)
return csv
} catch (err) {
throw new Error('An error occured when generating CSV:' + err)
}
}
</script>
<DarkModeObserver bind:darkMode />
@@ -157,39 +167,32 @@
color="light"
startIcon={{ icon: Download }}
on:click={() => {
const headers =
structuredObjects.length > 0
? Object.keys(structuredObjects[0].rowData).join(',')
: ''
const csvContent = [
headers, // Add headers as the first row
...structuredObjects
.filter(({ _id }) => {
if (selection.length > 0) {
return selection.includes(_id)
} else {
return true
}
})
.map(({ rowData }) =>
Object.values(rowData)
.map((field) =>
/[\",\n]/.test(field) ? '"' + field.replace(/"/g, '""') + '"' : field
)
.join(',')
)
].join('\n')
try {
const csvContent = convertJsonToCsv(
structuredObjects
.filter(({ _id }) => {
if (selection.length > 0) {
return selection.includes(_id)
} else {
return true
}
})
.map((obj) => obj.rowData)
)
const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' })
const url = URL.createObjectURL(blob)
const link = document.createElement('a')
link.setAttribute('href', url)
link.setAttribute('download', 'data.csv')
link.style.visibility = 'hidden'
document.body.appendChild(link)
link.click()
const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' })
const url = URL.createObjectURL(blob)
const link = document.createElement('a')
link.setAttribute('href', url)
link.setAttribute('download', 'data.csv')
link.style.visibility = 'hidden'
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
document.body.removeChild(link)
} catch (err) {
sendUserToast(err, true)
}
}}
>
{#if selection.length > 0}