From 89fc419f0f68648087f3669eb2c3efaaf5fdf80e Mon Sep 17 00:00:00 2001
From: Hermann Blum <hermannsblum@yahoo.de>
Date: Fri, 1 Dec 2017 14:45:18 +0100
Subject: [PATCH] refractor table-queries and add search

This adds an easy exact-match-search to tables.
In order to do so, we change the specifications that tables take query objects instead of query strings so we can combine them easier with the search query.
---
 src/views/tableView.js | 62 ++++++++++++++++++++++++++++++++++++++----
 1 file changed, 57 insertions(+), 5 deletions(-)

diff --git a/src/views/tableView.js b/src/views/tableView.js
index 183bc65..e501c1e 100644
--- a/src/views/tableView.js
+++ b/src/views/tableView.js
@@ -17,6 +17,7 @@ class TableRow {
   }
 }
 
+
 export default class TableView {
   constructor(vnode) {
     this.items = [];
@@ -24,17 +25,55 @@ export default class TableView {
     this.titles = vnode.attrs.titles || this.show_keys;
     this.resource = vnode.attrs.resource;
     // the querystring is either given or will be parsed from the url
-    if (vnode.attrs.querystring) {
-      this.querystring = vnode.attrs.querystring;
+    if (vnode.attrs.query) {
+      this.query = vnode.attrs.query;
     } else {
-      this.querystring = m.buildQueryString(m.route.param());
+      this.query = m.route.param();
     }
   }
 
-  oninit() {
+  // definitions of query parameters in addition to API go here
+  buildQuerystring() {
+    const queryKeys = Object.keys(this.query);
+
+    if (queryKeys.length === 0) return '';
+
+    const query = {};
+
+    if ('search' in this.query && this.query.search.length > 0) {
+      // translate search into where, we just look if any field contains search
+      const searchQuery = {
+        $or: this.show_keys.map((key) => {
+          const fieldQuery = {};
+          fieldQuery[key] = this.query.search;
+          return fieldQuery;
+        }),
+      };
+
+      // if there exists already a where-filter, AND them together
+      if ('where' in this.query) {
+        query.where = JSON.stringify({ $and: [searchQuery, this.query.where] });
+      } else {
+        query.where = JSON.stringify(searchQuery);
+      }
+    } else {
+      query.where = JSON.stringify(this.query.where);
+    }
+
+    // add all other keys
+    queryKeys.filter(key => (key !== 'where' && key !== 'search'))
+      .forEach((key) => { query[key] = JSON.stringify(this.query[key]); });
+
+    console.log(query);
+
+    // now we can acutally build the query string
+    return `?${m.buildQueryString(query)}`;
+  }
+
+  buildList() {
     getSession().then((apiSession) => {
       let url = this.resource;
-      if (this.querystring.length > 0) url += `?${this.querystring}`;
+      if (Object.keys(this.query).length > 0) url += this.buildQuerystring();
       apiSession.get(url).then((response) => {
         this.items = response.data._items;
         console.log(this.items);
@@ -45,8 +84,21 @@ export default class TableView {
     });
   }
 
+  oninit() {
+    this.buildList();
+  }
+
   view() {
     return m('div', [
+      m('div.row', m('div.col-xs-4.input-group', [
+        m('input[name=search].form-control', {
+          value: this.query.search,
+          onchange: m.withAttr('value', (value) => { this.query.search = value; }),
+        }),
+        m('span.input-group-btn', m('button.btn.btn-default', {
+          onclick: () => { this.buildList(); },
+        }, 'Search')),
+      ])),
       m('table.table.table-hover', [
         m('thead', m('tr', this.titles.map(title => m('th', title)))),
         m('tbody', this.items.map(item =>
-- 
GitLab