summaryrefslogtreecommitdiff
path: root/rt/html/Search
diff options
context:
space:
mode:
Diffstat (limited to 'rt/html/Search')
-rw-r--r--rt/html/Search/Build.html313
-rw-r--r--rt/html/Search/Bulk.html482
-rw-r--r--rt/html/Search/Chart68
-rwxr-xr-xrt/html/Search/Edit.html12
-rw-r--r--rt/html/Search/Elements/BuildFormatString27
-rw-r--r--rt/html/Search/Elements/DisplayOptions73
-rw-r--r--rt/html/Search/Elements/EditFormat30
-rw-r--r--rt/html/Search/Elements/EditQuery24
-rw-r--r--rt/html/Search/Elements/EditSearches59
-rw-r--r--rt/html/Search/Elements/NewListActions14
-rw-r--r--rt/html/Search/Elements/PickBasics65
-rw-r--r--rt/html/Search/Elements/PickCFs6
-rw-r--r--rt/html/Search/Elements/PickCriteria20
-rw-r--r--rt/html/Search/Elements/SearchPrivacy6
-rw-r--r--rt/html/Search/Elements/SelectAndOr10
-rw-r--r--rt/html/Search/Elements/SelectGroup14
-rw-r--r--rt/html/Search/Elements/SelectLinks12
-rw-r--r--rt/html/Search/Elements/SelectPersonType16
-rw-r--r--rt/html/Search/Elements/SelectSearchObject6
-rw-r--r--rt/html/Search/Elements/SelectSearchesForObjects11
-rwxr-xr-xrt/html/Search/Results.html89
-rw-r--r--rt/html/Search/Results.rdf8
-rw-r--r--rt/html/Search/Results.tsv109
-rw-r--r--rt/html/Search/Simple.html18
24 files changed, 882 insertions, 610 deletions
diff --git a/rt/html/Search/Build.html b/rt/html/Search/Build.html
index 5a66e02c9..263958775 100644
--- a/rt/html/Search/Build.html
+++ b/rt/html/Search/Build.html
@@ -2,7 +2,7 @@
%#
%# COPYRIGHT:
%#
-%# This software is Copyright (c) 1996-2005 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
%# <jesse@bestpractical.com>
%#
%# (Except where explicitly superseded by other copyright notices)
@@ -22,7 +22,9 @@
%#
%# 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
%#
%#
%# CONTRIBUTION SUBMISSION POLICY:
@@ -74,15 +76,15 @@
Rows => $RowsPerPage
&>
-<FORM METHOD="POST" ACTION="Build.html" NAME="BuildQuery">
-<input type=hidden name=SearchId value="<%$SearchId%>">
-<input type=hidden name=Query value="<%$Query%>">
-<input type=hidden name=Format value="<%$Format%>">
-<table width=100% border="0" cellpadding="5">
+<form method="post" action="Build.html" name="BuildQuery">
+<input type="hidden" class="hidden" name="SearchId" value="<%$SearchId%>" />
+<input type="hidden" class="hidden" name="Query" value="<%$Query%>" />
+<input type="hidden" class="hidden" name="Format" value="<%$Format%>" />
+<table width="100%" border="0" cellpadding="5">
<tr valign="top">
<td class="boxcontainer" rowspan="2" width="65%">
<& Elements/PickCriteria, query => $Query, cfqueues => $queues &>
-<& /Elements/Submit, Caption => loc('Add additional criteria'), Label => loc('Add'), Name => 'AddClause'&>
+<& /Elements/Submit, Caption => loc('Add these terms to your search'), Label => loc('Add'), Name => 'AddClause'&>
</td>
<td>
@@ -91,6 +93,7 @@
actions => \@actions,
optionlist => $optionlist,
Description => $Description &>
+<& /Elements/Submit, Label => loc('Add and Search'), Name => 'DoSearch'&>
</td>
</tr>
@@ -101,19 +104,15 @@
</tr>
<tr>
-<td colspan=2 class="boxcontainer">
+<td colspan="2" class="boxcontainer">
<& Elements/DisplayOptions, %ARGS, Format=> $Format,
AvailableColumns => $AvailableColumns, CurrentFormat => $CurrentFormat, RowsPerPage => $RowsPerPage, OrderBy => $OrderBy, Order => $Order &>
-</td>
-</tr>
-<tr>
-<td colspan=2 class="boxcontainer">
-<& /Elements/Submit, Caption => loc("Do the Search"), Label => loc('Search'), Name => 'DoSearch'&>
+<& /Elements/Submit, Label => loc('Add and Search'), Name => 'DoSearch'&>
</td>
</tr>
</table>
-</FORM>
+</form>
<%INIT>
use RT::Interface::Web::QueryBuilder;
@@ -134,7 +133,7 @@ if ( $NewQuery or $ARGS{'Delete'} ) {
$SearchId = '';
$Order = '';
$OrderBy = '';
- $RowsPerPage = '';
+ $RowsPerPage = undef;
# ($search hasn't been set yet; no need to clear)
@@ -147,22 +146,43 @@ if ( $NewQuery or $ARGS{'Delete'} ) {
# }}}
+if (ref $OrderBy eq "ARRAY") {
+ $OrderBy = join("|", @$OrderBy);
+}
+if (ref $Order eq "ARRAY") {
+ $Order = join("|", @$Order);
+}
+
# {{{ Attempt to load what we can from the session, set defaults
# We don't read or write to the session again until the end
$search_hash = $session{'CurrentSearchHash'};
+# Read from user preferences
+my $prefs = $session{'CurrentUser'}->UserObj->Preferences("SearchDisplay") || {};
+
# These variables are what define a search_hash; this is also
# where we give sane defaults.
$Query ||= $search_hash->{'Query'};
-$Format ||= $search_hash->{'Format'};
+$Format ||= $search_hash->{'Format'} || $prefs->{'Format'};
$Description ||= $search_hash->{'Description'};
$SearchId ||= $search_hash->{'SearchId'} || 'new';
-$Order ||= $search_hash->{'Order'} || 'ASC';
-$OrderBy ||= $search_hash->{'OrderBy'} || 'id';
-$RowsPerPage = ( $search_hash->{'RowsPerPage'} || 50 )
- unless defined($RowsPerPage);
-$search ||= $search_hash->{'Object'};
+$Order ||= $search_hash->{'Order'} || $prefs->{'Order'} || 'ASC';
+$OrderBy ||= $search_hash->{'OrderBy'} || $prefs->{'OrderBy'} || 'id';
+
+unless ( defined $RowsPerPage ) {
+ if ( defined $search_hash->{'RowsPerPage'} ) {
+ $RowsPerPage = $search_hash->{'RowsPerPage'};
+ }
+ elsif ( defined $prefs->{'RowsPerPage'} ) {
+ $RowsPerPage = $prefs->{'RowsPerPage'};
+ }
+ else {
+ $RowsPerPage = 50;
+ }
+}
+
+ $search ||= $search_hash->{'Object'};
# }}}
@@ -175,31 +195,14 @@ $Format = $m->comp( '/Elements/ScrubHTML', Content => $Format ) if ($Format);
if ( $ARGS{'Delete'} ) {
# We set $SearchId to 'new' above already, so peek into the %ARGS
- if ( $ARGS{'SearchId'} =~ /^(.*?)-(\d+)-SavedSearch-(\d+)$/ ) {
- my $obj_type = $1;
- my $obj_id = $2;
- my $search_id = $3;
-
- my $container_object;
- if ( $obj_type eq 'RT::User' && $obj_id == $session{'CurrentUser'}->Id )
- {
- $container_object = $session{'CurrentUser'}->UserObj;
- }
- elsif ( $obj_type eq 'RT::Group' ) {
- $container_object = RT::Group->new( $session{'CurrentUser'} );
- $container_object->Load($obj_id);
- }
-
- if ( $container_object->id ) {
-
- # We have the object the entry is an attribute on; delete
- # the entry..
- $container_object->Attributes->DeleteEntry(
- Name => 'SavedSearch',
- id => $search_id
+ my ($container_object, $search_id) = _parse_saved_search ($ARGS{'SearchId'});
+ if ($container_object && $container_object->id) {
+ # We have the object the entry is an attribute on; delete the
+ # entry..
+ $container_object->Attributes->DeleteEntry(
+ Name => 'SavedSearch',
+ id => $search_id
);
- }
-
}
}
@@ -223,25 +226,8 @@ if ( $ARGS{'Revert'} ) {
# {{{ if we're asked to load a search, load it.
-if ( $ARGS{'LoadSavedSearch'} =~ /^(.*?)-(\d+)-SavedSearch-(\d+)$/ ) {
- my $obj_type = $1;
- my $obj_id = $2;
- my $search_id = $3;
-
- # We explicitly list out the available types (user and group) and
- # don't trust user input here
- if ( ( $obj_type eq 'RT::User' )
- && ( $obj_id == $session{'CurrentUser'}->id ) )
- {
- $search =
- $session{'CurrentUser'}->UserObj->Attributes->WithId($search_id);
-
- }
- elsif ( $obj_type eq 'RT::Group' ) {
- my $group = RT::Group->new( $session{'CurrentUser'} );
- $group->Load($obj_id);
- $search = $group->Attributes->WithId($search_id);
- }
+if ( my ($container_object, $search_id ) = _parse_saved_search ($ARGS{'LoadSavedSearch'})) {
+ $search = $container_object->Attributes->WithId($search_id);
# We have a $search and now; import the others
$SearchId = $ARGS{'LoadSavedSearch'};
@@ -255,6 +241,62 @@ if ( $ARGS{'LoadSavedSearch'} =~ /^(.*?)-(\d+)-SavedSearch-(\d+)$/ ) {
# }}}
+# {{{ if we're asked to save the current search, save it
+if ( $ARGS{'Save'} ) {
+ if ( $search && $search->id ) {
+ # permission check
+ if ($search->Object->isa('RT::System')) {
+ unless ($session{'CurrentUser'}->HasRight( Object=> $RT::System, Right => 'SuperUser')) {
+ Abort("No permission to save system-wide searches");
+ }
+ }
+
+ # This search is based on a previously loaded search -- so
+ # just update the current search object with new values
+ $search->SetSubValues(
+ Format => $Format,
+ Query => $Query,
+ Order => $Order,
+ OrderBy => $OrderBy,
+ RowsPerPage => $RowsPerPage,
+ );
+ $search->SetDescription($Description);
+
+ }
+ elsif ( $SearchId eq 'new' ) {
+ my $saved_search = RT::SavedSearch->new( $session{'CurrentUser'} );
+ my ( $ok, $search_msg ) = $saved_search->Save(
+ Privacy => $ARGS{'Owner'},
+ Name => $Description,
+ SearchParams => {
+ Format => $Format,
+ Query => $Query,
+ Order => $Order,
+ OrderBy => $OrderBy,
+ RowsPerPage => $RowsPerPage } );
+
+ if ($ok) {
+ $search = $session{'CurrentUser'}->UserObj->Attributes->WithId($saved_search->Id);
+ # Build new SearchId
+ $SearchId =
+ ref( $session{'CurrentUser'}->UserObj ) . '-'
+ . $session{'CurrentUser'}->UserObj->Id
+ . '-SavedSearch-'
+ . $search->Id;
+ }
+ else {
+ push @actions, [ loc("Can't find a saved search to work with").': '.loc($search_msg), 0 ];
+ }
+ }
+ else {
+ push @actions, [ loc("Can't save this search"), 0 ];
+ }
+
+}
+
+# }}}
+
+
# {{{ Parse the query
use Regexp::Common qw /delimited/;
@@ -278,7 +320,7 @@ my $_match = sub {
my $ParseQuery = sub {
my $string = shift;
my $tree = shift;
- my @actions = shift;
+ my $actions = shift;
my $want = KEYWORD | PAREN;
my $last = undef;
@@ -287,9 +329,12 @@ my $ParseQuery = sub {
# make a tree root
$$tree = RT::Interface::Web::QueryBuilder::Tree->new;
my $root = RT::Interface::Web::QueryBuilder::Tree->new( 'AND', $$tree );
- my $lastnode = $root;
my $parentnode = $root;
+ # on new searches, we're passed undef but still need to construct the
+ # RT::Interface::Web::QueryBuilder::Tree. Quiet warning
+ return unless defined $string;
+
# get the FIELDS from Tickets_Overlay
my $tickets = new RT::Tickets( $session{'CurrentUser'} );
my %FIELDS = %{ $tickets->FIELDS };
@@ -339,13 +384,10 @@ my $ParseQuery = sub {
# Error
# FIXME: I will only print out the highest $want value
my $token = $tokens[ ( ( log $want ) / ( log 2 ) ) ];
- push @actions,
+ push @$actions,
[
- loc(
-"current: $current, want $want, Error near ->$val<- expecting a "
- . $token
- . " in '$string'\n"
- ),
+ loc("Error near ->[_1]<- expecting a [_2] in '[_3]'",
+ $val, $token, $string ),
-1
];
}
@@ -364,13 +406,13 @@ my $ParseQuery = sub {
else {
$depth--;
$parentnode = $parentnode->getParent();
- $lastnode = $parentnode;
}
$want = KEYWORD | PAREN | AGGREG;
}
elsif ( $current & AGGREG ) {
$ea = $val;
+ $parentnode->setNodeValue($ea);
$want = KEYWORD | PAREN;
}
elsif ( $current & KEYWORD ) {
@@ -400,20 +442,28 @@ my $ParseQuery = sub {
$val =~ s!\\(.)!$1!g;
my $class;
- if ( exists $lcfields{ lc $key } ) {
- $key = $lcfields{ lc $key };
- $class = $FIELDS{$key}->[0];
+
+ my ($key_base, $subkey) = split(/\./,$key,2);
+ $key_base =~ s/\..*$//; # Strip off .EmailAddress, for example
+
+ if ( exists $lcfields{lc $key_base } ) {
+ $key = $lcfields{lc $key_base } . (defined $subkey ? '.'.$subkey : '');
+ $class = $FIELDS{$key_base}->[0];
+ }
+ elsif ( $key =~ /^C(?:ustom)?F(?:ield)?\.{(.*)}$/i ) {
+ $class = $FIELDS{'CF'}->[0];
}
+
if ( $class ne 'INT' ) {
$val = "'$val'";
}
- push @actions, [ loc("Unknown field: $key"), -1 ] unless $class;
+ push @$actions, [ loc("Unknown field: [_1]", $key), -1 ] unless $class;
$want = PAREN | AGGREG;
}
else {
- push @actions, [ loc("I'm lost"), -1 ];
+ push @$actions, [ loc("I'm lost"), -1 ];
}
if ( $current & VALUE ) {
@@ -427,33 +477,40 @@ my $ParseQuery = sub {
};
# explicity add a child to it
- $lastnode = RT::Interface::Web::QueryBuilder::Tree->new( $clause, $parentnode );
- $lastnode->getParent()->setNodeValue($ea);
+ RT::Interface::Web::QueryBuilder::Tree->new( $clause, $parentnode );
( $ea, $key, $op, $value ) = ( "", "", "", "" );
+
}
$last = $current;
} # while
- push @actions, [ loc("Incomplete query"), -1 ]
+ push @$actions, [ loc("Incomplete query"), -1 ]
unless ( ( $want | PAREN ) || ( $want | KEYWORD ) );
- push @actions, [ loc("Incomplete Query"), -1 ]
+ push @$actions, [ loc("Incomplete Query"), -1 ]
unless ( $last && ( $last | PAREN ) || ( $last || VALUE ) );
# This will never happen, because the parser will complain
- push @actions, [ loc("Mismatched parentheses"), -1 ]
+ push @$actions, [ loc("Mismatched parentheses"), -1 ]
unless $depth == 1;
};
my $tree;
-$ParseQuery->( $Query, \$tree, \@actions );
-
-# if parsing went poorly, send them to the edit page to fix it
-if ( $actions[0] ) {
- $m->comp( "Edit.html", Query => $Query, actions => \@actions );
- $m->abort();
+{
+ my @parsing_errors;
+ $ParseQuery->( $Query, \$tree, \@parsing_errors );
+
+ # if parsing went poorly, send them to the edit page
+ # to fix it
+ if ( @parsing_errors ) {
+ return $m->comp(
+ "Edit.html",
+ Query => $Query,
+ actions => \@parsing_errors
+ );
+ }
}
$Query = "";
@@ -583,7 +640,7 @@ elsif ( $ARGS{"Toggle"} ) {
# {{{ Try to find if we're adding a clause
foreach my $arg ( keys %ARGS ) {
if (
- $arg =~ m/^ValueOf(.+)/
+ $arg =~ m/^ValueOf(\w+|'CF.{.*?}')$/
&& ( ref $ARGS{$arg} eq "ARRAY"
? grep { $_ ne "" } @{ $ARGS{$arg} }
: $ARGS{$arg} ne "" )
@@ -695,77 +752,6 @@ my ( $AvailableColumns, $CurrentFormat );
# }}}
-# {{{ if we're asked to save the current search, save it
-if ( $ARGS{'Save'} ) {
-
- if ( $search && $search->id ) {
-
- # This search is based on a previously loaded search -- so
- # just update the current search object with new values
- $search->SetSubValues(
- Format => $Format,
- Query => $Query,
- Order => $Order,
- OrderBy => $OrderBy,
- RowsPerPage => $RowsPerPage,
- );
- $search->SetDescription($Description);
-
- }
- elsif ( $SearchId eq 'new' && $ARGS{'Owner'} =~ /^(.*?)-(\d+)$/ ) {
-
- # We're saving a new search
- my $obj_type = $1;
- my $obj_id = $2;
-
- # Find out if we're saving on the user, or a group
- my $container_object;
- if ( $obj_type eq 'RT::User' && $obj_id == $session{'CurrentUser'}->Id )
- {
- $container_object = $session{'CurrentUser'}->UserObj;
- }
- elsif ( $obj_type eq 'RT::Group' ) {
- $container_object = RT::Group->new( $session{'CurrentUser'} );
- $container_object->Load($obj_id);
- }
-
- if ( $container_object->id ) {
-
- # If we got one or the other, add the saerch
- my ( $search_id, $search_msg ) = $container_object->AddAttribute(
- Name => 'SavedSearch',
- Description => $Description,
- Content => {
- Format => $Format,
- Query => $Query,
- Order => $Order,
- OrderBy => $OrderBy,
- RowsPerPage => $RowsPerPage,
- }
- );
- $search =
- $session{'CurrentUser'}->UserObj->Attributes->WithId($search_id);
-
- # Build new SearchId
- $SearchId =
- ref( $session{'CurrentUser'}->UserObj ) . '-'
- . $session{'CurrentUser'}->UserObj->Id
- . '-SavedSearch-'
- . $search->Id;
- }
- unless ( $search->id ) {
- push @actions, [ loc("Can't find a saved search to work with"), 0 ];
- }
-
- }
- else {
- push @actions, [ loc("Can't save this search"), 0 ];
- }
-
-}
-
-# }}}
-
# {{{ If we're modifying an old query, check if it has changed
my $dirty = 0;
$dirty = 1
@@ -793,7 +779,7 @@ $session{'CurrentSearchHash'} = $search_hash;
# }}}
# {{{ Show the results, if we were asked.
-if ( $ARGS{"DoSearch"} ) {
+if ( $ARGS{"DoSearch"}) {
$m->comp(
"Results.html",
Query => $Query,
@@ -802,6 +788,7 @@ if ( $ARGS{"DoSearch"} ) {
OrderBy => $OrderBy,
Rows => $RowsPerPage
);
+ $m->comp('/Elements/Footer');
$m->abort();
}
diff --git a/rt/html/Search/Bulk.html b/rt/html/Search/Bulk.html
index f9eef26b6..9742df5ae 100644
--- a/rt/html/Search/Bulk.html
+++ b/rt/html/Search/Bulk.html
@@ -2,7 +2,7 @@
%#
%# COPYRIGHT:
%#
-%# This software is Copyright (c) 1996-2005 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
%# <jesse@bestpractical.com>
%#
%# (Except where explicitly superseded by other copyright notices)
@@ -22,7 +22,9 @@
%#
%# 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
%#
%#
%# CONTRIBUTION SUBMISSION POLICY:
@@ -43,185 +45,220 @@
%# those contributions and any derivatives thereof.
%#
%# END BPS TAGGED BLOCK }}}
-<& /Elements/Header, Title => loc("Bulk ticket update") &>
-<& /Elements/Tabs, Title => loc("Bulk ticket update") &>
+<& /Elements/Header, Title => $title &>
+<& /Ticket/Elements/Tabs,
+ current_tab => "Search/Bulk.html",
+ Title => $title,
+ Format => $ARGS{'Format'}, # we don't want the locally modified one
+ Query => $Query,
+ Rows => $Rows,
+ OrderBy => $OrderBy,
+ Order => $Order &>
<& /Elements/ListActions, actions => \@results &>
-<FORM METHOD="POST" ACTION="<%$RT::WebPath%>/Search/Bulk.html" >
-<input type="hidden" name="Query" value="<%$ARGS{'Query'}%>">
-<TABLE WIDTH=100% border=0 cellpadding=3 CELLSPACING=0>
-<TR>
-<TH><&|/l&>Update</&></TH>
-%foreach my $col (@cols) {
-% my $colalias = $col;
-% $colalias =~ s/(Obj\-\>|)(Name|AsString)//;
-
-<TH><% loc($colalias) %>&nbsp;</TH>
+<form method="post" action="<%$RT::WebPath%>/Search/Bulk.html" enctype="multipart/form-data">
+% foreach my $var qw(Query Format OrderBy Order Rows Page) {
+<input type="hidden" class="hidden" name="<%$var%>" value="<%$ARGS{$var}%>" />
%}
-</TR>
-
-<%PERL>
-
-my $i;
-
-$Tickets->RedoSearch();
-while (my $Ticket = $Tickets->Next) {
- $i++;
- if ($i % 2) {
- $bgcolor = "#dddddd";
- }
- else {
- $bgcolor = "#ffffff";
- }
- </%PERL>
-<TR bgcolor="<%$bgcolor%>">
-<TD><input type=checkbox name="UpdateTicket<%$Ticket->Id%>" value="1" CHECKED></TD>
-%foreach my $col (@cols) {
-<TD>
-% if ($col eq 'id') {
-<A HREF="<% $RT::WebPath%>/Ticket/Display.html?id=<%$Ticket->Id%>"><%$Ticket->Id()%></A>
-% }
-%else {
-<% eval "\$Ticket->$col()" %>&nbsp;
-%}
-</TD>
-%}
-</TR>
-%}
-
-
-
-</TABLE>
-
-<HR>
-
-
-<& /Elements/TitleBoxStart, title => loc('Update selected tickets') &>
-<TABLE>
-<TR>
-<TD VALIGN=TOP>
+<& /Elements/TicketList, Query => $Query,
+ DisplayFormat => $Format,
+ Format => $ARGS{'Format'},
+ Verbatim => 1,
+ AllowSorting => 1,
+ OrderBy => $OrderBy,
+ Order => $Order,
+ Rows => $Rows,
+ Page => $Page,
+ BaseURL => $RT::WebPath."/Search/Bulk.html?"
+ &>
+
+<hr>
+
+<& /Elements/Submit, Label => loc('Update'), CheckAll => 1, ClearAll => 1 &>
+<br />
+<&|/Widgets/TitleBox, title => $title &>
+<table>
+<tr>
+<td valign="top">
<table>
-<tr><td class=label> <&|/l&>Make Owner</&>: </td>
-<td class=value> <& /Elements/SelectOwner, Name => "Owner" &> (<input type=checkbox name="ForceOwnerChange"> <&|/l&>Force change</&>) </td></tr>
-<tr><td class=label> <&|/l&>Add Requestor</&>: </td>
-<td class=value> <INPUT Name="AddRequestor" SIZE=20> </td></tr>
-<tr><td class=label> <&|/l&>Remove Requestor</&>: </td>
-<td class=value> <INPUT Name="DeleteRequestor" SIZE=20> </td></tr>
-<tr><td class=label> <&|/l&>Add Cc</&>: </td>
-<td class=value> <INPUT Name="AddCc" SIZE=20> </td></tr>
-<tr><td class=label> <&|/l&>Remove Cc</&>: </td>
-<td class=value> <INPUT Name="DeleteCc" SIZE=20> </td></tr>
-<tr><td class=label> <&|/l&>Add AdminCc</&>: </td>
-<td class=value> <INPUT Name="AddAdminCc" SIZE=20> </td></tr>
-<tr><td class=label> <&|/l&>Remove AdminCc</&>: </td>
-<td class=value> <INPUT Name="DeleteAdminCc" SIZE=20> </td></tr>
+<tr><td class="label"> <&|/l&>Make Owner</&>: </td>
+<td class="value"> <& /Elements/SelectOwner, Name => "Owner" &> (<input type="checkbox" class="checkbox" name="ForceOwnerChange" /> <&|/l&>Force change</&>) </td></tr>
+<tr><td class="label"> <&|/l&>Add Requestor</&>: </td>
+<td class="value"> <input name="AddRequestor" size="20" /> </td></tr>
+<tr><td class="label"> <&|/l&>Remove Requestor</&>: </td>
+<td class="value"> <input name="DeleteRequestor" size="20" /> </td></tr>
+<tr><td class="label"> <&|/l&>Add Cc</&>: </td>
+<td class="value"> <input name="AddCc" size="20" /> </td></tr>
+<tr><td class="label"> <&|/l&>Remove Cc</&>: </td>
+<td class="value"> <input name="DeleteCc" size="20" /> </td></tr>
+<tr><td class="label"> <&|/l&>Add AdminCc</&>: </td>
+<td class="value"> <input name="AddAdminCc" size="20" /> </td></tr>
+<tr><td class="label"> <&|/l&>Remove AdminCc</&>: </td>
+<td class="value"> <input name="DeleteAdminCc" size="20" /> </td></tr>
</table>
-</TD>
-<TD VALIGN=TOP>
+</td>
+<td valign="top">
<table>
-<tr><td class=label> <&|/l&>Make subject</&>: </td>
-<td class=value> <INPUT Name="Subject" SIZE=20> </td></tr>
-<tr><td class=label> <&|/l&>Make priority</&>: </td>
-<td class=value> <INPUT Name="Priority" SIZE=4> </td></tr>
-<tr><td class=label> <&|/l&>Make queue</&>: </td>
-<td class=value> <& /Elements/SelectQueue, Name => "Queue" &> </td></tr>
-<tr><td class=label> <&|/l&>Make Status</&>: </td>
-<td class=value> <& /Elements/SelectStatus, Name => "Status" &> </td></tr>
-<tr><td class=label> <&|/l&>Make date Starts</&>: </td>
-<td class=value> <& /Elements/SelectDate, Name => "Starts_Date", ShowTime => 0, Default => '' &> </td></tr>
-<tr><td class=label> <&|/l&>Make date Started</&>: </td>
-<td class=value> <& /Elements/SelectDate, Name => "Started_Date", ShowTime => 0, Default => '' &> </td></tr>
-<tr><td class=label> <&|/l&>Make date Told</&>: </td>
-<td class=value> <& /Elements/SelectDate, Name => "Told_Date", ShowTime => 0, Default => '' &> </td></tr>
-<tr><td class=label> <&|/l&>Make date Due</&>: </td>
-<td class=value> <& /Elements/SelectDate, Name => "Due_Date", ShowTime => 0, Default => '' &> </td></tr>
-<tr><td class=label> <&|/l&>Make date Resolved</&>: </td>
-<td class=value> <& /Elements/SelectDate, Name => "Resolved_Date", ShowTime => 0, Default => '' &> </td></tr>
+<tr><td class="label"> <&|/l&>Make subject</&>: </td>
+<td class="value"> <input name="Subject" size="20" /> </td></tr>
+<tr><td class="label"> <&|/l&>Make priority</&>: </td>
+<td class="value"> <input name="Priority" size="4" /> </td></tr>
+<tr><td class="label"> <&|/l&>Make queue</&>: </td>
+<td class="value"> <& /Elements/SelectQueue, Name => "Queue" &> </td></tr>
+<tr><td class="label"> <&|/l&>Make Status</&>: </td>
+<td class="value"> <& /Elements/SelectStatus, Name => "Status" &> </td></tr>
+<tr><td class="label"> <&|/l&>Make date Starts</&>: </td>
+<td class="value"> <& /Elements/SelectDate, Name => "Starts_Date", ShowTime => 0, Default => '' &> </td></tr>
+<tr><td class="label"> <&|/l&>Make date Started</&>: </td>
+<td class="value"> <& /Elements/SelectDate, Name => "Started_Date", ShowTime => 0, Default => '' &> </td></tr>
+<tr><td class="label"> <&|/l&>Make date Told</&>: </td>
+<td class="value"> <& /Elements/SelectDate, Name => "Told_Date", ShowTime => 0, Default => '' &> </td></tr>
+<tr><td class="label"> <&|/l&>Make date Due</&>: </td>
+<td class="value"> <& /Elements/SelectDate, Name => "Due_Date", ShowTime => 0, Default => '' &> </td></tr>
+<tr><td class="label"> <&|/l&>Make date Resolved</&>: </td>
+<td class="value"> <& /Elements/SelectDate, Name => "Resolved_Date", ShowTime => 0, Default => '' &> </td></tr>
</table>
-</TD>
-</TR>
+</td>
+</tr>
</table>
-<& /Elements/TitleBoxEnd&>
-<& /Elements/TitleBoxStart, title => loc('Add comments or replies to selected tickets') &>
+</&>
+<&| /Widgets/TitleBox, title => loc('Add comments or replies to selected tickets') &>
<table>
-<tr><td align=right><&|/l&>Update Type</&>:</td>
+<tr><td align="right"><&|/l&>Update Type</&>:</td>
<td><select name="UpdateType">
<option value="private" ><&|/l&>Comments (not sent to requestors)</&></option>
<option value="response" ><&|/l&>Reply to requestors</&></option>
</select>
</td></tr>
-<tr><td align=right><&|/l&>Subject</&>:</td><td> <input name="UpdateSubject" size=60 value=""></td></tr>
+<tr><td align="right"><&|/l&>Subject</&>:</td><td> <input name="UpdateSubject" size="60" value="" /></td></tr>
% while (my $CF = $TxnCFs->Next()) {
-<TR>
-<TD ALIGN=RIGHT><% $CF->Name %>:</TD>
-<TD><& /Elements/EditCustomField,
+<tr>
+<td align="right"><% $CF->Name %>:</td>
+<td><& /Elements/EditCustomField,
CustomField => $CF,
NamePrefix => "Object-RT::Transaction--CustomField-"
- &><em><% $CF->FriendlyType %></em></TD>
-</TD></TR>
+ &><em><% $CF->FriendlyType %></em></td>
+</td></tr>
% } # end if while
- <tr><td align=right><&|/l&>Attach</&>:</td><td><input name="UpdateAttachment" type="file"></td></tr>
- <tr><td class=labeltop><&|/l&>Message</&>:</td><td>
+ <tr><td align="right"><&|/l&>Attach</&>:</td><td><input name="UpdateAttachment" type="file" /></td></tr>
+ <tr><td class="labeltop"><&|/l&>Message</&>:</td><td>
<& /Elements/MessageBox, Name=>"UpdateContent"&>
</td></tr>
</table>
-<& /Elements/TitleBoxEnd &>
-
+</&>
+<&|/Widgets/TitleBox, title => loc('Edit Custom Fields'), color => "#336633"&>
+<%perl>
+my $cfs = RT::CustomFields->new($session{'CurrentUser'});
+$cfs->LimitToGlobal();
+$cfs->LimitToQueue($_) for keys %$seen_queues;
+</%perl>
+<table>
+<tr>
+<th><&|/l&>Name</&></th>
+<th><&|/l&>Add values</&></th>
+<th><&|/l&>Delete values</&></th>
+</tr>
+% while (my $cf = $cfs->Next()) {
+<tr>
+<td class="label"><%$cf->Name%><br />
+<em>(<%$cf->FriendlyType%>)</em></td>
+% my $rows = 5;
+% my @add = (NamePrefix => 'Bulk-Add-CustomField-', CustomField => $cf, Rows => $rows, Multiple => ($cf->MaxValues ==1 ? 0 : 1) , Cols => 25);
+% my @del = (NamePrefix => 'Bulk-Delete-CustomField-', CustomField => $cf, Rows => $rows, Multiple => 1, Cols => 25);
+% if ($cf->Type eq 'Select') {
+<td><& /Elements/EditCustomFieldSelect, @add &></td>
+<td><& /Elements/EditCustomFieldSelect, @del &></td>
+% } elsif ($cf->Type eq 'Combobox') {
+<td><& /Elements/EditCustomFieldCombobox, @add &></td>
+<td><& /Elements/EditCustomFieldCombobox, @del &></td>
+% } elsif ($cf->Type eq 'Freeform') {
+<td><& /Elements/EditCustomFieldFreeform, @add &></td>
+<td><& /Elements/EditCustomFieldFreeform, @del &></td>
+% } elsif ($cf->Type eq 'Text') {
+<td><& /Elements/EditCustomFieldText, @add &></td>
+<td>&nbsp;</td>
+% } else {
+% $RT::Logger->crit("Unknown CustomField type: " . $cf->Type);
+% }
+</tr>
+% }
+</table>
+</&>
-<& /Elements/TitleBoxStart, title => loc('Edit Links'), color => "#336633"&>
-<i><&|/l&>Enter tickets or URIs to link tickets to. Separate multiple entries with spaces.</&></i><br>
+<&|/Widgets/TitleBox, title => loc('Edit Links'), color => "#336633"&>
+<em><&|/l&>Enter tickets or URIs to link tickets to. Separate multiple entries with spaces.</&></em><br />
<& /Ticket/Elements/BulkLinks &>
-<& /Elements/TitleBoxEnd &>
+</&>
+
+<& /Elements/Submit, Label => loc('Update') &>
+
-<& /Elements/Submit, Label => loc('Update All') &>
+</form>
-</FORM>
<%INIT>
+my $title = loc("Update multiple tickets");
# Iterate through the ARGS hash and remove anything with a null value.
-map ($ARGS{$_} =~ /^$/ && (delete $ARGS{$_}), keys %ARGS);
-
-my ($bgcolor, @results);
-my @cols = qw(id Status Priority Subject QueueObj->Name OwnerObj->Name RequestorAddresses DueAsString );
-
-
-my $Tickets = RT::Tickets->new($session{'CurrentUser'});
-$Tickets->FromSQL($ARGS{'Query'});
-
-Abort(loc("No search to operate on.")) unless ($Tickets);
-
-my %allcfs;
-my %cfqnames;
-my %cfqs;
-my $count = 0;
-while (my $Ticket = $Tickets->Next) {
- my $cfq = $Ticket->QueueObj;
- my $cfqid = $cfq->Id;
- my $cfqn = $cfq->Name;
- unless ( exists $cfqs{$cfqid} ) {
- $cfqs{$cfqid} = 1;
- $count++;
- my $cfs = $cfq->TicketCustomFields;
- while (my $cf = $cfs->Next) {
- $allcfs{$cf->Id} = $cf;
- $cfqnames{$cf->Id} = $cfqn;
- }
+map ( $ARGS{$_} =~ /^$/ && ( delete $ARGS{$_} ), keys %ARGS );
+
+my (@results);
+
+$Page ||= 1;
+
+$Format ||= $RT::DefaultSearchResultFormat;
+
+# inject _CHECKBOX to the first field.
+$Format =~ s/'?([^']+)'?,/'___CHECKBOX__$1',/;
+
+my $Tickets = RT::Tickets->new( $session{'CurrentUser'} );
+$Tickets->FromSQL($Query);
+if ( $OrderBy =~ /\|/ ) {
+
+ # Multiple Sorts
+ my @OrderBy = split /\|/, $OrderBy;
+ my @Order = split /\|/, $Order;
+ $Tickets->OrderByCols(
+ map { { FIELD => $OrderBy[$_], ORDER => $Order[$_] } }
+ ( 0 .. $#OrderBy ) );
+}
+else {
+ $Tickets->OrderBy( FIELD => $OrderBy, ORDER => $Order );
+}
+
+$Tickets->RowsPerPage($Rows) if ($Rows);
+$Tickets->GotoPage( $Page - 1 ); # SB uses page 0 as the first page
+
+Abort( loc("No search to operate on.") ) unless ($Tickets);
+
+# build up a list of all custom fields for tickets that we're displaying, so
+# we can display sane edit widgets.
+
+my $fields = {};
+my $seen_queues = {};
+while ( my $ticket = $Tickets->Next ) {
+ next if $seen_queues->{ $ticket->Queue }++;
+
+ my $custom_fields = $ticket->QueueObj->TicketCustomFields;
+ while ( my $field = $custom_fields->Next ) {
+ $fields->{ $field->id } = $field;
}
}
-my $do_comment_reply=0;
+my $do_comment_reply = 0;
+
# Prepare for ticket updates
-$ARGS{'UpdateContent'} =~ s/\r\n/\n/g;
-chomp ($ARGS{'UpdateContent'}) ;
-
-if ($ARGS{'UpdateContent'} &&
- $ARGS{'UpdateContent'} ne '' &&
- $ARGS{'UpdateContent'} ne "-- \n" .
- $session{'CurrentUser'}->UserObj->Signature) {
- $do_comment_reply=1;
+if ($ARGS{'UpdateContent'}) {
+ $ARGS{'UpdateContent'} =~ s/\r\n/\n/g;
+ chomp( $ARGS{'UpdateContent'} );
+
+ if ($ARGS{'UpdateContent'} ne ''
+ && $ARGS{'UpdateContent'} ne "-- \n"
+ . $session{'CurrentUser'}->UserObj->Signature ) {
+ $do_comment_reply = 1;
+ }
}
#Iterate through each ticket we've been handed
@@ -229,50 +266,131 @@ my @linkresults;
my %queues;
$Tickets->RedoSearch();
-while (my $Ticket = $Tickets->Next) {
- $queues{$Ticket->QueueObj->Id}++;
- $RT::Logger->debug( "Checking Ticket ".$Ticket->Id ."\n");
- next unless ($ARGS{"UpdateTicket".$Ticket->Id});
- $RT::Logger->debug ("Matched\n");
- my @updateresults;
+
+# pull out the labels for any custom fields we want to update
+
+my $cf_del_keys;
+@$cf_del_keys = grep { /^Bulk-Delete-CustomField/ } keys %ARGS;
+my $cf_add_keys;
+@$cf_add_keys = grep { /^Bulk-Add-CustomField/ } keys %ARGS;
+
+
+while ( my $Ticket = $Tickets->Next ) {
+ next unless ( $ARGS{ "UpdateTicket" . $Ticket->Id } );
+
+ #Update the links
+ $ARGS{'id'} = $Ticket->id;
+ $queues{ $Ticket->QueueObj->Id }++;
+
+ my @updateresults;
if ($do_comment_reply) {
- ProcessUpdateMessage(TicketObj => $Ticket, ARGSRef => \%ARGS, Actions => \@updateresults);
+ ProcessUpdateMessage(
+ TicketObj => $Ticket,
+ ARGSRef => \%ARGS,
+ Actions => \@updateresults
+ );
}
#Update the basics.
- my @basicresults = ProcessTicketBasics(TicketObj => $Ticket, ARGSRef => \%ARGS);
- my @dateresults = ProcessTicketDates(TicketObj => $Ticket, ARGSRef => \%ARGS);
+ my @basicresults =
+ ProcessTicketBasics( TicketObj => $Ticket, ARGSRef => \%ARGS );
+ my @dateresults =
+ ProcessTicketDates( TicketObj => $Ticket, ARGSRef => \%ARGS );
+
#Update the watchers
- my @watchresults = ProcessTicketWatchers(TicketObj => $Ticket, ARGSRef => \%ARGS);
+ my @watchresults =
+ ProcessTicketWatchers( TicketObj => $Ticket, ARGSRef => \%ARGS );
+ foreach my $type qw(MergeInto DependsOn MemberOf RefersTo) {
+ $ARGS{ $Ticket->id . "-" . $type } = $ARGS{"Ticket-$type"};
+ $ARGS{ $type . "-" . $Ticket->id } = $ARGS{"$type-Ticket"};
+ }
+ @linkresults =
+ ProcessTicketLinks( TicketObj => $Ticket, ARGSRef => \%ARGS );
+ foreach my $type qw(MergeInto DependsOn MemberOf RefersTo) {
+ delete $ARGS{ $type . "-" . $Ticket->id };
+ delete $ARGS{ $Ticket->id . "-" . $type };
+ }
- #Update the links
- $ARGS{'id'} = $Ticket;
- $ARGS{$Ticket->Id.'-MergeInto'} = $ARGS{'Ticket-MergeInto'};
- $ARGS{$Ticket->Id.'-DependsOn'} = $ARGS{'Ticket-DependsOn'};
- $ARGS{'DependsOn-'.$Ticket->Id} = $ARGS{'DependsOn-Ticket'};
- $ARGS{$Ticket->Id.'-MemberOf'} = $ARGS{'Ticket-MemberOf'};
- $ARGS{'MemberOf-'.$Ticket->Id} = $ARGS{'MemberOf-Ticket'};
- $ARGS{$Ticket->Id.'-RefersTo'} = $ARGS{'Ticket-RefersTo'};
- $ARGS{'RefersTo-'.$Ticket->Id} = $ARGS{'RefersTo-Ticket'};
- @linkresults = ProcessTicketLinks( TicketObj => $Ticket, ARGSRef => \%ARGS);
- delete $ARGS{'id'};
- delete $ARGS{$Ticket->Id.'-MergeInto'};
- delete $ARGS{$Ticket->Id.'-DependsOn'};
- delete $ARGS{'DependsOn-'.$Ticket->Id};
- delete $ARGS{$Ticket->Id.'-MemberOf'};
- delete $ARGS{'MemberOf-'.$Ticket->Id};
- delete $ARGS{$Ticket->Id.'-RefersTo'};
- delete $ARGS{'RefersTo-'.$Ticket->Id};
- my @tempresults = (@watchresults, @basicresults, @dateresults,
- @updateresults, @linkresults);
- @tempresults = map { loc("Ticket [_1]: [_2]",$Ticket->Id,$_) } @tempresults;
-
- @results = (@results, @tempresults);
+ my @cfresults;
+
+ foreach my $list ( $cf_add_keys, $cf_del_keys ) {
+ next unless $list->[0];
+
+
+ my $op;
+ if ( $list->[0] =~ /Add/ ) {
+ $op = 'add';
+
+ }
+ elsif ( $list->[0] =~ /Del/ ) {
+ $op = 'del';
+ }
+ else {
+ $RT::Logger->crit(
+ "Got an op that was neither add nor delete. can never happen"
+ . $list->[0] );
+ last;
+ }
+
+ foreach my $key (@$list) {
+ my ( $cfid, $cf );
+ if ( $key =~ /CustomField-(\d+)-/ ) {
+ $cfid = $1;
+ $cf = RT::CustomField->new( $session{'CurrentUser'} );
+ $cf->Load($cfid);
+ }
+ else {next}
+ my @values =
+ ref( $ARGS{$key} ) eq 'ARRAY'
+ ? @{ $ARGS{$key} }
+ : ( $ARGS{$key} );
+ map { s/(\r\n|\r)/\n/g; } @values; # fix the newlines
+ # now break the multiline values into multivalues
+ @values = map { split( /\n/, $_ ) } @values
+ unless ( $cf->SingleValue );
+
+ my $current_values = $Ticket->CustomFieldValues($cfid);
+ foreach my $value (@values) {
+ if ( $op eq 'del' && $current_values->HasEntry($value) ) {
+ my ( $id, $msg ) = $Ticket->DeleteCustomFieldValue(
+ Field => $cfid,
+ Value => $value
+ );
+ push @cfresults, $msg;
+ }
+
+ elsif ( $op eq 'add' && !$current_values->HasEntry($value) ) {
+ my ( $id, $msg ) = $Ticket->AddCustomFieldValue(
+ Field => $cfid,
+ Value => $value
+ );
+ push @cfresults, $msg;
+ }
+ }
+ }
+ }
+ my @tempresults = (
+ @watchresults, @basicresults, @dateresults,
+ @updateresults, @linkresults, @cfresults
+ );
+
+ @tempresults =
+ map { loc( "Ticket [_1]: [_2]", $Ticket->Id, $_ ) } @tempresults;
+
+ @results = ( @results, @tempresults );
}
-my $TxnCFs = RT::CustomFields->new($session{CurrentUser});
-$TxnCFs->LimitToLookupType("RT::Queue-RT::Ticket-RT::Transaction");
-$TxnCFs->LimitToGlobalOrObjectId(sort keys %queues);
+my $TxnCFs = RT::CustomFields->new( $session{CurrentUser} );
+$TxnCFs->LimitToLookupType( RT::Transaction->CustomFieldLookupType );
+$TxnCFs->LimitToGlobalOrObjectId( sort keys %queues );
</%INIT>
+<%args>
+$Format => undef
+$Page => 1
+$Rows => undef
+$Order => 'ASC'
+$OrderBy => 'id'
+$Query => undef
+</%args>
diff --git a/rt/html/Search/Chart b/rt/html/Search/Chart
index ea52bb1f9..82704fdc7 100644
--- a/rt/html/Search/Chart
+++ b/rt/html/Search/Chart
@@ -74,14 +74,45 @@ $tix->GroupBy( FIELD => $PrimaryGroupBy );
my $value_name = $tix->Column( FIELD => $PrimaryGroupBy );
my $chart = $chart_class->new( 600 => 400 );
+
+my $font = $RT::ChartFont || ['verdana', 'arial', gdMediumBoldFont];
+$chart->set_title_font( $font, 12 ) if $chart->can('set_title_font');
+$chart->set_legend_font( $font, 12 ) if $chart->can('set_legend_font');
+$chart->set_x_label_font( $font, 10 ) if $chart->can('set_x_label_font');
+$chart->set_y_label_font( $font, 10 ) if $chart->can('set_y_label_font');
+$chart->set_label_font( $font, 10 ) if $chart->can('set_label_font');
+$chart->set_x_axis_font( $font, 9 ) if $chart->can('set_x_axis_font');
+$chart->set_y_axis_font( $font, 9 ) if $chart->can('set_y_axis_font');
+$chart->set_values_font( $font, 9 ) if $chart->can('set_values_font');
+$chart->set_value_font( $font, 9 ) if $chart->can('set_value_font');
+
+# Pie charts don't like having no input, so we show a special image
+# that indicates an error message. Because this is used in an <img>
+# context, it can't be a simple error message. Without this check,
+# the chart will just be a non-loading image.
+if ($tix->Count == 0) {
+ my $plot = GD::Image->new(600 => 400);
+ $plot->colorAllocate(255, 255, 255); # background
+ my $black = $plot->colorAllocate(0, 0, 0);
+
+ require GD::Text::Wrap;
+ my $error = GD::Text::Wrap->new($plot,
+ color => $black,
+ text => loc("No tickets found."),
+ );
+ $error->set_font( $font, 12 );
+ $error->draw(0, 0);
+
+ $m->comp( 'SELF:Plot', plot => $plot, %ARGS );
+}
+
if ($chart_class eq "GD::Graph::bars") {
$chart->set(
x_label => $tix->Label( $PrimaryGroupBy ),
x_labels_vertical => 1,
- y_label => 'Tickets',
+ y_label => loc('Tickets'),
show_values => 1
);
- $chart->set_legend_font( ['verdana', 'arial', gdMediumBoldFont], 12);
}
my %class = (
@@ -132,17 +163,26 @@ my @sorted_values = map { $data{$_}} @sorted_keys;
my $plot = $chart->plot( [ [@sorted_keys], [@sorted_values] ] ) or die $chart->error;
+$m->comp( 'SELF:Plot', plot => $plot, %ARGS );
+</%init>
-if ( $plot->can('png') ) {
- $r->content_type('image/png');
- $m->out( $plot->png );
-}
-elsif ( $plot->can('gif') ) {
- $r->content_type('image/gif');
- $m->out( $plot->gif );
-}
-else {
- die "Your GD library appears to support neither PNG nor GIF";
+<%METHOD Plot>
+<%ARGS>
+$plot => undef
+</%ARGS>
+<%INIT>
+my @types = ('png', 'gif');
+
+for my $type (@types) {
+ $plot->can($type)
+ or next;
+
+ $r->content_type("image/$type");
+ $m->out( $plot->$type );
+ $m->abort();
}
-$m->abort();
-</%init>
+
+die "Your GD library appears to support none of the following image types: " . join(', ', @types);
+</%INIT>
+
+</%METHOD>
diff --git a/rt/html/Search/Edit.html b/rt/html/Search/Edit.html
index 16e8a0e71..21df0db97 100755
--- a/rt/html/Search/Edit.html
+++ b/rt/html/Search/Edit.html
@@ -2,7 +2,7 @@
%#
%# COPYRIGHT:
%#
-%# This software is Copyright (c) 1996-2005 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
%# <jesse@bestpractical.com>
%#
%# (Except where explicitly superseded by other copyright notices)
@@ -22,7 +22,9 @@
%#
%# 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
%#
%#
%# CONTRIBUTION SUBMISSION POLICY:
@@ -56,11 +58,11 @@
<& Elements/NewListActions, actions => \@actions &>
<form method="post" action="Build.html">
-<input type="hidden" name="SearchId" value="<%$SearchId%>">
+<input type="hidden" class="hidden" name="SearchId" value="<%$SearchId%>" />
<textarea name="Query" rows="8" cols="72"><%$Query%></textarea>
-<br>
+<br />
<textarea name="Format" rows="8" cols="72"><%$Format%></textarea>
-<br>
+<br />
<& /Elements/Submit, Label => loc("Apply"), Reset => 1, Caption => loc("Apply your changes")&>
</form>
diff --git a/rt/html/Search/Elements/BuildFormatString b/rt/html/Search/Elements/BuildFormatString
index cffb81a48..3bd39b5c2 100644
--- a/rt/html/Search/Elements/BuildFormatString
+++ b/rt/html/Search/Elements/BuildFormatString
@@ -2,7 +2,7 @@
%#
%# COPYRIGHT:
%#
-%# This software is Copyright (c) 1996-2005 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
%# <jesse@bestpractical.com>
%#
%# (Except where explicitly superseded by other copyright notices)
@@ -22,7 +22,9 @@
%#
%# 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
%#
%#
%# CONTRIBUTION SUBMISSION POLICY:
@@ -171,12 +173,12 @@ elsif ( $AddCol ) {
$column{Column} = $col;
if ( $Face eq "Bold" ) {
- $column{Prefix} .= "<B>";
- $column{Suffix} .= "</B>";
+ $column{Prefix} .= "<b>";
+ $column{Suffix} .= "</b>";
}
if ( $Face eq "Italic" ) {
- $column{Prefix} .= "<I>";
- $column{Suffix} .= "</I>";
+ $column{Prefix} .= "<i>";
+ $column{Suffix} .= "</i>";
}
if ($Size) {
$column{Prefix} .= "<" . $m->interp->apply_escapes( $Size, 'h' ) . ">";
@@ -184,11 +186,11 @@ elsif ( $AddCol ) {
}
if ( $Link eq "Display" ) {
$column{Prefix} .=
- "<A HREF=\"" . $RT::WebPath . "/Ticket/Display.html?id=__id__\">";
+ "<a HREF=\"" . $RT::WebPath . "/Ticket/Display.html?id=__id__\">";
$column{Suffix} .= "</a>";
}
elsif ( $Link eq "Take" ) {
- $column{Prefix} .= "<A HREF=\"" . $RT::WebPath
+ $column{Prefix} .= "<a HREF=\"" . $RT::WebPath
. "/Ticket/Display.html?Action=Take&id=__id__\">";
$column{Suffix} .= "</a>";
}
@@ -223,10 +225,13 @@ elsif ( $ColDown ) {
my @format_string;
foreach my $field (@seen) {
next unless $field;
- my $row = "'" . $field->{Prefix};
- $row .= "__" . $m->interp->apply_escapes( $field->{Column}, 'h' ) . "__"
+ my $row = "'";
+ $row .= $field->{Prefix} if $field->{Prefix};
+ $row .= "__" . ($field->{Column} =~ m/\(/ ? $field->{Column} # func, don't escape
+ : $m->interp->apply_escapes( $field->{Column}, 'h' )) . "__"
unless ( $field->{Column} eq "<blank>" );
- $row .= $field->{Suffix} . "'";
+ $row .= $field->{Suffix} if $field->{Suffix};
+ $row .= "'";
push( @format_string, $row );
}
diff --git a/rt/html/Search/Elements/DisplayOptions b/rt/html/Search/Elements/DisplayOptions
index 43a9d9998..cc57f96dc 100644
--- a/rt/html/Search/Elements/DisplayOptions
+++ b/rt/html/Search/Elements/DisplayOptions
@@ -2,7 +2,7 @@
%#
%# COPYRIGHT:
%#
-%# This software is Copyright (c) 1996-2005 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
%# <jesse@bestpractical.com>
%#
%# (Except where explicitly superseded by other copyright notices)
@@ -22,7 +22,9 @@
%#
%# 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
%#
%#
%# CONTRIBUTION SUBMISSION POLICY:
@@ -43,43 +45,53 @@
%# those contributions and any derivatives thereof.
%#
%# END BPS TAGGED BLOCK }}}
-<& /Elements/TitleBoxStart, title => loc("Display Columns") &>
-<table>
+<&| /Widgets/TitleBox, title => loc("Display Columns") &>
+<table width="100%">
<tr>
<td>
<& EditFormat, %ARGS &>
</td>
-<td valign=top>
-<table valign=top>
+<td valign="top">
+<table valign="top">
+
+% for my $o (0..3) {
<tr>
-<td class=label>
+<td class="label">
+% if ($o == 0) {
<&|/l&>Order by</&>:
-</td><td class=value>
+% }
+</td>
+<td class="value">
<select name="OrderBy">
-% foreach my $field (keys %fields) {
+% if ($o > 0) {
+<option value=""><&|/l&>~[none~]</&></option>
+% }
+% foreach my $field (sort keys %fields) {
% next unless $field;
-<option value=<%$field%>
-% if ($field =~ /^$OrderBy$/i) {
-SELECTED
+<option value="<%$field%>"
+% if (defined $OrderBy[$o] and $field eq $OrderBy[$o]) {
+selected
% }
><&|/l&><%$field%></&></option>
% }
</select>
<select name="Order">
<option value="ASC"
-% if ($Order eq "ASC") {
-SELECTED
+% unless ( ($Order[$o]||'') eq "DESC" ) {
+selected
% }
-><&|/l&>Ascending</&></option>
+><&|/l&>Asc</&></option>
<option value="DESC"
-% if ($Order eq "DESC") {
-SELECTED
+% if ( ($Order[$o]||'') eq "DESC" ) {
+selected
% }
-><&|/l&>Descending</&></option>
+><&|/l&>Desc</&></option>
</select>
</td>
</tr>
-<td class=label>
+% }
+<tr>
+<td class="label">
<&|/l&>Rows per page</&>:
</td><td class="value">
<& /Elements/SelectResultsPerPage,
@@ -91,14 +103,34 @@ SELECTED
</td>
</tr>
</table>
-<& /Elements/TitleBoxEnd &>
+</&>
<%INIT>
my $tickets = new RT::Tickets($session{'CurrentUser'});
my %fields = %{$tickets->FIELDS};
map { $fields{$_}->[0] =~ /^(?:ENUM|INT|DATE|STRING)$/ || delete $fields{$_} } keys %fields;
delete $fields{'EffectiveId'};
+$fields{ $_ . '.EmailAddress' } = 1 foreach( qw(Requestor Cc AdminCc) );
+
+# Add all available CustomFields to the list of sortable columns.
+my @cfs = grep /^CustomField/, @{$ARGS{AvailableColumns}};
+$fields{$_}=1 for @cfs;
+
+# Add PAW sort
+$fields{'Custom.Ownership'} = 1;
+my @Order;
+my @OrderBy;
+if ($OrderBy =~ /\|/) {
+ @OrderBy = split /\|/, $OrderBy;
+} else {
+ @OrderBy = ( $OrderBy );
+}
+if ($Order =~ /\|/) {
+ @Order = split /\|/, $Order;
+} else {
+ @Order = ( $Order );
+}
</%INIT>
@@ -107,4 +139,5 @@ $Order => undef
$OrderBy => undef
$RowsPerPage => undef
$Format => undef
+$GroupBy => 'id'
</%ARGS>
diff --git a/rt/html/Search/Elements/EditFormat b/rt/html/Search/Elements/EditFormat
index dc8720f26..fa0ac96e0 100644
--- a/rt/html/Search/Elements/EditFormat
+++ b/rt/html/Search/Elements/EditFormat
@@ -2,7 +2,7 @@
%#
%# COPYRIGHT:
%#
-%# This software is Copyright (c) 1996-2005 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
%# <jesse@bestpractical.com>
%#
%# (Except where explicitly superseded by other copyright notices)
@@ -22,7 +22,9 @@
%#
%# 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
%#
%#
%# CONTRIBUTION SUBMISSION POLICY:
@@ -56,7 +58,7 @@
<&|/l&>Show Columns</&>:
</td>
<tr>
-<td valign=top>
+<td valign="top">
<select size="6" name="SelectDisplayColumns" multiple>
% foreach my $field ( @$AvailableColumns) {
<option value="<%$field%>"><% loc( $field) %></option>
@@ -71,14 +73,14 @@
<option value="Display"><&|/l&>Display</&></option>
<option value="Take"><&|/l&>Take</&></option>
</select>
-<br><&|/l&>Title</&>: <input name="Title" size=10>
-<br><&|/l&>Size</&>:
+<br /><&|/l&>Title</&>: <input name="Title" size="10" />
+<br /><&|/l&>Size</&>:
<select name="Size">
<option value="">-</option>
<option value="Small"><&|/l&>Small</&></option>
<option value="Large"><&|/l&>Large</&></option>
</select>
-<br><&|/l&>Style</&>:
+<br /><&|/l&>Style</&>:
<select name="Face">
<option value="">-</option>
<option value="Bold"><&|/l&>Bold</&></option>
@@ -86,24 +88,24 @@
</select>
</td>
<td>
-<input type=submit name="AddCol" value="->">
+<input type="submit" class="button" name="AddCol" value=" &rarr; " />
</td>
-<td valign=top>
-<select size=4 name="CurrentDisplayColumns">
+<td valign="top">
+<select size="4" name="CurrentDisplayColumns">
% my $i=0;
% foreach my $field (@$CurrentFormat) {
<option value="<%$i++%>><%$field->{Column}%>">
<%loc( $field->{Column}) %></option>
% }
</select>
-<br>
+<br />
<center>
-<input type="submit" name="ColUp" value="^">
-<input type="submit" name="ColDown" value="v">
-<input type="submit" name="RemoveCol" value="<%loc('Delete')%>">
+<input type="submit" class="button" name="ColUp" value=" &uarr; " />
+<input type="submit" class="button" name="ColDown" value=" &darr; " />
+<input type="submit" class="button" name="RemoveCol" value="<%loc('Delete')%>" />
</center>
</td>
-<td colspan=3 align=center>
+<td colspan="3" align="center">
</td>
</tr>
</table>
diff --git a/rt/html/Search/Elements/EditQuery b/rt/html/Search/Elements/EditQuery
index 783541a64..5c40c2573 100644
--- a/rt/html/Search/Elements/EditQuery
+++ b/rt/html/Search/Elements/EditQuery
@@ -2,7 +2,7 @@
%#
%# COPYRIGHT:
%#
-%# This software is Copyright (c) 1996-2005 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
%# <jesse@bestpractical.com>
%#
%# (Except where explicitly superseded by other copyright notices)
@@ -22,7 +22,9 @@
%#
%# 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
%#
%#
%# CONTRIBUTION SUBMISSION POLICY:
@@ -44,20 +46,20 @@
%#
%# END BPS TAGGED BLOCK }}}
<& NewListActions, actions => $actions &>
-<& /Elements/TitleBoxStart, title => join(': ', grep defined, loc("Query"), $Description) &>
+<&|/Widgets/TitleBox, title => join(': ', grep defined, loc("Current search"), $Description) &>
<select size="10" name="clauses" style="width: 100%" multiple>
% $m->out($optionlist);
</select>
<p align="center">
-<input type=submit name="Up" value="^">
-<input type=submit name="Down" value="v">
-<input type=submit name="Left" value="<">
-<input type=submit name="Right" value=">">
-<input type=submit name="Toggle" value="<&|/l&>And/Or</&>">
-<input type=submit name="DeleteClause" value="<&|/l&>Delete</&>">
-%#<input type=submit name="EditQuery" value="Advanced">
+<input type="submit" class="button" name="Up" value=" &uarr; " />
+<input type="submit" class="button" name="Down" value=" &darr; " />
+<input type="submit" class="button" name="Left" value=" &larr; " />
+<input type="submit" class="button" name="Right" value=" &rarr; " />
+<input type="submit" class="button" name="Toggle" value="<&|/l&>And/Or</&>" />
+<input type="submit" class="button" name="DeleteClause" value="<&|/l&>Delete</&>" />
+%#<input type="submit" class="button" name="EditQuery" value="Advanced" />
</p>
-<& /Elements/TitleBoxEnd &>
+</&>
<%ARGS>
$Description
$optionlist
diff --git a/rt/html/Search/Elements/EditSearches b/rt/html/Search/Elements/EditSearches
index bc6b80e6f..3978ea320 100644
--- a/rt/html/Search/Elements/EditSearches
+++ b/rt/html/Search/Elements/EditSearches
@@ -2,7 +2,7 @@
%#
%# COPYRIGHT:
%#
-%# This software is Copyright (c) 1996-2005 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
%# <jesse@bestpractical.com>
%#
%# (Except where explicitly superseded by other copyright notices)
@@ -22,7 +22,9 @@
%#
%# 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
%#
%#
%# CONTRIBUTION SUBMISSION POLICY:
@@ -43,62 +45,59 @@
%# those contributions and any derivatives thereof.
%#
%# END BPS TAGGED BLOCK }}}
-<& /Elements/TitleBoxStart, title => loc('Saved searches') &>
+<&| /Widgets/TitleBox, title => loc($Title)&>
%# Hide all the save functionality if the user shouldn't see it.
% if ($session{'CurrentUser'}->HasRight( Right => 'CreateSavedSearch',
% Object=> $RT::System )) {
<&|/l&>Privacy:</&>
% if ($CurrentSearch->{'Object'} && $CurrentSearch->{'Object'}->id) {
-<& SearchPrivacy, Object => $CurrentSearch->{'Object'}->Object &><br>
+<& SearchPrivacy, Object => $CurrentSearch->{'Object'}->Object &><br />
% } else {
-<& SelectSearchObject, Name => 'Owner', Objects => \@Objects &><br>
+<& SelectSearchObject, Name => 'Owner', Objects => \@Objects &><br />
% }
<&|/l&>Description</&>:<br>
-<font size="-1"><input size="25" name="Description" value="<%$CurrentSearch->{'Description'}%>"></font>
-<nobr>
+<font size="-1"><input size="25" name="Description" value="<%$CurrentSearch->{'Description'} || ''%>" /></font>
% if ($SearchId ne 'new') {
+<nobr>
% if ($Dirty) {
-<input type="submit" name="Revert" value="<%loc('Revert')%>">
+<input type="submit" class="button" name="Revert" value="<%loc('Revert')%>" />
% }
-<input type="submit" name="Delete" value="<%loc('Delete')%>">
-<input type="submit" name="CopySearch" value="<%loc('Copy')%>">
-</nobr>
-
+<input type="submit" class="button" name="Delete" value="<%loc('Delete')%>" />
+% if ($AllowCopy) {
+<input type="submit" class="button" name="CopySearch" value="<%loc('Copy')%>" />
% }
+</nobr>
-% if ($Dirty or $SearchId eq 'new') {
-<input type="submit" name="Save" value="<%loc('Save')%>">
% }
-<hr>
+<input type="submit" name="Save" value="<%loc('Save')%>" class="button" />
+<hr />
% }
-<&|/l&>Load saved search:</&><br>
-<& SelectSearchesForObjects, Name => 'LoadSavedSearch', Objects => \@Objects&>
-<input value="<%loc('Load')%>" type="submit">
-<& /Elements/TitleBoxEnd &>
+<&|/l&>Load saved search:</&><br />
+<& SelectSearchesForObjects, Name => 'LoadSavedSearch', Objects => \@Objects, SearchType => $SearchType &>
+<input value="<%loc('Load')%>" type="submit" class="button" />
+</&>
<%init>
-
unless ($session{'CurrentUser'}->HasRight( Right => 'LoadSavedSearch',
- Object=> $RT::System )) {
+ Object=> $RT::System )) {
return;
}
-my @Objects;
-
-push @Objects, $session{CurrentUser}->UserObj;
-
-my $groups = RT::Groups->new($session{'CurrentUser'});
-$groups->LimitToUserDefinedGroups;
-$groups->WithMember(PrincipalId => $session{'CurrentUser'}->Id,
- Recursively => 1);
+use RT::SavedSearches;
+my @Objects = RT::SavedSearches->new($session{CurrentUser})->_PrivacyObjects;
+push @Objects, RT::System->new($session{'CurrentUser'})
+ if $session{'CurrentUser'}->HasRight( Object=> $RT::System,
+ Right => 'SuperUser');
- push (@Objects, @{$groups->ItemsArrayRef()});
</%INIT>
<%ARGS>
+$SearchType => 'Ticket'
$SearchId => undef
$CurrentSearch => undef
$Description => undef
$HideResults => 0
$Dirty => 0
+$AllowCopy => 1
+$Title => 'Saved searches'
</%ARGS>
diff --git a/rt/html/Search/Elements/NewListActions b/rt/html/Search/Elements/NewListActions
index eb82544f3..535ac8cb9 100644
--- a/rt/html/Search/Elements/NewListActions
+++ b/rt/html/Search/Elements/NewListActions
@@ -2,7 +2,7 @@
%#
%# COPYRIGHT:
%#
-%# This software is Copyright (c) 1996-2005 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
%# <jesse@bestpractical.com>
%#
%# (Except where explicitly superseded by other copyright notices)
@@ -22,7 +22,9 @@
%#
%# 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
%#
%#
%# CONTRIBUTION SUBMISSION POLICY:
@@ -44,19 +46,19 @@
%#
%# END BPS TAGGED BLOCK }}}
% if ($actions[0] ) {
-<b><%loc('Results')%></b><br>
+<b><%loc('Results')%></b><br />
% foreach my $action (@actions) {
% next unless ($action);
% my @item = @$action;
% if ($item[1] < 0) {
-<font color=red>
+<font color="red">
% }
-&nbsp;<%$item[0]%><BR>
+&nbsp;<%$item[0]%><br />
% if ($item[1] < 0) {
</font>
% }
% }
-<BR>
+<br />
% }
<%init>
@actions = grep (/./,@actions);
diff --git a/rt/html/Search/Elements/PickBasics b/rt/html/Search/Elements/PickBasics
index 8a48f6b18..44a378c14 100644
--- a/rt/html/Search/Elements/PickBasics
+++ b/rt/html/Search/Elements/PickBasics
@@ -2,7 +2,7 @@
%#
%# COPYRIGHT:
%#
-%# This software is Copyright (c) 1996-2005 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
%# <jesse@bestpractical.com>
%#
%# (Except where explicitly superseded by other copyright notices)
@@ -22,7 +22,9 @@
%#
%# 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
%#
%#
%# CONTRIBUTION SUBMISSION POLICY:
@@ -49,11 +51,11 @@
</td><td>
<& /Elements/SelectEqualityOperator, Name => "idOp" &>
</td><td>
-<INPUT Name="ValueOfid" SIZE=5>
+<input name="ValueOfid" size="5" />
</td>
</tr>
-<tr><td align=right>
+<tr><td>
<& /Elements/SelectAttachmentField, Name => 'AttachmentField' &>
</td><td>
<& /Elements/SelectBoolean, Name => "AttachmentOp",
@@ -63,7 +65,7 @@
FalseVal => 'NOT LIKE'
&>
</td><td>
-<Input Name="ValueOfAttachment" Size=20>
+<input name="ValueOfAttachment" size="20" />
</td>
</tr>
<tr>
@@ -97,11 +99,11 @@
</td>
</tr>
<tr><td class="label">
-<SELECT NAME="ActorField">
-<OPTION VALUE="Owner"><&|/l&>Owner</&></OPTION>
-<OPTION VALUE="Creator"><&|/l&>Creator</&></OPTION>
-<OPTION VALUE="LastUpdatedBy"><&|/l&>LastUpdatedBy</&></OPTION>
-</SELECT>
+<select name="ActorField">
+<option value="Owner"><&|/l&>Owner</&></option>
+<option value="Creator"><&|/l&>Creator</&></option>
+<option value="LastUpdatedBy"><&|/l&>LastUpdatedBy</&></option>
+</select>
</td><td>
<& /Elements/SelectBoolean, Name => "ActorOp",
TrueVal=> '=',
@@ -117,21 +119,7 @@
</td><td>
<& /Elements/SelectMatch, Name => "WatcherOp" &>
</td><td>
-<Input Name="ValueOfWatcher" Size=20>
-</tr>
-<tr>
-<td class="label">
-<& SelectPersonType, Name => 'WatcherGroupField', Default => 'RequestorGroup', Suffix => 'Group' &>
-</td><td>
-<& /Elements/SelectBoolean, Name => "WatcherGroupOp",
- True=> loc('belongs to'),
- False=> loc('does not belong to'),
- TrueVal=> '=',
- FalseVal => '!='
-&>
-</td><td>
-<& SelectGroup, Name => 'ValueOfWatcherGroup' &>
-</td>
+<input name="ValueOfWatcher" size="20" />
</tr>
<tr>
<td class="label">
@@ -143,28 +131,29 @@
</td></tr>
<tr>
<td class="label">
-<SELECT NAME="TimeField">
-<OPTION VALUE="TimeWorked"><&|/l&>Time Worked</&></OPTION>
-<OPTION VALUE="TimeEstimated"><&|/l&>Time Estimated</&></OPTION>
-<OPTION VALUE="TimeLeft"><&|/l&>Time Left</&></OPTION>
-</SELECT>
+<select name="TimeField">
+<option value="TimeWorked"><&|/l&>Time Worked</&></option>
+<option value="TimeEstimated"><&|/l&>Time Estimated</&></option>
+<option value="TimeLeft"><&|/l&>Time Left</&></option>
+</select>
</td><td>
<& /Elements/SelectEqualityOperator, Name => "TimeOp" &>
</td><td>
-<INPUT Name="ValueOfTime" SIZE=5>
+<input name="ValueOfTime" size="5" />
+<& /Elements/SelectTimeUnits, Name =>'ValueOfTime' &>
</td>
</tr>
<tr>
<td class="label">
-<SELECT NAME="PriorityField">
-<OPTION VALUE="Priority"><&|/l&>Priority</&></OPTION>
-<OPTION VALUE="InitialPriority"><&|/l&>Initial Priority</&></OPTION>
-<OPTION VALUE="FinalPriority"><&|/l&>Final Priority</&></OPTION>
-</SELECT>
+<select name="PriorityField">
+<option value="Priority"><&|/l&>Priority</&></option>
+<option value="InitialPriority"><&|/l&>Initial Priority</&></option>
+<option value="FinalPriority"><&|/l&>Final Priority</&></option>
+</select>
</td><td>
<& /Elements/SelectEqualityOperator, Name => "PriorityOp" &>
</td><td>
-<INPUT Name="ValueOfPriority" SIZE=5>
+<input name="ValueOfPriority" size="5" />
</td>
</tr>
<tr>
@@ -177,7 +166,7 @@
TrueVal=> '=',
FalseVal => '!=' &>
</td><td>
-<INPUT Name="ValueOfLinks" value="" SIZE=5>
+<input name="ValueOfLinks" value="" size="5" />
</td></tr>
<%INIT>
my @people = ('Actor',
diff --git a/rt/html/Search/Elements/PickCFs b/rt/html/Search/Elements/PickCFs
index 435a07ad3..734f5f871 100644
--- a/rt/html/Search/Elements/PickCFs
+++ b/rt/html/Search/Elements/PickCFs
@@ -2,7 +2,7 @@
%#
%# COPYRIGHT:
%#
-%# This software is Copyright (c) 1996-2005 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
%# <jesse@bestpractical.com>
%#
%# (Except where explicitly superseded by other copyright notices)
@@ -22,7 +22,9 @@
%#
%# 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
%#
%#
%# CONTRIBUTION SUBMISSION POLICY:
diff --git a/rt/html/Search/Elements/PickCriteria b/rt/html/Search/Elements/PickCriteria
index 129344443..58b29fb57 100644
--- a/rt/html/Search/Elements/PickCriteria
+++ b/rt/html/Search/Elements/PickCriteria
@@ -2,7 +2,7 @@
%#
%# COPYRIGHT:
%#
-%# This software is Copyright (c) 1996-2005 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
%# <jesse@bestpractical.com>
%#
%# (Except where explicitly superseded by other copyright notices)
@@ -22,7 +22,9 @@
%#
%# 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
%#
%#
%# CONTRIBUTION SUBMISSION POLICY:
@@ -43,12 +45,12 @@
%# those contributions and any derivatives thereof.
%#
%# END BPS TAGGED BLOCK }}}
-<& /Elements/TitleBoxStart, title => loc('Add Criteria')&>
-<table width=100% cellspacing=0 cellpadding=0 border=0>
+<&| /Widgets/TitleBox, title => loc('Add Criteria')&>
+<table width="100%" cellspacing="0" cellpadding="0" border="0">
<tr>
<td>
- <table cellspacing=0 border=0>
- <tr><td class=label>
+ <table cellspacing="0" border="0">
+ <tr><td class="label">
<&|/l&>Aggregator</&>:
</td>
<td><& SelectAndOr, Name => "AndOr" &>
@@ -61,8 +63,8 @@
</td>
</tr>
<tr>
- <td valign=top>
- <table cellspacing=0 border=0>
+ <td valign="top">
+ <table cellspacing="0" border="0">
<& PickBasics &>
<& PickCFs, cfqueues => \%cfqueues &>
</table>
@@ -71,7 +73,7 @@
<tr><td>&nbsp;</td></tr>
</table>
-<& /Elements/TitleBoxEnd &>
+</&>
<%ARGS>
$addquery => 0
diff --git a/rt/html/Search/Elements/SearchPrivacy b/rt/html/Search/Elements/SearchPrivacy
index 270e1baa3..745ba62ac 100644
--- a/rt/html/Search/Elements/SearchPrivacy
+++ b/rt/html/Search/Elements/SearchPrivacy
@@ -2,7 +2,7 @@
%#
%# COPYRIGHT:
%#
-%# This software is Copyright (c) 1996-2005 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
%# <jesse@bestpractical.com>
%#
%# (Except where explicitly superseded by other copyright notices)
@@ -22,7 +22,9 @@
%#
%# 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
%#
%#
%# CONTRIBUTION SUBMISSION POLICY:
diff --git a/rt/html/Search/Elements/SelectAndOr b/rt/html/Search/Elements/SelectAndOr
index 2f3c70477..c8122660a 100644
--- a/rt/html/Search/Elements/SelectAndOr
+++ b/rt/html/Search/Elements/SelectAndOr
@@ -2,7 +2,7 @@
%#
%# COPYRIGHT:
%#
-%# This software is Copyright (c) 1996-2005 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
%# <jesse@bestpractical.com>
%#
%# (Except where explicitly superseded by other copyright notices)
@@ -22,7 +22,9 @@
%#
%# 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
%#
%#
%# CONTRIBUTION SUBMISSION POLICY:
@@ -43,8 +45,8 @@
%# those contributions and any derivatives thereof.
%#
%# END BPS TAGGED BLOCK }}}
-<input type=radio NAME="<%$Name%>" CHECKED VALUE="AND"><&|/l&>AND</&></input>
-<input type=radio NAME="<%$Name%>" VALUE="OR"><&|/l&>OR</&></input>
+<input type="radio" class="radio" name="<%$Name%>" checked value="AND" /><&|/l&>AND</&></input>
+<input type="radio" class="radio" name="<%$Name%>" value="OR" /><&|/l&>OR</&></input>
<%ARGS>
$Name => "Operator"
diff --git a/rt/html/Search/Elements/SelectGroup b/rt/html/Search/Elements/SelectGroup
index edd53713f..3f78d3964 100644
--- a/rt/html/Search/Elements/SelectGroup
+++ b/rt/html/Search/Elements/SelectGroup
@@ -2,7 +2,7 @@
%#
%# COPYRIGHT:
%#
-%# This software is Copyright (c) 1996-2005 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
%# <jesse@bestpractical.com>
%#
%# (Except where explicitly superseded by other copyright notices)
@@ -22,7 +22,9 @@
%#
%# 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
%#
%#
%# CONTRIBUTION SUBMISSION POLICY:
@@ -43,14 +45,14 @@
%# those contributions and any derivatives thereof.
%#
%# END BPS TAGGED BLOCK }}}
-<SELECT NAME="<%$Name%>">
+<select name="<%$Name%>">
% if ($AllowNull) {
-<OPTION VALUE="">-</OPTION>
+<option value="">-</option>
% }
%while (my $group = $groups->Next) {
-<OPTION VALUE="<%$group->id%>" <%$group->id eq $Default && "SELECTED"%>><%$group->Name%></OPTION>
+<option value="<%$group->id%>" <%$group->id eq $Default && "SELECTED"%>><%$group->Name%></option>
%}
-</SELECT>
+</select>
<%INIT>
my $groups = new RT::Groups($session{'CurrentUser'});
diff --git a/rt/html/Search/Elements/SelectLinks b/rt/html/Search/Elements/SelectLinks
index 00ec80bd3..f3586528d 100644
--- a/rt/html/Search/Elements/SelectLinks
+++ b/rt/html/Search/Elements/SelectLinks
@@ -2,7 +2,7 @@
%#
%# COPYRIGHT:
%#
-%# This software is Copyright (c) 1996-2005 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
%# <jesse@bestpractical.com>
%#
%# (Except where explicitly superseded by other copyright notices)
@@ -22,7 +22,9 @@
%#
%# 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
%#
%#
%# CONTRIBUTION SUBMISSION POLICY:
@@ -43,11 +45,11 @@
%# those contributions and any derivatives thereof.
%#
%# END BPS TAGGED BLOCK }}}
-<SELECT NAME="<%$Name%>">
+<select name="<%$Name%>">
% foreach (@fields) {
-<OPTION VALUE="<%$_%>"><&|/l&><%$_%></&></OPTION>
+<option value="<%$_%>"><&|/l&><%$_%></&></option>
% }
-</SELECT>
+</select>
<%ARGS>
$Name => 'LinksField'
</%ARGS>
diff --git a/rt/html/Search/Elements/SelectPersonType b/rt/html/Search/Elements/SelectPersonType
index d4127c97b..bc631dbb0 100644
--- a/rt/html/Search/Elements/SelectPersonType
+++ b/rt/html/Search/Elements/SelectPersonType
@@ -2,7 +2,7 @@
%#
%# COPYRIGHT:
%#
-%# This software is Copyright (c) 1996-2005 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
%# <jesse@bestpractical.com>
%#
%# (Except where explicitly superseded by other copyright notices)
@@ -22,7 +22,9 @@
%#
%# 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
%#
%#
%# CONTRIBUTION SUBMISSION POLICY:
@@ -43,20 +45,20 @@
%# those contributions and any derivatives thereof.
%#
%# END BPS TAGGED BLOCK }}}
-<SELECT NAME ="<%$Name%>">
+<select NAME ="<%$Name%>">
% if ($AllowNull) {
-<OPTION VALUE="">-</OPTION>
+<option value="">-</option>
% }
% for my $option (@types) {
% if ($Suffix) {
-<OPTION VALUE="<% $option %><% $Suffix %>" <%$option eq $Default && "SELECTED"%> ><%loc($option)%></OPTION>
+<option value="<% $option %><% $Suffix %>" <%$option eq $Default && "SELECTED"%> ><%loc($option)%></option>
% next;
% }
% foreach my $subtype (@subtypes) {
-<OPTION VALUE="<%"$option.$subtype"%>" <%$option eq $Default && $subtype eq 'EmailAddress' && "SELECTED"%> ><% loc($option) %> <% loc($subtype) %></OPTION>
+<option value="<%"$option.$subtype"%>" <%$option eq $Default && $subtype eq 'EmailAddress' && "SELECTED"%> ><% loc($option) %> <% loc($subtype) %></option>
% }
% }
-</SELECT>
+</select>
<%INIT>
my @types;
diff --git a/rt/html/Search/Elements/SelectSearchObject b/rt/html/Search/Elements/SelectSearchObject
index e9df5179f..f52a83372 100644
--- a/rt/html/Search/Elements/SelectSearchObject
+++ b/rt/html/Search/Elements/SelectSearchObject
@@ -2,7 +2,7 @@
%#
%# COPYRIGHT:
%#
-%# This software is Copyright (c) 1996-2005 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
%# <jesse@bestpractical.com>
%#
%# (Except where explicitly superseded by other copyright notices)
@@ -22,7 +22,9 @@
%#
%# 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
%#
%#
%# CONTRIBUTION SUBMISSION POLICY:
diff --git a/rt/html/Search/Elements/SelectSearchesForObjects b/rt/html/Search/Elements/SelectSearchesForObjects
index e6be66a58..dc8368577 100644
--- a/rt/html/Search/Elements/SelectSearchesForObjects
+++ b/rt/html/Search/Elements/SelectSearchesForObjects
@@ -2,7 +2,7 @@
%#
%# COPYRIGHT:
%#
-%# This software is Copyright (c) 1996-2005 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
%# <jesse@bestpractical.com>
%#
%# (Except where explicitly superseded by other copyright notices)
@@ -22,7 +22,9 @@
%#
%# 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
%#
%#
%# CONTRIBUTION SUBMISSION POLICY:
@@ -46,6 +48,7 @@
<%args>
@Objects => undef
$Name => undef
+$SearchType => 'Ticket',
</%args>
<select name="<%$Name%>">
% foreach my $object (@Objects) {
@@ -57,9 +60,9 @@ $Name => undef
% }
% my @searches = $object->Attributes->Named('SavedSearch');
% foreach my $search (@searches) {
-% # Skip it if it is not a ticket search.
+% # Skip it if it is not of search type we want.
% next if ($search->SubValue('SearchType')
-% && $search->SubValue('SearchType') ne 'Ticket');
+% && $search->SubValue('SearchType') ne $SearchType);
<option value="<%ref($object)%>-<%$object->id%>-SavedSearch-<%$search->Id%>"> -<%$search->Description||loc('Unnamed search')%></option>
% }
% }
diff --git a/rt/html/Search/Results.html b/rt/html/Search/Results.html
index 5849378a8..01bdfffde 100755
--- a/rt/html/Search/Results.html
+++ b/rt/html/Search/Results.html
@@ -2,7 +2,7 @@
%#
%# COPYRIGHT:
%#
-%# This software is Copyright (c) 1996-2005 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
%# <jesse@bestpractical.com>
%#
%# (Except where explicitly superseded by other copyright notices)
@@ -22,7 +22,9 @@
%#
%# 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
%#
%#
%# CONTRIBUTION SUBMISSION POLICY:
@@ -43,7 +45,8 @@
%# those contributions and any derivatives thereof.
%#
%# END BPS TAGGED BLOCK }}}
-<& /Elements/Header, Title => $title, Refresh => $session{'tickets_refresh_interval'} &>
+<& /Elements/Header, Title => $title, Refresh => $session{'tickets_refresh_interval'},
+ RSSAutoDiscovery => $RSSFeedURL &>
<& /Ticket/Elements/Tabs,
current_tab => "Search/Results.html".$QueryString,
Title => $title,
@@ -63,45 +66,82 @@
BaseURL => $RT::WebPath."/Search/Results.html?"
&>
-<div align=right>
-<form method=get action="<%$RT::WebPath%>/Search/Results.html">
-<input type="hidden" name="Query" value="<%$Query%>" />
-<input type="hidden" name="Format" value="<%$Format%>" />
-<input type="hidden" name="HideResults" value="<%$HideResults%>" />
-<input type="hidden" name="Rows" value="<%$Rows%>" />
-<input type="hidden" name="Page" value="<%$Page%>" />
-<input type="hidden" name="OrderBy" value="<%$OrderBy%>" />
-<input type="hidden" name="Order" value="<%$Order%>" />
+% my %hiddens = (Query => $Query, Format => $Format, Rows => $Rows, OrderBy => $OrderBy, Order => $Order, HideResults => $HideResults, Page => $Page );
+<div align="right">
+<form method="get" action="<%$RT::WebPath%>/Search/Results.html">
+%foreach my $key (keys(%hiddens)) {
+<input type="hidden" class="hidden" name="<%$key%>" value="<%defined($hiddens{$key})?$hiddens{$key}:''%>"/>
+%}
<& /Elements/Refresh, Name => 'TicketsRefreshInterval', Default => $session {'tickets_refresh_interval'} &>
-<input type=submit value="<&|/l&>Go!</&>">
+<input type="submit" class="button" value="<&|/l&>Go!</&>" />
</form>
</div>
-<div align=right>
-<a href="<%$RT::WebPath%>/Search/Bulk.html<%$QueryString%>"><&|/l&>Update multiple tickets</&></a><br>
-<a href="<%$RT::WebPath%>/Search/Results.html<%$QueryString%>"><&|/l&>Bookmarkable link</&></a><br>
+<div align="right">
+<a href="<%$RT::WebPath%>/Search/Bulk.html<%$QueryString%>"><&|/l&>Update multiple tickets</&></a><br />
+<a href="<%$RT::WebPath%>/Search/Results.html<%$QueryString%>"><&|/l&>Bookmarkable link</&></a><br />
<a href="<%$RT::WebPath%>/Search/Results.tsv<%$QueryString%>"><&|/l&>spreadsheet</&></a> |
-<a href="<%$RT::WebPath%>/Search/Results.rdf<%$ShortQueryString%>"><&|/l&>RSS</&></a> |
-<a href="<%$RT::WebPath%>/Tools/Offline.html<%$ShortQueryString%>"><&|/l&>Work offline</&></a><br>
+<a href="<%$RSSFeedURL%>"><&|/l&>RSS</&></a> |
+<a href="<%$RT::WebPath%>/Tools/Offline.html<%$ShortQueryString%>"><&|/l&>Work offline</&></a><br />
+<form method="get" action="<%$RT::WebPath%>/Search/Chart.html"><&|/l&>chart</&>
+% %hiddens = (Query => $Query, Format => $Format, Rows => $Rows, OrderBy => $OrderBy, Order => $Order);
+%foreach my $key (keys(%hiddens)) {
+<input type="hidden" class="hidden" name="<%$key%>" value="<%defined($hiddens{$key})?$hiddens{$key}:''%>"/>
+%}
+<&|/l, $m->scomp('Elements/SelectGroupBy', Name => 'PrimaryGroupBy', Query => $Query) &>grouped by [_1]</&>
+<&|/l, $m->scomp('Elements/SelectChartType', Name => 'ChartStyle') &>style: [_1]</&>
+<input type="submit" class="button" value="<%loc('Go!')%>" />
+</form>
<& /Elements/Callback, _CallbackName => 'SearchActions', QueryString => $QueryString&>
</div>
<%INIT>
+# Read from user preferences
+my $prefs = $session{'CurrentUser'}->UserObj->Preferences("SearchDisplay") || {};
+
+# These variables are what define a search_hash; this is also
+# where we give sane defaults.
+$Format ||= $prefs->{'Format'};
+$Order ||= $prefs->{'Order'} || 'ASC';
+$OrderBy ||= $prefs->{'OrderBy'} || 'id';
+
+# Some forms pass in "RowsPerPage" rather than "Rows"
+# We call it RowsPerPage everywhere else.
+
+if ( !defined($Rows) ) {
+ if ( $ARGS{'RowsPerPage'} ) {
+ $Rows = $ARGS{'RowsPerPage'};
+ } elsif ( defined $prefs->{'RowsPerPage'} ) {
+ $Rows = $prefs->{'RowsPerPage'};
+ } else {
+ $Rows = 50;
+ }
+}
+
my ($title, $ticketcount);
$session{'i'}++;
$session{'tickets'} = RT::Tickets->new($session{'CurrentUser'}) ;
$session{'tickets'}->FromSQL($Query) if ($Query);
-$session{'tickets'}->OrderBy(FIELD => $OrderBy, ORDER => $Order);
+if ($OrderBy =~ /\|/) {
+ # Multiple Sorts
+ my @OrderBy = split /\|/,$OrderBy;
+ my @Order = split /\|/,$Order;
+ $session{'tickets'}->OrderByCols(
+ map { { FIELD => $OrderBy[$_], ORDER => $Order[$_] } } ( 0
+ .. $#OrderBy ) );;
+} else {
+ $session{'tickets'}->OrderBy(FIELD => $OrderBy, ORDER => $Order);
+}
$session{'CurrentSearchHash'} = {
Format => $Format,
Query => $Query,
+ Page => $Page,
Order => $Order,
OrderBy => $OrderBy,
RowsPerPage => $Rows
};
-
if ( $session{'tickets'}->Query()) {
$ticketcount = $session{tickets}->CountAll();
$title = loc('Found [quant,_1,ticket]', $ticketcount);
@@ -116,13 +156,12 @@ my $QueryString = "?".$m->comp('/Elements/QueryString',
OrderBy => $OrderBy,
Order => $Order,
Page => $Page);
-
my $ShortQueryString = "?".$m->comp('/Elements/QueryString', Query => $Query);
+my $RSSFeedURL = "$RT::WebPath/Search/Results.rdf$ShortQueryString";
if ($ARGS{'TicketsRefreshInterval'}) {
$session{'tickets_refresh_interval'} = $ARGS{'TicketsRefreshInterval'};
}
-
</%INIT>
<%CLEANUP>
$session{'tickets'}->PrepForSerialization();
@@ -131,8 +170,8 @@ $session{'tickets'}->PrepForSerialization();
$Query => undef
$Format => undef
$HideResults => 0
-$Rows => 50
+$Rows => undef
$Page => 1
-$OrderBy => 'id'
-$Order => 'ASC'
+$OrderBy => undef
+$Order => undef
</%ARGS>
diff --git a/rt/html/Search/Results.rdf b/rt/html/Search/Results.rdf
index 7cc248306..fe97a314c 100644
--- a/rt/html/Search/Results.rdf
+++ b/rt/html/Search/Results.rdf
@@ -2,7 +2,7 @@
%#
%# COPYRIGHT:
%#
-%# This software is Copyright (c) 1996-2005 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
%# <jesse@bestpractical.com>
%#
%# (Except where explicitly superseded by other copyright notices)
@@ -22,7 +22,9 @@
%#
%# 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
%#
%#
%# CONTRIBUTION SUBMISSION POLICY:
@@ -47,7 +49,7 @@
my $Tickets = RT::Tickets->new($session{'CurrentUser'});
$Tickets->FromSQL($ARGS{'Query'});
-$r->content_type('application/rdf+xml');
+$r->content_type('application/rss+xml');
diff --git a/rt/html/Search/Results.tsv b/rt/html/Search/Results.tsv
index e6b20481f..bb1907317 100644
--- a/rt/html/Search/Results.tsv
+++ b/rt/html/Search/Results.tsv
@@ -2,7 +2,7 @@
%#
%# COPYRIGHT:
%#
-%# This software is Copyright (c) 1996-2005 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
%# <jesse@bestpractical.com>
%#
%# (Except where explicitly superseded by other copyright notices)
@@ -22,7 +22,9 @@
%#
%# 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
%#
%#
%# CONTRIBUTION SUBMISSION POLICY:
@@ -43,45 +45,64 @@
%# those contributions and any derivatives thereof.
%#
%# END BPS TAGGED BLOCK }}}
+<%ARGS>
+$OrderBy => 'id'
+$Order => 'ASC'
+</%ARGS>
<%INIT>
-my $Tickets = RT::Tickets->new($session{'CurrentUser'});
-$Tickets->FromSQL($ARGS{'Query'});
+my $Tickets = RT::Tickets->new( $session{'CurrentUser'} );
+$Tickets->FromSQL( $ARGS{'Query'} );
+if ( $OrderBy =~ /\|/ ) {
+
+ # Multiple Sorts
+ my @OrderBy = split /\|/, $OrderBy;
+ my @Order = split /\|/, $Order;
+ $Tickets->OrderByCols(
+ map { { FIELD => $OrderBy[$_], ORDER => $Order[$_] } }
+ ( 0 .. $#OrderBy ) );
+}
+else {
+ $Tickets->OrderBy( FIELD => $OrderBy, ORDER => $Order );
+}
my @rows;
my %known_cfs;
my @attrs = qw( id QueueObj->Name Subject Status TimeEstimated TimeWorked TimeLeft Priority FinalPriority OwnerObj->Name
- Requestors->MemberEmailAddressesAsString DueObj->ISO ToldObj->ISO
- CreatedObj->ISO ResolvedObj->ISO );
+ Requestors->MemberEmailAddressesAsString Cc->MemberEmailAddressesAsString AdminCc->MemberEmailAddressesAsString
+ DueObj->ISO ToldObj->ISO CreatedObj->ISO ResolvedObj->ISO LastUpdatedObj->ISO);
- $r->content_type('application/vnd.ms-excel');
- while ( my $Ticket = $Tickets->Next()) {
- my $row;
- foreach my $attr (@attrs) {
- my $method = '$Ticket->'.$attr.'()';
- $row->{$attr} = eval $method;
+$r->content_type('application/vnd.ms-excel');
+while ( my $Ticket = $Tickets->Next()) {
+ my $row;
+ foreach my $attr (@attrs) {
+ if ($attr =~ /(.*)->ISO$/ and $Ticket->$1->Unix <= 0) {
+ $row->{$attr} = "";
+ } else {
+ my $method = '$Ticket->'.$attr.'()';
+ $row->{$attr} = eval $method;
if ($@) {die "Failed to find $attr - ". $@};
- }
-
- my $cfs = $Ticket->QueueObj->TicketCustomFields();
- while (my $cf = $cfs->Next) {
- my @content;
- my $values = $Ticket->CustomFieldValues($cf->Id);
- while (my $value = $values->Next) {
- push @content, $value->Content;
- }
- $row->{'CustomField-'.$cf->Id} = join(', ',@content);
- if ($row->{'CustomField-'.$cf->Id}) {
- $known_cfs{$cf->Id} = $cf->Name;
- }
}
- push @rows, $row;
-
+ }
+ my $cfs = $Ticket->QueueObj->TicketCustomFields();
+ while (my $cf = $cfs->Next) {
+ my @content;
+ my $values = $Ticket->CustomFieldValues($cf->Id);
+ while (my $value = $values->Next) {
+ push @content, $value->Content;
+ }
+ $row->{'CustomField-'.$cf->Id} = join(', ',@content);
+ if ($row->{'CustomField-'.$cf->Id}) {
+ $known_cfs{$cf->Id} = $cf->Name;
+ }
}
+ push @rows, $row;
+}
+
{
-my @header;
+ my @header;
foreach my $attr (@attrs) {
my $label = $attr;
$label =~ s'Obj-.(?:AsString|Name|ISO)''g;
@@ -89,27 +110,25 @@ my @header;
push @header, $label;
}
foreach my $id (sort keys %known_cfs) {
- push @header, $known_cfs{$id};
+ push @header, "CF-".$known_cfs{$id};
}
-
-$m->out(join("\t", @header));
-$m->out("\n");
+ $m->out(join("\t", @header));
+ $m->out("\n");
}
+
foreach my $row (@rows) {
- my @row;
- foreach my $attr(@attrs) {
- push @row, $row->{"$attr"};
- }
- foreach my $id (sort keys %known_cfs) {
- my $val = $row->{'CustomField-'.$id};
- $val =~ s/(\n|\r)//g;
- push @row, $val;
- }
-
- $m->out(join("\t",@row));
- $m->out("\n");
+ my @row;
+ foreach my $attr(@attrs) {
+ push @row, $row->{"$attr"};
+ }
+ foreach my $id (sort keys %known_cfs) {
+ my $val = $row->{'CustomField-'.$id};
+ $val =~ s/(\n|\r)//g;
+ push @row, $val;
+ }
+ $m->out(join("\t",@row));
+ $m->out("\n");
}
-
$m->abort();
</%INIT>
diff --git a/rt/html/Search/Simple.html b/rt/html/Search/Simple.html
index cdffc4c46..01424a3b1 100644
--- a/rt/html/Search/Simple.html
+++ b/rt/html/Search/Simple.html
@@ -51,6 +51,8 @@
Title => $title
&>
+<& /Elements/Callback, _CallbackName => 'PreForm', %ARGS &>
+
<div id="SimpleSearchForm">
<form action="Simple.html" method="get">
@@ -64,6 +66,11 @@
<div align="center">
<input name="q" size="60" /><input type="submit" class="button" value="<&|/l&>Search</&>" />
</div>
+
+</form>
+
+<& /Elements/Callback, _CallbackName => 'PostForm', %ARGS &>
+
</div>
<%INIT>
@@ -78,8 +85,15 @@ if ($q) {
if ($q =~ /^(\d+)$/) {
RT::Interface::Web::Redirect($RT::WebURL."/Ticket/Display.html?id=".$q);
}
- my $search = RT::Search::Googleish->new(Argument => $q,
- TicketsObj => $tickets);
+
+ my %args = (
+ Argument => $q,
+ TicketsObj => $tickets,
+ );
+
+ $m->comp('/Elements/Callback', %ARGS, _CallbackName => 'SearchArgs', args => \%args);
+
+ my $search = RT::Search::Googleish->new(%args);
$m->comp( "Results.html", Query => $search->QueryToSQL() );
$m->comp( "/Elements/Footer" );