diff --git a/packages/analytics/addon/components/ca-report-preview.hbs b/packages/analytics/addon/components/ca-report-preview.hbs
index 22a97df6d..3bec1abbd 100644
--- a/packages/analytics/addon/components/ca-report-preview.hbs
+++ b/packages/analytics/addon/components/ca-report-preview.hbs
@@ -4,7 +4,16 @@
{{else}}
-
+
+ {{t "caluma.analytics.preview.export"}}
+
+
{{#each this.data.value.headings as |header|}}
diff --git a/packages/analytics/addon/components/ca-report-preview.js b/packages/analytics/addon/components/ca-report-preview.js
index 57a0fcb84..0ffd33a9f 100644
--- a/packages/analytics/addon/components/ca-report-preview.js
+++ b/packages/analytics/addon/components/ca-report-preview.js
@@ -1,9 +1,12 @@
+import { action } from "@ember/object";
+import { next } from "@ember/runloop";
import { inject as service } from "@ember/service";
import Component from "@glimmer/component";
import { tracked } from "@glimmer/tracking";
import { queryManager } from "ember-apollo-client";
import { task } from "ember-concurrency";
import { trackedTask } from "reactiveweb/ember-concurrency";
+import * as XLSX from "xlsx";
import getAnalyticsResultsQuery from "@projectcaluma/ember-analytics/gql/queries/get-analytics-results.graphql";
@@ -58,4 +61,17 @@ export default class CaReportPreviewComponent extends Component {
}
return null;
}
+
+ @action
+ exportTable() {
+ next(() => {
+ const wb = XLSX.utils.table_to_book(
+ document.getElementById("reports-table"),
+ );
+ XLSX.writeFile(
+ wb,
+ `${new Date().toLocaleDateString()}_${this.args.slug}.xlsx`,
+ );
+ });
+ }
}
diff --git a/packages/analytics/package.json b/packages/analytics/package.json
index d4cd05da3..590f36598 100644
--- a/packages/analytics/package.json
+++ b/packages/analytics/package.json
@@ -35,7 +35,8 @@
"ember-uikit": "^9.1.1",
"ember-validated-form": "^7.0.1",
"graphql": "^15.8.0",
- "reactiveweb": "^1.2.2"
+ "reactiveweb": "^1.2.2",
+ "xlsx": "https://cdn.sheetjs.com/xlsx-0.20.2/xlsx-0.20.2.tgz"
},
"//": [
"TODO: remove obsolete dependency to `ember-data` which is only necessary",
diff --git a/packages/analytics/tests/integration/components/ca-report-preview-test.js b/packages/analytics/tests/integration/components/ca-report-preview-test.js
index a08caaec5..c4c4d03dc 100644
--- a/packages/analytics/tests/integration/components/ca-report-preview-test.js
+++ b/packages/analytics/tests/integration/components/ca-report-preview-test.js
@@ -9,14 +9,11 @@ module("Integration | Component | ca-report-preview", function (hooks) {
setupRenderingTest(hooks);
setupIntl(hooks);
- test.skip("it renders", async function (assert) {
+ test("it renders", async function (assert) {
await render(hbs``);
- assert
- .dom(this.element)
- .hasText(
- "t:caluma.analytics.sections.table-preview:() t:caluma.analytics.preview.refresh:() t:caluma.analytics.preview.download:()",
- );
+ assert.dom(this.element).hasText("t:caluma.analytics.preview.export:()");
+ assert.dom(this.element.querySelector("#reports-table")).exists();
});
todo("it renders table data", async function () {});
diff --git a/packages/analytics/translations/de.yaml b/packages/analytics/translations/de.yaml
index 4b6b7aab8..1be7a0148 100644
--- a/packages/analytics/translations/de.yaml
+++ b/packages/analytics/translations/de.yaml
@@ -48,3 +48,5 @@ caluma:
cases: Dossiers
work-items: Aufgaben
documents: Dokumente
+ preview:
+ export: Export
diff --git a/packages/analytics/translations/en.yaml b/packages/analytics/translations/en.yaml
index c117350de..dbae58a5c 100644
--- a/packages/analytics/translations/en.yaml
+++ b/packages/analytics/translations/en.yaml
@@ -48,3 +48,5 @@ caluma:
cases: Cases
work-items: Work items
documents: Documents
+ preview:
+ export: Export
diff --git a/packages/analytics/translations/fr.yaml b/packages/analytics/translations/fr.yaml
index 72049c061..9dbff2288 100644
--- a/packages/analytics/translations/fr.yaml
+++ b/packages/analytics/translations/fr.yaml
@@ -48,3 +48,5 @@ caluma:
cases: Dossiers
work-items: Tâches
documents: Documents
+ preview:
+ export: Export
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 06c23ec18..e985eb94e 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -103,7 +103,7 @@ importers:
version: 16.3.1
stylelint-config-standard-scss:
specifier: 13.0.0
- version: 13.0.0(postcss@8.4.35)(stylelint@16.3.1)
+ version: 13.0.0(postcss@8.4.38)(stylelint@16.3.1)
stylelint-prettier:
specifier: ^5.0.0
version: 5.0.0(prettier@3.2.5)(stylelint@16.3.1)
@@ -374,6 +374,9 @@ importers:
reactiveweb:
specifier: ^1.2.2
version: 1.2.2(@babel/core@7.24.3)(@ember/test-waiters@3.1.0)(@glimmer/component@1.1.2)(@glimmer/tracking@1.1.2)(@glint/template@1.3.0)(ember-source@5.7.0)
+ xlsx:
+ specifier: https://cdn.sheetjs.com/xlsx-0.20.2/xlsx-0.20.2.tgz
+ version: '@cdn.sheetjs.com/xlsx-0.20.2/xlsx-0.20.2.tgz'
devDependencies:
'@ember/optional-features':
specifier: 2.1.0
@@ -653,7 +656,7 @@ importers:
version: file:packages/core(@glimmer/component@1.1.2)(@glint/template@1.3.0)(ember-data@5.3.3)(ember-resources@7.0.0)(ember-source@5.7.0)(webpack@5.91.0)
'@projectcaluma/ember-form':
specifier: workspace:^
- version: file:packages/form(@ember/test-waiters@3.1.0)(@glint/template@1.3.0)(@projectcaluma/ember-workflow@12.11.0)(ember-resources@7.0.0)(ember-source@5.7.0)(webpack@5.91.0)
+ version: file:packages/form(@ember/test-waiters@3.1.0)(@glint/template@1.3.0)(@projectcaluma/ember-workflow@12.11.1)(ember-resources@7.0.0)(ember-source@5.7.0)(webpack@5.91.0)
'@projectcaluma/ember-workflow':
specifier: workspace:^
version: file:packages/workflow(@ember/test-waiters@3.1.0)(@glimmer/tracking@1.1.2)(@glint/template@1.3.0)(ember-resources@7.0.0)(ember-source@5.7.0)(webpack@5.91.0)
@@ -17069,6 +17072,15 @@ packages:
postcss: 8.4.35
dev: true
+ /postcss-scss@4.0.9(postcss@8.4.38):
+ resolution: {integrity: sha512-AjKOeiwAitL/MXxQW2DliT28EKukvvbEWx3LBmJIRN8KfBGZbRTxNYW0kSqi1COiTZ57nZ9NW06S6ux//N1c9A==}
+ engines: {node: '>=12.0'}
+ peerDependencies:
+ postcss: ^8.4.29
+ dependencies:
+ postcss: 8.4.38
+ dev: true
+
/postcss-selector-parser@6.0.15:
resolution: {integrity: sha512-rEYkQOMUCEMhsKbK66tbEU9QVIxbhN18YiniAwA7XQYTVBqrBy+P2p5JcdqsHgKM2zWylp8d7J6eszocfds5Sw==}
engines: {node: '>=4'}
@@ -18840,7 +18852,7 @@ packages:
resolution: {integrity: sha512-DU2KZiB6VbPkO2tGSqQ9n96ZstUPjW7X4sGO6V2m1myIQluX0p1Ol8BrA/l6/EesqhMqXOIXs3cJNOy1UuU2BA==}
dev: true
- /stylelint-config-recommended-scss@14.0.0(postcss@8.4.35)(stylelint@16.3.1):
+ /stylelint-config-recommended-scss@14.0.0(postcss@8.4.38)(stylelint@16.3.1):
resolution: {integrity: sha512-HDvpoOAQ1RpF+sPbDOT2Q2/YrBDEJDnUymmVmZ7mMCeNiFSdhRdyGEimBkz06wsN+HaFwUh249gDR+I9JR7Onw==}
engines: {node: '>=18.12.0'}
peerDependencies:
@@ -18850,8 +18862,8 @@ packages:
postcss:
optional: true
dependencies:
- postcss: 8.4.35
- postcss-scss: 4.0.9(postcss@8.4.35)
+ postcss: 8.4.38
+ postcss-scss: 4.0.9(postcss@8.4.38)
stylelint: 16.3.1
stylelint-config-recommended: 14.0.0(stylelint@16.3.1)
stylelint-scss: 6.2.1(stylelint@16.3.1)
@@ -18866,7 +18878,7 @@ packages:
stylelint: 16.3.1
dev: true
- /stylelint-config-standard-scss@13.0.0(postcss@8.4.35)(stylelint@16.3.1):
+ /stylelint-config-standard-scss@13.0.0(postcss@8.4.38)(stylelint@16.3.1):
resolution: {integrity: sha512-WaLvkP689qSYUpJQPCo30TFJSSc3VzvvoWnrgp+7PpVby5o8fRUY1cZcP0sePZfjrFl9T8caGhcKg0GO34VDiQ==}
engines: {node: '>=18.12.0'}
peerDependencies:
@@ -18876,9 +18888,9 @@ packages:
postcss:
optional: true
dependencies:
- postcss: 8.4.35
+ postcss: 8.4.38
stylelint: 16.3.1
- stylelint-config-recommended-scss: 14.0.0(postcss@8.4.35)(stylelint@16.3.1)
+ stylelint-config-recommended-scss: 14.0.0(postcss@8.4.38)(stylelint@16.3.1)
stylelint-config-standard: 36.0.0(stylelint@16.3.1)
dev: true
@@ -20447,6 +20459,14 @@ packages:
/zen-observable@0.8.15:
resolution: {integrity: sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ==}
+ '@cdn.sheetjs.com/xlsx-0.20.2/xlsx-0.20.2.tgz':
+ resolution: {tarball: https://cdn.sheetjs.com/xlsx-0.20.2/xlsx-0.20.2.tgz}
+ name: xlsx
+ version: 0.20.2
+ engines: {node: '>=0.8'}
+ hasBin: true
+ dev: false
+
file:packages/core(@glimmer/component@1.1.2)(@glint/template@1.3.0)(ember-data@5.3.3)(ember-resources@7.0.0)(ember-source@5.7.0)(webpack@5.91.0):
resolution: {directory: packages/core, type: directory}
id: file:packages/core
@@ -20496,7 +20516,7 @@ packages:
- typescript
- webpack
- file:packages/form(@ember/test-waiters@3.1.0)(@glint/template@1.3.0)(@projectcaluma/ember-workflow@12.11.0)(ember-resources@7.0.0)(ember-source@5.7.0)(webpack@5.91.0):
+ file:packages/form(@ember/test-waiters@3.1.0)(@glint/template@1.3.0)(@projectcaluma/ember-workflow@12.11.1)(ember-resources@7.0.0)(ember-source@5.7.0)(webpack@5.91.0):
resolution: {directory: packages/form, type: directory}
id: file:packages/form
name: '@projectcaluma/ember-form'