Commits

xiaq committed 75e91cd

New TicketIndex itemtype, similar to Blog

Comments (0)

Files changed (2)

MoinMoin/items/ticket.py

 
 from flask import request, abort, redirect, url_for
 from flask import g as flaskg
+from flask import current_app as app
 
 from jinja2 import Markup
 
-from whoosh.query import Term
+from whoosh.query import Term, Prefix
 
 from MoinMoin.i18n import L_
 from MoinMoin.themes import render_template
 from MoinMoin.forms import (Form, OptionalText, OptionalMultilineText, SmallNatural, Tags,
                             Reference, BackReference, SelectSubmit)
 from MoinMoin.storage.middleware.protecting import AccessDenied
-from MoinMoin.constants.keys import ITEMTYPE, CONTENTTYPE, ITEMID, CURRENT, SUPERSEDED_BY, DEPENDS_ON, SUBSCRIBED_ITEMS
+from MoinMoin.constants.keys import ITEMTYPE, CONTENTTYPE, ITEMID, CURRENT, SUPERSEDED_BY, DEPENDS_ON, SUBSCRIBED_ITEMS, WIKINAME, NAME, NAME_EXACT
 from MoinMoin.constants.contenttypes import CONTENTTYPE_USER
-from MoinMoin.items import Item, Contentful, register, BaseModifyForm
+from MoinMoin.items import Item, Contentful, register, BaseModifyForm, Default, IndexEntry
 from MoinMoin.items.content import NonExistentContent
+from MoinMoin.schema.display import DisplayField
+from MoinMoin.constants.display_widgets import DISPLAY_PLAIN, DISPLAY_TAGS, DISPLAY_REFERENCE
 
 
 ITEMTYPE_TICKET = u'ticket'
     depends_on = OptionalTicketReference.using(label=L_("Depends On"))
 
 
+display_fields = [
+    DisplayField('summary', label=L_('Summary'), widget=DISPLAY_PLAIN),
+    DisplayField('effort', label=L_('Effort'), widget=DISPLAY_PLAIN),
+    DisplayField('difficulty', label=L_('Difficulty'), widget=DISPLAY_PLAIN),
+    DisplayField('severity', label=L_('Severity'), widget=DISPLAY_PLAIN),
+    DisplayField('priority', label=L_('Priority'), widget=DISPLAY_PLAIN),
+    DisplayField('tags', label=L_('Tags'), widget=DISPLAY_TAGS),
+    DisplayField('assigned_to', label=L_('Assigned To'), widget=DISPLAY_REFERENCE),
+    DisplayField('superseded_by', label=L_('Superseded By'), widget=DISPLAY_REFERENCE),
+    DisplayField('depends_on', label=L_('Depends On'), widget=DISPLAY_REFERENCE),
+]
+
+
 class TicketBackRefForm(Form):
     supersedes = BackReference.using(label=L_("Supersedes"))
     required_by = BackReference.using(label=L_("Required By"))
                                data_rendered=data_rendered,
                                form=form,
                               )
+
+
+ITEMTYPE_TICKET_INDEX = u'ticketindex'
+
+
+@register
+class TicketIndex(Default):
+    itemtype = ITEMTYPE_TICKET_INDEX
+    display_name = L_('Ticket Index')
+    description = L_('An index for all tickets under it')
+    show_template = 'ticket/index.html'
+
+    def do_show(self, revid):
+        prefix = self.subitems_prefix
+        prefixlen = len(prefix)
+        query = (Term(WIKINAME, app.cfg.interwikiname) &
+                 Term(ITEMTYPE, ITEMTYPE_TICKET) &
+                 Prefix(NAME_EXACT, prefix))
+        revs = flaskg.storage.search(query, limit=None)
+        tickets = []
+        for rev in revs:
+            fullname = rev.meta[NAME][0]
+            relname = fullname[prefixlen:]
+            tickets.append(IndexEntry(relname, fullname, rev.meta))
+        return render_template(self.show_template,
+                               item_name=self.name,
+                               data_rendered=Markup(self.content._render_data()),
+                               fields=display_fields,
+                               tickets=tickets
+                              )

MoinMoin/templates/ticket/index.html

+{% from "display_widgets.html" import render %}
+
+{% extends theme("layout.html") %}
+
+{% block content %}
+  {% if data_rendered %}
+    <div id="moin-content-data">
+      {{ data_rendered }}
+    </div>
+  {% endif %}
+
+  <table id="moin-index-table">
+    <thead>
+      <tr>
+        <th>
+          {{ _("Name") }}
+        </th>
+        {% for field in fields %}
+          <th>
+            {{ field.label }}
+          </th>
+        {% endfor %}
+      </tr>
+    </thead>
+
+    <tbody>
+      {% for e in tickets %}
+        <tr>
+          <td>
+            <a href="{{ url_for('.show_item', item_name=e.fullname) }}">
+              {{ e.relname }}
+            </a>
+          </td>
+          {% for field in fields %}
+            <td>
+              {{ render(e.meta[field.name], field.widget) }}
+            </td>
+          {% endfor %}
+        </tr>
+      {% else %}
+        <tr><td colspan="100"> {{ _("(No tickets yet)") }} </td></tr>
+      {% endfor %}
+    </tbody>
+  </table>
+{% endblock %}
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.