Browse Source

feat: basic csv export

Signed-off-by: Pranav C <pranavxc@gmail.com>
pull/714/head
Pranav C 3 years ago
parent
commit
1d9d4adc0c
  1. 105
      packages/nc-gui/components/project/spreadsheet/components/csvExport.vue
  2. 12
      packages/nc-gui/components/project/spreadsheet/rowsXcDataTable.vue
  3. 5
      packages/nc-gui/package-lock.json
  4. 1
      packages/nc-gui/package.json

105
packages/nc-gui/components/project/spreadsheet/components/csvExport.vue

@ -0,0 +1,105 @@
<template>
<v-btn
outlined
class="caption"
small
text
@click="exportCsv"
>
Export
</v-btn>
</template>
<script>
import Papaparse from 'papaparse'
import FileSaver from 'file-saver'
export default {
name: 'CsvExport',
props: {
data: Array,
meta: Object,
nodes: Object,
availableColumns: Array
},
methods: {
async extractCsvData() {
return Promise.all(this.data.map(async(r) => {
const row = {}
for (const col of this.availableColumns) {
console.log(col)
if (col.virtual) {
let prop, primCol
if (col.mm) {
await this.$store.dispatch('meta/ActLoadMeta', {
env: this.nodes.env,
dbAlias: this.nodes.dbAlias,
tn: col.mm.rtn
})
prop = `${col.mm._rtn}MMList`
primCol = this.$store.state.meta.metas[col.mm.rtn].columns.find(c => c.pv) ||
this.$store.state.meta.metas[col.mm.rtn].columns.find(c => c.pk)
row[col._cn] = r.row[prop] && r.row[prop].map(r => primCol && primCol._cn && r[primCol._cn])
} else if (col.hm) {
await this.$store.dispatch('meta/ActLoadMeta', {
env: this.nodes.env,
dbAlias: this.nodes.dbAlias,
tn: col.hm.tn
})
prop = `${col.hm._tn}List`
primCol = this.$store.state.meta.metas[col.hm.tn].columns.find(c => c.pv) ||
this.$store.state.meta.metas[col.hm.tn].columns.find(c => c.pk)
row[col._cn] = r.row[prop] && r.row[prop].map(r => primCol && primCol._cn && r[primCol._cn])
} else if (col.bt) {
await this.$store.dispatch('meta/ActLoadMeta', {
env: this.nodes.env,
dbAlias: this.nodes.dbAlias,
tn: col.bt.rtn
})
prop = `${col.bt._rtn}Read`
primCol = this.$store.state.meta.metas[col.bt.rtn].columns.find(c => c.pv) ||
this.$store.state.meta.metas[col.bt.rtn].columns.find(c => c.pk)
row[col._cn] = r.row[prop] &&
r.row[prop] && primCol && primCol._cn && r.row[prop][primCol._cn]
} else if (col.lk) {
// todo:
row[col._cn] = r.row[col._cn]
} else {
row[col._cn] = r.row[col._cn]
}
} else if (col.uidt === 'Attachment') {
let data = []
try {
if (typeof r.row[col._cn] === 'string') {
data = JSON.parse(r.row[col._cn])
} else if (r.row[col._cn]) {
data = r.row[col._cn]
}
} catch {
}
row[col._cn] = (data || []).map(a => `${a.title}(${a.url})`)
} else {
row[col._cn] = r.row[col._cn]
}
}
return row
}))
},
async exportCsv() {
const blob = new Blob([Papaparse.unparse(await this.extractCsvData())], { type: 'text/plain;charset=utf-8' })
FileSaver.saveAs(blob, `${this.meta._tn}_exported.csv`)
}
}
}
</script>
<style scoped>
</style>

12
packages/nc-gui/components/project/spreadsheet/rowsXcDataTable.vue

@ -4,7 +4,7 @@
<div v-if="!isForm" class="d-flex xc-border align-center search-box" style="min-width:156px">
<v-menu bottom offset-y>
<template #activator="{on}">
<div v-on="on" style="min-width: 56px">
<div style="min-width: 56px" v-on="on">
<v-icon
class="pa-1 pr-0 ml-2"
small
@ -61,6 +61,14 @@
<v-spacer class="h-100" @dblclick="debug=true" />
<csv-export
:available-columns="availableColumns"
:data="data"
:meta="meta"
:nodes="nodes"
class="mr-1"
/>
<template v-if="!isForm">
<debug-metas v-if="debug" class="mr-3" />
<v-tooltip bottom>
@ -544,10 +552,12 @@ import ExpandedForm from '@/components/project/spreadsheet/components/expandedFo
import Pagination from '@/components/project/spreadsheet/components/pagination'
import { SqlUI } from '~/helpers/sqlUi'
import ColumnFilter from '~/components/project/spreadsheet/components/columnFilterMenu'
import CsvExport from '~/components/project/spreadsheet/components/csvExport'
export default {
name: 'RowsXcDataTable',
components: {
CsvExport,
FormView,
DebugMetas,
Pagination,

5
packages/nc-gui/package-lock.json generated

@ -8533,6 +8533,11 @@
"resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
"integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw=="
},
"papaparse": {
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/papaparse/-/papaparse-5.3.1.tgz",
"integrity": "sha512-Dbt2yjLJrCwH2sRqKFFJaN5XgIASO9YOFeFP8rIBRG2Ain8mqk5r1M6DkfvqEVozVcz3r3HaUGw253hA1nLIcA=="
},
"parallel-transform": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz",

1
packages/nc-gui/package.json

@ -31,6 +31,7 @@
"nano-assign": "^1.0.1",
"nuxt": "^2.14.0",
"odometer": "^0.4.8",
"papaparse": "^5.3.1",
"secure-ls": "^1.2.6",
"socket.io-client": "^2.3.0",
"splitpanes": "^2.2.1",

Loading…
Cancel
Save