Edgewall Software

Ticket #7145: 7145-conflicts-busy-r10688.patch

File 7145-conflicts-busy-r10688.patch, 9.5 KB (added by rblank, 13 months ago)

Highlight field conflicts and show busy indicator.

  • trac/htdocs/css/ticket.css

    diff --git a/trac/htdocs/css/ticket.css b/trac/htdocs/css/ticket.css
    a b div.comment ol { list-style: decimal } 
    123123 font-size: 100%; 
    124124 font-weight: normal; 
    125125} 
     126.trac-loading { 
     127  background: url(../loading.gif) 0 50% no-repeat; 
     128  margin: 0 1em; 
     129  padding-left: 20px; 
     130  display: none; 
     131} 
    126132.threading, #changelog .inlinebuttons { float: right; margin-left: 0.2em } 
    127133.threading { font-size: 85%; } 
    128134.threading :link, .threading :visited { border-bottom: 0 } 
    div.comment ol { list-style: decimal } 
    134140#changelog .trac-lastedit :link, #changelog .trac-lastedit :visited { color: inherit } 
    135141 
    136142#changelog .changes, #ticketchange .changes { list-style: square; margin-left: 2em; padding: 0 } 
     143.trac-conflict { border-left: .3em solid #e44; padding-left: .3em; } 
    137144#changelog .comment, #ticketchange .comment { margin-left: 2em } 
    138145 
    139146form .field { margin-top: .75em; width: 100% } 
  • trac/htdocs/js/auto_preview.js

    diff --git a/trac/htdocs/js/auto_preview.js b/trac/htdocs/js/auto_preview.js
    a b  
    1212  //  - `args`: additional form data to be passed with the XHR. 
    1313  //  - `update`: the function that is called with the submission reply. It 
    1414  //              is called with the request data and the reply. 
    15   $.fn.autoSubmit = function(args, update) { 
     15  //  - `busy`: an object or jQuery selector to be shown while requesting an 
     16  //            update. 
     17  $.fn.autoSubmit = function(args, update, busy) { 
    1618    if (this.length == 0 || auto_preview_timeout <= 0) 
    1719      return this; 
    1820    if (this[0].nodeName == 'FORM') { 
     
    4648        if (values_changed(new_values)) { 
    4749          values = new_values; 
    4850          updating = true; 
     51          if (busy != undefined) 
     52            $(busy).show(); 
    4953           
    5054          // Construct request data 
    5155          var data = values.slice(0); 
     
    6064                timer = setTimeout(request, timeout); 
    6165              updating = false; 
    6266              queued = false; 
     67              if (busy != undefined) 
     68                $(busy).hide(); 
    6369              update(data, reply); 
    6470            }, 
    6571            error: function(req, err, exc) { 
    6672              updating = false; 
    6773              queued = false; 
     74              if (busy != undefined) 
     75                $(busy).hide(); 
    6876            }, 
    6977          }); 
    7078        } 
  • trac/ticket/templates/ticket.html

    diff --git a/trac/ticket/templates/ticket.html b/trac/ticket/templates/ticket.html
    a b  
    6060          // Collapse property form if comment editor has focus 
    6161          if (show_preview && comment_focused) 
    6262            $("#modify").parent().addClass("collapsed"); 
    63         }); 
     63        }, "#ticketchange .trac-loading"); 
    6464        $("#trac-comment-editor").autoSubmit({preview_comment: '1'}, function(data, reply) { 
    6565          var comment = $("#trac-comment-editor").next("div.comment").html(reply); 
    6666          comment.toggle(comment.children().length != 0); 
    67         }); 
     67        }, "#changelog .trac-loading"); 
    6868        /*]]>*/ 
    6969        <py:if test="preview_mode"> 
    7070        $("#attachments").toggleClass("collapsed"); 
     
    7474      <py:otherwise> 
    7575        $("#propertyform").autoSubmit({preview: '1'}, function(data, reply) { 
    7676          $('#ticket').replaceWith(reply); 
    77         }); 
     77        }, "#ticket .trac-loading"); 
    7878        <py:if test="not preview_mode"> 
    7979        $("#field-summary").focus(); 
    8080        </py:if> 
     
    167167          <div id="trac-edit-warning" class="warning system-message" 
    168168               style="${'display: none' if start_time == ticket['changetime'] else None}"> 
    169169            This ticket has been modified since you started editing. You should review the 
    170             <em class="trac-new">other modifications</em> which have been appended above. 
     170            <em class="trac-new">other modifications</em> which have been appended above, 
     171            and any <em class="trac-conflict">conflicts</em> shown in the preview below. 
    171172            You can nevertheless proceed and submit your changes if you wish so. 
    172173          </div> 
    173174          <!--! Comment field --> 
     
    317318        <div py:if="ticket.exists and can_append" id="ticketchange" class="ticketdraft" 
    318319             style="${'display: none' if not (change_preview.fields or change_preview.comment) 
    319320                                         or cnum_edit is not None else None}"> 
    320           <xi:include href="ticket_change.html" py:with="change = change_preview"/> 
     321          <xi:include href="ticket_change.html" py:with="change = change_preview; preview = True"/> 
    321322        </div> 
    322323 
    323324        <!--! Author or Reporter --> 
  • trac/ticket/templates/ticket_box.html

    diff --git a/trac/ticket/templates/ticket_box.html b/trac/ticket/templates/ticket_box.html
    a b Arguments: 
    1818  <div class="date"> 
    1919    <p i18n:msg="created" py:if="ticket.exists">Opened ${pretty_dateinfo(ticket.time)}</p> 
    2020    <p i18n:msg="modified" py:if="ticket.changetime != ticket.time">Last modified ${pretty_dateinfo(ticket.changetime)}</p> 
    21     <p py:if="not ticket.exists"><i>(ticket not yet created)</i></p> 
     21    <p py:if="not ticket.exists"><span class="trac-loading"/><i>(ticket not yet created)</i></p> 
    2222  </div> 
    2323  <!--! use a placeholder if it's a new ticket --> 
    2424  <h2 class="summary searchable">$ticket.summary</h2> 
  • trac/ticket/templates/ticket_change.html

    diff --git a/trac/ticket/templates/ticket_change.html b/trac/ticket/templates/ticket_change.html
    a b Arguments: 
    99 - cnum_hist=None: the comment number for which to show a historical content 
    1010 - can_append=False: True if the user is allowed to append to tickets 
    1111 - has_edit_comment=False: True if the user is allowed to edit all comments 
     12 - preview=False: True if rendering a change preview 
    1213--> 
    1314<html xmlns="http://www.w3.org/1999/xhtml" 
    1415      xmlns:py="http://genshi.edgewall.org/" 
    Arguments: 
    1718      py:with="cnum = change.get('cnum'); hide_buttons = value_of('hide_buttons', False); 
    1819               cnum_edit = value_of('cnum_edit'); cnum_hist = value_of('cnum_hist'); 
    1920               can_append = value_of('can_append', False); has_edit_comment = value_of('has_edit_comment', False); 
     21               preview = value_of('preview', False); 
    2022               can_edit_comment = has_edit_comment or (authname and authname != 'anonymous' 
    2123                                                       and authname == change.author); 
    2224               show_editor = can_edit_comment and str(cnum) == cnum_edit; 
    Arguments: 
    5456        <i18n:msg params="author">Changed by ${authorinfo(change.author)}</i18n:msg> 
    5557      </py:otherwise> 
    5658    </py:choose> 
     59    <span py:if="preview or show_editor" class="trac-loading"/> 
    5760  </h3> 
    5861  <div py:if="show_buttons" class="trac-ticket-buttons"> 
    5962    <form py:if="'cnum' in change and can_edit_comment" method="get" action="#comment:${cnum}"> 
    Arguments: 
    7174    </form> 
    7275  </div> 
    7376  <ul py:if="change.fields" class="changes"> 
    74     <li py:for="field_name, field in sorted(change.fields.iteritems(), key=lambda item: item[1].label.lower())"> 
     77    <li py:for="field_name, field in sorted(change.fields.iteritems(), key=lambda item: item[1].label.lower())" 
     78        class="${'trac-conflict' if preview and field_name in conflicts else None}"> 
    7579      <strong>${field.label}</strong> 
    7680      <py:choose> 
    7781        <py:when test="field_name == 'attachment'"><i18n:msg params="name"> 
  • trac/ticket/templates/ticket_preview.html

    diff --git a/trac/ticket/templates/ticket_preview.html b/trac/ticket/templates/ticket_preview.html
    a b Render data relevant to automatic ticket 
    1818  </div> 
    1919  <input type="hidden" name="view_time" value="${to_utimestamp(ticket['changetime'])}"/> 
    2020  <div id="preview"><xi:include py:if="change_preview.fields or change_preview.comment" 
    21                                 href="ticket_change.html" py:with="change = change_preview"/></div> 
     21                                href="ticket_change.html" py:with="change = change_preview; preview = True"/></div> 
    2222</html> 
  • trac/ticket/web_ui.py

    diff --git a/trac/ticket/web_ui.py b/trac/ticket/web_ui.py
    a b class TicketModule(Component): 
    14801480        changes = [] 
    14811481        cnum = 0 
    14821482        skip = False 
     1483        start_time = data.get('start_time') 
     1484        conflicts = set() 
    14831485        for change in self.rendered_changelog_entries(req, ticket): 
    14841486            # change['permanent'] is false for attachment changes; true for 
    14851487            # other changes. 
    class TicketModule(Component): 
    15061508                            values[k] = v['new'] 
    15071509                    if 'description' in change['fields']: 
    15081510                        data['description_change'] = change 
     1511                if start_time is not None and change['date'] > start_time: 
     1512                    conflicts.update(change['fields']) 
    15091513            if not skip: 
    15101514                changes.append(change) 
    15111515 
    class TicketModule(Component): 
    15661570                data['%s_link' % user] = self._query_link(req, user, 
    15671571                                                            ticket[user]) 
    15681572        data.update({ 
    1569             'context': context, 
     1573            'context': context, 'conflicts': conflicts, 
    15701574            'fields': fields, 'changes': changes, 'replies': replies, 
    15711575            'attachments': AttachmentModule(self.env).attachment_data(context), 
    15721576            'action_controls': action_controls, 'action': selected_action,