diff options
author | Ivan Kohler <ivan@freeside.biz> | 2012-04-24 11:35:56 -0700 |
---|---|---|
committer | Ivan Kohler <ivan@freeside.biz> | 2012-04-24 11:35:56 -0700 |
commit | 6587f6ba7d047ddc1686c080090afe7d53365bd4 (patch) | |
tree | ec77342668e8865aca669c9b4736e84e3077b523 /rt/share/html/Admin | |
parent | 47153aae5c2fc00316654e7277fccd45f72ff611 (diff) |
first pass RT4 merge, RT#13852
Diffstat (limited to 'rt/share/html/Admin')
18 files changed, 2023 insertions, 0 deletions
diff --git a/rt/share/html/Admin/Articles/Classes/CustomFields.html b/rt/share/html/Admin/Articles/Classes/CustomFields.html new file mode 100644 index 000000000..868c288b8 --- /dev/null +++ b/rt/share/html/Admin/Articles/Classes/CustomFields.html @@ -0,0 +1,64 @@ +%# BEGIN BPS TAGGED BLOCK {{{ +%# +%# COPYRIGHT: +%# +%# This software is Copyright (c) 1996-2012 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 => $title &> +<& /Elements/Tabs &> +<& /Admin/Elements/EditCustomFields, %ARGS, title => $title, Object => $Object, ObjectType => 'RT::Class', SubType => 'RT::Article' &> +<%INIT> +my $Object = RT::Class->new( $session{'CurrentUser'} ); + +$Object->Load($id) || Abort( loc( "Couldn't load object [_1]", $id ) ); +my $FriendlySubTypes = + RT::CustomField->new( $session{'CurrentUser'} ) + ->FriendlyLookupType( $Object->CustomFieldLookupType ); + +my $title = loc( 'Edit Custom Fields for [_1]', $Object->Name ); + +</%INIT> +<%ARGS> +$id => undef +</%ARGS> diff --git a/rt/share/html/Admin/Articles/Classes/GroupRights.html b/rt/share/html/Admin/Articles/Classes/GroupRights.html new file mode 100644 index 000000000..092ea4b23 --- /dev/null +++ b/rt/share/html/Admin/Articles/Classes/GroupRights.html @@ -0,0 +1,73 @@ +%# BEGIN BPS TAGGED BLOCK {{{ +%# +%# COPYRIGHT: +%# +%# This software is Copyright (c) 1996-2012 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 group rights for Class [_1]', $ClassObj->Name) &> +<& /Elements/Tabs &> +<& /Elements/ListActions, actions => \@results &> + +<form method="post" action="GroupRights.html" id="ModifyGroupRights" name="ModifyGroupRights"> +<input type="hidden" name="id" value="<% $ClassObj->id %>" /> + + <& /Admin/Elements/EditRights, Context => $ClassObj, Principals => \@principals &> + + <& /Elements/Submit, Label => loc('Save Changes') &> +</form> +<%INIT> + +if (!defined $id) { + $m->comp("/Elements/Error", Why => loc("No Class defined")); +} + +my $ClassObj = RT::Class->new($session{'CurrentUser'}); +$ClassObj->Load($id) || $m->comp("/Elements/Error", Why => loc("Couldn't load Class [_1]",$id)); + +my @results = ProcessACLs(\%ARGS); +my @principals = GetPrincipalsMap($ClassObj, qw(System Groups)); +</%INIT> +<%ARGS> +$id => undef +</%ARGS> diff --git a/rt/share/html/Admin/Articles/Classes/Modify.html b/rt/share/html/Admin/Articles/Classes/Modify.html new file mode 100644 index 000000000..8dbd2897d --- /dev/null +++ b/rt/share/html/Admin/Articles/Classes/Modify.html @@ -0,0 +1,199 @@ +%# BEGIN BPS TAGGED BLOCK {{{ +%# +%# COPYRIGHT: +%# +%# This software is Copyright (c) 1996-2012 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 name="ModifyClass" action="<% RT->Config->Get('WebPath') %>/Admin/Articles/Classes/Modify.html" method="post"> +<input type="hidden" name="Submitted" value="1" /> +%if ($Create ) { +<input type="hidden" name="id" value="new" /> +% } else { +<input type="hidden" name="id" value="<%$ClassObj->Id%>" /> +% } + +<table> +<tr> +<td align="right"><&|/l&>Class Name</&>: </td> +<td><input name="Name" value="<% $ClassObj->Name || $Name || ''%>" /></td> +</tr> +<tr> +<td align="right"><&|/l&>Description</&>:</td> +<td><input name="Description" value="<% $ClassObj->Description || $Description || '' %>" size=60 /></td> +</tr> +<tr> +<td> </td> +<td><input type="checkbox" name="Enabled" value="1" <%$EnabledChecked%>> <&|/l&>Enabled (Unchecking this box disables this class)</&></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> +</tr> +</table> + +<h3>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> +% if ( $cfs ) { +% while (my $cf = $cfs->Next) { +<li>Include custom field '<% $cf->Name %>' + <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> + </ul> +</li> +% } } +</ul> + +%$m->callback( CallbackName => 'BeforeSubmit', CustomFields => $cfs, ClassObj => $ClassObj ); + +% if ( $Create ) { +<& /Elements/Submit, Label => loc('Create') &> +% } else { +<& /Elements/Submit, Label => loc('Save Changes') &> +% } +</form> + +<%INIT> + +my $ClassObj = RT::Class->new($session{'CurrentUser'}); +my ($title, @results, $Disabled); + +if ($Create) { + $title = loc("Create a Class"); +} else { + my ( $val, $msg ); + if ($id eq 'new') { + ($val, $msg) = $ClassObj->Create(Name => $Name); + if ( $val ) { + push @results, $msg; + } + else { + push @results, loc('Class could not be created: [_1]', $msg); + } + } else { + $ClassObj->Load($id) || $ClassObj->Load($Name) || $m->comp("/Elements/Error", Why => "Couldn't load class '$Name'"); + $val = $ClassObj->id; + } + + if ( $val ) { + $title = loc('Modify the Class [_1]', $ClassObj->Name); + } + else { + $title = loc("Create a Class"); + $Create = 1; + } +} + +if ($ClassObj->Id()) { + $ARGS{HotList} ||= 0 if $Submitted; + my @attribs= qw(Description Name HotList); + $m->callback( CallbackName => 'AttributeList', Attributes => \@attribs, ARGSRef => \%ARGS ); + push @results, UpdateRecordObject( AttributesRef => \@attribs, + Object => $ClassObj, + ARGSRef => \%ARGS); +} + +#we're asking about enabled on the web page but really care about disabled. +if ((defined $Enabled && $Enabled == 1) or (not defined $Enabled and $Create)) { + $Disabled = 0; +} else { + $Disabled = 1; +} + +my %include = (Name => 1, Summary => 1); + +my $cfs; +if ( $ClassObj->id ) { + $cfs = $ClassObj->ArticleCustomFields; + $include{"CF-Title-".$_->Id} = $include{"CF-Value-".$_->Id} = 1 while $_ = $cfs->Next; +} + +if ( $ClassObj->id && $Submitted ) { + if ( $Disabled != $ClassObj->Disabled) { + my ($code, $msg) = $ClassObj->SetDisabled($Disabled); + push @results, loc('Enabled status [_1]', loc_fuzzy($msg)); + } + + for (keys %include) { + if ($ARGS{"Include-$_"}) { + $ClassObj->DeleteAttribute("Skip-$_"); + } else { + $ClassObj->SetAttribute(Name => "Skip-$_", Content => 1); + } + } +} + +# This code does automatic redirection if any updates happen. +MaybeRedirectForResults( + Actions => \@results, + Arguments => { id => $ClassObj->Id }, +) if $ClassObj->id; + + +if ( $ClassObj->id ) { + $include{$_} = not $ClassObj->FirstAttribute("Skip-$_") for keys %include; +} + +$include{$_} = $include{$_} ? " CHECKED" : "" for keys %include; + +my $EnabledChecked = ($Create ? $Disabled : $ClassObj->Disabled()) ? "" : "CHECKED"; +my $HotListChecked = $ClassObj->id && $ClassObj->HotList ? "CHECKED" : ""; +</%INIT> + + +<%ARGS> +$id => undef +$result => undef +$Name => undef +$Create => undef +$Description => undef +$Submitted => undef +$Enabled => undef +</%ARGS> diff --git a/rt/share/html/Admin/Articles/Classes/Objects.html b/rt/share/html/Admin/Articles/Classes/Objects.html new file mode 100644 index 000000000..f7be9f598 --- /dev/null +++ b/rt/share/html/Admin/Articles/Classes/Objects.html @@ -0,0 +1,154 @@ +%# BEGIN BPS TAGGED BLOCK {{{ +%# +%# COPYRIGHT: +%# +%# This software is Copyright (c) 1996-2012 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 action="Objects.html" method="post"> +<input type="hidden" class="hidden" name="id" value="<% $id %>" /> + +% 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.</&> +% } 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.</&> + +<h2><&|/l&>Selected Queues</&></h2> +<& /Elements/CollectionList, + OrderBy => 'id', + Order => 'ASC', + %ARGS, + Collection => $applied, + Rows => 0, + Page => 1, + Format => $format, + DisplayFormat => "'__CheckBox.{RemoveClass-". $Class->id ."}__',". $format, + AllowSorting => 0, + ShowEmpty => 0, + PassArguments => [ + qw(id Format Rows Page Order OrderBy), + ], +&> + +<h2><&|/l&>Unselected Queues</&></h2> +<& /Elements/CollectionList, + OrderBy => 'id', + Order => 'ASC', + %ARGS, + Collection => $not_applied, + Rows => 50, + Format => $format, + DisplayFormat => "'__CheckBox.{AddClass-". $Class->id ."}__',". $format, + AllowSorting => 1, + ShowEmpty => 0, + PassArguments => [ + qw(id Format Rows Page Order OrderBy), + ], +&> + +% } + +<& /Elements/Submit, Name => 'UpdateObjs' &> +</form> + +<%INIT> +my $Class = RT::Class->new($session{'CurrentUser'}); +$Class->Load($id) or Abort(loc("Could not load Class [_1]"), $id); + +my (@results); + +if ( $UpdateObjs ) { + if ( defined (my $del = $ARGS{'RemoveClass-'.$Class->id}) ) { + foreach my $id ( ref $del? (@$del) : ($del) ) { + my $object = RT::Queue->new( $session{'CurrentUser'} ); + if ( $id ) { + $object->Load( $id ); + next unless $object->id; + } + + my ($status, $msg) = $Class->RemoveFromObject( $object ); + push @results, $msg; + } + } + if ( defined (my $add = $ARGS{'AddClass-'.$Class->id}) ) { + foreach my $id ( ref $add? (@$add) : ($add) ) { + my $object = RT::Queue->new( $session{'CurrentUser'} ); + if ( $id ) { + $object->Load( $id ); + next unless $object->id; + } + + my ($status, $msg) = $Class->AddToObject( $object ); + push @results, $msg; + } + } +} + +my $is_global = $Class->IsApplied(0); + +my $applied = $Class->AppliedTo; +my $not_applied = $Class->NotAppliedTo; + +my $collection_class = ref($applied); +$collection_class =~ s/^RT:://; + +my $format = RT->Config->Get('AdminSearchResultFormat')->{$collection_class} + || '__id__,__Name__'; + +my $title = loc('Modify associated objects for [_1]', $Class->Name); + +</%INIT> +<%ARGS> +$id => undef +$FindDisabledObjects => 0 +$UpdateObjs => 0 +</%ARGS> diff --git a/rt/share/html/Admin/Articles/Classes/Topics.html b/rt/share/html/Admin/Articles/Classes/Topics.html new file mode 100644 index 000000000..5418d81a5 --- /dev/null +++ b/rt/share/html/Admin/Articles/Classes/Topics.html @@ -0,0 +1,68 @@ +%# BEGIN BPS TAGGED BLOCK {{{ +%# +%# COPYRIGHT: +%# +%# This software is Copyright (c) 1996-2012 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 &> + +<& /Admin/Articles/Elements/Topics, title => $title, RootObj => $ClassObj, %ARGS &> + +<%INIT> + +my $ClassObj = RT::Class->new($session{'CurrentUser'}); +$ClassObj->Load($ARGS{'id'}) || $m->comp("/Elements/Error", Why => "Couldn't load class '$id'"); + +my $title = $Modify + ? loc("Modify topic for [_1]", $ClassObj->Name) + : loc("Edit topic hierarchy for [_1]", $ClassObj->Name); + +</%INIT> + + +<%ARGS> +$id => undef +$Modify => "" +</%ARGS> diff --git a/rt/share/html/Admin/Articles/Classes/UserRights.html b/rt/share/html/Admin/Articles/Classes/UserRights.html new file mode 100644 index 000000000..c1aedeb33 --- /dev/null +++ b/rt/share/html/Admin/Articles/Classes/UserRights.html @@ -0,0 +1,72 @@ +%# BEGIN BPS TAGGED BLOCK {{{ +%# +%# COPYRIGHT: +%# +%# This software is Copyright (c) 1996-2012 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 user rights for class [_1]', $ClassObj->Name) &> +<& /Elements/Tabs &> +<& /Elements/ListActions, actions => \@results &> + +<form method="post" action="UserRights.html" name="ModifyUserRights" id="ModifyUserRights"> +<input type="hidden" name="id" value="<% $ClassObj->id %>" /> + <& /Admin/Elements/EditRights, Context => $ClassObj, Principals => \@principals &> + + <& /Elements/Submit, Label => loc('Save Changes') &> +<%INIT> +my @results = ProcessACLs(\%ARGS); + +if (!defined $id) { + $m->comp("/Elements/Error", Why => loc("No Class defined")); +} + +my $ClassObj = RT::Class->new($session{'CurrentUser'}); +$ClassObj->Load($id) || $m->comp("/Elements/Error", Why => loc("Couldn't load Class [_1]",$id)); + +my @principals = GetPrincipalsMap($ClassObj, 'Users'); + +</%INIT> +<%ARGS> +$id => undef +</%ARGS> diff --git a/rt/share/html/Admin/Articles/Classes/index.html b/rt/share/html/Admin/Articles/Classes/index.html new file mode 100644 index 000000000..8c32677c9 --- /dev/null +++ b/rt/share/html/Admin/Articles/Classes/index.html @@ -0,0 +1,91 @@ +%# BEGIN BPS TAGGED BLOCK {{{ +%# +%# COPYRIGHT: +%# +%# This software is Copyright (c) 1996-2012 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("Select a Class") &> +<& /Elements/Tabs &> + +<h1><%$caption%>:</h1> +<p><&|/l&>Select a Class</&>:</p> +% unless ($Classes->Count) { +<em><&|/l&>No Classes matching search criteria found.</&></em> +% } else { +<& /Elements/CollectionList, + OrderBy => 'Name', + Order => 'ASC', + %ARGS, + Format => $Format, + Collection => $Classes, + AllowSorting => 1, + PassArguments => [qw( Format Rows Page Order OrderBy FindDisabledClasses )], +&> +% } + +<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 /> +<div align="right"><input type="submit" value="<&|/l&>Go!</&>" /></div> +</form> +<%INIT> +my $caption; +my $Classes = RT::Classes->new($session{'CurrentUser'}); + +if ($FindDisabledClasses) { + $caption = loc("All Classes"); + $Classes->{'find_disabled_rows'} = 1; + $Classes->UnLimit(); +} else { + $caption = loc("Enabled Classes"); + $Classes->LimitToEnabled(); + +} + +$Format ||= RT->Config->Get('AdminSearchResultFormat')->{'Classes'}; + +</%INIT> +<%ARGS> +$FindDisabledClasses => 0 +$Format => undef +</%ARGS> diff --git a/rt/share/html/Admin/Articles/Elements/Topics b/rt/share/html/Admin/Articles/Elements/Topics new file mode 100644 index 000000000..96ddaf00c --- /dev/null +++ b/rt/share/html/Admin/Articles/Elements/Topics @@ -0,0 +1,215 @@ +%# BEGIN BPS TAGGED BLOCK {{{ +%# +%# COPYRIGHT: +%# +%# This software is Copyright (c) 1996-2012 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/ListActions, actions => \@results &> + +<form action="<%RT->Config->Get('WebPath')%><% $m->request_comp->path |n %>" method="post"> +<input type="hidden" name="id" value="<%$RootObj->Id%>" /> + +% if (!$Modify) { +<table> +<tr> +<td><&|/l&>Topic Name</&></td> +<td><input type="text" name="Name" size="30" /></td> +</tr> +<tr> +<td><&|/l&>Description</&></td> +<td><input type="text" name="Description" size="50" /></td> +</tr> +</table> +% } else { +<a href="Topics.html">New topic</a> +% } + +<& .tree, Element => $tree, Action => $Modify ? "Move" : "Add", Prefix => $Modify ? "Topic-$Modify-Parent" : "Insert", RootObj => $RootObj, Modify => $Modify &> + +</form> + +<%def .edit> + +<table style="margin-top: -0.75em"> +<tr> + <td>Topic Name:</td> + <td><input type="text" name="Topic-<%$topic->Id%>-Name" size="20" value="<%$topic->Name%>" /></td> + <td><input type="submit" name="Update" value="Update"><br /></td> +</tr> +<tr> + <td>Description:</td> + <td> <input type="text" name="Topic-<%$topic->Id%>-Description" size="20" value="<%$topic->Description%>" /></td> + <td><input type="submit" name="Delete-Topic-<%$topic->Id%>" value="Delete" /></td> +</tr> +</table> +<%args> +$topic +</%args> +</%def> + +<%def .tree> +% my $topic = $Element->getNodeValue; +% unless ($Element->isRoot) { +% if ($Modify and $topic->Id == $Modify) { +% $Action = ""; +<& .edit, topic => $topic &> +% } else { +<a href="<%RT->Config->Get('WebPath')%><% $m->request_comp->path |n %>?id=<%$RootObj->Id%>&Modify=<%$topic->Id%>" + title="<%$topic->Description%>"><%$topic->Name || loc("(no name)") %></a> +% } +% } +<ul> +% for my $e (sort {$a->getNodeValue->Name cmp $b->getNodeValue->Name} $Element->getAllChildren) { +<li><& .tree, Element => $e, Action => $Action, Prefix => $Prefix, RootObj => $RootObj, Modify => $Modify &></li> +% } +% if ($Action) { +% unless ($Action eq "Move" and grep {$_->getNodeValue->Id == $Modify} $Element->getAllChildren) { +<li><input type="submit" name="<%$Prefix%>-<%$topic eq "root" ? 0 : $topic->Id%>" value="<&|/l&><%$Action%> here</&>" /></li> +% } +% } +</ul> +<%args> +$Element +$Action +$Prefix +$RootObj +$Modify +</%args> +</%def> + +<%INIT> + +my @results; + +for my $k (keys %ARGS) { + if ($k =~ /^Topic-(\d+)-(Name|Description)/) { + my $topic = RT::Topic->new($session{'CurrentUser'}); + $topic->Load($1); + if ($topic->Id) { + next if $ARGS{$k} eq $topic->$2; + my $proc = "Set$2"; + my ($val, $msg) = $topic->$proc($ARGS{$k}); + push @results, $msg; + } else { + $m->comp("/Elements/Error", Why => loc("Topic not found")); + } + } elsif ($k =~ /^Topic-(\d+)-Parent-(\d+)/) { + my $topic = RT::Topic->new($session{'CurrentUser'}); + $topic->Load($1); + if ($topic->Id) { + next if $2 eq $topic->Parent; + my $old = $topic->Parent; + my $new = "$2"; + my ($val, $msg) = $topic->setParent($new); + push @results, $msg; + } else { + $m->comp("/Elements/Error", Why => loc("Topic not found")); + } + } elsif ($k =~ /^Insert-(\d+)/) { + my $topic = RT::Topic->new($session{'CurrentUser'}); + my ($id, $msg) = $topic->Create( + Parent => $1, + Name => $ARGS{'Name'}, + Description => $ARGS{'Description'}, + ObjectType => ref($RootObj), + ObjectId => $RootObj->Id, + ); + push @results, $msg; + } +} +for my $k (keys %ARGS) { + next unless $k =~ /^Delete-Topic-(\d+)/; + my $topic = RT::Topic->new($session{'CurrentUser'}); + $topic->Load($1); + if ($topic->Id) { + my ($val, $msg) = $topic->DeleteAll(); + push @results, $msg; + } else { + $m->comp("/Elements/Error", Why => loc("Topic not found")); + } +} + +my $topics = RT::Topics->new($session{'CurrentUser'}); +$topics->LimitToObject($RootObj); +$topics->OrderByCols({FIELD => 'Parent'}, {FIELD => 'id'}); + +use Tree::Simple; +my $tree = Tree::Simple->new(Tree::Simple->ROOT); +my %lookup = (0 => $tree); + +my @todo; +while (my $topic = $topics->Next) { + push @todo, $topic; +} + +{ + my $changed = 0; + my @work = @todo; + @todo = (); + for my $topic (@work) { + if (defined $lookup{$topic->Parent}) { + $lookup{$topic->Id} = Tree::Simple->new($topic, $lookup{$topic->Parent}); + $changed = 1; + } else { + push @todo, $topic; + } + } + redo unless $changed == 0; +} + +for my $topic (@todo) { + $topic->setParent(0); + $lookup{$topic->Id} = Tree::Simple->new($topic, $tree); + push @results, "Reparented orphan ".$topic->Id." to root"; +} + +</%INIT> + + +<%ARGS> +$RootObj => undef +$title => "" +$Modify => "" +</%ARGS> + diff --git a/rt/share/html/Admin/Articles/index.html b/rt/share/html/Admin/Articles/index.html new file mode 100644 index 000000000..d697dc3e0 --- /dev/null +++ b/rt/share/html/Admin/Articles/index.html @@ -0,0 +1,50 @@ +%# BEGIN BPS TAGGED BLOCK {{{ +%# +%# COPYRIGHT: +%# +%# This software is Copyright (c) 1996-2012 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 => loc('Article Administration') &> +<& /Elements/Tabs &> +<& /Elements/ListMenu, menu => Menu()->child('tools')->child('config')->child('articles') &> diff --git a/rt/share/html/Admin/Elements/EditQueueWatcherGroup b/rt/share/html/Admin/Elements/EditQueueWatcherGroup new file mode 100644 index 000000000..8bc1de29a --- /dev/null +++ b/rt/share/html/Admin/Elements/EditQueueWatcherGroup @@ -0,0 +1,56 @@ +%# BEGIN BPS TAGGED BLOCK {{{ +%# +%# COPYRIGHT: +%# +%# This software is Copyright (c) 1996-2012 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 }}} +<%ARGS> +$Label +$QueueObj +$Watchers +</%ARGS> +<span><% $Label %>:</span> + +<& /Admin/Elements/EditQueueWatchers, QueueObj => $QueueObj, Watchers => $Watchers &> + diff --git a/rt/share/html/Admin/Elements/EditRights b/rt/share/html/Admin/Elements/EditRights new file mode 100644 index 000000000..e5b9908b5 --- /dev/null +++ b/rt/share/html/Admin/Elements/EditRights @@ -0,0 +1,175 @@ +%# BEGIN BPS TAGGED BLOCK {{{ +%# +%# COPYRIGHT: +%# +%# This software is Copyright (c) 1996-2012 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 }}} +<%args> +$Context +$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 ); + +# Try to detect if we want to include an add user/group box +unless ( $AddPrincipal ) { + my $last = $Principals->[-1]; + if ( $last->[0] =~ /Groups/i ) { + $AddPrincipal = 'group'; # loc + } + elsif ( $last->[0] =~ /Users/i ) { + $AddPrincipal = 'user'; # loc + } +} +</%init> +%# Principals is an array of arrays, where the inner arrays are like: +%# [ 'Category name' => $CollectionObj => 'DisplayColumn' => 1 ] +%# The last value is a boolen determining if the value of DisplayColumn +%# should be loc()-ed before display. + +<script type="text/javascript"> + jQuery(function() { + jQuery(".rights-editor").tabs({ + select: function(ev, ui) { + window.location.hash = ui.tab.hash; + } + }); + jQuery(".rights-editor .category-tabs").tabs(); + }); +</script> + +<div class="rights-editor clearfix"> + <ul> +<%perl> +for my $category (@$Principals) { + my ($name, $collection, $col, $loc) = @$category; +</%perl> +<li class="category"><% loc($name) %></li> +<%perl> + while ( my $obj = $collection->Next ) { + my $display = ref $col eq 'CODE' ? $col->($obj) : $obj->$col; + my $id = "acl-$name-" . $obj->PrincipalId; + $id =~ s/[^a-zA-Z0-9\-]/_/g; +</%perl> +<li><a href="#<% $id %>"><% $loc ? loc($display) : $display %></a></li> +<%perl> + } +} +</%perl> +% if ( $AddPrincipal ) { + <li class="category"><&|/l, loc($AddPrincipal) &>Add [_1]</&></li> + <li class="addprincipal"> + <a href="#acl-AddPrincipal"> + <input type="text" value="" + name="AddPrincipalForRights-<% lc $AddPrincipal %>" + id="AddPrincipalForRights-<% lc $AddPrincipal %>" /> + <script type="text/javascript"> + jQuery(function() { + jQuery("#AddPrincipalForRights-<% lc $AddPrincipal %>").keyup(function(){ + toggle_addprincipal_validity(this, true); + }); + +% if (lc $AddPrincipal eq 'group') { + jQuery("#AddPrincipalForRights-<% lc $AddPrincipal %>").autocomplete({ + source: "<% RT->Config->Get('WebPath')%>/Helpers/Autocomplete/Groups", + select: addprincipal_onselect, + change: addprincipal_onchange + }); +% } + }); + </script> +% my $type = lc $AddPrincipal eq 'user' ? loc('username') : loc($AddPrincipal); + <span class="warning"><&|/l, $type &>Invalid [_1]</&></span> + </a> + </li> +% } + </ul> + +<%perl> +# Now generate our rights panels for each principal +for my $category (@$Principals) { + my ($name, $collection, $col, $loc) = @$category; + while ( my $obj = $collection->Next ) { + my $display = ref $col eq 'CODE' ? $col->($obj) : $obj->$col; + my $id = "acl-$name-" . $obj->PrincipalId; + $id =~ s/[^a-zA-Z0-9\-]/_/g; +</%perl> + + <div id="<% $id %>"> + <h3> + <% $loc ? loc($display) : $display %> +<%perl> +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 ); + + if ( $subgroups->Count ) { + my $inc = join ", ", map $_->Name, @{$subgroups->ItemsArrayRef}; +</%perl> + <span class="subgroups"><&|/l, $inc &>includes [_1]</&></span>\ +<%perl> + } +} +</%perl> + </h3> + <& EditRightsCategoryTabs, Context => $Context, Principal => $obj, id => $id &> + </div> +<%perl> + } +} + +if ( $AddPrincipal ) { +</%perl> + <div id="acl-AddPrincipal"> + <h3><&|/l, loc($AddPrincipal) &>Add rights for this [_1]</&></h3> + <& EditRightsCategoryTabs, Context => $Context, id => 'acl-AddPrincipal' &> + </div> +% } + +</div> diff --git a/rt/share/html/Admin/Elements/EditRightsCategoryTabs b/rt/share/html/Admin/Elements/EditRightsCategoryTabs new file mode 100644 index 000000000..786cafdd8 --- /dev/null +++ b/rt/share/html/Admin/Elements/EditRightsCategoryTabs @@ -0,0 +1,129 @@ +%# BEGIN BPS TAGGED BLOCK {{{ +%# +%# COPYRIGHT: +%# +%# This software is Copyright (c) 1996-2012 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 }}} +<%args> +$Context +$Principal => undef +$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}; +} else { + %available_rights = ( loc('System Error') => loc("No rights found") ); +} + +# ...and their categories +if ( blessed($Context) and $Context->can('RightCategories') ) { + my %right_categories = %{$Context->RightCategories}; + + for my $right (keys %available_rights) { + push @{$categories{$right_categories{$right}}}, $right; + } +} + +# Find all the current rights for this principal +my %current_rights; +if ($Principal) { + my $acls = RT::ACL->new($session{'CurrentUser'}); + $acls->LimitToObject( $Context ); + $acls->LimitToPrincipal( Id => $Principal->PrincipalId ); + + while ( my $ace = $acls->Next ) { + my $right = $ace->RightName; + $current_rights{$right} = 1; + } +} + +my %category_desc = ( + 'General' => loc('General rights'), + 'Staff' => loc('Rights for Staff'), + 'Admin' => loc('Rights for Administrators'), + 'Status' => loc('Status changes'), +); + +my %catsort = ( General => 1, Staff => 2, Admin => 3, Status => 4 ); + +$acldesc ||= join '-', ($Principal ? $Principal->PrincipalId : 'addprincipal'), + ref($Context), $Context->Id; +</%init> + <div class="category-tabs"> + <ul> +% for my $category (sort { $catsort{$a} <=> $catsort{$b} } keys %categories) { + <li><a href="#<% "$id-$category" %>"><% $category_desc{$category} || loc('Miscellaneous') %></a></li> +% } + </ul> +% for my $category (sort { $catsort{$a} <=> $catsort{$b} } keys %categories) { + <div id="<% "$id-$category" %>"> + <ul class="rights-list"> +% for my $right (sort { $available_rights{$a} cmp $available_rights{$b} } @{$categories{$category}}) { + <li> + <input type="checkbox" class="checkbox" + name="SetRights-<% $acldesc %>" + id="SetRights-<% $acldesc %>-<% $right %>" + value="<% $right %>" + <% $current_rights{$right} ? 'checked' : '' %> /> + <label for="SetRights-<% $acldesc %>-<% $right %>" title="<% loc($right) %>"> + <% loc($available_rights{$right}) %> + <span class="separator">—</span> + <span class="rightname"><% loc($right) %></span> + </label> + </li> +% } + </ul> + </div> +% } + </div> + <input type="hidden" name="CheckACL" value="<% $acldesc %>" /> diff --git a/rt/share/html/Admin/Elements/Portal b/rt/share/html/Admin/Elements/Portal new file mode 100644 index 000000000..d5e75c598 --- /dev/null +++ b/rt/share/html/Admin/Elements/Portal @@ -0,0 +1,52 @@ +%# BEGIN BPS TAGGED BLOCK {{{ +%# +%# COPYRIGHT: +%# +%# This software is Copyright (c) 1996-2012 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 }}} +<div id="rt-portal"> +<&| /Widgets/TitleBox, title => 'RT Portal' &> +<iframe src="http://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/SelectCustomFieldRenderType b/rt/share/html/Admin/Elements/SelectCustomFieldRenderType new file mode 100644 index 000000000..5034c4dfb --- /dev/null +++ b/rt/share/html/Admin/Elements/SelectCustomFieldRenderType @@ -0,0 +1,70 @@ +%# BEGIN BPS TAGGED BLOCK {{{ +%# +%# COPYRIGHT: +%# +%# This software is Copyright (c) 1996-2012 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%>"> +%for my $option (@types) { +<option value="<%$option%>"<%$option eq $Default && qq[ selected="selected"] |n%>><% $option %></option> +%} +</select> +<%INIT> +my $cf = RT::CustomField->new($session{'CurrentUser'}); +$Default ||= $cf->DefaultRenderType($TypeComposite); + +my @types = $cf->RenderTypes($TypeComposite); + +# XXX: We currently don't support cascaded select CFs when +# rendering as a list, so don't offer it for now. +if ( $BasedOn ) { + @types = grep { not /List/ } @types; +} +</%INIT> +<%ARGS> +$Default => undef +$TypeComposite => 'Select-0' +$Name => 'RenderType' +$BasedOn => 0 +</%ARGS> diff --git a/rt/share/html/Admin/Global/CustomFields/Class-Article.html b/rt/share/html/Admin/Global/CustomFields/Class-Article.html new file mode 100644 index 000000000..771e9efac --- /dev/null +++ b/rt/share/html/Admin/Global/CustomFields/Class-Article.html @@ -0,0 +1,54 @@ +%# BEGIN BPS TAGGED BLOCK {{{ +%# +%# COPYRIGHT: +%# +%# This software is Copyright (c) 1996-2012 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 &> +<& /Admin/Elements/EditCustomFields, %ARGS, title => $title, ObjectType => 'RT::Class', Object => $object, SubType => 'RT::Article' &> +<%INIT> + my $title = loc( 'Edit Custom Fields for articles in all classes'); + my $object = RT::Class->new($session{'CurrentUser'}); +</%INIT> diff --git a/rt/share/html/Admin/Global/Topics.html b/rt/share/html/Admin/Global/Topics.html new file mode 100644 index 000000000..b1a1d9796 --- /dev/null +++ b/rt/share/html/Admin/Global/Topics.html @@ -0,0 +1,63 @@ +%# BEGIN BPS TAGGED BLOCK {{{ +%# +%# COPYRIGHT: +%# +%# This software is Copyright (c) 1996-2012 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 &> +<& /Admin/Articles/Elements/Topics, RootObj => $RT::System, title => $title, %ARGS &> + +<%INIT> + +my $title = $Modify + ? loc("Modify global topics") + : loc("Edit global topic hierarchy"); + +</%INIT> + +<%ARGS> +$id => undef +$Modify => "" +</%ARGS> diff --git a/rt/share/html/Admin/Tools/Queries.html b/rt/share/html/Admin/Tools/Queries.html new file mode 100644 index 000000000..2fe2d5ac1 --- /dev/null +++ b/rt/share/html/Admin/Tools/Queries.html @@ -0,0 +1,129 @@ +%# BEGIN BPS TAGGED BLOCK {{{ +%# +%# COPYRIGHT: +%# +%# This software is Copyright (c) 1996-2012 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 $title = loc('SQL Queries'); +unless ($session{'CurrentUser'}->HasRight( Object=> $RT::System, Right => 'SuperUser')) { + Abort(loc('This feature is only available to system administrators.')); +} +</%init> +<& /Admin/Elements/Header, Title => $title &> +<& /Elements/Tabs &> +<script type="text/javascript" src="<%RT->Config->Get('WebPath')%>/NoAuth/js/jquery.tablesorter.min.js"></script> + +<&|/Widgets/TitleBox, title => loc('SQL Queries') &> +% my $history = $RT::Handle->QueryHistory; +% if (!RT->Config->Get('StatementLog')) { + <p><&|/l&>You must set StatementLog to true to enable this query history page.</&></p> +% } elsif (!$history) { + <p><&|/l&>This server process has recorded no SQL queries.</&></p> +% } else { + <script type="text/javascript"> + jQuery(function () { jQuery(".tablesorter").tablesorter(); }); + </script> + + <ol> +% my $r = 0; +% for my $request (@$history) { +% ++$r; + +% my ($seconds, $count) = (0, 0); +% for my $statement (@{ $request->{Queries} }) { +% $seconds += $statement->[3]; +% $count++; +% } + + <li> + <tt><% $request->{Path} %></tt> - <i><&|/l, sprintf('%.4f', $seconds) &>[_1]s</&></i> + <a href="#" onclick="return hideshow('queries-<%$r%>');"><&|/l, $count &>Toggle [quant,_1,query,queries]</&></a> + <table id="queries-<%$r%>" class="tablesorter hidden"> + <thead> + <tr> + <th><&|/l&>index</&></th> + <th><&|/l&>duration</&></th> + <th><&|/l&>statement</&></th> + </tr> + </thead> + <tbody> +% my $s = 0; +% my @undup; +% for my $statement (@{ $request->{Queries} }) { +% my ($dup) = grep {$_->[1] eq $statement->[1]} @undup[-(@undup > 3?3:@undup)..-1]; +% if ($dup) { +% $dup->[2] = [$dup->[2]] unless $dup->[5]; +% push @{$dup->[2]}, $statement->[2]; +% $dup->[3] += $statement->[3]; +% $dup->[5] ||= 1; $dup->[5]++; +% } else { +% push @undup, $statement; +% } +% } +% for my $statement (@undup) { +% my ( $time, $sql, $bind, $duration, $trace, $dup ) = @$statement; +% $sql = $RT::Handle->FillIn($sql, $bind) unless $dup; + <tr> + <td><% ++$s %><% $dup ? " (x $dup)" : "" %></td> + <td><i><&|/l, sprintf('%.4f', $duration) &>[_1]s</&></i></td> + <td> + <tt><% $sql %></tt> +% if ($dup and @{$bind->[0]}) { +% for my $b (@{$bind}) { + <br><tt>[<% join(", ", @$b) %>]</tt> +% } +% } + <a class="query-stacktrace-toggle" href="#" onclick="return hideshow('trace-<%$r%>-<%$s%>');"><&|/l &>Toggle stack trace</&></a> + <pre id="trace-<%$r%>-<%$s%>" class="hidden"><% $trace %></pre> + </td> + </tr> +% } + </tbody> + </table> + </li> +% } + </ol> +% } +</&> diff --git a/rt/share/html/Admin/Tools/Theme.html b/rt/share/html/Admin/Tools/Theme.html new file mode 100644 index 000000000..11888cac5 --- /dev/null +++ b/rt/share/html/Admin/Tools/Theme.html @@ -0,0 +1,309 @@ +%# BEGIN BPS TAGGED BLOCK {{{ +%# +%# COPYRIGHT: +%# +%# This software is Copyright (c) 1996-2012 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("Theme"), +&> +<& /Elements/Tabs &> +<& /Elements/ListActions, actions => \@results &> + +<script type="text/javascript" src="<%RT->Config->Get('WebPath')%>/NoAuth/js/farbtastic.js"></script> + +<div id="simple-customize"> +<div id="upload-logo"> + <h2>Logo</h2> + <& /Elements/Logo, id => 'logo-theme-editor', ShowName => 0 &> + <form method="POST" enctype="multipart/form-data"> + <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) { + <&|/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" /> + </form> +</div> + +<div id="customize-theme"> + <h2>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> +% if ($colors) { +<div class="primary-colors"> +% for (@$colors) { +% my $fg = $_->{l} >= $text_threshold ? 'black' : 'white'; +<button type="button" class="color-template" + style="background-color: rgb(<% $_->{c} %>); color: <% $fg %>;"> + <&|/l&>Text</&> +</button> +% } +</div> +% } + <div id="color-picker"></div> + </li> + </ol> +</div> +</div> + +<div id="custom-css"> + <h2>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" /> + </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 title' => ['div#header h1']], + ['Page content' => ['div#body']], + ['Buttons' => ['input[type="reset"], input[type="submit"], input[class="button"]']], + ['Button hover' => ['input[type="reset"]:hover, input[type="submit"]:hover, input[class="button"]:hover']], +); +</%ONCE> +<script type="text/javascript"> +var section_css_mapping = <% JSON(\@sections) |n%>; + +jQuery(function($) { + + jQuery.each(section_css_mapping, function(i,v){ + $('select#section').append($("<option/>") + .attr('value', v[0]) + .text(v[0])); + }); + + $("style#sitecss").text($('#user_css').val()); + $('#try').click(function() { + $("style#sitecss").text($('#user_css').val()); + }); + + $('#reset').click(function() { + setTimeout(function() { + $("style#sitecss").text($('#user_css').val()); + }, 1000); + }); + + function change_color(bg, fg) { + var section = $('select#section').val(); + + var applying = jQuery.grep(section_css_mapping, function(a){ return a[0] == section })[0][1]; + var css = $('#user_css').val(); + if (applying) { + var specials = new RegExp("([.*+?|()\\[\\]{}\\\\])", "g"); + for (var name in applying) { + var selector = (applying[name]).replace(specials, "\\$1"); + var rule = new RegExp('^'+selector+'\\s*\{.*?\}', "m"); + var newcss = "background: " + bg; + + /* Don't set the text color on <body> as it affects too much */ + if (applying[name] != "body") + newcss += "; color: " + fg; + + /* Kill the border on the quickbar if we're styling it */ + if (applying[name].match(/quickbar/)) + newcss += "; border: none;" + + /* Page title's text color is the selected color */ + if (applying[name].match(/#header/)) + newcss = "color: " + bg; + + /* Nav doesn't need a background, but it wants text color */ + if (applying[name].match(/#main-navigation/)) + newcss = "color: " + fg; + + css = css.replace(rule, applying[name]+" { "+newcss+" }"); + } + } + $('#user_css').val(css); + $("style#sitecss").text(css); + } + + $('#color-picker').farbtastic(function(color){ change_color(color, this.hsl[2] > <% $text_threshold %> ? '#000' : '#fff') }); + + $('button.color-template').click(function() { + change_color($(this).css('background-color'), $(this).css('color')); + }); + + +}); +</script> +<%INIT> +unless ($session{'CurrentUser'}->HasRight( Object=> RT->System, Right => 'SuperUser')) { + Abort(loc('This feature is only available to system administrators.')); +} + +use Digest::MD5 'md5_hex'; + +my $text_threshold = 0.6; +my @results; +my $imgdata; + +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}), + } ); + push @results, loc("Unable to set UserLogo: [_1]", $msg) unless $id; + + $imgdata = $file_hash->{LargeContent}; +} +elsif ($ARGS{'reset_logo'}) { + RT->System->DeleteAttribute('UserLogo'); +} +else { + if (my $attr = RT->System->FirstAttribute('UserLogo')) { + my $content = $attr->Content; + if (ref($content) eq 'HASH') { + $imgdata = $content->{data}; + } + else { + RT->System->DeleteAttribute('UserLogo'); + } + } +} + +if ($user_css) { + if ($ARGS{'reset_css'}) { + RT->System->DeleteAttribute('UserCSS'); + undef $user_css; + } + else { + my ($id, $msg) = RT->System->SetAttribute( Name => "UserCSS", + Description => "User-provided css", + Content => $user_css ); + push @results, loc("Unable to set UserCSS: [_1]", $msg) unless $id; + } +} + +if (!$user_css) { + my $attr = RT->System->FirstAttribute('UserCSS'); + $user_css = $attr ? $attr->Content : join( + "\n\n" => map { + join "\n" => "/* ". $_->[0] ." */", + map { "$_ {}" } @{$_->[1]} + } @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) { + warn "bad"; + } + return \@top5; +} +</%INIT> +<%ARGS> +$user_css => '' +</%ARGS> |