changeset 2634:4cc1d15c203c

Added tags filter option
author Saurabh Kathpalia <saurabh.kathpalia95@gmail.com>
date Thu, 26 Jun 2014 13:34:13 +0530
parents 647ee04f863e
children d98612551045
files MoinMoin/apps/frontend/views.py MoinMoin/items/ticket.py MoinMoin/static/js/tickets.js MoinMoin/templates/tickets.html MoinMoin/themes/basic/static/css/basic.css MoinMoin/themes/basic/static/custom-less/basic.less
diffstat 6 files changed, 84 insertions(+), 49 deletions(-) [+]
line wrap: on
line diff
--- a/MoinMoin/apps/frontend/views.py	Fri Jun 20 15:52:42 2014 +0530
+++ b/MoinMoin/apps/frontend/views.py	Thu Jun 26 13:34:13 2014 +0530
@@ -20,6 +20,7 @@
 import time
 import mimetypes
 import json
+from itertools import chain
 from datetime import datetime
 from collections import namedtuple
 from functools import wraps, partial
@@ -2215,18 +2216,25 @@
     terms = [Term(ITEMTYPE, ITEMTYPE_TICKET)]
     if query:
         terms.append(qp.parse(query))
+
     if status == u'open':
         terms.append(Term(CLOSED, False))
     elif status == u'closed':
         terms.append(Term(CLOSED, True))
+
+    selected_tags = set(request.args.getlist(u'selected_tags'))
+    terms.extend(Term(TAGS, tag) for tag in selected_tags)
     q = And(terms)
 
     with flaskg.storage.indexer.ix[LATEST_REVS].searcher() as searcher:
         results = searcher.search(q, limit=None)
+        tags = set(chain.from_iterable(r[TAGS] for r in results))
         return render_template('tickets.html',
                                results=results,
                                query=query,
                                status=status,
+                               tags=tags,
+                               selected_tags=selected_tags,
         )
 
 
--- a/MoinMoin/items/ticket.py	Fri Jun 20 15:52:42 2014 +0530
+++ b/MoinMoin/items/ticket.py	Thu Jun 26 13:34:13 2014 +0530
@@ -34,7 +34,7 @@
 USER_QUERY = Term(CONTENTTYPE, CONTENTTYPE_USER)
 TICKET_QUERY = Term(ITEMTYPE, ITEMTYPE_TICKET)
 
-Rating = SmallNatural.using(optional=False).with_properties(lower=1, upper=5)
+Rating = SmallNatural.using(optional=True).with_properties(lower=1, upper=5)
 
 
 def get_itemid_short_summary(rev):
--- a/MoinMoin/static/js/tickets.js	Fri Jun 20 15:52:42 2014 +0530
+++ b/MoinMoin/static/js/tickets.js	Thu Jun 26 13:34:13 2014 +0530
@@ -1,41 +1,15 @@
 $(document).ready(function(){
 
-    // adds filter option in /+tickets view
-    // User can click on on any td element in the table to filter according to the value in that
-    function filter(selected_column) {
-        return function () {
-            var table = document.getElementById('ticket-list');
-            var cols = table.rows[0].cells.length;
-            var columns = table.getElementsByTagName("td");
-            var rows = table.getElementsByTagName("tr");
-            var selected_row = parseInt(selected_column/cols) + 1;
-            selected_column = selected_column%cols;
-            var data_to_filter = table.rows[selected_row].cells[selected_column].innerHTML;
-            var len = columns.length;
-
-            for ( var i = len-1; i >= 0; i-- ) {
-                if( i%cols == selected_column ) {
-                    var row = parseInt(i/cols) + 1;
-                    var data = table.rows[row].cells[selected_column].innerHTML;
-                    if( data != data_to_filter ) {
-                        rows[row].remove();
-                        i = i - selected_column;
-                    }
-                }
-            }
-        };
+    $("table").tablesorter({
+    widgets: ["resizable"],
+    widgetOptions : {
+        // css class name applied to the sticky header
+        resizable : false
+    },
+    headers: {
+        // remove sorting option for tags column
+        7: { sorter: false }
     }
-
-    var table = document.getElementById('ticket-list');
-    var cols = table.rows[0].cells.length;
-    var columns = table.getElementsByTagName("td");
-    for (var  i = 0; i < columns.length; i++ ) {
-    // listener not required for Summary and Itemid columns
-        if ( i%cols != 0 && i%cols != 1 ) {
-            columns[i].onclick = filter(i);
-        }
-    }
-
-    $("#ticket-list").tablesorter();
+  });
 
 });
--- a/MoinMoin/templates/tickets.html	Fri Jun 20 15:52:42 2014 +0530
+++ b/MoinMoin/templates/tickets.html	Thu Jun 26 13:34:13 2014 +0530
@@ -49,23 +49,23 @@
                 </a>
             <td>
                 <a href="{{  url_for_item(result['itemid'], field='itemid', namespace=result['namespace'])}}" title="{{ _('ITEMID: %(itemid)s', itemid=result['itemid'])}}">
-                    {{ result['summary'][:50] }}
+                    {{ result['summary'] }}
                 </a>
             </td>
-            <td title="{{ _('Filter by status: %(status)s', status='Closed' if result['closed'] else 'Open') }}">
+            <td>
                 {{ _("Closed") if result['closed'] else _("Open") }}
             </td>
-            <td title="{{ _('Filter by effort: %(effort)d', effort=result['effort']) }}">
-                {{ result['effort'] }}
+            <td>
+                {{ result.get('effort', '') }}
             </td>
-            <td title="{{ _('Filter by difficulty: %(difficulty)d', difficulty=result['difficulty']) }}">
-                {{ result['difficulty'] }}
+            <td>
+                {{ result.get('difficulty', '') }}
             </td>
-            <td title="{{ _('Filter by severity: %(severity)d', severity=result['severity']) }}">
-                {{ result['severity'] }}
+            <td>
+                {{ result.get('severity', '') }}
             </td>
-            <td title="{{ _('Filter by priority: %(priority)d', priority=result['priority']) }}">
-                {{ result['priority'] }}
+            <td>
+                {{ result.get('priority', '') }}
             </td>
             <td>
                 {% for tag in result['tags'] %}
@@ -76,6 +76,21 @@
     {% endfor %}
     </tbody>
     </table>
+    <h3>{{_("Tags")}}</h3>
+    {% for tag in tags %}
+        {# If user clicks on the tag then it gets selected if it is not already selected #}
+        {# If that tag is already selected then it gets deselected #}
+        {% set selected_tags_value = list(selected_tags.difference([tag]) if tag in selected_tags else selected_tags.union([tag])) %}
+        <form action="{{ url_for('frontend.tickets', selected_tags=selected_tags_value) }}" method="post">
+            <input type="hidden" name="q" value="{{ query if query }}" >
+            <input type="hidden" name="status" value="{{ status }}">
+            <input type="submit" value="{{ tag }}" class="{{ 'ticket-tags-button btn btn-primary active' if tag in selected_tags else 'ticket-tags-button btn btn-default' }}">
+        </form>
+    {% endfor %}
+
+    <p id="ticket-table-tip">
+        {{_("Tip: Sort multiple columns simultaneously by holding down the Shift key and clicking a second, third or even fourth column header!")}}
+    </p>
 {% else %}
     {{ _("No Ticket found.") }}
 {% endif %}
--- a/MoinMoin/themes/basic/static/css/basic.css	Fri Jun 20 15:52:42 2014 +0530
+++ b/MoinMoin/themes/basic/static/css/basic.css	Thu Jun 26 13:34:13 2014 +0530
@@ -6362,6 +6362,7 @@
 #ticket-list tr td,
 #ticket-list thead th {
   cursor: pointer;
+  padding-left: 20px;
 }
 #ticket-list tr td:first-child a {
   font-family: monospace;
@@ -6386,7 +6387,7 @@
 .tablesorter-header {
   background-image: url('../img/bg.png');
   background-repeat: no-repeat;
-  background-position: right center;
+  background-position: left center;
 }
 .tablesorter-headerAsc {
   background-image: url('../img/asc.png');
@@ -6394,3 +6395,21 @@
 .tablesorter-headerDesc {
   background-image: url('../img/desc.png');
 }
+.tablesorter-header.sorter-false {
+  background-image: None;
+}
+#ticket-summary {
+  width: 50%;
+}
+#ticket-list {
+  float: right;
+  width: 90%;
+}
+.ticket-tags-button {
+  padding: 4px;
+  width: 100px;
+}
+#ticket-table-tip {
+  float: right;
+  color: #999999;
+}
--- a/MoinMoin/themes/basic/static/custom-less/basic.less	Fri Jun 20 15:52:42 2014 +0530
+++ b/MoinMoin/themes/basic/static/custom-less/basic.less	Thu Jun 26 13:34:13 2014 +0530
@@ -335,6 +335,7 @@
 }
 #ticket-list tr td, #ticket-list thead th {
   cursor: pointer;
+  padding-left: 20px;
 }
 #ticket-list tr td:first-child a {
   font-family: monospace;
@@ -358,7 +359,7 @@
 .tablesorter-header {
   background-image: url('../img/bg.png');
   background-repeat: no-repeat;
-  background-position: right center;
+  background-position: left center;
 }
 .tablesorter-headerAsc {
   background-image: url('../img/asc.png');
@@ -366,3 +367,21 @@
 .tablesorter-headerDesc {
   background-image: url('../img/desc.png');
 }
+.tablesorter-header.sorter-false {
+  background-image: None;
+}
+#ticket-summary {
+  width: 50%;
+}
+#ticket-list {
+  float: right;
+  width: 90%;
+}
+.ticket-tags-button {
+  padding: 4px;
+  width: 100px;
+}
+#ticket-table-tip {
+  float: right;
+  color: #999999;
+}