9d032dbf867d

Add signoff support to the web UI.
[view raw] [browse files]
author Steve Losh <steve@stevelosh.com>
date Sat, 01 May 2010 13:51:22 -0400
parents b8654f4e6386
children ebc5f7c7a6b7
branches/tags (none)
files review/api.py review/web_media/comments.js review/web_templates/changeset.html review/web_ui.py

Changes

--- a/review/api.py	Sat May 01 11:48:45 2010 -0400
+++ b/review/api.py	Sat May 01 13:51:22 2010 -0400
@@ -330,6 +330,12 @@
                 { 'message': 'Initialize review data for changeset %s' % self.node,
                   'addremove': True, })
     
+    def signoffs_for_user(self, username):
+        return filter(lambda s: s.author == username, self.signoffs)
+    
+    def signoffs_for_current_user(self):
+        return self.signoffs_for_user(self.ui.username())
+    
     def add_signoff(self, message, opinion='', force=False):
         """Add (and commit) a signoff for the given revision.
         
@@ -339,7 +345,7 @@
         will be raised unless the force argument is used.
         
         """
-        existing = filter(lambda s: s.author == self.ui.username(), self.signoffs)
+        existing = self.signoffs_for_current_user()
         
         if existing:
             if not force:
--- a/review/web_media/comments.js	Sat May 01 11:48:45 2010 -0400
+++ b/review/web_media/comments.js	Sat May 01 13:51:22 2010 -0400
@@ -9,6 +9,12 @@
         return false;
     });
     
+    $("p.signoff-activate a").click(function(event) {
+        $(event.target).hide();
+        $(event.target).closest("div").children("form").fadeIn("fast");
+        return false;
+    });
+    
     $("tr.rem.commentable,tr.add.commentable,tr.con.commentable").click(function(event) {
         $(event.target).closest("tr").addClass("comment-line-selected");
         var filename = $(event.target).closest("tr").find(".line-data").children(".filename").first().text();
--- a/review/web_templates/changeset.html	Sat May 01 11:48:45 2010 -0400
+++ b/review/web_templates/changeset.html	Sat May 01 13:51:22 2010 -0400
@@ -37,12 +37,12 @@
     <h2>Signoffs</h2>
     
     {% for signoff in rcset.signoffs %}
-        <div class="signoff {{ signoff.opinion }}">
+        <div class="signoff {{ signoff.opinion or 'neutral' }}">
             {{ macros.gravatar(signoff, utils) }}
             <div>
                 <div class="author">
                     <a href="mailto:${ email(signoff.author) }">{{ utils['templatefilters'].person(signoff.author) }}</a>
-                    signed off as <span class="opinion">{{ signoff.opinion }}</span> on this changeset, saying:
+                    signed off as <span class="opinion">{{ signoff.opinion or "neutral" }}</span> on this changeset, saying:
                 </div>
                 <div class="message">{{ signoff.message }}</div>
             </div>
@@ -51,7 +51,27 @@
     
     {% if not read_only %}
         <div id="signoff-review">
-            <p class="signoff-activate"><a href="#">Sign off on this changeset (currently unimplemented)</a></p>
+            <p class="signoff-activate">
+                {% if cu_signoff %}
+                    <a href="#">Change your signoff</a>
+                {% else %}
+                    <a href="#">Sign off on this changeset</a>
+                {% endif %}
+            </p>
+            <form id="signoff-review-form" method="post" action="">
+                <div class="field">
+                    <input type="radio" name="signoff" value="yes" {% if cu_signoff and cu_signoff.opinion == 'yes' %}checked{% endif %}/><span>Yes</span>
+                    <input type="radio" name="signoff" value="no" {% if cu_signoff and cu_signoff.opinion == 'no' %}checked{% endif %}/><span>No</span>
+                    <input type="radio" name="signoff" value="neutral" {% if cu_signoff and cu_signoff.opinion == '' %}checked{% endif %}/><span>Neutral</span>
+                </div>
+                <div class="field">
+                    <label for="body">Signoff message:</label>
+                    <textarea cols="60" rows="6" name="new-signoff-body">{% if cu_signoff %}{{ cu_signoff.message }}{% endif %}</textarea>
+                </div>
+                <div class="buttons">
+                    <input type="submit" class="button" value="Submit" />
+                </div>
+            </form>
         </div>
     {% endif %}
 
--- a/review/web_ui.py	Sat May 01 11:48:45 2010 -0400
+++ b/review/web_ui.py	Sat May 01 13:51:22 2010 -0400
@@ -73,12 +73,22 @@
         rev_id = args[0]
         
         if kwargs and not self.read_only:
+            signoff = kwargs.get('signoff', None)
+            if signoff:
+                if signoff not in ['yes', 'no', 'neutral']:
+                    return 'Invalid signoff type.'
+                if signoff == 'neutral':
+                    signoff = ''
+                body = kwargs.get('new-signoff-body', '')
+                rcset = self.datastore[rev_id]
+                rcset.add_signoff(body, signoff, force=True)
+                raise cherrypy.HTTPRedirect("/changeset/%s/" % rev_id)
+            
             filename = kwargs.get('filename', '')
             lines = str(kwargs['lines']) if 'lines' in kwargs else ''
             if lines:
                 lines = lines.split(',')
             body = kwargs['new-comment-body']
-            print filename, lines, body
             
             if body:
                 rcset = self.datastore[rev_id]
@@ -89,11 +99,15 @@
         rcset = self.datastore[rev_id]
         rev = rcset.target[rev_id]
         
+        cu_signoffs = rcset.signoffs_for_current_user()
+        cu_signoff = cu_signoffs[0] if cu_signoffs else None
+        print cu_signoff
+        
         return jinja_env.get_template('changeset.html').render(
             read_only=self.read_only,
             utils=utils, datastore=self.datastore,
             title='%s:%s' % (rev.rev(), short(rev.node())),
-            rcset=rcset, rev=rev,
+            rcset=rcset, rev=rev, cu_signoff=cu_signoff
         )