changeset 335:0718a9ef6cd5

Tracker items list + bug fixes
author Sylvain Beucler <beuc@beuc.net>
date Sun, 22 Aug 2010 23:10:40 +0200
parents 70f5630b1e1e
children caf040382bee
files savane/tracker/models.py savane/tracker/urls.py savane/tracker/views.py templates/base.html templates/tracker/item_form.html templates/tracker/item_list.html
diffstat 6 files changed, 80 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- a/savane/tracker/models.py
+++ b/savane/tracker/models.py
@@ -220,12 +220,13 @@
             field_definition['display_size'] = self.display_size
             print field_definition['name'], field_definition['display_size']
             # Make it easier to access the field from templates:
-            if field_definition['display_type'] == 'TF':
-                field_definition['input_size'] = field_definition['display_size'].split("/")[0]
-                field_definition['input_maxlength'] = field_definition['display_size'].split("/")[1]
-            else:
-                field_definition['textarea_cols'] = field_definition['display_size'].split("/")[0]
-                field_definition['textarea_rows'] = field_definition['display_size'].split("/")[1]
+            if field_definition['display_size'] is not None:  # some old data may have weird values
+                if field_definition['display_type'] == 'TF':
+                    field_definition['input_size'] = field_definition['display_size'].split("/")[0]
+                    field_definition['input_maxlength'] = field_definition['display_size'].split("/")[1]
+                else:
+                    field_definition['textarea_cols'] = field_definition['display_size'].split("/")[0]
+                    field_definition['textarea_rows'] = field_definition['display_size'].split("/")[1]
         if self.group_id is None or field_definition['special'] != 1:
             field_definition['keep_history'] = self.keep_history
         if self.group_id is None or field_definition['custom'] == 1:
@@ -305,7 +306,7 @@
             for v in values:
                 if v['value_id'] == o['value_id']:
                     found = True
-                    if v['status'] == 'H':
+                    if o['status'] == 'H':
                         del values[i]
                         i -= 1
                     else:
@@ -314,7 +315,7 @@
                     break
                 i += 1
             if not found and o['status'] != 'H' and field_def['scope'] != 'S':
-                v.append(o)
+                values.append(o)
         values.sort(key=lambda x: x['rank'])
 
     # Try to apply a translation:
@@ -541,11 +542,7 @@
             # it out!
             return None
         elif key in ('submitted_by', 'assigned_to'):
-            user = getattr(self, key)
-            if user is None:
-                return None
-            else:
-                return user.pk
+            return getattr(self, key+'_id')
         else:
             return getattr(self, key)
 
@@ -600,6 +597,10 @@
         #return mark_safe(''.join(['%s (%d)<br />' % (f, v['rank']) for f,v in form_fields]))
         return mark_safe(html)
 
+    @models.permalink
+    def get_absolute_url(self):
+        return ('savane:tracker:item_detail', [self.tracker_id, self.get_public_id()])
+
     def __unicode__(self):
         return "%s #%d" % (self.tracker_id, self.get_public_id())
 
--- a/savane/tracker/urls.py
+++ b/savane/tracker/urls.py
@@ -17,18 +17,23 @@
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 from django.conf.urls.defaults import *
-import views
 from django.utils.translation import ugettext, ugettext_lazy as _
-from django.views.generic.list_detail import object_detail
+from django.views.generic.list_detail import object_detail, object_list
 from django.views.generic.create_update import create_object, update_object
 from django.contrib.auth.decorators import login_required
 from savane.utils import get_site_name
 from savane.perms import only_project_admin
 from savane.django_utils import decorated_patterns
+import views
+import models as tracker_models
 
 urlpatterns = patterns ('',)
 
 urlpatterns += patterns ('',
+  url(r'^(?P<tracker>[-\w]+)/$', views.item_list,
+      { 'paginate_by': 50,
+        'extra_context' : { 'title' : _("Bugs") }, },
+      name='item_list'),
   url(r'^(?P<tracker>[-\w]+)/(?P<object_id>\d+)/$', views.item_detail,
       {},
       name='item_detail'),
--- a/savane/tracker/views.py
+++ b/savane/tracker/views.py
@@ -21,10 +21,16 @@
 from django.core.urlresolvers import reverse
 from django.utils.translation import ugettext as _, ungettext
 import django.contrib.auth.models as auth_models
+from django.views.generic.list_detail import object_detail, object_list
 import savane.tracker.models as tracker_models
 from annoying.decorators import render_to
 from savane.middleware.exception import HttpAppException
 
+def item_list(request, tracker, extra_context={}, paginate_by=None):
+    queryset = tracker_models.Item.objects.filter(tracker=tracker).order_by('-public_%s' % tracker)
+    return object_list(request, queryset=queryset, extra_context=extra_context,
+                       paginate_by=paginate_by)
+
 @render_to('tracker/item_form.html', mimetype=None)
 def item_detail(request, tracker, object_id, extra_context={}):
     if tracker not in [k for (k,v) in tracker_models.Tracker.NAME_CHOICES]:
@@ -33,6 +39,11 @@
     kwargs = {'public_%s' % tracker : object_id}
     item = get_object_or_404(tracker_models.Item, **kwargs)
 
+    if item.privacy == 1:
+        # Allowed: members with 'private items' privs
+        if not request.user.is_superuser:
+            raise HttpAppException(_("Access denied") + _(": ") + _("private item"))
+
     context = {
         'object' : item,
         }
--- a/templates/base.html
+++ b/templates/base.html
@@ -53,6 +53,9 @@
       <li class="menuitem"><a href="{% url savane:svmain:group_list %}">{% trans "Projects" %}</a></li>
       <li class="menuitem"><a href="{% url savane:svpeople:index %}">{% trans "Contributors wanted" %}</a></li>
 
+      <li class="menutitle">{% trans "Trackers" %}</li>
+      <li class="menuitem"><a href="{% url savane:tracker:item_list 'bugs' %}">{% trans "Bugs" %}</a></li>
+
       <li class="menutitle">{% trans "Site help" %}</li>
       <li class="menuitem"><a href="{% url savane:svmain:contact %}">{% trans "Contact us" %}</a></li>
       <!-- /sitemenu -->
--- a/templates/tracker/item_form.html
+++ b/templates/tracker/item_form.html
@@ -27,10 +27,14 @@
 <tr>
   <th>{% trans "Submitted by" %}{% trans ": " %}</th>
   <td>
-    {% if object.submitted_by %}
-    <a href="{% url savane:svmain:user_detail object.submitted_by.username %}"
-    >{{object.submitted_by.get_full_name}}
-      &lt;{{object.submitted_by.username}}&gt;</a>
+    {% if object.submitted_by_id %}
+      {% if object.submitted_by %}
+      <a href="{% url savane:svmain:user_detail object.submitted_by.username %}"
+      >{{object.submitted_by.get_full_name}}
+        &lt;{{object.submitted_by.username}}&gt;</a>
+      {% else %}
+        <strong>{% trans "Invalid user ID" %}</strong>
+      {% endif %}
     {% else %}
     {% trans "Anonymous" %}
     {% endif %}
@@ -41,7 +45,7 @@
 </tr>
 <tr>
   <th>{% trans "Submitted on" %}{% trans ": " %}</th>
-  <td>{{ object.date }}</td>
+  <td width="35%">{{ object.date }}</td>
   <td colspan="2" class="button"><input type="submit" value="{% trans "Submit changes and return to this item" %}" /></td>
 </tr>
 <tr><td colspan="4" style="height: 15px;"></td></tr>
new file mode 100644
--- /dev/null
+++ b/templates/tracker/item_list.html
@@ -0,0 +1,36 @@
+{% extends "base.html" %}
+{% load i18n %}
+
+{% block icon %}bug{% endblock %}
+
+{% block content %}
+
+{% include "svmain/pagination.inc.html" %}
+
+<form action="." method="get">
+  {% trans "Search" %}: <input type="text" name="q" value="TODO {{q}}" />
+</form>
+
+{% if object_list %}
+  <table class="box">
+    <tr><th>{% trans "Id" %}</th><th>{% trans "Summary" %}</th></tr>
+    {% for object in object_list %}
+    <tr class="{% cycle 'boxitem' 'boxitemalt' %}">
+      <td><a href="{{ object.get_absolute_url }}">{{ object.get_public_id }}</a></td>
+      <td><a href="{{ object.get_absolute_url }}">{{ object.get_summary }}</a></td>
+    </tr>
+    {% endfor %}
+  </table>
+{% else %}
+    <p>{% trans "No users." %}</p>
+{% endif %}
+
+{% endblock %}
+
+{% comment %}
+Local Variables: **
+mode: django-html **
+tab-width: 4 **
+indent-tabs-mode: nil **
+End: **
+{% endcomment %}