[Rt-commit] rt branch, 4.2/user-summary, created. rt-4.1.6-377-g918d46a

Alex Vandiver alexmv at bestpractical.com
Wed Mar 20 14:26:17 EDT 2013


The branch, 4.2/user-summary has been created
        at  918d46a1155ee996eeac01a427dcc12097d023a4 (commit)

- Log -----------------------------------------------------------------
commit 5568b7a423573778df73bd666f131ae956cb32d3
Author: Kevin Falcone <falcone at bestpractical.com>
Date:   Thu Mar 7 19:01:03 2013 -0500

    Refector the user searching logic from the Autocompleter into RT::Users
    
    This lets any other front-end user searching borrow the logic (and
    Oracle-aware magic) already present in the autocompleter.

diff --git a/lib/RT/Users.pm b/lib/RT/Users.pm
index 0936449..0391f6f 100644
--- a/lib/RT/Users.pm
+++ b/lib/RT/Users.pm
@@ -566,6 +566,84 @@ sub WhoBelongToGroups {
     }
 }
 
+=head2 SimpleSearch
+
+Does a 'simple' search of Users against a specified Term.
+
+This Term is compared to a number of fields using various types of SQL
+comparison operators.
+
+Ensures that the returned collection of Users will have a value for Return.
+
+This method is passed the following.  You must specify a Term and a Return.
+
+    Privileged - Whether or not to limit to Privileged Users (0 or 1)
+    Fields     - Hashref of data - defaults to C<$UserSearchFields> emulate that if you want to override
+    Term       - String that is in the fields specified by Fields
+    Return     - What field on the User you want to be sure isn't empty
+    Exclude    - Comma separated list of user ids to skip
+    Max        - What to limit this collection to
+
+=cut
+
+sub SimpleSearch {
+    my $self = shift;
+    my %args = (
+        Privileged  => 0,
+        Fields      => RT->Config->Get('UserSearchFields'),
+        Term        => undef,
+        Exclude     => '',
+        Return      => undef,
+        Max         => 10,
+        @_
+    );
+
+    return $self unless defined $args{Return}
+                        and defined $args{Term}
+                        and length $args{Term};
+
+    $self->RowsPerPage( $args{Max} );
+
+    $self->LimitToPrivileged() if $args{Privileged};
+
+    while (my ($name, $op) = each %{$args{Fields}}) {
+        $op = 'STARTSWITH'
+        unless $op =~ /^(?:LIKE|(?:START|END)SWITH|=|!=)$/i;
+
+        $self->Limit(
+            FIELD           => $name,
+            OPERATOR        => $op,
+            VALUE           => $args{Term},
+            ENTRYAGGREGATOR => 'OR',
+            SUBCLAUSE       => 'autocomplete',
+        );
+    }
+
+    # Exclude users we don't want
+    foreach (split /\s*,\s*/, $args{Exclude}) {
+        $self->Limit(FIELD => 'id', VALUE => $_, OPERATOR => '!=');
+    }
+
+    if ( RT->Config->Get('DatabaseType') eq 'Oracle' ) {
+        $self->Limit(
+            FIELD    => $args{Return},
+            OPERATOR => 'IS NOT',
+            VALUE    => 'NULL',
+        );
+    }
+    else {
+        $self->Limit( FIELD => $args{Return}, OPERATOR => '!=', VALUE => '' );
+        $self->Limit(
+            FIELD           => $args{Return},
+            OPERATOR        => 'IS NOT',
+            VALUE           => 'NULL',
+            ENTRYAGGREGATOR => 'AND'
+        );
+    }
+
+    return $self;
+}
+
 
 =head2 NewItem
 
diff --git a/share/html/Helpers/Autocomplete/Users b/share/html/Helpers/Autocomplete/Users
index 5e0fc35..efa824e 100644
--- a/share/html/Helpers/Autocomplete/Users
+++ b/share/html/Helpers/Autocomplete/Users
@@ -91,48 +91,16 @@ my %fields = %{ RT->Config->Get('UserAutocompleteFields')
 # using that operator
 %fields = ( $return => $op ) if $op;
 
-my $users = RT::Users->new( $CurrentUser );
-$users->RowsPerPage( $max );
-
-$users->LimitToPrivileged() if $privileged;
-
-while (my ($name, $op) = each %fields) {
-    $op = 'STARTSWITH'
-        unless $op =~ /^(?:LIKE|(?:START|END)SWITH|=|!=)$/i;
-
-    $users->Limit(
-        FIELD           => $name,
-        OPERATOR        => $op,
-        VALUE           => $term,
-        ENTRYAGGREGATOR => 'OR',
-        SUBCLAUSE       => 'autocomplete',
-    );
-}
-
-# Exclude users we don't want
-foreach (split /\s*,\s*/, $exclude) {
-    $users->Limit(FIELD => 'id', VALUE => $_, OPERATOR => '!=');
-}
+my $users = RT::Users->new($CurrentUser);
+$users->SimpleSearch( Privileged => $privileged,
+                      Return     => $return,
+                      Term       => $term,
+                      Max        => $max,
+                      Exclude    => $exclude,
+                      Fields     => \%fields,
+                    );
 
 my @suggestions;
-
-if ( RT->Config->Get('DatabaseType') eq 'Oracle' ) {
-    $users->Limit(
-        FIELD    => $return,
-        OPERATOR => 'IS NOT',
-        VALUE    => 'NULL',
-    );
-}
-else {
-    $users->Limit( FIELD => $return, OPERATOR => '!=', VALUE => '' );
-    $users->Limit(
-        FIELD           => $return,
-        OPERATOR        => 'IS NOT',
-        VALUE           => 'NULL',
-        ENTRYAGGREGATOR => 'AND'
-    );
-}
-
 while ( my $user = $users->Next ) {
     next if $user->id == RT->SystemUser->id
          or $user->id == RT->Nobody->id;

commit 4c7f8c4f6990d2e5ce5374bb393a37fe60fd5bcb
Author: Kevin Falcone <falcone at bestpractical.com>
Date:   Thu Mar 14 19:38:45 2013 -0400

    Convert Exclude to a list of ids rather than a comma separated list

diff --git a/lib/RT/Users.pm b/lib/RT/Users.pm
index 0391f6f..03bc9b3 100644
--- a/lib/RT/Users.pm
+++ b/lib/RT/Users.pm
@@ -581,7 +581,7 @@ This method is passed the following.  You must specify a Term and a Return.
     Fields     - Hashref of data - defaults to C<$UserSearchFields> emulate that if you want to override
     Term       - String that is in the fields specified by Fields
     Return     - What field on the User you want to be sure isn't empty
-    Exclude    - Comma separated list of user ids to skip
+    Exclude    - Array reference of ids to exclude
     Max        - What to limit this collection to
 
 =cut
@@ -592,7 +592,7 @@ sub SimpleSearch {
         Privileged  => 0,
         Fields      => RT->Config->Get('UserSearchFields'),
         Term        => undef,
-        Exclude     => '',
+        Exclude     => [],
         Return      => undef,
         Max         => 10,
         @_
@@ -620,7 +620,7 @@ sub SimpleSearch {
     }
 
     # Exclude users we don't want
-    foreach (split /\s*,\s*/, $args{Exclude}) {
+    foreach (@{$args{Exclude}}) {
         $self->Limit(FIELD => 'id', VALUE => $_, OPERATOR => '!=');
     }
 
diff --git a/share/html/Helpers/Autocomplete/Users b/share/html/Helpers/Autocomplete/Users
index efa824e..aeda6be 100644
--- a/share/html/Helpers/Autocomplete/Users
+++ b/share/html/Helpers/Autocomplete/Users
@@ -91,12 +91,15 @@ my %fields = %{ RT->Config->Get('UserAutocompleteFields')
 # using that operator
 %fields = ( $return => $op ) if $op;
 
+# the API wants a list of ids
+my @exclude = split /\s*,\s*/, $exclude;
+
 my $users = RT::Users->new($CurrentUser);
 $users->SimpleSearch( Privileged => $privileged,
                       Return     => $return,
                       Term       => $term,
                       Max        => $max,
-                      Exclude    => $exclude,
+                      Exclude    => \@exclude,
                       Fields     => \%fields,
                     );
 

commit 0181e49cd495d19b79afb39fc11dc9aedf071186
Author: Kevin Falcone <falcone at bestpractical.com>
Date:   Thu Mar 14 19:39:28 2013 -0400

    Limit the excludes list by AND
    
    Otherwise this code generates (id != 7 OR id != 9) which returns both 7
    and 9.  In the Group membership page, this meant users who are already
    members were returned in the user autocompleter.
    
    A separate branch 4.0/autocomplete-exclude fixes this for Groups

diff --git a/lib/RT/Users.pm b/lib/RT/Users.pm
index 03bc9b3..cf27993 100644
--- a/lib/RT/Users.pm
+++ b/lib/RT/Users.pm
@@ -621,7 +621,7 @@ sub SimpleSearch {
 
     # Exclude users we don't want
     foreach (@{$args{Exclude}}) {
-        $self->Limit(FIELD => 'id', VALUE => $_, OPERATOR => '!=');
+        $self->Limit(FIELD => 'id', VALUE => $_, OPERATOR => '!=', ENTRYAGGREGATOR => 'AND');
     }
 
     if ( RT->Config->Get('DatabaseType') eq 'Oracle' ) {

commit f1a019c53d29455c6de51429097ebd9aa1d48913
Author: Kevin Falcone <falcone at bestpractical.com>
Date:   Thu Mar 14 19:51:25 2013 -0400

    Exclude Nobody and RT_System in SQL
    
    Instead of skipping these in perl, push the restriction down into SQL
    via RT::Users->SimpleSearch.

diff --git a/share/html/Helpers/Autocomplete/Users b/share/html/Helpers/Autocomplete/Users
index aeda6be..b7f2dc5 100644
--- a/share/html/Helpers/Autocomplete/Users
+++ b/share/html/Helpers/Autocomplete/Users
@@ -93,6 +93,7 @@ my %fields = %{ RT->Config->Get('UserAutocompleteFields')
 
 # the API wants a list of ids
 my @exclude = split /\s*,\s*/, $exclude;
+push @exclude, RT->SystemUser->id, RT->Nobody->id;
 
 my $users = RT::Users->new($CurrentUser);
 $users->SimpleSearch( Privileged => $privileged,
@@ -105,9 +106,6 @@ $users->SimpleSearch( Privileged => $privileged,
 
 my @suggestions;
 while ( my $user = $users->Next ) {
-    next if $user->id == RT->SystemUser->id
-         or $user->id == RT->Nobody->id;
-
     my $suggestion = { label => $user->Format, value => $user->$return };
     $m->callback( CallbackName => "ModifySuggestion", suggestion => $suggestion, user => $user );
     push @suggestions, $suggestion;

commit a0a7815ca9d8add07918d4070da3d8e418ed3b88
Author: Kevin Falcone <falcone at bestpractical.com>
Date:   Thu Mar 7 18:12:08 2013 -0500

    Provide a simple, publicly accessible, user search
    
    The results are currently unlinked, as there is no non-admin page about
    a user to link to.

diff --git a/etc/RT_Config.pm.in b/etc/RT_Config.pm.in
index d3fd15a..a878075 100755
--- a/etc/RT_Config.pm.in
+++ b/etc/RT_Config.pm.in
@@ -943,6 +943,20 @@ RealName and EmailAddress.
 
 Set($UsernameFormat, "concise");
 
+=item C<$UserSearchResultFormat>
+
+This controls the display of lists of users returned from the User
+Summary Search. The display of users in the Admin interface is
+controlled by C<%AdminSearchResultFormat>.
+
+=cut
+
+Set($UserSearchResultFormat,
+         q{ __id__}
+        .q{,__Name__}
+        .q{,__RealName__, __EmailAddress__}
+);
+
 =item C<$WebBaseURL>, C<$WebURL>
 
 Usually you don't want to set these options. The only obvious reason
diff --git a/share/html/Elements/Tabs b/share/html/Elements/Tabs
index 66082b8..caaefdc 100644
--- a/share/html/Elements/Tabs
+++ b/share/html/Elements/Tabs
@@ -491,6 +491,8 @@ my $build_main_nav = sub {
 
     $search->child( articles => title => loc('Articles'),   path => "/Articles/Article/Search.html" );
 
+    $search->child( users => title => loc('Users'),   path => "/User/Search.html" );
+
 
     my $tools = Menu->child( tools => title => loc('Tools'), path => '/Tools/index.html' );
     my $articles = $tools->child( articles => title => loc('Articles'), path => "/Articles/index.html");
diff --git a/share/html/User/Search.html b/share/html/User/Search.html
new file mode 100644
index 0000000..67115c8
--- /dev/null
+++ b/share/html/User/Search.html
@@ -0,0 +1,108 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2013 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 }}}
+<& /Elements/Header, Title => loc('User Search') &>
+<& /Elements/Tabs &>
+    
+<form name="UserSearch" method="post" action="<% RT->Config->Get('WebPath') %>/User/Search.html">
+<input type="text" name="UserString" value="" id="autocomplete-UserString" />
+<script type="text/javascript">
+jQuery(function(){
+    jQuery("#autocomplete-UserString").autocomplete({
+        source: RT.Config.WebPath + "/Helpers/Autocomplete/Users?return=Name",
+        // Auto-submit once a user is chosen
+        select: function( event, ui ) {
+            jQuery(event.target).val(ui.item.value);
+            var form = jQuery(event.target).closest('form');
+            form.submit();
+        }
+    });
+});
+</script>
+<input type="submit" name="UserSearch" value="<&|/l&>Search</&>" class="button" />
+</form>
+
+<p> <&|/l&>This will search for users by looking in the following fields:</&> <% $search_fields %></p>
+
+% if ($UserString) {
+
+% unless ( $users->Count ) {
+<p><&|/l&>No users matching search criteria found.</&></p>
+% } else {
+<p><&|/l&>Select a user</&>:</p>
+
+<& /Elements/CollectionList,
+    OrderBy => 'Name',
+    Order => 'ASC',
+    Rows  => 100,
+    %ARGS,
+    Format => $Format,
+    Collection => $users,
+    AllowSorting => 1,
+    PassArguments => [qw(Format Rows Page Order OrderBy q)],
+&>
+
+% }
+% }
+
+<%INIT>
+
+my $exclude = [RT->Nobody->Id, RT->System->Id];
+my $users = RT::Users->new($session{'CurrentUser'});
+$users->SimpleSearch( Return    => 'Name',
+                      Term      => $UserString,
+                      Max       => 100,
+                      Exclude   => $exclude );
+
+my $Format = RT->Config->Get('UserSearchResultFormat');
+
+my $search_fields = join ", ", map loc($_), keys %{RT->Config->Get('UserAutocompleteFields')};
+
+</%INIT>
+<%ARGS>
+$UserString => undef
+</%ARGS>

commit 50b1d371b29be241125212ed96df76b531ebe5bb
Author: Kevin Falcone <falcone at bestpractical.com>
Date:   Thu Mar 7 19:39:10 2013 -0500

    Rename UserAutocompleteFields to UserSearchFields
    
    Now the configuration option is used in two places, it is misleading to
    call it by a name containing "Autocomplete."
    
    Log loudly about rename, but also be nice and make it "just work."

diff --git a/etc/RT_Config.pm.in b/etc/RT_Config.pm.in
index a878075..c9aeb2d 100755
--- a/etc/RT_Config.pm.in
+++ b/etc/RT_Config.pm.in
@@ -1375,7 +1375,9 @@ is ignored. Helpful when owners list is huge in the query builder.
 
 Set($AutocompleteOwnersForSearch, 0);
 
-=item C<$UserAutocompleteFields>
+=item C<$UserSearchFields>
+
+Used by the User Autocompleter as well as the User Search.
 
 Specifies which fields of L<RT::User> to match against and how to
 match each field when autocompleting users.  Valid match methods are
@@ -1383,7 +1385,7 @@ LIKE, STARTSWITH, ENDSWITH, =, and !=.
 
 =cut
 
-Set($UserAutocompleteFields, {
+Set($UserSearchFields, {
     EmailAddress => 'STARTSWITH',
     Name         => 'STARTSWITH',
     RealName     => 'LIKE',
diff --git a/lib/RT/Config.pm b/lib/RT/Config.pm
index 6675137..10fff8e 100644
--- a/lib/RT/Config.pm
+++ b/lib/RT/Config.pm
@@ -780,6 +780,25 @@ our %META = (
                 if $self->Meta('LogToScreen')->{'Source'}{'Package'};
         },
     },
+    UserAutocompleteFields => {
+        PostSet => sub {
+            my $self  = shift;
+            my $value = shift;
+            $self->SetFromConfig(
+                Option => \'UserSearchFields',
+                Value  => [$value],
+                %{$self->Meta('UserAutocompleteFields')->{'Source'}}
+            );
+        },
+        PostLoadCheck => sub {
+            my $self = shift;
+            RT->Deprecated(
+                Message => '$UserAutocompleteFields is deprecated',
+                Instead => '$UserSearchFields',
+                Remove => "4.4"
+            ) if $self->Meta('UserAutocompleteFields')->{'Source'}{'Package'};
+        },
+    },
     CustomFieldGroupings => {
         Type            => 'HASH',
         PostLoadCheck   => sub {
diff --git a/share/html/Helpers/Autocomplete/Users b/share/html/Helpers/Autocomplete/Users
index b7f2dc5..b80a604 100644
--- a/share/html/Helpers/Autocomplete/Users
+++ b/share/html/Helpers/Autocomplete/Users
@@ -84,7 +84,7 @@ my $CurrentUser = $session{'CurrentUser'};
 $m->abort unless $CurrentUser->Privileged
               or RT->Config->Get('AllowUserAutocompleteForUnprivileged');
 
-my %fields = %{ RT->Config->Get('UserAutocompleteFields')
+my %fields = %{ RT->Config->Get('UserSearchFields')
                 || { EmailAddress => 1, Name => 1, RealName => 'LIKE' } };
 
 # If an operator is provided, check against only the returned field
diff --git a/share/html/User/Search.html b/share/html/User/Search.html
index 67115c8..683e196 100644
--- a/share/html/User/Search.html
+++ b/share/html/User/Search.html
@@ -100,7 +100,7 @@ $users->SimpleSearch( Return    => 'Name',
 
 my $Format = RT->Config->Get('UserSearchResultFormat');
 
-my $search_fields = join ", ", map loc($_), keys %{RT->Config->Get('UserAutocompleteFields')};
+my $search_fields = join ", ", map loc($_), keys %{RT->Config->Get('UserSearchFields')};
 
 </%INIT>
 <%ARGS>

commit e7c82945ae344c95ed129dcbec54393f31b1e11b
Author: Kevin Falcone <falcone at bestpractical.com>
Date:   Thu Mar 7 19:02:45 2013 -0500

    Make user search "sticky"

diff --git a/share/html/User/Search.html b/share/html/User/Search.html
index 683e196..9831821 100644
--- a/share/html/User/Search.html
+++ b/share/html/User/Search.html
@@ -49,7 +49,7 @@
 <& /Elements/Tabs &>
     
 <form name="UserSearch" method="post" action="<% RT->Config->Get('WebPath') %>/User/Search.html">
-<input type="text" name="UserString" value="" id="autocomplete-UserString" />
+<input type="text" name="UserString" value="<% $UserString||'' %>" id="autocomplete-UserString" />
 <script type="text/javascript">
 jQuery(function(){
     jQuery("#autocomplete-UserString").autocomplete({

commit 4a7ec2b40bb05257bdbccfc4d7e4b342eab74c95
Author: Kevin Falcone <falcone at bestpractical.com>
Date:   Thu Mar 7 19:07:28 2013 -0500

    Focus the search box by default when loading the User Search

diff --git a/share/html/User/Search.html b/share/html/User/Search.html
index 9831821..c4c19f9 100644
--- a/share/html/User/Search.html
+++ b/share/html/User/Search.html
@@ -45,7 +45,7 @@
 %# those contributions and any derivatives thereof.
 %#
 %# END BPS TAGGED BLOCK }}}
-<& /Elements/Header, Title => loc('User Search') &>
+<& /Elements/Header, Title => loc('User Search'), Focus => 'autocomplete-UserString' &>
 <& /Elements/Tabs &>
     
 <form name="UserSearch" method="post" action="<% RT->Config->Get('WebPath') %>/User/Search.html">

commit bd6d3e36b4cf314d43495f7ee3905b9310722fcc
Author: Kevin Falcone <falcone at bestpractical.com>
Date:   Mon Mar 18 21:02:13 2013 -0400

    Factor out the user searching widget

diff --git a/share/html/User/Search.html b/share/html/Elements/GotoUser
similarity index 69%
copy from share/html/User/Search.html
copy to share/html/Elements/GotoUser
index c4c19f9..482f018 100644
--- a/share/html/User/Search.html
+++ b/share/html/Elements/GotoUser
@@ -45,11 +45,8 @@
 %# those contributions and any derivatives thereof.
 %#
 %# END BPS TAGGED BLOCK }}}
-<& /Elements/Header, Title => loc('User Search'), Focus => 'autocomplete-UserString' &>
-<& /Elements/Tabs &>
-    
 <form name="UserSearch" method="post" action="<% RT->Config->Get('WebPath') %>/User/Search.html">
-<input type="text" name="UserString" value="<% $UserString||'' %>" id="autocomplete-UserString" />
+<input type="text" name="UserString" value="<% $Default %>" id="autocomplete-UserString" />
 <script type="text/javascript">
 jQuery(function(){
     jQuery("#autocomplete-UserString").autocomplete({
@@ -65,44 +62,6 @@ jQuery(function(){
 </script>
 <input type="submit" name="UserSearch" value="<&|/l&>Search</&>" class="button" />
 </form>
-
-<p> <&|/l&>This will search for users by looking in the following fields:</&> <% $search_fields %></p>
-
-% if ($UserString) {
-
-% unless ( $users->Count ) {
-<p><&|/l&>No users matching search criteria found.</&></p>
-% } else {
-<p><&|/l&>Select a user</&>:</p>
-
-<& /Elements/CollectionList,
-    OrderBy => 'Name',
-    Order => 'ASC',
-    Rows  => 100,
-    %ARGS,
-    Format => $Format,
-    Collection => $users,
-    AllowSorting => 1,
-    PassArguments => [qw(Format Rows Page Order OrderBy q)],
-&>
-
-% }
-% }
-
-<%INIT>
-
-my $exclude = [RT->Nobody->Id, RT->System->Id];
-my $users = RT::Users->new($session{'CurrentUser'});
-$users->SimpleSearch( Return    => 'Name',
-                      Term      => $UserString,
-                      Max       => 100,
-                      Exclude   => $exclude );
-
-my $Format = RT->Config->Get('UserSearchResultFormat');
-
-my $search_fields = join ", ", map loc($_), keys %{RT->Config->Get('UserSearchFields')};
-
-</%INIT>
 <%ARGS>
-$UserString => undef
+$Default => ''
 </%ARGS>
diff --git a/share/html/User/Search.html b/share/html/User/Search.html
index c4c19f9..38ef044 100644
--- a/share/html/User/Search.html
+++ b/share/html/User/Search.html
@@ -48,23 +48,7 @@
 <& /Elements/Header, Title => loc('User Search'), Focus => 'autocomplete-UserString' &>
 <& /Elements/Tabs &>
     
-<form name="UserSearch" method="post" action="<% RT->Config->Get('WebPath') %>/User/Search.html">
-<input type="text" name="UserString" value="<% $UserString||'' %>" id="autocomplete-UserString" />
-<script type="text/javascript">
-jQuery(function(){
-    jQuery("#autocomplete-UserString").autocomplete({
-        source: RT.Config.WebPath + "/Helpers/Autocomplete/Users?return=Name",
-        // Auto-submit once a user is chosen
-        select: function( event, ui ) {
-            jQuery(event.target).val(ui.item.value);
-            var form = jQuery(event.target).closest('form');
-            form.submit();
-        }
-    });
-});
-</script>
-<input type="submit" name="UserSearch" value="<&|/l&>Search</&>" class="button" />
-</form>
+<& /Elements/GotoUser, Default => $UserString||'' &>
 
 <p> <&|/l&>This will search for users by looking in the following fields:</&> <% $search_fields %></p>
 

commit d843fe2430d732a573e1237389a259f02b63453c
Author: Kevin Falcone <falcone at bestpractical.com>
Date:   Thu Mar 7 18:15:16 2013 -0500

    Add a User Summary page
    
    Shows the user search again, followed by a list of portlets specified in
    UserSummaryPortlets.  No user customization is available, just a simple
    list of things to display.

diff --git a/etc/RT_Config.pm.in b/etc/RT_Config.pm.in
index c9aeb2d..b397844 100755
--- a/etc/RT_Config.pm.in
+++ b/etc/RT_Config.pm.in
@@ -952,11 +952,21 @@ controlled by C<%AdminSearchResultFormat>.
 =cut
 
 Set($UserSearchResultFormat,
-         q{ __id__}
-        .q{,__Name__}
+         q{ '<a href="__WebPath__/User/Summary.html?id=__id__">__id__</a>/TITLE:#'}
+        .q{,'<a href="__WebPath__/User/Summary.html?id=__id__">__Name__</a>/TITLE:Name'}
         .q{,__RealName__, __EmailAddress__}
 );
 
+=item C<@UserSummaryPortlets>
+
+A list of portlets to be displayed on the User Summary page.
+By default, we show all of the available portlets.
+Extensions may provide their own portlets for this page.
+
+=cut
+
+Set(@UserSummaryPortlets, (qw//));
+
 =item C<$WebBaseURL>, C<$WebURL>
 
 Usually you don't want to set these options. The only obvious reason
diff --git a/share/html/User/Summary.html b/share/html/User/Summary.html
new file mode 100644
index 0000000..473e24c
--- /dev/null
+++ b/share/html/User/Summary.html
@@ -0,0 +1,87 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2013 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 }}}
+<& /Elements/Header, Title => loc('User: [_1]', $User->Format) &>
+<& /Elements/Tabs &>
+    
+<& /Elements/GotoUser &>
+
+<%perl>
+$m->callback( CallbackName => 'BeforePortlets', User => $User );
+for my $portlet (@$portlets) {
+    $show_portlet->($portlet);
+}
+$m->callback( CallbackName => 'AfterPortlets', User => $User );
+</%perl>
+
+<%INIT>
+my $User = RT::User->new( $session{'CurrentUser'} );
+my ($status, $msg) = $User->Load($id);
+unless ($status) {
+    RT->Logger->error("Unable to load user $id: $msg");
+    Abort("Unable to load User $id");
+}
+
+my $portlets = RT->Config->Get('UserSummaryPortlets');
+
+my $show_portlet = sub {
+    my $portlet = shift;
+    my $full_path = "/User/Elements/Portlets/$portlet";
+    unless ( RT::Interface::Web->ComponentPathIsSafe($full_path) ) {
+        RT->Logger->error("unsafe portlet $portlet specified in UserSummaryPortlets");
+        return;
+    }
+    unless ( $m->comp_exists($full_path) ) {
+        RT->Logger->error("Unable to find $portlet in /User/Elements/Portlets - specified in UserSummaryPortlets");
+        return;
+    }
+    $m->comp( $full_path, User => $User );
+};
+</%INIT>
+<%ARGS>
+$id => undef
+</%ARGS>

commit 99c6bfbb68af1a87f913c1fddc41da760001d38a
Author: Kevin Falcone <falcone at bestpractical.com>
Date:   Mon Mar 18 21:06:42 2013 -0400

    Jump directly to a user if selected by autocomplete

diff --git a/share/html/Elements/GotoUser b/share/html/Elements/GotoUser
index 482f018..94cf526 100644
--- a/share/html/Elements/GotoUser
+++ b/share/html/Elements/GotoUser
@@ -47,14 +47,15 @@
 %# END BPS TAGGED BLOCK }}}
 <form name="UserSearch" method="post" action="<% RT->Config->Get('WebPath') %>/User/Search.html">
 <input type="text" name="UserString" value="<% $Default %>" id="autocomplete-UserString" />
+<input type="hidden" name="UserName" value="">
 <script type="text/javascript">
 jQuery(function(){
     jQuery("#autocomplete-UserString").autocomplete({
         source: RT.Config.WebPath + "/Helpers/Autocomplete/Users?return=Name",
         // Auto-submit once a user is chosen
         select: function( event, ui ) {
-            jQuery(event.target).val(ui.item.value);
             var form = jQuery(event.target).closest('form');
+            form.find('input[name=UserName]').val(ui.item.value);
             form.submit();
         }
     });
diff --git a/share/html/User/Search.html b/share/html/User/Search.html
index 38ef044..530467f 100644
--- a/share/html/User/Search.html
+++ b/share/html/User/Search.html
@@ -75,6 +75,16 @@
 
 <%INIT>
 
+if ($UserName) {
+    my $user = RT::User->new( $session{'CurrentUser'} );
+    my ($status, $msg) = $user->Load($UserName);
+    if ($status) {
+        RT::Interface::Web::Redirect(RT->Config->Get('WebURL')."User/Summary.html?id=".$user->Id);
+    } else {
+        RT->Logger->error("Unable to load $UserName: $msg");
+    }
+}
+
 my $exclude = [RT->Nobody->Id, RT->System->Id];
 my $users = RT::Users->new($session{'CurrentUser'});
 $users->SimpleSearch( Return    => 'Name',
@@ -89,4 +99,5 @@ my $search_fields = join ", ", map loc($_), keys %{RT->Config->Get('UserSearchFi
 </%INIT>
 <%ARGS>
 $UserString => undef
+$UserName   => undef
 </%ARGS>

commit e8dfbee61cf53ef3237033f6e95289f4de429d4d
Author: Kevin Falcone <falcone at bestpractical.com>
Date:   Thu Mar 7 18:19:35 2013 -0500

    Add an ExtraInfo User portlet
    
    A thin wrapper around Elements/User/ExtraInfo, this uses the
    UserSummaryExtraInfo config to control how much data you want on your
    User Summary.  It seems natural that you might list 4 or 5 attributes in
    More About Requestors and then list more here.

diff --git a/etc/RT_Config.pm.in b/etc/RT_Config.pm.in
index b397844..bd00dd8 100755
--- a/etc/RT_Config.pm.in
+++ b/etc/RT_Config.pm.in
@@ -965,7 +965,20 @@ Extensions may provide their own portlets for this page.
 
 =cut
 
-Set(@UserSummaryPortlets, (qw//));
+Set(@UserSummaryPortlets, (qw/ExtraInfo/));
+
+=item C<$UserSummaryExtraInfo>
+
+This controls what information is displayed on the User Summary
+portal. By default the user's Real Name, Email Address and Username
+are displayed. You can remove these or add more as needed. This
+expects a Format string of user attributes. Please note that not all
+the attributes are supported in this display because we're not
+building a table.
+
+=cut
+
+Set($UserSummaryExtraInfo, "RealName, EmailAddress, Name");
 
 =item C<$WebBaseURL>, C<$WebURL>
 
diff --git a/share/html/User/Elements/Portlets/ExtraInfo b/share/html/User/Elements/Portlets/ExtraInfo
new file mode 100644
index 0000000..1578005
--- /dev/null
+++ b/share/html/User/Elements/Portlets/ExtraInfo
@@ -0,0 +1,58 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2013 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 }}}
+<&| /Widgets/TitleBox, title => loc('User Information') &>
+<div class="details">
+
+% $m->callback( User => $User, CallbackName => 'BeforeExtraInfo' );
+<& /User/Elements/UserInfo, User => $User, FormatConfig => 'UserSummaryExtraInfo', ClassPrefix => 'user-summary' &>
+
+</div>
+</&>
+<%ARGS>
+$User
+</%ARGS>

commit 017f6c38dd3392c004b13a52f0787fa4397cea76
Author: Kevin Falcone <falcone at bestpractical.com>
Date:   Thu Mar 7 18:21:08 2013 -0500

    Add user portlets for Active and Inactive tickets
    
    Controllable by the UserSummaryTicketListFormat, and displayed by
    default on the User Summary.

diff --git a/etc/RT_Config.pm.in b/etc/RT_Config.pm.in
index bd00dd8..0c5d3e6 100755
--- a/etc/RT_Config.pm.in
+++ b/etc/RT_Config.pm.in
@@ -965,7 +965,7 @@ Extensions may provide their own portlets for this page.
 
 =cut
 
-Set(@UserSummaryPortlets, (qw/ExtraInfo/));
+Set(@UserSummaryPortlets, (qw/ExtraInfo ActiveTickets InactiveTickets/));
 
 =item C<$UserSummaryExtraInfo>
 
@@ -980,6 +980,29 @@ building a table.
 
 Set($UserSummaryExtraInfo, "RealName, EmailAddress, Name");
 
+=item C<$UserSummaryTicketListFormat>
+
+Control the appearance of the Active and Inactive ticket lists in the
+User Summary.
+
+=cut
+
+Set($UserSummaryTicketListFormat, q{
+       '<B><A HREF="__WebPath__/Ticket/Display.html?id=__id__">__id__</a></B>/TITLE:#',
+       '<B><A HREF="__WebPath__/Ticket/Display.html?id=__id__">__Subject__</a></B>/TITLE:Subject',
+       Status,
+       QueueName,
+       OwnerName,
+       Priority,
+       '__NEWLINE__',
+       '',
+       '<small>__Requestors__</small>',
+       '<small>__CreatedRelative__</small>',
+       '<small>__ToldRelative__</small>',
+       '<small>__LastUpdatedRelative__</small>',
+       '<small>__TimeLeft__</small>'
+});
+
 =item C<$WebBaseURL>, C<$WebURL>
 
 Usually you don't want to set these options. The only obvious reason
diff --git a/share/html/User/Elements/Portlets/ActiveTickets b/share/html/User/Elements/Portlets/ActiveTickets
new file mode 100644
index 0000000..7756d8d
--- /dev/null
+++ b/share/html/User/Elements/Portlets/ActiveTickets
@@ -0,0 +1,68 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2013 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 }}}
+<& /User/Elements/TicketList ,
+    User => $User,
+    conditions => $conditions,
+    Rows => $Rows,
+    WatcherTypes => [qw(Watcher)],
+    Title => loc('Active Tickets'),
+    TitleBox => 1,
+    Format => RT->Config->Get('UserSummaryTicketListFormat'),
+&>
+<%INIT>
+unless ( @$conditions ) {
+    foreach (RT::Queue->ActiveStatusArray()) {
+        push @$conditions, { cond => "Status = '$_'", name => loc($_) };
+    }
+}
+</%INIT>
+<%ARGS>
+$User => undef
+$conditions => []
+$Rows => 10
+</%ARGS>
diff --git a/share/html/User/Elements/Portlets/InactiveTickets b/share/html/User/Elements/Portlets/InactiveTickets
new file mode 100644
index 0000000..d13692d
--- /dev/null
+++ b/share/html/User/Elements/Portlets/InactiveTickets
@@ -0,0 +1,68 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2013 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 }}}
+<& /User/Elements/TicketList ,
+    User => $User,
+    conditions => $conditions,
+    Rows => $Rows,
+    WatcherTypes => [qw(Watcher)],
+    Title => loc('Inactive Tickets'),
+    TitleBox => 1,
+    Format => RT->Config->Get('UserSummaryTicketListFormat'),
+&>
+<%INIT>
+unless ( @$conditions ) {
+    foreach (RT::Queue->InactiveStatusArray()) {
+        push @$conditions, { cond => "Status = '$_'", name => loc($_) };
+    }
+}
+</%INIT>
+<%ARGS>
+$User => undef
+$conditions => []
+$Rows => 10
+</%ARGS>

commit ab188ee0361a1655b769b48f030d6b2cc7e2c5d4
Author: Kevin Falcone <falcone at bestpractical.com>
Date:   Thu Mar 7 20:21:42 2013 -0500

    Add a simple Create Ticket user portlet
    
    Tickets thus created sets the user as the Requestor

diff --git a/etc/RT_Config.pm.in b/etc/RT_Config.pm.in
index 0c5d3e6..279103c 100755
--- a/etc/RT_Config.pm.in
+++ b/etc/RT_Config.pm.in
@@ -965,7 +965,7 @@ Extensions may provide their own portlets for this page.
 
 =cut
 
-Set(@UserSummaryPortlets, (qw/ExtraInfo ActiveTickets InactiveTickets/));
+Set(@UserSummaryPortlets, (qw/ExtraInfo CreateTicket ActiveTickets InactiveTickets/));
 
 =item C<$UserSummaryExtraInfo>
 
diff --git a/share/html/User/Elements/Portlets/CreateTicket b/share/html/User/Elements/Portlets/CreateTicket
new file mode 100644
index 0000000..421bb4f
--- /dev/null
+++ b/share/html/User/Elements/Portlets/CreateTicket
@@ -0,0 +1,60 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2013 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 }}}
+<div class="quick-create user">
+<&| /Widgets/TitleBox, title => loc('Quick ticket creation') &>
+<form action="<%RT->Config->Get('WebPath')%>/Ticket/Create.html">
+<&|/l&>Create a ticket with this user as the Requestor</&>
+<input type="hidden" name="Requestors" value="<%$User->EmailAddress%>">
+<& /Elements/SelectNewTicketQueue &>
+<input type="submit" name="Create">
+</form>
+</&>
+</div>
+<%ARGS>
+$User
+</%ARGS>

commit 918d46a1155ee996eeac01a427dcc12097d023a4
Author: Kevin Falcone <falcone at bestpractical.com>
Date:   Tue Mar 12 20:11:42 2013 -0400

    Show Titles for ticket lists on the User Summary
    
    While "More About Requestor" may wish a more concise format, headings
    are of use for a full-page display.

diff --git a/share/html/User/Elements/Portlets/ActiveTickets b/share/html/User/Elements/Portlets/ActiveTickets
index 7756d8d..35e9a0f 100644
--- a/share/html/User/Elements/Portlets/ActiveTickets
+++ b/share/html/User/Elements/Portlets/ActiveTickets
@@ -52,6 +52,7 @@
     WatcherTypes => [qw(Watcher)],
     Title => loc('Active Tickets'),
     TitleBox => 1,
+    ShowHeader => 1,
     Format => RT->Config->Get('UserSummaryTicketListFormat'),
 &>
 <%INIT>
diff --git a/share/html/User/Elements/Portlets/InactiveTickets b/share/html/User/Elements/Portlets/InactiveTickets
index d13692d..0c4e8d2 100644
--- a/share/html/User/Elements/Portlets/InactiveTickets
+++ b/share/html/User/Elements/Portlets/InactiveTickets
@@ -52,6 +52,7 @@
     WatcherTypes => [qw(Watcher)],
     Title => loc('Inactive Tickets'),
     TitleBox => 1,
+    ShowHeader => 1,
     Format => RT->Config->Get('UserSummaryTicketListFormat'),
 &>
 <%INIT>

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


More information about the Rt-commit mailing list