diff options
author | Magnus Hagander | 2013-07-19 14:39:57 +0000 |
---|---|---|
committer | Magnus Hagander | 2013-07-19 14:39:57 +0000 |
commit | 520992c4ab012ee26f4f302b7cc15331e61746ba (patch) | |
tree | 4011c3e9e608ded69d77505d3af41a66218e8c93 | |
parent | e71c90043dea5194ab1bbc82915d08cb8c7bcac5 (diff) |
Break out the thread browsing functionality and create a widget for it
Also, move the javascript to a shared javascript file
-rw-r--r-- | pgcommitfest/commitfest/static/commitfest/js/commitfest.js | 111 | ||||
-rw-r--r-- | pgcommitfest/commitfest/templates/base.html | 1 | ||||
-rw-r--r-- | pgcommitfest/commitfest/templates/base_form.html | 22 | ||||
-rw-r--r-- | pgcommitfest/commitfest/templates/patch.html | 138 | ||||
-rw-r--r-- | pgcommitfest/commitfest/templates/thread_attach.inc | 39 | ||||
-rw-r--r-- | pgcommitfest/commitfest/widgets.py | 8 |
6 files changed, 183 insertions, 136 deletions
diff --git a/pgcommitfest/commitfest/static/commitfest/js/commitfest.js b/pgcommitfest/commitfest/static/commitfest/js/commitfest.js new file mode 100644 index 0000000..8f84d8b --- /dev/null +++ b/pgcommitfest/commitfest/static/commitfest/js/commitfest.js @@ -0,0 +1,111 @@ +function verify_reject() { + return confirm('Are you sure you want to close this patch as Rejected?\n\nThis should only be done when a patch will never be applied - if more work is needed, it should instead be set to "Returned with Feedback".\n\nSo - are you sure?'); +} +function verify_returned() { + return confirm('Are you sure you want to close this patch as Returned with Feedback?\n\nThis means the patch will be marked as closed in this commitfest, but will automatically be moved to the next one. If no further work is expected on this patch, it should be closed with "Rejected" istead.\n\nSo - are you sure?'); +} +function verify_committed(is_committer) { + if (is_committer) + return confirm('Are you sure you want to close this patch as Committed?'); + else { + alert('Currently, only the committer who actually made the commit can do this. We should make a little prompt for the committer field otherwise..'); + return false; + } +} + +function findLatestThreads() { + $('#attachThreadListWrap').addClass('loading'); + $('#attachThreadSearchButton').addClass('disabled'); + $.get('/ajax/getThreads/', { + 's': $('#attachThreadSearchField').val(), + }).success(function(data) { + sel = $('#attachThreadList'); + sel.find('option').remove(); + $.each(data, function(m,i) { + sel.append('<option value="' + i.msgid + '">' + i.from + ': ' + i.subj + ' (' + i.date + ')</option>'); + }); + }).always(function() { + $('#attachThreadListWrap').removeClass('loading'); + $('#attachThreadSearchButton').removeClass('disabled'); + attachThreadChanged(); + }); + return false; +} + +function browseThreads(attachfunc) { + $('#attachThreadList').find('option').remove(); + $('#attachThreadMessageId').val(''); + $('#attachModal').modal(); + findLatestThreads(); + + $('#doAttachThreadButton').unbind('click'); + $('#doAttachThreadButton').click(function() { + msgid = $('#attachThreadMessageId').val(); + if (!msgid || msgid == '') { + msgid = $('#attachThreadList').val(); + if (!msgid) return; + } + + $('#attachThreadListWrap').addClass('loading'); + $('#attachThreadSearchButton').addClass('disabled'); + $('#attachThreadButton').addClass('disabled'); + if (attachfunc(msgid)) { + $('#attachModal').modal('hide'); + } + $('#attachThreadListWrap').removeClass('loading'); + $('#attachThreadSearchButton').removeClass('disabled'); + attachThreadChanged(); + }); + +} + +function attachThread(cfid, patchid) { + browseThreads(function(msgid) { + doAttachThread(cfid, patchid, msgid); + }); +} + +function detachThread(cfid, patchid, msgid) { + if (confirm('Are you sure you want to detach the thread with messageid "' + msgid + '" from this patch?')) { + $.post('/ajax/detachThread/', { + 'cf': cfid, + 'p': patchid, + 'msg': msgid, + }).success(function(data) { + location.reload(); + }).fail(function(data) { + alert('Failed to detach thread!'); + }); + } +} + +function attachThreadChanged() { + if ($('#attachThreadList').val() || $('#attachThreadMessageId').val()) { + $('#doAttachThreadButton').removeClass('disabled'); + } + else { + $('#doAttachThreadButton').addClass('disabled'); + } +} + +function doAttachThread(cfid, patchid, msgid) { + $.post('/ajax/attachThread/', { + 'cf': cfid, + 'p': patchid, + 'msg': msgid, + }).success(function(data) { + location.reload(); + return true; + }).fail(function(data) { + if (data.status == 404) { + alert('Message with messageid ' + msgid + ' not found'); + } + else if (data.status == 503) { + alert('Failed to attach thread: ' + data.responseText); + } + else { + alert('Failed to attach thread: ' + data.statusText); + } + return false; + }); +} diff --git a/pgcommitfest/commitfest/templates/base.html b/pgcommitfest/commitfest/templates/base.html index 644c975..4e94f13 100644 --- a/pgcommitfest/commitfest/templates/base.html +++ b/pgcommitfest/commitfest/templates/base.html @@ -43,5 +43,6 @@ li.selectable-deck-item .selectable-deck-remove { <script src="/https/git.postgresql.org/static/commitfest/js/bootstrap-collapse.js"></script> <script src="/https/git.postgresql.org/static/commitfest/js/jquery-ui.js"></script> <script type="text/javascript" src="/https/git.postgresql.org/static/selectable/js/jquery.dj.selectable.js"></script> +<script src="/https/git.postgresql.org/static/commitfest/js/commitfest.js"></script> {%block morescript%}{%endblock%} </html> diff --git a/pgcommitfest/commitfest/templates/base_form.html b/pgcommitfest/commitfest/templates/base_form.html index e204c34..f51bf76 100644 --- a/pgcommitfest/commitfest/templates/base_form.html +++ b/pgcommitfest/commitfest/templates/base_form.html @@ -45,4 +45,26 @@ div.control-group div.controls ul li label { </div> </form> +{%if threadbrowse %} +{%include "thread_attach.inc" %} +{%endif%} +{%endblock%} + +{%if threadbrowse %} +{%block morescript%} +<script> +$(document).ready(function() { + $('button.attachThreadButton').each(function (i,o) { + var b = $(o); + b.click(function() { + browseThreads(function(msgid) { + b.prev().val(msgid); + return true; + }); + return false; + }); + }); +}); +</script> {%endblock%} +{%endif%} diff --git a/pgcommitfest/commitfest/templates/patch.html b/pgcommitfest/commitfest/templates/patch.html index 26071b1..562d7e6 100644 --- a/pgcommitfest/commitfest/templates/patch.html +++ b/pgcommitfest/commitfest/templates/patch.html @@ -2,16 +2,6 @@ {%load commitfest%} {%block contents%} <style> -#attachThreadListWrap.loading { - display: block; - background: url('/https/git.postgresql.org/static/commitfest/spinner.gif') no-repeat center; - width: 124px; - height: 124px; - margin: 0 auto; -} -#attachThreadListWrap.loading * { - display: none; -} .close-nofloat { float: none !important; } @@ -66,7 +56,7 @@ <th>Emails</th> <td> {%if user.is_authenticated%} - <div style="float:right"><button class="btn" onclick="attachThread()">Attach thread</button></div> + <div style="float:right"><button class="btn" onclick="attachThread({{cf.id}},{{patch.id}})">Attach thread</button></div> {%else%} <div style="float:right"><button class="btn" onclick="location.href='/https/git.postgresql.org/login_and_redirect_back'">Attach thread</button></div> {%endif%} @@ -120,134 +110,10 @@ {%include "patch_commands.inc"%} -{%comment%}Modal dialog for attach thread{%endcomment%} -<div class="modal hide fade" id="attachModal" role="dialog" style="width:80%; left: 10%; margin-left:auto; margin-right: auto;"> - <div class="modal-header"> - <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> - <h3>Attach thread</h3> - </div> - <div class="modal-body"> - <form class="form-search" style="margin-bottom: 5px;"> - <div class="input-append"> - <input id="attachThreadSearchField" type="text" class="span2 search-query"> - <button id="attachThreadSearchButton" onclick="return findLatestThreads()" class="btn disabled">Search</button> - </div> - </form> - <div>Pick one of the recent emails from pgsql-hackers, or search above for subject or name:</div> - <div id="attachThreadListWrap"> - <select id="attachThreadList" size="6" style="width:100%;" onchange="attachThreadChanged()"> - </select> - </div> - <div>Or enter an <i>exact</i> message id:</div> - <input type="text" id="attachThreadMessageId" placeholder="Message id" class="input-block-level" onkeypress="attachThreadChanged()" onchange="attachThreadChanged()"> - </div> - <div class="modal-footer"> - <a href="#" class="btn" data-dismiss="modal">Close</a> - <a href="#" id="doAttachThreadButton" class="btn btn-primary disabled" onclick="doAttachThread({{cf.id}}, {{patch.id}})">Attach thread</a> - </div> -</div> +{%include "thread_attach.inc"%} {%endblock%} {%block morescript%} -<script language="javascript"> -/* XXX: Much of this should of course be in a shared .js file instead! */ -function verify_reject() { - return confirm('Are you sure you want to close this patch as Rejected?\n\nThis should only be done when a patch will never be applied - if more work is needed, it should instead be set to "Returned with Feedback".\n\nSo - are you sure?'); -} -function verify_returned() { - return confirm('Are you sure you want to close this patch as Returned with Feedback?\n\nThis means the patch will be marked as closed in this commitfest, but will automatically be moved to the next one. If no further work is expected on this patch, it should be closed with "Rejected" istead.\n\nSo - are you sure?'); -} -function verify_committed() { -{%if is_committer%} - return confirm('Are you sure you want to close this patch as Committed?'); -{%else%} - alert('Currently, only the committer who actually made the commit can do this. We should make a little prompt for the committer field otherwise..'); - return false; -{%endif%} -} - -function findLatestThreads() { - $('#attachThreadListWrap').addClass('loading'); - $('#attachThreadSearchButton').addClass('disabled'); - $.get('/ajax/getThreads/', { - 's': $('#attachThreadSearchField').val(), - }).success(function(data) { - sel = $('#attachThreadList'); - sel.find('option').remove(); - $.each(data, function(m,i) { - sel.append('<option value="' + i.msgid + '">' + i.from + ': ' + i.subj + ' (' + i.date + ')</option>'); - }); - }).always(function() { - $('#attachThreadListWrap').removeClass('loading'); - $('#attachThreadSearchButton').removeClass('disabled'); - attachThreadChanged(); - }); - return false; -} - -function attachThread() { - $('#attachThreadList').find('option').remove(); - $('#attachThreadMessageId').val(''); - $('#attachModal').modal(); - findLatestThreads(); -} - -function detachThread(cfid, patchid, msgid) { - if (confirm('Are you sure you want to detach the thread with messageid "' + msgid + '" from this patch?')) { - $.post('/ajax/detachThread/', { - 'cf': cfid, - 'p': patchid, - 'msg': msgid, - }).success(function(data) { - location.reload(); - }).fail(function(data) { - alert('Failed to detach thread!'); - }); - } -} - -function attachThreadChanged() { - if ($('#attachThreadList').val() || $('#attachThreadMessageId').val()) { - $('#doAttachThreadButton').removeClass('disabled'); - } - else { - $('#doAttachThreadButton').addClass('disabled'); - } -} - -function doAttachThread(cfid, patchid) { - v = $('#attachThreadMessageId').val(); - if (!v || v == '') { - v = $('#attachThreadList').val(); - if (!v) return; - } - - $('#attachThreadListWrap').addClass('loading'); - $('#attachThreadSearchButton').addClass('disabled'); - $('#attachThreadButton').addClass('disabled'); - - $.post('/ajax/attachThread/', { - 'cf': cfid, - 'p': patchid, - 'msg': $('#attachThreadList').val(), - }).success(function(data) { - location.reload(); - }).fail(function(data) { - if (data.status == 404) { - alert('Message with specified messageid not found'); - } - else if (data.status == 503) { - alert('Failed to attach thread: ' + data.responseText); - } - else { - alert('Failed to attach thread: ' + data.statusText); - } - $('#attachThreadListWrap').removeClass('loading'); - $('#attachThreadSearchButton').removeClass('disabled'); - attachThreadChanged(); - }); -} - /* Run on startup */ $(document).ready(function() { $('button.close-nofloat').each(function(i,o) { diff --git a/pgcommitfest/commitfest/templates/thread_attach.inc b/pgcommitfest/commitfest/templates/thread_attach.inc new file mode 100644 index 0000000..b3eb19a --- /dev/null +++ b/pgcommitfest/commitfest/templates/thread_attach.inc @@ -0,0 +1,39 @@ +{%comment%}Modal dialog for attach thread{%endcomment%} +<style> +#attachThreadListWrap.loading { + display: block; + background: url('/https/git.postgresql.org/static/commitfest/spinner.gif') no-repeat center; + width: 124px; + height: 124px; + margin: 0 auto; +} +#attachThreadListWrap.loading * { + display: none; +} +</style> + +<div class="modal hide fade" id="attachModal" role="dialog" style="width:80%; left: 10%; margin-left:auto; margin-right: auto;"> + <div class="modal-header"> + <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> + <h3>Attach thread</h3> + </div> + <div class="modal-body"> + <form class="form-search" style="margin-bottom: 5px;"> + <div class="input-append"> + <input id="attachThreadSearchField" type="text" class="span2 search-query"> + <button id="attachThreadSearchButton" onclick="return findLatestThreads()" class="btn disabled">Search</button> + </div> + </form> + <div>Pick one of the recent emails from pgsql-hackers, or search above for subject or name:</div> + <div id="attachThreadListWrap"> + <select id="attachThreadList" size="6" style="width:100%;" onchange="attachThreadChanged()"> + </select> + </div> + <div>Or enter an <i>exact</i> message id:</div> + <input type="text" id="attachThreadMessageId" placeholder="Message id" class="input-block-level" onkeypress="attachThreadChanged()" onchange="attachThreadChanged()"> + </div> + <div class="modal-footer"> + <a href="#" class="btn" data-dismiss="modal">Close</a> + <a href="#" id="doAttachThreadButton" class="btn btn-primary disabled">Attach thread</a> + </div> +</div> diff --git a/pgcommitfest/commitfest/widgets.py b/pgcommitfest/commitfest/widgets.py new file mode 100644 index 0000000..623643f --- /dev/null +++ b/pgcommitfest/commitfest/widgets.py @@ -0,0 +1,8 @@ +from django.forms import TextInput +from django.utils.safestring import mark_safe + +class ThreadPickWidget(TextInput): + def render(self, name, value, attrs=None): + html = super(ThreadPickWidget, self).render(name, value, attrs) + html = html + ' <button class="btn attachThreadButton" id="btn_%s">Find thread</button>' % name + return mark_safe(html) |