[Rt-commit] rt branch, 4.4/ticket-history-infinite-scroll, repushed

Dustin Graves dustin at bestpractical.com
Mon Oct 19 10:58:43 EDT 2015


The branch 4.4/ticket-history-infinite-scroll was deleted and repushed:
       was f6596c4047af1366672b6cdc5581d1a1dc89e318
       now 1456980b48e1e361cdca3cfab61dfc002994dd8a

1:  f6596c4 ! 1:  1456980 add infinite scrolling option to ticket display transaction history
    @@ -1,6 +1,6 @@
     Author: Dustin Graves <dustin at bestpractical.com>
     
    -    add infinite scrolling and infinite scroll with gradual link to load page
    +    add infinite scrolling option to ticket display transaction history
         
         Fixes: T#154449
     
    @@ -12,23 +12,180 @@
              WidgetArguments => {
                  Description => 'Show history',                #loc
     -            Values      => [qw(delay click always)],
    -+            Values      => [qw(delay click always continuous)],
    ++            Values      => [qw(delay click always scroll)],
                  ValuesLabel => {
    --                delay   => "after the rest of the page loads",  #loc
    --                click   => "after clicking a link",             #loc
    --                always  => "immediately",                       #loc
    -+                delay       => "after the rest of the page loads",  #loc
    -+                click       => "after clicking a link",             #loc
    -+                always      => "immediately",                       #loc
    -+                continuous  => "as you scroll",                     #loc
    +                 delay   => "after the rest of the page loads",  #loc
    +                 click   => "after clicking a link",             #loc
    +                 always  => "immediately",                       #loc
    ++                scroll  => "as you scroll",                     #loc
                  },
              },
          },
     
    -diff --git a/share/html/Elements/ShowHistoryPage b/share/html/Elements/ShowHistoryPage
    +diff --git a/share/html/Elements/ShowHistory b/share/html/Elements/ShowHistory
    +--- a/share/html/Elements/ShowHistory
    ++++ b/share/html/Elements/ShowHistory
    +@@
    + %# those contributions and any derivatives thereof.
    + %#
    + %# END BPS TAGGED BLOCK }}}
    +-<div class="history <% lc $record_type %>" id="<% $histid %>">
    +-<%perl>
    +-if ( $ShowDisplayModes or $ShowTitle ) {
    +-    my $title = $ShowTitle
    +-                    ? loc('History')
    +-                    : ' ';
    ++<& /Elements/ShowHistoryHeader,
    ++    Object            => $Object,
    ++    ShowHeaders       => $ShowHeaders,
    ++    ShowTitle         => $ShowTitle,
    ++    ShowDisplayModes  => $ShowDisplayModes,
    ++    &>
    ++
    ++% $m->callback( %ARGS, Object => $Object, CallbackName => 'BeforeTransactions' );
    ++
    ++<& /Elements/ShowHistoryPage,
    ++    Object            => $Object,
    ++    Transactions      => $Object->SortedTransactions,
    ++    ShowHeaders       => $ARGS{'ShowHeaders'},
    ++    Attachments       => $Attachments,
    ++    AttachmentContent => $AttachmentContent,
    ++    PathPrefix        => ''
    ++    &>
    + 
    +-    my $titleright = '';
    +-    if ( $ShowDisplayModes ) {
    +-        if ( RT->Config->Get( 'QuoteFolding', $session{CurrentUser} ) ) {
    +-            my $open_all  = $m->interp->apply_escapes( loc("Show all quoted text"), 'j' );
    +-            my $open_html = $m->interp->apply_escapes( loc("Show all quoted text"), 'h' );
    +-            my $close_all = $m->interp->apply_escapes( loc("Hide all quoted text"), 'j' );
    +-            $titleright .=    '<a href="#" data-direction="open" '
    +-                            . qq{onclick="return toggle_all_folds(this, $open_all, $close_all);"}
    +-                            . ">$open_html</a> — ";
    +-        }
    +-
    +-        if ($ShowHeaders) {
    +-            $titleright .= qq{<a href="?ForceShowHistory=1;id=} .
    +-                           $Object->id.qq{#$histid">} .
    +-                           loc("Show brief headers") .
    +-                           qq{</a>};
    +-        } else {
    +-            $titleright .= qq{<a href="?ForceShowHistory=1;ShowHeaders=1;id=} .
    +-                           $Object->id.qq{#$histid">} .
    +-                           loc("Show full headers") .
    +-                           qq{</a>};
    +-        }
    +-    }
    +-</%perl>
    +-<& /Widgets/TitleBoxStart, title => $title, titleright_raw => $titleright &>
    +-% }
    +-
    +-<div class="history-container">
    +-<%perl>
    +-$m->callback( %ARGS, Object => $Object, CallbackName => 'BeforeTransactions' );
    +-my $i = 1;
    +-while ( my $Transaction = $Transactions->Next ) {
    +-    my $skip = 0;
    +-
    +-    # Skip display of SetWatcher transactions for ticket Owner groups.  Owner
    +-    # was a single member role group and denormalized into a column well before
    +-    # the generic role group handling and transactions came about.  For
    +-    # tickets, we rely on rendering ownership changes using the Set-Owner
    +-    # transaction.  For all other record types, or even potential ticket single
    +-    # role groups which aren't Owner, we use SetWatcher to render history and
    +-    # skip the Set transactions.  This complication is necessary to avoid
    +-    # creating backdated transactions on upgrade which normalize to one type or
    +-    # another.
    +-    # 
    +-    # These conditions assumes ticket Owner is a single-member denormalized
    +-    # role group, which is safe since that is unlikely to ever change in the
    +-    # future.
    +-    if ($Object->isa("RT::Ticket") and ($Transaction->Field || '') eq "Owner") {
    +-        $skip = 1 if $Transaction->Type eq "SetWatcher";
    +-    } else {
    +-        $skip = 1 if $Transaction->Type eq "Set"
    +-                 and $Transaction->Field
    +-                 and $Object->DOES("RT::Record::Role::Roles")
    +-                 and $Object->HasRole( $Transaction->Field )
    +-                 and $Object->RoleGroup( $Transaction->Field )->SingleMemberRoleGroupColumn;
    +-    }
    +-
    +-    $m->callback(
    +-        %ARGS,
    +-        Transaction   => $Transaction,
    +-        skip          => \$skip,
    +-        CallbackName  => 'SkipTransaction',
    +-    );
    +-    next if $skip;
    +-
    +-    # ARGS is first because we're clobbering the "Attachments" parameter
    +-    $m->comp( 'ShowTransaction',
    +-        %ARGS,
    +-        Object            => $Object,
    +-        Transaction       => $Transaction,
    +-        ShowHeaders       => $ShowHeaders,
    +-        RowNum            => $i,
    +-        Attachments       => $trans_attachments->{$Transaction->id} || {},
    +-        AttachmentContent => $trans_content,
    +-        HasTxnCFs         => $HasTxnCFs,
    +-    );
    +-
    +-    # manually flush the content buffer after each txn,
    +-    # so the user sees some update
    +-    $m->flush_buffer;
    +-
    +-    $i++;
    +-}
    +-
    +-</%perl>
    + </div>
    + % if ($ShowDisplayModes or $ShowTitle) {
    + <& /Widgets/TitleBoxEnd &>
    + % }
    + </div>
    +-<%INIT>
    +-my $trans_content = {};
    +-my $trans_attachments = {};
    +-
    +-for my $content (@{$AttachmentContent->ItemsArrayRef()}) {
    +-    $trans_content->{$content->TransactionId}->{$content->Id} = $content;
    +-}
    +-
    +-for my $attachment (@{$Attachments->ItemsArrayRef()}) {
    +-    my $tmp = $trans_attachments->{ $attachment->TransactionId } ||= {};
    +-    push @{ $tmp->{ $attachment->Parent || 0 } ||= [] }, $attachment;
    +-}
    +-
    +-{
    +-    my %tmp = (
    +-        DisplayPath     => 'Display.html',
    +-        AttachmentPath  => 'Attachment',
    +-        UpdatePath      => 'Update.html',
    +-        ForwardPath     => 'Forward.html',
    +-        EmailRecordPath => 'ShowEmailRecord.html',
    +-        EncryptionPath  => 'Crypt.html',
    +-    );
    +-
    +-    my $prefix = $ARGS{PathPrefix}||'';
    +-    while ( my ($arg, $path) = each %tmp ) {
    +-        next if defined $ARGS{ $arg };
    +-        $ARGS{ $arg } = $prefix.$path;
    +-    }
    +-}
    +-
    +-my $record_type = $Object->RecordType;
    +-my $histid      = "\L$record_type\E-" . $Object->id . "-history";
    +-
    +-my $HasTxnCFs = ($Object->can("TransactionCustomFields") and $Object->TransactionCustomFields->Count);
    +-</%INIT>
    + <%ARGS>
    + $Object
    + $Transactions      => $Object->SortedTransactions
    +
    +diff --git a/share/html/Elements/ShowHistoryHeader b/share/html/Elements/ShowHistoryHeader
     new file mode 100644
     --- /dev/null
    -+++ b/share/html/Elements/ShowHistoryPage
    ++++ b/share/html/Elements/ShowHistoryHeader
     @@
     +%# BEGIN BPS TAGGED BLOCK {{{
     +%#
    @@ -79,10 +236,110 @@
     +%# END BPS TAGGED BLOCK }}}
     +<%ARGS>
     +$Object
    ++$ShowHeaders       => 0
    ++$ShowTitle         => 1
    ++$ShowDisplayModes  => 1
    ++</%ARGS>
    ++<%INIT>
    ++my $record_type = $Object->RecordType;
    ++my $histid      = "\L$record_type\E-" . $Object->id . "-history";
    ++</%INIT>
    ++<div class="history <% lc $record_type %>" id="<% $histid %>">
    ++<%perl>
    ++if ( $ShowDisplayModes or $ShowTitle ) {
    ++    my $title = $ShowTitle
    ++                    ? loc('History')
    ++                    : ' ';
    ++
    ++    my $titleright = '';
    ++    if ( $ShowDisplayModes ) {
    ++        if ( RT->Config->Get( 'QuoteFolding', $session{CurrentUser} ) ) {
    ++            my $open_all  = $m->interp->apply_escapes( loc("Show all quoted text"), 'j' );
    ++            my $open_html = $m->interp->apply_escapes( loc("Show all quoted text"), 'h' );
    ++            my $close_all = $m->interp->apply_escapes( loc("Hide all quoted text"), 'j' );
    ++            $titleright .=    '<a href="#" data-direction="open" '
    ++                            . qq{onclick="return toggle_all_folds(this, $open_all, $close_all);"}
    ++                            . ">$open_html</a> — ";
    ++        }
    ++
    ++        if ($ShowHeaders) {
    ++            $titleright .= qq{<a href="?ForceShowHistory=1;id=} .
    ++                           $Object->id.qq{#$histid">} .
    ++                           loc("Show brief headers") .
    ++                           qq{</a>};
    ++        } else {
    ++            $titleright .= qq{<a href="?ForceShowHistory=1;ShowHeaders=1;id=} .
    ++                           $Object->id.qq{#$histid">} .
    ++                           loc("Show full headers") .
    ++                           qq{</a>};
    ++        }
    ++    }
    ++</%perl>
    ++<& /Widgets/TitleBoxStart, title => $title, titleright_raw => $titleright &>
    ++% }
    ++
    ++<div class="history-container">
    +
    +diff --git a/share/html/Elements/ShowHistoryPage b/share/html/Elements/ShowHistoryPage
    +new file mode 100644
    +--- /dev/null
    ++++ b/share/html/Elements/ShowHistoryPage
    +@@
    ++%# BEGIN BPS TAGGED BLOCK {{{
    ++%#
    ++%# COPYRIGHT:
    ++%#
    ++%# This software is Copyright (c) 1996-2015 Best Practical Solutions, LLC
    ++%#                                          <sales at bestpractical.com>
    ++%#
    ++%# (Except where explicitly superseded by other copyright notices)
    ++%#
    ++%#
    ++%# LICENSE:
    ++%#
    ++%# This work is made available to you under the terms of Version 2 of
    ++%# the GNU General Public License. A copy of that license should have
    ++%# been provided with this software, but in any event can be snarfed
    ++%# from www.gnu.org.
    ++%#
    ++%# This work is distributed in the hope that it will be useful, but
    ++%# WITHOUT ANY WARRANTY; without even the implied warranty of
    ++%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    ++%# General Public License for more details.
    ++%#
    ++%# You should have received a copy of the GNU General Public License
    ++%# along with this program; if not, write to the Free Software
    ++%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    ++%# 02110-1301 or visit their web page on the internet at
    ++%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
    ++%#
    ++%#
    ++%# CONTRIBUTION SUBMISSION POLICY:
    ++%#
    ++%# (The following paragraph is not intended to limit the rights granted
    ++%# to you to modify and distribute this software under the terms of
    ++%# the GNU General Public License and is only of importance to you if
    ++%# you choose to contribute your changes and enhancements to the
    ++%# community by submitting them to Best Practical Solutions, LLC.)
    ++%#
    ++%# By intentionally submitting any modifications, corrections or
    ++%# derivatives to this work, or any other work intended for use with
    ++%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
    ++%# you are the copyright holder for those contributions and you grant
    ++%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
    ++%# royalty-free, perpetual, license to use, copy, create derivative
    ++%# works based on those contributions, and sublicense and distribute
    ++%# those contributions and any derivatives thereof.
    ++%#
    ++%# END BPS TAGGED BLOCK }}}
    ++<%ARGS>
    ++$Object
     +$Transactions      => $Object->SortedTransactions
     +$Attachments       => $Object->Attachments( WithHeaders => 1 )
     +$AttachmentContent => $Object->TextAttachments
    ++
     +$ShowHeaders       => 0
    ++
     +$PathPrefix        => ''
     +</%ARGS>
     +<%INIT>
    @@ -115,20 +372,11 @@
     +    }
     +}
     +
    -+my $record_type = $Object->RecordType;
    -+my $histid      = "\L$record_type\E-" . $Object->id . "-history";
    -+
     +my $HasTxnCFs = ($Object->can("TransactionCustomFields") and $Object->TransactionCustomFields->Count);
     +</%INIT>
     +<%perl>
    -+$m->callback( %ARGS, Object => $Object, CallbackName => 'BeforeTransactions' );
    -+
    -+# Properly set starting index
    -+my $i = 0;
    -+
    -+my $Transaction;
    -+
    -+while ( $Transaction = $Transactions->Next ) {
    ++my $i = 1;
    ++while ( my $Transaction = $Transactions->Next ) {
     +    my $skip = 0;
     +
     +    # Skip display of SetWatcher transactions for ticket Owner groups.  Owner
    @@ -140,7 +388,7 @@
     +    # skip the Set transactions.  This complication is necessary to avoid
     +    # creating backdated transactions on upgrade which normalize to one type or
     +    # another.
    -+    #
    ++    # 
     +    # These conditions assumes ticket Owner is a single-member denormalized
     +    # role group, which is safe since that is unlikely to ever change in the
     +    # future.
    @@ -180,11 +428,8 @@
     +
     +    $i++;
     +}
    -+
    -+# abort if we have no transactions, so the client knows we had no results
    -+$m->abort() unless ($Transaction);
     +</%perl>
    -+<script type="text/javascript">ReplaceUserReferences()</script>
    ++
     
     diff --git a/share/html/Elements/ShowTransaction b/share/html/Elements/ShowTransaction
     --- a/share/html/Elements/ShowTransaction
    @@ -255,14 +500,12 @@
     +$id
     +$oldestTransactionsFirst
     +$lastTransactionId => undef
    -+$transactionId => undef
    ++$focusTransactionId => undef
     +</%ARGS>
     +<%INIT>
     +my $TicketObj = RT::Ticket->new($session{'CurrentUser'});
     +$TicketObj->Load($id);
     +
    -+my $attachments = $TicketObj->Attachments;
    -+my $attachment_content = $TicketObj->TextAttachments;
     +my %extra_args;
     +$m->callback( CallbackName => 'ExtraShowHistoryArguments', Ticket => $TicketObj, ExtraArgs => \%extra_args );
     +
    @@ -279,13 +522,13 @@
     +    { FIELD => 'Created',   ORDER => $order },
     +    { FIELD => 'id',        ORDER => $order },
     +);
    -+if ($transactionId) {
    ++if ($focusTransactionId) { # make sure we load enough if we need to focus a transaction
     +    $transactions->Limit(
     +        FIELD    => 'id',
     +        OPERATOR => $oldestTransactionsFirst ? '<=' : '>=',
    -+        VALUE    => $transactionId
    ++        VALUE    => $focusTransactionId
     +    );
    -+} else {
    ++} else { # otherwise, just load the standard page of 10 transactions
     +    $transactions->RowsPerPage(10);
     +    $transactions->FirstPage();
     +}
    @@ -293,8 +536,6 @@
     +<& /Elements/ShowHistoryPage,
     +    Object => $TicketObj,
     +    ShowHeaders => $ARGS{'ShowHeaders'},
    -+    Attachments => $attachments,
    -+    AttachmentContent => $attachment_content,
     +    Transactions => $transactions,
     +    %extra_args,
     +    &>
    @@ -308,8 +549,8 @@
      
      % my $ShowHistory = RT->Config->Get("ShowHistory", $session{'CurrentUser'});
     -% if ($ShowHistory eq "delay") {
    -+% if ($ShowHistory eq "continuous") {
    -+    <& /Ticket/Elements/ContinuousShowHistory,
    ++% if ($ShowHistory eq "scroll") {
    ++    <& /Ticket/Elements/ScrollShowHistory,
     +        Ticket => $TicketObj
     +    &>
     +% } elsif ($ShowHistory eq "delay") {
    @@ -317,10 +558,10 @@
              Ticket => $TicketObj,
              ShowHeaders => $ARGS{'ShowHeaders'},
     
    -diff --git a/share/html/Ticket/Elements/ContinuousShowHistory b/share/html/Ticket/Elements/ContinuousShowHistory
    +diff --git a/share/html/Ticket/Elements/ScrollShowHistory b/share/html/Ticket/Elements/ScrollShowHistory
     new file mode 100644
     --- /dev/null
    -+++ b/share/html/Ticket/Elements/ContinuousShowHistory
    ++++ b/share/html/Ticket/Elements/ScrollShowHistory
     @@
     +%# BEGIN BPS TAGGED BLOCK {{{
     +%#
    @@ -372,6 +613,7 @@
     +<%ARGS>
     +$Ticket
     +</%ARGS>
    ++
     +<%INIT>
     +my %params = %ARGS;
     +delete $params{Ticket};
    @@ -386,61 +628,27 @@
     +my $ShowTitle =        1 || $extra_args{'ShowTitle'};
     +my $ShowHeaders =      0 || $extra_args{'ShowHeaders'};
     +
    -+my $record_type = $Ticket->RecordType;
    -+my $histid      = "\L$record_type\E-" . $Ticket->id . "-history";
    -+
     +my $oldestTransactionsFirst = RT->Config->Get("OldestTransactionsFirst", $session{CurrentUser});
     +</%INIT>
    -+<div id="delayed_ticket_history">
    -+<div class="history <% lc $record_type %>" id="<% $histid %>">
    -+<%perl>
    -+if ( $ShowDisplayModes or $ShowTitle ) {
    -+    my $title = $ShowTitle
    -+                    ? loc('History')
    -+                    : ' ';
    -+
    -+    my $titleright = '';
    -+    if ( $ShowDisplayModes ) {
    -+        if ( RT->Config->Get( 'QuoteFolding', $session{CurrentUser} ) ) {
    -+            my $open_all  = $m->interp->apply_escapes( loc("Show all quoted text"), 'j' );
    -+            my $open_html = $m->interp->apply_escapes( loc("Show all quoted text"), 'h' );
    -+            my $close_all = $m->interp->apply_escapes( loc("Hide all quoted text"), 'j' );
    -+            $titleright .=    '<a href="#" data-direction="open" '
    -+                            . qq{onclick="return toggle_all_folds(this, $open_all, $close_all);"}
    -+                            . ">$open_html</a> — ";
    -+        }
    -+
    -+        if ($ShowHeaders) {
    -+            $titleright .= qq{<a href="?ForceShowHistory=1;id=} .
    -+                           $Ticket->id.qq{#$histid">} .
    -+                           loc("Show brief headers") .
    -+                           qq{</a>};
    -+        } else {
    -+            $titleright .= qq{<a href="?ForceShowHistory=1;ShowHeaders=1;id=} .
    -+                           $Ticket->id.qq{#$histid">} .
    -+                           loc("Show full headers") .
    -+                           qq{</a>};
    -+        }
    -+    }
    -+</%perl>
    -+<& /Widgets/TitleBoxStart, title => $title, titleright_raw => $titleright &>
    -+% }
    -+
    -+<div class="history-container">
    -+
    ++
    ++<& /Elements/ShowHistoryHeader,
    ++    Object            => $Ticket,
    ++    ShowHeaders       => $ShowHeaders,
    ++    ShowTitle         => $ShowTitle,
    ++    ShowDisplayModes  => $ShowDisplayModes,
    ++    &>
    ++
    ++</div>
     +% if ($ShowDisplayModes or $ShowTitle) {
     +    <& /Widgets/TitleBoxEnd &>
     +% }
    -+
    -+</div>
    -+</div>
     +</div>
     +
     +<script type="text/javascript">
     +jQuery(function(){
     +    var isLoading = false, // prevent multiple simultaneous load events
     +        disableLoading = false, // prevent repeated fruitless attempts
    -+        loadDistanceFromBottom = 600, // to load before bottom of page is reached
    ++        loadDistanceFromBottom = 750, // to load before bottom of page is reached
     +        lastTransactionId = null,
     +        hash = window.location.hash,
     +        hashTransactionId = null;
    @@ -448,13 +656,11 @@
     +    var oldestTransactionsFirst = <% $oldestTransactionsFirst || 0 %>;
     +
     +    var removeLoadingMessage = function() {
    -+        var loadingMessages = jQuery('.loading-message');
    -+        if (loadingMessages.length) loadingMessages.remove();
    ++        jQuery('.loading-message').remove();
     +    };
     +
     +    var removeLoadLink = function() {
    -+        var loadLink = jQuery('.error-load-history');
    -+        if (loadLink.length) loadLink.remove();
    ++        jQuery('.error-load-history').remove();
     +    };
     +
     +    var showLoadingMessage = function() {
    @@ -467,7 +673,7 @@
     +        removeLoadingMessage();
     +        disableLoading = true;
     +        removeLoadLink();
    -+        var loadLink = jQuery('<div class="error-load-history"><&|/l&>Could not load ticket history. Reason: </&>' + reason + '.<br/><a href="#"><&|/l&>Try again</&></a></div>');
    ++        var loadLink = jQuery('<div class="error-load-history"><&|/l&>Could not load ticket history. Reason: </&>' + reason + '<br/><a href="#"><&|/l&>Try again</&></a></div>');
     +        jQuery(".history-container").append(loadLink);
     +    };
     +
    @@ -480,20 +686,21 @@
     +        var queryString = '&oldestTransactionsFirst=' + oldestTransactionsFirst;
     +        if (lastTransactionId) queryString += '&lastTransactionId=' + lastTransactionId;
     +
    -+        // check for link to specific transaction and make sure we load enough to view it
    ++        // check for link to specific transaction and make sure we load enough to focus it
     +        if (hash && !lastTransactionId) {
     +            var matches = hash.match(/^#txn-(\d+)$/);
     +            if (matches) {
     +                hashTransactionId = matches[1];
    -+                queryString += '&transactionId=' + hashTransactionId;
    ++                queryString += '&focusTransactionId=' + hashTransactionId;
     +            }
     +        }
     +
     +        jQuery.ajax({
     +            url: "<% $url %>" + queryString,
     +            success: function(html) {
    -+                if(html) {
    -+                    lastTransactionId = jQuery(html).filter('div.transaction').last().data('transactionId');
    ++                var transactions = jQuery(html).filter('div.transaction');
    ++                if(html && transactions.length) {
    ++                    lastTransactionId = transactions.last().data('transactionId');
     +                    jQuery(".history-container").append(html);
     +
     +                    if (hashTransactionId) { // focus transaction if we are following a link to it



More information about the rt-commit mailing list