From c79ec3cc18068387b66f28e4d463d14ea12031c4 Mon Sep 17 00:00:00 2001
From: meyer <meyer@astron.nl>
Date: Wed, 9 Sep 2020 15:11:02 +0200
Subject: [PATCH] added pagination to IVOA query

---
 src/components/Interactive.js             |  7 ++++++
 src/components/Rucio.js                   | 18 ++++++---------
 src/components/query/QueryIVOARegistry.js | 13 ++++++-----
 src/components/query/VORegistryResults.js | 18 +++++++++++++--
 src/components/query/VOServiceResults.js  | 28 +++++++++++++++++++++--
 src/utils/form/parseADEXForm.js           |  8 +++++--
 src/utils/form/parseASTRONVOForm.js       |  5 ++--
 src/utils/form/parseApertifForm.js        |  5 ++--
 src/utils/form/parseIVOAForm.js           |  8 +++++--
 src/utils/form/parseLOFARForm.js          |  5 ++--
 src/utils/form/parseQueryForm.js          | 10 ++++----
 src/utils/form/parseVOServiceForm.js      |  8 +++++--
 12 files changed, 95 insertions(+), 38 deletions(-)

diff --git a/src/components/Interactive.js b/src/components/Interactive.js
index b3508f3..e219659 100644
--- a/src/components/Interactive.js
+++ b/src/components/Interactive.js
@@ -3,6 +3,13 @@ import { Alert } from "react-bootstrap";
 
 export default function Interactive() {
   return (
+    // <div class="embed-responsive embed-responsive-16by9">
+    //   <iframe
+    //     class="embed-responsive-item"
+    //     src="http://130.246.212.44/escape/"
+    //     allowfullscreen
+    //   ></iframe>
+    // </div>
     <Alert variant="warning">
       <p>You will leave ESAP GUI and be redirected to</p>
       <a
diff --git a/src/components/Rucio.js b/src/components/Rucio.js
index 6dd2613..5c774b3 100644
--- a/src/components/Rucio.js
+++ b/src/components/Rucio.js
@@ -1,17 +1,13 @@
 import React from "react";
-import { Alert } from "react-bootstrap";
 
 export default function Rucio() {
   return (
-    <Alert variant="warning">
-      <p>You will leave ESAP GUI and be redirected to</p>
-      <a
-        target="_blank"
-        rel="noopener noreferrer"
-        href="https://escape-dios-dl.cern.ch/ui/"
-      >
-        Rucio Web UI
-      </a>
-    </Alert>
+    <div class="embed-responsive embed-responsive-16by9">
+      <iframe
+        class="embed-responsive-item"
+        src="https://escape-rucio.cern.ch"
+        allowfullscreen
+      ></iframe>
+    </div>
   );
 }
diff --git a/src/components/query/QueryIVOARegistry.js b/src/components/query/QueryIVOARegistry.js
index cf1101a..2c9e039 100644
--- a/src/components/query/QueryIVOARegistry.js
+++ b/src/components/query/QueryIVOARegistry.js
@@ -17,7 +17,7 @@ export default function QueryIVOARegistry() {
   //  "catalogquery": "querystring",
   //  "status": "fetching|fechted",
   //  "results": null}
-  const { queryMap, formData, setFormData } = useContext(QueryContext);
+  const { queryMap, formData, setFormData, page } = useContext(QueryContext);
   const { config, api_host, setConfigName } = useContext(GlobalContext);
   const { selectedRegistry, queryStep, setQueryStep } = useContext(IVOAContext);
   const { uri } = useParams();
@@ -59,16 +59,17 @@ export default function QueryIVOARegistry() {
 
     if (queryStep === "run-query") {
       selectedRegistry.forEach((access_url) => {
-        queries = [...queries, ...parseVOServiceForm(formData, access_url)];
+        queries = [
+          ...queries,
+          ...parseVOServiceForm(formData, access_url, page),
+        ];
       });
     } else {
-      queries = parseQueryForm(gui, formData);
+      queries = parseQueryForm(gui, formData, page);
     }
 
     console.log("queries:", queries);
 
-    // Ideally query for each catalog is sent to ESAP API Gateway, and query results is returned
-    // This is under development in the backend at the moment
     queryMap.clear();
     queries.forEach((query) => {
       queryMap.set(query.catalog, {
@@ -100,7 +101,7 @@ export default function QueryIVOARegistry() {
           });
         });
     });
-  }, [formData]);
+  }, [formData, page]);
 
   function formTemplate({ TitleField, properties, title, description }) {
     return (
diff --git a/src/components/query/VORegistryResults.js b/src/components/query/VORegistryResults.js
index d8481c9..d57804f 100644
--- a/src/components/query/VORegistryResults.js
+++ b/src/components/query/VORegistryResults.js
@@ -6,7 +6,7 @@ import Paginate from "../Paginate";
 import { IVOAContext } from "../../contexts/IVOAContext";
 
 export default function VORegistryResults({ catalog }) {
-  const { queryMap } = useContext(QueryContext);
+  const { queryMap, page, setPage } = useContext(QueryContext);
   const {
     selectedRegistry,
     addRegistry,
@@ -35,8 +35,23 @@ export default function VORegistryResults({ catalog }) {
     setRegistryList(queryMap.get(catalog).results.results);
     console.log("Registry List:", registryList);
 
+    const numPages = queryMap.get(catalog).results.pages;
+    function newPageCallback(setPage) {
+      return (args) => {
+        if (args.target) {
+          setPage(parseFloat(args.target.text));
+        }
+      };
+    }
+
     return (
       <>
+        <Paginate
+          getNewPage={newPageCallback(setPage)}
+          currentPage={page}
+          numAdjacent={3}
+          numPages={numPages}
+        />
         <Table className="mt-3" responsive>
           <thead>
             <tr className="bg-light">
@@ -96,7 +111,6 @@ export default function VORegistryResults({ catalog }) {
             })}
           </tbody>
         </Table>
-        {/* <Paginate /> */}
       </>
     );
   } else {
diff --git a/src/components/query/VOServiceResults.js b/src/components/query/VOServiceResults.js
index 0f9ee8c..b811f06 100644
--- a/src/components/query/VOServiceResults.js
+++ b/src/components/query/VOServiceResults.js
@@ -1,18 +1,40 @@
-import React, { useContext } from "react";
+import React, { useContext, useEffect } from "react";
 import { Alert, Table } from "react-bootstrap";
 import { QueryContext } from "../../contexts/QueryContext";
+import LoadingSpinner from "../LoadingSpinner";
+import Paginate from "../Paginate";
 
 export default function VORegistryResults({ catalog }) {
-  const { queryMap } = useContext(QueryContext);
+  const { queryMap, page, setPage } = useContext(QueryContext);
 
   if (!queryMap.get(catalog)) return null;
   console.log("VO service queryMap:", queryMap.get(catalog));
+
   if (queryMap.get(catalog).status === "fetched") {
+    if (queryMap.get(catalog).results[0].includes("ERROR"))
+      return (
+        <Alert variant="warning">{queryMap.get(catalog).results[0]}</Alert>
+      );
     if (queryMap.get(catalog).results.results.length === 0)
       return <Alert variant="warning">No matching results found!</Alert>;
+
+    const numPages = queryMap.get(catalog).results.pages;
+    function newPageCallback(setPage) {
+      return (args) => {
+        if (args.target) {
+          setPage(parseFloat(args.target.text));
+        }
+      };
+    }
     return (
       <div>
         <h1>Results from {catalog}</h1>
+        <Paginate
+          getNewPage={newPageCallback(setPage)}
+          currentPage={page}
+          numAdjacent={3}
+          numPages={numPages}
+        />
         <Table className="mt-3" responsive>
           <thead>
             <tr className="bg-light">
@@ -35,6 +57,8 @@ export default function VORegistryResults({ catalog }) {
         </Table>
       </div>
     );
+  } else {
+    return <LoadingSpinner />;
   }
   return null;
 }
diff --git a/src/utils/form/parseADEXForm.js b/src/utils/form/parseADEXForm.js
index 351fabe..1c6a1d6 100644
--- a/src/utils/form/parseADEXForm.js
+++ b/src/utils/form/parseADEXForm.js
@@ -1,4 +1,4 @@
-export default function ParseADEXForm(formData) {
+export default function ParseADEXForm(formData, page) {
   let catalogs = ["apertif", "astron_vo"];
   let queries = [];
   // queries is an array of dictionaries, where each dictionary consists of
@@ -32,7 +32,11 @@ export default function ParseADEXForm(formData) {
       return null;
     });
   } else {
-    let esapquery = query + `${`${query}` ? "&" : ""}archive_uri=` + catalog;
+    let esapquery =
+      query +
+      `${`${query}` ? "&" : ""}archive_uri=` +
+      catalog +
+      `&page=${page}`;
 
     queries.push({
       catalog: catalog,
diff --git a/src/utils/form/parseASTRONVOForm.js b/src/utils/form/parseASTRONVOForm.js
index 9162c82..c0eef34 100644
--- a/src/utils/form/parseASTRONVOForm.js
+++ b/src/utils/form/parseASTRONVOForm.js
@@ -1,4 +1,4 @@
-export default function ParseASTRONVOForm(formData) {
+export default function ParseASTRONVOForm(formData, page) {
   let queries = [];
   // queries is an array of dictionaries, where each dictionary consists of
   // {"catalog": "catalogname",
@@ -19,7 +19,8 @@ export default function ParseASTRONVOForm(formData) {
   //  "status": "null|fetching|fetched",
   //  "results": null}
   let catalog = formInput.find(([key]) => key === "catalog")[1];
-  let esapquery = query + `${`${query}` ? "&" : ""}archive_uri=` + catalog;
+  let esapquery =
+    query + `${`${query}` ? "&" : ""}archive_uri=` + catalog + `&page=${page}`;
   queries.push({
     catalog: catalog,
     esapquery: esapquery,
diff --git a/src/utils/form/parseApertifForm.js b/src/utils/form/parseApertifForm.js
index 4a76405..6aab904 100644
--- a/src/utils/form/parseApertifForm.js
+++ b/src/utils/form/parseApertifForm.js
@@ -1,4 +1,4 @@
-export default function ParseApertifForm(formData) {
+export default function ParseApertifForm(formData, page) {
   let queries = [];
   // queries is an array of dictionaries, where each dictionary consists of
   // {"catalog": "catalogname",
@@ -19,7 +19,8 @@ export default function ParseApertifForm(formData) {
   //  "status": "null|fetching|fetched",
   //  "results": null}
   let catalog = formInput.find(([key]) => key === "catalog")[1];
-  let esapquery = query + `${`${query}` ? "&" : ""}archive_uri=` + catalog;
+  let esapquery =
+    query + `${`${query}` ? "&" : ""}archive_uri=` + catalog + `&page=${page}`;
   queries.push({
     catalog: catalog,
     esapquery: esapquery,
diff --git a/src/utils/form/parseIVOAForm.js b/src/utils/form/parseIVOAForm.js
index e518ff0..2b3fadc 100644
--- a/src/utils/form/parseIVOAForm.js
+++ b/src/utils/form/parseIVOAForm.js
@@ -1,4 +1,4 @@
-export default function ParseIVOAForm(formData) {
+export default function ParseIVOAForm(formData, page) {
   let queries = [];
   // queries is an array of dictionaries, where each dictionary consists of
   // {"catalog": "catalogname",
@@ -25,7 +25,11 @@ export default function ParseIVOAForm(formData) {
   let service_type = formInput.find(([key]) => key === "service_type")[1];
 
   let esapquery =
-    "get-services/?" + query + `${`${query}` ? "&" : ""}dataset_uri=` + catalog;
+    "get-services/?" +
+    query +
+    `${`${query}` ? "&" : ""}dataset_uri=` +
+    catalog +
+    `&page=${page}`;
 
   queries.push({
     catalog: catalog,
diff --git a/src/utils/form/parseLOFARForm.js b/src/utils/form/parseLOFARForm.js
index badc2b8..8f8ff91 100644
--- a/src/utils/form/parseLOFARForm.js
+++ b/src/utils/form/parseLOFARForm.js
@@ -1,4 +1,4 @@
-export default function ParseLOFARForm(formData) {
+export default function ParseLOFARForm(formData, page) {
   let queries = [];
   // queries is an array of dictionaries, where each dictionary consists of
   // {"catalog": "catalogname",
@@ -19,7 +19,8 @@ export default function ParseLOFARForm(formData) {
   //  "status": "null|fetching|fetched",
   //  "results": null}
   let catalog = formInput.find(([key]) => key === "catalog")[1];
-  let esapquery = query + `${`${query}` ? "&" : ""}archive_uri=` + catalog;
+  let esapquery =
+    query + `${`${query}` ? "&" : ""}archive_uri=` + catalog + `&page=${page}`;
   queries.push({
     catalog: catalog,
     esapquery: esapquery,
diff --git a/src/utils/form/parseQueryForm.js b/src/utils/form/parseQueryForm.js
index ecf4e15..08c3162 100644
--- a/src/utils/form/parseQueryForm.js
+++ b/src/utils/form/parseQueryForm.js
@@ -8,17 +8,17 @@ import parseASTRONVOForm from "./parseASTRONVOForm";
 export default function parseQueryForm(gui, formData, page) {
   switch (gui) {
     case "adex":
-      return parseADEXForm(formData);
+      return parseADEXForm(formData, page);
     case "zooniverse":
       return parseZooniverseForm(formData, page);
     case "lofar":
-      return parseLOFARForm(formData);
+      return parseLOFARForm(formData, page);
     case "apertif":
-      return parseApertifForm(formData);
+      return parseApertifForm(formData, page);
     case "astron_vo":
-      return parseASTRONVOForm(formData);
+      return parseASTRONVOForm(formData, page);
     case "ivoa":
-      return parseIVOAForm(formData);
+      return parseIVOAForm(formData, page);
     default:
       return null;
   }
diff --git a/src/utils/form/parseVOServiceForm.js b/src/utils/form/parseVOServiceForm.js
index c42aec9..9b308fc 100644
--- a/src/utils/form/parseVOServiceForm.js
+++ b/src/utils/form/parseVOServiceForm.js
@@ -1,4 +1,4 @@
-export default function ParseVOServiceForm(formData, access_url) {
+export default function ParseVOServiceForm(formData, access_url, page) {
   let queries = [];
   // queries is an array of dictionaries, where each dictionary consists of
   // {"catalog": "catalogname",
@@ -29,7 +29,11 @@ export default function ParseVOServiceForm(formData, access_url) {
   let service_type = formInput.find(([key]) => key === "service_type")[1];
 
   let esapquery =
-    "query/?" + query + `${`${query}` ? "&" : ""}dataset_uri=` + catalog;
+    "query/?" +
+    query +
+    `${`${query}` ? "&" : ""}dataset_uri=` +
+    catalog +
+    `&page=${page}`;
 
   queries.push({
     catalog: access_url,
-- 
GitLab