diff --git a/package.json b/package.json index e04487d..64b7d82 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,8 @@ "html-to-text": "^9.0.5", "pinia": "^2.1.7", "vue-highlight-words": "^3.0.1", - "vue-json-viewer": "3" + "vue-json-viewer": "3", + "zipcelx": "^1.6.2" }, "devDependencies": { "@acdh-oeaw/eslint-config": "^1.0.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index adc221b..15ea084 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -35,6 +35,9 @@ dependencies: vue-json-viewer: specifier: '3' version: 3.0.4(vue@3.3.7) + zipcelx: + specifier: ^1.6.2 + version: 1.6.2 devDependencies: '@acdh-oeaw/eslint-config': @@ -4821,6 +4824,10 @@ packages: flat-cache: 3.1.1 dev: true + /file-saver@2.0.5: + resolution: {integrity: sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA==} + dev: false + /file-type@3.9.0: resolution: {integrity: sha512-RLoqTXE8/vPmMuTI88DAzhMYC99I8BWv7zYP4A1puo5HIjEJ5EX48ighy4ZyKMG9EDXxBgW6e++cn7d1xuFghA==} engines: {node: '>=0.10.0'} @@ -5643,6 +5650,10 @@ packages: dev: false optional: true + /immediate@3.0.6: + resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==} + dev: false + /immutable@4.3.4: resolution: {integrity: sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA==} dev: true @@ -6140,6 +6151,15 @@ packages: engines: {'0': node >= 0.2.0} dev: true + /jszip@3.10.1: + resolution: {integrity: sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==} + dependencies: + lie: 3.3.0 + pako: 1.0.11 + readable-stream: 2.3.8 + setimmediate: 1.0.5 + dev: false + /keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} dependencies: @@ -6203,6 +6223,12 @@ packages: type-check: 0.4.0 dev: true + /lie@3.3.0: + resolution: {integrity: sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==} + dependencies: + immediate: 3.0.6 + dev: false + /lilconfig@2.1.0: resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==} engines: {node: '>=10'} @@ -6297,6 +6323,10 @@ packages: /lodash.defaults@4.2.0: resolution: {integrity: sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==} + /lodash.escape@4.0.1: + resolution: {integrity: sha512-nXEOnb/jK9g0DYMr1/Xvq6l5xMD7GDG55+GSYIYmS0G4tBk/hURD4JR9WCavs04t33WmJx9kCyp9vJ+mr4BOUw==} + dev: false + /lodash.isarguments@3.1.0: resolution: {integrity: sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==} @@ -8023,6 +8053,10 @@ packages: - supports-color dev: true + /pako@1.0.11: + resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==} + dev: false + /parent-module@1.0.1: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} @@ -9294,6 +9328,10 @@ packages: has-property-descriptors: 1.0.1 dev: true + /setimmediate@1.0.5: + resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==} + dev: false + /setprototypeof@1.2.0: resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} dev: true @@ -11399,6 +11437,14 @@ packages: readable-stream: 3.6.2 dev: true + /zipcelx@1.6.2: + resolution: {integrity: sha512-4Rj0/D7Z6GCQTFgtcPavj2xnD0d5hxw+yDdHHsucZDv54NQZGyytItAaxHnBOnY7jj5qWaAeMGsb7YcNS3gRPQ==} + dependencies: + file-saver: 2.0.5 + jszip: 3.10.1 + lodash.escape: 4.0.1 + dev: false + /zwitch@2.0.4: resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} dev: false diff --git a/src/components/DataDisplay/KWICDetailDialog.vue b/src/components/DataDisplay/KWICDetailDialog.vue index 1ff5d4d..820134a 100644 --- a/src/components/DataDisplay/KWICDetailDialog.vue +++ b/src/components/DataDisplay/KWICDetailDialog.vue @@ -39,8 +39,7 @@ watch(active, async () => { }); const parsedText = computed(() => { - if (!details.value) return "not loaded yet, lol"; - + if (!details.value?.content) return "not loaded yet."; const html = details.value.content.map((a) => a.str).join(" "); const text = convert(html.replaceAll("

", "

\n\n"), { preserveNewlines: true }); return text; diff --git a/src/plugins/helpers/highchartsExcelFunction.ts b/src/plugins/helpers/highchartsExcelFunction.ts new file mode 100644 index 0000000..c67f100 --- /dev/null +++ b/src/plugins/helpers/highchartsExcelFunction.ts @@ -0,0 +1,56 @@ +// @ts-nocheck +/* eslint-disable */ +// sadly this function is just js, so need to disable typechecker for it +import zipcelx from "zipcelx"; + +export const HighchartsExcelDownload = (H) => { + if (H.getOptions().exporting) { + H.Chart.prototype.downloadXLSX = function () { + const div = document.createElement("div"); + let name, + xlsxRows = []; + div.style.display = "none"; + document.body.appendChild(div); + const rows = this.getDataRows(true); + xlsxRows = rows.slice(1).map(function (row) { + return row.map(function (column) { + return { + type: typeof column === "number" ? "number" : "string", + value: column, + }; + }); + }); + + // Get the filename, copied from the Chart.fileDownload function + if (this.options.exporting.filename) { + name = this.options.exporting.filename; + } else if (this.title.textStr) { + name = this.title.textStr.replace(/ /g, "-").toLowerCase(); + } else { + name = "chart"; + } + + zipcelx({ + filename: name, + sheet: { + data: xlsxRows, + }, + }); + }; + + // Default lang string, overridable in i18n options + H.getOptions().lang.downloadXLSX = "Download XLSX"; + + // Add the menu item handler + H.getOptions().exporting.menuItemDefinitions.downloadXLSX = { + textKey: "downloadXLSX", + onclick: function () { + this.downloadXLSX(); + }, + }; + + // Replace the menu item + const menuItems = H.getOptions().exporting.buttons.contextButton.menuItems; + menuItems[menuItems.indexOf("downloadXLS")] = "downloadXLSX"; + } +}; diff --git a/src/plugins/highcharts.client.ts b/src/plugins/highcharts.client.ts index 3addfb5..fadab77 100644 --- a/src/plugins/highcharts.client.ts +++ b/src/plugins/highcharts.client.ts @@ -1,12 +1,18 @@ import Highcharts from "highcharts"; +import ExportingDataModule from "highcharts/modules/export-data"; +import ExportingModule from "highcharts/modules/exporting"; import MapsModule from "highcharts/modules/map"; import HighchartsVue from "highcharts-vue"; -// In order to use Highcharts Maps we need to -// wrap Highcharts with the correct module: +import { HighchartsExcelDownload } from "./helpers/highchartsExcelFunction"; export default defineNuxtPlugin((nuxtApp) => { MapsModule(Highcharts); + ExportingModule(Highcharts); + ExportingDataModule(Highcharts); + + // overwrites the excel download to work propperly. this part is copied and adapted from a highcharts fiddle using that library. could be adapted to use a more maintained one, but would only recomend, if issues surface + HighchartsExcelDownload(Highcharts); // @ts-ignore nuxtApp.vueApp.use(HighchartsVue, { tagName: "HighCharts" }); });