& /Elements/Header, Title => $title,
    Refresh => $refresh,
    LinkRel => \%link_rel &>
<& /Elements/Tabs &>
% my $DisplayFormat;
% $m->callback( ARGSRef => \%ARGS, Format => \$Format, DisplayFormat => \$DisplayFormat, CallbackName => 'BeforeResults' );
% unless ($ok) {
%    $msg =~ s{ at .*? line .*}{}s;
<&| /Widgets/TitleBox, title => loc("Error"), class => "error-titlebox" &>
<&|/l_unsafe, "".$m->interp->apply_escapes($msg, "h")."" &>There was an error parsing your search query: [_1].  Your RT admin can find more information in the error logs.&>
&>
% } else {
% my $Collection = RT::Assets->new($session{CurrentUser});
% $Collection->FromSQL($Query);
<& /Elements/CollectionList, 
    Collection => $Collection,
    Query => $Query,
    TotalFound => $assetcount,
    AllowSorting => 1,
    OrderBy => $OrderBy,
    Order => $Order,
    Rows => $Rows,
    Page => $Page,
    Format => $Format,
    DisplayFormat => $DisplayFormat, # in case we set it in callbacks
    Class => 'RT::Assets',
    BaseURL => $BaseURL,
    SavedSearchId => $ARGS{'SavedSearchId'},
    SavedChartSearchId => $ARGS{'SavedChartSearchId'},
    PassArguments => [qw(Query Format Rows Page Order OrderBy SavedSearchId SavedChartSearchId)],
&>
% }
% $m->callback( ARGSRef => \%ARGS, CallbackName => 'AfterResults' );
% my %hiddens = (Query => $Query, Format => $Format, Rows => $Rows, OrderBy => $OrderBy, Order => $Order, HideResults => $HideResults, Page => $Page );
<%INIT>
$m->callback( ARGSRef => \%ARGS, CallbackName => 'Initial' );
# These variables are what define a search_hash; this is also
# where we give sane defaults.
$Format ||= ProcessAssetSearchFormatConfig;
# Some forms pass in "RowsPerPage" rather than "Rows"
# We call it RowsPerPage everywhere else.
if ( !defined($Rows) ) {
    if (defined $ARGS{'RowsPerPage'} ) {
        $Rows = $ARGS{'RowsPerPage'};
    } else {
        $Rows = 50;
    }
}
$Page = 1 unless $Page && $Page > 0;
$session{'i'}++;
$session{'assets'} = RT::Assets->new($session{'CurrentUser'}) ;
my ($ok, $msg) = $Query ? $session{'assets'}->FromSQL($Query) : (1, "Vacuously OK");
# Provide an empty search if parsing failed
$session{'assets'}->FromSQL("id < 0") unless ($ok);
if ($OrderBy =~ /\|/) {
    # Multiple Sorts
    my @OrderBy = split /\|/,$OrderBy;
    my @Order = split /\|/,$Order;
    $session{'assets'}->OrderByCols(
        map { { FIELD => $OrderBy[$_], ORDER => $Order[$_] } } ( 0
        .. $#OrderBy ) );; 
} else {
    $session{'assets'}->OrderBy(FIELD => $OrderBy, ORDER => $Order); 
}
$session{'assets'}->RowsPerPage( $Rows ) if $Rows;
$session{'assets'}->GotoPage( $Page - 1 );
$session{'CurrentAssetSearchHash'} = {
    Format      => $Format,
    Query       => $Query,
    Page        => $Page,
    Order       => $Order,
    OrderBy     => $OrderBy,
    RowsPerPage => $Rows
};
my ($title, $assetcount) = (loc("Find assets"), 0);
if ( $session{'assets'}->Query()) {
    $assetcount = $session{assets}->CountAll();
    $title = loc('Found [quant,_1,asset,assets]', $assetcount);
}
my $QueryString = "?".$m->comp('/Elements/QueryString',
                               Query => $Query,
                               Format => $Format,
                               Rows => $Rows,
                               OrderBy => $OrderBy,
                               Order => $Order,
                               Page => $Page);
my $ShortQueryString = "?".$m->comp('/Elements/QueryString', Query => $Query);
if ($ARGS{'AssetsRefreshInterval'}) {
    $session{'assets_refresh_interval'} = $ARGS{'AssetsRefreshInterval'};
}
my $refresh = $session{'assets_refresh_interval'}
    || RT->Config->Get('SearchResultsRefreshInterval', $session{'CurrentUser'} );
# Check $m->request_args, not $DECODED_ARGS, to avoid creating a new CSRF token on each refresh
if (RT->Config->Get('RestrictReferrer') and $refresh and not $m->request_args->{CSRF_Token}) {
    my $token = RT::Interface::Web::StoreRequestToken( $session{'CurrentAssetSearchHash'} );
    $m->notes->{RefreshURL} = RT->Config->Get('WebURL')
        . "Asset/Search/Results.html?CSRF_Token="
            . $token;
}
my %link_rel;
my $genpage = sub {
    return $m->comp(
        '/Elements/QueryString',
        Query   => $Query,
        Format  => $Format,
        Rows    => $Rows,
        OrderBy => $OrderBy,
        Order   => $Order,
        Page    => shift(@_),
    );
};
if ( RT->Config->Get('SearchResultsAutoRedirect') && $assetcount == 1 &&
    $session{assets}->First ) {
# $assetcount is not always precise unless $UseSQLForACLChecks is set to true,
# check $session{assets}->First here is to make sure the asset is there.
    RT::Interface::Web::Redirect( RT->Config->Get('WebURL')
            ."Asset/Display.html?id=". $session{assets}->First->id );
}
my $BaseURL = RT->Config->Get('WebPath')."/Asset/Search/Results.html?";
$link_rel{first} = $BaseURL . $genpage->(1)         if $Page > 1;
$link_rel{prev}  = $BaseURL . $genpage->($Page - 1) if $Page > 1;
$link_rel{next}  = $BaseURL . $genpage->($Page + 1) if ($Page * $Rows) < $assetcount;
$link_rel{last}  = $BaseURL . $genpage->(POSIX::ceil($assetcount/$Rows)) if $Rows and ($Page * $Rows) < $assetcount;
%INIT>
<%CLEANUP>
$session{'assets'}->PrepForSerialization();
%CLEANUP>
<%ARGS>
$Query => undef
$Format => undef 
$HideResults => 0
$Rows => undef
$Page => 1
$OrderBy => undef
$Order => undef
$SavedSearchId => undef
$SavedChartSearchId => undef
%ARGS>