diff options
author | ivan <ivan> | 2006-10-17 08:51:01 +0000 |
---|---|---|
committer | ivan <ivan> | 2006-10-17 08:51:01 +0000 |
commit | a513c0bef534d05f03c1242831b6f3be19b97dae (patch) | |
tree | 2f2a88caf104fef31a3a8dc190ac3fe41dd017c1 /rt/html | |
parent | d4d0590bef31071e8809ec046717444b95b3f30a (diff) |
import rt 3.4.5
Diffstat (limited to 'rt/html')
-rw-r--r-- | rt/html/Approvals/Elements/PendingMyApproval | 1 | ||||
-rw-r--r-- | rt/html/Elements/Callback | 4 | ||||
-rw-r--r-- | rt/html/Elements/CollectionAsTable/Row | 1 | ||||
-rw-r--r-- | rt/html/Elements/EditCustomField | 4 | ||||
-rw-r--r-- | rt/html/Elements/EditCustomFieldSelect | 3 | ||||
-rw-r--r-- | rt/html/Elements/Header | 8 | ||||
-rw-r--r-- | rt/html/Elements/QueryString | 6 | ||||
-rw-r--r-- | rt/html/Elements/RT__Ticket/ColumnMap | 3 | ||||
-rw-r--r-- | rt/html/Elements/ScrubHTML | 2 | ||||
-rw-r--r-- | rt/html/Elements/ShowCustomFields | 3 | ||||
-rw-r--r-- | rt/html/NoAuth/printrt.css | 77 | ||||
-rw-r--r-- | rt/html/NoAuth/webrt.css | 28 | ||||
-rw-r--r-- | rt/html/Search/Build.html | 488 | ||||
-rw-r--r-- | rt/html/Search/Elements/BuildFormatString | 6 | ||||
-rw-r--r-- | rt/html/Search/Results.rdf | 2 | ||||
-rw-r--r-- | rt/html/Search/Results.tsv | 2 | ||||
-rw-r--r-- | rt/html/Ticket/Elements/EditCustomFields | 3 | ||||
-rw-r--r-- | rt/html/Ticket/Elements/ShowTransactionAttachments | 9 | ||||
-rw-r--r-- | rt/html/User/Elements/Tabs | 3 |
19 files changed, 374 insertions, 279 deletions
diff --git a/rt/html/Approvals/Elements/PendingMyApproval b/rt/html/Approvals/Elements/PendingMyApproval index f13ddf0f3..8d19399ab 100644 --- a/rt/html/Approvals/Elements/PendingMyApproval +++ b/rt/html/Approvals/Elements/PendingMyApproval @@ -77,6 +77,7 @@ $tickets->LimitOwner( VALUE => $session{'CurrentUser'}->Id ); # also consider AdminCcs as potential approvers. my $group_tickets = RT::Tickets->new( $session{'CurrentUser'} ); +$group_tickets->LimitWatcher( VALUE => $session{'CurrentUser'}->UserObj->EmailAddress, TYPE => 'AdminCc' ); my $created_before = RT::Date->new( $session{'CurrentUser'} ); my $created_after = RT::Date->new( $session{'CurrentUser'} ); diff --git a/rt/html/Elements/Callback b/rt/html/Elements/Callback index 937e923a1..c7aeb9f5d 100644 --- a/rt/html/Elements/Callback +++ b/rt/html/Elements/Callback @@ -68,14 +68,14 @@ if (!$callbacks) { push @$callbacks, # Skip backup files, files without a leading package name, # and files we've already seen - grep { !/^\.|~$/ + grep { !/\/\.|~$/ and $_ ne "/Callbacks/$Page/$_CallbackName" and not $seen{$_}++ } $m->interp->resolver->glob_path($path, $root); } $m->notes($CacheKey => $callbacks); - $cache{$Page,$_CallbackName} = $callbacks if !$RT::DevelMode; + $cache{$CacheKey} = $callbacks if !$RT::DevelMode; } my @rv; diff --git a/rt/html/Elements/CollectionAsTable/Row b/rt/html/Elements/CollectionAsTable/Row index 3316bc027..0de362ea8 100644 --- a/rt/html/Elements/CollectionAsTable/Row +++ b/rt/html/Elements/CollectionAsTable/Row @@ -71,6 +71,7 @@ foreach my $column (@Format) { $item++; $m->out('<td class="collection-as-table" '); $m->out( 'align="' . $column->{align} . '"' ) if ( $column->{align} ); + $m->out( 'style="' . $column->{style} . '"' ) if ( $column->{style} ); $m->out('>'); foreach my $subcol ( @{ $column->{output} } ) { if ( $subcol =~ /^__(.*?)__$/o ) { diff --git a/rt/html/Elements/EditCustomField b/rt/html/Elements/EditCustomField index d2398c9da..e443c764e 100644 --- a/rt/html/Elements/EditCustomField +++ b/rt/html/Elements/EditCustomField @@ -49,6 +49,10 @@ if ($Object) { $Values = $Object->CustomFieldValues($CustomField->id); $Values->Columns( qw( id CustomField ObjectType ObjectId Disabled Content ContentType ContentEncoding ) ); $NamePrefix ||= join('-', 'Object', ref($Object), $Object->Id, 'CustomField', ''); +} elsif (not $Default) { + my %TOP = $m->request_args; + $Default = $TOP{ $NamePrefix .$CustomField->Id . '-Values' } + || $TOP{ $NamePrefix .$CustomField->Id . '-Value' }; } my $Type = $CustomField->Type; diff --git a/rt/html/Elements/EditCustomFieldSelect b/rt/html/Elements/EditCustomFieldSelect index db33a6839..2a2a64a1d 100644 --- a/rt/html/Elements/EditCustomFieldSelect +++ b/rt/html/Elements/EditCustomFieldSelect @@ -53,7 +53,8 @@ % if ($Values) { <% $Values->HasEntry($value->Name) && ($selected = 1) && 'SELECTED' %> % } elsif ($Default) { - <% ($Default eq $value->Name) && ($selected = 1) && 'SELECTED' %> + <% (ref $Default ? (grep {$_ eq $value->Name} @{$Default}) : ($Default eq $value->Name)) + && ($selected = 1) && 'SELECTED' %> % } ><% $value->Name%></option> % } diff --git a/rt/html/Elements/Header b/rt/html/Elements/Header index 8c3775bba..f5a616ece 100644 --- a/rt/html/Elements/Header +++ b/rt/html/Elements/Header @@ -47,12 +47,14 @@ <HTML> <HEAD> <TITLE><%$Title%></TITLE> -% if ($Refresh > 0) { +% if ($Refresh && $Refresh > 0) { <META HTTP-EQUIV="REFRESH" CONTENT="<%$Refresh%>"> % } -<link rel="shortcut icon" href="<%$RT::WebImagesURL%>/favicon.png" type="image/png"> -<link rel="stylesheet" href="<%$RT::WebPath%>/NoAuth/webrt.css" type="text/css"> +<link rel="shortcut icon" href="<%$RT::WebImagesURL%>/favicon.png" type="image/png" /> +<link media="all" rel="stylesheet" href="<%$RT::WebPath%>/NoAuth/webrt.css" type="text/css" /> +<link media="print" rel="stylesheet" href="<%$RT::WebPath%>/NoAuth/printrt.css" type="text/css" /> + <script> function hideshow(num) { idstring = "element-" + num; diff --git a/rt/html/Elements/QueryString b/rt/html/Elements/QueryString index 7d41f15e0..1ddab85de 100644 --- a/rt/html/Elements/QueryString +++ b/rt/html/Elements/QueryString @@ -45,8 +45,12 @@ %# END BPS TAGGED BLOCK }}} <%init> my @params; -while ( (my $key, my $value) = each %ARGS ){ +while ( my ($key, $value) = each %ARGS ){ + if( UNIVERSAL::isa( $value, 'ARRAY' ) ) { + push @params, map $key."=".$m->interp->apply_escapes($_,'u'), @$value; + } else { push @params, $key."=".$m->interp->apply_escapes($value,'u'); + } } return(join('&',@params)); </%init> diff --git a/rt/html/Elements/RT__Ticket/ColumnMap b/rt/html/Elements/RT__Ticket/ColumnMap index dade91494..80e3c693c 100644 --- a/rt/html/Elements/RT__Ticket/ColumnMap +++ b/rt/html/Elements/RT__Ticket/ColumnMap @@ -95,6 +95,7 @@ sub LinkCallback { my $mode = $RT::Ticket::LINKTYPEMAP{$method}{Mode}; my $type = $RT::Ticket::LINKTYPEMAP{$method}{Type}; + my $other_mode = ($mode eq "Target" ? "Base" : "Target"); my $mode_uri = $mode.'URI'; my $local_type = 'Local'.$mode; @@ -105,7 +106,7 @@ sub LinkCallback { \'">', ( $_->$mode_uri->IsLocal ? $_->$local_type : $_->$mode ), \'</A><BR>', - } @{ $_[0]->Links($mode,$type)->ItemsArrayRef } + } @{ $_[0]->Links($other_mode,$type)->ItemsArrayRef } } } diff --git a/rt/html/Elements/ScrubHTML b/rt/html/Elements/ScrubHTML index 94a729907..443ded9c4 100644 --- a/rt/html/Elements/ScrubHTML +++ b/rt/html/Elements/ScrubHTML @@ -62,7 +62,7 @@ $scrubber->default( $scrubber->deny(qw[*]); $scrubber->allow( - qw[A B U P BR I HR BR SMALL EM FONT SPAN DIV UL OL LI DL DT DD]); + qw[A B U P BR I HR BR SMALL EM FONT SPAN DIV UL OL LI DL DT DD PRE]); $scrubber->comment(0); return ( $scrubber->scrub($Content) ); </%init> diff --git a/rt/html/Elements/ShowCustomFields b/rt/html/Elements/ShowCustomFields index 7591fa3aa..986184120 100644 --- a/rt/html/Elements/ShowCustomFields +++ b/rt/html/Elements/ShowCustomFields @@ -71,6 +71,9 @@ </table> <%INIT> my $CustomFields = $Object->CustomFields; + $m->comp('/Elements/Callback', _CallbackName => 'MassageCustomFields', + CustomFields => $CustomFields); + </%INIT> <%ARGS> $Object => undef diff --git a/rt/html/NoAuth/printrt.css b/rt/html/NoAuth/printrt.css new file mode 100644 index 000000000..72e7e8b7e --- /dev/null +++ b/rt/html/NoAuth/printrt.css @@ -0,0 +1,77 @@ +%# {{{ BEGIN BPS TAGGED BLOCK +%# +%# +%# +%# 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., 675 Mass Ave, Cambridge, MA 02139, USA. +%# +%# +%# 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 +%# +%# Special stylesheet for printing tickets +%# Koos van den Hout koos@cs.uu.nl 2005-11-21 +%# + +SPAN.nav { display: none !important; } +.nav2 { display: none !important; } +.nav { display: none !important; } +.topnav { display: none !important; } +.blue { display: none !important; } +.darkblue { display: none !important; } +.blueright { display: none !important; } +.currentnav { display: none !important; } +th.titlebox { border-top: none; border-bottom: none; } +th.titleboxright { display:none !important; border-top: none; border-bottom: none; } +.titlebox { border-top: none; border-bottom: none; } + +div.downloadattachment, div.downloadcontenttype { + display: none !important; +} + + +a[href$="Respond"], a[href$="Comment"], a[href*="ShowEmailRecord"] { + display: none !important; +} + + +%# Provide a callback for adding/modifying the style sheet. +%# http://www.w3.org/TR/REC-CSS1 - section 3.2, says: +%# "latter specified rule wins" +<& /Elements/Callback &> +<%flags> +inherit => undef +</%flags> +<%init> +$r->content_type('text/css'); +$r->headers_out->{'Expires'} = '+30m'; +</%init> diff --git a/rt/html/NoAuth/webrt.css b/rt/html/NoAuth/webrt.css index ccdd49d60..7fa2f83f8 100644 --- a/rt/html/NoAuth/webrt.css +++ b/rt/html/NoAuth/webrt.css @@ -74,37 +74,37 @@ SPAN.nav { font-family: Verdana, Arial, Helvetica, sans-serif; %# This modification sets a different class name for each level, allowing %# style sheet control over the formats. -a.topnav-0 { font-family: Verdana, sans-serif; +a.topnav-0 { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 16px; font-weight: normal; color: #FFFFFF; text-decoration: none; white-space: nowrap} -a.topnav-1 { font-family: Verdana, sans-serif; +a.topnav-1 { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 14px; font-weight: normal; color: #FFFFFF; text-decoration: none; white-space: nowrap} -a.topnav-2 { font-family: Verdana, sans-serif; +a.topnav-2 { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; font-weight: normal; color: #FFFFFF; text-decoration: none; white-space: nowrap} -a.topnav-3 { font-family: Verdana, sans-serif; +a.topnav-3 { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 11px; font-weight: normal; color: #FFFFFF; text-decoration: none; white-space: nowrap} -a.topnav-4 { font-family: Verdana, sans-serif; +a.topnav-4 { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 11px; font-weight: normal; color: #FFFFFF; text-decoration: none; white-space: nowrap} -a.topnav-5 { font-family: Verdana, sans-serif; +a.topnav-5 { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 11px; font-weight: normal; color: #FFFFFF; @@ -183,37 +183,37 @@ li.topnav-5-major { %# This modification sets a different class name for each level, allowing %# style sheet control over the formats -a.currenttopnav-0 { font-family: Verdana, sans-serif; +a.currenttopnav-0 { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 16px; font-weight: bold; color: #FFFF66; text-decoration: none; white-space: nowrap} -a.currenttopnav-1 { font-family: Verdana, sans-serif; +a.currenttopnav-1 { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 14px; font-weight: bold; color: #FFFF66; text-decoration: none; white-space: nowrap} -a.currenttopnav-2 { font-family: Verdana, sans-serif; +a.currenttopnav-2 { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; font-weight: normal; color: #FFFF66; text-decoration: none; white-space: nowrap} -a.currenttopnav-3 { font-family: Verdana, sans-serif; +a.currenttopnav-3 { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 11px; font-weight: normal; color: #FFFF66; text-decoration: none; white-space: nowrap} -a.currenttopnav-4 { font-family: Verdana, sans-serif; +a.currenttopnav-4 { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 11px; font-weight: normal; color: #FFFF66; text-decoration: none; white-space: nowrap} -a.currenttopnav-5 { font-family: Verdana, sans-serif; +a.currenttopnav-5 { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 11px; font-weight: normal; color: #FFFF66; @@ -454,7 +454,7 @@ SPAN.message { BODY { color: #000; background: #FFFFFF; - font-family: "Helvetica", sans-serif; + font-family: Verdana, Arial, Helvetica, sans-serif; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; @@ -477,7 +477,7 @@ TR.evenline { H1, H2, H3 { margin-top: 0.2em; color: #336699; - font-family: "Helvetica", sans-serif; + font-family: Verdana, Arial, Helvetica, sans-serif; clear: both; } diff --git a/rt/html/Search/Build.html b/rt/html/Search/Build.html index cb6462651..5a66e02c9 100644 --- a/rt/html/Search/Build.html +++ b/rt/html/Search/Build.html @@ -256,237 +256,6 @@ if ( $ARGS{'LoadSavedSearch'} =~ /^(.*?)-(\d+)-SavedSearch-(\d+)$/ ) { # }}} # {{{ Parse the query -my $tree; -ParseQuery( $Query, \$tree, \@actions ); - -# if parsing went poorly, send them to the edit page to fix it -if ( $actions[0] ) { - $m->comp( "Edit.html", Query => $Query, actions => \@actions ); - $m->abort(); -} - -$Query = ""; - -my @options = $tree->GetDisplayedNodes; - -my @current_values = grep { defined } @options[@clauses]; - -# {{{ Try to find if we're adding a clause -foreach my $arg ( keys %ARGS ) { - if ( - $arg =~ m/^ValueOf(.+)/ - && ( ref $ARGS{$arg} eq "ARRAY" - ? grep { $_ ne "" } @{ $ARGS{$arg} } - : $ARGS{$arg} ne "" ) - ) - { - - # We're adding a $1 clause - my $field = $1; - my ( $keyword, $op, $value ); - - #figure out if it's a grouping - if ( $ARGS{ $field . "Field" } ) { - $keyword = $ARGS{ $field . "Field" }; - } - else { - $keyword = $field; - } - - my ( @ops, @values ); - if ( ref $ARGS{ 'ValueOf' . $field } eq "ARRAY" ) { - - # we have many keys/values to iterate over, because there is - # more than one CF with the same name. - @ops = @{ $ARGS{ $field . 'Op' } }; - @values = @{ $ARGS{ 'ValueOf' . $field } }; - } - else { - @ops = ( $ARGS{ $field . 'Op' } ); - @values = ( $ARGS{ 'ValueOf' . $field } ); - } - $RT::Logger->error("Bad Parameters passed into Query Builder") - unless @ops == @values; - - for my $i ( 0 .. @ops - 1 ) { - my ( $op, $value ) = ( $ops[$i], $values[$i] ); - next if $value eq ""; - - if ( $value eq 'NULL' && $op =~ /=/ ) { - if ( $op eq '=' ) { - $op = "IS"; - } - elsif ( $op eq '!=' ) { - $op = "IS NOT"; - } - - # This isn't "right", but... - # It has to be this way until #5182 is fixed - $value = "'NULL'"; - } - else { - $value = "'$value'"; - } - - my $clause = { - Key => $keyword, - Op => $op, - Value => $value - }; - - my $newnode = RT::Interface::Web::QueryBuilder::Tree->new($clause); - if (@current_values) { - foreach my $value (@current_values) { - my $newindex = $value->getIndex() + 1; - $value->insertSibling( $newindex, $newnode ); - $value = $newnode; - } - } - else { - $tree->getChild(0)->addChild($newnode); - @current_values = $newnode; - } - $newnode->getParent()->setNodeValue( $ARGS{'AndOr'} ); - } - } -} - -# }}} - -# {{{ Move things around -if ( $ARGS{"Up"} ) { - if (@current_values) { - foreach my $value (@current_values) { - my $index = $value->getIndex(); - if ( $value->getIndex() > 0 ) { - my $parent = $value->getParent(); - $parent->removeChild($index); - $parent->insertChild( $index - 1, $value ); - $value = $parent->getChild( $index - 1 ); - } - else { - push( @actions, [ loc("error: can't move up"), -1 ] ); - } - } - } - else { - push( @actions, [ loc("error: nothing to move"), -1 ] ); - } -} -elsif ( $ARGS{"Down"} ) { - if (@current_values) { - foreach my $value (@current_values) { - my $index = $value->getIndex(); - my $parent = $value->getParent(); - if ( $value->getIndex() < ( $parent->getChildCount - 1 ) ) { - $parent->removeChild($index); - $parent->insertChild( $index + 1, $value ); - $value = $parent->getChild( $index + 1 ); - } - else { - push( @actions, [ loc("error: can't move down"), -1 ] ); - } - } - } - else { - push( @actions, [ loc("error: nothing to move"), -1 ] ); - } -} -elsif ( $ARGS{"Left"} ) { - if (@current_values) { - foreach my $value (@current_values) { - my $parent = $value->getParent(); - my $grandparent = $parent->getParent(); - if ( !$grandparent->isRoot ) { - my $index = $parent->getIndex(); - $parent->removeChild($value); - $grandparent->insertChild( $index, $value ); - if ( $parent->isLeaf() ) { - $grandparent->removeChild($parent); - } - } - else { - push( @actions, [ loc("error: can't move left"), -1 ] ); - } - } - } - else { - push( @actions, [ loc("error: nothing to move"), -1 ] ); - } -} -elsif ( $ARGS{"Right"} ) { - if (@current_values) { - foreach my $value (@current_values) { - my $parent = $value->getParent(); - my $index = $value->getIndex(); - my $newparent; - if ( $index > 0 ) { - my $sibling = $parent->getChild( $index - 1 ); - if ( ref( $sibling->getNodeValue ) ) { - $parent->removeChild($value); - my $newtree = RT::Interface::Web::QueryBuilder::Tree->new( 'AND', $parent ); - $newtree->addChild($value); - } - else { - $parent->removeChild($index); - $sibling->addChild($value); - } - } - else { - $parent->removeChild($value); - $newparent = RT::Interface::Web::QueryBuilder::Tree->new( 'AND', $parent ); - $newparent->addChild($value); - } - } - } - else { - push( @actions, [ loc("error: nothing to move"), -1 ] ); - } -} -elsif ( $ARGS{"DeleteClause"} ) { - if (@current_values) { - $_->getParent()->removeChild($_) for @current_values; - } - else { - push( @actions, [ loc("error: nothing to delete"), -1 ] ); - } -} -elsif ( $ARGS{"Toggle"} ) { - my $ea; - if (@current_values) { - foreach my $value (@current_values) { - my $parent = $value->getParent(); - - if ( $parent->getNodeValue eq 'AND' ) { - $parent->setNodeValue('OR'); - } - else { - $parent->setNodeValue('AND'); - } - } - } - else { - push( @actions, [ loc("error: nothing to toggle"), -1 ] ); - } -} - -$tree->PruneChildlessAggregators; - -# }}} - -# {{{ Rebuild $Query based on the additions / movements -$Query = ""; -my $optionlist_arrayref; - -($Query, $optionlist_arrayref) = $tree->GetQueryAndOptionList(\@current_values); - -my $optionlist = join "\n", map { qq(<option value="$_->{INDEX}" $_->{SELECTED}>) - . (" " x (5 * $_->{DEPTH})) - . $m->interp->apply_escapes($_->{TEXT}, 'h') . qq(</option>) } @$optionlist_arrayref; - - - - use Regexp::Common qw /delimited/; # States @@ -496,7 +265,17 @@ use constant OP => 4; use constant PAREN => 8; use constant KEYWORD => 16; -sub ParseQuery { +my $_match = sub { + + # Case insensitive equality + my ( $y, $x ) = @_; + return 1 if $x =~ /^$y$/i; + + # return 1 if ((lc $x) eq (lc $y)); # Why isnt this equiv? + return 0; +}; + +my $ParseQuery = sub { my $string = shift; my $tree = shift; my @actions = shift; @@ -548,12 +327,12 @@ sub ParseQuery { my $current = 0; # Highest priority is last - $current = OP if _match( $re_op, $val ); - $current = VALUE if _match( $re_value, $val ); + $current = OP if $_match->( $re_op, $val ); + $current = VALUE if $_match->( $re_value, $val ); $current = KEYWORD - if _match( $re_keyword, $val ) && ( $want & KEYWORD ); - $current = AGGREG if _match( $re_aggreg, $val ); - $current = PAREN if _match( $re_paren, $val ); + if $_match->( $re_keyword, $val ) && ( $want & KEYWORD ); + $current = AGGREG if $_match->( $re_aggreg, $val ); + $current = PAREN if $_match->( $re_paren, $val ); unless ( $current && $want & $current ) { @@ -666,25 +445,242 @@ sub ParseQuery { # This will never happen, because the parser will complain push @actions, [ loc("Mismatched parentheses"), -1 ] unless $depth == 1; +}; + +my $tree; +$ParseQuery->( $Query, \$tree, \@actions ); + +# if parsing went poorly, send them to the edit page to fix it +if ( $actions[0] ) { + $m->comp( "Edit.html", Query => $Query, actions => \@actions ); + $m->abort(); } -sub _match { +$Query = ""; - # Case insensitive equality - my ( $y, $x ) = @_; - return 1 if $x =~ /^$y$/i; +my @options = $tree->GetDisplayedNodes; - # return 1 if ((lc $x) eq (lc $y)); # Why isnt this equiv? - return 0; +my @current_values = grep { defined } @options[@clauses]; + +# {{{ Move things around +if ( $ARGS{"Up"} ) { + if (@current_values) { + foreach my $value (@current_values) { + my $index = $value->getIndex(); + if ( $value->getIndex() > 0 ) { + my $parent = $value->getParent(); + $parent->removeChild($index); + $parent->insertChild( $index - 1, $value ); + $value = $parent->getChild( $index - 1 ); + } + else { + push( @actions, [ loc("error: can't move up"), -1 ] ); + } + } + } + else { + push( @actions, [ loc("error: nothing to move"), -1 ] ); + } +} +elsif ( $ARGS{"Down"} ) { + if (@current_values) { + foreach my $value (@current_values) { + my $index = $value->getIndex(); + my $parent = $value->getParent(); + if ( $value->getIndex() < ( $parent->getChildCount - 1 ) ) { + $parent->removeChild($index); + $parent->insertChild( $index + 1, $value ); + $value = $parent->getChild( $index + 1 ); + } + else { + push( @actions, [ loc("error: can't move down"), -1 ] ); + } + } + } + else { + push( @actions, [ loc("error: nothing to move"), -1 ] ); + } } +elsif ( $ARGS{"Left"} ) { + if (@current_values) { + foreach my $value (@current_values) { + my $parent = $value->getParent(); + my $grandparent = $parent->getParent(); + if ( !$grandparent->isRoot ) { + my $index = $parent->getIndex(); + $parent->removeChild($value); + $grandparent->insertChild( $index, $value ); + if ( $parent->isLeaf() ) { + $grandparent->removeChild($parent); + } + } + else { + push( @actions, [ loc("error: can't move left"), -1 ] ); + } + } + } + else { + push( @actions, [ loc("error: nothing to move"), -1 ] ); + } +} +elsif ( $ARGS{"Right"} ) { + if (@current_values) { + foreach my $value (@current_values) { + my $parent = $value->getParent(); + my $index = $value->getIndex(); + my $newparent; + if ( $index > 0 ) { + my $sibling = $parent->getChild( $index - 1 ); + if ( ref( $sibling->getNodeValue ) ) { + $parent->removeChild($value); + my $newtree = RT::Interface::Web::QueryBuilder::Tree->new( 'AND', $parent ); + $newtree->addChild($value); + } + else { + $parent->removeChild($index); + $sibling->addChild($value); + } + } + else { + $parent->removeChild($value); + $newparent = RT::Interface::Web::QueryBuilder::Tree->new( 'AND', $parent ); + $newparent->addChild($value); + } + } + } + else { + push( @actions, [ loc("error: nothing to move"), -1 ] ); + } +} +elsif ( $ARGS{"DeleteClause"} ) { + if (@current_values) { + $_->getParent()->removeChild($_) for @current_values; + @current_values = (); + } + else { + push( @actions, [ loc("error: nothing to delete"), -1 ] ); + } +} +elsif ( $ARGS{"Toggle"} ) { + my $ea; + if (@current_values) { + foreach my $value (@current_values) { + my $parent = $value->getParent(); + + if ( $parent->getNodeValue eq 'AND' ) { + $parent->setNodeValue('OR'); + } + else { + $parent->setNodeValue('AND'); + } + } + } + else { + push( @actions, [ loc("error: nothing to toggle"), -1 ] ); + } +} + +# {{{ Try to find if we're adding a clause +foreach my $arg ( keys %ARGS ) { + if ( + $arg =~ m/^ValueOf(.+)/ + && ( ref $ARGS{$arg} eq "ARRAY" + ? grep { $_ ne "" } @{ $ARGS{$arg} } + : $ARGS{$arg} ne "" ) + ) + { + + # We're adding a $1 clause + my $field = $1; + my ( $keyword, $op, $value ); + + #figure out if it's a grouping + if ( $ARGS{ $field . "Field" } ) { + $keyword = $ARGS{ $field . "Field" }; + } + else { + $keyword = $field; + } + + my ( @ops, @values ); + if ( ref $ARGS{ 'ValueOf' . $field } eq "ARRAY" ) { + + # we have many keys/values to iterate over, because there is + # more than one CF with the same name. + @ops = @{ $ARGS{ $field . 'Op' } }; + @values = @{ $ARGS{ 'ValueOf' . $field } }; + } + else { + @ops = ( $ARGS{ $field . 'Op' } ); + @values = ( $ARGS{ 'ValueOf' . $field } ); + } + $RT::Logger->error("Bad Parameters passed into Query Builder") + unless @ops == @values; + + for my $i ( 0 .. @ops - 1 ) { + my ( $op, $value ) = ( $ops[$i], $values[$i] ); + next if $value eq ""; -sub debug { - my $message = shift; - $m->print( $message . "<br>" ); + if ( $value eq 'NULL' && $op =~ /=/ ) { + if ( $op eq '=' ) { + $op = "IS"; + } + elsif ( $op eq '!=' ) { + $op = "IS NOT"; + } + + # This isn't "right", but... + # It has to be this way until #5182 is fixed + $value = "'NULL'"; + } + else { + $value = "'$value'"; + } + + my $clause = { + Key => $keyword, + Op => $op, + Value => $value + }; + + my $newnode = RT::Interface::Web::QueryBuilder::Tree->new($clause); + if (@current_values) { + foreach my $value (@current_values) { + my $newindex = $value->getIndex() + 1; + $value->insertSibling( $newindex, $newnode ); + $value = $newnode; + } + } + else { + $tree->getChild(0)->addChild($newnode); + @current_values = $newnode; + } + $newnode->getParent()->setNodeValue( $ARGS{'AndOr'} ); + } + } } # }}} +$tree->PruneChildlessAggregators; + +# }}} + +# {{{ Rebuild $Query based on the additions / movements +$Query = ""; +my $optionlist_arrayref; + +($Query, $optionlist_arrayref) = $tree->GetQueryAndOptionList(\@current_values); + +my $optionlist = join "\n", map { qq(<option value="$_->{INDEX}" $_->{SELECTED}>) + . (" " x (5 * $_->{DEPTH})) + . $m->interp->apply_escapes($_->{TEXT}, 'h') . qq(</option>) } @$optionlist_arrayref; + + + + +# }}} + # }}} my $queues = $tree->GetReferencedQueues; diff --git a/rt/html/Search/Elements/BuildFormatString b/rt/html/Search/Elements/BuildFormatString index 639e62c29..cffb81a48 100644 --- a/rt/html/Search/Elements/BuildFormatString +++ b/rt/html/Search/Elements/BuildFormatString @@ -121,11 +121,7 @@ foreach my $id (keys %cfqueues) { $CustomFields->LimitToGlobal; while ( my $CustomField = $CustomFields->Next ) { - my $queuestr; - if ($CustomField->QueueObj && $CustomField->QueueObj->Id != 0) { - $queuestr = $CustomField->QueueObj->Name . "."; - } - push @fields, "CustomField." . $queuestr . "{" . $CustomField->Name . "}"; + push @fields, "CustomField.{" . $CustomField->Name . "}"; } my ( @seen); diff --git a/rt/html/Search/Results.rdf b/rt/html/Search/Results.rdf index ee71fea94..7cc248306 100644 --- a/rt/html/Search/Results.rdf +++ b/rt/html/Search/Results.rdf @@ -75,7 +75,7 @@ $r->content_type('application/rdf+xml'); link => $RT::WebURL."/Ticket/Display.html?id=".$Ticket->id, description => $Ticket->Transactions->First->Content, dc => { - subject => $Ticket->Subject, + subject => ($Ticket->Subject || loc('No subject')), creator => $Ticket->CreatorObj->RealName . "<".$Ticket->CreatorObj->EmailAddress.">", }, ); diff --git a/rt/html/Search/Results.tsv b/rt/html/Search/Results.tsv index 17aa88ae1..e6b20481f 100644 --- a/rt/html/Search/Results.tsv +++ b/rt/html/Search/Results.tsv @@ -64,7 +64,7 @@ my @attrs = qw( id QueueObj->Name Subject Status TimeEstimated TimeWorked TimeLe if ($@) {die "Failed to find $attr - ". $@}; } - my $cfs = $Ticket->QueueObj->CustomFields(); + my $cfs = $Ticket->QueueObj->TicketCustomFields(); while (my $cf = $cfs->Next) { my @content; my $values = $Ticket->CustomFieldValues($cf->Id); diff --git a/rt/html/Ticket/Elements/EditCustomFields b/rt/html/Ticket/Elements/EditCustomFields index d566f4e71..6ae188fa7 100644 --- a/rt/html/Ticket/Elements/EditCustomFields +++ b/rt/html/Ticket/Elements/EditCustomFields @@ -91,7 +91,8 @@ if ($TicketObj) { $NamePrefix = "Object-RT::Ticket--CustomField-"; } - + $m->comp('/Elements/Callback', _CallbackName => 'MassageCustomFields', + CustomFields => $CustomFields); </%INIT> <%ARGS> diff --git a/rt/html/Ticket/Elements/ShowTransactionAttachments b/rt/html/Ticket/Elements/ShowTransactionAttachments index 8dabff421..d9e94ffa2 100644 --- a/rt/html/Ticket/Elements/ShowTransactionAttachments +++ b/rt/html/Ticket/Elements/ShowTransactionAttachments @@ -89,13 +89,13 @@ foreach my $message ( grep { $_->Parent == $Parent } @$Attachments ) { <div class="messagebody"> <%perl> # {{{ if it has a content-disposition: attachment, don't show inline -unless ( $message->GetHeader('Content-Disposition') =~ /attachment/i ) { +unless ( ($message->GetHeader('Content-Disposition')||"") =~ /attachment/i ) { my $content; # If it's text if ( $message->ContentType =~ m{^(text|message)}i - && $size <= $RT::MaxInlineBody ) + && $message->ContentLength <= $RT::MaxInlineBody ) { if ( @@ -158,6 +158,11 @@ unless ( $message->GetHeader('Content-Disposition') =~ /attachment/i ) { . $message->Id . '/">' ); } + elsif ( $message->ContentLength > 0 ) { + $m->out( + loc( 'Message body not shown because it is too large or is not plain text.' ) + ); + } } # }}} diff --git a/rt/html/User/Elements/Tabs b/rt/html/User/Elements/Tabs index 1d25fb926..625b30f93 100644 --- a/rt/html/User/Elements/Tabs +++ b/rt/html/User/Elements/Tabs @@ -61,6 +61,9 @@ }, }; + # Now let callbacks add their extra tabs + $m->comp('/Elements/Callback', tabs => $tabs, %ARGS); + foreach my $tab (sort keys %{$tabs}) { if ($tabs->{$tab}->{'path'} eq $current_tab) { $tabs->{$tab}->{"subtabs"} = $subtabs; |