[Rt-commit] rt branch, 5.0/move-rt-extension-formattedtransactions-to-core, created. rt-5.0.0-5-g4f3893e7b6

Dianne Skoll dianne at bestpractical.com
Wed Aug 12 09:20:21 EDT 2020


The branch, 5.0/move-rt-extension-formattedtransactions-to-core has been created
        at  4f3893e7b617367bbb65cdac799644dc9ddb990b (commit)

- Log -----------------------------------------------------------------
commit fd7dbf8f7eeaba798ddd02aff52ab6a65e1dce2c
Author: Dianne Skoll <dianne at bestpractical.com>
Date:   Wed Jul 29 10:09:48 2020 -0400

    Move RT::Extension::FormattedTransaction into core.

diff --git a/etc/cpanfile b/etc/cpanfile
index e4fb6d629f..dbfa5d74d1 100644
--- a/etc/cpanfile
+++ b/etc/cpanfile
@@ -82,6 +82,7 @@ requires 'Text::Password::Pronounceable';
 requires 'Text::Quoted', '>= 2.07';
 requires 'Text::Template', '>= 1.44';
 requires 'Text::WikiFormat', '>= 0.76';
+requires 'Text::WordDiff';
 requires 'Text::Wrapper';
 requires 'Time::HiRes';
 requires 'Time::ParseDate';
diff --git a/lib/RT.pm b/lib/RT.pm
index 83fa8d28fd..ff90d1a9a9 100644
--- a/lib/RT.pm
+++ b/lib/RT.pm
@@ -776,6 +776,7 @@ our %CORED_PLUGINS = (
     'RT::Extension::REST2' => '5.0',
     'RT::Authen::Token' => '5.0',
     'RT::Extension::QuoteSelection' => 5.0,
+    'RT::Extension::FormattedTransactions' => 5.0,
 );
 
 sub InitPlugins {
diff --git a/lib/RT/Interface/Web/Scrubber.pm b/lib/RT/Interface/Web/Scrubber.pm
index 20a005ab8b..ad3ce7f333 100644
--- a/lib/RT/Interface/Web/Scrubber.pm
+++ b/lib/RT/Interface/Web/Scrubber.pm
@@ -95,7 +95,7 @@ Passed to L<HTML::Scrubber/rules>.
 
 our @ALLOWED_TAGS = qw(
     A B U P BR I HR BR SMALL EM FONT SPAN STRONG SUB SUP S DEL STRIKE H1 H2 H3 H4 H5
-    H6 DIV UL OL LI DL DT DD PRE BLOCKQUOTE BDO TABLE THEAD TBODY TFOOT TR TD TH
+    H6 INS DIV UL OL LI DL DT DD PRE BLOCKQUOTE BDO TABLE THEAD TBODY TFOOT TR TD TH
 );
 
 our %ALLOWED_ATTRIBUTES = (
diff --git a/lib/RT/Transaction.pm b/lib/RT/Transaction.pm
index b45488d4b2..e4862815f8 100644
--- a/lib/RT/Transaction.pm
+++ b/lib/RT/Transaction.pm
@@ -1045,6 +1045,16 @@ sub _CanonicalizeRoleName {
                     $new = $date->AsString( Time => 0, Timezone => 'UTC' );
                 }
             }
+            elsif ( $cf->Type =~ /text/i) {
+                if (!defined($old) || ($old eq '')) {
+                    return ( "[_1] added", $field);   #loc()
+                }
+                if (!defined($new) || ($new eq '')) {
+                    return ( "[_1] deleted", $field);   #loc()
+                } else {
+                    return ( "[_1] changed", $field);   #loc()
+                }
+            }
         }
 
         if ( !defined($old) || $old eq '' ) {
diff --git a/share/html/Elements/JavascriptConfig b/share/html/Elements/JavascriptConfig
index 2566873126..e9cf69735e 100644
--- a/share/html/Elements/JavascriptConfig
+++ b/share/html/Elements/JavascriptConfig
@@ -78,6 +78,8 @@ my $Catalog = {
     history_scroll_error => "Could not load ticket history. Reason:", #loc
     unclip => "Show all", #loc
     clip => "Show less", #loc
+    show_details => "Show Details", #loc
+    hide_details => "Hide Details", #loc
 };
 $_ = loc($_) for values %$Catalog;
 
diff --git a/share/html/Elements/ShowHistory b/share/html/Elements/ShowHistory
index 0e32e10649..25b8b10787 100644
--- a/share/html/Elements/ShowHistory
+++ b/share/html/Elements/ShowHistory
@@ -56,6 +56,13 @@
 <& /Widgets/TitleBoxEnd &>
 % }
 </div>
+<script type="text/javascript">
+jQuery(function() {
+    jQuery('.toggle-txn-details').click(function () {
+        return toggleTransactionDetails.apply(this);
+    });
+});
+</script>
 <%ARGS>
 $Object
 $Transactions      => $Object->SortedTransactions
diff --git a/share/html/Elements/ShowTransaction b/share/html/Elements/ShowTransaction
index d89b3d5650..e509fc8a8b 100644
--- a/share/html/Elements/ShowTransaction
+++ b/share/html/Elements/ShowTransaction
@@ -83,6 +83,50 @@ $m->comp(
 ) if $ShowBody;
 </%PERL>
   </div>
+% if ($Transaction->Type eq 'CustomField' && $Transaction->Field ) {
+%     my ($old, $new);
+%     my $cf = RT::CustomField->new( $session{CurrentUser} );
+%     $cf->SetContextObject( $Transaction->Object );
+%     $cf->Load( $Transaction->Field );
+%     if ($cf->Id && $cf->Type =~ /text/i) {
+%        $old = $Transaction->OldValue // loc('(no value)');
+%        $old = $m->comp('/Elements/ScrubHTML', Content => $old);
+%        $old =~ s|\n|<br />|g;
+%        $new = $Transaction->NewValue // loc('(no value)');
+%        $new = $m->comp('/Elements/ScrubHTML', Content => $new);
+%        $new =~ s|\n|<br />|g;
+<div class="details hidden" id="txn-<% $Transaction->Id %>-details">
+  <table>
+% if ( $old eq loc('(no value)')  ) {
+    <tr>
+      <td class="label"><% loc('Added') %>:</td>
+      <td class="value"><% $new |n %></td>
+    </tr>
+% }
+% elsif ( $new eq loc('(no value)')  ) {
+    <tr>
+      <td class="label"><% loc('Deleted') %>:</td>
+      <td class="value"><% $old |n %></td>
+    </tr>
+% }
+% else {
+    <tr>
+      <td class="label"><% loc('From') %>:</td>
+      <td class="value" ><% $old |n %></td>
+    </tr>
+    <tr>
+      <td class="label"><% loc('To') %>:</td>
+      <td class="value"><% $new |n %></td>
+    </tr>
+    <tr class="diff">
+      <td class="label"><% loc('Changes') %>:</td>
+      <td class="value"><% loc('Loading...') %></td>
+    </tr>
+% }
+  </table>
+</div>
+%     }
+% }
 % $m->callback( %ARGS, Transaction => $Transaction, CallbackName => 'AfterContent' );
 </div>
 
@@ -165,7 +209,14 @@ if ( $txn_type =~ /EmailRecord$/ ) {
 
     $ShowBody = 0;
 }
-
+elsif ($txn_type eq 'CustomField' && $Transaction->Field) {
+    my $cf = RT::CustomField->new( $session{CurrentUser} );
+    $cf->SetContextObject( $Transaction->Object );
+    $cf->Load( $Transaction->Field );
+    if ($cf->Id && $cf->Type =~ /text/i) {
+        push @actions, { class => 'toggle-txn-details', title => loc('Show Details'), path => '#' };
+    }
+}
 # If the transaction has anything attached to it at all
 elsif ( %$Attachments && $ShowActions ) {
     my %has_right = map {
diff --git a/share/html/Elements/ShowHistory b/share/html/Helpers/TextDiff
similarity index 77%
copy from share/html/Elements/ShowHistory
copy to share/html/Helpers/TextDiff
index 0e32e10649..ae70978e40 100644
--- a/share/html/Elements/ShowHistory
+++ b/share/html/Helpers/TextDiff
@@ -45,26 +45,35 @@
 %# those contributions and any derivatives thereof.
 %#
 %# END BPS TAGGED BLOCK }}}
-<& /Elements/ShowHistoryHeader, %ARGS &>
+<%INIT>
 
-% $m->callback( %ARGS, Object => $Object, CallbackName => 'BeforeTransactions' );
+my ( $old, $new );
 
-<& /Elements/ShowHistoryPage, %ARGS &>
+if ($TransactionId) {
+    my $txn = RT::Transaction->new( $session{'CurrentUser'} );
+    $txn->Load($TransactionId);
+    if ( $txn->Id ) {
+        $old = $txn->OldValue;
+        $new = $txn->NewValue;
+    }
+    else {
+        RT->Logger->error("Could not load transaction #$TransactionId");
+        $m->abort;
+    }
+}
+else {
+    $m->abort;
+}
 
-</div>
-% if ($ShowDisplayModes or $ShowTitle) {
-<& /Widgets/TitleBoxEnd &>
-% }
-</div>
-<%ARGS>
-$Object
-$Transactions      => $Object->SortedTransactions
-$Attachments       => $Object->Attachments( WithHeaders => 1 )
-$AttachmentContent => $Object->TextAttachments
+use Text::WordDiff;
+my $diff = word_diff( \$old, \$new, { STYLE => 'HTML' } );
+$diff = $m->comp( '/Elements/ScrubHTML', Content => $diff );
+$diff =~ s|\n|<br />|g;
 
-$ShowHeaders       => 0
-$ShowTitle         => 1
-$ShowDisplayModes  => 1
+</%INIT>
+<% $diff |n %>
+% $m->abort();
 
-$PathPrefix        => ''
+<%ARGS>
+$TransactionId => undef
 </%ARGS>
diff --git a/share/html/Elements/ShowHistory b/share/html/SelfService/TextDiff
similarity index 79%
copy from share/html/Elements/ShowHistory
copy to share/html/SelfService/TextDiff
index 0e32e10649..e863db23e0 100644
--- a/share/html/Elements/ShowHistory
+++ b/share/html/SelfService/TextDiff
@@ -45,26 +45,4 @@
 %# those contributions and any derivatives thereof.
 %#
 %# END BPS TAGGED BLOCK }}}
-<& /Elements/ShowHistoryHeader, %ARGS &>
-
-% $m->callback( %ARGS, Object => $Object, CallbackName => 'BeforeTransactions' );
-
-<& /Elements/ShowHistoryPage, %ARGS &>
-
-</div>
-% if ($ShowDisplayModes or $ShowTitle) {
-<& /Widgets/TitleBoxEnd &>
-% }
-</div>
-<%ARGS>
-$Object
-$Transactions      => $Object->SortedTransactions
-$Attachments       => $Object->Attachments( WithHeaders => 1 )
-$AttachmentContent => $Object->TextAttachments
-
-$ShowHeaders       => 0
-$ShowTitle         => 1
-$ShowDisplayModes  => 1
-
-$PathPrefix        => ''
-</%ARGS>
+% $m->comp( '/Helpers/TextDiff', %ARGS );
diff --git a/share/static/css/elevator-light/history.css b/share/static/css/elevator-light/history.css
index 91b7b7e96b..3dcb32b0e3 100644
--- a/share/static/css/elevator-light/history.css
+++ b/share/static/css/elevator-light/history.css
@@ -210,3 +210,9 @@ border: none;
 .transaction .message-header-value.verify.done.trust-FULL      { color: #060; }
 .transaction .message-header-value.verify.done.trust-FULLY     { color: #060; }
 .transaction .message-header-value.verify.done.trust-ULTIMATE  { color: #060; }
+.transaction.other .details { margin-top: 0.5em; }
+.transaction.other .details tr:not(:first-child) td.value { border-top: 1px solid #ccc; }
+.transaction.other .details td.label { min-width: 0; }
+.diff del { color: #a00; }
+.diff { color: #888; }
+.diff ins { color: #080; }
diff --git a/share/static/js/util.js b/share/static/js/util.js
index 34dd5ec92f..3e67be520a 100644
--- a/share/static/js/util.js
+++ b/share/static/js/util.js
@@ -1078,3 +1078,28 @@ jQuery(function() {
         }
     }
 });
+
+function toggleTransactionDetails () {
+
+    var txn_div = jQuery(this).closest('div.transaction[data-transaction-id]');
+    var details_div = txn_div.find('div.details');
+
+    if (details_div.hasClass('hidden')) {
+        details_div.removeClass('hidden');
+        jQuery(this).text(RT.I18N.Catalog['hide_details']);
+    }
+    else {
+        details_div.addClass('hidden');
+        jQuery(this).text(RT.I18N.Catalog['show_details']);
+    }
+
+    var diff = details_div.find('.diff td.value');
+    if (!diff.children().length) {
+        diff.load(RT.Config.WebHomePath + '/Helpers/TextDiff', {
+            TransactionId: txn_div.attr('data-transaction-id')
+        });
+    }
+
+    return false;
+}
+

commit 4f3893e7b617367bbb65cdac799644dc9ddb990b
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Sat Mar 14 06:03:38 2020 +0800

    Add test for the formatted transaction output.

diff --git a/t/web/cf_textarea.t b/t/web/cf_textarea.t
index 50b00c57d4..a15aa5edc1 100644
--- a/t/web/cf_textarea.t
+++ b/t/web/cf_textarea.t
@@ -82,4 +82,51 @@ $m->content_lacks("<li>TheTextarea $content changed to $content</li>", 'textarea
 # #32440: Spurious "CF changed from 0 to 0"
 $m->content_lacks("<li>Zero 0 changed to 0</li>", "Zero wasn't updated");
 
+my $new_content = 'The quick brown fox jumps over the lazy dog.';
+
+$m->submit_form_ok({
+    with_fields => {
+        $cfs->{area}{input}            => $new_content,
+        $cfs->{area}{input} . '-Magic' => "1",
+    },
+}, 'submitted form to update textarea CF');
+
+$m->content_contains( "<li>TheTextarea $content changed to $new_content</li>", 'textarea was updated' );
+
+my $newer_content = 'The quick yellow fox jumps over the lazy dog.';
+
+$m->submit_form_ok({
+    with_fields => {
+        $cfs->{area}{input}            => $newer_content,
+        $cfs->{area}{input} . '-Magic' => "1",
+    },
+}, 'submitted form to update textarea CF');
+
+$m->content_contains( "<li>TheTextarea $new_content changed to $newer_content</li>", 'textarea was updated' );
+
+my $txn = $ticket->Transactions->Last;
+$m->get_ok( '/Helpers/TextDiff?TransactionId=' . $txn->id );
+$m->content_like( qr{<del>brown\s*</del><ins>yellow\s*</ins>}, 'text diff has the brown => yellow change' );
+
+$m->back;
+$m->submit_form_ok({
+    with_fields => {
+        $cfs->{area}{input}            => '',
+        $cfs->{area}{input} . '-Magic' => "1",
+    },
+}, 'submitted form to update textarea CF');
+
+$m->content_contains( "<li>$newer_content is no longer a value for custom field TheTextarea</li>",
+    'textarea was deleted' );
+
+$m->follow_link_ok( { text => 'Display' } );
+$content =~ s!\n+!!g;
+$m->text_like(
+    qr/TheTextarea\sadded.+\Q$content\E.+
+       TheTextarea\schanged.+From:\Q$content\ETo:\Q$new_content\E.+
+       TheTextarea\schanged.+From:\Q$new_content\ETo:\Q$newer_content\E.+
+       TheTextarea\sdeleted.+\Q$newer_content\E/xs,
+    'textarea change details'
+);
+
 done_testing;

-----------------------------------------------------------------------


More information about the rt-commit mailing list