diff --git a/package-lock.json b/package-lock.json
index 3931a1c..ccb8f1f 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -10,9 +10,10 @@
"dependencies": {
"bootstrap": "^5.3.2",
"bootstrap-icons": "^1.10.3",
+ "file-saver": "^2.0.5",
"mc-react-header": "^0.3.1",
"mc-react-library": "^0.3.1",
- "mc-react-ptable-materials-grid": "^0.7.3",
+ "mc-react-ptable-materials-grid": "^0.8.0",
"mc-react-structure-visualizer": "^0.7.2",
"plotly.js": "^2.6.2",
"react": "^18.1.0",
@@ -5705,17 +5706,25 @@
"node": ">=8.9"
}
},
+ "node_modules/ag-charts-types": {
+ "version": "10.1.0",
+ "resolved": "https://registry.npmjs.org/ag-charts-types/-/ag-charts-types-10.1.0.tgz",
+ "integrity": "sha512-pk9ft8hbgTXJ/thI/SEUR1BoauNplYExpcHh7tMOqVikoDsta1O15TB1ZL4XWnl4TPIzROBmONKsz7d8a2HBuQ=="
+ },
"node_modules/ag-grid-community": {
- "version": "31.3.4",
- "resolved": "https://registry.npmjs.org/ag-grid-community/-/ag-grid-community-31.3.4.tgz",
- "integrity": "sha512-jOxQO86C6eLnk1GdP24HB6aqaouFzMWizgfUwNY5MnetiWzz9ZaAmOGSnW/XBvdjXvC5Fpk3gSbvVKKQ7h9kBw=="
+ "version": "32.1.0",
+ "resolved": "https://registry.npmjs.org/ag-grid-community/-/ag-grid-community-32.1.0.tgz",
+ "integrity": "sha512-RVvkjRH61nuCXwIqTKQPqNbKR+8cGBKw7S1qmmMXsy0pCBAJaQn4kL3v31hKHxDtV4bPscBXLFKGnKzHuss0GQ==",
+ "dependencies": {
+ "ag-charts-types": "10.1.0"
+ }
},
"node_modules/ag-grid-react": {
- "version": "31.3.4",
- "resolved": "https://registry.npmjs.org/ag-grid-react/-/ag-grid-react-31.3.4.tgz",
- "integrity": "sha512-WmPASHRFGSTxCMRStWG5bRtln0Ugsdqbb3+Y8sEyGHeLw4hXqfpqie3lT9kqCOl7wPWUjCpwmFdXzRnWPmyyeg==",
+ "version": "32.1.0",
+ "resolved": "https://registry.npmjs.org/ag-grid-react/-/ag-grid-react-32.1.0.tgz",
+ "integrity": "sha512-GDbtvU3aicSajWXWxvQio5ZaPqJDx2jzgRBKQf1RF1IVzL+XATDmLFNuMND0+wJ/VW/xUjBFjiq9W1fjXg/DCA==",
"dependencies": {
- "ag-grid-community": "31.3.4",
+ "ag-grid-community": "32.1.0",
"prop-types": "^15.8.1"
},
"peerDependencies": {
@@ -9790,6 +9799,11 @@
"webpack": "^4.0.0 || ^5.0.0"
}
},
+ "node_modules/file-saver": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/file-saver/-/file-saver-2.0.5.tgz",
+ "integrity": "sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA=="
+ },
"node_modules/filelist": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz",
@@ -14185,16 +14199,18 @@
}
},
"node_modules/mc-react-ptable-materials-grid": {
- "version": "0.7.3",
- "resolved": "https://registry.npmjs.org/mc-react-ptable-materials-grid/-/mc-react-ptable-materials-grid-0.7.3.tgz",
- "integrity": "sha512-P5SimnNeH9JFQnh/btZJg8xRkDGb55zdphlcEpxto60lDIiNnb0gN++4zxy7ipNt0re56eJToSkhGs0kAJjzzA==",
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/mc-react-ptable-materials-grid/-/mc-react-ptable-materials-grid-0.8.0.tgz",
+ "integrity": "sha512-wll8BIpYLbdbec1XTsIZfj0WENAEmCC6KBVCs9QqPMoxPdXpEtoDyQDs8S4gYAP2yT1JTWsnd9uSVQKVEwzGEQ==",
"dependencies": {
"@testing-library/jest-dom": "^5.16.4",
"@testing-library/react": "^13.3.0",
"@testing-library/user-event": "^13.5.0",
- "ag-grid-community": "^31.3.4",
- "ag-grid-react": "^31.3.4",
+ "ag-grid-community": "^32.1.0",
+ "ag-grid-react": "^32.1.0",
"bootstrap": "^5.2.2",
+ "file-saver": "^2.0.5",
+ "mc-react-library": "^0.3.1",
"react": "^18.1.0",
"react-bootstrap": "^2.6.0",
"react-dom": "^18.1.0",
@@ -24736,17 +24752,25 @@
"regex-parser": "^2.2.11"
}
},
+ "ag-charts-types": {
+ "version": "10.1.0",
+ "resolved": "https://registry.npmjs.org/ag-charts-types/-/ag-charts-types-10.1.0.tgz",
+ "integrity": "sha512-pk9ft8hbgTXJ/thI/SEUR1BoauNplYExpcHh7tMOqVikoDsta1O15TB1ZL4XWnl4TPIzROBmONKsz7d8a2HBuQ=="
+ },
"ag-grid-community": {
- "version": "31.3.4",
- "resolved": "https://registry.npmjs.org/ag-grid-community/-/ag-grid-community-31.3.4.tgz",
- "integrity": "sha512-jOxQO86C6eLnk1GdP24HB6aqaouFzMWizgfUwNY5MnetiWzz9ZaAmOGSnW/XBvdjXvC5Fpk3gSbvVKKQ7h9kBw=="
+ "version": "32.1.0",
+ "resolved": "https://registry.npmjs.org/ag-grid-community/-/ag-grid-community-32.1.0.tgz",
+ "integrity": "sha512-RVvkjRH61nuCXwIqTKQPqNbKR+8cGBKw7S1qmmMXsy0pCBAJaQn4kL3v31hKHxDtV4bPscBXLFKGnKzHuss0GQ==",
+ "requires": {
+ "ag-charts-types": "10.1.0"
+ }
},
"ag-grid-react": {
- "version": "31.3.4",
- "resolved": "https://registry.npmjs.org/ag-grid-react/-/ag-grid-react-31.3.4.tgz",
- "integrity": "sha512-WmPASHRFGSTxCMRStWG5bRtln0Ugsdqbb3+Y8sEyGHeLw4hXqfpqie3lT9kqCOl7wPWUjCpwmFdXzRnWPmyyeg==",
+ "version": "32.1.0",
+ "resolved": "https://registry.npmjs.org/ag-grid-react/-/ag-grid-react-32.1.0.tgz",
+ "integrity": "sha512-GDbtvU3aicSajWXWxvQio5ZaPqJDx2jzgRBKQf1RF1IVzL+XATDmLFNuMND0+wJ/VW/xUjBFjiq9W1fjXg/DCA==",
"requires": {
- "ag-grid-community": "31.3.4",
+ "ag-grid-community": "32.1.0",
"prop-types": "^15.8.1"
}
},
@@ -27804,6 +27828,11 @@
"schema-utils": "^3.0.0"
}
},
+ "file-saver": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/file-saver/-/file-saver-2.0.5.tgz",
+ "integrity": "sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA=="
+ },
"filelist": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz",
@@ -31178,16 +31207,18 @@
"requires": {}
},
"mc-react-ptable-materials-grid": {
- "version": "0.7.3",
- "resolved": "https://registry.npmjs.org/mc-react-ptable-materials-grid/-/mc-react-ptable-materials-grid-0.7.3.tgz",
- "integrity": "sha512-P5SimnNeH9JFQnh/btZJg8xRkDGb55zdphlcEpxto60lDIiNnb0gN++4zxy7ipNt0re56eJToSkhGs0kAJjzzA==",
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/mc-react-ptable-materials-grid/-/mc-react-ptable-materials-grid-0.8.0.tgz",
+ "integrity": "sha512-wll8BIpYLbdbec1XTsIZfj0WENAEmCC6KBVCs9QqPMoxPdXpEtoDyQDs8S4gYAP2yT1JTWsnd9uSVQKVEwzGEQ==",
"requires": {
"@testing-library/jest-dom": "^5.16.4",
"@testing-library/react": "^13.3.0",
"@testing-library/user-event": "^13.5.0",
- "ag-grid-community": "^31.3.4",
- "ag-grid-react": "^31.3.4",
+ "ag-grid-community": "^32.1.0",
+ "ag-grid-react": "^32.1.0",
"bootstrap": "^5.2.2",
+ "file-saver": "^2.0.5",
+ "mc-react-library": "^0.3.1",
"react": "^18.1.0",
"react-bootstrap": "^2.6.0",
"react-dom": "^18.1.0",
diff --git a/package.json b/package.json
index 01ae44b..2aa2539 100644
--- a/package.json
+++ b/package.json
@@ -14,9 +14,10 @@
"dependencies": {
"bootstrap": "^5.3.2",
"bootstrap-icons": "^1.10.3",
+ "file-saver": "^2.0.5",
"mc-react-header": "^0.3.1",
"mc-react-library": "^0.3.1",
- "mc-react-ptable-materials-grid": "^0.7.3",
+ "mc-react-ptable-materials-grid": "^0.8.0",
"mc-react-structure-visualizer": "^0.7.2",
"plotly.js": "^2.6.2",
"react": "^18.1.0",
diff --git a/src/MainPage/DownloadButton.css b/src/MainPage/DownloadButton.css
new file mode 100644
index 0000000..7086104
--- /dev/null
+++ b/src/MainPage/DownloadButton.css
@@ -0,0 +1,22 @@
+.aggrid-style-button {
+ padding: 10px;
+ background-color: #f8f8f8;
+ color: #000000;
+ font-family: var(--ag-font-family);
+ font-size: 12px;
+ font-weight: bold;
+ border: 1px solid #babfc7;
+ cursor: pointer;
+ margin-bottom: 3px;
+ margin-top: 2px;
+}
+
+.aggrid-style-button:hover {
+ background-color: #dbdbdb;
+}
+
+.aggrid-style-button-disabled {
+ opacity: 0.4;
+ cursor: none;
+ pointer-events: none;
+}
diff --git a/src/MainPage/DownloadButton.jsx b/src/MainPage/DownloadButton.jsx
new file mode 100644
index 0000000..cfe44de
--- /dev/null
+++ b/src/MainPage/DownloadButton.jsx
@@ -0,0 +1,36 @@
+import { saveAs } from "file-saver";
+
+import "./DownloadButton.css";
+
+export const DownloadButton = ({ materialSelectorRef, disabled }) => {
+ /*
+ Note: the plan is to potentially also include direct download links (via the AiiDA rest api)
+ to each of the materials in the downloaded file, but currently the index page doesn't have
+ the structure UUIDs. Including them in the default index download is not great, as they would
+ increase the initial download size considerably, while not really needed for the table.
+
+ Therefore, it probably might make sense to implement an additional endpoint, e.g. pbe-v1/uuids
+ that is only called when this download button is clicked.
+ */
+
+ const handleDownload = () => {
+ if (materialSelectorRef.current) {
+ const data = materialSelectorRef.current.getFilteredRows();
+ const json = JSON.stringify(data, null, 2);
+ const blob = new Blob([json], { type: "application/json" });
+ const filename = `mc3d_index_data_n${data.length}.json`;
+ saveAs(blob, filename);
+ }
+ };
+
+ return (
+
+ );
+};
diff --git a/src/MainPage/index.jsx b/src/MainPage/index.jsx
index 9c1f1cf..c63827a 100644
--- a/src/MainPage/index.jsx
+++ b/src/MainPage/index.jsx
@@ -1,4 +1,4 @@
-import React, { useEffect, useState } from "react";
+import React, { useEffect, useState, useRef } from "react";
import "./index.css";
@@ -16,12 +16,13 @@ import { restapiText } from "./restapi";
import { loadDataMc3d } from "./loadDataMc3d";
+import { DownloadButton } from "./DownloadButton";
+
import Form from "react-bootstrap/Form";
function MainPage() {
const [columns, setColumns] = useState([]);
const [rows, setRows] = useState([]);
-
const [method, setMethod] = useState("pbe-v1");
useEffect(() => {
@@ -37,6 +38,8 @@ function MainPage() {
setMethod(event.target.value);
};
+ const materialSelectorRef = useRef(null);
+
return (
-
+
+
{aboutText}
diff --git a/src/MainPage/loadDataMc3d.js b/src/MainPage/loadDataMc3d.js
index aeb62d2..ba22a14 100644
--- a/src/MainPage/loadDataMc3d.js
+++ b/src/MainPage/loadDataMc3d.js
@@ -151,7 +151,9 @@ function formatRows(indexData, metadata, method) {
let row = {};
Object.entries(entry).map(([key, value]) => {
- row[labelMap[key]] = value;
+ if (key in labelMap) {
+ row[labelMap[key]] = value;
+ }
});
let modifiedKeys = {