From 4203350268cda492b9b386f991fc73281ac2849e Mon Sep 17 00:00:00 2001 From: Kristjan Eimre Date: Sat, 16 Nov 2024 00:35:15 +0200 Subject: [PATCH] adapt to the new api organization --- src/MainPage/DownloadButton.jsx | 80 +++++++++++++++++++++------------ src/MainPage/loadIndexMc2d.js | 10 +++-- src/MainPage/restapiText.jsx | 40 +++++++++++------ src/common/restApiUtils.js | 24 ++++++++-- 4 files changed, 104 insertions(+), 50 deletions(-) diff --git a/src/MainPage/DownloadButton.jsx b/src/MainPage/DownloadButton.jsx index eac60b3..86fb34d 100644 --- a/src/MainPage/DownloadButton.jsx +++ b/src/MainPage/DownloadButton.jsx @@ -1,8 +1,13 @@ +import React, { useState } from "react"; +import { Spinner } from "react-bootstrap"; + import { saveAs } from "file-saver"; import { HelpButton } from "mc-react-library"; import { Popover } from "react-bootstrap"; +import { loadStructureUuids, AIIDA_REST_API_URL } from "../common/restApiUtils"; + import "./DownloadButton.css"; const getCurrentDateString = () => { @@ -27,40 +32,47 @@ const popover = ( the Materials Grid. The data is downloaded in JSON format, as an array. The array contains a JSON object for each material entry, with key-value pairs corresponding to the column properties. Additionally, each entry - includes a link to the corresponding detail page. + includes a link to the corresponding detail page and a link to download + the file in CIF format.
+
+ Note, to download all of the CIF files directly, see the corresponding + Materials Cloud Archive entry.

); 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 [isLoading, setIsLoading] = useState(false); - const handleDownload = () => { + const handleDownload = async () => { if (materialSelectorRef.current) { - const data = materialSelectorRef.current.getFilteredRows(); - // href currently just contains the url subpath to the details page - // replace it with a better name and full url - let modData = data.map((entry) => { - let modEntry = { - ...entry, - details_link: `${window.location.origin}${entry.href}`, - }; - delete modEntry.href; - return modEntry; - }); - const json = JSON.stringify(modData, null, 2); - const blob = new Blob([json], { type: "application/json" }); - const filename = `mc2d_filtered_entries_${getCurrentDateString()}.json`; - saveAs(blob, filename); + setIsLoading(true); + try { + const structureUuids = await loadStructureUuids(); + const data = materialSelectorRef.current.getFilteredRows(); + + let modData = data.map((entry) => { + let uuid = structureUuids[entry.id]; + let downloadLink = `${AIIDA_REST_API_URL}/nodes/${uuid}/download?download_format=cif`; + let modEntry = { + ...entry, + details_link: `${window.location.origin}${entry.href}`, + download_cif: downloadLink, + }; + delete modEntry.href; + return modEntry; + }); + + const json = JSON.stringify(modData, null, 2); + const blob = new Blob([json], { type: "application/json" }); + const filename = `mc2d_filtered_entries_${getCurrentDateString()}.json`; + saveAs(blob, filename); + } catch (error) { + console.error("Error downloading data:", error); + } finally { + setIsLoading(false); + } } }; @@ -68,11 +80,21 @@ export const DownloadButton = ({ materialSelectorRef, disabled }) => {
diff --git a/src/MainPage/loadIndexMc2d.js b/src/MainPage/loadIndexMc2d.js index f22c42f..d280a9b 100644 --- a/src/MainPage/loadIndexMc2d.js +++ b/src/MainPage/loadIndexMc2d.js @@ -10,16 +10,18 @@ import { getSymmetryInfo } from "mc-react-library"; const COLUMN_ORDER_AND_SETTINGS = [ { field: "id", hide: false, width: 120 }, { field: "formula", hide: false }, + { field: "formula_hill", hide: true }, { field: "num_elements", hide: false }, { field: "num_atoms", hide: true }, { field: "prototype", hide: false }, - { field: "space_group_number", hide: false }, - { field: "space_group_int", hide: true }, + { field: "space_group_int", hide: false }, + { field: "space_group_number", hide: true }, { field: "band_gap", hide: false }, { field: "abundance", hide: false }, { field: "magnetic_state", hide: true }, { field: "total_magnetization", hide: true, minWidth: 130 }, { field: "absolute_magnetization", hide: true, minWidth: 130 }, + { field: "phonons_unstable", hide: true }, { field: "binding_energy_df2", hide: false, minWidth: 140 }, { field: "binding_energy_rvv10", hide: false }, { field: "parent_formula", hide: false }, @@ -35,7 +37,7 @@ const FRONTEND_COLUMNS = [ headerName: "Number of elements", colType: "integer", }, - calcFunc: (entry) => countNumberOfElements(entry["formula"]), + calcFunc: (entry) => countNumberOfElements(entry["formula_h"]), }, { columnDef: { @@ -43,7 +45,7 @@ const FRONTEND_COLUMNS = [ headerName: "Num. of atoms/cell", colType: "integer", }, - calcFunc: (entry) => countNumberOfAtoms(entry["formula"]), + calcFunc: (entry) => countNumberOfAtoms(entry["formula_h"]), }, // { // columnDef: { diff --git a/src/MainPage/restapiText.jsx b/src/MainPage/restapiText.jsx index 37e4f8e..2b9e140 100644 --- a/src/MainPage/restapiText.jsx +++ b/src/MainPage/restapiText.jsx @@ -1,9 +1,14 @@ -import { MC_REST_API_URL, AIIDA_REST_API_URL } from "../common/restApiUtils"; +import { + MC_REST_API_URL_BASE, + MC_REST_API_URL, + AIIDA_REST_API_URL, +} from "../common/restApiUtils"; import "./restapiText.css"; -const INDEX_URL = `${MC_REST_API_URL}/entries`; -const SINGLE_ENTRY_URL = `${MC_REST_API_URL}/entries/mc2d-1`; +const DOCS_URL = `${MC_REST_API_URL_BASE}/docs`; +const INDEX_URL = `${MC_REST_API_URL}/overview`; +const SINGLE_ENTRY_URL = `${MC_REST_API_URL}/base/mc2d-1`; export const restapiText = (
@@ -13,19 +18,28 @@ export const restapiText = (

1. Materials Cloud and AiiDA REST APIs
- The MC2D frontend is running on the following APIs: + The MC2D frontend is running on:
  • - Index of materials:{" "} - - {INDEX_URL} - -
  • -
  • - Single compound data:{" "} - - {SINGLE_ENTRY_URL} + The Materials Cloud REST API for the curated metadata:{" "} + + {DOCS_URL} + , see e.g. +
  • AiiDA REST API for properties and provenance:{" "} diff --git a/src/common/restApiUtils.js b/src/common/restApiUtils.js index bda539c..3d9b07d 100644 --- a/src/common/restApiUtils.js +++ b/src/common/restApiUtils.js @@ -2,8 +2,9 @@ // REST API UTILITIES // Define all functions for api calls here. -export const MC_REST_API_URL = - "https://dev-aiida.materialscloud.org/mc-rest-api/mc2d/pbe-v1"; +export const MC_REST_API_URL_BASE = + "https://dev-aiida.materialscloud.org/mc-rest-api"; +export const MC_REST_API_URL = `${MC_REST_API_URL_BASE}/mc2d/pbe-v1`; export const AIIDA_REST_API_URL = "https://dev-aiida.materialscloud.org/mc2d-new/api/v4"; export const EXPLORE_URL = "https://dev-www.materialscloud.org/explore/mc2d"; @@ -13,7 +14,7 @@ const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); export async function loadIndex() { // await delay(2000); - let endpoint = `${MC_REST_API_URL}/entries`; + let endpoint = `${MC_REST_API_URL}/overview`; try { const response = await fetch(endpoint, { method: "get" }); const json = await response.json(); @@ -35,7 +36,7 @@ export async function loadMetadata() { } export async function loadDetails(id) { - let endpoint = `${MC_REST_API_URL}/entries/${id}`; + let endpoint = `${MC_REST_API_URL}/base/${id}`; try { const response = await fetch(endpoint, { method: "get" }); const json = await response.json(); @@ -93,3 +94,18 @@ export async function loadPhononVis(id) { return null; } } + +export async function loadStructureUuids() { + let endpoint = `${MC_REST_API_URL}/structure-uuids`; + try { + const response = await fetch(endpoint, { method: "get" }); + if (!response.ok) { + return null; + } + const json = await response.json(); + return json; + } catch (error) { + console.error("Error fetching structure-uuids:", error); + return null; + } +}