diff --git a/ui/cap-react/src/antd/search/Loaders/Results.js b/ui/cap-react/src/antd/search/Loaders/Results.js
index 2a75703d39..e7a5538fef 100644
--- a/ui/cap-react/src/antd/search/Loaders/Results.js
+++ b/ui/cap-react/src/antd/search/Loaders/Results.js
@@ -1,9 +1,9 @@
import { Skeleton } from "antd";
const Results = () => {
- return [...Array(5)].map(item => (
+ return [...Array(5)].map((_, index) => (
diff --git a/ui/cap-react/src/antd/search/components/Header.js b/ui/cap-react/src/antd/search/components/Header.js
index 88200cc1e2..9e962718fd 100644
--- a/ui/cap-react/src/antd/search/components/Header.js
+++ b/ui/cap-react/src/antd/search/components/Header.js
@@ -1,7 +1,8 @@
import PropTypes from "prop-types";
import queryString from "query-string";
-import { Button, Row, Select, Space, Typography } from "antd";
-import { FilterOutlined } from "@ant-design/icons";
+import { Button, Dropdown, Row, Select, Space, Typography } from "antd";
+import { EllipsisOutlined, FilterOutlined } from "@ant-design/icons";
+import { DRAFTS, PUBLISHED } from "../../routes";
const SORT_OPTIONS = [
{ value: "mostrecent", label: "Newest First" },
@@ -9,6 +10,17 @@ const SORT_OPTIONS = [
{ value: "bestmatch", label: "Best Match" },
];
+const EXPORT_OPTIONS = [
+ {
+ key: "csv",
+ label: "Export CSV",
+ },
+ {
+ key: "xml",
+ label: "Export XML",
+ },
+];
+
const getValueFromLocation = (value = "mostrecent") => {
const choices = {
mostrecent: "Newest First",
@@ -30,6 +42,45 @@ const Header = ({
let searchParams = queryString.parse(location.search);
let sortParam = searchParams.sort || "mostrecent";
+
+ const onExport = async (mimetype) => {
+ let acceptHeader = null;
+ if (mimetype == "csv") { acceptHeader = "application/csv"}
+ else if (mimetype == "xml") { acceptHeader = "application/marcxml+xml"}
+ else return;
+
+ const timestamp = new Date().getTime();
+ const filename = `export-${timestamp}.${mimetype}`
+
+ let record_type = null;
+ if (location.pathname == DRAFTS) { record_type = "deposits"}
+ else if (location.pathname == PUBLISHED) { record_type = "records"}
+ else return;
+
+ try {
+ const apiUrl = `/api/${record_type}/${location.search}`;
+ const headers = { 'Accept': acceptHeader };
+
+ const response = await fetch(apiUrl, { headers });
+
+ if (!response.ok) {
+ throw new Error(`Error: ${response.statusText}`);
+ }
+
+ const blob = await response.blob();
+ const downloadUrl = window.URL.createObjectURL(blob);
+ const link = document.createElement('a');
+ link.href = downloadUrl;
+ link.setAttribute('download', filename);
+ document.body.appendChild(link);
+ link.click();
+ link.parentNode.removeChild(link);
+ window.URL.revokeObjectURL(downloadUrl);
+ } catch (error) {
+ console.error('Download failed', error);
+ }
+ };
+
// let isDescending = sortParam && sortParam[0] == "-";
// TODO: For asc/desc sorting
// let sortValue = isDescending ? sortParam.substring(1) : sortParam;
@@ -60,7 +111,7 @@ const Header = ({
)}
{shouldDisplayFacetButton && (
- } onClick={updateDisplayFacet}>
+ } onClick={updateDisplayFacet}>
Filters
)}
@@ -82,6 +133,16 @@ const Header = ({
))}
+ onExport(e.key)
+ }}
+ >
+ } />
+
{/*
diff --git a/ui/cap-react/src/antd/search/components/Results.js b/ui/cap-react/src/antd/search/components/Results.js
index a9263baad5..9c4b46cbe4 100644
--- a/ui/cap-react/src/antd/search/components/Results.js
+++ b/ui/cap-react/src/antd/search/components/Results.js
@@ -16,7 +16,7 @@ const Results = ({ results, loading }) => {
if (!results.size > 0)
return (
-
+