[Rt-commit] rt branch, 4.2/user-summary, created. rt-4.1.6-361-g7dd97c5

Kevin Falcone falcone at bestpractical.com
Thu Mar 14 20:13:13 EDT 2013


The branch, 4.2/user-summary has been created
        at  7dd97c5cf84328fec6228eeafab85bfbf79329dc (commit)

- Log -----------------------------------------------------------------
commit 0f0dbfac01e60e050246f8cbad25eb18c1504250
Author: Kevin Falcone <falcone at bestpractical.com>
Date:   Thu Mar 7 18:05:19 2013 -0500

    Small PageWidget for searching for users
    
    Uses the normal user autocomplete endpoint.

diff --git a/share/html/Elements/GotoUser b/share/html/Elements/GotoUser
new file mode 100644
index 0000000..6527381
--- /dev/null
+++ b/share/html/Elements/GotoUser
@@ -0,0 +1,72 @@
+%# 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 }}}
+<form name="UserSearch" method="post" action="<% RT->Config->Get('WebPath') %>/User/Search.html">
+<input type="text" name="UserString" value="" id="autocomplete-UserString" />
+<input type="hidden" name="UserName" value="">
+<script type="text/javascript">
+jQuery(function(){
+    jQuery("#autocomplete-UserString").autocomplete({
+        source: <% RT->Config->Get('WebPath') |n,j%>+"/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();
+        }
+    });
+});
+</script>
+% if ($Button) {
+  <input type="submit" name="UserSearch" value="<&|/l&>Search</&>" class="button" />
+%#  <& /Elements/Submit, Label => 'Search' &>
+% }
+</form>
+<%ARGS>
+$Button => undef,
+</%ARGS>

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

    Simple User Search
    
    Embeds the GotoUser widget and redirects off to a User Summary once a
    username has been chosen

diff --git a/share/html/User/Search.html b/share/html/User/Search.html
new file mode 100644
index 0000000..b003904
--- /dev/null
+++ b/share/html/User/Search.html
@@ -0,0 +1,71 @@
+%# 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 &>
+    
+<& /Elements/GotoUser, Button => 1 &>
+<p> <&|/l&>This will search for users by looking in the following fields:</&> <% $search_fields %></p>
+
+<%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 $search_fields = join ", ", map loc($_), keys %{RT->Config->Get('UserAutocompleteFields')};
+
+</%INIT>
+<%ARGS>
+$UserString => undef,
+$UserName   => undef,
+</%ARGS>

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

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

diff --git a/etc/RT_Config.pm.in b/etc/RT_Config.pm.in
index d3fd15a..73c444f 100755
--- a/etc/RT_Config.pm.in
+++ b/etc/RT_Config.pm.in
@@ -943,6 +943,16 @@ RealName and EmailAddress.
 
 Set($UsernameFormat, "concise");
 
+=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/ExtraInfo ActiveTickets InactiveTickets/));
+
 =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..034228f
--- /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 Summary') &>
+<& /Elements/Tabs &>
+    
+<& /Elements/GotoUser, Button => 1 &>
+
+% $m->callback( CallbackName => 'BeforePortlets', User => $User );
+
+% for my $portlet (@$portlets) {
+    <% $show_portlet->($portlet) %>
+% }
+
+% $m->callback( CallbackName => 'AfterPortlets', User => $User );
+
+<%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 3779d242311a935f2dfc60283a276a4299b0c36f
Author: Kevin Falcone <falcone at bestpractical.com>
Date:   Thu Mar 7 18:19:35 2013 -0500

    ExtraInfo User portlet
    
    Thin wrapper around Elements/User/ExtraInfo, 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 73c444f..869a9ee 100755
--- a/etc/RT_Config.pm.in
+++ b/etc/RT_Config.pm.in
@@ -943,6 +943,19 @@ RealName and EmailAddress.
 
 Set($UsernameFormat, "concise");
 
+=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<@UserSummaryPortlets>
 
 A list of portlets to be displayed on the User Summary page.
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 e5a2453b4e4856c2abf46a2eaf7aafeac3f36c63
Author: Kevin Falcone <falcone at bestpractical.com>
Date:   Thu Mar 7 18:21:08 2013 -0500

    Active and Inactive ticket lists for a given user
    
    Controllable by the UserSummaryTicketListFormat, displayed by default on
    the User Summary

diff --git a/etc/RT_Config.pm.in b/etc/RT_Config.pm.in
index 869a9ee..89c7375 100755
--- a/etc/RT_Config.pm.in
+++ b/etc/RT_Config.pm.in
@@ -966,6 +966,20 @@ Extensions may provide their own portlets for this page.
 
 Set(@UserSummaryPortlets, (qw/ExtraInfo ActiveTickets InactiveTickets/));
 
+=item C<$UserSummaryTicketListFormat>
+
+Control the appearance of the Active and Inactive ticket lists in the
+User Summary.
+
+=cut
+
+Set($UserSummaryTicketListFormat, q{
+       '<a href="__WebPath__/Ticket/Display.html?id=__id__">__id__</a>',
+       '(__OwnerName__)',
+       '<a href="__WebPath__/Ticket/Display.html?id=__id__">__Subject__</a>',
+       '__Status__',
+});
+
 =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 1c381fd5dc65d502edcc9f365596c768945ee0e5
Author: Kevin Falcone <falcone at bestpractical.com>
Date:   Thu Mar 7 19:02:45 2013 -0500

    Allow you to pass in a default
    
    This lets me replicate Simple Search's 'sticky' searching which I find
    invaluable.

diff --git a/share/html/Elements/GotoUser b/share/html/Elements/GotoUser
index 6527381..f662a38 100644
--- a/share/html/Elements/GotoUser
+++ b/share/html/Elements/GotoUser
@@ -46,7 +46,7 @@
 %#
 %# END BPS TAGGED BLOCK }}}
 <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="<% $Default %>" id="autocomplete-UserString" />
 <input type="hidden" name="UserName" value="">
 <script type="text/javascript">
 jQuery(function(){
@@ -68,5 +68,6 @@ jQuery(function(){
 % }
 </form>
 <%ARGS>
-$Button => undef,
+$Button  => undef
+$Default => ''
 </%ARGS>
diff --git a/share/html/User/Search.html b/share/html/User/Search.html
index b003904..43c9ac4 100644
--- a/share/html/User/Search.html
+++ b/share/html/User/Search.html
@@ -48,7 +48,7 @@
 <& /Elements/Header, Title => loc('User Search') &>
 <& /Elements/Tabs &>
     
-<& /Elements/GotoUser, Button => 1 &>
+<& /Elements/GotoUser, Button => 1, Default => $UserString||'' &>
 <p> <&|/l&>This will search for users by looking in the following fields:</&> <% $search_fields %></p>
 
 <%INIT>

commit dedca491e4dce4f18cc438f306c9910884d273c4
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 43c9ac4..b852dea 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 &>
     
 <& /Elements/GotoUser, Button => 1, Default => $UserString||'' &>

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

    Rip out the central user searching logic from the Autocompleter
    
    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;
diff --git a/share/html/Helpers/Autocomplete/Users b/share/html/User/Elements/Search
similarity index 65%
copy from share/html/Helpers/Autocomplete/Users
copy to share/html/User/Elements/Search
index 5e0fc35..ee35449 100644
--- a/share/html/Helpers/Autocomplete/Users
+++ b/share/html/User/Elements/Search
@@ -45,58 +45,18 @@
 %# those contributions and any derivatives thereof.
 %#
 %# END BPS TAGGED BLOCK }}}
-% $r->content_type('application/json; charset=utf-8');
-<% JSON( \@suggestions ) |n %>
-% $m->abort;
-<%ARGS>
-$return => ''
-$term => undef
-$delim => undef
-$max => 10
-$privileged => undef
-$exclude => ''
-$op => undef
-</%ARGS>
 <%INIT>
-# Only allow certain return fields
-$return = 'EmailAddress'
-    unless $return =~ /^(?:EmailAddress|Name|RealName)$/;
-
-$m->abort unless defined $return
-             and defined $term
-             and length $term;
-
-# Use our delimeter if we have one
-if ( defined $delim and length $delim ) {
-    if ( $delim eq ',' ) {
-        $delim = qr/,\s*/;
-    } else {
-        $delim = qr/\Q$delim\E/;
-    }
-
-    # If the field handles multiple values, pop the last one off
-    $term = (split $delim, $term)[-1] if $term =~ $delim;
-}
-
-my $CurrentUser = $session{'CurrentUser'};
-
-# Require privileged users or overriding config
-$m->abort unless $CurrentUser->Privileged
-              or RT->Config->Get('AllowUserAutocompleteForUnprivileged');
+my $users = RT::Users->new( $session{'CurrentUser'} );
 
-my %fields = %{ RT->Config->Get('UserAutocompleteFields')
-                || { EmailAddress => 1, Name => 1, RealName => 'LIKE' } };
+return $users unless defined $return
+                     and defined $term
+                     and length $term;
 
-# If an operator is provided, check against only the returned field
-# 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) {
+while (my ($name, $op) = each %$fields) {
     $op = 'STARTSWITH'
         unless $op =~ /^(?:LIKE|(?:START|END)SWITH|=|!=)$/i;
 
@@ -114,8 +74,6 @@ foreach (split /\s*,\s*/, $exclude) {
     $users->Limit(FIELD => 'id', VALUE => $_, OPERATOR => '!=');
 }
 
-my @suggestions;
-
 if ( RT->Config->Get('DatabaseType') eq 'Oracle' ) {
     $users->Limit(
         FIELD    => $return,
@@ -133,13 +91,13 @@ else {
     );
 }
 
-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;
-}
-
+return $users;
 </%INIT>
+<%ARGS>
+$privileged => undef
+$fields => RT->Config->Get('UserAutocompleteFields')
+$term => undef
+$exclude => ''
+$return => undef
+$max => 10
+</%ARGS>

commit d7ad719cd8d43f0a0c16beae0275cbec13cea676
Author: Kevin Falcone <falcone at bestpractical.com>
Date:   Thu Mar 7 19:11:15 2013 -0500

    Use RT::Users->SimpleSearch to allow non-autocomplete-searching
    
    This displays users very similarly to the Admin user search list.
    You can refine the search, switch back to autocomplete and eventually
    click through to a user.

diff --git a/etc/RT_Config.pm.in b/etc/RT_Config.pm.in
index 89c7375..54e8405 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<$UserSummaryFormat>
+
+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($UserSummaryFormat,
+         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<$UserSummaryExtraInfo>
 
 This controls what information is displayed on the User Summary
diff --git a/share/html/User/Search.html b/share/html/User/Search.html
index b852dea..05f2596 100644
--- a/share/html/User/Search.html
+++ b/share/html/User/Search.html
@@ -51,6 +51,27 @@
 <& /Elements/GotoUser, Button => 1, Default => $UserString||'' &>
 <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>
 
 if ($UserName) {
@@ -62,6 +83,12 @@ if ($UserName) {
         RT->Logger->error("Unable to load $UserName: $msg");
     }
 }
+
+my $users = RT::Users->new($session{'CurrentUser'});
+$users->SimpleSearch( Return => 'Name', Term => $UserString, Max => 100 );
+
+my $Format = RT->Config->Get('UserSummaryFormat');
+
 my $search_fields = join ", ", map loc($_), keys %{RT->Config->Get('UserAutocompleteFields')};
 
 </%INIT>

commit b8b006124c4d487842e57855d2e7fe88645ba17f
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..3330fae 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,8 +620,8 @@ sub SimpleSearch {
     }
 
     # Exclude users we don't want
-    foreach (split /\s*,\s*/, $args{Exclude}) {
         $self->Limit(FIELD => 'id', VALUE => $_, OPERATOR => '!=');
+    foreach (@{$args{Exclude}}) {
     }
 
     if ( RT->Config->Get('DatabaseType') eq 'Oracle' ) {
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 9941805d09db68734a29372d598536247d976af0
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.
    
    A separate branch 4.0/autocomplete-exclude fixes this for Groups

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

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

    Exclude Nobody and RT_System in SQL
    
    The autocompleter was manually skipping those users and User/Search.html
    wasn't skipping them at all.  Pass them along to 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;
diff --git a/share/html/User/Search.html b/share/html/User/Search.html
index 05f2596..4b614d0 100644
--- a/share/html/User/Search.html
+++ b/share/html/User/Search.html
@@ -84,8 +84,12 @@ if ($UserName) {
     }
 }
 
+my $exclude = [RT->Nobody->Id, RT->System->Id];
 my $users = RT::Users->new($session{'CurrentUser'});
-$users->SimpleSearch( Return => 'Name', Term => $UserString, Max => 100 );
+$users->SimpleSearch( Return    => 'Name',
+                      Term      => $UserString,
+                      Max       => 100,
+                      Exclude   => $exclude );
 
 my $Format = RT->Config->Get('UserSummaryFormat');
 

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

    Rename UserAutocompleteFields to UserSearchFields
    
    Now that I'm using them in two places, it's really misleading to call
    them Autocomplete fields.
    
    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 54e8405..5013cb0 100755
--- a/etc/RT_Config.pm.in
+++ b/etc/RT_Config.pm.in
@@ -1412,7 +1412,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
@@ -1420,7 +1422,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/Elements/Search b/share/html/User/Elements/Search
index ee35449..ea95ad7 100644
--- a/share/html/User/Elements/Search
+++ b/share/html/User/Elements/Search
@@ -95,7 +95,7 @@ return $users;
 </%INIT>
 <%ARGS>
 $privileged => undef
-$fields => RT->Config->Get('UserAutocompleteFields')
+$fields => RT->Config->Get('UserSearchFields')
 $term => undef
 $exclude => ''
 $return => undef
diff --git a/share/html/User/Search.html b/share/html/User/Search.html
index 4b614d0..b03ef19 100644
--- a/share/html/User/Search.html
+++ b/share/html/User/Search.html
@@ -93,7 +93,7 @@ $users->SimpleSearch( Return    => 'Name',
 
 my $Format = RT->Config->Get('UserSummaryFormat');
 
-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 1bfb9bef512cd6c3f2409fb00cc6caff492bb242
Author: Kevin Falcone <falcone at bestpractical.com>
Date:   Thu Mar 7 19:40:15 2013 -0500

    Switch from manual deprecated to RT->Deprecated
    
    This makes the logging 'louder' (warn vs info) but I don't believe that
    to be a bad thing.

diff --git a/lib/RT/Config.pm b/lib/RT/Config.pm
index 10fff8e..58b3b39 100644
--- a/lib/RT/Config.pm
+++ b/lib/RT/Config.pm
@@ -775,9 +775,11 @@ our %META = (
         },
         PostLoadCheck => sub {
             my $self = shift;
-            # XXX: deprecated, remove in 4.4
-            $RT::Logger->info("You set \$LogToScreen in your config, but it's been renamed to \$LogToSTDERR.  Please update your config.")
-                if $self->Meta('LogToScreen')->{'Source'}{'Package'};
+            RT->Deprecated(
+                Message => '$LogToScreen is deprecated',
+                Instead => '$LogToSTDERR',
+                Remove => "4.4"
+            ) if $self->Meta('LogToScreen')->{'Source'}{'Package'};
         },
     },
     UserAutocompleteFields => {

commit 36a97ee5fe425abafb97b51fef7bd6c69302cd85
Author: Kevin Falcone <falcone at bestpractical.com>
Date:   Wed Feb 27 22:34:52 2013 -0500

    link to the User Search

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");

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

    A simple Create Ticket portlet
    
    Sets this user as the Requestor

diff --git a/etc/RT_Config.pm.in b/etc/RT_Config.pm.in
index 5013cb0..e7da730 100755
--- a/etc/RT_Config.pm.in
+++ b/etc/RT_Config.pm.in
@@ -978,7 +978,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<$UserSummaryTicketListFormat>
 
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 7dd97c5cf84328fec6228eeafab85bfbf79329dc
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

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