diff options
author | Ivan Kohler <ivan@freeside.biz> | 2015-07-09 22:18:55 -0700 |
---|---|---|
committer | Ivan Kohler <ivan@freeside.biz> | 2015-07-09 22:18:55 -0700 |
commit | 1c538bfabc2cd31f27067505f0c3d1a46cba6ef0 (patch) | |
tree | 96922ad4459eda1e649327fd391d60c58d454c53 /rt/share/html/Admin | |
parent | 4f5619288413a185e9933088d9dd8c5afbc55dfa (diff) |
RT 4.2.11, ticket#13852
Diffstat (limited to 'rt/share/html/Admin')
71 files changed, 2068 insertions, 1464 deletions
diff --git a/rt/share/html/Admin/Articles/Classes/Modify.html b/rt/share/html/Admin/Articles/Classes/Modify.html index 7dcc77945..17a9ae7ae 100644 --- a/rt/share/html/Admin/Articles/Classes/Modify.html +++ b/rt/share/html/Admin/Articles/Classes/Modify.html @@ -68,29 +68,60 @@ </tr> <tr> <td> </td> -<td><input type="checkbox" name="Enabled" value="1" <%$EnabledChecked%>> <&|/l&>Enabled (Unchecking this box disables this class)</&></td> +<td> + <input type="checkbox" id="Enabled" name="Enabled" value="1" <%$EnabledChecked%>> + <label for="Enabled"><&|/l&>Enabled (Unchecking this box disables this class)</&></label> +</td> </tr> <tr> <td> </td> -<td><input type="checkbox" name="HotList" value="1" <%$HotListChecked%>> <&|/l&>All Articles in this class should be listed in a dropdown of the ticket reply page</&></td> +<td> + <input type="checkbox" id="HotList" name="HotList" value="1" <%$HotListChecked%>> + <label for="HotList"><&|/l&>All Articles in this class should be listed in a dropdown of the ticket reply page</&></label> +</td> </tr> </table> -<h3>When inserting articles in this class into emails:</h3> +<h3><&|/l&>When inserting articles in this class into emails:</&></h3> <ul> -<li><input type="checkbox" name="Include-Name" value="1" <% $include{Name} %>> Include article name</li> -<li><input type="checkbox" name="Include-Summary" value="1" <% $include{Summary} %>> Include article summary</li> +<li> + <input type="checkbox" id="Include-Name" name="Include-Name" value="1" <% $include{Name} %>> + <label for="Include-Name"><&|/l&>Include article name</&></label> +</li> +<li> + <input type="checkbox" id="Include-Summary" name="Include-Summary" value="1" <% $include{Summary} %>> + <label for="Include-Summary"><&|/l&>Include article summary</&></label> +</li> % if ( $cfs ) { % while (my $cf = $cfs->Next) { -<li>Include custom field '<% $cf->Name %>' +<li><&|/l, $cf->Name &>Include custom field '[_1]'</&> <ul> - <li><input type="checkbox" name="Include-CF-Title-<% $cf->Id %>" <% $include{"CF-Title-".$cf->Id} %> />Title</li> - <li><input type="checkbox" name="Include-CF-Value-<% $cf->Id %>" <% $include{"CF-Value-".$cf->Id} %> />Value</li> + <li> + <input type="checkbox" id="Include-CF-Title-<% $cf->Id %>" name="Include-CF-Title-<% $cf->Id %>" <% $include{"CF-Title-".$cf->Id} %> /> + <label for="Include-CF-Title-<% $cf->Id %>"><&|/l&>Title</&></label> + </li> + <li> + <input type="checkbox" id="Include-CF-Value-<% $cf->Id %>" name="Include-CF-Value-<% $cf->Id %>" <% $include{"CF-Value-".$cf->Id} %> /> + <label for="Include-CF-Value-<% $cf->Id %>"><&|/l&>Value</&></label> + </li> </ul> </li> % } } </ul> +% if ( @$subject_cfs ) { +<h3><&|/l&>Change email subject:</&></h3> +<p><&|/l&>If a Custom Field is selected, the Subject of your outgoing email will be overridden by this article.</&></p> + +<& /Widgets/Form/Select, + Name => 'SubjectOverride', + DefaultLabel => loc('No Subject Override'), + Values => $subject_cfs, + ValuesLabel => $subject_cf_labels, + CurrentValue => $ClassObj->SubjectOverride, +&> +% } + %$m->callback( CallbackName => 'BeforeSubmit', CustomFields => $cfs, ClassObj => $ClassObj ); % if ( $Create ) { @@ -132,8 +163,17 @@ if ($Create) { } if ($ClassObj->Id()) { + + if ($ARGS{SubjectOverride}) { + $ARGS{SubjectOverride} = $m->comp('/Widgets/Form/Select:Process', + Arguments => \%ARGS, + Name => 'SubjectOverride', + DefaultValue => (''), + ); + } + $ARGS{HotList} ||= 0 if $Submitted; - my @attribs= qw(Description Name HotList); + my @attribs= qw(Description Name HotList SubjectOverride); $m->callback( CallbackName => 'AttributeList', Attributes => \@attribs, ARGSRef => \%ARGS ); push @results, UpdateRecordObject( AttributesRef => \@attribs, Object => $ClassObj, @@ -148,11 +188,17 @@ if ((defined $Enabled && $Enabled == 1) or (not defined $Enabled and $Create)) { } my %include = (Name => 1, Summary => 1); +my $subject_cfs = []; +my $subject_cf_labels = {}; my $cfs; if ( $ClassObj->id ) { $cfs = $ClassObj->ArticleCustomFields; - $include{"CF-Title-".$_->Id} = $include{"CF-Value-".$_->Id} = 1 while $_ = $cfs->Next; + while ( my $cf = $cfs->Next ) { + $include{"CF-Title-".$cf->Id} = $include{"CF-Value-".$cf->Id} = 1; + push @$subject_cfs,$cf->Id; + $subject_cf_labels->{$cf->Id} = $cf->Name; + } } if ( $ClassObj->id && $Submitted ) { diff --git a/rt/share/html/Admin/Articles/Classes/Objects.html b/rt/share/html/Admin/Articles/Classes/Objects.html index 62c57256b..37a3617d5 100644 --- a/rt/share/html/Admin/Articles/Classes/Objects.html +++ b/rt/share/html/Admin/Articles/Classes/Objects.html @@ -54,13 +54,13 @@ % if ( $is_global ) { <h2><&|/l&>Applies to all objects</&></h2> -<input type="checkbox" name="RemoveClass-<% $Class->id %>" value="0" /> -<&|/l&>check this box to remove this Class globally and be able to choose specific Queues.</&> +<input type="checkbox" id="RemoveClass-<% $Class->id %>" name="RemoveClass-<% $Class->id %>" value="0" /> +<label for="RemoveClass-<% $Class->id %>"><&|/l&>check this box to remove this Class globally and be able to choose specific Queues.</&></label> % } else { <h2><&|/l&>Apply globally</&></h2> -<input type="checkbox" name="AddClass-<% $Class->id %>" value="0" /> -<&|/l&>check this box to apply this Class globally to all Queues.</&> +<input type="checkbox" id="AddClass-<% $Class->id %>" name="AddClass-<% $Class->id %>" value="0" /> +<label for="AddClass-<% $Class->id %>"><&|/l&>check this box to apply this Class globally to all Queues.</&></label> <h2><&|/l&>Selected Queues</&></h2> <& /Elements/CollectionList, @@ -85,7 +85,7 @@ Order => 'ASC', %ARGS, Collection => $not_applied, - Rows => 50, + Rows => $rows, Format => $format, DisplayFormat => "'__CheckBox.{AddClass-". $Class->id ."}__',". $format, AllowSorting => 1, @@ -143,6 +143,7 @@ $collection_class =~ s/^RT:://; my $format = RT->Config->Get('AdminSearchResultFormat')->{$collection_class} || '__id__,__Name__'; +my $rows = RT->Config->Get('AdminSearchResultRows')->{$collection_class} || 50; my $title = loc('Modify associated objects for [_1]', $Class->Name); diff --git a/rt/share/html/Admin/Articles/Classes/index.html b/rt/share/html/Admin/Articles/Classes/index.html index 97d77c6e7..6158bcbfa 100644 --- a/rt/share/html/Admin/Articles/Classes/index.html +++ b/rt/share/html/Admin/Articles/Classes/index.html @@ -56,6 +56,7 @@ <& /Elements/CollectionList, OrderBy => 'Name', Order => 'ASC', + Rows => $Rows, %ARGS, Format => $Format, Collection => $Classes, @@ -65,7 +66,8 @@ % } <form method="post" action="<% RT->Config->Get('WebPath') %>/Admin/Articles/Classes/index.html"> -<input type="checkbox" name="FindDisabledClasses" value="1" /><&|/l&>Include disabled classes in listing.</&><br /> +<input type="checkbox" id="FindDisabledClasses" name="FindDisabledClasses" value="1" /> +<label for="FindDisabledClasses"><&|/l&>Include disabled classes in listing.</&></label><br /> <div align="right"><input type="submit" value="<&|/l&>Go!</&>" /></div> </form> <%INIT> @@ -83,6 +85,7 @@ if ($FindDisabledClasses) { } $Format ||= RT->Config->Get('AdminSearchResultFormat')->{'Classes'}; +my $Rows = RT->Config->Get('AdminSearchResultRows')->{'Classes'} || 50; </%INIT> <%ARGS> diff --git a/rt/share/html/Admin/Articles/index.html b/rt/share/html/Admin/Articles/index.html index 3aabaa965..b3d6a9a4b 100644 --- a/rt/share/html/Admin/Articles/index.html +++ b/rt/share/html/Admin/Articles/index.html @@ -47,4 +47,4 @@ %# END BPS TAGGED BLOCK }}} <& /Elements/Header, Title => loc('Article Administration') &> <& /Elements/Tabs &> -<& /Elements/ListMenu, menu => Menu()->child('tools')->child('config')->child('articles') &> +<& /Elements/ListMenu, menu => Menu()->child('admin')->child('articles') &> diff --git a/rt/share/html/Admin/CustomFields/GroupRights.html b/rt/share/html/Admin/CustomFields/GroupRights.html index 2e0b5b0ec..96024d7a5 100644 --- a/rt/share/html/Admin/CustomFields/GroupRights.html +++ b/rt/share/html/Admin/CustomFields/GroupRights.html @@ -70,7 +70,7 @@ my @results = ProcessACLs( \%ARGS ); my $title = loc('Modify group rights for custom field [_1]', $CustomFieldObj->Name); # Principal collections -my @principals = GetPrincipalsMap($CustomFieldObj, qw(System Groups)); +my @principals = GetPrincipalsMap($CustomFieldObj, qw(System Roles Groups)); </%INIT> <%ARGS> diff --git a/rt/share/html/Admin/CustomFields/Modify.html b/rt/share/html/Admin/CustomFields/Modify.html index f9ca71c21..ae27c589e 100644 --- a/rt/share/html/Admin/CustomFields/Modify.html +++ b/rt/share/html/Admin/CustomFields/Modify.html @@ -45,7 +45,12 @@ %# those contributions and any derivatives thereof. %# %# END BPS TAGGED BLOCK }}} -<& /Admin/Elements/Header, Title => $title &> +<& /Admin/Elements/Header, + Title => $title, + Focus => (($added_cfv or $ARGS{FocusAddValue}) + ? "input[name=CustomField-$id-Value-new-Name]" + : undef), + &> <& /Elements/Tabs &> <& /Elements/ListActions, actions => \@results &> @@ -125,7 +130,7 @@ <i><&|/l&>Some browsers may only load content from the same domain as your RT server.</&></i> </div></td></tr> -% if ( $CustomFieldObj->Id && $CustomFieldObj->IsSelectionType && !$CustomFieldObj->IsExternalValues ) { +% if ( $CustomFieldObj->Id && $CustomFieldObj->IsSelectionType ) { <tr class="categoriesbasedon"><td class="label"><&|/l&>Categories are based on</&></td><td> <& /Admin/Elements/SelectCustomField, Name => "BasedOn", @@ -150,8 +155,8 @@ <tr><td class="label"> </td><td> <input type="hidden" class="hidden" name="SetEnabled" value="1" /> -<input type="checkbox" class="checkbox" name="Enabled" value="1" <% $EnabledChecked |n%> /> -<&|/l&>Enabled (Unchecking this box disables this custom field)</&> +<input type="checkbox" class="checkbox" id="Enabled" name="Enabled" value="1" <% $EnabledChecked |n %> /> +<label for="Enabled"><&|/l&>Enabled (Unchecking this box disables this custom field)</&></label> </td></tr> % $m->callback(CallbackName => 'EndOfTable', CustomField => $CustomFieldObj, CFvalidations => \@CFvalidations); @@ -170,7 +175,7 @@ </form> <%INIT> -my ($title, @results); +my ($title, @results, $added_cfv); my $CustomFieldObj = RT::CustomField->new( $session{'CurrentUser'} ); @@ -191,7 +196,7 @@ else { LinkValueTo => $LinkValueTo, IncludeContentForValue => $IncludeContentForValue, BasedOn => $BasedOn, - Disabled => !$Enabled, + Disabled => ($Enabled ? 0 : 1), NoClone => !$YesClone, ); if (!$val) { @@ -306,6 +311,7 @@ if ( $ARGS{'Update'} && $id ne 'new' ) { $_ => $ARGS{ $paramtag ."-new-$_" } } qw/ Name Description SortOrder Category/ ); push (@results, $msg); + $added_cfv = 1 if $id; my $cfv = RT::CustomFieldValue->new( $session{CurrentUser} ); $cfv->Load($id); @@ -314,12 +320,27 @@ CustomFieldObj => $CustomFieldObj, CustomFieldValueObj => $cfv, ARGSRef => \%ARG } } +if ( $CustomFieldObj->id && $CustomFieldObj->IsOnlyGlobal ) { + my ( $ret, $msg ); + my $object = $CustomFieldObj->RecordClassFromLookupType->new( $session{'CurrentUser'} ); + + if ( $CustomFieldObj->Disabled && $CustomFieldObj->IsGlobal ) { + ( $ret, $msg ) = $CustomFieldObj->RemoveFromObject($object); + } + elsif ( !$CustomFieldObj->Disabled && !$CustomFieldObj->IsGlobal ) { + ( $ret, $msg ) = $CustomFieldObj->AddToObject($object); + } + + # successful msg("object created" or "object deleted ) is useless here + push @results, $msg unless $ret; +} + $id = $CustomFieldObj->id if $CustomFieldObj->id; # This code does automatic redirection if any updates happen. MaybeRedirectForResults( Actions => \@results, - Arguments => { id => $id }, + Arguments => { id => $id, FocusAddValue => ($added_cfv ? 1 : 0) }, ) if $CustomFieldObj->id; diff --git a/rt/share/html/Admin/CustomFields/Objects.html b/rt/share/html/Admin/CustomFields/Objects.html index aac209461..2e0a3dc83 100644 --- a/rt/share/html/Admin/CustomFields/Objects.html +++ b/rt/share/html/Admin/CustomFields/Objects.html @@ -53,23 +53,23 @@ <form action="Objects.html" method="post"> <input type="hidden" class="hidden" name="id" value="<% $id %>" /> -% if ( $is_global ) { +% if ( $CF->IsGlobal ) { <h2><&|/l&>Applies to all objects</&></h2> -<input type="checkbox" name="RemoveCustomField-<% $CF->id %>" value="0" /> -<&|/l&>check this box to remove this Custom Field from all objects and be able to choose specific objects.</&> +<input type="checkbox" id="RemoveCustomField-<% $CF->id %>" name="RemoveCustomField-<% $CF->id %>" value="0" /> +<label for="RemoveCustomField-<% $CF->id %>"><&|/l&>check this box to remove this Custom Field from all objects and be able to choose specific objects.</&></label> % } else { <h2><&|/l&>Apply globally</&></h2> -<input type="checkbox" name="AddCustomField-<% $CF->id %>" value="0" /> -<&|/l&>check this box to apply this Custom Field to all objects.</&> +<input type="checkbox" id="AddCustomField-<% $CF->id %>" name="AddCustomField-<% $CF->id %>" value="0" /> +<label for="AddCustomField-<% $CF->id %>"><&|/l&>check this box to apply this Custom Field to all objects.</&></label> -% unless ( $CF->ApplyGlobally ) { +% unless ( $CF->IsOnlyGlobal ) { <h2><&|/l&>Selected objects</&></h2> <& /Elements/CollectionList, OrderBy => 'id', Order => 'ASC', %ARGS, - Collection => $applied, + Collection => $added, Rows => 0, Page => 1, Format => $format, @@ -86,8 +86,8 @@ OrderBy => 'id', Order => 'ASC', %ARGS, - Collection => $not_applied, - Rows => 50, + Collection => $not_added, + Rows => $rows, Format => $format, DisplayFormat => "'__CheckBox.{AddCustomField-". $CF->id ."}__',". $format, AllowSorting => 1, @@ -141,16 +141,15 @@ if ( $UpdateObjs ) { } } -my $is_global = $CF->IsApplied(0); +my $added = $CF->AddedTo; +my $not_added = $CF->NotAddedTo; -my $applied = $CF->AppliedTo; -my $not_applied = $CF->NotAppliedTo; - -my $collection_class = ref($applied); +my $collection_class = ref($added); $collection_class =~ s/^RT:://; my $format = RT->Config->Get('AdminSearchResultFormat')->{$collection_class} || '__id__,__Name__'; +my $rows = RT->Config->Get('AdminSearchResultRows')->{$collection_class} || 50; my $title = loc('Modify associated objects for [_1]', $CF->Name); diff --git a/rt/share/html/Admin/CustomFields/index.html b/rt/share/html/Admin/CustomFields/index.html index e8687ed21..cd9884f15 100644 --- a/rt/share/html/Admin/CustomFields/index.html +++ b/rt/share/html/Admin/CustomFields/index.html @@ -49,24 +49,7 @@ <& /Elements/Tabs &> % my $tmp = RT::CustomField->new( $session{'CurrentUser'} ); -% if ( $Type ) { -<h2><% loc("Custom Fields for [_1]", $tmp->FriendlyLookupType( $Type )) %></h2> -% } - -<& /Elements/CollectionList, - OrderBy => 'LookupType|Name', - Order => 'ASC|ASC', - Rows => 50, - %ARGS, - Collection => $CustomFields, - Format => $Format, - DisplayFormat => ($Type? '' : '__FriendlyLookupType__,'). $Format, - AllowSorting => 1, - PassArguments => [ - qw(Format Rows Page Order OrderBy), - qw(Type ShowDisabled) - ], -&> +<h1><% $Type ? loc("Custom Fields for [_1]", $Type) : loc('All Custom Fields') %></h1> <form action="<%RT->Config->Get('WebPath')%>/Admin/CustomFields/index.html" method="get"> <&|/l&>Only show custom fields for:</&> @@ -77,15 +60,30 @@ % } </select> <br /> -<input type="checkbox" class="checkbox" name="ShowDisabled" value="1" <% $ShowDisabled && 'checked="checked"' |n%> /> -<&|/l&>Include disabled custom fields in listing.</&> +<input type="checkbox" class="checkbox" id="ShowDisabled" name="ShowDisabled" value="1" <% $ShowDisabled && 'checked="checked"' |n %> /> +<label for="ShowDisabled"><&|/l&>Include disabled custom fields in listing.</&></label> <br /> % $m->callback(CallbackName => 'BeforeSubmit'); -<input type="submit" value="<% loc('Go!') %>" /> +<div align="right"><input type="submit" value="<% loc('Go!') %>" /></div> </form> +<& /Elements/CollectionList, + OrderBy => 'LookupType|Name', + Order => 'ASC|ASC', + Rows => $Rows, + %ARGS, + Collection => $CustomFields, + Format => $Format, + DisplayFormat => ($Type? '' : '__FriendlyLookupType__,'). $Format, + AllowSorting => 1, + PassArguments => [ + qw(Format Rows Page Order OrderBy), + qw(Type ShowDisabled) + ], +&> + <%args> $Type => '' $ShowDisabled => 0 @@ -95,12 +93,6 @@ $Format => undef <%INIT> my $title = loc('Select a Custom Field'); -$Type ||= $ARGS{'type'} || ''; -if ( !$Type && $ARGS{'type'} ) { - $Type ||= $ARGS{'type'}; - $RT::Logger->warning("'type' argument is deprecated use 'Type' instead"); -} - my $CustomFields = RT::CustomFields->new($session{'CurrentUser'}); $CustomFields->UnLimit; $CustomFields->FindAllRows if $ShowDisabled; @@ -109,5 +101,6 @@ $CustomFields->LimitToLookupType( $Type ) if $Type; $m->callback(CallbackName => 'MassageCustomFields', CustomFields => $CustomFields); $Format ||= RT->Config->Get('AdminSearchResultFormat')->{'CustomFields'}; +my $Rows = RT->Config->Get('AdminSearchResultRows')->{'CustomFields'} || 50; </%INIT> diff --git a/rt/share/html/Admin/Global/Scrip.html b/rt/share/html/Admin/Elements/ConfigureDashboardsInMenu index 057032a44..2b16af575 100755..100644 --- a/rt/share/html/Admin/Global/Scrip.html +++ b/rt/share/html/Admin/Elements/ConfigureDashboardsInMenu @@ -45,19 +45,32 @@ %# those contributions and any derivatives thereof. %# %# END BPS TAGGED BLOCK }}} -<& /Admin/Elements/Header, Title => $title &> -<& /Elements/Tabs &> -<& /Elements/ListActions, actions => \@results &> -<& /Admin/Elements/EditScrip, title => $title, %ARGS, id => $id &> - +<%args> +$Action +$OnSave +$items +$panes +$current_portlets +$ReadOnly => 0 +</%args> <%init> -my ($id, @results) = $m->comp( '/Admin/Elements/EditScrip:Process', %ARGS ); - -my ($title); -if ( $id ) { - $title = loc("Modify a scrip that applies to all queues"); -} -else { - $title = loc("Add a scrip which will apply to all queues"); +my $portlets = $current_portlets; +my @panes; +for my $pane (@$panes) { + push @panes, $m->comp( + '/Widgets/SelectionBox:new', + Action => $Action, + Name => $pane, + Available => $items, + AutoSave => 1, + ReadOnly => $ReadOnly, + OnSubmit => sub { + my $sel = shift; + $OnSave->( { dashboards => $sel->{Current} } ); + }, + Selected => $portlets, + ); } + +return @panes; </%init> diff --git a/rt/share/html/Admin/Elements/EditCustomField b/rt/share/html/Admin/Elements/EditCustomField index d58bed5c7..500e91191 100755 --- a/rt/share/html/Admin/Elements/EditCustomField +++ b/rt/share/html/Admin/Elements/EditCustomField @@ -71,7 +71,8 @@ <tr><td> </td><td> <input type="hidden" class="hidden" name="SetEnabled" value="1" /> -<input type="checkbox" class="checkbox" name="Enabled" value="1" <%$EnabledChecked%> /> <&|/l&>Enabled (Unchecking this box disables this custom field)</&> +<input type="checkbox" class="checkbox" id="Enabled" name="Enabled" value="1" <%$EnabledChecked%> /> +<label for="Enabled"><&|/l&>Enabled (Unchecking this box disables this custom field)</&></label> </td></tr> </table> @@ -100,19 +101,19 @@ if (! $CustomField ) { } else { if ($CustomField eq 'new') { - my ($val, $msg) = $CustomFieldObj->Create(Queue => $Queue, - Name => $Name, + my ($val, $msg) = $CustomFieldObj->Create(Queue => $Queue, + Name => $Name, Type => $Type, Description => $Description, - ); - + ); + # if there is an error, then abort. But since at this point there's # stuff already printed, clear it out. # (This only works in conjunction with temporarily turning autoflush # off in the files that use this component.) unless ($val) { - $m->clear_buffer; - Abort(loc("Could not create CustomField: [_1]", $msg), SuppressHeader => 1); + $m->clear_buffer; + Abort(loc("Could not create CustomField: [_1]", $msg), SuppressHeader => 1); } push @results, $msg; $CustomFieldObj->SetSortOrder($CustomFieldObj->id); diff --git a/rt/share/html/Admin/Elements/EditCustomFieldValuesSource b/rt/share/html/Admin/Elements/EditCustomFieldValuesSource index 79029cae1..2198e4cf4 100644 --- a/rt/share/html/Admin/Elements/EditCustomFieldValuesSource +++ b/rt/share/html/Admin/Elements/EditCustomFieldValuesSource @@ -60,9 +60,7 @@ my @sources; foreach my $class( 'RT::CustomFieldValues', RT->Config->Get('CustomFieldValuesSources') ) { next unless $class; - local $@; - eval "require $class"; - if( $@ ) { + unless ($class->require) { $RT::Logger->crit("Couldn't load class '$class': $@"); next; } diff --git a/rt/share/html/Admin/Elements/EditCustomFields b/rt/share/html/Admin/Elements/EditCustomFields index 904a82c97..5ad1ec58d 100755 --- a/rt/share/html/Admin/Elements/EditCustomFields +++ b/rt/share/html/Admin/Elements/EditCustomFields @@ -55,7 +55,7 @@ <h2><&|/l&>Selected Custom Fields</&></h2> <& /Elements/CollectionList, %ARGS, - Collection => $applied_cfs, + Collection => $added_cfs, Rows => 0, Page => 1, Format => $format, @@ -73,8 +73,8 @@ OrderBy => 'Name', Order => 'ASC', %ARGS, - Collection => $not_applied_cfs, - Rows => 50, + Collection => $not_added_cfs, + Rows => $rows, Format => $format, DisplayFormat => "'__CheckBox.{AddCustomField}__',". $format, AllowSorting => 1, @@ -152,17 +152,18 @@ if ( $UpdateCFs ) { $m->callback(CallbackName => 'UpdateExtraFields', Results => \@results, Object => $Object, %ARGS); -my $applied_cfs = RT::CustomFields->new( $session{'CurrentUser'} ); -$applied_cfs->LimitToLookupType($lookup); -$applied_cfs->LimitToGlobalOrObjectId($id); -$applied_cfs->SetContextObject( $Object ); -$applied_cfs->ApplySortOrder; +my $added_cfs = RT::CustomFields->new( $session{'CurrentUser'} ); +$added_cfs->LimitToLookupType($lookup); +$added_cfs->LimitToGlobalOrObjectId($id); +$added_cfs->SetContextObject( $Object ); +$added_cfs->ApplySortOrder; -my $not_applied_cfs = RT::CustomFields->new( $session{'CurrentUser'} ); -$not_applied_cfs->LimitToLookupType($lookup); -$not_applied_cfs->LimitToNotApplied( $id ? ($id, 0) : (0) ); +my $not_added_cfs = RT::CustomFields->new( $session{'CurrentUser'} ); +$not_added_cfs->LimitToLookupType($lookup); +$not_added_cfs->LimitToNotAdded( $id ? ($id, 0) : (0) ); my $format = RT->Config->Get('AdminSearchResultFormat')->{'CustomFields'}; +my $rows = RT->Config->Get('AdminSearchResultRows')->{'CustomFields'} || 50; my $display_format = $id ? ("'__RemoveCheckBox.{$id}__',". $format .", '__MoveCF.{$id}__'") diff --git a/rt/share/html/Admin/Elements/EditQueueWatchers b/rt/share/html/Admin/Elements/EditQueueWatchers index 98c13931a..c4c1a6f4a 100755 --- a/rt/share/html/Admin/Elements/EditQueueWatchers +++ b/rt/share/html/Admin/Elements/EditQueueWatchers @@ -52,13 +52,12 @@ <ul> % while (my $watcher=$Members->Next) { <li> -<input type="checkbox" class="checkbox" name="Queue-<%$QueueObj->Id%>-DeleteWatcher-Type-<%$Watchers->Type%>-Principal-<%$watcher->MemberId%>" value="1" +<input type="checkbox" class="checkbox" name="Queue-<%$QueueObj->Id%>-DeleteWatcher-Type-<%$Watchers->Name%>-Principal-<%$watcher->MemberId%>" value="1" unchecked /> % if ($watcher->MemberObj->IsUser) { -<a href="<%RT->Config->Get('WebPath')%>/Admin/Users/Modify.html?id=<%$watcher->MemberObj->ObjectId%>"> -<& /Elements/ShowUser, User => $watcher->MemberObj->Object &></a> +<& /Elements/ShowUser, User => $watcher->MemberObj->Object &> % } else { -<a href="<%RT->Config->Get('WebPath')%>/Admin/Groups/Modify.html?id=<%$watcher->MemberObj->ObjectId%>"> +<a href="<%RT->Config->Get('WebPath')%>/Admin/Groups/Modify.html?id=<%$watcher->MemberObj->Id%>"> <%$watcher->MemberObj->Object->Name%></a> % } % } diff --git a/rt/share/html/Admin/Elements/EditRights b/rt/share/html/Admin/Elements/EditRights index ff8aece17..bd861310f 100644 --- a/rt/share/html/Admin/Elements/EditRights +++ b/rt/share/html/Admin/Elements/EditRights @@ -51,8 +51,6 @@ $Principals $AddPrincipal => undef </%args> <%init> -use Scalar::Util qw(blessed); - # Let callbacks get at principals and context before we do anything with them $m->callback( Principals => $Principals, Context => $Context ); @@ -94,22 +92,23 @@ if ($anchor =~ /AddPrincipal/) { sync_anchor(<% $anchor |n,j %>); jQuery(".rights-editor").tabs({ - select: function(ev, ui) { - sync_anchor(ui.tab.hash); - if ( jQuery(ui.tab).find('input[type=text]').size() > 0 ) { - jQuery(ui.tab).find('input[type=text]:first').focus(); + beforeActivate: function(ev, ui) { + sync_anchor(ui.newPanel.selector); + if ( ui.newTab.find('input[type=text]').size() > 0 ) { + ui.newTab.find('input[type=text]:first').focus(); } } }); jQuery(".rights-editor .category-tabs").tabs({ - cookie: { name: "rights-category-tab" /* saves current tab in cookie */ }, - show: function(ev, ui) { + active: jQuery.cookie('rights-category-tab') || 0, + activate: function(ev, ui) { + jQuery.cookie('rights-category-tab', ui.newTab.index()); jQuery(".rights-editor .category-tabs").not(this).each(function() { var item = jQuery(this); - var selected = item.tabs("option", "selected") || 0; - if (selected != ui.index) - item.tabs("select", ui.index); + var selected = item.tabs("option", "active") || 0; + if (selected != ui.newTab.index()) + item.tabs("option", "active", ui.newTab.index()); }); } }); @@ -140,21 +139,23 @@ for my $category (@$Principals) { <li class="addprincipal"> <a href="#acl-AddPrincipal"> <input type="text" value="" + data-autocomplete="<% lc $AddPrincipal eq 'user' ? 'Users' : 'Groups' %>" +% if ( lc $AddPrincipal eq 'user' ) { + data-autocomplete-return="Name" + data-autocomplete-privileged="1" +% } name="AddPrincipalForRights-<% lc $AddPrincipal %>" id="AddPrincipalForRights-<% lc $AddPrincipal %>" /> <script type="text/javascript"> jQuery(function() { jQuery("#AddPrincipalForRights-"+<% lc $AddPrincipal |n,j%>).keyup(function(){ toggle_addprincipal_validity(this, true); + }).keydown(function(event){ + event.stopPropagation() // Disable tabs keyboard nav }); -% if (lc $AddPrincipal eq 'group') { - jQuery("#AddPrincipalForRights-"+<% lc $AddPrincipal |n,j%>).autocomplete({ - source: <% RT->Config->Get('WebPath') |n,j%>+"/Helpers/Autocomplete/Groups", - select: addprincipal_onselect, - change: addprincipal_onchange - }); -% } + jQuery("#AddPrincipalForRights-"+<% lc $AddPrincipal |n,j%>).on("autocompleteselect", addprincipal_onselect); + jQuery("#AddPrincipalForRights-"+<% lc $AddPrincipal |n,j%>).on("autocompletechange", addprincipal_onchange); }); </script> % my $type = lc $AddPrincipal eq 'user' ? loc('username') : loc($AddPrincipal); @@ -180,7 +181,7 @@ for my $category (@$Principals) { if ($obj->isa('RT::Group') and $obj->Domain eq 'UserDefined') { my $subgroups = $obj->GroupMembersObj( Recursively => 1 ); $subgroups->LimitToUserDefinedGroups; - $subgroups->Limit( FIELD => 'Name', OPERATOR => '!=', VALUE => $obj->Name ); + $subgroups->Limit( FIELD => 'Name', OPERATOR => '!=', VALUE => $obj->Name, CASESENSITIVE => 0 ); if ( $subgroups->Count ) { my $inc = join ", ", map $_->Name, @{$subgroups->ItemsArrayRef}; diff --git a/rt/share/html/Admin/Elements/EditRightsCategoryTabs b/rt/share/html/Admin/Elements/EditRightsCategoryTabs index b6eb18900..6174e68d7 100644 --- a/rt/share/html/Admin/Elements/EditRightsCategoryTabs +++ b/rt/share/html/Admin/Elements/EditRightsCategoryTabs @@ -52,15 +52,10 @@ $id $acldesc => '' </%args> <%init> -# XXX OPTIMIZATION: Moving the calls to AvailableRights and RightCategories up -# one component to avoid calling them for every principal would be a win, but -# it's cleaner to do it here. The values can really be computed once per -# $Context. - # Find all our available rights... my (%available_rights, %categories); if ( blessed($Context) and $Context->can('AvailableRights') ) { - %available_rights = %{$Context->AvailableRights}; + %available_rights = %{$Context->AvailableRights( $Principal ? $Principal->PrincipalObj : undef )}; } else { %available_rights = ( loc('System Error') => loc("No rights found") ); } @@ -104,6 +99,8 @@ for my $category ( sort keys %categories ) { $acldesc ||= join '-', ($Principal ? $Principal->PrincipalId : 'addprincipal'), ref($Context), $Context->Id; + +$available_rights{$_} = loc( $available_rights{$_} ) for keys %available_rights; </%init> <div class="category-tabs"> <ul> @@ -121,10 +118,10 @@ $acldesc ||= join '-', ($Principal ? $Principal->PrincipalId : 'addprincipal'), id="SetRights-<% $acldesc %>-<% $right %>" value="<% $right %>" <% $current_rights{$right} ? 'checked' : '' %> /> - <label for="SetRights-<% $acldesc %>-<% $right %>" title="<% loc($right) %>"> - <% loc($available_rights{$right}) %> + <label for="SetRights-<% $acldesc %>-<% $right %>" title="<% $right %>"> + <% $available_rights{$right} %> <span class="separator">—</span> - <span class="rightname"><% loc($right) %></span> + <span class="rightname"><% $right %></span> </label> </li> % } diff --git a/rt/share/html/Admin/Elements/EditScrips b/rt/share/html/Admin/Elements/EditScrips index 127677d79..759470719 100755 --- a/rt/share/html/Admin/Elements/EditScrips +++ b/rt/share/html/Admin/Elements/EditScrips @@ -50,86 +50,151 @@ <form action="Scrips.html" method="post"> <input type="hidden" class="hidden" name="id" value="<% $id %>" /> -<h2><&|/l&>Current Scrips</&></h2> +<h2><&|/l&>Scrips</&></h2> +<div class="admin-hint"><&|/l&>Scrips normally run after each individual change to a ticket.</&></div> +% my $scrips = $find_scrips->(Stage => 'TransactionCreate'); +<& /Elements/CollectionList, %common_applied_args, Collection => $scrips &> +% unless ( $scrips->Count ) { +<p><i><&|/l&>(No scrips)</&></i></p> +% } + +<h2><&|/l&>Batch scrips</&></h2> +<div class="admin-hint"><&|/l&>Batch scrips run after a set of related changes to a ticket.</&></div> +% $scrips = $find_scrips->(Stage => 'TransactionBatch'); +<& /Elements/CollectionList, %common_applied_args, Collection => $scrips &> +% unless ( $scrips->Count ) { +<p><i><&|/l&>(No scrips)</&></i></p> +% } + +<& /Elements/Submit, + Name => 'RemoveScrips', + Caption => loc("Un-apply selected scrips"), + Label => loc("Update"), +&> + +<h2><&|/l&>Not applied scrips</&></h2> +% $scrips = $find_scrips->(Added => 0); <& /Elements/CollectionList, - OrderBy => 'Description', - Order => 'ASC', - Rows => 100, + Rows => $Rows, + Page => 1, %ARGS, - Format => $Format, - DisplayFormat => "__CheckBox.{DeleteScrip}__, $Format", - Collection => $Scrips, + Collection => $scrips, + Format => $Format, + DisplayFormat => "__CheckBox.{AddScrip}__, $Format", AllowSorting => 1, - PassArguments => [ qw(Query Format Rows Page Order OrderBy id) ], + PassArguments => [ qw(Format Rows Page Order OrderBy id) ], &> - -% if ( $Scrips->Count ) { -<p><i><&|/l&>(Check box to delete)</&></i></p> -% } else { +% unless ( $scrips->Count ) { <p><i><&|/l&>(No scrips)</&></i></p> % } + +<& SelectStageForAdded &> + <& /Elements/Submit, - Caption => loc("Delete selected scrips"), - Label => loc("Delete") + Name => 'AddScrips', + Caption => loc("Apply selected scrips"), + Label => loc("Update"), &> + </form> <%init> my (@actions); -my $Scrips = RT::Scrips->new($session{'CurrentUser'}); - -my $QueueObj = RT::Queue->new($session{'CurrentUser'}); if ( $id ) { + my $QueueObj = RT::Queue->new($session{'CurrentUser'}); $QueueObj->Load( $id ); - unless ( $QueueObj->id ) { - push @actions, loc("Couldn't load queue #[_1]", $id) + Abort(loc("Couldn't load queue #[_1]", $id)) unless $QueueObj->id; +} +$id ||= 0; + +my $find_scrips = sub { + my %args = (Added => 1, @_); + my $scrips = RT::Scrips->new($session{'CurrentUser'}); + $scrips->LimitByStage( $args{'Stage'} ) + if $args{'Stage'}; + my $method = $args{'Added'}? 'LimitToAdded' : 'LimitToNotAdded'; + $scrips->$method(0, $id); + $scrips->ApplySortOrder if $args{'Added'}; + $scrips->FindAllRows; + return $scrips; +}; + +$Format ||= RT->Config->Get('AdminSearchResultFormat')->{'Scrips'}; +my $Rows = RT->Config->Get('AdminSearchResultRows')->{'Scrips'} || 50; +my $DisplayFormat = $Format; +if ( $id ) { + $DisplayFormat = "__RemoveCheckBox__, $DisplayFormat"; +} else { + $DisplayFormat = "__CheckBox.{RemoveScrip}__, $DisplayFormat"; +} +$DisplayFormat .= ", __Move.{$id}__"; + +my %common_applied_args = ( + %ARGS, + Format => $Format, + DisplayFormat => $DisplayFormat, + Rows => 0, + Page => 1, + AllowSorting => 0, + PassArguments => [ qw(Format id) ], +); + +if ( $RemoveScrips ) { + foreach my $sid ( @RemoveScrip ) { + my $scrip = RT::Scrip->new( $session{'CurrentUser'} ); + $scrip->Load( $sid ); + next unless $scrip->id; + + my ($status, $msg) = $scrip->RemoveFromObject( $id ); + push @actions, $msg; } } -if ($QueueObj->id) { - $Scrips->LimitToQueue($id); - $Format ||= RT->Config->Get('AdminSearchResultFormat')->{'Scrips'}; +if ( $AddScrips ) { + foreach my $sid ( @AddScrip ) { + my $scrip = RT::Scrip->new( $session{'CurrentUser'} ); + $scrip->Load( $sid ); + next unless $scrip->id; + + my ($status, $msg) = $scrip->AddToObject( $id, Stage => $Stage ); + push @actions, $msg; + } } -else { - $Scrips->LimitToGlobal(); - $Format ||= RT->Config->Get('AdminSearchResultFormat')->{'GlobalScrips'}; + +if ( $MoveScripUp ) { + my $scrip = RT::ObjectScrip->new( $session{'CurrentUser'} ); + $scrip->LoadByCols( Scrip => $MoveScripUp, ObjectId => $id ); + if ( $scrip->id ) { + my ($status, $msg) = $scrip->MoveUp; + push @actions, $msg; + } } -# deal with modifying and deleting existing scrips -# we still support DeleteScrip-id format but array is preferred - -my @not_deleted; -foreach my $id ( grep $_, @DeleteScrip, map /^DeleteScrip-(\d+)/, keys %ARGS ) { - my $scrip = RT::Scrip->new($session{'CurrentUser'}); - $scrip->Load( $id ); - my $a = $scrip->FirstAttribute('Immutable'); - if ( defined($a) and $a->Content ) { - # then disable the scrip instead of deleting it - my ($retval, $msg) = $scrip->SetStage('Disabled'); - if ( $retval ) { - push @actions, loc("Scrip disabled (cannot delete system scrips)"); - } else { - push @actions, $msg; - push @not_deleted, $id; - } - } else { # not an immutable scrip - my ($retval, $msg) = $scrip->Delete; - if ($retval) { - push @actions, loc("Scrip deleted"); - } - else { - push @actions, $msg; - push @not_deleted, $id; - } +if ( $MoveScripDown ) { + my $scrip = RT::ObjectScrip->new( $session{'CurrentUser'} ); + $scrip->LoadByCols( Scrip => $MoveScripDown, ObjectId => $id ); + if ( $scrip->id ) { + my ($status, $msg) = $scrip->MoveDown; + push @actions, $msg; } } -$DECODED_ARGS->{DeleteScrip} = \@not_deleted; + </%init> <%ARGS> $id => undef $title => undef $Format => undef -@DeleteScrip => () + +@RemoveScrip => () +$RemoveScrips => undef + +@AddScrip => () +$AddScrips => undef +$Stage => 'TransactionCreate' + +$MoveScripUp => undef +$MoveScripDown => undef + </%ARGS> diff --git a/rt/share/html/Admin/Elements/EditTemplates b/rt/share/html/Admin/Elements/EditTemplates index 1c86a4e25..a5b64e1f7 100755 --- a/rt/share/html/Admin/Elements/EditTemplates +++ b/rt/share/html/Admin/Elements/EditTemplates @@ -58,6 +58,7 @@ <& /Elements/CollectionList, OrderBy => 'id', Order => 'ASC', + Rows => $Rows, %ARGS, DisplayFormat => '__CheckBox.{DeleteTemplates}__,'. $Format, Format => $Format, @@ -74,6 +75,7 @@ <%INIT> $Format ||= RT->Config->Get('AdminSearchResultFormat')->{'Templates'}; +my $Rows = RT->Config->Get('AdminSearchResultRows')->{'Templates'} || 50; my $QueueObj = RT::Queue->new( $session{'CurrentUser'} ); $QueueObj->Load( $id ) if $id; diff --git a/rt/share/html/Admin/Elements/EditUserComments b/rt/share/html/Admin/Elements/EditUserComments deleted file mode 100755 index d0c6d62df..000000000 --- a/rt/share/html/Admin/Elements/EditUserComments +++ /dev/null @@ -1,56 +0,0 @@ -%# BEGIN BPS TAGGED BLOCK {{{ -%# -%# COPYRIGHT: -%# -%# This software is Copyright (c) 1996-2015 Best Practical Solutions, LLC -%# <sales@bestpractical.com> -%# -%# (Except where explicitly superseded by other copyright notices) -%# -%# -%# LICENSE: -%# -%# This work is made available to you under the terms of Version 2 of -%# the GNU General Public License. A copy of that license should have -%# been provided with this software, but in any event can be snarfed -%# from www.gnu.org. -%# -%# This work is distributed in the hope that it will be useful, but -%# WITHOUT ANY WARRANTY; without even the implied warranty of -%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -%# General Public License for more details. -%# -%# You should have received a copy of the GNU General Public License -%# along with this program; if not, write to the Free Software -%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -%# 02110-1301 or visit their web page on the internet at -%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html. -%# -%# -%# CONTRIBUTION SUBMISSION POLICY: -%# -%# (The following paragraph is not intended to limit the rights granted -%# to you to modify and distribute this software under the terms of -%# the GNU General Public License and is only of importance to you if -%# you choose to contribute your changes and enhancements to the -%# community by submitting them to Best Practical Solutions, LLC.) -%# -%# By intentionally submitting any modifications, corrections or -%# derivatives to this work, or any other work intended for use with -%# Request Tracker, to Best Practical Solutions, LLC, you confirm that -%# you are the copyright holder for those contributions and you grant -%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable, -%# royalty-free, perpetual, license to use, copy, create derivative -%# works based on those contributions, and sublicense and distribute -%# those contributions and any derivatives thereof. -%# -%# END BPS TAGGED BLOCK }}} -<& /Elements/Header, Title => "Comments about $name" &> -<&|/l&>These comments aren't generally visible to the user</&>:<br /> -<input type="hidden" class="hidden" name="id" value="<%$id%>" /> -<textarea cols="60" rows="15" wrap="soft" name="Comments"><% $UserObj->Comments %></textarea> -</form> - -<%ARGS> -$UserObj => undef -</%ARGS> diff --git a/rt/share/html/Admin/Elements/ListGlobalCustomFields b/rt/share/html/Admin/Elements/ListGlobalCustomFields deleted file mode 100755 index 39caa42ea..000000000 --- a/rt/share/html/Admin/Elements/ListGlobalCustomFields +++ /dev/null @@ -1,61 +0,0 @@ -%# BEGIN BPS TAGGED BLOCK {{{ -%# -%# COPYRIGHT: -%# -%# This software is Copyright (c) 1996-2015 Best Practical Solutions, LLC -%# <sales@bestpractical.com> -%# -%# (Except where explicitly superseded by other copyright notices) -%# -%# -%# LICENSE: -%# -%# This work is made available to you under the terms of Version 2 of -%# the GNU General Public License. A copy of that license should have -%# been provided with this software, but in any event can be snarfed -%# from www.gnu.org. -%# -%# This work is distributed in the hope that it will be useful, but -%# WITHOUT ANY WARRANTY; without even the implied warranty of -%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -%# General Public License for more details. -%# -%# You should have received a copy of the GNU General Public License -%# along with this program; if not, write to the Free Software -%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -%# 02110-1301 or visit their web page on the internet at -%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html. -%# -%# -%# CONTRIBUTION SUBMISSION POLICY: -%# -%# (The following paragraph is not intended to limit the rights granted -%# to you to modify and distribute this software under the terms of -%# the GNU General Public License and is only of importance to you if -%# you choose to contribute your changes and enhancements to the -%# community by submitting them to Best Practical Solutions, LLC.) -%# -%# By intentionally submitting any modifications, corrections or -%# derivatives to this work, or any other work intended for use with -%# Request Tracker, to Best Practical Solutions, LLC, you confirm that -%# you are the copyright holder for those contributions and you grant -%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable, -%# royalty-free, perpetual, license to use, copy, create derivative -%# works based on those contributions, and sublicense and distribute -%# those contributions and any derivatives thereof. -%# -%# END BPS TAGGED BLOCK }}} -% my $count = 0; -% while (my $CustomFieldObj = $CustomFields->Next) { -% $count++; -<font size="-1"><%$CustomFieldObj->id%>/<% loc($CustomFieldObj->Type) %>/<%$CustomFieldObj->Name%>: <%$CustomFieldObj->Description%></font> -<br /> -% } -% if (!$count) { -<font size="-1"><&|/l&>(No custom fields)</&></font> -% } - -<%init> -my $CustomFields = RT::CustomFields->new ($session{'CurrentUser'}); -$CustomFields->LimitToGlobal(); -</%INIT> diff --git a/rt/share/html/Admin/Elements/LoggingSummary b/rt/share/html/Admin/Elements/LoggingSummary new file mode 100644 index 000000000..a1b829942 --- /dev/null +++ b/rt/share/html/Admin/Elements/LoggingSummary @@ -0,0 +1,92 @@ +%# BEGIN BPS TAGGED BLOCK {{{ +%# +%# COPYRIGHT: +%# +%# This software is Copyright (c) 1996-2015 Best Practical Solutions, LLC +%# <sales@bestpractical.com> +%# +%# (Except where explicitly superseded by other copyright notices) +%# +%# +%# LICENSE: +%# +%# This work is made available to you under the terms of Version 2 of +%# the GNU General Public License. A copy of that license should have +%# been provided with this software, but in any event can be snarfed +%# from www.gnu.org. +%# +%# This work is distributed in the hope that it will be useful, but +%# WITHOUT ANY WARRANTY; without even the implied warranty of +%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +%# General Public License for more details. +%# +%# You should have received a copy of the GNU General Public License +%# along with this program; if not, write to the Free Software +%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +%# 02110-1301 or visit their web page on the internet at +%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html. +%# +%# +%# CONTRIBUTION SUBMISSION POLICY: +%# +%# (The following paragraph is not intended to limit the rights granted +%# to you to modify and distribute this software under the terms of +%# the GNU General Public License and is only of importance to you if +%# you choose to contribute your changes and enhancements to the +%# community by submitting them to Best Practical Solutions, LLC.) +%# +%# By intentionally submitting any modifications, corrections or +%# derivatives to this work, or any other work intended for use with +%# Request Tracker, to Best Practical Solutions, LLC, you confirm that +%# you are the copyright holder for those contributions and you grant +%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable, +%# royalty-free, perpetual, license to use, copy, create derivative +%# works based on those contributions, and sublicense and distribute +%# those contributions and any derivatives thereof. +%# +%# END BPS TAGGED BLOCK }}} +<%init> +my @summary; + +if (my $level = RT->Config->Get("LogToSTDERR")) { + push @summary, loc("Logging [_1] level messages and higher to STDERR, which will usually end up in your webserver's error logs.", $level); +} + +if (my $level = RT->Config->Get("LogToFile") and + my $logger = RT->Logger->output("file")) { + # Using the Log::Dispatch::File object let's us avoid duplicating + # filename logic from RT::InitLogging() + push @summary, loc("Logging [_1] level messages and higher to [_2]", $level, $logger->{filename}); +} + +if (my $level = RT->Config->Get("LogToSyslog")) { + my %conf = RT->Config->Get("LogToSyslogConf"); + my $conf = join ", ", map { "$_=$conf{$_}" } keys %conf; + if ($conf) { + push @summary, loc("Logging [_1] level messages and higher to syslog with the following configuration: [_2]", $level, $conf); + } else { + push @summary, loc("Logging [_1] level messages and higher to syslog.", $level); + } +} + +if (my $level = RT->Config->Get("LogStackTraces")) { + push @summary, loc("Stack traces are added to message levels [_1] and higher.", $level); +} else { + push @summary, loc("Stack traces are not logged."); +} + +if (my $level = RT->Config->Get("StatementLog")) { + my $url = RT->Config->Get("WebPath") . "/Admin/Tools/Queries.html"; + push @summary, \loc("SQL queries are logged at the [_1] level and also available in the [_2]query tool[_3].", $m->interp->apply_escapes($level, 'h'), qq[<strong><a href="$url">], '</a></strong>'); +} else { + push @summary, loc("SQL queries are not logged."); +} +</%init> +<p> +<&|/l&>RT's logging configuration is summarized below:</&> +<ul> +% for my $msg (@summary) { + <li><% ref($msg) ? $$msg : $m->interp->apply_escapes($msg, 'h') |n %></li> +% } +</ul> +</p> diff --git a/rt/share/html/Admin/Elements/MembershipsPage b/rt/share/html/Admin/Elements/MembershipsPage new file mode 100644 index 000000000..e637e76cc --- /dev/null +++ b/rt/share/html/Admin/Elements/MembershipsPage @@ -0,0 +1,152 @@ +%# BEGIN BPS TAGGED BLOCK {{{ +%# +%# COPYRIGHT: +%# +%# This software is Copyright (c) 1996-2015 Best Practical Solutions, LLC +%# <sales@bestpractical.com> +%# +%# (Except where explicitly superseded by other copyright notices) +%# +%# +%# LICENSE: +%# +%# This work is made available to you under the terms of Version 2 of +%# the GNU General Public License. A copy of that license should have +%# been provided with this software, but in any event can be snarfed +%# from www.gnu.org. +%# +%# This work is distributed in the hope that it will be useful, but +%# WITHOUT ANY WARRANTY; without even the implied warranty of +%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +%# General Public License for more details. +%# +%# You should have received a copy of the GNU General Public License +%# along with this program; if not, write to the Free Software +%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +%# 02110-1301 or visit their web page on the internet at +%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html. +%# +%# +%# CONTRIBUTION SUBMISSION POLICY: +%# +%# (The following paragraph is not intended to limit the rights granted +%# to you to modify and distribute this software under the terms of +%# the GNU General Public License and is only of importance to you if +%# you choose to contribute your changes and enhancements to the +%# community by submitting them to Best Practical Solutions, LLC.) +%# +%# By intentionally submitting any modifications, corrections or +%# derivatives to this work, or any other work intended for use with +%# Request Tracker, to Best Practical Solutions, LLC, you confirm that +%# you are the copyright holder for those contributions and you grant +%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable, +%# royalty-free, perpetual, license to use, copy, create derivative +%# works based on those contributions, and sublicense and distribute +%# those contributions and any derivatives thereof. +%# +%# END BPS TAGGED BLOCK }}} +<& /Admin/Elements/Header, Title => $title &> +<& /Elements/Tabs &> +<& /Elements/ListActions &> + +<form method="post" action=""> +<input type="hidden" id="<% $id %>" /> + +<h2><&|/l&>Groups the principal is member of (check box to delete)</&></h2> + +<& /Elements/CollectionList, + OrderBy => 'Name', + Order => 'ASC', + %ARGS, + Rows => $Rows, + DisplayFormat => "__CheckBox.{Delete}__,$Format", + Format => $Format, + Collection => $is_member, + AllowSorting => 1, + PassArguments => [qw(Format Rows Page Order OrderBy id)], +&> + +<h2><&|/l&>Groups the principal is not member of (check box to add)</&></h2> + +<& /Elements/CollectionList, + OrderBy => 'Name', + Order => 'ASC', + Rows => $Rows, + %ARGS, + DisplayFormat => "__CheckBox.{Add}__,'__HasMemberRecursively.{$id}__/TITLE:Recursive member',$Format", + Format => $Format, + Collection => $is_not_member, + AllowSorting => 1, + PassArguments => [qw(Format Rows Page Order OrderBy id)], +&> + +<& /Elements/Submit, Label => loc('Update'), Name => 'Update' &> + +</form> + +<%INIT> +my $principal = RT::Principal->new( $session{'CurrentUser'} ); +$principal->Load( $id ) || Abort(loc("Couldn't load principal #[_1]", $id)); + +my $object = $principal->Object; +$id = $object->id; + +if ( $Update ) { + my @results; + foreach my $gid( @Add ) { + my $group = RT::Group->new( $session{'CurrentUser'} ); + $group->LoadUserDefinedGroup( $gid ); + unless ( $group->id ) { + push @results, loc( "Couldn't load group #[_1]", $gid ); + next; + } + my ($status, $msg) = $group->AddMember( $id ); + push @results, $msg; + } + foreach my $gid( @Delete ) { + my $group = RT::Group->new( $session{'CurrentUser'} ); + $group->LoadUserDefinedGroup( $gid ); + unless ( $group->id ) { + push @results, loc( "Couldn't load group #[_1]", $gid ); + next; + } + my ($status, $msg) = $group->DeleteMember( $id ); + push @results, $msg; + } + MaybeRedirectForResults( + Arguments => { id => $id }, + Actions => \@results, + ); +} + +my $is_member = RT::Groups->new( $session{'CurrentUser'} ); +$is_member->LimitToUserDefinedGroups; +$is_member->WithMember( PrincipalId => $id ); + +my $is_not_member = RT::Groups->new( $session{'CurrentUser'} ); +$is_not_member->LimitToUserDefinedGroups; +$is_not_member->WithoutMember( PrincipalId => $id ); +$is_not_member->Limit( FIELD => 'id', OPERATOR => '!=', VALUE => $id ); + +$Format ||= RT->Config->Get('AdminSearchResultFormat')->{'Groups'}; +my $Rows = RT->Config->Get('AdminSearchResultRows')->{'Groups'} || 50; + +my $title; +if ( $principal->IsUser ) { + $title = loc("Memberships of the user [_1]", $object->Name); +} elsif ( $principal->IsGroup ) { + $title = loc("Memberships of the group [_1]", $object->Name); +} else { + $title = loc("Memberships of the principal #[_1]", $id); +} + +</%INIT> +<%ARGS> +$id => undef + +$Update => 0, +@Add => (), +@Delete => (), + +$Format => undef +</%ARGS> diff --git a/rt/share/html/Admin/Elements/ModifyTemplate b/rt/share/html/Admin/Elements/ModifyTemplate index a30ae056c..7d738eb6d 100755 --- a/rt/share/html/Admin/Elements/ModifyTemplate +++ b/rt/share/html/Admin/Elements/ModifyTemplate @@ -48,7 +48,7 @@ <table> <tr> <td class="label"><&|/l&>Name</&>:</td> -<td class="value"><input name="Name" value="<%$Name||''%>" size="20" /></td> +<td class="value"><input name="Name" value="<%$Name||''%>" size="80" /></td> </tr> <tr> <td class="label"><&|/l&>Description</&>:</td> @@ -57,8 +57,13 @@ <tr> <td class="label"><&|/l&>Type</&>:</td> <td class="value"> -<input type="radio" name="Type" value="Perl" <% $Type eq "Perl" ? 'checked="checked"' : "" |n %>><&|/l&>Perl</&></input><br /> -<input type="radio" name="Type" value="Simple" <% $Type eq "Simple" ? 'checked="checked"' : "" |n %>><&|/l&>Simple</&></input><br /> + +<input type="radio" name="Type" id="Type-Perl" value="Perl" <% $Type eq "Perl" ? 'checked="checked"' : "" |n %>></input> +<label for="Type-Perl"><&|/l&>Perl</&></label><br /> + +<input type="radio" name="Type" id="Type-Simple" value="Simple" <% $Type eq "Simple" ? 'checked="checked"' : "" |n %>> +<label for="Type-Simple"><&|/l&>Simple</&></label><br /> + </td> </tr> <tr> diff --git a/rt/share/html/Admin/Elements/PickObjects b/rt/share/html/Admin/Elements/PickObjects deleted file mode 100644 index 6ab014c52..000000000 --- a/rt/share/html/Admin/Elements/PickObjects +++ /dev/null @@ -1,81 +0,0 @@ -%# BEGIN BPS TAGGED BLOCK {{{ -%# -%# COPYRIGHT: -%# -%# This software is Copyright (c) 1996-2015 Best Practical Solutions, LLC -%# <sales@bestpractical.com> -%# -%# (Except where explicitly superseded by other copyright notices) -%# -%# -%# LICENSE: -%# -%# This work is made available to you under the terms of Version 2 of -%# the GNU General Public License. A copy of that license should have -%# been provided with this software, but in any event can be snarfed -%# from www.gnu.org. -%# -%# This work is distributed in the hope that it will be useful, but -%# WITHOUT ANY WARRANTY; without even the implied warranty of -%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -%# General Public License for more details. -%# -%# You should have received a copy of the GNU General Public License -%# along with this program; if not, write to the Free Software -%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -%# 02110-1301 or visit their web page on the internet at -%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html. -%# -%# -%# CONTRIBUTION SUBMISSION POLICY: -%# -%# (The following paragraph is not intended to limit the rights granted -%# to you to modify and distribute this software under the terms of -%# the GNU General Public License and is only of importance to you if -%# you choose to contribute your changes and enhancements to the -%# community by submitting them to Best Practical Solutions, LLC.) -%# -%# By intentionally submitting any modifications, corrections or -%# derivatives to this work, or any other work intended for use with -%# Request Tracker, to Best Practical Solutions, LLC, you confirm that -%# you are the copyright holder for those contributions and you grant -%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable, -%# royalty-free, perpetual, license to use, copy, create derivative -%# works based on those contributions, and sublicense and distribute -%# those contributions and any derivatives thereof. -%# -%# END BPS TAGGED BLOCK }}} -% if (@Objects == 0) { -<p><i><&|/l&>(None)</&></i></p> -% } else { -<table cellspacing="0" cellpadding="2"> -% my $count; -% foreach my $Object (@Objects) { -<tr> -% my $id = "Object-".$Object->id."-CF-".$id; -% if (!$ReadOnly) { - <td valign="top"> -<input type="checkbox" id="<% $id %>" name="<% $id %>" value="1" <% $Checked ? 'checked="checked"' : ''%> -/> - </td> -% } - <td valign="top"> - <label for="<% $id %>"> -% if ($Object->Name) { - <b><%$Object->Name%></b><br /> -% } else { - <i>(<%loc("no name")%>)</i><br /> -% } - <%$Object->can('Description') ? ($Object->Description||'') : '' %> - </label> - </td> -</tr> -% } -</table> -% } -<%ARGS> -@Objects -$id -$ReadOnly => 0 -$Checked => 0 -</%ARGS> diff --git a/rt/share/html/Admin/Elements/Portal b/rt/share/html/Admin/Elements/Portal index 9207e1e97..3028524da 100644 --- a/rt/share/html/Admin/Elements/Portal +++ b/rt/share/html/Admin/Elements/Portal @@ -46,7 +46,7 @@ %# %# END BPS TAGGED BLOCK }}} <div id="rt-portal"> -<&| /Widgets/TitleBox, title => 'RT Portal' &> +<&| /Widgets/TitleBox, title => loc('RT Portal') &> <iframe src="https://bestpractical.com/rt/integration/news?utm_source=rt&utm_medium=iframe&utm_campaign=<%$RT::VERSION%>"></iframe> </&> </div> diff --git a/rt/share/html/Admin/Elements/SelectGroups b/rt/share/html/Admin/Elements/SelectGroups index f45dca096..491a2fa21 100755 --- a/rt/share/html/Admin/Elements/SelectGroups +++ b/rt/share/html/Admin/Elements/SelectGroups @@ -53,7 +53,7 @@ <%INIT> my $groups = RT::Groups->new($session{'CurrentUser'}); -$groups->Limit(FIELD => 'Domain', OPERATOR => '=', VALUE => $Domain); +$groups->Limit(FIELD => 'Domain', OPERATOR => '=', VALUE => $Domain, CASESENSITIVE => 0 ); </%INIT> <%ARGS> diff --git a/rt/share/html/Admin/Elements/SelectModifyGroup b/rt/share/html/Admin/Elements/SelectModifyGroup deleted file mode 100755 index 29c924bdb..000000000 --- a/rt/share/html/Admin/Elements/SelectModifyGroup +++ /dev/null @@ -1,57 +0,0 @@ -%# BEGIN BPS TAGGED BLOCK {{{ -%# -%# COPYRIGHT: -%# -%# This software is Copyright (c) 1996-2015 Best Practical Solutions, LLC -%# <sales@bestpractical.com> -%# -%# (Except where explicitly superseded by other copyright notices) -%# -%# -%# LICENSE: -%# -%# This work is made available to you under the terms of Version 2 of -%# the GNU General Public License. A copy of that license should have -%# been provided with this software, but in any event can be snarfed -%# from www.gnu.org. -%# -%# This work is distributed in the hope that it will be useful, but -%# WITHOUT ANY WARRANTY; without even the implied warranty of -%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -%# General Public License for more details. -%# -%# You should have received a copy of the GNU General Public License -%# along with this program; if not, write to the Free Software -%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -%# 02110-1301 or visit their web page on the internet at -%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html. -%# -%# -%# CONTRIBUTION SUBMISSION POLICY: -%# -%# (The following paragraph is not intended to limit the rights granted -%# to you to modify and distribute this software under the terms of -%# the GNU General Public License and is only of importance to you if -%# you choose to contribute your changes and enhancements to the -%# community by submitting them to Best Practical Solutions, LLC.) -%# -%# By intentionally submitting any modifications, corrections or -%# derivatives to this work, or any other work intended for use with -%# Request Tracker, to Best Practical Solutions, LLC, you confirm that -%# you are the copyright holder for those contributions and you grant -%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable, -%# royalty-free, perpetual, license to use, copy, create derivative -%# works based on those contributions, and sublicense and distribute -%# those contributions and any derivatives thereof. -%# -%# END BPS TAGGED BLOCK }}} -%while ( $Group = $Groups->Next) { -<a href="Modify.html?id=<%$Group->id%>"><%$Group->id%>: <%$Group->Name%></a><br /> -%} -<%INIT> -my ($Group); -my $Groups = RT::Groups->new($session{'CurrentUser'}); -$Groups->UnLimit; -</%INIT> -<%ARGS> -</%ARGS> diff --git a/rt/share/html/Admin/Elements/SelectModifyUser b/rt/share/html/Admin/Elements/SelectModifyUser deleted file mode 100755 index 442e0ca48..000000000 --- a/rt/share/html/Admin/Elements/SelectModifyUser +++ /dev/null @@ -1,73 +0,0 @@ -%# BEGIN BPS TAGGED BLOCK {{{ -%# -%# COPYRIGHT: -%# -%# This software is Copyright (c) 1996-2015 Best Practical Solutions, LLC -%# <sales@bestpractical.com> -%# -%# (Except where explicitly superseded by other copyright notices) -%# -%# -%# LICENSE: -%# -%# This work is made available to you under the terms of Version 2 of -%# the GNU General Public License. A copy of that license should have -%# been provided with this software, but in any event can be snarfed -%# from www.gnu.org. -%# -%# This work is distributed in the hope that it will be useful, but -%# WITHOUT ANY WARRANTY; without even the implied warranty of -%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -%# General Public License for more details. -%# -%# You should have received a copy of the GNU General Public License -%# along with this program; if not, write to the Free Software -%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -%# 02110-1301 or visit their web page on the internet at -%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html. -%# -%# -%# CONTRIBUTION SUBMISSION POLICY: -%# -%# (The following paragraph is not intended to limit the rights granted -%# to you to modify and distribute this software under the terms of -%# the GNU General Public License and is only of importance to you if -%# you choose to contribute your changes and enhancements to the -%# community by submitting them to Best Practical Solutions, LLC.) -%# -%# By intentionally submitting any modifications, corrections or -%# derivatives to this work, or any other work intended for use with -%# Request Tracker, to Best Practical Solutions, LLC, you confirm that -%# you are the copyright holder for those contributions and you grant -%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable, -%# royalty-free, perpetual, license to use, copy, create derivative -%# works based on those contributions, and sublicense and distribute -%# those contributions and any derivatives thereof. -%# -%# END BPS TAGGED BLOCK }}} -%while ( $user = $users->Next) { -<a href="Modify.html?id=<%$user->id%>"><%$user->id%>: <& /Elements/ShowUser, User => $user &></a><br /> -%} -<%INIT> -my ($user); -my $users = RT::Users->new($session{'CurrentUser'}); -$users->Limit(FIELD => 'id', - VALUE => RT->SystemUser->id, - OPERATOR => '!=' ); - -if (defined $IdLike) { -$users->Limit(FIELD => 'Name', - VALUE => $IdLike, - OPERATOR => 'LIKE' ); -} -if (defined $EmailLike) { -$users->Limit(FIELD => 'EmailAddress', - VALUE => $EmailLike, - OPERATOR => 'LIKE'); - -} -</%INIT> -<%ARGS> -$IdLike => undef -$EmailLike => undef -</%ARGS> diff --git a/rt/share/html/Admin/Elements/SelectNewGroupMembers b/rt/share/html/Admin/Elements/SelectNewGroupMembers index 8cdda89b4..07418b5d3 100755 --- a/rt/share/html/Admin/Elements/SelectNewGroupMembers +++ b/rt/share/html/Admin/Elements/SelectNewGroupMembers @@ -45,39 +45,43 @@ %# those contributions and any derivatives thereof. %# %# END BPS TAGGED BLOCK }}} +<table> % if ( $Show ne 'Groups' ) { -<label for="<% $Name %>Users"><&|/l&>Add user</&>:</label> -<input type="text" value="" name="<% $Name %>Users" id="<% $Name %>Users" /><br /> +<tr> +<td class="label"><label for="<% $Name %>Users"><&|/l&>Add user</&>:</label></td> +<td> +<input type="text" value="" name="<% $Name %>Users" id="<% $Name %>Users" data-autocomplete="Users" data-autocomplete-return="Name" data-autocomplete-privileged="1" data-autocomplete-exclude="<% $user_ids |n %>" /> <script type="text/javascript"> jQuery(function(){ - jQuery("#"+<% $Name |n,j%>+"Users").autocomplete({ - source: <% RT->Config->Get('WebPath') |n,j%>+"/Helpers/Autocomplete/Users?return=Name;privileged=1;exclude="+<% $user_ids |n,u,j %>, - // Auto-submit once a user is chosen - select: function( event, ui ) { - jQuery(event.target).val(ui.item.value); - jQuery(event.target).closest("form").submit(); - } - }).addClass("autocompletes-user"); + // Auto-submit once a user is chosen + jQuery("#"+<% $Name |n,j%>+"Users").on("autocompleteselect", function( event, ui ) { + jQuery(event.target).val(ui.item.value); + jQuery(event.target).closest("form").submit(); + }); }); </script> +</td> +</tr> % } % if ( $Show ne 'Users' ) { -<label for="<% $Name %>Groups"><&|/l&>Add group</&>:</label> -<input type="text" value="" name="<% $Name %>Groups" id="<% $Name %>Groups" /><br /> +<tr> +<td class="label"><label for="<% $Name %>Groups"><&|/l&>Add group</&>:</label></td> +<td> +<input type="text" value="" name="<% $Name %>Groups" id="<% $Name %>Groups" data-autocomplete="Groups" data-autocomplete-exclude="<% $group_ids |n %>" /> <script type="text/javascript"> jQuery(function(){ - jQuery("#"+<% $Name |n,j%>+"Groups").autocomplete({ - source: <% RT->Config->Get('WebPath') |n,j%>+"/Helpers/Autocomplete/Groups?exclude="+<% $group_ids |n,u,j %>, - // Auto-submit once a user is chosen - select: function( event, ui ) { - jQuery(event.target).val(ui.item.value); - jQuery(event.target).closest("form").submit(); - } + // Auto-submit once a group is chosen + jQuery("#"+<% $Name |n,j%>+"Groups").on("autocompleteselect", function( event, ui ) { + jQuery(event.target).val(ui.item.value); + jQuery(event.target).closest("form").submit(); }); }); </script> +</td> +</tr> % } +</table> <%INIT> my $user_ids = join(',', grep { $SkipUsers->{$_} } keys %$SkipUsers); my $group_ids = join(',', grep { $SkipGroups->{$_} } keys %$SkipGroups); diff --git a/rt/share/html/Admin/Elements/SelectRights b/rt/share/html/Admin/Elements/SelectRights deleted file mode 100755 index df1f72412..000000000 --- a/rt/share/html/Admin/Elements/SelectRights +++ /dev/null @@ -1,120 +0,0 @@ -%# BEGIN BPS TAGGED BLOCK {{{ -%# -%# COPYRIGHT: -%# -%# This software is Copyright (c) 1996-2015 Best Practical Solutions, LLC -%# <sales@bestpractical.com> -%# -%# (Except where explicitly superseded by other copyright notices) -%# -%# -%# LICENSE: -%# -%# This work is made available to you under the terms of Version 2 of -%# the GNU General Public License. A copy of that license should have -%# been provided with this software, but in any event can be snarfed -%# from www.gnu.org. -%# -%# This work is distributed in the hope that it will be useful, but -%# WITHOUT ANY WARRANTY; without even the implied warranty of -%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -%# General Public License for more details. -%# -%# You should have received a copy of the GNU General Public License -%# along with this program; if not, write to the Free Software -%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -%# 02110-1301 or visit their web page on the internet at -%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html. -%# -%# -%# CONTRIBUTION SUBMISSION POLICY: -%# -%# (The following paragraph is not intended to limit the rights granted -%# to you to modify and distribute this software under the terms of -%# the GNU General Public License and is only of importance to you if -%# you choose to contribute your changes and enhancements to the -%# community by submitting them to Best Practical Solutions, LLC.) -%# -%# By intentionally submitting any modifications, corrections or -%# derivatives to this work, or any other work intended for use with -%# Request Tracker, to Best Practical Solutions, LLC, you confirm that -%# you are the copyright holder for those contributions and you grant -%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable, -%# royalty-free, perpetual, license to use, copy, create derivative -%# works based on those contributions, and sublicense and distribute -%# those contributions and any derivatives thereof. -%# -%# END BPS TAGGED BLOCK }}} -<input type="hidden" class="hidden" name="CheckACL" value="<%$ACLDesc%>" /> - <table border="0"> -<tr> -<td valign="top" width="180" align="left"> -<%PERL> -my %current_rights; -my @pairs; -while ( my $ace = $ACLObj->Next ) { - my $right = $ace->RightName; - $current_rights{ $right } = 1; - push @pairs, [$right, loc($right)]; -} -@pairs = sort { $a->[1] cmp $b->[1] } @pairs; -</%PERL> -<h3><&|/l&>Current rights</&></h3> -% unless ( @pairs ) { -<i><&|/l&>No rights granted.</&></i> <br /> -% } else { -<i>(<&|/l&>Check box to revoke right</&>)</i><br /> -% foreach my $pair ( @pairs ) { -<input type="checkbox" class="checkbox" value="<% $pair->[0] %>" name="RevokeRight-<% $ACLDesc %>" /> <% $pair->[1] %><br /> -% } } -</td> -<td valign="top"> -<h3><&|/l&>New rights</&></h3> -<select size="5" multiple="multiple" name="GrantRight-<%$ACLDesc%>"> -% foreach my $pair (sort { $a->[1] cmp $b->[1] } map [$_, loc($_)], grep !$current_rights{$_}, keys %Rights) { - <option value="<% $pair->[0] %>" title="<% loc($Rights{$pair->[0]}) %>"><% $pair->[1] %></option> -% } -<option value="" selected="selected"><&|/l&>(no value)</&></option> -</select> -</td> -</tr> -</table> -<%INIT> - my ($ACLDesc, $AppliesTo, %Rights); - - # if the principal id points to a user, we really want to point - # to their ACL equivalence group. The machinations we're going through - # lead me to start to suspect that we really want users and groups - # to just be the same table. or _maybe_ that we want an object db. - my $princ = RT::Principal->new($RT::SystemUser); - $princ->Load($PrincipalId); - if ($princ->PrincipalType eq 'User') { - my $group = RT::Group->new($RT::SystemUser); - $group->LoadACLEquivalenceGroup($princ); - $PrincipalId = $group->PrincipalId; - } - - - my $ACLObj = RT::ACL->new($session{'CurrentUser'}); - my $ACE = RT::ACE->new($session{'CurrentUser'}); - - - $ACLObj->LimitToObject( $Object); - $ACLObj->LimitToPrincipal( Id => $PrincipalId); - $ACLObj->OrderBy(FIELD=>'RightName'); - - eval { - %Rights = %{$Object->AvailableRights}; - }; - if ($@) { - %Rights = ( loc('System Error') => loc("No rights found") ); - } - - $ACLDesc = "$PrincipalId-".ref($Object)."-".$Object->Id; -</%INIT> - -<%ARGS> -$PrincipalType => undef -$PrincipalId => undef -$Object =>undef -</%ARGS> diff --git a/rt/share/html/Admin/Elements/SelectSingleOrMultiple b/rt/share/html/Admin/Elements/SelectSingleOrMultiple deleted file mode 100755 index d6909b8c2..000000000 --- a/rt/share/html/Admin/Elements/SelectSingleOrMultiple +++ /dev/null @@ -1,67 +0,0 @@ -%# BEGIN BPS TAGGED BLOCK {{{ -%# -%# COPYRIGHT: -%# -%# This software is Copyright (c) 1996-2015 Best Practical Solutions, LLC -%# <sales@bestpractical.com> -%# -%# (Except where explicitly superseded by other copyright notices) -%# -%# -%# LICENSE: -%# -%# This work is made available to you under the terms of Version 2 of -%# the GNU General Public License. A copy of that license should have -%# been provided with this software, but in any event can be snarfed -%# from www.gnu.org. -%# -%# This work is distributed in the hope that it will be useful, but -%# WITHOUT ANY WARRANTY; without even the implied warranty of -%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -%# General Public License for more details. -%# -%# You should have received a copy of the GNU General Public License -%# along with this program; if not, write to the Free Software -%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -%# 02110-1301 or visit their web page on the internet at -%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html. -%# -%# -%# CONTRIBUTION SUBMISSION POLICY: -%# -%# (The following paragraph is not intended to limit the rights granted -%# to you to modify and distribute this software under the terms of -%# the GNU General Public License and is only of importance to you if -%# you choose to contribute your changes and enhancements to the -%# community by submitting them to Best Practical Solutions, LLC.) -%# -%# By intentionally submitting any modifications, corrections or -%# derivatives to this work, or any other work intended for use with -%# Request Tracker, to Best Practical Solutions, LLC, you confirm that -%# you are the copyright holder for those contributions and you grant -%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable, -%# royalty-free, perpetual, license to use, copy, create derivative -%# works based on those contributions, and sublicense and distribute -%# those contributions and any derivatives thereof. -%# -%# END BPS TAGGED BLOCK }}} - <select name="<%$Name%>"> - <option value="1" <%$SingleDefault|n%>><&|/l&>Single</&></option> - <option value="0" <%$MultipleDefault|n%>><&|/l&>Multiple</&></option> - </select> - - -<%INIT> -my ($SingleDefault, $MultipleDefault); -if ($Default == 1) { - $SingleDefault = qq[ selected="selected"]; -} -elsif ($Default == 0 ) { - $MultipleDefault = qq[ selected="selected"]; -} - -</%INIT> -<%ARGS> -$Name => 'Single' -$Default => 1 -</%ARGS> diff --git a/rt/share/html/Admin/Elements/SelectStage b/rt/share/html/Admin/Elements/SelectStage index 32d39c786..03260b139 100644 --- a/rt/share/html/Admin/Elements/SelectStage +++ b/rt/share/html/Admin/Elements/SelectStage @@ -46,28 +46,20 @@ %# %# END BPS TAGGED BLOCK }}} <select name="<%$Name%>"> -% foreach my $stage (@stages) { - -%# allow [stage, display] in place of a scalar stage name -% my ($value, $display) = ref($stage) ? @$stage : ($stage, $stage); - +% foreach my $value (@stages) { <option value="<%$value%>" <% ($value eq $Default) && qq[ selected="selected"] |n %> -><% loc($display) %> +<% ($value eq 'TransactionBatch' and not RT->Config->Get('UseTransactionBatch')) && qq[ disabled ] %> +><% loc( RT::Scrip->FriendlyStage($value) ) %> </option> % } +</select> <%INIT> if ( !defined $Default || $Default eq '') { $Default = 'TransactionCreate'; } -my @stages = 'TransactionCreate'; - -push @stages, RT->Config->Get('UseTransactionBatch') - ? 'TransactionBatch' - : ['TransactionBatch', 'TransactionBatch (DISABLED)']; - -push @stages, 'Disabled'; +my @stages = ('TransactionCreate', 'TransactionBatch'); </%INIT> <%ARGS> $Default => 'TransactionCreate' diff --git a/rt/share/html/Admin/Elements/CreateUserCalled b/rt/share/html/Admin/Elements/SelectStageForAdded index fb15893f0..7d8747060 100755..100644 --- a/rt/share/html/Admin/Elements/CreateUserCalled +++ b/rt/share/html/Admin/Elements/SelectStageForAdded @@ -45,6 +45,10 @@ %# those contributions and any derivatives thereof. %# %# END BPS TAGGED BLOCK }}} -<form method="get" action="<% RT->Config->Get('WebPath') %>/Admin/Users/Create.html"> -<&|/l&>New user called</&> <input name="Name" size="10" /><input type="submit" class="button" value="<&|/l&>Create</&>" /> -</form> +<div style="text-align:right"> +<% $Label %> +<& SelectStage, %ARGS &> +</div> +<%args> +$Label => loc('Select scrip stage for newly added queues:') +</%args> diff --git a/rt/share/html/Admin/Elements/ShowKeyInfo b/rt/share/html/Admin/Elements/ShowKeyInfo index 0a7ef0f02..035125957 100644 --- a/rt/share/html/Admin/Elements/ShowKeyInfo +++ b/rt/share/html/Admin/Elements/ShowKeyInfo @@ -45,18 +45,29 @@ %# those contributions and any derivatives thereof. %# %# END BPS TAGGED BLOCK }}} -<&| /Widgets/TitleBox, title => $title &> -% if ( $res{'exit_code'} || !keys %{ $res{'info'} } ) { -<% loc('No keys for this address') %> +<&| /Widgets/TitleBox, title => $title &><table> +% while ( my $protocol = shift @protocols ) { +% my %res = RT::Crypt->GetKeyInfo( +% Protocol => $protocol, +% Key => $EmailAddress, +% Type => $Type, +% ); +% if ( $res{'exit_code'} ) { +<tr><th colspan="2"><% loc("Couldn't get [_1] keys information", $protocol) %></th></tr> +% } elsif ( !keys %{ $res{'info'} } ) { +<tr><th colspan="2"><% loc('No [_1] keys for this address', $protocol) %></th></tr> % } else { -<table> -% unless ( $Type eq 'private' ) { +<tr><th colspan="2"><% loc("[_1] key '[_2]'", $protocol, $res{'info'}{'Formatted'} ) %></th></tr> + +% if ( $Type ne 'private' && $res{'info'}{'Trust'} ) { <tr><th class="label"><% loc('Trust') %>:</th> <td><% loc( $res{'info'}{'Trust'} ) %></td></tr> % } <tr><th class="label"><% loc('Fingerprint') %>:</th> <td><% $res{'info'}{'Fingerprint'} %></td></tr> + +% $_->CurrentUser( $session{CurrentUser} ) for grep {$_} (@{$res{'info'}}{qw|Created Expire|}); <tr><th class="label"><% loc('Created') %>:</th> <td><% $res{'info'}{'Created'}? $res{'info'}{'Created'}->AsString( Time => 0 ): loc('never') %></td></tr> @@ -64,30 +75,38 @@ <td><% $res{'info'}{'Expire'}? $res{'info'}{'Expire'}->AsString( Time => 0 ): loc('never') %></td></tr> % foreach my $uinfo( @{ $res{'info'}{'User'} } ) { +% if ($uinfo->{'Created'} or $uinfo->{'Expire'}) { +% $_->CurrentUser( $session{CurrentUser} ) for grep {$_} ($uinfo->{'Created'}, $uinfo->{'Expire'}); <tr><th class="label"><% loc('User (created - expire)') %>:</th> -<td><% $uinfo->{'String'} %>\ +<td><% $uinfo->{'String'} %> \ (<% $uinfo->{'Created'}? $uinfo->{'Created'}->AsString( Time => 0 ): loc('never') %> - \ -<% $uinfo->{'Expire'}? $uinfo->{'Expire'}->AsString( Time => 0 ): loc('never') %>) -</td></tr> +<% $uinfo->{'Expire'}? $uinfo->{'Expire'}->AsString( Time => 0 ): loc('never') %>)</td></tr> +% } else { +<tr><th class="label"><% loc('User') %>:</th> +<td><% $uinfo->{'String'} %></td></tr> +% } % } -</table> % } -</&> + +% if ( @protocols ) { +<tr><th colspan="2"> </th></tr> +% } + +% } +</table></&> <%ARGS> $EmailAddress $Type => 'public' </%ARGS> <%INIT> -require RT::Crypt::GnuPG; -my %res = RT::Crypt::GnuPG::GetKeyInfo( $EmailAddress, $Type ); +my @protocols = RT::Crypt->EnabledProtocols; my $title; unless ( $Type eq 'private' ) { - $title = loc('GnuPG public key(s) for [_1]', $EmailAddress); + $title = loc('Public key(s) for [_1]', $EmailAddress); } else { - $title = loc('GnuPG private key(s) for [_1]', $EmailAddress); + $title = loc('Private key(s) for [_1]', $EmailAddress); } - </%INIT> diff --git a/rt/share/html/Admin/Queues/Scrip.html b/rt/share/html/Admin/Elements/UpgradeHistory index d4f349929..ccdc8f5a3 100755..100644 --- a/rt/share/html/Admin/Queues/Scrip.html +++ b/rt/share/html/Admin/Elements/UpgradeHistory @@ -45,33 +45,27 @@ %# those contributions and any derivatives thereof. %# %# END BPS TAGGED BLOCK }}} -<& /Admin/Elements/Header, Title => $title &> -<& /Elements/Tabs &> +% for my $package (@packages) { +% my ($version_status, @lines) = RT->System->ParsedUpgradeHistory($package); +<h4><% $package %> (<% $version_status %>)</h4> +<table border="0" cellspacing="0" cellpadding="5" width="100%" class="collection upgrade-history"> +<thead> +<tr class="collection-as-table"> +<th class="collection-as-table"> </th> +<th class="collection-as-table"><&|/l&>Action</&></th> +<th class="collection-as-table"><&|/l&>Date</&></th> +<th class="collection-as-table"><&|/l&>Elapsed</&></th> +<th class="collection-as-table"><&|/l, $package &>[_1] Version</&></th> +</tr></thead> -<& /Elements/ListActions, actions => \@results &> -<& /Admin/Elements/EditScrip, title => $title, %ARGS, id => $id &> +% my $i = 0; +% for my $upgrade (@lines) { +<& UpgradeHistoryRow, i => \$i, row => $upgrade &> +% } +</table> +% } <%init> -my $QueueObj = RT::Queue->new( $session{'CurrentUser'} ); -$QueueObj->Load( $Queue ); -unless( $QueueObj->id ) { - Abort(loc("Queue [_1] not found", $id)); -} - -my ($title); - -($id, my @results) = $m->comp( '/Admin/Elements/EditScrip:Process', %ARGS ); - -if ( $id ) { - $title = loc("Modify a scrip for queue [_1]", $QueueObj->Name); -} else { - $title = loc("Create a scrip for queue [_1]", $QueueObj->Name); -} - - +my $upgrade_history = RT->System->UpgradeHistory; +my @packages = ('RT', sort grep { $_ ne 'RT' } keys %$upgrade_history); </%init> - -<%ARGS> -$id => undef -$Queue => undef -</%ARGS> diff --git a/rt/share/html/Admin/Elements/PickCustomFields b/rt/share/html/Admin/Elements/UpgradeHistoryRow index 5a90d139a..dc5374126 100644 --- a/rt/share/html/Admin/Elements/PickCustomFields +++ b/rt/share/html/Admin/Elements/UpgradeHistoryRow @@ -45,54 +45,54 @@ %# those contributions and any derivatives thereof. %# %# END BPS TAGGED BLOCK }}} -% if (@CustomFields == 0) { -<p><i><&|/l&>(None)</&></i></p> -% } else { -<table cellspacing="0" cellpadding="2"> -% my $count; -% foreach my $CustomFieldObj (@CustomFields) { -<tr> -% if (!$ReadOnly) { - <td valign="top"> -<input type="checkbox" class="checkbox" name="Object-<%$id%>-CF-<%$CustomFieldObj->Id%>" value="1" <% $Checked ? 'checked="checked"' : '' %> -/> - </td> -% } - <td valign="top"> - <a href="<% RT->Config->Get('WebPath') %>/Admin/CustomFields/Modify.html?id=<%$CustomFieldObj->id()%>"> -% if ($CustomFieldObj->Name) { -<b><%$CustomFieldObj->Name%></b> -% } else { -<i>(<&|/l&>no name</&>)</i> +<tr class="<% join ' ', map {CSSClass($_)} @classes %>"> + <td class="upgrade-history-parent" id="parent-upgrade-history-<% $row->{individual_id} %>"> +% if ($top) { + <span class="widget"><a href="#" onclick="toggle_upgrade_history(this, '.upgrade-history-' + <% $row->{full_id} | n,j %>); return false";"></a></span> % } -</a><br /> - <%$CustomFieldObj->Description%> - </td> - <td valign="top"> - <i><% $CustomFieldObj->FriendlyTypeComposite %></i> - </td> -% # show 'move up' unless it's the first item -% if ($count++ and $Checked) { - <td valign="top"> - [<a href="<%RT->Config->Get('WebPath')%><% $m->request_comp->path |n %>?id=<%$id%>&SubType=<%$SubType%>&CustomField=<%$CustomFieldObj->id%>&Move=-1"><&|/l&>Move up</&></a>] -% } else { - <td valign="top" align="right"> -% } - -% # show 'move down' unless it's the last item -% if ($count != @CustomFields and $Checked) { -% $m->print(' | ') if $count > 1; - [<a href="<%RT->Config->Get('WebPath')%><% $m->request_comp->path |n %>?id=<%$id%>&SubType=<%$SubType%>&CustomField=<%$CustomFieldObj->id%>&Move=1"><&|/l&>Move down</&></a>] -% } - </td> + </td> + <td class="collection-as-table" style="padding-left: <% $indent * 3%>em"> +% if ($row->{'action'} eq 'upgrade') { # type is more specific for upgrades +<&|/l, $row->{'from'}, $row->{'to'} &>Upgrade from [_1] to [_2]</&> +% } elsif ( $row->{'action'} eq 'insert' ) { +<&|/l, $row->{filename} &>Insert from [_1]</&> +% } elsif ( $row->{'action'} eq 'schema' ) { +<&|/l, $row->{filename} &>Schema updates from [_1]</&> +% } elsif ( $row->{'action'} eq 'acl' ) { +<&|/l, $row->{filename} &>ACL updates from [_1]</&> +% } elsif ( $row->{'action'} eq 'indexes' ) { +<&|/l, $row->{filename} &>Index updates from [_1]</&> +% } else { +<% ucfirst($row->{action}) %> +% } +% if (not $complete) { + <&|/l&>(Incomplete)</&> +% } + </td> + <td class="collection-as-table"><% $timestamp->AsString %></td> + <td class="collection-as-table"><% $duration %></td> + <td class="collection-as-table"><% $row->{ext_version} || $row->{rt_version} %></td> </tr> +% for (@{$kids || []}) { +<& UpgradeHistoryRow, row => $_, indent => $indent+1, i => $i &> % } -</table> -% } -<%ARGS> -@CustomFields -$id -$ReadOnly => 0 -$Checked => 0 -$SubType -</%ARGS> +<%args> +$indent => 0 +$i +$row +</%args> +<%init> +my $complete = $row->{return_value} ? $row->{return_value}[0] : $row->{end}; +my $kids = $row->{sub_events}; +my $top = $row->{full_id} eq $row->{individual_id}; + +my @classes; +push @classes, $complete ? 'complete' : 'incomplete'; +push @classes, $$i++ % 2 ? 'oddline' : 'evenline'; +push @classes, 'upgrade-history-'.$row->{full_id} unless $top; + +my $timestamp = RT::Date->new($session{CurrentUser}); +$timestamp->Set(Value => $row->{timestamp}); + +my $duration = $row->{end} ? $timestamp->DurationAsString($row->{end} - $row->{timestamp}) : ''; +</%init> diff --git a/rt/share/html/Admin/Global/DashboardsInMenu.html b/rt/share/html/Admin/Global/DashboardsInMenu.html new file mode 100644 index 000000000..1422e7686 --- /dev/null +++ b/rt/share/html/Admin/Global/DashboardsInMenu.html @@ -0,0 +1,113 @@ +%# BEGIN BPS TAGGED BLOCK {{{ +%# +%# COPYRIGHT: +%# +%# This software is Copyright (c) 1996-2015 Best Practical Solutions, LLC +%# <sales@bestpractical.com> +%# +%# (Except where explicitly superseded by other copyright notices) +%# +%# +%# LICENSE: +%# +%# This work is made available to you under the terms of Version 2 of +%# the GNU General Public License. A copy of that license should have +%# been provided with this software, but in any event can be snarfed +%# from www.gnu.org. +%# +%# This work is distributed in the hope that it will be useful, but +%# WITHOUT ANY WARRANTY; without even the implied warranty of +%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +%# General Public License for more details. +%# +%# You should have received a copy of the GNU General Public License +%# along with this program; if not, write to the Free Software +%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +%# 02110-1301 or visit their web page on the internet at +%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html. +%# +%# +%# CONTRIBUTION SUBMISSION POLICY: +%# +%# (The following paragraph is not intended to limit the rights granted +%# to you to modify and distribute this software under the terms of +%# the GNU General Public License and is only of importance to you if +%# you choose to contribute your changes and enhancements to the +%# community by submitting them to Best Practical Solutions, LLC.) +%# +%# By intentionally submitting any modifications, corrections or +%# derivatives to this work, or any other work intended for use with +%# Request Tracker, to Best Practical Solutions, LLC, you confirm that +%# you are the copyright holder for those contributions and you grant +%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable, +%# royalty-free, perpetual, license to use, copy, create derivative +%# works based on those contributions, and sublicense and distribute +%# those contributions and any derivatives thereof. +%# +%# END BPS TAGGED BLOCK }}} +<& /Admin/Elements/Header, Title => loc("Dashboards in menu") &> +<& /Elements/Tabs &> + +<& /Elements/ListActions, actions => \@actions &> +<br /> +% for my $pane (@panes) { +<&|/Widgets/TitleBox, title => loc('Dashboards in menu'), bodyclass => "" &> +<& /Widgets/SelectionBox:show, self => $pane &></&> +<br /> +% } +<%init> +my @actions; +my $sys = RT::System->new( $session{'CurrentUser'} ); + +my $has_right = $session{'CurrentUser'}->HasRight( Object=> $RT::System, Right => 'SuperUser'); + +my ($dashboard_attr) = $sys->Attributes->Named('DashboardsInMenu'); +my $default_dashboards_in_menu = + $dashboard_attr && $dashboard_attr->Content->{dashboards} + ? $dashboard_attr->Content->{dashboards} + : []; + +use RT::Dashboards; +my $dashboards = RT::Dashboards->new( $RT::SystemUser ); +$dashboards->LimitToPrivacy('RT::System-' . $sys->id); + +my @dashboards; +while ( my $dashboard = $dashboards->Next ) { + push @dashboards, [$dashboard->id, $dashboard->Name]; +} + +my @panes = $m->comp( + '/Admin/Elements/ConfigureDashboardsInMenu', + Action => 'DashboardsInMenu.html', + panes => ['dashboards_in_menu'], + ReadOnly => !$has_right, + items => \@dashboards, + current_portlets => $default_dashboards_in_menu, + OnSave => sub { + my ( $conf ) = @_; + my ( $status, $msg ); + + if (!$has_right) { + push @actions, loc( 'Permission Denied' ); + } + elsif ( $dashboard_attr ) { + ($status, $msg) = $dashboard_attr->SetContent($conf); + } + else { + $dashboard_attr = RT::Attribute->new($RT::SystemUser); + ( $status, $msg ) = $dashboard_attr->Create( + Name => 'DashboardsInMenu', + Object => $sys, + Content => $conf, + ); + } + push @actions, $status ? loc('Global dashboards in menu saved.') : $msg; + } +); + +$m->comp( '/Widgets/SelectionBox:process', %ARGS, self => $_ ) + for @panes; + + +</%init> + diff --git a/rt/share/html/Admin/Global/MyRT.html b/rt/share/html/Admin/Global/MyRT.html index d903553e4..0a62d23f6 100644 --- a/rt/share/html/Admin/Global/MyRT.html +++ b/rt/share/html/Admin/Global/MyRT.html @@ -48,13 +48,11 @@ <& /Admin/Elements/Header, Title => loc("RT at a glance") &> <& /Elements/Tabs &> -<& /Widgets/SelectionBox:header, nojs => 1 &> - <& /Elements/ListActions, actions => \@actions &> <br /> % for my $pane (@panes) { <&|/Widgets/TitleBox, title => loc('RT at a glance').': '.loc($pane->{Name}), bodyclass => "" &> -<& /Widgets/SelectionBox:show, self => $pane, nojs => 1 &></&> +<& /Widgets/SelectionBox:show, self => $pane &></&> <br /> % } <%init> @@ -86,7 +84,7 @@ my @panes = $m->comp( '/Admin/Elements/ConfigureMyRT', panes => [ 'body', #loc - 'summary', #loc + 'sidebar', #loc ], Action => 'MyRT.html', items => \@items, @@ -95,7 +93,7 @@ my @panes = $m->comp( OnSave => sub { my ( $conf, $pane ) = @_; if (!$has_right) { - push @actions, loc( 'Permission denied' ); + push @actions, loc( 'Permission Denied' ); } else { $default_portlets->SetContent( $conf ); @@ -104,7 +102,7 @@ my @panes = $m->comp( } ); -$m->comp( '/Widgets/SelectionBox:process', %ARGS, self => $_, nojs => 1 ) +$m->comp( '/Widgets/SelectionBox:process', %ARGS, self => $_ ) for @panes; diff --git a/rt/share/html/Admin/Global/Template.html b/rt/share/html/Admin/Global/Template.html index c88d26c44..c2a802d3c 100755 --- a/rt/share/html/Admin/Global/Template.html +++ b/rt/share/html/Admin/Global/Template.html @@ -59,10 +59,10 @@ %# hang onto the queue id <input type="hidden" class="hidden" name="Queue" value="<%$Queue%>" /> <& /Admin/Elements/ModifyTemplate, - Name => $TemplateObj->Name, - Description => $TemplateObj->Description, - Content => $TemplateObj->Content, - Type => $TemplateObj->Type + Name => $TemplateObj->Name // $ARGS{Name}, + Description => $TemplateObj->Description // $ARGS{Description}, + Content => $TemplateObj->Content // $ARGS{Content}, + Type => $TemplateObj->Type // $ARGS{Type}, &> <& /Elements/Submit, Label => $SubmitLabel, Reset => 1 &> </form> @@ -73,35 +73,37 @@ my $TemplateObj = RT::Template->new($session{'CurrentUser'}); my ($title, @results, $SubmitLabel); -if ($Create) { - $title = loc("Create a template"); - $SubmitLabel = loc('Create'); -} - -else { - if (defined ($Template) && $Template eq 'new') { - my ($val, $msg) = $TemplateObj->Create(Queue => $Queue, Name => $Name, Type => $Type); - Abort(loc("Could not create template: [_1]", $msg)) unless ($val); - push @results, $msg; +if (!$Create) { + if (defined ($Template) && $Template eq 'new') { + my ($val, $msg) = $TemplateObj->Create(Queue => $Queue, Name => $Name, Type => $Type); + push @results, $msg; + } else { + $TemplateObj->Load($Template) || Abort(loc('No Template')); } - else { - $TemplateObj->Load($Template) || Abort(loc('No Template')); - } - $title = loc('Modify template [_1]', loc($TemplateObj->Name())); - $SubmitLabel = loc('Save Changes'); - } + if ($TemplateObj->Id()) { - my @attribs = qw( Name Description Queue Type Content ); - my @aresults = UpdateRecordObject( AttributesRef => \@attribs, - Object => $TemplateObj, - ARGSRef => \%ARGS); - push @results, @aresults; + my @attribs = qw( Name Description Queue Type Content ); + my @aresults = UpdateRecordObject( AttributesRef => \@attribs, + Object => $TemplateObj, + ARGSRef => \%ARGS); + push @results, @aresults; - my ($ok, $msg) = $TemplateObj->CompileCheck; - push @results, $msg if !$ok; + my ($ok, $msg) = $TemplateObj->CompileCheck; + push @results, $msg if !$ok; +} else { + $Create = 1; } +if ($Create) { + $title = loc("Create a template"); + $SubmitLabel = loc('Create'); +} else { + $title = loc('Modify template [_1]', loc($TemplateObj->Name())); + $SubmitLabel = loc('Save Changes'); +} + + </%INIT> <%ARGS> $Queue => '' diff --git a/rt/share/html/Admin/Global/index.html b/rt/share/html/Admin/Global/index.html index cdac7d9a2..223ecd007 100755 --- a/rt/share/html/Admin/Global/index.html +++ b/rt/share/html/Admin/Global/index.html @@ -47,4 +47,4 @@ %# END BPS TAGGED BLOCK }}} <& /Admin/Elements/Header, Title => loc('Admin/Global configuration') &> <& /Elements/Tabs &> -<& /Elements/ListMenu, menu => Menu()->child('tools')->child('config')->child('global') &> +<& /Elements/ListMenu, menu => Menu()->child('admin')->child('global') &> diff --git a/rt/share/html/Admin/Groups/History.html b/rt/share/html/Admin/Groups/History.html index bc3ff950a..45df06938 100644 --- a/rt/share/html/Admin/Groups/History.html +++ b/rt/share/html/Admin/Groups/History.html @@ -48,9 +48,10 @@ <& /Admin/Elements/Header, Title => $title &> <& /Elements/Tabs &> -<& /Ticket/Elements/ShowHistory, - Ticket => $GroupObj, +<& /Elements/ShowHistory, + Object => $GroupObj, ShowDisplayModes => 0, + DisplayPath => 'History.html', &> <%INIT> diff --git a/rt/share/html/Admin/Elements/SelectModifyQueue b/rt/share/html/Admin/Groups/Memberships.html index 81acc9e1b..1910ff5c2 100755..100644 --- a/rt/share/html/Admin/Elements/SelectModifyQueue +++ b/rt/share/html/Admin/Groups/Memberships.html @@ -45,13 +45,4 @@ %# those contributions and any derivatives thereof. %# %# END BPS TAGGED BLOCK }}} -%while ( $queue = $queues->Next) { -<a href="Modify.html?id=<%$queue->id%>"><%$queue->id%>: <%$queue->Name%></a><br /> -%} -<%INIT> -my ($queue); -my $queues = RT::Queues->new($session{'CurrentUser'}); -$queues->UnLimit; -</%INIT> -<%ARGS> -</%ARGS> +<& /Admin/Elements/MembershipsPage, %ARGS &> diff --git a/rt/share/html/Admin/Groups/Modify.html b/rt/share/html/Admin/Groups/Modify.html index eb10d14bc..6c65ea058 100755 --- a/rt/share/html/Admin/Groups/Modify.html +++ b/rt/share/html/Admin/Groups/Modify.html @@ -72,18 +72,17 @@ % my $CFs = $Group->CustomFields; % while (my $CF = $CFs->Next) { <tr valign="top"><td align="right"> -<% loc($CF->Name) %>: +<% $CF->Name %>: </td><td> <& /Elements/EditCustomField, CustomField => $CF, - Object => $Group, - ($Create ? (NamePrefix => 'Object-RT::Group--CustomField-') - : () )&> + Object => $Group, &> </td></tr> % } <tr> <td colspan="2"> <input type="hidden" class="hidden" name="SetEnabled" value="1" /> -<input type="checkbox" class="checkbox" name="Enabled" value="1" <%$EnabledChecked%> /> <&|/l&>Enabled (Unchecking this box disables this group)</&><br /> +<input type="checkbox" class="checkbox" id="Enabled" name="Enabled" value="1" <%$EnabledChecked%> /> +<label for="Enabled"><&|/l&>Enabled (Unchecking this box disables this group)</&></label><br /> </td> </tr> % $m->callback( %ARGS, GroupObj => $Group, results => \@results ); @@ -104,7 +103,7 @@ if ($Create) { $title = loc("Create a new group"); } else { if ($id eq 'new' ) { - my ($create_id, $create_msg) = $Group->CreateUserDefinedGroup(Name => $Name ); + my ($create_id, $create_msg) = $Group->CreateUserDefinedGroup(Name => $Name ); if ($create_id) { $id = $Group->Id; push @results, $create_msg; @@ -112,32 +111,32 @@ if ($Create) { push @results, loc("Group could not be created: [_1]", $create_msg); } } else { - $Group->Load($id) || Abort('Could not load group'); + $Group->Load($id) || Abort('Could not load group'); } if ($Group->Id) { - $title = loc("Modify the group [_1]", $Group->Name); + $title = loc("Modify the group [_1]", $Group->Name); } # If the create failed else { - $title = loc("Create a new group"); - $Create = 1; + $title = loc("Create a new group"); + $Create = 1; } } if ($Group->Id) { my @fields = qw(Description Name ); my @fieldresults = UpdateRecordObject ( AttributesRef => \@fields, - Object => $Group, - ARGSRef => \%ARGS ); + Object => $Group, + ARGSRef => \%ARGS ); push (@results,@fieldresults); push @results, ProcessObjectCustomFieldUpdates( ARGSRef => \%ARGS, Object => $Group ); # Warn about duplicate groups my $dupcheck = RT::Groups->new(RT->SystemUser); $dupcheck->LimitToUserDefinedGroups(); - $dupcheck->Limit( FIELD => 'Name', VALUE => $Group->Name ); + $dupcheck->Limit( FIELD => 'Name', VALUE => $Group->Name, CASESENSITIVE => 0 ); if ($dupcheck->Count > 1) { push @warnings, loc("There is more than one group with the name '[_1]'. This may cause inconsistency in parts of the admin interface, and therefore it's recommended you rename the conflicting groups.", $Group->Name); } diff --git a/rt/share/html/Admin/Groups/index.html b/rt/share/html/Admin/Groups/index.html index 43a1c6748..7298f28f4 100755 --- a/rt/share/html/Admin/Groups/index.html +++ b/rt/share/html/Admin/Groups/index.html @@ -53,18 +53,12 @@ <input type="hidden" name="GroupField" value="Name" /> <input type="hidden" name="GroupOp" value="LIKE" /> <&|/l&>Go to group</&> -<input type="text" name="GroupString" value="" id="autocomplete-GroupString" /> +<input type="text" name="GroupString" value="" data-autocomplete="Groups" id="autocomplete-GroupString" /> <script type="text/javascript"> jQuery(function(){ - jQuery("#autocomplete-GroupString").autocomplete({ - source: <% RT->Config->Get('WebPath') |n,j%>+"/Helpers/Autocomplete/Groups", - // Auto-submit once a group is chosen - select: function( event, ui ) { - jQuery(event.target).val(ui.item.value); - var form = jQuery(event.target).closest('form'); - form.find('input[name=GroupOp]').val('='); - form.submit(); - } + // Jump directly to the page if a group is chosen + jQuery("#autocomplete-GroupString").on("autocompleteselect", function( event, ui ) { + document.location = RT.Config.WebPath + "/Admin/Groups/Modify.html?id=" + ui.item.id; }); }); </script> @@ -72,7 +66,8 @@ jQuery(function(){ <form method="post" action="<% RT->Config->Get('WebPath') %>/Admin/Groups/index.html"> <&|/l&>Find groups whose</&> <& /Elements/SelectGroups &><br /> -<input type="checkbox" class="checkbox" name="FindDisabledGroups" value="1" <% $FindDisabledGroups? 'checked="checked"': '' |n %> /> <&|/l&>Include disabled groups in listing.</&><br /> +<input type="checkbox" class="checkbox" id="FindDisabledGroups" name="FindDisabledGroups" value="1" <% $FindDisabledGroups? 'checked="checked"': '' |n %> /> +<label for="FindDisabledGroups"><&|/l&>Include disabled groups in listing.</&></label><br /> <div align="right"><input type="submit" class="button" value="<&|/l&>Go!</&>" /></div> </form> @@ -84,7 +79,7 @@ jQuery(function(){ <& /Elements/CollectionList, OrderBy => 'Name', Order => 'ASC', - Rows => 100, + Rows => $Rows, %ARGS, Format => $Format, Collection => $Groups, @@ -106,18 +101,18 @@ if ($FindDisabledGroups) { if (length $GroupString) { $caption = loc("Groups matching search criteria"); if ($GroupField =~ /^CustomField-(\d+)/) { - $Groups->LimitCustomField( - CUSTOMFIELD => $1, - OPERATOR => $GroupOp, - VALUE => $GroupString, - ); + $Groups->LimitCustomField( + CUSTOMFIELD => $1, + OPERATOR => $GroupOp, + VALUE => $GroupString, + ); } else { - $Groups->Limit( - FIELD => $GroupField, - OPERATOR => $GroupOp, - VALUE => $GroupString, - ); + $Groups->Limit( + FIELD => $GroupField, + OPERATOR => $GroupOp, + VALUE => $GroupString, + ); } RT::Interface::Web::Redirect(RT->Config->Get('WebURL')."Admin/Groups/Modify.html?id=".$Groups->First->id) if $Groups->Count == 1 and $Groups->First; @@ -127,6 +122,7 @@ else { } $Format ||= RT->Config->Get('AdminSearchResultFormat')->{'Groups'}; +my $Rows = RT->Config->Get('AdminSearchResultRows')->{'Groups'} || 50; </%INIT> <%ARGS> diff --git a/rt/share/html/Admin/Queues/History.html b/rt/share/html/Admin/Queues/History.html index 1b4a1abed..8b74a4782 100644 --- a/rt/share/html/Admin/Queues/History.html +++ b/rt/share/html/Admin/Queues/History.html @@ -48,9 +48,10 @@ <& /Admin/Elements/Header, Title => $title &> <& /Elements/Tabs &> -<& /Ticket/Elements/ShowHistory, - Ticket => $QueueObj, +<& /Elements/ShowHistory, + Object => $QueueObj, ShowDisplayModes => 0, + DisplayPath => 'History.html', &> <%INIT> diff --git a/rt/share/html/Admin/Queues/Modify.html b/rt/share/html/Admin/Queues/Modify.html index e9afc7ec5..9610b2519 100755 --- a/rt/share/html/Admin/Queues/Modify.html +++ b/rt/share/html/Admin/Queues/Modify.html @@ -52,26 +52,33 @@ <form action="<%RT->Config->Get('WebPath')%>/Admin/Queues/Modify.html" name="ModifyQueue" method="post" enctype="multipart/form-data"> -<input type="hidden" class="hidden" name="SetEnabled" value="1" /> <input type="hidden" class="hidden" name="id" value="<% $Create? 'new': $QueueObj->Id %>" /> <table> -<tr><td align="right"><&|/l&>Queue Name</&>:</td> -<td colspan="3"><input name="Name" value="<% $Create ? "" : $QueueObj->Name || $Name %>" /></td> -</tr> +<tr><td align="right"><&|/l&>Queue Name</&>:</td><td colspan="3"> +% if ($InternalQueue) { +<% $QueueObj->Name %> +% } else { +<input name="Name" value="<% $Create ? "" : $QueueObj->Name || $Name %>" /> +% } +</td></tr> <tr><td align="right"><&|/l&>Description</&>:</td> <td colspan="3"><input name="Description" value="<% $Create ? "" : $QueueObj->Description || $Description || '' %>" size="60" /></td> </tr> -<tr><td align="right"><&|/l&>Lifecycle</&>:</td> -<td colspan="3"><& /Widgets/Form/Select:InputOnly, +<tr><td align="right"><&|/l&>Lifecycle</&>:</td><td colspan="3"> +% if ($InternalQueue) { +<% $QueueObj->Lifecycle %> +% } else { +<& /Widgets/Form/Select:InputOnly, Name => 'Lifecycle', Values => [ sort { loc($a) cmp loc($b) } RT::Lifecycle->List ], CurrentValue => $Create ? "default" : $QueueObj->Lifecycle || $ARGS{'Lifecycle'}, Default => 0, -&></td> -</tr> +&> +% } +</td></tr> <tr><td align="right"><&|/l&>Subject Tag</&>:</td> <td colspan="3"><input name="SubjectTag" value="<% $ARGS{'SubjectTag'} || ($Create ? "" : $QueueObj->SubjectTag || '' ) %>" size="60" /></td> @@ -104,38 +111,40 @@ % my $CFs = $QueueObj->CustomFields; % while (my $CF = $CFs->Next) { <tr valign="top"><td align="right"> -<% loc($CF->Name) %>: +<% $CF->Name %>: </td><td> -<& /Elements/EditCustomField, CustomField => $CF, - Object => $QueueObj, - ($Create ? (NamePrefix => 'Object-RT::Queue--CustomField-') - : () )&> +<& /Elements/EditCustomField, CustomField => $CF, + Object => $QueueObj, &> </td></tr> % } -% if ( RT->Config->Get('GnuPG')->{'Enable'} ) { -<tr><td align="right"><input type="checkbox" class="checkbox" name="Sign" value="1" <% $QueueObj->Sign? 'checked="checked"': '' |n%> /></td> -<td><&|/l&>Sign by default</&></td> -<td align="right"><input type="checkbox" class="checkbox" name="Encrypt" value="1" <% $QueueObj->Encrypt? 'checked="checked"': '' |n%> /></td> -<td><&|/l&>Encrypt by default</&></td> +% if ( RT->Config->Get('Crypt')->{'Enable'} ) { +<tr><td align="right"><input type="checkbox" class="checkbox" id="Sign" name="Sign" value="1" <% $QueueObj->Sign? 'checked="checked"': '' |n%> /></td> +<td><label for="Sign"><&|/l&>Sign by default</&></label></td> +<td align="right"><input type="checkbox" class="checkbox" id="Encrypt" name="Encrypt" value="1" <% $QueueObj->Encrypt? 'checked="checked"': '' |n%> /></td> +<td><label for="Encrypt"><&|/l&>Encrypt by default</&></label></td> </tr> -<tr><td align="right"><input type="checkbox" class="checkbox" name="SignAuto" value="1" <% $QueueObj->SignAuto? 'checked="checked"': '' |n%> /></td> -<td colspan="3"><&|/l_unsafe, "<b>","</b>","<i>","</i>"&>Sign all auto-generated mail. [_1]Caution[_2]: Enabling this option alters the signature from providing [_3]authentication[_4] to providing [_3]integrity[_4].</&></td></tr> +<tr><td align="right"><input type="checkbox" class="checkbox" id="SignAuto" name="SignAuto" value="1" <% $QueueObj->SignAuto? 'checked="checked"': '' |n%> /></td> +<td colspan="3"><label for="SignAuto"><&|/l_unsafe, "<b>","</b>","<i>","</i>"&>Sign all auto-generated mail. [_1]Caution[_2]: Enabling this option alters the signature from providing [_3]authentication[_4] to providing [_3]integrity[_4].</&></label></td></tr> % } -<tr><td align="right"><input type="checkbox" class="checkbox" name="Enabled" value="1" <%$EnabledChecked|n%> /></td> -<td colspan="3"><&|/l&>Enabled (Unchecking this box disables this queue)</&><br /> +% unless ($InternalQueue) { +<tr><td align="right"><input type="checkbox" class="checkbox" id="Enabled" name="Enabled" value="1" <%$EnabledChecked|n%> /></td> +<td colspan="3"><label for="Enabled"><&|/l&>Enabled (Unchecking this box disables this queue)</&></label><br /> +<input type="hidden" class="hidden" name="SetEnabled" value="1" /> % $m->callback( %ARGS, QueueObj => $QueueObj, results => \@results ); </td></tr> +% } -% if ( RT->Config->Get('GnuPG')->{'Enable'} ) { +% if ( RT->Config->Get('Crypt')->{'Enable'} ) { <tr><td colspan="4"> +<input type="hidden" class="hidden" name="SetCrypt" value="1" /> % if ( my $email = $QueueObj->CorrespondAddress || RT->Config->Get('CorrespondAddress') ) { <& /Admin/Elements/ShowKeyInfo, Type => 'private', EmailAddress => $email &> % } else { -<&|/Widgets/TitleBox, title => loc( 'GnuPG private keys') &> -<i><&|/l&>You have enabled GnuPG support but have not set a correspondence address for this queue.</&> -<&|/l&>You must set a correspondence address for this queue in order to configure a GnuPG private key.</&></i> +<&|/Widgets/TitleBox, title => loc( 'Private keys') &> +<i><&|/l&>You have enabled encryption support but have not set a correspondence address for this queue.</&> +<&|/l&>You must set a correspondence address for this queue in order to configure a private key.</&></i> </&> % } </td></tr> @@ -143,9 +152,9 @@ % if ( my $email = $QueueObj->CommentAddress || RT->Config->Get('CommentAddress') ) { <& /Admin/Elements/ShowKeyInfo, Type => 'private', EmailAddress => $email &> % } else { -<&|/Widgets/TitleBox, title => loc( 'GnuPG private keys') &> -<i><&|/l&>You have enabled GnuPG support but have not set a comment address for this queue.</&> -<&|/l&>You must set a comment address for this queue in order to configure a GnuPG private key.</&></i> +<&|/Widgets/TitleBox, title => loc( 'Private keys') &> +<i><&|/l&>You have enabled encryption support but have not set a comment address for this queue.</&> +<&|/l&>You must set a comment address for this queue in order to configure a private key.</&></i> </&> %} </td></tr> @@ -188,8 +197,10 @@ if ( $QueueObj->Id ) { # we're asking about enabled on the web page but really care about disabled if ( $SetEnabled ) { $Disabled = $ARGS{'Disabled'} = $Enabled? 0: 1; + } + if ( $SetCrypt ) { $ARGS{$_} = 0 foreach grep !defined $ARGS{$_} || !length $ARGS{$_}, - qw(Sign SignAuto Encrypt Disabled); + qw(Sign SignAuto Encrypt); } $m->callback( @@ -229,6 +240,8 @@ if ( $QueueObj->Id ) { $title = loc("Create a queue"); } +my $InternalQueue = ($QueueObj->Id and $QueueObj->Disabled == 2); + # This code does automatic redirection if any updates happen. MaybeRedirectForResults( Actions => \@results, @@ -251,5 +264,6 @@ $InitialPriority => undef $FinalPriority => undef $DefaultDueIn => undef $SetEnabled => undef +$SetCrypt => undef $Enabled => undef </%ARGS> diff --git a/rt/share/html/Admin/Queues/People.html b/rt/share/html/Admin/Queues/People.html index 8a226e894..2d0bb910a 100755 --- a/rt/share/html/Admin/Queues/People.html +++ b/rt/share/html/Admin/Queues/People.html @@ -174,10 +174,7 @@ if ( $ARGS{'UserString'} ) { if ( $ARGS{'GroupString'} ) { $Groups = RT::Groups->new( $session{'CurrentUser'} ); - $Groups->Limit( FIELD => 'Domain', - OPERATOR => '=', - VALUE => 'UserDefined' - ); + $Groups->LimitToUserDefinedGroups; $Groups->Limit( FIELD => $ARGS{'GroupField'}, VALUE => $ARGS{'GroupString'}, OPERATOR => $ARGS{'GroupOp'} diff --git a/rt/share/html/Admin/Queues/Scrips.html b/rt/share/html/Admin/Queues/Scrips.html index 02d91a053..e179cce92 100755 --- a/rt/share/html/Admin/Queues/Scrips.html +++ b/rt/share/html/Admin/Queues/Scrips.html @@ -47,24 +47,13 @@ %# END BPS TAGGED BLOCK }}} <& /Admin/Elements/Header, Title => $title &> <& /Elements/Tabs &> - -% unless ( $QueueObj->Disabled ) { # Global scrips does not apply to disabled queues -<h2><&|/l&>Scrips which apply to all queues</&></h2> -<& /Admin/Elements/ListGlobalScrips &> -<br /> -% } <& /Admin/Elements/EditScrips, title => $title, %ARGS &> <%init> my $QueueObj = RT::Queue->new($session{'CurrentUser'}); $QueueObj->Load($id); +Abort(loc("Queue [_1] not found",$id)) unless $QueueObj->id; -my $title; - -if ($QueueObj->id) { - $title = loc("Modify scrips for queue [_1]", $QueueObj->Name); -} else { - Abort(loc("Queue [_1] not found",$id)); -} +my $title = loc("Modify scrips for queue [_1]", $QueueObj->Name); </%init> <%ARGS> diff --git a/rt/share/html/Admin/Queues/Template.html b/rt/share/html/Admin/Queues/Template.html index 8e4cd2362..7e58ec787 100755 --- a/rt/share/html/Admin/Queues/Template.html +++ b/rt/share/html/Admin/Queues/Template.html @@ -59,10 +59,10 @@ %# hang onto the queue id <input type="hidden" class="hidden" name="Queue" value="<%$Queue%>" /> <& /Admin/Elements/ModifyTemplate, - Name => $TemplateObj->Name, - Description => $TemplateObj->Description, - Content => $TemplateObj->Content, - Type => $TemplateObj->Type + Name => $TemplateObj->Name // $ARGS{Name}, + Description => $TemplateObj->Description // $ARGS{Description}, + Content => $TemplateObj->Content // $ARGS{Content}, + Type => $TemplateObj->Type // $ARGS{Type}, &> <& /Elements/Submit, Label => $SubmitLabel, Reset => 1 &> </form> @@ -80,7 +80,6 @@ if ( !$Create ) { if ( $Template eq 'new' ) { my ( $val, $msg ) = $TemplateObj->Create( Queue => $Queue, Name => $Name, Type => $Type ); - Abort( loc( "Could not create template: [_1]", $msg ) ) unless ($val); push @results, $msg; } else { $TemplateObj->Load($Template) || Abort( loc('No Template') ); @@ -102,6 +101,7 @@ if ( $TemplateObj->Id() ) { my ( $ok, $msg ) = $TemplateObj->CompileCheck; push @results, $msg if !$ok; } else { + $Create = 1; $QueueObj = RT::Queue->new( $session{'CurrentUser'} ); $QueueObj->Load($Queue); } diff --git a/rt/share/html/Admin/Queues/index.html b/rt/share/html/Admin/Queues/index.html index 672b4fac1..4b01825a2 100755 --- a/rt/share/html/Admin/Queues/index.html +++ b/rt/share/html/Admin/Queues/index.html @@ -48,9 +48,28 @@ <& /Admin/Elements/Header, Title => loc("Admin queues") &> <& /Elements/Tabs &> +<h1><%$caption%></h1> +<form method="post" action="<% RT->Config->Get('WebPath') %>/Admin/Queues/index.html"> +% foreach my $field( qw(Format Rows Page Order OrderBy) ) { +% next unless defined $ARGS{ $field } && length $ARGS{ $field }; +<input type="hidden" name="<% $field %>" value="<% $ARGS{ $field } %>" /> +% } + +<select name="QueueField"> +% foreach my $col (qw(Name Description CorrespondAddress CommentAddress InitialPriority FinalPriority DefaultDueIn Lifecycle SubjectTag)) { +<option <% $QueueField eq $col ? 'selected="selected"' : '' |n %> value="<% $col %>"><% loc($col) %></option> +% } +</select> +<& /Elements/SelectMatch, Name => 'QueueOp', Default => $QueueOp &> +<input size="8" name="QueueString" value="<% $QueueString %>" /> +<br /> + +<input type="checkbox" class="checkbox" id="FindDisabledQueues" name="FindDisabledQueues" value="1" <% $FindDisabledQueues? 'checked="checked"': '' |n%> /> +<label for="FindDisabledQueues"><&|/l&>Include disabled queues in listing.</&></label> +<div align="right"><input type="submit" class="button" value="<&|/l&>Go!</&>" /></div> +</form> -<h1><%$caption%></h1> <p><&|/l&>Select a queue</&>:</p> % unless ( $queues->Count ) { <em><&|/l&>No queues matching search criteria found.</&></em> @@ -58,7 +77,7 @@ <& /Elements/CollectionList, OrderBy => 'Name', Order => 'ASC', - Rows => 50, + Rows => $Rows, %ARGS, Format => $Format, Collection => $queues, @@ -69,25 +88,6 @@ )], &> % } -<form method="post" action="<% RT->Config->Get('WebPath') %>/Admin/Queues/index.html"> -% foreach my $field( qw(Format Rows Page Order OrderBy) ) { -% next unless defined $ARGS{ $field } && length $ARGS{ $field }; -<input type="hidden" name="<% $field %>" value="<% $ARGS{ $field } %>" /> -% } - -<select name="QueueField"> -% foreach my $col (qw(Name Description CorrespondAddress CommentAddress InitialPriority FinalPriority DefaultDueIn)) { -<option <% $QueueField eq $col ? 'selected="selected"' : '' |n %> value="<% $col %>"><% loc($col) %></option> -% } -</select> -<& /Elements/SelectMatch, Name => 'QueueOp', Default => $QueueOp &> -<input size="8" name="QueueString" value="<% $QueueString %>" /> -<br /> - -<input type="checkbox" class="checkbox" name="FindDisabledQueues" value="1" <% $FindDisabledQueues? 'checked="checked"': '' |n%> /> -<&|/l&>Include disabled queues in listing.</&> -<div align="right"><input type="submit" class="button" value="<&|/l&>Go!</&>" /></div> -</form> <%INIT> my $queues = RT::Queues->new($session{'CurrentUser'}); @@ -113,6 +113,7 @@ if ( defined $QueueString && length $QueueString ) { } $Format ||= RT->Config->Get('AdminSearchResultFormat')->{'Queues'}; +my $Rows = RT->Config->Get('AdminSearchResultRows')->{'Queues'} || 50; </%INIT> <%ARGS> @@ -120,6 +121,6 @@ $FindDisabledQueues => 0 $Format => undef $QueueField => 'Name' -$QueueOp => '=' +$QueueOp => 'LIKE' $QueueString => '' </%ARGS> diff --git a/rt/share/html/Admin/Scrips/Create.html b/rt/share/html/Admin/Scrips/Create.html new file mode 100644 index 000000000..7716ea89e --- /dev/null +++ b/rt/share/html/Admin/Scrips/Create.html @@ -0,0 +1,147 @@ +%# BEGIN BPS TAGGED BLOCK {{{ +%# +%# COPYRIGHT: +%# +%# This software is Copyright (c) 1996-2015 Best Practical Solutions, LLC +%# <sales@bestpractical.com> +%# +%# (Except where explicitly superseded by other copyright notices) +%# +%# +%# LICENSE: +%# +%# This work is made available to you under the terms of Version 2 of +%# the GNU General Public License. A copy of that license should have +%# been provided with this software, but in any event can be snarfed +%# from www.gnu.org. +%# +%# This work is distributed in the hope that it will be useful, but +%# WITHOUT ANY WARRANTY; without even the implied warranty of +%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +%# General Public License for more details. +%# +%# You should have received a copy of the GNU General Public License +%# along with this program; if not, write to the Free Software +%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +%# 02110-1301 or visit their web page on the internet at +%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html. +%# +%# +%# CONTRIBUTION SUBMISSION POLICY: +%# +%# (The following paragraph is not intended to limit the rights granted +%# to you to modify and distribute this software under the terms of +%# the GNU General Public License and is only of importance to you if +%# you choose to contribute your changes and enhancements to the +%# community by submitting them to Best Practical Solutions, LLC.) +%# +%# By intentionally submitting any modifications, corrections or +%# derivatives to this work, or any other work intended for use with +%# Request Tracker, to Best Practical Solutions, LLC, you confirm that +%# you are the copyright holder for those contributions and you grant +%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable, +%# royalty-free, perpetual, license to use, copy, create derivative +%# works based on those contributions, and sublicense and distribute +%# those contributions and any derivatives thereof. +%# +%# END BPS TAGGED BLOCK }}} +<& /Admin/Elements/Header, Title => $title &> +<& /Elements/Tabs &> +<& /Elements/ListActions, actions => \@results &> + +<form method="post" action="Create.html" id="CreateScrip" name="CreateScrip"> +<input type="hidden" class="hidden" name="Queue" value="<% $Queue %>" /> +<input type="hidden" class="hidden" name="Global" value="<% $Global || q{} %>" /> + +<&| /Widgets/TitleBox, title => loc('Basics') &> +<table> + +<& Elements/EditBasics, %ARGS, Scrip => $scrip, Queue => $queue_obj &> + +<tr><td class="label"><&|/l&>Stage</&>:</td><td class="value">\ +<& /Admin/Elements/SelectStage, Default => $ARGS{"Stage"} &></td></tr> + +<tr><td class="label"> </td><td> +<input type="hidden" class="hidden" name="SetEnabled" value="1" /> +<input type="checkbox" class="checkbox" name="Enabled" value="1" <% $ARGS{'Enabled'}? 'checked="checked"': '' |n%> /> +<label for="Enabled"><&|/l&>Enabled (Unchecking this box disables this scrip)</&></label> +</td></tr> + +</table> +</&> + +<& /Elements/Submit, + Label => loc('Create'), + Name => 'Create', +&> + +% if ($session{CurrentUser}->HasRight(Object => $RT::System, Right => 'ExecuteCode')) { +<& Elements/EditCustomCode, %ARGS, Scrip => $scrip &> +<& /Elements/Submit, + Label => loc('Create'), + Name => 'Create', +&> +% } + +</form> +<%ARGS> +$Queue => 0 +$Create => undef +$Global => undef +</%ARGS> +<%INIT> +my @results; + +$ARGS{'Enabled'} = 1 unless $ARGS{'SetEnabled'}; + +my $queue_obj; +if ( $Queue ) { + $queue_obj = RT::Queue->new( $session{'CurrentUser'} ); + $queue_obj->Load( $Queue ); + Abort( loc("Couldn't load queue [_1]", $Queue) ) + unless $queue_obj->id; +} + +my $title; +if ( $queue_obj ) { + $title = loc('Create a scrip and add to queue [_1]', $queue_obj->Name ); +} else { + $title = loc('Create a global scrip'); +} + +my $scrip = RT::Scrip->new( $session{'CurrentUser'} ); +if ( $Create ) { + my ($status, $msg) = $scrip->Create( + Description => $ARGS{"Description"}, + + Queue => $Queue || 0, + Stage => $ARGS{"Stage"}, + Disabled => $ARGS{"Disabled"}, + + ScripAction => $ARGS{"ScripAction"}, + ScripCondition => $ARGS{"ScripCondition"}, + Template => $ARGS{"Template"}, + + CustomPrepareCode => $ARGS{"CustomPrepareCode"}, + CustomCommitCode => $ARGS{"CustomCommitCode"}, + CustomIsApplicableCode => $ARGS{"CustomIsApplicableCode"}, + ); + + MaybeRedirectForResults( + Force => 1, + Actions => [ $msg ], + Path => 'Admin/Scrips/Modify.html', + Arguments => { + id => $scrip->id, + $Queue ? ( + From => $Queue, + ) : $Global ? ( + From => 'Global', + ) : () + }, + ) if $status; + + push @results, $msg; +} + +</%INIT> diff --git a/rt/share/html/Admin/Elements/SelectScrip b/rt/share/html/Admin/Scrips/Elements/EditBasics index e55804a26..ed7a800e4 100755..100644 --- a/rt/share/html/Admin/Elements/SelectScrip +++ b/rt/share/html/Admin/Scrips/Elements/EditBasics @@ -45,28 +45,30 @@ %# those contributions and any derivatives thereof. %# %# END BPS TAGGED BLOCK }}} -<select name="<%$Name%>"> -<option value="" -<% $Default eq undef && qq[ selected="selected"] |n %> ->-</option> -%while (my $Scrip = $Scrips->Next) { -<option value="<% $Scrip->Id %>" -<% $Scrip->Id == $Default && qq[ selected="selected"] |n %> -><% loc($Scrip->Name) %> -</option> -%} -</select> +<tr><td class="label"><&|/l&>Description</&>:</td><td class="value">\ +<input name="Description" \ + size="60" \ + value="<% $ARGS{"Description"} || $Scrip->Description || '' %>" /> +</td></tr> -<%INIT> -my $Scrips = RT::Scrips->new($session{'CurrentUser'}); -$Scrips->UnLimit; +<tr><td class="label"><&|/l&>Condition</&>:</td><td class="value">\ +<& /Admin/Elements/SelectScripCondition, + Default => $ARGS{"ScripCondition"} || $Scrip->ConditionObj->Id, +&></td></tr> +<tr><td class="label"><&|/l&>Action</&>:</td><td class="value">\ +<& /Admin/Elements/SelectScripAction, + Default => $ARGS{"ScripAction"} || $Scrip->ActionObj->Id, +&></td></tr> +<tr><td class="label"><&|/l&>Template</&>:</td><td class="value">\ +<& SelectTemplate, + Default => $ARGS{"Template"}, Scrip => $Scrip, Queue => $Queue, +&></td></tr> -</%INIT> <%ARGS> - -$Default => undef -$Name => 'Scrip' - +$Scrip +$Queue => undef </%ARGS> +<%INIT> +</%INIT> diff --git a/rt/share/html/Admin/Elements/QueueRightsForUser b/rt/share/html/Admin/Scrips/Elements/EditCustomCode index 2dc99a295..dfd0fdbc9 100755..100644 --- a/rt/share/html/Admin/Elements/QueueRightsForUser +++ b/rt/share/html/Admin/Scrips/Elements/EditCustomCode @@ -45,20 +45,33 @@ %# those contributions and any derivatives thereof. %# %# END BPS TAGGED BLOCK }}} -<ul> -%while(my $ACE = $ACL->Next) { +<&| /Widgets/TitleBox, title => loc('User Defined conditions and results') &> -<li><checkbox name="delete_ace_<%$ACE->id%>" value="1"> <% loc($ACE->RightName) %> (<%$ACE->UserObj->RealName%>) +<table> +<tr><td colspan="2" class="comment"> +<i><&|/l&>(Use these fields when you choose 'User Defined' for a condition or action)</&></i> +</td></tr> -%} -</ul> +% while ( my ($method, $desc) = splice @list, 0, 2 ) { +<tr><td class="labeltop"><% $desc %>:</td><td class="value"> +% my $code = $ARGS{ $method } || $Scrip->$method() || ''; +% my $lines = @{[ $code =~ /\n/gs ]} + 3; +% $lines = $min_lines if $lines < $min_lines; +<textarea cols="80" rows="<% $lines %>" name="<% $method %>"><% $code %></textarea> +</td></tr> +% } -<%INIT> -my $ACL = RT::ACL->new($session{'CurrentUser'}); -$ACL->LimitToQueue($QueueObj->id); -$ACL->LimitPrincipalToUser($PrincipalId); -</%INIT> +</table> +</&> <%ARGS> -$PrincipalId => undef -$QueueObj => undef +$Scrip </%ARGS> +<%INIT> +my @list = ( + CustomIsApplicableCode => loc('Custom condition'), + CustomPrepareCode => loc('Custom action preparation code'), + CustomCommitCode => loc('Custom action commit code'), +); + +my $min_lines = 10; +</%INIT> diff --git a/rt/share/html/Admin/Elements/SelectTemplate b/rt/share/html/Admin/Scrips/Elements/SelectTemplate index 02b78405a..ee7e96bf5 100755..100644 --- a/rt/share/html/Admin/Elements/SelectTemplate +++ b/rt/share/html/Admin/Scrips/Elements/SelectTemplate @@ -45,33 +45,64 @@ %# those contributions and any derivatives thereof. %# %# END BPS TAGGED BLOCK }}} -<select name="<%$Name%>"> -<option value="" -<% defined($Default) && $Default eq 'none' && qq[ selected="selected"] |n %>>-</option> -%while (my $Template = $PrimaryTemplates->Next) { -<option value="<%$Template->Id%>" <% ($Template->Id == $Default) && qq[ selected="selected"] |n %>><% loc($Template->Name) %></option> -%} -%while (my $Template = $OtherTemplates->Next) { -<option value="<%$Template->Id%>" <% defined($Default) && ($Template->Id == $Default) && qq[ selected="selected"] |n %>><&|/l, loc($Template->Name) &>Global template: [_1]</&></option> -%} +<select name="<% $Name %>"> +<option value=""><% $current || '-' %></option> +% foreach my $name ( @list ) { +<option value="<% $name %>" \ + <% lc($Default||'') eq lc $name ? 'selected="selected"' : '' |n %> +><% loc($name) %></option> +% } </select> - +<%ARGS> +$Name => 'Template' +$Queue => undef +$Scrip => undef +$Default => undef +</%ARGS> <%INIT> +my $current; +$current = $Scrip->Template if $Scrip; + +my @list; +if ( $Scrip && $Scrip->id && !$Scrip->IsAddedToAny ) { + my $templates = RT::Templates->new($session{'CurrentUser'}); + $templates->UnLimit; + @list = $templates->DistinctFieldValues('Name'); +} else { + my $global = RT::Templates->new($session{'CurrentUser'}); + $global->LimitToGlobal; + + my %global; -my $PrimaryTemplates = RT::Templates->new($session{'CurrentUser'}); -if ($Queue != 0) { -$PrimaryTemplates->LimitToQueue($Queue); -$PrimaryTemplates->OrderBy(FIELD => 'Name'); + while (my $t = $global->Next) { + $global{ lc $t->Name } = $t->Name + } + + my @queues; + push @queues, @{ $Scrip->AddedTo->ItemsArrayRef } if $Scrip && $Scrip->id; + push @queues, $Queue if $Queue && $Queue->id; + + my (%names, %counters); + foreach my $queue ( @queues ) { + my $templates = RT::Templates->new($session{'CurrentUser'}); + $templates->LimitToQueue( $queue->id ); + foreach my $name ( map $_->Name, @{ $templates->ItemsArrayRef } ) { + next if $global{ lc $name }; + $counters{ lc $name }++; + $names{lc $name} = $name; + } + } + delete $counters{ $_ } + foreach grep $counters{$_} != @queues, + keys %counters; + + @list = + map $global{$_} || $names{$_}, + keys %global, keys %counters; } -my $OtherTemplates = RT::Templates->new($session{'CurrentUser'}); -$OtherTemplates->LimitToGlobal; -$OtherTemplates->OrderBy(FIELD => 'Name'); +@list = sort { lc loc($a) cmp lc loc($b) } @list + if @list; </%INIT> -<%ARGS> -$Queue => undef -$Default => 'none' -$Name => 'Template' -</%ARGS> diff --git a/rt/share/html/Admin/Scrips/Modify.html b/rt/share/html/Admin/Scrips/Modify.html new file mode 100644 index 000000000..b6315ad5d --- /dev/null +++ b/rt/share/html/Admin/Scrips/Modify.html @@ -0,0 +1,141 @@ +%# BEGIN BPS TAGGED BLOCK {{{ +%# +%# COPYRIGHT: +%# +%# This software is Copyright (c) 1996-2015 Best Practical Solutions, LLC +%# <sales@bestpractical.com> +%# +%# (Except where explicitly superseded by other copyright notices) +%# +%# +%# LICENSE: +%# +%# This work is made available to you under the terms of Version 2 of +%# the GNU General Public License. A copy of that license should have +%# been provided with this software, but in any event can be snarfed +%# from www.gnu.org. +%# +%# This work is distributed in the hope that it will be useful, but +%# WITHOUT ANY WARRANTY; without even the implied warranty of +%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +%# General Public License for more details. +%# +%# You should have received a copy of the GNU General Public License +%# along with this program; if not, write to the Free Software +%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +%# 02110-1301 or visit their web page on the internet at +%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html. +%# +%# +%# CONTRIBUTION SUBMISSION POLICY: +%# +%# (The following paragraph is not intended to limit the rights granted +%# to you to modify and distribute this software under the terms of +%# the GNU General Public License and is only of importance to you if +%# you choose to contribute your changes and enhancements to the +%# community by submitting them to Best Practical Solutions, LLC.) +%# +%# By intentionally submitting any modifications, corrections or +%# derivatives to this work, or any other work intended for use with +%# Request Tracker, to Best Practical Solutions, LLC, you confirm that +%# you are the copyright holder for those contributions and you grant +%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable, +%# royalty-free, perpetual, license to use, copy, create derivative +%# works based on those contributions, and sublicense and distribute +%# those contributions and any derivatives thereof. +%# +%# END BPS TAGGED BLOCK }}} +<& /Admin/Elements/Header, Title => loc("Modify scrip #[_1]", $id) &> +<& /Elements/Tabs &> +<& /Elements/ListActions, actions => \@results &> + +<form method="post" action="Modify.html" id="ModifyScrip" name="ModifyScrip"> +<input type="hidden" class="hidden" name="id" value="<% $id %>" /> +<input type="hidden" class="hidden" name="From" value="<% $From || q{} %>" /> + +<&| /Widgets/TitleBox, title => loc('Basics') &> +<table> + +<& Elements/EditBasics, %ARGS, Scrip => $scrip &> + +% if ( not $disabled ) { +<tr><td class="label"><a href="Objects.html?id=<% $id %>"><&|/l&>Applies to</&></a>:</td> +<td class="value">\ +% if ( $scrip->IsGlobal ) { +<a href="<% RT->Config->Get('WebPath') %>/Admin/Global/Scrips.html"><% loc('Global') %></a> +% } else { +% my $added_to = $scrip->AddedTo; +% my $found = 0; +% while ( my $queue = $added_to->Next ) { +% $m->out(', ') if $found++; +<a href="<% RT->Config->Get('WebPath') %>/Admin/Queues/Scrips.html?id=<% $queue->id %>">\ +<% $queue->Name %></a>\ +% last if $found == 10; +% } +% $m->out(', ...') if $found == 10; +% } +<td></tr> +% } + +<tr><td class="label"> </td><td> +<input type="hidden" class="hidden" name="SetEnabled" value="1" /> +<input type="checkbox" class="checkbox" name="Enabled" id="Enabled" value="1" <% $EnabledChecked |n%> /> +<label for="Enabled"><&|/l&>Enabled (Unchecking this box disables this scrip)</&></label> +</td></tr> + +</table> +</&> + +<& /Elements/Submit, Label => loc('Save Changes'), Name => 'Update', Reset => 1 &> + +% if ($session{CurrentUser}->HasRight(Object => $RT::System, Right => 'ExecuteCode')) { +<& Elements/EditCustomCode, %ARGS, Scrip => $scrip &> +<& /Elements/Submit, Label => loc('Save Changes'), Name => 'Update', Reset => 1 &> +% } + +</form> +<%ARGS> +$id => undef +$Update => undef +$From => undef +</%ARGS> +<%INIT> +my $scrip = RT::Scrip->new( $session{'CurrentUser'} ); +$scrip->Load( $id ); +Abort(loc("Couldn't load scrip #[_1]", $id)) + unless $scrip->id; + +my $disabled = $scrip->Disabled; + +if ( $Update ) { + my @attribs = qw( + Description + ScripAction ScripCondition + CustomPrepareCode CustomCommitCode CustomIsApplicableCode + ); + push @attribs, "Template" if defined $ARGS{Template} and length $ARGS{Template}; + if ($ARGS{"SetEnabled"}) { + push @attribs, "Disabled"; + $ARGS{"Disabled"} = not $ARGS{"Enabled"}; + } + my @results = UpdateRecordObject( + AttributesRef => \@attribs, + Object => $scrip, + ARGSRef => \%ARGS + ); + MaybeRedirectForResults( + Actions => \@results, + Arguments => { + id => $scrip->id, + From => $From, + }, + ); +} + +my $EnabledChecked = qq[checked="checked"]; +$EnabledChecked = '' if $disabled; + +my @results; +my ($ok, $msg) = $scrip->CompileCheck; +push @results, $msg if !$ok; +</%INIT> diff --git a/rt/share/html/Admin/Scrips/Objects.html b/rt/share/html/Admin/Scrips/Objects.html new file mode 100644 index 000000000..58ca59cc9 --- /dev/null +++ b/rt/share/html/Admin/Scrips/Objects.html @@ -0,0 +1,172 @@ +%# BEGIN BPS TAGGED BLOCK {{{ +%# +%# COPYRIGHT: +%# +%# This software is Copyright (c) 1996-2015 Best Practical Solutions, LLC +%# <sales@bestpractical.com> +%# +%# (Except where explicitly superseded by other copyright notices) +%# +%# +%# LICENSE: +%# +%# This work is made available to you under the terms of Version 2 of +%# the GNU General Public License. A copy of that license should have +%# been provided with this software, but in any event can be snarfed +%# from www.gnu.org. +%# +%# This work is distributed in the hope that it will be useful, but +%# WITHOUT ANY WARRANTY; without even the implied warranty of +%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +%# General Public License for more details. +%# +%# You should have received a copy of the GNU General Public License +%# along with this program; if not, write to the Free Software +%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +%# 02110-1301 or visit their web page on the internet at +%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html. +%# +%# +%# CONTRIBUTION SUBMISSION POLICY: +%# +%# (The following paragraph is not intended to limit the rights granted +%# to you to modify and distribute this software under the terms of +%# the GNU General Public License and is only of importance to you if +%# you choose to contribute your changes and enhancements to the +%# community by submitting them to Best Practical Solutions, LLC.) +%# +%# By intentionally submitting any modifications, corrections or +%# derivatives to this work, or any other work intended for use with +%# Request Tracker, to Best Practical Solutions, LLC, you confirm that +%# you are the copyright holder for those contributions and you grant +%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable, +%# royalty-free, perpetual, license to use, copy, create derivative +%# works based on those contributions, and sublicense and distribute +%# those contributions and any derivatives thereof. +%# +%# END BPS TAGGED BLOCK }}} +<& /Admin/Elements/Header, Title => $title &> +<& /Elements/Tabs &> +<& /Elements/ListActions &> + +<form action="Objects.html" method="post" name="AddRemoveScrip"> +<input type="hidden" class="hidden" name="id" value="<% $id %>" /> +<input type="hidden" class="hidden" name="From" value="<% $From || q{} %>" /> + +% if ( $global ) { +<h2><&|/l&>Applies to all objects</&></h2> +<label> +<input type="checkbox" name="RemoveScrip-<% $id %>" value="0" /> +<&|/l&>check this box to remove this scrip from all objects and be able to choose specific objects.</&> +</label> + +<& /Admin/Elements/SelectStageForAdded, + Default => $Stage || $global->Stage, + Label => loc("Select global scrip stage:") + &> +% } else { +<h2><&|/l&>Apply globally</&></h2> + +<label> +<input type="checkbox" name="AddScrip-<% $id %>" value="0" /> +<&|/l&>check this box to apply this scrip to all objects.</&> +</label> + +<h2><&|/l&>Selected objects</&></h2> +<& /Elements/CollectionList, + OrderBy => 'id', + Order => 'ASC', + %ARGS, + Collection => $added, + Rows => 0, + Page => 1, + Format => $format, + DisplayFormat => "'__CheckBox.{RemoveScrip-$id}__','__ScripStage.{$id}__',". $format, + AllowSorting => 0, + ShowEmpty => 0, + PassArguments => [ + qw(id Stage Format Rows Page Order OrderBy), + ], +&> + +<h2><&|/l&>Unselected objects</&></h2> +<& /Elements/CollectionList, + OrderBy => 'Name', + Order => 'ASC', + %ARGS, + Collection => $not_added, + Rows => $rows, + Format => $format, + DisplayFormat => "'__CheckBox.{AddScrip-". $id ."}__',". $format, + AllowSorting => 1, + ShowEmpty => 0, + PassArguments => [ + qw(id Stage Format Rows Page Order OrderBy), + ], +&> + +<& /Admin/Elements/SelectStageForAdded, Default => $Stage &> +<div style="text-align:right"> +<% loc('You can change template if needed') %>: +<& Elements/SelectTemplate, Scrip => $scrip, Default => $Template &> +</div> + +% } + +<& /Elements/Submit, Name => 'Update' &> +</form> + +<%ARGS> +$id => undef +$Stage => undef +$Template => '' +$Update => 0 +$From => undef +</%ARGS> +<%INIT> +my $scrip = RT::Scrip->new( $session{'CurrentUser'} ); +$scrip->Load($id) or Abort(loc("Could not load scrip #[_1]", $id)); +$id = $scrip->id; + +my $global = $scrip->IsGlobal; + +if ( $Update ) { + my (@results); + if ( $Template ) { + my ($status, $msg) = $scrip->SetTemplate( $Template ); + push @results, loc('Template: [_1]', $msg); + } + if ( defined (my $del = $ARGS{"RemoveScrip-$id"}) ) { + foreach my $id ( ref $del? (@$del) : ($del) ) { + my ($status, $msg) = $scrip->RemoveFromObject( $id ); + push @results, $msg; + } + } + if ( defined (my $add = $ARGS{"AddScrip-$id"}) ) { + foreach my $id ( ref $add? (@$add) : ($add) ) { + my ($status, $msg) = $scrip->AddToObject( $id, Stage => $Stage ); + push @results, $msg; + } + } + if ($global and $global->Stage ne $Stage) { + my ($status, $msg) = $global->SetStage($Stage); + push @results, $msg; + } + MaybeRedirectForResults( + Actions => \@results, + Arguments => { + id => $id, + From => $From, + }, + ); +} + +my $added = $scrip->AddedTo; +my $not_added = $scrip->NotAddedTo; + +my $format = RT->Config->Get('AdminSearchResultFormat')->{'Queues'}; +my $rows = RT->Config->Get('AdminSearchResultRows')->{'Queues'} || 50; + +my $title = loc('Modify associated objects for scrip #[_1]', $id); + +</%INIT> diff --git a/rt/share/html/Admin/Elements/ListGlobalScrips b/rt/share/html/Admin/Scrips/index.html index 3f97dbd12..7c54dcfc5 100755..100644 --- a/rt/share/html/Admin/Elements/ListGlobalScrips +++ b/rt/share/html/Admin/Scrips/index.html @@ -45,24 +45,28 @@ %# those contributions and any derivatives thereof. %# %# END BPS TAGGED BLOCK }}} -% unless ( $Scrips->Count ) { -<p><i><&|/l&>(No scrips)</&></i></p> -% } else { +<& /Admin/Elements/Header, Title => loc('Select a Scrip') &> +<& /Elements/Tabs &> <& /Elements/CollectionList, - OrderBy => 'Description', - Order => 'ASC', - Rows => 0, + OrderBy => 'Description', + Order => 'ASC', + Rows => $Rows, %ARGS, - Format => $Format, - Collection => $Scrips, + Collection => $scrips, + Format => $Format, + AllowSorting => 1, &> +<%args> +$Format => undef +</%args> +<%INIT> +my $scrips = RT::Scrips->new( $session{'CurrentUser'} ); +$scrips->FindAllRows; +$scrips->UnLimit; -% } +$m->callback(CallbackName => 'Massage', Scrips => $scrips); -<%init> -my $Format = RT->Config->Get('AdminSearchResultFormat')->{'GlobalScrips'}; - -my $Scrips = RT::Scrips->new( $session{'CurrentUser'} ); -$Scrips->LimitToGlobal; +$Format ||= RT->Config->Get('AdminSearchResultFormat')->{'Scrips'}; +my $Rows = RT->Config->Get('AdminSearchResultRows')->{'Scrips'} || 50; </%INIT> diff --git a/rt/share/html/Admin/Tools/Configuration.html b/rt/share/html/Admin/Tools/Configuration.html index f60cdba6f..fea3a5fcc 100644 --- a/rt/share/html/Admin/Tools/Configuration.html +++ b/rt/share/html/Admin/Tools/Configuration.html @@ -87,7 +87,7 @@ foreach my $key ( RT->Config->Options( Overridable => undef, Sorted => 0 ) ) { <tr class="<% $index_conf%2 ? 'oddline' : 'evenline'%>"> <td class="collection-as-table"><% $key %></td> <td class="collection-as-table"> -% if ( $key =~ /Password(?!Length)/i ) { +% if ( $key =~ /Password/i and $key !~ /MinimumPasswordLength|AllowLoginPasswordAutoComplete/ ) { <em><% loc('Password not printed' ) %></em>\ % } else { <% stringify($val) |n %>\ @@ -150,6 +150,7 @@ for my $type (qw/Tickets Queues Transactions Groups PrivilegedUsers Unprivileged $class =~ s/Privileged|Unprivileged//; my $collection = $class->new(RT->SystemUser); $collection->UnLimit; + $collection->FindAllRows; # find disabled if ($type =~ /PrivilegedUsers/) { $user_count = $collection->CountAll; $collection->LimitToPrivileged; @@ -179,6 +180,15 @@ for my $type (qw/Tickets Queues Transactions Groups PrivilegedUsers Unprivileged </ol> </&> +<&|/Widgets/TitleBox, title => loc("Static file search order") &> +<ol> +% foreach my $path ( (map {$_->{root}} RT->Config->Get('StaticRoots')), +% RT::Interface::Web->StaticRoots ) { +<li><% $path %></li> +% } +</ol> +</&> + <&|/Widgets/TitleBox, title => loc("Perl library search order") &> <ol> % foreach my $inc (@INC) { @@ -187,6 +197,22 @@ for my $type (qw/Tickets Queues Transactions Groups PrivilegedUsers Unprivileged </ol> </&> +<&|/Widgets/TitleBox, title=> loc("Loaded config files") &> +<ol> +% foreach my $config (RT->Config->LoadedConfigs) { +% if ($config->{site}) { +<li><strong><% $config->{filename} %></strong></li> +% } else { +<li><% $config->{filename} %></li> +% } +% } +</ol> +</&> + +<&|/Widgets/TitleBox, title=> loc("Logging summary") &> + <& /Admin/Elements/LoggingSummary &> +</&> + </td> </table> @@ -199,6 +225,7 @@ for my $type (qw/Tickets Queues Transactions Groups PrivilegedUsers Unprivileged % my $attrs = $RT::System->Attributes; % my $index_size = 0; % while ( my $attr = $attrs->Next ) { +% next if $attr->Name eq 'UpgradeHistory'; <tr class="<% $index_size%2 ? 'oddline' : 'evenline'%>"> % if ($attr->Name eq 'UserLogo') { % my $content = $attr->Content; @@ -249,6 +276,10 @@ if ($item =~ /^\s*(.*?)\s*v(\S+);/) { </table> </&> +<&|/Widgets/TitleBox, title => loc("RT upgrade history")&> +<& /Admin/Elements/UpgradeHistory &> +</&> + <&|/Widgets/TitleBox, title => loc("Perl configuration") &> % require Config; <pre> @@ -256,6 +287,66 @@ if ($item =~ /^\s*(.*?)\s*v(\S+);/) { </pre> </&> +<&|/Widgets/TitleBox, title=> loc("Environment variables") &> +<table border="0" cellspacing="0" cellpadding="5" width="100%" class="collection"> +<tr class="collection-as-table"> +<th class="collection-as-table"><&|/l&>Variable</&></th> +<th class="collection-as-table"><&|/l&>Value</&></th> +</tr> +% my $row = 0; +% for my $key (sort keys %ENV) { +<tr class="collection-as-table <% $row++ %2 ? 'oddline' : 'evenline'%>"> +<td class="collection-as-table"><% $key %></td> +<td class="collection-as-table"><% $ENV{$key} %></td> +</tr> +% } +</table> +</&> + +<&|/Widgets/TitleBox, title => loc("Operating System") &> +<table border="0" cellspacing="0" cellpadding="5" width="100%" class="collection"> +<tr class="collection-as-table evenline"> +<td class="collection-as-table">Deployment type</td> +<td class="collection-as-table"><% + $INC{'mod_perl.pm'} ? "mod_perl" : + $INC{'FCGI.pm'} ? "fastcgi" : + "standalone" %> +</td> +</tr> +<%perl> +my @os = ( + "Distribution" => 'lsb_release --all', + "uname -a" => 'uname -a', + "SELinux status" => 'getenforce', + "Apache" => [map { "$_ -V" } qw(apache2ctl apachectl httpdctl)], + "nginx" => 'nginx -V 2>&1', + "lighttpd" => 'lighttpd -V', +); +my @os_info; + +while (my ($name, $cmd) = splice @os, 0, 2) { + $cmd = [$cmd] unless ref $cmd eq 'ARRAY'; + for my $run (@$cmd) { + $run .= " </dev/null"; + $run .= " 2>/dev/null" unless $run =~ /2>/; + my $result = `$run`; + if (defined $result and $result =~ /\S/) { + push @os_info, $name => $result; + last; + } + } +} +my $row = 1; +</%perl> +% while (my ($name, $output) = splice @os_info, 0, 2) { +<tr class="collection-as-table <% $row++ % 2 ? "oddline" : "evenline" %>"> +<td class="collection-as-table"><% $name %></td> +<td class="collection-as-table" style="white-space: pre-wrap; font-family: monospace"><% $output %></td> +</tr> +% } +</table> +</&> + <%INIT> use Data::Dumper; local $Data::Dumper::Terse = 1; @@ -264,7 +355,7 @@ local $Data::Dumper::Indent = 2; sub stringify { my $value = shift; my $output = Dumper $value; - RT::Interface::Web::EscapeUTF8(\$output); + RT::Interface::Web::EscapeHTML(\$output); $output =~ s/ / /g; $output =~ s!\n!<br />!g; return $output; diff --git a/rt/share/html/Admin/Tools/Queries.html b/rt/share/html/Admin/Tools/Queries.html index 23025ec4b..66427dedf 100644 --- a/rt/share/html/Admin/Tools/Queries.html +++ b/rt/share/html/Admin/Tools/Queries.html @@ -53,7 +53,7 @@ unless ($session{'CurrentUser'}->HasRight( Object=> $RT::System, Right => 'Super </%init> <& /Admin/Elements/Header, Title => $title &> <& /Elements/Tabs &> -<script type="text/javascript" src="<%RT->Config->Get('WebPath')%>/NoAuth/js/jquery.tablesorter.min.js"></script> +<script type="text/javascript" src="<%RT->Config->Get('WebPath')%>/static/js/jquery.tablesorter.min.js"></script> <&|/Widgets/TitleBox, title => loc('SQL Queries') &> % my $history = $RT::Handle->QueryHistory; diff --git a/rt/share/html/Admin/Tools/Shredder/Elements/ObjectCheckBox b/rt/share/html/Admin/Tools/Shredder/Elements/ObjectCheckBox index 757e10658..e333d0779 100644 --- a/rt/share/html/Admin/Tools/Shredder/Elements/ObjectCheckBox +++ b/rt/share/html/Admin/Tools/Shredder/Elements/ObjectCheckBox @@ -48,12 +48,12 @@ <%ARGS> $Object => undef </%ARGS> -<input type="checkbox" name="WipeoutObject" value="<% $Object->_AsString %>" /> +<input type="checkbox" name="WipeoutObject" value="<% $Object->UID %>" /> <span> % if( $m->comp_exists( $path ) ) { % $m->comp( $path, Object => $Object ); % } else { -<% $Object->_AsString %> +<% $Object->UID %> % } </span><br /> <%ONCE> diff --git a/rt/share/html/Admin/Tools/Shredder/Elements/PluginHelp b/rt/share/html/Admin/Tools/Shredder/Elements/PluginHelp index bf37a890a..cc082767a 100644 --- a/rt/share/html/Admin/Tools/Shredder/Elements/PluginHelp +++ b/rt/share/html/Admin/Tools/Shredder/Elements/PluginHelp @@ -59,8 +59,8 @@ my %plugins = $plugin_obj->List; <%INIT> my $file = $plugins{ $Plugin }; unless( $file ) { - $RT::Logger->error( "Couldn't find plugin '$Plugin'" ); - return; + $RT::Logger->error( "Couldn't find plugin '$Plugin'" ); + return; } use RT::Shredder::POD qw(); diff --git a/rt/share/html/Admin/Tools/Shredder/autohandler b/rt/share/html/Admin/Tools/Shredder/autohandler index 62909b0c3..9a5ecd106 100644 --- a/rt/share/html/Admin/Tools/Shredder/autohandler +++ b/rt/share/html/Admin/Tools/Shredder/autohandler @@ -47,13 +47,13 @@ %# END BPS TAGGED BLOCK }}} <%INIT> unless( $session{'CurrentUser'}->HasRight( Right => 'SuperUser', Object => $RT::System ) ) { - return $m->comp( 'Elements/Error/NoRights' ); + return $m->comp( 'Elements/Error/NoRights' ); } use RT::Shredder (); my $path = RT::Shredder->StoragePath; unless( -d $path && -w _ ) { - return $m->comp( 'Elements/Error/NoStorage', Path => $path ); + return $m->comp( 'Elements/Error/NoStorage', Path => $path ); } $m->call_next(%ARGS); diff --git a/rt/share/html/Admin/Tools/Theme.html b/rt/share/html/Admin/Tools/Theme.html index 83f88a98b..3a0c71b35 100644 --- a/rt/share/html/Admin/Tools/Theme.html +++ b/rt/share/html/Admin/Tools/Theme.html @@ -51,7 +51,7 @@ <& /Elements/Tabs &> <& /Elements/ListActions, actions => \@results &> -<script type="text/javascript" src="<%RT->Config->Get('WebPath')%>/NoAuth/js/farbtastic.js"></script> +<script type="text/javascript" src="<%RT->Config->Get('WebPath')%>/static/js/farbtastic.js"></script> <div id="simple-customize"> <div id="upload-logo"> @@ -61,26 +61,31 @@ <label for="logo-upload"><&|/l&>Upload a new logo</&>:</label> <input type="file" name="logo-upload" id="logo-upload" /><br /> <div class="gd-support"> -% if (%gd_can) { +% if ($valid_image_types) { <&|/l, $valid_image_types &>Your system supports automatic color suggestions for: [_1]</&> % } else { <&|/l&>GD is disabled or not installed. You can upload an image, but you won't get automatic color suggestions.</&> % } </div> - <input name="reset_logo" value="Reset to default RT Logo" type="submit" /> - <input type="submit" value="Upload" /> + <input name="reset_logo" value="<&|/l&>Reset to default RT Logo</&>" type="submit" /> + <input type="submit" value="<&|/l&>Upload</&>" /> </form> </div> <div id="customize-theme"> - <h2>Customize the RT theme</h2> + <h2><&|/l&>Customize the RT theme</&></h2> <ol> <li> <label for="section"><&|/l&>Select a section</&>:</label> <select id="section"></select> </li> <li> - <div class="description"><&|/l&>Select a color for the section</&>:</div> + <div class="description"> + <&|/l&>Select a color for the section</&>: + <div id="logo-picker-hint" style="display: none;"> + <&|/l&>You can also click on the logo above to get colors!</&> + </div> + </div> % if ($colors) { <div class="primary-colors"> % for (@$colors) { @@ -93,27 +98,29 @@ </div> % } <div id="color-picker"></div> + <canvas id="logo-color-picker" title="<&|/l&>Click to choose a color</&>"></canvas> </li> </ol> </div> </div> <div id="custom-css"> - <h2>Custom CSS (Advanced)</h2> - + <h2><&|/l&>Custom CSS (Advanced)</&></h2> + <form method="POST"> <textarea rows=20 id="user_css" name="user_css" wrap="off"><% $user_css %></textarea><br /> - <input id="try" type="button" class="button" value="Try" /> - <input id="reset" type="reset" value="Reset" type="submit" /> - <input name="reset_css" value="Reset to default RT Theme" type="submit" /> - <input value="Save" type="submit" /> + <input id="try" type="button" class="button" value="<&|/l&>Try</&>" /> + <input id="reset" type="reset" value="<&|/l&>Reset</&>" type="submit" /> + <input name="reset_css" value="<&|/l&>Reset to default RT Theme</&>" type="submit" /> + <input value="<&|/l&>Save</&>" type="submit" /> </form> </div> <%ONCE> my @sections = ( - ['Page' => ['body']], - ['Header' => ['div#quickbar', 'body.aileron #main-navigation #app-nav > li, body.aileron #main-navigation #app-nav > li > a, #prefs-menu > li, #prefs-menu > li > a, #logo .rtname']], + ['Page' => ['body', 'div#body']], + ['Menu bar' => ['div#quickbar', '#main-navigation #app-nav.sf-shadow > li, #main-navigation #app-nav.sf-shadow > li > a, #prefs-menu > li, #prefs-menu > li > a, #logo .rtname']], + ['Title bar' => ['div#header']], ['Page title' => ['div#header h1']], ['Page content' => ['div#body']], ['Buttons' => ['input[type="reset"], input[type="submit"], input[class="button"]']], @@ -173,7 +180,7 @@ jQuery(function($) { newcss += "; border: none;" /* Page title's text color is the selected color */ - if (applying[name].match(/#header/)) + if (applying[name].match(/h1/)) newcss = "color: " + bg; /* Nav doesn't need a background, but it wants text color */ @@ -193,7 +200,35 @@ jQuery(function($) { change_color($(this).css('background-color'), $(this).css('color')); }); - + // Setup the canvas color picker + $("#logo-theme-editor img").load(function() { + var logo = $(this); + var canvas = $("#logo-color-picker"); + var el_canvas = canvas.get(0); + + if (!el_canvas.getContext) return; + + var context = el_canvas.getContext("2d"); + el_canvas.width = logo.width(); + el_canvas.height = logo.height(); + context.drawImage(logo.get(0), 0, 0); + + logo.hide().after(canvas); + canvas.show().click(function(ev) { + ev.preventDefault(); + var R = 0, + G = 1, + B = 2, + A = 3; + var pixel = this.getContext("2d").getImageData(ev.offsetX, ev.offsetY, 1, 1).data; + // Farbtastic expects values in the range of 0..1 + var rgba = $.makeArray(pixel).map(function(v,i) { return v / 255 }); + var wheel = $.farbtastic("#color-picker"); + wheel.setHSL( wheel.RGBToHSL( rgba.slice(R,A) ) ); + // XXX TODO factor in the alpha channel too + }); + $('#logo-picker-hint').show(); + }); }); </script> <%INIT> @@ -207,14 +242,82 @@ my $text_threshold = 0.6; my @results; my $imgdata; +my $colors; +my $valid_image_types; +if (not RT->Config->Get('DisableGD') and Convert::Color->require) { + require GD; + + # Always find out what GD can read... + my %gd_can; + for my $type (qw(Png Jpeg Gif)) { + $gd_can{$type}++ if GD::Image->can("newFrom${type}Data"); + } + $valid_image_types = join(", ", map { uc } sort { lc $a cmp lc $b } keys %gd_can); +} + +my $analyze_img = sub { + return undef unless $valid_image_types; + + my $imgdata = shift; + return undef unless $imgdata; + + # ...but only analyze the image if we have data + my $img = GD::Image->new($imgdata); + unless ($img) { + # This has to be one damn long line because the loc() needs to be + # source parsed correctly. + push @results, loc("Automatically suggested theme colors aren't available for your image. This might be because you uploaded an image type that your installed version of GD doesn't support. Supported types are: [_1]. You can recompile libgd and GD.pm to include support for other image types.", $valid_image_types); + return undef; + } + + my %colors; + + my @wsamples; + my @hsamples; + if ($img->width > 200) { + @wsamples = map { int($img->width*($_/200)) } (0..199); + } else { + @wsamples = ( 0 .. $img->width - 1 ); + } + if ($img->height > 200) { + @hsamples = map { int($img->height*($_/200)) } (0..199); + } else { + @hsamples = ( 0 .. $img->height - 1 ); + } + for my $i (@wsamples) { + for my $j (@hsamples) { + my @color = $img->rgb( $img->getPixel($i,$j) ); + my $hsl = Convert::Color->new('rgb:'.join(',',map { $_ / 255 } @color))->convert_to('hsl'); + my $c = join(',',@color); + next if $hsl->lightness < 0.1; + $colors{$c} ||= { h => $hsl->hue, s => $hsl->saturation, l => $hsl->lightness, cnt => 0, c => $c}; + $colors{$c}->{cnt}++; + } + } + + for (values %colors) { + $_->{rank} = $_->{s} * $_->{cnt}; + } + my @top5 = grep { defined and $_->{'l'} and $_->{'c'} } + (sort { $b->{rank} <=> $a->{rank} } values %colors)[0..5]; + return \@top5; +}; + if (my $file_hash = _UploadedFile( 'logo-upload' )) { - my ($id, $msg) = RT->System->SetAttribute( Name => "UserLogo", - Description => "User-provided logo", - Content => { - type => $file_hash->{ContentType}, - data => $file_hash->{LargeContent}, - hash => md5_hex($file_hash->{LargeContent}), - } ); + $colors = $analyze_img->($file_hash->{LargeContent}); + + my $my_system = RT::System->new( $session{CurrentUser} ); + my ( $id, $msg ) = $my_system->SetAttribute( + Name => "UserLogo", + Description => "User-provided logo", + Content => { + type => $file_hash->{ContentType}, + data => $file_hash->{LargeContent}, + hash => md5_hex($file_hash->{LargeContent}), + colors => $colors, + }, + ); + push @results, loc("Unable to set UserLogo: [_1]", $msg) unless $id; $imgdata = $file_hash->{LargeContent}; @@ -227,6 +330,19 @@ else { my $content = $attr->Content; if (ref($content) eq 'HASH') { $imgdata = $content->{data}; + $colors = $content->{colors}; + unless ($colors) { + # No colors cached; attempt to generate them + $colors = $content->{colors} = $analyze_img->($content->{data}); + if ($content->{colors}) { + # Found colors; update the attribute + RT->System->SetAttribute( + Name => "UserLogo", + Description => "User-provided logo", + Content => $content, + ); + } + } } else { RT->System->DeleteAttribute('UserLogo'); @@ -256,63 +372,6 @@ if (!$user_css) { } @sections ); } - -# XXX: move this to some other modules - -use List::MoreUtils qw(uniq); - -my $has_color_analyzer = eval { require Convert::Color; 1 }; -my $colors; -my %gd_can; -my $valid_image_types; - -if (not RT->Config->Get('DisableGD') and $has_color_analyzer) { - require GD; - - # Always find out what GD can read... - for my $type (qw(Png Jpeg Gif)) { - $gd_can{$type}++ if GD::Image->can("newFrom${type}Data"); - } - $valid_image_types = join(", ", map { uc } sort { lc $a cmp lc $b } keys %gd_can); - - # ...but only analyze the image if we have data - if ($imgdata) { - if ( my $img = GD::Image->new($imgdata) ) { - $colors = analyze_img($img); - } - else { - # This has to be one damn long line because the loc() needs to be - # source parsed correctly. - push @results, loc("Automatically suggested theme colors aren't available for your image. This might be because you uploaded an image type that your installed version of GD doesn't support. Supported types are: [_1]. You can recompile libgd and GD.pm to include support for other image types.", $valid_image_types); - } - } -} - -sub analyze_img { - my $img = shift; - my $color; - - for my $i (0..$img->width-1) { - for my $j (0..$img->height-1) { - my @color = $img->rgb( $img->getPixel($i,$j) ); - my $hsl = Convert::Color->new('rgb:'.join(',',map { $_ / 255 } @color))->convert_to('hsl'); - my $c = join(',',@color); - next if $hsl->lightness < 0.1; - $color->{$c} ||= { h => $hsl->hue, s => $hsl->saturation, l => $hsl->lightness, cnt => 0, c => $c}; - $color->{$c}->{cnt}++; - } - } - - for (values %$color) { - $_->{rank} = $_->{s} * $_->{cnt}; - } - my @top5 = grep { defined and $_->{'l'} and $_->{'c'} } - (sort { $b->{rank} <=> $a->{rank} } values %$color)[0..5]; - if ((scalar uniq map {$_->{rank}} @top5) == 1) { - $RT::Logger->info("Only one color found in logo image"); - } - return \@top5; -} </%INIT> <%ARGS> $user_css => '' diff --git a/rt/share/html/Admin/Tools/index.html b/rt/share/html/Admin/Tools/index.html index 891fe000a..b80ed0a32 100644 --- a/rt/share/html/Admin/Tools/index.html +++ b/rt/share/html/Admin/Tools/index.html @@ -47,4 +47,4 @@ %# END BPS TAGGED BLOCK }}} <& /Admin/Elements/Header, Title => loc('System Tools') &> <& /Elements/Tabs &> -<& /Elements/ListMenu, menu => Menu()->child('tools')->child('config')->child('tools') &> +<& /Elements/ListMenu, menu => Menu()->child('admin')->child('tools') &> diff --git a/rt/share/html/Admin/Users/DashboardsInMenu.html b/rt/share/html/Admin/Users/DashboardsInMenu.html new file mode 100644 index 000000000..bdbcc9816 --- /dev/null +++ b/rt/share/html/Admin/Users/DashboardsInMenu.html @@ -0,0 +1,118 @@ +%# BEGIN BPS TAGGED BLOCK {{{ +%# +%# COPYRIGHT: +%# +%# This software is Copyright (c) 1996-2015 Best Practical Solutions, LLC +%# <sales@bestpractical.com> +%# +%# (Except where explicitly superseded by other copyright notices) +%# +%# +%# LICENSE: +%# +%# This work is made available to you under the terms of Version 2 of +%# the GNU General Public License. A copy of that license should have +%# been provided with this software, but in any event can be snarfed +%# from www.gnu.org. +%# +%# This work is distributed in the hope that it will be useful, but +%# WITHOUT ANY WARRANTY; without even the implied warranty of +%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +%# General Public License for more details. +%# +%# You should have received a copy of the GNU General Public License +%# along with this program; if not, write to the Free Software +%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +%# 02110-1301 or visit their web page on the internet at +%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html. +%# +%# +%# CONTRIBUTION SUBMISSION POLICY: +%# +%# (The following paragraph is not intended to limit the rights granted +%# to you to modify and distribute this software under the terms of +%# the GNU General Public License and is only of importance to you if +%# you choose to contribute your changes and enhancements to the +%# community by submitting them to Best Practical Solutions, LLC.) +%# +%# By intentionally submitting any modifications, corrections or +%# derivatives to this work, or any other work intended for use with +%# Request Tracker, to Best Practical Solutions, LLC, you confirm that +%# you are the copyright holder for those contributions and you grant +%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable, +%# royalty-free, perpetual, license to use, copy, create derivative +%# works based on those contributions, and sublicense and distribute +%# those contributions and any derivatives thereof. +%# +%# END BPS TAGGED BLOCK }}} +<& /Admin/Elements/Header, Title => $title &> +<& /Elements/Tabs &> + +<& /Elements/ListActions, actions => \@actions &> + +<form method="post" action="DashboardsInMenu.html"> +<input type="hidden" name="id" value="<% $id %>" /> +<input type="hidden" name="Reset" value="1" /> +<input type="submit" class="button" value="<%loc('Reset to default')%>"> +</form> + +<br /> + +% for my $pane (@panes) { +<&|/Widgets/TitleBox, title => loc('Dashboards in menu'), bodyclass => "" &> +<& /Widgets/SelectionBox:show, self => $pane &></&> +<br /> +% } + +<%init> +my @actions; +my $UserObj = RT::User->new($session{'CurrentUser'}); +$UserObj->Load($id) || Abort("Couldn't load user '" . ($id || '') . "'"); +my $title = loc("Dashboards in menu for the user [_1]", $UserObj->Name); + +if ($ARGS{Reset}) { + my ($ok, $msg) = $UserObj->SetPreferences('DashboardsInMenu', {}); + push @actions, $ok ? loc('Preferences saved for user [_1].', $UserObj->Name) : $msg; +} + +my ($default_dashboards) = +RT::System->new($session{'CurrentUser'})->Attributes->Named('DashboardsInMenu'); + +my $user = RT::CurrentUser->new( $session{CurrentUser} ); +$user->Load( $UserObj->id ); +my @dashboards = + map { [ $_->id, $_->Name ] } + $m->comp( "/Dashboards/Elements/ListOfDashboards", User => $user, IncludeSuperuserGroups => 0 ); + + +my $current_pref = + $UserObj->Preferences( 'DashboardsInMenu', + $default_dashboards ? $default_dashboards->Content : () ); +my $current_portlets = + $current_pref && $current_pref->{dashboards} + ? $current_pref->{dashboards} + : []; + +my @panes = $m->comp( + '/Admin/Elements/ConfigureDashboardsInMenu', + Action => "DashboardsInMenu.html?id=$id", + panes => ['dashboards_in_menu'], + items => \@dashboards, + current_portlets => $current_portlets, + OnSave => sub { + my ($conf) = @_; + my ( $ok, $msg ) = + $UserObj->SetPreferences( 'DashboardsInMenu', $conf ); + push @actions, + $ok ? loc('Preferences saved for dashboards in menu.') : $msg; + } +); + + +$m->comp( '/Widgets/SelectionBox:process', %ARGS, self => $_ ) + for @panes; + +</%init> +<%ARGS> +$id => undef +</%ARGS> diff --git a/rt/share/html/Admin/Users/History.html b/rt/share/html/Admin/Users/History.html index 752b20f83..cda3f736e 100644 --- a/rt/share/html/Admin/Users/History.html +++ b/rt/share/html/Admin/Users/History.html @@ -48,9 +48,10 @@ <& /Admin/Elements/Header, Title => $title &> <& /Elements/Tabs &> -<& /Ticket/Elements/ShowHistory, - Ticket => $UserObj, +<& /Elements/ShowHistory, + Object => $UserObj, ShowDisplayModes => 0, + DisplayPath => 'History.html', &> <%INIT> diff --git a/rt/share/html/Admin/Users/GnuPG.html b/rt/share/html/Admin/Users/Keys.html index 3ca593a5d..699075904 100644 --- a/rt/share/html/Admin/Users/GnuPG.html +++ b/rt/share/html/Admin/Users/Keys.html @@ -45,7 +45,7 @@ %# those contributions and any derivatives thereof. %# %# END BPS TAGGED BLOCK }}} -<& /Admin/Elements/Header, Title => $title &> +<& /Admin/Elements/Header, Title => loc("[_1]'s encryption keys",$UserObj->Name) &> <& /Elements/Tabs &> <& /Elements/ListActions, actions => \@results &> @@ -56,11 +56,11 @@ <h2><% loc("User has empty email address") %></h2> % } - -<form action="<%RT->Config->Get('WebPath')%>/Admin/Users/GnuPG.html" method="post" enctype="multipart/form-data"> +<form action="<%RT->Config->Get('WebPath')%>/Admin/Users/Keys.html" method="post" enctype="multipart/form-data"> <input type="hidden" class="hidden" name="id" value="<% $UserObj->Id %>" /> -<&|/Widgets/TitleBox, title => 'GnuPG private key'&> +% if (RT::Crypt->UseForOutgoing eq 'GnuPG') { +<&|/Widgets/TitleBox, title => loc('GnuPG private key') &> <& /Widgets/Form/Select, Name => 'PrivateKey', Description => loc('Private Key'), @@ -69,17 +69,23 @@ DefaultLabel => loc('No private key'), &> </&> +% } + +% if (RT::Crypt->UseForOutgoing eq 'SMIME') { +<&|/Widgets/TitleBox, title => loc('SMIME Certificate') &> +<textarea name="SMIMECertificate"><% $UserObj->SMIMECertificate || '' %></textarea> +</&> +% } <& /Elements/Submit, Name => 'Update', Label => loc('Save Changes') &> </form> + <%ARGS> $id => undef $Update => undef </%ARGS> <%INIT> -return unless RT->Config->Get('GnuPG')->{'Enable'}; - -require RT::Crypt::GnuPG; +return unless RT->Config->Get('Crypt')->{'Enable'}; my @results; @@ -90,27 +96,36 @@ unless ( $UserObj->id ) { } $id = $ARGS{'id'} = $UserObj->id; +my @potential_keys; my $email = $UserObj->EmailAddress; -my %keys_meta = RT::Crypt::GnuPG::GetKeysForSigning( $email ); -my @potential_keys = map $_->{'Key'}, @{ $keys_meta{'info'} || [] }; -$ARGS{'PrivateKey'} = $m->comp('/Widgets/Form/Select:Process', - Name => 'PrivateKey', - Arguments => \%ARGS, - Default => 1, -); +if (RT::Crypt->UseForOutgoing eq 'GnuPG') { + my %keys_meta = RT::Crypt->GetKeysForSigning( Signer => $email, Protocol => 'GnuPG' ); + @potential_keys = map $_->{'Key'}, @{ $keys_meta{'info'} || [] }; + + $ARGS{'PrivateKey'} = $m->comp('/Widgets/Form/Select:Process', + Name => 'PrivateKey', + Arguments => \%ARGS, + Default => 1, + ); -if ( $Update ) { - if (not $ARGS{'PrivateKey'} or grep {$_ eq $ARGS{'PrivateKey'}} @potential_keys) { - if (($ARGS{'PrivateKey'}||'') ne ($UserObj->PrivateKey||'')) { - my ($status, $msg) = $UserObj->SetPrivateKey( $ARGS{'PrivateKey'} ); - push @results, $msg; + if ( $Update ) { + if (not $ARGS{'PrivateKey'} or grep {$_ eq $ARGS{'PrivateKey'}} @potential_keys) { + if (($ARGS{'PrivateKey'}||'') ne ($UserObj->PrivateKey||'')) { + my ($status, $msg) = $UserObj->SetPrivateKey( $ARGS{'PrivateKey'} ); + push @results, $msg; + } + } else { + push @results, loc("Invalid key [_1] for address '[_2]'", $ARGS{'PrivateKey'}, $email); } - } else { - push @results, loc("Invalid key [_1] for address '[_2]'", $ARGS{'PrivateKey'}, $email); } } -my $title = loc("[_1]'s GnuPG keys",$UserObj->Name); +if (RT::Crypt->UseForOutgoing eq 'SMIME') { + if ( $Update and ($ARGS{'SMIMECertificate'}||'') ne ($UserObj->SMIMECertificate||'') ) { + my ($status, $msg) = $UserObj->SetSMIMECertificate( $ARGS{'SMIMECertificate'} ); + push @results, $msg; + } +} </%INIT> diff --git a/rt/share/html/Admin/Users/Memberships.html b/rt/share/html/Admin/Users/Memberships.html index 74f10b813..1910ff5c2 100644 --- a/rt/share/html/Admin/Users/Memberships.html +++ b/rt/share/html/Admin/Users/Memberships.html @@ -45,92 +45,4 @@ %# those contributions and any derivatives thereof. %# %# END BPS TAGGED BLOCK }}} -<& /Admin/Elements/Header, Title => $title &> -<& /Elements/Tabs &> - -<& /Elements/ListActions, actions => \@results &> - -<form method="post" action=""> -<input type="hidden" id="<% $id %>" /> - -<h2><&|/l&>Groups the user is member of (check box to delete)</&></h2> - -<& /Elements/CollectionList, - OrderBy => 'Name', - Order => 'ASC', - %ARGS, - Rows => 20, - DisplayFormat => "__CheckBox.{Delete}__,$Format", - Format => $Format, - Collection => $is_member, - AllowSorting => 1, - PassArguments => [qw(Format Rows Page Order OrderBy id)], -&> - -<h2><&|/l&>Groups the user is not member of (check box to add)</&></h2> - -<& /Elements/CollectionList, - OrderBy => 'Name', - Order => 'ASC', - Rows => 20, - %ARGS, - DisplayFormat => "__CheckBox.{Add}__,'__HasMemberRecursively.{$id}__/TITLE:Recursive',$Format", - Format => $Format, - Collection => $is_not_member, - AllowSorting => 1, - PassArguments => [qw(Format Rows Page Order OrderBy id)], -&> - -<& /Elements/Submit, Label => loc('Update'), Name => 'Update' &> - -</form> - -<%INIT> -my $UserObj = RT::User->new($session{'CurrentUser'}); -$UserObj->Load( $id ) || Abort("Couldn't load user '$id'"); - -my $title = loc("Memberships of the user [_1]", $UserObj->Name); - -my @results; -if ( $Update ) { - foreach my $gid( @Add ) { - my $group = RT::Group->new( $session{'CurrentUser'} ); - $group->LoadUserDefinedGroup( $gid ); - unless ( $group->id ) { - push @results, loc( "Couldn't load group #[_1]", $gid ); - next; - } - my ($status, $msg) = $group->AddMember( $id ); - push @results, $msg; - } - foreach my $gid( @Delete ) { - my $group = RT::Group->new( $session{'CurrentUser'} ); - $group->LoadUserDefinedGroup( $gid ); - unless ( $group->id ) { - push @results, loc( "Couldn't load group #[_1]", $gid ); - next; - } - my ($status, $msg) = $group->DeleteMember( $id ); - push @results, $msg; - } -} - -my $is_member = RT::Groups->new( $session{'CurrentUser'} ); -$is_member->LimitToUserDefinedGroups; -$is_member->WithMember( PrincipalId => $UserObj->Id ); - -my $is_not_member = RT::Groups->new( $session{'CurrentUser'} ); -$is_not_member->LimitToUserDefinedGroups; -$is_not_member->WithoutMember( PrincipalId => $UserObj->Id ); - -$Format ||= RT->Config->Get('AdminSearchResultFormat')->{'Groups'}; -</%INIT> -<%ARGS> -$id => undef - -$Update => 0, -@Add => (), -@Delete => (), - -$Format => undef -</%ARGS> +<& /Admin/Elements/MembershipsPage, %ARGS &> diff --git a/rt/share/html/Admin/Users/Modify.html b/rt/share/html/Admin/Users/Modify.html index 62d828c18..fc944dc3e 100755 --- a/rt/share/html/Admin/Users/Modify.html +++ b/rt/share/html/Admin/Users/Modify.html @@ -50,7 +50,7 @@ <& /Elements/ListActions, actions => \@results &> -<form action="<%RT->Config->Get('WebPath')%>/Admin/Users/Modify.html" method="post" enctype="multipart/form-data"> +<form action="<%RT->Config->Get('WebPath')%>/Admin/Users/Modify.html" method="post" enctype="multipart/form-data" name="<% $Create ? 'UserCreate': 'UserModify' %>"> %if ($Create) { <input type="hidden" class="hidden" name="id" value="new" /> % } else { @@ -60,46 +60,48 @@ <tr> <td valign="top" class="boxcontainer"> -<&| /Widgets/TitleBox, title => loc('Identity') &> +<&| /Widgets/TitleBox, title => loc('Identity'), class => 'user-info-identity' &> <table> <tr><td align="right"> <&|/l&>Username</&>: </td><td> -<input name="Name" value="<%$UserObj->Name||$Name||''%>" /> <strong><&|/l&>(required)</&></strong> +<input name="Name" value="<%$UserObj->Name//$ARGS{Name}//''%>" /> <strong><&|/l&>(required)</&></strong> </td></tr> <tr><td align="right"> <&|/l&>Email</&>: </td><td> -<input name="EmailAddress" value="<%$UserObj->EmailAddress||$EmailAddress||''%>" /> +<input name="EmailAddress" value="<%$UserObj->EmailAddress//$ARGS{EmailAddress}//''%>" /> </td></tr> <tr><td align="right"> -<&|/l&>Real Name</&>: +<&|/l&>Real Name</&>: </td><td> -<input name="RealName" value="<%$UserObj->RealName||$RealName||''%>" /> +<input name="RealName" value="<%$UserObj->RealName//$ARGS{RealName}//''%>" /> </td></tr> <tr><td align="right"> -<&|/l&>Nickname</&>: +<&|/l&>Nickname</&>: </td><td> -<input name="NickName" value="<%$UserObj->NickName||$NickName||''%>" /> +<input name="NickName" value="<%$UserObj->NickName//$ARGS{NickName}//''%>" /> </td></tr> <tr><td align="right"> -<&|/l&>Unix login</&>: +<&|/l&>Unix login</&>: </td><td> -<input name="Gecos" value="<%$UserObj->Gecos||$Gecos||''%>" /> +<input name="Gecos" value="<%$UserObj->Gecos//$ARGS{Gecos}//''%>" /> </td></tr> <tr><td align="right"> -<&|/l&>Language</&>: +<&|/l&>Language</&>: </td><td> -<& /Elements/SelectLang, Name => 'Lang', Default => $UserObj->Lang||$Lang &> +<& /Elements/SelectLang, Name => 'Lang', Default => $UserObj->Lang//$ARGS{Lang} &> </td></tr> <tr><td align="right"> -<&|/l&>Extra info</&>: +<&|/l&>Extra info</&>: </td><td> -<textarea name="FreeformContactInfo" cols="20" rows="5"><%$UserObj->FreeformContactInfo||$FreeformContactInfo||''%></textarea> +<textarea name="FreeformContactInfo" cols="20" rows="5"><%$UserObj->FreeformContactInfo//$ARGS{FreeformContactInfo}//''%></textarea> </td></tr> +<& /Elements/EditCustomFields, Object => $UserObj, Grouping => 'Identity', InTable => 1 &> </table> </&> + <br /> <&| /Widgets/TitleBox, title => loc('Customers') &> @@ -107,119 +109,117 @@ </&> <br /> -<&| /Widgets/TitleBox, title => loc('Access control') &> +<&| /Widgets/TitleBox, title => loc('Access control'), class => 'user-info-access-control' &> <input type="hidden" class="hidden" name="SetEnabled" value="1" /> -<input type="checkbox" class="checkbox" name="Enabled" value="1" <%$EnabledChecked||''%> /> -<&|/l&>Let this user access RT</&><br /> +<input type="checkbox" class="checkbox" id="Enabled" name="Enabled" value="1" <% ($UserObj->Id && $UserObj->Disabled) ? '' : 'checked="checked"' |n%> /> +<label for="Enabled"><&|/l&>Let this user access RT</&></label><br /> +% my $PrivilegedChecked = ((!$Create && $UserObj->Privileged()) or (!$UserObj->Id and $ARGS{Privileged})) ? 'checked="checked"' : ''; <input type="hidden" class="hidden" name="SetPrivileged" value="1" /> -<input type="checkbox" class="checkbox" name="Privileged" value="1" <%$PrivilegedChecked||''%> /> <&|/l&>Let this user be granted rights</&> (<&|/l&>Privileged</&>)<br /> +<input type="checkbox" class="checkbox" id="Privileged" name="Privileged" value="1" <%$PrivilegedChecked|n%> /> +<label for="Privileged"><&|/l&>Let this user be granted rights</&> (<&|/l&>Privileged</&>)</label><br /> <& /Elements/EditPassword, User => $UserObj, Name => [qw(CurrentPass Pass1 Pass2)], &> + +<& /Elements/EditCustomFields, Object => $UserObj, Grouping => 'Access control' &> + </&> % $m->callback( %ARGS, CallbackName => 'LeftColumnBottom', UserObj => $UserObj ); </td> <td valign="top" class="boxcontainer"> -<&| /Widgets/TitleBox, title => loc('Location') &> +<&| /Widgets/TitleBox, title => loc('Location'), class => 'user-info-location' &> <table> <tr><td align="right"> -<&|/l&>Organization</&>: +<&|/l&>Organization</&>: </td><td> -<input name="Organization" value="<%$UserObj->Organization||$Organization||''%>" /> +<input name="Organization" value="<%$UserObj->Organization//$ARGS{Organization}//''%>" /> </td></tr> <tr><td align="right"> -<&|/l&>Address1</&>: +<&|/l&>Address1</&>: </td><td> -<input name="Address1" value="<%$UserObj->Address1||$Address1||''%>" /> +<input name="Address1" value="<%$UserObj->Address1//$ARGS{Address1}//''%>" /> </td></tr> <tr><td align="right"> -<&|/l&>Address2</&>: +<&|/l&>Address2</&>: </td><td> -<input name="Address2" value="<%$UserObj->Address2||$Address2||''%>" /> +<input name="Address2" value="<%$UserObj->Address2//$ARGS{Address2}//''%>" /> </td></tr> <tr><td align="right"> -<&|/l&>City</&>: +<&|/l&>City</&>: </td><td> -<input name="City" value="<%$UserObj->City||$City||''%>" size="14" /> +<input name="City" value="<%$UserObj->City//$ARGS{City}//''%>" size="14" /> </td></tr> <tr><td align="right"> -<&|/l&>State</&>: +<&|/l&>State</&>: </td><td> -<input name="State" value="<%$UserObj->State||$State||''%>" size="3" /> +<input name="State" value="<%$UserObj->State//$ARGS{State}//''%>" size="3" /> </td></tr> <tr><td align="right"> -<&|/l&>Zip</&>: +<&|/l&>Zip</&>: </td><td> -<input name="Zip" value="<%$UserObj->Zip||$Zip||''%>" size="9" /> +<input name="Zip" value="<%$UserObj->Zip//$ARGS{Zip}//''%>" size="9" /> </td></tr> <tr><td align="right"> -<&|/l&>Country</&>: +<&|/l&>Country</&>: </td><td> -<input name="Country" value="<%$UserObj->Country||$Country||''%>" /> +<input name="Country" value="<%$UserObj->Country//$ARGS{Country}//''%>" /> </td></tr> + +<& /Elements/EditCustomFields, Object => $UserObj, Grouping => 'Location', InTable => 1 &> + </table> </&> <br /> -<&| /Widgets/TitleBox, title => loc('Phone numbers') &> +<&| /Widgets/TitleBox, title => loc('Phone numbers'), class => 'user-info-phones' &> <table> <tr><td align="right"> -<&|/l&>Residence</&>: +<&|/l&>Residence</&>: </td><td> -<input name="HomePhone" value="<%$UserObj->HomePhone||$HomePhone||''%>" size="13" /><br /> +<input name="HomePhone" value="<%$UserObj->HomePhone//$ARGS{HomePhone}//''%>" size="13" /><br /> </td></tr> <tr><td align="right"> -<&|/l&>Work</&>: +<&|/l&>Work</&>: </td><td> -<input name="WorkPhone" value="<%$UserObj->WorkPhone||$WorkPhone||''%>" size="13" /><br /> +<input name="WorkPhone" value="<%$UserObj->WorkPhone//$ARGS{WorkPhone}//''%>" size="13" /><br /> </td></tr> <tr><td align="right"> -<&|/l&>Mobile</&>: +<&|/l&>Mobile</&>: </td><td> -<input name="MobilePhone" value="<%$UserObj->MobilePhone||$MobilePhone||''%>" size="13" /><br /> +<input name="MobilePhone" value="<%$UserObj->MobilePhone//$ARGS{MobilePhone}//''%>" size="13" /><br /> </td></tr> <tr><td align="right"> -<&|/l&>Pager</&>: +<&|/l&>Pager</&>: </td><td> -<input name="PagerPhone" value="<%$UserObj->PagerPhone||$PagerPhone||''%>" size="13" /><br /> +<input name="PagerPhone" value="<%$UserObj->PagerPhone//$ARGS{PagerPhone}//''%>" size="13" /><br /> </td> </tr> + +<& /Elements/EditCustomFields, Object => $UserObj, Grouping => 'Phones', InTable => 1 &> + </table> </&> <br /> -<&| /Widgets/TitleBox, title => loc('Custom Fields') &> -<table> -% my $CFs = $UserObj->CustomFields; -% while (my $CF = $CFs->Next) { -<tr valign="top"><td align="right"> -<% loc($CF->Name) %>: -</td><td> -% if ($UserObj->id) { -<& /Elements/EditCustomField, %ARGS, Object => $UserObj, CustomField => $CF &> -% } else { -<& /Elements/EditCustomField, %ARGS, NamePrefix => 'Object-RT::User--CustomField-', CustomField => $CF &> -% } -</td></tr> -% } -</table> -</&> + +<& /Elements/EditCustomFieldCustomGroupings, Object => $UserObj &> + % $m->callback( %ARGS, CallbackName => 'RightColumnBottom', UserObj => $UserObj ); </td></tr> <tr> <td colspan="2"> -<&| /Widgets/TitleBox, title => loc('Comments about this user') &> -<textarea class="comments" name="Comments" cols="80" rows="5" wrap="virtual"><%$UserObj->Comments||$Comments||''%></textarea> +<&| /Widgets/TitleBox, title => loc('Comments about this user'), class => 'user-info-comments' &> +<textarea class="comments" name="Comments" cols="80" rows="5" wrap="virtual"><%$UserObj->Comments//$ARGS{Comments}//''%></textarea> </&> %if (!$Create && $UserObj->Privileged) { <br /> -<&| /Widgets/TitleBox, title => loc('Signature') &> -<textarea class="signature" cols="80" rows="5" name="Signature" wrap="hard"><%$UserObj->Signature||$Signature||''%></textarea> +<&| /Widgets/TitleBox, title => loc('Signature'), class => 'user-info-signature' &> +<textarea class="signature" cols="80" rows="5" name="Signature" wrap="hard"><%$UserObj->Signature//$ARGS{Signature}//''%></textarea> </&> % } @@ -237,114 +237,69 @@ <%INIT> my $UserObj = RT::User->new($session{'CurrentUser'}); -my ($title, $PrivilegedChecked, $EnabledChecked, $Disabled, $result, @results); ++my ($title, @results); my ($val, $msg); +$ARGS{Privileged} = $ARGS{Privileged} ? 1 : 0; +delete $ARGS{Privileged} unless $ARGS{SetPrivileged}; + +$ARGS{Disabled} = $ARGS{Enabled} ? 0 : 1; +delete $ARGS{Disabled} unless $ARGS{SetEnabled}; + +my @fields = qw(Name Comments Signature EmailAddress FreeformContactInfo + Organization RealName NickName Lang EmailEncoding WebEncoding + ExternalContactInfoId ContactInfoSystem Gecos ExternalAuthId + AuthSystem HomePhone WorkPhone MobilePhone PagerPhone Address1 + Address2 City State Zip Country + ); + if ($Create) { $title = loc("Create a new user"); -} -else { - - if ( defined $id && $id eq 'new') { - ( $val, $msg ) = $UserObj->Create( - Name => $Name, - EmailAddress => $ARGS{'EmailAddress'}, - Name => $ARGS{'Name'}, - Comments => $ARGS{'Comments'}, - Signature => $ARGS{'Signature'}, - EmailAddress => $ARGS{'EmailAddress'}, - FreeformContactInfo => $ARGS{'FreeformContactInfo'}, - Organization => $ARGS{'Organization'}, - RealName => $ARGS{'RealName'}, - NickName => $ARGS{'NickName'}, - Lang => $ARGS{'Lang'}, - EmailEncoding => $ARGS{'EmailEncoding'}, - WebEncoding => $ARGS{'WebEncoding'}, - ExternalContactInfoId => $ARGS{'ExternalContactInfoId'}, - ContactInfoSystem => $ARGS{'ContactInfoSystem'}, - Gecos => $ARGS{'Gecos'}, - ExternalAuthId => $ARGS{'ExternalAuthId'}, - AuthSystem => $ARGS{'AuthSystem'}, - HomePhone => $ARGS{'HomePhone'}, - WorkPhone => $ARGS{'WorkPhone'}, - MobilePhone => $ARGS{'MobilePhone'}, - PagerPhone => $ARGS{'PagerPhone'}, - Address1 => $ARGS{'Address1'}, - Address2 => $ARGS{'Address2'}, - City => $ARGS{'City'}, - State => $ARGS{'State'}, - Zip => $ARGS{'Zip'}, - Country => $ARGS{'Country'}, - Privileged => $ARGS{'Privileged'}, - Disabled => ($ARGS{'Enabled'} ? 0 : 1) - ); - - if ($val) { - push @results, $msg; - push @results, ProcessObjectCustomFieldUpdates( ARGSRef => \%ARGS, Object => $UserObj ); - } else { - push @results, loc('User could not be created: [_1]', $msg); - } - } else { - $UserObj->Load($id) || $UserObj->Load($Name) - || Abort("Couldn't load user '" . ( $Name || '') . "'"); - $val = $UserObj->Id(); - } +} elsif ( defined $id && $id eq 'new') { + ( $val, $msg ) = $UserObj->Create( + (map {($_ => $ARGS{$_})} @fields), + Privileged => $ARGS{'Privileged'}, + Disabled => $ARGS{'Disabled'}, + ); if ($val) { - $title = loc("Modify the user [_1]", $UserObj->Name); - } - - # If the create failed - else { - $title = loc("Create a new user"); - $Create = 1; + push @results, $msg; + push @results, ProcessObjectCustomFieldUpdates( ARGSRef => \%ARGS, Object => $UserObj ); + $title = loc("Modify the user [_1]", $UserObj->Name); + } else { + push @results, loc('User could not be created: [_1]', $msg); + $title = loc("Create a new user"); + $Create = 1; } -} - - -$m->callback( %ARGS, CallbackName => 'BeforeUpdate', User => $UserObj, ARGSRef => \%ARGS, Results => \@results ); +} else { + $UserObj->Load($id) || $UserObj->Load($ARGS{Name}) + || Abort("Couldn't load user '" . ( $ARGS{Name} || '') . "'"); + $title = loc("Modify the user [_1]", $UserObj->Name); -# If we have a user to modify, lets try. -if ($UserObj->Id && $id ne 'new') { - - my @fields = qw(Name Comments Signature EmailAddress FreeformContactInfo - Organization RealName NickName Lang EmailEncoding WebEncoding - ExternalContactInfoId ContactInfoSystem Gecos ExternalAuthId - AuthSystem HomePhone WorkPhone MobilePhone PagerPhone Address1 - Address2 City State Zip Country - ); + $m->callback( %ARGS, CallbackName => 'BeforeUpdate', User => $UserObj, ARGSRef => \%ARGS, Results => \@results ); my @fieldresults = UpdateRecordObject ( AttributesRef => \@fields, - Object => $UserObj, - ARGSRef => \%ARGS ); + Object => $UserObj, + ARGSRef => \%ARGS ); push (@results,@fieldresults); push @results, ProcessObjectCustomFieldUpdates( ARGSRef => \%ARGS, Object => $UserObj ); #deal with freeside customer links push @results, ProcessObjectCustomers( ARGSRef => \%ARGS, Object => $UserObj ); - # {{{ Deal with special fields: Privileged, Enabled - if ( $SetPrivileged and $Privileged != $UserObj->Privileged ) { - my ($code, $msg) = $UserObj->SetPrivileged($Privileged); - push @results, loc('Privileged status: [_1]', loc_fuzzy($msg)); + if ( defined $ARGS{Privileged} and $ARGS{Privileged} != ($UserObj->Privileged || 0) ) { + my ($code, $msg) = $UserObj->SetPrivileged($ARGS{Privileged}); + push @results, loc('Privileged status: [_1]', loc_fuzzy($msg)); } - #we're asking about enabled on the web page but really care about disabled. - $Disabled = $Enabled ? 0 : 1; - - if ( ($SetEnabled) and ( $Disabled != $UserObj->Disabled) ) { - my ($code, $msg) = $UserObj->SetDisabled($Disabled); + if ( defined $ARGS{Disabled} and $ARGS{Disabled} != $UserObj->Disabled ) { + my ($code, $msg) = $UserObj->SetDisabled($ARGS{Disabled}); push @results, $msg; } - - } - -my %password_cond = $UserObj->CurrentUserRequireToSetPassword; if ( $UserObj->Id ) { # Deal with Password field my ($status, $msg) = $UserObj->SafeSetPassword( @@ -359,16 +314,6 @@ if ( $UserObj->Id ) { } } - -# Do some setup for the ui -unless ( $UserObj->id && $UserObj->Disabled ) { - $EnabledChecked = 'checked="checked"'; -} - -if ((!$Create && $UserObj->Privileged()) or (!$UserObj->Id and $Privileged)) { - $PrivilegedChecked = 'checked="checked"'; -} - # This code does automatic redirection if any updates happen. MaybeRedirectForResults( Actions => \@results, @@ -380,36 +325,6 @@ MaybeRedirectForResults( <%ARGS> $id => undef -$Name => undef -$Comments => undef -$Signature => undef -$EmailAddress => undef -$FreeformContactInfo => undef -$Organization => undef -$RealName => undef -$NickName => undef -$Privileged => undef -$SetPrivileged => undef -$Enabled => undef -$SetEnabled => undef -$Lang => undef -$EmailEncoding => undef -$WebEncoding => undef -$ExternalContactInfoId => undef -$ContactInfoSystem => undef -$Gecos => undef -$ExternalAuthId => undef -$AuthSystem => undef -$HomePhone => undef -$WorkPhone => undef -$MobilePhone => undef -$PagerPhone => undef -$Address1 => undef -$Address2 => undef -$City => undef -$State => undef -$Zip => undef -$Country => undef $CurrentPass => undef $Pass1 => undef $Pass2 => undef diff --git a/rt/share/html/Admin/Users/MyRT.html b/rt/share/html/Admin/Users/MyRT.html index c9a193aec..37d4b3b46 100644 --- a/rt/share/html/Admin/Users/MyRT.html +++ b/rt/share/html/Admin/Users/MyRT.html @@ -48,8 +48,6 @@ <& /Admin/Elements/Header, Title => $title &> <& /Elements/Tabs &> -<& /Widgets/SelectionBox:header, nojs => 1 &> - <& /Elements/ListActions, actions => \@actions &> <form method="post" action="MyRT.html"> @@ -62,7 +60,7 @@ % for my $pane (@panes) { <&|/Widgets/TitleBox, title => loc('RT at a glance').': '.loc($pane->{Name}), bodyclass => "" &> -<& /Widgets/SelectionBox:show, self => $pane, nojs => 1 &></&> +<& /Widgets/SelectionBox:show, self => $pane &></&> <br /> % } @@ -100,7 +98,8 @@ for my $object (@objs) { else { my $oid = ref($object).'-'.$object->Id.'-SavedSearch-'.$search->Id; my $type = ($SearchType eq 'Ticket') - ? 'Saved Search' : $SearchType; # loc + ? 'Saved Search' # loc + : $SearchType; push @items, ["saved-$oid", loc($type).": $loc_desc"]; } } @@ -108,7 +107,7 @@ for my $object (@objs) { my @panes = $m->comp( '/Admin/Elements/ConfigureMyRT', - panes => ['body', 'summary'], + panes => ['body', 'sidebar'], Action => "MyRT.html?id=$id", items => \@items, current_portlets => $portlets, @@ -119,7 +118,7 @@ my @panes = $m->comp( } ); -$m->comp( '/Widgets/SelectionBox:process', %ARGS, self => $_, nojs => 1 ) +$m->comp( '/Widgets/SelectionBox:process', %ARGS, self => $_ ) for @panes; </%init> diff --git a/rt/share/html/Admin/Users/index.html b/rt/share/html/Admin/Users/index.html index ec3368b3b..94d0fa578 100755 --- a/rt/share/html/Admin/Users/index.html +++ b/rt/share/html/Admin/Users/index.html @@ -58,19 +58,13 @@ <input type="hidden" name="UserField" value="Name" /> <input type="hidden" name="UserOp" value="LIKE" /> <&|/l&>Go to user</&> -<input type="text" name="UserString" value="" id="autocomplete-UserString" /> +<input type="text" name="UserString" value="" data-autocomplete="Users" data-autocomplete-return="Name" id="autocomplete-UserString" /> <script type="text/javascript"> jQuery(function(){ - jQuery("#autocomplete-UserString").autocomplete({ - source: <% RT->Config->Get('WebPath') |n,j%>+"/Helpers/Autocomplete/Users?return=Name", - // Auto-submit once a user is chosen - select: function( event, ui ) { - jQuery(event.target).val(ui.item.value); - var form = jQuery(event.target).closest('form'); - form.find('input[name=UserOp]').val('='); - form.submit(); - } - }).addClass("autocompletes-user"); + // Jump directly to the page if a user is chosen + jQuery("#autocomplete-UserString").on("autocompleteselect", function( event, ui ) { + document.location = RT.Config.WebPath + "/Admin/Users/Modify.html?id=" + ui.item.id; + }); }); </script> </form> @@ -81,8 +75,8 @@ jQuery(function(){ <input type="hidden" name="<% $field %>" value="<% $ARGS{ $field } %>" /> % } <&|/l&>Find all users whose</&> <& /Elements/SelectUsers, %ARGS, Fields => \@fields &><br /> -<input type="checkbox" class="checkbox" name="FindDisabledUsers" value="1" <% $FindDisabledUsers? 'checked="checked"': '' %> /> -<&|/l&>Include disabled users in search.</&> +<input type="checkbox" class="checkbox" id="FindDisabledUsers" name="FindDisabledUsers" value="1" <% $FindDisabledUsers? 'checked="checked"': '' %> /> +<label for="FindDisabledUsers"><&|/l&>Include disabled users in search.</&></label> <br /> <div align="right"><input type="submit" class="button" value="<&|/l&>Go!</&>" /></div> </form> @@ -95,7 +89,7 @@ jQuery(function(){ <& /Elements/CollectionList, OrderBy => 'Name', Order => 'ASC', - Rows => 100, + Rows => $Rows, %ARGS, Format => $Format, Collection => $users, @@ -135,13 +129,14 @@ else { } $Format ||= RT->Config->Get('AdminSearchResultFormat')->{'Users'}; +my $Rows = RT->Config->Get('AdminSearchResultRows')->{'Users'} || 50; # Build up the list of fields to display for searching my $i = 0; my %sorted = map { $_ => $i++ } qw( Name EmailAddress RealName Organization NickName WorkPhone HomePhone MobilePhone PagerPhone Address1 Address2 City State Zip Country - Timezone Lang Gecos Comments + Timezone Lang Gecos SMIMECertificate Comments ); my @attrs = sort { $sorted{$a} <=> $sorted{$b} } diff --git a/rt/share/html/Admin/index.html b/rt/share/html/Admin/index.html index 17e93fa9f..b9768e662 100755 --- a/rt/share/html/Admin/index.html +++ b/rt/share/html/Admin/index.html @@ -47,7 +47,7 @@ %# END BPS TAGGED BLOCK }}} <& /Admin/Elements/Header, Title => loc('RT Administration') &> <& /Elements/Tabs &> -<& /Elements/ListMenu, menu => Menu()->child('tools')->child('config') &> +<& /Elements/ListMenu, menu => Menu()->child('admin') &> % if (RT->Config->Get('ShowRTPortal')) { <& /Admin/Elements/Portal &> % } |