From cfe8a4c07e510d76acfc0b1c123543f0951be0aa Mon Sep 17 00:00:00 2001 From: Nicolas Bonnel Date: Thu, 20 Jun 2024 14:29:15 +0200 Subject: [PATCH] fix: catalog CSV export --- package-lock.json | 63 +++++++++++++++++++++++++++++++++ package.json | 1 + public/pages/datasets/index.vue | 24 +++++++++++-- 3 files changed, 85 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index a55c213..dd95847 100644 --- a/package-lock.json +++ b/package-lock.json @@ -33,6 +33,7 @@ "http-link-header": "^1.1.0", "json-schema-defaults": "^0.4.0", "json-schema-ref-parser": "^9.0.9", + "json2csv": "^6.0.0-alpha.2", "marked": "^4.3.0", "memoizee": "^0.4.15", "mime-types": "^2.1.35", @@ -6843,6 +6844,11 @@ "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", "optional": true }, + "node_modules/@streamparser/json": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/@streamparser/json/-/json-0.0.6.tgz", + "integrity": "sha512-vL9EVn/v+OhZ+Wcs6O4iKE9EUpwHUqHmCtNUMWjqp+6dr85+XPOSGTEsqYNq1Vn04uk9SWlOVmx9J48ggJVT2Q==" + }, "node_modules/@szmarczak/http-timer": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", @@ -14611,6 +14617,31 @@ "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", "dev": true }, + "node_modules/json2csv": { + "version": "6.0.0-alpha.2", + "resolved": "https://registry.npmjs.org/json2csv/-/json2csv-6.0.0-alpha.2.tgz", + "integrity": "sha512-nJ3oP6QxN8z69IT1HmrJdfVxhU1kLTBVgMfRnNZc37YEY+jZ4nU27rBGxT4vaqM/KUCavLRhntmTuBFqZLBUcA==", + "dependencies": { + "@streamparser/json": "^0.0.6", + "commander": "^6.2.0", + "lodash.get": "^4.4.2" + }, + "bin": { + "json2csv": "bin/json2csv.js" + }, + "engines": { + "node": ">= 12", + "npm": ">= 6.13.0" + } + }, + "node_modules/json2csv/node_modules/commander": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", + "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", + "engines": { + "node": ">= 6" + } + }, "node_modules/json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", @@ -14867,6 +14898,11 @@ "integrity": "sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==", "dev": true }, + "node_modules/lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==" + }, "node_modules/lodash.invokemap": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/lodash.invokemap/-/lodash.invokemap-4.6.0.tgz", @@ -30139,6 +30175,11 @@ } } }, + "@streamparser/json": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/@streamparser/json/-/json-0.0.6.tgz", + "integrity": "sha512-vL9EVn/v+OhZ+Wcs6O4iKE9EUpwHUqHmCtNUMWjqp+6dr85+XPOSGTEsqYNq1Vn04uk9SWlOVmx9J48ggJVT2Q==" + }, "@szmarczak/http-timer": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", @@ -36206,6 +36247,23 @@ "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", "dev": true }, + "json2csv": { + "version": "6.0.0-alpha.2", + "resolved": "https://registry.npmjs.org/json2csv/-/json2csv-6.0.0-alpha.2.tgz", + "integrity": "sha512-nJ3oP6QxN8z69IT1HmrJdfVxhU1kLTBVgMfRnNZc37YEY+jZ4nU27rBGxT4vaqM/KUCavLRhntmTuBFqZLBUcA==", + "requires": { + "@streamparser/json": "^0.0.6", + "commander": "^6.2.0", + "lodash.get": "^4.4.2" + }, + "dependencies": { + "commander": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", + "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==" + } + } + }, "json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", @@ -36420,6 +36478,11 @@ "integrity": "sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==", "dev": true }, + "lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==" + }, "lodash.invokemap": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/lodash.invokemap/-/lodash.invokemap-4.6.0.tgz", diff --git a/package.json b/package.json index c512ef2..676e4e4 100644 --- a/package.json +++ b/package.json @@ -76,6 +76,7 @@ "http-link-header": "^1.1.0", "json-schema-defaults": "^0.4.0", "json-schema-ref-parser": "^9.0.9", + "json2csv": "^6.0.0-alpha.2", "marked": "^4.3.0", "memoizee": "^0.4.15", "mime-types": "^2.1.35", diff --git a/public/pages/datasets/index.vue b/public/pages/datasets/index.vue index 6524825..c74a33f 100644 --- a/public/pages/datasets/index.vue +++ b/public/pages/datasets/index.vue @@ -200,6 +200,20 @@ import DatasetCard from '~/components/dataset/card.vue' import { isMobileOnly } from 'mobile-device-detect' const { mapState, mapGetters, mapActions } = require('vuex') +const { Parser } = require('json2csv') +const fields = [ + { label: 'Identifiant', value: 'slug' }, + { label: 'Titre', value: 'title' }, + { label: 'Description', value: 'description' }, + { label: 'Themes', value: 'themes' }, + { label: 'Couverture spatiale', value: 'spatial' }, + { label: 'Page', value: 'page' }, + { label: 'Api', value: 'href' }, + { label: 'Date de création', value: 'createdAt' }, + { label: 'Date de mise a jour', value: 'dataUpdatedAt' } +] +const parser = new Parser({ fields }) + export default { components: { DatasetCard @@ -390,9 +404,13 @@ export default { if (!this.user) params.visibility = 'public' try { const datasets = (await this.$axios.$get(this.$store.getters.dataFairUrl + '/api/v1/datasets', { params })).results - const header = 'identifiant,titre,description,themes,couverture spatiale,page,api,date de création,date de mise a jour' - const content = datasets.map(d => `${d.slug},"${d.title}","${d.description}","${(d.topics || []).map(t => t.title).join(';')}",${d.bbox ? ('"' + JSON.stringify(d.bbox) + '"') : ''},${this.url + '/' + d.id},${d.href},${d.dataUpdatedAt},${d.createdAt}`).join('\n') - const blob = new Blob([header + '\n' + content], { type: 'text/csv' }) + datasets.forEach(d => { + d.themes = (d.topics || []).map(t => t.title).join(';') + d.spatial = d.bbox ? JSON.stringify(d.bbox) : '' + d.page = this.url + '/' + d.id + }) + const csv = parser.parse(datasets) + const blob = new Blob([csv], { type: 'text/csv' }) fileDownload(blob, name) } catch (err) { } this.downloading = null