summaryrefslogtreecommitdiff
path: root/rt/share/html/Search
diff options
context:
space:
mode:
Diffstat (limited to 'rt/share/html/Search')
-rw-r--r--rt/share/html/Search/Article.html52
-rw-r--r--rt/share/html/Search/Build.html90
-rwxr-xr-xrt/share/html/Search/Bulk.html44
-rw-r--r--rt/share/html/Search/Calendar.html9
-rw-r--r--rt/share/html/Search/Chart8
-rw-r--r--rt/share/html/Search/Chart.html61
-rwxr-xr-xrt/share/html/Search/Edit.html16
-rw-r--r--rt/share/html/Search/Elements/Article64
-rw-r--r--rt/share/html/Search/Elements/BuildFormatString15
-rw-r--r--rt/share/html/Search/Elements/Chart82
-rw-r--r--rt/share/html/Search/Elements/ConditionRow2
-rw-r--r--rt/share/html/Search/Elements/DisplayOptions87
-rw-r--r--rt/share/html/Search/Elements/EditFormat31
-rw-r--r--rt/share/html/Search/Elements/EditQuery2
-rw-r--r--rt/share/html/Search/Elements/EditSearches21
-rw-r--r--rt/share/html/Search/Elements/EditSort142
-rw-r--r--rt/share/html/Search/Elements/Graph2
-rw-r--r--rt/share/html/Search/Elements/NewListActions2
-rw-r--r--rt/share/html/Search/Elements/PickBasics9
-rw-r--r--rt/share/html/Search/Elements/PickCFs36
-rw-r--r--rt/share/html/Search/Elements/PickCriteria6
-rw-r--r--rt/share/html/Search/Elements/ResultsRSSView6
-rw-r--r--rt/share/html/Search/Elements/SearchPrivacy2
-rw-r--r--rt/share/html/Search/Elements/SearchesForObject2
-rw-r--r--rt/share/html/Search/Elements/SelectAndOr2
-rw-r--r--rt/share/html/Search/Elements/SelectChartType2
-rw-r--r--rt/share/html/Search/Elements/SelectGroup4
-rw-r--r--rt/share/html/Search/Elements/SelectGroupBy2
-rw-r--r--rt/share/html/Search/Elements/SelectLinks2
-rw-r--r--rt/share/html/Search/Elements/SelectPersonType2
-rw-r--r--rt/share/html/Search/Elements/SelectSearchObject2
-rw-r--r--rt/share/html/Search/Elements/SelectSearchesForObjects8
-rw-r--r--rt/share/html/Search/Graph.html2
-rwxr-xr-xrt/share/html/Search/Results.html63
-rw-r--r--rt/share/html/Search/Results.rdf2
-rw-r--r--rt/share/html/Search/Results.tsv156
-rw-r--r--rt/share/html/Search/Simple.html47
37 files changed, 635 insertions, 450 deletions
diff --git a/rt/share/html/Search/Article.html b/rt/share/html/Search/Article.html
new file mode 100644
index 000000000..a50990598
--- /dev/null
+++ b/rt/share/html/Search/Article.html
@@ -0,0 +1,52 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+%# <sales@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 }}}
+<%init>
+RT::Interface::Web::Redirect(RT->Config->Get('WebURL').
+ 'Articles/Article/Search.html?' . $m->comp( '/Elements/QueryString',
+ %ARGS, Load => 'Load', CurrentSearch => $ARGS{LoadSavedSearch} ) );
+</%init>
diff --git a/rt/share/html/Search/Build.html b/rt/share/html/Search/Build.html
index 506384c4b..b200f9050 100644
--- a/rt/share/html/Search/Build.html
+++ b/rt/share/html/Search/Build.html
@@ -2,7 +2,7 @@
%#
%# COPYRIGHT:
%#
-%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
%# <sales@bestpractical.com>
%#
%# (Except where explicitly superseded by other copyright notices)
@@ -53,7 +53,7 @@
%# Build/Edit.html (Advanced).)
%#
%# After doing some stuff with default arguments and saved searches, the ParseQuery
-%# function (which is similar to, but not the same as, _parser in RT/Tickets_Overlay_SQL)
+%# function (which is similar to, but not the same as, _parser in lib/RT/Tickets_SQL.pm)
%# converts the Query into a RT::Interface::Web::QueryBuilder::Tree. This mason file
%# then adds stuff to or modifies the tree based on the actions that had been requested
%# by clicking buttons. It then calls GetQueryAndOptionList on the tree to generate
@@ -66,15 +66,9 @@
%# action does quote it (this breaks SQLite).
%#
<& /Elements/Header, Title => $title &>
-<& /Ticket/Elements/Tabs,
- current_tab => "Search/Build.html?".$QueryString,
- Title => $title,
- %query,
- SavedSearchId => $saved_search{'Id'},
- SavedChartSearchId => $ARGS{SavedChartSearchId},
-&>
+<& /Elements/Tabs, %TabArgs &>
-<form method="post" action="Build.html" name="BuildQuery">
+<form method="post" action="Build.html" name="BuildQuery" id="BuildQuery">
<input type="hidden" class="hidden" name="SavedSearchId" value="<% $saved_search{'Id'} %>" />
<input type="hidden" class="hidden" name="SavedChartSearchId" value="<% $ARGS{'SavedChartSearchId'} %>" />
<input type="hidden" class="hidden" name="Query" value="<% $query{'Query'} %>" />
@@ -84,9 +78,9 @@
<div id="pick-criteria">
- <& Elements/PickCriteria, query => $query{'Query'}, cfqueues => $queues &>
-<& /Elements/Submit, Label => loc('Add these terms'), Name => 'AddClause'&>
-<& /Elements/Submit, Label => loc('Add these terms and Search'), Name => 'DoSearch'&>
+ <& Elements/PickCriteria, query => $query{'Query'}, queues => $queues &>
+<& /Elements/Submit, Label => loc('Add these terms'), SubmitId => 'AddClause', Name => 'AddClause'&>
+<& /Elements/Submit, Label => loc('Add these terms and Search'), SubmitId => 'DoSearch', Name => 'DoSearch'&>
</div>
@@ -108,8 +102,8 @@
AvailableColumns => $AvailableColumns,
CurrentFormat => $CurrentFormat,
&>
-<& /Elements/Submit, Label => loc('Update format and Search'), Name => 'DoSearch', id=>"formatbuttons"&>
</span>
+<& /Elements/Submit, Label => loc('Update format and Search'), Name => 'DoSearch', id=>"formatbuttons"&>
</form>
<%INIT>
@@ -179,14 +173,22 @@ my $tree = $ParseQuery->( $query{'Query'}, \@parse_results );
# if parsing went poorly, send them to the edit page to fix it
if ( @parse_results ) {
- return $m->comp( "Edit.html", Query => $query{'Query'}, actions => \@actions );
+ push @actions, @parse_results;
+ return $m->comp(
+ "Edit.html",
+ Query => $query{'Query'},
+ Format => $query{'Format'},
+ SavedSearchId => $saved_search{'Id'},
+ SavedChartSearchId => $ARGS{'SavedChartSearchId'},
+ actions => \@actions,
+ );
}
my @options = $tree->GetDisplayedNodes;
my @current_values = grep defined, @options[@clauses];
my @new_values = ();
-# {{{ Try to find if we're adding a clause
+# Try to find if we're adding a clause
foreach my $arg ( keys %ARGS ) {
next unless $arg =~ m/^ValueOf([\w\.]+|'CF.{.*?}')$/
&& ( ref $ARGS{$arg} eq "ARRAY"
@@ -226,14 +228,16 @@ foreach my $arg ( keys %ARGS ) {
elsif ( $op eq '!=' ) {
$op = "IS NOT";
}
-
- # This isn't "right", but...
- # It has to be this way until #5182 is fixed
- $value = "'NULL'";
}
- else {
- $value =~ s/'/\\'/g;
- $value = "'$value'" unless $value =~ /^\d+$/;
+ elsif ($value =~ /\D/) {
+ $value =~ s/(['\\])/\\$1/g;
+ $value = "'$value'";
+ }
+
+ if ($keyword =~ /^'CF\.{(.*)}'/) {
+ my $cf = $1;
+ $cf =~ s/(['\\])/\\$1/g;
+ $keyword = "'CF.{$cf}'";
}
my $clause = {
@@ -246,7 +250,6 @@ foreach my $arg ( keys %ARGS ) {
}
}
-# }}}
push @actions, $m->comp('Elements/EditQuery:Process',
%ARGS,
@@ -255,7 +258,7 @@ push @actions, $m->comp('Elements/EditQuery:Process',
New => \@new_values,
);
-# {{{ Rebuild $Query based on the additions / movements
+# Rebuild $Query based on the additions / movements
my $optionlist_arrayref;
($query{'Query'}, $optionlist_arrayref) = $tree->GetQueryAndOptionList(\@current_values);
@@ -264,25 +267,29 @@ my $optionlist = join "\n", map { qq(<option value="$_->{INDEX}" $_->{SELECTED}>
. ("&nbsp;" x (5 * $_->{DEPTH}))
. $m->interp->apply_escapes($_->{TEXT}, 'h') . qq(</option>) } @$optionlist_arrayref;
-# }}}
my $queues = $tree->GetReferencedQueues;
-# {{{ Deal with format changes
+# Deal with format changes
my ( $AvailableColumns, $CurrentFormat );
( $query{'Format'}, $AvailableColumns, $CurrentFormat ) = $m->comp(
'Elements/BuildFormatString',
%ARGS,
- cfqueues => $queues,
+ queues => $queues,
Format => $query{'Format'},
);
-# }}}
# if we're asked to save the current search, save it
push @actions, $m->comp( 'Elements/EditSearches:Save', %ARGS, Query => \%query, SavedSearch => \%saved_search);
-# {{{ Push the updates into the session so we don't loose 'em
+# Populate the "query" context with saved search data
+
+if ($ARGS{SavedSearchSave}) {
+ $query{'SavedSearchId'} = $saved_search{'Id'};
+}
+
+# Push the updates into the session so we don't lose 'em
$session{'CurrentSearchHash'} = {
%query,
@@ -291,30 +298,31 @@ $session{'CurrentSearchHash'} = {
Description => $saved_search{'Description'},
};
-# }}}
-# {{{ Show the results, if we were asked.
+# Show the results, if we were asked.
if ( $ARGS{'DoSearch'} ) {
- $m->comp( 'Results.html', %query, SavedChartSearchId => $ARGS{'SavedChartSearchId'}, );
- $m->comp( '/Elements/Footer' );
+ my $redir_query_string = $m->comp(
+ '/Elements/QueryString',
+ %query,
+ SavedChartSearchId => $ARGS{'SavedChartSearchId'},
+ SavedSearchId => $saved_search{'Id'},
+ );
+ RT::Interface::Web::Redirect(RT->Config->Get('WebURL') . 'Search/Results.html?' . $redir_query_string);
$m->abort;
}
-# }}}
-# {{{ Build a querystring for the tabs
+# Build a querystring for the tabs
-my $QueryString = '';
+my %TabArgs = ();
if ($NewQuery) {
- $QueryString = 'NewQuery=1';
+ $TabArgs{QueryString} = 'NewQuery=1';
}
elsif ( $query{'Query'} ) {
- $QueryString = $m->comp('/Elements/QueryString', %query );
+ $TabArgs{QueryArgs} = \%query;
}
-# }}}
-
</%INIT>
<%ARGS>
diff --git a/rt/share/html/Search/Bulk.html b/rt/share/html/Search/Bulk.html
index 9f58789ab..250f6135d 100755
--- a/rt/share/html/Search/Bulk.html
+++ b/rt/share/html/Search/Bulk.html
@@ -2,7 +2,7 @@
%#
%# COPYRIGHT:
%#
-%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
%# <sales@bestpractical.com>
%#
%# (Except where explicitly superseded by other copyright notices)
@@ -46,20 +46,10 @@
%#
%# END BPS TAGGED BLOCK }}}
<& /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,
- SavedSearchId => $SavedSearchId,
- SavedChartSearchId => $SavedChartSearchId,
- &>
+<& /Elements/Tabs &>
<& /Elements/ListActions, actions => \@results &>
-<form method="post" action="<% RT->Config->Get('WebPath') %>/Search/Bulk.html" enctype="multipart/form-data">
+<form method="post" action="<% RT->Config->Get('WebPath') %>/Search/Bulk.html" enctype="multipart/form-data" name="BulkUpdate" id="BulkUpdate">
% foreach my $var (qw(Query Format OrderBy Order Rows Page SavedChartSearchId)) {
<input type="hidden" class="hidden" name="<%$var%>" value="<%$ARGS{$var} || ''%>" />
%}
@@ -81,7 +71,7 @@
<hr />
-<& /Elements/Submit, Label => loc('Update'), CheckAll => 1, ClearAll => 1 &>
+<& /Elements/Submit, Label => loc('Update'), CheckboxNameRegex => '/^UpdateTicket\d+$/', CheckAll => 1, ClearAll => 1 &>
<br />
<&|/Widgets/TitleBox, title => $title &>
<table>
@@ -142,7 +132,7 @@
<table>
<tr><td align="right"><&|/l&>Update Type</&>:</td>
<td><select name="UpdateType">
- <option value="private" <% $ARGS{UpdateType} && $ARGS{UpdateType} eq 'private' ? 'selected="selected"' : '' %> ><&|/l&>Comments (not sent to requestors)</&></option>
+ <option value="private" <% $ARGS{UpdateType} && $ARGS{UpdateType} eq 'private' ? 'selected="selected"' : '' %> ><&|/l&>Comments (Not sent to requestors)</&></option>
<option value="response" <% $ARGS{UpdateType} && $ARGS{UpdateType} eq 'response' ? 'selected="selected"' : '' %>><&|/l&>Reply to requestors</&></option>
</select>
</td></tr>
@@ -159,20 +149,9 @@ size="60" value="<% $ARGS{UpdateSubject} || "" %>" /></td></tr>
&><em><% $CF->FriendlyType %></em></td>
</td></tr>
% } # end if while
-% if (exists $session{'Attachments'}) {
-<tr><td><&|/l&>Attached file</&>:</td>
-<td>
-<&|/l&>Check box to delete</&><br />
-% foreach my $attach_name (keys %{$session{'Attachments'}}) {
-<input type="checkbox" class="checkbox" name="DeleteAttach-<%$attach_name%>" value="1" /><%$attach_name%><br />
-% } # end of foreach
-</td>
-</tr>
-% } # end of if
- <tr><td align="right"><&|/l&>Attach</&>:</td><td><input name="Attach" type="file" />
- <input type="submit" class="button" name="AddMoreAttach" value="<&|/l&>Add More Files</&>" />
- <input type="hidden" class="hidden" name="UpdateAttach" value="1" /></td></tr>
+<& /Ticket/Elements/AddAttachments, %ARGS &>
+
<tr><td class="labeltop"><&|/l&>Message</&>:</td><td>
%# Currently, bulk update always starts with Comment not Reply selected, so we check this unconditionally
% my $IncludeSignature = RT->Config->Get('MessageBoxIncludeSignatureOnComment');
@@ -255,17 +234,16 @@ map ( $ARGS{$_} =~ /^$/ && ( delete $ARGS{$_} ), keys %ARGS );
my (@results);
-# {{{ deal with deleting uploaded attachments
+# deal with deleting uploaded attachments
foreach my $key (keys %ARGS) {
if ($key =~ m/^DeleteAttach-(.+)$/) {
delete $session{'Attachments'}{$1};
}
$session{'Attachments'} = { %{$session{'Attachments'} || {}} };
}
-# }}}
-# {{{ store the uploaded attachment in session
-if ($ARGS{'Attach'}) { # attachment?
+# store the uploaded attachment in session
+if ( defined $ARGS{'Attach'} && length $ARGS{'Attach'} ) { # attachment?
my $attachment = MakeMIMEEntity(
AttachmentFieldName => 'Attach'
);
@@ -276,13 +254,11 @@ if ($ARGS{'Attach'}) { # attachment?
$file_path => $attachment,
};
}
-# }}}
# delete temporary storage entry to make WebUI clean
unless (keys %{$session{'Attachments'}} and $ARGS{'UpdateAttach'}) {
delete $session{'Attachments'};
}
-# }}}
$Page ||= 1;
diff --git a/rt/share/html/Search/Calendar.html b/rt/share/html/Search/Calendar.html
index 9d2b6f546..8a1b79609 100644
--- a/rt/share/html/Search/Calendar.html
+++ b/rt/share/html/Search/Calendar.html
@@ -10,9 +10,8 @@ $NewQuery => 0
</%args>
<& /Elements/Header, Title => $title &>
-<& /Ticket/Elements/Tabs,
- current_tab => "Search/Calendar.html?$QueryString",
- Title => $title &>
+<& /Elements/Tabs &>
+
<&| /Widgets/TitleBox,
title => loc('Calendar for ') . $rtdate->GetMonth($Month) . " $Year" ,
title_class=> 'inverse',
@@ -195,7 +194,7 @@ my $set = DateTime::Set->from_recurrence(
next => sub { $_[0]->truncate( to => 'day' )->add( days => 1 ) }
);
-my $QueryString =
+my $QueryString =
$m->comp(
'/Elements/QueryString',
Query => $Query,
@@ -212,7 +211,7 @@ $QueryString ||= 'NewQuery=1';
my $TempFormat = "__Starts__ __Due__";
my $TempQuery = "( Status = 'new' OR Status = 'open' OR Status = 'stalled')
AND ( Owner = '" . $session{CurrentUser}->Id ."' OR Owner = 'Nobody' )
- AND ( Type = 'reminder' OR 'Type' = 'ticket' )";
+ AND ( Type = 'reminder' OR 'Type' = 'ticket' )";
if ( my $Search = RTx::Calendar::SearchDefaultCalendar($session{CurrentUser}) ) {
$TempFormat = $Search->SubValue('Format');
diff --git a/rt/share/html/Search/Chart b/rt/share/html/Search/Chart
index 7bcb8d0d9..2709eb9c2 100644
--- a/rt/share/html/Search/Chart
+++ b/rt/share/html/Search/Chart
@@ -2,7 +2,7 @@
%#
%# COPYRIGHT:
%#
-%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
%# <sales@bestpractical.com>
%#
%# (Except where explicitly superseded by other copyright notices)
@@ -48,7 +48,6 @@
<%args>
$Query => "id > 0"
$PrimaryGroupBy => 'Queue'
-$SecondaryGroupBy => undef
$ChartStyle => 'bars'
</%args>
<%init>
@@ -170,9 +169,8 @@ if ($chart_class eq "GD::Graph::bars") {
# refine values' colors, with both Color::Scheme's help and my own tweak
$chart->{dclrs} = [
'66cc66', 'ff6666', 'ffcc66', '663399',
- '3333cc',
- '339933', '993333', '996633', '663399',
- '33cc33', 'cc3333', 'cc9933', '6633cc'
+ '3333cc', '339933', '993333', '996633',
+ '33cc33', 'cc3333', 'cc9933', '6633cc',
];
{
diff --git a/rt/share/html/Search/Chart.html b/rt/share/html/Search/Chart.html
index 1a80ee385..070ce7cf7 100644
--- a/rt/share/html/Search/Chart.html
+++ b/rt/share/html/Search/Chart.html
@@ -2,7 +2,7 @@
%#
%# COPYRIGHT:
%#
-%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
%# <sales@bestpractical.com>
%#
%# (Except where explicitly superseded by other copyright notices)
@@ -47,12 +47,10 @@
%# END BPS TAGGED BLOCK }}}
<%args>
$PrimaryGroupBy => 'Queue'
-$SecondaryGroupBy => ''
$ChartStyle => 'bars'
$Description => undef
</%args>
<%init>
-$ARGS{SecondaryGroupBy} ||= '';
$ARGS{Query} ||= 'id > 0';
# FIXME: should be factored with RT::Report::Tickets::Label :(
@@ -74,25 +72,64 @@ my $title = loc( "Search results grouped by [_1]", $PrimaryGroupByLabel );
my $saved_search = $m->comp( '/Widgets/SavedSearch:new',
SearchType => 'Chart',
- SearchFields => [qw(Query PrimaryGroupBy SecondaryGroupBy ChartStyle)] );
+ SearchFields => [qw(Query PrimaryGroupBy ChartStyle)] );
my @actions = $m->comp( '/Widgets/SavedSearch:process', args => \%ARGS, self => $saved_search );
+my %query;
+
+{
+ if ($saved_search->{'CurrentSearch'}->{'Object'}) {
+ foreach my $search_field (@{ $saved_search->{'SearchFields'} }) {
+ $query{$search_field} = $saved_search->{'CurrentSearch'}->{'Object'}->Content->{$search_field};
+ }
+ }
+
+ my $current = $session{'CurrentSearchHash'};
+
+ my @session_fields = qw(
+ Query
+ SavedChartSearchId
+ SavedSearchDescription
+ SavedSearchLoad
+ SavedSearchLoadButton
+ SavedSearchOwner
+ );
+
+ for(@session_fields) {
+ $query{$_} = $current->{$_} unless defined $query{$_};
+ $query{$_} = $m->request_args->{$_} unless defined $query{$_};
+ }
+
+ if ($m->request_args->{'SavedSearchLoadSubmit'}) {
+ $query{'SavedChartSearchId'} = $m->request_args->{'SavedSearchLoad'};
+ }
+
+ if ($m->request_args->{'SavedSearchSave'}) {
+ $query{'SavedChartSearchId'} = $saved_search->{'SearchId'};
+ }
+
+}
+
</%init>
<& /Elements/Header, Title => $title &>
-<& /Ticket/Elements/Tabs, Title => $title, Query => $ARGS{Query},
- SavedChartSearchId => $saved_search->{SearchId} &>
+<& /Elements/Tabs, QueryArgs => \%query &>
<& /Elements/ListActions, actions => \@actions &>
<& /Search/Elements/Chart, %ARGS &>
-<br />
-<&| /Widgets/TitleBox, title => loc('Graph Properties')&>
+<div class="chart-meta">
+<div class="chart-type">
+<&| /Widgets/TitleBox, title => loc('Chart Properties')&>
<form method="get" action="<%RT->Config->Get('WebPath')%>/Search/Chart.html">
<input type="hidden" class="hidden" name="Query" value="<% $ARGS{Query} %>" />
<input type="hidden" class="hidden" name="SavedChartSearchId" value="<% $saved_search->{SearchId} || 'new' %>" />
-<&|/l, $m->scomp('Elements/SelectChartType', Name => 'ChartStyle', Default => $ChartStyle), $m->scomp('Elements/SelectGroupBy', Name => 'PrimaryGroupBy', Query => $ARGS{Query}, Default => $PrimaryGroupBy)
-&>[_1] chart by [_2]</&><input type="submit" class="button" value="<%loc('Update Graph')%>" />
+
+<&|/l_unsafe, $m->scomp('Elements/SelectChartType', Name => 'ChartStyle', Default => $ChartStyle), $m->scomp('Elements/SelectGroupBy', Name => 'PrimaryGroupBy', Query => $ARGS{Query}, Default => $PrimaryGroupBy)
+&>[_1] chart by [_2]</&><input type="submit" class="button" value="<%loc('Update Chart')%>" />
</form>
</&>
-
-<& /Widgets/SavedSearch:show, %ARGS, Action => 'Chart.html', self => $saved_search, Title => loc('Saved charts') &>
+</div>
+<div class="saved-search">
+ <& /Widgets/SavedSearch:show, %ARGS, Action => 'Chart.html', self => $saved_search, Title => loc('Saved charts') &>
+</div>
+</div>
diff --git a/rt/share/html/Search/Edit.html b/rt/share/html/Search/Edit.html
index 76993f138..2459be0e4 100755
--- a/rt/share/html/Search/Edit.html
+++ b/rt/share/html/Search/Edit.html
@@ -2,7 +2,7 @@
%#
%# COPYRIGHT:
%#
-%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
%# <sales@bestpractical.com>
%#
%# (Except where explicitly superseded by other copyright notices)
@@ -46,21 +46,11 @@
%#
%# END BPS TAGGED BLOCK }}}
<& /Elements/Header, Title => $title&>
-<& /Ticket/Elements/Tabs,
- current_tab => "Search/Edit.html?".$QueryString,
- Title => $title,
- Format => $Format,
- Query => $Query,
- Rows => $Rows,
- OrderBy => $OrderBy,
- Order => $Order,
- SavedSearchId => $SavedSearchId,
- SavedChartSearchId => $SavedChartSearchId,
-&>
+<& /Elements/Tabs &>
<& Elements/NewListActions, actions => \@actions &>
-<form method="post" action="Build.html">
+<form method="post" action="Build.html" id="BuildQueryAdvanced" name="BuildQueryAdvanced">
<input type="hidden" class="hidden" name="SavedSearchId" value="<% $SavedSearchId %>" />
<input type="hidden" class="hidden" name="SavedChartSearchId" value="<% $SavedChartSearchId %>" />
<&|/Widgets/TitleBox, title => loc('Query'), &>
diff --git a/rt/share/html/Search/Elements/Article b/rt/share/html/Search/Elements/Article
new file mode 100644
index 000000000..46c13d79e
--- /dev/null
+++ b/rt/share/html/Search/Elements/Article
@@ -0,0 +1,64 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+%# <sales@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/CollectionList, %ARGS,
+ Collection => $articles,
+ Class => 'RT::Articles',
+ Format => q{
+ '<a href="/Articles/Article/Display.html?id=__id__">__id__</a>/TITLE:#',
+ '<a href="/Articles/Article/Display.html?id=__id__">__Name__</a>/TITLE:Name',
+ '__ClassName__',
+ '__CreatedRelative__',
+ '__LastUpdatedRelative__',
+ '__Summary__',
+ '__Topics__', }
+ &>
+<%INIT>
+my $QueryString = "?".$m->comp('/Elements/QueryString', %{$ARGS{args}});
+my $articles = RT::Articles->new( $session{CurrentUser} );
+$articles->Search( %{$ARGS{args}} );
+</%INIT>
diff --git a/rt/share/html/Search/Elements/BuildFormatString b/rt/share/html/Search/Elements/BuildFormatString
index 57c767911..a39287bff 100644
--- a/rt/share/html/Search/Elements/BuildFormatString
+++ b/rt/share/html/Search/Elements/BuildFormatString
@@ -2,7 +2,7 @@
%#
%# COPYRIGHT:
%#
-%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
%# <sales@bestpractical.com>
%#
%# (Except where explicitly superseded by other copyright notices)
@@ -48,7 +48,7 @@
<%ARGS>
$Format => RT->Config->Get('DefaultSearchResultFormat')
-%cfqueues => ()
+%queues => ()
$Face => undef
$Size => undef
@@ -104,23 +104,18 @@ my @fields = (
Bookmark
NEWLINE
+ NBSP
)
); # loc_qw
$m->callback( CallbackOnce => 1, CallbackName => 'SetFieldsOnce', Fields => \@fields );
my $CustomFields = RT::CustomFields->new( $session{'CurrentUser'});
-foreach my $id (keys %cfqueues) {
+foreach my $id (keys %queues) {
# Gotta load up the $queue object, since queues get stored by name now. my $id
my $queue = RT::Queue->new($session{'CurrentUser'});
$queue->Load($id);
- unless ($queue->id) {
- # XXX TODO: This ancient code dates from a former developer
- # we have no idea what it means or why cfqueues are so encoded.
- $id =~ s/^.'*(.*).'*$/$1/;
- $queue->Load($id);
- }
- $CustomFields->LimitToQueue($queue->Id);
+ $CustomFields->LimitToQueue($queue->Id) if $queue->Id;
}
$CustomFields->LimitToGlobal;
diff --git a/rt/share/html/Search/Elements/Chart b/rt/share/html/Search/Elements/Chart
index e25a9efd0..be05da315 100644
--- a/rt/share/html/Search/Elements/Chart
+++ b/rt/share/html/Search/Elements/Chart
@@ -2,7 +2,7 @@
%#
%# COPYRIGHT:
%#
-%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
%# <sales@bestpractical.com>
%#
%# (Except where explicitly superseded by other copyright notices)
@@ -48,7 +48,6 @@
<%args>
$Query => "id > 0"
$PrimaryGroupBy => 'Queue'
-$SecondaryGroupBy => undef
$ChartStyle => 'bars'
</%args>
<%init>
@@ -89,65 +88,66 @@ my %loc_keys;
foreach my $key (@keys) { $data{$key} = shift @values; $loc_keys{$key} = loc($key); }
my @sorted_keys = map { $loc_keys{$_}} sort { $loc_keys{$a} cmp $loc_keys{$b} } keys %loc_keys;
my @sorted_values = map { $data{$_}} sort { $loc_keys{$a} cmp $loc_keys{$b} } keys %loc_keys;
-
-
my $query_string = $m->comp('/Elements/QueryString', %ARGS);
-</%init>
-
-<% loc('Query:') %>&nbsp;<% $Query %><br />
+my ($i,$total);
+</%init>
+<div class="chart-wrapper">
+<span class="chart image">
% if (RT->Config->Get('DisableGD')) {
<% loc('Graphical charts are not available.') %><br />
% } else {
-<img src="<%RT->Config->Get('WebPath')%>/Search/Chart?<%$query_string|n%>" /><br />
+<img src="<%RT->Config->Get('WebPath')%>/Search/Chart?<%$query_string|n%>" />
% }
-
-<table class="collection-as-table">
+</span>
+<table class="collection-as-table chart">
<tr>
<th class="collection-as-table"><% loc($tix->Label($PrimaryGroupBy)) %>
</th>
<th class="collection-as-table"><&|/l&>Tickets</&>
</th>
</tr>
-% my ($i,$total);
-% while (my $key = shift @sorted_keys) {
-% $i++;
-% my $value = shift @sorted_values;
-% $total += $value;
-<tr class="<%$i%2 ? 'evenline' : 'oddline' %>">
+<%perl>
+ while (my $key = shift @sorted_keys) {
+ $i++;
+ my $value = shift @sorted_values;
+ $total += $value;
+</%perl>
+<tr class="<% $i%2 ? 'evenline' : 'oddline' %>">
+<%perl>
+# TODO sadly we don't have "creator.city is null" or alike support yet
+# so no link if the key is undef for now
+ if ( $PrimaryGroupBy !~ /(Hourly|Daily|Monthly|Annually)$/
+ && $key ne loc('(no value)') ) {
+ my $group = $PrimaryGroupBy; $group =~ s! !.!;
+ my %orig_keys = reverse %loc_keys;
+ my $QueryString = $m->comp('/Elements/QueryString',
+ Query => "$Query and $group = '$orig_keys{$key}'",
+ Format => $ARGS{Format},
+ Rows => $ARGS{Rows},
+ OrderBy => $ARGS{OrderBy},
+ Order => $ARGS{Order},
+ );
+</%perl>
<td class="label collection-as-table">
-%# TODO sadly we don't have "creator.city is null" or alike support yet
-%# so no link if the key is undef for now
-% if ( $PrimaryGroupBy !~ /(Hourly|Daily|Monthly|Annually)$/
-% && $key ne loc('(no value)') ) {
-% my $group = $PrimaryGroupBy; $group =~ s! !.!;
-% my %orig_keys = reverse %loc_keys;
-% my $QueryString = $m->comp('/Elements/QueryString',
-% Query => "$Query and $group = '$orig_keys{$key}'",
-% Format => $ARGS{Format},
-% Rows => $ARGS{Rows},
-% OrderBy => $ARGS{OrderBy},
-% Order => $ARGS{Order},
-% );
-<a href=<% RT->Config->Get('WebURL') %>Search/Results.html?<%$QueryString%>><%$key%></a>
-% } else {
-<% $key %>
-% }
+<a href=<% RT->Config->Get('WebPath') %>/Search/Results.html?<%$QueryString%>><%$key%></a>
</td>
<td class="value collection-as-table">
-<%$value%>
+<a href=<% RT->Config->Get('WebPath') %>/Search/Results.html?<%$QueryString%>><%$value%></a>
</td>
+% } else {
+<td class="label collection-as-table"><% $key %></td>
+<td class="value collection-as-table"><% $value %></td>
+% }
</tr>
% }
%$i++;
-<tr class="<%$i%2 ? 'evenline' : 'oddline' %>">
-<td class="label collection-as-table">
-<%loc('Total')%>
-</td>
-<td class="value collection-as-table">
-<%$total||''%>
-</td>
+<tr class="<%$i%2 ? 'evenline' : 'oddline' %> total">
+<td class="label collection-as-table"><%loc('Total')%></td>
+<td class="value collection-as-table"><%$total||'0'%></td>
</tr>
</table>
+<div class="query"><span class="label"><% loc('Query') %>:</span><span class="value"><% $Query %></span></div>
+</div>
diff --git a/rt/share/html/Search/Elements/ConditionRow b/rt/share/html/Search/Elements/ConditionRow
index 65e217639..9d68b0925 100644
--- a/rt/share/html/Search/Elements/ConditionRow
+++ b/rt/share/html/Search/Elements/ConditionRow
@@ -2,7 +2,7 @@
%#
%# COPYRIGHT:
%#
-%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
%# <sales@bestpractical.com>
%#
%# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/share/html/Search/Elements/DisplayOptions b/rt/share/html/Search/Elements/DisplayOptions
index c83035884..fbd497eb8 100644
--- a/rt/share/html/Search/Elements/DisplayOptions
+++ b/rt/share/html/Search/Elements/DisplayOptions
@@ -2,7 +2,7 @@
%#
%# COPYRIGHT:
%#
-%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
%# <sales@bestpractical.com>
%#
%# (Except where explicitly superseded by other copyright notices)
@@ -46,91 +46,8 @@
%#
%# END BPS TAGGED BLOCK }}}
<&| /Widgets/TitleBox, title => loc("Sorting"), id => 'sorting' &>
-<table valign="top">
-
-% for my $o (0..3) {
-% $Order[$o] ||= ''; $OrderBy[$o] ||= '';
-<tr>
-<td class="label">
-% if ($o == 0) {
-<&|/l&>Order by</&>:
-% }
-</td>
-<td class="value">
-<select name="OrderBy">
-% if ($o > 0) {
-<option value=""><&|/l&>~[none~]</&></option>
-% }
-% foreach my $field (sort keys %fields) {
-% next unless $field;
-<option value="<%$field%>"
-% if (defined $OrderBy[$o] and $field eq $OrderBy[$o]) {
-selected="selected"
-% }
-><% loc($field) %></option>
-% }
-</select>
-<select name="Order">
-<option value="ASC"
-% unless ( ($Order[$o]||'') eq "DESC" ) {
-selected="selected"
-% }
-><&|/l&>Asc</&></option>
-<option value="DESC"
-% if ( ($Order[$o]||'') eq "DESC" ) {
-selected="selected"
-% }
-><&|/l&>Desc</&></option>
-</select>
-</td>
-</tr>
-% }
-<tr>
-<td class="label">
-<&|/l&>Rows per page</&>:
-</td><td class="value">
-<& /Elements/SelectResultsPerPage,
- Name => "RowsPerPage",
- Default => $RowsPerPage &>
-</td>
-</tr>
-</table>
+<& EditSort, %ARGS &>
</&>
<&| /Widgets/TitleBox, title => loc("Display Columns"), id => 'columns' &>
<& EditFormat, %ARGS &>
</&>
-
-<%INIT>
-my $tickets = new RT::Tickets($session{'CurrentUser'});
-my %fields = %{$tickets->FIELDS};
-map { $fields{$_}->[0] =~ /^(?:ENUM|INT|DATE|STRING|ID)$/ || delete $fields{$_} } keys %fields;
-delete $fields{'EffectiveId'};
-$fields{'Owner'} = 1;
-$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;
-
-$fields{"Customer.$_"} = 1 foreach qw( Number Name ); #Freeside
-
-my @Order = split /\|/, $Order;
-my @OrderBy = split /\|/, $OrderBy;
-if ($Order =~ /\|/) {
- @Order = split /\|/, $Order;
-} else {
- @Order = ( $Order );
-}
-
-</%INIT>
-
-<%ARGS>
-$Order => undef
-$OrderBy => undef
-$RowsPerPage => undef
-$Format => undef
-$GroupBy => 'id'
-</%ARGS>
diff --git a/rt/share/html/Search/Elements/EditFormat b/rt/share/html/Search/Elements/EditFormat
index bb869fe66..3eb5a9100 100644
--- a/rt/share/html/Search/Elements/EditFormat
+++ b/rt/share/html/Search/Elements/EditFormat
@@ -2,7 +2,7 @@
%#
%# COPYRIGHT:
%#
-%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
%# <sales@bestpractical.com>
%#
%# (Except where explicitly superseded by other copyright notices)
@@ -45,7 +45,7 @@
%# those contributions and any derivatives thereof.
%#
%# END BPS TAGGED BLOCK }}}
-<table>
+<table class="edit-columns">
<tr>
<th><&|/l&>Add Columns</&>:</th>
@@ -62,8 +62,10 @@
<option value="<% $field %>"><% loc($field) %></option>
% }
</select></td>
-
-<td><&|/l&>Link</&>:
+<td>
+<div class="row">
+<span class="label"><&|/l&>Link</&>:</span>
+<span class="value">
<select name="Link">
<option value="None">-</option>
<option value="Display"><&|/l&>Display</&></option>
@@ -72,19 +74,30 @@
<option value="Comment"><&|/l&>Comment</&></option>
<option value="Resolve"><&|/l&>Resolve</&></option>
</select>
-<br /><&|/l&>Title</&>: <input name="Title" size="10" />
-<br /><&|/l&>Size</&>:
-<select name="Size">
+</span>
+</div>
+<div class="row">
+<span class="label"><&|/l&>Title</&>:</span>
+<span class="value"><input name="Title" size="10" /></span>
+</div>
+<div class="row">
+<span class="label"><&|/l&>Size</&>:</span>
+<span class="value"><select name="Size">
<option value="">-</option>
<option value="Small"><&|/l&>Small</&></option>
<option value="Large"><&|/l&>Large</&></option>
</select>
-<br /><&|/l&>Style</&>:
-<select name="Face">
+</span>
+</div>
+<div class="row">
+<span class="label"><&|/l&>Style</&>:</span>
+<span class="value"><select name="Face">
<option value="">-</option>
<option value="Bold"><&|/l&>Bold</&></option>
<option value="Italic"><&|/l&>Italic</&></option>
</select>
+</span>
+</div>
</td>
<td><input type="submit" class="button" name="AddCol" value=" &rarr; " /></td>
diff --git a/rt/share/html/Search/Elements/EditQuery b/rt/share/html/Search/Elements/EditQuery
index e6f649ea8..cfa8e0d1b 100644
--- a/rt/share/html/Search/Elements/EditQuery
+++ b/rt/share/html/Search/Elements/EditQuery
@@ -2,7 +2,7 @@
%#
%# COPYRIGHT:
%#
-%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
%# <sales@bestpractical.com>
%#
%# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/share/html/Search/Elements/EditSearches b/rt/share/html/Search/Elements/EditSearches
index 08f84c70c..64309cb00 100644
--- a/rt/share/html/Search/Elements/EditSearches
+++ b/rt/share/html/Search/Elements/EditSearches
@@ -2,7 +2,7 @@
%#
%# COPYRIGHT:
%#
-%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
%# <sales@bestpractical.com>
%#
%# (Except where explicitly superseded by other copyright notices)
@@ -45,14 +45,15 @@
%# those contributions and any derivatives thereof.
%#
%# END BPS TAGGED BLOCK }}}
+<div class="edit-saved-searches">
<&| /Widgets/TitleBox, title => loc($Title)&>
%# Hide all the save functionality if the user shouldn't see it.
% if ( $can_modify ) {
-<&|/l&>Privacy:</&>
+<span class="label"><&|/l&>Privacy</&>:</span>
<& SelectSearchObject, Name => 'SavedSearchOwner', Objects => \@Objects, Object => ( $Object && $Object->id ) ? $Object->Object : '' &>
<br />
-<&|/l&>Description</&>:
+<span class="label"><&|/l&>Description</&>:</span>
<input size="25" name="SavedSearchDescription" value="<% $Description || '' %>" />
% if ($Id ne 'new') {
@@ -67,19 +68,19 @@
</nobr>
% }
% if ( $Object && $Object->Id ) {
-<input type="submit" class="button" name="SavedSearchSave" value="<%loc('Update')%>" />
+<input type="submit" class="button" id="SavedSearchSave" name="SavedSearchSave" value="<%loc('Update')%>" />
% } else {
-<input type="submit" class="button" name="SavedSearchSave" value="<%loc('Save')%>" />
+<input type="submit" class="button" id="SavedSearchSave" name="SavedSearchSave" value="<%loc('Save')%>" />
%}
% }
<br />
<hr />
-<&|/l&>Load saved search:</&>
+<span class="label"><&|/l&>Load saved search</&>:</span>
<& SelectSearchesForObjects, Name => 'SavedSearchLoad', Objects => \@Objects, SearchType => $Type &>
-<input type="submit" value="<% loc('Load') %>" class="button" />
+<input type="submit" value="<% loc('Load') %>" id="SavedSearchLoadSubmit" name="SavedSearchLoadSubmit" class="button" />
</&>
-
+</div>
<%INIT>
return unless $session{'CurrentUser'}->HasRight(
Right => 'LoadSavedSearch',
@@ -91,8 +92,8 @@ my $can_modify = $session{'CurrentUser'}->HasRight(
Object => $RT::System,
);
-use RT::SavedSearches;
-my @Objects = RT::SavedSearches->new($session{CurrentUser})->_PrivacyObjects;
+use RT::SavedSearch;
+my @Objects = RT::SavedSearch->new($session{CurrentUser})->_PrivacyObjects;
push @Objects, RT::System->new( $session{'CurrentUser'} )
if $session{'CurrentUser'}->HasRight( Object=> $RT::System,
Right => 'SuperUser' );
diff --git a/rt/share/html/Search/Elements/EditSort b/rt/share/html/Search/Elements/EditSort
new file mode 100644
index 000000000..497611e13
--- /dev/null
+++ b/rt/share/html/Search/Elements/EditSort
@@ -0,0 +1,142 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+%# <sales@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 }}}
+<table valign="top">
+
+% for my $o (0..3) {
+% $Order[$o] ||= ''; $OrderBy[$o] ||= '';
+<tr>
+<td class="label">
+% if ($o == 0) {
+<&|/l&>Order by</&>:
+% }
+</td>
+<td class="value">
+<select name="OrderBy">
+% if ($o > 0) {
+<option value=""><&|/l&>~[none~]</&></option>
+% }
+% # %fields maps display name to SQL column/function
+% foreach my $field (sort keys %fields) {
+% next unless $field;
+% my $fieldval = $fields{$field};
+<option value="<%$fieldval%>"
+% if (defined $OrderBy[$o] and $fieldval eq $OrderBy[$o]) {
+selected="selected"
+% }
+><% loc($field) %></option>
+% }
+</select>
+<select name="Order">
+<option value="ASC"
+% unless ( ($Order[$o]||'') eq "DESC" ) {
+selected="selected"
+% }
+><&|/l&>Asc</&></option>
+<option value="DESC"
+% if ( ($Order[$o]||'') eq "DESC" ) {
+selected="selected"
+% }
+><&|/l&>Desc</&></option>
+</select>
+</td>
+</tr>
+% }
+<tr>
+<td class="label">
+<&|/l&>Rows per page</&>:
+</td><td class="value">
+<& /Elements/SelectResultsPerPage,
+ Name => "RowsPerPage",
+ Default => $RowsPerPage &>
+</td>
+</tr>
+</table>
+
+<%INIT>
+my $tickets = RT::Tickets->new($session{'CurrentUser'});
+my %FieldDescriptions = %{$tickets->FIELDS};
+my %fields;
+
+for my $field (keys %FieldDescriptions) {
+ next if $field eq 'EffectiveId';
+ next unless $FieldDescriptions{$field}->[0] =~ /^(?:ENUM|INT|DATE|STRING|ID)$/;
+ $fields{$field} = $field;
+}
+
+$fields{'Owner'} = 'Owner';
+$fields{ $_ . '.EmailAddress' } = $_ . '.EmailAddress'
+ for qw(Requestor Cc AdminCc);
+
+# Add all available CustomFields to the list of sortable columns.
+my @cfs = grep /^CustomField/, @{$ARGS{AvailableColumns}};
+$fields{$_} = $_ for @cfs;
+
+# Add PAW sort
+$fields{'Custom.Ownership'} = 'Custom.Ownership';
+
+$fields{"Customer.$_"} = 1 foreach qw( Number Name ); #Freeside
+
+$m->callback(CallbackName => 'MassageSortFields', Fields => \%fields );
+
+my @Order = split /\|/, $Order;
+my @OrderBy = split /\|/, $OrderBy;
+if ($Order =~ /\|/) {
+ @Order = split /\|/, $Order;
+} else {
+ @Order = ( $Order );
+}
+
+</%INIT>
+
+<%ARGS>
+$Order => ''
+$OrderBy => ''
+$RowsPerPage => undef
+$Format => undef
+$GroupBy => 'id'
+</%ARGS>
diff --git a/rt/share/html/Search/Elements/Graph b/rt/share/html/Search/Elements/Graph
index 1cf1f1baa..ba2f4dbb8 100644
--- a/rt/share/html/Search/Elements/Graph
+++ b/rt/share/html/Search/Elements/Graph
@@ -2,7 +2,7 @@
%#
%# COPYRIGHT:
%#
-%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
%# <sales@bestpractical.com>
%#
%# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/share/html/Search/Elements/NewListActions b/rt/share/html/Search/Elements/NewListActions
index 8c7846a19..db185da3b 100644
--- a/rt/share/html/Search/Elements/NewListActions
+++ b/rt/share/html/Search/Elements/NewListActions
@@ -2,7 +2,7 @@
%#
%# COPYRIGHT:
%#
-%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
%# <sales@bestpractical.com>
%#
%# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/share/html/Search/Elements/PickBasics b/rt/share/html/Search/Elements/PickBasics
index e9534237b..db7d9f5c1 100644
--- a/rt/share/html/Search/Elements/PickBasics
+++ b/rt/share/html/Search/Elements/PickBasics
@@ -2,7 +2,7 @@
%#
%# COPYRIGHT:
%#
-%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
%# <sales@bestpractical.com>
%#
%# (Except where explicitly superseded by other copyright notices)
@@ -103,7 +103,7 @@ my @lines = (
Value => {
Type => 'component',
Path => '/Elements/SelectStatus',
- Arguments => { SkipDeleted => 1 },
+ Arguments => { SkipDeleted => 1, Queues => \%queues },
},
},
{
@@ -124,7 +124,7 @@ my @lines = (
Value => {
Type => 'component',
Path => '/Elements/SelectOwner',
- Arguments => { ValueAttribute => 'Name' },
+ Arguments => { ValueAttribute => 'Name', Queues => \%queues },
},
},
{
@@ -214,3 +214,6 @@ my @lines = (
$m->callback( Conditions => \@lines );
</%INIT>
+<%ARGS>
+%queues => ()
+</%ARGS>
diff --git a/rt/share/html/Search/Elements/PickCFs b/rt/share/html/Search/Elements/PickCFs
index 9abab4443..f2dc21f68 100644
--- a/rt/share/html/Search/Elements/PickCFs
+++ b/rt/share/html/Search/Elements/PickCFs
@@ -2,7 +2,7 @@
%#
%# COPYRIGHT:
%#
-%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
%# <sales@bestpractical.com>
%#
%# (Except where explicitly superseded by other copyright notices)
@@ -50,21 +50,11 @@
% }
<%INIT>
my $CustomFields = RT::CustomFields->new( $session{'CurrentUser'});
-foreach my $id (keys %cfqueues) {
- # Gotta load up the $queue object, since queues get stored by name now. my $id
+foreach my $id (keys %queues) {
+ # Gotta load up the $queue object, since queues get stored by name now.
my $queue = RT::Queue->new($session{'CurrentUser'});
$queue->Load($id);
- unless ($queue->id) {
- # XXX TODO: This ancient code dates from a former developer
- # we have no idea what it means or why cfqueues are so encoded.
- $id =~ s/^.'*(.*).'*$/$1/;
-
- # unescape internal quotes
- $id =~ s/(\\(.))/$2 eq "'" ? "'" : $1/eg;
-
- $queue->Load($id);
- }
- $CustomFields->LimitToQueue($queue->Id);
+ $CustomFields->LimitToQueue($queue->Id) if $queue->Id;
}
$CustomFields->LimitToGlobal;
$m->callback(
@@ -80,12 +70,19 @@ while ( my $CustomField = $CustomFields->Next ) {
$line{'Field'} = $CustomField->Name;
# Op
- if ($CustomField->Type eq 'Date') {
+ if ($CustomField->Type =~ /^Date(Time)?$/ ) {
$line{'Op'} = {
Type => 'component',
Path => '/Elements/SelectDateRelation',
Arguments => {},
};
+ }
+ elsif ($CustomField->Type =~ /^IPAddress(Range)?$/ ) {
+ $line{'Op'} = {
+ Type => 'component',
+ Path => '/Elements/SelectIPRelation',
+ Arguments => {},
+ };
} else {
$line{'Op'} = {
Type => 'component',
@@ -99,11 +96,12 @@ while ( my $CustomField = $CustomFields->Next ) {
}
# Value
- if ($CustomField->Type eq 'Date') {
+ if ($CustomField->Type =~ /^Date(Time)?$/) {
+ my $is_datetime = $1 ? 1 : 0;
$line{'Value'} = {
Type => 'component',
Path => '/Elements/SelectDate',
- Arguments => {},
+ Arguments => { $is_datetime ? (ShowTime => 1) : (ShowTime => 0), },
};
} else {
$line{'Value'} = {
@@ -116,10 +114,10 @@ while ( my $CustomField = $CustomFields->Next ) {
push @lines, \%line;
}
-$m->callback( Conditions => \@lines, Queues => \%cfqueues );
+$m->callback( Conditions => \@lines, Queues => \%queues );
</%INIT>
<%ARGS>
-%cfqueues => undef
+%queues => ()
</%ARGS>
diff --git a/rt/share/html/Search/Elements/PickCriteria b/rt/share/html/Search/Elements/PickCriteria
index 5eb112d17..74547c7da 100644
--- a/rt/share/html/Search/Elements/PickCriteria
+++ b/rt/share/html/Search/Elements/PickCriteria
@@ -2,7 +2,7 @@
%#
%# COPYRIGHT:
%#
-%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
%# <sales@bestpractical.com>
%#
%# (Except where explicitly superseded by other copyright notices)
@@ -53,7 +53,7 @@
<& PickBasics &>
<& PickCustomerFields &>
-<& PickCFs, cfqueues => \%cfqueues &>
+<& PickCFs, queues => \%queues &>
<tr class="separator"><td colspan="3"><hr /></td></tr>
<tr>
@@ -69,5 +69,5 @@
<%ARGS>
$addquery => 0
$query => undef
-%cfqueues => undef
+%queues => ()
</%ARGS>
diff --git a/rt/share/html/Search/Elements/ResultsRSSView b/rt/share/html/Search/Elements/ResultsRSSView
index f3b416a4e..5033c8c64 100644
--- a/rt/share/html/Search/Elements/ResultsRSSView
+++ b/rt/share/html/Search/Elements/ResultsRSSView
@@ -2,7 +2,7 @@
%#
%# COPYRIGHT:
%#
-%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
%# <sales@bestpractical.com>
%#
%# (Except where explicitly superseded by other copyright notices)
@@ -70,7 +70,7 @@ if ( $m->request_comp->path =~ RT->Config->Get('WebNoAuthRegex') ) {
# convert to perl strings
$name = Encode::decode_utf8($name);
- my $user = RT::User->new($RT::SystemUser);
+ my $user = RT::User->new(RT->SystemUser);
$user->Load($name);
$notfound->("Invalid user: $user") unless $user->id;
@@ -102,7 +102,7 @@ $r->content_type('application/rss+xml');
# create an RSS 1.0 file (http://purl.org/rss/1.0/)
use XML::RSS;
- my $rss = new XML::RSS (version => '1.0');
+ my $rss = XML::RSS->new(version => '1.0');
$rss->channel(
title => RT->Config->Get('rtname').": Search " . $ARGS{'Query'},
link => RT->Config->Get('WebURL'),
diff --git a/rt/share/html/Search/Elements/SearchPrivacy b/rt/share/html/Search/Elements/SearchPrivacy
index f943af143..f36c1c894 100644
--- a/rt/share/html/Search/Elements/SearchPrivacy
+++ b/rt/share/html/Search/Elements/SearchPrivacy
@@ -2,7 +2,7 @@
%#
%# COPYRIGHT:
%#
-%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
%# <sales@bestpractical.com>
%#
%# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/share/html/Search/Elements/SearchesForObject b/rt/share/html/Search/Elements/SearchesForObject
index 35007bde5..efbf22078 100644
--- a/rt/share/html/Search/Elements/SearchesForObject
+++ b/rt/share/html/Search/Elements/SearchesForObject
@@ -2,7 +2,7 @@
%#
%# COPYRIGHT:
%#
-%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
%# <sales@bestpractical.com>
%#
%# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/share/html/Search/Elements/SelectAndOr b/rt/share/html/Search/Elements/SelectAndOr
index a644a71d8..ec19271b2 100644
--- a/rt/share/html/Search/Elements/SelectAndOr
+++ b/rt/share/html/Search/Elements/SelectAndOr
@@ -2,7 +2,7 @@
%#
%# COPYRIGHT:
%#
-%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
%# <sales@bestpractical.com>
%#
%# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/share/html/Search/Elements/SelectChartType b/rt/share/html/Search/Elements/SelectChartType
index 42cd4e4b2..aeee7cdbc 100644
--- a/rt/share/html/Search/Elements/SelectChartType
+++ b/rt/share/html/Search/Elements/SelectChartType
@@ -2,7 +2,7 @@
%#
%# COPYRIGHT:
%#
-%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
%# <sales@bestpractical.com>
%#
%# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/share/html/Search/Elements/SelectGroup b/rt/share/html/Search/Elements/SelectGroup
index 2ed965d42..ff5fc0786 100644
--- a/rt/share/html/Search/Elements/SelectGroup
+++ b/rt/share/html/Search/Elements/SelectGroup
@@ -2,7 +2,7 @@
%#
%# COPYRIGHT:
%#
-%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
%# <sales@bestpractical.com>
%#
%# (Except where explicitly superseded by other copyright notices)
@@ -55,7 +55,7 @@
</select>
<%INIT>
-my $groups = new RT::Groups($session{'CurrentUser'});
+my $groups = RT::Groups->new($session{'CurrentUser'});
$groups->Limit(FIELD => 'Domain', OPERATOR => '=', VALUE => $Domain);
</%INIT>
diff --git a/rt/share/html/Search/Elements/SelectGroupBy b/rt/share/html/Search/Elements/SelectGroupBy
index fbf19addb..9a6951a82 100644
--- a/rt/share/html/Search/Elements/SelectGroupBy
+++ b/rt/share/html/Search/Elements/SelectGroupBy
@@ -2,7 +2,7 @@
%#
%# COPYRIGHT:
%#
-%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
%# <sales@bestpractical.com>
%#
%# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/share/html/Search/Elements/SelectLinks b/rt/share/html/Search/Elements/SelectLinks
index 20c0dd311..0b7ce1251 100644
--- a/rt/share/html/Search/Elements/SelectLinks
+++ b/rt/share/html/Search/Elements/SelectLinks
@@ -2,7 +2,7 @@
%#
%# COPYRIGHT:
%#
-%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
%# <sales@bestpractical.com>
%#
%# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/share/html/Search/Elements/SelectPersonType b/rt/share/html/Search/Elements/SelectPersonType
index 6454acff3..d07e49c22 100644
--- a/rt/share/html/Search/Elements/SelectPersonType
+++ b/rt/share/html/Search/Elements/SelectPersonType
@@ -2,7 +2,7 @@
%#
%# COPYRIGHT:
%#
-%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
%# <sales@bestpractical.com>
%#
%# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/share/html/Search/Elements/SelectSearchObject b/rt/share/html/Search/Elements/SelectSearchObject
index d1b38abf0..6a511027e 100644
--- a/rt/share/html/Search/Elements/SelectSearchObject
+++ b/rt/share/html/Search/Elements/SelectSearchObject
@@ -2,7 +2,7 @@
%#
%# COPYRIGHT:
%#
-%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
%# <sales@bestpractical.com>
%#
%# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/share/html/Search/Elements/SelectSearchesForObjects b/rt/share/html/Search/Elements/SelectSearchesForObjects
index eafe88843..5f3169bbd 100644
--- a/rt/share/html/Search/Elements/SelectSearchesForObjects
+++ b/rt/share/html/Search/Elements/SelectSearchesForObjects
@@ -2,7 +2,7 @@
%#
%# COPYRIGHT:
%#
-%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
%# <sales@bestpractical.com>
%#
%# (Except where explicitly superseded by other copyright notices)
@@ -51,10 +51,11 @@ $Name => undef
$SearchType => 'Ticket',
</%args>
<select id="<%$Name%>" name="<%$Name%>">
-<option value="" selected>&nbsp;</option>
+<option value="">-</option>
% foreach my $object (@Objects) {
-<optgroup label="<& SearchPrivacy, Object => $object &>">
% my @searches = $object->Attributes->Named('SavedSearch');
+% if ( @searches ) {
+<optgroup label="<& SearchPrivacy, Object => $object &>">
% foreach my $search (@searches) {
% # Skip it if it is not of search type we want.
% next if ($search->SubValue('SearchType')
@@ -63,4 +64,5 @@ $SearchType => 'Ticket',
% }
</optgroup>
% }
+% }
</select>
diff --git a/rt/share/html/Search/Graph.html b/rt/share/html/Search/Graph.html
index 483aaae3d..c85181c3a 100644
--- a/rt/share/html/Search/Graph.html
+++ b/rt/share/html/Search/Graph.html
@@ -2,7 +2,7 @@
%#
%# COPYRIGHT:
%#
-%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
%# <sales@bestpractical.com>
%#
%# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/share/html/Search/Results.html b/rt/share/html/Search/Results.html
index 8aea1fc58..171b38d92 100755
--- a/rt/share/html/Search/Results.html
+++ b/rt/share/html/Search/Results.html
@@ -2,7 +2,7 @@
%#
%# COPYRIGHT:
%#
-%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
%# <sales@bestpractical.com>
%#
%# (Except where explicitly superseded by other copyright notices)
@@ -46,22 +46,12 @@
%#
%# END BPS TAGGED BLOCK }}}
<& /Elements/Header, Title => $title,
- Refresh => $session{'tickets_refresh_interval'} || RT->Config->Get('SearchResultsRefreshInterval', $session{'CurrentUser'} ),
- RSSAutoDiscovery => $RSSFeedURL,
+ Refresh => $refresh,
LinkRel => \%link_rel &>
-<& /Ticket/Elements/Tabs,
- current_tab => "Search/Results.html".$QueryString,
- Title => $title,
- Format => $Format,
- Query => $Query,
- Rows => $Rows,
- OrderBy => $OrderBy,
- Order => $Order,
- SavedSearchId => $SavedSearchId,
- SavedChartSearchId => $SavedChartSearchId,
- &>
+<& /Elements/Tabs &>
<& /Elements/CollectionList,
Query => $Query,
+ TotalFound => $ticketcount,
AllowSorting => 1,
OrderBy => $OrderBy,
Order => $Order,
@@ -82,22 +72,9 @@
<input type="submit" class="button" value="<&|/l&>Change</&>" />
</form>
</div>
-<div align="right" class="search-result-actions">
-<& Elements/ResultViews,
- Collection => $session{'tickets'},
- QueryString => $QueryString,
- Query => $Query,
- Format => $Format,
- Rows => $Rows,
- OrderBy => $OrderBy,
- Order => $Order,
- RSSFeedURL => $RSSFeedURL,
- ShortQueryString => $ShortQueryString,
-&>
-
-% $m->callback( QueryString => $QueryString, CallbackName => 'SearchActions' );
-</div>
<%INIT>
+$m->callback( ARGSRef => \%ARGS, CallbackName => 'Initial' );
+
# Read from user preferences
my $prefs = $session{'CurrentUser'}->UserObj->Preferences("SearchDisplay") || {};
@@ -124,7 +101,9 @@ $Page = 1 unless $Page && $Page > 0;
my ($title, $ticketcount);
$session{'i'}++;
$session{'tickets'} = RT::Tickets->new($session{'CurrentUser'}) ;
-$session{'tickets'}->FromSQL($Query) if ($Query);
+my ($ok, $msg) = $Query ? $session{'tickets'}->FromSQL($Query) : (1, "Vacuously OK");
+# Provide an empty search if parsing failed
+$session{'tickets'}->FromSQL("id < 0") unless ($ok);
if ($OrderBy =~ /\|/) {
# Multiple Sorts
@@ -164,16 +143,21 @@ my $QueryString = "?".$m->comp('/Elements/QueryString',
Order => $Order,
Page => $Page);
my $ShortQueryString = "?".$m->comp('/Elements/QueryString', Query => $Query);
-my $RSSQueryString = "?".$m->comp('/Elements/QueryString', Query => $Query, Order => $Order, OrderBy => $OrderBy);
-my $RSSPath = join '/', map $m->interp->apply_escapes($_, 'u'),
- $session{'CurrentUser'}->UserObj->Name,
- $session{'CurrentUser'}->UserObj->GenerateAuthString( $Query.$Order.$OrderBy );
-my $RSSFeedURL = RT->Config->Get('WebPath')."/NoAuth/rss/$RSSPath/$RSSQueryString";
if ($ARGS{'TicketsRefreshInterval'}) {
$session{'tickets_refresh_interval'} = $ARGS{'TicketsRefreshInterval'};
}
+my $refresh = $session{'tickets_refresh_interval'}
+ || RT->Config->Get('SearchResultsRefreshInterval', $session{'CurrentUser'} );
+
+if (RT->Config->Get('RestrictReferrer') and $refresh and not $m->request_args->{CSRF_Token}) {
+ my $token = RT::Interface::Web::StoreRequestToken( $session{'CurrentSearchHash'} );
+ $m->notes->{RefreshURL} = RT->Config->Get('WebURL')
+ . "Search/Results.html?CSRF_Token="
+ . $token;
+}
+
my %link_rel;
my $genpage = sub {
return $m->comp(
@@ -186,6 +170,15 @@ my $genpage = sub {
Page => shift(@_),
);
};
+
+if ( RT->Config->Get('SearchResultsAutoRedirect') && $ticketcount == 1 &&
+ $session{tickets}->First ) {
+# $ticketcount is not always precise unless $UseSQLForACLChecks is set to true,
+# check $session{tickets}->First here is to make sure the ticket is there.
+ RT::Interface::Web::Redirect( RT->Config->Get('WebURL')
+ ."Ticket/Display.html?id=". $session{tickets}->First->id );
+}
+
my $BaseURL = RT->Config->Get('WebPath')."/Search/Results.html?";
$link_rel{first} = $BaseURL . $genpage->(1) if $Page > 1;
$link_rel{prev} = $BaseURL . $genpage->($Page - 1) if $Page > 1;
diff --git a/rt/share/html/Search/Results.rdf b/rt/share/html/Search/Results.rdf
index 8356d027a..1c64b9a84 100644
--- a/rt/share/html/Search/Results.rdf
+++ b/rt/share/html/Search/Results.rdf
@@ -2,7 +2,7 @@
%#
%# COPYRIGHT:
%#
-%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
%# <sales@bestpractical.com>
%#
%# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/share/html/Search/Results.tsv b/rt/share/html/Search/Results.tsv
index cdf1ebad0..977b1ea7b 100644
--- a/rt/share/html/Search/Results.tsv
+++ b/rt/share/html/Search/Results.tsv
@@ -2,7 +2,7 @@
%#
%# COPYRIGHT:
%#
-%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
%# <sales@bestpractical.com>
%#
%# (Except where explicitly superseded by other copyright notices)
@@ -46,12 +46,64 @@
%#
%# END BPS TAGGED BLOCK }}}
<%ARGS>
+$Format => undef
$Query => ''
$OrderBy => 'id'
$Order => 'ASC'
+$PreserveNewLines => 0
</%ARGS>
<%INIT>
+$r->content_type('text/tab-separated-values');
+$r->header_out('Content-Disposition' => 'attachment;filename="Results.tsv"');
+
+my $DisplayFormat = $m->comp('/Elements/ScrubHTML', Content => $Format);
+
+my @Format = $m->comp('/Elements/CollectionAsTable/ParseFormat', Format => $DisplayFormat);
+
+my @columns;
+
+my $should_loc = { map { $_ => 1 } qw(Status) };
+
+my $col_entry = sub {
+ my $col = shift;
+ # in tsv output, "#" is often a comment character but we use it for "id"
+ delete $col->{title}
+ if $col->{title} and $col->{title} =~ /^\s*#\s*$/;
+ return {
+ header => Encode::encode_utf8(loc($col->{title} || $col->{attribute})),
+ map => $m->comp(
+ "/Elements/ColumnMap",
+ Name => $col->{attribute},
+ Attr => 'value'
+ ),
+ should_loc => $should_loc->{$col->{attribute}},
+ }
+};
+
+if ($PreserveNewLines) {
+ my $col = [];
+ push @columns, $col;
+ for (@Format) {
+ if ($_->{title} eq 'NEWLINE') {
+ $col = [];
+ push @columns, $col;
+ }
+ else {
+ push @$col, $col_entry->($_);
+ }
+ }
+}
+else {
+ push @columns, [map { $_->{attribute}
+ ? $col_entry->($_)
+ : () } @Format];
+}
+
+for (@columns) {
+ $m->out(join("\t", map { $_->{header} } @$_)."\n");
+}
+
my $Tickets = RT::Tickets->new( $session{'CurrentUser'} );
$Tickets->FromSQL( $Query );
if ( $OrderBy =~ /\|/ ) {
@@ -67,97 +119,19 @@ else {
$Tickets->OrderBy( FIELD => $OrderBy, ORDER => $Order );
}
-my %cf_id_to_name;
-my %cf_name_to_pos;
-{
- my $cfs = RT::SQL::PossibleCustomFields(
- Query => $Query, CurrentUser => $session{'CurrentUser'},
- );
- while ( my $cf = $cfs->Next ) {
- my $name = $cf->Name;
- $cf_id_to_name{ $cf->id } = $name;
- next if $cf_name_to_pos{ $name };
-
- $cf_name_to_pos{ $name } =
- (sort { $b <=> $a } values %cf_name_to_pos)[0] + 1;
+my $ii = 0;
+while (my $row = $Tickets->Next) {
+ for my $col (@columns) {
+ $m->out(join("\t", map {
+ my $val = ProcessColumnMapValue($_->{map}, Arguments => [$row, $ii++], Escape => 0);
+ $val = loc($val) if $_->{should_loc};
+ # remove tabs from all field values, they screw up the tsv
+ $val = '' unless defined $val;
+ $val =~ s/(?:\n|\r)//g; $val =~ s{\t}{ }g;
+ Encode::encode_utf8($val);
+ } @$col)."\n");
}
}
-
-my @attrs = qw(
- id QueueObj->Name Subject Status
- TimeEstimated TimeWorked TimeLeft
- Priority FinalPriority
- OwnerObj->Name
- Requestors->MemberEmailAddressesAsString
- Cc->MemberEmailAddressesAsString
- AdminCc->MemberEmailAddressesAsString
- DueObj->ISO ToldObj->ISO CreatedObj->ISO
- ResolvedObj->ISO LastUpdatedObj->ISO LastUpdatedByObj->Name
-);
-
-$r->content_type('text/tab-separated-values');
-$r->header_out('Content-Disposition' => 'attachment;filename="Results.tsv"');
-{
- my @header;
- foreach my $attr (@attrs) {
- my $label = $attr;
- $label =~ s'Obj-.(?:AsString|Name|ISO)''g;
- $label =~ s'-\>MemberEmailAddressesAsString''g;
- push @header, $label;
- }
-
- $_ += @header - 1 foreach values %cf_name_to_pos;
-
- foreach my $name ( sort { $cf_name_to_pos{$a} <=> $cf_name_to_pos{$b} } keys %cf_name_to_pos ) {
- push @header, "CF-". $name;
- }
- $m->out(join("\t", @header));
- $m->out("\n");
- $m->flush_buffer;
-}
-
-my $i = 0;
-while ( my $Ticket = $Tickets->Next()) {
- my @row;
- foreach my $attr (@attrs) {
- my $value;
- if ($attr =~ /(.*)->ISO$/ and $Ticket->$1->Unix <= 0) {
- $value = '';
- } else {
- my $method = '$Ticket->'.$attr.'()';
- $method =~ s/->ISO\(\)$/->ISO( Timezone => 'user' )/;
- $value = eval $method;
- if ($@) {die "Failed to find $attr - ". $@};
- }
- push @row, $value;
- }
-
- my $values = $Ticket->CustomFieldValues;
- $values->OrderByCols; # don't sort them
- while (my $value = $values->Next) {
- my $pos = $cf_name_to_pos{ $cf_id_to_name{ $value->CustomField } };
- next unless $pos;
-
- $row[$pos] = '' unless defined $row[$pos];
- $row[$pos] .= ', ' if $row[$pos];
- $row[$pos] .= $value->Content;
- }
-
- # remove tabs from all field values, they screw up the tsv
- for (@row) {
- $_ = '' unless defined;
- $_ =~ s/(?:\n|\r)//g;
- $_ =~ s{\t}{ }g;
- }
-
- $m->out(join("\t",@row));
- $m->out("\n");
-
- unless (++$i%10) {
- $i = 0;
- $m->flush_buffer;
- }
-}
-
$m->abort();
+
</%INIT>
diff --git a/rt/share/html/Search/Simple.html b/rt/share/html/Search/Simple.html
index dc5c14d10..4d7b1e3c5 100644
--- a/rt/share/html/Search/Simple.html
+++ b/rt/share/html/Search/Simple.html
@@ -2,7 +2,7 @@
%#
%# COPYRIGHT:
%#
-%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
%# <sales@bestpractical.com>
%#
%# (Except where explicitly superseded by other copyright notices)
@@ -46,9 +46,7 @@
%#
%# END BPS TAGGED BLOCK }}}
<& /Elements/Header, Title => $title &>
-<& /Elements/Tabs,
- current_toptab => "Search/Simple.html",
- Title => $title
+<& /Elements/Tabs
&>
% $m->callback( %ARGS, CallbackName => 'PreForm' );
@@ -56,17 +54,42 @@
<div id="SimpleSearchForm">
<form action="Simple.html" method="get">
-<p><&|/l&>Search for tickets. Enter <strong>id</strong> numbers, <strong>queues</strong> by name, Owners by <strong>username</strong> and Requestors by <strong>email address</strong>.</&></p>
-
-<p><&|/l&>Searching the full text of every ticket can take a long time, but if you need to do it, you can search for any word in full ticket history for any word by typing <b>fulltext:<i>word</i></b>.</&></p>
-<p><&|/l&>RT will look for anything else you enter in ticket subjects.</&></p>
-
-<br />
-<br />
<div align="center">
<input name="q" size="60" /><input type="submit" class="button" value="<&|/l&>Search</&>" />
</div>
+% my @strong = qw(<strong> </strong>);
+
+<p><&|/l_unsafe, @strong &>Search for tickets by entering [_1]id[_2] numbers, subject words [_1]"in quotes"[_2], [_1]queues[_2] by name, Owners by [_1]username[_2], Requestors by [_1]email address[_2], and ticket [_1]statuses[_2].</&></p>
+
+<p><&|/l&>Any word not recognized by RT is searched for in ticket subjects.</&></p>
+
+% my $config = RT->Config->Get('FullTextSearch') || {};
+% my $fulltext_keyword = 'fulltext:';
+% if ( $config->{'Enable'} ) {
+% if ( $config->{'Indexed'} ) {
+<p><&|/l, $fulltext_keyword &>You can search for any word in full ticket history by typing <b>[_1]<i>word</i></b>.</&></p>
+% } else {
+<p><&|/l, $fulltext_keyword &>Searching the full text of every ticket can take a long time, but if you need to do it, you can search for any word in full ticket history by typing <b>[_1]<i>word</i></b>.</&></p>
+% }
+% }
+
+<p><&|/l_unsafe, map { "<strong>$_</strong>" } qw(initial active inactive any) &>Entering [_1], [_2], [_3], or [_4] limits results to tickets with one of the respective types of statuses. Any individual status name limits results to just the statuses named.</&>
+
+% if (RT->Config->Get('OnlySearchActiveTicketsInSimpleSearch', $session{'CurrentUser'})) {
+% my $status_str = join ', ', map { loc($_) } RT::Queue->ActiveStatusArray;
+<&|/l, $status_str &>Unless you specify a specific status, only tickets with active statuses ([_1]) are searched.</&>
+% }
+</p>
+
+<p><&|/l_unsafe, map { "<strong>$_</strong>" } 'queue:"Example Queue"', 'owner:email@example.com' &>Start the search term with the name of a supported field followed by a colon, as in [_1] and [_2], to explicitly specify the search type.</&></p>
+
+<p><&|/l_unsafe, '<strong>cf.Name:value</strong>' &>CFs may be searched using a similar syntax as above with [_1].</&></p>
+
+% my $link_start = '<a href="' . RT->Config->Get('WebPath') . '/Search/Build.html">';
+% my $link_end = '</a>';
+<p><&|/l_unsafe, $link_start, $link_end &>For the full power of RT's searches, please visit the [_1]search builder interface[_2].</&></p>
+
</form>
% $m->callback( %ARGS, CallbackName => 'PostForm' );
@@ -78,7 +101,7 @@ my $title = loc("Search for tickets");
use RT::Search::Googleish;
if ($q) {
- my $tickets = new RT::Tickets( $session{'CurrentUser'} );
+ my $tickets = RT::Tickets->new( $session{'CurrentUser'} );
$m->callback( %ARGS, query => \$q, CallbackName => 'ModifyQuery' );
if ($q =~ /^#?(\d+)$/) {