diff options
author | Ivan Kohler <ivan@freeside.biz> | 2012-06-07 00:56:06 -0700 |
---|---|---|
committer | Ivan Kohler <ivan@freeside.biz> | 2012-06-07 00:56:06 -0700 |
commit | 43a06151e47d2c59b833cbd8c26d97865ee850b6 (patch) | |
tree | 42c51d94e7fa265461b508d061562be204ccc2c1 /rt/share/html/Ticket | |
parent | 6587f6ba7d047ddc1686c080090afe7d53365bd4 (diff) |
starting to work...
Diffstat (limited to 'rt/share/html/Ticket')
56 files changed, 1242 insertions, 1117 deletions
diff --git a/rt/share/html/Ticket/Attachment/WithHeaders/dhandler b/rt/share/html/Ticket/Attachment/WithHeaders/dhandler index 7dc46d3b3..11b77010c 100644 --- a/rt/share/html/Ticket/Attachment/WithHeaders/dhandler +++ b/rt/share/html/Ticket/Attachment/WithHeaders/dhandler @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC %# <sales@bestpractical.com> %# %# (Except where explicitly superseded by other copyright notices) @@ -53,7 +53,7 @@ Abort("Corrupted attachment URL"); } - my $AttachmentObj = new RT::Attachment( $session{'CurrentUser'} ); + my $AttachmentObj = RT::Attachment->new( $session{'CurrentUser'} ); $AttachmentObj->Load( $id ); unless ( $AttachmentObj->id ) { Abort("Couldn't load attachment #$id"); diff --git a/rt/share/html/Ticket/Attachment/dhandler b/rt/share/html/Ticket/Attachment/dhandler index 9d4d5322c..75efeffbc 100755 --- a/rt/share/html/Ticket/Attachment/dhandler +++ b/rt/share/html/Ticket/Attachment/dhandler @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC %# <sales@bestpractical.com> %# %# (Except where explicitly superseded by other copyright notices) @@ -55,7 +55,7 @@ else { Abort("Corrupted attachment URL."); } - my $AttachmentObj = new RT::Attachment($session{'CurrentUser'}); + my $AttachmentObj = RT::Attachment->new($session{'CurrentUser'}); $AttachmentObj->Load($attach) || Abort("Attachment '$attach' could not be loaded"); @@ -81,10 +81,6 @@ $iana = $iana? $iana->mime_name : $enc; $content_type .= ";charset=$iana"; - # unless (RT->Config->Get('TrustMIMEAttachments')) { - # $content_type = 'application/octet-stream'; - # } - $r->subprocess_env('no-gzip' => 1); # disable mod_deflate $r->content_type( $content_type ); $m->clear_buffer(); diff --git a/rt/share/html/Ticket/Create.html b/rt/share/html/Ticket/Create.html index 57e3bd476..9fb2b2bc5 100755 --- a/rt/share/html/Ticket/Create.html +++ b/rt/share/html/Ticket/Create.html @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC %# <sales@bestpractical.com> %# %# (Except where explicitly superseded by other copyright notices) @@ -45,54 +45,83 @@ %# those contributions and any derivatives thereof. %# %# END BPS TAGGED BLOCK }}} -%# use Data::Dumper; warn Dumper \%ARGS; #DEBUG <& /Elements/Header, Title => $title, - onload => "function () { hide(document.getElementById('Ticket-Create-details')) }" &> -<& /Elements/Tabs, - current_toptab => "Ticket/Create.html", - Title => $title, - actions => $actions &> + onload => "function () { hide('Ticket-Create-details') }" &> +<& /Elements/Tabs &> + <& /Elements/ListActions, actions => \@results &> + <form action="<% RT->Config->Get('WebPath') %>/Ticket/Create.html" method="post" enctype="multipart/form-data" name="TicketCreate"> -<input type="hidden" class="hidden" name="id" value="new" /> + <input type="hidden" class="hidden" name="id" value="new" /> + % $m->callback( CallbackName => 'FormStart', QueueObj => $QueueObj, ARGSRef => \%ARGS ); + % if ($gnupg_widget) { -<& /Elements/GnuPG/SignEncryptWidget:ShowIssues, self => $gnupg_widget &> + <& /Elements/GnuPG/SignEncryptWidget:ShowIssues, self => $gnupg_widget &> % } + <div id="Ticket-Create-basics"> <a name="basics"></a> -<&| /Widgets/TitleBox, title => $title &> -<table border="0" cellpadding="0" cellspacing="0"> -<tr><td class="label"><&|/l&>Queue</&>:</td> -%#<td class="value"><& Elements/ShowQueue, QueueObj => $QueueObj &> -%#<input type="hidden" class="hidden" name="Queue" value="<% $QueueObj->Name %>" /> -<td class="value"><& /Elements/SelectQueue, - Name => 'Queue', - Default => $QueueObj->Name, - ShowNullOption => 0, - ShowAllQueues => 0, - OnChange => "document.getElementsByName('id')[0].value = 'refresh'; form.submit()" &> -</td> -<td class="label"><&|/l&>Status</&>: -</td> -<td class="value"> -<& /Elements/SelectStatus, Name => "Status", Default => $ARGS{Status}||'new', DefaultValue => 0, SkipDeleted => 1 &> -</td> -<td class="label"> -<&|/l&>Owner</&>: -</td> -<td class="value"> -<& /Elements/SelectOwner, Name => "Owner", QueueObj => $QueueObj, Default => $ARGS{Owner}||$RT::Nobody->Id, DefaultValue => 0 &> -</td> + +<div id="ticket-create-metadata"> + <&| /Widgets/TitleBox, title => loc("Basics"), class=>'ticket-info-basics' &> + <input type="hidden" class="hidden" name="Queue" value="<% $QueueObj->Id %>" /> + <table width="100%" border="0"> + <& /Ticket/Elements/EditBasics, + InTable => 1, + fields => [ + { name => 'Queue', + comp => '/Elements/SelectQueue', + args => { + Name => 'Queue', + Default => $QueueObj->Name, + QueueObj => $QueueObj, + ShowNullOption => 0, + ShowAllQueues => 0, + OnChange => "document.getElementsByName('id')[0].value = 'refresh'; form.submit()", + }, + }, + { name => 'Status', + comp => '/Elements/SelectStatus', + args => { + Name => "Status", + Default => $ARGS{Status} || $QueueObj->Lifecycle->DefaultOnCreate, + DefaultValue => 0, + SkipDeleted => 1, + QueueObj => $QueueObj, + }, + }, + { name => 'Owner', + comp => '/Elements/SelectOwner', + args => { + Name => "Owner", + Default => $ARGS{Owner} || RT->Nobody->Id, + DefaultValue => 0, + QueueObj => $QueueObj, + }, + } + ] + &> + % $m->callback( CallbackName => 'AfterOwner', ARGSRef => \%ARGS ); -</tr> + + <& /Ticket/Elements/EditCustomFields, %ARGS, QueueObj => $QueueObj, InTable => 1 &> + <& /Ticket/Elements/EditTransactionCustomFields, %ARGS, QueueObj => $QueueObj, InTable => 1 &> + </table> + </&> +% $m->callback( CallbackName => 'AfterBasics', QueueObj => $QueueObj ); +</div> + +<div id="ticket-create-message"> + <&| /Widgets/TitleBox, title => $title, class => 'messagedetails' &> +<table border="0" cellpadding="0" cellspacing="0"> <tr> <td class="label"> <&|/l&>Requestors</&>: </td> <td class="value" colspan="5"> -<& /Elements/EmailInput, Name => 'Requestors', Size => '40', Default => exists($ARGS{Requestors}) ? $ARGS{Requestors} : $session{CurrentUser}->EmailAddress &> +<& /Elements/EmailInput, Name => 'Requestors', Size => undef, Default => exists($ARGS{Requestors}) ? $ARGS{Requestors} : $session{CurrentUser}->EmailAddress &> % $m->callback( CallbackName => 'AfterRequestors', QueueObj => $QueueObj, ARGSRef => \%ARGS ); </td> </tr> @@ -100,55 +129,41 @@ <td class="label"> <&|/l&>Cc</&>: </td> -<td class="value" colspan="3"><& /Elements/EmailInput, Name => 'Cc', Size => '40', Default => $ARGS{Cc} &></td> -<td class="comment" colspan="2"><i><font size="-2"> -<&|/l&>(Sends a carbon-copy of this update to a comma-delimited list of email addresses. These people <strong>will</strong> receive future updates.)</&></font></i> -</td> +<td class="value" colspan="5"><& /Elements/EmailInput, Name => 'Cc', Size => undef, Default => $ARGS{Cc} &></td> </tr> + <tr> -<td class="label"> -<&|/l&>Admin Cc</&>: -</td> -<td class="value" colspan="3"><& /Elements/EmailInput, Name => 'AdminCc', Size => '40', Default => $ARGS{AdminCc} &></td> -<td class="comment" colspan="2"><i><font size="-2"> -<&|/l&>(Sends a carbon-copy of this update to a comma-delimited list of administrative email addresses. These people <strong>will</strong> receive future updates.)</&></font></i> -</td> + <td class="label"> </td> + <td class="comment" colspan="5"> + <i><font size="-2"> + <&|/l&>(Sends a carbon-copy of this update to a comma-delimited list of email addresses. These people <strong>will</strong> receive future updates.)</&> + </font></i> + </td> </tr> + <tr> <td class="label"> -<&|/l&>Subject</&>: -</td> -<td class="value" colspan="5"> -<input name="Subject" size="60" maxsize="200" value="<%$ARGS{Subject} || ''%>" /> -% $m->callback( %ARGS, CallbackName => 'AfterSubject' ); -</td> -</tr> -<tr> -<td colspan="6"> -<& /Ticket/Elements/EditCustomFields, %ARGS, QueueObj => $QueueObj &> +<&|/l&>Admin Cc</&>: </td> +<td class="value" colspan="5"><& /Elements/EmailInput, Name => 'AdminCc', Size => undef, Default => $ARGS{AdminCc} &></td> </tr> -<& /Ticket/Elements/EditTransactionCustomFields, %ARGS, QueueObj => $QueueObj &> + <tr> -% if (exists $session{'Attachments'}) { -<td class="label"> -<&|/l&>Attached file</&>: -</td> -<td colspan="5"> -<&|/l&>Check box to delete</&><br /> -% foreach my $attach_name (keys %{$session{'Attachments'}}) { -<input type="checkbox" class="checkbox" name="DeleteAttach-<%$attach_name%>" value="1" /><%$attach_name%><br /> -% } # end of foreach -</td> + <td class="label"> </td> + <td class="comment" colspan="5"> + <i><font size="-2"> + <&|/l&>(Sends a carbon-copy of this update to a comma-delimited list of administrative email addresses. These people <strong>will</strong> receive future updates.)</&> + </font></i> + </td> </tr> + <tr> -% } # end of if <td class="label"> -<&|/l&>Attach file</&>: +<&|/l&>Subject</&>: </td> <td class="value" colspan="5"> -<input type="file" name="Attach" /> -<input type="submit" class="button" name="AddMoreAttach" value="<&|/l&>Add More Files</&>" /> +<input type="text" name="Subject" maxsize="200" value="<%$ARGS{Subject} || ''%>" /> +% $m->callback( %ARGS, CallbackName => 'AfterSubject' ); </td> </tr> @@ -161,6 +176,9 @@ <tr> <td colspan="6"> <&|/l&>Describe the issue below</&>:<br /> +% if ( RT->Config->Get('ArticleOnTicketCreate')) { +<& /Articles/Elements/BeforeMessageBox, %ARGS, QueueObj => $QueueObj &> +% } % $m->callback( %ARGS, QueueObj => $QueueObj, CallbackName => 'BeforeMessageBox' ); % if (exists $ARGS{Content}) { <& /Elements/MessageBox, Default => $ARGS{Content}, IncludeSignature => 0 &> @@ -172,9 +190,12 @@ <br /> </td> </tr> -</table> -</&> -<& /Elements/Submit, Label => loc("Create")&> + + <& /Ticket/Elements/AddAttachments, %ARGS, QueueObj => $QueueObj &> + </table> + </&> + <& /Elements/Submit, Label => loc("Create"), id => 'SubmitTicket' &> + </div> </div> <div id="Ticket-Create-details"> @@ -243,7 +264,6 @@ <tr><td class="label"><&|/l&>Referred to by</&></td><td><input size="10" name="RefersTo-new" value="<% $ARGS{'RefersTo-new'} || '' %>" /></td></tr> <tr><td class="label">Customer ID</td><td><input size="10" name="new-Customer" value="<% $ARGS{'new-Customer'} || '' %>" /></td></tr> - </table> </&> </div> @@ -259,10 +279,10 @@ <%INIT> $m->callback( CallbackName => "Init", ARGSRef => \%ARGS ); my $Queue = $ARGS{Queue}; +$session{DefaultQueue} = $Queue; -my $CloneTicketObj; if ($CloneTicket) { - $CloneTicketObj = RT::Ticket->new( $session{CurrentUser} ); + my $CloneTicketObj = RT::Ticket->new( $session{CurrentUser} ); $CloneTicketObj->Load($CloneTicket) or Abort( loc("Ticket could not be loaded") ); @@ -352,7 +372,7 @@ my @results; my $title = loc("Create a new ticket"); -my $QueueObj = new RT::Queue($session{'CurrentUser'}); +my $QueueObj = RT::Queue->new($session{'CurrentUser'}); $QueueObj->Load($Queue) || Abort(loc("Queue could not be loaded.")); $m->callback( QueueObj => $QueueObj, title => \$title, results => \@results, ARGSRef => \%ARGS ); @@ -367,17 +387,16 @@ my $ValidCFs = $m->comp( ARGSRef => \%ARGS ); -# {{{ deal with deleting uploaded attachments +# deal with deleting uploaded attachments foreach my $key (keys %ARGS) { if ($key =~ m/^DeleteAttach-(.+)$/) { delete $session{'Attachments'}{$1}; } $session{'Attachments'} = { %{$session{'Attachments'} || {}} }; } -# }}} -# {{{ store the uploaded attachment in session -if ($ARGS{'Attach'}) { # attachment? +# store the uploaded attachment in session +if ( defined $ARGS{'Attach'} && length $ARGS{'Attach'} ) { # attachment? my $attachment = MakeMIMEEntity( AttachmentFieldName => 'Attach' ); @@ -388,7 +407,6 @@ if ($ARGS{'Attach'}) { # attachment? $file_path => $attachment, }; } -# }}} # delete temporary storage entry to make WebUI clean unless (keys %{$session{'Attachments'}} and @@ -434,6 +452,9 @@ my $skip_create = 0; $m->callback( CallbackName => 'BeforeCreate', ARGSRef => \%ARGS, skip_create => \$skip_create, checks_failure => $checks_failure, results => \@results ); +$m->comp( '/Articles/Elements/CheckSkipCreate', ARGSRef => \%ARGS, skip_create => \$skip_create, + checks_failure => $checks_failure, results => \@results ); + if ((!exists $ARGS{'AddMoreAttach'}) and (defined($ARGS{'id'}) and $ARGS{'id'} eq 'new')) { # new ticket? if ( $ValidCFs && !$checks_failure && !$skip_create ) { # CREATE THE TICKET. @@ -459,15 +480,8 @@ if ((!exists $ARGS{'AddMoreAttach'}) and (defined($ARGS{'id'}) and $ARGS{'id'} e } } } - -my $actions = { - A => { - html => q[<a href="#basics" onclick="return switchVisibility('Ticket-Create-basics','Ticket-Create-details');">] . loc('Show basics') . q[</a>], - }, - B => { - html => q[<a href="#details" onclick="return switchVisibility('Ticket-Create-details','Ticket-Create-basics');">] . loc('Show details') . q[</a>], - }, -}; +PageMenu->child( basics => raw_html => q[<a href="#basics" onclick="return switchVisibility('Ticket-Create-basics','Ticket-Create-details');">] . loc('Basics') . q[</a>]); +PageMenu->child( details => raw_html => q[<a href="#details" onclick="return switchVisibility('Ticket-Create-details','Ticket-Create-basics');">] . loc('Details') . q[</a>]); </%INIT> <%ARGS> diff --git a/rt/share/html/Ticket/Display.html b/rt/share/html/Ticket/Display.html index 59adbd68d..6deb65cac 100755 --- a/rt/share/html/Ticket/Display.html +++ b/rt/share/html/Ticket/Display.html @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC %# <sales@bestpractical.com> %# %# (Except where explicitly superseded by other copyright notices) @@ -46,12 +46,9 @@ %# %# END BPS TAGGED BLOCK }}} <& /Elements/Header, - Title => loc("Ticket #[_1]: [_2]", $TicketObj->Id, $TicketObj->Subject), + Title => $title, LinkRel => \%link_rel &> -<& /Ticket/Elements/Tabs, - Ticket => $TicketObj, - current_tab => 'Ticket/Display.html?id='.$TicketObj->id, - Title => loc("Ticket #[_1]: [_2]", $TicketObj->Id, $TicketObj->Subject) &> +<& /Elements/Tabs &> % $m->callback(CallbackName => 'BeforeActionList', %ARGS, Actions => \@Actions, ARGSRef => \%ARGS, Ticket => $TicketObj); @@ -68,18 +65,24 @@ % $m->callback( Ticket => $TicketObj, %ARGS, CallbackName => 'BeforeShowHistory' ); -<& /Ticket/Elements/ShowHistory , - Ticket => $TicketObj, - Tickets => $Tickets, - Collapsed => $ARGS{'Collapsed'}, - ShowHeaders => $ARGS{'ShowHeaders'}, - Attachments => $attachments, - AttachmentContent => $attachment_content -&> +% if (not $ForceShowHistory and RT->Config->Get( 'DeferTransactionLoading', $session{'CurrentUser'} )) { + <& /Ticket/Elements/ClickToShowHistory, + Ticket => $TicketObj, + &> +% } else { + <& /Ticket/Elements/ShowHistory , + Ticket => $TicketObj, + Tickets => $Tickets, + Transactions => $transactions, + Collapsed => $ARGS{'Collapsed'}, + ShowHeaders => $ARGS{'ShowHeaders'}, + Attachments => $attachments, + AttachmentContent => $attachment_content + &> +% } % $m->callback( %ARGS, % Ticket => $TicketObj, -% current_tab => 'Ticket/Display.html?id=' . $TicketObj->id, % CallbackName => 'AfterShowHistory', % ); @@ -88,13 +91,21 @@ $id => undef $TicketObj => undef $ShowHeaders => 0 $Collapsed => undef +$ForceShowHistory => 0 </%ARGS> <%INIT> $m->callback( TicketObj => $TicketObj, ARGSRef => \%ARGS, CallbackName => 'Initial' ); -my (@Actions, $Tickets); +if ( ! $ARGS{'NoRedirect'} && RT::Interface::Web->MobileClient()) { + $id ||= $TicketObj->id if $TicketObj; + RT::Interface::Web::Redirect(RT->Config->Get('WebURL').'m/ticket/show?id='.$id); + $m->abort; +} + + +my (@Actions, $Tickets, $title); unless ($id || $TicketObj) { @@ -112,7 +123,7 @@ if ($ARGS{'id'} eq 'new') { $ARGS{'new-MemberOf'} = join(' ', $ARGS{'new-MemberOf'}, @cust_uris); - my $Queue = new RT::Queue( $session{'CurrentUser'} ); + my $Queue = RT::Queue->new( $session{'CurrentUser'} ); $Queue->Load($ARGS{'Queue'}); unless ( $Queue->id ) { Abort('Queue not found'); @@ -129,89 +140,95 @@ if ($ARGS{'id'} eq 'new') { unless ( $TicketObj->CurrentUserHasRight('ShowTicket') ) { Abort("No permission to view newly created ticket #".$TicketObj->id."."); } - # }}} } else { $TicketObj ||= LoadTicket($ARGS{'id'}); + $TicketObj->CurrentUser->PrincipalObj->HasRights( Object => $TicketObj ); + + my $SkipProcessing; + $m->callback( CallbackName => 'BeforeProcessArguments', TicketObj => $TicketObj, Tickets => $Tickets, - ActionsRef => \@Actions, ARGSRef => \%ARGS ); - if ( defined $ARGS{'Action'} ) { - if ($ARGS{'Action'} =~ /^(Steal|Kill|Take|SetTold)$/) { - my $action = $1; - my ($res, $msg) = $TicketObj->$action(); - push(@Actions, $msg); + ActionsRef => \@Actions, ARGSRef => \%ARGS, + SkipProcessing => \$SkipProcessing ); + + if ( !$SkipProcessing ) { + if ( defined $ARGS{'Action'} ) { + if ($ARGS{'Action'} =~ /^(Steal|Delete|Take|SetTold)$/) { + my $action = $1; + my ($res, $msg) = $TicketObj->$action(); + push(@Actions, $msg); + } } - } - $m->callback(CallbackName => 'ProcessArguments', - Ticket => $TicketObj, - ARGSRef => \%ARGS, - Actions => \@Actions); - - $ARGS{UpdateAttachments} = $session{'Attachments'}; - push @Actions, - ProcessUpdateMessage( - ARGSRef => \%ARGS, - Actions => \@Actions, - TicketObj => $TicketObj, - ); - delete $session{'Attachments'}; - - #Process status updates - push @Actions, ProcessTicketWatchers(ARGSRef => \%ARGS, TicketObj => $TicketObj ); - push @Actions, ProcessTicketBasics( ARGSRef => \%ARGS, TicketObj => $TicketObj ); - push @Actions, ProcessTicketLinks( ARGSRef => \%ARGS, TicketObj => $TicketObj ); - push @Actions, ProcessTicketDates( ARGSRef => \%ARGS, TicketObj => $TicketObj ); - push @Actions, ProcessTicketCustomFieldUpdates(ARGSRef => \%ARGS, TicketObj => $TicketObj ); - # If this fails due to required fields being empty, it will set - # notes('RedirectToBasics'). - push @Actions, ProcessTicketStatus( ARGSRef => \%ARGS, TicketObj => $TicketObj ); - - # XXX: we shouldn't block actions here if user has no right to see the - # ticket, but we should allow him to see actions he has done - unless ($TicketObj->CurrentUserHasRight('ShowTicket')) { - Abort("No permission to view ticket"); - } - if ( $ARGS{'MarkAsSeen'} ) { - $TicketObj->SetAttribute( - Name => 'User-'. $TicketObj->CurrentUser->id .'-SeenUpTo', - Content => $TicketObj->LastUpdated, - ); - push @Actions, loc('Marked all messages as seen'); + $m->callback(CallbackName => 'ProcessArguments', + Ticket => $TicketObj, + ARGSRef => \%ARGS, + Actions => \@Actions); + + $ARGS{UpdateAttachments} = $session{'Attachments'}; + push @Actions, + ProcessUpdateMessage( + ARGSRef => \%ARGS, + Actions => \@Actions, + TicketObj => $TicketObj, + ); + delete $session{'Attachments'}; + + #Process status updates + push @Actions, ProcessTicketWatchers(ARGSRef => \%ARGS, TicketObj => $TicketObj ); + push @Actions, ProcessTicketBasics( ARGSRef => \%ARGS, TicketObj => $TicketObj ); + push @Actions, ProcessTicketLinks( ARGSRef => \%ARGS, TicketObj => $TicketObj ); + push @Actions, ProcessTicketDates( ARGSRef => \%ARGS, TicketObj => $TicketObj ); + push @Actions, ProcessTicketCustomFieldUpdates(ARGSRef => \%ARGS, TicketObj => $TicketObj ); + # If this fails due to required fields being empty, it will set + # notes('RedirectToBasics'). + push @Actions, ProcessTicketStatus( ARGSRef => \%ARGS, TicketObj => $TicketObj ); + + push @Actions, ProcessTicketReminders( ARGSRef => \%ARGS, TicketObj => $TicketObj ); + + # XXX: we shouldn't block actions here if user has no right to see the ticket, + # but we should allow him to see actions he has done + unless ($TicketObj->CurrentUserHasRight('ShowTicket')) { + Abort("No permission to view ticket"); + } + if ( $ARGS{'MarkAsSeen'} ) { + $TicketObj->SetAttribute( + Name => 'User-'. $TicketObj->CurrentUser->id .'-SeenUpTo', + Content => $TicketObj->LastUpdated, + ); + push @Actions, loc('Marked all messages as seen'); + } } } + +$title = loc("Ticket #[_1]: [_2]", $TicketObj->Id, $TicketObj->Subject || ''); + $m->callback( CallbackName => 'BeforeDisplay', TicketObj => \$TicketObj, Tickets => \$Tickets, Actions => \@Actions, + title => \$title, ARGSRef => \%ARGS, ); # This code does automatic redirection if any updates happen. +my $path = '/Ticket/'. ( $m->notes('RedirectToBasics') ? 'Modify.html' + : 'Display.html' ); +MaybeRedirectForResults( + Actions => \@Actions, + $TicketObj->Type eq 'approval' && RT->Config->Get('ForceApprovalsView') + ? (Path => "/Approvals/Display.html", Force => 1) + : (Path => $path) + , + Anchor => $ARGS{'Anchor'}, + Arguments => { id => $TicketObj->id }, +); -if (@Actions) { - - # We've done something, so we need to clear the decks to avoid - # resubmission on refresh. - # But we need to store Actions somewhere too, so we don't lose them. - my $key = Digest::MD5::md5_hex( rand(1024) ); - push @{ $session{"Actions"}->{$key} ||= [] }, @Actions; - $session{'i'}++; - my $url = RT->Config->Get('WebURL'); - if ( $m->notes('RedirectToBasics') ) { - $url .= 'Ticket/Modify.html'; - } - else { - $url .= 'Ticket/Display.html'; - } - $url .= '?id=' . $TicketObj->id . "&results=" . $key; - $url .= '#' . $ARGS{Anchor} if $ARGS{Anchor}; - RT::Interface::Web::Redirect($url); -} - +# Get the transactoins before the attachments, for great ACL justice +my $transactions = $m->comp('Elements/FindTransactions',Ticket => $TicketObj, Tickets => $Tickets || undef); my $attachments = $m->comp('Elements/FindAttachments', Ticket => $TicketObj, Tickets => $Tickets); my $attachment_content = $m->comp('Elements/LoadTextAttachments', Ticket => $TicketObj); diff --git a/rt/share/html/Ticket/Elements/AddWatchers b/rt/share/html/Ticket/Elements/AddWatchers index b015f5c43..8590a2aef 100755 --- a/rt/share/html/Ticket/Elements/AddWatchers +++ b/rt/share/html/Ticket/Elements/AddWatchers @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC %# <sales@bestpractical.com> %# %# (Except where explicitly superseded by other copyright notices) diff --git a/rt/share/html/Ticket/Elements/Bookmark b/rt/share/html/Ticket/Elements/Bookmark index 28034c50e..83931918d 100644 --- a/rt/share/html/Ticket/Elements/Bookmark +++ b/rt/share/html/Ticket/Elements/Bookmark @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC %# <sales@bestpractical.com> %# %# (Except where explicitly superseded by other copyright notices) @@ -81,9 +81,9 @@ if ( $Toggle ) { $id $Toggle => 0 </%ARGS> -<span id="toggle-<% $id %>" class="toggle-<% $id %>"> +<span class="toggle-bookmark-<% $id %>"> % my $url = RT->Config->Get('WebPath') ."/Helpers/Toggle/TicketBookmark?id=". $id; -<a align="right" href="<% $url %>" onclick="toggleTicketBookmark('<% $id|n %>', '<% $url %>'); return false;"> +<a align="right" href="<% $url %>" onclick="jQuery('.toggle-bookmark-<% $id |n%>').load('<% $url |n %>'); return false;" > % if ( $bookmarked ) { <img src="<% RT->Config->Get('WebPath') %>/NoAuth/images/star.gif" alt="<% loc('Remove Bookmark') %>" style="border-style: none" /> % } else { diff --git a/rt/share/html/Ticket/Elements/BulkLinks b/rt/share/html/Ticket/Elements/BulkLinks index 181fbed56..bae556cd1 100755 --- a/rt/share/html/Ticket/Elements/BulkLinks +++ b/rt/share/html/Ticket/Elements/BulkLinks @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC %# <sales@bestpractical.com> %# %# (Except where explicitly superseded by other copyright notices) diff --git a/rt/share/html/Ticket/Elements/EditBasics b/rt/share/html/Ticket/Elements/EditBasics index b91329870..b428aab29 100755 --- a/rt/share/html/Ticket/Elements/EditBasics +++ b/rt/share/html/Ticket/Elements/EditBasics @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC %# <sales@bestpractical.com> %# %# (Except where explicitly superseded by other copyright notices) @@ -45,86 +45,100 @@ %# those contributions and any derivatives thereof. %# %# END BPS TAGGED BLOCK }}} -<table> - <tr> - <td class="label"><&|/l&>Subject</&>:</td> - <td class="value"><input name="Subject" value="<%$TicketObj->Subject|h%>" size="50" /></td> - </tr> - - <tr> - <td class="label"><&|/l&>Status</&>:</td> - <td class="value"><%$SelectStatus|n%></td> - </tr> - <tr> - <td class="label"><&|/l&>Queue</&>:</td> - <td class="value"><%$SelectQueue|n%></td> - </tr> - <tr> - <td class="label"><&|/l&>Owner</&>:</td> - <td class="value"><& /Elements/SelectOwner, - Name => 'Owner', - QueueObj => $TicketObj->QueueObj, - TicketObj => $TicketObj, - Default => $TicketObj->OwnerObj->Id, - DefaultValue => 0, - &></td> - </tr> - - <tr> - <td class="label"><&|/l&>Time Estimated</&>:</td> - <td class="value"> - <& /Elements/EditTimeValue, - Name => 'TimeEstimated', - Default => $TicketObj->TimeEstimated, - &> - </td> - </tr> - <tr> - <td class="label"><&|/l&>Time Worked</&>:</td> - <td class="value"> - <& /Elements/EditTimeValue, - Name => 'TimeWorked', - Default => $TicketObj->TimeWorked, - &> - </td> - </tr> - <tr> - <td class="label"><&|/l&>Time Left</&>:</td> - <td class="value"> - <& /Elements/EditTimeValue, - Name => 'TimeLeft', - Default => $TicketObj->TimeLeft, - &> - </td> - </tr> - - <tr> - <td class="label"><&|/l&>Priority</&>:</td> - <td class="value"><& /Elements/SelectPriority, - Default => $TicketObj->Priority, - &></td> - </tr> - - <tr> - <td class="label"><&|/l&>Final Priority</&>:</td> - <td class="value"><& /Elements/SelectPriority, - Name => "FinalPriority", - Default => $TicketObj->FinalPriority, - &></td> - </tr> +<%ARGS> +$TicketObj => undef +@fields => () +$InTable => 0 +%defaults => () +</%ARGS> +<%INIT> +unless ( @fields ) { + @fields = ( + { name => 'Subject', + html => '<input name="Subject" value="'.$m->interp->apply_escapes( $defaults{'Subject'} || $TicketObj->Subject, 'h' ).'" />', + }, + { name => 'Status', + comp => '/Elements/SelectStatus', + args => { + Name => 'Status', + DefaultLabel => loc("[_1] (Unchanged)",loc($TicketObj->Status)), + Default => $defaults{'Status'} || undef, + TicketObj => $TicketObj, + QueueObj => $TicketObj->QueueObj, + }, + }, + { name => 'Queue', + comp => '/Elements/SelectQueue', + args => { + Name => 'Queue', + Default => $defaults{'Queue'} || $TicketObj->QueueObj->Id, + ShowNullOption => 0, + } + }, + { name => 'Owner', + comp => '/Elements/SelectOwner', + args => { + Name => 'Owner', + QueueObj => $TicketObj->QueueObj, + TicketObj => $TicketObj, + Default => $defaults{'Owner'} || $TicketObj->OwnerObj->Id, + DefaultValue => 0, + } + }, + # Time Estimated, Worked, and Left + ( + map { + (my $field = $_) =~ s/ //g; + { + name => $_, + comp => '/Elements/EditTimeValue', + args => { + Name => $field, + Default => $defaults{$field} || $TicketObj->$field, + } + } + } ('Time Estimated', 'Time Worked', 'Time Left') + ), + # Priority and Final Priority + ( + map { + (my $field = $_) =~ s/ //g; + { + name => $_, + comp => '/Elements/SelectPriority', + args => { + Name => $field, + Default => $defaults{$field} || $TicketObj->$field, + } + } + } ('Priority', 'Final Priority') + ), + ); +} +$m->callback( CallbackName => 'MassageFields', %ARGS, TicketObj => $TicketObj, Fields => \@fields ); +# Process the field list, skipping if html is provided and running the +# components otherwise +for my $field (@fields) { + next if defined $field->{'html'}; + if ( $field->{'comp'} ) { + $field->{'html'} = $m->scomp($field->{'comp'}, %{$field->{'args'} || {}}); + } +} +</%INIT> -% $m->callback( CallbackName => 'EndOfList', TicketObj => $TicketObj, %ARGS ); +% unless ($InTable) { +<table> +% } +% for my $field (@fields) { + <tr class="<% lc $field->{'name'} %>">\ +<td class="label"><&|/l&><% $field->{'name'} %></&>:</td>\ +<td class="value"><% $field->{'html'} |n %></td>\ +</tr> +% } +% $m->callback( CallbackName => 'EndOfList', TicketObj => $TicketObj, %ARGS, Fields => \@fields ); +% unless ($InTable) { </table> +% } -<%INIT> -#It's hard to do this inline, so we'll preload the html of the selectstatus in here. -my $SelectStatus = $m->scomp("/Elements/SelectStatus", Name => 'Status', DefaultLabel => loc("[_1] (Unchanged)",loc($TicketObj->Status))); -my $SelectQueue = $m->scomp("/Elements/SelectQueue", Name => 'Queue', Default =>$TicketObj->QueueObj->Id, ShowNullOption => 0); - -</%INIT> -<%ARGS> - -$TicketObj => undef -</%ARGS> diff --git a/rt/share/html/Ticket/Elements/EditCustomFields b/rt/share/html/Ticket/Elements/EditCustomFields index ee55e996f..29ac95ad0 100755 --- a/rt/share/html/Ticket/Elements/EditCustomFields +++ b/rt/share/html/Ticket/Elements/EditCustomFields @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC %# <sales@bestpractical.com> %# %# (Except where explicitly superseded by other copyright notices) @@ -46,22 +46,18 @@ %# %# END BPS TAGGED BLOCK }}} % $m->callback( %ARGS, CallbackName => 'BeforeCustomFields' ); -<table> -% my $i = 0; +% if ( $WRAP ) { +<<% $WRAP %> class="edit-custom-fields"> +% } % while ( my $CustomField = $CustomFields->Next ) { % next unless $CustomField->CurrentUserHasRight('ModifyCustomField'); -% my $escaped_name = lc $CustomField->Name; -% $escaped_name =~ s/[^a-z0-9_-]/_/g; -% my $type = $CustomField->Type || 'Unknown'; -% $i++; -% if ( $single_column || $i % 2 ) { -<tr class="edit-custom-field"> -% } - <td class="cflabel cftype-<% $type %> cfname-<% $escaped_name %>" id="<% $CFIDPrefix %>cflabel-<% $CustomField->Id %>" > - <b><% loc($CustomField->Name) %></b><br /> - <i><% $CustomField->FriendlyType %></i> - </td> - <td class="entry cftype-<% $type %> cfname-<% $escaped_name %>" id="<% $CFIDPrefix %>cfentry-<% $CustomField->Id %>"> +% my $Type = $CustomField->Type || 'Unknown'; + <<% $FIELD %> class="edit-custom-field cftype-<% $Type %>"> + <<% $CELL %> class="cflabel"> + <span class="name"><% loc($CustomField->Name) %></span><br /> + <span class="type"><% $CustomField->FriendlyType %></span> + </<% $CELL %>> + <<% $CELL %> class="entry"> % my $default = $m->notes('Field-' . $CustomField->Id); % $default ||= $ARGS{"CustomField-". $CustomField->Id }; <& /Elements/EditCustomField, @@ -73,22 +69,15 @@ &> % if (my $msg = $m->notes('InvalidField-' . $CustomField->Id)) { <br /> - <span class="cfinvalidfield cftype-<% $type %> cfname-<% $escaped_name %>"><% $msg %></span> + <span class="cfinvalidfield"><% $msg %></span> % } - </td> - -% if ($single_column || not $i % 2 ) { -</tr> -% } - + </<% $CELL %>> + </<% $FIELD %>> % } -%# close row if required -% if ( !$single_column || $i % 2 ) { -</tr> +% if ( $WRAP ) { +</<% $WRAP %>> % } - -</table> % $m->callback( %ARGS, CallbackName => 'AfterCustomFields', TicketObj => $TicketObj, QueueObj => $QueueObj ); <%INIT> my $CustomFields; @@ -103,7 +92,15 @@ if ($TicketObj && !$OnCreate) { $m->callback( %ARGS, CallbackName => 'MassageCustomFields', CustomFields => $CustomFields ); -my $single_column = RT->Config->Get('EditCustomFieldsSingleColumn'); +$AsTable ||= $InTable; +my $FIELD = $AsTable ? 'tr' : 'div'; +my $CELL = $AsTable ? 'td' : 'div'; +my $WRAP = ''; +if ( $AsTable ) { + $WRAP = 'table' unless $InTable; +} else { + $WRAP = 'div'; +} # show hints for missing required fields if ( $TicketObj ) { @@ -119,5 +116,6 @@ $TicketObj => undef $QueueObj => undef $OnCreate => undef $DefaultsFromTopArguments => 1 -$CFIDPrefix => '' +$AsTable => 0 +$InTable => 0 </%ARGS> diff --git a/rt/share/html/Ticket/Elements/EditDates b/rt/share/html/Ticket/Elements/EditDates index 4b9a93bb8..93ca4cc30 100755 --- a/rt/share/html/Ticket/Elements/EditDates +++ b/rt/share/html/Ticket/Elements/EditDates @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC %# <sales@bestpractical.com> %# %# (Except where explicitly superseded by other copyright notices) diff --git a/rt/share/html/Ticket/Elements/EditPeople b/rt/share/html/Ticket/Elements/EditPeople index 980700ed0..09cf6f365 100755 --- a/rt/share/html/Ticket/Elements/EditPeople +++ b/rt/share/html/Ticket/Elements/EditPeople @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC %# <sales@bestpractical.com> %# %# (Except where explicitly superseded by other copyright notices) diff --git a/rt/share/html/Ticket/Elements/EditTransactionCustomFields b/rt/share/html/Ticket/Elements/EditTransactionCustomFields index a4ade8721..e9a1bbb5c 100644 --- a/rt/share/html/Ticket/Elements/EditTransactionCustomFields +++ b/rt/share/html/Ticket/Elements/EditTransactionCustomFields @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC %# <sales@bestpractical.com> %# %# (Except where explicitly superseded by other copyright notices) @@ -46,30 +46,36 @@ %# %# END BPS TAGGED BLOCK }}} % $m->callback( CallbackName => 'BeforeTransactionCustomFields', TicketObj => $TicketObj, QueueObj => $QueueObj, NamePrefix => $NamePrefix ); +% if ( $WRAP ) { +<<% $WRAP %> class="edit-transaction-custom-fields"> +% } % if ($CustomFields->Count) { % while (my $CF = $CustomFields->Next()) { % $CF->SetContextObject($TicketObj || $QueueObj); % next unless $CF->CurrentUserHasRight('ModifyCustomField'); % next unless $CF->UILocation eq $UILocation; -<tr> -<td class="label"> -<% loc($CF->Name) %>: -</td> -<td> +<<% $FIELD %>> +<<% $CELL %> class="label cflabel"> + <span class="name"><% loc($CF->Name) %>:</span><br /> +% if ( $CF->Type ne 'TimeValue' ) { + <span class="type"><% $CF->FriendlyType %></span> +% } +</<% $CELL %>> +<<% $CELL %>> <& /Elements/EditCustomField, CustomField => $CF, NamePrefix => $NamePrefix &> -% if ( $CF->Type ne 'TimeValue' ) { -<em><% $CF->FriendlyType %></em> -% } -% if (my $msg = $m->notes('InvalidField-' . $CF->Id)) { +% if (my $msg = $m->notes('InvalidField-' . $CF->Id)) { <br /> <span class="cfinvalidfield"><% $msg %></span> +% } +</<% $CELL %>> +</<% $FIELD %>> % } -</td> -</td></tr> % } +% if ( $WRAP ) { +</<% $WRAP %>> % } % $m->callback( CallbackName => 'AfterTransactionCustomFields', TicketObj => $TicketObj, QueueObj => $QueueObj, NamePrefix => $NamePrefix ); @@ -84,11 +90,23 @@ if ($TicketObj) { $m->callback( CallbackName => 'MassageTransactionCustomFields', CustomFields => $CustomFields ); +$AsTable ||= $InTable; +my $FIELD = $AsTable ? 'tr' : 'div'; +my $CELL = $AsTable ? 'td' : 'div'; +my $WRAP = ''; +if ( $AsTable ) { + $WRAP = 'table' unless $InTable; +} else { + $WRAP = 'div'; +} + </%INIT> <%ARGS> $NamePrefix => "Object-RT::Transaction--CustomField-" $TicketObj => undef $QueueObj => undef +$AsTable => 0 +$InTable => 0 $UILocation => '' </%ARGS> diff --git a/rt/share/html/Ticket/Elements/EditWatchers b/rt/share/html/Ticket/Elements/EditWatchers index 952a411ce..abfbf0096 100755 --- a/rt/share/html/Ticket/Elements/EditWatchers +++ b/rt/share/html/Ticket/Elements/EditWatchers @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC %# <sales@bestpractical.com> %# %# (Except where explicitly superseded by other copyright notices) @@ -57,16 +57,23 @@ <li> <input type="checkbox" class="checkbox" name="Ticket-DeleteWatcher-Type-<% $Watchers->Type %>-Principal-<% $watcher->MemberId %>" value="1" unchecked /> % if ( $member->isa( 'RT::User' ) ) { +% if ( $session{CurrentUser}->HasRight( Right => 'AdminUsers', Object => $RT::System ) && +% $session{CurrentUser}->HasRight( Right => 'ShowConfigTab', Object =>$RT::System ) ) { <a href="<% RT->Config->Get('WebPath') %>/Admin/Users/Modify.html?id=<% $watcher->MemberId %>"> -<& /Elements/ShowUser, User => $member &></a> -% if ($TicketObj and grep { $_->Content eq $member->EmailAddress } $TicketObj->SquelchMailTo) { -<b><&|/l&>(Will not be sent email)</&></b> -% } - +<& /Elements/ShowUser, User => $member &></a> <& /Elements/ShowUserEmailFrequency, User => $member, Ticket => $TicketObj &> % } else { +<& /Elements/ShowUser, User => $member &> <& /Elements/ShowUserEmailFrequency, User => $member, Ticket => $TicketObj &> +% } } +% else { +% if ( $session{CurrentUser}->HasRight( Right => 'AdminGroup', Object => $RT::System ) && +% $session{CurrentUser}->HasRight( Right => 'ShowConfigTab', Object =>$RT::System ) ) { <a href="<% RT->Config->Get('WebPath') %>/Admin/Groups/Modify.html?id=<% $watcher->MemberId %>"> -<% $member->Name %></a> -% } +<% $member->Name %> +</a> +% } else { +<% $member->Name %> +% } } + </li> % } </ul> diff --git a/rt/share/html/Ticket/Elements/FindAttachments b/rt/share/html/Ticket/Elements/FindAttachments index 8c1d1f8a8..cb9975199 100644 --- a/rt/share/html/Ticket/Elements/FindAttachments +++ b/rt/share/html/Ticket/Elements/FindAttachments @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC %# <sales@bestpractical.com> %# %# (Except where explicitly superseded by other copyright notices) diff --git a/rt/share/html/Ticket/Elements/LoadTextAttachments b/rt/share/html/Ticket/Elements/LoadTextAttachments index e8f7e6b8f..b1ff5326a 100644 --- a/rt/share/html/Ticket/Elements/LoadTextAttachments +++ b/rt/share/html/Ticket/Elements/LoadTextAttachments @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC %# <sales@bestpractical.com> %# %# (Except where explicitly superseded by other copyright notices) diff --git a/rt/share/html/Ticket/Elements/PreviewScrips b/rt/share/html/Ticket/Elements/PreviewScrips index dcf85a558..75fbc4563 100755 --- a/rt/share/html/Ticket/Elements/PreviewScrips +++ b/rt/share/html/Ticket/Elements/PreviewScrips @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC %# <sales@bestpractical.com> %# %# (Except where explicitly superseded by other copyright notices) @@ -47,213 +47,73 @@ %# END BPS TAGGED BLOCK }}} <%args> $TicketObj => undef - </%args> <%init> -my %squelch = $m->comp('SELF:SquelchRecipients', %ARGS); -my $Object = $squelch{'Object'}; -my @non_recipients = @{ $squelch{'EmailAddresses'} }; - +my $Object = $m->notes("DryRun-".$TicketObj->Id) || $TicketObj->DryRun(%ARGS); +my %recips = %{ $m->notes("DryRun-Recipients-".$TicketObj->Id) || {} }; +return unless $Object; </%init> -<h2><&|/l&>This message will be sent to...</&></h2> - -% if ( $Object and $Object->Scrips ) { -<i><&|/l&>(Check boxes to disable notifications to the listed recipients)</&></i><br /> - -% foreach my $scrip (@{$Object->Scrips->Prepared}) { -% next unless $scrip->ActionObj->Action->isa('RT::Action::SendEmail'); -<b><% $scrip->Description || loc('Scrip #[_1]',$scrip->id) %></b><br /> -<&|/l, loc($scrip->ConditionObj->Name), loc($scrip->ActionObj->Name), loc($scrip->TemplateObj->Name)&>[_1] [_2] with template [_3]</&> -<br /> -%foreach my $type (qw(To Cc Bcc)) { -%my @addresses = $scrip->ActionObj->Action->$type(); -<ul> -%foreach my $addr (@addresses) { -<li> - <b><%loc($type)%></b>: <input type="checkbox" class="checkbox" name="Ticket-<%$TicketObj->id%>-SquelchMailTo" value="<%$addr->address%>" /> <%$addr->address%> - -% $m->callback(CallbackName => 'AfterAddress', Ticket => $TicketObj, Address => $addr, Type => $type); -</li> -% } -</ul> -% } -% if (RT->Config->Get('PreviewScripMessages')) { -<textarea cols="80" rows="5"> -<%$scrip->ActionObj->TemplateObj->MIMEObj->as_string%> -</textarea> -% } -% } +<p> +<&|/l, RT->Config->Get('WebPath')."/Ticket/ModifyPeople.html?id=".$TicketObj->Id, +&>Uncheck boxes to disable notifications to the listed recipients <b>for this transaction only</b>; persistent squelching is managed on the <a href="[_1]">People page</a>.</&> +</p> + +% if ( $Object->Scrips ) { +% # Sort scrips with recipients before those without +% my @scrips = map { $_->[0] } +% sort { ($b->[1]?1:0) <=> ($a->[1]?1:0) } +% map { [$_, $_->ActionObj->Action->To + $_->ActionObj->Action->Cc + $_->ActionObj->Action->Bcc] } +% grep {$_->ActionObj->Action->isa('RT::Action::SendEmail')} +% @{$Object->Scrips->Prepared}; +% for my $scrip (@scrips) { + <b><% $scrip->Description || loc('Scrip #[_1]',$scrip->id) %></b><br /> + <&|/l, loc($scrip->ConditionObj->Name), loc($scrip->ActionObj->Name), loc($scrip->TemplateObj->Name)&>[_1] [_2] with template [_3]</&> + <br /> +% for my $type (qw(To Cc Bcc)) { +% my @addresses = $scrip->ActionObj->Action->$type(); +% next unless @addresses; + <ul> +% for my $addr (@addresses) { + <li> +% my $checked = 1; +% $m->callback(CallbackName => 'BeforeAddress', Ticket => $TicketObj, Address => $addr, Type => $type, Checked => \$checked); +% $recips{$addr->address}++; + <b><%loc($type)%></b>: <input type="checkbox" class="checkbox" name="TxnSendMailTo" <% $checked ? 'checked="checked"' : '' |n%> value="<%$addr->address%>" id="TxnSendMailTo-<% $addr->address %>-<% $recips{$addr->address} %>" /> + <label for="TxnSendMailTo-<% $addr->address %>-<% $recips{$addr->address} %>"><& /Elements/ShowUser, Address => $addr &></label> +% $m->callback(CallbackName => 'AfterAddress', Ticket => $TicketObj, Address => $addr, Type => $type); + </li> +% } + </ul> +% } +% if (RT->Config->Get('PreviewScripMessages')) { + <textarea cols="80" rows="5"><%$scrip->ActionObj->TemplateObj->MIMEObj->as_string%></textarea> +% } + <br /> +% } % } -% if ( $Object and $Object->Rules ) { -% for my $rule (@{$Object->Rules}) { -% next unless $rule->{hints} && $rule->{hints}{class} eq 'SendEmail'; -<b><% $rule->Describe %></b> -% my $data = $rule->{hints}{recipients}; -% foreach my $type (qw(To Cc Bcc)) { -<ul> -% foreach my $address (@{$data->{$type}}) { -<li> - <b><%loc($type)%></b>: <input type="checkbox" class="checkbox" name="Ticket-<%$TicketObj->id%>-SquelchMailTo" value="<%$address%>" /> <%$address%> - -% $m->callback(CallbackName => 'AfterAddress', Ticket => $TicketObj, Address => Email::Address->parse($address), Type => $type); -</li> -% } -</ul> - -% } -% } -% } -<br /> - -<h2><&|/l&>Messages about this ticket will not be sent to...</&></h2> -<i><&|/l&>(Check boxes to enable notifications to the listed recipients)</&></i> -<br /> -<ul> -% foreach my $recipient (@non_recipients) { -<li><input type="checkbox" class="checkbox" name="Ticket-<%$TicketObj->id%>-UnsquelchMailTo" value="<%$recipient->Content%>" /> -<% $recipient->Content %> +% if ( $Object->Rules ) { +% for my $rule (@{$Object->Rules}) { +% next unless $rule->{hints} && $rule->{hints}{class} eq 'SendEmail'; + <b><% $rule->Describe %></b> +% my $data = $rule->{hints}{recipients}; +% for my $type (qw(To Cc Bcc)) { +% next unless @{$data->{$type}}; + <ul> +% for my $address (@{$data->{$type}}) { + <li> +% my $checked = 1; +% $m->callback(CallbackName => 'BeforeAddress', Ticket => $TicketObj, Address => Email::Address->parse($address), Type => $type, Checked => \$checked); +% $recips{$address}++; + <b><%loc($type)%></b>: <input type="checkbox" class="checkbox" name="TxnSendMailTo" <% $checked ? 'checked="checked"' : '' |n%> value="<%$address%>" id="TxnSendMailTo-<% $address %>-<% $recips{$address} %>" /> + <label for="TxnSendMailTo-<% $address %>-<% $recips{$address} %>"><%$address%></label> +% $m->callback(CallbackName => 'AfterAddress', Ticket => $TicketObj, Address => Email::Address->parse($address), Type => $type); + </li> +% } + </ul> +% } + <br /> +% } % } -</ul> -<& /Elements/Submit, Name => 'UpdatePreview', Value => 'UpdatePreview', Label => loc('Save Changes')&> - -<%METHOD SquelchRecipients> -<%ARGS> -$TicketObj => undef -</%ARGS> -<%INIT> -my $arg = 'Ticket-'.$TicketObj->Id.'-SquelchMailTo'; -my @squelchto = ref($ARGS{$arg}) eq 'ARRAY' ? @{$ARGS{$arg}} : ($ARGS{$arg}); - -foreach my $address (@squelchto) { - $TicketObj->SquelchMailTo($address) if ($address); -} - - -$arg = 'Ticket-'.$TicketObj->Id.'-UnsquelchMailTo'; -my @unsquelchto = ref($ARGS{$arg}) eq 'ARRAY' ? @{$ARGS{$arg}} : ($ARGS{$arg}); - -foreach my $address (@unsquelchto) { - $TicketObj->UnsquelchMailTo($address) if ($address); -} - - -my $action; - -if (($ARGS{'UpdateType'} && $ARGS{'UpdateType'} eq 'response' ) || ($ARGS{'Action'} && $ARGS{'Action'} eq 'Respond' )) { - $action = 'Correspond'; -} -else { - $action = 'Comment'; -} - -my $Message = MakeMIMEEntity( - Subject => $ARGS{'UpdateSubject'}, - Body => $ARGS{'UpdateContent'}, -); - -my ( $Transaction, $Description, $Object ) = $TicketObj->$action( - CcMessageTo => $ARGS{'UpdateCc'}, - BccMessageTo => $ARGS{'UpdateBcc'}, - MIMEObj => $Message, - TimeTaken => $ARGS{'UpdateTimeWorked'}, - DryRun => 1 -); -unless ( $Transaction ) { - $RT::Logger->error("Coulfn't fire '$action' action: $Description"); -} - - -return (Object => $Object, EmailAddresses => [$TicketObj->SquelchMailTo]); -</%INIT> -</%METHOD> - -<%METHOD GetRecipients> -<%ARGS> -$TicketObj -</%ARGS> -<%INIT> -my $action; -if ( ( $ARGS{'UpdateType'} && $ARGS{'UpdateType'} eq 'response' ) - || ( $ARGS{'Action'} && $ARGS{'Action'} eq 'Respond' ) ) -{ - $action = 'Correspond'; -} -else { - $action = 'Comment'; -} - -my $Message = MakeMIMEEntity( - Subject => $ARGS{'UpdateSubject'}, - Body => $ARGS{'UpdateContent'}, -); - -my ( $id, $msg, $txn ) = $TicketObj->$action( - CcMessageTo => $ARGS{'UpdateCc'}, - BccMessageTo => $ARGS{'UpdateBcc'}, - MIMEObj => $Message, - TimeTaken => $ARGS{'UpdateTimeWorked'}, - DryRun => 1 -); -unless ( $id && $txn ) { - $RT::Logger->error("Couldn't fire '$action' action: $msg"); - return (); -} - -my @recipients; -foreach my $scrip ( @{ $txn->Scrips->Prepared } ) { - my $action = $scrip->ActionObj->Action; - next unless $action->isa('RT::Action::SendEmail'); - - foreach my $type (qw(To Cc Bcc)) { - push @recipients, $action->$type(); - } -} -return @recipients; -</%INIT> -</%METHOD> - -<%METHOD GetRecipientsOnCreate> -<%INIT> -my $action; -my $Message = MakeMIMEEntity( - Subject => $ARGS{'Subject'}, - Cc => $ARGS{'Cc'}, - Body => $ARGS{'Content'}, -); - -my $TicketObj = RT::Ticket->new( $session{'CurrentUser'} ); -my ( $id, $txn, $msg ) = $TicketObj->Create( - Type => $ARGS{'Type'} || 'ticket', - Queue => $ARGS{'Queue'}, - Owner => $ARGS{'Owner'}, - Requestor => $ARGS{'Requestors'}, - Cc => $ARGS{'Cc'}, - AdminCc => $ARGS{'AdminCc'}, - InitialPriority => $ARGS{'InitialPriority'}, - FinalPriority => $ARGS{'FinalPriority'}, - TimeLeft => $ARGS{'TimeLeft'}, - TimeEstimated => $ARGS{'TimeEstimated'}, - TimeWorked => $ARGS{'TimeWorked'}, - Subject => $ARGS{'Subject'}, - Status => $ARGS{'Status'}, - MIMEObj => $Message, - DryRun => 1 -); -unless ( $id && $txn ) { - $RT::Logger->error("Couldn't fire '$action' action: $msg"); - return (); -} - -my @recipients; -foreach my $scrip ( @{ $txn->Scrips->Prepared } ) { - my $action = $scrip->ActionObj->Action; - next unless $action->isa('RT::Action::SendEmail'); - foreach my $type (qw(To Cc Bcc)) { - push @recipients, $action->$type(); - } -} -return @recipients; -</%INIT> -</%METHOD> +% $m->notes("DryRun-Recipients-".$TicketObj->Id, \%recips); diff --git a/rt/share/html/Ticket/Elements/Reminders b/rt/share/html/Ticket/Elements/Reminders index 8526da3c0..563b0f0cd 100644 --- a/rt/share/html/Ticket/Elements/Reminders +++ b/rt/share/html/Ticket/Elements/Reminders @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC %# <sales@bestpractical.com> %# %# (Except where explicitly superseded by other copyright notices) @@ -55,96 +55,80 @@ $Edit => 0 $Ticket = LoadTicket($id) if ($id); -my $request_args = $m->request_args(); - -my $reminder_collection = $Ticket->Reminders->Collection; - -if ( $request_args->{'update-reminders'} ) { - while ( my $reminder = $reminder_collection->Next ) { - if ( $reminder->Status ne 'resolved' && $request_args->{ 'Complete-Reminder-' . $reminder->id } ) { - $Ticket->Reminders->Resolve($reminder); - } - elsif ( $reminder->Status eq 'resolved' && !$request_args->{ 'Complete-Reminder-' . $reminder->id } ) { - $Ticket->Reminders->Open($reminder); - } - - if ( exists( $request_args->{ 'Reminder-Subject-' . $reminder->id } ) && ( $reminder->Subject ne $request_args->{ 'Reminder-Subject-' . $reminder->id } )) { - $reminder->SetSubject( $request_args->{ 'Reminder-Subject-' . $reminder->id } ) ; - } - - if ( exists( $request_args->{ 'Reminder-Owner-' . $reminder->id } ) && ( $reminder->Owner != $request_args->{ 'Reminder-Owner-' . $reminder->id } )) { - $reminder->SetOwner( $request_args->{ 'Reminder-Owner-' . $reminder->id } , "Force" ) ; - } - - if ( exists( $request_args->{ 'Reminder-Due-' . $reminder->id } ) && ( $reminder->DueObj->Date ne $request_args->{ 'Reminder-Due-' . $reminder->id } )) { - $reminder->SetDue( $request_args->{ 'Reminder-Due-' . $reminder->id } ) ; - } - } -} - -if ( $request_args->{'NewReminder-Subject'} ) { - my $due_obj = RT::Date->new( $session{'CurrentUser'} ); - my $date = Time::ParseDate::parsedate( - $request_args->{'NewReminder-Due'}, - UK => RT->Config->Get('DateDayBeforeMonth'), - PREFER_PAST => 0, - PREFER_FUTURE => 1 - ); - $due_obj->Set( Value => $date, Format => 'unix' ); - my ( $add_id, $msg, $txnid ) = $Ticket->Reminders->Add( - - Subject => $request_args->{'NewReminder-Subject'}, - Owner => $request_args->{'NewReminder-Owner'}, - Due => $due_obj->ISO - ); +my $count_reminders = RT::Reminders->new($session{'CurrentUser'}); +$count_reminders->Ticket($Ticket->id); +my $count_tickets = $count_reminders->Collection; +if (!$ShowCompleted) { + # XXX: don't break encapsulation if we can avoid it + $count_tickets->FromSQL('Type = "reminder" AND RefersTo = "'.$Ticket->id.'" AND Status != "resolved"'); } +my $has_reminders = $count_tickets->Count; # We've made changes, let's reload our search - -$reminder_collection = $Ticket->Reminders->Collection; +my $reminder_collection = $count_reminders->Collection; </%init> <input type="hidden" class="hidden" name="id" value="<% $Ticket->id %>" /> <input type="hidden" class="hidden" name="update-reminders" value="1" /> -<div> -% while (my $reminder = $reminder_collection->Next) { -% if ($reminder->Status eq 'resolved' && !$ShowCompleted) { +% if ($has_reminders) { +<table border="0" cellpadding="1" cellspacing="0" class="collection-as-table"<% $Edit ? ' style="width: auto;"' : '' |n %>> +<tr> +% if ( $Edit ) { +<th class="collection-as-table" colspan="5"><&|/l&>Reminders</&></th> +% } else { +<th class="collection-as-table"></th> +<th class="collection-as-table"><&|/l&>Reminder</&></th> +<th class="collection-as-table"><&|/l&>Due</&></th> +<th class="collection-as-table"><&|/l&>Owner</&></th> +% } +</tr> +% my $i = 0; +% my $visible = 0; +% while ( my $reminder = $reminder_collection->Next ) { +% $i++; +% if ( $reminder->Status eq 'resolved' && !$ShowCompleted ) { +<tr class="hidden"><td><input type="hidden" class="hidden" name="Complete-Reminder-<% $reminder->id %>" value="1" /></td></tr> +% $i++; +% } elsif ($Edit) { +<& SELF:EditEntry, Reminder => $reminder, Ticket => $Ticket, Index => $i &> +% $visible++; +% } else { +<& SELF:ShowEntry, Reminder => $reminder, Ticket => $Ticket, Index => $i &> +% $visible++; +% } +% } +</table> +% if ( $visible > 0 ) { +<i><&|/l&>(Check box to complete)</&></i><br /><br /> +% } +% } else { + +%# we must always include resolved reminders due to the browser +%# checkbox-with-false-value issue +% while ( my $reminder = $reminder_collection->Next ) { +% if ( $reminder->Status eq 'resolved' && !$ShowCompleted ) { <input type="hidden" class="hidden" name="Complete-Reminder-<% $reminder->id %>" value="1" /> -% } elsif ($Edit) { -<& SELF:EditEntry, Reminder => $reminder, Ticket => $Ticket &> -% } else { -<& SELF:ShowEntry, Reminder => $reminder, Ticket => $Ticket &> -% } % } -% if ($reminder_collection->Count) { -<i><&|/l&>(Check box to delete)</&></i><br /><br /> % } -</div> -<div> +% } + <&|/l&>New reminder:</&> <& SELF:NewReminder, Ticket => $Ticket &> -</div> <%method NewReminder> <%args> $Ticket </%args> <table> -<tr class="input-row"> -<td class="label"><label class="horizontal" for="NewReminder-Subject" ><&|/l&>Subject</&>:</label></td> -<td class="value"> -<input type="text" size="15" name="NewReminder-Subject" id="NewReminder-Subject" /> -</td> +<tr> +<td class="label"><&|/l&>Subject</&>:</td> +<td class="entry" colspan="3"><input type="text" size="50" name="NewReminder-Subject" id="NewReminder-Subject" /></td> </tr> -<tr class="input-row"> -<td class="label"> -<label class="horizontal" for="NewReminder-Owner" ><&|/l&>Owner</&>:</label></td><td class="value"> -<& /Elements/SelectOwner, Name => 'NewReminder-Owner', QueueObj => $Ticket->QueueObj, Default=>$session{'CurrentUser'}->id, DefaultValue => 0 &> -</td> +<tr> +<td class="label"><&|/l&>Owner</&>:</td> +<td class="entry"><& /Elements/SelectOwner, Name => 'NewReminder-Owner', QueueObj => $Ticket->QueueObj, Default=>$session{'CurrentUser'}->id, DefaultValue => 0 &></td> </tr> -<tr class="input-row"> -<td class="label"><label class="horizontal" for="NewReminder-Due" ><&|/l&>Due</&>:</label></td> -<td class="value"> -<& /Elements/SelectDate, Name => "NewReminder-Due", Default => "" &> -</td> +<tr> +<td class="label"><&|/l&>Due</&>:</td> +<td class="entry"><& /Elements/SelectDate, Name => "NewReminder-Due", Default => "" &></td> </tr> </table> </%method> @@ -152,28 +136,33 @@ $Ticket <%args> $Reminder $Ticket +$Index </%args> -<input - type="checkbox" - name="Complete-Reminder-<%$Reminder->id%>" - <% $Reminder->Status eq 'resolved' ? 'checked="checked"' : '' %> -/> - <input type="text" size="15" name="Reminder-Subject-<% $Reminder->id %>" value="<%$Reminder->Subject%>" /> • - <& /Elements/SelectOwner, Name => 'Reminder-Owner-'.$Reminder->id, Queue => $Ticket->QueueObj, Default => $Reminder->Owner, DefaultValue => 0 &> - <& /Elements/SelectDate, Name => 'Reminder-Due-'.$Reminder->id, Default => $Reminder->DueObj->Date &> - (<%$Reminder->DueObj->Unix>0 ? $Reminder->DueObj->AgeAsString : '' %>)<br /> +<tr class="<% $Index%2 ? 'oddline' : 'evenline' %>"> +<td class="entry"><input type="checkbox" value="1" name="Complete-Reminder-<% $Reminder->id %>" <% $Reminder->Status eq 'resolved' ? 'checked="checked"' : '' |n %> /></td> +<td class="label"><&|/l&>Subject</&>:</td> +<td class="entry" colspan="3"><input type="text" size="50" name="Reminder-Subject-<% $Reminder->id %>" value="<% $Reminder->Subject %>" /></td> +</tr> +<tr class="<% $Index%2 ? 'oddline' : 'evenline' %>"> +<td class="entry"> </td> +<td class="label"><&|/l&>Owner</&>:</td> +<td class="entry"><& /Elements/SelectOwner, Name => 'Reminder-Owner-'.$Reminder->id, QueueObj => $Ticket->QueueObj, Default => $Reminder->Owner, DefaultValue => 0 &></td> +<td class="label"><&|/l&>Due</&>:</td> +<td class="entry"><& /Elements/SelectDate, Name => 'Reminder-Due-'.$Reminder->id &> (<% $Reminder->DueObj->AsString %>)</td> +</tr> </%method> <%method ShowEntry> <%args> $Reminder $Ticket +$Index </%args> -<input - type="checkbox" - name="Complete-Reminder-<%$Reminder->id%>" - <% $Reminder->Status eq 'resolved' ? 'checked="checked"' : '' %> -/> - <%$Reminder->Subject%> • - <& /Elements/ShowUser, User => $Reminder->OwnerObj &> - <%$Reminder->DueObj->Unix>0 ? "• ". $Reminder->DueObj->AgeAsString : '' |n%><br /> +% my $dueobj = $Reminder->DueObj; +% my $overdue = $dueobj->Unix > 0 && $dueobj->Diff < 0 ? 1 : 0; +<tr class="<% $Index%2 ? 'oddline' : 'evenline' %>"> +<td class="collection-as-table"><input type="checkbox" value="1" name="Complete-Reminder-<% $Reminder->id %>" <% $Reminder->Status eq 'resolved' ? 'checked="checked"' : '' |n %> /></td> +<td class="collection-as-table"><% $Reminder->Subject %></td> +<td class="collection-as-table"><% $overdue ? '<span class="overdue">' : '' |n %><% $dueobj->AgeAsString || loc('Not set') %><% $overdue ? '</span>' : '' |n %></td> +<td class="collection-as-table"><& /Elements/ShowUser, User => $Reminder->OwnerObj &></td> +</tr> </%method> diff --git a/rt/share/html/Ticket/Elements/ShowAttachments b/rt/share/html/Ticket/Elements/ShowAttachments index c97a1ef12..12130e4de 100755 --- a/rt/share/html/Ticket/Elements/ShowAttachments +++ b/rt/share/html/Ticket/Elements/ShowAttachments @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC %# <sales@bestpractical.com> %# %# (Except where explicitly superseded by other copyright notices) @@ -51,7 +51,7 @@ class => 'ticket-info-attachments', color => "#336699" &> -% foreach my $key (keys %documents) { +% foreach my $key (sort { lc($a) cmp lc($b) } keys %documents) { <%$key%><br /> <ul> @@ -104,7 +104,7 @@ $Attachments ||= $m->comp('FindAttachments', Ticket => $Ticket); my %documents; while ( my $attach = $Attachments->Next() ) { - next unless ($attach->Filename()); + next unless defined $attach->Filename && length $attach->Filename; unshift( @{ $documents{ $attach->Filename } }, $attach ); } diff --git a/rt/share/html/Ticket/Elements/ShowBasics b/rt/share/html/Ticket/Elements/ShowBasics index 0959f72e0..0ecb6d8ba 100755 --- a/rt/share/html/Ticket/Elements/ShowBasics +++ b/rt/share/html/Ticket/Elements/ShowBasics @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC %# <sales@bestpractical.com> %# %# (Except where explicitly superseded by other copyright notices) @@ -46,40 +46,43 @@ %# %# END BPS TAGGED BLOCK }}} <table> - <tr> - <td class="label id"><&|/l&>Id</&>:</td> - <td class="value id"><%$Ticket->Id %></td> + <tr class="id"> + <td class="label"><&|/l&>Id</&>:</td> + <td class="value"><%$Ticket->Id %></td> </tr> - <tr> - <td class="label status"><&|/l&>Status</&>:</td> - <td class="value status"><% loc($Ticket->Status) %></td> + <tr class="status"> + <td class="label"><&|/l&>Status</&>:</td> + <td class="value"><% loc($Ticket->Status) %></td> </tr> % if ($Ticket->TimeEstimated) { - <tr> - <td class="label time estimated"><&|/l&>Estimated</&>:</td> - <td class="value time estimated"><& ShowTime, minutes => $Ticket->TimeEstimated &></td> + <tr class="time estimated"> + <td class="label"><&|/l&>Estimated</&>:</td> + <td class="value"><& ShowTime, minutes => $Ticket->TimeEstimated &></td> </tr> % } % if ($Ticket->TimeWorked) { - <tr> - <td class="label time worked"><&|/l&>Worked</&>:</td> - <td class="value time worked"><& ShowTime, minutes => $Ticket->TimeWorked &></td> + <tr class="time worked"> + <td class="label"><&|/l&>Worked</&>:</td> + <td class="value"><& ShowTime, minutes => $Ticket->TimeWorked &></td> </tr> % } % if ($Ticket->TimeLeft) { - <tr> - <td class="label time left"><&|/l&>Left</&>:</td> - <td class="value time left"><& ShowTime, minutes => $Ticket->TimeLeft &></td> + <tr class="time left"> + <td class="label"><&|/l&>Left</&>:</td> + <td class="value"><& ShowTime, minutes => $Ticket->TimeLeft &></td> </tr> % } - <tr> - <td class="label priority"><&|/l&>Priority</&>:</td> - <td class="value priority"><& ShowPriority, Ticket => $Ticket &></td> + <tr class="priority"> + <td class="label"><&|/l&>Priority</&>:</td> + <td class="value"><& ShowPriority, Ticket => $Ticket &></td> </tr> - <tr> - <td class="label queue"><&|/l&>Queue</&>:</td> - <td class="value queue"><& ShowQueue, QueueObj => $Ticket->QueueObj &></td> +%# This will check SeeQueue at the ticket role level, queue level, and global level +% if ($Ticket->CurrentUserHasRight('SeeQueue')) { + <tr class="queue"> + <td class="label"><&|/l&>Queue</&>:</td> + <td class="value"><& ShowQueue, Ticket => $Ticket, QueueObj => $Ticket->QueueObj &></td> </tr> +% } % $m->callback( %ARGS, CallbackName => 'EndOfList', TicketObj => $Ticket ); </table> <%ARGS> diff --git a/rt/share/html/Ticket/Elements/ShowCustomFields b/rt/share/html/Ticket/Elements/ShowCustomFields index 3a2924d65..4a0604331 100755 --- a/rt/share/html/Ticket/Elements/ShowCustomFields +++ b/rt/share/html/Ticket/Elements/ShowCustomFields @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC %# <sales@bestpractical.com> %# %# (Except where explicitly superseded by other copyright notices) diff --git a/rt/share/html/Ticket/Elements/ShowDates b/rt/share/html/Ticket/Elements/ShowDates index 1df0f8084..c0d26f7c1 100755 --- a/rt/share/html/Ticket/Elements/ShowDates +++ b/rt/share/html/Ticket/Elements/ShowDates @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC %# <sales@bestpractical.com> %# %# (Except where explicitly superseded by other copyright notices) @@ -46,34 +46,34 @@ %# %# END BPS TAGGED BLOCK }}} <table> - <tr> - <td class="label date created"><&|/l&>Created</&>:</td> - <td class="value date created"><% $Ticket->CreatedObj->AsString %></td> + <tr class="date created"> + <td class="label"><&|/l&>Created</&>:</td>\ + <td class="value"><% $Ticket->CreatedObj->AsString %></td> </tr> - <tr> - <td class="label date starts"><&|/l&>Starts</&>:</td> - <td class="value date starts"><% $Ticket->StartsObj->AsString %></td> + <tr class="date starts"> + <td class="label"><&|/l&>Starts</&>:</td>\ + <td class="value"><% $Ticket->StartsObj->AsString %></td> </tr> - <tr> - <td class="label date started"><&|/l&>Started</&>:</td> - <td class="value date started"><% $Ticket->StartedObj->AsString %></td> + <tr class="date started"> + <td class="label"><&|/l&>Started</&>:</td>\ + <td class="value"><% $Ticket->StartedObj->AsString %></td> </tr> - <tr> - <td class="label date told"><a href="<% RT->Config->Get('WebPath') %>/Ticket/Display.html?id=<% $Ticket->id %>&Action=SetTold"><&|/l&>Last Contact</&></a>:</td> - <td class="value date told"><% $Ticket->ToldObj->AsString %></td> + <tr class="date told"> + <td class="label"><a href="<% RT->Config->Get('WebPath') %>/Ticket/Display.html?id=<% $Ticket->id %>&Action=SetTold"><&|/l&>Last Contact</&></a>:</td>\ + <td class="value"><% $Ticket->ToldObj->AsString %></td> </tr> - <tr> - <td class="label date due"><&|/l&>Due</&>:</td> + <tr class="date due"> + <td class="label"><&|/l&>Due</&>:</td>\ % my $due = $Ticket->DueObj; % if ( $due && $due->Unix > 0 && $due->Diff < 0 ) { - <td class="value date due"><span class="overdue"><% $due->AsString %></span></td> + <td class="value"><span class="overdue"><% $due->AsString %></span></td> % } else { - <td class="value date due"><% $due->AsString %></td> + <td class="value"><% $due->AsString %></td> % } </tr> - <tr> - <td class="label date resolved"><&|/l&>Resolved</&>:</td> - <td class="value date resolved"><% $Ticket->ResolvedObj->AsString %></td> + <tr class="date resolved"> + <td class="label"><&|/l&>Resolved</&>:</td>\ + <td class="value"><% $Ticket->ResolvedObj->AsString %></td> </tr> % my $willresolve = $Ticket->WillResolveObj; % if ( $willresolve && $willresolve->Unix > 0 ) { @@ -81,14 +81,13 @@ <td class="label date willresolve"><&|/l&>Will Resolve</&>:</td> <td class="value date willresolve"><% $willresolve->AsString %></td> </tr> -% } # else don't display either of them - <tr> - <td class="label date updated"><&|/l&>Updated</&>:</td> +% } # else don't display either of them <tr class="date updated"> + <td class="label"><&|/l&>Updated</&>:</td>\ % my $UpdatedString = $Ticket->LastUpdated ? loc("[_1] by [_2]", $Ticket->LastUpdatedAsString, $m->scomp('/Elements/ShowUser', User => $Ticket->LastUpdatedByObj)) : loc("Never"); % if ($UpdatedLink) { - <td class="value date updated"><a href="#lasttrans"><% $UpdatedString |n%></a></td> + <td class="value"><a href="#lasttrans"><% $UpdatedString | n %></a></td> % } else { - <td class="value date updated"><% $UpdatedString |n%></td> + <td class="value"><% $UpdatedString | n %></td> % } </tr> % $m->callback( %ARGS, CallbackName => 'EndOfList', TicketObj => $Ticket ); diff --git a/rt/share/html/Ticket/Elements/ShowDependencies b/rt/share/html/Ticket/Elements/ShowDependencies index b052c15c5..d56aa862c 100755 --- a/rt/share/html/Ticket/Elements/ShowDependencies +++ b/rt/share/html/Ticket/Elements/ShowDependencies @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC %# <sales@bestpractical.com> %# %# (Except where explicitly superseded by other copyright notices) diff --git a/rt/share/html/Ticket/Elements/ShowGnuPGStatus b/rt/share/html/Ticket/Elements/ShowGnuPGStatus index cd5426a1f..126f23b9e 100644 --- a/rt/share/html/Ticket/Elements/ShowGnuPGStatus +++ b/rt/share/html/Ticket/Elements/ShowGnuPGStatus @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC %# <sales@bestpractical.com> %# %# (Except where explicitly superseded by other copyright notices) diff --git a/rt/share/html/Ticket/Elements/ShowGroupMembers b/rt/share/html/Ticket/Elements/ShowGroupMembers index 97c7a9dcf..add377d74 100644 --- a/rt/share/html/Ticket/Elements/ShowGroupMembers +++ b/rt/share/html/Ticket/Elements/ShowGroupMembers @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC %# <sales@bestpractical.com> %# %# (Except where explicitly superseded by other copyright notices) diff --git a/rt/share/html/Ticket/Elements/ShowHistory b/rt/share/html/Ticket/Elements/ShowHistory index 1833ecd51..b5e009c34 100755 --- a/rt/share/html/Ticket/Elements/ShowHistory +++ b/rt/share/html/Ticket/Elements/ShowHistory @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC %# <sales@bestpractical.com> %# %# (Except where explicitly superseded by other copyright notices) @@ -60,18 +60,21 @@ if ($ShowDisplayModes or $ShowTitle) { if ($ShowDisplayModes) { $titleright = ''; + my $open_all = $m->interp->apply_escapes( loc("Show all quoted text"), 'h' ); + my $close_all = $m->interp->apply_escapes( loc("Hide all quoted text"), 'h' ); + $titleright .= '<a href="#" data-direction="open" ' + . qq{onclick='return toggle_all_folds(this, "$open_all", "$close_all");'} + . ">$open_all</a> — "; + if ($ShowHeaders) { $titleright .= qq{<a href="$URIFile?id=} . $Ticket->id.qq{">} . - loc("Brief headers") . - qq{</a> — }; - $titleright .= q[<span class="selected">] . loc("Full headers") . "</span>"; - } - else { - $titleright .= q[<span class="selected">] . loc("Brief headers") . "</span> — "; + loc("Show brief headers") . + qq{</a>}; + } else { $titleright .= qq{<a href="$URIFile?ShowHeaders=1;id=} . $Ticket->id.qq{">} . - loc("Full headers") . + loc("Show full headers") . qq{</a>}; } } @@ -79,11 +82,18 @@ if ($ShowDisplayModes or $ShowTitle) { <div class="history"> <& /Widgets/TitleBoxStart, title => $title, titleright_raw => $titleright &> % } - <div id="ticket-history"> <%perl> -my @attachments = @{$Attachments->ItemsArrayRef()}; -my @attachment_content = @{$AttachmentContent->ItemsArrayRef()}; +my $trans_content = {}; +my $trans_attachments = {}; + +for my $content (@{$AttachmentContent->ItemsArrayRef()}) { + $trans_content->{$content->TransactionId}->{$content->Id} = $content; +} + +for my $attachment (@{$Attachments->ItemsArrayRef()}) { + push (@{$trans_attachments->{$attachment->TransactionId}}, $attachment) +} while ( my $Transaction = $Transactions->Next ) { my $skip = 0; @@ -97,14 +107,8 @@ while ( my $Transaction = $Transactions->Next ) { $i++; - my @trans_attachments = grep { $_->TransactionId == $Transaction->Id } @attachments; - - my $trans_content = {}; - grep { ($_->TransactionId == $Transaction->Id ) && ($trans_content->{$_->Id} = $_) } @attachment_content; - - my $IsLastTransaction = 0; - if ( $OldestFirst ) { + if ( RT->Config->Get( 'OldestTransactionsFirst', $session{'CurrentUser'} )){ $IsLastTransaction = $Transactions->IsLast; } else { $IsLastTransaction = 1 if ( $i == 1 ); @@ -118,7 +122,7 @@ while ( my $Transaction = $Transactions->Next ) { Transaction => $Transaction, ShowHeaders => $ShowHeaders, RowNum => $i, - Attachments => \@trans_attachments, + Attachments => $trans_attachments->{$Transaction->id}, AttachmentContent => $trans_content, LastTransaction => $IsLastTransaction ); @@ -135,25 +139,9 @@ $m->flush_buffer(); </div> % } <%INIT> -my $Transactions = new RT::Transactions($session{'CurrentUser'}); -if ($Tickets) { - while (my $t = $Tickets->Next) { - $Transactions->LimitToTicket($t->id); - } -} else { - $Transactions = $Ticket->Transactions; -} - - -my $OldestFirst = RT->Config->Get( 'OldestTransactionsFirst', $session{'CurrentUser'} ); -my $SortOrder = $OldestFirst? 'ASC': 'DESC'; -$Transactions->OrderByCols( { FIELD => 'Created', - ORDER => $SortOrder }, - { FIELD => 'id', - ORDER => $SortOrder }, - ); my $i; +$Transactions ||= $m->comp('/Ticket/Elements/FindTransactions',Ticket => $Ticket, Tickets => $Tickets || undef); $Attachments ||= $m->comp('/Ticket/Elements/FindAttachments', Ticket => $Ticket, Tickets => $Tickets || undef); $AttachmentContent ||= $m->comp('/Ticket/Elements/LoadTextAttachments', Ticket => $Ticket); @@ -162,6 +150,7 @@ $AttachmentContent ||= $m->comp('/Ticket/Elements/LoadTextAttachments', Ticket = $URIFile => RT->Config->Get('WebPath')."/Ticket/Display.html" $Ticket => undef $Tickets => undef +$Transactions => undef $Attachments => undef $AttachmentContent => undef $ShowHeaders => undef diff --git a/rt/share/html/Ticket/Elements/ShowMembers b/rt/share/html/Ticket/Elements/ShowMembers index 7e9ba492f..c17c6e7b8 100755 --- a/rt/share/html/Ticket/Elements/ShowMembers +++ b/rt/share/html/Ticket/Elements/ShowMembers @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC %# <sales@bestpractical.com> %# %# (Except where explicitly superseded by other copyright notices) diff --git a/rt/share/html/Ticket/Elements/ShowMessageHeaders b/rt/share/html/Ticket/Elements/ShowMessageHeaders index 943b567d2..3c86162b1 100755 --- a/rt/share/html/Ticket/Elements/ShowMessageHeaders +++ b/rt/share/html/Ticket/Elements/ShowMessageHeaders @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC %# <sales@bestpractical.com> %# %# (Except where explicitly superseded by other copyright notices) diff --git a/rt/share/html/Ticket/Elements/ShowMessageStanza b/rt/share/html/Ticket/Elements/ShowMessageStanza index 6f8875195..8a8544328 100755 --- a/rt/share/html/Ticket/Elements/ShowMessageStanza +++ b/rt/share/html/Ticket/Elements/ShowMessageStanza @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC %# <sales@bestpractical.com> %# %# (Except where explicitly superseded by other copyright notices) @@ -45,67 +45,144 @@ %# those contributions and any derivatives thereof. %# %# END BPS TAGGED BLOCK }}} -<%perl> -if ( ref $Message ) { - $m->out('<pre>') if $plain_text_pre && !$Depth && !$plain_text_mono; - $m->out( qq{<div class="message-stanza-depth-$Depth } .($plain_text_mono ? "plain-text-white-space" : "") .qq{">} ); +<%INIT> +my $plain_text_pre + = RT->Config->Get( 'PlainTextPre', $session{'CurrentUser'} ); +my $plain_text_mono + = RT->Config->Get( 'PlainTextMono', $session{'CurrentUser'} ); +my $Depth = 0; + +my $ticket = $Transaction ? $Transaction->TicketObj : undef; + +my $print_content = sub { + my $ref = shift; + return unless defined $$ref && length $$ref; + $m->callback( content => $ref, %ARGS ); + if ( $ContentType eq 'text/plain' ) { + $m->comp( '/Elements/MakeClicky', + content => $ref, + ticket => $ticket, + %ARGS + ); + + if ( defined $$ref && !$plain_text_pre && !$plain_text_mono ) { + $$ref =~ s{(\r?\n)}{<br />}g; + } + } else { + if ( defined $$ref ) { + $$ref =~ s/^[\r\n]+//g; + } + } + $m->out($$ref); +}; + +if ( ref $Message ) { + $m->out('<pre>') + if ( $ContentType eq 'text/plain' + && $plain_text_pre + && !$Depth + && !$plain_text_mono ); + $m->out( '<div class="message-stanza' + . ( ($ContentType eq 'text/plain' && $plain_text_mono) ? ' plain-text-white-space' : '' ) . '"' + . '>' ); my @stack; my $para = ''; - my $i = 0; + my $i = 0; - AGAIN: foreach ( ; $i < @$Message; $i++ ) { +AGAIN: foreach ( ; $i < @$Message; $i++ ) { my $stanza = $Message->[$i]; if ( ref $stanza eq "HASH" ) { - $para .= ( defined $stanza->{raw} ? $stanza->{raw} : '') ."\n"; + # Fix message stanza nesting for Outlook's quoting styles + if ( $stanza->{raw} + and not $stanza->{_outlooked} + and $stanza->{raw} =~ /^ # start of an internal line + \s* # optional whitespace + (?: + -{3,} # at least three hyphens + \s* # whitespace varies between Outlook versions + # don't trigger on PGP signed message or signature blocks + (?!(?:BEGIN|END)\s+PGP) + \w # at least one word character + [\w\s]{3,}? # the rest of the word(s), totalling at least 5 characters, + # loose to get different languages + \w # at least one ending word character + \s* # whitespace varies between Outlook versions + -{3,} # at least three hyphens again + | + _{6,} # OR: six or more underscores + ) + \s*$ # optional whitespace until the end of the line + /xm ) + { + # There's content before the quoted message, but in the + # same stanza. Break it out! + if ( my $start = $-[0] ) { + my %preceding = %$stanza; + + # We don't process $stanza->{text} because we don't use it + # and it isn't given to us by HTML::Quoted. If we ever + # need to, we can process it the same way as 'raw'. + $preceding{raw} = substr($stanza->{raw}, 0, $start, ''); + + # Replace the current stanza with the two we just created + splice @$Message, $i, 1, \%preceding, $stanza; + + # Try it again from the top now that we've rejiggered our + # stanzas. We'll process the Outlook stanza again, and hit + # the else below this time. + redo; + } else { + # Nest the current stanza and everything that follows + $stanza->{_outlooked}++; + $stanza = $Message->[ $i ] = [ splice @$Message, $i ]; + } + } + else { + $para .= ( defined $stanza->{raw} ? $stanza->{raw} : '' )."\n"; + } } next unless ref $stanza eq "ARRAY"; - $print_content->( \$para ); $para = ''; + $print_content->( \$para ); + $para = ''; $Depth++; - push @stack, [$Message, $i+1]; - ($Message, $i) = ($stanza, -1); - $m->out( qq{<div class="message-stanza-depth-$Depth">} ); + push @stack, [ $Message, $i + 1 ]; + ( $Message, $i ) = ( $stanza, -1 ); + + if ( $Depth == 1 ) { + $m->comp('FoldStanzaJS'); + } + my @classes = ('message-stanza'); + push @classes, $Depth == 1 ? 'closed' : 'open'; + $m->out( '<div class="' . join(" ", @classes) . '">' ); } if ( length $para ) { - $print_content->( \$para ); $para = ''; + $print_content->( \$para ); + $para = ''; } - if ( @stack ) { - ($Message, $i) = @{ pop @stack }; + if (@stack) { + ( $Message, $i ) = @{ pop @stack }; $Depth--; $m->out('</div>'); goto AGAIN; } $m->out('</div>'); - $m->out('</pre>') if $plain_text_pre && !$Depth && !$plain_text_mono; + $m->out('</pre>') + if ( $ContentType eq 'text/plain' + && $plain_text_pre + && !$Depth + && !$plain_text_mono ); } else { - $print_content->( \$Message ); + $print_content->( \$Message ); } -</%perl> -<%INIT> -my $plain_text_pre = RT->Config->Get('PlainTextPre', $session{'CurrentUser'}); -my $plain_text_mono = RT->Config->Get('PlainTextMono', $session{'CurrentUser'}); - -my $ticket = $Transaction ? $Transaction->TicketObj : undef; - -my $print_content = sub { - my $ref = shift; - return unless defined $$ref && length $$ref; - - $m->callback( content => $ref, %ARGS ); - $m->comp('/Elements/MakeClicky', content => $ref, ticket => $ticket, %ARGS); - unless ( $plain_text_pre || $plain_text_mono ) { - $$ref =~ s{(\r?\n)}{<br />}g if defined $$ref; - } - $m->out( $$ref ); -}; </%INIT> <%ARGS> $Message => undef -$Depth => 0 $Transaction => undef +$ContentType => 'text/plain' </%ARGS> diff --git a/rt/share/html/Ticket/Elements/ShowParents b/rt/share/html/Ticket/Elements/ShowParents index 74bd8e174..2a64cfce0 100644 --- a/rt/share/html/Ticket/Elements/ShowParents +++ b/rt/share/html/Ticket/Elements/ShowParents @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC %# <sales@bestpractical.com> %# %# (Except where explicitly superseded by other copyright notices) diff --git a/rt/share/html/Ticket/Elements/ShowPeople b/rt/share/html/Ticket/Elements/ShowPeople index cb5fb329c..8047aff85 100755 --- a/rt/share/html/Ticket/Elements/ShowPeople +++ b/rt/share/html/Ticket/Elements/ShowPeople @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC %# <sales@bestpractical.com> %# %# (Except where explicitly superseded by other copyright notices) diff --git a/rt/share/html/Ticket/Elements/ShowPriority b/rt/share/html/Ticket/Elements/ShowPriority index caf26fec3..7b6b361a1 100644 --- a/rt/share/html/Ticket/Elements/ShowPriority +++ b/rt/share/html/Ticket/Elements/ShowPriority @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC %# <sales@bestpractical.com> %# %# (Except where explicitly superseded by other copyright notices) diff --git a/rt/share/html/Ticket/Elements/ShowQueue b/rt/share/html/Ticket/Elements/ShowQueue index 6742d4a72..255225591 100644 --- a/rt/share/html/Ticket/Elements/ShowQueue +++ b/rt/share/html/Ticket/Elements/ShowQueue @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC %# <sales@bestpractical.com> %# %# (Except where explicitly superseded by other copyright notices) @@ -45,12 +45,20 @@ %# those contributions and any derivatives thereof. %# %# END BPS TAGGED BLOCK }}} -<% $QueueObj->Name %> +<% $value %> <%ARGS> +$Ticket => undef $QueueObj </%ARGS> <%INIT> my $value = $QueueObj->Name; + +if ( $Ticket and $Ticket->CurrentUserHasRight('SeeQueue') ) { + # Grab the queue name anyway if the current user can + # see the queue based on his role for this ticket + $value = $QueueObj->__Value('Name'); +} + $value = '#'. $QueueObj->id unless defined $value && length $value; </%INIT> diff --git a/rt/share/html/Ticket/Elements/ShowRequestor b/rt/share/html/Ticket/Elements/ShowRequestor index b5d7c7dcb..3e5f41fb9 100755 --- a/rt/share/html/Ticket/Elements/ShowRequestor +++ b/rt/share/html/Ticket/Elements/ShowRequestor @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC %# <sales@bestpractical.com> %# %# (Except where explicitly superseded by other copyright notices) @@ -45,61 +45,143 @@ %# those contributions and any derivatives thereof. %# %# END BPS TAGGED BLOCK }}} -<%PERL> -# Unsure sane default -unless ( @$conditions ) { - foreach (RT::Queue->ActiveStatusArray()) { - push @$conditions, { cond => "Status = '$_'", name => loc($_) }; - } -} -my $rows = 10; -my $has_right_adminusers = $session{'CurrentUser'}->HasRight( - Object => $RT::System, Right => 'AdminUsers' -); -$has_right_adminusers &&= $session{'CurrentUser'}->HasRight( - Object => $RT::System, Right => 'ShowConfigTab' -); -my $people = $Ticket->Requestors->UserMembersObj; -while ( my $requestor = $people->Next ) { - next if $requestor->Privileged; - my $name = $m->scomp('/Elements/ShowUser', User => $requestor); +<script type="text/javascript"> + jQuery(function() { + jQuery("#requestor-accordion").accordion({ + active: <% $count == 1 ? 0 : 'false' %>, + collapsible: true, + autoHeight: false + }); - my $tickets = RT::Tickets->new( $session{'CurrentUser'} ); - $tickets->FromSQL( "Requestor.id = ". $requestor->id ." AND (".join( " OR ", map $_->{cond}, @$conditions).")" ); - $tickets->RowsPerPage( $rows ); - $tickets->OrderBy( FIELD => 'Priority', ORDER => 'DESC' ); -</%PERL> +% if ($ShowTickets) { + jQuery(".more-about-requestor-tickets").tabs({ + cache: true, + collapsible: true, + selected: <% $selected %> + }); +% } + }); +</script> <&| /Widgets/TitleBox, - title_href => $has_right_adminusers? RT->Config->Get('WebPath')."/Admin/Users/Modify.html?id=".$requestor->id: undef, - title_raw => loc("More about [_1]", $name), + title_raw => loc("More about the requestors"), class => 'ticket-info-requestor' &> +<div id="requestor-accordion"> + +% while ( my $requestor = $people->Next ) { + <h3><a href="#"><& /Elements/ShowUser, User => $requestor &></a></h3> + <div class="details"> + %# Additional information about this user. Empty by default. % $m->callback( requestor => $requestor, %ARGS, CallbackName => 'AboutThisUser' ); +<& ShowRequestorExtraInfo, Requestor => $requestor &> -<span class="label"><&|/l&>Comments about this user</&>:</span><br /> -<b class="value"><% ($requestor->Comments || loc("No comment entered about this user")) %></b><br /> +% if ( $ShowComments ) { +<div class="comments-about-user"> + <span class="label"><&|/l&>Comments about this user</&>:</span> + <span class="value"><% ($requestor->Comments || loc("No comment entered about this user")) %></span> +</div> +% } + +% if ( $ShowTickets ) { +<div class="more-about-requestor-tickets ui-tabs" id="more-about-requestor-tickets-<%$requestor->Id%>"> + <ul> +% my $index = 1; +% for my $status ( @$status_order ) { + <li> +% if ( $status eq $DefaultTicketsTab ) { + <a href="#requestor-<%$requestor->Id%>-ticket-tab-default">\ +% } else { +% my $url = RT->Config->Get('WebPath').'/Helpers/Toggle/ShowRequestor?'. +% $m->comp('/Elements/QueryString', Requestor => $requestor->Id , Status => $status); + <a href="<% $url | n %>" title="requestor-<%$requestor->Id%>-ticket-tab-<% $index++ %>">\ +% } +<% $status_link_text->{$status} %></a> + </li> +% } + </ul> +% $index = 1; +% for my $status (@$status_order) { +% if ( $status eq $DefaultTicketsTab ) { + <div id="requestor-<%$requestor->Id%>-ticket-tab-default"> + <& $TicketTemplate, Requestor => $requestor &> +% } else { + <div id="requestor-<%$requestor->Id%>-ticket-tab-<% $index++ %>" class="ui-tabs-hide"> + <span class="label"><&|/l&>Loading...</&></span> +% } + </div> +% } +</div> +% } -<span class="label"><&|/l, $rows &>This user's [_1] highest priority tickets</&>:</span> -<ul> -%while (my $w=$tickets->Next) { -%my $uri = RT::URI->new( $session{'CurrentUser'} ); -%$uri->FromObject($w); -<li class="value"><& /Elements/ShowLink, URI => $uri &></li> -%} -</ul> +% my $grouplimit = RT->Config->Get('MoreAboutRequestorGroupsLimit'); +% if ( $ShowGroups and defined $grouplimit ) { +<div class="more-about-user-groups"> + <span class="label"> + <&|/l&>Groups this user belongs to</&> + +% if ( $session{CurrentUser}->HasRight( Right => 'AdminUsers', Object => $RT::System ) && +% $session{CurrentUser}->HasRight( Right => 'ShowConfigTab', Object =>$RT::System ) ) { + [<a href=<% RT->Config->Get('WebPath') . '/Admin/Users/Memberships.html?id=' . $requestor->id %> ><&|/l&>Edit</&></a>] +% } + </span> + <span class="value"><& /Elements/ShowMemberships, UserObj => $requestor, Limit => $grouplimit &></span> +</div> +% } -<&|/l&>Groups this user belongs to</&>:<br /> +% if ( $has_right_adminusers ) { + <a class="modify-user" href="<% RT->Config->Get('WebPath')."/Admin/Users/Modify.html?id=".$requestor->id %>">Modify this user</a> +% } -<& /Elements/ShowMemberships, UserObj => $requestor &> +%# end of individual requestor details <div> + </div> +% } +%# end of requestors loop +</div> </&> +<%INIT> +my $show_privileged = RT->Config->Get('ShowMoreAboutPrivilegedUsers'); -% } +my $people = $Ticket->Requestors->UserMembersObj; +$people->LimitToUnprivileged unless $show_privileged; + +my $count = $people->Count; +return unless $count; + +my $has_right_adminusers = $session{'CurrentUser'}->HasRight( + Object => $RT::System, Right => 'AdminUsers' +); +$has_right_adminusers &&= $session{'CurrentUser'}->HasRight( + Object => $RT::System, Right => 'ShowConfigTab' +); + +# Ticket list tabs +my $selected = -1; +$DefaultTicketsTab ||= RT->Config->Get('MoreAboutRequestorTicketList', $session{CurrentUser}) || 'Active'; +my $status_link_text = {Active => loc('Active Tickets'), + Inactive => loc('Inactive Tickets'), + All => loc('All Tickets')}; +my $status_order = [qw/Active Inactive All/]; +$m->callback( CallbackName => 'AddStatus', status_link_text => \$status_link_text, status_order => \$status_order ); + +unless ( $DefaultTicketsTab eq 'None' ) { + for (0 .. (@$status_order - 1)) { + $selected = $_ && last + if $status_order->[$_] eq $DefaultTicketsTab; + } +} + +my $TicketTemplate = "ShowRequestorTickets$DefaultTicketsTab"; +$TicketTemplate = "ShowRequestorTicketsActive" unless $m->comp_exists($TicketTemplate); +</%INIT> <%ARGS> $Ticket=>undef -$DisplayPath => "/Ticket/Display.html" -$conditions => [] +$DefaultTicketsTab => undef +$ShowComments => 1 +$ShowTickets => 1 +$ShowGroups => 1 +$Title => 'More about [_1]' </%ARGS> diff --git a/rt/share/html/Ticket/Elements/ShowSummary b/rt/share/html/Ticket/Elements/ShowSummary index ef5960e01..a1d1610dc 100755 --- a/rt/share/html/Ticket/Elements/ShowSummary +++ b/rt/share/html/Ticket/Elements/ShowSummary @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC %# <sales@bestpractical.com> %# %# (Except where explicitly superseded by other copyright notices) @@ -49,81 +49,58 @@ <tr> <td valign="top" class="boxcontainer"> % $m->callback( %ARGS, CallbackName => 'LeftColumnTop' ); - <&| /Widgets/TitleBox, title => loc('The Basics'), - title_href => RT->Config->Get('WebPath')."/Ticket/Modify.html?id=".$Ticket->Id, + (($can_modify || $can_modify_cf) ? (title_href => RT->Config->Get('WebPath')."/Ticket/Modify.html?id=".$Ticket->Id) : ()), class => 'ticket-info-basics', - &> - <& /Ticket/Elements/ShowBasics, Ticket => $Ticket &> - </&> - -% if ($Ticket->CustomFields->First) { + &><& /Ticket/Elements/ShowBasics, Ticket => $Ticket &></&> <&| /Widgets/TitleBox, title => loc('Custom Fields'), - title_href => RT->Config->Get('WebPath')."/Ticket/Modify.html?id=".$Ticket->Id, + (($can_modify || $can_modify_cf) ? (title_href => RT->Config->Get('WebPath')."/Ticket/Modify.html?id=".$Ticket->Id) : ()), class => 'ticket-info-cfs', - &> - <& /Ticket/Elements/ShowCustomFields, Ticket => $Ticket &> - </&> -% } + hide_empty => 1, + &><& /Ticket/Elements/ShowCustomFields, Ticket => $Ticket &></&> - <&| /Widgets/TitleBox, title => loc('Customers'), - title_href => RT->Config->Get('WebPath')."/Ticket/ModifyCustomers.html?id=".$Ticket->Id, - class => 'ticket-info-customers' - &> - <& /Ticket/Elements/ShowCustomers, Ticket => $Ticket &> - </&> + <&| /Widgets/TitleBox, title => loc('Customers'), + #$can_modify_customers? + ($can_modify ? (title_href => RT->Config->Get('WebPath')."/Ticket/ModifyCustomers.html?id=".$Ticket->Id) : ()), + class => 'ticket-info-customers', + &><& /Ticket/Elements/ShowCustomers, Ticket => $Ticket &></&> <&| /Widgets/TitleBox, title => loc('People'), - title_href => RT->Config->Get('WebPath')."/Ticket/ModifyPeople.html?id=".$Ticket->Id, + (($can_modify || $can_modify_owner) ? (title_href => RT->Config->Get('WebPath')."/Ticket/ModifyPeople.html?id=".$Ticket->Id) : ()), class => 'ticket-info-people', - &> - <& /Ticket/Elements/ShowPeople, Ticket => $Ticket &> - </&> - + &><& /Ticket/Elements/ShowPeople, Ticket => $Ticket &></&> <& /Ticket/Elements/ShowAttachments, Ticket => $Ticket, Attachments => $Attachments &> - <& /Ticket/Elements/ShowRequestor, Ticket => $Ticket &> - % $m->callback( %ARGS, CallbackName => 'LeftColumn' ); - </td> <td valign="top" class="boxcontainer"> - % $m->callback( %ARGS, CallbackName => 'RightColumnTop' ); - % if ( RT->Config->Get('EnableReminders') ) { <&|/Widgets/TitleBox, title => loc("Reminders"), title_href => RT->Config->Get('WebPath')."/Ticket/Reminders.html?id=".$Ticket->Id, class => 'ticket-info-reminders', &> <table><tr><td> - <form action="<%RT->Config->Get('WebPath')%>/Ticket/Display.html" method="post"> + <form action="<%RT->Config->Get('WebPath')%>/Ticket/Display.html" name="UpdateReminders" id="UpdateReminders" method="post"> <& /Ticket/Elements/Reminders, Ticket => $Ticket, ShowCompleted => 0 &> <div align="right"><input type="submit" class="button" value="<&|/l&>Save</&>" /></div> </form> </td></tr></table> </&> % } - <&| /Widgets/TitleBox, title => loc("Dates"), - title_href => RT->Config->Get('WebPath')."/Ticket/ModifyDates.html?id=".$Ticket->Id, + ($can_modify ? (title_href => RT->Config->Get('WebPath')."/Ticket/ModifyDates.html?id=".$Ticket->Id) : ()), class => 'ticket-info-dates', - &> - <& /Ticket/Elements/ShowDates, Ticket => $Ticket &> - </&> - + &><& /Ticket/Elements/ShowDates, Ticket => $Ticket &></&> % my (@extra); % push @extra, titleright_raw => '<a href="'. RT->Config->Get('WebPath'). '/Ticket/Graphs/index.html?id='.$Ticket->id.'">'.loc('Graph').'</a>' unless RT->Config->Get('DisableGraphViz'); +% $m->callback( %ARGS, CallbackName => 'LinksExtra', extra => \@extra ); <&| /Widgets/TitleBox, title => loc('Links'), - title_href => RT->Config->Get('WebPath')."/Ticket/ModifyLinks.html?id=".$Ticket->Id, + ($can_modify ? (title_href => RT->Config->Get('WebPath')."/Ticket/ModifyLinks.html?id=".$Ticket->Id) : ()), class => 'ticket-info-links', @extra, - &> - <& /Elements/ShowLinks, Ticket => $Ticket &> - </&> - + &><& /Elements/ShowLinks, Ticket => $Ticket &></&> % $m->callback( %ARGS, CallbackName => 'RightColumn' ); - </td> </tr> </table> @@ -131,3 +108,10 @@ $Ticket => undef $Attachments => undef </%ARGS> +<%INIT> +my $can_modify = $Ticket->CurrentUserHasRight('ModifyTicket'); +my $can_modify_cf = $Ticket->CurrentUserHasRight('ModifyCustomField'); +my $can_modify_owner = $Ticket->CurrentUserHasRight('OwnTicket') + || $Ticket->CurrentUserHasRight('TakeTicket') + || $Ticket->CurrentUserHasRight('StealTicket'); +</%INIT> diff --git a/rt/share/html/Ticket/Elements/ShowTime b/rt/share/html/Ticket/Elements/ShowTime index 4ccc7908b..fc678c2d5 100644 --- a/rt/share/html/Ticket/Elements/ShowTime +++ b/rt/share/html/Ticket/Elements/ShowTime @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC %# <sales@bestpractical.com> %# %# (Except where explicitly superseded by other copyright notices) diff --git a/rt/share/html/Ticket/Elements/ShowTransaction b/rt/share/html/Ticket/Elements/ShowTransaction index e76e00495..2e0acd39e 100755 --- a/rt/share/html/Ticket/Elements/ShowTransaction +++ b/rt/share/html/Ticket/Elements/ShowTransaction @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC %# <sales@bestpractical.com> %# %# (Except where explicitly superseded by other copyright notices) @@ -47,37 +47,33 @@ %# END BPS TAGGED BLOCK }}} <div class="ticket-transaction <% $type_class %> <%$type%> <% $RowNum % 2 ? 'odd' : 'even' %>"> % $m->callback( titlebar_cmd => \$titlebar_commands, Transaction => $Transaction, %ARGS, CallbackName => 'ModifyDisplay' ); - <div class="ticket-transaction"> % $m->callback( titlebar_cmd => \$titlebar_commands, Transaction => $Transaction, %ARGS, CallbackName => 'ModifyCommand' ); <div class="metadata"> <span class="type"> - <a name="txn-<% $Transaction->Id %>" href="<% $DisplayPath %>#txn-<% $Transaction->Id %>">#</a> + <a name="txn-<% $Transaction->Id %>" href="<% $DisplayPath %>#txn-<% $Transaction->Id %>">#</a>\ <% $LastTransaction ? '<a id="lasttrans" name="lasttrans"></a>' : ''|n %> </span> % $m->callback( Transaction => $Transaction, %ARGS, CallbackName => 'AfterAnchor' ); <span class="date"><% $transdate|n %></span> % my $desc = $Transaction->BriefDescription; % $m->callback( text => \$desc, Transaction => $Transaction, %ARGS, CallbackName => 'ModifyDisplay' ); - <span class="description"> - <& /Elements/ShowUser, User => $Transaction->CreatorObj &> - <% $TicketString %> <% $desc %> + <span class="description">\ +<& /Elements/ShowUser, User => $Transaction->CreatorObj &> - <% $TicketString %> <% $desc %>\ % $m->callback( Transaction => $Transaction, %ARGS, CallbackName => 'AfterDescription' ); - </span> +</span> % $m->callback( TimeTaken => \$TimeTaken, Transaction => $Transaction, %ARGS, CallbackName => 'ModifyTimeTaken' ); - <span class="time-taken"><% $TimeTaken %></span> + <span class="time-taken"><% $TimeTaken %></span>\ <span class="actions<% $titlebar_commands ? '': ' hidden'%>"><% $titlebar_commands |n %></span> </div> - <div class="content"> -% if ( $Transaction->CustomFieldValues->Count ) { +% if ( $type_class eq 'message' ) { <& /Elements/ShowCustomFields, Object => $Transaction &> % } % $m->comp('ShowTransactionAttachments', %ARGS, Parent => 0) unless ($Collapsed ||!$ShowBody); </div> - </div> </div> - <%ARGS> $Ticket => undef $Transaction => undef @@ -100,7 +96,6 @@ $WarnUnsigned => undef <%ONCE> my %class = ( - Create => 'message', Correspond => 'message', Comment => 'message', @@ -124,6 +119,9 @@ $transdate =~ s/\s/ /g; my ($type, $field) = ($Transaction->Type, $Transaction->Field || ''); my $type_class = $class{ $type }; +if ( $type eq 'Create' && $Transaction->ObjectType eq 'RT::Ticket' ) { + $type_class = 'message'; +} unless ( $type_class ) { if ( $field eq 'Owner' ) { @@ -194,28 +192,35 @@ else { my $can_modify = $ticket->CurrentUserHasRight('ModifyTicket'); if ( $can_modify || $ticket->CurrentUserHasRight('ReplyToTicket') ) { $titlebar_commands .= - "[<a href=\"".$UpdatePath + "[<a href=\"" . $UpdatePath . "?id=" . $Transaction->Ticket . "&QuoteTransaction=" . $Transaction->Id - . "&Action=Respond\">" + . "&Action=Respond\" " + . "class=\"reply-link\"" + . ">" . loc('Reply') . "</a>] "; } if ( $can_modify || $ticket->CurrentUserHasRight('CommentOnTicket') ) { $titlebar_commands .= - "[<a href=\"".$UpdatePath."?id=" - . $Transaction->Ticket - . "&QuoteTransaction=" - . $Transaction->Id - . "&Action=Comment\">" - . loc('Comment') . "</a>]"; + "[<a href=\"" . $UpdatePath + . "?id=" . $Transaction->Ticket + . "&QuoteTransaction=" . $Transaction->Id + . "&Action=Comment\" " + . "class=\"comment-link\"" + . ">" + . loc('Comment') + . "</a>]"; } if ( $ticket->CurrentUserHasRight('ForwardMessage') ) { $titlebar_commands .= - "[<a href=\"". $ForwardPath - . "?id=". $Transaction->Ticket - . "&QuoteTransaction=". $Transaction->Id - . "\">". loc('Forward') . "</a>]"; + "[<a href=\"" . $ForwardPath + . "?id=" . $Transaction->Ticket + . "&QuoteTransaction=" . $Transaction->Id ."\" " + . "class=\"forward-link\"" + . ">" + . loc('Forward') + . "</a>]"; } if ( $can_modify && RT->Config->Get('GnuPG')->{'Enable'} @@ -223,9 +228,12 @@ else { && $ticket->CurrentUserHasRight('ForwardMessage') ) { $titlebar_commands .= - "[<a href=\"". $EncryptionPath - . "?id=". $Transaction->Id - . "\">". loc('Encrypt/Decrypt') . "</a>]"; + "[<a href=\"" . $EncryptionPath + . "?id=" . $Transaction->Id ."\" " + . "class=\"gpg-link\"" + . ">" + . loc('Encrypt/Decrypt') + . "</a>]"; } } } diff --git a/rt/share/html/Ticket/Elements/ShowTransactionAttachments b/rt/share/html/Ticket/Elements/ShowTransactionAttachments index 625e124f8..877201f55 100644 --- a/rt/share/html/Ticket/Elements/ShowTransactionAttachments +++ b/rt/share/html/Ticket/Elements/ShowTransactionAttachments @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC %# <sales@bestpractical.com> %# %# (Except where explicitly superseded by other copyright notices) @@ -60,21 +60,19 @@ foreach my $message ( grep $_->__Value('Parent') == $Parent, @$Attachments ) { ); my $size = $message->ContentLength; + my $name = defined $message->Filename && length $message->Filename ? $message->Filename : ''; if ( $size ) { </%PERL> <div class="downloadattachment"> -<a href="<% $AttachPath %>/<% $Transaction->Id %>/<% $message->Id %>/<% ($message->Filename ||'')| u%>"><&|/l&>Download</&> <% $message->Filename || loc('(untitled)') %></a> -% if ( $DownloadableHeaders && !$message->Filename && $message->ContentType =~ /text/ ) { +<a href="<% $AttachPath %>/<% $Transaction->Id %>/<% $message->Id %>/<% $name | u%>"><&|/l&>Download</&> <% length $name ? $name : loc('(untitled)') %></a>\ +% if ( $DownloadableHeaders && ! length $name && $message->ContentType =~ /text/ ) { / <a href="<% $AttachPath %>/WithHeaders/<% $message->Id %>"><% loc('with headers') %></a> % } - % $m->callback(CallbackName => 'AfterDownloadLinks', ARGSRef => \%ARGS, Ticket => $Ticket, Transaction => $Transaction, Attachment => $message); - <br /> <span class="downloadcontenttype"><% $message->ContentType %> <% $size_to_str->( $size ) %></span> </div> % } - %# If there is sub-messages, open a dedicated div % if ( scalar ( grep $_->__Value('Parent') == $message->id, @$Attachments ) ) { <div class="messageattachments"> @@ -125,6 +123,8 @@ elsif (!$ShowHeaders) { push @DisplayHeaders, 'RT-Send-Bcc' if RT->Config->Get('ShowBccHeader'); } +$m->callback(CallbackName => 'MassageDisplayHeaders', DisplayHeaders => \@DisplayHeaders, Transaction => $Transaction); + my $size_to_str = sub { my $size = shift; # show a download link @@ -142,11 +142,13 @@ my $size_to_str = sub { my $render_attachment = sub { my $message = shift; + my $name = defined $message->Filename && length $message->Filename ? $message->Filename : ''; # if it has a content-disposition: attachment, don't show inline my $disposition = $message->GetHeader('Content-Disposition'); - if ( $disposition && $disposition =~ /attachment/i && $disposition !~ /^\s*inline/ ) { - $disposition = 'attachemnt'; + + if ( $disposition && $disposition =~ /^\s*attachment/i ) { + $disposition = 'attachment'; } else { $disposition = 'inline'; } @@ -154,16 +156,16 @@ my $render_attachment = sub { # If it's text if ( $message->ContentType =~ m{^(text|message)}i ) { my $max_size = RT->Config->Get( 'MaxInlineBody', $session{'CurrentUser'} ); - if ( $message->Filename && RT->Config->Get('SuppressInlineTextFiles', $session{'CurrentUser'} ) ) { - $m->out('<p>'. loc( 'Text file is not shown because it is disabled in preferences.' ) .'</p>'); + if ( $disposition ne 'inline' ) { + $m->out('<p>'. loc( 'Message body is not shown because sender requested not to inline it.' ) .'</p>'); return; } - elsif ( $max_size && $message->ContentLength > $max_size ) { - $m->out('<p>'. loc( 'Message body not shown because it is too large.' ) .'</p>'); + elsif ( length $name && RT->Config->Get('SuppressInlineTextFiles', $session{'CurrentUser'} ) ) { + $m->out('<p>'. loc( 'Text file is not shown because it is disabled in preferences.' ) .'</p>'); return; } - elsif ( $disposition ne 'inline' ) { - $m->out('<p>'. loc( 'Message body is not shown because sender requested not to inline it.' ) .'</p>'); + elsif ( $max_size && $message->ContentLength > $max_size ) { + $m->out('<p>'. loc( 'Message body is not shown because it is too large.' ) .'</p>'); return; } @@ -185,45 +187,63 @@ my $render_attachment = sub { && ( $message->ContentType !~ m{^text/(?:html|enriched)$} ) ) ) - ) - { + ) { my $content; - if ( $AttachmentContent->{ $message->id } ) { - $content = $AttachmentContent->{ $message->id }->Content; + # If we've cached the content, use it from there + if (my $x = $AttachmentContent->{ $Transaction->id }->{$message->id}) { + $content = $x->Content; } else { $content = $message->Content; } + my $content_type = lc $message->ContentType; + $RT::Logger->debug( + "Rendering attachment #". $message->id + ." of '$content_type' type" + ); + # if it's a text/html clean the body and show it - if ( $message->ContentType =~ m{^text/(?:html|enriched)$}i ) { + if ( $content_type eq 'text/html' ) { + $content = $m->comp( '/Elements/ScrubHTML', Content => $content ); + + $m->comp( + '/Elements/MakeClicky', + content => \$content, + html => 1, + ticket => $Ticket, + ); + + require HTML::Quoted; + $content = HTML::Quoted->extract($content) unless length $name; + + $m->comp( + 'ShowMessageStanza', + Message => $content, + Transaction => $Transaction, + ContentType => 'text/html', + ); + } + + elsif ( $content_type eq 'text/enriched' ) { $content = $m->comp( '/Elements/ScrubHTML', Content => $content ); - if ( $message->ContentType eq 'text/html' ) { - $m->comp('/Elements/MakeClicky', - content => \$content, html => 1, - ticket => $Ticket ); - } $m->out( $content ); } # if it's a text/plain show the body elsif ( $message->ContentType =~ m{^(text|message)}i ) { - #don't want to use this even if it is installed, its - #segfaulting on weird characters and silently truncating the - #ticket history output - #see: - # r44838@pinglin: jesse | 2006-11-14 15:53:18 -0500 - # * Move Text::Quoted back to being a run-time require. So that it's possible to turn off the feature if it causes your perl to segfault. (Text::Tabs is...not robust in the face of perl bugs) - #eval { require Text::Quoted; $content = Text::Quoted::extract($content); }; - #if ($@) { $RT::Logger->warning( "Text::Quoted failed: $@" ) } + unless ( length $name ) { + eval { require Text::Quoted; $content = Text::Quoted::extract($content); }; + if ($@) { $RT::Logger->warning( "Text::Quoted failed: $@" ) } + } $m->comp( 'ShowMessageStanza', - Depth => 0, Message => $content, - Transaction => $Transaction + Transaction => $Transaction, + ContentType => 'text/plain', ); } } @@ -236,7 +256,7 @@ my $render_attachment = sub { return; } - my $filename = $message->Filename || loc('(untitled)'); + my $filename = length $name ? $name : loc('(untitled)'); $m->out('<img' . ' alt="' . $filename diff --git a/rt/share/html/Ticket/Elements/ShowUpdateStatus b/rt/share/html/Ticket/Elements/ShowUpdateStatus index 16406bfbc..07a57e139 100644 --- a/rt/share/html/Ticket/Elements/ShowUpdateStatus +++ b/rt/share/html/Ticket/Elements/ShowUpdateStatus @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC %# <sales@bestpractical.com> %# %# (Except where explicitly superseded by other copyright notices) @@ -47,7 +47,7 @@ %# END BPS TAGGED BLOCK }}} <div class="unread-messages"> <&| /Widgets/TitleBox, title => loc('New messages'), title_href => "#txn-". $txn->id &> -<&|/l, &>There are unread messages on this ticket.</&> +<&|/l&>There are unread messages on this ticket.</&> <&|/l, RT->Config->Get('WebPath') ."/Ticket/Display.html?id=". $Ticket->id. "#txn-".$txn->id, RT->Config->Get('WebPath') ."/Ticket/Display.html?id=". $Ticket->id ."&MarkAsSeen=1&Anchor=txn-" . $txn->id diff --git a/rt/share/html/Ticket/Elements/ShowUserEntry b/rt/share/html/Ticket/Elements/ShowUserEntry index 6e78a8826..fe3d35f9e 100644 --- a/rt/share/html/Ticket/Elements/ShowUserEntry +++ b/rt/share/html/Ticket/Elements/ShowUserEntry @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC %# <sales@bestpractical.com> %# %# (Except where explicitly superseded by other copyright notices) diff --git a/rt/share/html/Ticket/Elements/UpdateCc b/rt/share/html/Ticket/Elements/UpdateCc index f30fdadd1..392ee86b1 100644 --- a/rt/share/html/Ticket/Elements/UpdateCc +++ b/rt/share/html/Ticket/Elements/UpdateCc @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC %# <sales@bestpractical.com> %# %# (Except where explicitly superseded by other copyright notices) @@ -45,7 +45,9 @@ %# those contributions and any derivatives thereof. %# %# END BPS TAGGED BLOCK }}} -<tr><td class="label"><&|/l&>One-time Cc</&>:</td><td><& /Elements/EmailInput, Name => 'UpdateCc', Size => '60', Default => $ARGS{UpdateCc} &> +% $m->callback(CallbackName => 'BeforeCc', ARGSRef => \%ARGS, Ticket => $TicketObj, one_time_Ccs => \@one_time_Ccs, txn_addresses => \%txn_addresses); + +<tr><td class="label"><&|/l&>One-time Cc</&>:</td><td><& /Elements/EmailInput, Name => 'UpdateCc', Size => undef, Default => $ARGS{UpdateCc} &> <input type="hidden" id="UpdateIgnoreAddressCheckboxes" name="UpdateIgnoreAddressCheckboxes" value="0"> <br /> @@ -53,17 +55,18 @@ <i class="label">(<&|/l&>check to add</&>)</i> %} %foreach my $addr ( @one_time_Ccs ) { -<input -id="UpdateCc-<%$addr%>" -name="UpdateCc-<%$addr%>" - type="checkbox" +<input + id="UpdateCc-<%$addr%>" + name="UpdateCc-<%$addr%>" + class="onetime onetimecc" + type="checkbox" % my $clean_addr = $txn_addresses{$addr}->format; % $clean_addr =~ s/'/\\'/g; - onClick="checkboxToInput('UpdateCc', 'UpdateCc-<%$addr%>','<%$clean_addr%>' ); $(UpdateIgnoreAddressCheckboxes).value=1" + onClick="checkboxToInput('UpdateCc', 'UpdateCc-<%$addr%>','<%$clean_addr%>' );" <% $ARGS{'UpdateCc-'.$addr} ? 'checked="checked"' : ''%> > <& /Elements/ShowUser, Address => $txn_addresses{$addr}&> %} </td></tr> -<tr><td class="label"><&|/l&>One-time Bcc</&>:</td><td><& /Elements/EmailInput, Name => 'UpdateBcc', Size => '60', Default => $ARGS{UpdateBcc} &><br /> +<tr><td class="label"><&|/l&>One-time Bcc</&>:</td><td><& /Elements/EmailInput, Name => 'UpdateBcc', Size => undef, Default => $ARGS{UpdateBcc} &><br /> %if (scalar @one_time_Ccs) { <i class="label">(<&|/l&>check to add</&>)</i> %} @@ -71,10 +74,11 @@ name="UpdateCc-<%$addr%>" <input id="UpdateBcc-<%$addr%>" name="UpdateBcc-<%$addr%>" - type="checkbox" + class="onetime onetimebcc" + type="checkbox" % my $clean_addr = $txn_addresses{$addr}->format; % $clean_addr =~ s/'/\\'/g; - onClick="checkboxToInput('UpdateBcc', 'UpdateBcc-<%$addr%>','<%$clean_addr%>' ); $(UpdateIgnoreAddressCheckboxes).value=1" + onClick="checkboxToInput('UpdateBcc', 'UpdateBcc-<%$addr%>','<%$clean_addr%>' );" <% $ARGS{'UpdateBcc-'.$addr} ? 'checked="checked"' : ''%>> <& /Elements/ShowUser, Address => $txn_addresses{$addr}&> %} diff --git a/rt/share/html/Ticket/Forward.html b/rt/share/html/Ticket/Forward.html index 87c2d0a3c..8aa75c7a8 100644 --- a/rt/share/html/Ticket/Forward.html +++ b/rt/share/html/Ticket/Forward.html @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC %# <sales@bestpractical.com> %# %# (Except where explicitly superseded by other copyright notices) @@ -46,32 +46,31 @@ %# %# END BPS TAGGED BLOCK }}} <& /Elements/Header, Title => $Title &> -<& /Ticket/Elements/Tabs, - Ticket => $TicketObj, - Title => $Title, -&> +<& /Elements/Tabs &> % $m->callback(CallbackName => 'BeforeActionList', Actions => \@results, ARGSRef => \%ARGS, Ticket => $TicketObj); <& /Elements/ListActions, actions => \@results &> -<form action="Forward.html" name="ForwardMessage" method="post"> +<form action="Forward.html" id="ForwardMessage" name="ForwardMessage" method="post"> % $m->callback( CallbackName => 'FormStart', ARGSRef => \%ARGS ); <input type="hidden" class="hidden" name="id" value="<% $id %>" /><br /> -<input type="hidden" class="hidden" name="QuoteTransaction" value="<% $ARGS{'QuoteTransaction'} %>" /> +<input type="hidden" class="hidden" name="QuoteTransaction" value="<% $ARGS{'QuoteTransaction'} || '' %>" /> <table border="0"> +<tr><td align="right"><&|/l&>From</&>:</td> +<td><% $from %></td></tr> <tr><td align="right"><&|/l&>Subject</&>:</td> -<td><% $TicketObj->Subject %></td></tr> +<td><% $subject %></td></tr> <tr><td align="right"><&|/l&>To</&>:</td> -<td><input name="To" size="60" value="<% $ARGS{'To'} %>" /></td></tr> +<td><input name="To" size="60" value="<% $ARGS{'To'} || '' %>" /></td></tr> <tr><td align="right"><&|/l&>Cc</&>:</td> -<td><input name="Cc" size="60" value="<% $ARGS{'Cc'} %>" /></td></tr> +<td><input name="Cc" size="60" value="<% $ARGS{'Cc'} || '' %>" /></td></tr> -<tr><td align="right"><&|/l&>BCc</&>:</td> -<td><input name="Bcc" size="60" value="<% $ARGS{'Bcc'} %>" /></td></tr> +<tr><td align="right"><&|/l&>Bcc</&>:</td> +<td><input name="Bcc" size="60" value="<% $ARGS{'Bcc'} || '' %>" /></td></tr> </table> @@ -113,6 +112,13 @@ my $Title = $txn ? loc('Forward transaction #[_1]', $txn->id) : loc('Forward ticket #[_1]', $TicketObj->id); +my $from = RT::Interface::Email::GetForwardFrom( + $txn ? ( Transaction => $txn ) : ( Ticket => $TicketObj ) ); + +my $subject = $TicketObj->Subject; +$subject = RT::Interface::Email::AddSubjectTag( $subject, $TicketObj ) + unless RT->Config->Get('ForwardFromUser'); + </%INIT> <%ARGS> diff --git a/rt/share/html/Ticket/GnuPG.html b/rt/share/html/Ticket/GnuPG.html index 5270d54ed..6269907ca 100644 --- a/rt/share/html/Ticket/GnuPG.html +++ b/rt/share/html/Ticket/GnuPG.html @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC %# <sales@bestpractical.com> %# %# (Except where explicitly superseded by other copyright notices) @@ -46,11 +46,7 @@ %# %# END BPS TAGGED BLOCK }}} <& /Elements/Header, Title => $title &> -<& /Ticket/Elements/Tabs, - Ticket => $txn->TicketObj, - current_tab => 'Ticket/Encrypt.html?id='. $id, - Title => $title, -&> +<& /Elements/Tabs &> % $m->callback( CallbackName => 'BeforeActionList', %ARGS, Actions => \@results, ARGSRef => \%ARGS ); <& /Elements/ListActions, actions => \@results &> diff --git a/rt/share/html/Ticket/Graphs/Elements/EditGraphProperties b/rt/share/html/Ticket/Graphs/Elements/EditGraphProperties index beb67a299..e68aaed55 100644 --- a/rt/share/html/Ticket/Graphs/Elements/EditGraphProperties +++ b/rt/share/html/Ticket/Graphs/Elements/EditGraphProperties @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC %# <sales@bestpractical.com> %# %# (Except where explicitly superseded by other copyright notices) diff --git a/rt/share/html/Ticket/Graphs/Elements/ShowGraph b/rt/share/html/Ticket/Graphs/Elements/ShowGraph index 1d905c74a..967a5e4aa 100644 --- a/rt/share/html/Ticket/Graphs/Elements/ShowGraph +++ b/rt/share/html/Ticket/Graphs/Elements/ShowGraph @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC %# <sales@bestpractical.com> %# %# (Except where explicitly superseded by other copyright notices) diff --git a/rt/share/html/Ticket/Graphs/Elements/ShowLegends b/rt/share/html/Ticket/Graphs/Elements/ShowLegends index d0d109847..4c63d4b38 100644 --- a/rt/share/html/Ticket/Graphs/Elements/ShowLegends +++ b/rt/share/html/Ticket/Graphs/Elements/ShowLegends @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC %# <sales@bestpractical.com> %# %# (Except where explicitly superseded by other copyright notices) diff --git a/rt/share/html/Ticket/Graphs/dhandler b/rt/share/html/Ticket/Graphs/dhandler index a1dfebec7..ba41445d0 100644 --- a/rt/share/html/Ticket/Graphs/dhandler +++ b/rt/share/html/Ticket/Graphs/dhandler @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC %# <sales@bestpractical.com> %# %# (Except where explicitly superseded by other copyright notices) diff --git a/rt/share/html/Ticket/Graphs/index.html b/rt/share/html/Ticket/Graphs/index.html index ca7bde2cc..80ec9f347 100644 --- a/rt/share/html/Ticket/Graphs/index.html +++ b/rt/share/html/Ticket/Graphs/index.html @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC %# <sales@bestpractical.com> %# %# (Except where explicitly superseded by other copyright notices) @@ -46,11 +46,7 @@ %# %# END BPS TAGGED BLOCK }}} <& /Elements/Header, Title => $title &> -<& /Ticket/Elements/Tabs, - Ticket => $ticket, - Title => $title, - current_tab => "Ticket/ModifyLinks.html?id=$id", -&> +<& /Elements/Tabs &> <& /Elements/ListActions, actions => \@results &> diff --git a/rt/share/html/Ticket/History.html b/rt/share/html/Ticket/History.html index e0e0462da..afc174fd6 100755 --- a/rt/share/html/Ticket/History.html +++ b/rt/share/html/Ticket/History.html @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC %# <sales@bestpractical.com> %# %# (Except where explicitly superseded by other copyright notices) @@ -46,9 +46,7 @@ %# %# END BPS TAGGED BLOCK }}} <& /Elements/Header, Title => loc("Ticket History # [_1] [_2]", $Ticket->Id, $Ticket->Subject) &> -<& /Ticket/Elements/Tabs, - Ticket => $Ticket, current_tab => 'Ticket/History.html?id='.$Ticket->id, - Title => loc("Ticket History # [_1] [_2]", $Ticket->Id, $Ticket->Subject) &> +<& /Elements/Tabs &> % $m->callback( %ARGS, Ticket => $Ticket, CallbackName => 'BeforeActionList' ); @@ -63,7 +61,7 @@ AttachmentContent => $attachment_content &> -% $m->callback( %ARGS, CallbackName => 'AfterShowHistory', Ticket => $Ticket, current_tab => 'Ticket/History.html?id=' . $Ticket->id ); +% $m->callback( %ARGS, CallbackName => 'AfterShowHistory', Ticket => $Ticket ); <%ARGS> $id => undef diff --git a/rt/share/html/Ticket/Modify.html b/rt/share/html/Ticket/Modify.html index 9f1a95932..372a84e23 100755 --- a/rt/share/html/Ticket/Modify.html +++ b/rt/share/html/Ticket/Modify.html @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC %# <sales@bestpractical.com> %# %# (Except where explicitly superseded by other copyright notices) @@ -46,14 +46,12 @@ %# %# END BPS TAGGED BLOCK }}} <& /Elements/Header, Title => loc('Modify ticket #[_1]', $TicketObj->Id) &> -<& /Ticket/Elements/Tabs, - Ticket => $TicketObj, current_subtab => "Ticket/Modify.html?id=".$TicketObj->Id, - Title => loc('Modify ticket #[_1]', $TicketObj->Id) &> +<& /Elements/Tabs &> % $m->callback(CallbackName => 'BeforeActionList', Actions => \@results, ARGSRef => \%ARGS, Ticket => $TicketObj); <& /Elements/ListActions, actions => \@results &> -<form method="post" action="Modify.html" enctype="multipart/form-data"> +<form method="post" action="Modify.html" enctype="multipart/form-data" name="TicketModify" id="TicketModify"> % $m->callback( CallbackName => 'FormStart', ARGSRef => \%ARGS ); <input type="hidden" class="hidden" name="id" value="<% $TicketObj->Id %>" /> @@ -61,6 +59,7 @@ <& Elements/EditBasics, TicketObj => $TicketObj &> <& Elements/EditCustomFields, TicketObj => $TicketObj, DefaultsFromTopArguments => 0 &> </&> +% $m->callback( CallbackName => 'AfterBasics', Ticket => $TicketObj ); <& /Elements/Submit, Name => 'SubmitTicket', Label => loc('Save Changes'), Caption => loc("If you've updated anything above, be sure to"), color => "#993333" &> </form> diff --git a/rt/share/html/Ticket/ModifyAll.html b/rt/share/html/Ticket/ModifyAll.html index cd9bb3891..4ed393451 100755 --- a/rt/share/html/Ticket/ModifyAll.html +++ b/rt/share/html/Ticket/ModifyAll.html @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC %# <sales@bestpractical.com> %# %# (Except where explicitly superseded by other copyright notices) @@ -46,15 +46,12 @@ %# %# END BPS TAGGED BLOCK }}} <& /Elements/Header, Title => loc("Ticket #[_1] Jumbo update: [_2]", $Ticket->Id, $Ticket->Subject) &> -<& /Ticket/Elements/Tabs, - Ticket => $Ticket, - current_tab => "Ticket/ModifyAll.html?id=".$Ticket->Id, - Title => loc("Ticket #[_1] Jumbo update: [_2]", $Ticket->Id, $Ticket->Subject) &> +<& /Elements/Tabs &> % $m->callback(CallbackName => 'BeforeActionList', Actions => \@results, ARGSRef => \%ARGS, Ticket => $Ticket); <& /Elements/ListActions, actions => \@results &> -<form method="post" action="ModifyAll.html" enctype="multipart/form-data"> +<form method="post" action="ModifyAll.html" name="TicketModifyAll" enctype="multipart/form-data"> % $m->callback( CallbackName => 'FormStart', ARGSRef => \%ARGS ); <input type="hidden" class="hidden" name="id" value="<%$Ticket->Id%>" /> @@ -63,6 +60,7 @@ <& Elements/EditCustomFields, TicketObj => $Ticket &> </&> +% $m->callback(CallbackName => 'AfterBasics', Ticket => $Ticket); <br /> <&| /Widgets/TitleBox, title => loc('Dates'), class=>'ticket-info-dates'&> @@ -106,40 +104,15 @@ % $m->callback( %ARGS, CallbackName => 'AfterSubject' ); </td> </tr> -% if (my $TxnCFs = $Ticket->TransactionCustomFields) { -% while (my $CF = $TxnCFs->Next()) { -<tr> -<td class="label"><% loc($CF->Name) %>:</td> -<td class="entry"><& /Elements/EditCustomField, - CustomField => $CF, - NamePrefix => "Object-RT::Transaction--CustomField-" - &><em><% $CF->FriendlyType %></em> -</td></tr> -% } # end if while -% } # end of if -% if (exists $session{'Attachments'}) { -<tr><td><&|/l&>Attached file</&>:</td> -<td> -<&|/l&>Check box to delete</&><br /> -% foreach my $attach_name (keys %{$session{'Attachments'}}) { -<input type="checkbox" class="checkbox" name="DeleteAttach-<%$attach_name%>" value="1" /><%$attach_name%><br /> -% } # end of foreach -</td> -</tr> -% } # end of if - <tr> - <td class="label"><&|/l&>Attach</&>:</td> - <td class="entry"><input name="Attach" type="file" /> - <input type="submit" class="button" name="AddMoreAttach" value="<&|/l&>Add More Files</&>" /> - <input type="hidden" class="hidden" name="UpdateAttach" value="1" /> -% $m->callback( %ARGS, CallbackName => 'AfterAttach' ); - </td> - </tr> + <tr><td colspan="2"><& /Ticket/Elements/EditTransactionCustomFields, %ARGS, TicketObj => $Ticket &></td></tr> + +<& /Ticket/Elements/AddAttachments, %ARGS, TicketObj => $Ticket &> + <tr> <td class="labeltop"><&|/l&>Content</&>:</td> <td class="entry"> -% if (defined $ARGS{UpdateContent} && length($ARGS{UpdateContent})) { +% if (defined $ARGS{UpdateContent} && length($ARGS{UpdateContent} && !grep { /Message recorded/ } @results )) { <& /Elements/MessageBox, Name=>"UpdateContent", Default=>$ARGS{UpdateContent}, IncludeSignature => 0 &> % } else { <& /Elements/MessageBox, Name=>"UpdateContent", QuoteTransaction=>$ARGS{QuoteTransaction} &> @@ -179,17 +152,16 @@ $CanRespond = 1 if ( $Ticket->CurrentUserHasRight('ReplyToTicket') or $CanComment = 1 if ( $Ticket->CurrentUserHasRight('CommentOnTicket') or $Ticket->CurrentUserHasRight('ModifyTicket') ); -# {{{ deal with deleting uploaded attachments +# deal with deleting uploaded attachments foreach my $key (keys %ARGS) { if ($key =~ m/^DeleteAttach-(.+)$/) { delete $session{'Attachments'}{$1}; } $session{'Attachments'} = { %{$session{'Attachments'} || {}} }; } -# }}} -# {{{ store the uploaded attachment in session -if ($ARGS{'Attach'}) { # attachment? +# store the uploaded attachment in session +if ( defined $ARGS{'Attach'} && length $ARGS{'Attach'} ) { # attachment? my $attachment = MakeMIMEEntity( AttachmentFieldName => 'Attach' ); @@ -200,13 +172,11 @@ if ($ARGS{'Attach'}) { # attachment? $file_path => $attachment, }; } -# }}} # delete temporary storage entry to make WebUI clean unless (keys %{$session{'Attachments'}} and $ARGS{'UpdateAttach'}) { delete $session{'Attachments'}; } -# }}} $m->callback( TicketObj => $Ticket, ARGSRef => \%ARGS ); @@ -218,7 +188,12 @@ unless ($OnlySearchForPeople or $OnlySearchForGroup or $ARGS{'AddMoreAttach'} ) my @owners =@{$ARGS{'Owner'}}; delete $ARGS{'Owner'}; foreach my $owner(@owners){ - $ARGS{'Owner'} = $owner unless ($Ticket->OwnerObj->id == $owner); + if (defined($owner) && $owner =~ /\D/) { + $ARGS{'Owner'} = $owner unless ($Ticket->OwnerObj->Name eq $owner); + } + elsif (length $owner) { + $ARGS{'Owner'} = $owner unless ($Ticket->OwnerObj->id == $owner); + } } } diff --git a/rt/share/html/Ticket/ModifyDates.html b/rt/share/html/Ticket/ModifyDates.html index 461283a9c..c85d2f425 100755 --- a/rt/share/html/Ticket/ModifyDates.html +++ b/rt/share/html/Ticket/ModifyDates.html @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC %# <sales@bestpractical.com> %# %# (Except where explicitly superseded by other copyright notices) @@ -46,10 +46,7 @@ %# %# END BPS TAGGED BLOCK }}} <& /Elements/Header, Title => loc('Modify dates for #[_1]', $TicketObj->Id) &> -<& /Ticket/Elements/Tabs, - Ticket => $TicketObj, - current_tab => "Ticket/ModifyDates.html?id=".$TicketObj->Id, - Title => loc('Modify dates for #[_1]', $TicketObj->Id) &> +<& /Elements/Tabs &> % $m->callback(CallbackName => 'BeforeActionList', Actions => \@results, ARGSRef => \%ARGS, Ticket => $TicketObj); <& /Elements/ListActions, actions => \@results &> diff --git a/rt/share/html/Ticket/ModifyLinks.html b/rt/share/html/Ticket/ModifyLinks.html index 09a7a4687..28942e060 100755 --- a/rt/share/html/Ticket/ModifyLinks.html +++ b/rt/share/html/Ticket/ModifyLinks.html @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC %# <sales@bestpractical.com> %# %# (Except where explicitly superseded by other copyright notices) @@ -46,10 +46,7 @@ %# %# END BPS TAGGED BLOCK }}} <& /Elements/Header, Title => loc("Link ticket #[_1]", $Ticket->Id) &> -<& /Ticket/Elements/Tabs, - Ticket => $Ticket, - current_tab => "Ticket/ModifyLinks.html?id=".$Ticket->Id, - Title => loc("Link ticket #[_1]", $Ticket->Id) &> +<& /Elements/Tabs &> % $m->callback(CallbackName => 'BeforeActionList', Actions => \@results, ARGSRef => \%ARGS, Ticket => $Ticket); <& /Elements/ListActions, actions => \@results &> diff --git a/rt/share/html/Ticket/ModifyPeople.html b/rt/share/html/Ticket/ModifyPeople.html index 7ccd875ff..56db2bb0c 100755 --- a/rt/share/html/Ticket/ModifyPeople.html +++ b/rt/share/html/Ticket/ModifyPeople.html @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC %# <sales@bestpractical.com> %# %# (Except where explicitly superseded by other copyright notices) @@ -46,10 +46,7 @@ %# %# END BPS TAGGED BLOCK }}} <& /Elements/Header, Title => loc('Modify people related to ticket #[_1]', $Ticket->id) &> -<& /Ticket/Elements/Tabs, - Ticket => $Ticket, - current_tab => "Ticket/ModifyPeople.html?id=".$Ticket->Id, - Title => loc('Modify people related to ticket #[_1]', $Ticket->id) &> +<& /Elements/Tabs &> % $m->callback(CallbackName => 'BeforeActionList', Actions => \@results, ARGSRef => \%ARGS, Ticket => $Ticket); <& /Elements/ListActions, actions => \@results &> @@ -60,6 +57,22 @@ <&| /Widgets/TitleBox, title => loc('Modify people related to ticket #[_1]', $Ticket->Id), width => "100%", color=> "#333399", class=>'ticket-info-people' &> <& Elements/EditPeople, Ticket => $Ticket, UserField => $UserField, UserString => $UserString, UserOp => $UserOp, GroupString => $GroupString, GroupOp => $GroupOp, GroupField => $GroupField &> </&> +<&| /Widgets/TitleBox, title => loc("Modify who receives mail for ticket #[_1]", $Ticket->Id), width => "100%", color=> "#333399", class=>'ticket-info-squelch' &> +<p> + The checked users may receive email related to this ticket depending on the + action taken. Uncheck users to stop sending email to them about this ticket. +</p> + +<ul> +% for my $addr (sort keys %recips) { + <li> + <input type="hidden" name="autorecipient" value="<% $addr %>"> + <input type="checkbox" name="checked_recipient" id="checked_recipient_<%$addr%>" value="<%$addr%>" <% $recips{$addr} ? "checked" : "" %>> + <label for="checked_recipient_<%$addr%>"><& /Elements/ShowUser, Address => Email::Address->parse($addr) &></label> + </li> +% } +</ul> +</&> <& /Elements/Submit, Name => 'SubmitTicket', Label => loc('Save Changes'), Caption => loc("If you've updated anything above, be sure to"), color => "#333399" &> </form> @@ -70,12 +83,44 @@ my @results; my $Ticket = LoadTicket($id); $m->callback( TicketObj => $Ticket, ARGSRef => \%ARGS ); +# Update the squelch list +my %squelched = map {$_->Content => 1} $Ticket->SquelchMailTo; +my %checked = map {$_ => 1} grep {defined} + (ref $ARGS{'checked_recipient'} eq "ARRAY" ? @{$ARGS{'checked_recipient'}} + : defined $ARGS{'checked_recipient'} ? ($ARGS{'checked_recipient'}) : ()); +my @all = grep {defined} + (ref $ARGS{'autorecipient'} eq "ARRAY" ? @{$ARGS{'autorecipient'}} + : defined $ARGS{'autorecipient'} ? ($ARGS{'autorecipient'}) : ()); +$Ticket->UnsquelchMailTo($_) + for grep {$squelched{$_}} keys %checked; +$Ticket->SquelchMailTo($_) + for grep {!$squelched{$_} and !$checked{$_}} @all; + # if we're trying to search for watchers and nothing else unless ($OnlySearchForPeople or $OnlySearchForGroup) { push @results, ProcessTicketBasics( TicketObj => $Ticket, ARGSRef => \%ARGS); push @results, ProcessTicketWatchers( TicketObj => $Ticket, ARGSRef => \%ARGS); $Ticket->ApplyTransactionBatch; } + +# Use the ticket's scrips to figure out the new list of recipients. +my @txns = grep {defined} map {$Ticket->DryRun( Action => $_ )} qw/comment respond/; +my %recips=(); +for my $scrip (map {@{$_->Scrips->Prepared}} @txns) { + next unless $scrip->ActionObj->Action->isa('RT::Action::SendEmail'); + for my $type (qw(To Cc Bcc)) { + $recips{$_->address} = 1 for $scrip->ActionObj->Action->$type(); + } +} +for my $rule (map {@{$_->Rules}} @txns) { + next unless $rule->{hints} && $rule->{hints}{class} eq "SendEmail"; + for my $type (qw(To Cc Bcc)) { + $recips{$_} = 1 for @{$rule->{hints}{recips}{$type}}; + } +} + +# Use tkt squelch list to get recipients who will NOT get mail: +$recips{$_->Content} = 0 for $Ticket->SquelchMailTo; </%INIT> diff --git a/rt/share/html/Ticket/Reminders.html b/rt/share/html/Ticket/Reminders.html index 0bbd87e9a..8461efe44 100755 --- a/rt/share/html/Ticket/Reminders.html +++ b/rt/share/html/Ticket/Reminders.html @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC %# <sales@bestpractical.com> %# %# (Except where explicitly superseded by other copyright notices) @@ -45,29 +45,27 @@ %# those contributions and any derivatives thereof. %# %# END BPS TAGGED BLOCK }}} -<& /Elements/Header, Title => loc("Reminder ticket #[_1]", $Ticket->Id) &> -<& /Ticket/Elements/Tabs, - Ticket => $Ticket, - current_tab => "Ticket/Reminders.html?id=".$Ticket->Id, - Title => loc("Reminders for ticket #[_1]", $Ticket->Id) &> +<& /Elements/Header, Title => loc("Reminders for ticket #[_1]", $Ticket->Id) &> +<& /Elements/Tabs &> % $m->callback(CallbackName => 'BeforeActionList', ARGSRef => \%ARGS, Ticket => $Ticket); -<form action="<%RT->Config->Get('WebPath')%>/Ticket/Reminders.html" method="post"> +<form action="<%RT->Config->Get('WebPath')%>/Ticket/Reminders.html" name="UpdateReminders" id="UpdateReminders" method="post"> <&|/Widgets/TitleBox, title => loc("Reminders"), class=>'ticket-info-reminders' &> <& /Ticket/Elements/Reminders, Ticket => $Ticket, ShowCompleted => 1, Edit => 1 &> </&> -<& /Elements/Submit, Label => loc('Save') &> +<& /Elements/Submit, + Label => loc('Save Changes') &> </form> <%INIT> - my $Ticket = LoadTicket($id); - + +ProcessTicketReminders( TicketObj => $Ticket, ARGSRef => \%ARGS ); </%INIT> <%ARGS> $id => undef diff --git a/rt/share/html/Ticket/ShowEmailRecord.html b/rt/share/html/Ticket/ShowEmailRecord.html index 77f0f5966..55ee82338 100644 --- a/rt/share/html/Ticket/ShowEmailRecord.html +++ b/rt/share/html/Ticket/ShowEmailRecord.html @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC %# <sales@bestpractical.com> %# %# (Except where explicitly superseded by other copyright notices) @@ -79,7 +79,7 @@ $show = sub { $m->out( '</pre></div>' ); }; -my $AttachmentObj = new RT::Attachment($session{'CurrentUser'}); +my $AttachmentObj = RT::Attachment->new($session{'CurrentUser'}); $AttachmentObj->Load($Attachment) || Abort(loc("Attachment '[_1]' could not be loaded", $Attachment)); unless ( $AttachmentObj->id ) { Abort(loc("Attachment '[_1]' could not be loaded", $Attachment)); diff --git a/rt/share/html/Ticket/Update.html b/rt/share/html/Ticket/Update.html index 0d4e3b223..64bd531cf 100755 --- a/rt/share/html/Ticket/Update.html +++ b/rt/share/html/Ticket/Update.html @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC %# <sales@bestpractical.com> %# %# (Except where explicitly superseded by other copyright notices) @@ -45,11 +45,9 @@ %# those contributions and any derivatives thereof. %# %# END BPS TAGGED BLOCK }}} -<& /Elements/Header, Title => $title &> -<& /Ticket/Elements/Tabs, - Ticket => $TicketObj, - Title=> $title &> - +<& /Elements/Header, Title => $title &> +<& /Elements/Tabs &> + % $m->callback(CallbackName => 'BeforeActionList', ARGSRef => \%ARGS, Ticket => $TicketObj); <& /Elements/ListActions, actions => \@results &> @@ -62,79 +60,24 @@ <& /Elements/GnuPG/SignEncryptWidget:ShowIssues, self => $gnupg_widget &> +<div id="ticket-update-metadata"> + <&|/Widgets/TitleBox, title => loc('Ticket and Transaction') &> <table width="100%" border="0"> % $m->callback(CallbackName => 'AfterTableOpens', ARGSRef => \%ARGS, Ticket => $TicketObj); -<tr><td valign="baseline" class="label"><&|/l&>Status</&>:</td> -<td valign="baseline"> -<script type="text/javascript"> -function changeStatus() { - var Status_select = document.getElementById('Status'); - var x = Status_select.options[Status_select.selectedIndex].value; - var text = document.getElementById('WillResolve_Date'); - var button = document.getElementById('WillResolve_Date_date_button'); - if (x == 'resolved' || x == 'rejected' || x == 'deleted') { - text.disabled = true; - button.style.display = 'none'; - } - else { - text.disabled = false; - button.style.display = 'inline'; - } -} -</script> -<& /Elements/SelectStatus, - Name=>"Status", - DefaultLabel => loc("[_1] (Unchanged)", loc($TicketObj->Status)), - Default => $ARGS{'Status'} - || ($TicketObj->Status eq $DefaultStatus ? undef : $DefaultStatus, - onchange => 'changeStatus()' -)&> -<span class="label"><&|/l&>Resolve this Ticket on</&>:</span> -<& /Elements/SelectDate, - menu_prefix => 'WillResolve', - current => 0, - ShowTime => 0, -&> -% if ( $TicketObj->WillResolve ) { -<span class="label"> (<% $TicketObj->WillResolveObj->AsString %>)</span> -% } -<script type="text/javascript"> -changeStatus(); -</script> -</td> -<td rowspan=4 valign="top"> -<table style="float:right;"> -<tr> -<td class="label"><&|/l&>Worked</&>:</td> -<td><& /Elements/EditTimeValue, - Name => 'UpdateTimeWorked', - Default => $ARGS{UpdateTimeWorked}||'', - InUnits => $ARGS{'UpdateTimeWorked-TimeUnits'}||'minutes', -&> -</td></tr> <& /Ticket/Elements/EditTransactionCustomFields, %ARGS, TicketObj => $TicketObj, UILocation => 'TimeWorked', &> -</table></td></tr> + % my $skip; % $m->callback( %ARGS, CallbackName => 'BeforeUpdateType', skip => \$skip ); % if (!$skip) { <input type="hidden" class="hidden" name="id" value="<%$TicketObj->Id%>" /><br /> % } -<tr><td class="label"><&|/l&>Owner</&>:</td> -<td><& /Elements/SelectOwner, - Name => "Owner", - TicketObj => $TicketObj, - QueueObj => $TicketObj->QueueObj, - DefaultLabel => loc("[_1] (Unchanged)", $m->scomp('/Elements/ShowUser', User => $TicketObj->OwnerObj)), - Default => $ARGS{'Owner'} -&></td> -</tr> <tr><td class="label"><&|/l&>Update Type</&>:</td> -<td><select name="UpdateType"> +<td><select name="UpdateType" id="UpdateType"> % if ($CanComment) { <option value="private" <% ($ARGS{'UpdateType'} && $ARGS{'UpdateType'} eq "private") ? qq[ selected="selected"] : !$ARGS{'UpdateType'}&&$CommentDefault |n %>><&|/l&>Comments (Not sent to requestors)</&></option> % } @@ -142,29 +85,105 @@ changeStatus(); <option value="response" <% ($ARGS{'UpdateType'} && $ARGS{'UpdateType'} eq "response") ? qq[ selected="selected"] : !$ARGS{'UpdateType'}&&$ResponseDefault |n %>><&|/l&>Reply to requestors</&></option> % } </select> + +<script type="text/javascript"> + jQuery(function() { + jQuery("#UpdateType").change(function(ev) { + jQuery(".messagebox-container") + .removeClass("action-response action-private") + .addClass("action-"+ev.target.value); + }); + }); + jQuery(function() { + jQuery("input[name=TxnSendMailTo]").change(function(ev) { + jQuery("input[name=TxnSendMailTo][value="+ev.target.value+"]") + .attr("checked",jQuery(ev.target).attr('checked')); + }); + }); +</script> + % $m->callback( %ARGS, CallbackName => 'AfterUpdateType' ); </td></tr> -<tr><td class="label"><&|/l&>Subject</&>:</td><td> <input name="UpdateSubject" size="60" value="<% $ARGS{UpdateSubject} || $TicketObj->Subject()%>" /> -% $m->callback( %ARGS, CallbackName => 'AfterSubject' ); -</td></tr> -<& /Ticket/Elements/UpdateCc, %ARGS, TicketObj => $TicketObj &> +<script type="text/javascript"> +function changeStatus() { + var Status_select = document.getElementById('Status'); + var x = Status_select.options[Status_select.selectedIndex].value; + var text = document.getElementById('WillResolve_Date'); + var button = document.getElementById('WillResolve_Date_date_button'); + if (x == 'resolved' || x == 'rejected' || x == 'deleted') { + text.disabled = true; + button.style.display = 'none'; + } + else { + text.disabled = false; + button.style.display = 'inline'; + } +} +</script> -<& /Ticket/Elements/EditTransactionCustomFields, %ARGS, TicketObj => $TicketObj &> +<& /Ticket/Elements/EditBasics, + TicketObj => $TicketObj, + InTable => 1, + fields => [ + { name => 'Status', + comp => '/Elements/SelectStatus', + args => { + Name => 'Status', + DefaultLabel => loc("[_1] (Unchanged)", loc($TicketObj->Status)), + Default => $ARGS{'Status'} || ($TicketObj->Status eq $DefaultStatus ? undef : $DefaultStatus), + TicketObj => $TicketObj, + QueueObj => $TicketObj->QueueObj, + onchange => 'changeStatus()' + }, + }, + { name => 'Resolve this Ticket on', + comp => '/Elements/SelectDate', + args => { + menu_prefix => 'WillResolve', + current => 0, + ShowTime => 0, + }, + }, + { name => 'Owner', + comp => '/Elements/SelectOwner', + args => { + Name => "Owner", + TicketObj => $TicketObj, + QueueObj => $TicketObj->QueueObj, + DefaultLabel => loc("[_1] (Unchanged)", $m->scomp('/Elements/ShowUser', User => $TicketObj->OwnerObj)), + Default => $ARGS{'Owner'} + } + }, + { name => 'Worked', + comp => '/Elements/EditTimeValue', + args => { + Name => 'UpdateTimeWorked', + Default => $ARGS{UpdateTimeWorked}||'', + InUnits => $ARGS{'UpdateTimeWorked-TimeUnits'}||'minutes', + } + }, + ] +&> -% if (exists $session{'Attachments'}) { -<tr><td><&|/l&>Attached file</&>:</td> -<td> -<&|/l&>Check box to delete</&><br /> -% foreach my $attach_name (keys %{$session{'Attachments'}}) { -<input type="checkbox" class="checkbox" name="DeleteAttach-<%$attach_name%>" value="1" /><%$attach_name%><br /> -% } # end of foreach -</td> -</tr> -% } # end of if +<script type="text/javascript"> +changeStatus(); +</script> -<tr><td class="label"><&|/l&>Attach</&>:</td><td><input name="Attach" type="file" /><input type="submit" class="button" name="AddMoreAttach" value="<&|/l&>Add More Files</&>" /><input type="hidden" class="hidden" name="UpdateAttach" value="1" /> -</td></tr> +% $m->callback( %ARGS, CallbackName => 'AfterWorked', Ticket => $TicketObj ); + +<& /Ticket/Elements/EditTransactionCustomFields, %ARGS, TicketObj => $TicketObj, AsTable => 1 &> + + <!--</table>--> + </&> +</div> + +<div id="ticket-update-message"> + <& /Ticket/Elements/ShowSimplifiedRecipients, TicketObj => $TicketObj, %ARGS &> + + <&|/Widgets/TitleBox, title => loc('Message'), class => 'messagedetails' &> + <table width="100%" border="0"> +<& /Ticket/Elements/UpdateCc, %ARGS, TicketObj => $TicketObj &> % if ( $gnupg_widget ) { <tr><td> </td><td> @@ -176,7 +195,13 @@ changeStatus(); % } % $m->callback( %ARGS, CallbackName => 'AfterGnuPG' ); -<tr><td class="label" valign="top"><&|/l&>Message</&>:</td><td colspan=2> +<tr><td class="label"><&|/l&>Subject</&>:</td><td> <input type="text" name="UpdateSubject" value="<% $ARGS{UpdateSubject} || $TicketObj->Subject || '' %>" /> +% $m->callback( %ARGS, CallbackName => 'AfterSubject' ); +</td></tr> + +<tr><td class="label" valign="top"><&|/l&>Message</&>:</td> +<td class="messagebox-container action-<% $type %>"> +<& /Articles/Elements/BeforeMessageBox, %ARGS &> % $m->callback( %ARGS, CallbackName => 'BeforeMessageBox' ); % if (exists $ARGS{UpdateContent}) { % # preserve QuoteTransaction so we can use it to set up sane references/in/reply to @@ -189,25 +214,32 @@ changeStatus(); % $IncludeSignature = 0 if $Action ne 'Respond' && !RT->Config->Get('MessageBoxIncludeSignatureOnComment'); <& /Elements/MessageBox, Name=>"UpdateContent", IncludeSignature => $IncludeSignature, %ARGS &> % } +% $m->callback( %ARGS, CallbackName => 'AfterMessageBox' ); </td></tr> -</table> - + <& /Ticket/Elements/AddAttachments, %ARGS, TicketObj => $TicketObj &> + </table> +</&> + <& /Elements/Submit, Label => loc('Update Ticket'), Name => 'SubmitTicket', id => 'SubmitTicket' &> -<& /Elements/Submit, Label => loc('Update Ticket'), Name => 'SubmitTicket' &> % if ($TicketObj->CurrentUserHasRight('ShowOutgoingEmail')) { -<&|/Widgets/TitleBox, title => loc('Scrips and Recipients') &> -<& /Ticket/Elements/PreviewScrips, TicketObj => $TicketObj, %ARGS &> -</&> + <&|/Widgets/TitleBox, title => loc('Scrips and Recipients'), id => 'previewscrips', rolledup => RT->Config->Get('SimplifiedRecipients', $session{'CurrentUser'}) &> + <& /Ticket/Elements/PreviewScrips, TicketObj => $TicketObj, %ARGS &> + </&> +% } +</div> +% if (my $recips = $m->notes("DryRun-Recipients-".$TicketObj->Id)) { +<input type="hidden" name="TxnRecipients" value="<% join ",",sort keys %{$recips} %>" /> % } + </form> +<hr class="clear" /> <%INIT> my $CanRespond = 0; my $CanComment = 0; my $checks_failure = 0; -my $title; my $TicketObj = LoadTicket($id); @@ -219,17 +251,7 @@ unless($DefaultStatus){ $DefaultStatus=($ARGS{'Status'} ||$TicketObj->Status()); } -unless (RT->Config->Get('SuppressAutoOpenOnUpdate', $session{'CurrentUser'})) { - if ($DefaultStatus eq 'new') { - $DefaultStatus = 'open'; - } -} - -if ($DefaultStatus eq 'resolved') { - $title = loc("Resolve ticket #[_1] ([_2])", $TicketObj->id, $TicketObj->Subject); -} else { - $title = loc("Update ticket #[_1] ([_2])", $TicketObj->id, $TicketObj->Subject); -} +my $title = loc("Update ticket #[_1] ([_2])", $TicketObj->id, $TicketObj->Subject||''); # Things needed in the template - we'll do the processing here, just # for the convenience: @@ -243,6 +265,10 @@ if ($Action ne 'Respond') { $ResponseDefault = qq[ selected="selected"]; } +my $type = $ARGS{'UpdateType'} ? $ARGS{'UpdateType'} : + lc $ARGS{'Action'} eq 'respond' ? 'response' : + lc $ARGS{'Action'} eq 'comment' ? 'private' : + 'none' ; $CanRespond = 1 if ( $TicketObj->CurrentUserHasRight('ReplyToTicket') or @@ -252,17 +278,16 @@ $CanComment = 1 if ( $TicketObj->CurrentUserHasRight('CommentOnTicket') or $TicketObj->CurrentUserHasRight('ModifyTicket') ); -# {{{ deal with deleting uploaded attachments +# deal with deleting uploaded attachments foreach my $key (keys %ARGS) { if ($key =~ m/^DeleteAttach-(.+)$/) { delete $session{'Attachments'}{$1}; } $session{'Attachments'} = { %{$session{'Attachments'} || {}} }; } -# }}} -# {{{ store the uploaded attachment in session -if ($ARGS{'Attach'}) { # attachment? +# store the uploaded attachment in session +if ( defined $ARGS{'Attach'} && length $ARGS{'Attach'} ) { # attachment? my $attachment = MakeMIMEEntity( AttachmentFieldName => 'Attach' ); @@ -273,13 +298,11 @@ if ($ARGS{'Attach'}) { # attachment? $file_path => $attachment, }; } -# }}} # delete temporary storage entry to make WebUI clean unless (keys %{$session{'Attachments'}} and $ARGS{'UpdateAttach'}) { delete $session{'Attachments'}; } -# }}} my $gnupg_widget = $m->comp('/Elements/GnuPG/SignEncryptWidget:new', Arguments => \%ARGS ); $m->comp( '/Elements/GnuPG/SignEncryptWidget:Process', @@ -288,6 +311,14 @@ $m->comp( '/Elements/GnuPG/SignEncryptWidget:Process', ); if ( $ARGS{'SubmitTicket'} ) { + + my %checked = map {$_ => 1} grep {defined} + (ref $ARGS{'TxnSendMailTo'} eq "ARRAY" ? @{$ARGS{'TxnSendMailTo'}} + : defined $ARGS{'TxnSendMailTo'} ? ($ARGS{'TxnSendMailTo'}) : ()); + + my @squelchlist = grep {not $checked{$_}} split /,/, ($ARGS{'TxnRecipients'}||''); + $ARGS{'SquelchMailTo'} = \@squelchlist if @squelchlist; + my $CFs = $TicketObj->TransactionCustomFields; my $ValidCFs = $m->comp( '/Elements/ValidateCustomFields', |