diff --git a/web/app/static/js/nopaque/lists/CorpusFileList.js b/web/app/static/js/nopaque/lists/CorpusFileList.js
index afd2a42cb133173d5136c3cf968d05acca15870c..478be52ef0bfde2eed7ca134a512208ff2a3c2d4 100644
--- a/web/app/static/js/nopaque/lists/CorpusFileList.js
+++ b/web/app/static/js/nopaque/lists/CorpusFileList.js
@@ -40,7 +40,7 @@ class CorpusFileList extends RessourceList {
         window.location.href = this.corpus.files[corpusFileId].download_url;
         break;
       case 'view':
-        window.location.href = this.corpus.files[corpusFileId].url;
+        if (corpusFileId !== '-1') {window.location.href = this.corpus.files[corpusFileId].url;}
         break;
       default:
         console.error(`Unknown action: "${action}"`);
@@ -49,7 +49,7 @@ class CorpusFileList extends RessourceList {
   }
 
   patch(patch) {
-    let id, match, re;
+    let id, match, re, valueName;
     for (let operation of patch) {
       switch(operation.op) {
         case 'add':
@@ -65,6 +65,14 @@ class CorpusFileList extends RessourceList {
             this.remove(id);
           }
           break;
+        case 'replace':
+          // Matches the only paths that should be handled here: /corpora/{corpusId}/{status || description || title}
+          re = new RegExp('^/corpora/' + this.corpus.id + '/files/(\\d+)/(author|filename|publishing_year|title)$');
+          if (re.test(operation.path)) {
+            [match, id, valueName] = operation.path.match(re);
+            this.replace(id, valueName, operation.value);
+          }
+          break;
         default:
           break;
       }
@@ -72,7 +80,7 @@ class CorpusFileList extends RessourceList {
   }
 
   preprocessRessource(corpusFile) {
-    return {id: corpusFile.id, author: corpusFile.author, filename: corpusFile.filename, 'publishing-year': corpusFile.publishing_year, title: corpusFile.title};
+    return {id: corpusFile.id, author: corpusFile.author, filename: corpusFile.filename, publishing_year: corpusFile.publishing_year, title: corpusFile.title};
   }
 }
 CorpusFileList.options = {
@@ -80,12 +88,12 @@ CorpusFileList.options = {
            <td><span class="filename"></span></td>
            <td><span class="author"></span></td>
            <td><span class="title"></span></td>
-           <td><span class="publishing-year"></span></td>
+           <td><span class="publishing_year"></span></td>
            <td class="right-align">
              <a class="action-button btn-floating red tooltipped waves-effect waves-light" data-action="delete" data-position="top" data-tooltip="Delete"><i class="material-icons">delete</i></a>
              <a class="action-button btn-floating tooltipped waves-effect waves-light" data-action="download" data-position="top" data-tooltip="View"><i class="material-icons">file_download</i></a>
              <a class="action-button btn-floating tooltipped waves-effect waves-light" data-action="view" data-position="top" data-tooltip="View"><i class="material-icons">send</i></a>
            </td>
          </tr>`,
-  valueNames: [{data: ['id']}, 'author', 'filename', 'publishing-year', 'title']
+  valueNames: [{data: ['id']}, 'author', 'filename', 'publishing_year', 'title']
 };
diff --git a/web/app/static/js/nopaque/lists/CorpusList.js b/web/app/static/js/nopaque/lists/CorpusList.js
index e9fd392cb0a815c9665c5dd61b01d8e10b585de6..a343341130ad8f83ccff99b30475fd78a63ae871 100644
--- a/web/app/static/js/nopaque/lists/CorpusList.js
+++ b/web/app/static/js/nopaque/lists/CorpusList.js
@@ -36,7 +36,7 @@ class CorpusList extends RessourceList {
         deleteModal.open();
         break;
       case 'view':
-        window.location.href = this.corpora[corpusId].url;
+        if (corpusId !== '-1') {window.location.href = this.corpora[corpusId].url;}
         break;
       default:
         console.error(`Unknown action: ${action}`);
diff --git a/web/app/static/js/nopaque/lists/JobList.js b/web/app/static/js/nopaque/lists/JobList.js
index 52d308250d9eb2ec9a18ab8daee3ab54ca4da53d..b4cd84fffb3b120baf74c92232e302c785367445 100644
--- a/web/app/static/js/nopaque/lists/JobList.js
+++ b/web/app/static/js/nopaque/lists/JobList.js
@@ -30,7 +30,7 @@ class JobList extends RessourceList {
         deleteModal.open();
         break;
       case 'view':
-        window.location.href = this.user.data.jobs[jobId].url;
+        if (jobId !== '-1') {window.location.href = this.user.data.jobs[jobId].url;}
         break;
       default:
         console.error(`Unknown action: "${action}"`);
@@ -57,7 +57,7 @@ class JobList extends RessourceList {
           break;
         case 'replace':
           // Matches the only paths that should be handled here: /jobs/{jobId}/{service || status || description || title}
-          re = /^\/jobs\/(\d+)\/(status|description|title)$/;
+          re = /^\/jobs\/(\d+)\/(service|status|description|title)$/;
           if (re.test(operation.path)) {
             [match, id, valueName] = operation.path.match(re);
             this.replace(id, valueName, operation.value);
diff --git a/web/app/static/js/nopaque/lists/QueryResultList.js b/web/app/static/js/nopaque/lists/QueryResultList.js
index c8cf0771f6e7c08dd57e901df2bad8e51b6b49f8..98f3e7fbc22bd7f29208279397dc86a19ea599a1 100644
--- a/web/app/static/js/nopaque/lists/QueryResultList.js
+++ b/web/app/static/js/nopaque/lists/QueryResultList.js
@@ -2,6 +2,79 @@ class QueryResultList extends RessourceList {
   constructor(listElement, options = {}) {
     super(listElement, {...QueryResultList.options, ...options});
     this.user.eventListeners.queryResult.addEventListener((eventType, payload) => this.eventHandler(eventType, payload));
+    listElement.addEventListener('click', event => this.onclick(event));
+  }
+
+  onclick(event) {
+    let ressourceElement = event.target.closest('tr');
+    if (ressourceElement === null) {return;}
+    let queryResultId = ressourceElement.dataset.id;
+    let actionButtonElement = event.target.closest('.action-button');
+    let action = actionButtonElement === null ? 'view' : actionButtonElement.dataset.action;
+    switch (action) {
+      case 'delete':
+        let deleteModalHTML = `<div class="modal">
+                                 <div class="modal-content">
+                                   <h4>Confirm query result deletion</h4>
+                                   <p>Do you really want to delete the query result <b>${this.user.data.query_results[queryResultId].title}</b>? It will be permanently deleted!</p>
+                                 </div>
+                                 <div class="modal-footer">
+                                   <a href="#!" class="btn modal-close waves-effect waves-light">Cancel</a>
+                                   <a class="btn modal-close red waves-effect waves-light" href="${this.user.data.query_results[queryResultId].url}/delete"><i class="material-icons left">delete</i>Delete</a>
+                                 </div>
+                               </div>`;
+        let deleteModalParentElement = document.querySelector('main');
+        deleteModalParentElement.insertAdjacentHTML('beforeend', deleteModalHTML);
+        let deleteModalElement = deleteModalParentElement.lastChild;
+        let deleteModal = M.Modal.init(deleteModalElement, {onCloseEnd: () => {deleteModal.destroy(); deleteModalElement.remove();}});
+        deleteModal.open();
+        break;
+      case 'view':
+        if (queryResultId !== '-1') {window.location.href = this.user.data.query_results[queryResultId].url;}
+        break;
+      default:
+        console.error(`Unknown action: "${action}"`);
+        break;
+    }
+  }
+
+  patch(patch) {
+    let id, match, re, valueName;
+    for (let operation of patch) {
+      switch(operation.op) {
+        case 'add':
+          // Matches the only paths that should be handled here: /jobs/{jobId}
+          re = /^\/query_results\/(\d+)$/;
+          if (re.test(operation.path)) {this.add(operation.value);}
+          break;
+        case 'remove':
+          // See case add ;)
+          re = /^\/query_results\/(\d+)$/;
+          if (re.test(operation.path)) {
+            [match, id] = operation.path.match(re);
+            this.remove(id);
+          }
+          break;
+        case 'replace':
+          // Matches the only paths that should be handled here: /jobs/{jobId}/{service || status || description || title}
+          re = /^\/query_results\/(\d+)\/(corpus_title|description|query|title)$/;
+          if (re.test(operation.path)) {
+            [match, id, valueName] = operation.path.match(re);
+            this.replace(id, valueName, operation.value);
+          }
+          break;
+        default:
+          break;
+      }
+    }
+  }
+
+  preprocessRessource(queryResult) {
+    return {id: queryResult.id,
+            corpus_title: queryResult.corpus_title,
+            description: queryResult.description,
+            query: queryResult.query,
+            title: queryResult.title};
   }
 }
 QueryResultList.options = {
@@ -11,7 +84,6 @@ QueryResultList.options = {
            <td class="right-align">
              <a class="action-button btn-floating red tooltipped waves-effect waves-light" data-action="delete" data-position="top" data-tooltip="Delete"><i class="material-icons">delete</i></a>
              <a class="action-button btn-floating tooltipped waves-effect waves-light" data-action="view" data-position="top" data-tooltip="View"><i class="material-icons">send</i></a>
-             <a class="action-button btn-floating tooltipped waves-effect waves-light" data-action="analyse" data-position="top" data-tooltip="Analyse"><i class="material-icons">search</i></a>
            </td>
          </tr>`,
   valueNames: [{data: ['id']}, 'corpus_title', 'description', 'query', 'title']
diff --git a/web/app/static/js/nopaque/lists/RessourceList.js b/web/app/static/js/nopaque/lists/RessourceList.js
index 3aabfc9d7d319b04232f892aadaaa4533e3d5fdc..ec5afa695dd0d4c0d0645af037cb5cd19afd0b91 100644
--- a/web/app/static/js/nopaque/lists/RessourceList.js
+++ b/web/app/static/js/nopaque/lists/RessourceList.js
@@ -34,8 +34,8 @@ class RessourceList {
                                       </div>
                                     </div>
                                     <div class="col s9 m6 xl5">
-                                      <span class="card-title">Preparing data...</span>
-                                      <p>No ressource available (yet).</p>
+                                      <span class="card-title">Waiting for data...</span>
+                                      <p>This list is not initialized yet.</p>
                                     </div>
                                   </td>
                                 </tr>`;
@@ -59,6 +59,13 @@ class RessourceList {
     this.list.clear();
     this.add(Object.values(ressources));
     this.list.sort('id', {order: 'desc'});
+    let emptyListElementHTML = `<tr class="show-if-only-child" data-id="-1">
+                                  <td colspan="100%">
+                                    <span class="card-title"><i class="left material-icons" style="font-size: inherit;">file_download</i>Nothing here...</span>
+                                    <p>No ressource available.</p>
+                                  </td>
+                                </tr>`;
+    this.list.list.insertAdjacentHTML('afterbegin', emptyListElementHTML);
   }
 
   patch(patch) {
diff --git a/web/app/static/js/nopaque/main.js b/web/app/static/js/nopaque/main.js
index 1bf3561c7c348c4cac82882ded27e836c3a8a094..c8f886bec370470c5f5d9906e3599ba059ab5547 100644
--- a/web/app/static/js/nopaque/main.js
+++ b/web/app/static/js/nopaque/main.js
@@ -42,41 +42,32 @@ class User {
   init(data) {
     this.data = data;
 
-    if (Object.keys(this.data.corpora).length > 0) {
-      //for (listener of this.eventListeners.corporaInit) {listener(this.data.corpora);}
-      for (let [corpusId, eventListeners] of Object.entries(this.eventListeners.corpus)) {
-        if (corpusId === '*') {
-          for (let eventListener of eventListeners) {eventListener('init', this.data.corpora);}
-        } else {
-          if (corpusId in this.data.corpora) {
-            for (let eventListener of eventListeners) {eventListener('init', this.data.corpora[corpusId]);}
-          }
+    for (let [corpusId, eventListeners] of Object.entries(this.eventListeners.corpus)) {
+      if (corpusId === '*') {
+        for (let eventListener of eventListeners) {eventListener('init', this.data.corpora);}
+      } else {
+        if (corpusId in this.data.corpora) {
+          for (let eventListener of eventListeners) {eventListener('init', this.data.corpora[corpusId]);}
         }
       }
     }
 
-    if (Object.keys(this.data.jobs).length > 0) {
-      //for (listener of this.eventListeners.jobsInit) {listener(this.data.jobs);}
-      for (let [jobId, eventListeners] of Object.entries(this.eventListeners.job)) {
-        if (jobId === '*') {
-          for (let eventListener of eventListeners) {eventListener('init', this.data.jobs);}
-        } else {
-          if (jobId in this.data.jobs) {
-            for (let eventListener of eventListeners) {eventListener('init', this.data.jobs[jobId]);}
-          }
+    for (let [jobId, eventListeners] of Object.entries(this.eventListeners.job)) {
+      if (jobId === '*') {
+        for (let eventListener of eventListeners) {eventListener('init', this.data.jobs);}
+      } else {
+        if (jobId in this.data.jobs) {
+          for (let eventListener of eventListeners) {eventListener('init', this.data.jobs[jobId]);}
         }
       }
     }
 
-    if (Object.keys(this.data.query_results).length > 0) {
-      //for (listener of this.eventListeners.queryResultsInit) {listener(this.data.query_results);}
-      for (let [queryResultId, eventListeners] of Object.entries(this.eventListeners.queryResult)) {
-        if (queryResultId === '*') {
-          for (let eventListener of eventListeners) {eventListener('init', this.data.query_results);}
-        } else {
-          if (queryResultId in this.data.query_results) {
-            for (let eventListener of eventListeners) {eventListener('init', this.data.query_results[queryResultId]);}
-          }
+    for (let [queryResultId, eventListeners] of Object.entries(this.eventListeners.queryResult)) {
+      if (queryResultId === '*') {
+        for (let eventListener of eventListeners) {eventListener('init', this.data.query_results);}
+      } else {
+        if (queryResultId in this.data.query_results) {
+          for (let eventListener of eventListeners) {eventListener('init', this.data.query_results[queryResultId]);}
         }
       }
     }