From 896441fa3b6dddebfd54d570398ede630063ebcc Mon Sep 17 00:00:00 2001
From: Moises Sacal <moisbo@gmail.com>
Date: Wed, 2 Oct 2019 15:26:49 +1000
Subject: [PATCH] added pagination eresearch/rdm#1289

---
 README.md                          | 29 +++++++++++++++++++++++++++++
 src/components/RegisterEvents.js   | 29 ++++++++++++++++++-----------
 src/components/Router.js           | 24 ++++++++++++++++++++++++
 src/components/SolrService.js      | 11 +++++++----
 src/components/views/ListDocs.js   |  4 +++-
 src/components/views/Main.js       |  4 ++--
 src/components/views/Pagination.js | 23 +++++++++++++++++++++++
 src/index.js                       |  6 +++++-
 8 files changed, 111 insertions(+), 19 deletions(-)
 create mode 100644 README.md
 create mode 100644 src/components/views/Pagination.js

diff --git a/README.md b/README.md
new file mode 100644
index 0000000..303bab2
--- /dev/null
+++ b/README.md
@@ -0,0 +1,29 @@
+### Data-Portal 
+
+This is the code of a single page application for searching with SOLR
+
+### Install
+
+```bash
+npm intstall
+```
+
+### Development
+
+run npm scripts for development
+
+#### Webpack
+
+```bash
+npm run start:dev
+``` 
+
+and go to [http://localhost:9000](http://localhost:9000)
+
+### Compile
+
+```bash
+npm run build
+```
+
+should generate a [dist](./dist) folder with compiled SPA
\ No newline at end of file
diff --git a/src/components/RegisterEvents.js b/src/components/RegisterEvents.js
index 3149fa6..59a9492 100644
--- a/src/components/RegisterEvents.js
+++ b/src/components/RegisterEvents.js
@@ -16,28 +16,35 @@ const RegisterEvents = function (state) {
 
   delegate('#app', 'click', '#search-text', async () => {
     const search = document.querySelector('#text-to-search');
-    const {data, status} = await solrService.search({api: state.config.api}, search.value);
-    state.main.docs = data.docs;
-    state.main.numFound = data.numFound;
-    renderApp(state, app);
+    window.location.hash = `#search/${state.main.start}/${state.main.page}/${search.value}`;
+
+    // const {data, status} = await solrService.search({api: state.config.api}, {start: state.main.start, page: state.main.page, text: search.value});
+    // state.main.docs = data.docs;
+    // state.main.numFound = data.numFound;
+    // renderApp(state, app);
   });
 
   delegate('#app', 'keyup', '#text-to-search', async (event) => {
     if (event.keyCode === 13) {
       event.preventDefault();
+
       const search = document.querySelector('#text-to-search');
-      const {data, status} = await solrService.search({api: state.config.api}, search.value);
-      state.main.docs = data.docs;
-      state.main.numFound = data.numFound;
-      renderApp(state, app);
+      window.location.hash = `#search/${state.main.start}/${state.main.page}/${search.value}`;
+
+      // const {data, status} = await solrService.search({api: state.config.api}, {start: state.main.start, page: state.main.page, text: search.value});
+      // state.main.docs = data.docs;
+      // state.main.numFound = data.numFound;
+      // renderApp(state, app);
     }
   });
 
   delegate('#app', 'click', '#search-text-1', async () => {
     const search = document.querySelector('#text-to-search');
-    const {data, status} = await solrService.search({api: state.config.api}, search.value);
-    state.main.docs = data;
-    renderApp(state, app);
+    window.location.hash = `#search/${state.main.start}/${state.main.page}/${search.value}`;
+
+    // const {data, status} = await solrService.search({api: state.config.api}, {start: state.main.start, page: state.main.page, text: search.value});
+    // state.main.docs = data;
+    // renderApp(state, app);
   });
 };
 
diff --git a/src/components/Router.js b/src/components/Router.js
index 9a49693..eed2ba8 100644
--- a/src/components/Router.js
+++ b/src/components/Router.js
@@ -23,11 +23,35 @@ const Router = async function (state) {
         app.innerHTML = [Header(state), Search(state), ViewError(state), Footer(state)].join('');
       }
     }
+    if (verb === '#search/') {
+      const splits = match[2].split('/');
+      const start = splits[0] || state.main.start;
+      const page = splits[1] || '';
+      const searchText = splits[2] || '';
+      const {data, status} = await solrService.search({api: state.config.api}, {
+        start: start,
+        page: page,
+        text: searchText
+      });
+      if (status === 200) {
+        state.main.docs = data.docs;
+        state.main.numFound = data.numFound;
+        state.main.searchText = searchText;
+        app.innerHTML = [Header(state), Search(state), Main(state), Footer(state)].join('');
+        const input = document.getElementById('text-to-search');
+        if (input) {
+          input.value = searchText;
+        }
+      } else {
+        app.innerHTML = [Header(state), Search(state), ViewError(state), Footer(state)].join('');
+      }
+    }
   } else {
     const {data, status} = await solrService.searchAll({api: state.config.api});
     if (status === 200) {
       state.main.docs = data.docs;
       state.main.numFound = data.numFound;
+      state.main.searchText = '';
       app.innerHTML = [Header(state), Search(state), Main(state), Footer(state)].join('');
     } else {
       app.innerHTML = [Header(state), Search(state), ViewError(state), Footer(state)].join('');
diff --git a/src/components/SolrService.js b/src/components/SolrService.js
index 9005a7a..66c0b00 100644
--- a/src/components/SolrService.js
+++ b/src/components/SolrService.js
@@ -28,13 +28,16 @@ const SolrService = {
       return {data: {}, status: e.message};
     }
   },
-  search: async function (config, data) {
+  search: async function (config, {start: start, page: page, text: text}) {
     try {
       let param = `select?q=main_search%3A`;
       //Twice encoded, once for html one for solr
-      data = encodeURIComponent(`${data}`);
-      data = encodeURIComponent(`${data}`);
-      const req = await axios.get(`${config.api}/${param}${data}`);
+      let data = encodeURIComponent(`${text}`);
+      data = encodeURIComponent(`${text}`);
+      if (text === '' || !text) {
+        data = '*';
+      }
+      const req = await axios.get(`${config.api}/${param}${data}&start=${start}&page=${page}`);
       if (req.data) {
         return {data: req.data['response'], status: req.status};
       } else {
diff --git a/src/components/views/ListDocs.js b/src/components/views/ListDocs.js
index 6438315..9e85d11 100644
--- a/src/components/views/ListDocs.js
+++ b/src/components/views/ListDocs.js
@@ -10,8 +10,10 @@ const ListDocs = function (data) {
         <div class="item"><a href="${url}">${d['name'][0]}</a> ${d['record_type_s']} </div>
       </li>`;
     });
+  } else {
+    html += `<div class="text-center"> No data found</div>`;
   }
-  html += `</ul>`;
+  html += `<div></div><br/></div></ul>`;
   return html;
 };
 
diff --git a/src/components/views/Main.js b/src/components/views/Main.js
index 673c3f5..c1ff76e 100644
--- a/src/components/views/Main.js
+++ b/src/components/views/Main.js
@@ -1,12 +1,12 @@
 const $ = require("jquery");
 const ListDocs = require('./ListDocs');
+const Pagination = require('./Pagination');
 
 const Main = function (data) {
   let html = '';
-  html = [ListDocs(data)].join('');
+  html = [ListDocs(data), Pagination(data)].join('');
 
   html += `<div class="container">
-  <br/>
   <div class="text-center">
   <p>Results: ${data.main.numFound}</p>
   </div>`;
diff --git a/src/components/views/Pagination.js b/src/components/views/Pagination.js
new file mode 100644
index 0000000..dc3a09d
--- /dev/null
+++ b/src/components/views/Pagination.js
@@ -0,0 +1,23 @@
+const Pagination = function (data) {
+  const numFound = data.main.numFound;
+  const pageSize = data.main.pageSize;
+  const searchText = data.main.searchText || '';
+  let start = data.main.start;
+  const pages = Math.ceil(numFound / pageSize);
+
+  let html = `
+  <div class="container">
+    <nav class="d-flex justify-content-center" aria-label="Pagination">
+    <ul class="pagination">`;
+  for (let x = 1; x < pages + 1; x++) {
+    html += `<li class="page-item"><a class="page-link" href="#search/${start}/${x}/${searchText}">${x}</a></li>`;
+    start = (start + pageSize);
+  }
+  html += `</ul>
+  </nav>
+  </div>`;
+
+  return html;
+}
+
+module.exports = Pagination;
\ No newline at end of file
diff --git a/src/index.js b/src/index.js
index 7f100b5..87bd8c6 100644
--- a/src/index.js
+++ b/src/index.js
@@ -32,7 +32,11 @@ let state = {
   main: {
     docs: [],
     doc: {},
-    numFound: 0
+    start: 0,
+    page: 1,
+    numFound: 0,
+    pageSize: 10,
+    searchText: ''
   },
   config: config
 };
-- 
GitLab