%# BEGIN BPS TAGGED BLOCK {{{
%#
%# COPYRIGHT:
%#
%# This software is Copyright (c) 1996-2026 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>

my $query_string = sub {
    my %args = @_;
    my $u    = URI->new();
    %args = ShortenSearchQuery(%args);
    $u->query_form( map { $_ => $args{$_} } sort keys %args );
    return $u->query || '';
};

my $args = $DECODED_ARGS;
my $request_path = $Path;

my @query_fields = qw(Query Format RowsPerPage Page OrderBy Order ExtraQueryParams);

my $search_arguments = sub {
    my %res = ();
    my $caller_args = $m->caller_args(1);
    if ( $caller_args->{'SearchArgs'} ) {
        @res{ @query_fields } = @{ $caller_args->{'SearchArgs'} }{ @query_fields };
        if ( $res{ExtraQueryParams} ) {
            $res{$_} = $caller_args->{'SearchArgs'}{$_}
              for ref $res{ExtraQueryParams} ? @{ $res{ExtraQueryParams} } : $res{ExtraQueryParams};
        }
    } else {
        @res{ @query_fields } = @{ $args }{ @query_fields };
        if ( $res{ExtraQueryParams} ) {
            $res{$_} = $args->{$_}
              for ref $res{ExtraQueryParams} ? @{ $res{ExtraQueryParams} } : $res{ExtraQueryParams};
        }
    }

    delete $res{$_} foreach grep !defined $res{$_}, keys %res;
    return %res;
};

if ( $request_path =~ m{^/Search/} ) {
    my %args;
    if ( $ARGS{ARGSRef}{QueryArgs} ) {
        %args = %{ $ARGS{ARGSRef}{QueryArgs} };
    }
    else {
        %args = %$DECODED_ARGS;
    }

    my $rtir_search;
    ( $rtir_search, my @lifecycles ) = RT::IR->OurQuery( $args{'Query'} ) if $args{Query};
    $rtir_search ||= $args{RTIR};
    if ( $rtir_search ) {
        my $lifecycle = '';
        $lifecycle = $lifecycles[ 0 ] if @lifecycles == 1;

        if ( $lifecycle eq RT::IR->lifecycle_incident ) {
            PageMenu()->child(
                report     => title => loc( 'Report' ),
                path       => RT::IR->HREFTo( "Reporting/", IncludeWebPath => 0 ),
            );

            PageMenu()->child(
                abandon => title => loc('Bulk Abandon'),
                path    => RT::IR->HREFTo(
                    "Incident/BulkAbandon.html?" . $query_string->( %args, Format => undef ),
                    IncludeWebPath => 0,
                ),
            );
        }
        elsif ( $lifecycle eq RT::IR->lifecycle_report ) {
            PageMenu()->child(
                reject => title => loc('Bulk Reject'),
                path   => RT::IR->HREFTo(
                    "Report/BulkReject.html?" . $query_string->( %args, Format => undef ),
                    IncludeWebPath => 0,
                ),
            );
        }

        if ( $args{Query} ) {
            PageMenu()->child( 'more' )->{sort_order} = 99;
        }

        if ( my $results = PageMenu()->child('results') ) {
            if ( $results->path =~ m{^/RTIR/Incident/Reply/} ) {
                $results->title( loc('Back to Incident Reply #[_1]', $args{id}) );
            }
            elsif ( $results->path =~ m{^/RTIR/Link/} ) {
                $results->title( loc('Back to Link #[_1]', $args{id}) );
            }
            elsif ( $results->path =~ m{^/RTIR/Merge/} ) {
                $results->title( loc('Back to Merge #[_1]', $args{id}) );
            }
        }
    }
}

return unless $request_path =~ m{^/RTIR/};

my $re_rtir_path = qr'^/RTIR/(?:c/[^/]*/?)?';
my $re_rtir_types = '(?:'. join( '|', map "\Q$_\E", RT::IR->Types ) .')';

if ( $request_path =~ m{(?:$re_rtir_path)(?:$re_rtir_types/)?(Display|Edit|Update|Forward|Advanced)\.html$} ) {
    my $id = $args->{'id'};

    # we'll never get here unless ticket is there and it's rtir's type
    my $ticket = RT::Ticket->new( $session{'CurrentUser'} );
    $ticket->Load($id);
    $id = $ticket->id;

    my %can;
    my $can = sub {
        return $can{$_[0]} if exists $can{$_[0]};
        return $can{$_[0]} = $ticket->CurrentUserHasRight( $_[0] );
    };

    my $actions_tab = PageMenu()->child( actions => title => loc('Actions'), sort_order  => 95 );

    PageMenu()->child( display => title => loc('Display'), path =>RT::IR->HREFTo( "Display.html?id=$id", IncludeWebPath => 0) );

    # RT4 TODO: something wrong, this doesn't work
    if ( $session{'tickets'} ) {
        # we have to update session data if we get new ItemMap
        my $updatesession = 1 unless ( $session{"tickets"}->{'item_map'} );
        my $item_map = $session{"tickets"}->ItemMap;
        $session{"tickets"}->PrepForSerialization
            if $updatesession;

        # Don't display prev links if we're on the first ticket
        my $top = PageMenu();
        if ( my $t = $item_map->{$id}->{'prev'} ) {
            $top = $top->child(
                previouse => path => RT::IR->HREFTo("Display.html?id=$id", IncludeWebPath => 0),
                title => '< ' . loc('Prev')
            );
        }
        if ( my $t = $item_map->{'first'} ) {
            $top->child(
                first => path  => RT::IR->HREFTo("Display.html?id=$t", IncludeWebPath => 0),
                title => '<< ' . loc('First')
            ) if $t != $id;
        }

        $top = PageMenu();
        if ( my $t = $item_map->{$id}->{'next'} ) {
            $top = $top->child(
                next => path  => RT::IR->HREFTo("Display.html?id=$t", IncludeWebPath => 0),
                title => loc('Next') . ' >'
            );
        }
        if ( my $t = $item_map->{'last'} ) {
            $top->child(
                last => path  => RT::IR->HREFTo("Display.html?id=$t", IncludeWebPath => 0),
                title => loc('Last') . ' >>'
            ) if $t != $id;
        }
    }

    if ( $can->('ModifyTicket') ) {
        PageMenu()->child( split => title => loc('Split'), path => RT::IR->HREFTo("Split.html?Split=$id", IncludeWebPath => 0) );
        # XXX: we're missing query string here
        PageMenu()->child( merge => title => loc('Merge'), path => RT::IR->HREFTo("Merge/?id=$id", IncludeWebPath => 0) );
        PageMenu()->child( advanced => title => loc('Advanced'), path => RT::IR->HREFTo("Advanced.html?id=$id", IncludeWebPath => 0) );
    }

    if ( $can->('OwnTicket') ) {
        if ( $ticket->Owner == $RT::Nobody->id ) {
            $actions_tab->child(
                take => title => loc('Take'),
                path  => RT::IR->HREFTo("Display.html?Action=Take&id=$id", IncludeWebPath => 0),
            ) if $can->('ModifyTicket') || $can->('TakeTicket');
        } elsif ( $ticket->Owner != $session{CurrentUser}->id ) {
            $actions_tab->child(
                steal => title => loc('Steal'),
                path  => RT::IR->HREFTo("Display.html?Action=Steal&id=$id", IncludeWebPath => 0),
            ) if $can->('ModifyTicket') || $can->('StealTicket');
        }
    }

    my $LifecycleObj = $ticket->QueueObj->LifecycleObj;
    my $lifecycle = $ticket->QueueObj->Lifecycle;


    if ( $can->('ModifyTicket') || $can->('ReplyToTicket') ) {
        if ( RT::IR->IsIncidentQueue($ticket->QueueObj)) {
            $actions_tab->child(
                reply_reporters => title => loc('Reply to Reporters'),
                path  => RT::IR->HREFTo("Incident/Reply/?id=$id&SelectedReportsAll=1", IncludeWebPath => 0),
            );
            $actions_tab->child(
                reply_all => title => loc('Reply to All'),
                path  => RT::IR->HREFTo("Incident/Reply/?id=$id&All=1&SelectedReportsAll=1&SelectedInvestigationsAll=1&SelectedCountermeasuresAll=1", IncludeWebPath => 0),
            );
        } else {
            $actions_tab->child(
                reply => title => loc('Reply'),
                path  => RT::IR->HREFTo("Update.html?id=$id&Action=Respond", IncludeWebPath => 0),
            );
        }
    }

    if ( $can->('ForwardMessage') ) {
        $actions_tab->child( forward => title => loc('Forward'), path => RT::IR->HREFTo("Forward.html?id=" . $id, IncludeWebPath => 0) );
    }

    my $i = 0;
    my $status = $ticket->Status;
    foreach my $info ( $LifecycleObj->Actions( $status ) ) {
        my $next = $info->{'to'};
        next unless $LifecycleObj->IsTransition( $status => $next );

        my %args = (%$info, id => $id);
        delete @args{qw(to from label update)};

        # if user will be owner then he will get more rights
        # TODO: check actually if he will get required rights
        if ( !$args{'TakeOrStealFirst'} || $session{'CurrentUser'}->id == $ticket->Owner ) {
            my $check = $LifecycleObj->CheckRight( $status => $next );
            next unless $can->( $check );
        }

        my $path = '';
        $path .= 'Incident/' if RT::IR->IsIncidentQueue($ticket->QueueObj);
        if ( my $update = $info->{'update'} ) {
            $path .= RT::IR->IsIncidentQueue($ticket->QueueObj) ? 'Reply/' : 'Update.html';
            $path .= "?". $m->comp(
                '/Elements/QueryString',
                %args,
                Action => $update,
                Status => $next,
            );
        } else {
            $path .= "Display.html?". $m->comp(
                '/Elements/QueryString',
                %args,
                Status => $next,
            );
        }
            $path=RT::IR->HREFTo($path, IncludeWebPath => 0);
        $actions_tab->child(
            lc($info->{'label'} || $next),
            title => loc( $info->{'label'} || ucfirst($next) ),
            path  => $path,
        );
    }

    if ( $can->('ModifyTicket') || $can->('CommentOnTicket') ) {
        $actions_tab->child(
            comment => title => loc('Comment'),
            path  => RT::IR->HREFTo("Update.html?Action=Comment&id=$id", IncludeWebPath => 0),
        );
    }

    # TODO needs a "Can extract article into a class applied to this queue" check
    $actions_tab->child( 'extract-article' =>
            title => loc('Extract Article'),
            path  => "/Articles/Article/ExtractIntoClass.html?Ticket=$id",
    ) if $session{CurrentUser}->HasRight( Right => 'ShowArticlesMenu', Object => RT->System );


    PageMenu()->child(
        bookmark => raw_html => $m->scomp( '/Ticket/Elements/Bookmark', id => $id ),
        sort_order   => 98
    );
    if ($can->('ModifyTicket')) {
        PageMenu()->child(
            timer => raw_html => $m->scomp( '/Ticket/Elements/PopupTimerLink', id => $id, TicketObj => $ticket ),
            sort_order => 99
        );
    }

} elsif ( $request_path =~ m{(?:$re_rtir_path)Link/(ToIncident|FromIncident)} ) {
    my $direction = $1;

    my $lifecycle = $args->{'Lifecycle'};

    my $ticket = RT::Ticket->new( $session{'CurrentUser'} );
    $ticket->Load( $args->{'id'} );
    my $id = $ticket->id;

    my %args = (
        $search_arguments->(),
        id => $id,
        Lifecycle => $lifecycle,
        ExtraQueryParams => [ 'RTIR', 'id', 'Lifecycle' ],
        RTIR => 1,
    );

    PageMenu()->child(
        link => title => loc('Show Results'),
        path => RT::IR->HREFTo("Link/$direction/?". $query_string->( %args ), IncludeWebPath => 0),
    );
    PageMenu()->child(
        edit_search => title => loc('Edit Search'),
        path => '/Search/Build.html?' . $query_string->( %args, ResultPage => RT::IR->HREFTo("Link/$direction/") ),
    );
    PageMenu()->child(
        new => title => loc("New [_1]", RT::IR::TicketType( Lifecycle => $lifecycle || RT::IR->lifecycle_incident ) ),
        path => !$lifecycle
            ? RT::IR->HREFTo("Incident/Create.html?Child=$id&Lifecycle=".RT::IR->lifecycle_incident, IncludeWebPath => 0)
            : RT::IR->HREFTo('Create.html?' . $query_string->( Incident => $id, Lifecycle => $lifecycle ), IncludeWebPath => 0)
        ,
    );
    PageMenu()->child(
        back => title => loc('Back to [_1] #[_2]',lc RT::IR::TicketType(Lifecycle => $ticket->QueueObj->Lifecycle), $id),
        path => RT::IR->HREFTo("Display.html?id=$id", IncludeWebPath => 0),
    );
} elsif ( $request_path =~ m{(?:$re_rtir_path)Incident/Children} ) {
    my $lifecycle = $args->{'Lifecycle'} ||  RT::IR->lifecycle_report;

    my $ticket = RT::Ticket->new( $session{'CurrentUser'} );
    $ticket->Load( $args->{'id'} );
    my $id = $ticket->id;

    my %args = (
        id => $id,
        Lifecycle => $lifecycle,
    );

    PageMenu()->child(
        new => title => loc("New [_1]",RT::IR::TicketType( Lifecycle => $lifecycle ) ),
        path => RT::IR->HREFTo("Create.html?". $query_string->( Incident => $id, Lifecycle => $lifecycle ), IncludeWebPath => 0),
    );
    PageMenu()->child(
        back => title => loc('Back to [_1] #[_2]', lc RT::IR::TicketType( Lifecycle => $ticket->QueueObj->Lifecycle), $id),
        path => RT::IR->HREFTo( "Display.html?id=$id", IncludeWebPath => 0),
    );
} elsif ( $request_path =~ m{^(?:$re_rtir_path)Merge} ) {
    my $ticket = RT::Ticket->new( $session{'CurrentUser'} );
    $ticket->Load( $args->{'id'} );
    my $id = $ticket->id;

    my %args = (
        $search_arguments->(),
        id    => $id,
        ExtraQueryParams => [ 'RTIR', 'id' ],
        RTIR             => 1,
    );

    PageMenu()->child(
        link => title => loc('Merge'),
        path => RT::IR->HREFTo("Merge/?". $query_string->( %args ), IncludeWebPath => 0),
    );
    PageMenu()->child(
        edit_search => title => loc('Edit Search'),
        path => '/Search/Build.html?' . $query_string->( %args, ResultPage => RT::IR->HREFTo("Merge/") ),
    );
    PageMenu()->child(
        back => title => loc('Back to [_1] #[_2]', lc RT::IR::TicketType( Lifecycle => $ticket->QueueObj->Lifecycle), $id),
        path => RT::IR->HREFTo("Display.html?id=$id", IncludeWebPath => 0),
    );
} elsif ( $request_path =~ m{(?:$re_rtir_path)Incident/Reply} ) {
    my $ticket = RT::Ticket->new( $session{'CurrentUser'} );
    $ticket->Load( $args->{'id'} );
    my $id = $ticket->id;

    my %args = (
        $search_arguments->(),
        id => $id,
        All => $args->{'All'},
        Status => $args->{'Status'},
        Action => $args->{'Action'},
        map( { $_ => $DECODED_ARGS->{$_} } grep { /Selected\w+All/ } keys %$DECODED_ARGS ),
        ExtraQueryParams => [ 'RTIR', 'id', 'All', grep { /Selected\w+All/ } keys %$DECODED_ARGS ],
        RTIR             => 1,
    );

    PageMenu()->child(
        edit_search => title => loc('Edit Search'),
        path => '/Search/Build.html?' . $query_string->( %args, ResultPage => RT::IR->HREFTo('Incident/Reply/') ),
    );
    PageMenu()->child(
        back => title => loc('Back to [_1] #[_2]', lc RT::IR::TicketType(Lifecycle => $ticket->QueueObj->Lifecycle), $id),
        path => RT::IR->HREFTo("Display.html?id=$id", IncludeWebPath => 0),
    );
} elsif ( $request_path =~ m{(?:$re_rtir_path)(Incident/BulkAbandon\.html$|Report/BulkReject\.html$)} ) {
    my %args = $search_arguments->();

    my $lifecycle = $args->{'Lifecycle'} || '';
    unless ( $lifecycle ) {
        if ( $request_path =~ /Incident/ ) {
            $lifecycle =  RT::IR->lifecycle_incident;
        }
        elsif ( $request_path =~ /Report/ ) {
            $lifecycle =  RT::IR->lifecycle_report;
        }
    }
    unless ( $lifecycle ) {
        my (undef, @lifecycles) = RT::IR->OurQuery( $args{'Query'} );
        $lifecycle = $lifecycles[0] if @lifecycles == 1;
    }

    $args{'Lifecycle'} = $lifecycle if $lifecycle;

    if ( $args{'Query'} ) {
        PageMenu()->child(
            link => title => loc('Show Results'),
            path => "/Search/Results.html?". $query_string->( %args ),
        );
    }

    # Refine.html doesn't let you change the Queue, so don't link there from the
    # full RTIR Search UI, only from the Bulk screens.
    my $bulk_path = 1 if $request_path =~ m{(?:$re_rtir_path)(Incident/BulkAbandon\.html$|Report/BulkReject\.html$)};

    PageMenu()->child(
        edit_search => title => loc('Edit Search'),
        path => '/Search/Build.html?' . $query_string->( %args ),
    );
    if ( $args{'Query'} && !$bulk_path ) {
        PageMenu()->child(
            new_search => title => loc('New Search'),
            path => '/Search/Build.html?NewQuery=1&ExtraQueryParams=RTIR&RTIR=1'
        );
    }

    if ( $lifecycle eq RT::IR->lifecycle_incident ) {
        PageMenu()->child(
            report => title => loc('Report'),
            path => RT::IR->HREFTo("Reporting/", IncludeWebPath => 0),
        );

        PageMenu()->child(
            abandon => title => loc('Bulk Abandon'),
            path => RT::IR->HREFTo("Incident/BulkAbandon.html?". $query_string->( %args ), IncludeWebPath => 0),
        );
    }
    elsif ( $lifecycle eq RT::IR->lifecycle_report) {
        PageMenu()->child(
            reject => title => loc('Bulk Reject'),
            path => RT::IR->HREFTo("Report/BulkReject.html?". $query_string->( %args ), IncludeWebPath => 0),
        );
    }

    if ( $args{'Query'} ) {
        my $more = PageMenu->child( more => title => loc('Feeds') );
        $more->child(
                spreadsheet => title => loc('Spreadsheet'),
                path => "/Search/Results.tsv?". $query_string->( %args ),
        );

        # other paths need query defined
        $args{'Query'} = RT::IR->Query( Lifecycle => $args{'Lifecycle'} )
            if !$args{'Query'} && $args{'Lifecycle'};

        my $RSSPath = join '/', map $m->interp->apply_escapes( $_, 'u' ),
            $session{'CurrentUser'}->UserObj->Name,
            $session{'CurrentUser'}->UserObj->GenerateAuthString(
                join '', map $args{$_}||'', qw(Query Order OrderBy)
            )
        ;
        $more->child(
            rss => title => loc('RSS'),
            path => "/NoAuth/rss/$RSSPath/?". $query_string->(
                Query => $args{Query}, Order => $args{Order}, OrderBy => $args{OrderBy}
            ),
        );

        my $ical_path = join '/', map $m->interp->apply_escapes($_, 'u'),
            $session{'CurrentUser'}->UserObj->Name,
            $session{'CurrentUser'}->UserObj->GenerateAuthString( $args{Query} ),
            $args{Query}
        ;
        $more->child( ical => title => loc('iCal') => path => '/NoAuth/iCal/'.$ical_path);

        if ( $session{'CurrentUser'}->HasRight( Right => 'SuperUser', Object => RT->System ) ) {
            my $shred_args = $query_string->(
                Search          => 1,
                Plugin          => 'Tickets',
                'Tickets:query' => $args{'Query'},
                'Tickets:limit' => $args{'RowsPerPage'},
            );
            $more->child(
                shredder => title => loc('Shredder'),
                path => '/Admin/Tools/Shredder/?' . $shred_args
            );
        }
    }
} elsif ( $request_path =~ m{(?:$re_rtir_path)(?:$re_rtir_types/)?Split\.html$} ) {
    my $id = $args->{'Split'};

    my $ticket = RT::Ticket->new($session{'CurrentUser'});
    $ticket->Load($id);
    PageMenu()->child(
        back => title => loc('Back to  [_1] #[_2]',lc RT::IR::TicketType(Lifecycle => $ticket->QueueObj->Lifecycle), $id),
        path => RT::IR->HREFTo("Display.html?id=$id", IncludeWebPath => 0),
    );
}

if ( $session{'CurrentUser'}->HasRight(Right => 'ModifySelf', Object => $RT::System) ) {
    if ( $request_path =~ m{(?:$re_rtir_path)(?:index\.html|)$} ) {
        my $alt = loc('Edit');
        PageMenu()->child( edit => raw_html => qq[<span class="rt-inline-icon border rounded" alt="$alt" data-bs-toggle="tooltip" data-bs-placement="top" data-bs-title="$alt"><a id="page-edit" aria-label="$alt" class="menu-item" href="] . RT::IR->HREFTo("Prefs/Home.html") . q[">] . HTML::Mason::Commands::GetSVGImage(Name => 'gear') . q[</a></span>] );
    }
}

PageWidgets()->child('simple_search')->raw_html( $m->scomp(
    '/Elements/SimpleSearch',
    SendTo => RT::IR->HREFTo('index.html', IncludeWebPath => 0),
    Placeholder => 'Search Incidents'
) ) if PageWidgets()->child('simple_search'); # /Views/Component/PageMenu doesn't fully set up PageWidgets
PageWidgets()->child( create_ticket => raw_html => $HTML::Mason::Commands::m->scomp('/Elements/CreateTicket', SendTo => '/RTIR/Create.html?Queue=' . (RT::IR::GetRTIRDefaultQueue() // '')) );

if ( $request_path =~ m{$re_rtir_path(?:Incident/)?Create\.html} ) {
    my $default_queue = GetDefaultQueue();
    my $queue;
    if ( $default_queue && !RT::IR->OurQueue($default_queue) ) {
        $queue = $default_queue;
    }
    else {
        # Find the first non-RTIR queue current user can create
        my $cache_key = SetObjectSessionCache(
            ObjectType       => 'Queue',
            CheckRight       => 'CreateTicket',
            CacheNeedsUpdate => RT->System->QueueCacheNeedsUpdate,
            ShowAll          => 0,
        );
        ($queue) = map { $_->{Id} } grep { !RT::IR->OurQueue( $_->{Id} ) } @{ $session{$cache_key}{objects} };
    }

    if ($queue) {
        PageMenu()->child(
            rt_create_ticket => title => loc('RT Create Ticket'),
            path             => "/Ticket/Create.html?Queue=$queue",
        );
    }
}
</%INIT>

<%ARGS>
$Path
</%ARGS>
