Skip to content

Commit

Permalink
adapt to the new api organization
Browse files Browse the repository at this point in the history
  • Loading branch information
eimrek committed Nov 15, 2024
1 parent ed445c4 commit 4203350
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 50 deletions.
80 changes: 51 additions & 29 deletions src/MainPage/DownloadButton.jsx
Original file line number Diff line number Diff line change
@@ -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 = () => {
Expand All @@ -27,52 +32,69 @@ 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. <br />
<br />
Note, to download all of the CIF files directly, see the corresponding
Materials Cloud Archive entry.
</p>
</Popover.Body>
</Popover>
);

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);
}
}
};

return (
<div className="download-button-outer-container">
<button
onClick={handleDownload}
disabled={disabled}
className={`aggrid-style-button ${disabled ? "aggrid-style-button-disabled" : ""}`}
disabled={disabled || isLoading}
className={`aggrid-style-button ${disabled || isLoading ? "aggrid-style-button-disabled" : ""}`}
style={{ marginTop: "5px" }}
>
Download filtered entries
{isLoading ? (
<Spinner
as="span"
animation="border"
size="sm"
role="status"
aria-hidden="true"
/>
) : (
"Download filtered entries"
)}
</button>
<HelpButton popover={popover} />
</div>
Expand Down
10 changes: 6 additions & 4 deletions src/MainPage/loadIndexMc2d.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 },
Expand All @@ -35,15 +37,15 @@ const FRONTEND_COLUMNS = [
headerName: "Number of elements",
colType: "integer",
},
calcFunc: (entry) => countNumberOfElements(entry["formula"]),
calcFunc: (entry) => countNumberOfElements(entry["formula_h"]),
},
{
columnDef: {
field: "num_atoms",
headerName: "Num. of atoms/cell",
colType: "integer",
},
calcFunc: (entry) => countNumberOfAtoms(entry["formula"]),
calcFunc: (entry) => countNumberOfAtoms(entry["formula_h"]),
},
// {
// columnDef: {
Expand Down
40 changes: 27 additions & 13 deletions src/MainPage/restapiText.jsx
Original file line number Diff line number Diff line change
@@ -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 = (
<div className="restapi-text-container">
Expand All @@ -13,19 +18,28 @@ export const restapiText = (
</p>
<div className="restapi-h">1. Materials Cloud and AiiDA REST APIs</div>
<div>
The MC2D frontend is running on the following APIs:
The MC2D frontend is running on:
<ul>
<li>
Index of materials:{" "}
<a href={INDEX_URL} target="_blank">
{INDEX_URL}
</a>
</li>
<li>
Single compound data:{" "}
<a href={SINGLE_ENTRY_URL} target="_blank">
{SINGLE_ENTRY_URL}
The Materials Cloud REST API for the curated metadata:{" "}
<a href={DOCS_URL} target="_blank">
{DOCS_URL}
</a>
, see e.g.
<ul>
<li>
Index of materials:{" "}
<a href={INDEX_URL} target="_blank">
{INDEX_URL}
</a>
</li>
<li>
Single entry data:{" "}
<a href={SINGLE_ENTRY_URL} target="_blank">
{SINGLE_ENTRY_URL}
</a>
</li>
</ul>
</li>
<li>
AiiDA REST API for properties and provenance:{" "}
Expand Down
24 changes: 20 additions & 4 deletions src/common/restApiUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand All @@ -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();
Expand All @@ -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();
Expand Down Expand Up @@ -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;
}
}

0 comments on commit 4203350

Please sign in to comment.