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/Helpers | |
parent | 4f5619288413a185e9933088d9dd8c5afbc55dfa (diff) |
RT 4.2.11, ticket#13852
Diffstat (limited to 'rt/share/html/Helpers')
-rw-r--r-- | rt/share/html/Helpers/Autocomplete/CustomFieldValues | 27 | ||||
-rw-r--r-- | rt/share/html/Helpers/Autocomplete/Groups | 12 | ||||
-rw-r--r-- | rt/share/html/Helpers/Autocomplete/Owners | 33 | ||||
-rw-r--r-- | rt/share/html/Helpers/Autocomplete/Tickets | 109 | ||||
-rw-r--r-- | rt/share/html/Helpers/Autocomplete/Users | 71 | ||||
-rw-r--r-- | rt/share/html/Helpers/TicketHistory | 23 | ||||
-rw-r--r-- | rt/share/html/Helpers/UserInfo | 77 |
7 files changed, 257 insertions, 95 deletions
diff --git a/rt/share/html/Helpers/Autocomplete/CustomFieldValues b/rt/share/html/Helpers/Autocomplete/CustomFieldValues index 0694e9d8f..7e14067cc 100644 --- a/rt/share/html/Helpers/Autocomplete/CustomFieldValues +++ b/rt/share/html/Helpers/Autocomplete/CustomFieldValues @@ -45,7 +45,7 @@ %# those contributions and any derivatives thereof. %# %# END BPS TAGGED BLOCK }}} -% $r->content_type('application/json'); +% $r->content_type('application/json; charset=utf-8'); <% JSON( \@suggestions ) |n %> % $m->abort; <%INIT> @@ -53,8 +53,8 @@ my $term = (split /\n/, $ARGS{term} || '')[-1]; my $abort = sub { - $r->content_type('application/json'); - $m->out(JSON::to_json( [] )); + $r->content_type('application/json; charset=utf-8'); + $m->out(JSON( [] )); $m->abort; }; @@ -63,11 +63,17 @@ unless ( exists $ARGS{ContextType} and exists $ARGS{ContextId} ) { $abort->(); } +# Use _ParseObjectCustomFieldArgs to avoid duplicating the regex. +# See the docs for _ParseObjectCustomFieldArgs for details on the data +# structure returned. There will be only one CF, so drill down 2 layers +# to get the cf id, if one is there. + +my %custom_fields = _ParseObjectCustomFieldArgs(\%ARGS); my $CustomField; -for my $k ( keys %ARGS ) { - next unless $k =~ /^Object-.*?-\d*-CustomField-(\d+)-Values?$/; - $CustomField = $1; - last; +foreach my $class ( keys %custom_fields ){ + foreach my $id ( keys %{$custom_fields{$class}} ){ + ($CustomField) = keys %{$custom_fields{$class}{$id}}; + } } unless ( $CustomField ) { @@ -119,6 +125,13 @@ $values->Limit( SUBCLAUSE => 'autocomplete', CASESENSITIVE => 0, ); +$m->callback( + CallbackName => 'ModifyMaxResults', + max => \$ARGS{max}, + term => $term, + CustomField => $CustomFieldObj, +); +$values->RowsPerPage( $ARGS{max} // 10 ); my @suggestions; diff --git a/rt/share/html/Helpers/Autocomplete/Groups b/rt/share/html/Helpers/Autocomplete/Groups index 1f4043fc6..7e694844b 100644 --- a/rt/share/html/Helpers/Autocomplete/Groups +++ b/rt/share/html/Helpers/Autocomplete/Groups @@ -45,12 +45,12 @@ %# those contributions and any derivatives thereof. %# %# END BPS TAGGED BLOCK }}} -% $r->content_type('application/json'); +% $r->content_type('application/json; charset=utf-8'); <% JSON( \@suggestions ) |n %> % $m->abort; <%ARGS> $term => undef -$max => 10 +$max => undef $exclude => '' $op => 'LIKE' </%ARGS> @@ -66,6 +66,9 @@ $m->abort unless $CurrentUser->Privileged; # Sanity check the operator $op = 'LIKE' unless $op =~ /^(?:LIKE|(?:START|END)SWITH|=|!=)$/i; +$m->callback( CallbackName => 'ModifyMaxResults', max => \$max ); +$max //= 10; + my $groups = RT::Groups->new( $CurrentUser ); $groups->RowsPerPage( $max ); $groups->LimitToUserDefinedGroups(); @@ -73,6 +76,7 @@ $groups->Limit( FIELD => 'Name', OPERATOR => $op, VALUE => $term, + CASESENSITIVE => 0, ); # Exclude groups we don't want @@ -83,6 +87,8 @@ foreach (split /\s*,\s*/, $exclude) { my @suggestions; while ( my $group = $groups->Next ) { - push @suggestions, { label => $group->Name, value => $group->Name, id => $group->id }; + my $suggestion = { id => $group->Id, label => $group->Name, value => $group->Name }; + $m->callback( CallbackName => "ModifySuggestion", suggestion => $suggestion, group => $group ); + push @suggestions, $suggestion; } </%INIT> diff --git a/rt/share/html/Helpers/Autocomplete/Owners b/rt/share/html/Helpers/Autocomplete/Owners index be4a85622..123ba6b70 100644 --- a/rt/share/html/Helpers/Autocomplete/Owners +++ b/rt/share/html/Helpers/Autocomplete/Owners @@ -45,14 +45,14 @@ %# those contributions and any derivatives thereof. %# %# END BPS TAGGED BLOCK }}} -% $r->content_type('application/json'); +% $r->content_type('application/json; charset=utf-8'); <% JSON( \@suggestions ) |n %> % $m->abort; <%ARGS> $return => 'Name' $limit => undef $term => undef -$max => 10 +$max => undef </%ARGS> <%INIT> # Only allow certain return fields @@ -65,13 +65,13 @@ $m->abort unless defined $return my $CurrentUser = $session{'CurrentUser'}; -my %fields = %{ RT->Config->Get('UserAutocompleteFields') - || { EmailAddress => 1, Name => 1, RealName => 'LIKE' } }; - my %user_uniq_hash; my $isSU = $session{CurrentUser} ->HasRight( Right => 'SuperUser', Object => $RT::System ); +$m->callback( CallbackName => 'ModifyMaxResults', max => \$max ); +$max //= 10; + # Turn RT::Ticket-1|RT::Queue-2 into ['RT::Ticket', 1], ['RT::Queue', 2] foreach my $spec (map { [split /\-/, $_, 2] } split /\|/, $limit) { next unless $spec->[0] =~ /^RT::(Ticket|Queue)$/; @@ -89,22 +89,13 @@ foreach my $spec (map { [split /\-/, $_, 2] } split /\|/, $limit) { } my $Users = RT::Users->new( $session{CurrentUser} ); - $Users->RowsPerPage( $max ); - # Limit by our autocomplete term BEFORE we limit to OwnTicket because that # does a funky union hack - while (my ($name, $op) = each %fields) { - $op = 'STARTSWITH' - unless $op =~ /^(?:LIKE|(?:START|END)SWITH)$/i; - - $Users->Limit( - FIELD => $name, - OPERATOR => $op, - VALUE => $term, - ENTRYAGGREGATOR => 'OR', - SUBCLAUSE => 'autocomplete', - ); - } + $Users->SimpleSearch( + Max => $max, + Term => $term, + Return => $return, + ); $Users->WhoHaveRight( Right => 'OwnTicket', @@ -117,7 +108,7 @@ foreach my $spec (map { [split /\-/, $_, 2] } split /\|/, $limit) { next if $user_uniq_hash{ $User->Id }; $user_uniq_hash{ $User->Id() } = [ $User, - $m->scomp('/Elements/ShowUser', User => $User, NoEscape => 1) + $User->Format, ]; } } @@ -127,7 +118,7 @@ my $nobody = qr/^n(?:o(?:b(?:o(?:d(?:y)?)?)?)?)?$/i; if ( not $user_uniq_hash{RT->Nobody->id} and $term =~ $nobody ) { $user_uniq_hash{RT->Nobody->id} = [ RT->Nobody, - $m->scomp('/Elements/ShowUser', User => RT->Nobody, NoEscape => 1) + RT->Nobody->Format, ]; } diff --git a/rt/share/html/Helpers/Autocomplete/Tickets b/rt/share/html/Helpers/Autocomplete/Tickets new file mode 100644 index 000000000..0b8a83283 --- /dev/null +++ b/rt/share/html/Helpers/Autocomplete/Tickets @@ -0,0 +1,109 @@ +%# 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 }}} +% $r->content_type('application/json; charset=utf-8'); +<% JSON( \@suggestions ) |n %> +% $m->abort; +<%ARGS> +$return => '' +$term => undef +$max => undef +$exclude => '' +</%ARGS> +<%INIT> +# Only allow certain return fields +$return = 'id' + unless $return =~ /^(?:id|Subject)$/; + +$m->abort unless defined $return + and defined $term + and length $term; + +my $CurrentUser = $session{'CurrentUser'}; + +# Require privileged users +$m->abort unless $CurrentUser->Privileged; + +my @excludes; + +(my $prev, $term) = $term =~ /^((?:\d+\s+)*)(.*)/; +@excludes = split ' ', $prev if $prev; +push @excludes, split ' ', $exclude if $exclude; + +$m->abort unless $term; + +my %fields = %{ RT->Config->Get('TicketAutocompleteFields') + || { id => 'STARTSWITH', Subject => 'LIKE' } }; + +my $tickets = RT::Tickets->new( $CurrentUser ); + +my @clauses; +$term =~ s/(['\\])/\\$1/g; #' +while (my ($name, $op) = each %fields) { + $op = 'STARTSWITH' + unless $op =~ /^(?:LIKE|(?:START|END)SWITH|=|!=)$/i; + push @clauses, qq{$name $op '$term'}; +} +my $sql = join ' OR ', @clauses; +if ( @excludes ) { # exclude ids already these + $sql = join ' AND ', "($sql)", map { qq{id != '$_'} } @excludes; +} + +$m->callback( CallbackName => 'ModifyMaxResults', max => \$max ); +$max //= 10; + +$tickets->FromSQL($sql); +$tickets->RowsPerPage( $max ); + +my @suggestions; + +while ( my $ticket = $tickets->Next ) { + my $formatted = loc("#[_1]: [_2]", $ticket->Id, $ticket->Subject); + push @suggestions, { label => $formatted, value => $ticket->$return }; +} + +</%INIT> diff --git a/rt/share/html/Helpers/Autocomplete/Users b/rt/share/html/Helpers/Autocomplete/Users index e5b7624ba..a8df1c4e9 100644 --- a/rt/share/html/Helpers/Autocomplete/Users +++ b/rt/share/html/Helpers/Autocomplete/Users @@ -45,14 +45,14 @@ %# those contributions and any derivatives thereof. %# %# END BPS TAGGED BLOCK }}} -% $r->content_type('application/json'); +% $r->content_type('application/json; charset=utf-8'); <% JSON( \@suggestions ) |n %> % $m->abort; <%ARGS> $return => '' $term => undef $delim => undef -$max => 10 +$max => undef $privileged => undef $exclude => '' $op => undef @@ -84,62 +84,27 @@ my $CurrentUser = $session{'CurrentUser'}; $m->abort unless $CurrentUser->Privileged or RT->Config->Get('AllowUserAutocompleteForUnprivileged'); -my %fields = %{ RT->Config->Get('UserAutocompleteFields') - || { EmailAddress => 1, Name => 1, RealName => 'LIKE' } }; +# the API wants a list of ids +my @exclude = split /\s*,\s*/, $exclude; +push @exclude, RT->SystemUser->id, RT->Nobody->id; -# If an operator is provided, check against only the returned field -# using that operator -%fields = ( $return => $op ) if $op; +$m->callback( CallbackName => 'ModifyMaxResults', max => \$max ); +$max //= 10; -my $users = RT::Users->new( $CurrentUser ); -$users->RowsPerPage( $max ); - -$users->LimitToPrivileged() if $privileged; - -while (my ($name, $op) = each %fields) { - $op = 'STARTSWITH' - unless $op =~ /^(?:LIKE|(?:START|END)SWITH|=|!=)$/i; - - $users->Limit( - FIELD => $name, - OPERATOR => $op, - VALUE => $term, - ENTRYAGGREGATOR => 'OR', - SUBCLAUSE => 'autocomplete', - ); -} - -# Exclude users we don't want -foreach (split /\s*,\s*/, $exclude) { - $users->Limit(FIELD => 'id', VALUE => $_, OPERATOR => '!=', ENTRYAGGREGATOR => 'AND'); -} +my $users = RT::Users->new($CurrentUser); +$users->SimpleSearch( Privileged => $privileged, + Return => $return, + Term => $term, + Max => $max, + Exclude => \@exclude, + # If an operator is provided, check against only + # the returned field using that operator + $op ? ( Fields => { $return => $op } ) : (), + ); my @suggestions; - -if ( RT->Config->Get('DatabaseType') eq 'Oracle' ) { - $users->Limit( - FIELD => $return, - OPERATOR => 'IS NOT', - VALUE => 'NULL', - ); -} -else { - $users->Limit( FIELD => $return, OPERATOR => '!=', VALUE => '' ); - $users->Limit( - FIELD => $return, - OPERATOR => 'IS NOT', - VALUE => 'NULL', - ENTRYAGGREGATOR => 'AND' - ); -} - while ( my $user = $users->Next ) { - next if $user->id == RT->SystemUser->id - or $user->id == RT->Nobody->id; - - my $formatted = $m->scomp('/Elements/ShowUser', User => $user, NoEscape => 1); - $formatted =~ s/\n//g; - my $suggestion = { label => $formatted, value => $user->$return, id => $user->id }; + my $suggestion = { id => $user->id, label => $user->Format, value => $user->$return }; $m->callback( CallbackName => "ModifySuggestion", suggestion => $suggestion, user => $user ); push @suggestions, $suggestion; } diff --git a/rt/share/html/Helpers/TicketHistory b/rt/share/html/Helpers/TicketHistory index 91c975c23..433508d6b 100644 --- a/rt/share/html/Helpers/TicketHistory +++ b/rt/share/html/Helpers/TicketHistory @@ -52,16 +52,17 @@ $id my $TicketObj = RT::Ticket->new($session{'CurrentUser'}); $TicketObj->Load($id); -my $attachments = $m->comp('/Ticket/Elements/FindAttachments', Ticket => $TicketObj); -my $attachment_content = $m->comp('/Ticket/Elements/LoadTextAttachments', Ticket => $TicketObj); - -$m->comp('/Ticket/Elements/ShowHistory', - Ticket => $TicketObj, - Collapsed => $ARGS{'Collapsed'}, +my $attachments = $TicketObj->Attachments; +my $attachment_content = $TicketObj->TextAttachments; +my %extra_args; +$m->callback( CallbackName => 'ExtraShowHistoryArguments', Ticket => $TicketObj, ExtraArgs => \%extra_args ); +</%INIT> +<& /Elements/ShowHistory, + Object => $TicketObj, ShowHeaders => $ARGS{'ShowHeaders'}, Attachments => $attachments, - AttachmentContent => $attachment_content -); - -$m->abort(); -</%INIT> + AttachmentContent => $attachment_content, + %extra_args, + &> +<script type="text/javascript">ReplaceUserReferences()</script> +% $m->abort(); diff --git a/rt/share/html/Helpers/UserInfo b/rt/share/html/Helpers/UserInfo new file mode 100644 index 000000000..3350954a5 --- /dev/null +++ b/rt/share/html/Helpers/UserInfo @@ -0,0 +1,77 @@ +%# 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 }}} +<%args> +$id +</%args> +<%init> +my %users; + +$id = [$id] unless ref($id) eq 'ARRAY'; + +for my $uid (@$id) { + next if exists $users{$uid}; + + my $user = RT::User->new($session{'CurrentUser'}); + $user->Load($uid); + + unless ($user->id) { + $users{$uid} = undef; + next; + } + + my %user = map { $_ => $user->$_ } + qw(id Name EmailAddress RealName); + $user{Privileged} = $user->Privileged ? JSON::true : JSON::false; + $user{_formatted} = $user->Format; + $user{_html} = $m->scomp('/Elements/ShowUser', User => $user); + $users{$uid} = \%user; +} +$r->content_type('application/json; charset=utf-8'); +$m->out( JSON(\%users) ); +$m->abort; +</%init> |