[Rt-commit] rt branch, 4.6/txn-query-builder-with-new-themes, repushed

? sunnavy sunnavy at bestpractical.com
Mon Dec 9 16:51:48 EST 2019


The branch 4.6/txn-query-builder-with-new-themes was deleted and repushed:
       was 644931a63b1b0c0aa02fc5d2ca0eb9a4e70c7705
       now 127c50b88f0ee4540d2b9c890fbd7ea707c19c28

1: 87fe8ee2a7 ! 1: 457762464c Initial ticket transaction query builder
    @@ -330,6 +330,14 @@
     --- a/lib/RT/Transactions.pm
     +++ b/lib/RT/Transactions.pm
     @@
    + use base 'RT::SearchBuilder';
    + 
    + use RT::Transaction;
    ++use 5.010;
    + 
    + sub Table { 'Transactions'}
    + 
    +@@
          return $self->SUPER::AddRecord($record);
      }
      
    @@ -376,6 +384,7 @@
     +    TicketPriority        => ['TICKETFIELD'],                  #loc_left_pair
     +    TicketInitialPriority => ['TICKETFIELD'],                  #loc_left_pair
     +    TicketFinalPriority   => ['TICKETFIELD'],                  #loc_left_pair
    ++    TicketQueueLifecycle  => ['TICKETQUEUEFIELD'],             #loc_left_pair
     +
     +    CustomFieldName => ['CUSTOMFIELDNAME'],                    #loc_left_pair
     +    CFName          => ['CUSTOMFIELDNAME'],                    #loc_left_pair
    @@ -397,6 +406,7 @@
     +    ATTACHFIELD            => \&_AttachLimit,
     +    ATTACHCONTENT          => \&_AttachContentLimit,
     +    TICKETFIELD            => \&_TicketLimit,
    ++    TICKETQUEUEFIELD       => \&_TicketQueueLimit,
     +    OBJECTCUSTOMFIELDVALUE => \&_ObjectCustomFieldValueLimit,
     +    CUSTOMFIELDNAME        => \&_CustomFieldNameLimit,
     +);
    @@ -990,20 +1000,6 @@
     +    my ( $self, $field, $op, $value, %rest ) = @_;
     +    $field =~ s!^Ticket!!;
     +
    -+    unless ( defined $self->{_sql_ticketalias} ) {
    -+        $self->{_sql_ticketalias} = $self->Join(
    -+            TYPE   => 'LEFT',
    -+            FIELD1 => 'ObjectId',
    -+            TABLE2 => 'Tickets',
    -+            FIELD2 => 'id',
    -+        );
    -+        $self->Limit(
    -+            FIELD           => 'ObjectType',
    -+            VALUE           => 'RT::Ticket',
    -+            ENTRYAGGREGATOR => 'AND',
    -+        );
    -+    }
    -+
     +    if ( $field eq 'Queue' && $value =~ /\D/ ) {
     +        my $queue = RT::Queue->new($self->CurrentUser);
     +        $queue->Load($value);
    @@ -1016,13 +1012,39 @@
     +        $value = $user->id if $user->id;
     +    }
     +
    ++    if ( $field eq 'Status' && $value =~ /^(?:__(?:in)?active__)$/i ) {
    ++        my $user = RT::User->new( $self->CurrentUser );
    ++        $user->Load($value);
    ++        $value = $user->id if $user->id;
    ++    }
    ++
     +    $self->Limit(
     +        %rest,
    -+        ALIAS         => $self->{_sql_ticketalias},
    ++        ALIAS         => $self->_JoinTickets,
     +        FIELD         => $field,
     +        OPERATOR      => $op,
     +        VALUE         => $value,
     +        CASESENSITIVE => 0,
    ++    );
    ++}
    ++
    ++sub _TicketQueueLimit {
    ++    my ( $self, $field, $op, $value, %rest ) = @_;
    ++    $field =~ s!^TicketQueue!!;
    ++
    ++    my $queue = $self->{_sql_aliases}{ticket_queues} ||= $_[0]->Join(
    ++        ALIAS1 => $self->_JoinTickets,
    ++        FIELD1 => 'Queue',
    ++        TABLE2 => 'Queues',
    ++        FIELD2 => 'id',
    ++    );
    ++
    ++    $self->Limit(
    ++        ALIAS    => $queue,
    ++        FIELD    => $field,
    ++        OPERATOR => $op,
    ++        VALUE    => $value,
    ++        %rest,
     +    );
     +}
     +
    @@ -1073,6 +1095,111 @@
     +        Class => ref $self || $self,
     +    );
     +    die join "; ", map { ref $_ eq 'ARRAY' ? $_->[ 0 ] : $_ } @results if @results;
    ++
    ++
    ++    # To handle __Active__ and __InActive__ statuses, copied from
    ++    # RT::Tickets::_parser with field name updates, i.e.
    ++    #   Lifecycle => TicketQueueLifecycle
    ++    #   Status => TicketStatus
    ++
    ++    state ( $active_status_node, $inactive_status_node );
    ++    my $escape_quotes = sub {
    ++        my $text = shift;
    ++        $text =~ s{(['\\])}{\\$1}g;
    ++        return $text;
    ++    };
    ++
    ++    $tree->traverse(
    ++        sub {
    ++            my $node = shift;
    ++            return unless $node->isLeaf and $node->getNodeValue;
    ++            my ($key, $subkey, $meta, $op, $value, $bundle)
    ++                = @{$node->getNodeValue}{qw/Key Subkey Meta Op Value Bundle/};
    ++            return unless $key eq "TicketStatus" && $value =~ /^(?:__(?:in)?active__)$/i;
    ++
    ++            my $parent = $node->getParent;
    ++            my $index = $node->getIndex;
    ++
    ++            if ( ( lc $value eq '__inactive__' && $op eq '=' ) || ( lc $value eq '__active__' && $op eq '!=' ) ) {
    ++                unless ( $inactive_status_node ) {
    ++                    my %lifecycle =
    ++                      map { $_ => $RT::Lifecycle::LIFECYCLES{ $_ }{ inactive } }
    ++                      grep { @{ $RT::Lifecycle::LIFECYCLES{ $_ }{ inactive } || [] } }
    ++                      grep { $RT::Lifecycle::LIFECYCLES_CACHE{ $_ }{ type } eq 'ticket' }
    ++                      keys %RT::Lifecycle::LIFECYCLES;
    ++                    return unless %lifecycle;
    ++
    ++                    my $sql;
    ++                    if ( keys %lifecycle == 1 ) {
    ++                        $sql = join ' OR ', map { qq{ TicketStatus = '$_' } } map { $escape_quotes->($_) } map { @$_ } values %lifecycle;
    ++                    }
    ++                    else {
    ++                        my @inactive_sql;
    ++                        for my $name ( keys %lifecycle ) {
    ++                            my $escaped_name = $escape_quotes->($name);
    ++                            my $inactive_sql =
    ++                                qq{TicketQueueLifecycle = '$escaped_name'}
    ++                              . ' AND ('
    ++                              . join( ' OR ', map { qq{ TicketStatus = '$_' } } map { $escape_quotes->($_) } @{ $lifecycle{ $name } } ) . ')';
    ++                            push @inactive_sql, qq{($inactive_sql)};
    ++                        }
    ++                        $sql = join ' OR ', @inactive_sql;
    ++                    }
    ++                    $inactive_status_node = RT::Interface::Web::QueryBuilder::Tree->new;
    ++                    $inactive_status_node->ParseSQL(
    ++                        Class       => ref $self,
    ++                        Query       => $sql,
    ++                        CurrentUser => $self->CurrentUser,
    ++                    );
    ++                }
    ++                $parent->removeChild( $node );
    ++                $parent->insertChild( $index, $inactive_status_node );
    ++            }
    ++            else {
    ++                unless ( $active_status_node ) {
    ++                    my %lifecycle =
    ++                      map {
    ++                        $_ => [
    ++                            @{ $RT::Lifecycle::LIFECYCLES{ $_ }{ initial } || [] },
    ++                            @{ $RT::Lifecycle::LIFECYCLES{ $_ }{ active }  || [] },
    ++                          ]
    ++                      }
    ++                      grep {
    ++                             @{ $RT::Lifecycle::LIFECYCLES{ $_ }{ initial } || [] }
    ++                          || @{ $RT::Lifecycle::LIFECYCLES{ $_ }{ active }  || [] }
    ++                      }
    ++                      grep { $RT::Lifecycle::LIFECYCLES_CACHE{ $_ }{ type } eq 'ticket' }
    ++                      keys %RT::Lifecycle::LIFECYCLES;
    ++                    return unless %lifecycle;
    ++
    ++                    my $sql;
    ++                    if ( keys %lifecycle == 1 ) {
    ++                        $sql = join ' OR ', map { qq{ TicketStatus = '$_' } } map { $escape_quotes->($_) } map { @$_ } values %lifecycle;
    ++                    }
    ++                    else {
    ++                        my @active_sql;
    ++                        for my $name ( keys %lifecycle ) {
    ++                            my $escaped_name = $escape_quotes->($name);
    ++                            my $active_sql =
    ++                                qq{TicketQueueLifecycle = '$escaped_name'}
    ++                              . ' AND ('
    ++                              . join( ' OR ', map { qq{ TicketStatus = '$_' } } map { $escape_quotes->($_) } @{ $lifecycle{ $name } } ) . ')';
    ++                            push @active_sql, qq{($active_sql)};
    ++                        }
    ++                        $sql = join ' OR ', @active_sql;
    ++                    }
    ++                    $active_status_node = RT::Interface::Web::QueryBuilder::Tree->new;
    ++                    $active_status_node->ParseSQL(
    ++                        Class       => ref $self,
    ++                        Query       => $sql,
    ++                        CurrentUser => $self->CurrentUser,
    ++                    );
    ++                }
    ++                $parent->removeChild( $node );
    ++                $parent->insertChild( $index, $active_status_node );
    ++            }
    ++        }
    ++    );
     +
     +    my $ea = '';
     +    $tree->traverse(
    @@ -1129,10 +1256,32 @@
     +        return (0, $error);
     +    }
     +
    ++    $self->Limit( FIELD => 'ObjectType', VALUE => 'RT::Ticket' );
    ++    $self->Limit(
    ++        ALIAS         => $self->_JoinTickets,
    ++        FIELD         => 'Type',
    ++        OPERATOR      => '=',
    ++        VALUE         => 'ticket',
    ++        CASESENSITIVE => 0,
    ++    );
    ++
     +    # set SB's dirty flag
     +    $self->{'must_redo_search'} = 1;
     +
     +    return (1, $self->loc("Valid Query"));
    ++}
    ++
    ++sub _JoinTickets {
    ++    my $self = shift;
    ++    unless ( defined $self->{_sql_aliases}{tickets} ) {
    ++        $self->{_sql_aliases}{tickets} = $self->Join(
    ++            TYPE   => 'LEFT',
    ++            FIELD1 => 'ObjectId',
    ++            TABLE2 => 'Tickets',
    ++            FIELD2 => 'id',
    ++        );
    ++    }
    ++    return $self->{_sql_aliases}{tickets};
     +}
     +
     +=head2 Query
    @@ -1980,8 +2129,12 @@
     +                Type => 'component',
     +                Path => '/Elements/SelectBoolean',
     +                Arguments => { TrueVal=> '=', FalseVal => '!=' },
    ++            },
    ++            Value => {
    ++                Type => 'component',
    ++                Path => '/Elements/EmailInput',
    ++                Arguments => { AutocompleteReturn => 'Name' },
                  },
    -+            Value => { Type => 'text', Size => 5 },
              },
     -        Value => { Type => 'text', Size => 20 },
     -    },
    @@ -2036,7 +2189,8 @@
     +            Field => loc('Type'),
     +            Op => {
     +                Type => 'component',
    -+                Path => '/Elements/SelectMatch',
    ++                Path => '/Elements/SelectBoolean',
    ++                Arguments => { TrueVal=> '=', FalseVal => '!=' },
     +            },
     +            Value => {
     +                Type    => 'select',
-:  ------- > 2: 9a186b1295 Resolve the inconsistent $Class param in Search and CollectionAsTable
2: 7d5010b358 ! 3: 99f4dcdfda Add support to clip long search result columns
    @@ -1,9 +1,9 @@
     Author: sunnavy <sunnavy at bestpractical.com>
     
    -    Add support to clamp long search result columns
    +    Add support to clip long search result columns
         
         This is initially for transaction's Content column, which could be very
    -    long and we need to clamp it.
    +    long and we need to clip it.
         
         To get real height of the column value, this feature requires the value
         to be wrapped into an HTML tag, like '<small>__Content__</small>'
    @@ -15,7 +15,7 @@
          contains => "Contains", # loc
          lower_disabled => "disabled", # loc
          history_scroll_error => "Could not load ticket history. Reason:", #loc
    -+    unclamp => "Show all", #loc
    ++    unclip => "Show all", #loc
      };
      $_ = loc($_) for values %$Catalog;
      
    @@ -32,7 +32,7 @@
     +    overflow-y: hidden;
     +}
     +
    -+.collection-as-table a.unclamp {
    ++.collection-as-table a.unclip {
     +    font-size: smaller;
     +    font-weight: normal;
     +}
    @@ -51,11 +51,11 @@
     +            if ( jQuery(this).children().height() > max_height ) {
     +                jQuery(this).children().wrapAll('<div class="clamp">');
     +                jQuery(this).children('div.clamp').height('' + max_height + 'px');
    -+                jQuery(this).append('<a href="#" class="unclamp button btn btn-primary">' + loc_key('unclamp') + '</a>');
    ++                jQuery(this).append('<a href="#" class="unclip button btn btn-primary">' + loc_key('unclip') + '</a>');
     +            }
     +        }
     +    });
    -+    jQuery('a.unclamp').click(function() {
    ++    jQuery('a.unclip').click(function() {
     +        jQuery(this).siblings('div.clamp').css('height', 'auto');
     +        jQuery(this).hide();
     +        return false;
3: 37b156ed02 ! 4: 1b6abdd28c Add transaction search tests
    @@ -29,6 +29,21 @@
     +for my $field ( keys %field_value ) {
     +    is( $txn->$field, $field_value{$field}, $field );
     +}
    ++
    ++$txns->FromSQL('Type="Create" AND TicketStatus="__Active__"');
    ++is( $txns->Count, 2, 'Found the 2 create txns of active tickets' );
    ++
    ++$txns->FromSQL('Type="Create" AND TicketStatus="__Inactive__"');
    ++is( $txns->Count, 0, 'Found the 0 create txns of inactive tickets' );
    ++
    ++ok( $frodo->SetStatus('resolved'), 'Resolved 1 ticket' );
    ++$txns->FromSQL('Type="Create" AND TicketStatus="__Active__"');
    ++is( $txns->Count, 1, 'Found the 1 create txn of active tickets' );
    ++is( $txns->Next->ObjectId, $bilbo->id, 'Active ticket is bilbo' );
    ++
    ++$txns->FromSQL('Type="Create" AND TicketStatus="__Inactive__"');
    ++is( $txns->Count, 1, 'Found the 1 create txn of inactive tickets' );
    ++is( $txns->Next->ObjectId, $frodo->id, 'Inactive ticket is frodo' );
     +
     +my $cf_age = RT::Test->load_or_create_custom_field(
     +    Name  => 'Age',
4: 116ffe73f2 = 5: f6e4814f80 Add transaction query builder tests
5: 644931a63b = 6: 127c50b88f Add Transactions to query builder docs



More information about the rt-commit mailing list