no need for FS calendar buttons in RT 4.2
[freeside.git] / rt / share / html / Elements / Tabs
1 %# BEGIN BPS TAGGED BLOCK {{{
2 %#
3 %# COPYRIGHT:
4 %#
5 %# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
6 %#                                          <sales@bestpractical.com>
7 %#
8 %# (Except where explicitly superseded by other copyright notices)
9 %#
10 %#
11 %# LICENSE:
12 %#
13 %# This work is made available to you under the terms of Version 2 of
14 %# the GNU General Public License. A copy of that license should have
15 %# been provided with this software, but in any event can be snarfed
16 %# from www.gnu.org.
17 %#
18 %# This work is distributed in the hope that it will be useful, but
19 %# WITHOUT ANY WARRANTY; without even the implied warranty of
20 %# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21 %# General Public License for more details.
22 %#
23 %# You should have received a copy of the GNU General Public License
24 %# along with this program; if not, write to the Free Software
25 %# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26 %# 02110-1301 or visit their web page on the internet at
27 %# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
28 %#
29 %#
30 %# CONTRIBUTION SUBMISSION POLICY:
31 %#
32 %# (The following paragraph is not intended to limit the rights granted
33 %# to you to modify and distribute this software under the terms of
34 %# the GNU General Public License and is only of importance to you if
35 %# you choose to contribute your changes and enhancements to the
36 %# community by submitting them to Best Practical Solutions, LLC.)
37 %#
38 %# By intentionally submitting any modifications, corrections or
39 %# derivatives to this work, or any other work intended for use with
40 %# Request Tracker, to Best Practical Solutions, LLC, you confirm that
41 %# you are the copyright holder for those contributions and you grant
42 %# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
43 %# royalty-free, perpetual, license to use, copy, create derivative
44 %# works based on those contributions, and sublicense and distribute
45 %# those contributions and any derivatives thereof.
46 %#
47 %# END BPS TAGGED BLOCK }}}
48 <& /Elements/PageLayout, show_menu => $show_menu &>
49 <a name="skipnav" id="skipnav" accesskey="8"></a>
50 <%INIT>
51
52 #my $request_path = $HTML::Mason::Commands::r->path_info;
53 my $request_path = $m->request_comp->path;
54 $request_path =~ s!/{2,}!/!g;
55
56 my $query_string = sub {
57     my %args = @_;
58     my $u    = URI->new();
59     $u->query_form(map { $_ => $args{$_} } sort keys %args);
60     return $u->query;
61 };
62
63 my $build_admin_menu = sub {
64     my $top = shift;
65     my $admin = $top->child( admin => title => loc('Admin'), path => '/Admin/' );
66     if ( $session{'CurrentUser'}->HasRight( Object => RT->System, Right => 'AdminUsers' ) ) {
67         my $users = $admin->child( users =>
68             title       => loc('Users'),
69             description => loc('Manage users and passwords'),
70             path        => '/Admin/Users/',
71         );
72         $users->child( select => title => loc('Select'), path => "/Admin/Users/" );
73         $users->child( create => title => loc('Create'), path => "/Admin/Users/Modify.html?Create=1" );
74     }
75     my $groups = $admin->child( groups =>
76         title       => loc('Groups'),
77         description => loc('Manage groups and group membership'),
78         path        => '/Admin/Groups/',
79     );
80     $groups->child( select => title => loc('Select'), path => "/Admin/Groups/" );
81     $groups->child( create => title => loc('Create'), path => "/Admin/Groups/Modify.html?Create=1" );
82
83     my $queues = $admin->child( queues =>
84         title       => loc('Queues'),
85         description => loc('Manage queues and queue-specific properties'),
86         path        => '/Admin/Queues/',
87     );
88     $queues->child( select => title => loc('Select'), path => "/Admin/Queues/" );
89     $queues->child( create => title => loc('Create'), path => "/Admin/Queues/Modify.html?Create=1" );
90
91     if ( $session{'CurrentUser'}->HasRight( Object => RT->System, Right => 'AdminCustomField' ) ) {
92         my $cfs = $admin->child( 'custom-fields' =>
93             title       => loc('Custom Fields'),
94             description => loc('Manage custom fields and custom field values'),
95             path        => '/Admin/CustomFields/',
96         );
97         $cfs->child( select => title => loc('Select'), path => "/Admin/CustomFields/" );
98         $cfs->child( create => title => loc('Create'), path => "/Admin/CustomFields/Modify.html?Create=1" );
99     }
100
101     if ( $session{'CurrentUser'}->HasRight( Object => RT->System, Right => 'ModifyScrips' ) ) {
102         my $scrips = $admin->child( 'scrips' =>
103             title       => loc('Scrips'),
104             description => loc('Manage scrips'),
105             path        => '/Admin/Scrips/',
106         );
107         $scrips->child( select => title => loc('Select'), path => "/Admin/Scrips/" );
108         $scrips->child( create => title => loc('Create'), path => "/Admin/Scrips/Create.html" );
109     }
110
111     my $admin_global = $admin->child( global =>
112         title       => loc('Global'),
113         description => loc('Manage properties and configuration which apply to all queues'),
114         path        => '/Admin/Global/',
115     );
116
117     my $scrips = $admin_global->child( scrips =>
118         title       => loc('Scrips'),
119         description => loc('Modify scrips which apply to all queues'),
120         path        => '/Admin/Global/Scrips.html',
121     );
122     $scrips->child( select => title => loc('Select'), path => "/Admin/Global/Scrips.html" );
123     $scrips->child( create => title => loc('Create'), path => "/Admin/Scrips/Create.html?Global=1" );
124
125     my $templates = $admin_global->child( templates =>
126         title       => loc('Templates'),
127         description => loc('Edit system templates'),
128         path        => '/Admin/Global/Templates.html',
129     );
130     $templates->child( select => title => loc('Select'), path => "/Admin/Global/Templates.html" );
131     $templates->child( create => title => loc('Create'), path => "/Admin/Global/Template.html?Create=1" );
132
133     my $cfadmin = $admin_global->child( 'custom-fields' =>
134         title       => loc('Custom Fields'),
135         description => loc('Modify global custom fields'),
136         path        => '/Admin/Global/CustomFields/index.html',
137     );
138     $cfadmin->child( users =>
139         title       => loc('Users'),
140         description => loc('Select custom fields for all users'),
141         path        => '/Admin/Global/CustomFields/Users.html',
142     );
143     $cfadmin->child( groups =>
144         title       => loc('Groups'),
145         description => loc('Select custom fields for all user groups'),
146         path        => '/Admin/Global/CustomFields/Groups.html',
147     );
148     $cfadmin->child( queues =>
149         title       => loc('Queues'),
150         description => loc('Select custom fields for all queues'),
151         path        => '/Admin/Global/CustomFields/Queues.html',
152     );
153     $cfadmin->child( tickets =>
154         title       => loc('Tickets'),
155         description => loc('Select custom fields for tickets in all queues'),
156         path        => '/Admin/Global/CustomFields/Queue-Tickets.html',
157     );
158     $cfadmin->child( transactions =>
159         title       => loc('Ticket Transactions'),
160         description => loc('Select custom fields for transactions on tickets in all queues'),
161         path        => '/Admin/Global/CustomFields/Queue-Transactions.html',
162     );
163     $cfadmin->child( 'custom-fields' =>
164         title       => loc('Articles'),
165         description => loc('Select Custom Fields for Articles in all Classes'),
166         path        => '/Admin/Global/CustomFields/Class-Article.html',
167     );
168
169     my $article_admin = $admin->child( articles => title => loc('Articles'), path => "/Admin/Articles/index.html" );
170     my $class_admin = $article_admin->child(classes => title => loc('Classes'), path => '/Admin/Articles/Classes/' );
171     $class_admin->child( select =>
172         title       => loc('Select'),
173         description => loc('Modify and Create Classes'),
174         path        => '/Admin/Articles/Classes/',
175     );
176     $class_admin->child( create =>
177         title       => loc('Create'),
178         description => loc('Modify and Create Custom Fields for Articles'),
179         path        => '/Admin/Articles/Classes/Modify.html?Create=1',
180     );
181
182
183     my $cfs = $article_admin->child( 'custom-fields' =>
184         title => loc('Custom Fields'),
185         path  => '/Admin/CustomFields/index.html?'.$m->comp('/Elements/QueryString', Type => 'RT::Class-RT::Article'),
186     );
187     $cfs->child( select =>
188         title => loc('Select'),
189         path => '/Admin/CustomFields/index.html?'.$m->comp('/Elements/QueryString', Type => 'RT::Class-RT::Article'),
190     );
191     $cfs->child( create =>
192         title => loc('Create'),
193         path => '/Admin/CustomFields/Modify.html?'.$m->comp("/Elements/QueryString", Create=>1, LookupType=> "RT::Class-RT::Article" ),
194     );
195
196     $admin_global->child( 'group-rights' =>
197         title       => loc('Group Rights'),
198         description => loc('Modify global group rights'),
199         path        => '/Admin/Global/GroupRights.html',
200     );
201     $admin_global->child( 'user-rights' =>
202         title       => loc('User Rights'),
203         description => loc('Modify global user rights'),
204         path        => '/Admin/Global/UserRights.html',
205     );
206     $admin_global->child( 'my-rt' =>
207         title       => loc('RT at a glance'),
208         description => loc('Modify the default "RT at a glance" view'),
209         path        => '/Admin/Global/MyRT.html',
210     );
211     $admin_global->child( 'dashboards-in-menu' =>
212         title       => loc('Dashboards in menu'),
213         description => loc('Customize dashboards in menu'),
214         path        => '/Admin/Global/DashboardsInMenu.html',
215     );
216     $admin_global->child( 'topics' =>
217         title       => loc('Topics'),
218         description => loc('Modify global article topics'),
219         path        => '/Admin/Global/Topics.html',
220     );
221
222     my $admin_tools = $admin->child( tools =>
223         title       => loc('Tools'),
224         description => loc('Use other RT administrative tools'),
225         path        => '/Admin/Tools/',
226     );
227     $admin_tools->child( configuration =>
228         title       => loc('System Configuration'),
229         description => loc('Detailed information about your RT setup'),
230         path        => '/Admin/Tools/Configuration.html',
231     );
232     $admin_tools->child( theme =>
233         title       => loc('Theme'),
234         description => loc('Customize the look of your RT'),
235         path        => '/Admin/Tools/Theme.html',
236     );
237     if (RT->Config->Get('StatementLog')
238         && $session{'CurrentUser'}->HasRight( Right => 'SuperUser', Object => RT->System )) {
239        $admin_tools->child( 'sql-queries' =>
240            title       => loc('SQL Queries'),
241            description => loc('Browse the SQL queries made in this process'),
242            path        => '/Admin/Tools/Queries.html',
243        );
244     }
245     $admin_tools->child( shredder =>
246         title       => loc('Shredder'),
247         description => loc('Permanently wipeout data from RT'),
248         path        => '/Admin/Tools/Shredder',
249     );
250
251     if ( $request_path =~ m{^/Admin/(Queues|Users|Groups|CustomFields)} ) {
252         my $type = $1;
253         my $tabs = PageMenu();
254
255         my %labels = (
256             Queues       => loc("Queues"),
257             Users        => loc("Users"),
258             Groups       => loc("Groups"),
259             CustomFields => loc("Custom Fields"),
260         );
261
262         my $section;
263         if ( $request_path =~ m|^/Admin/$type/?(?:index.html)?$|
264              || (    $request_path =~ m|^/Admin/$type/(?:Modify.html)$|
265                   && $DECODED_ARGS->{'Create'} )
266            )
267         {
268             $section = $tabs;
269
270         } else {
271             $section = $tabs->child( select => title => $labels{$type},
272                                      path => "/Admin/$type/" );
273         }
274
275         $section->child( select => title => loc('Select'), path => "/Admin/$type/" );
276         $section->child( create => title => loc('Create'), path => "/Admin/$type/Modify.html?Create=1" );
277     }
278
279     if ( $request_path =~ m{^/Admin/Queues} ) {
280         if ( $DECODED_ARGS->{'id'} && $DECODED_ARGS->{'id'} =~ /^\d+$/
281                 ||
282               $DECODED_ARGS->{'Queue'} && $DECODED_ARGS->{'Queue'} =~ /^\d+$/
283                 ) {
284             my $id = $DECODED_ARGS->{'Queue'} || $DECODED_ARGS->{'id'};
285             my $queue_obj = RT::Queue->new( $session{'CurrentUser'} );
286             $queue_obj->Load($id);
287
288             if ( $queue_obj and $queue_obj->id ) {
289                 my $queue = PageMenu();
290                 $queue->child( basics => title => loc('Basics'),   path => "/Admin/Queues/Modify.html?id=" . $id );
291                 $queue->child( people => title => loc('Watchers'), path => "/Admin/Queues/People.html?id=" . $id );
292
293                 my $templates = $queue->child(templates => title => loc('Templates'), path => "/Admin/Queues/Templates.html?id=" . $id);
294                 $templates->child( select => title => loc('Select'), path => "/Admin/Queues/Templates.html?id=".$id);
295                 $templates->child( create => title => loc('Create'), path => "/Admin/Queues/Template.html?Create=1;Queue=".$id);
296
297                 my $scrips = $queue->child( scrips => title => loc('Scrips'), path => "/Admin/Queues/Scrips.html?id=" . $id);
298                 $scrips->child( select => title => loc('Select'), path => "/Admin/Queues/Scrips.html?id=" . $id );
299                 $scrips->child( create => title => loc('Create'), path => "/Admin/Scrips/Create.html?Queue=" . $id);
300
301                 my $cfs = $queue->child( 'custom-fields' => title => loc('Custom Fields') );
302                 my $ticket_cfs = $cfs->child( 'tickets' => title => loc('Tickets'),
303                     path => '/Admin/Queues/CustomFields.html?SubType=RT::Ticket&id=' . $id );
304
305                 my $txn_cfs = $cfs->child( 'transactions' => title => loc('Transactions'),
306                     path => '/Admin/Queues/CustomFields.html?SubType=RT::Ticket-RT::Transaction&id='.$id );
307
308                 $queue->child( 'tasks' => title => loc('Subtasks'), path => "Admin/Queues/Tasks.html?Queue=".$id );
309
310                 $queue->child( 'group-rights' => title => loc('Group Rights'), path => "/Admin/Queues/GroupRights.html?id=".$id );
311                 $queue->child( 'user-rights' => title => loc('User Rights'), path => "/Admin/Queues/UserRights.html?id=" . $id );
312                 $queue->child( 'history' => title => loc('History'), path => "/Admin/Queues/History.html?id=" . $id );
313
314                 $m->callback( CallbackName => 'PrivilegedQueue', queue_id => $id, page_menu => $queue);
315             }
316         }
317     }
318     if ( $request_path =~ m{^(/Admin/Users|/User/(Summary|History)\.html)} and $admin->child("users") ) {
319         if ( $DECODED_ARGS->{'id'} && $DECODED_ARGS->{'id'} =~ /^\d+$/ ) {
320             my $id = $DECODED_ARGS->{'id'};
321             my $obj = RT::User->new( $session{'CurrentUser'} );
322             $obj->Load($id);
323
324             if ( $obj and $obj->id ) {
325                 my $tabs = PageMenu();
326                 $tabs->child( basics      => title => loc('Basics'),         path => "/Admin/Users/Modify.html?id=" . $id );
327                 $tabs->child( memberships => title => loc('Memberships'),    path => "/Admin/Users/Memberships.html?id=" . $id );
328                 $tabs->child( history     => title => loc('History'),        path => "/Admin/Users/History.html?id=" . $id );
329                 $tabs->child( 'my-rt'     => title => loc('RT at a glance'), path => "/Admin/Users/MyRT.html?id=" . $id );
330                 $tabs->child( 'dashboards-in-menu' =>
331                     title => loc('Dashboards in menu'),
332                     path  => '/Admin/Users/DashboardsInMenu.html?id=' . $id,
333                 );
334                 if ( RT->Config->Get('Crypt')->{'Enable'} ) {
335                     $tabs->child( keys    => title => loc('Private keys'),   path => "/Admin/Users/Keys.html?id=" . $id );
336                 }
337                 $tabs->child( 'summary'   => title => loc('User Summary'),   path => "/User/Summary.html?id=" . $id );
338             }
339         }
340
341     }
342
343     if ( $request_path =~ m{^/Admin/Groups} ) {
344         if ( $DECODED_ARGS->{'id'} && $DECODED_ARGS->{'id'} =~ /^\d+$/ ) {
345             my $id = $DECODED_ARGS->{'id'};
346             my $obj = RT::Group->new( $session{'CurrentUser'} );
347             $obj->Load($id);
348
349             if ( $obj and $obj->id ) {
350                 my $tabs = PageMenu();
351                 $tabs->child( basics         => title => loc('Basics'),       path => "/Admin/Groups/Modify.html?id=" . $obj->id );
352                 $tabs->child( members        => title => loc('Members'),      path => "/Admin/Groups/Members.html?id=" . $obj->id );
353                 $tabs->child( memberships    => title => loc('Memberships'),  path => "/Admin/Groups/Memberships.html?id=" . $obj->id );
354                 $tabs->child( 'group-rights' => title => loc('Group Rights'), path => "/Admin/Groups/GroupRights.html?id=" . $obj->id );
355                 $tabs->child( 'user-rights'  => title => loc('User Rights'),  path => "/Admin/Groups/UserRights.html?id=" . $obj->id );
356                 $tabs->child( history        => title => loc('History'),      path => "/Admin/Groups/History.html?id=" . $obj->id );
357             }
358         }
359     }
360
361     if ( $request_path =~ m{^/Admin/CustomFields/} ) {
362         if ( $DECODED_ARGS->{'id'} && $DECODED_ARGS->{'id'} =~ /^\d+$/ ) {
363             my $id = $DECODED_ARGS->{'id'};
364             my $obj = RT::CustomField->new( $session{'CurrentUser'} );
365             $obj->Load($id);
366
367             if ( $obj and $obj->id ) {
368                 my $tabs = PageMenu();
369                 $tabs->child( basics           => title => loc('Basics'),       path => "/Admin/CustomFields/Modify.html?id=".$id );
370                 $tabs->child( 'group-rights'   => title => loc('Group Rights'), path => "/Admin/CustomFields/GroupRights.html?id=" . $id );
371                 $tabs->child( 'user-rights'    => title => loc('User Rights'),  path => "/Admin/CustomFields/UserRights.html?id=" . $id );
372                 unless ( $obj->IsOnlyGlobal ) {
373                     $tabs->child( 'applies-to' => title => loc('Applies to'),   path => "/Admin/CustomFields/Objects.html?id=" . $id );
374                 }
375             }
376         }
377     }
378
379     if ( $request_path =~ m{^/Admin/Scrips/} ) {
380         if ( $m->request_args->{'id'} && $m->request_args->{'id'} =~ /^\d+$/ ) {
381             my $id = $m->request_args->{'id'};
382             my $obj = RT::Scrip->new( $session{'CurrentUser'} );
383             $obj->Load($id);
384
385             my $tabs = PageMenu();
386
387             my ( $admin_cat, $create_path_arg, $from_query_param );
388             my $from_arg = $DECODED_ARGS->{'From'} || q{};
389             my ($from_queue) = $from_arg =~ /^(\d+)$/;
390             if ( $from_queue ) {
391                 $admin_cat = "Queues/Scrips.html?id=$from_queue";
392                 $create_path_arg = "?Queue=$from_queue";
393                 $from_query_param = "&From=$from_queue";
394             }
395             elsif ( $from_arg eq 'Global' ) {
396                 $admin_cat = 'Global/Scrips.html';
397                 $create_path_arg = '?Global=1';
398                 $from_query_param = '&From=Global';
399             }
400             else {
401                 $admin_cat = 'Scrips';
402                 $from_query_param = $create_path_arg = q{};
403             }
404             my $scrips = $tabs->child( scrips => title => loc('Scrips'), path => "/Admin/${admin_cat}" );
405             $scrips->child( select => title => loc('Select'), path => "/Admin/${admin_cat}" );
406             $scrips->child( create => title => loc('Create'), path => "/Admin/Scrips/Create.html${create_path_arg}" );
407
408             $tabs->child( basics => title => loc('Basics') => path => "/Admin/Scrips/Modify.html?id=" . $id . $from_query_param );
409             $tabs->child( 'applies-to' => title => loc('Applies to'), path => "/Admin/Scrips/Objects.html?id=" . $id . $from_query_param );
410         }
411         elsif ( $request_path =~ m{^/Admin/Scrips/(index\.html)?$} ) {
412             PageMenu->child( select => title => loc('Select') => path => "/Admin/Scrips/" );
413             PageMenu->child( create => title => loc('Create') => path => "/Admin/Scrips/Create.html" );
414         }
415         elsif ( $request_path =~ m{^/Admin/Scrips/Create\.html$} ) {
416             my ($queue) = $DECODED_ARGS->{'Queue'} && $DECODED_ARGS->{'Queue'} =~ /^(\d+)$/;
417             my $global_arg = $DECODED_ARGS->{'Global'};
418             if ($queue) {
419                 PageMenu->child( select => title => loc('Select') => path => "/Admin/Queues/Scrips.html?id=$queue" );
420                 PageMenu->child( create => title => loc('Create') => path => "/Admin/Scrips/Create.html?Queue=$queue" );
421             } elsif ($global_arg) {
422                 PageMenu->child( select => title => loc('Select') => path => "/Admin/Global/Scrips.html" );
423                 PageMenu->child( create => title => loc('Create') => path => "/Admin/Scrips/Create.html?Global=1" );
424             } else {
425                 PageMenu->child( select => title => loc('Select') => path => "/Admin/Scrips" );
426                 PageMenu->child( create => title => loc('Create') => path => "/Admin/Scrips/Create.html" );
427             }
428         }
429     }
430
431     if ( $request_path =~ m{^/Admin/Global/Scrips\.html} ) {
432         my $tabs = PageMenu();
433         $tabs->child( select => title => loc('Select'), path => "/Admin/Global/Scrips.html" );
434         $tabs->child( create => title => loc('Create'), path => "/Admin/Scrips/Create.html?Global=1" );
435     }
436
437     if ( $request_path =~ m{^/Admin/Global/Templates?\.html} ) {
438         my $tabs = PageMenu();
439         $tabs->child( select => title => loc('Select'), path => "/Admin/Global/Templates.html" );
440         $tabs->child( create => title => loc('Create'), path => "/Admin/Global/Template.html?Create=1" );
441     }
442
443     if ( $request_path =~ m{^/Admin/Articles/Classes/} ) {
444         my $tabs = PageMenu();
445         if ( my $id = $DECODED_ARGS->{'id'} ) {
446             my $obj = RT::Class->new( $session{'CurrentUser'} );
447             $obj->Load($id);
448
449             if ( $obj and $obj->id ) {
450                 my $section = $tabs->child( select => title => loc("Classes"), path => "/Admin/Articles/Classes/" );
451                 $section->child( select => title => loc('Select'), path => "/Admin/Articles/Classes/" );
452                 $section->child( create => title => loc('Create'), path => "/Admin/Articles/Classes/Modify.html?Create=1" );
453
454                 $tabs->child( basics          => title => loc('Basics'),        path => "/Admin/Articles/Classes/Modify.html?id=".$id );
455                 $tabs->child( topics          => title => loc('Topics'),        path => "/Admin/Articles/Classes/Topics.html?id=".$id );
456                 $tabs->child( 'custom-fields' => title => loc('Custom Fields'), path => "/Admin/Articles/Classes/CustomFields.html?id=".$id );
457                 $tabs->child( 'group-rights'  => title => loc('Group Rights'),  path => "/Admin/Articles/Classes/GroupRights.html?id=".$id );
458                 $tabs->child( 'user-rights'   => title => loc('User Rights'),   path => "/Admin/Articles/Classes/UserRights.html?id=".$id );
459                 $tabs->child( 'applies-to'    => title => loc('Applies to'),    path => "/Admin/Articles/Classes/Objects.html?id=$id" );
460             }
461         } else {
462             $tabs->child( select => title => loc('Select'), path => "/Admin/Articles/Classes/" );
463             $tabs->child( create => title => loc('Create'), path => "/Admin/Articles/Classes/Modify.html?Create=1" );
464         }
465     }
466 };
467
468 my $build_main_nav = sub {
469
470     PageWidgets()->child( simple_search => raw_html => $m->scomp('SimpleSearch') );
471     PageWidgets()->child( create_ticket => raw_html => $m->scomp('CreateTicket') );
472
473     my $home = Menu->child( home => title => loc('Homepage'), path => '/' );
474     unless ($session{'dashboards_in_menu'}) {
475         my $dashboards_in_menu = $session{CurrentUser}->UserObj->Preferences(
476             'DashboardsInMenu',
477             {},
478         );
479
480         unless ($dashboards_in_menu->{dashboards}) {
481             my ($default_dashboards) =
482                 RT::System->new( $session{'CurrentUser'} )
483                     ->Attributes
484                     ->Named('DashboardsInMenu');
485             if ($default_dashboards) {
486                 $dashboards_in_menu = $default_dashboards->Content;
487             }
488         }
489
490         $session{'dashboards_in_menu'} = $dashboards_in_menu->{dashboards} || [];
491     }
492
493     my @dashboards;
494     for my $id ( @{$session{'dashboards_in_menu'}} ) {
495         my $dash = RT::Dashboard->new( $session{CurrentUser} );
496         my ( $status, $msg ) = $dash->LoadById($id);
497         if ( $status ) {
498             push @dashboards, $dash;
499         } else {
500             $RT::Logger->debug( "Failed to load dashboard $id: $msg, removing from menu" );
501             $home->RemoveDashboardMenuItem( DashboardId => $id, CurrentUser => $session{CurrentUser}->UserObj );
502             @{$session{'dashboards_in_menu'}} = grep { $_ != $id } @{$session{'dashboards_in_menu'}};
503         }
504     }
505
506     my $dashes = Menu()->child('home');
507     if (@dashboards) {
508         for my $dash (@dashboards) {
509             $home->child( 'dashboard-' . $dash->id,
510                 title => $dash->Name,
511                 path  => '/Dashboards/' . $dash->id . '/' . $dash->Name
512             );
513         }
514     }
515     $dashes->child( edit => title => loc('Update This Menu'), path => 'Prefs/DashboardsInMenu.html' );
516     $dashes->child( more => title => loc('All Dashboards'),   path => 'Dashboards/index.html' );
517     my $dashboard = RT::Dashboard->new( $session{CurrentUser} );
518     if ( $dashboard->CurrentUserCanCreateAny ) {
519         $dashes->child('dashboard_create' => title => loc('New Dashboard'), path => "/Dashboards/Modify.html?Create=1" );
520     }
521
522     my $search = Menu->child( search => title => loc('Search'), path => '/Search/Simple.html' );
523
524     my $tickets = $search->child( tickets => title => loc('Tickets'), path => '/Search/Build.html' );
525     $tickets->child( simple => title => loc('Simple Search'), path => "/Search/Simple.html" );
526     $tickets->child( new    => title => loc('New Search'),    path => "/Search/Build.html?NewQuery=1" );
527
528     $search->child( articles => title => loc('Articles'),   path => "/Articles/Article/Search.html" )
529         if $session{CurrentUser}->HasRight( Right => 'ShowArticlesMenu', Object => RT->System );
530
531     $search->child( users => title => loc('Users'),   path => "/User/Search.html" );
532
533     if ($session{CurrentUser}->HasRight( Right => 'ShowArticlesMenu', Object => RT->System )) {
534         my $articles = Menu->child( articles => title => loc('Articles'), path => "/Articles/index.html");
535         $articles->child( articles => title => loc('Overview'), path => "/Articles/index.html" );
536         $articles->child( topics   => title => loc('Topics'),   path => "/Articles/Topics.html" );
537         $articles->child( create   => title => loc('Create'),   path => "/Articles/Article/PreCreate.html" );
538         $articles->child( search   => title => loc('Search'),   path => "/Articles/Article/Search.html" );
539     }
540
541     my $tools = Menu->child( tools => title => loc('Tools'), path => '/Tools/index.html' );
542
543     $tools->child( my_day =>
544         title       => loc('My Day'),
545         description => loc('Easy updating of your open tickets'),
546         path        => '/Tools/MyDay.html',
547     );
548
549     if ( RT->Config->Get('EnableReminders') ) {
550         $tools->child( my_reminders =>
551             title       => loc('My Reminders'),
552             description => loc('Easy viewing of your reminders'),
553             path        => '/Tools/MyReminders.html',
554         );
555     }
556
557     if ( $session{'CurrentUser'}->HasRight( Right => 'ShowApprovalsTab', Object => RT->System ) ) {
558         $tools->child( approval =>
559             title       => loc('Approval'),
560             description => loc('My Approvals'),
561             path        => '/Approvals/',
562         );
563     }
564
565     if ( $session{'CurrentUser'}->HasRight( Right => 'ShowConfigTab', Object => RT->System ) )
566     {
567         $build_admin_menu->(Menu());
568     }
569
570     my $username = '<span class="current-user">'
571                  . $m->interp->apply_escapes($session{'CurrentUser'}->Name, 'h')
572                  . '</span>';
573     my $about_me = Menu->child( 'preferences' =>
574         title        => loc('Logged in as [_1]', $username),
575         escape_title => 0,
576         path         => '/User/Summary.html?id=' . $session{CurrentUser}->id,
577         sort_order   => 99,
578     );
579
580
581     if ( $session{'CurrentUser'}->UserObj
582          && $session{'CurrentUser'}->HasRight( Right => 'ModifySelf', Object => RT->System )) {
583         my $settings = $about_me->child( settings => title => loc('Settings'), path => '/Prefs/Other.html' );
584         $settings->child( options        => title => loc('Preferences'),        path => '/Prefs/Other.html' );
585         $settings->child( about_me       => title => loc('About me'),       path => '/User/Prefs.html' );
586         $settings->child( search_options => title => loc('Search options'), path => '/Prefs/SearchOptions.html' );
587         $settings->child( myrt           => title => loc('RT at a glance'), path => '/Prefs/MyRT.html' );
588         $settings->child( dashboards_in_menu =>
589             title => loc('Dashboards in menu'),
590             path  => '/Prefs/DashboardsInMenu.html',
591         );
592         $settings->child( quicksearch    => title => loc('Quick search'),   path => '/Prefs/Quicksearch.html' );
593
594         my $search_menu = $settings->child( 'saved-searches' => title => loc('Saved Searches') );
595         my $searches = [ $m->comp( "/Search/Elements/SearchesForObject",
596                           Object => RT::System->new( $session{'CurrentUser'} )) ];
597         my $i = 0;
598
599         for my $search (@$searches) {
600             $search_menu->child( "search-" . $i++ =>
601                 title => $search->[1],
602                 path  => "/Prefs/Search.html?"
603                        . $query_string->( name => ref( $search->[2] ) . '-' . $search->[2]->Id ),
604             );
605
606         }
607     }
608     if ( $session{'CurrentUser'}->Name
609          && (   !RT->Config->Get('WebRemoteUserAuth')
610               || RT->Config->Get('WebFallbackToRTLogin') )) {
611         $about_me->child( logout => title => loc('Logout'), path => '/NoAuth/Logout.html' );
612     }
613     if ( $request_path =~ m{^/Dashboards/(\d+)?}) {
614         if ( my $id = ( $1 || $DECODED_ARGS->{'id'} ) ) {
615             my $obj = RT::Dashboard->new( $session{'CurrentUser'} );
616             $obj->LoadById($id);
617             if ( $obj and $obj->id ) {
618                 my $tabs = PageMenu;
619                 $tabs->child( basics       => title => loc('Basics'),       path => "/Dashboards/Modify.html?id=" . $obj->id);
620                 $tabs->child( content      => title => loc('Content'),      path => "/Dashboards/Queries.html?id=" . $obj->id);
621                 $tabs->child( subscription => title => loc('Subscription'), path => "/Dashboards/Subscription.html?id=" . $obj->id)
622                     if $obj->CurrentUserCanSubscribe;
623                 $tabs->child( show         => title => loc('Show'),         path => "/Dashboards/" . $obj->id . "/" . $obj->Name)
624             }
625         } else {
626             my $tabs = PageMenu();
627             if ( $dashboard->CurrentUserCanCreateAny ) {
628                 # FREESIDE: provide a way to create dashboards
629                 $tabs->child('dashboard_create' => title => loc('New Dashboard'), path => "/Dashboards/Modify.html?Create=1");
630             }
631         }
632     }
633
634     if ( $request_path =~ m{^/Ticket/} ) {
635         if ( ( $DECODED_ARGS->{'id'} || '' ) =~ /^(\d+)$/ ) {
636             my $id  = $1;
637             my $obj = RT::Ticket->new( $session{'CurrentUser'} );
638             $obj->Load($id);
639
640             if ( $obj and $obj->id ) {
641                 my $actions = PageMenu()->child( actions => title => loc('Actions'), sort_order  => 95 );
642                 my $tabs = PageMenu();
643                 $tabs->child( bookmark => raw_html => $m->scomp( '/Ticket/Elements/Bookmark', id => $id ), sort_order => 99 );
644                 $tabs->child( display => title => loc('Display'), path => "/Ticket/Display.html?id=" . $id );
645                 $tabs->child( history => title => loc('History'), path => "/Ticket/History.html?id=" . $id );
646
647                 my %can = %{ $obj->CurrentUser->PrincipalObj->HasRights( Object => $obj ) };
648                 $can{'_ModifyOwner'} = $obj->CurrentUserCanSetOwner();
649                 my $can = sub {
650                     unless ($_[0] eq 'ExecuteCode') {
651                         return $can{$_[0]} || $can{'SuperUser'};
652                     } else {
653                         return !RT->Config->Get('DisallowExecuteCode')
654                             && ( $can{'ExecuteCode'} || $can{'SuperUser'} );
655                     }
656                 };
657
658                 # comment out until we can do it for an individual custom field
659                 #if ( $can->('ModifyTicket') || $can->('ModifyCustomField') ) {
660                 $tabs->child( basics => title => loc('Basics'), path => "/Ticket/Modify.html?id=" . $id );
661
662                 #}
663
664                 #ACL?
665                 $tabs->child( customers => title => loc('Customers'), path => "/Ticket/ModifyCustomers.html?id=" . $id );
666
667                 if ( $can->('ModifyTicket') || $can->('_ModifyOwner') || $can->('Watch') || $can->('WatchAsAdminCc') ) {
668                     $tabs->child( people => title => loc('People'), path => "/Ticket/ModifyPeople.html?id=" . $id );
669                 }
670
671                 if ( $can->('ModifyTicket') ) {
672                     $tabs->child( dates => title => loc('Dates'), path => "/Ticket/ModifyDates.html?id=" . $id );
673                     $tabs->child( links => title => loc('Links'), path => "/Ticket/ModifyLinks.html?id=" . $id );
674                 }
675
676                 #if ( $can->('ModifyTicket') || $can->('ModifyCustomField') || $can->('_ModifyOwner') ) {
677                 $tabs->child( jumbo => title => loc('Jumbo'), path => "/Ticket/ModifyAll.html?id=" . $id );
678                 #}
679
680                 if ( RT->Config->Get('EnableReminders') ) {
681                     $tabs->child( reminders => title => loc('Reminders'), path => "/Ticket/Reminders.html?id=" . $id );
682                 }
683
684                 if ( $can->('ModifyTicket') or $can->('ReplyToTicket') ) {
685                     $actions->child( reply => title => loc('Reply'), path => "/Ticket/Update.html?Action=Respond;id=" . $id );
686                 }
687
688                 if ( $can->('ModifyTicket') or $can->('CommentOnTicket') ) {
689                     $actions->child( comment => title => loc('Comment'), path => "/Ticket/Update.html?Action=Comment;id=" . $id );
690                 }
691
692                 if ( $can->('ForwardMessage') ) {
693                     $actions->child( forward => title => loc('Forward'), path => "/Ticket/Forward.html?id=" . $id );
694                 }
695
696                 my $hide_resolve_with_deps = RT->Config->Get('HideResolveActionsWithDependencies')
697                     && $obj->HasUnresolvedDependencies;
698
699                 my $current   = $obj->Status;
700                 my $lifecycle = $obj->LifecycleObj;
701                 my $i         = 1;
702                 foreach my $info ( $lifecycle->Actions($current) ) {
703                     my $next = $info->{'to'};
704                     next unless $lifecycle->IsTransition( $current => $next );
705
706                     my $check = $lifecycle->CheckRight( $current => $next );
707                     next unless $can->($check);
708
709                     next if $hide_resolve_with_deps
710                         && $lifecycle->IsInactive($next)
711                         && !$lifecycle->IsInactive($current);
712
713                     my $action = $info->{'update'} || '';
714                     my $url = '/Ticket/';
715                     $url .= "Update.html?". $query_string->(
716                         $action
717                             ? (Action        => $action)
718                             : (SubmitTicket  => 1, Status => $next),
719                         DefaultStatus => $next,
720                         id            => $id,
721                     );
722                     my $key = $info->{'label'} || ucfirst($next);
723                     $actions->child( $key => title => loc( $key ), path => $url);
724                 }
725
726                 my ($can_take, $tmsg) = $obj->CurrentUserCanSetOwner( Type => 'Take' );
727                 my ($can_steal, $smsg) = $obj->CurrentUserCanSetOwner( Type => 'Steal' );
728                 if ( $can_take ){
729                     $actions->child( take => title => loc('Take'), path => "/Ticket/Display.html?Action=Take;id=" . $id );
730                 }
731                 elsif ( $can_steal ){
732                     $actions->child( steal => title => loc('Steal'), path => "/Ticket/Display.html?Action=Steal;id=" . $id );
733                 }
734
735                 # TODO needs a "Can extract article into a class applied to this queue" check
736                 $actions->child( 'extract-article' =>
737                     title => loc('Extract Article'),
738                     path  => "/Articles/Article/ExtractIntoClass.html?Ticket=".$obj->id,
739                 ) if $session{CurrentUser}->HasRight( Right => 'ShowArticlesMenu', Object => RT->System );
740
741                 if ( defined $session{"tickets"} ) {
742                     # we have to update session data if we get new ItemMap
743                     my $updatesession = 1 unless ( $session{"tickets"}->{'item_map'} );
744
745                     my $item_map = $session{"tickets"}->ItemMap;
746
747                     if ($updatesession) {
748                         $session{"tickets"}->PrepForSerialization();
749                     }
750
751                     my $search = Menu()->child('search')->child('tickets');
752                     # Don't display prev links if we're on the first ticket
753                     if ( $item_map->{$id}->{prev} ) {
754                         $search->child( first =>
755                             title => '<< ' . loc('First'), class => "nav", path => "/Ticket/Display.html?id=" . $item_map->{first});
756                         $search->child( prev =>
757                             title => '< ' . loc('Prev'),   class => "nav", path => "/Ticket/Display.html?id=" . $item_map->{$id}->{prev});
758                     }
759                     # Don't display next links if we're on the last ticket
760                     if ( $item_map->{$id}->{next} ) {
761                         $search->child( next =>
762                             title => loc('Next') . ' >',  class => "nav", path => "/Ticket/Display.html?id=" . $item_map->{$id}->{next});
763                         if ( $item_map->{last} ) {
764                             $search->child( last =>
765                                 title => loc('Last') . ' >>', class => "nav", path => "/Ticket/Display.html?id=" . $item_map->{last});
766                         }
767                     }
768                 }
769             }
770         }
771     }
772
773     # Scope here so we can share in the Privileged callback
774     my $args      = '';
775     my $has_query = '';
776     if (
777         (
778                $request_path =~ m{^/(?:Ticket|Search)/}
779             && $request_path !~ m{^/Search/Simple\.html}
780         )
781         || (   $request_path =~ m{^/Search/Simple\.html}
782             && $DECODED_ARGS->{'q'} )
783       )
784     {
785         my $search = Menu()->child('search')->child('tickets');
786         my $current_search = $session{"CurrentSearchHash"} || {};
787         my $search_id = $DECODED_ARGS->{'SavedSearchLoad'} || $DECODED_ARGS->{'SavedSearchId'} || $current_search->{'SearchId'} || '';
788         my $chart_id = $DECODED_ARGS->{'SavedChartSearchId'} || $current_search->{SavedChartSearchId};
789
790         $has_query = 1 if ( $DECODED_ARGS->{'Query'} or $current_search->{'Query'} );
791
792         my %query_args;
793         my %fallback_query_args = (
794             SavedSearchId => ( $search_id eq 'new' ) ? undef : $search_id,
795             SavedChartSearchId => $chart_id,
796             (
797                 map {
798                     my $p = $_;
799                     $p => $DECODED_ARGS->{$p} || $current_search->{$p}
800                 } qw(Query Format OrderBy Order Page)
801             ),
802             RowsPerPage => (
803                 defined $DECODED_ARGS->{'RowsPerPage'}
804                 ? $DECODED_ARGS->{'RowsPerPage'}
805                 : $current_search->{'RowsPerPage'}
806             ),
807         );
808
809         if ($QueryString) {
810             $args = '?' . $QueryString;
811         }
812         else {
813             my %final_query_args = ();
814             # key => callback to avoid unnecessary work
815
816             for my $param (keys %fallback_query_args) {
817                 $final_query_args{$param} = defined($QueryArgs->{$param})
818                                           ? $QueryArgs->{$param}
819                                           : $fallback_query_args{$param};
820             }
821
822             for my $field (qw(Order OrderBy)) {
823                 if ( ref( $final_query_args{$field} ) eq 'ARRAY' ) {
824                     $final_query_args{$field} = join( "|", @{ $final_query_args{$field} } );
825                 } elsif (not defined $final_query_args{$field}) {
826                     delete $final_query_args{$field};
827                 }
828                 else {
829                     $final_query_args{$field} ||= '';
830                 }
831             }
832
833             $args = '?' . $query_string->(%final_query_args);
834         }
835
836         my $current_search_menu;
837         if ( $request_path =~ m{^/Ticket} ) {
838             $current_search_menu = $search->child( current_search => title => loc('Current Search') );
839             $current_search_menu->path("/Search/Results.html$args") if $has_query;
840         } else {
841             $current_search_menu = PageMenu();
842         }
843
844         $current_search_menu->child( edit_search =>
845             title => loc('Edit Search'), path => "/Search/Build.html" . ( ($has_query) ? $args : '' ) );
846         $current_search_menu->child( advanced =>
847             title => loc('Advanced'),    path => "/Search/Edit.html$args" );
848         if ($has_query) {
849             $current_search_menu->child( results => title => loc('Show Results'), path => "/Search/Results.html$args" );
850         }
851
852         if ( $has_query ) {
853             #freeside
854             if ( $session{'CurrentUser'}->HasRight( Right => 'BulkUpdateTickets', Object => RT->System ) ) {
855               $current_search_menu->child( bulk  => title => loc('Bulk Update'), path => "/Search/Bulk.html$args" );
856             }
857             $current_search_menu->child( chart => title => loc('Chart'),       path => "/Search/Chart.html$args" );
858
859             #formerly Callbacks/RTx-Calendar/Ticket/Element/Tabs/Default
860             $current_search_menu->child( calendar => title => loc('Calendar'), path => "/Search/Calendar.html$args" );
861
862             my $more = $current_search_menu->child( more => title => loc('Feeds') );
863
864             $more->child( tsv => title => loc('TSV'), path => "/Search/Results.tsv$args" );
865             $more->child( csv => title => loc('CSV'), path => "/Search/Results.csv$args" );
866             $more->child( spreadsheet => title => loc('Spreadsheet'), path => "/Search/Results.xls$args" );
867
868             my %rss_data = map {
869                 $_ => $QueryArgs->{$_} || $fallback_query_args{$_} || '' }
870                     qw(Query Order OrderBy);
871             my $RSSQueryString = "?"
872                 . $query_string->( Query   => $rss_data{Query},
873                                    Order   => $rss_data{Order},
874                                    OrderBy => $rss_data{OrderBy}
875                                  );
876             my $RSSPath = join '/', map $m->interp->apply_escapes( $_, 'u' ),
877                 $session{'CurrentUser'}->UserObj->Name,
878                 $session{'CurrentUser'}
879                 ->UserObj->GenerateAuthString(   $rss_data{Query}
880                                                . $rss_data{Order}
881                                                . $rss_data{OrderBy} );
882
883             $more->child( rss => title => loc('RSS'), path => "/NoAuth/rss/$RSSPath/$RSSQueryString");
884             my $ical_path = join '/', map $m->interp->apply_escapes($_, 'u'),
885                 $session{'CurrentUser'}->UserObj->Name,
886                 $session{'CurrentUser'}->UserObj->GenerateAuthString( $rss_data{Query} ),
887                 $rss_data{Query};
888             $more->child( ical => title => loc('iCal'), path => '/NoAuth/iCal/'.$ical_path);
889
890             if ($request_path =~ m{^/Search/Results.html}
891                 &&                        #XXX TODO better abstraction
892                 $session{'CurrentUser'}->HasRight( Right => 'SuperUser', Object => RT->System )) {
893                 my $shred_args = $query_string->(
894                     Search          => 1,
895                     Plugin          => 'Tickets',
896                     'Tickets:query' => $rss_data{'Query'},
897                     'Tickets:limit' => $QueryArgs->{'Rows'},
898                 );
899
900                 $more->child( shredder => title => loc('Shredder'), path => '/Admin/Tools/Shredder/?' . $shred_args);
901             }
902
903         }
904     }
905
906     if ( $request_path =~ m{^/Article/} ) {
907         if ( $DECODED_ARGS->{'id'} && $DECODED_ARGS->{'id'} =~ /^\d+$/ ) {
908             my $id = $DECODED_ARGS->{'id'};
909             my $tabs = PageMenu();
910
911             $tabs->child( display => title => loc('Display'), path => "/Articles/Article/Display.html?id=".$id );
912             $tabs->child( history => title => loc('History'), path => "/Articles/Article/History.html?id=".$id );
913             $tabs->child( modify  => title => loc('Modify'),  path => "/Articles/Article/Edit.html?id=".$id );
914             $tabs->child( delete  => title => loc('Delete'),  path => "/Articles/Article/Delete.html?id=".$id );
915         }
916     }
917
918     if ( $request_path =~ m{^/Articles/} ) {
919         PageWidgets()->child( article_search => raw_html => $m->scomp('/Articles/Elements/GotoArticle') );
920         PageWidgets()->delete('create_ticket');
921         PageWidgets()->delete('simple_search');
922
923         my $tabs = PageMenu();
924         $tabs->child( search => title => loc("Search"),       path => "/Articles/Article/Search.html" );
925         $tabs->child( create => title => loc("New Article" ), path => "/Articles/Article/PreCreate.html" );
926         if ( $request_path =~ m{^/Articles/Article/} and ( $DECODED_ARGS->{'id'} || '' ) =~ /^(\d+)$/ ) {
927             my $id  = $1;
928             my $obj = RT::Article->new( $session{'CurrentUser'} );
929             $obj->Load($id);
930
931             if ( $obj and $obj->id ) {
932                 $tabs->child( display => title => loc("Display"), path => "/Articles/Article/Display.html?id=" . $id );
933                 $tabs->child( history => title => loc('History'), path => '/Articles/Article/History.html?id=' . $id );
934
935                 if ( $obj->CurrentUserHasRight('ModifyArticle') ) {
936                     $tabs->child(modify => title => loc('Modify'), path => '/Articles/Article/Edit.html?id=' . $id );
937                 }
938                 if ( $obj->CurrentUserHasRight('DeleteArticle') ) {
939                     $tabs->child(delete => title => loc('Delete'), path => '/Articles/Article/Delete.html?id=' . $id );
940                 }
941             }
942         }
943
944     }
945
946     if ( $request_path =~ m{^/User/(Summary|History)\.html} ) {
947         if (PageMenu()->child('summary')) {
948             # Already set up from having AdminUser and ShowConfigTab;
949             # but rename "Basics" to "Edit" in this context
950             PageMenu()->child( 'basics' )->title( loc('Edit') );
951         } elsif ( $session{'CurrentUser'}->HasRight( Object => $RT::System, Right => 'ShowUserHistory' ) ) {
952             PageMenu()->child( display => title => loc('Summary'), path => '/User/Summary.html?id=' . $DECODED_ARGS->{'id'} );
953             PageMenu()->child( history => title => loc('History'), path => '/User/History.html?id=' . $DECODED_ARGS->{'id'} );
954         }
955     }
956
957     if ( $request_path =~ /^\/(?:index.html|$)/ ) {
958         PageMenu()->child( edit => title => loc('Edit'), path => '/Prefs/MyRT.html' );
959     }
960
961     $m->callback( CallbackName => 'Privileged', Path => $request_path, Search_Args => $args, Has_Query => $has_query );
962 };
963
964 my $build_selfservice_nav = sub {
965     my $queues = RT::Queues->new( $session{'CurrentUser'} );
966     $queues->UnLimit;
967
968     my $queue_count = 0;
969     my $queue_id;
970
971     while ( my $queue = $queues->Next ) {
972         next unless $queue->CurrentUserHasRight('CreateTicket');
973         $queue_id = $queue->id;
974         $queue_count++;
975         last if ( $queue_count > 1 );
976     }
977
978
979     if ( $queue_count > 1 ) {
980         Menu->child( new => title => loc('New ticket'), path => '/SelfService/CreateTicketInQueue.html' );
981     } elsif ( $queue_id ) {
982         Menu->child( new => title => loc('New ticket'), path => '/SelfService/Create.html?Queue=' . $queue_id );
983     }
984     my $tickets = Menu->child( tickets => title => loc('Tickets'), path => '/SelfService/' );
985     $tickets->child( open   => title => loc('Open tickets'),   path => '/SelfService/' );
986     $tickets->child( closed => title => loc('Closed tickets'), path => '/SelfService/Closed.html' );
987
988
989     my $username = '<span class="current-user">'
990                  . $m->interp->apply_escapes($session{'CurrentUser'}->Name, 'h')
991                  . '</span>';
992     my $about_me = Menu->child( preferences =>
993         title        => loc('Logged in as [_1]', $username),
994         escape_title => 0,
995         sort_order   => 99,
996     );
997
998     if ( $session{'CurrentUser'}->HasRight( Right => 'ModifySelf', Object => RT->System ) ) {
999         $about_me->child( prefs => title => loc('Preferences'), path => '/SelfService/Prefs.html' );
1000     }
1001
1002     if ( $session{'CurrentUser'}->Name
1003          && (   !RT->Config->Get('WebRemoteUserAuth')
1004               || RT->Config->Get('WebFallbackToRTLogin') )) {
1005         $about_me->child( logout => title => loc('Logout'), path => '/NoAuth/Logout.html' );
1006     }
1007
1008     if ($session{'CurrentUser'}->HasRight( Right => 'ShowArticle', Object => RT->System )) {
1009         PageWidgets->child( 'goto-article' => raw_html => $m->scomp('/SelfService/Elements/SearchArticle') );
1010     }
1011
1012     PageWidgets->child( goto => raw_html => $m->scomp('/SelfService/Elements/GotoTicket') );
1013
1014     $m->callback( CallbackName => 'SelfService', Path => $request_path );
1015 };
1016
1017
1018
1019 if ( $request_path !~ m{^/SelfService/} ) {
1020     $build_main_nav->();
1021 } else {
1022     $build_selfservice_nav->();
1023 }
1024
1025
1026
1027
1028 </%INIT>
1029 <%ARGS>
1030 $show_menu => 1
1031 $QueryString => ''
1032 $QueryArgs => {}
1033 </%ARGS>