Преглед изворни кода

[beeswax] Multiple Issues with Saved Queries page when it runs into multiple pages.

Converted search filter to use a server-side search query via GET for list_designs and list_trashed_designs views. Added tests. Incorporated FE form and filterInput events.
Jenny Kim пре 10 година
родитељ
комит
41474e3

+ 15 - 6
apps/beeswax/src/beeswax/templates/list_designs.mako

@@ -47,7 +47,9 @@ ${ layout.menubar(section='saved queries') }
     %>
     <%actionbar:render>
       <%def name="search()">
-        <input id="filterInput" type="text" class="input-xlarge search-query" placeholder="${_('Search for %s') % noun }">
+        <form id="searchQueryForm" action="${ url(app_name + ':list_designs') }" method="GET" class="inline">
+          <input id="filterInput" type="text" name="text" class="input-xlarge search-query" value="${ filter_params.get(prefix + 'text', '') }" placeholder="${_('Search for %s') % noun }" />
+        </form>
       </%def>
 
       <%def name="actions()">
@@ -178,11 +180,7 @@ ${ layout.menubar(section='saved queries') }
         "sEmptyTable":"${_('No data available')}",
         "sZeroRecords":"${_('No matching records')}",
       },
-      "bStateSave": true
-    });
-
-    $("#filterInput").keyup(function () {
-      savedQueries.fnFilter($(this).val());
+      "bStateSave": false
     });
 
     $(".selectAll").click(function () {
@@ -259,6 +257,17 @@ ${ layout.menubar(section='saved queries') }
     });
 
     $("a[data-row-selector='true']").jHueRowSelector();
+
+    var _searchInputValue = $("#filterInput").val();
+
+    $("#filterInput").jHueDelayedInput(function(){
+      if ($("#filterInput").val() != _searchInputValue){
+        $("#searchQueryForm").submit();
+      }
+    });
+
+    $("#filterInput").focus();
+    $("#filterInput").val(_searchInputValue); // set caret at the end of the field
   });
 </script>
 

+ 15 - 6
apps/beeswax/src/beeswax/templates/list_trashed_designs.mako

@@ -34,7 +34,9 @@ ${layout.menubar(section='saved queries')}
 
     <%actionbar:render>
       <%def name="search()">
-        <input id="filterInput" type="text" class="input-xlarge search-query" placeholder="${_('Search for query')}">
+        <form id="searchQueryForm" action="${ url(app_name + ':list_trashed_designs') }" method="GET" class="inline">
+          <input id="filterInput" type="text" name="text" class="input-xlarge search-query" value="${ filter_params.get(prefix + 'text', '') }" placeholder="${_('Search for query')}" />
+        </form>
       </%def>
 
       <%def name="actions()">
@@ -154,11 +156,7 @@ ${layout.menubar(section='saved queries')}
         "sEmptyTable":"${_('No data available')}",
         "sZeroRecords":"${_('No matching records')}",
       },
-      "bStateSave": true
-    });
-
-    $("#filterInput").keyup(function () {
-      savedQueries.fnFilter($(this).val());
+      "bStateSave": false
     });
 
     $(".selectAll").click(function () {
@@ -232,6 +230,17 @@ ${layout.menubar(section='saved queries')}
     });
 
     $("a[data-row-selector='true']").jHueRowSelector();
+
+    var _searchInputValue = $("#filterInput").val();
+
+    $("#filterInput").jHueDelayedInput(function(){
+      if ($("#filterInput").val() != _searchInputValue){
+        $("#searchQueryForm").submit();
+      }
+    });
+
+    $("#filterInput").focus();
+    $("#filterInput").val(_searchInputValue); // set caret at the end of the field
   });
 </script>
 

+ 30 - 0
apps/beeswax/src/beeswax/tests.py

@@ -2413,6 +2413,36 @@ class TestWithMockedServer(object):
       redaction.global_redaction_engine.policies = old_policies
 
 
+  def test_search_designs(self):
+    # Create 20 (DEFAULT_PAGE_SIZE) queries to fill page 1, plus a target query for page 2
+    page_1 = []
+    for i in xrange(1, 21):
+      response = _make_query(self.client, 'SELECT', submission_type='Save', name='My Name %d' % i, desc='My Description')
+      content = json.loads(response.content)
+      query_id = content['design_id']
+      page_1.append(query_id)
+
+    response = _make_query(self.client, 'SELECT', submission_type='Save', name='Test Search Design', desc='My Test Search Design')
+    content = json.loads(response.content)
+    query_id = content['design_id']
+    page_2 = [query_id]
+
+    resp = self.client.get(reverse('beeswax:list_designs') + '?text=Test+Search+Design')
+    ids_page = set([query.id for query in resp.context['page'].object_list])
+    assert_equal(0, sum([query_id in ids_page for query_id in page_1]))
+    assert_equal(1, sum([query_id in ids_page for query_id in page_2]))
+
+    # Trash all designs and test search trashed designs
+    ids = page_1 + page_2
+    self.client.post(reverse('beeswax:delete_design'), {u'skipTrash': [u'false'], u'designs_selection': ids})
+    SavedQuery.objects.filter(id__in=ids)
+
+    resp = self.client.get(reverse('beeswax:list_trashed_designs') + '?text=Test+Search+Design')
+    ids_page = set([query.id for query in resp.context['page'].object_list])
+    assert_equal(0, sum([query_id in ids_page for query_id in page_1]))
+    assert_equal(1, sum([query_id in ids_page for query_id in page_2]))
+
+
 class TestDesign():
 
   def test_hql_resource(self):

+ 13 - 2
apps/beeswax/src/beeswax/views.py

@@ -221,11 +221,17 @@ def list_designs(request):
   querydict_query = _copy_prefix(prefix, request.GET)
   # Manually limit up the user filter.
   querydict_query[ prefix + 'type' ] = app_name
+  # Get search filter input if any
+  search_filter = request.GET.get('text', None)
+  if search_filter is not None:
+    querydict_query[ prefix + 'text' ] = search_filter
+
   page, filter_params = _list_designs(request.user, querydict_query, DEFAULT_PAGE_SIZE, prefix)
 
   return render('list_designs.mako', request, {
     'page': page,
     'filter_params': filter_params,
+    'prefix': prefix,
     'user': request.user,
     'designs_json': json.dumps([query.id for query in page.object_list])
   })
@@ -242,17 +248,22 @@ def list_trashed_designs(request):
   querydict_query = _copy_prefix(prefix, request.GET)
   # Manually limit up the user filter.
   querydict_query[ prefix + 'type' ] = app_name
+  # Get search filter input if any
+  search_filter = request.GET.get('text', None)
+  if search_filter is not None:
+    querydict_query[ prefix + 'text' ] = search_filter
+
   page, filter_params = _list_designs(user, querydict_query, DEFAULT_PAGE_SIZE, prefix, is_trashed=True)
 
   return render('list_trashed_designs.mako', request, {
     'page': page,
     'filter_params': filter_params,
+    'prefix': prefix,
     'user': request.user,
     'designs_json': json.dumps([query.id for query in page.object_list])
   })
 
 
-
 def my_queries(request):
   """
   View a mix of history and saved queries.
@@ -840,7 +851,7 @@ def _list_designs(user, querydict, page_size, prefix="", is_trashed=False):
   page = paginator.page(pagenum)
 
   # We need to pass the parameters back to the template to generate links
-  keys_to_copy = [ prefix + key for key in ('user', 'type', 'sort') ]
+  keys_to_copy = [ prefix + key for key in ('user', 'type', 'sort', 'text') ]
   filter_params = copy_query_dict(querydict, keys_to_copy)
 
   return page, filter_params