[Rt-commit] rt branch, master, updated. rt-4.4.1rc1-49-gc321a9f

Shawn Moore shawn at bestpractical.com
Tue Jun 28 15:12:02 EDT 2016


The branch, master has been updated
       via  c321a9f62a081a849285c4f6e9957f819d430403 (commit)
       via  5cce23edbfef62c2f26e9ef0f94b2d1933b37e59 (commit)
       via  c50da430656093028dc14e2a2665d7d31107e641 (commit)
       via  ad11c4dc43b513dd467a0d4a3fda1a4270c22a8e (commit)
       via  16bdea4d95726999249d6b5043863c140e986ca7 (commit)
       via  755042f6a9941734e21a987a638ff03b36b4dc18 (commit)
       via  1cc51e1178342e0b8f1fd192fc26d64018be2091 (commit)
       via  c6ddc87f0a8b0ddd2d5d7ba8dd41f425a40103a2 (commit)
       via  5e4b627423b954a671a2d12726a91f62cad2a2ce (commit)
       via  8621b21ac7062b46fd0684876ae0f1ee63454f80 (commit)
       via  c926d6c848394e6a4e5051db0c7a9a4cc262779f (commit)
       via  b75055288684e704444027d05e3363c5ecddd9d2 (commit)
       via  b9560b6ec037e4b89745a9a77c185e32b52952b5 (commit)
       via  8c6c1319de8d6ba4668c2b5fb3074c5abe939201 (commit)
       via  a32c5813bddccbb8b15bf1debba947766fe595d3 (commit)
       via  86b45ac4e262ecf38ea896b08b938a590741b100 (commit)
       via  5a60a9d8632bd35d783de434e3a15ce3c1941ecc (commit)
       via  5d0a88d47f141f37fdb8bb7c6e3428c122aff423 (commit)
       via  572fa79284eef205beb1be76739a324463983da1 (commit)
       via  d17c2df55b1535b3144f565b35ffb45b01657ebb (commit)
       via  160088fc025dda145bfaa615d31743ca5eaa1f69 (commit)
       via  df888f03c7ab964075789515264f9ce19e28ece5 (commit)
       via  d23a82c9106e9189ecaea7e04443703a5a8351ec (commit)
      from  24e905dee6278832efe8aadbb09cc6c6b2393bd9 (commit)

Summary of changes:
 docs/UPGRADING-4.4                                 |   76 +-
 etc/RT_Config.pm.in                                |   12 +
 etc/initialdata                                    |   15 +-
 lib/RT/Attachments.pm                              |   29 +
 lib/RT/CustomRole.pm                               |    5 +-
 lib/RT/Handle.pm                                   |    9 +
 .../Tabs => lib/RT/Interface/Web/MenuBuilder.pm    | 1841 ++++++++++----------
 lib/RT/Queue.pm                                    |   62 +
 share/html/Elements/JavascriptConfig               |    3 +
 share/html/Elements/ShowHistory                    |   17 +-
 share/html/Elements/Tabs                           | 1138 +-----------
 share/html/Ticket/Elements/AddAttachments          |    8 +-
 share/html/Ticket/Elements/ScrollShowHistory       |    7 +-
 share/html/Ticket/Elements/ShowAssets              |   15 +
 share/html/Ticket/Elements/ShowAttachments         |   11 +-
 share/html/Ticket/Elements/ShowSummary             |    2 +-
 share/po/ar.po                                     | 1298 +++++++-------
 share/po/bg.po                                     | 1298 +++++++-------
 share/po/ca.po                                     | 1298 +++++++-------
 share/po/cs.po                                     | 1298 +++++++-------
 share/po/da.po                                     | 1298 +++++++-------
 share/po/de.po                                     | 1302 +++++++-------
 share/po/el.po                                     | 1304 +++++++-------
 share/po/en.po                                     |    6 +-
 share/po/en_GB.po                                  |  179 +-
 share/po/es.po                                     | 1298 +++++++-------
 share/po/et.po                                     | 1298 +++++++-------
 share/po/eu.po                                     | 1301 +++++++-------
 share/po/fa.po                                     | 1298 +++++++-------
 share/po/fi.po                                     | 1514 ++++++++--------
 share/po/fr.po                                     | 1300 +++++++-------
 share/po/hr.po                                     | 1298 +++++++-------
 share/po/hu.po                                     | 1396 ++++++++-------
 share/po/id.po                                     | 1298 +++++++-------
 share/po/is.po                                     | 1298 +++++++-------
 share/po/it.po                                     | 1298 +++++++-------
 share/po/ja.po                                     | 1300 +++++++-------
 share/po/lt.po                                     | 1790 ++++++++++---------
 share/po/lv.po                                     | 1578 +++++++++--------
 share/po/nb.po                                     | 1298 +++++++-------
 share/po/nl.po                                     | 1298 +++++++-------
 share/po/nn.po                                     | 1298 +++++++-------
 share/po/pl.po                                     | 1298 +++++++-------
 share/po/pt.po                                     | 1298 +++++++-------
 share/po/pt_BR.po                                  | 1298 +++++++-------
 share/po/pt_PT.po                                  | 1298 +++++++-------
 share/po/rt.pot                                    | 1292 +++++++-------
 share/po/ru.po                                     | 1498 ++++++++--------
 share/po/sk.po                                     | 1298 +++++++-------
 share/po/sl.po                                     | 1298 +++++++-------
 share/po/sr.po                                     | 1298 +++++++-------
 share/po/sv.po                                     | 1298 +++++++-------
 share/po/tr.po                                     | 1336 +++++++-------
 share/po/zh_CN.po                                  | 1298 +++++++-------
 share/po/zh_TW.po                                  | 1298 +++++++-------
 share/static/css/base/assets.css                   |   29 +
 56 files changed, 26904 insertions(+), 25921 deletions(-)
 copy share/html/Elements/Tabs => lib/RT/Interface/Web/MenuBuilder.pm (61%)

- Log -----------------------------------------------------------------
commit c321a9f62a081a849285c4f6e9957f819d430403
Merge: 24e905d 5cce23e
Author: Shawn M Moore <shawn at bestpractical.com>
Date:   Tue Jun 28 15:11:25 2016 -0400

    Merge branch '4.4/show-assets-action-menu'

diff --cc lib/RT/Interface/Web/MenuBuilder.pm
index f4ac8a9,d286824..d72e1c6
--- a/lib/RT/Interface/Web/MenuBuilder.pm
+++ b/lib/RT/Interface/Web/MenuBuilder.pm
@@@ -825,138 -389,646 +389,648 @@@ sub BuildMainNav 
          }
      }
  
-     if (
-         (
-                $request_path =~ m{^/(?:Ticket|Search)/}
-             && $request_path !~ m{^/Search/Simple\.html}
-         )
-         || (   $request_path =~ m{^/Search/Simple\.html}
-             && $DECODED_ARGS->{'q'} )
-       )
-     {
-         my $search = Menu()->child('search')->child('tickets');
-         my $args      = '';
-         my $has_query = '';
-         my $current_search = $session{"CurrentSearchHash"} || {};
-         my $search_id = $DECODED_ARGS->{'SavedSearchLoad'} || $DECODED_ARGS->{'SavedSearchId'} || $current_search->{'SearchId'} || '';
-         my $chart_id = $DECODED_ARGS->{'SavedChartSearchId'} || $current_search->{SavedChartSearchId};
- 
-         $has_query = 1 if ( $DECODED_ARGS->{'Query'} or $current_search->{'Query'} );
+     if (
+         (
+                $request_path =~ m{^/(?:Ticket|Search)/}
+             && $request_path !~ m{^/Search/Simple\.html}
+         )
+         || (   $request_path =~ m{^/Search/Simple\.html}
+             && $HTML::Mason::Commands::DECODED_ARGS->{'q'} )
+       )
+     {
+         my $search = $top->child('search')->child('tickets');
+         my $args      = '';
+         my $has_query = '';
+         my $current_search = $HTML::Mason::Commands::session{"CurrentSearchHash"} || {};
+         my $search_id = $HTML::Mason::Commands::DECODED_ARGS->{'SavedSearchLoad'} || $HTML::Mason::Commands::DECODED_ARGS->{'SavedSearchId'} || $current_search->{'SearchId'} || '';
+         my $chart_id = $HTML::Mason::Commands::DECODED_ARGS->{'SavedChartSearchId'} || $current_search->{SavedChartSearchId};
+ 
+         $has_query = 1 if ( $HTML::Mason::Commands::DECODED_ARGS->{'Query'} or $current_search->{'Query'} );
+ 
+         my %query_args;
+         my %fallback_query_args = (
+             SavedSearchId => ( $search_id eq 'new' ) ? undef : $search_id,
+             SavedChartSearchId => $chart_id,
+             (
+                 map {
+                     my $p = $_;
+                     $p => $HTML::Mason::Commands::DECODED_ARGS->{$p} || $current_search->{$p}
+                 } qw(Query Format OrderBy Order Page)
+             ),
+             RowsPerPage => (
+                 defined $HTML::Mason::Commands::DECODED_ARGS->{'RowsPerPage'}
+                 ? $HTML::Mason::Commands::DECODED_ARGS->{'RowsPerPage'}
+                 : $current_search->{'RowsPerPage'}
+             ),
+         );
+ 
+         if ($query_string) {
+             $args = '?' . $query_string;
+         }
+         else {
+             my %final_query_args = ();
+             # key => callback to avoid unnecessary work
+ 
+             for my $param (keys %fallback_query_args) {
+                 $final_query_args{$param} = defined($query_args->{$param})
+                                           ? $query_args->{$param}
+                                           : $fallback_query_args{$param};
+             }
+ 
+             for my $field (qw(Order OrderBy)) {
+                 if ( ref( $final_query_args{$field} ) eq 'ARRAY' ) {
+                     $final_query_args{$field} = join( "|", @{ $final_query_args{$field} } );
+                 } elsif (not defined $final_query_args{$field}) {
+                     delete $final_query_args{$field};
+                 }
+                 else {
+                     $final_query_args{$field} ||= '';
+                 }
+             }
+ 
+             $args = '?' . QueryString(%final_query_args);
+         }
+ 
+         my $current_search_menu;
+         if ( $request_path =~ m{^/Ticket} ) {
+             $current_search_menu = $search->child( current_search => title => loc('Current Search') );
+             $current_search_menu->path("/Search/Results.html$args") if $has_query;
+         } else {
+             $current_search_menu = $page;
+         }
+ 
+         $current_search_menu->child( edit_search =>
+             title => loc('Edit Search'), path => "/Search/Build.html" . ( ($has_query) ? $args : '' ) );
+         $current_search_menu->child( advanced =>
+             title => loc('Advanced'),    path => "/Search/Edit.html$args" );
+         if ($has_query) {
+             $current_search_menu->child( results => title => loc('Show Results'), path => "/Search/Results.html$args" );
+         }
+ 
+         if ( $has_query ) {
+             $current_search_menu->child( bulk  => title => loc('Bulk Update'), path => "/Search/Bulk.html$args" );
+             $current_search_menu->child( chart => title => loc('Chart'),       path => "/Search/Chart.html$args" );
+ 
+             my $more = $current_search_menu->child( more => title => loc('Feeds') );
+ 
+             $more->child( spreadsheet => title => loc('Spreadsheet'), path => "/Search/Results.tsv$args" );
+ 
+             my %rss_data = map {
+                 $_ => $query_args->{$_} || $fallback_query_args{$_} || '' }
+                     qw(Query Order OrderBy);
+             my $RSSQueryString = "?"
+                 . QueryString( Query   => $rss_data{Query},
+                                    Order   => $rss_data{Order},
+                                    OrderBy => $rss_data{OrderBy}
+                                  );
+             my $RSSPath = join '/', map $HTML::Mason::Commands::m->interp->apply_escapes( $_, 'u' ),
+                 $current_user->UserObj->Name,
+                 $current_user
+                 ->UserObj->GenerateAuthString(   $rss_data{Query}
+                                                . $rss_data{Order}
+                                                . $rss_data{OrderBy} );
+ 
+             $more->child( rss => title => loc('RSS'), path => "/NoAuth/rss/$RSSPath/$RSSQueryString");
+             my $ical_path = join '/', map $HTML::Mason::Commands::m->interp->apply_escapes($_, 'u'),
+                 $current_user->UserObj->Name,
+                 $current_user->UserObj->GenerateAuthString( $rss_data{Query} ),
+                 $rss_data{Query};
+             $more->child( ical => title => loc('iCal'), path => '/NoAuth/iCal/'.$ical_path);
+ 
+             if ($request_path =~ m{^/Search/Results.html}
+                 &&                        #XXX TODO better abstraction
+                 $current_user->HasRight( Right => 'SuperUser', Object => RT->System )) {
+                 my $shred_args = QueryString(
+                     Search          => 1,
+                     Plugin          => 'Tickets',
+                     'Tickets:query' => $rss_data{'Query'},
+                     'Tickets:limit' => $query_args->{'Rows'},
+                 );
+ 
+                 $more->child( shredder => title => loc('Shredder'), path => '/Admin/Tools/Shredder/?' . $shred_args);
+             }
+ 
+         }
+     }
+ 
+     if ( $request_path =~ m{^/Article/} ) {
+         if ( $HTML::Mason::Commands::DECODED_ARGS->{'id'} && $HTML::Mason::Commands::DECODED_ARGS->{'id'} =~ /^\d+$/ ) {
+             my $id = $HTML::Mason::Commands::DECODED_ARGS->{'id'};
+             $page->child( display => title => loc('Display'), path => "/Articles/Article/Display.html?id=".$id );
+             $page->child( history => title => loc('History'), path => "/Articles/Article/History.html?id=".$id );
+             $page->child( modify  => title => loc('Modify'),  path => "/Articles/Article/Edit.html?id=".$id );
+         }
+     }
+ 
+     if ( $request_path =~ m{^/Articles/} ) {
+         $widgets->child( article_search => raw_html => $HTML::Mason::Commands::m->scomp('/Articles/Elements/GotoArticle') );
+         $widgets->delete('create_ticket');
+         $widgets->delete('simple_search');
+ 
+         $page->child( search => title => loc("Search"),       path => "/Articles/Article/Search.html" );
+         $page->child( create => title => loc("New Article" ), path => "/Articles/Article/PreCreate.html" );
+         if ( $request_path =~ m{^/Articles/Article/} and ( $HTML::Mason::Commands::DECODED_ARGS->{'id'} || '' ) =~ /^(\d+)$/ ) {
+             my $id  = $1;
+             my $obj = RT::Article->new( $current_user );
+             $obj->Load($id);
+ 
+             if ( $obj and $obj->id ) {
+                 $page->child( display => title => loc("Display"), path => "/Articles/Article/Display.html?id=" . $id );
+                 $page->child( history => title => loc('History'), path => '/Articles/Article/History.html?id=' . $id );
+ 
+                 if ( $obj->CurrentUserHasRight('ModifyArticle') ) {
+                     $page->child(modify => title => loc('Modify'), path => '/Articles/Article/Edit.html?id=' . $id );
+                 }
+             }
+         }
+ 
+     }
+ 
+     if ($request_path =~ m{^/Asset/} and $HTML::Mason::Commands::DECODED_ARGS->{id} and $HTML::Mason::Commands::DECODED_ARGS->{id} !~ /\D/) {
+         _BuildAssetMenu( $request_path, $top, $widgets, $page, %args );
+     } elsif ($request_path =~ m{^/Asset/Search/}) {
+         my %search = map @{$_},
+             grep defined $_->[1] && length $_->[1],
+             map {ref $HTML::Mason::Commands::DECODED_ARGS->{$_} ? [$_, $HTML::Mason::Commands::DECODED_ARGS->{$_}[0]] : [$_, $HTML::Mason::Commands::DECODED_ARGS->{$_}] }
+             grep /^(?:q|SearchAssets|!?(Name|Description|Catalog|Status|Role\..+|CF\..+)|Order(?:By)?|Page)$/,
+             keys %$HTML::Mason::Commands::DECODED_ARGS;
+         if ( $request_path =~ /Bulk/) {
+             $page->child('search',
+                 title => loc('Show Results'),
+                 path => '/Asset/Search/?' . (keys %search ? QueryString(%search) : ''),
+             );
+         } else {
+             $page->child('bulk',
+                 title => loc('Bulk Update'),
+                 path => '/Asset/Search/Bulk.html?' . (keys %search ? QueryString(%search) : ''),
+             );
+         }
+         $page->child('csv',
+             title => loc('Download Spreadsheet'),
+             path  => '/Asset/Search/Results.tsv?' . (keys %search ? QueryString(%search) : ''),
+         );
+     } elsif ($request_path =~ m{^/Admin/Global/CustomFields/Catalog-Assets\.html$}) {
+         $page->child("create", title => loc("Create New"), path => "/Admin/CustomFields/Modify.html?Create=1;LookupType=" . RT::Asset->CustomFieldLookupType);
+     } elsif ($request_path =~ m{^/Admin/CustomFields(/|/index\.html)?$}
+             and $HTML::Mason::Commands::DECODED_ARGS->{'Type'} and $HTML::Mason::Commands::DECODED_ARGS->{'Type'} eq RT::Asset->CustomFieldLookupType) {
+         $page->child("create")->path( $page->child("create")->path . "&LookupType=" . RT::Asset->CustomFieldLookupType );
+     } elsif ($request_path =~ m{^/Admin/Assets/Catalogs/}) {
+         my $actions = $request_path =~ m{/((index|Create)\.html)?$}
+             ? $page
+             : $page->child("catalogs", title => loc("Catalogs"), path => "/Admin/Assets/Catalogs/");
+ 
+         $actions->child("select", title => loc("Select"), path => "/Admin/Assets/Catalogs/");
+         $actions->child("create", title => loc("Create"), path => "/Admin/Assets/Catalogs/Create.html");
+ 
+         my $catalog = RT::Catalog->new( $current_user );
+         $catalog->Load($HTML::Mason::Commands::DECODED_ARGS->{id}) if $HTML::Mason::Commands::DECODED_ARGS->{id};
+ 
+         if ($catalog->id and $catalog->CurrentUserCanSee) {
+             my $query = "id=" . $catalog->id;
+             $page->child("modify", title => loc("Basics"), path => "/Admin/Assets/Catalogs/Modify.html?$query");
+             $page->child("people", title => loc("Roles"),  path => "/Admin/Assets/Catalogs/Roles.html?$query");
+ 
+             $page->child("cfs", title => loc("Asset Custom Fields"), path => "/Admin/Assets/Catalogs/CustomFields.html?$query");
+ 
+             $page->child("group-rights", title => loc("Group Rights"), path => "/Admin/Assets/Catalogs/GroupRights.html?$query");
+             $page->child("user-rights",  title => loc("User Rights"),  path => "/Admin/Assets/Catalogs/UserRights.html?$query");
++
++            $page->child("default-values", title => loc('Default Values'), path => "/Admin/Assets/Catalogs/DefaultValues.html?$query");
+         }
+     }
+ 
+     if ( $request_path =~ m{^/User/(Summary|History)\.html} ) {
+         if ($page->child('summary')) {
+             # Already set up from having AdminUser and ShowConfigTab;
+             # but rename "Basics" to "Edit" in this context
+             $page->child( 'basics' )->title( loc('Edit') );
+         } elsif ( $current_user->HasRight( Object => $RT::System, Right => 'ShowUserHistory' ) ) {
+             $page->child( display => title => loc('Summary'), path => '/User/Summary.html?id=' . $HTML::Mason::Commands::DECODED_ARGS->{'id'} );
+             $page->child( history => title => loc('History'), path => '/User/History.html?id=' . $HTML::Mason::Commands::DECODED_ARGS->{'id'} );
+         }
+     }
+ 
+     if ( $request_path =~ /^\/(?:index.html|$)/ ) {
+         $page->child( edit => title => loc('Edit'), path => '/Prefs/MyRT.html' );
+     }
+ 
+     # due to historical reasons of always having been in /Elements/Tabs
+     $HTML::Mason::Commands::m->callback( CallbackName => 'Privileged', Path => $request_path, CallbackPage => '/Elements/Tabs' );
+ }
+ 
+ sub _BuildAssetMenu {
+     my $request_path = shift;
+     my $top          = shift;
+     my $widgets      = shift;
+     my $page         = shift;
+ 
+     my %args = ( @_ );
+ 
+     my $current_user = $HTML::Mason::Commands::session{CurrentUser};
+ 
+     my $id    = $HTML::Mason::Commands::DECODED_ARGS->{id};
+     my $asset = RT::Asset->new( $current_user );
+     $asset->Load($id);
+ 
+     if ($asset->id) {
+         $page->child("display",     title => HTML::Mason::Commands::loc("Display"),        path => "/Asset/Display.html?id=$id");
+         $page->child("history",     title => HTML::Mason::Commands::loc("History"),        path => "/Asset/History.html?id=$id");
+         $page->child("basics",      title => HTML::Mason::Commands::loc("Basics"),         path => "/Asset/Modify.html?id=$id");
+         $page->child("links",       title => HTML::Mason::Commands::loc("Links"),          path => "/Asset/ModifyLinks.html?id=$id");
+         $page->child("people",      title => HTML::Mason::Commands::loc("People"),         path => "/Asset/ModifyPeople.html?id=$id");
+         $page->child("dates",       title => HTML::Mason::Commands::loc("Dates"),          path => "/Asset/ModifyDates.html?id=$id");
+ 
+         for my $grouping (RT::CustomField->CustomGroupings($asset)) {
+             my $cfs = $asset->CustomFields;
+             $cfs->LimitToGrouping( $asset => $grouping );
+             next unless $cfs->Count;
+             $page->child(
+                 "cf-grouping-$grouping",
+                 title   => HTML::Mason::Commands::loc($grouping),
+                 path    => "/Asset/ModifyCFs.html?id=$id;Grouping=" . $HTML::Mason::Commands::m->interp->apply_escapes($grouping, 'u'),
+             );
+         }
+ 
+         _BuildAssetMenuActionSubmenu( $request_path, $top, $widgets, $page, %args, Asset => $asset );
+     }
+ }
+ 
+ sub _BuildAssetMenuActionSubmenu {
+     my $request_path = shift;
+     my $top          = shift;
+     my $widgets      = shift;
+     my $page         = shift;
+ 
+     my %args = (
+         Asset => undef,
+         @_
+     );
+ 
+     my $asset = $args{Asset};
+     my $id    = $asset->id;
+ 
+     my $actions = $page->child("actions", title => HTML::Mason::Commands::loc("Actions"));
+     $actions->child("create-linked-ticket", title => HTML::Mason::Commands::loc("Create linked ticket"), path => "/Asset/CreateLinkedTicket.html?Asset=$id");
+ 
+     my $status    = $asset->Status;
+     my $lifecycle = $asset->LifecycleObj;
+     for my $action ( $lifecycle->Actions($status) ) {
+         my $next = $action->{'to'};
+         next unless $lifecycle->IsTransition( $status => $next );
+ 
+         my $check = $lifecycle->CheckRight( $status => $next );
+         next unless $asset->CurrentUserHasRight($check);
+ 
+         my $label = $action->{'label'} || ucfirst($next);
+         $actions->child(
+             $label,
+             title   => HTML::Mason::Commands::loc($label),
+             path    => "/Asset/Modify.html?id=$id;Update=1;DisplayAfter=1;Status="
+                         . $HTML::Mason::Commands::m->interp->apply_escapes($next, 'u'),
+ 
+             class       => "asset-lifecycle-action",
+             attributes  => {
+                 'data-current-status'   => $status,
+                 'data-next-status'      => $next,
+             },
+         );
+     }
+ }
+ 
+ sub _BuildAdminMenu {
+     my $request_path = shift;
+     my $top          = shift;
+     my $widgets      = shift;
+     my $page         = shift;
+ 
+     my %args = ( @_ );
+ 
+     my $current_user = $HTML::Mason::Commands::session{CurrentUser};
+ 
+     my $admin = $top->child( admin => title => loc('Admin'), path => '/Admin/' );
+     if ( $current_user->HasRight( Object => RT->System, Right => 'AdminUsers' ) ) {
+         my $users = $admin->child( users =>
+             title       => loc('Users'),
+             description => loc('Manage users and passwords'),
+             path        => '/Admin/Users/',
+         );
+         $users->child( select => title => loc('Select'), path => "/Admin/Users/" );
+         $users->child( create => title => loc('Create'), path => "/Admin/Users/Modify.html?Create=1" );
+     }
+     my $groups = $admin->child( groups =>
+         title       => loc('Groups'),
+         description => loc('Manage groups and group membership'),
+         path        => '/Admin/Groups/',
+     );
+     $groups->child( select => title => loc('Select'), path => "/Admin/Groups/" );
+     $groups->child( create => title => loc('Create'), path => "/Admin/Groups/Modify.html?Create=1" );
+ 
+     my $queues = $admin->child( queues =>
+         title       => loc('Queues'),
+         description => loc('Manage queues and queue-specific properties'),
+         path        => '/Admin/Queues/',
+     );
+     $queues->child( select => title => loc('Select'), path => "/Admin/Queues/" );
+     $queues->child( create => title => loc('Create'), path => "/Admin/Queues/Modify.html?Create=1" );
+ 
+     if ( $current_user->HasRight( Object => RT->System, Right => 'AdminCustomField' ) ) {
+         my $cfs = $admin->child( 'custom-fields' =>
+             title       => loc('Custom Fields'),
+             description => loc('Manage custom fields and custom field values'),
+             path        => '/Admin/CustomFields/',
+         );
+         $cfs->child( select => title => loc('Select'), path => "/Admin/CustomFields/" );
+         $cfs->child( create => title => loc('Create'), path => "/Admin/CustomFields/Modify.html?Create=1" );
+     }
+ 
+     if ( $current_user->HasRight( Object => RT->System, Right => 'AdminCustomRoles' ) ) {
+         my $roles = $admin->child( 'custom-roles' =>
+             title       => loc('Custom Roles'),
+             description => loc('Manage custom roles'),
+             path        => '/Admin/CustomRoles/',
+         );
+         $roles->child( select => title => loc('Select'), path => "/Admin/CustomRoles/" );
+         $roles->child( create => title => loc('Create'), path => "/Admin/CustomRoles/Modify.html?Create=1" );
+     }
+ 
+     if ( $current_user->HasRight( Object => RT->System, Right => 'ModifyScrips' ) ) {
+         my $scrips = $admin->child( 'scrips' =>
+             title       => loc('Scrips'),
+             description => loc('Manage scrips'),
+             path        => '/Admin/Scrips/',
+         );
+         $scrips->child( select => title => loc('Select'), path => "/Admin/Scrips/" );
+         $scrips->child( create => title => loc('Create'), path => "/Admin/Scrips/Create.html" );
+     }
+ 
+     my $admin_global = $admin->child( global =>
+         title       => loc('Global'),
+         description => loc('Manage properties and configuration which apply to all queues'),
+         path        => '/Admin/Global/',
+     );
+ 
+     my $scrips = $admin_global->child( scrips =>
+         title       => loc('Scrips'),
+         description => loc('Modify scrips which apply to all queues'),
+         path        => '/Admin/Global/Scrips.html',
+     );
+     $scrips->child( select => title => loc('Select'), path => "/Admin/Global/Scrips.html" );
+     $scrips->child( create => title => loc('Create'), path => "/Admin/Scrips/Create.html?Global=1" );
+ 
+     my $templates = $admin_global->child( templates =>
+         title       => loc('Templates'),
+         description => loc('Edit system templates'),
+         path        => '/Admin/Global/Templates.html',
+     );
+     $templates->child( select => title => loc('Select'), path => "/Admin/Global/Templates.html" );
+     $templates->child( create => title => loc('Create'), path => "/Admin/Global/Template.html?Create=1" );
+ 
+     my $cfadmin = $admin_global->child( 'custom-fields' =>
+         title       => loc('Custom Fields'),
+         description => loc('Modify global custom fields'),
+         path        => '/Admin/Global/CustomFields/index.html',
+     );
+     $cfadmin->child( users =>
+         title       => loc('Users'),
+         description => loc('Select custom fields for all users'),
+         path        => '/Admin/Global/CustomFields/Users.html',
+     );
+     $cfadmin->child( groups =>
+         title       => loc('Groups'),
+         description => loc('Select custom fields for all user groups'),
+         path        => '/Admin/Global/CustomFields/Groups.html',
+     );
+     $cfadmin->child( queues =>
+         title       => loc('Queues'),
+         description => loc('Select custom fields for all queues'),
+         path        => '/Admin/Global/CustomFields/Queues.html',
+     );
+     $cfadmin->child( tickets =>
+         title       => loc('Tickets'),
+         description => loc('Select custom fields for tickets in all queues'),
+         path        => '/Admin/Global/CustomFields/Queue-Tickets.html',
+     );
+     $cfadmin->child( transactions =>
+         title       => loc('Ticket Transactions'),
+         description => loc('Select custom fields for transactions on tickets in all queues'),
+         path        => '/Admin/Global/CustomFields/Queue-Transactions.html',
+     );
+     $cfadmin->child( 'custom-fields' =>
+         title       => loc('Articles'),
+         description => loc('Select Custom Fields for Articles in all Classes'),
+         path        => '/Admin/Global/CustomFields/Class-Article.html',
+     );
+     $cfadmin->child( 'assets' =>
+         title       => loc('Assets'),
+         description => loc('Select Custom Fields for Assets in all Catalogs'),
+         path        => '/Admin/Global/CustomFields/Catalog-Assets.html',
+     );
+ 
+     my $article_admin = $admin->child( articles => title => loc('Articles'), path => "/Admin/Articles/index.html" );
+     my $class_admin = $article_admin->child(classes => title => loc('Classes'), path => '/Admin/Articles/Classes/' );
+     $class_admin->child( select =>
+         title       => loc('Select'),
+         description => loc('Modify and Create Classes'),
+         path        => '/Admin/Articles/Classes/',
+     );
+     $class_admin->child( create =>
+         title       => loc('Create'),
+         description => loc('Modify and Create Custom Fields for Articles'),
+         path        => '/Admin/Articles/Classes/Modify.html?Create=1',
+     );
+ 
+ 
+     my $cfs = $article_admin->child( 'custom-fields' =>
+         title => loc('Custom Fields'),
+         path  => '/Admin/CustomFields/index.html?'.$HTML::Mason::Commands::m->comp('/Elements/QueryString', Type => 'RT::Class-RT::Article'),
+     );
+     $cfs->child( select =>
+         title => loc('Select'),
+         path => '/Admin/CustomFields/index.html?'.$HTML::Mason::Commands::m->comp('/Elements/QueryString', Type => 'RT::Class-RT::Article'),
+     );
+     $cfs->child( create =>
+         title => loc('Create'),
+         path => '/Admin/CustomFields/Modify.html?'.$HTML::Mason::Commands::m->comp("/Elements/QueryString", Create=>1, LookupType=> "RT::Class-RT::Article" ),
+     );
+ 
+     my $assets_admin = $admin->child( assets => title => loc("Assets"), path => '/Admin/Assets/' );
+     my $catalog_admin = $assets_admin->child( catalogs =>
+         title       => loc("Catalogs"),
+         description => loc("Modify asset catalogs"),
+         path        => "/Admin/Assets/Catalogs/"
+     );
+     $catalog_admin->child( "select", title => loc("Select"), path => $catalog_admin->path );
+     $catalog_admin->child( "create", title => loc("Create"), path => "Create.html" );
+ 
+ 
+     my $assets_cfs = $assets_admin->child( "cfs",
+         title => loc("Custom Fields"),
+         description => loc("Modify asset custom fields"),
+         path => "/Admin/CustomFields/?Type=" . RT::Asset->CustomFieldLookupType
+     );
+     $assets_cfs->child( "select", title => loc("Select"), path => $assets_cfs->path );
+     $assets_cfs->child( "create", title => loc("Create"), path => "/Admin/CustomFields/Modify.html?Create=1&LookupType=" . RT::Asset->CustomFieldLookupType);
+ 
+     $admin_global->child( 'group-rights' =>
+         title       => loc('Group Rights'),
+         description => loc('Modify global group rights'),
+         path        => '/Admin/Global/GroupRights.html',
+     );
+     $admin_global->child( 'user-rights' =>
+         title       => loc('User Rights'),
+         description => loc('Modify global user rights'),
+         path        => '/Admin/Global/UserRights.html',
+     );
+     $admin_global->child( 'my-rt' =>
+         title       => loc('RT at a glance'),
+         description => loc('Modify the default "RT at a glance" view'),
+         path        => '/Admin/Global/MyRT.html',
+     );
+     $admin_global->child( 'dashboards-in-menu' =>
+         title       => loc('Dashboards in menu'),
+         description => loc('Customize dashboards in menu'),
+         path        => '/Admin/Global/DashboardsInMenu.html',
+     );
+     $admin_global->child( 'topics' =>
+         title       => loc('Topics'),
+         description => loc('Modify global article topics'),
+         path        => '/Admin/Global/Topics.html',
+     );
+ 
+     my $admin_tools = $admin->child( tools =>
+         title       => loc('Tools'),
+         description => loc('Use other RT administrative tools'),
+         path        => '/Admin/Tools/',
+     );
+     $admin_tools->child( configuration =>
+         title       => loc('System Configuration'),
+         description => loc('Detailed information about your RT setup'),
+         path        => '/Admin/Tools/Configuration.html',
+     );
+     $admin_tools->child( theme =>
+         title       => loc('Theme'),
+         description => loc('Customize the look of your RT'),
+         path        => '/Admin/Tools/Theme.html',
+     );
+     if (RT->Config->Get('StatementLog')
+         && $current_user->HasRight( Right => 'SuperUser', Object => RT->System )) {
+        $admin_tools->child( 'sql-queries' =>
+            title       => loc('SQL Queries'),
+            description => loc('Browse the SQL queries made in this process'),
+            path        => '/Admin/Tools/Queries.html',
+        );
+     }
+     $admin_tools->child( shredder =>
+         title       => loc('Shredder'),
+         description => loc('Permanently wipeout data from RT'),
+         path        => '/Admin/Tools/Shredder',
+     );
+ 
+     if ( $request_path =~ m{^/Admin/(Queues|Users|Groups|CustomFields|CustomRoles)} ) {
+         my $type = $1;
  
-         my %query_args;
-         my %fallback_query_args = (
-             SavedSearchId => ( $search_id eq 'new' ) ? undef : $search_id,
-             SavedChartSearchId => $chart_id,
-             (
-                 map {
-                     my $p = $_;
-                     $p => $DECODED_ARGS->{$p} || $current_search->{$p}
-                 } qw(Query Format OrderBy Order Page)
-             ),
-             RowsPerPage => (
-                 defined $DECODED_ARGS->{'RowsPerPage'}
-                 ? $DECODED_ARGS->{'RowsPerPage'}
-                 : $current_search->{'RowsPerPage'}
-             ),
+         my %labels = (
+             Queues       => loc("Queues"),
+             Users        => loc("Users"),
+             Groups       => loc("Groups"),
+             CustomFields => loc("Custom Fields"),
+             CustomRoles  => loc("Custom Roles"),
          );
  
-         if ($QueryString) {
-             $args = '?' . $QueryString;
-         }
-         else {
-             my %final_query_args = ();
-             # key => callback to avoid unnecessary work
- 
-             for my $param (keys %fallback_query_args) {
-                 $final_query_args{$param} = defined($QueryArgs->{$param})
-                                           ? $QueryArgs->{$param}
-                                           : $fallback_query_args{$param};
-             }
- 
-             for my $field (qw(Order OrderBy)) {
-                 if ( ref( $final_query_args{$field} ) eq 'ARRAY' ) {
-                     $final_query_args{$field} = join( "|", @{ $final_query_args{$field} } );
-                 } elsif (not defined $final_query_args{$field}) {
-                     delete $final_query_args{$field};
-                 }
-                 else {
-                     $final_query_args{$field} ||= '';
-                 }
-             }
- 
-             $args = '?' . $query_string->(%final_query_args);
-         }
+         my $section;
+         if ( $request_path =~ m|^/Admin/$type/?(?:index.html)?$|
+              || (    $request_path =~ m|^/Admin/$type/(?:Modify.html)$|
+                   && $HTML::Mason::Commands::DECODED_ARGS->{'Create'} )
+            )
+         {
+             $section = $page;
  
-         my $current_search_menu;
-         if ( $request_path =~ m{^/Ticket} ) {
-             $current_search_menu = $search->child( current_search => title => loc('Current Search') );
-             $current_search_menu->path("/Search/Results.html$args") if $has_query;
          } else {
-             $current_search_menu = PageMenu();
+             $section = $page->child( select => title => $labels{$type},
+                                      path => "/Admin/$type/" );
          }
  
-         $current_search_menu->child( edit_search =>
-             title => loc('Edit Search'), path => "/Search/Build.html" . ( ($has_query) ? $args : '' ) );
-         $current_search_menu->child( advanced =>
-             title => loc('Advanced'),    path => "/Search/Edit.html$args" );
-         if ($has_query) {
-             $current_search_menu->child( results => title => loc('Show Results'), path => "/Search/Results.html$args" );
-         }
+         $section->child( select => title => loc('Select'), path => "/Admin/$type/" );
+         $section->child( create => title => loc('Create'), path => "/Admin/$type/Modify.html?Create=1" );
+     }
  
-         if ( $has_query ) {
-             $current_search_menu->child( bulk  => title => loc('Bulk Update'), path => "/Search/Bulk.html$args" );
-             $current_search_menu->child( chart => title => loc('Chart'),       path => "/Search/Chart.html$args" );
+     if ( $request_path =~ m{^/Admin/Queues} ) {
+         if ( $HTML::Mason::Commands::DECODED_ARGS->{'id'} && $HTML::Mason::Commands::DECODED_ARGS->{'id'} =~ /^\d+$/
+                 ||
+               $HTML::Mason::Commands::DECODED_ARGS->{'Queue'} && $HTML::Mason::Commands::DECODED_ARGS->{'Queue'} =~ /^\d+$/
+                 ) {
+             my $id = $HTML::Mason::Commands::DECODED_ARGS->{'Queue'} || $HTML::Mason::Commands::DECODED_ARGS->{'id'};
+             my $queue_obj = RT::Queue->new( $current_user );
+             $queue_obj->Load($id);
  
-             my $more = $current_search_menu->child( more => title => loc('Feeds') );
+             if ( $queue_obj and $queue_obj->id ) {
+                 my $queue = $page;
+                 $queue->child( basics => title => loc('Basics'),   path => "/Admin/Queues/Modify.html?id=" . $id );
+                 $queue->child( people => title => loc('Watchers'), path => "/Admin/Queues/People.html?id=" . $id );
  
-             $more->child( spreadsheet => title => loc('Spreadsheet'), path => "/Search/Results.tsv$args" );
+                 my $templates = $queue->child(templates => title => loc('Templates'), path => "/Admin/Queues/Templates.html?id=" . $id);
+                 $templates->child( select => title => loc('Select'), path => "/Admin/Queues/Templates.html?id=".$id);
+                 $templates->child( create => title => loc('Create'), path => "/Admin/Queues/Template.html?Create=1;Queue=".$id);
  
-             my %rss_data = map {
-                 $_ => $QueryArgs->{$_} || $fallback_query_args{$_} || '' }
-                     qw(Query Order OrderBy);
-             my $RSSQueryString = "?"
-                 . $query_string->( Query   => $rss_data{Query},
-                                    Order   => $rss_data{Order},
-                                    OrderBy => $rss_data{OrderBy}
-                                  );
-             my $RSSPath = join '/', map $m->interp->apply_escapes( $_, 'u' ),
-                 $session{'CurrentUser'}->UserObj->Name,
-                 $session{'CurrentUser'}
-                 ->UserObj->GenerateAuthString(   $rss_data{Query}
-                                                . $rss_data{Order}
-                                                . $rss_data{OrderBy} );
+                 my $scrips = $queue->child( scrips => title => loc('Scrips'), path => "/Admin/Queues/Scrips.html?id=" . $id);
+                 $scrips->child( select => title => loc('Select'), path => "/Admin/Queues/Scrips.html?id=" . $id );
+                 $scrips->child( create => title => loc('Create'), path => "/Admin/Scrips/Create.html?Queue=" . $id);
  
-             $more->child( rss => title => loc('RSS'), path => "/NoAuth/rss/$RSSPath/$RSSQueryString");
-             my $ical_path = join '/', map $m->interp->apply_escapes($_, 'u'),
-                 $session{'CurrentUser'}->UserObj->Name,
-                 $session{'CurrentUser'}->UserObj->GenerateAuthString( $rss_data{Query} ),
-                 $rss_data{Query};
-             $more->child( ical => title => loc('iCal'), path => '/NoAuth/iCal/'.$ical_path);
+                 my $cfs = $queue->child( 'custom-fields' => title => loc('Custom Fields') );
+                 my $ticket_cfs = $cfs->child( 'tickets' => title => loc('Tickets'),
+                     path => '/Admin/Queues/CustomFields.html?SubType=RT::Ticket&id=' . $id );
  
-             if ($request_path =~ m{^/Search/Results.html}
-                 &&                        #XXX TODO better abstraction
-                 $session{'CurrentUser'}->HasRight( Right => 'SuperUser', Object => RT->System )) {
-                 my $shred_args = $query_string->(
-                     Search          => 1,
-                     Plugin          => 'Tickets',
-                     'Tickets:query' => $rss_data{'Query'},
-                     'Tickets:limit' => $QueryArgs->{'Rows'},
-                 );
+                 my $txn_cfs = $cfs->child( 'transactions' => title => loc('Transactions'),
+                     path => '/Admin/Queues/CustomFields.html?SubType=RT::Ticket-RT::Transaction&id='.$id );
  
-                 $more->child( shredder => title => loc('Shredder'), path => '/Admin/Tools/Shredder/?' . $shred_args);
+                 $queue->child( 'group-rights' => title => loc('Group Rights'), path => "/Admin/Queues/GroupRights.html?id=".$id );
+                 $queue->child( 'user-rights' => title => loc('User Rights'), path => "/Admin/Queues/UserRights.html?id=" . $id );
+                 $queue->child( 'history' => title => loc('History'), path => "/Admin/Queues/History.html?id=" . $id );
+                 $queue->child( 'default-values' => title => loc('Default Values'), path => "/Admin/Queues/DefaultValues.html?id=" . $id );
+ 
+                 # due to historical reasons of always having been in /Elements/Tabs
+                 $HTML::Mason::Commands::m->callback( CallbackName => 'PrivilegedQueue', queue_id => $id, page_menu => $queue, CallbackPage => '/Elements/Tabs' );
              }
+         }
+     }
+     if ( $request_path =~ m{^(/Admin/Users|/User/(Summary|History)\.html)} and $admin->child("users") ) {
+         if ( $HTML::Mason::Commands::DECODED_ARGS->{'id'} && $HTML::Mason::Commands::DECODED_ARGS->{'id'} =~ /^\d+$/ ) {
+             my $id = $HTML::Mason::Commands::DECODED_ARGS->{'id'};
+             my $obj = RT::User->new( $current_user );
+             $obj->Load($id);
  
+             if ( $obj and $obj->id ) {
+                 $page->child( basics      => title => loc('Basics'),         path => "/Admin/Users/Modify.html?id=" . $id );
+                 $page->child( memberships => title => loc('Memberships'),    path => "/Admin/Users/Memberships.html?id=" . $id );
+                 $page->child( history     => title => loc('History'),        path => "/Admin/Users/History.html?id=" . $id );
+                 $page->child( 'my-rt'     => title => loc('RT at a glance'), path => "/Admin/Users/MyRT.html?id=" . $id );
+                 $page->child( 'dashboards-in-menu' =>
+                     title => loc('Dashboards in menu'),
+                     path  => '/Admin/Users/DashboardsInMenu.html?id=' . $id,
+                 );
+                 if ( RT->Config->Get('Crypt')->{'Enable'} ) {
+                     $page->child( keys    => title => loc('Private keys'),   path => "/Admin/Users/Keys.html?id=" . $id );
+                 }
+                 $page->child( 'summary'   => title => loc('User Summary'),   path => "/User/Summary.html?id=" . $id );
+             }
          }
+ 
      }
  
-     if ( $request_path =~ m{^/Article/} ) {
-         if ( $DECODED_ARGS->{'id'} && $DECODED_ARGS->{'id'} =~ /^\d+$/ ) {
-             my $id = $DECODED_ARGS->{'id'};
-             my $tabs = PageMenu();
+     if ( $request_path =~ m{^/Admin/Groups} ) {
+         if ( $HTML::Mason::Commands::DECODED_ARGS->{'id'} && $HTML::Mason::Commands::DECODED_ARGS->{'id'} =~ /^\d+$/ ) {
+             my $id = $HTML::Mason::Commands::DECODED_ARGS->{'id'};
+             my $obj = RT::Group->new( $current_user );
+             $obj->Load($id);
  
-             $tabs->child( display => title => loc('Display'), path => "/Articles/Article/Display.html?id=".$id );
-             $tabs->child( history => title => loc('History'), path => "/Articles/Article/History.html?id=".$id );
-             $tabs->child( modify  => title => loc('Modify'),  path => "/Articles/Article/Edit.html?id=".$id );
+             if ( $obj and $obj->id ) {
+                 $page->child( basics         => title => loc('Basics'),       path => "/Admin/Groups/Modify.html?id=" . $obj->id );
+                 $page->child( members        => title => loc('Members'),      path => "/Admin/Groups/Members.html?id=" . $obj->id );
+                 $page->child( memberships    => title => loc('Memberships'),  path => "/Admin/Groups/Memberships.html?id=" . $obj->id );
+                 $page->child( 'group-rights' => title => loc('Group Rights'), path => "/Admin/Groups/GroupRights.html?id=" . $obj->id );
+                 $page->child( 'user-rights'  => title => loc('User Rights'),  path => "/Admin/Groups/UserRights.html?id=" . $obj->id );
+                 $page->child( history        => title => loc('History'),      path => "/Admin/Groups/History.html?id=" . $obj->id );
+             }
          }
      }
  

-----------------------------------------------------------------------


More information about the rt-commit mailing list