diff options
8 files changed, 356 insertions, 0 deletions
diff --git a/extensions/MozReview/Config.pm b/extensions/MozReview/Config.pm new file mode 100644 index 000000000..44d8dd2ff --- /dev/null +++ b/extensions/MozReview/Config.pm @@ -0,0 +1,15 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +package Bugzilla::Extension::MozReview; + +use 5.10.1; +use strict; + +use constant NAME => 'MozReview'; + +__PACKAGE__->NAME; diff --git a/extensions/MozReview/Extension.pm b/extensions/MozReview/Extension.pm new file mode 100644 index 000000000..2287a2136 --- /dev/null +++ b/extensions/MozReview/Extension.pm @@ -0,0 +1,58 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +package Bugzilla::Extension::MozReview; + +use 5.10.1; +use strict; +use parent qw(Bugzilla::Extension); + +use Bugzilla::Attachment; +use Bugzilla::Config::Common; + +our $VERSION = '0.01'; + +sub template_before_process { + my ($self, $args) = @_; + my $file = $args->{'file'}; + my $vars = $args->{'vars'}; + + return unless (($file eq 'bug/show-header.html.tmpl' || + $file eq 'bug/edit.html.tmpl') && + Bugzilla->params->{mozreview_base_url}); + + my $bug = exists $vars->{'bugs'} ? $vars->{'bugs'}[0] : $vars->{'bug'}; + + if ($bug) { + my @rrids; + my $attachments = Bugzilla::Attachment->get_attachments_by_bug($bug); + + foreach my $attachment (@$attachments) { + if ($attachment->contenttype eq 'text/x-review-board-request' && + !$attachment->isobsolete) { + push @rrids, ($attachment->data =~ m#/r/(\d+)/?$#); + } + } + + if (scalar @rrids) { + $vars->{'mozreview'} = 1; + $vars->{'review_request_ids'} = \@rrids; + } + } +} + +sub config_modify_panels { + my ($self, $args) = @_; + push @{ $args->{panels}->{advanced}->{params} }, { + name => 'mozreview_base_url', + type => 't', + default => '', + checker => \&check_urlbase + }; +} + +__PACKAGE__->NAME; diff --git a/extensions/MozReview/template/en/default/hook/admin/params/editparams-current_panel.html.tmpl b/extensions/MozReview/template/en/default/hook/admin/params/editparams-current_panel.html.tmpl new file mode 100644 index 000000000..f16aaddb8 --- /dev/null +++ b/extensions/MozReview/template/en/default/hook/admin/params/editparams-current_panel.html.tmpl @@ -0,0 +1,11 @@ +[%# This Source Code Form is subject to the terms of the Mozilla Public + # License, v. 2.0. If a copy of the MPL was not distributed with this + # file, You can obtain one at http://mozilla.org/MPL/2.0/. + # + # This Source Code Form is "Incompatible With Secondary Licenses", as + # defined by the Mozilla Public License, v. 2.0. + #%] + +[% IF panel.name == "advanced" %] + [% panel.param_descs.mozreview_base_url = 'MozReview Base URL' %] +[% END -%] diff --git a/extensions/MozReview/template/en/default/hook/bug/edit-after_bug_data.html.tmpl b/extensions/MozReview/template/en/default/hook/bug/edit-after_bug_data.html.tmpl new file mode 100644 index 000000000..a2afa0351 --- /dev/null +++ b/extensions/MozReview/template/en/default/hook/bug/edit-after_bug_data.html.tmpl @@ -0,0 +1,62 @@ +[%# This Source Code Form is subject to the terms of the Mozilla Public + # License, v. 2.0. If a copy of the MPL was not distributed with this + # file, You can obtain one at http://mozilla.org/MPL/2.0/. + # + # This Source Code Form is "Incompatible With Secondary Licenses", as + # defined by the Mozilla Public License, v. 2.0. + #%] + +[% USE Bugzilla %] +[% cgi = Bugzilla.cgi %] + +[% RETURN UNLESS mozreview %] + +<br> +<table + class="mozreview-table" + data-mozreview-url="[% Bugzilla.params.mozreview_base_url FILTER html %]"> + <thead> + <tr> + <th>MozReview Requests</th> + </tr> + </thead> + + <tbody> + <tr> + <td> + <table class="mozreview-requests"> + <thead> + <th>Commit</th> + <th>Status</th> + <th>Open Issues</th> + <th>Last Updated</th> + </thead> + [% FOREACH rrid IN review_request_ids %] + [%# rrid is guaranteed to be an integer %] + <tbody class="mozreview-request" + data-rrid="[% rrid FILTER none %]"> + <tr class="mozreview-loading-row"> + <td colspan="4">Loading...</td> + </tr> + <tr class="mozreview-loading-error-row bz_default_hidden"> + <td colspan="4">Error loading review + request <span class="mozreview-load-error-rrid"></span>: + <span class="mozreview-load-error-string"></span></td> + </tr> + </tbody> + [% END %] + </table> + </td> + </tr> + </tbody> + + <tfoot> + <tr class="mozreview-hide-discarded-row bz_default_hidden"> + <td class="mozreview-hide-discarded"> + <a class="mozreview-hide-discarded-link" + href="#"><span class="mozreview-discarded-action">Show</span> + discarded requests</a> + </td> + </tr> + </tfoot> +</table> diff --git a/extensions/MozReview/template/en/default/hook/bug/show-header-end.html.tmpl b/extensions/MozReview/template/en/default/hook/bug/show-header-end.html.tmpl new file mode 100644 index 000000000..995dd8868 --- /dev/null +++ b/extensions/MozReview/template/en/default/hook/bug/show-header-end.html.tmpl @@ -0,0 +1,12 @@ +[%# This Source Code Form is subject to the terms of the Mozilla Public + # License, v. 2.0. If a copy of the MPL was not distributed with this + # file, You can obtain one at http://mozilla.org/MPL/2.0/. + # + # This Source Code Form is "Incompatible With Secondary Licenses", as + # defined by the Mozilla Public License, v. 2.0. + #%] + +[% RETURN UNLESS mozreview %] + +[% style_urls.push('extensions/MozReview/web/style/mozreview.css') %] +[% javascript_urls.push('extensions/MozReview/web/js/mozreview.js') %] diff --git a/extensions/MozReview/web/js/mozreview.js b/extensions/MozReview/web/js/mozreview.js new file mode 100644 index 000000000..714863a74 --- /dev/null +++ b/extensions/MozReview/web/js/mozreview.js @@ -0,0 +1,141 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This Source Code Form is "Incompatible With Secondary Licenses", as + * defined by the Mozilla Public License, v. 2.0. + */ + +var MozReview = {}; + +MozReview.formatElapsedTime = function(s, val) { + val = Math.floor(val); + return val + ' ' + s + (val == 1 ? '' : 's') + ' ago'; +}; + +MozReview.elapsedTime = function(d) { + var ms = Date.now() - d; + + var seconds = ms / 1000; + if (seconds < 60) { + return MozReview.formatElapsedTime('second', seconds); + } + + var minutes = seconds / 60; + if (minutes < 60) { + return MozReview.formatElapsedTime('minute', minutes); + } + + var hours = minutes / 60; + if (hours < 24) { + return MozReview.formatElapsedTime('hour', hours); + } + + var days = hours / 24; + if (days < 30) { + return MozReview.formatElapsedTime("day", days); + } + + var months = days / 30; // enh fudge it + if (months < 12) { + return MozReview.formatElapsedTime("month", months); + } + + var years = months / 12; + return MozReview.formatElapsedTime("year", years); +}; + +MozReview.getReviewRequest = function() { + var hostUrl = $('.mozreview-table').data('mozreviewUrl'); + var tr = $('<tr/>'); + var td = $('<td/>'); + + var rrApiBaseUrl = hostUrl + + 'api/extensions/mozreview.extension.MozReviewExtension/summary/'; + var rrUiBaseUrl = hostUrl + 'r/'; + + function rrUrl(rrId) { + return rrUiBaseUrl + rrId + '/'; + } + + function rrRow(rr, isParent) { + var tdSummary = td.clone(); + var trCommit = tr.clone(); + var a = $('<a/>'); + + if (!isParent) { + tdSummary.addClass('mozreview-child-request-summary'); + } + + a.attr('href', rrUrl(rr.id)); + a.text(rr.summary); + tdSummary.append(a); + + if (isParent) { + tdSummary.append($('<span/>').text(' (' + rr.submitter + ')')); + } + + tdSummary.addClass('mozreview-summary'); + + trCommit.append( + tdSummary, + td.clone().text(rr.status), + td.clone().text(rr.issue_open_count) + .addClass('mozreview-open-issues'), + td.clone().text(MozReview.elapsedTime(new Date(rr.last_updated))) + ); + + if (rr.status == "discarded") { + $('.mozreview-hide-discarded-row').removeClass('bz_default_hidden'); + trCommit.addClass('bz_default_hidden mozreview-discarded-request'); + } + + return trCommit; + } + + $('.mozreview-hide-discarded-link').click(function() { + if ($('.bz_default_hidden.mozreview-discarded-request').length) { + $('.mozreview-discarded-request').removeClass('bz_default_hidden'); + $('.mozreview-discarded-action').text('Hide'); + } else { + $('.mozreview-discarded-request').addClass('bz_default_hidden'); + $('.mozreview-discarded-action').text('Show'); + } + return false; + }); + + $('.mozreview-request').each(function() { + var tbody = $(this); + var rrId = tbody.data('rrid'); + var url = rrApiBaseUrl + rrId + '/'; + var i; + + $.getJSON(url, function(data) { + var parent = data.parent; + tbody.append(rrRow(parent, true)); + for (i = 0; i < data.children.length; i++) { + tbody.append(rrRow(data.children[i], false)); + } + tbody.find('.mozreview-loading-row').addClass('bz_default_hidden'); + }).fail(function(jqXHR, textStatus, errorThrown) { + tbody.find('.mozreview-loading-row').addClass('bz_default_hidden'); + tbody.find('.mozreview-load-error-rrid').text(rrId); + var errRow = tbody.find('.mozreview-loading-error-row'); + var errStr; + if (jqXHR.responseJSON && jqXHR.responseJSON.err && + jqXHR.responseJSON.err.msg) { + errStr = jqXHR.responseJSON.err.msg; + } else if (errorThrown) { + errStr = errorThrown; + } else { + errStr = 'unknown'; + } + errRow.find('.mozreview-load-error-string').text(errStr); + errRow.removeClass('bz_default_hidden'); + }); + }); +}; + +$().ready(function() { + MozReview.getReviewRequest(); +}); diff --git a/extensions/MozReview/web/style/mozreview.css b/extensions/MozReview/web/style/mozreview.css new file mode 100644 index 000000000..5c021ea96 --- /dev/null +++ b/extensions/MozReview/web/style/mozreview.css @@ -0,0 +1,54 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This Source Code Form is "Incompatible With Secondary Licenses", as + * defined by the Mozilla Public License, v. 2.0. */ + +.mozreview-table { + background: #fff; + border: none; + border-collapse: collapse; + border-bottom: 1px solid rgba(0, 0, 0, 0.2); + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1); +} + +.mozreview-table th { + text-align: left; + padding: 4px; +} + +.mozreview-table td { + padding: 4px; +} + +.mozreview-table thead, .mozreview-table tfoot { + background-color: #eee; + color: #404040; +} + +.mozreview-requests { + background: #fff; + border: none; + border-collapse: collapse; +} + +.mozreview-requests th { + padding: 2px; +} + +.mozreview-requests td { + padding: 2px; +} + +.mozreview-requests .mozreview-summary { + text-align: left; +} + +.mozreview-requests .mozreview-open-issues { + text-align: center; +} + +.mozreview-child-request-summary { + text-indent: 1em; +} diff --git a/template/en/default/bug/edit.html.tmpl b/template/en/default/bug/edit.html.tmpl index 92e7bea70..c9d81b34c 100644 --- a/template/en/default/bug/edit.html.tmpl +++ b/template/en/default/bug/edit.html.tmpl @@ -187,6 +187,9 @@ <table id="bz_big_form_parts" cellspacing="0" cellpadding="0"><tr> <td> + [%# BMO hook for adding MozReview table %] + [% Hook.process("after_bug_data") %] + [% IF user.is_timetracker %] [% PROCESS section_timetracking %] [% END %] |