Commits

xiaq committed 7ae56d3

support close/reopen ticket

Comments (0)

Files changed (3)

MoinMoin/items/ticket.py

 from MoinMoin.i18n import L_
 from MoinMoin.themes import render_template
 from MoinMoin.forms import (Form, OptionalText, OptionalMultilineText, SmallNatural, Tags,
-                            Reference, BackReference)
+                            Reference, BackReference, SelectSubmit)
 from MoinMoin.storage.middleware.protecting import AccessDenied
 from MoinMoin.constants.keys import ITEMTYPE, CONTENTTYPE, ITEMID, CURRENT
 from MoinMoin.constants.contenttypes import CONTENTTYPE_USER
     meta = TicketMetaForm
     backrefs = TicketBackRefForm
     message = OptionalMultilineText.using(label=L_("Message")).with_properties(rows=8, cols=80)
-    submit_label = L_("Update ticket")
 
     def _load(self, item):
         meta = item.prepare_meta_for_modify(item.meta)
             self['backrefs']._load(item)
 
 
+class TicketSubmitForm(TicketForm):
+    submit_label = L_("Submit ticket")
+
+    def _dump(self, item):
+        # initial metadata for Ticket-itemtyped item
+        meta = {
+            ITEMTYPE: item.itemtype,
+            # XXX support other markups
+            CONTENTTYPE: 'text/x.moin.wiki;charset=utf-8',
+            'closed': False,
+        }
+        return meta, message_markup(self['message'].value)
+
+
+class TicketUpdateForm(TicketForm):
+    submit = SelectSubmit.valued('update', 'update_negate_status')
+
+    def _load(self, item):
+        super(TicketUpdateForm, self)._load(item)
+        self['submit'].properties['labels'] = {
+            'update': L_('Update ticket'),
+            'update_negate_status':
+                L_('Update & reopen ticket') if item.meta.get('closed') else
+                L_('Update & close ticket')
+        }
+
+    def _dump(self, item):
+        # Since the metadata form for tickets is an incomplete one, we load the
+        # original meta and update it with those from the metadata editor
+        meta = item.meta_filter(item.prepare_meta_for_modify(item.meta))
+        meta.update(self['meta'].value)
+        if self['submit'].value == 'update_negate_status':
+            meta['closed'] = not meta.get('closed')
+
+        data = item.content.data_storage_to_internal(item.content.data)
+        message = self['message'].value
+        if message:
+            data += message_markup(message)
+
+        return meta, data
+
+
 # XXX Ideally we should generate DOM instead of moin wiki source. But
 # currently this is not very useful, since
 # * DOM cannot be stored directly, it has to be converted to some markup first
 
     def do_modify(self):
         is_new = isinstance(self.content, NonExistentContent)
+        closed = self.meta.get('closed')
+
+        Form = TicketSubmitForm if is_new else TicketUpdateForm
 
         if request.method in ['GET', 'HEAD']:
-            form = TicketForm.from_item(self)
+            form = Form.from_item(self)
         elif request.method == 'POST':
-            form = TicketForm.from_request(request)
+            form = Form.from_request(request)
             if form.validate():
-                meta = form['meta'].value
-                meta.update({
-                    ITEMTYPE: self.itemtype,
-                    # XXX support other markups
-                    CONTENTTYPE: 'text/x.moin.wiki;charset=utf-8',
-                })
-
-                data = u'' if is_new else self.content.data_storage_to_internal(self.content.data)
-                message = form['message'].value
-                if message:
-                    data += message_markup(message)
-
+                meta, data = form._dump(self)
                 try:
                     self.modify(meta, data)
                 except AccessDenied:
                     abort(403)
                 else:
                     return redirect(url_for('.show_item', item_name=self.name))
-        if is_new:
-            # XXX suppress the "foo doesn't exist. Create it?" dummy content
-            data_rendered = None
-            form.submit_label = L_('Submit ticket')
-        else:
-            data_rendered = Markup(self.content._render_data())
+
+        # XXX When creating new item, suppress the "foo doesn't exist. Create it?" dummy content
+        data_rendered = None if is_new else Markup(self.content._render_data())
 
         return render_template(self.modify_template,
                                is_new=is_new,
+                               closed=closed,
                                item_name=self.name,
                                data_rendered=data_rendered,
                                form=form,

MoinMoin/storage/middleware/indexing.py

             'difficulty': NUMERIC(stored=True),
             'severity': NUMERIC(stored=True),
             'priority': NUMERIC(stored=True),
-            'status': ID(stored=True),
             'assigned_to': ID(stored=True),
             'superseded_by': ID(stored=True),
             'depends_on': ID(stored=True),
+            'closed': BOOLEAN(stored=True),
         }
         latest_revs_fields.update(**ticket_fields)
 

MoinMoin/templates/ticket.html

 {% endblock %}
 
 {% block content %}
-<h1>{{ title }}</h1>
+<h1>
+    {{ title }}
+    {% if closed %}
+        {# TODO style .moin-ticket-closed #}
+        <span class="moin-ticket-closed">{{ _("(Closed)") }}</span>
+    {% endif %}
+</h1>
 <div class="moin-form" id="moin-ticket-form">
     {{ gen.form.open(form, method='post', enctype='multipart/form-data') }}
 
         {{ forms.render(form['meta'][e]) }}
     {% endfor %}
     </dl>
-    {{ forms.render_submit(form) }}
+
+    {# see comments concerning the submit button within TicketForm in items/ticket.py #}
+    {% if is_new %}
+        {{ forms.render_submit(form) }}
+    {% else %}
+        {{ forms.render(form['submit']) }}
+    {% endif %}
 
     <h2>Back references</h2>
     <dl>
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.