From 8d9c748a5e694fb544c082128c9756a0ca702334 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Buclin?= Date: Wed, 2 Aug 2017 12:59:20 +0200 Subject: Implement inline history --- extensions/Mageia/Extension.pm | 52 ++++++++++++++- extensions/Mageia/lib/Util.pm | 24 ++++++- .../hook/bug/comments-a_comment-end.html.tmpl | 76 ++++++++++++++++++++++ .../hook/global/setting-descs-settings.none.tmpl | 9 +++ extensions/Mageia/web/style.css | 21 ++++++ 5 files changed, 179 insertions(+), 3 deletions(-) create mode 100644 extensions/Mageia/template/en/default/hook/bug/comments-a_comment-end.html.tmpl create mode 100644 extensions/Mageia/template/en/default/hook/global/setting-descs-settings.none.tmpl diff --git a/extensions/Mageia/Extension.pm b/extensions/Mageia/Extension.pm index 60ca57f00..982a3bdb7 100644 --- a/extensions/Mageia/Extension.pm +++ b/extensions/Mageia/Extension.pm @@ -17,7 +17,8 @@ use Bugzilla::Constants qw(EVT_CC REL_GLOBAL_WATCHER); use Bugzilla::Bug qw(LogActivityEntry); use Bugzilla::Field qw(get_field_id); use Bugzilla::User qw(); -use Bugzilla::Extension::Mageia::Util; +use Bugzilla::User::Setting qw(add_setting); +use Bugzilla::Extension::Mageia::Util qw(compare_datetimes); use Email::Address; use Encode qw(encode); @@ -28,6 +29,10 @@ our $VERSION = '5.0'; # sysadmin-bugs@ml.mageia.org user ID = 175. use constant SYSADMIN_USER_ID => 175; +use constant MGA_SETTINGS => { + mga_inline_history => { options => ['on', 'off'], default => 'on' }, +}; + sub bug_end_of_create_validators { my ($self, $args) = @_; @@ -110,6 +115,14 @@ sub enter_bug_entrydefaultvars { $cgi->param('format', $format); } +sub install_before_final_checks { + # A hook in Bugzilla::Install::SETTINGS() would be much cleaner. :( + my %settings = %{MGA_SETTINGS()}; + foreach my $setting (keys %settings) { + add_setting($setting, $settings{$setting}->{options}, $settings{$setting}->{default}); + } +} + sub mailer_before_send { my ($self, $args) = @_; my $email = $args->{email}; @@ -123,6 +136,43 @@ sub mailer_before_send { } } +sub template_before_process { + my ($self, $args) = @_; + _inline_history($args) if $args->{file} eq 'bug/comments.html.tmpl'; +} + +sub _inline_history { + my $args = shift; + my $user = Bugzilla->user; + return if $user->setting('mga_inline_history') eq 'off'; + # Only display the bug history in chronological order. + return if $user->setting('comment_sort_order') ne 'oldest_to_newest'; + + my $bug = $args->{vars}->{bug}; + my ($history) = $bug->get_activity(); + # Filter private comments that the user is not allowed to see. + my @comments = grep { !$_->is_private || $user->is_insider || $user->id == $_->author->id } @{ $bug->comments }; + my %h_times = map { $_->{when} => $_ } @$history; + my %c_times = map { $_->creation_ts => $_ } @comments; + my @all_times = sort { compare_datetimes($a, $b) } (keys %c_times, keys %h_times); + my $curr_comment; + + foreach my $time (@all_times) { + if ($c_times{$time}) { + $curr_comment = $c_times{$time}; + $curr_comment->{inline_history} //= []; + } + if (my $activity = $h_times{$time}) { + # If we have no visible comment to attach the activity to, then ignore it. + # This can happen if the initial comment (comment 0) is private. + next unless $curr_comment; + $activity->{after} = compare_datetimes($time, $curr_comment->creation_ts); + $activity->{who} = new Bugzilla::User({ name => $activity->{who}, cache => 1 }); + push(@{ $curr_comment->{inline_history} }, $activity); + } + } +} + sub user_wants_mail { my ($self, $args) = @_; return unless $args->{relationship} == REL_GLOBAL_WATCHER; diff --git a/extensions/Mageia/lib/Util.pm b/extensions/Mageia/lib/Util.pm index f13ee2091..60447fa28 100644 --- a/extensions/Mageia/lib/Util.pm +++ b/extensions/Mageia/lib/Util.pm @@ -13,12 +13,32 @@ use warnings; use parent qw(Exporter); -our @EXPORT = qw( -); +our @EXPORT = qw(compare_datetimes); # This file can be loaded by your extension via # "use Bugzilla::Extension::Mageia::Util". You can put functions # used by your extension in here. (Make sure you also list them in # @EXPORT.) +# Return -1 if $t1 < $t2, 0 if $t1 == $t2, 1 if $t1 > $t2, undef if a date is invalid. +sub compare_datetimes { + my ($t1, $t2) = @_; + my (@time1, @time2); + if ($t1 =~ /^(\d{4})[\.-](\d{2})[\.-](\d{2})(?: (\d{2}):(\d{2}):(\d{2}))?$/) { + @time1 = ($1, $2, $3, $4, $5, $6); + } + if ($t2 =~ /^(\d{4})[\.-](\d{2})[\.-](\d{2})(?: (\d{2}):(\d{2}):(\d{2}))?$/) { + @time2 = ($1, $2, $3, $4, $5, $6); + } + return undef unless scalar(@time1) && scalar(@time2); + + for my $i (0..5) { + $t1 = $time1[$i] // 0; + $t2 = $time2[$i] // 0; + next if $t1 == $t2; + return $t1 <=> $t2; + } + return 0; +} + 1; diff --git a/extensions/Mageia/template/en/default/hook/bug/comments-a_comment-end.html.tmpl b/extensions/Mageia/template/en/default/hook/bug/comments-a_comment-end.html.tmpl new file mode 100644 index 000000000..cbe11b4ca --- /dev/null +++ b/extensions/Mageia/template/en/default/hook/bug/comments-a_comment-end.html.tmpl @@ -0,0 +1,76 @@ +[%# 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 IF user.setting('mga_inline_history') == 'off' %] + +[% FOREACH activity = comment.inline_history %] + [% IF activity.after %] + +
+
+ + [%# No need to recreate the exact same template if we already have it. %] + [% who_id = activity.who.id %] + [% UNLESS user_cache.$who_id %] + [% user_cache.$who_id = BLOCK %] + [% INCLUDE global/user.html.tmpl who = activity.who %] + [% END %] + [% END %] + [% user_cache.$who_id FILTER none %] + + + + [% FOREACH group = activity.who.groups_with_icon %] + [% group.name FILTER html %] + [% END %] + + + + [%+ activity.when FILTER time %] + +
+ [% ELSE %] +
+ [% END %] + +

+ [% FOREACH change = activity.changes %] + [% IF change.attachid AND field_descs.${change.fieldname}.match('^Attachment') %] + + [% field_descs.${change.fieldname}.replace('^Attachment', "Attachment ${change.attachid}") FILTER none %]: + [% ELSIF activity.comment_id AND field_descs.${change.fieldname}.match('^Comment') %] + [% comment_num = change.comment.count %] + + [% field_descs.${change.fieldname}.replace('^Comment', "Comment $comment_num") FILTER none %]: + [% ELSE %] + [% field_descs.${change.fieldname} FILTER html %]: + [% END %] + [% PROCESS format_field_value value = change.removed %] => + [% PROCESS format_field_value value = change.added %]
+ [% END %] +

+[% END %] + +[% BLOCK format_field_value %] + [% IF value.length %] + [% IF change.fieldname == 'assigned_to' || + change.fieldname == 'reporter' || + change.fieldname == 'qa_contact' || + change.fieldname == 'cc' || + change.fieldname == 'flagtypes.name' %] + [% display_value(change.fieldname, value) FILTER email FILTER html %] + [% ELSE %] + [% display_value(change.fieldname, value) FILTER html FILTER html_line_break %] + [% END %] + [% ELSE %] + (none) + [% END %] +[% END %] diff --git a/extensions/Mageia/template/en/default/hook/global/setting-descs-settings.none.tmpl b/extensions/Mageia/template/en/default/hook/global/setting-descs-settings.none.tmpl new file mode 100644 index 000000000..5b1da08aa --- /dev/null +++ b/extensions/Mageia/template/en/default/hook/global/setting-descs-settings.none.tmpl @@ -0,0 +1,9 @@ +[%# 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. + #%] + +[% setting_descs.mga_inline_history = "Display inline history in $terms.bug reports" %] diff --git a/extensions/Mageia/web/style.css b/extensions/Mageia/web/style.css index b43d174d8..daffc088a 100644 --- a/extensions/Mageia/web/style.css +++ b/extensions/Mageia/web/style.css @@ -29,3 +29,24 @@ body { #guided_form .field_label { white-space: nowrap; } + +.bz_inline_history { + font-style: italic; + background-color: #fff !important; +} + +div.bz_comment_hilite { + border: solid 3px; +} + +.bz_comment_hilite pre { + background-color: inherit; +} + +.change_removed { + color: darkred; +} + +.change_added { + color: darkgreen; +} -- cgit v1.2.1