Browse Source

Sort them users!

Rafał Pitoń 11 years ago
parent
commit
6d88e92468

+ 68 - 1
misago/admin/views/generic.py

@@ -1,6 +1,7 @@
 from django.contrib import messages
 from django.core.paginator import Paginator, EmptyPage
 from django.shortcuts import redirect
+from django.utils.translation import ugettext_lazy as _
 from django.views.generic import View
 from misago.core.exceptions import ExplicitFirstPage
 from misago.admin import site
@@ -47,18 +48,35 @@ class AdminView(View):
             messages.error(request, self.message_404)
             return redirect(self.root_link)
 
+    def current_link(self, request):
+        matched_url = request.resolver_match.url_name
+        return '%s:%s' % (request.resolver_match.namespace, matched_url)
+
     def render(self, request, context=None):
         context = context or {}
 
         context['root_link'] = self.root_link
+        context['current_link'] = self.current_link(request)
 
         return render(request, self.final_template(), context)
 
 
 class ItemsList(AdminView):
+    """
+    Admin items list view
+
+    Uses following attributes:
+
+    template = template name used to render items list
+    items_per_page = number of items displayed on single page
+                     (enter 0 or don't define for no pagination)
+    ordering = tuple of tuples defining allowed orderings
+               typles should follow this format: (name, order_by)
+    """
     template = 'list.html'
 
     items_per_page = 0
+    ordering = None
 
     def get_queryset(self):
         return self.get_model().objects.all()
@@ -79,16 +97,65 @@ class ItemsList(AdminView):
         context['page'] = context['paginator'].page(page)
         context['items'] = context['page'].object_list
 
-    def filter_items(self, request, context):
+    def set_filters(self, request):
         pass
 
+    def filter_items(self, request, context):
+        context['is_filtering'] = False
+
+    def ordering_session_key(self):
+        return 'misago_admin_%s_order_by' % self.root_link
+
+    def set_ordering(self, request, new_order):
+        for order in self.ordering:
+            if order[1] == new_order:
+                request.session[self.ordering_session_key()] = order[1]
+                return redirect(self.current_link(request))
+        else:
+            messages.error(request, _("New sorting method is incorrect."))
+            raise ValueError()
+
+    def order_items(self, request, context):
+        current_ordering = request.session.get(self.ordering_session_key())
+
+        for order in self.ordering:
+            order_as_dict = {
+                'name': order[0],
+                'order_by': order[1],
+                'type': 'desc' if order[1][0] == '-' else 'asc',
+            }
+
+            if order[1] == current_ordering:
+                context['order'] = order_as_dict
+                context['items'] = context['items'].order_by(
+                    order_as_dict['order_by'])
+            else:
+                context['order_by'].append(order_as_dict)
+
+        if not current_ordering:
+            current_ordering = context['order_by'].pop(0)
+            context['order'] = current_ordering
+            context['items'] = context['items'].order_by(
+                current_ordering['order_by'])
+
     def dispatch(self, request, *args, **kwargs):
         context = {
             'items': self.get_queryset(),
             'paginator': None,
             'page': None,
+            'order_by': [],
+            'order': None,
         }
 
+        if self.ordering:
+            if request.method == 'POST' and 'order_by' in request.POST:
+                try:
+                    return self.set_ordering(request,
+                                             request.POST.get('order_by'))
+                except ValueError:
+                    pass
+            self.order_items(request, context)
+
         if self.items_per_page:
             self.paginate_items(context, kwargs.get('page', 0))
 

+ 4 - 7
misago/static/misago/admin/css/misago/dropdowns.less

@@ -28,7 +28,7 @@
     button {
       background: none;
       border: none;
-      padding: 3px 20px;
+      padding: 3px 10px;
       width: 100%;
 
       color: @dropdown-link-color;
@@ -98,11 +98,14 @@
   .dropdown-menu {
     .dropdown-title {
       background-color: #ecf0f1;
+      border-bottom: 1px solid darken(#ecf0f1, 5%);
       border-radius: @border-radius-base @border-radius-base 0px 0px;
       margin-top: -5px;
       margin-bottom: 5px;
       padding: @padding-base-vertical @padding-base-horizontal;
 
+      font-weight: bold;
+
       .badge {
         background-color: darken(@brand-danger, 10%);
         border-radius: @border-radius-small;
@@ -119,12 +122,6 @@
       }
 
       button {
-        background: none;
-        border: none;
-        padding: 3px 20px;
-
-        color: @dropdown-link-color;
-        text-align: left;
         white-space: nowrap;
 
         &:hover {

+ 3 - 6
misago/static/misago/admin/css/style.css

@@ -5994,7 +5994,7 @@ body {
 .dropdown-menu li button {
   background: none;
   border: none;
-  padding: 3px 20px;
+  padding: 3px 10px;
   width: 100%;
   color: #5e5e5e;
   text-align: left;
@@ -6040,10 +6040,12 @@ body {
 @media (min-width: 768px) {
   .dropdown-menu .dropdown-title {
     background-color: #ecf0f1;
+    border-bottom: 1px solid #dde4e6;
     border-radius: 4px 4px 0px 0px;
     margin-top: -5px;
     margin-bottom: 5px;
     padding: 6px 12px;
+    font-weight: bold;
   }
   .dropdown-menu .dropdown-title .badge {
     background-color: #d62c1a;
@@ -6056,11 +6058,6 @@ body {
     white-space: nowrap;
   }
   .dropdown-menu > li button {
-    background: none;
-    border: none;
-    padding: 3px 20px;
-    color: #5e5e5e;
-    text-align: left;
     white-space: nowrap;
   }
   .dropdown-menu > li button:hover {

+ 24 - 0
misago/templates/misago/admin/generic/list.html

@@ -14,6 +14,30 @@
   {% include "misago/admin/generic/paginator.html" %}
   {% endif%}
 
+  {% if order_by %}
+  <div class="btn-group pull-left">
+    <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
+      {% trans "Sorting:"%} <span class="fa fa-sort-numeric-{{ order.type }}"></span> <strong>{{ order.name }}</strong>
+    </button>
+    <ul class="dropdown-menu" role="menu">
+      <li class="dropdown-title">
+        {% trans "Change sorting to:" %}
+      </li>
+      {% for order in order_by %}
+      <li>
+        <form method="post">
+          {% csrf_token %}
+          <button type="submit" name="order_by" value="{{ order.order_by }}">
+            <span class="fa fa-sort-numeric-{{ order.type }}"></span>
+            {{ order.name }}
+          </button>
+        </form>
+      </li>
+      {% endfor %}
+    </ul>
+  </div>
+  {% endif %}
+
 </div><!-- /.table-actions -->
 
 <div class="table-panel">

+ 7 - 0
misago/users/views/useradmin.py

@@ -1,4 +1,5 @@
 from django.contrib.auth import get_user_model
+from django.utils.translation import ugettext_lazy as _
 from misago.admin.views import generic
 
 
@@ -12,3 +13,9 @@ class UserAdmin(generic.AdminBaseMixin):
 
 class UsersList(UserAdmin, generic.ItemsList):
     items_per_page = 20
+    ordering = (
+        (_("Newest first"), '-joined_on'),
+        (_("Oldest first"), 'joined_on'),
+        (_("A to z"), 'username'),
+        (_("Z to a"), '-username'),
+        )